driftlet 0.1.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/LICENSE +14 -0
- package/README.md +285 -0
- package/llms.txt +299 -0
- package/package.json +54 -0
- package/src/bernoulli.js +29 -0
- package/src/blockTridiagonal.js +492 -0
- package/src/constants.js +36 -0
- package/src/data.js +127 -0
- package/src/describe.js +190 -0
- package/src/device.js +954 -0
- package/src/equation.js +188 -0
- package/src/errors.js +8 -0
- package/src/fermi.js +106 -0
- package/src/grid.js +111 -0
- package/src/index.js +207 -0
- package/src/kit.js +76 -0
- package/src/live.js +217 -0
- package/src/merge.js +11 -0
- package/src/plot.js +267 -0
- package/src/solution.js +246 -0
- package/src/solver.js +2884 -0
- package/src/stack.js +172 -0
- package/src/statistics.js +593 -0
- package/src/traces.js +125 -0
- package/src/types.js +221 -0
- package/src/worker.js +24 -0
- package/types/bernoulli.d.ts +4 -0
- package/types/blockTridiagonal.d.ts +92 -0
- package/types/constants.d.ts +33 -0
- package/types/data.d.ts +73 -0
- package/types/describe.d.ts +15 -0
- package/types/device.d.ts +20 -0
- package/types/equation.d.ts +102 -0
- package/types/errors.d.ts +3 -0
- package/types/fermi.d.ts +3 -0
- package/types/grid.d.ts +28 -0
- package/types/index.d.ts +103 -0
- package/types/kit.d.ts +61 -0
- package/types/live.d.ts +101 -0
- package/types/merge.d.ts +1 -0
- package/types/plot.d.ts +60 -0
- package/types/solution.d.ts +18 -0
- package/types/solver.d.ts +342 -0
- package/types/stack.d.ts +59 -0
- package/types/statistics.d.ts +10 -0
- package/types/traces.d.ts +118 -0
- package/types/types.d.ts +574 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One participant of an equation as written.
|
|
3
|
+
* @typedef {object} Term
|
|
4
|
+
* @property {string} name the participant as written (with any trailing parenthesis)
|
|
5
|
+
* @property {number} nu signed coefficient (< 0 on the left of the equation)
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Parse an equation into its terms, in order. The two sides are separated by `=` (or `⇌`, `<=>`,
|
|
9
|
+
* `->`, `→`), terms by ` + ` (spaces around the plus, which keeps it apart from charges), and a
|
|
10
|
+
* side with nothing on it is `0` or `∅`. A coefficient is an integer followed by a space
|
|
11
|
+
* (`2 e-`), so names may start with digits (`3He`).
|
|
12
|
+
* @param {string} text
|
|
13
|
+
* @param {string} [path] for error messages
|
|
14
|
+
* @returns {Term[]}
|
|
15
|
+
*/
|
|
16
|
+
export function parseEquation(text: string, path?: string): Term[];
|
|
17
|
+
/**
|
|
18
|
+
* The signed stoichiometry `{ name: ν }` of a homogeneous reaction, as a bulk reaction's `nu`.
|
|
19
|
+
* A participant on both sides is an error: give the net reaction.
|
|
20
|
+
* @param {string} text
|
|
21
|
+
* @param {string} [path]
|
|
22
|
+
* @returns {Record<string, number>}
|
|
23
|
+
*/
|
|
24
|
+
export function stoichiometry(text: string, path?: string): Record<string, number>;
|
|
25
|
+
/**
|
|
26
|
+
* Which side of a face each participant of an equation is on: the side whose material holds it
|
|
27
|
+
* (on a conductor's side, only its carrier). A species held on both sides is labelled with its
|
|
28
|
+
* side, 'Li+(left)', or its material, 'Li+(graphite)'. Participants in `fixed` (fixed-activity
|
|
29
|
+
* neutrals) go beside a conductor if there is one, else on the left (their side doesn't matter).
|
|
30
|
+
* @param {Term[]} terms
|
|
31
|
+
* @param {{ name: string, holds: (species: string) => boolean, conductor?: boolean }} left
|
|
32
|
+
* @param {{ name: string, holds: (species: string) => boolean, conductor?: boolean }} right
|
|
33
|
+
* @param {Record<string, number> | undefined} fixed
|
|
34
|
+
* @param {string} path
|
|
35
|
+
* @returns {{ left: Record<string, number>, right: Record<string, number> }}
|
|
36
|
+
*/
|
|
37
|
+
export function faceSides(terms: Term[], left: {
|
|
38
|
+
name: string;
|
|
39
|
+
holds: (species: string) => boolean;
|
|
40
|
+
conductor?: boolean;
|
|
41
|
+
}, right: {
|
|
42
|
+
name: string;
|
|
43
|
+
holds: (species: string) => boolean;
|
|
44
|
+
conductor?: boolean;
|
|
45
|
+
}, fixed: Record<string, number> | undefined, path: string): {
|
|
46
|
+
left: Record<string, number>;
|
|
47
|
+
right: Record<string, number>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A half-reaction: an equation with electrons `e-` on one side, and the μ (J/mol) of any
|
|
51
|
+
* participant that isn't a species (a fixed-activity neutral, such as a solid metal). It's plain
|
|
52
|
+
* data, `{ equation, fixed }`: spread it into a face reaction with its kinetics,
|
|
53
|
+
* `{ ...silver, k0: 1e-3 }`, or pass it to `level()`.
|
|
54
|
+
* @param {string} equation e.g. 'Ag+ + e- = Ag(s)'
|
|
55
|
+
* @param {Record<string, number>} [fixed] μ of the fixed participants, J/mol
|
|
56
|
+
* @returns {{ equation: string, fixed?: Record<string, number> }}
|
|
57
|
+
*/
|
|
58
|
+
export function half(equation: string, fixed?: Record<string, number>): {
|
|
59
|
+
equation: string;
|
|
60
|
+
fixed?: Record<string, number>;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The electronic level a half-reaction implies at each node, as an electron voltage
|
|
64
|
+
* V = −μ̄_e/F: where an electrode exchanging electrons by that reaction would sit in equilibrium
|
|
65
|
+
* with the local composition (the couple's redox level). With `standard: true`, every
|
|
66
|
+
* species is taken at its reference concentration (its standard level μ° + zFφ), so it's the
|
|
67
|
+
* standard level: for `SHE`, V°_e⁻(SHE) = φ + μ°_H⁺/F. `NaN` where a participant is absent.
|
|
68
|
+
* @param {{ mu: Record<string, ArrayLike<number>>, muStd: Record<string, ArrayLike<number>> }} sol a solution
|
|
69
|
+
* @param {{ equation: string, fixed?: Record<string, number> }} halfReaction from `half()`
|
|
70
|
+
* @param {{ standard?: boolean }} [opts]
|
|
71
|
+
* @returns {Float64Array}
|
|
72
|
+
*/
|
|
73
|
+
export function level(sol: {
|
|
74
|
+
mu: Record<string, ArrayLike<number>>;
|
|
75
|
+
muStd: Record<string, ArrayLike<number>>;
|
|
76
|
+
}, halfReaction: {
|
|
77
|
+
equation: string;
|
|
78
|
+
fixed?: Record<string, number>;
|
|
79
|
+
}, { standard }?: {
|
|
80
|
+
standard?: boolean;
|
|
81
|
+
}): Float64Array;
|
|
82
|
+
/**
|
|
83
|
+
* The standard hydrogen electrode, 2 H⁺ + 2 e⁻ ⇌ H₂, with μ(H₂) = 0 (the element in its standard
|
|
84
|
+
* state, on the usual table convention). Needs `H+` among the species.
|
|
85
|
+
*/
|
|
86
|
+
export const SHE: Readonly<{
|
|
87
|
+
equation: string;
|
|
88
|
+
fixed?: Record<string, number>;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* One participant of an equation as written.
|
|
92
|
+
*/
|
|
93
|
+
export type Term = {
|
|
94
|
+
/**
|
|
95
|
+
* the participant as written (with any trailing parenthesis)
|
|
96
|
+
*/
|
|
97
|
+
name: string;
|
|
98
|
+
/**
|
|
99
|
+
* signed coefficient (< 0 on the left of the equation)
|
|
100
|
+
*/
|
|
101
|
+
nu: number;
|
|
102
|
+
};
|
package/types/fermi.d.ts
ADDED
package/types/grid.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cell widths for one region: fine at both ends, growing toward the middle.
|
|
3
|
+
* @param {number} length m
|
|
4
|
+
* @param {import('./types.js').GridOptions} [opts]
|
|
5
|
+
* @returns {number[]} widths summing to `length`
|
|
6
|
+
*/
|
|
7
|
+
export function gradedCells(length: number, { hmin, hmax, ratio, minCells, hLeft, hRight }?: import("./types.js").GridOptions): number[];
|
|
8
|
+
/**
|
|
9
|
+
* Build the device grid.
|
|
10
|
+
* @param {{length: number, grid?: object, cells?: number[]}[]} regions in order, left to right
|
|
11
|
+
* @param {object} [opts] defaults for every region: { hmin, hmax, ratio, minCells }
|
|
12
|
+
*/
|
|
13
|
+
export function buildGrid(regions: {
|
|
14
|
+
length: number;
|
|
15
|
+
grid?: object;
|
|
16
|
+
cells?: number[];
|
|
17
|
+
}[], opts?: object): {
|
|
18
|
+
nNodes: number;
|
|
19
|
+
x: Float64Array<ArrayBuffer>;
|
|
20
|
+
nodeRegion: Int32Array<ArrayBuffer>;
|
|
21
|
+
segLength: Float64Array<ArrayBuffer>;
|
|
22
|
+
segRegion: Int32Array<ArrayBuffer>;
|
|
23
|
+
segFace: Int32Array<ArrayBuffer>;
|
|
24
|
+
vol: Float64Array<ArrayBuffer>;
|
|
25
|
+
regionStart: Int32Array<ArrayBuffer>;
|
|
26
|
+
regionEnd: Int32Array<ArrayBuffer>;
|
|
27
|
+
length: number;
|
|
28
|
+
};
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export { SolverError } from "./solver.js";
|
|
2
|
+
export { BlockTridiagonal } from "./blockTridiagonal.js";
|
|
3
|
+
export * from "./constants.js";
|
|
4
|
+
/** @typedef {import('./types.js').DeviceDefinition} DeviceDefinition */
|
|
5
|
+
/** @typedef {import('./types.js').Solution} Solution */
|
|
6
|
+
export class Device {
|
|
7
|
+
/** @param {DeviceDefinition} def plain, serialisable device definition (see docs/device.md) */
|
|
8
|
+
constructor(def: DeviceDefinition);
|
|
9
|
+
def: import("./types.js").DeviceDefinition;
|
|
10
|
+
model: any;
|
|
11
|
+
_solver: any;
|
|
12
|
+
/** The solver, built on first use (so construction only validates the definition). */
|
|
13
|
+
get solver(): any;
|
|
14
|
+
get grid(): any;
|
|
15
|
+
/**
|
|
16
|
+
* Change part of the definition (deep-merged). A change to the terminals' drives alone (V, I,
|
|
17
|
+
* R) is applied in place, cheaply. Otherwise the device is rebuilt, keeping the current state as
|
|
18
|
+
* the warm start when the grid and species are unchanged (else restarting from the regions' c0).
|
|
19
|
+
* @param {object} patch a partial device definition, merged into the current one
|
|
20
|
+
* @returns {this}
|
|
21
|
+
*/
|
|
22
|
+
set(patch: object): this;
|
|
23
|
+
_redefineDrives(def: any): void;
|
|
24
|
+
/**
|
|
25
|
+
* Steady state (or equilibrium), warm-started from the current state. Doesn't advance time.
|
|
26
|
+
* @param {{ maxSteps?: number, tol?: number, continuation?: boolean }} [opts]
|
|
27
|
+
* @returns {Solution}
|
|
28
|
+
*/
|
|
29
|
+
solve(opts?: {
|
|
30
|
+
maxSteps?: number;
|
|
31
|
+
tol?: number;
|
|
32
|
+
continuation?: boolean;
|
|
33
|
+
}): Solution;
|
|
34
|
+
/**
|
|
35
|
+
* Advance the transient by dt (s) with backward Euler. If Newton fails, the interval is
|
|
36
|
+
* split into smaller steps automatically; `substeps` in the result says how many.
|
|
37
|
+
* With `{ method: 'bdf2' }`, steps after the first use second-order BDF2.
|
|
38
|
+
* @param {number} dt s
|
|
39
|
+
* @param {{ method?: 'be' | 'bdf2' }} [opts]
|
|
40
|
+
* @returns {Solution}
|
|
41
|
+
*/
|
|
42
|
+
step(dt: number, opts?: {
|
|
43
|
+
method?: "be" | "bdf2";
|
|
44
|
+
}): Solution;
|
|
45
|
+
/**
|
|
46
|
+
* Adaptive transient to time tEnd (s): variable-step BDF2 with local error control. With
|
|
47
|
+
* `budgetMs`, it returns after that much wall time even if tEnd isn't reached (`done` says
|
|
48
|
+
* which), so an animation can call it once per frame; the step size carries over.
|
|
49
|
+
* @param {number} tEnd s
|
|
50
|
+
* @param {{ tol?: number, dt0?: number, dtMax?: number, budgetMs?: number, maxSteps?: number, method?: 'bdf2' | 'be' }} [opts]
|
|
51
|
+
* @returns {Solution}
|
|
52
|
+
*/
|
|
53
|
+
advance(tEnd: number, opts?: {
|
|
54
|
+
tol?: number;
|
|
55
|
+
dt0?: number;
|
|
56
|
+
dtMax?: number;
|
|
57
|
+
budgetMs?: number;
|
|
58
|
+
maxSteps?: number;
|
|
59
|
+
method?: "bdf2" | "be";
|
|
60
|
+
}): Solution;
|
|
61
|
+
/**
|
|
62
|
+
* Small-signal impedance Z(f) about the steady state (solved first), at one terminal: its
|
|
63
|
+
* held voltage is perturbed (or its driven current), the others keep their drives.
|
|
64
|
+
* Z = δV/δI with I into the device (Ω·m²).
|
|
65
|
+
* @param {ArrayLike<number>} frequencies Hz
|
|
66
|
+
* @param {{ terminal?: string, profiles?: boolean }} [opts] the terminal (default 'right'), and
|
|
67
|
+
* whether to return complex profiles per frequency
|
|
68
|
+
* @returns {import('./types.js').ImpedanceResult}
|
|
69
|
+
*/
|
|
70
|
+
impedance(frequencies: ArrayLike<number>, opts?: {
|
|
71
|
+
terminal?: string;
|
|
72
|
+
profiles?: boolean;
|
|
73
|
+
}): import("./types.js").ImpedanceResult;
|
|
74
|
+
/**
|
|
75
|
+
* A checkpoint of the definition and solver state, for `_rollback()` (the live wrapper keeps
|
|
76
|
+
* its last good state this way).
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
_checkpoint(): {
|
|
80
|
+
def: import("./types.js").DeviceDefinition;
|
|
81
|
+
model: any;
|
|
82
|
+
solver: any;
|
|
83
|
+
snap: any;
|
|
84
|
+
solvedV: any;
|
|
85
|
+
referenceAmounts: any;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Back to a checkpoint taken on this device.
|
|
89
|
+
* @param {ReturnType<Device['_checkpoint']>} cp
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
_rollback(cp: ReturnType<Device["_checkpoint"]>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Snapshot of the current state.
|
|
95
|
+
* @returns {Solution}
|
|
96
|
+
*/
|
|
97
|
+
solution(): Solution;
|
|
98
|
+
}
|
|
99
|
+
export type DeviceDefinition = import("./types.js").DeviceDefinition;
|
|
100
|
+
export type Solution = import("./types.js").Solution;
|
|
101
|
+
export { DeviceError, normalizeDevice } from "./device.js";
|
|
102
|
+
export { buildGrid, gradedCells } from "./grid.js";
|
|
103
|
+
export { bernoulli, bernoulliDerivative } from "./bernoulli.js";
|
package/types/kit.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One material seen from vacuum: a level inside it (the anchor) and how far above that level,
|
|
3
|
+
* in electron energy, the vacuum level just outside lies (the offset, V). So
|
|
4
|
+
* V_vac = V_anchor − offset.
|
|
5
|
+
* @typedef {object} VacuumSide
|
|
6
|
+
* @property {string} material material name in the definition
|
|
7
|
+
* @property {string} anchor a charged species present there (its standard level
|
|
8
|
+
* V°_i = φ + μ°_i/(z_i F): a band edge for e⁻ or h⁺), or 'phi' (the inner potential itself)
|
|
9
|
+
* @property {number} offset V: an electron affinity, ionisation energy, Trasatti's 4.44 V, …
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A material's vacuum level relative to its own φ, V_vac − φ, in volts.
|
|
13
|
+
* @param {object} def device definition (its `species` and `materials` are read)
|
|
14
|
+
* @param {VacuumSide} side
|
|
15
|
+
* @param {string} [path] for error messages
|
|
16
|
+
*/
|
|
17
|
+
export function vacuumLevel(def: object, side: VacuumSide, path?: string): number;
|
|
18
|
+
/**
|
|
19
|
+
* The vacuum-level (Anderson-type) estimate of a face's alignment: the two sides' vacuum levels
|
|
20
|
+
* are taken to coincide. Returns the face's `dipole`, φ_R − φ_L in volts.
|
|
21
|
+
* @param {object} def device definition
|
|
22
|
+
* @param {VacuumSide} left
|
|
23
|
+
* @param {VacuumSide} right
|
|
24
|
+
*/
|
|
25
|
+
export function vacuumDipole(def: object, left: VacuumSide, right: VacuumSide): number;
|
|
26
|
+
/**
|
|
27
|
+
* The vacuum-level (Schottky–Mott-type) estimate of a `zeroCharge` where a conductor meets a
|
|
28
|
+
* material: at a conductor region's face, or a contact's capacitive or dipole law. The conductor's
|
|
29
|
+
* vacuum level sits its work function W beyond its Fermi level, so
|
|
30
|
+
* zeroCharge = V_F − φ_edge at zero charge = W + (V_vac − φ)_inside.
|
|
31
|
+
* @param {object} def device definition
|
|
32
|
+
* @param {number} workFunction V
|
|
33
|
+
* @param {VacuumSide} inside the material across the face
|
|
34
|
+
*/
|
|
35
|
+
export function vacuumZeroCharge(def: object, workFunction: number, inside: VacuumSide): number;
|
|
36
|
+
export { live } from "./live.js";
|
|
37
|
+
/**
|
|
38
|
+
* One material seen from vacuum: a level inside it (the anchor) and how far above that level,
|
|
39
|
+
* in electron energy, the vacuum level just outside lies (the offset, V). So
|
|
40
|
+
* V_vac = V_anchor − offset.
|
|
41
|
+
*/
|
|
42
|
+
export type VacuumSide = {
|
|
43
|
+
/**
|
|
44
|
+
* material name in the definition
|
|
45
|
+
*/
|
|
46
|
+
material: string;
|
|
47
|
+
/**
|
|
48
|
+
* a charged species present there (its standard level
|
|
49
|
+
* V°_i = φ + μ°_i/(z_i F): a band edge for e⁻ or h⁺), or 'phi' (the inner potential itself)
|
|
50
|
+
*/
|
|
51
|
+
anchor: string;
|
|
52
|
+
/**
|
|
53
|
+
* V: an electron affinity, ionisation energy, Trasatti's 4.44 V, …
|
|
54
|
+
*/
|
|
55
|
+
offset: number;
|
|
56
|
+
};
|
|
57
|
+
export { build, combine, layer, ohmic, bath } from "./stack.js";
|
|
58
|
+
export { parseEquation, stoichiometry, half, SHE, level } from "./equation.js";
|
|
59
|
+
export { traces, speciesRole, typeset } from "./traces.js";
|
|
60
|
+
export { describe, unitWarnings } from "./describe.js";
|
|
61
|
+
export { IONS, H2O, WATER_EPSR, SEMICONDUCTORS, METALS, aqueous, semiconductor, metal } from "./data.js";
|
package/types/live.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export function between(a: any, b: any, s: any): any;
|
|
2
|
+
/**
|
|
3
|
+
* A live device.
|
|
4
|
+
* @typedef {object} Live
|
|
5
|
+
* @property {(patch: object) => Promise<{ solution: object | null, info: object }>} set merge a change
|
|
6
|
+
* (as Device.set()) and solve it, after the solve under way; changes made meanwhile are merged
|
|
7
|
+
* and solved once, and all their promises resolve with that solution
|
|
8
|
+
* @property {Promise<{ solution: object | null, info: object }>} ready the first solve
|
|
9
|
+
* @property {object | null} solution the last good solution
|
|
10
|
+
* @property {() => void} close stop the worker, if any
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A device for live demos: `live.set(patch)` as often as a slider moves, and draw what comes
|
|
14
|
+
* back (or in `onsolution`). Solves run one at a time, each warm from the last, letting the page
|
|
15
|
+
* paint in between; changes made during a solve are merged and solved together.
|
|
16
|
+
*
|
|
17
|
+
* On failure, the solution is the last good one, with `info.failed` (and `info.error` for an
|
|
18
|
+
* invalid change, `info.warnings` for one that didn't converge). `info.ramp` says how many steps
|
|
19
|
+
* a ramp from the last good state took (0: none needed), and `info.ms` the time.
|
|
20
|
+
*
|
|
21
|
+
* With `worker: true`, solving happens in a Web Worker (module workers are needed, as in every
|
|
22
|
+
* current browser). A function returning a Worker-like object can be given instead.
|
|
23
|
+
* @param {object} def device definition
|
|
24
|
+
* @param {{ worker?: boolean | (() => any), onsolution?: (solution: object, info: object) => void, maxRamp?: number }} [opts]
|
|
25
|
+
* @returns {Live}
|
|
26
|
+
*/
|
|
27
|
+
export function live(def: object, { worker, onsolution, maxRamp }?: {
|
|
28
|
+
worker?: boolean | (() => any);
|
|
29
|
+
onsolution?: (solution: object, info: object) => void;
|
|
30
|
+
maxRamp?: number;
|
|
31
|
+
}): Live;
|
|
32
|
+
/**
|
|
33
|
+
* What a live device does with each change, on whichever thread solves it: apply, solve warm,
|
|
34
|
+
* ramp from the last good state if that fails, and fall back to the last good solution.
|
|
35
|
+
*/
|
|
36
|
+
export class Session {
|
|
37
|
+
/** @param {object} def device definition */
|
|
38
|
+
constructor(def: object, { maxRamp }?: {
|
|
39
|
+
maxRamp?: number;
|
|
40
|
+
});
|
|
41
|
+
device: Device;
|
|
42
|
+
maxRamp: number;
|
|
43
|
+
good: {
|
|
44
|
+
cp: {
|
|
45
|
+
def: import("./types.js").DeviceDefinition;
|
|
46
|
+
model: any;
|
|
47
|
+
solver: any;
|
|
48
|
+
snap: any;
|
|
49
|
+
solvedV: any;
|
|
50
|
+
referenceAmounts: any;
|
|
51
|
+
};
|
|
52
|
+
sol: import("./types.js").Solution;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Apply changes in order, then solve once. Each change is applied on its own, so an invalid
|
|
56
|
+
* one is refused (its message in `errors`) without losing the others.
|
|
57
|
+
* @param {object[]} patches each merged into the definition, as by Device.set()
|
|
58
|
+
* @returns {{ solution: object | null, errors: (string | undefined)[], info: { ms: number, ramp: number, failed: boolean, error?: string, warnings?: string[] } }}
|
|
59
|
+
*/
|
|
60
|
+
update(patches: object[]): {
|
|
61
|
+
solution: object | null;
|
|
62
|
+
errors: (string | undefined)[];
|
|
63
|
+
info: {
|
|
64
|
+
ms: number;
|
|
65
|
+
ramp: number;
|
|
66
|
+
failed: boolean;
|
|
67
|
+
error?: string;
|
|
68
|
+
warnings?: string[];
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A live device.
|
|
74
|
+
*/
|
|
75
|
+
export type Live = {
|
|
76
|
+
/**
|
|
77
|
+
* merge a change
|
|
78
|
+
* (as Device.set()) and solve it, after the solve under way; changes made meanwhile are merged
|
|
79
|
+
* and solved once, and all their promises resolve with that solution
|
|
80
|
+
*/
|
|
81
|
+
set: (patch: object) => Promise<{
|
|
82
|
+
solution: object | null;
|
|
83
|
+
info: object;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* the first solve
|
|
87
|
+
*/
|
|
88
|
+
ready: Promise<{
|
|
89
|
+
solution: object | null;
|
|
90
|
+
info: object;
|
|
91
|
+
}>;
|
|
92
|
+
/**
|
|
93
|
+
* the last good solution
|
|
94
|
+
*/
|
|
95
|
+
solution: object | null;
|
|
96
|
+
/**
|
|
97
|
+
* stop the worker, if any
|
|
98
|
+
*/
|
|
99
|
+
close: () => void;
|
|
100
|
+
};
|
|
101
|
+
import { Device } from './index.js';
|
package/types/merge.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function merge(base: any, patch: any): any;
|
package/types/plot.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The colour of a trace's role and slot (a CSS colour), for drawing other charts in the same
|
|
3
|
+
* colours as the level diagrams.
|
|
4
|
+
* @param {'electron' | 'cation' | 'anion' | 'redox'} role
|
|
5
|
+
* @param {number} slot
|
|
6
|
+
* @param {{ dark?: boolean }} [opts]
|
|
7
|
+
*/
|
|
8
|
+
export function themeColor(role: "electron" | "cation" | "anion" | "redox", slot: number, { dark }?: {
|
|
9
|
+
dark?: boolean;
|
|
10
|
+
}): string;
|
|
11
|
+
/**
|
|
12
|
+
* A label split into plain and subscript runs. Labels mark subscripts TeX-style: `V_{e⁻}`, or
|
|
13
|
+
* `C_ox` for a run of letters, digits and charge signs. Everything else is literal.
|
|
14
|
+
* @param {string} label
|
|
15
|
+
* @returns {{ text: string, sub: boolean }[]}
|
|
16
|
+
*/
|
|
17
|
+
export function labelParts(label: string): {
|
|
18
|
+
text: string;
|
|
19
|
+
sub: boolean;
|
|
20
|
+
}[];
|
|
21
|
+
/**
|
|
22
|
+
* Line chart of level-diagram traces as an SVG string.
|
|
23
|
+
* @param {ReturnType<typeof traces>} tr from `traces()`
|
|
24
|
+
* @param {{ width?: number, height?: number, ylabel?: string, range?: [number, number], xlim?: [number, number], title?: string, ytick?: (v: number) => string }} [opts]
|
|
25
|
+
* `xlim` (m) zooms into part of the device; the range then fits what's shown. `ytick` writes
|
|
26
|
+
* the y axis's tick labels, say as powers of ten for lines that are log₁₀ of something
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
export function levelChart(tr: ReturnType<typeof traces>, { width, height, ylabel, range, xlim, title, ytick }?: {
|
|
30
|
+
width?: number;
|
|
31
|
+
height?: number;
|
|
32
|
+
ylabel?: string;
|
|
33
|
+
range?: [number, number];
|
|
34
|
+
xlim?: [number, number];
|
|
35
|
+
title?: string;
|
|
36
|
+
ytick?: (v: number) => string;
|
|
37
|
+
}): string;
|
|
38
|
+
/**
|
|
39
|
+
* A solution's level diagram as an SVG string: each charged species' voltage (thick) and
|
|
40
|
+
* standard level (thin), regions as bands. Options are those of `traces()` and `levelChart()`.
|
|
41
|
+
* @param {import('./types.js').Solution} sol
|
|
42
|
+
* @param {Parameters<typeof traces>[1] & Parameters<typeof levelChart>[1]} [opts]
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
45
|
+
export function bandDiagram(sol: import("./types.js").Solution, opts?: Parameters<typeof traces>[1] & Parameters<typeof levelChart>[1]): string;
|
|
46
|
+
export const THEME: Readonly<{
|
|
47
|
+
light: {
|
|
48
|
+
electron: string[];
|
|
49
|
+
cation: string[];
|
|
50
|
+
anion: string[];
|
|
51
|
+
redox: string[];
|
|
52
|
+
};
|
|
53
|
+
dark: {
|
|
54
|
+
electron: string[];
|
|
55
|
+
cation: string[];
|
|
56
|
+
anion: string[];
|
|
57
|
+
redox: string[];
|
|
58
|
+
};
|
|
59
|
+
}>;
|
|
60
|
+
import { traces } from './traces.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function makeSolution(solver: any, result?: {}): {
|
|
2
|
+
x: Float64Array<ArrayBuffer>;
|
|
3
|
+
region: Int32Array<ArrayBuffer>;
|
|
4
|
+
species: any;
|
|
5
|
+
regions: any;
|
|
6
|
+
phi: Float64Array<any>;
|
|
7
|
+
c: {};
|
|
8
|
+
mu: {};
|
|
9
|
+
muStd: {};
|
|
10
|
+
V: {};
|
|
11
|
+
Vstd: {};
|
|
12
|
+
time: any;
|
|
13
|
+
converged: any;
|
|
14
|
+
iterations: any;
|
|
15
|
+
steps: any;
|
|
16
|
+
substeps: any;
|
|
17
|
+
history: any;
|
|
18
|
+
};
|