16#ifndef lois_sodium_span_included
17#define lois_sodium_span_included
27#define i_it std::distance(res.begin(), &val)
29using VectorD = std::vector<double>;
30using SpanD = tcb::span<double>;
32const double Ksil = 1e-9;
35inline void IRhoL(
const SpanD T, SpanD res,
int ncomp,
int id)
39 const double tk = T[i_it * ncomp + id] + 273.15;
40 val = (9.829728e-4 + tk * (2.641186e-7 + tk * (-3.340743e-11 + tk * 6.680973e-14)));
45inline void DTIRhoL(
const SpanD T, SpanD res,
int ncomp,
int id)
49 const double tk = T[i_it * ncomp + id] + 273.15;
50 val = (2.641186e-7 + tk * (-3.340743e-11 * 2 + tk * 6.680973e-14 * 3));
54inline void RhoL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
56 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
57 IRhoL(T,res,ncomp,
id);
58 for (
auto& val : res) val = exp(Ksil * (P[i_it] - 1e5)) / val;
62inline void DPRhoL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
64 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
65 RhoL(T,P,res,ncomp,
id);
66 for (
auto& val : res) val = Ksil * val;
69inline void DTRhoL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
71 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
72 VectorD invRhoL((
int)res.size()), DinvRhoL((
int)res.size());
73 IRhoL(T,SpanD(invRhoL),ncomp,
id);
74 DTIRhoL(T,SpanD(DinvRhoL),ncomp,
id);
75 for (
auto& val : res) val = - exp(Ksil * (P[i_it] - 1e5)) * DinvRhoL[i_it] / (invRhoL[i_it] * invRhoL[i_it]);
79inline void HL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
81 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
82 VectorD invRhoL((
int)res.size()), DinvRhoL((
int)res.size());
83 IRhoL(T,SpanD(invRhoL),ncomp,
id);
84 DTIRhoL(T,SpanD(DinvRhoL),ncomp,
id);
87 const double tk = T[i_it * ncomp + id] + 273.15;
88 val = (2992600 / tk - 365487.2 + tk * (1658.2 + tk * (-.42395 + tk * 1.4847e-4)))+ (invRhoL[i_it] - tk * DinvRhoL[i_it]) * (1 - exp(Ksil*(1e5 - P[i_it]))) / Ksil;
93inline void DPHL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
95 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
96 VectorD invRhoL((
int)res.size()), DinvRhoL((
int)res.size());
97 IRhoL(T,SpanD(invRhoL),ncomp,
id);
98 DTIRhoL(T,SpanD(DinvRhoL),ncomp,
id);
101 const double tk = T[i_it * ncomp + id] + 273.15;
102 val = (invRhoL[i_it] - tk * DinvRhoL[i_it]) * exp(Ksil * (1e5 - P[i_it]));
106inline void DTHL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
108 assert ((
int)T.size() == ncomp * (
int)res.size() && (
int)T.size() == ncomp * (
int)P.size());
109 for (
auto& val : res)
111 const double tk = T[i_it * ncomp + id] + 273.15;
112 val = (-2992600 / (tk*tk) + 1658.2 + tk * (-.42395 * 2 + tk * 1.4847e-4 * 3))- tk * (-3.340743e-11 * 2 + tk * 6.680973e-14 * 6) * (1 - exp(Ksil*(1e5 - P[i_it]))) / Ksil;
116inline void BETAL(
const SpanD T, SpanD res,
int ncomp,
int id)
118 assert ((
int)T.size() == ncomp * (
int)res.size());
119 VectorD invRhoL((
int)res.size()), DinvRhoL((
int)res.size());
120 IRhoL(T,SpanD(invRhoL),ncomp,
id);
121 DTIRhoL(T,SpanD(DinvRhoL),ncomp,
id);
122 for (
auto& val : res) val = DinvRhoL[i_it] / invRhoL[i_it];
126inline void MuL(
const SpanD T, SpanD res,
int ncomp,
int id)
128 assert ((
int)T.size() == ncomp * (
int)res.size());
129 for (
auto& val : res)
131 const double tk = T[i_it * ncomp + id] + 273.15;
132 val = exp( -6.4406 - 0.3958 * log(tk) + 556.835 / tk );
137inline void LambdaL(
const SpanD T, SpanD res,
int ncomp,
int id)
139 assert ((
int)T.size() == ncomp * (
int)res.size());
140 for (
auto& val : res)
142 const double tk = T[i_it * ncomp + id] + 273.15;
143 val = std::max(124.67 + tk * (-.11381 + tk * (5.5226e-5 - tk * 1.1848e-8)), 0.045);
148inline void SigmaL(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
150 assert ((
int)P.size() == (
int)res.size());
151 for (
auto& val : res)
153 const double tk = T[i_it * ncomp + id] + 273.15;
154 val = 0.2405 * pow(1 - tk / 2503.7, 1.126);
165inline void Tsat_Na(
const SpanD P, SpanD res,
int ncomp,
int ind)
167 assert (ncomp * (
int)P.size() == (
int)res.size());
168 const double A = 7.8130, B = 11209, C = 5.249e5;
169 for (
int i =0; i < (int)P.size(); i++) res[i * ncomp + ind] = 2 * C / ( -B + sqrt(B*B + 4 * A * C - 4 * C * log(P[i] / 1e6))) - 273.15;
173inline void DTsat_Na(
const SpanD P, SpanD res,
int ncomp,
int ind)
175 assert (ncomp * (
int)P.size() == (
int)res.size());
176 const double A = 7.8130, B = 11209, C = 5.249e5;
177 Tsat_Na(P,res,ncomp,ind);
178 for (
int i =0; i < (int)P.size(); i++)
180 const double Tsk = res[i * ncomp + ind] + 273.15;
181 res[i * ncomp + ind] = Tsk * Tsk / ( P[i] * sqrt(B*B + 4 * A * C - 4 * C * log(P[i] / 1e6)));
186inline void Psat_Na(
const SpanD T, SpanD res,
int ncomp,
int ind)
188 assert ((
int)T.size() == (
int)res.size());
189 const double A = 7.8130, B = 11209, C = 5.249e5;
190 for (
int i =0; i < (int)T.size() / ncomp; i++)
192 const double tk = T[i * ncomp + ind] + 273.15;
193 res[i * ncomp + ind] = 1.e6 * exp(A - B / tk - C / (tk * tk));
198inline void DPsat_Na(
const SpanD T, SpanD res,
int ncomp,
int ind)
200 assert ((
int)T.size() == (
int)res.size());
201 const double B = 11209, C = 5.249e5;
203 Psat_Na(T,res,ncomp,ind);
204 for (
int i =0; i < (int)T.size() / ncomp; i++)
206 const double tk = T[i * ncomp + ind] + 273.15;
207 res[i * ncomp + ind] = (B / (tk * tk) + 2 * C / (tk * tk * tk)) * res[i * ncomp + ind];
212inline void Hsat(
const SpanD P, SpanD res,
int ncomp,
int ind)
214 assert (ncomp * (
int)P.size() == (
int)res.size());
215 VectorD Ts_((
int)P.size()), HL_((
int)P.size());
216 Tsat_Na(P,SpanD(Ts_),1,0);
217 HL(SpanD(Ts_),P,SpanD(HL_),1,0);
218 for (
int i =0; i < (int)P.size(); i++) res[i * ncomp + ind] = HL_[i];
222inline void DHsat(
const SpanD P, SpanD res,
int ncomp,
int ind)
224 assert (ncomp * (
int)P.size() == (
int)res.size());
225 VectorD Ts_((
int)P.size()), DTs_((
int)P.size()), DTHL_((
int)P.size()), DPHL_((
int)P.size());
226 Tsat_Na(P,SpanD(Ts_),1,0);
227 DTsat_Na(P,SpanD(DTs_),1,0);
228 DTHL(SpanD(Ts_),P,SpanD(DTHL_),1,0);
229 DPHL(SpanD(Ts_),P,SpanD(DPHL_),1,0);
230 for (
int i =0; i < (int)P.size(); i++) res[i * ncomp + ind] = DTs_[i] * DTHL_[i] + DPHL_[i];
234#define f1 (2.49121 + Tsk * (-5.53796e-3 + Tsk * (7.5465e-6 + Tsk * (-4.20217e-9 + Tsk * 8.59212e-13))))
235#define f2 (1 + dT * (-5e-4 + dT * (6.25e-7 - dT * 4.1359e-25)))
236#define Df1 (-5.53796e-3 + Tsk * (2 * 7.5465e-6 + Tsk * (-3 * 4.20217e-9 + Tsk * 4 * 8.59212e-13)))
237#define Df2 (-5e-4 + dT * (2 * 6.25e-7 - dT * 3 * 4.1359e-25))
239inline void RhoV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
241 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
243 for (
auto& val : res)
245 const double Tsk = val + 273.15;
246 const double tk = T[i_it * ncomp + id] + 273.15;
247 const double dT = tk - Tsk;
248 val = P[i_it] * 2.7650313e-3 * f1 * f2 / tk;
253inline void DPRhoV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
255 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
256 VectorD Tsk_((
int)res.size()), DTsk_((
int)res.size());
257 Tsat_Na(P,SpanD(Tsk_),1,0);
258 DTsat_Na(P,SpanD(DTsk_),1,0);
259 for (
auto& val : res)
261 const double Tsk = Tsk_[i_it] + 273.15;
262 const double tk = T[i_it * ncomp + id] + 273.15;
263 const double dT = tk - Tsk;
264 val = 2.7650313e-3 * (f1 * f2 + P[i_it] * DTsk_[i_it] * (Df1 * f2 - f1 * Df2)) / tk;
268inline void DTRhoV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
270 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
272 for (
auto& val : res)
274 const double Tsk = val + 273.15;
275 const double tk = T[i_it * ncomp + id] + 273.15;
276 const double dT = tk - Tsk;
277 val = P[i_it] * 2.7650313e-3 * f1 * (Df2 - f2 / tk) / tk;
287inline void Lvap_Na(
const SpanD P, SpanD res,
int ncomp,
int ind)
289 assert (ncomp * (
int)P.size() == (
int)res.size());
290 Tsat_Na(P,res,ncomp,ind);
291 const double Tc = 2503.7;
292 for (
int i =0; i < (int)P.size(); i++)
294 const double Tsk = res[i * ncomp + ind] + 273.15;
295 res[i * ncomp + ind] = 3.9337e5 * ( 1 - Tsk / Tc) + 4.3986e6 * pow( 1 - Tsk / Tc, .29302);
300inline void DLvap_Na(
const SpanD P, SpanD res,
int ncomp,
int ind)
302 assert (ncomp * (
int)P.size() == (
int)res.size());
303 const double Tc = 2503.7;
304 VectorD Tsk_((
int)P.size()), DTsk_((
int)P.size());
305 Tsat_Na(P,SpanD(Tsk_),1,0);
306 DTsat_Na(P,SpanD(DTsk_),1,0);
307 for (
int i =0; i < (int)P.size(); i++)
309 const double Tsk = Tsk_[i] + 273.15;
310 res[i * ncomp + ind] = DTsk_[i] * (-3.9337e5 / Tc - 4.3986e6 * .29302 * pow( 1 - Tsk / Tc, .29302 - 1) / Tc);
315inline void HVsat(
const SpanD P, SpanD res,
int ncomp,
int ind)
317 assert (ncomp * (
int)P.size() == (
int)res.size());
318 VectorD Hs_((
int)P.size()), Lv_((
int)P.size());
319 Hsat(P,SpanD(Hs_),1,0);
320 Lvap_Na(P,SpanD(Lv_),1,0);
321 for (
int i =0; i < (int)P.size(); i++) res[i * ncomp + ind] = Hs_[i] + Lv_[i];
325inline void DHVsat(
const SpanD P, SpanD res,
int ncomp,
int ind)
327 assert (ncomp * (
int)P.size() == (
int)res.size());
328 VectorD DHs_((
int)P.size()), DLv_((
int)P.size());
329 DHsat(P,SpanD(DHs_),1,0);
330 DLvap_Na(P,SpanD(DLv_),1,0);
331 for (
int i =0; i < (int)P.size(); i++) res[i * ncomp + ind] = DHs_[i] + DLv_[i];
335inline void HV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
337 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
338 const double Cp0 = 910, k = -4.6e-3;
339 VectorD Ts_((
int)res.size()), Lvap_((
int)res.size());
340 Tsat_Na(P,SpanD(Ts_),1,0);
341 Lvap_Na(P,SpanD(Lvap_),1,0);
342 HL(SpanD(Ts_),P,res,1,0);
343 for (
auto& val : res)
345 const double dT = T[i_it * ncomp + id] - Ts_[i_it];
346 const double CpVs = (-1223.89 + Ts_[i_it] * (14.1191 + Ts_[i_it] * (-1.62025e-2 + Ts_[i_it] * 5.76923e-6)));
347 val = val + Lvap_[i_it] + Cp0 * dT + (Cp0 - CpVs) * (1 - exp(k * dT)) / k;
352inline void DPHV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
354 assert ((
int)T.size() == ncomp * (
int)P.size() && (
int)T.size() == ncomp * (
int)res.size());
355 VectorD DTHL_((
int)res.size()), DPHL_((
int)res.size()), Ts_((
int)res.size()), DTs_((
int)res.size()), DLvap_((
int)res.size());
356 Tsat_Na(P,SpanD(Ts_),1,0);
357 DTsat_Na(P,SpanD(DTs_),1,0);
358 DLvap_Na(P,SpanD(DLvap_),1,0);
359 DTHL(SpanD(Ts_),P,SpanD(DTHL_),1,0);
360 DPHL(SpanD(Ts_),P,SpanD(DPHL_),1,0);
362 const double Cp0 = 910, k = -4.6e-3;
363 for (
auto& val : res)
365 const double dT = T[i_it * ncomp + id] - Ts_[i_it];
366 const double CpVs = (-1223.89 + Ts_[i_it] * (14.1191 + Ts_[i_it] * (-1.62025e-2 + Ts_[i_it] * 5.76923e-6)));
367 const double DCpVs = (14.1191 + Ts_[i_it] * (- 2 * 1.62025e-2 + Ts_[i_it] * 3 * 5.76923e-6));
368 val = DPHL_[i_it] + DLvap_[i_it] + DTs_[i_it] * (DTHL_[i_it] - Cp0 - DCpVs * (1 - exp(k * dT)) / k + (Cp0 - CpVs) * exp(k * dT));
372inline void DTHV(
const SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
374 assert ((
int)T.size() == ncomp * (
int)res.size() && (
int)T.size() == ncomp * (
int)P.size());
375 const double Cp0 = 910, k = -4.6e-3;
377 for (
auto& val : res)
379 const double dT = T[i_it * ncomp + id] - val;
380 const double CpVs = (-1223.89 + val * (14.1191 + val * (-1.62025e-2 + val * 5.76923e-6)));
381 val = Cp0 - (Cp0 - CpVs) * exp(k * dT);
386inline void IRhoV_vec(SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
388 RhoV(T,P,res,ncomp,
id);
389 for (
auto& val : res) val = 1. / val;
392inline void DTIRhoV_vec(SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
394 VectorD RhoV_((
int)res.size()), DTRhoV_((
int)res.size());
395 RhoV(T,P,SpanD(RhoV_),ncomp,
id);
396 DTRhoV(T,P,SpanD(DTRhoV_),ncomp,
id);
397 for (
auto& val : res) val = -DTRhoV_[i_it] / ( RhoV_[i_it] * RhoV_[i_it] );
400inline void DPIRhoV_vec(SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
402 VectorD RhoV_((
int)res.size()), DPRhoV_((
int)res.size());
403 RhoV(T,P,SpanD(RhoV_),ncomp,
id);
404 DPRhoV(T,P,SpanD(DPRhoV_),ncomp,
id);
405 for (
auto& val : res) val = -DPRhoV_[i_it] / ( RhoV_[i_it] * RhoV_[i_it] );
408inline void BETAV(SpanD T,
const SpanD P, SpanD res,
int ncomp,
int id)
410 assert ((
int)T.size() == ncomp * (
int)res.size() && (
int)T.size() == ncomp * (
int)P.size());
411 VectorD IRhoV_((
int)res.size()), DTIRhoV_((
int)res.size());
412 IRhoV_vec(T,P,SpanD(IRhoV_),ncomp,
id);
413 DTIRhoV_vec(T,P,SpanD(DTIRhoV_),ncomp,
id);
414 for (
auto& val : res) val = DTIRhoV_[i_it] / IRhoV_[i_it];
418inline void MuV(
const SpanD T, SpanD res,
int ncomp,
int id)
420 assert ((
int)T.size() == ncomp * (
int)res.size());
421 for (
auto& val : res) val = 2.5e-6 + 1.5e-8 * (T[i_it * ncomp + id] + 273.15);
425inline void LambdaV(
const SpanD T, SpanD res,
int ncomp,
int id)
427 assert ((
int)T.size() == ncomp * (
int)res.size());
428 for (
auto& val : res) val = 0.045;