Holds the EOS variant tag + scalar EOS coefficients (linear
Boussinesq) and the kernels that convert (T, S) -> ρ on the
multilayer C-grid. Coastal uses a sibling linear EOS in
rdb_ml_eos; the ocean path needs a real nonlinear EOS along
the FV pressure-gradient integration path. Default is Wright
(1997) — the same EOS MOM6 uses by default — chosen for cost
(one rational expression, no LUT) and accuracy in the open
ocean. TEOS-10 is a future option.
Phase 5c status: linear branch live; Wright + LUT scratch
still pending. The kernel follows the outer-shim + flat-impl
pattern: an outer shim pulls the registered S, T tracer arrays
off the owning state and forwards them as bare 3D arrays to the
inner _impl routine. This avoids the NVHPC stdpar deep-deref
issue with array-of-derived-types tracer registries (see
CLAUDE.md feedback_nvhpc_impl_inlining). This module is
regime-agnostic — it carries NO ocean-state dependency; the
ocean C-grid shim ocean_eos_compute lives in
rdb_ocean_eos_compute (core/ocean/state/), and the coastal
shim in rdb_ml_eos.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | EOS_VARIANT_LINEAR | = | 1 |
Linear T/S (debug / lock-exchange / Eady). |
| integer, | public, | parameter | :: | EOS_VARIANT_ROQUET_SPV | = | 4 |
Roquet et al. (2015) “Accurate polynomial expressions for the
density and specific volume of seawater using the TEOS-10
standard.” Ocean Modelling 90:29-43 — the specific-volume
(SpV) polynomial variant (NEMO / MOM6 |
| integer, | public, | parameter | :: | EOS_VARIANT_TEOS10 | = | 3 |
TEOS-10 (future). |
| integer, | public, | parameter | :: | EOS_VARIANT_WRIGHT_97 | = | 2 |
Wright (1997) “An Equation of State for Use in Ocean
Models: Eckart’s Formula Revisited” (JAOT 14:735-740).
Rational form: ρ = (P + p_0) / (λ + α_0*(P + p_0)) with
cubic / linear polynomials in (T, S). Matches the MOM6
default EOS. Phase Tier-1 evaluates at P = |
| real(kind=wp), | public, | parameter | :: | ROQ_CP0 | = | 3991.86795711963_wp | |
| real(kind=wp), | public, | parameter | :: | ROQ_CT_SFAC | = | 0.0248826675584615_wp |
(35.16504/35)/40 [(g/kg)^-1] — normalises SR for the poly. |
| real(kind=wp), | public, | parameter | :: | ROQ_R1_S0 | = | 0.875_wp/35.16504_wp |
Inverse plausible salinity range (kg/g). |
| real(kind=wp), | public, | parameter | :: | ROQ_RDELTAS | = | 24.0_wp |
Salinity offset before the sqrt (g/kg). |
| real(kind=wp), | public, | parameter | :: | ROQ_SR_FACTOR | = | 35.16504_wp/35.0_wp |
SP -> SR (Reference Salinity) conversion factor. |
| real(kind=wp), | public, | parameter | :: | ROQ_V00 | = | -4.4015007269e-05_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | ROQ_V01 | = | 6.9232335784e-06_wp*ROQ_PA2KB**2 | |
| real(kind=wp), | public, | parameter | :: | ROQ_V02 | = | -7.5004675975e-07_wp*ROQ_PA2KB**3 | |
| real(kind=wp), | public, | parameter | :: | ROQ_V03 | = | 1.7009109288e-08_wp*ROQ_PA2KB**4 | |
| real(kind=wp), | public, | parameter | :: | ROQ_V04 | = | -1.6884162004e-08_wp*ROQ_PA2KB**5 | |
| real(kind=wp), | public, | parameter | :: | ROQ_V05 | = | 1.9613503930e-09_wp*ROQ_PA2KB**6 | |
| real(kind=wp), | public, | parameter | :: | SPV000 | = | 1.0772899069e-03_wp | |
| real(kind=wp), | public, | parameter | :: | SPV001 | = | -1.6889436589e-05_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | SPV002 | = | 1.0500241168e-06_wp*ROQ_PA2KB**2 | |
| real(kind=wp), | public, | parameter | :: | SPV003 | = | -4.1503454190e-07_wp*ROQ_PA2KB**3 | |
| real(kind=wp), | public, | parameter | :: | SPV010 | = | -1.4949652640e-05_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV011 | = | 1.5355844621e-05_wp*(ROQ_I_TS*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV012 | = | -3.8541359685e-06_wp*(ROQ_I_TS*ROQ_PA2KB**2) | |
| real(kind=wp), | public, | parameter | :: | SPV013 | = | -1.1293871415e-07_wp*(ROQ_I_TS*ROQ_PA2KB**3) | |
| real(kind=wp), | public, | parameter | :: | SPV020 | = | 2.7546851539e-05_wp*ROQ_I_TS**2 | |
| real(kind=wp), | public, | parameter | :: | SPV021 | = | -9.6659393016e-06_wp*(ROQ_I_TS**2*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV022 | = | 1.7178343158e-06_wp*(ROQ_I_TS**2*ROQ_PA2KB**2) | |
| real(kind=wp), | public, | parameter | :: | SPV030 | = | -1.6506828994e-05_wp*ROQ_I_TS**3 | |
| real(kind=wp), | public, | parameter | :: | SPV031 | = | 3.1134283336e-06_wp*(ROQ_I_TS**3*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV040 | = | 6.7896174634e-06_wp*ROQ_I_TS**4 | |
| real(kind=wp), | public, | parameter | :: | SPV041 | = | -5.6590253863e-07_wp*(ROQ_I_TS**4*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV050 | = | -7.2535743349e-07_wp*ROQ_I_TS**5 | |
| real(kind=wp), | public, | parameter | :: | SPV060 | = | 1.9041365570e-07_wp*ROQ_I_TS**6 | |
| real(kind=wp), | public, | parameter | :: | SPV100 | = | -3.1263658781e-04_wp | |
| real(kind=wp), | public, | parameter | :: | SPV101 | = | 2.1106556158e-05_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | SPV102 | = | 1.9600661704e-06_wp*ROQ_PA2KB**2 | |
| real(kind=wp), | public, | parameter | :: | SPV103 | = | 3.5627020989e-07_wp*ROQ_PA2KB**3 | |
| real(kind=wp), | public, | parameter | :: | SPV110 | = | 3.1866349188e-05_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV111 | = | 2.0914122241e-06_wp*(ROQ_I_TS*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV112 | = | 1.0157632247e-06_wp*(ROQ_I_TS*ROQ_PA2KB**2) | |
| real(kind=wp), | public, | parameter | :: | SPV120 | = | -3.6597334199e-05_wp*ROQ_I_TS**2 | |
| real(kind=wp), | public, | parameter | :: | SPV121 | = | -7.0686982208e-07_wp*(ROQ_I_TS**2*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV130 | = | 2.4412359055e-05_wp*ROQ_I_TS**3 | |
| real(kind=wp), | public, | parameter | :: | SPV131 | = | 7.9562529879e-08_wp*(ROQ_I_TS**3*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV140 | = | -8.7951832993e-06_wp*ROQ_I_TS**4 | |
| real(kind=wp), | public, | parameter | :: | SPV150 | = | -3.4680559205e-07_wp*ROQ_I_TS**5 | |
| real(kind=wp), | public, | parameter | :: | SPV200 | = | 6.7615860683e-04_wp | |
| real(kind=wp), | public, | parameter | :: | SPV201 | = | -2.1322804368e-05_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | SPV202 | = | -2.1666693382e-06_wp*ROQ_PA2KB**2 | |
| real(kind=wp), | public, | parameter | :: | SPV210 | = | -3.8070687610e-05_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV211 | = | -5.7751479725e-06_wp*(ROQ_I_TS*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV220 | = | 3.4489154625e-05_wp*ROQ_I_TS**2 | |
| real(kind=wp), | public, | parameter | :: | SPV221 | = | 1.4488066593e-06_wp*(ROQ_I_TS**2*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV230 | = | -1.4606740723e-05_wp*ROQ_I_TS**3 | |
| real(kind=wp), | public, | parameter | :: | SPV240 | = | 4.4249040774e-06_wp*ROQ_I_TS**4 | |
| real(kind=wp), | public, | parameter | :: | SPV300 | = | -8.6127884515e-04_wp | |
| real(kind=wp), | public, | parameter | :: | SPV301 | = | 1.7347655458e-05_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | SPV310 | = | 2.9818473563e-05_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV311 | = | 1.0767234341e-06_wp*(ROQ_I_TS*ROQ_PA2KB) | |
| real(kind=wp), | public, | parameter | :: | SPV320 | = | -1.7663254122e-05_wp*ROQ_I_TS**2 | |
| real(kind=wp), | public, | parameter | :: | SPV330 | = | 2.3293406656e-06_wp*ROQ_I_TS**3 | |
| real(kind=wp), | public, | parameter | :: | SPV400 | = | 5.9010812596e-04_wp | |
| real(kind=wp), | public, | parameter | :: | SPV401 | = | -4.3209400767e-06_wp*ROQ_PA2KB | |
| real(kind=wp), | public, | parameter | :: | SPV410 | = | -1.0011321965e-05_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV420 | = | 3.5965131935e-06_wp*ROQ_I_TS**2 | |
| real(kind=wp), | public, | parameter | :: | SPV500 | = | -2.1503943538e-04_wp | |
| real(kind=wp), | public, | parameter | :: | SPV510 | = | 1.0751931163e-06_wp*ROQ_I_TS | |
| real(kind=wp), | public, | parameter | :: | SPV600 | = | 3.2678954455e-05_wp | |
| integer, | public, | parameter | :: | TFREEZE_SET_INVALID | = | 0 |
Unrecognised |
| integer, | public, | parameter | :: | TFREEZE_SET_ISOMIP | = | 2 |
ISOMIP+ ice-shelf-cavity liquidus ( |
| integer, | public, | parameter | :: | TFREEZE_SET_SEAICE | = | 1 |
SIS2/MOM6 sea-ice linear liquidus ( |
| real(kind=wp), | public, | parameter | :: | TFR_0_COEFF | = | 0.0_wp |
Liquidus intercept (degC). EXACTLY zero for this set — the
SIS2 form has no constant term. Named (rather than left
implicit) so the handle’s default and |
| real(kind=wp), | public, | parameter | :: | TFR_ISOMIP_0_COEFF | = | 0.0832_wp |
ISOMIP+ λ2, liquidus intercept (degC). |
| real(kind=wp), | public, | parameter | :: | TFR_ISOMIP_P_COEFF | = | -7.53e-8_wp |
ISOMIP+ λ3, liquidus pressure coefficient (degC/Pa). Numerically
equal to |
| real(kind=wp), | public, | parameter | :: | TFR_ISOMIP_S_COEFF | = | -0.0573_wp |
ISOMIP+ λ1, liquidus slope (degC per PSU). |
| real(kind=wp), | public, | parameter | :: | TFR_P_COEFF | = | -7.53e-8_wp |
Pressure depression dT_f/dp (degC/Pa) — MOM6 |
| real(kind=wp), | public, | parameter | :: | TFR_S_COEFF | = | -0.054_wp |
Liquidus slope dT_f/dS (degC per g/kg) — SIS2’s |
| integer, | public, | parameter | :: | TS_CONS_ABS | = | 2 |
(CT, SA) — for a future TEOS-10/Roquet-CT branch that does
the CT/SA->PT/SP conversion locally inside its |
| integer, | public, | parameter | :: | TS_POT_PRAC | = | 1 |
Tracer T/S convention: potential temperature + practical salinity (the model-prognostic pair). Identity for the linear and Wright (1997) branches — they consume (PT, SP) directly. Default. |
| real(kind=wp), | public, | parameter | :: | WRIGHT_A0 | = | 7.057924e-4_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_A1 | = | 3.480336e-7_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_A2 | = | -1.112733e-7_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B0 | = | 5.790749e8_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B1 | = | 3.516535e6_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B2 | = | -4.002714e4_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B3 | = | 2.084372e2_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B4 | = | 5.944068e5_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_B5 | = | -9.643486e3_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C0 | = | 1.704853e5_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C1 | = | 7.904722e2_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C2 | = | -7.984422e0_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C3 | = | 5.140652e-2_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C4 | = | -2.302158e2_wp | |
| real(kind=wp), | public, | parameter | :: | WRIGHT_C5 | = | -3.079464e0_wp | |
| real(kind=wp), | private, | parameter | :: | ALP000 | = | SPV010 | |
| real(kind=wp), | private, | parameter | :: | ALP001 | = | SPV011 | |
| real(kind=wp), | private, | parameter | :: | ALP002 | = | SPV012 | |
| real(kind=wp), | private, | parameter | :: | ALP003 | = | SPV013 | |
| real(kind=wp), | private, | parameter | :: | ALP010 | = | 2.0_wp*SPV020 | |
| real(kind=wp), | private, | parameter | :: | ALP011 | = | 2.0_wp*SPV021 | |
| real(kind=wp), | private, | parameter | :: | ALP012 | = | 2.0_wp*SPV022 | |
| real(kind=wp), | private, | parameter | :: | ALP020 | = | 3.0_wp*SPV030 | |
| real(kind=wp), | private, | parameter | :: | ALP021 | = | 3.0_wp*SPV031 | |
| real(kind=wp), | private, | parameter | :: | ALP030 | = | 4.0_wp*SPV040 | |
| real(kind=wp), | private, | parameter | :: | ALP031 | = | 4.0_wp*SPV041 | |
| real(kind=wp), | private, | parameter | :: | ALP040 | = | 5.0_wp*SPV050 | |
| real(kind=wp), | private, | parameter | :: | ALP050 | = | 6.0_wp*SPV060 | |
| real(kind=wp), | private, | parameter | :: | ALP100 | = | SPV110 | |
| real(kind=wp), | private, | parameter | :: | ALP101 | = | SPV111 | |
| real(kind=wp), | private, | parameter | :: | ALP102 | = | SPV112 | |
| real(kind=wp), | private, | parameter | :: | ALP110 | = | 2.0_wp*SPV120 | |
| real(kind=wp), | private, | parameter | :: | ALP111 | = | 2.0_wp*SPV121 | |
| real(kind=wp), | private, | parameter | :: | ALP120 | = | 3.0_wp*SPV130 | |
| real(kind=wp), | private, | parameter | :: | ALP121 | = | 3.0_wp*SPV131 | |
| real(kind=wp), | private, | parameter | :: | ALP130 | = | 4.0_wp*SPV140 | |
| real(kind=wp), | private, | parameter | :: | ALP140 | = | 5.0_wp*SPV150 | |
| real(kind=wp), | private, | parameter | :: | ALP200 | = | SPV210 | |
| real(kind=wp), | private, | parameter | :: | ALP201 | = | SPV211 | |
| real(kind=wp), | private, | parameter | :: | ALP210 | = | 2.0_wp*SPV220 | |
| real(kind=wp), | private, | parameter | :: | ALP211 | = | 2.0_wp*SPV221 | |
| real(kind=wp), | private, | parameter | :: | ALP220 | = | 3.0_wp*SPV230 | |
| real(kind=wp), | private, | parameter | :: | ALP230 | = | 4.0_wp*SPV240 | |
| real(kind=wp), | private, | parameter | :: | ALP300 | = | SPV310 | |
| real(kind=wp), | private, | parameter | :: | ALP301 | = | SPV311 | |
| real(kind=wp), | private, | parameter | :: | ALP310 | = | 2.0_wp*SPV320 | |
| real(kind=wp), | private, | parameter | :: | ALP320 | = | 3.0_wp*SPV330 | |
| real(kind=wp), | private, | parameter | :: | ALP400 | = | SPV410 | |
| real(kind=wp), | private, | parameter | :: | ALP410 | = | 2.0_wp*SPV420 | |
| real(kind=wp), | private, | parameter | :: | ALP500 | = | SPV510 | |
| real(kind=wp), | private, | parameter | :: | BET000 | = | 0.5_wp*SPV100*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET001 | = | 0.5_wp*SPV101*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET002 | = | 0.5_wp*SPV102*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET003 | = | 0.5_wp*SPV103*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET010 | = | 0.5_wp*SPV110*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET011 | = | 0.5_wp*SPV111*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET012 | = | 0.5_wp*SPV112*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET020 | = | 0.5_wp*SPV120*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET021 | = | 0.5_wp*SPV121*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET030 | = | 0.5_wp*SPV130*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET031 | = | 0.5_wp*SPV131*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET040 | = | 0.5_wp*SPV140*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET050 | = | 0.5_wp*SPV150*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET100 | = | SPV200*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET101 | = | SPV201*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET102 | = | SPV202*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET110 | = | SPV210*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET111 | = | SPV211*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET120 | = | SPV220*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET121 | = | SPV221*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET130 | = | SPV230*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET140 | = | SPV240*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET200 | = | 1.5_wp*SPV300*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET201 | = | 1.5_wp*SPV301*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET210 | = | 1.5_wp*SPV310*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET211 | = | 1.5_wp*SPV311*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET220 | = | 1.5_wp*SPV320*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET230 | = | 1.5_wp*SPV330*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET300 | = | 2.0_wp*SPV400*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET301 | = | 2.0_wp*SPV401*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET310 | = | 2.0_wp*SPV410*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET320 | = | 2.0_wp*SPV420*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET400 | = | 2.5_wp*SPV500*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET410 | = | 2.5_wp*SPV510*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | BET500 | = | 3.0_wp*SPV600*ROQ_R1_S0 | |
| real(kind=wp), | private, | parameter | :: | ROQ_I_TS | = | 0.025_wp |
Inverse plausible temperature range (1/degC). |
| real(kind=wp), | private, | parameter | :: | ROQ_PA2KB | = | 1.0e-8_wp |
Pa -> kbar. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public | :: | S_ref | = | 35.0_wp |
Reference salinity for linear EOS (PSU). |
|
| real(kind=wp), | public | :: | T_ref | = | 10.0_wp |
Reference temperature for linear EOS (degC). |
|
| real(kind=wp), | public | :: | alpha_T | = | 1.7e-4_wp |
Thermal expansion coeff (linear EOS), kg/m^3 per degC.
NOTE: this default is ~1000× smaller than the standard
seawater value (~0.17 kg/m³/K). The small value
suppresses baroclinic feedback from PPM round-off in
tests that don’t care about realistic density gradients.
Density-driven tests (e.g. |
|
| real(kind=wp), | public | :: | beta_S | = | 7.6e-4_wp |
Haline contraction coeff (linear EOS), kg/m^3 per PSU.
See |
|
| logical, | public | :: | is_init | = | .false. |
True between |
|
| real(kind=wp), | public | :: | p_ref | = | 0.0_wp |
Reference pressure (Pa) at which |
|
| real(kind=wp), | public | :: | rho0 | = | 1035.0_wp |
Boussinesq reference density (kg/m^3). |
|
| real(kind=wp), | public | :: | tfr_0 | = | TFR_0_COEFF |
Liquidus intercept λ2 (degC). Exactly |
|
| real(kind=wp), | public | :: | tfr_p | = | TFR_P_COEFF |
Liquidus pressure coefficient λ3 (degC/Pa). |
|
| real(kind=wp), | public | :: | tfr_s | = | TFR_S_COEFF |
Liquidus slope λ1 (degC per PSU) — the |
|
| integer, | public | :: | ts_convention | = | TS_POT_PRAC |
Tracer T/S convention this EOS expects (TS_POT_PRAC /
TS_CONS_ABS). Identity for linear + Wright. This type is
a flat POD — NO allocatable component — so it copies into
registers for free when passed by value into the device
point routines ( |
|
| integer, | public | :: | variant | = | EOS_VARIANT_LINEAR |
Active EOS variant. Defaults to linear two-tracer
(the simplest implemented branch). Wright (1997)
rational EOS is also shipped — opt in by setting
|
| procedure, public, non_overridable :: destroy => eos_destroy | |
| procedure, public, non_overridable :: init => eos_init |
Scalar density evaluation at a point — the same formulas the
3D eos_*_impl kernels apply, exposed for finite-difference
verification of eos_specvol_derivs and for host-side
diagnostics. Takes the shared eos_t handle by value.
The else is unreachable-by-contract (see
eos_validate).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos | |||
| real(kind=wp), | intent(in) | :: | T | |||
| real(kind=wp), | intent(in) | :: | S | |||
| real(kind=wp), | intent(in) | :: | p |
Seawater freezing point T_f (degC) at salinity S and pressure
p — the ocean-side prerequisite for the sea-ice port
(PLAN_SEA_ICE.md, PR 1). Same point-function style as
eos_density_point (flat-POD eos_t by value, device-
callable), plus elemental so callers can evaluate whole
salinity arrays in one reference.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle, by value — carries the liquidus
coefficient set ( |
||
| real(kind=wp), | intent(in) | :: | S |
Salinity (PSU / g/kg). |
||
| real(kind=wp), | intent(in) | :: | p |
Pressure (Pa), hydrostatic surface-relative (0 at the surface — the frazil kernel’s use case). |
Translate a &ocean_eos_nml eos=... string into an
EOS_VARIANT_* code. Unrecognised values fall back to
EOS_VARIANT_LINEAR (the default = bit-identical to runs that
omit the knob). Membership in the device-callable set is
enforced separately by eos_validate at configure time.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
Translate a &ocean_eos_nml tfreeze_set=... string into a
TFREEZE_SET_* code. Unlike parse_eos_variant this one does
NOT fall back to a default on a typo: it returns
TFREEZE_SET_INVALID and validate_config aborts. Silently
defaulting would turn a mistyped liquidus into a 0.03 °C shift
in the freezing point — a melt-rate sign change at the margin,
with no run-time symptom at all.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
VALUE-ONLY Roquet et al. (2015) specific volume (m^3/kg) at a point,
model variables (PT degC, SP PSU, p Pa). The same number as
roquet_spv_point’s sv without the dSV/dT, dSV/dS and PT->CT
chain-rule work that a density-only consumer (rho_layer,
eos_density_point) would discard – roughly half the arithmetic.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | T_pt | |||
| real(kind=wp), | intent(in) | :: | S_sp | |||
| real(kind=wp), | intent(in) | :: | p |
Write the named liquidus coefficient SET onto the EOS handle.
Called once, at configure time, from the earliest
configure_ocean_* stage — before the flat-POD handle is copied
onto the vmix / EPBL / kappa-shear / tidal-mixing slots and
before ocean_state_enter_data, so every copy and every device
kernel taking eos_t by value sees the configured set (same
contract as rho0 / p_ref; no !$acc update device is owed).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(inout) | :: | eos | |||
| integer, | intent(in) | :: | code |
Thermal-expansion and haline-contraction coefficients of the
ACTIVE equation of state at a point, in the SAME DIMENSIONAL
convention the eos_t members alpha_T / beta_S carry:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle (variant + scalar coeffs), by value. |
||
| real(kind=wp), | intent(in) | :: | T |
Potential temperature (degC) and practical salinity (PSU) —
the model-prognostic pair, per the |
||
| real(kind=wp), | intent(in) | :: | S |
Potential temperature (degC) and practical salinity (PSU) —
the model-prognostic pair, per the |
||
| real(kind=wp), | intent(in) | :: | p |
Pressure (Pa) at which to evaluate. Which pressure is the
CONSUMER’s choice and is documented at each call site: a
surface buoyancy flux wants the top of the column
( |
||
| real(kind=wp), | intent(out) | :: | alpha_T |
−∂ρ/∂T (kg/m³ per degC). |
||
| real(kind=wp), | intent(out) | :: | beta_S |
+∂ρ/∂S (kg/m³ per PSU). |
Variant dispatch on bare 3D arrays — the state-agnostic body of
ocean_eos_compute (the shim hosted in
rdb_ocean_eos_compute), which forwards the multilayer state’s
registry arrays here. Kept free of state-type dependencies so
the dispatch stays callable from a bare array context. All impls
evaluate at the SINGLE, HORIZONTALLY UNIFORM reference pressure
eos%p_ref (&ocean_eos_nml p_ref, default 0 ⇒ surface/potential
density) with the H_VANISHED vanishing-layer fallback to
eos%rho0.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(out) | :: | rho_layer(nx,ny,nz) | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
Density sensitivities ∂ρ/∂T and ∂ρ/∂S of the ACTIVE equation
of state at a point — the signed twin of eos_buoyancy_coeffs,
which is where the per-variant closed forms live:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos | |||
| real(kind=wp), | intent(in) | :: | T | |||
| real(kind=wp), | intent(in) | :: | S | |||
| real(kind=wp), | intent(in) | :: | p | |||
| real(kind=wp), | intent(out) | :: | drho_dt |
∂ρ/∂T (kg/m³ per degC). |
||
| real(kind=wp), | intent(out) | :: | drho_ds |
∂ρ/∂S (kg/m³ per PSU). |
eos_density_point AND eos_specvol_derivs at the same point from
ONE evaluation of the active EOS. The isopycnal-slope and Redi
builders need both (drho/dX = -rho^2 * dSV/dX, locally
referenced); calling the two routines separately evaluated the EOS
twice – under Roquet, two full roquet_spv_point calls, the first
of which threw its derivatives away. Each branch uses the same
expressions as the two routines it fuses, so rho, dsv_dt and
dsv_ds are the numbers they return.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle (variant + scalar coeffs), by value. |
||
| real(kind=wp), | intent(in) | :: | T |
Potential temperature (degC) and practical salinity (PSU). |
||
| real(kind=wp), | intent(in) | :: | S |
Potential temperature (degC) and practical salinity (PSU). |
||
| real(kind=wp), | intent(in) | :: | p |
Pressure (Pa). |
||
| real(kind=wp), | intent(out) | :: | rho |
In-situ density (kg/m^3), as |
||
| real(kind=wp), | intent(out) | :: | dsv_dt |
dSV/dT, dSV/dS, as |
||
| real(kind=wp), | intent(out) | :: | dsv_ds |
dSV/dT, dSV/dS, as |
Analytic specific-volume sensitivities dSV/dT and dSV/dS (SV = 1/rho) at a point. Needed by the EPBL energy bookkeeping (pressure-weighted PE-per-unit-tracer-change weights) and kappa-shear buoyancy — dSV/dX = -(1/rho^2) d(rho)/dX.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle (variant + scalar coeffs), by value. |
||
| real(kind=wp), | intent(in) | :: | T |
In-situ temperature (degC) and salinity (PSU). |
||
| real(kind=wp), | intent(in) | :: | S |
In-situ temperature (degC) and salinity (PSU). |
||
| real(kind=wp), | intent(in) | :: | p |
Pressure (Pa), hydrostatic surface-relative. |
||
| real(kind=wp), | intent(out) | :: | dsv_dt |
dSV/dT (m^3/kg/degC); > 0 for warm-expands water. |
||
| real(kind=wp), | intent(out) | :: | dsv_ds |
dSV/dS (m^3/kg/PSU); < 0 (salt contracts). |
Host-side fail-loud gate over the device-supported variant
set. Device point routines (!$acc routine seq) cannot
error stop, so membership in the device-callable set is
guaranteed HERE at configure time; the device else branch
is then unreachable-by-contract.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos | |||
| integer, | intent(out), | optional | :: | ierr |
|
FV-Wright PGF column sweep. Top-down per-column traversal
that simultaneously produces the hydrostatic pressure stack
p_edge_out and the in-situ density rho_insitu_out at each
layer centre.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | rho_layer_seed(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | p_top(nx,ny) |
Top-of-column pressure (Pa, |
||
| real(kind=wp), | intent(out) | :: | p_edge_out(nx,ny,nz+1) | |||
| real(kind=wp), | intent(out) | :: | rho_insitu_out(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | gravity | |||
| real(kind=wp), | intent(in) | :: | rho_0 | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
The (T, S)-dependent coefficients of the Roquet et al. (2015) SpV
polynomial viewed as a polynomial in PRESSURE, in model variables
(potential temperature T_pt degC, practical salinity S_sp PSU):
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | T_pt |
Potential temperature (degC). |
||
| real(kind=wp), | intent(in) | :: | S_sp |
Practical salinity (PSU). |
||
| real(kind=wp), | intent(out) | :: | sv0 |
Pressure-independent part, |
||
| real(kind=wp), | intent(out) | :: | sv1 |
Coefficients of |
||
| real(kind=wp), | intent(out) | :: | sv2 |
Coefficients of |
||
| real(kind=wp), | intent(out) | :: | sv3 |
Coefficients of |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(eos_t), | intent(inout) | :: | this |
Linear two-tracer EOS, flat-impl form:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(out) | :: | rho_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | rho_0 | |||
| real(kind=wp), | intent(in) | :: | beta_S | |||
| real(kind=wp), | intent(in) | :: | S_ref | |||
| real(kind=wp), | intent(in) | :: | alpha_T | |||
| real(kind=wp), | intent(in) | :: | T_ref | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
Roquet et al. (2015) SpV EOS evaluated at a single reference
pressure p_ref (a SCALAR by design — see the
horizontal-uniformity contract in eos_compute_arrays). Same
outer-shim signature as eos_linear_impl/eos_wright_impl —
bare 3D arrays, model (PT, SP) tracers, vanishing-layer fallback
to rho_0.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(out) | :: | rho_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | rho_0 | |||
| real(kind=wp), | intent(in) | :: | p_ref | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
Wright (1997) rational EOS evaluated at a single reference
pressure p_ref, which is a SCALAR by design — see the
horizontal-uniformity contract in eos_compute_arrays. Same
outer-shim signature as eos_linear_impl — bare 3D arrays,
vanishing-layer fallback to rho_0.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(out) | :: | rho_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | rho_0 | |||
| real(kind=wp), | intent(in) | :: | p_ref | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
Fused Roquet et al. (2015) SpV evaluation at a point, in MODEL
variables (potential temperature T_pt degC, practical salinity
S_sp PSU, pressure p Pa). Returns specific volume sv
(m^3/kg) and the analytic sensitivities w.r.t. the MODEL
variables (dsv_dt_model = dSV/dPT, dsv_ds_model = dSV/dSP)
so the variant-agnostic consumers (which work in PT, SP) get the
correct chain-ruled derivatives.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | T_pt | |||
| real(kind=wp), | intent(in) | :: | S_sp | |||
| real(kind=wp), | intent(in) | :: | p | |||
| real(kind=wp), | intent(out) | :: | sv | |||
| real(kind=wp), | intent(out) | :: | dsv_dt_model | |||
| real(kind=wp), | intent(out) | :: | dsv_ds_model |