Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+*More consistent non-Boussinesq mixed layer thicknesses #610

Merged
merged 6 commits into from
May 31, 2024

Conversation

Hallberg-NOAA
Copy link
Member

This PR includes a series of commits that standardize how the depth of active surface mixing is passed around and how and where that depth is converted into a thickness when in non-Boussinesq mode. This is accomplished via calls to the new routine convert_MLD_to_ML_thickness() and by accessing the new variable visc%h_ML in the various places where the mixed layer thickness is used. Because this variable may be used from a previous timestep, it has been added to the restart file in cases where it is in use. These changes make the use of the surface boundary layer thickness much more consistent with how it is calculated when in non-Boussinesq mode, without changing anything in Boussinesq mode.

This PR includes a number of changes to public interfaces. There is a new argument to mixedlayer_restrat(), mixedlayer_restrat_Bodner(), bulkmixedlayer(), tracer_hordiff(), hor_bnd_diffusion() and neutral_diffusion_calc_coeffs(), along with changes to the units of arguments to mixedlayer_restrat_OM4 and applyBoundaryFluxesInOut(). One widely used argument in diabatic and its children was converted from a pointer to an ordinary 2-d array renamed from Hml to BLD for more clarity about its meaning and units. In the ideal age tracer package, ideal_age_tracer_column_physics() has one less argument and changed units to another, while the units of all variables in count_BL_layers() were revised. There is an additional variable the restart files in some cases.

This PR will change answers in the fully non-Boussinesq mode, but because this mode is not yet being used in production, there is not an answer-date or bug flag that will recover the previous non-Boussinesq answers. All Boussinesq answers are bitwise identical.

All answers are bitwise identical in Boussinesq mode, but in non-Boussinesq mode there are changes in answers in some cases. There is a new element in the vertvisc_type, the new publicly visible routine convert_MLD_to_ML_thickness() and a number of new or modified arguments to existing publicly visible interfaces.

The commits in this PR include:

  • b97034eee +*Pass visc%h_ML to call_tracer_column_fns
  • e2e52ea46 +*Use visc%h_ML in tracer diffusion routines
  • 7a8f5bcae +*Convert MLD to ML_thickness in diabatic
  • c06f080c1 +Pass h_MLD to mixedlayer_restrat
  • e1d9244fe +*Use thickness in ideal_age_tracer_column_physics
  • 6536d42a2 +Add convert_MLD_to_ML_thickness

@Hallberg-NOAA Hallberg-NOAA added enhancement New feature or request answer-changing A change in results (actual or potential) labels Apr 26, 2024
Copy link
Member

@marshallward marshallward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably not the best one to review, but I think this is all correct. The greater persistence of hML simplifies a lot of internal operations, at the cost of passing around visc everywhere. The conversion loops also look correct.

@marshallward
Copy link
Member

marshallward commented May 30, 2024

@Hallberg-NOAA There is one minor conflict that needs to be fixed.

  Added the routine convert_MLD_to_ML_thickness to consistently convert the
mixed layer depths (in units of [Z ~> m]) back to the mixed layer thicknesses
(in [H ~> m or kg m-2]), with proper error checking and handling of the
non-Boussinesq case.  The body of this routine was taken from duplicated
blocks of code in MOM_mixedlayer_restrat.F90.  This is not tested directly
in this PR, but it was tested via revisions to MOM_mixedlayer_restrat.F90 that
are included in a subsequent commit.  All answers are bitwise identical, but
there is a new publicly visible interface.
  Pass mixed layer thickness, rather than mixed layer depth, to
ideal_age_tracer_column_physics, and determine the number of layers within
the mixed layer in count_BL_layers in thickness units rather than depth units.
To accommodate these changes there is now a call to convert_MLD_to_ML_thickness
inside of call_tracer_column_fns.  The thermo_var_ptrs type argument (tv) to
ideal_age_tracer_column_physics and count_BL_layers are no longer used and
have been removed.  All answers are bitwise identical in Boussinesq mode, but
in non-Boussinesq mode there are changes in the passive ideal age tracers at
the level of roundoff.  There are also changes in the units of arguments and
the number of arguments to a public interface.
  Provide the mixed layer thickness, as well as the mixed layer depth as
