driftlet 0.9.0 → 0.11.4
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/README.md +47 -37
- package/docs/device.md +142 -96
- package/docs/kit.md +5 -0
- package/docs/numerics.md +197 -26
- package/docs/reliability.md +122 -0
- package/llms.txt +111 -7
- package/package.json +3 -1
- package/src/blockTridiagonal.js +17 -4
- package/src/checks.js +44 -33
- package/src/describe.js +15 -9
- package/src/device.js +16 -5
- package/src/difference.js +142 -0
- package/src/index.js +39 -10
- package/src/polarization.js +51 -16
- package/src/solution.js +29 -11
- package/src/solver.js +1115 -165
- package/src/types.js +4 -0
- package/types/blockTridiagonal.d.ts +9 -1
- package/types/checks.d.ts +3 -3
- package/types/difference.d.ts +30 -0
- package/types/index.d.ts +3 -1
- package/types/live.d.ts +1 -0
- package/types/polarization.d.ts +8 -2
- package/types/solver.d.ts +65 -12
- package/types/types.d.ts +6 -0
package/src/types.js
CHANGED
|
@@ -197,6 +197,10 @@
|
|
|
197
197
|
*/
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
|
+
* The device's totals through its cross-section (currents, fluxes through contacts and ports,
|
|
201
|
+
* charges, amounts, reaction totals, impedance) are per m² of a planar device, as below, and
|
|
202
|
+
* whole (A, mol/s, C, mol, Ω; per metre of a cylinder) for one with a `geometry`. Rates at a
|
|
203
|
+
* face or an electrode are always per m² of it.
|
|
200
204
|
* @typedef {object} Solution
|
|
201
205
|
* @property {Float64Array} x node positions, m (interface positions appear twice)
|
|
202
206
|
* @property {Int32Array} region region index per node
|
|
@@ -31,11 +31,19 @@ export class BlockTridiagonal {
|
|
|
31
31
|
minPivotRatio: number;
|
|
32
32
|
/** The block found exactly singular by the last factor(), or −1. */
|
|
33
33
|
singularBlock: number;
|
|
34
|
+
/**
|
|
35
|
+
* Static pivoting: an exactly zero pivot (all its candidates cancelled to nothing) is
|
|
36
|
+
* replaced by 1e-15 of its block's largest entry rather than thrown on, for a caller that
|
|
37
|
+
* refines its solves (and counted in `perturbedPivots`).
|
|
38
|
+
*/
|
|
39
|
+
staticPivots: boolean;
|
|
40
|
+
/** How many pivots the last factor() replaced. */
|
|
41
|
+
perturbedPivots: number;
|
|
34
42
|
/** Zero all of A, B, C (ready for fresh assembly). */
|
|
35
43
|
clear(): void;
|
|
36
44
|
/**
|
|
37
45
|
* Factorise the current A, B, C. A, B, C are left untouched.
|
|
38
|
-
* Throws if a diagonal block is exactly singular.
|
|
46
|
+
* Throws if a diagonal block is exactly singular (unless `staticPivots`).
|
|
39
47
|
*/
|
|
40
48
|
factor(): void;
|
|
41
49
|
/**
|
package/types/checks.d.ts
CHANGED
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
* - **warnings**: the solution's warnings (unresolved double layers, steep profiles, weakly held
|
|
14
14
|
* parts) and the definition's likely unit slips.
|
|
15
15
|
* - **balance** (a steady state): each species' ledger, what comes in through each terminal and
|
|
16
|
-
* what each reaction (bulk or at a face) makes or uses, in mol/(m²·s)
|
|
17
|
-
* species, as a current F·|z|·rate. The terms must sum to
|
|
18
|
-
* and it says where every carrier went.
|
|
16
|
+
* what each reaction (bulk or at a face) makes or uses, in mol/(m²·s) (mol/s if the device
|
|
17
|
+
* isn't planar) and, for a charged species, as a current F·|z|·rate. The terms must sum to
|
|
18
|
+
* zero; under light it's J = F(G − R), and it says where every carrier went.
|
|
19
19
|
* - **conservation** (a transient): every closed, unreacting stretch keeps what it held plus
|
|
20
20
|
* what came in.
|
|
21
21
|
* - **grid** (a steady state, with `refine`, the default): the device solved again on a grid
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class DifferenceTerms {
|
|
2
|
+
constructor(N: any, nodes: any, segments: any);
|
|
3
|
+
N: any;
|
|
4
|
+
dead: Uint8Array<any>;
|
|
5
|
+
nI: Int32Array<any>;
|
|
6
|
+
nP: Int32Array<any>;
|
|
7
|
+
nZ: Float64Array<any>;
|
|
8
|
+
nMass: Float64Array<any>;
|
|
9
|
+
nCharge: Float64Array<any>;
|
|
10
|
+
sI: Int32Array<ArrayBuffer>;
|
|
11
|
+
sZ: Float64Array<any>;
|
|
12
|
+
sC: Float64Array<ArrayBuffer>;
|
|
13
|
+
dI: Int32Array<ArrayBuffer>;
|
|
14
|
+
dK: Float64Array<any>;
|
|
15
|
+
combos: any[];
|
|
16
|
+
t: Float64Array<any>;
|
|
17
|
+
x: Float64Array<any>;
|
|
18
|
+
reset(rate?: number): void;
|
|
19
|
+
rate: number;
|
|
20
|
+
nn: number;
|
|
21
|
+
ns: number;
|
|
22
|
+
nd: number;
|
|
23
|
+
node(i: any, p: any, z: any, mass: any, charge: any): void;
|
|
24
|
+
segment(iL: any, iR: any, pL: any, pR: any, z: any, a: any, b: any, d: any): void;
|
|
25
|
+
displacement(pL: any, pR: any, k: any): void;
|
|
26
|
+
kill(row: any): void;
|
|
27
|
+
combine(rk: any, ri: any, w: any): void;
|
|
28
|
+
capture(row: any, w: any, mass: any, into: any): void;
|
|
29
|
+
apply(v: any, out: any, steady?: number, mass?: number): any;
|
|
30
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -14,7 +14,8 @@ export class Device {
|
|
|
14
14
|
get grid(): any;
|
|
15
15
|
/**
|
|
16
16
|
* Change part of the definition (deep-merged). A contact given V or I drops the other, so
|
|
17
|
-
* `{ contacts: { right: { I: 0 } } }` switches it to open circuit.
|
|
17
|
+
* `{ contacts: { right: { I: 0 } } }` switches it to open circuit. Ports are patched by name,
|
|
18
|
+
* `{ ports: { gate: { V: 0.2 } } }` (an array replaces them all). A change to the terminals'
|
|
18
19
|
* drives alone (V, I, R) is applied in place, cheaply. Otherwise the device is rebuilt, keeping the current state as
|
|
19
20
|
* the warm start when the grid and species are unchanged (else restarting from the regions' c0).
|
|
20
21
|
* @param {object} patch a partial device definition, merged into the current one
|
|
@@ -93,6 +94,7 @@ export class Device {
|
|
|
93
94
|
snap: any;
|
|
94
95
|
solvedV: any;
|
|
95
96
|
referenceAmounts: any;
|
|
97
|
+
surfaceRef: any;
|
|
96
98
|
};
|
|
97
99
|
/**
|
|
98
100
|
* Back to a checkpoint taken on this device.
|
package/types/live.d.ts
CHANGED
package/types/polarization.d.ts
CHANGED
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* @param {{ face: number } | { port: string | number, x?: number }} where a face's index, or a port
|
|
10
10
|
* (name or index) and the position in its window (m, the device's x; default its first node)
|
|
11
11
|
* @param {number | ArrayLike<number>} V the metal's level(s), V
|
|
12
|
-
* @
|
|
12
|
+
* @param {{ surface?: 'held' | 'equilibrium' }} [opts] an electrode port's surface coverages: held as
|
|
13
|
+
* in `sol` (the default: this instant's curves), or in equilibrium at each V (the steady-state
|
|
14
|
+
* curve, with a passive film's active–passive peak), each species by the reaction that makes it
|
|
15
|
+
* @returns {{ V: Float64Array, current: Float64Array, bare?: Float64Array, reactions: { equation: string, level: number,
|
|
13
16
|
* rate: Float64Array, current: Float64Array }[] }} per reaction: its equilibrium level here (where
|
|
14
17
|
* its rate is zero), its rate (mol/(m²·s) of electrode, forward) and its current (A/m², anodic
|
|
15
18
|
* positive: into the solution); and their sum
|
|
@@ -19,9 +22,12 @@ export function polarization(device: import("./index.js").Device, sol: object, w
|
|
|
19
22
|
} | {
|
|
20
23
|
port: string | number;
|
|
21
24
|
x?: number;
|
|
22
|
-
}, V: number | ArrayLike<number
|
|
25
|
+
}, V: number | ArrayLike<number>, opts?: {
|
|
26
|
+
surface?: "held" | "equilibrium";
|
|
27
|
+
}): {
|
|
23
28
|
V: Float64Array;
|
|
24
29
|
current: Float64Array;
|
|
30
|
+
bare?: Float64Array;
|
|
25
31
|
reactions: {
|
|
26
32
|
equation: string;
|
|
27
33
|
level: number;
|
package/types/solver.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export class Solver {
|
|
|
17
17
|
blockOfFace: Int32Array<ArrayBuffer>;
|
|
18
18
|
surfPort: Int32Array<any>;
|
|
19
19
|
surfW: Int32Array<any>;
|
|
20
|
+
surfCols: any;
|
|
21
|
+
surfColOf: any;
|
|
20
22
|
th: Float64Array<ArrayBuffer>;
|
|
21
23
|
thOld: Float64Array<ArrayBuffer>;
|
|
22
24
|
th0: Float64Array<any>;
|
|
@@ -52,6 +54,7 @@ export class Solver {
|
|
|
52
54
|
time: number;
|
|
53
55
|
lastDt: number;
|
|
54
56
|
atSteady: boolean;
|
|
57
|
+
lin: DifferenceTerms;
|
|
55
58
|
contactFlux: {
|
|
56
59
|
left: Float64Array<any>;
|
|
57
60
|
right: Float64Array<any>;
|
|
@@ -65,6 +68,9 @@ export class Solver {
|
|
|
65
68
|
portQStart: Float64Array<any>;
|
|
66
69
|
portQOld: Float64Array<any>;
|
|
67
70
|
portQEnd: any;
|
|
71
|
+
qg: Float64Array<any>;
|
|
72
|
+
qgSlope: Float64Array<any>;
|
|
73
|
+
qgTerms: any[][];
|
|
68
74
|
contactDOld: {
|
|
69
75
|
left: number;
|
|
70
76
|
right: number;
|
|
@@ -90,43 +96,63 @@ export class Solver {
|
|
|
90
96
|
rxs: any;
|
|
91
97
|
portArea: any;
|
|
92
98
|
portRates: any;
|
|
93
|
-
strictlyNeutral: any;
|
|
94
99
|
generationScale: number;
|
|
95
100
|
hasGeneration: any;
|
|
96
101
|
rxsIn: any;
|
|
102
|
+
closedEnd: {
|
|
103
|
+
left: any;
|
|
104
|
+
right: any;
|
|
105
|
+
};
|
|
97
106
|
chargeNode: Uint8Array<any>;
|
|
98
107
|
chargeNodes: Int32Array<ArrayBuffer>;
|
|
108
|
+
lateStorage: Uint8Array<any>;
|
|
99
109
|
combining: boolean;
|
|
100
110
|
bookkeeping: any;
|
|
101
111
|
bookkeepingFaces: number[];
|
|
102
112
|
referenceAmounts: number[];
|
|
113
|
+
surfaceRef: Float64Array<ArrayBuffer>;
|
|
103
114
|
boundaryIntake: Float64Array<ArrayBuffer>;
|
|
104
115
|
_activeSlots(): void;
|
|
105
116
|
active: Uint8Array<ArrayBuffer>;
|
|
106
117
|
loc: Int32Array<ArrayBuffer>;
|
|
107
|
-
sys:
|
|
118
|
+
sys: any;
|
|
108
119
|
SINK: number;
|
|
109
120
|
rix: Int32Array<ArrayBuffer>;
|
|
110
121
|
fullOf: Int32Array<ArrayBuffer>;
|
|
111
122
|
res: Float64Array<ArrayBuffer>;
|
|
112
123
|
delta: Float64Array<ArrayBuffer>;
|
|
124
|
+
rowScale: Float64Array<ArrayBuffer>;
|
|
113
125
|
_factor(): void;
|
|
114
126
|
_solveLinear(rhs: any, delta: any): void;
|
|
115
127
|
_findStretches(): void;
|
|
116
128
|
stretches: any[];
|
|
117
129
|
stretchOf: Int32Array<ArrayBuffer>;
|
|
118
|
-
moieties: Float64Array<
|
|
130
|
+
moieties: Float64Array<any>[];
|
|
131
|
+
flatStretches: any[];
|
|
132
|
+
levelStretches: any[];
|
|
133
|
+
flattening: boolean;
|
|
119
134
|
constraints: any[];
|
|
120
135
|
localConstraints: any[];
|
|
136
|
+
islands: any[];
|
|
137
|
+
pinnedIslands: any[];
|
|
138
|
+
islandsOn: boolean;
|
|
139
|
+
pins: any[];
|
|
121
140
|
constrained: boolean;
|
|
122
141
|
_captureLocal(): void;
|
|
142
|
+
_applyIslands(): any[];
|
|
143
|
+
islandRow: Float64Array<any>;
|
|
144
|
+
_rowInto(o: any, add: any): void;
|
|
145
|
+
linRow: Float64Array<any>;
|
|
123
146
|
_applyLocalConstraints(): void;
|
|
124
|
-
_conservedMoieties(): Float64Array<
|
|
147
|
+
_conservedMoieties(): Float64Array<any>[];
|
|
125
148
|
_directSteady(): boolean;
|
|
126
149
|
_applyConstraints(): void;
|
|
127
150
|
_solveBordered(rhs: any, delta: any, deltaV: any, pins: any): void;
|
|
128
|
-
dWork: Float64Array<
|
|
151
|
+
dWork: Float64Array<any>;
|
|
129
152
|
borderCols: any[];
|
|
153
|
+
_surfaceStart(g: any): void;
|
|
154
|
+
/** Amount (mol per unit area) of surface column j's species, Γ Σ v·a·θ, in the current state. */
|
|
155
|
+
surfaceAmount(j: any): number;
|
|
130
156
|
/** Total amount (mol per unit area) of a stretch's species in the current state. */
|
|
131
157
|
amount(stretch: any): number;
|
|
132
158
|
redrive(): void;
|
|
@@ -155,7 +181,7 @@ export class Solver {
|
|
|
155
181
|
_j(rb: any, rs: any, cb: any, cs: any, v: any): void;
|
|
156
182
|
/** Assemble residual and Jacobian for a backward-Euler step of size dt. */
|
|
157
183
|
assemble(dt: any): void;
|
|
158
|
-
transformed:
|
|
184
|
+
transformed: any;
|
|
159
185
|
_nodeConductor(g: any, dt: any): void;
|
|
160
186
|
_nodesDilute(g0: any, g1: any, dt: any): void;
|
|
161
187
|
_nodeConcentrated(g: any, dt: any): void;
|
|
@@ -183,31 +209,42 @@ export class Solver {
|
|
|
183
209
|
_faceReaction(rx: any, k: any, f: any, bf: any, bL: any, bR: any, Af: any): void;
|
|
184
210
|
_terminals(dt: any): void;
|
|
185
211
|
_circuit(k: any): void;
|
|
186
|
-
_captureRow(b: any, s: any, w: any, into: any):
|
|
187
|
-
_port(port: any, flux: any, k: any, dt: any): void;
|
|
212
|
+
_captureRow(b: any, s: any, w: any, into: any): any;
|
|
213
|
+
_port(port: any, flux: any, k: any, dt: any, holds: any): void;
|
|
188
214
|
_portReaction(port: any, rx: any, area: any, rates: any, flux: any, k: any): void;
|
|
189
215
|
_portCapacitance(port: any, k: any, dt: any): void;
|
|
190
216
|
_surfaceStorage(port: any, dt: any): void;
|
|
191
217
|
_contact(side: any, dt: any): void;
|
|
218
|
+
_flatRows(): void;
|
|
219
|
+
_levelRows(): void;
|
|
192
220
|
_replaceRow(b: any, rs: any): void;
|
|
193
221
|
_equilibrate(): void;
|
|
222
|
+
_assembleDifference(dt: any): {
|
|
223
|
+
rest: any;
|
|
224
|
+
lin: DifferenceTerms;
|
|
225
|
+
};
|
|
226
|
+
sysRest: any;
|
|
227
|
+
diffTerms: DifferenceTerms;
|
|
228
|
+
_refine(dt: any, delta: any, deltaV: any): boolean;
|
|
194
229
|
_maxPotentialStep(delta: any, deltaV?: Float64Array<any>): number;
|
|
195
230
|
/**
|
|
196
231
|
* Newton iteration for one backward-Euler step from the current cOld.
|
|
197
232
|
* @returns {{converged: boolean, iterations: number, history: number[]}}
|
|
198
233
|
*/
|
|
199
|
-
newton(dt: any, { maxIter, tol, maxStep }?: {
|
|
234
|
+
newton(dt: any, { maxIter, tol, maxStep, islands }?: {
|
|
200
235
|
maxIter?: number;
|
|
201
236
|
tol?: number;
|
|
202
237
|
maxStep?: number;
|
|
238
|
+
islands?: boolean;
|
|
203
239
|
}): {
|
|
204
240
|
converged: boolean;
|
|
205
241
|
iterations: number;
|
|
206
242
|
history: number[];
|
|
207
243
|
};
|
|
244
|
+
_kirchhoff(): number;
|
|
208
245
|
_noteConditioning(): void;
|
|
209
246
|
conditioning: {
|
|
210
|
-
digits:
|
|
247
|
+
digits: any;
|
|
211
248
|
x: number;
|
|
212
249
|
where: string;
|
|
213
250
|
};
|
|
@@ -236,7 +273,7 @@ export class Solver {
|
|
|
236
273
|
/**
|
|
237
274
|
* Adaptive time stepping to tEnd: variable-step BDF2 (or backward Euler), with the local error
|
|
238
275
|
* estimated against an explicit predictor through the previous states, and controlled to
|
|
239
|
-
* `tol` thermal units per step in every potential (φ̂, each η, a
|
|
276
|
+
* `tol` thermal units per step in every potential (φ̂, each η, a surface's coverages as η). The first
|
|
240
277
|
* step is checked by step doubling. Stops early when `budgetMs` of wall time is used, so an
|
|
241
278
|
* animation can call it once per frame; the step size carries over between calls.
|
|
242
279
|
*/
|
|
@@ -316,6 +353,13 @@ export class Solver {
|
|
|
316
353
|
im: Float64Array<ArrayBuffer>;
|
|
317
354
|
};
|
|
318
355
|
};
|
|
356
|
+
_regionShift(yr: any, yi: any): Float64Array<any>[];
|
|
357
|
+
_regionEdgeRows(): Uint8Array<any>;
|
|
358
|
+
_currentCuts(): {
|
|
359
|
+
idx: any[];
|
|
360
|
+
g: any[];
|
|
361
|
+
d: any[];
|
|
362
|
+
}[];
|
|
319
363
|
_smallSignalProfiles(xr: any, xi: any): {
|
|
320
364
|
phi: {
|
|
321
365
|
re: Float64Array<any>;
|
|
@@ -339,7 +383,16 @@ export class Solver {
|
|
|
339
383
|
* The clock is not advanced, and open-system conservation bookkeeping restarts here.
|
|
340
384
|
*/
|
|
341
385
|
solveSteady(opts?: {}): any;
|
|
386
|
+
unreached: {
|
|
387
|
+
terminal: any;
|
|
388
|
+
target: any;
|
|
389
|
+
low: any;
|
|
390
|
+
high: any;
|
|
391
|
+
};
|
|
392
|
+
_solveSteadyAll(opts: any): any;
|
|
342
393
|
_steadyFromHere(opts: any): any;
|
|
394
|
+
dimmer: boolean;
|
|
395
|
+
_floatingContinuation(opts: any, r: any): any;
|
|
343
396
|
_generationContinuation(opts: any, r: any): {
|
|
344
397
|
converged: boolean;
|
|
345
398
|
steps: any;
|
|
@@ -385,4 +438,4 @@ export class Solver {
|
|
|
385
438
|
_renormalizeSpectators(): void;
|
|
386
439
|
_diff(): Float64Array<ArrayBuffer>;
|
|
387
440
|
}
|
|
388
|
-
import {
|
|
441
|
+
import { DifferenceTerms } from './difference.js';
|
package/types/types.d.ts
CHANGED
|
@@ -471,6 +471,12 @@ export type ContactResult = {
|
|
|
471
471
|
*/
|
|
472
472
|
current: number;
|
|
473
473
|
};
|
|
474
|
+
/**
|
|
475
|
+
* The device's totals through its cross-section (currents, fluxes through contacts and ports,
|
|
476
|
+
* charges, amounts, reaction totals, impedance) are per m² of a planar device, as below, and
|
|
477
|
+
* whole (A, mol/s, C, mol, Ω; per metre of a cylinder) for one with a `geometry`. Rates at a
|
|
478
|
+
* face or an electrode are always per m² of it.
|
|
479
|
+
*/
|
|
474
480
|
export type Solution = {
|
|
475
481
|
/**
|
|
476
482
|
* node positions, m (interface positions appear twice)
|