@@ -26,6 +26,11 @@ enum class EosType {
2626 Teos10Eos // / Roquet et al. 2015 75 term expansion
2727};
2828
29+ enum class EosLimits {
30+ Funnel, // /
31+ Cube // /
32+ };
33+
2934struct EosRange {
3035 Real Lo;
3136 Real Hi;
@@ -35,6 +40,8 @@ struct EosRange {
3540class Teos10Eos {
3641 public:
3742 Array2DReal SpecVolPCoeffs;
43+ EosLimits EosLimChoice; // /< EOS clamping option in use
44+ bool ClampingEnable; // /< EOS clamping option in use
3845
3946 // / constructor declaration
4047 Teos10Eos (int NVertLayers);
@@ -90,10 +97,14 @@ class Teos10Eos {
9097 constexpr Real DeltaS = 24.0 ;
9198 EosRange SRange = calcSLimits (P);
9299 EosRange TRange = calcTLimits (Sa, P);
93- Real SaInFunnel = Kokkos::clamp (
94- Sa, SRange.Lo , SRange.Hi ); // Salt limited to Poly75t valid range
95- Real Ss = Kokkos::sqrt ((SaInFunnel + DeltaS) / SAu);
96- Real Tt = Kokkos::clamp (Ct, TRange.Lo , TRange.Hi ) / CTu;
100+ Real Ss = Kokkos::sqrt ((Sa + DeltaS) / SAu);
101+ Real Tt = Ct / CTu;
102+ if (ClampingEnable) {
103+ Real SaInRange = Kokkos::clamp (
104+ Sa, SRange.Lo , SRange.Hi ); // Salt limited to Poly75t valid range
105+ Ss = Kokkos::sqrt ((SaInRange + DeltaS) / SAu);
106+ Tt = Kokkos::clamp (Ct, TRange.Lo , TRange.Hi ) / CTu;
107+ }
97108
98109 // / Coefficients for the polynomial expansion
99110 constexpr Real V000 = 1.0769995862e-03 ;
@@ -215,10 +226,15 @@ class Teos10Eos {
215226 KOKKOS_FUNCTION Real calcDelta (const Array2DReal &SpecVolPCoeffs, const I4 K,
216227 const Real P) const {
217228
218- constexpr Real Pu = 1e4 ;
219- constexpr Real Pmax = 8000.0 ;
220- Real Pp = Kokkos::min (P, Pmax) / Pu; // P limited to Poly75t valid range
221-
229+ constexpr Real Pu = 1e4 ;
230+ const Real Pmax = (EosLimChoice == EosLimits::Funnel) ? 8000.0 : 10000.0 ;
231+ Real Pp = P / Pu;
232+ if (ClampingEnable) {
233+ Pp = Kokkos::min (P, Pmax) / Pu; // P limited to Poly75t valid range
234+ LOG_INFO (" P={} exceeds Pmax={}; Clamping the pressure" , P, Pmax);
235+ } else if (P > Pmax) {
236+ LOG_WARN (" P={} exceeds Pmax={}" , P, Pmax);
237+ }
222238 Real Delta = ((((SpecVolPCoeffs (5 , K) * Pp + SpecVolPCoeffs (4 , K)) * Pp +
223239 SpecVolPCoeffs (3 , K)) *
224240 Pp +
@@ -232,15 +248,20 @@ class Teos10Eos {
232248
233249 // / Calculate reference profile for TEOS-10
234250 KOKKOS_FUNCTION Real calcRefProfile (const Real P) const {
235- constexpr Real Pu = 1e4 ;
236- constexpr Real V00 = -4.4015007269e-05 ;
237- constexpr Real V01 = 6.9232335784e-06 ;
238- constexpr Real V02 = -7.5004675975e-07 ;
239- constexpr Real V03 = 1.7009109288e-08 ;
240- constexpr Real V04 = -1.6884162004e-08 ;
241- constexpr Real V05 = 1.9613503930e-09 ;
242- constexpr Real Pmax = 8000.0 ;
243- Real Pp = Kokkos::min (P, Pmax) / Pu; // P limited to Poly75t valid range
251+ constexpr Real Pu = 1e4 ;
252+ constexpr Real V00 = -4.4015007269e-05 ;
253+ constexpr Real V01 = 6.9232335784e-06 ;
254+ constexpr Real V02 = -7.5004675975e-07 ;
255+ constexpr Real V03 = 1.7009109288e-08 ;
256+ constexpr Real V04 = -1.6884162004e-08 ;
257+ constexpr Real V05 = 1.9613503930e-09 ;
258+ const Real Pmax = (EosLimChoice == EosLimits::Funnel) ? 8000.0 : 10000.0 ;
259+ Real Pp = P / Pu;
260+ if (ClampingEnable) {
261+ Pp = Kokkos::min (P, Pmax) / Pu; // P limited to Poly75t valid range
262+ } else if (P > Pmax) {
263+ LOG_WARN (" P={} exceeds Pmax={}" , P, Pmax);
264+ }
244265
245266 Real V0 =
246267 (((((V05 * Pp + V04) * Pp + V03) * Pp + V02) * Pp + V01) * Pp + V00) *
@@ -250,15 +271,17 @@ class Teos10Eos {
250271
251272 // / Calculate S limits of validity given pressure p
252273 KOKKOS_FUNCTION EosRange calcSLimits (const Real P) const {
253- Real Lo = 0.0 ;
254- Real Hi = 42.0 ;
255- Real Lo2 = P * 5e-3 - 2.5 ;
256- Real Lo3 = 30.0 ;
257-
258- if (P >= 500.0 && P < 6500.0 ) {
259- Lo = Kokkos::max (Lo, Lo2);
260- } else if (P >= 6500.0 ) {
261- Lo = Kokkos::max (Lo, Lo3);
274+ Real Lo = 0.0 ;
275+ Real Hi = 42.0 ;
276+ if (EosLimChoice == EosLimits::Funnel) {
277+ Real Lo2 = P * 5e-3 - 2.5 ;
278+ Real Lo3 = 30.0 ;
279+
280+ if (P >= 500.0 && P < 6500.0 ) {
281+ Lo = Kokkos::max (Lo, Lo2);
282+ } else if (P >= 6500.0 ) {
283+ Lo = Kokkos::max (Lo, Lo3);
284+ }
262285 }
263286 return {Lo, Hi};
264287 }
@@ -268,14 +291,20 @@ class Teos10Eos {
268291 Real Lo = -15.0 ;
269292 Real Hi = 95.0 ;
270293
271- if (P < 500.0 ) {
272- Lo = calcCtFreezing (Sa, P, 0 .0_Real);
273- } else if (P < 6500.0 ) {
274- Lo = calcCtFreezing (Sa, 500 .0_Real, 0 .0_Real);
275- Hi = 31.66666666666667 - P * 3.333333333333334e-3 ;
276- } else {
277- Lo = calcCtFreezing (Sa, 500 .0_Real, 0 .0_Real);
278- Hi = 10.0 ;
294+ if (EosLimChoice == EosLimits::Funnel) {
295+ if (P < 500.0 ) {
296+ Lo = calcCtFreezing (Sa, P, 0 .0_Real);
297+ } else if (P < 6500.0 ) {
298+ Lo = calcCtFreezing (Sa, 500 .0_Real, 0 .0_Real);
299+ Hi = 31.66666666666667 - P * 3.333333333333334e-3 ;
300+ } else {
301+ Lo = calcCtFreezing (Sa, 500 .0_Real, 0 .0_Real);
302+ Hi = 10.0 ;
303+ }
304+ }
305+ if (EosLimChoice == EosLimits::Cube) {
306+ Lo = -2.0 ;
307+ Hi = 40.0 ;
279308 }
280309 return {Lo, Hi};
281310 }
0 commit comments