arguments to mixedlayer_restrat.  The code that had previously been used to
convert between the two has now been removed to the new external function
convert_MLD_to_ML_thickness.  To accommodate these changes, a new element,
h_ML, was added to the vertvisc type, and a call to convert_MLD_to_ML_thickness
was temporarily added in step_MOM_dynamics just before the call to
mixedlayer_restrat.  All answers are bitwise identical, but there
are changes to a public interface.
  Moved the call to convert mixed layer depths into mixed layer thicknesses
from right before the call to mixedlayer_restrat into the various diabatic
routines just after they are calculated.  This code rearrangement changes
answers in non-Boussinesq mode because the layer specific volumes will have
evolved between these two calls, but it is consistent with the mixed
layer thicknesses as used in the boundary layer parameterizations.

  A new argument was added to bulkmixedlayer to return the mixed layer
thickness that was already being calculated.  The previous argument Hml
was renamed to BLD and changed from a pointer into a simple array.  Both
are intent(inout) rather than intent(out) to preserve values in halos.

  This commit also revises the logic around the allocation of visc%h_ML and
its registration as a restart variable, including handling cases where an older
restart file is being read that includes MLD but not h_ML.  Because the mixed
layer depth is used in almost cases, CS%Hml in the control structure for
MOM.F90 was changed from a pointer to an allocatable, with values of 0 in those
cases (e.g., when ADIABATIC is true) where it is not used.

  In addition, the argument Hml to the various diabatic routines was changed to
MLD to more clearly reflect that it is a depth and not a thickness.  Outside of
diabatic, BML is only used to provide the tracer point boundary layer depths
to the calling routines, so it does not need a halo update.  Instead, all of
the halo updates for the various elements of visc that do need halo updates
after the diabatic calls are collected into one place for efficiency and more
accurate timings.

  The scale arguments of 34 checksum calls were revised from GV%H_to_m to
GV%H_to_MKS for more accurate checksums in non-Boussinesq configurations by
avoiding multiplication by an reference specific volume, and instead only
rescaling by an integer power of 2.

  All answers are bitwise identical in Boussinesq mode, but in non-Boussinesq
mode there are changes in answers in cases that use the boundary layer
thicknesses obtained from the boundary layer parameterizations in subsequent
calculations, such as mixed layer restratification with some options.  There are
also changes to the arguments of several publicly visible routines.
  Pass visc%h_ML to applyBoundaryFluxesInOut, which avoids the need for the
thickness conversions inside of that routine.  Answers are bitwise identical for
Boussinesq cases, but they will change in non-Boussinesq cases because the layer
specific volumes have changed between the time the boundary layer thicknesses
have been calculated and when they are being used in the brine plume
parameterization.

  Also use visc%h_ML in place of calls to KPP_get_BLD or energetic_PBL_get_MLD
in step_MOM_dyn_split_RK2, hor_bnd_diffusion and neutral_diffusion_calc_coeffs.
This change requires a new vertvisc_type argument to tracer_hordiff,
hor_bnd_diffusion and neutral_diffusion_calc_coeffs.  Boussinesq answers are
bitwise identical, but non-Boussinesq answers change because they now use the
actual model specific volumes rather than some prescribed constant value to to
the relevant unit conversions.

  The logic in set_visc_register_restarts was also updated so that visc%MLD and
visc%h_ML are allocated and registered for restarts in the cases where they will
be used.

  All answers are bitwise identical in Boussinesq mode, but in non-Boussinesq
mode there are changes in answers in cases that use neutral tracer diffusion
that excludes the boundary layer, horizontal tracer diffusion in the boundary
layer or FPMIX.  There are also changes to the arguments of several publicly
visible routines.
  Added the optional argument h_BL to call_tracer_column_fns, and then pass
visc%h_ML to this routine as a part of the calls from the diabatic routines.
This argument is not provided in adiabatic mode or in offline tracer mode, which
is why it has been made optional.  All answers are bitwise identical in
Boussinesq mode but ideal age tracers can change in non-Boussinesq mode due to
the updates to the layer specific volumes between the calculation of the
boundary layer properties and the calls to call_tracer_column_fns.
@Hallberg-NOAA Hallberg-NOAA force-pushed the NonBous_ML_thickness branch from 9031a83 to 75b9437 Compare May 31, 2024 15:08
@marshallward
Copy link
Member

@marshallward marshallward merged commit d66adff into NOAA-GFDL:dev/gfdl May 31, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answer-changing A change in results (actual or potential) enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants