From b6319f842a59ecb6f22f89c7ee38df98223eb65e Mon Sep 17 00:00:00 2001 From: Matthew Harrison Date: Thu, 5 Oct 2023 11:32:15 -0400 Subject: [PATCH] *Patches for nonBous_OBCs to prevent blocking This adds logical tests to determine the global OBC data update patterns to allow for halo updates related to these updates without having the model hang up with inconsistently blocked message passing calls. This commit corrects a bug with some test cases that was introduced with the halo update after the call to thicknesses_to_dz in update_OBC_segment_data two commits previously. --- src/core/MOM_boundary_update.F90 | 2 +- src/core/MOM_open_boundary.F90 | 18 ++++++++++++++++-- .../MOM_state_initialization.F90 | 5 ++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/core/MOM_boundary_update.F90 b/src/core/MOM_boundary_update.F90 index 5a098cdf84..75f69dc779 100644 --- a/src/core/MOM_boundary_update.F90 +++ b/src/core/MOM_boundary_update.F90 @@ -156,7 +156,7 @@ subroutine update_OBC_data(OBC, G, GV, US, tv, h, CS, Time) call shelfwave_set_OBC_data(OBC, CS%shelfwave_OBC_CSp, G, GV, US, h, Time) if (CS%use_dyed_channel) & call dyed_channel_update_flow(OBC, CS%dyed_channel_OBC_CSp, G, GV, US, Time) - if (OBC%needs_IO_for_data .or. OBC%add_tide_constituents) & + if (OBC%any_needs_IO_for_data .or. OBC%add_tide_constituents) & call update_OBC_segment_data(G, GV, US, OBC, tv, h, Time) end subroutine update_OBC_data diff --git a/src/core/MOM_open_boundary.F90 b/src/core/MOM_open_boundary.F90 index d32e947da1..896a677b02 100644 --- a/src/core/MOM_open_boundary.F90 +++ b/src/core/MOM_open_boundary.F90 @@ -278,7 +278,9 @@ module MOM_open_boundary logical :: update_OBC = .false. !< Is OBC data time-dependent logical :: update_OBC_seg_data = .false. !< Is it the time for OBC segment data update for fields that !! require less frequent update - logical :: needs_IO_for_data = .false. !< Is any i/o needed for OBCs + logical :: needs_IO_for_data = .false. !< Is any i/o needed for OBCs on the current PE + logical :: any_needs_IO_for_data = .false. !< Is any i/o needed for OBCs globally + logical :: some_need_no_IO_for_data = .false. !< Are there any PEs with OBCs that do not need i/o. logical :: zero_vorticity = .false. !< If True, sets relative vorticity to zero on open boundaries. logical :: freeslip_vorticity = .false. !< If True, sets normal gradient of tangential velocity to zero !! in the relative vorticity on open boundaries. @@ -736,6 +738,7 @@ subroutine initialize_segment_data(G, GV, US, OBC, PF) integer, dimension(1) :: single_pelist type(external_tracers_segments_props), pointer :: obgc_segments_props_list =>NULL() !will be able to dynamically switch between sub-sampling refined grid data or model grid + integer :: IO_needs(3) ! Sums to determine global OBC data use and update patterns. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -1045,6 +1048,15 @@ subroutine initialize_segment_data(G, GV, US, OBC, PF) call Set_PElist(saved_pelist) + ! Determine global IO data requirement patterns. + IO_needs(1) = 0 ; if (OBC%needs_IO_for_data) IO_needs(1) = 1 + IO_needs(2) = 0 ; if (OBC%update_OBC) IO_needs(2) = 1 + IO_needs(3) = 0 ; if (.not.OBC%needs_IO_for_data) IO_needs(3) = 1 + call sum_across_PES(IO_needs, 3) + OBC%any_needs_IO_for_data = (IO_needs(1) > 0) + OBC%update_OBC = (IO_needs(2) > 0) + OBC%some_need_no_IO_for_data = (IO_needs(3) > 0) + end subroutine initialize_segment_data !> Return an appropriate dimensional scaling factor for input data based on an OBC segment data @@ -1909,7 +1921,7 @@ logical function open_boundary_query(OBC, apply_open_OBC, apply_specified_OBC, a OBC%Flather_v_BCs_exist_globally if (present(apply_nudged_OBC)) open_boundary_query = OBC%nudged_u_BCs_exist_globally .or. & OBC%nudged_v_BCs_exist_globally - if (present(needs_ext_seg_data)) open_boundary_query = OBC%needs_IO_for_data + if (present(needs_ext_seg_data)) open_boundary_query = OBC%any_needs_IO_for_data end function open_boundary_query @@ -5755,6 +5767,8 @@ subroutine rotate_OBC_config(OBC_in, G_in, OBC, G, turns) OBC%brushcutter_mode = OBC_in%brushcutter_mode OBC%update_OBC = OBC_in%update_OBC OBC%needs_IO_for_data = OBC_in%needs_IO_for_data + OBC%any_needs_IO_for_data = OBC_in%any_needs_IO_for_data + OBC%some_need_no_IO_for_data = OBC_in%some_need_no_IO_for_data OBC%ntr = OBC_in%ntr diff --git a/src/initialization/MOM_state_initialization.F90 b/src/initialization/MOM_state_initialization.F90 index fc676781bc..0f01e9fb62 100644 --- a/src/initialization/MOM_state_initialization.F90 +++ b/src/initialization/MOM_state_initialization.F90 @@ -18,6 +18,7 @@ module MOM_state_initialization use MOM_get_input, only : directories use MOM_grid, only : ocean_grid_type, isPointInCell use MOM_interface_heights, only : find_eta, dz_to_thickness, dz_to_thickness_simple +use MOM_interface_heights, only : calc_derived_thermo use MOM_io, only : file_exists, field_size, MOM_read_data, MOM_read_vector, slasher use MOM_open_boundary, only : ocean_OBC_type, open_boundary_init, set_tracer_data use MOM_open_boundary, only : OBC_NONE @@ -607,8 +608,10 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, & call initialize_segment_data(G, GV, US, OBC, PF) ! call open_boundary_config(G, US, PF, OBC) ! Call this once to fill boundary arrays from fixed values - if (.not. OBC%needs_IO_for_data) & + if (OBC%some_need_no_IO_for_data) then + call calc_derived_thermo(tv, h, G, GV, US) call update_OBC_segment_data(G, GV, US, OBC, tv, h, Time) + endif call get_param(PF, mdl, "OBC_USER_CONFIG", config, & "A string that sets how the user code is invoked to set open boundary data: \n"//&