From db3a5b5a2b945536b4f73864a51ac4dbd4d1eaa9 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Wed, 14 Jun 2017 16:01:03 -0400 Subject: [PATCH 1/3] (*)Corrected the barotropic mass source compensation Corrected a bug when DIABATIC_FIRST=True in how the compensation for the difference between the dynamic sea surface height used by the barotropic solver and the height that the layers would have if net mass sources were applied gradually instead of abruptly at the start of the thermodynamic time step. This would change answers if both SPLIT and DIABATIC_FIRST are true and the value of BT_MASS_SOURCE_LIMIT > 0.0, but as there are currently no test cases that match these conditions, the answers are unchanged in all of the test cases. In cases where the answers do change, they are unambiguously better based on weaker high frequency gravity waves arising from coupling shocks. --- src/core/MOM.F90 | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index ee017b176e..57c324badb 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -186,7 +186,7 @@ module MOM logical :: adiabatic !< If true, then no diapycnal mass fluxes, with no calls !! to routines to calculate or apply diapycnal fluxes. logical :: use_temperature !< If true, temp and saln used as state variables. - logical :: calc_rho_for_sea_lev !< If true, calculate rho to convert pressure to sea level + logical :: calc_rho_for_sea_lev !< If true, calculate rho to convert pressure to sea level logical :: use_frazil !< If true, liquid seawater freezes if temp below freezing, !! with accumulated heat deficit returned to surface ocean. logical :: bound_salinity !< If true, salt is added to keep salinity above @@ -774,17 +774,12 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) ! recalculated. This always occurs at the start of a coupling time ! step because the externally prescribed stresses may have changed. do_calc_bbl = ((CS%t_dyn_rel_adv == 0.0) .or. (n==1)) - if (do_calc_bbl) then ; if (thermo_does_span_coupling) then - bbl_time_int = dt_therm - else !### This is inconsistent with corresponding expressions above. -RWH - bbl_time_int = dt*real(1+MIN(ntstep-MOD(n,ntstep),n_max-n)) - endif ; endif - if (do_calc_bbl) then ! Calculate the BBL properties and store them inside visc (u,h). call cpu_clock_begin(id_clock_BBL_visc) + bbl_time_int = max(dt, min(dt_therm - CS%t_dyn_rel_adv, dt*(1+n_max-n)) ) call enable_averaging(bbl_time_int, & - Time_local+set_time(int(bbl_time_int-dt)), CS%diag) + Time_local+set_time(int(bbl_time_int-dt+0.5)), CS%diag) call set_viscous_BBL(u, v, h, CS%tv, CS%visc, G, GV, CS%set_visc_CSp) call disable_averaging(CS%diag) call cpu_clock_end(id_clock_BBL_visc) @@ -852,9 +847,7 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) dtbt_reset_time = CS%rel_time endif - mass_src_time = CS%t_dyn_rel_adv - !### This should be mass_src_time = CS%t_dyn_rel_thermo - + mass_src_time = CS%t_dyn_rel_thermo if (CS%legacy_split) then call step_MOM_dyn_legacy_split(u, v, h, CS%tv, CS%visc, & Time_local, dt, fluxes, CS%p_surf_begin, CS%p_surf_end, & From 5daf60f92bbf438fcc4187eb63307f09cef14f6d Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Wed, 14 Jun 2017 18:02:53 -0400 Subject: [PATCH 2/3] Corrected typos in dOxyGen comments Corrected spelling errors and content errors in several of the comments describing subroutine arguments. All answers are bitwise identical. --- src/core/MOM_barotropic.F90 | 7 +++---- src/core/MOM_dynamics_split_RK2.F90 | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/MOM_barotropic.F90 b/src/core/MOM_barotropic.F90 index e316a068f5..0ed63a1c35 100644 --- a/src/core/MOM_barotropic.F90 +++ b/src/core/MOM_barotropic.F90 @@ -2342,7 +2342,7 @@ subroutine apply_velocity_OBCs(OBC, ubt, vbt, uhbt, vhbt, ubt_trans, vbt_trans, !! column mass anomaly, in m or kg m-2. real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: ubt_old !< The starting value of ubt in a barotropic step, !! m s-1. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: vbt_old !< The starting value of ubt in a barotropic step, + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: vbt_old !< The starting value of vbt in a barotropic step, !! m s-1. type(BT_OBC_type), intent(in) :: BT_OBC !< A structure with the private barotropic arrays !! related to the open boundary conditions, @@ -2350,12 +2350,11 @@ subroutine apply_velocity_OBCs(OBC, ubt, vbt, uhbt, vhbt, ubt_trans, vbt_trans, integer, intent(in) :: halo !< The extra halo size to use here. real, intent(in) :: dtbt !< The time step, in s. real, intent(in) :: bebt !< The fractional weighting of the future velocity - !! in - !! determining the transport. + !! in determining the transport. logical, intent(in) :: use_BT_cont !< If true, use the BT_cont_types to calculate !! transports. real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: Datu !< A fixed estimate of the face areas at u points. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at u points. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at v points. type(local_BT_cont_u_type), dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: BTCL_u !< Structure of information used !! for a dynamic estimate of the face areas at !! u-points. diff --git a/src/core/MOM_dynamics_split_RK2.F90 b/src/core/MOM_dynamics_split_RK2.F90 index 16342f49da..1f79a83ff5 100644 --- a/src/core/MOM_dynamics_split_RK2.F90 +++ b/src/core/MOM_dynamics_split_RK2.F90 @@ -214,7 +214,7 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, & type(forcing), intent(in) :: fluxes !< forcing fields real, dimension(:,:), pointer :: p_surf_begin !< surf pressure at start of this dynamic time step (Pa) real, dimension(:,:), pointer :: p_surf_end !< surf pressure at end of this dynamic time step (Pa) - real, intent(in) :: dt_since_flux !< elapesed time since fluxes were applied (sec) + real, intent(in) :: dt_since_flux !< elapsed time since fluxes were applied (sec) real, intent(in) :: dt_therm !< thermodynamic time step (sec) real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target, intent(inout) :: uh !< zonal volume/mass transport (m3/s or kg/s) real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target, intent(inout) :: vh !< merid volume/mass transport (m3/s or kg/s) From a8565c774848a62099a95c6753e8f8ee5f040a6a Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Wed, 14 Jun 2017 18:17:51 -0400 Subject: [PATCH 3/3] Replaced group_pass of h with pass_var of h Reverted to the simpler pass_var routines for the single 3-d variable h. This avoids the issue that triggered the recent pull request #520, and it should have no performance impacts. (In fact, by letting each call have its own halo size, it might lead to performance improvements in subsequent commits.) All answers are bitwise identical. --- src/core/MOM.F90 | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 9a4ee330ad..517220f50e 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -413,7 +413,6 @@ module MOM ! These are used for group halo updates. type(group_pass_type) :: pass_tau_ustar_psurf - type(group_pass_type) :: pass_h type(group_pass_type) :: pass_ray type(group_pass_type) :: pass_bbl_thick_kv_bbl type(group_pass_type) :: pass_T_S_h @@ -568,8 +567,6 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%ustar(:,:), G%Domain) if (ASSOCIATED(fluxes%p_surf)) & call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%p_surf(:,:), G%Domain) - if ((CS%thickness_diffuse .and. (.not.CS%thickness_diffuse_first .or. CS%t_dyn_rel_adv == 0)) .OR. CS%mixedlayer_restrat) & - call create_group_pass(CS%pass_h, h, G%Domain) !###, halo=max(2,cont_stensil)) do_pass_Ray = .FALSE. if ((.not.G%Domain%symmetric) .and. & @@ -758,7 +755,7 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) CS%MEKE, CS%VarMix, CS%CDp, CS%thickness_diffuse_CSp) call cpu_clock_end(id_clock_thick_diff) call cpu_clock_begin(id_clock_pass) - call do_group_pass(CS%pass_h, G%Domain) + call pass_var(h, G%Domain) !###, halo=max(2,cont_stensil)) call cpu_clock_end(id_clock_pass) call disable_averaging(CS%diag) if (showCallTree) call callTree_waypoint("finished thickness_diffuse_first (step_MOM)") @@ -898,7 +895,7 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) if (CS%debug) call hchksum(h,"Post-thickness_diffuse h", G%HI, haloshift=1, scale=GV%H_to_m) call cpu_clock_end(id_clock_thick_diff) call cpu_clock_begin(id_clock_pass) - call do_group_pass(CS%pass_h, G%Domain) + call pass_var(h, G%Domain) !###, halo=max(2,cont_stensil)) call cpu_clock_end(id_clock_pass) if (showCallTree) call callTree_waypoint("finished thickness_diffuse (step_MOM)") endif @@ -915,7 +912,7 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) G, GV, CS%mixedlayer_restrat_CSp) call cpu_clock_end(id_clock_ml_restrat) call cpu_clock_begin(id_clock_pass) - call do_group_pass(CS%pass_h, G%Domain) + call pass_var(h, G%Domain) !###, halo=max(2,cont_stensil)) call cpu_clock_end(id_clock_pass) if (CS%debug) then call hchksum(h,"Post-mixedlayer_restrat h", G%HI, haloshift=1, scale=GV%H_to_m) @@ -1396,7 +1393,7 @@ subroutine step_tracers(fluxes, state, Time_start, time_interval, CS) fluxes%netMassOut(:,:) = CS%offline_CSp%netMassOut(:,:) call offline_diabatic_ale(fluxes, Time_start, Time_end, time_interval, CS%offline_CSp, & CS%h, eatr, ebtr) - call pass_var(CS%h,G%Domain) + call pass_var(CS%h, G%Domain) ! Do the transport, the final ALE remappings, horizontal diffusion if it is ! the last iteration @@ -1415,9 +1412,7 @@ subroutine step_tracers(fluxes, state, Time_start, time_interval, CS) call cpu_clock_begin(id_clock_ALE) call ALE_offline_tracer_final( G, GV, CS%h, h_end, CS%tracer_Reg, CS%ALE_CSp) call cpu_clock_end(id_clock_ALE) - call pass_var(CS%h,G%Domain) - - + call pass_var(CS%h, G%Domain) endif else ! NON-ALE MODE...NOT WELL TESTED @@ -1445,9 +1440,9 @@ subroutine step_tracers(fluxes, state, Time_start, time_interval, CS) CS%tv%S = salt_mean CS%h = h_end - call pass_var(CS%tv%T,G%Domain) - call pass_var(CS%tv%S,G%Domain) - call pass_var(CS%h,G%Domain) + call pass_var(CS%tv%T, G%Domain) + call pass_var(CS%tv%S, G%Domain) + call pass_var(CS%h, G%Domain) endif