forked from E3SM-Project/E3SM
-
Notifications
You must be signed in to change notification settings - Fork 8
[WIP] add KPP mixing #512
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
Draft
vanroekel
wants to merge
36
commits into
E3SM-Project:develop
Choose a base branch
from
vanroekel:vanroekel/omega/kpp-final
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
[WIP] add KPP mixing #512
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
52d08cc
port forcing tendencies (thickness and tracers) + update doc, yml
alicebarthel 363a505
added the enthalpy of mass fluxes; CtFrz has public interface
alicebarthel 3ecac9a
added a test for thermo forcing tendencies
alicebarthel 8befc58
made mass enthalpy flux dependent on thickness flag - under discussion
alicebarthel e2b0ba0
draft a non-teos10 CtFrz in comments - WIP
alicebarthel 5a9ad35
updated the documentation
alicebarthel 5078bec
Revert "made mass enthalpy flux dependent on thickness flag - under d…
alicebarthel c421724
updated the documentation
alicebarthel 5ae42d3
correction to pressure units and ctest
alicebarthel f4ba88c
update due to fill values and review comments
alicebarthel 0ca27d5
resolve memory issue on GPUs
alicebarthel 251dc55
inlines eos::calcPtFromCt in header with kokkos_function to fix gpu w…
katsmith133 5e0445f
adds linear and constant eos options to thermal forcing
katsmith133 ec02e7e
adds notes to docs and adds suggestions from review
katsmith133 2092194
Adds reset of forcing fields if not in stream
vanroekel 947fb1e
Update components/omega/doc/devGuide/Forcing.md
cbegeman 9897605
Fixup documentation
cbegeman 236ed0b
remove SurfInsituTemp calcs
0bd6f8b
fixes GPU failures on frontier
054dda3
Revert "fixes GPU failures on frontier"
katsmith133 c6a46e4
fixed GPU isssues on Frontier
katsmith133 833aa97
fixes omega_pr errors on Frontier
katsmith133 ec8de99
Add KPP mixing and non-local tracer tendencies
vanroekel 0cd2f5a
fixes to unit tests
vanroekel b6a1de2
adds KPP connections to all time stepping routines
vanroekel 0315a40
Updates to docs for KPP
vanroekel eb78878
Fixes KPP depth and adds cTest for depth
vanroekel 0ba9f8b
Updates variable names and descriptions
vanroekel 5bc36af
Add review suggestions to documentation
vanroekel 01cad80
Remove redundant KPP StopOBLSearch parameter
vanroekel 3437975
Carry KPP surface-layer averages across trial depths
vanroekel 38056c3
Stop the KPP boundary layer search at the crossing
vanroekel 95d9022
updates docs and makes KPP compute once each step only
vanroekel bc5946c
Deduplicate KPP device math and decouple non-local shape
vanroekel 4213aa1
moves KPP functors to header in tendencies
vanroekel cb185f2
removes unneeded debug information
vanroekel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| (omega-design-kppmix)= | ||
| # KPP Boundary Layer Mixing | ||
|
|
||
| **Table of Contents** | ||
| 1. [Overview](#1-overview) | ||
| 2. [Requirements](#2-requirements) | ||
| 3. [Algorithmic Formulation](#3-algorithmic-formulation) | ||
| 4. [Design](#4-design) | ||
| 5. [Verification and Testing](#5-verification-and-testing) | ||
|
|
||
| ## 1 Overview | ||
|
|
||
| This document describes the Omega implementation of the K Profile Parameterization | ||
| (KPP) ocean boundary layer mixing. KPP computes a boundary-layer depth, vertical | ||
| viscosity, vertical diffusivity, and a non-local tracer flux shape implemented outside | ||
| the implicit vertical mixing routine. The implementation follows that in MPAS-Ocean and | ||
| uses direct ports of the functions defined in the [CVMix](https://github.com/CVMix/CVMix-src) | ||
| version of KPP. | ||
|
|
||
| The implementation is in `KPPMix` and is integrated with the Omega tendency and | ||
| RK2, RK4, and Forward-backward stepping routines. Relative to broad vertical mixing documentation, this | ||
| page focuses specifically on KPP theory, algorithmic choices, and testing. | ||
|
|
||
| ## 2 Requirements | ||
|
|
||
| ### 2.1 Requirement: Boundary-layer depth from bulk Richardson criterion | ||
|
|
||
| Following [Large et al (1994)](https://agupubs.onlinelibrary.wiley.com/doi/10.1029/94RG01872), | ||
| the OBL depth must be diagnosed from a bulk Richardson criterion so that | ||
| mixing depth responds to evolving stratification, shear, and surface forcing. It also | ||
| must include a unresolved turbulent shear contribution. | ||
|
|
||
| ### 2.2 Requirement: Coefficients must be computable in parallel over columns | ||
|
|
||
| The KPP implementation must operate over many columns in parallel using Omega | ||
| array/kernels, rather than serial single-column calls. | ||
|
|
||
| ### 2.3 Requirement: Compatible with additive vertical-mixing framework | ||
|
|
||
| KPP viscosity/diffusivity fields must be compatible with existing Omega vertical | ||
| mixing infrastructure so that other chosen vertical mixing sources can be merged | ||
| with KPP. | ||
|
|
||
| ### 2.4 Desired: Non-local flux and profile matching controls | ||
|
|
||
| KPP will support a non-local tracer flux from LMD94 and include configurable | ||
| viscosity/diffusivity matching at the base of the boundary layer. | ||
|
|
||
| ## 3 Algorithmic Formulation | ||
|
|
||
| The implementation follows a two-stage KPP structure. | ||
|
|
||
| ### 3.1 Stage 1: OBL depth search | ||
|
|
||
| For each water column, OBL depth $h$ is diagnosed by searching downward until | ||
| bulk Richardson number reaches a critical value: | ||
|
|
||
| $$ | ||
| Ri_b(z) = \frac{\Delta b(z)\, z}{|\Delta \mathbf{U}(z)|^2 + V_t^2(z)} | ||
| $$ | ||
|
|
||
| with threshold | ||
|
|
||
| $$ | ||
| Ri_b(h) = Ri_{crit}. | ||
| $$ | ||
|
|
||
| Here, $\Delta b$ is buoyancy jump relative to a surface layer average, | ||
| $|\Delta \mathbf{U}|^2$ is shear contribution again computed relative to the | ||
| surface layer average, and $V_t^2$ is unresolved shear. | ||
|
|
||
| When the bulk Richardson number falls between model layers, quadratic interpolation | ||
| is utilized to find the depth. In addition the boundary layer depth is constrained | ||
| to fall between a configurable minimum OBL under sea ice and a maximum set by the water | ||
| column depth. | ||
|
|
||
| The boundary layer depth search is a growing inner loop. The outer loop iterates over all model layers. | ||
| The current model layer is set as a boundary layer depth candidate and $Ri_b$ is calculated for all | ||
| model layers shallower than the current depth. If any layer in the inner loop has an $Ri_b*StopOBL$ that | ||
| exceeds $Ri_{crit}$ the loop terminates. | ||
|
|
||
| ### 3.2 Stage 2: KPP coefficients and non-local flux | ||
|
|
||
| Given a diagnosed $h$, KPP computes viscosity and diffusivity coefficients at the top of every | ||
| Omega cell except the surface and the bottom using shape functions | ||
| in normalized depth $\sigma = -d/h$, where $d$ is the depth relative to the sea surface height, not the physical depth: | ||
|
|
||
| $$ | ||
| K_m(\sigma) = h\, w_m(\sigma)\, M_1(\sigma), | ||
| $$ | ||
|
|
||
| $$ | ||
| K_s(\sigma) = h\, w_s(\sigma)\, S_1(\sigma), | ||
| $$ | ||
|
|
||
| where $w_m$ and $w_s$ are turbulent velocity scales from Monin-Obukhov style | ||
| stability functions, see Appendix B of [Large et al, 1994](https://agupubs.onlinelibrary.wiley.com/doi/10.1029/94RG01872). $M_1$ and $S_1$ are shape functions. | ||
| The generic form of the shape function is given by | ||
|
|
||
| $$ | ||
| X(\sigma) = c_1 \sigma^3 + c_2 \sigma^2 + c_3 \sigma + c_4 | ||
| $$ | ||
|
|
||
| The coefficients are determined by various conditions, e.g., zero viscosity and diffusivity at the | ||
| surface, assuming a linear reduction of the turbulent flux with distance from the surface in the | ||
| surface layer. As in MPAS-Ocean, we include two options to determine the final coefficients. The original | ||
| version of KPP matches predicted viscosities and diffusivities to those predicted by other schemes | ||
| (e.g., shear instability driven mixing) and a second option where viscosities and diffusivities are | ||
| instead additive. In the latter case, the shape function greatly simplifies to $X(\sigma) = \sigma(1-\sigma)^2. | ||
|
|
||
| For either shape function, enhanced diffusivity can be included near the boundary layer base. This can smooth boundary layer deepening in time. | ||
|
|
||
| The non-local tracer flux uses the scalar shape function, scaled by the constant | ||
| $C_s$ from Eq. (20) of Large et al. (1994) rather than by $h\, w_s$: | ||
|
|
||
| $$ | ||
| \gamma_s(\sigma) = C_s\, S_1(\sigma). | ||
| $$ | ||
|
|
||
| Here $S_1$ is always the unmatched scalar shape $\sigma(1-\sigma)^2$, regardless | ||
| of the `MatchTechnique` setting. Matching is a property of the diffusivity | ||
| profile only: the matched shape is non-zero at $\sigma = -1$ by construction, so | ||
| reusing it for $\gamma_s$ would leave a finite non-local flux at the boundary | ||
| layer base that drops discontinuously to zero immediately below it. CVMix draws | ||
| the same distinction, exposing the non-local shape as a separate choice from the | ||
| matching option. | ||
|
|
||
|
|
||
|
|
||
| ## 4 Design | ||
|
|
||
| ### 4.1 Data types and parameters | ||
|
|
||
| #### 4.1.1 Parameters | ||
|
|
||
| KPP is configured from the `VertMix: KPP` YAML group. Key parameters include: | ||
|
|
||
| - `Enable` | ||
| - `CriticalBulkRichardsonNumber` | ||
| - `MatchTechnique` (`SimpleShapes` or `MatchBoth`) | ||
| - `InterpType2` (`LMD94`, `Linear`, `Quadratic`, `Cubic`) | ||
| - `UseEnhancedDiffusion` | ||
| - `IceFractionThresholdForLangmuir` | ||
| - `IceFractionThresholdForMinimumOBL` | ||
| - `MinimumOBLUnderSeaIce` | ||
| - `BackgroundViscosity` | ||
| - `BackgroundDiffusivity` | ||
| - `DebugDiagnostics` | ||
|
|
||
| Defaults and usage examples are documented in the user guide page: | ||
| [KPP in the User Guide](../userGuide/KPPMix.md). | ||
|
|
||
| #### 4.1.2 Class/data structure | ||
|
|
||
| `KPPMix` is a singleton that owns persistent output fields, including: | ||
|
|
||
| - `BoundaryLayerDepth`, `IndexBoundaryLayerDepth` | ||
| - `VertDiff`, `VertVisc` | ||
| - `VertNonLocalFlux` | ||
| - diagnostics such as `BulkRichardsonNumber`, `BulkRichardsonShear`, | ||
| `UnresolvedShear`, `BuoyancyJump`, and `TurbulentVelocityScale` | ||
|
|
||
| ### 4.2 Methods | ||
|
|
||
| Main interface: | ||
|
|
||
| ```c++ | ||
| void computeKPPMix(const Array2DReal &PotentialDensity, | ||
| const Array2DReal &NormalVelocity, | ||
| const Array2DReal &TangentialVelocity, | ||
| const Array1DReal &SurfaceFrictionVelocity, | ||
| const Array1DReal &SurfaceBuoyancyFlux, | ||
| const Array2DReal &BruntVaisalaFreqSq, | ||
| const Array1DReal &IceFraction, | ||
| const Array1DReal &WindSpeed10m = Array1DReal()); | ||
| ``` | ||
|
|
||
| Internal stages: | ||
| - `computeOBLDepth(...)` | ||
| - `computeMixingCoefficients(...)` | ||
|
|
||
| ### 4.3 Time stepper coupling behavior | ||
|
|
||
| KPP is coupled to all three Omega time steppers -- Forward-Backward, | ||
| RungeKutta2, and RungeKutta4. For every stepper, KPP is evaluated exactly | ||
| once per time step, at the start of the step on the state at time $n$, before | ||
| any tendency is evaluated. The resulting boundary-layer depth, viscosity, | ||
| diffusivity, and non-local flux profile are then held fixed for the remainder | ||
| of the step. | ||
|
|
||
| This design differs from MPAS-Ocean, where the boundary layer depth, diffusivity, and viscosity are computed at the end of the time step and the non local flux is applied on the following timestep. The primary advantage of this new approach is: | ||
|
|
||
| 1. **Consistency.** The non-local flux $\gamma_s$ applied in the tracer | ||
| tendency at each stage and the diffusivity $K_s$ used by the end-of-step | ||
| implicit vertical mixing solve are derived from the same OBL depth and the | ||
| same shape function $S_1(\sigma)$. Recomputing KPP at each stage would | ||
| pair a stage-dependent $\gamma_s$ with a different $K_s$, breaking the | ||
| correspondence described in section 3.2. | ||
|
|
||
| Because KPP is evaluated before the step advances, the KPP diagnostics | ||
| written for a step describe the state at the beginning of that step. The | ||
| coefficients are lagged relative to the state during the implicit solve at the end of the | ||
| step. Full call-flow detail per stepper is described for developers and | ||
| users in: | ||
|
|
||
| - [Developer KPP workflow](../devGuide/KPPMix.md) | ||
| - [User runtime notes](../userGuide/KPPMix.md) | ||
|
|
||
| ## 5 Verification and Testing | ||
|
|
||
| ### 5.1 Unit-level checks | ||
|
|
||
| Use targeted tests and diagnostics to verify: | ||
|
|
||
| - OBL depth search monotonicity and threshold crossing behavior | ||
| - Positive bounded coefficients and expected background behavior below OBL | ||
| - Correct enable/disable behavior for non-local flux and enhanced diffusion | ||
|
|
||
| Tests cover requirements: 2.1, 2.2, 2.3, 2.4. | ||
|
|
||
| ### 5.2 Polaris testing | ||
|
|
||
| The single column test case can be run across a wide range of surface forcing | ||
| (heat, evaporative, and momentum fluxes) and the following diagnostics will be | ||
| plotted over time | ||
|
|
||
| - `BoundaryLayerDepth` | ||
| - `BulkRichardsonNumber` | ||
| - `VertDiff`, `VertVisc` | ||
| - `VertNonLocalFlux` | ||
|
|
||
| For simple cases, such as free convection, boundary layer depth can be compared against | ||
| a semi-analytic solution (e.g., Appendix F, ([Van Roekel et al, 2018](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2018MS001336)). | ||
|
|
||
| The global test case, forced by annual averaged ERA-5 net surface heat, freshwater, and | ||
| momentum fluxes provides a qualitative assessment of KPP behavior. | ||
|
|
||
| ### 5.3 Configuration sensitivity checks | ||
|
|
||
| Short single column and global test cases can be run varying critical parameters such as | ||
|
|
||
| - `CriticalBulkRichardsonNumber` | ||
| - `MatchTechnique` | ||
| - `InterpType2` | ||
| - `UseEnhancedDiffusion` | ||
| - sea-ice thresholds | ||
|
|
||
| to ensure expected qualitative and quantitative responses in OBL depth and | ||
| mixing intensity. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is it possible to only have one flag for NonLocalFlux configurable by the user, either here or in the KPP section. I worry that you could set one and not know you need to set the other? Especially since I don't see this
TracerNonLocalFluxTendencyEnableflag discussed in the user or devDocs.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.
Removed
UseNonLocalFluxand added a description of this flag