iapws-if97 2.1.5 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -1
- package/README.md +78 -215
- package/dist/backward/candidate-resolution.d.ts +8 -0
- package/dist/backward/candidate-resolution.js +40 -0
- package/dist/backward/fixed-temperature-candidates.d.ts +4 -0
- package/dist/backward/fixed-temperature-candidates.js +188 -0
- package/dist/backward/fixed-temperature-solver.d.ts +6 -6
- package/dist/backward/fixed-temperature-solver.js +56 -9
- package/dist/backward/fixed-temperature-stationary.d.ts +4 -0
- package/dist/backward/fixed-temperature-stationary.js +146 -0
- package/dist/backward/hs-region.d.ts +50 -0
- package/dist/backward/hs-region.js +695 -0
- package/dist/backward/hs-state.d.ts +15 -0
- package/dist/backward/hs-state.js +316 -0
- package/dist/backward/hs.d.ts +1 -2
- package/dist/backward/hs.js +28 -232
- package/dist/backward/ph.d.ts +8 -3
- package/dist/backward/ph.js +102 -54
- package/dist/backward/pressure-property-region.d.ts +13 -0
- package/dist/backward/pressure-property-region.js +262 -0
- package/dist/backward/ps.d.ts +6 -1
- package/dist/backward/ps.js +103 -38
- package/dist/backward/solution-validation.d.ts +7 -2
- package/dist/backward/solution-validation.js +162 -37
- package/dist/backward/th.d.ts +3 -6
- package/dist/backward/th.js +10 -73
- package/dist/backward/tolerances.d.ts +3 -1
- package/dist/backward/tolerances.js +9 -4
- package/dist/backward/ts.d.ts +3 -6
- package/dist/backward/ts.js +10 -73
- package/dist/boundaries.d.ts +0 -1
- package/dist/boundaries.js +0 -1
- package/dist/constants.d.ts +11 -24
- package/dist/constants.js +17 -28
- package/dist/core/floating-point.d.ts +2 -0
- package/dist/core/floating-point.js +7 -0
- package/dist/core/formulation-seams.d.ts +27 -0
- package/dist/core/formulation-seams.js +289 -0
- package/dist/core/input-validation.d.ts +1 -1
- package/dist/core/input-validation.js +5 -1
- package/dist/core/region-detector.d.ts +3 -41
- package/dist/core/region-detector.js +39 -597
- package/dist/core/region3-pt.d.ts +12 -1
- package/dist/core/region3-pt.js +68 -13
- package/dist/core/solve-input-normalization.d.ts +0 -1
- package/dist/core/solve-input-normalization.js +4 -2
- package/dist/core/solver.d.ts +7 -11
- package/dist/core/solver.js +26 -18
- package/dist/core/thermodynamic-derivatives.d.ts +17 -0
- package/dist/core/thermodynamic-derivatives.js +27 -0
- package/dist/detect.d.ts +16 -3
- package/dist/detect.js +36 -3
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +16 -0
- package/dist/gas-constant.d.ts +5 -0
- package/dist/gas-constant.js +5 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.js +10 -22
- package/dist/regions/boundaries.d.ts +0 -1
- package/dist/regions/boundaries.js +0 -1
- package/dist/regions/region1.d.ts +2 -2
- package/dist/regions/region1.js +1 -2
- package/dist/regions/region2.d.ts +2 -2
- package/dist/regions/region2.js +1 -2
- package/dist/regions/region3-data.d.ts +0 -1
- package/dist/regions/region3-data.js +3 -4
- package/dist/regions/region3-eval.d.ts +0 -1
- package/dist/regions/region3-eval.js +0 -1
- package/dist/regions/region3-subregions.d.ts +0 -1
- package/dist/regions/region3-subregions.js +15 -11
- package/dist/regions/region3.d.ts +4 -2
- package/dist/regions/region3.js +32 -3
- package/dist/regions/region4.d.ts +2 -1
- package/dist/regions/region4.js +39 -13
- package/dist/regions/region5.d.ts +2 -2
- package/dist/regions/region5.js +2 -3
- package/dist/regions.d.ts +0 -1
- package/dist/regions.js +0 -1
- package/dist/saturation/common.d.ts +2 -9
- package/dist/saturation/common.js +66 -45
- package/dist/saturation/region4-boundaries.d.ts +0 -5
- package/dist/saturation/region4-boundaries.js +17 -18
- package/dist/saturation/region4-hs.d.ts +2 -1
- package/dist/saturation/region4-hs.js +499 -106
- package/dist/saturation/two-phase.d.ts +2 -3
- package/dist/saturation/two-phase.js +7 -8
- package/dist/saturation.d.ts +0 -1
- package/dist/saturation.js +0 -1
- package/dist/solvers/bracketed-newton.d.ts +10 -6
- package/dist/solvers/bracketed-newton.js +19 -13
- package/dist/solvers/damped-newton-2d.d.ts +12 -0
- package/dist/solvers/damped-newton-2d.js +68 -0
- package/dist/solvers/extended-arithmetic.d.ts +6 -0
- package/dist/solvers/extended-arithmetic.js +38 -0
- package/dist/solvers/newton-raphson.d.ts +0 -1
- package/dist/solvers/newton-raphson.js +0 -1
- package/dist/transport/properties.d.ts +4 -3
- package/dist/transport/properties.js +14 -5
- package/dist/transport.d.ts +0 -1
- package/dist/transport.js +0 -1
- package/dist/types.d.ts +18 -1
- package/dist/types.js +14 -1
- package/package.json +18 -10
- package/dist/backward/objective-normalization.d.ts +0 -7
- package/dist/backward/objective-normalization.js +0 -8
- package/dist/core/public-normalization.d.ts +0 -4
- package/dist/core/public-normalization.js +0 -54
- package/dist/solvers/nelder-mead.d.ts +0 -17
- package/dist/solvers/nelder-mead.js +0 -116
package/dist/backward/ps.js
CHANGED
|
@@ -4,18 +4,19 @@
|
|
|
4
4
|
* Reference: IAPWS-IF97 Supplementary Release on Backward Equations
|
|
5
5
|
*/
|
|
6
6
|
import { Region, IF97Error, OutOfRangeError } from '../types.js';
|
|
7
|
+
import { SaturationEndpointError } from '../errors.js';
|
|
7
8
|
import * as C from '../constants.js';
|
|
8
9
|
import { region1 } from '../regions/region1.js';
|
|
9
10
|
import { region2 } from '../regions/region2.js';
|
|
10
|
-
import { region3ByRhoT } from '../regions/region3.js';
|
|
11
|
+
import { region3ByRhoT, region3PressureResidual } from '../regions/region3.js';
|
|
11
12
|
import { region5 } from '../regions/region5.js';
|
|
12
|
-
import { assertFiniteNumber } from '../core/input-validation.js';
|
|
13
|
-
import { detectRegionPS } from '
|
|
13
|
+
import { assertFiniteNumber, withinClosedLowerBound } from '../core/input-validation.js';
|
|
14
|
+
import { assertPressurePropertyEnvelope, detectRegionPS, pressurePropertyBoundaryState, pressurePropertySeam } from './pressure-property-region.js';
|
|
14
15
|
import { newtonRaphson } from '../solvers/newton-raphson.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
import { bracketedNewton } from '../solvers/bracketed-newton.js';
|
|
17
|
+
import { dampedNewton2D } from '../solvers/damped-newton-2d.js';
|
|
18
|
+
import { validateBackwardState, validateRegion3PTReconstruction } from './solution-validation.js';
|
|
19
|
+
import { helmholtzPropertyDerivatives } from '../core/thermodynamic-derivatives.js';
|
|
19
20
|
import { mixSaturationState, qualityFromSaturationProperty, saturationEndpointsAtPressure, } from '../saturation/common.js';
|
|
20
21
|
import { assertCriticalRegion4PSInput, assertRegion4StateAllowed, } from '../saturation/region4-boundaries.js';
|
|
21
22
|
function evalPoly(table, piShift, sigShift, pi, sig) {
|
|
@@ -34,7 +35,7 @@ const R1_PS = [
|
|
|
34
35
|
[2, 31, -4.2522657042207e-26], [3, 10, 2.6400441360689e-13], [3, 32, 7.8124600459723e-29],
|
|
35
36
|
[4, 32, -3.0732199903668e-31],
|
|
36
37
|
];
|
|
37
|
-
function r1BackwardT(p, s) {
|
|
38
|
+
export function r1BackwardT(p, s) {
|
|
38
39
|
return evalPoly(R1_PS, 0, -2, p, s);
|
|
39
40
|
}
|
|
40
41
|
// ─── Region 2 Backward T(P,S) — Subregions 2a/2b/2c ───────────────────────
|
|
@@ -42,7 +43,7 @@ const R2A_PS = [
|
|
|
42
43
|
[-1.5, -24, -392359.83861984], [-1.5, -23, 515265.7382727], [-1.5, -19, 40482.443161048],
|
|
43
44
|
[-1.5, -13, -321.93790923902], [-1.5, -11, 96.961424218694], [-1.5, -10, -22.867846371773],
|
|
44
45
|
[-1.25, -19, -449429.14124357], [-1.25, -15, -5011.8336020166], [-1.25, -6, 0.35684463560015],
|
|
45
|
-
[-1, -26, 44235.33584819], [-1, -21, -13673.388811708], [-1, -17, 421632.
|
|
46
|
+
[-1, -26, 44235.33584819], [-1, -21, -13673.388811708], [-1, -17, 421632.60207864],
|
|
46
47
|
[-1, -16, 22516.925837475], [-1, -9, 474.42144865646], [-1, -8, -149.31130797647],
|
|
47
48
|
[-0.75, -15, -197811.26320452], [-0.75, -14, -23554.39947076], [-0.5, -26, -19070.616302076],
|
|
48
49
|
[-0.5, -13, 55375.669883164], [-0.5, -9, 3829.3691437363], [-0.5, -7, -603.91860580567],
|
|
@@ -85,14 +86,14 @@ const R2C_PS = [
|
|
|
85
86
|
[6, 1, 1.0136618529763e-8], [7, 0, 5.9925719692351e-12], [7, 1, -2.0677870105164e-11],
|
|
86
87
|
[7, 3, -2.0874278181886e-11], [7, 4, 1.0162166825089e-10], [7, 5, -1.6429828281347e-10],
|
|
87
88
|
];
|
|
88
|
-
function r2BackwardT(p, s) {
|
|
89
|
+
export function r2BackwardT(p, s) {
|
|
89
90
|
if (p <= C.R2_P_CRT) {
|
|
90
91
|
return evalPoly(R2A_PS, 0, 2, p, s / 2);
|
|
91
92
|
}
|
|
92
93
|
if (s >= C.R2_S_CRT) {
|
|
93
|
-
return evalPoly(R2B_PS, 0, 10, p, s / 0.7853);
|
|
94
|
+
return evalPoly(R2B_PS, 0, -10, p, -s / 0.7853);
|
|
94
95
|
}
|
|
95
|
-
return evalPoly(R2C_PS, 0, 2, p, s / 2.9251);
|
|
96
|
+
return evalPoly(R2C_PS, 0, -2, p, -s / 2.9251);
|
|
96
97
|
}
|
|
97
98
|
// ─── Region 3 Backward T(P,S) and v(P,S) ──────────────────────────────────
|
|
98
99
|
const R3A_PS_T_TABLE = [
|
|
@@ -145,6 +146,40 @@ const R3B_PS_V_TABLE = [
|
|
|
145
146
|
[0, 2, -19.1449143716586], [1, 0, -0.0150448002905284], [1, 2, 14.6407900162154],
|
|
146
147
|
[2, 2, -3.2747778718823],
|
|
147
148
|
];
|
|
149
|
+
export function r3BackwardPSInitial(p, s) {
|
|
150
|
+
if (s <= C.R3_S_CRT) {
|
|
151
|
+
const T = 760 * evalPoly(R3A_PS_T_TABLE, -0.240, 0.703, p / 100, s / 4.4);
|
|
152
|
+
const v = 0.0028 * evalPoly(R3A_PS_V_TABLE, -0.187, 0.755, p / 100, s / 4.4);
|
|
153
|
+
return { rho: 1 / v, T };
|
|
154
|
+
}
|
|
155
|
+
const T = 860 * evalPoly(R3B_PS_T_TABLE, -0.760, 0.818, p / 100, s / 5.3);
|
|
156
|
+
const v = 0.0088 * evalPoly(R3B_PS_V_TABLE, -0.298, 0.816, p / 100, s / 5.3);
|
|
157
|
+
return { rho: 1 / v, T };
|
|
158
|
+
}
|
|
159
|
+
function solveRegion3PS(p, s, rho0, T0, refinePressure = false) {
|
|
160
|
+
// Scaling the 1e-13 solver tolerance by 1e-4 resolves pressure below one ULP before PT reconstruction.
|
|
161
|
+
const pScale = Math.max(1, Math.abs(p)) * (refinePressure ? 1e-4 : 1);
|
|
162
|
+
const sScale = Math.max(1, Math.abs(s));
|
|
163
|
+
const [rho, T] = dampedNewton2D(([candidateRho, candidateT]) => {
|
|
164
|
+
const state = region3ByRhoT(candidateRho, candidateT);
|
|
165
|
+
const derivatives = helmholtzPropertyDerivatives(state, candidateRho);
|
|
166
|
+
return {
|
|
167
|
+
residual: [
|
|
168
|
+
(refinePressure ? region3PressureResidual(candidateRho, candidateT, p) : state.pressure - p) / pScale,
|
|
169
|
+
(state.entropy - s) / sScale,
|
|
170
|
+
],
|
|
171
|
+
jacobian: [
|
|
172
|
+
[derivatives.dpDrho / pScale, derivatives.dpDT / pScale],
|
|
173
|
+
[derivatives.dsDrho / sScale, derivatives.dsDT / sScale],
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
}, [rho0, T0], {
|
|
177
|
+
// Near saturation, the default residual can put the liquid root across Tsat.
|
|
178
|
+
tolerance: 1e-13,
|
|
179
|
+
isValid: ([candidateRho, candidateT]) => candidateRho > 0 && candidateT > 0,
|
|
180
|
+
});
|
|
181
|
+
return region3ByRhoT(rho, T);
|
|
182
|
+
}
|
|
148
183
|
// ─── Main PS Solver ────────────────────────────────────────────────────────
|
|
149
184
|
/**
|
|
150
185
|
* Solve for thermodynamic state given P and S.
|
|
@@ -157,51 +192,81 @@ export function solvePS(p, s) {
|
|
|
157
192
|
if (p < C.P_MIN || p > C.P_MAX) {
|
|
158
193
|
throw new OutOfRangeError('Pressure', p, C.P_MIN, C.P_MAX);
|
|
159
194
|
}
|
|
160
|
-
if (s
|
|
195
|
+
if (!withinClosedLowerBound(s, C.S_MIN, 'entropy') || s > C.S_MAX) {
|
|
161
196
|
throw new OutOfRangeError('Entropy', s, C.S_MIN, C.S_MAX);
|
|
162
197
|
}
|
|
163
198
|
assertCriticalRegion4PSInput(p, s, 'solvePS');
|
|
164
|
-
|
|
199
|
+
assertPressurePropertyEnvelope(p, s, 'entropy');
|
|
200
|
+
const seam = pressurePropertySeam(p, s, 'entropy');
|
|
201
|
+
if (seam !== null && seam.kind !== 'overlap') {
|
|
202
|
+
return validateBackwardState(seam.state, [
|
|
203
|
+
{ label: 'pressure', expected: p },
|
|
204
|
+
{ label: 'entropy', expected: s },
|
|
205
|
+
], { solverName: 'solvePS', expectedRegion: seam.state.region, seam });
|
|
206
|
+
}
|
|
207
|
+
if (seam === null) {
|
|
208
|
+
const boundary = pressurePropertyBoundaryState(p, s, 'entropy');
|
|
209
|
+
if (boundary !== null)
|
|
210
|
+
return boundary;
|
|
211
|
+
}
|
|
212
|
+
let region;
|
|
213
|
+
let saturationFailure = null;
|
|
214
|
+
try {
|
|
215
|
+
region = seam?.state.region ?? detectRegionPS(p, s);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (!(error instanceof SaturationEndpointError)) {
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
saturationFailure = error;
|
|
222
|
+
region = Region.Region3;
|
|
223
|
+
}
|
|
165
224
|
switch (region) {
|
|
166
225
|
case Region.Region1: {
|
|
167
226
|
const T0 = r1BackwardT(p, s);
|
|
168
|
-
const T = newtonRaphson((T_x) => region1(p, T_x).entropy - s, T0);
|
|
227
|
+
const T = newtonRaphson((T_x) => region1(p, T_x).entropy - s, T0, (T_x) => (region1(p, T_x).cp ?? Number.NaN) / T_x);
|
|
169
228
|
return validateBackwardState(region1(p, T), [
|
|
170
229
|
{ label: 'pressure', expected: p },
|
|
171
230
|
{ label: 'entropy', expected: s },
|
|
172
231
|
], { solverName: 'solvePS', expectedRegion: Region.Region1 });
|
|
173
232
|
}
|
|
174
233
|
case Region.Region2: {
|
|
234
|
+
const targetS = Math.min(s, region2(p, C.R2_T_MAX).entropy);
|
|
175
235
|
const T0 = r2BackwardT(p, s);
|
|
176
|
-
const T = newtonRaphson((T_x) => region2(p, T_x).entropy -
|
|
236
|
+
const T = newtonRaphson((T_x) => region2(p, T_x).entropy - targetS, T0, (T_x) => (region2(p, T_x).cp ?? Number.NaN) / T_x);
|
|
177
237
|
return validateBackwardState(region2(p, T), [
|
|
178
238
|
{ label: 'pressure', expected: p },
|
|
179
239
|
{ label: 'entropy', expected: s },
|
|
180
240
|
], { solverName: 'solvePS', expectedRegion: Region.Region2 });
|
|
181
241
|
}
|
|
182
242
|
case Region.Region3: {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
243
|
+
try {
|
|
244
|
+
const initial = r3BackwardPSInitial(p, s);
|
|
245
|
+
const validate = (state) => validateBackwardState(state, [
|
|
246
|
+
{ label: 'pressure', expected: p },
|
|
247
|
+
{ label: 'entropy', expected: s },
|
|
248
|
+
], { solverName: 'solvePS', expectedRegion: Region.Region3 });
|
|
249
|
+
const validated = validate(solveRegion3PS(p, s, initial.rho, initial.T));
|
|
250
|
+
// Compressibility can amplify an accepted pressure residual beyond PT's density accuracy.
|
|
251
|
+
const relativeDensityError = Math.abs(region3PressureResidual(1 / validated.specificVolume, validated.temperature, p)) * validated.isothermalCompressibility;
|
|
252
|
+
if (saturationFailure === null && relativeDensityError <= 1e-12)
|
|
253
|
+
return validated;
|
|
254
|
+
try {
|
|
255
|
+
const refined = validate(solveRegion3PS(p, s, 1 / validated.specificVolume, validated.temperature, true));
|
|
256
|
+
validateRegion3PTReconstruction(refined, 'solvePS');
|
|
257
|
+
return refined;
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
if (!(error instanceof IF97Error))
|
|
261
|
+
throw error;
|
|
262
|
+
return saturationFailure === null ? validated : validateRegion3PTReconstruction(validated, 'solvePS');
|
|
263
|
+
}
|
|
189
264
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
265
|
+
catch (error) {
|
|
266
|
+
if (saturationFailure !== null && error instanceof IF97Error)
|
|
267
|
+
throw saturationFailure;
|
|
268
|
+
throw error;
|
|
193
269
|
}
|
|
194
|
-
const sol = nelderMead((pair) => {
|
|
195
|
-
const state = region3ByRhoT(1 / pair[0], pair[1]);
|
|
196
|
-
return sumNormalizedResiduals([
|
|
197
|
-
{ actual: state.entropy, expected: s, tolerance: entropyTolerance },
|
|
198
|
-
{ actual: state.pressure, expected: p, tolerance: pressureTolerance },
|
|
199
|
-
]);
|
|
200
|
-
}, [v0, T0], { maxIterations: 1000, minErrorDelta: 1e-8, minTolerance: 1e-9 });
|
|
201
|
-
return validateBackwardState(region3ByRhoT(1 / sol.x[0], sol.x[1]), [
|
|
202
|
-
{ label: 'pressure', expected: p, tolerance: pressureTolerance },
|
|
203
|
-
{ label: 'entropy', expected: s },
|
|
204
|
-
], { solverName: 'solvePS', expectedRegion: Region.Region3 });
|
|
205
270
|
}
|
|
206
271
|
case Region.Region4: {
|
|
207
272
|
const endpoints = saturationEndpointsAtPressure(p);
|
|
@@ -213,7 +278,8 @@ export function solvePS(p, s) {
|
|
|
213
278
|
], { solverName: 'solvePS', expectedRegion: Region.Region4 });
|
|
214
279
|
}
|
|
215
280
|
case Region.Region5: {
|
|
216
|
-
const
|
|
281
|
+
const targetS = Math.min(s, region5(p, C.R5_T_MAX).entropy);
|
|
282
|
+
const T = bracketedNewton((T_x) => region5(p, T_x).entropy - targetS, C.R5_T_MIN + Number.EPSILON * C.R5_T_MIN, C.R5_T_MAX, 1500, { derivative: (T_x) => (region5(p, T_x).cp ?? Number.NaN) / T_x, tolerance: 1e-12 });
|
|
217
283
|
return validateBackwardState(region5(p, T), [
|
|
218
284
|
{ label: 'pressure', expected: p },
|
|
219
285
|
{ label: 'entropy', expected: s },
|
|
@@ -223,4 +289,3 @@ export function solvePS(p, s) {
|
|
|
223
289
|
throw new IF97Error(`Cannot determine region for P=${p} MPa, s=${s} kJ/(kg·K)`);
|
|
224
290
|
}
|
|
225
291
|
}
|
|
226
|
-
//# sourceMappingURL=ps.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { FormulationSeamResolution } from '../core/formulation-seams.js';
|
|
1
2
|
import type { BasicProperties } from '../types.js';
|
|
2
|
-
import { Region } from '../types.js';
|
|
3
|
+
import { IF97Error, Region } from '../types.js';
|
|
3
4
|
export interface BackwardConstraint {
|
|
4
5
|
label: 'pressure' | 'temperature' | 'enthalpy' | 'entropy';
|
|
5
6
|
expected: number;
|
|
@@ -8,6 +9,10 @@ export interface BackwardConstraint {
|
|
|
8
9
|
export interface BackwardValidationOptions {
|
|
9
10
|
solverName: string;
|
|
10
11
|
expectedRegion?: Region;
|
|
12
|
+
seam?: FormulationSeamResolution;
|
|
11
13
|
}
|
|
14
|
+
/** Inspect a candidate without moving it across a formulation or domain boundary. */
|
|
15
|
+
export declare function backwardCandidateError(state: BasicProperties, constraints: readonly BackwardConstraint[], options: BackwardValidationOptions): IF97Error | null;
|
|
16
|
+
export declare function normalizeBackwardState(state: BasicProperties, constraints: readonly BackwardConstraint[], solverName: string): BasicProperties;
|
|
12
17
|
export declare function validateBackwardState(state: BasicProperties, constraints: readonly BackwardConstraint[], options: BackwardValidationOptions): BasicProperties;
|
|
13
|
-
|
|
18
|
+
export declare function validateRegion3PTReconstruction(state: BasicProperties, solverName: string): BasicProperties;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import * as C from '../constants.js';
|
|
2
|
-
import { detectRegionPT } from '../core/region-detector.js';
|
|
2
|
+
import { detectRegionPT, nativeB23TemperatureBracket, nativeSaturationTemperatureBracket } from '../core/region-detector.js';
|
|
3
|
+
import { solveRegion3PTBasic } from '../core/region3-pt.js';
|
|
4
|
+
import { nextPositiveFloat } from '../core/floating-point.js';
|
|
5
|
+
import { region2 } from '../regions/region2.js';
|
|
6
|
+
import { region1 } from '../regions/region1.js';
|
|
3
7
|
import { saturationPressure } from '../regions/region4.js';
|
|
8
|
+
import { region5 } from '../regions/region5.js';
|
|
4
9
|
import { IF97Error, Region } from '../types.js';
|
|
10
|
+
import { NumericalStateError, RegionMismatchError } from '../errors.js';
|
|
5
11
|
import { backwardConstraintTolerance, region4SaturationPressureTolerance, } from './tolerances.js';
|
|
6
12
|
function propertyValue(state, label) {
|
|
7
13
|
switch (label) {
|
|
@@ -17,69 +23,188 @@ function propertyValue(state, label) {
|
|
|
17
23
|
return Number.NaN;
|
|
18
24
|
}
|
|
19
25
|
}
|
|
20
|
-
function
|
|
26
|
+
function boundaryTolerance(value, boundary) {
|
|
27
|
+
return 1e-9 * Math.max(1, Math.abs(value), Math.abs(boundary));
|
|
28
|
+
}
|
|
29
|
+
function snapUpFromBelow(value, boundary) {
|
|
30
|
+
return value < boundary && boundary - value <= boundaryTolerance(value, boundary)
|
|
31
|
+
? boundary
|
|
32
|
+
: value;
|
|
33
|
+
}
|
|
34
|
+
function snapDownFromAbove(value, boundary) {
|
|
35
|
+
return value > boundary && value - boundary <= boundaryTolerance(value, boundary)
|
|
36
|
+
? boundary
|
|
37
|
+
: value;
|
|
38
|
+
}
|
|
39
|
+
function normalizeComputedPT(state) {
|
|
40
|
+
if (state.region === Region.Region4)
|
|
41
|
+
return state;
|
|
42
|
+
let pressure = state.pressure < C.P_MIN &&
|
|
43
|
+
C.P_MIN - state.pressure <= backwardConstraintTolerance('pressure', C.P_MIN)
|
|
44
|
+
? C.P_MIN
|
|
45
|
+
: state.pressure;
|
|
46
|
+
pressure = snapDownFromAbove(pressure, state.region === Region.Region5 ? C.R5_P_MAX : C.P_MAX);
|
|
47
|
+
let temperature = snapUpFromBelow(state.temperature, C.T_MIN);
|
|
48
|
+
if (state.region === Region.Region1) {
|
|
49
|
+
temperature = snapDownFromAbove(temperature, C.R2_T_MIN);
|
|
50
|
+
}
|
|
51
|
+
else if (state.region === Region.Region2) {
|
|
52
|
+
temperature = snapDownFromAbove(temperature, C.R2_T_MAX);
|
|
53
|
+
}
|
|
54
|
+
temperature = snapDownFromAbove(temperature, C.T_MAX);
|
|
55
|
+
if (pressure === state.pressure && temperature === state.temperature)
|
|
56
|
+
return state;
|
|
57
|
+
switch (state.region) {
|
|
58
|
+
case Region.Region1: return region1(pressure, temperature);
|
|
59
|
+
case Region.Region2: return region2(pressure, temperature);
|
|
60
|
+
case Region.Region3: return solveRegion3PTBasic(pressure, temperature);
|
|
61
|
+
case Region.Region5: return region5(pressure, temperature);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function normalizeB23State(state) {
|
|
65
|
+
if ((state.region !== Region.Region2 && state.region !== Region.Region3) ||
|
|
66
|
+
state.pressure <= C.B23_P_MIN || state.pressure > C.P_MAX ||
|
|
67
|
+
(state.temperature <= C.R2_T_MIN &&
|
|
68
|
+
(state.region !== Region.Region2 || state.pressure <= saturationPressure(C.R2_T_MIN))) ||
|
|
69
|
+
state.temperature >= C.B23_T_MAX ||
|
|
70
|
+
detectRegionPT(state.pressure, state.temperature) === state.region) {
|
|
71
|
+
return state;
|
|
72
|
+
}
|
|
73
|
+
const [lower, upper] = nativeB23TemperatureBracket(state.pressure);
|
|
74
|
+
const vaporT = state.region === Region.Region2 && state.pressure < C.Pc
|
|
75
|
+
? nativeSaturationTemperatureBracket(state.pressure)[1] : upper;
|
|
76
|
+
const temperature = state.region === Region.Region3 ? lower : Math.max(upper, vaporT);
|
|
77
|
+
if (Math.abs(temperature - state.temperature) > boundaryTolerance(temperature, state.temperature)) {
|
|
78
|
+
return state;
|
|
79
|
+
}
|
|
80
|
+
return state.region === Region.Region3
|
|
81
|
+
? solveRegion3PTBasic(state.pressure, temperature)
|
|
82
|
+
: region2(state.pressure, temperature);
|
|
83
|
+
}
|
|
84
|
+
function normalizeRegion3LowerState(state) {
|
|
85
|
+
if (state.region !== Region.Region3 || !(state.temperature <= C.R2_T_MIN) ||
|
|
86
|
+
C.R2_T_MIN - state.temperature > boundaryTolerance(state.temperature, C.R2_T_MIN))
|
|
87
|
+
return state;
|
|
88
|
+
return solveRegion3PTBasic(state.pressure, nextPositiveFloat(C.R2_T_MIN, 1));
|
|
89
|
+
}
|
|
90
|
+
function normalizeSaturationState(state, constraints, solverName) {
|
|
91
|
+
if ((state.region !== Region.Region1 && state.region !== Region.Region2) ||
|
|
92
|
+
state.pressure > saturationPressure(C.R2_T_MIN) ||
|
|
93
|
+
state.temperature < C.T_MIN || state.temperature > C.R2_T_MIN ||
|
|
94
|
+
detectRegionPT(state.pressure, state.temperature) === state.region) {
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
if (!constraints.some(({ label }) => label === 'pressure')) {
|
|
98
|
+
const psat = saturationPressure(state.temperature);
|
|
99
|
+
const pressure = state.region === Region.Region1 ? psat : nextPositiveFloat(psat, -1);
|
|
100
|
+
const projected = state.region === Region.Region1
|
|
101
|
+
? region1(pressure, state.temperature)
|
|
102
|
+
: region2(pressure, state.temperature);
|
|
103
|
+
if (Math.abs(pressure - state.pressure) <= backwardConstraintTolerance('pressure', psat) &&
|
|
104
|
+
backwardCandidateError(projected, constraints, { solverName }) === null)
|
|
105
|
+
return projected;
|
|
106
|
+
}
|
|
107
|
+
const [liquidT, vaporT] = nativeSaturationTemperatureBracket(state.pressure);
|
|
108
|
+
const temperature = state.region === Region.Region1 ? liquidT : vaporT;
|
|
109
|
+
if (Math.abs(temperature - state.temperature) > boundaryTolerance(temperature, state.temperature)) {
|
|
110
|
+
return state;
|
|
111
|
+
}
|
|
112
|
+
return state.region === Region.Region1
|
|
113
|
+
? region1(state.pressure, temperature)
|
|
114
|
+
: region2(state.pressure, temperature);
|
|
115
|
+
}
|
|
116
|
+
function basicEnvelopeError(state, solverName) {
|
|
21
117
|
if (!Number.isFinite(state.pressure) || !Number.isFinite(state.temperature) ||
|
|
22
|
-
!Number.isFinite(state.specificVolume)
|
|
23
|
-
|
|
118
|
+
!Number.isFinite(state.specificVolume)) {
|
|
119
|
+
return new NumericalStateError(`${solverName} produced an invalid thermodynamic state`);
|
|
24
120
|
}
|
|
121
|
+
if (state.specificVolume <= 0)
|
|
122
|
+
return new IF97Error(`${solverName} produced an invalid thermodynamic state`);
|
|
25
123
|
if (state.pressure < C.P_MIN || state.pressure > C.P_MAX ||
|
|
26
124
|
state.temperature < C.T_MIN || state.temperature > C.T_MAX) {
|
|
27
|
-
|
|
125
|
+
return new IF97Error(`${solverName} produced a state outside the IF97 PT envelope`);
|
|
28
126
|
}
|
|
127
|
+
if (state.region === Region.Region3) {
|
|
128
|
+
const stability = [state.cp, state.cv, state.isothermalCompressibility, state.speedOfSound];
|
|
129
|
+
if (!stability.every((value) => value !== null && Number.isFinite(value) && value > 0)) {
|
|
130
|
+
const ErrorType = stability.some((value) => value === null || !Number.isFinite(value))
|
|
131
|
+
? NumericalStateError : IF97Error;
|
|
132
|
+
return new ErrorType(`${solverName}: Region 3 numerical inconsistency: computed EOS state at p=${state.pressure} MPa, T=${state.temperature} K failed stability checks`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
29
136
|
}
|
|
30
|
-
function
|
|
137
|
+
function regionConsistencyError(state, solverName, expectedRegion) {
|
|
31
138
|
if (expectedRegion !== undefined && state.region !== expectedRegion) {
|
|
32
|
-
|
|
139
|
+
return new IF97Error(`${solverName} returned Region ${state.region}, expected Region ${expectedRegion}`);
|
|
33
140
|
}
|
|
34
141
|
if (state.region === Region.Region4) {
|
|
35
142
|
if (state.quality === null || !Number.isFinite(state.quality) || state.quality < 0 || state.quality > 1) {
|
|
36
|
-
|
|
143
|
+
return new IF97Error(`${solverName} produced an invalid Region 4 quality`);
|
|
37
144
|
}
|
|
38
145
|
const psat = saturationPressure(state.temperature);
|
|
39
146
|
const pTolerance = region4SaturationPressureTolerance(state.pressure);
|
|
40
147
|
if (Math.abs(psat - state.pressure) > pTolerance) {
|
|
41
|
-
|
|
148
|
+
return new IF97Error(`${solverName} produced a Region 4 state off the saturation curve`);
|
|
42
149
|
}
|
|
43
|
-
return;
|
|
150
|
+
return null;
|
|
44
151
|
}
|
|
45
152
|
const detectedRegion = detectRegionPT(state.pressure, state.temperature);
|
|
46
153
|
if (detectedRegion !== state.region) {
|
|
47
|
-
|
|
154
|
+
return new RegionMismatchError(solverName, detectedRegion, state.region);
|
|
48
155
|
}
|
|
156
|
+
return null;
|
|
49
157
|
}
|
|
50
|
-
function
|
|
158
|
+
function constraintError(state, constraints, solverName) {
|
|
51
159
|
for (const constraint of constraints) {
|
|
52
160
|
const actual = propertyValue(state, constraint.label);
|
|
53
161
|
const tolerance = constraint.tolerance ?? backwardConstraintTolerance(constraint.label, constraint.expected);
|
|
54
|
-
if (
|
|
55
|
-
|
|
162
|
+
if (!Number.isFinite(actual)) {
|
|
163
|
+
return new NumericalStateError(`${solverName} failed to match ${constraint.label}: expected ${constraint.expected}, got ${actual}`);
|
|
164
|
+
}
|
|
165
|
+
if (!Number.isFinite(constraint.expected) || !Number.isFinite(tolerance) ||
|
|
166
|
+
tolerance < 0 || Math.abs(actual - constraint.expected) > tolerance) {
|
|
167
|
+
return new IF97Error(`${solverName} failed to match ${constraint.label}: expected ${constraint.expected}, got ${actual}`);
|
|
56
168
|
}
|
|
57
169
|
}
|
|
170
|
+
return null;
|
|
58
171
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
172
|
+
/** Inspect a candidate without moving it across a formulation or domain boundary. */
|
|
173
|
+
export function backwardCandidateError(state, constraints, options) {
|
|
174
|
+
return basicEnvelopeError(state, options.solverName) ??
|
|
175
|
+
constraintError(state, constraints, options.solverName) ??
|
|
176
|
+
regionConsistencyError(state, options.solverName, options.expectedRegion);
|
|
177
|
+
}
|
|
178
|
+
export function normalizeBackwardState(state, constraints, solverName) {
|
|
179
|
+
const computed = normalizeComputedPT(state);
|
|
180
|
+
return constraints.some(({ label }) => label === 'temperature')
|
|
181
|
+
? computed
|
|
182
|
+
: normalizeSaturationState(normalizeB23State(normalizeRegion3LowerState(computed)), constraints, solverName);
|
|
183
|
+
}
|
|
184
|
+
export function validateBackwardState(state, constraints, options) {
|
|
185
|
+
const seam = options.seam;
|
|
186
|
+
if (seam !== undefined && state !== seam.state) {
|
|
187
|
+
throw new IF97Error(`${options.solverName} supplied an unrelated formulation seam state`);
|
|
76
188
|
}
|
|
189
|
+
const checkedConstraints = seam?.kind === 'gap'
|
|
190
|
+
? constraints.map((constraint) => constraint.label === 'enthalpy' || constraint.label === 'entropy'
|
|
191
|
+
? { ...constraint, tolerance: seam.budgets[constraint.label] }
|
|
192
|
+
: constraint)
|
|
193
|
+
: constraints;
|
|
194
|
+
const initialError = constraintError(state, checkedConstraints, options.solverName);
|
|
195
|
+
if (initialError !== null)
|
|
196
|
+
throw initialError;
|
|
197
|
+
const normalized = normalizeBackwardState(state, checkedConstraints, options.solverName);
|
|
198
|
+
const error = backwardCandidateError(normalized, checkedConstraints, options);
|
|
199
|
+
if (error !== null)
|
|
200
|
+
throw error;
|
|
77
201
|
return normalized;
|
|
78
202
|
}
|
|
79
|
-
export function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
203
|
+
export function validateRegion3PTReconstruction(state, solverName) {
|
|
204
|
+
return validateBackwardState(solveRegion3PTBasic(state.pressure, state.temperature), [
|
|
205
|
+
{ label: 'pressure', expected: state.pressure },
|
|
206
|
+
{ label: 'temperature', expected: state.temperature },
|
|
207
|
+
{ label: 'enthalpy', expected: state.enthalpy },
|
|
208
|
+
{ label: 'entropy', expected: state.entropy },
|
|
209
|
+
], { solverName, expectedRegion: Region.Region3 });
|
|
84
210
|
}
|
|
85
|
-
//# sourceMappingURL=solution-validation.js.map
|
package/dist/backward/th.d.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Backward equation T,H → state.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* and solves for pressure using a bracketed Newton method, then returns
|
|
6
|
-
* the full set of basic thermodynamic properties.
|
|
4
|
+
* Returns a state only when temperature and enthalpy determine it uniquely.
|
|
7
5
|
*/
|
|
8
6
|
import type { BasicProperties } from '../types.js';
|
|
9
7
|
/**
|
|
10
8
|
* Solve for full basic thermodynamic state from temperature and enthalpy.
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
* within the appropriate bracket for that region.
|
|
10
|
+
* Searches every valid isotherm branch and rejects ambiguous inputs.
|
|
14
11
|
*
|
|
15
12
|
* Temperatures within ±CRITICAL_T_EXCLUSION_BAND of Tc are rejected because
|
|
16
13
|
* the enthalpy surface is nearly flat there, making pressure recovery unreliable.
|
|
@@ -20,6 +17,6 @@ import type { BasicProperties } from '../types.js';
|
|
|
20
17
|
* @returns Basic thermodynamic properties (without transport)
|
|
21
18
|
* @throws {OutOfRangeError} if T is outside [T_MIN, T_MAX]
|
|
22
19
|
* @throws {IF97Error} if T is within the critical exclusion band
|
|
20
|
+
* @throws {AmbiguousStateError} if multiple physical states match T and h
|
|
23
21
|
*/
|
|
24
22
|
export declare function solveTH(T: number, h: number): BasicProperties;
|
|
25
|
-
//# sourceMappingURL=th.d.ts.map
|
package/dist/backward/th.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
import * as C from '../constants.js';
|
|
2
|
-
import { IF97Error, OutOfRangeError
|
|
3
|
-
import { assertFiniteNumber } from '../core/input-validation.js';
|
|
4
|
-
import {
|
|
5
|
-
import { solveRegion3PTBasic } from '../core/region3-pt.js';
|
|
6
|
-
import { region1 } from '../regions/region1.js';
|
|
7
|
-
import { region2 } from '../regions/region2.js';
|
|
8
|
-
import { region5 } from '../regions/region5.js';
|
|
9
|
-
import { boundary23_T_to_P } from '../regions/boundaries.js';
|
|
10
|
-
import { saturationPressure } from '../regions/region4.js';
|
|
11
|
-
import { mixSaturationState, qualityFromSaturationProperty, saturationEndpointsAtTemperature, } from '../saturation/common.js';
|
|
12
|
-
import { assertRegion4StateAllowed } from '../saturation/region4-boundaries.js';
|
|
13
|
-
import { solveFixedTemperaturePressure } from './fixed-temperature-solver.js';
|
|
14
|
-
import { validateBackwardState } from './solution-validation.js';
|
|
15
|
-
const extractH = (s) => s.enthalpy;
|
|
2
|
+
import { IF97Error, OutOfRangeError } from '../types.js';
|
|
3
|
+
import { assertFiniteNumber, withinClosedLowerBound } from '../core/input-validation.js';
|
|
4
|
+
import { uniqueFixedTemperatureState } from './fixed-temperature-candidates.js';
|
|
16
5
|
/**
|
|
17
6
|
* Solve for full basic thermodynamic state from temperature and enthalpy.
|
|
18
7
|
*
|
|
19
|
-
*
|
|
20
|
-
* within the appropriate bracket for that region.
|
|
8
|
+
* Searches every valid isotherm branch and rejects ambiguous inputs.
|
|
21
9
|
*
|
|
22
10
|
* Temperatures within ±CRITICAL_T_EXCLUSION_BAND of Tc are rejected because
|
|
23
11
|
* the enthalpy surface is nearly flat there, making pressure recovery unreliable.
|
|
@@ -27,6 +15,7 @@ const extractH = (s) => s.enthalpy;
|
|
|
27
15
|
* @returns Basic thermodynamic properties (without transport)
|
|
28
16
|
* @throws {OutOfRangeError} if T is outside [T_MIN, T_MAX]
|
|
29
17
|
* @throws {IF97Error} if T is within the critical exclusion band
|
|
18
|
+
* @throws {AmbiguousStateError} if multiple physical states match T and h
|
|
30
19
|
*/
|
|
31
20
|
export function solveTH(T, h) {
|
|
32
21
|
assertFiniteNumber('Temperature', T);
|
|
@@ -34,67 +23,15 @@ export function solveTH(T, h) {
|
|
|
34
23
|
if (T < C.T_MIN || T > C.T_MAX) {
|
|
35
24
|
throw new OutOfRangeError('Temperature', T, C.T_MIN, C.T_MAX);
|
|
36
25
|
}
|
|
37
|
-
if (h
|
|
26
|
+
if (!withinClosedLowerBound(h, C.H_MIN, 'enthalpy') || h > C.H_MAX) {
|
|
38
27
|
throw new OutOfRangeError('Enthalpy', h, C.H_MIN, C.H_MAX);
|
|
39
28
|
}
|
|
40
29
|
if (Math.abs(T - C.Tc) < C.CRITICAL_T_EXCLUSION_BAND) {
|
|
41
30
|
throw new IF97Error(`solveTH does not support temperatures within ${C.CRITICAL_T_EXCLUSION_BAND} K of the critical-point temperature Tc=${C.Tc} K; received T=${T} K`);
|
|
42
31
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return validateBackwardState(solveFixedTemperaturePressure(region1, T, h, saturationPressure(T), C.P_MAX, extractH, 'solveTH'), [
|
|
47
|
-
{ label: 'temperature', expected: T },
|
|
48
|
-
{ label: 'enthalpy', expected: h },
|
|
49
|
-
], {
|
|
50
|
-
solverName: 'solveTH',
|
|
51
|
-
expectedRegion: Region.Region1,
|
|
52
|
-
});
|
|
53
|
-
case Region.Region2: {
|
|
54
|
-
const upper = T <= C.Tc
|
|
55
|
-
? saturationPressure(T)
|
|
56
|
-
: T <= C.B23_T_MAX
|
|
57
|
-
? boundary23_T_to_P(T)
|
|
58
|
-
: C.P_MAX;
|
|
59
|
-
return validateBackwardState(solveFixedTemperaturePressure(region2, T, h, C.P_MIN, upper, extractH, 'solveTH'), [
|
|
60
|
-
{ label: 'temperature', expected: T },
|
|
61
|
-
{ label: 'enthalpy', expected: h },
|
|
62
|
-
], {
|
|
63
|
-
solverName: 'solveTH',
|
|
64
|
-
expectedRegion: Region.Region2,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
case Region.Region3: {
|
|
68
|
-
const lower = T <= C.Tc
|
|
69
|
-
? saturationPressure(T)
|
|
70
|
-
: boundary23_T_to_P(T);
|
|
71
|
-
return validateBackwardState(solveFixedTemperaturePressure(solveRegion3PTBasic, T, h, lower, C.P_MAX, extractH, 'solveTH'), [
|
|
72
|
-
{ label: 'temperature', expected: T },
|
|
73
|
-
{ label: 'enthalpy', expected: h },
|
|
74
|
-
], {
|
|
75
|
-
solverName: 'solveTH',
|
|
76
|
-
expectedRegion: Region.Region3,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
case Region.Region4: {
|
|
80
|
-
const endpoints = saturationEndpointsAtTemperature(T);
|
|
81
|
-
assertRegion4StateAllowed(endpoints.pressure, endpoints.temperature, 'solveTH');
|
|
82
|
-
const x = qualityFromSaturationProperty(endpoints.liquid.enthalpy, endpoints.vapor.enthalpy, h);
|
|
83
|
-
return validateBackwardState(mixSaturationState(endpoints, x), [
|
|
84
|
-
{ label: 'temperature', expected: T },
|
|
85
|
-
{ label: 'enthalpy', expected: h },
|
|
86
|
-
], { solverName: 'solveTH', expectedRegion: Region.Region4 });
|
|
87
|
-
}
|
|
88
|
-
case Region.Region5:
|
|
89
|
-
return validateBackwardState(solveFixedTemperaturePressure(region5, T, h, C.P_MIN, C.R5_P_MAX, extractH, 'solveTH'), [
|
|
90
|
-
{ label: 'temperature', expected: T },
|
|
91
|
-
{ label: 'enthalpy', expected: h },
|
|
92
|
-
], {
|
|
93
|
-
solverName: 'solveTH',
|
|
94
|
-
expectedRegion: Region.Region5,
|
|
95
|
-
});
|
|
96
|
-
default:
|
|
97
|
-
throw new IF97Error(`solveTH cannot determine a valid IF97 state for T=${T} K, h=${h} kJ/kg`);
|
|
32
|
+
const state = uniqueFixedTemperatureState(T, h, 'enthalpy');
|
|
33
|
+
if (state === null) {
|
|
34
|
+
throw new IF97Error(`solveTH cannot determine a valid IF97 state for T=${T} K, h=${h} kJ/kg`);
|
|
98
35
|
}
|
|
36
|
+
return state;
|
|
99
37
|
}
|
|
100
|
-
//# sourceMappingURL=th.js.map
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type BackwardToleranceLabel = 'pressure' | 'temperature' | 'enthalpy' | 'entropy';
|
|
2
2
|
export declare const BACKWARD_REGION4_QUALITY_TOLERANCE = 0.000001;
|
|
3
|
+
export declare const BACKWARD_HS_NEWTON_TOLERANCE = 1e-12;
|
|
4
|
+
export declare const BACKWARD_PRESSURE_PROPERTY_TEMPERATURE_TOLERANCE = 1e-13;
|
|
5
|
+
export declare function fixedTemperatureRootTolerance(property: 'enthalpy' | 'entropy'): number;
|
|
3
6
|
export declare function backwardConstraintTolerance(label: BackwardToleranceLabel, expected: number): number;
|
|
4
7
|
export declare function region4SaturationPressureTolerance(pressure: number): number;
|
|
5
8
|
export declare function backwardSpecificVolumeTolerance(expected: number): number;
|
|
6
|
-
//# sourceMappingURL=tolerances.d.ts.map
|