driftlet 0.10.0 → 0.12.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/README.md +50 -36
- package/docs/device.md +129 -7
- package/docs/kit.md +12 -0
- package/docs/numerics.md +188 -22
- package/docs/reliability.md +122 -0
- package/llms.txt +55 -8
- package/package.json +2 -1
- package/src/blockTridiagonal.js +17 -4
- package/src/channels.js +73 -0
- package/src/checks.js +17 -10
- package/src/describe.js +4 -2
- package/src/device.js +55 -11
- package/src/difference.js +142 -0
- package/src/index.js +22 -6
- package/src/kit.js +1 -0
- package/src/recorder.js +1 -1
- package/src/solution.js +20 -3
- package/src/solver.js +1166 -146
- package/types/blockTridiagonal.d.ts +9 -1
- package/types/channels.d.ts +39 -0
- package/types/difference.d.ts +30 -0
- package/types/index.d.ts +2 -1
- package/types/kit.d.ts +1 -0
- package/types/recorder.d.ts +7 -3
- package/types/solver.d.ts +77 -11
|
@@ -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
|
/**
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function ghkCurrent(z: any, inside: any, outside: any, V: any, T: any): number;
|
|
2
|
+
/**
|
|
3
|
+
* Hodgkin and Huxley's squid-axon channels, for a membrane face with the outside on its left
|
|
4
|
+
* (so the gates' voltage, φ_right − φ_left, is the membrane potential): the face's `gates`, and
|
|
5
|
+
* `species` links for Na⁺ (P·m³h), K⁺ (P·n⁴) and the leak (ungated), to spread into the face
|
|
6
|
+
* beside its φ law, `{ phi: { type: 'capacitive', C: 0.01 }, ...hh }`, adding links (or blocks)
|
|
7
|
+
* for any other species.
|
|
8
|
+
*
|
|
9
|
+
* The currents are GHK's, which rectify, so a permeability matches a conductance at one voltage
|
|
10
|
+
* only: each is the one whose chord conductance at `at` (rest, −65 mV) is Hodgkin and Huxley's
|
|
11
|
+
* (`g`: 120, 36 and 0.3 mS/cm²), at the concentrations given. The leak is carried by one ion
|
|
12
|
+
* (`leak`, of charge `leakZ`: Cl⁻ by default, whose Nernst level in squid is near their leak
|
|
13
|
+
* reversal, −54 mV). The
|
|
14
|
+
* rates are theirs at 6.3 °C, scaled to `T` by Q₁₀ = 3.
|
|
15
|
+
* @param {{ inside: object, outside: object, T?: number, g?: { Na?: number, K?: number, leak?: number },
|
|
16
|
+
* leak?: string, leakZ?: number, at?: number, names?: { Na?: string, K?: string } }} opts concentrations in
|
|
17
|
+
* mol/m³ by species name, K, S/m², V
|
|
18
|
+
* @returns {{ gates: object, species: object }}
|
|
19
|
+
*/
|
|
20
|
+
export function hodgkinHuxley({ inside, outside, T, g, leak, leakZ, at, names }?: {
|
|
21
|
+
inside: object;
|
|
22
|
+
outside: object;
|
|
23
|
+
T?: number;
|
|
24
|
+
g?: {
|
|
25
|
+
Na?: number;
|
|
26
|
+
K?: number;
|
|
27
|
+
leak?: number;
|
|
28
|
+
};
|
|
29
|
+
leak?: string;
|
|
30
|
+
leakZ?: number;
|
|
31
|
+
at?: number;
|
|
32
|
+
names?: {
|
|
33
|
+
Na?: string;
|
|
34
|
+
K?: string;
|
|
35
|
+
};
|
|
36
|
+
}): {
|
|
37
|
+
gates: object;
|
|
38
|
+
species: object;
|
|
39
|
+
};
|
|
@@ -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
|
package/types/kit.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export { build, combine, layer, ohmic, bath } from "./stack.js";
|
|
|
61
61
|
export { parseEquation, stoichiometry, half, SHE, level } from "./equation.js";
|
|
62
62
|
export { traces, speciesRole, typeset } from "./traces.js";
|
|
63
63
|
export { pulse, square, triangle, ramp, injector, recombination, photogeneration } from "./sources.js";
|
|
64
|
+
export { hodgkinHuxley, ghkCurrent } from "./channels.js";
|
|
64
65
|
export { describe, unitWarnings } from "./describe.js";
|
|
65
66
|
export { henderson, planck } from "./junction.js";
|
|
66
67
|
export { perovskiteCell, PEROVSKITE_SCANS, hysteresis } from "./devices.js";
|
package/types/recorder.d.ts
CHANGED
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
* neither, at the end of each `advance()` call. The trace (`t`, `current`, `voltage`, and
|
|
5
5
|
* `probes` if given) runs from the start through every accepted step of every call.
|
|
6
6
|
* @param {import('./index.js').Device} device
|
|
7
|
-
* @param {{ every?: number, times?: number[], probes?: { x: number, species?: string, quantity?: 'c' | 'V' | 'phi', region?: string | number }[] }} [opts]
|
|
7
|
+
* @param {{ every?: number, times?: number[], probes?: ({ x: number, species?: string, quantity?: 'c' | 'V' | 'phi', region?: string | number } | { interface: number, species?: string, gate?: string })[] }} [opts]
|
|
8
8
|
*/
|
|
9
9
|
export function recorder(device: import("./index.js").Device, opts?: {
|
|
10
10
|
every?: number;
|
|
11
11
|
times?: number[];
|
|
12
|
-
probes?: {
|
|
12
|
+
probes?: ({
|
|
13
13
|
x: number;
|
|
14
14
|
species?: string;
|
|
15
15
|
quantity?: "c" | "V" | "phi";
|
|
16
16
|
region?: string | number;
|
|
17
|
-
}
|
|
17
|
+
} | {
|
|
18
|
+
interface: number;
|
|
19
|
+
species?: string;
|
|
20
|
+
gate?: string;
|
|
21
|
+
})[];
|
|
18
22
|
}): {
|
|
19
23
|
advance: (tEnd: number, aopts?: object) => import("./types.js").Solution;
|
|
20
24
|
frame: (t: number) => import("./types.js").Solution;
|
package/types/solver.d.ts
CHANGED
|
@@ -23,6 +23,11 @@ export class Solver {
|
|
|
23
23
|
thOld: Float64Array<ArrayBuffer>;
|
|
24
24
|
th0: Float64Array<any>;
|
|
25
25
|
th0Old: Float64Array<any>;
|
|
26
|
+
gatePort: Int32Array<any>;
|
|
27
|
+
gateList: any[];
|
|
28
|
+
gateOld: Float64Array<ArrayBuffer>;
|
|
29
|
+
gateIndex: Int32Array<ArrayBuffer>;
|
|
30
|
+
portGateIndex: any;
|
|
26
31
|
present: Uint8Array<ArrayBuffer>;
|
|
27
32
|
cRef: Float64Array<ArrayBuffer>;
|
|
28
33
|
mu0hat: Float64Array<ArrayBuffer>;
|
|
@@ -54,6 +59,7 @@ export class Solver {
|
|
|
54
59
|
time: number;
|
|
55
60
|
lastDt: number;
|
|
56
61
|
atSteady: boolean;
|
|
62
|
+
lin: DifferenceTerms;
|
|
57
63
|
contactFlux: {
|
|
58
64
|
left: Float64Array<any>;
|
|
59
65
|
right: Float64Array<any>;
|
|
@@ -95,7 +101,6 @@ export class Solver {
|
|
|
95
101
|
rxs: any;
|
|
96
102
|
portArea: any;
|
|
97
103
|
portRates: any;
|
|
98
|
-
strictlyNeutral: any;
|
|
99
104
|
generationScale: number;
|
|
100
105
|
hasGeneration: any;
|
|
101
106
|
rxsIn: any;
|
|
@@ -105,6 +110,7 @@ export class Solver {
|
|
|
105
110
|
};
|
|
106
111
|
chargeNode: Uint8Array<any>;
|
|
107
112
|
chargeNodes: Int32Array<ArrayBuffer>;
|
|
113
|
+
lateStorage: Uint8Array<any>;
|
|
108
114
|
combining: boolean;
|
|
109
115
|
bookkeeping: any;
|
|
110
116
|
bookkeepingFaces: number[];
|
|
@@ -114,29 +120,42 @@ export class Solver {
|
|
|
114
120
|
_activeSlots(): void;
|
|
115
121
|
active: Uint8Array<ArrayBuffer>;
|
|
116
122
|
loc: Int32Array<ArrayBuffer>;
|
|
117
|
-
sys:
|
|
123
|
+
sys: any;
|
|
118
124
|
SINK: number;
|
|
119
125
|
rix: Int32Array<ArrayBuffer>;
|
|
120
126
|
fullOf: Int32Array<ArrayBuffer>;
|
|
121
127
|
res: Float64Array<ArrayBuffer>;
|
|
122
128
|
delta: Float64Array<ArrayBuffer>;
|
|
129
|
+
rowScale: Float64Array<ArrayBuffer>;
|
|
123
130
|
_factor(): void;
|
|
124
131
|
_solveLinear(rhs: any, delta: any): void;
|
|
125
132
|
_findStretches(): void;
|
|
126
133
|
stretches: any[];
|
|
127
134
|
stretchOf: Int32Array<ArrayBuffer>;
|
|
128
135
|
moieties: Float64Array<any>[];
|
|
136
|
+
flatStretches: any[];
|
|
137
|
+
levelStretches: any[];
|
|
138
|
+
flattening: boolean;
|
|
129
139
|
constraints: any[];
|
|
130
140
|
localConstraints: any[];
|
|
141
|
+
islands: any[];
|
|
142
|
+
pinnedIslands: any[];
|
|
143
|
+
islandsOn: boolean;
|
|
144
|
+
pins: any[];
|
|
131
145
|
constrained: boolean;
|
|
132
146
|
_captureLocal(): void;
|
|
147
|
+
_applyIslands(): any[];
|
|
148
|
+
islandRow: Float64Array<any>;
|
|
149
|
+
_rowInto(o: any, add: any): void;
|
|
150
|
+
linRow: Float64Array<any>;
|
|
133
151
|
_applyLocalConstraints(): void;
|
|
134
152
|
_conservedMoieties(): Float64Array<any>[];
|
|
135
153
|
_directSteady(): boolean;
|
|
136
154
|
_applyConstraints(): void;
|
|
137
155
|
_solveBordered(rhs: any, delta: any, deltaV: any, pins: any): void;
|
|
138
|
-
dWork: Float64Array<
|
|
156
|
+
dWork: Float64Array<any>;
|
|
139
157
|
borderCols: any[];
|
|
158
|
+
_surfaceStart(g: any): void;
|
|
140
159
|
/** Amount (mol per unit area) of surface column j's species, Γ Σ v·a·θ, in the current state. */
|
|
141
160
|
surfaceAmount(j: any): number;
|
|
142
161
|
/** Total amount (mol per unit area) of a stretch's species in the current state. */
|
|
@@ -167,7 +186,8 @@ export class Solver {
|
|
|
167
186
|
_j(rb: any, rs: any, cb: any, cs: any, v: any): void;
|
|
168
187
|
/** Assemble residual and Jacobian for a backward-Euler step of size dt. */
|
|
169
188
|
assemble(dt: any): void;
|
|
170
|
-
|
|
189
|
+
dtNow: any;
|
|
190
|
+
transformed: any;
|
|
171
191
|
_nodeConductor(g: any, dt: any): void;
|
|
172
192
|
_nodesDilute(g0: any, g1: any, dt: any): void;
|
|
173
193
|
_nodeConcentrated(g: any, dt: any): void;
|
|
@@ -178,6 +198,11 @@ export class Solver {
|
|
|
178
198
|
_segmentDisplacement(s: any, bL: any, bR: any, mat: any, h: any): void;
|
|
179
199
|
_segmentsDilute(g0: any, g1: any, region: any, mat: any, vel: any): void;
|
|
180
200
|
_face(f: any): void;
|
|
201
|
+
_gateSlot(f: any, q: any): any;
|
|
202
|
+
_gateVoltage(gt: any): number;
|
|
203
|
+
_portVoltage(k: any, g: any): number;
|
|
204
|
+
_faceVoltage(f: any): number;
|
|
205
|
+
_faceGates(f: any, bf: any, bL: any, bR: any): void;
|
|
181
206
|
_segmentConcentrated(s: any, bL: any, bR: any, mat: any, h: any, vel: any): void;
|
|
182
207
|
_segmentConductor(s: any, bL: any, bR: any, mat: any, h: any): void;
|
|
183
208
|
_segmentMixing(s: any, bL: any, bR: any, Dm: any, h: any, mat: any): void;
|
|
@@ -193,33 +218,49 @@ export class Solver {
|
|
|
193
218
|
Ca: number;
|
|
194
219
|
};
|
|
195
220
|
_faceReaction(rx: any, k: any, f: any, bf: any, bL: any, bR: any, Af: any): void;
|
|
221
|
+
_liveTerms(): any;
|
|
222
|
+
_allTerms: any;
|
|
196
223
|
_terminals(dt: any): void;
|
|
197
224
|
_circuit(k: any): void;
|
|
198
|
-
_captureRow(b: any, s: any, w: any, into: any):
|
|
225
|
+
_captureRow(b: any, s: any, w: any, into: any): any;
|
|
199
226
|
_port(port: any, flux: any, k: any, dt: any, holds: any): void;
|
|
200
227
|
_portReaction(port: any, rx: any, area: any, rates: any, flux: any, k: any): void;
|
|
228
|
+
_portGates(port: any, k: any, dt: any): void;
|
|
229
|
+
_open(gated: any, x: any): number;
|
|
230
|
+
_dOpen(gated: any, q: any, p: any, x: any): number;
|
|
201
231
|
_portCapacitance(port: any, k: any, dt: any): void;
|
|
202
232
|
_surfaceStorage(port: any, dt: any): void;
|
|
203
233
|
_contact(side: any, dt: any): void;
|
|
234
|
+
_flatRows(): void;
|
|
235
|
+
_levelRows(): void;
|
|
204
236
|
_replaceRow(b: any, rs: any): void;
|
|
205
237
|
_equilibrate(): void;
|
|
238
|
+
_assembleDifference(dt: any): {
|
|
239
|
+
rest: any;
|
|
240
|
+
lin: DifferenceTerms;
|
|
241
|
+
};
|
|
242
|
+
sysRest: any;
|
|
243
|
+
diffTerms: DifferenceTerms;
|
|
244
|
+
_refine(dt: any, delta: any, deltaV: any): boolean;
|
|
206
245
|
_maxPotentialStep(delta: any, deltaV?: Float64Array<any>): number;
|
|
207
246
|
/**
|
|
208
247
|
* Newton iteration for one backward-Euler step from the current cOld.
|
|
209
248
|
* @returns {{converged: boolean, iterations: number, history: number[]}}
|
|
210
249
|
*/
|
|
211
|
-
newton(dt: any, { maxIter, tol, maxStep }?: {
|
|
250
|
+
newton(dt: any, { maxIter, tol, maxStep, islands }?: {
|
|
212
251
|
maxIter?: number;
|
|
213
252
|
tol?: number;
|
|
214
253
|
maxStep?: number;
|
|
254
|
+
islands?: boolean;
|
|
215
255
|
}): {
|
|
216
256
|
converged: boolean;
|
|
217
257
|
iterations: number;
|
|
218
258
|
history: number[];
|
|
219
259
|
};
|
|
260
|
+
_kirchhoff(): number;
|
|
220
261
|
_noteConditioning(): void;
|
|
221
262
|
conditioning: {
|
|
222
|
-
digits:
|
|
263
|
+
digits: any;
|
|
223
264
|
x: number;
|
|
224
265
|
where: string;
|
|
225
266
|
};
|
|
@@ -285,6 +326,7 @@ export class Solver {
|
|
|
285
326
|
cOld: Float64Array<ArrayBuffer>;
|
|
286
327
|
thOld: Float64Array<ArrayBuffer>;
|
|
287
328
|
th0Old: Float64Array<ArrayBuffer>;
|
|
329
|
+
gateOld: Float64Array<ArrayBuffer>;
|
|
288
330
|
time: number;
|
|
289
331
|
lastDt: number;
|
|
290
332
|
atSteady: boolean;
|
|
@@ -318,16 +360,31 @@ export class Solver {
|
|
|
318
360
|
* Z = δV/δI with I into the device (positive real part for a passive device).
|
|
319
361
|
* @param {ArrayLike<number>} frequencies Hz
|
|
320
362
|
*/
|
|
321
|
-
impedance(frequencies: ArrayLike<number>,
|
|
363
|
+
impedance(frequencies: ArrayLike<number>, opts: any): {
|
|
364
|
+
f: Float64Array<ArrayBuffer>;
|
|
365
|
+
Z: {
|
|
366
|
+
re: Float64Array<any>;
|
|
367
|
+
im: Float64Array<any>;
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
allTerminals: any;
|
|
371
|
+
_impedance(frequencies: any, { profiles, terminal }?: {
|
|
322
372
|
profiles?: boolean;
|
|
323
373
|
terminal?: string;
|
|
324
374
|
}): {
|
|
325
375
|
f: Float64Array<ArrayBuffer>;
|
|
326
376
|
Z: {
|
|
327
|
-
re: Float64Array<
|
|
328
|
-
im: Float64Array<
|
|
377
|
+
re: Float64Array<any>;
|
|
378
|
+
im: Float64Array<any>;
|
|
329
379
|
};
|
|
330
380
|
};
|
|
381
|
+
_regionShift(yr: any, yi: any): Float64Array<any>[];
|
|
382
|
+
_regionEdgeRows(): Uint8Array<any>;
|
|
383
|
+
_currentCuts(): {
|
|
384
|
+
idx: any[];
|
|
385
|
+
g: any[];
|
|
386
|
+
d: any[];
|
|
387
|
+
}[];
|
|
331
388
|
_smallSignalProfiles(xr: any, xi: any): {
|
|
332
389
|
phi: {
|
|
333
390
|
re: Float64Array<any>;
|
|
@@ -351,7 +408,16 @@ export class Solver {
|
|
|
351
408
|
* The clock is not advanced, and open-system conservation bookkeeping restarts here.
|
|
352
409
|
*/
|
|
353
410
|
solveSteady(opts?: {}): any;
|
|
411
|
+
unreached: {
|
|
412
|
+
terminal: any;
|
|
413
|
+
target: any;
|
|
414
|
+
low: any;
|
|
415
|
+
high: any;
|
|
416
|
+
};
|
|
417
|
+
_solveSteadyAll(opts: any): any;
|
|
354
418
|
_steadyFromHere(opts: any): any;
|
|
419
|
+
dimmer: boolean;
|
|
420
|
+
_floatingContinuation(opts: any, r: any): any;
|
|
355
421
|
_generationContinuation(opts: any, r: any): {
|
|
356
422
|
converged: boolean;
|
|
357
423
|
steps: any;
|
|
@@ -397,4 +463,4 @@ export class Solver {
|
|
|
397
463
|
_renormalizeSpectators(): void;
|
|
398
464
|
_diff(): Float64Array<ArrayBuffer>;
|
|
399
465
|
}
|
|
400
|
-
import {
|
|
466
|
+
import { DifferenceTerms } from './difference.js';
|