From e1b9ac7a01559c3c311a922927baf1ef7d4f0532 Mon Sep 17 00:00:00 2001 From: Lionel GUEZ <guez@lmd.ens.fr> Date: Thu, 25 May 2023 22:00:58 +0200 Subject: [PATCH] Move some computation to main program unit Move the computation of the search window for the outermost contour and `outside_points` from procedure `set_contours` to main program unit. The motivation is to have a clearer interface of procedure `set_contours`, without `s` and `i`. --- Inst_eddies/inst_eddies.f90 | 50 +++++++++++++++++++++++++++++++++--- Inst_eddies/set_contours.f90 | 47 ++++++++------------------------- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/Inst_eddies/inst_eddies.f90 b/Inst_eddies/inst_eddies.f90 index 4a267803..a5768244 100644 --- a/Inst_eddies/inst_eddies.f90 +++ b/Inst_eddies/inst_eddies.f90 @@ -7,12 +7,13 @@ program inst_eddies use, intrinsic:: ISO_FORTRAN_ENV ! Libraries: - use jumble, only: assert, new_unit, pi, argwhere + use jumble, only: assert, new_unit, pi, argwhere, twopi use numer_rec_95, only: indexx use config_m, only: config, min_radius use derived_types, only: snapshot, shpc_slice_handler - use input_ssh_m, only: input_ssh + use input_ssh_m, only: input_ssh, max_radius + use nearby_extr_m, only: nearby_extr use set_all_extr_m, only: set_all_extr use set_contours_m, only: set_contours use shpc_close_m, only: shpc_close @@ -24,7 +25,7 @@ program inst_eddies type(snapshot) s TYPE(shpc_slice_handler) hshpc_cyclo, hshpc_anti - integer iostat, i, l + integer iostat, i, l, nlon, nlat character(len = 200) iomsg integer unit @@ -59,6 +60,16 @@ program inst_eddies ! identifying numbers of a selection of extrema integer n_cycl ! number of cyclones + integer llc(2) ! indices in global grid of lower left corner + integer urc(2) ! indices in global grid of upper right corner + + real corner_window(2) ! longitude and latitude of the window around each + ! extremum, in rad + + real, allocatable:: outside_points(:, :) ! (2, :) longitude and + ! latitude, in rad, of all the significant extrema, except the + ! target extremum + !-------------------------------------------------------------- @@ -133,7 +144,38 @@ program inst_eddies loop_extr: do l = 1, s%number_extr i = sorted_extr(l) - call set_contours(s, step, periodic, ssh, u, v, corner, min_area, i) + if (.not. periodic) nlon = size(ssh, 1) + nlat = size(ssh, 2) + + associate (e => s%list(i)) + ! Define the geographical window around each eddy extremum: + + llc = e%extr%coord_proj - max_radius + urc = e%extr%coord_proj + max_radius + + llc(2) = max(llc(2), 1) + urc(2) = min(urc(2), nlat) + + if (.not. periodic) then + llc(1) = max(llc(1), 1) + urc(1) = min(urc(1), nlon) + end if + + corner_window = corner + (llc - 1) * step + end associate + + outside_points = nearby_extr(s%extr_map(llc(1):urc(1), llc(2):urc(2)), & + s%list, i) + + ! Shift the longitude of each point to a value close to the + ! longitude of the target extremum: + if (periodic) outside_points(1, :) = outside_points(1, :) & + + ceiling((corner_window(1) - outside_points(1, :)) / twopi) & + * twopi + + call set_contours(s, step, ssh(llc(1):urc(1), llc(2):urc(2)), & + u(llc(1):urc(1), llc(2):urc(2)), v(llc(1):urc(1), llc(2):urc(2)), & + corner_window, min_area, i, outside_points) end do loop_extr call cpu_time(t1) diff --git a/Inst_eddies/set_contours.f90 b/Inst_eddies/set_contours.f90 index 9f538292..7c809d51 100644 --- a/Inst_eddies/set_contours.f90 +++ b/Inst_eddies/set_contours.f90 @@ -4,19 +4,17 @@ module set_contours_m contains - subroutine set_contours(s, step, periodic, ssh, u, v, corner, min_area, i) + subroutine set_contours(s, step, ssh, u, v, corner, min_area, i, & + outside_points) ! This procedure sets all contours in the snapshot "s". ! Libraries: use contour_531, only: convert_to_ind - use jumble, only: twopi use config_m, only: min_amp use derived_types, only: snapshot, null_ssh_contour, ssh_contour use get_1_outerm_m, only: get_1_outerm - use input_ssh_m, only: max_radius - use nearby_extr_m, only: nearby_extr use set_max_speed_m, only: set_max_speed type(snapshot), intent(inout):: s @@ -25,9 +23,8 @@ contains ! s%list%innermost_level, s%extr_map should be defined on entry. real, intent(in):: step(:) ! (2) longitude and latitude steps, in rad - logical, intent(in):: periodic ! grid is periodic in longitude - real, intent(in), dimension(merge(1 - max_radius(1), 1, periodic):, :):: & + real, intent(in), dimension(:, :):: & ssh, u, v ! (1 - max_radius(1):nlon + max_radius(1), nlat) if the grid is ! periodic in longitude, else (nlon, nlat). Sea-surface height, in @@ -39,6 +36,10 @@ contains real, intent(in):: min_area ! minimum area of an outermost contour, in m2 integer, intent(in):: i + real, intent(in):: outside_points(:, :) ! (2, :) longitude and + ! latitude, in rad, of all the significant extrema, except the + ! target extremum + ! Local: integer nlon, nlat @@ -52,10 +53,6 @@ contains real corner_window(2) ! longitude and latitude of the window around each ! extremum, in rad - real, allocatable:: outside_points(:, :) ! (2, :) longitude and - ! latitude, in rad, of all the significant extrema, except the - ! target extremum - integer, parameter:: n_max_cont = 31 ! must be >= 3 type(ssh_contour) cont_list(n_max_cont) @@ -72,42 +69,18 @@ contains !-------------------------------------------------------------- - if (.not. periodic) nlon = size(ssh, 1) + nlon = size(ssh, 1) nlat = size(ssh, 2) associate (e => s%list(i)) - ! Define the geographical window around each eddy extremum: - - llc = e%extr%coord_proj - max_radius - urc = e%extr%coord_proj + max_radius - - llc(2) = max(llc(2), 1) - urc(2) = min(urc(2), nlat) - - if (.not. periodic) then - llc(1) = max(llc(1), 1) - urc(1) = min(urc(1), nlon) - end if - - corner_window = corner + (llc - 1) * step - ! Only look for good contours with amplitudes >= min_amp: innermost_level_2 = merge(e%extr%ssh + merge(min_amp, - min_amp, & e%cyclone), e%innermost_level, & abs(e%extr%ssh - e%innermost_level) < min_amp) - outside_points = nearby_extr(s%extr_map(llc(1):urc(1), & - llc(2):urc(2)), s%list, i) - - ! Shift the longitude of each point to a value close to the - ! longitude of the target extremum: - if (periodic) outside_points(1, :) = outside_points(1, :) & - + ceiling((corner_window(1) - outside_points(1, :)) / twopi) & - * twopi - call get_1_outerm(e%out_cont, cont_list, n_cont, e%cyclone, & e%extr%coord, innermost_level_2, outside_points, & - ssh(llc(1):urc(1), llc(2):urc(2)), corner_window, step, min_area) + ssh, corner, step, min_area) ! Done with outermost contour, now let us take care of the ! max-speed contour. @@ -122,7 +95,7 @@ contains ! Should have no effect except because of roundup error: urc(2) = min(urc(2), nlat) - if (.not. periodic) urc(1) = min(urc(1), nlon) + urc(1) = min(urc(1), nlon) corner_window = corner + (llc - 1) * step -- GitLab