-
Notifications
You must be signed in to change notification settings - Fork 35
Update stokes most #106
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
Update stokes most #106
Conversation
This commit introduces an alternative method for computing the boundary layer depth (BLD) in KPP, based on the entrainment rule. This method is activated when the non-solar surface buoyancy flux (surfBuoy_NS) is negative and STOKES_MOST = True. In all other cases, the standard Richardson Number-based method is used. The non-solar surface buoyancy flux is estimated internally using an exponential attenuation function, since only the total surface buoyancy flux (solar + non-solar) is currently available to the module. Ideally, the non-solar component should be provided explicitly. Several new diagnostics have been added, and some of the existing ones have been updated. Specifically, the parameterized shear, buoyancy, and Stokes TKE production terms are calculated. We conducted multiple tests where these terms are passed to the MLE module and used in the denominator of the Bodner streamfunction. However, because of the small Cr value we adopted (0.01), this had minimal effect on the solutions, so we decided to keep the original simpler implementation and not pursue this option for now. This commit should be evaluated together with CVMix/CVMix-src#106.
mnlevy1981
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to sit on this for a month, but there are some minor updates needed. I'm happy to help you with them next week.
src/shared/cvmix_kpp.F90
Outdated
| public :: cvmix_kpp_ustokes_SL_model | ||
|
|
||
| public :: cvmix_kpp_compute_ER_depth | ||
| public :: cvmix_kpp_quad_fit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a polynomial fit in cvmix_math.F90, though it needs a little updating because the wants two points and a derivative instead of the three points used here. Still, it makes more sense to add this functionality to the existing routine rather than create a new subroutine here.
src/shared/cvmix_kpp.F90
Outdated
| Cu = 0.023_cvmix_r8 | ||
| Cs = 0.038_cvmix_r8 | ||
| Cb = 0.96_cvmix_r8 | ||
| CempCGm = 3.5_cvmix_r8 | ||
| CempCGs = 4.7_cvmix_r8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be declared as real(cvmix_r8), parameter (and it would be nice to see a comment describing units / where these values come from)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
| PBfact = 0.0893759_cvmix_r8 | ||
| PB = MAX( -surfBuoy_NS * BLdepth * PBfact , cvmix_zero ) | ||
| PBfact = 0.00215_cvmix_r8 * CempCGs | ||
| PB = PB + PBfact * BLdepth * ( abs(surf_buoy_force) - surf_buoy_force ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think PBfact could also be a Fortran parameter (0.0893759_cvmix_r8) and then
PB = MAX( -surfBuoy_NS * BLdepth * PBfact , cvmix_zero ) &
+ PBfact * CempCGs * BLdepth * ( abs(surf_buoy_force) - surf_buoy_force )There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PBfact cannot be used as a parameter because it is used with different values.
src/shared/cvmix_kpp.F90
Outdated
|
|
||
| nlev = size(OBL_depth) | ||
| Cemp_Rs = 4.7_cvmix_r8 | ||
| ! Gat1 = cvmix_zero |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just remove lines instead of commenting them out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
src/shared/cvmix_kpp.F90
Outdated
| ! kinv = MAXLOC( Nsq ) ! interface index of maximum stratification, N2>0 (inversion) | ||
| ! maxNsq = Nsq( kinv ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just remove lines instead of commenting them out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
src/shared/cvmix_kpp.F90
Outdated
| sigma(:) = cvmix_zero | ||
| Bflux(1) = Bsfc_ns ! non-solar surface buoyancy boundary condition for all kbl | ||
| ! Set OBL_depth(1)=top cell center values | ||
| BEnt(1) = cvmix_zero |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a duplicate of line 3591; should it be removed, or should it be BEnt(2) instead of BEnt(1)? Looking at how BEnt is used, I see a couple of BEnt(kbl+1) but no other index is evaluated. Maybe this should be a scalar instead of an array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BEnt is now a scalar.
|
Thank you, @mnlevy1981, for all the suggestions. We have addressed all comments except for switching to the polynomial fit in cvmix_math.F90. |
The function cvmix_kpp_quad_fit did two things: 1. Given three values of (sigma, Bflux), find quadratic polynomial that interpolates function 2. Find the root of the derivative of the quadratic, and evaluate the polynomial at that point I created an interface for cvmix_math_poly_interp() to do the interpolation (that routine could do quadratic interpolation, but based on two points and a derivative instead of three points), and then find the derivative and evaluate the polynomial in cvmix_kpp_compute_ER_depth() instead of a separate function
|
@mnlevy1981, here is the difference in SST when adding your polynomial fit after 1 month ( B = baseline):
This is more than I expected, so I will run for longer to check the effects on climate-related metrics. |
|
This PR has minimal impact on climate metrics. |
* Add entrainment rule BLD calculation to KPP This commit introduces an alternative method for computing the boundary layer depth (BLD) in KPP, based on the entrainment rule. This method is activated when the non-solar surface buoyancy flux (surfBuoy_NS) is negative and STOKES_MOST = True. In all other cases, the standard Richardson Number-based method is used. The non-solar surface buoyancy flux is estimated internally using an exponential attenuation function, since only the total surface buoyancy flux (solar + non-solar) is currently available to the module. Ideally, the non-solar component should be provided explicitly. Several new diagnostics have been added, and some of the existing ones have been updated. Specifically, the parameterized shear, buoyancy, and Stokes TKE production terms are calculated. We conducted multiple tests where these terms are passed to the MLE module and used in the denominator of the Bodner streamfunction. However, because of the small Cr value we adopted (0.01), this had minimal effect on the solutions, so we decided to keep the original simpler implementation and not pursue this option for now. This commit should be evaluated together with CVMix/CVMix-src#106. * Fix typos * Update CVMix to latest commit Include new entreinment rule depth changes. * Revert unit conversion for Vt2 and GoRho * Update description and remove empty line * Split description of variables * Refactor KPP StokesMOST diagnostics and allocations - Removed unused `ustar` array from KPP_CS type. - Restricted registration, allocation, and posting of StokesMOST diagnostics (`StokesXI`, `Lam2`, `BEdE_ER`, `ERdepth`, `RNdepth`, `PU_TKE`, `PS_TKE`, `PB_TKE`) to cases when `CS%StokesMOST` is enabled. - Moved allocations of related arrays inside StokesMOST conditional block. - Updated condition for calculating `surfBuoy_NS` to avoid division by zero in alog(buoyFlux(i,j,2)/buoyFlux(i,j,3)). - Wrapped diagnostic and debug checks in `if (CS%StokesMOST)` conditions. - Minor cleanup of comments and diagnostic labeling.
* Add entrainment rule BLD calculation to KPP This commit introduces an alternative method for computing the boundary layer depth (BLD) in KPP, based on the entrainment rule. This method is activated when the non-solar surface buoyancy flux (surfBuoy_NS) is negative and STOKES_MOST = True. In all other cases, the standard Richardson Number-based method is used. The non-solar surface buoyancy flux is estimated internally using an exponential attenuation function, since only the total surface buoyancy flux (solar + non-solar) is currently available to the module. Ideally, the non-solar component should be provided explicitly. Several new diagnostics have been added, and some of the existing ones have been updated. Specifically, the parameterized shear, buoyancy, and Stokes TKE production terms are calculated. We conducted multiple tests where these terms are passed to the MLE module and used in the denominator of the Bodner streamfunction. However, because of the small Cr value we adopted (0.01), this had minimal effect on the solutions, so we decided to keep the original simpler implementation and not pursue this option for now. This commit should be evaluated together with CVMix/CVMix-src#106. * Fix typos * Update CVMix to latest commit Include new entreinment rule depth changes. * Revert unit conversion for Vt2 and GoRho * Update description and remove empty line * Split description of variables * Refactor KPP StokesMOST diagnostics and allocations - Removed unused `ustar` array from KPP_CS type. - Restricted registration, allocation, and posting of StokesMOST diagnostics (`StokesXI`, `Lam2`, `BEdE_ER`, `ERdepth`, `RNdepth`, `PU_TKE`, `PS_TKE`, `PB_TKE`) to cases when `CS%StokesMOST` is enabled. - Moved allocations of related arrays inside StokesMOST conditional block. - Updated condition for calculating `surfBuoy_NS` to avoid division by zero in alog(buoyFlux(i,j,2)/buoyFlux(i,j,3)). - Wrapped diagnostic and debug checks in `if (CS%StokesMOST)` conditions. - Minor cleanup of comments and diagnostic labeling. * Add support for Lam2 in MLE and KPP - Introduced `Lam2` as an optional pointer field in `vertvisc_type` and restart registry. - Extended `mixedlayer_restrat` and `mixedlayer_restrat_Bodner` to accept/use `Lam2` when available, with fallback to equilibrium value. - Added `KPP_get_Lam2` routine to expose Lam2 from KPP control structure. - Connected `Lam2` into `diabatic_ALE_legacy` and `diabatic_ALE` and copied into `visc%Lam2` when allocated. - Enabled allocation and restart registration of `Lam2` when STOKES_MOST and Bodner MLE are used. - Updated MOM.F90 call sites to conditionally pass `Lam2`. This integrates Langmuir turbulence effects via Lam2 into MLE restratification. * Fix duplicate declaration of Lam2 * Change paramFile to param_file * Fixed OMP directive in KPP_get_Lam2 * Defined Lam2 in diabatic_ALE * Add ParameterBlock for KPP so STOKES_MOST can be read * Fix segfault by checking CS%visc before accessing Lam2 Wrapped the mixedlayer_restrat call with an outer check on `associated(CS%visc)` to ensure the derived type is valid before testing `CS%visc%Lam2`. This prevents invalid memory references when `CS%visc` is unassociated. * Replace associated with allocated * Replace associated with allocated * Replace allocated with associated for checking CS%visc%Lam2 * Only call KPP_get_Lam2 if visc%Lam2 is associated * Implement conditional logic for passing Lam2 to MLE. Read `StokesMOST` and `wave_enhanced_ustar` to determine whether Lam2 should be passed to the `mixedlayer_restrat` subroutine. * Safely handle optional Lam2 pointer in mixedlayer_restrat Added local logical flag `haveLam2` to ensure Lam2 is only used when both present and associated. This avoids potential segfaults from evaluating `associated(Lam2)` when Lam2 is not passed. * Improve description of WAVE_ENHANCED_USTAR

cvmix_kpp_compute_ER_depthto calculate the entrainment flux and corresponding depth using the entrainment rule. For each assumed boundary layer depth (OBL_depth) at cell centers, the subroutine iteratively searches for the first depth where the entrainment depth (ERdepth) becomes positive. The corresponding index (kER_depth) is also returned. If no viable solution is found, the subroutine returnsERdepth = -1andkER_depth = -1.cvmix_kpp_quad_fitto estimate the maximum of a quadratic fit.cvmix_kpp_compute_StokesXi