@neutrium/thermo.eos.iapws97
Version:
A javascript implementation of the IAWPS formulations for the thermodynamic properties of water and steam.
349 lines (283 loc) • 14.1 kB
text/typescript
import {State} from '@neutrium/thermo';
import * as NS from './base';
import * as PT from './PT';
let R = NS.constants['R'];
//
// Comments : Determines which IAPWS-IF97 region a pressure and entropy combination lie in.
//
// @param P is the pressure of the water in mega Pascals
// @param s is the entropy in kJ . K^-1 . kg^1
//
export function solve(P : number, s: number) : State
{
let region = findRegion_PS(P,s),
result = null;
switch(region)
{
case 1 : result = r1(P, s); break;
case 2 : result = r2(P, s); break;
case 3 : result = r3(P, s); break;
//case 4 : result = R4_PS(P, s); break;
default : throw new Error('Insufficent inputs provided');
}
return result;
}
//
// Comments : Determines which IAPWS-IF97 region a pressure and entropy combination lie in.
//
// @param P is the pressure of the water in mega Pascals
// @param s is the entropy in kJ/kg
//
function findRegion_PS(P : number, s : number) : number
{
let r = PT.r5(P, NS.CONST('R5_MAX_T'));
if (P >= NS.CONST('MIN_P') && P <= NS.CONST('MAX_P') && s >= NS.CONST('MIN_S') && s <= r.s)
{
r = PT.r2(P, NS.CONST('R5_MIN_T'));
if (s > r.s && P <= NS.CONST('R5_MAX_P'))
{
return 5;
}
if (P > NS.CONST('B23_MIN_P'))
{
r = PT.r2(P, PT.b23_P_T(P));
if (s > r.s)
{
return 2;
}
r = PT.r3(P, NS.CONST('R3_MIN_T'));
if (s > r.s)
{
return 3;
}
}
r = PT.r1(P, PT.r4_P_Tsat(P));
if (P <= NS.CONST('B23_MIN_P') && s > r.s)
{
return 2;
}
r = PT.r1(P, NS.CONST('MIN_T'));
if (s >= r.s)
{
return 1;
}
}
return -1;
}
//
// Backwards equations for region 1 (P and s given)
//
function r1(P : number, s : number) : State
{
let T = r1_PS_T(P,s);
return PT.r1(P,T);
}
function r1_PS_T(P : number, s : number) : number
{
let R1_PS_I = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4],
R1_PS_J = [0, 1, 2, 3, 11, 31, 0, 1, 2, 3, 12, 31, 0, 1, 2, 9, 31, 10, 32, 32],
R1_PS_N = [174.78268058307, 34.806930892873, 6.5292584978455, 0.33039981775489, -1.9281382923196E-7, -2.4909197244573E-23, -0.26107636489332, 0.22592965981586, -0.064256463395226, 0.0078876289270526, 3.5672110607366E-10, 1.7332496994895E-24, 0.00056608900654837, -0.00032635483139717, 0.000044778286690632, -5.1322156908507E-10, -4.2522657042207E-26, 2.6400441360689E-13, 7.8124600459723E-29, -3.0732199903668E-31],
pi = P,
sig = s,
T = 0;
for (let i = 0; i < 20; i++)
{
var N = R1_PS_N[i],
I = R1_PS_I[i],
J = R1_PS_J[i];
T += N*Math.pow(pi,I)*Math.pow(sig+2,J);
}
return T;
}
//
// Backwards equation for region 2 (P and s given)
//
function r2(P : number, s : number) : State
{
let T = r2_PS_T(P,s);
return PT.r2(P,T);
}
function r2_PS_T(P : number, s : number) : number
{
let T : number;
if (P <= NS.CONST('R2_CRT_P'))
{
T = r2A_PS_T(P, s);
}
else
{
if(s >= NS.CONST('R2_CRT_S'))
{
T = r2B_PS_T(P, s);
}
else
{
T = r2C_PS_T(P, s);
}
}
return T;
}
function r2A_PS_T(P : number, s : number) : number
{
let R2A_PS_I = [-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.25, -1.25, -1.25, -1, -1, -1, -1, -1, -1, -0.75, -0.75, -0.5, -0.5, -0.5, -0.5, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.75, 0.75, 0.75, 0.75, 1, 1, 1.25, 1.25, 1.5, 1.5],
R2A_PS_J = [-24, -23, -19, -13, -11, -10, -19, -15, -6, -26, -21, -17, -16, -9, -8, -15, -14, -26, -13, -9, -7, -27, -25, -11, -6, 1, 4, 8, 11, 0, 1, 5, 6, 10, 14, 16, 0, 4, 9, 17, 7, 18, 3, 15, 5, 18],
R2A_PS_N = [-392359.83861984, 515265.7382727, 40482.443161048, -321.93790923902, 96.961424218694, -22.867846371773, -449429.14124357, -5011.8336020166, 0.35684463560015, 44235.33584819, -13673.388811708, 421632.6027864, 22516.925837475, 474.42144865646, -149.31130797647, -197811.26320452, -23554.39947076, -19070.616302076, 55375.669883164, 3829.3691437363, -603.91860580567, 1936.3102620331, 4266.064369861, -5978.0638872718, -704.01463926862, 338.36784107553, 20.862786635187, 0.033834172656196, -0.000043124428414893, 166.53791356412, -139.86292055898, -0.78849547999872, 0.072132411753872, -0.0059754839398283, -0.000012141358953904, 2.3227096733871E-7, -10.538463566194, 2.0718925496502, -0.072193155260427, 2.074988708112E-7, -0.018340657911379, 2.9036272348696E-7, 0.21037527893619, 0.00025681239729999, -0.012799002933781, -8.2198102652018E-6],
pi = P,
sig = s/2,
T = 0;
for (let i = 0; i < 46; i++)
{
let N = R2A_PS_N[i],
I = R2A_PS_I[i],
J = R2A_PS_J[i];
T += N*Math.pow(pi, I)*Math.pow(sig-2, J);
}
return T;
}
function r2B_PS_T(P : number, s : number) : number
{
let R2B_PS_I = [-6, -6, -5, -5, -4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5],
R2B_PS_J = [0, 11, 0, 11, 0, 1, 11, 0, 1, 11, 12, 0, 1, 6, 10, 0, 1, 5, 8, 9, 0, 1, 2, 4, 5, 6, 9, 0, 1, 2, 3, 7, 8, 0, 1, 5, 0, 1, 3, 0, 1, 0, 1, 2],
R2B_PS_N = [316876.65083497, 20.864175881858, -398593.99803599, -21.816058518877, 223697.85194242, -2784.1703445817, 9.920743607148, -75197.512299157, 2970.8605951158, -3.4406878548526, 0.38815564249115, 17511.29508575, -1423.7112854449, 1.0943803364167, 0.89971619308495, -3375.9740098958, 471.62885818355, -1.9188241993679, 0.41078580492196, -0.33465378172097, 1387.0034777505, -406.63326195838, 41.72734715961, 2.1932549434532, -1.0320050009077, 0.35882943516703, 0.0052511453726066, 12.838916450705, -2.8642437219381, 0.56912683664855, -0.099962954584931, -0.0032632037778459, 0.00023320922576723, -0.1533480985745, 0.029072288239902, 0.00037534702741167, 0.0017296691702411, -0.00038556050844504, -0.000035017712292608, -0.000014566393631492, 5.6420857267269E-06, 4.1286150074605E-08, -2.0684671118824E-08, 1.6409393674725E-09],
pi = P,
sig = s/0.7853,
T = 0;
for (let i = 0; i < 44; i++)
{
let N = R2B_PS_N[i],
I = R2B_PS_I[i],
J = R2B_PS_J[i];
T += N*Math.pow(pi, I)*Math.pow(10.0-sig, J);
}
return T;
}
function r2C_PS_T(P : number, s : number) : number
{
let R2C_PS_I = [-2, -2, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 7],
R2C_PS_J = [0, 1, 0, 0, 1, 2, 3, 0, 1, 3, 4, 0, 1, 2, 0, 1, 5, 0, 1, 4, 0, 1, 2, 0, 1, 0, 1, 3, 4, 5],
R2C_PS_N = [909.68501005365, 2404.566708842, -591.6232638713, 541.45404128074, -270.98308411192, 979.76525097926, -469.66772959435, 14.399274604723, -19.104204230429, 5.3299167111971, -21.252975375934, -0.3114733441376, 0.60334840894623, -0.042764839702509, 0.0058185597255259, -0.014597008284753, 0.0056631175631027, -0.000076155864584577, 0.00022440342919332, -0.000012561095013413, 6.3323132660934E-07, -2.0541989675375E-06, 3.6405370390082E-08, -2.9759897789215E-09, 1.0136618529763E-08, 5.9925719692351E-12, -2.0677870105164E-11, -2.0874278181886E-11, 1.0162166825089E-10, -1.6429828281347E-10],
pi = P,
sig = s/2.9251,
T = 0;
for (let i = 0; i < 30; i++)
{
let N = R2C_PS_N[i],
I = R2C_PS_I[i],
J = R2C_PS_J[i];
T += N*Math.pow(pi,I)*Math.pow(2.0-sig,J);
}
return T;
}
//
// Backwards equation for region 3 (P and s given)
// From : Revised Supplementary Release on Backward Equations for the Functions
// T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS Industrial
// Formulation 1997 for the Thermodynamic Properties of Water and Steam
//
function r3(P : number, s : number) : State
{
let T, rho;
if (s <= NS.CONST('R3_CRT_S'))
{
T = r3A_PS_T(P,s);
rho = r3A_PS_V(P,s);
}
else
{
T = r3B_PS_T(P,s);
rho = r3B_PS_V(P,s);
}
return PT.r3(P, T, rho);
}
function r3A_PS_T(P : number, s : number) : number
{
let R3A_I = [-12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -6, -6, -5, -5, -5, -4, -4, -4, -2, -2, -1, -1, 0, 0, 0, 1, 2, 2, 3, 8, 8, 10],
R3A_J = [28, 32, 4, 10, 12, 14, 5, 7, 8, 28, 2, 6, 32, 0, 14, 32, 6, 10, 36, 1, 4, 1, 6, 0, 1, 4, 0, 0, 3, 2, 0, 1, 2, ],
R3A_N = [1500420082.63875, -159397258480.424, 5.02181140217975E-4, -67.2057767855466, 1450.58545404456, -8238.8953488889, -0.154852214233853, 11.2305046746695, -29.7000213482822, 43856513263.5495, 0.00137837838635464, -2.97478527157462, 9717779473494.13, -5.71527767052398E-5, 28830.794977842, -74442828926270.3, 12.8017324848921, -368.275545889071, 6647689047791770, 0.044935925195888, -4.22897836099655, -0.240614376434179, -4.74341365254924, 0.72409399912611, 0.923874349695897, 3.99043655281015, 0.0384066651868009, -0.00359344365571848, -0.735196448821653, 0.188367048396131, 0.000141064266818704, -0.00257418501496337, 0.00123220024851555],
pi = P/100,
sig = s/4.4,
T = 0;
for (let i = 0; i < 33; i++)
{
let N = R3A_N[i],
I = R3A_I[i],
J = R3A_J[i];
T += N*Math.pow(pi + 0.24, I)*Math.pow(sig - 0.703, J);
}
return 760*T;
}
export function r3A_PS_V(P : number, s : number) : number
{
let R3A_I = [-12, -12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -5, -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 1, 2, 4, 5, 6],
R3A_J = [10, 12, 14, 4, 8, 10, 20, 5, 6, 14, 16, 28, 1, 5, 2, 4, 3, 8, 1, 2, 0, 1, 3, 0, 0, 2, 2, 0],
R3A_N = [79.5544074093975, -2382.6124298459, 17681.3100617787, -0.00110524727080379, -15.3213833655326, 297.544599376982, -35031520.6871242, 0.277513761062119, -0.523964271036888, -148011.182995403, 1600148.99374266, 1708023226634.27, 0.000246866996006494, 1.6532608479798, -0.118008384666987, 2.537986423559, 0.965127704669424, -28.2172420532826, 0.203224612353823, 1.10648186063513, 0.52612794845128, 0.277000018736321, 1.08153340501132, -0.0744127885357893, 0.0164094443541384, -0.0680468275301065, 0.025798857610164, -0.000145749861944416],
pi = P/100,
sig = s/4.4,
v = 0;
for (let i = 0; i < 28; i++)
{
let N = R3A_N[i],
I = R3A_I[i],
J = R3A_J[i];
v += N*Math.pow(pi+0.187,I)*Math.pow(sig-0.755,J);
}
return 0.0028*v;
}
function r3B_PS_T(P : number, s : number) : number
{
let R3B_PS_I = [-12, -12, -12, -12, -8, -8, -8, -6, -6, -6, -5, -5, -5, -5, -5, -4, -3, -3, -2, 0, 2, 3, 4, 5, 6, 8, 12, 14],
R3B_PS_J = [1, 3, 4, 7, 0, 1, 3, 0, 2, 4, 0, 1, 2, 4, 6, 12, 1, 6, 2, 0, 1, 1, 0, 24, 0, 3, 1, 2],
R3B_PS_N = [0.52711170160166, -40.1317830052742, 153.020073134484, -2247.99398218827, -0.193993484669048, -1.40467557893768, 42.6799878114024, 0.752810643416743, 22.6657238616417, -622.873556909932, -0.660823667935396, 0.841267087271658, -25.3717501764397, 485.708963532948, 880.531517490555, 2650155.92794626, -0.359287150025783, -656.991567673753, 2.41768149185367, 0.856873461222588, 0.655143675313458, -0.213535213206406, 0.00562974957606348, -316955725450471.0, -0.000699997000152457, 0.0119845803210767, 1.93848122022095E-05, -2.15095749182309E-05],
pi = P/100,
sig = s/5.3,
T = 0;
for (let i = 0; i < 28; i++)
{
let N = R3B_PS_N[i],
I = R3B_PS_I[i],
J = R3B_PS_J[i];
T += N*Math.pow(pi+0.76,I)*Math.pow(sig-0.818,J);
}
return 860*T;
}
export function r3B_PS_V(P : number, s : number) : number
{
let R3B_PS_v_I = [-12, -12, -12, -12, -12, -12, -10, -10, -10, -10, -8, -5, -5, -5, -4, -4, -4, -4, -3, -2, -2, -2, -2, -2, -2, 0, 0, 0, 1, 1, 2],
R3B_PS_v_J = [0, 1, 2, 3, 5, 6, 0, 1, 2, 4, 0, 1, 2, 3, 0, 1, 2, 3, 1, 0, 1, 2, 3, 4, 12, 0, 1, 2, 0, 2, 2],
R3B_PS_v_N = [5.91599780322238E-5, -0.00185465997137856, 0.0104190510480013, 0.0059864730203859, -0.771391189901699, 1.72549765557036, -0.000467076079846526, 0.0134533823384439, -0.0808094336805495, 0.508139374365767, 0.00128584643361683, -1.63899353915435, 5.86938199318063, -2.92466667918613, -0.00614076301499537, 5.76199014049172, -12.1613320606788, 1.67637540957944, -7.44135838773463, 0.0378168091437659, 4.01432203027688, 16.0279837479185, 3.17848779347728, -3.58362310304853, -1159952.60446827, 0.199256573577909, -0.122270624794624, -19.1449143716586, -0.0150448002905284, 14.6407900162154, -3.2747778718823],
pi = P/100,
sig = s/5.3,
v = 0;
for (let i = 0; i < 31; i++)
{
let N = R3B_PS_v_N[i],
I = R3B_PS_v_I[i],
J = R3B_PS_v_J[i];
v += N*Math.pow(pi+0.298, I)*Math.pow(sig-0.816, J);
}
return 0.0088*v;
}
//
// Region 4
//
function r4(P : number , s : number) : State
{
let T = PT.r4_P_Tsat(P);
return PT.solve(P, T);
}
function r4_S_Psat(s : number) : number
{
let R4_I = [0, 1, 1, 4, 12, 12, 16, 24, 28, 32],
R4_J = [0, 1, 32, 7, 4, 14, 36, 10, 0, 18],
R4_N = [0.639767553612785, -1.29727445396014E1, -2.24595125848403E16, 1.77466741801846E6, 7.17079349571538E9, -3.78829107169011E17, -9.55586736431328E34, 1.87269814676188E23, 1.19254746466473E11, 1.10649277244882E36],
sig = s/5.2,
p = 0;
for(let i = 0; i < 10; i++)
{
let I = R4_I[i],
J = R4_J[i],
N = R4_N[i];
p += N*Math.pow(sig - 1.03, I)*Math.pow(sig - 0.699, J);
}
return 22*p;
}