iapws-if97 2.1.5 → 2.2.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 +8 -0
- package/README.md +134 -94
- package/dist/backward/fixed-temperature-solver.d.ts +6 -6
- package/dist/backward/fixed-temperature-solver.js +34 -8
- package/dist/backward/hs.d.ts +1 -2
- package/dist/backward/hs.js +66 -56
- package/dist/backward/ph.d.ts +8 -5
- package/dist/backward/ph.js +43 -46
- package/dist/backward/ps.d.ts +0 -1
- package/dist/backward/ps.js +30 -18
- package/dist/backward/solution-validation.d.ts +0 -1
- package/dist/backward/solution-validation.js +33 -5
- package/dist/backward/th.d.ts +0 -1
- package/dist/backward/th.js +4 -6
- package/dist/backward/thermodynamic-derivatives.d.ts +17 -0
- package/dist/backward/thermodynamic-derivatives.js +27 -0
- package/dist/backward/tolerances.d.ts +0 -1
- package/dist/backward/tolerances.js +0 -1
- package/dist/backward/ts.d.ts +0 -1
- package/dist/backward/ts.js +4 -6
- package/dist/boundaries.d.ts +0 -1
- package/dist/boundaries.js +0 -1
- package/dist/constants.d.ts +0 -9
- package/dist/constants.js +3 -13
- package/dist/core/input-validation.d.ts +0 -1
- package/dist/core/input-validation.js +0 -1
- package/dist/core/public-normalization.d.ts +0 -1
- package/dist/core/public-normalization.js +0 -1
- package/dist/core/region-detector.d.ts +0 -1
- package/dist/core/region-detector.js +232 -65
- package/dist/core/region3-pt.d.ts +12 -1
- package/dist/core/region3-pt.js +38 -9
- package/dist/core/solve-input-normalization.d.ts +0 -1
- package/dist/core/solve-input-normalization.js +0 -1
- package/dist/core/solver.d.ts +0 -1
- package/dist/core/solver.js +0 -1
- package/dist/detect.d.ts +0 -1
- package/dist/detect.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/regions/boundaries.d.ts +0 -1
- package/dist/regions/boundaries.js +0 -1
- package/dist/regions/region1.d.ts +0 -1
- package/dist/regions/region1.js +0 -1
- package/dist/regions/region2.d.ts +0 -1
- package/dist/regions/region2.js +0 -1
- package/dist/regions/region3-data.d.ts +0 -1
- package/dist/regions/region3-data.js +0 -1
- 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 +0 -1
- package/dist/regions/region3.d.ts +0 -1
- package/dist/regions/region3.js +0 -1
- package/dist/regions/region4.d.ts +0 -1
- package/dist/regions/region4.js +0 -1
- package/dist/regions/region5.d.ts +0 -1
- package/dist/regions/region5.js +0 -1
- package/dist/regions.d.ts +0 -1
- package/dist/regions.js +0 -1
- package/dist/saturation/common.d.ts +0 -1
- package/dist/saturation/common.js +6 -13
- package/dist/saturation/region4-boundaries.d.ts +0 -5
- package/dist/saturation/region4-boundaries.js +4 -5
- package/dist/saturation/region4-hs.d.ts +2 -1
- package/dist/saturation/region4-hs.js +277 -108
- package/dist/saturation/two-phase.d.ts +0 -1
- package/dist/saturation/two-phase.js +0 -1
- package/dist/saturation.d.ts +0 -1
- package/dist/saturation.js +0 -1
- package/dist/solvers/bracketed-newton.d.ts +5 -4
- package/dist/solvers/bracketed-newton.js +5 -6
- package/dist/solvers/damped-newton-2d.d.ts +12 -0
- package/dist/solvers/damped-newton-2d.js +68 -0
- package/dist/solvers/newton-raphson.d.ts +0 -1
- package/dist/solvers/newton-raphson.js +0 -1
- package/dist/transport/properties.d.ts +0 -1
- package/dist/transport/properties.js +0 -1
- package/dist/transport.d.ts +0 -1
- package/dist/transport.js +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/package.json +17 -9
- package/dist/backward/objective-normalization.d.ts +0 -7
- package/dist/backward/objective-normalization.js +0 -8
- package/dist/solvers/nelder-mead.d.ts +0 -17
- package/dist/solvers/nelder-mead.js +0 -116
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Damped Newton solver for two coupled nonlinear equations. */
|
|
2
|
+
import { ConvergenceError, IF97Error } from '../types.js';
|
|
3
|
+
function maxNorm([a, b]) {
|
|
4
|
+
return Math.max(Math.abs(a), Math.abs(b));
|
|
5
|
+
}
|
|
6
|
+
function isFiniteEvaluation(value) {
|
|
7
|
+
return value.residual.every(Number.isFinite) &&
|
|
8
|
+
value.jacobian.every((row) => row.every(Number.isFinite));
|
|
9
|
+
}
|
|
10
|
+
export function dampedNewton2D(evaluate, initial, options) {
|
|
11
|
+
const tolerance = options?.tolerance ?? 1e-10;
|
|
12
|
+
const maxIterations = options?.maxIterations ?? 20;
|
|
13
|
+
const maxBacktracks = options?.maxBacktracks ?? 20;
|
|
14
|
+
const isValid = (point) => point.every(Number.isFinite) && (options?.isValid?.(point) ?? true);
|
|
15
|
+
const tryEvaluate = (point) => {
|
|
16
|
+
if (!isValid(point))
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
const value = evaluate(point);
|
|
20
|
+
return isFiniteEvaluation(value) ? value : null;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof IF97Error)
|
|
24
|
+
return null;
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
let point = [...initial];
|
|
29
|
+
let value = tryEvaluate(point);
|
|
30
|
+
if (value === null)
|
|
31
|
+
throw new ConvergenceError('dampedNewton2D', 1);
|
|
32
|
+
for (let iteration = 0; iteration < maxIterations; iteration += 1) {
|
|
33
|
+
const norm = maxNorm(value.residual);
|
|
34
|
+
if (norm <= tolerance)
|
|
35
|
+
return point;
|
|
36
|
+
const [[a, b], [c, d]] = value.jacobian;
|
|
37
|
+
const determinant = a * d - b * c;
|
|
38
|
+
const determinantScale = Math.abs(a * d) + Math.abs(b * c);
|
|
39
|
+
if (!Number.isFinite(determinant) || determinantScale === 0 ||
|
|
40
|
+
Math.abs(determinant) <= Number.EPSILON * determinantScale) {
|
|
41
|
+
throw new ConvergenceError('dampedNewton2D', iteration + 1);
|
|
42
|
+
}
|
|
43
|
+
const [r1, r2] = value.residual;
|
|
44
|
+
const step = [
|
|
45
|
+
(d * r1 - b * r2) / determinant,
|
|
46
|
+
(a * r2 - c * r1) / determinant,
|
|
47
|
+
];
|
|
48
|
+
let damping = 1;
|
|
49
|
+
let accepted = false;
|
|
50
|
+
for (let backtrack = 0; backtrack <= maxBacktracks; backtrack += 1) {
|
|
51
|
+
const candidate = [
|
|
52
|
+
point[0] - damping * step[0],
|
|
53
|
+
point[1] - damping * step[1],
|
|
54
|
+
];
|
|
55
|
+
const candidateValue = tryEvaluate(candidate);
|
|
56
|
+
if (candidateValue !== null && maxNorm(candidateValue.residual) < norm) {
|
|
57
|
+
point = candidate;
|
|
58
|
+
value = candidateValue;
|
|
59
|
+
accepted = true;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
damping /= 2;
|
|
63
|
+
}
|
|
64
|
+
if (!accepted)
|
|
65
|
+
throw new ConvergenceError('dampedNewton2D', iteration + 1);
|
|
66
|
+
}
|
|
67
|
+
throw new ConvergenceError('dampedNewton2D', maxIterations);
|
|
68
|
+
}
|
|
@@ -19,4 +19,3 @@ export interface NewtonRaphsonOptions {
|
|
|
19
19
|
* @throws {ConvergenceError} if the iteration diverges or does not converge
|
|
20
20
|
*/
|
|
21
21
|
export declare function newtonRaphson(f: (x: number) => number, x0: number, fp?: ((x: number) => number) | null, options?: NewtonRaphsonOptions): number;
|
|
22
|
-
//# sourceMappingURL=newton-raphson.d.ts.map
|
package/dist/transport.d.ts
CHANGED
package/dist/transport.js
CHANGED
package/dist/types.d.ts
CHANGED
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iapws-if97",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "TypeScript implementation of IAPWS-IF97 for water and steam properties, including forward/backward solvers, saturation states, and transport properties.",
|
|
5
5
|
"author": "jltonghui",
|
|
6
6
|
"repository": {
|
|
@@ -16,28 +16,34 @@
|
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
19
20
|
"import": "./dist/index.js",
|
|
20
|
-
"
|
|
21
|
+
"default": "./dist/index.js"
|
|
21
22
|
},
|
|
22
23
|
"./transport": {
|
|
24
|
+
"types": "./dist/transport.d.ts",
|
|
23
25
|
"import": "./dist/transport.js",
|
|
24
|
-
"
|
|
26
|
+
"default": "./dist/transport.js"
|
|
25
27
|
},
|
|
26
28
|
"./regions": {
|
|
29
|
+
"types": "./dist/regions.d.ts",
|
|
27
30
|
"import": "./dist/regions.js",
|
|
28
|
-
"
|
|
31
|
+
"default": "./dist/regions.js"
|
|
29
32
|
},
|
|
30
33
|
"./saturation": {
|
|
34
|
+
"types": "./dist/saturation.d.ts",
|
|
31
35
|
"import": "./dist/saturation.js",
|
|
32
|
-
"
|
|
36
|
+
"default": "./dist/saturation.js"
|
|
33
37
|
},
|
|
34
38
|
"./boundaries": {
|
|
39
|
+
"types": "./dist/boundaries.d.ts",
|
|
35
40
|
"import": "./dist/boundaries.js",
|
|
36
|
-
"
|
|
41
|
+
"default": "./dist/boundaries.js"
|
|
37
42
|
},
|
|
38
43
|
"./detect": {
|
|
44
|
+
"types": "./dist/detect.d.ts",
|
|
39
45
|
"import": "./dist/detect.js",
|
|
40
|
-
"
|
|
46
|
+
"default": "./dist/detect.js"
|
|
41
47
|
},
|
|
42
48
|
"./package.json": "./package.json"
|
|
43
49
|
},
|
|
@@ -49,21 +55,23 @@
|
|
|
49
55
|
"README.md"
|
|
50
56
|
],
|
|
51
57
|
"engines": {
|
|
52
|
-
"node": ">=
|
|
58
|
+
"node": ">=20.19.0"
|
|
53
59
|
},
|
|
54
60
|
"publishConfig": {
|
|
55
61
|
"access": "public"
|
|
56
62
|
},
|
|
57
63
|
"sideEffects": false,
|
|
58
64
|
"scripts": {
|
|
65
|
+
"prebuild": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
59
66
|
"build": "tsc",
|
|
60
67
|
"test": "vitest run",
|
|
68
|
+
"test:package": "npm run build && node scripts/check-package.mjs",
|
|
61
69
|
"test:watch": "vitest",
|
|
62
70
|
"test:coverage": "vitest run --coverage",
|
|
63
71
|
"test:standards": "vitest run tests/standards-asme tests/standards-cn",
|
|
64
72
|
"test:standards:asme": "vitest run tests/standards-asme",
|
|
65
73
|
"test:standards:cn": "vitest run tests/standards-cn",
|
|
66
|
-
"prepack": "npm run
|
|
74
|
+
"prepack": "npm run test:package && npm test",
|
|
67
75
|
"prepublishOnly": "npm run build && npm test"
|
|
68
76
|
},
|
|
69
77
|
"devDependencies": {
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface NelderMeadOptions {
|
|
2
|
-
maxIterations?: number;
|
|
3
|
-
nonZeroDelta?: number;
|
|
4
|
-
zeroDelta?: number;
|
|
5
|
-
minErrorDelta?: number;
|
|
6
|
-
minTolerance?: number;
|
|
7
|
-
rho?: number;
|
|
8
|
-
chi?: number;
|
|
9
|
-
psi?: number;
|
|
10
|
-
sigma?: number;
|
|
11
|
-
}
|
|
12
|
-
export interface NelderMeadResult {
|
|
13
|
-
x: number[];
|
|
14
|
-
fx: number;
|
|
15
|
-
}
|
|
16
|
-
export declare function nelderMead(f: (x: number[]) => number, x0: number[], opts?: NelderMeadOptions): NelderMeadResult;
|
|
17
|
-
//# sourceMappingURL=nelder-mead.d.ts.map
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nelder-Mead (downhill simplex) minimizer.
|
|
3
|
-
* Minimizes f(x) where x is an array of numbers.
|
|
4
|
-
*/
|
|
5
|
-
import { ConvergenceError } from '../types.js';
|
|
6
|
-
export function nelderMead(f, x0, opts) {
|
|
7
|
-
const maxIter = opts?.maxIterations ?? x0.length * 200;
|
|
8
|
-
const nonZeroDelta = opts?.nonZeroDelta ?? 1.05;
|
|
9
|
-
const zeroDelta = opts?.zeroDelta ?? 0.001;
|
|
10
|
-
const minErrDelta = opts?.minErrorDelta ?? 1e-11;
|
|
11
|
-
const minTol = opts?.minTolerance ?? 1e-11;
|
|
12
|
-
const rho = opts?.rho ?? 1;
|
|
13
|
-
const chi = opts?.chi ?? 2;
|
|
14
|
-
const psi = opts?.psi ?? -0.5;
|
|
15
|
-
const sigma = opts?.sigma ?? 0.5;
|
|
16
|
-
const N = x0.length;
|
|
17
|
-
let converged = false;
|
|
18
|
-
function evaluate(point, iteration) {
|
|
19
|
-
const value = f(point);
|
|
20
|
-
if (!Number.isFinite(value)) {
|
|
21
|
-
throw new ConvergenceError('nelderMead', iteration);
|
|
22
|
-
}
|
|
23
|
-
return value;
|
|
24
|
-
}
|
|
25
|
-
const simplex = new Array(N + 1);
|
|
26
|
-
// Initialize simplex
|
|
27
|
-
const v0 = [...x0];
|
|
28
|
-
v0.fx = evaluate(x0, 1);
|
|
29
|
-
simplex[0] = v0;
|
|
30
|
-
for (let i = 0; i < N; i++) {
|
|
31
|
-
const pt = [...x0];
|
|
32
|
-
pt[i] = pt[i] ? pt[i] * nonZeroDelta : zeroDelta;
|
|
33
|
-
pt.fx = evaluate(pt, 1);
|
|
34
|
-
simplex[i + 1] = pt;
|
|
35
|
-
}
|
|
36
|
-
const sortOrder = (a, b) => a.fx - b.fx;
|
|
37
|
-
function weightedSum(ret, w1, v1, w2, v2) {
|
|
38
|
-
for (let j = 0; j < ret.length; j++) {
|
|
39
|
-
ret[j] = w1 * v1[j] + w2 * v2[j];
|
|
40
|
-
}
|
|
41
|
-
return ret;
|
|
42
|
-
}
|
|
43
|
-
const centroid = [...x0];
|
|
44
|
-
const reflected = [...x0];
|
|
45
|
-
const contracted = [...x0];
|
|
46
|
-
const expanded = [...x0];
|
|
47
|
-
function updateSimplex(value) {
|
|
48
|
-
for (let i = 0; i < N; i++)
|
|
49
|
-
simplex[N][i] = value[i];
|
|
50
|
-
simplex[N].fx = value.fx;
|
|
51
|
-
}
|
|
52
|
-
for (let iter = 0; iter < maxIter; iter++) {
|
|
53
|
-
simplex.sort(sortOrder);
|
|
54
|
-
let maxDiff = 0;
|
|
55
|
-
for (let i = 1; i < simplex.length; i++) {
|
|
56
|
-
for (let j = 0; j < N; j++) {
|
|
57
|
-
maxDiff = Math.max(maxDiff, Math.abs(simplex[0][j] - simplex[i][j]));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (Math.abs(simplex[0].fx - simplex[N].fx) < minErrDelta && maxDiff < minTol) {
|
|
61
|
-
converged = true;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
for (let i = 0; i < N; i++) {
|
|
65
|
-
centroid[i] = 0;
|
|
66
|
-
for (let j = 0; j < N; j++)
|
|
67
|
-
centroid[i] += simplex[j][i];
|
|
68
|
-
centroid[i] /= N;
|
|
69
|
-
}
|
|
70
|
-
const worst = simplex[N];
|
|
71
|
-
weightedSum(reflected, 1 + rho, centroid, -rho, worst);
|
|
72
|
-
reflected.fx = evaluate(reflected, iter + 1);
|
|
73
|
-
if (reflected.fx < simplex[0].fx) {
|
|
74
|
-
weightedSum(expanded, 1 + chi, centroid, -chi, worst);
|
|
75
|
-
expanded.fx = evaluate(expanded, iter + 1);
|
|
76
|
-
updateSimplex(expanded.fx < reflected.fx ? expanded : reflected);
|
|
77
|
-
}
|
|
78
|
-
else if (reflected.fx >= simplex[N - 1].fx) {
|
|
79
|
-
let shouldReduce = false;
|
|
80
|
-
if (reflected.fx > worst.fx) {
|
|
81
|
-
weightedSum(contracted, 1 + psi, centroid, -psi, worst);
|
|
82
|
-
contracted.fx = evaluate(contracted, iter + 1);
|
|
83
|
-
if (contracted.fx < worst.fx)
|
|
84
|
-
updateSimplex(contracted);
|
|
85
|
-
else
|
|
86
|
-
shouldReduce = true;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
weightedSum(contracted, 1 - psi * rho, centroid, psi * rho, worst);
|
|
90
|
-
contracted.fx = evaluate(contracted, iter + 1);
|
|
91
|
-
if (contracted.fx < reflected.fx)
|
|
92
|
-
updateSimplex(contracted);
|
|
93
|
-
else
|
|
94
|
-
shouldReduce = true;
|
|
95
|
-
}
|
|
96
|
-
if (shouldReduce) {
|
|
97
|
-
if (sigma >= 1) {
|
|
98
|
-
throw new ConvergenceError('nelderMead', iter + 1);
|
|
99
|
-
}
|
|
100
|
-
for (let i = 1; i < simplex.length; i++) {
|
|
101
|
-
weightedSum(simplex[i], 1 - sigma, simplex[0], sigma, simplex[i]);
|
|
102
|
-
simplex[i].fx = evaluate(simplex[i], iter + 1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
updateSimplex(reflected);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!converged) {
|
|
111
|
-
throw new ConvergenceError('nelderMead', maxIter);
|
|
112
|
-
}
|
|
113
|
-
simplex.sort(sortOrder);
|
|
114
|
-
return { fx: simplex[0].fx, x: simplex[0].slice(0, N) };
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=nelder-mead.js.map
|