driftlet 0.1.1 → 0.3.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 +12 -2
- package/docs/alignment.md +146 -0
- package/docs/conventions.md +194 -0
- package/docs/data.md +120 -0
- package/docs/device.md +541 -0
- package/docs/kit.md +299 -0
- package/docs/logo-dark.svg +7 -0
- package/docs/logo.svg +7 -0
- package/docs/numerics.md +629 -0
- package/docs/statistics.md +226 -0
- package/docs/visualization.md +259 -0
- package/llms.txt +71 -9
- package/package.json +4 -1
- package/src/constants.js +11 -0
- package/src/describe.js +17 -2
- package/src/device.js +23 -8
- package/src/fermi.js +5 -3
- package/src/index.js +5 -2
- package/src/kit.js +1 -0
- package/src/plot.js +2 -1
- package/src/pow.js +24 -0
- package/src/solver.js +110 -22
- package/src/sources.js +103 -0
- package/src/statistics.js +4 -3
- package/src/types.js +6 -4
- package/types/constants.d.ts +10 -0
- package/types/index.d.ts +11 -2
- package/types/kit.d.ts +1 -0
- package/types/pow.d.ts +4 -0
- package/types/solver.d.ts +9 -3
- package/types/sources.d.ts +102 -0
- package/types/types.d.ts +11 -5
package/types/index.d.ts
CHANGED
|
@@ -45,9 +45,12 @@ export class Device {
|
|
|
45
45
|
/**
|
|
46
46
|
* Adaptive transient to time tEnd (s): variable-step BDF2 with local error control. With
|
|
47
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.
|
|
48
|
+
* which), so an animation can call it once per frame; the step size carries over. `probes`
|
|
49
|
+
* read a species at points inside the device after every accepted step, into `trace.probes`
|
|
50
|
+
* (one array per probe, alongside `trace.t`): what a detector at x sees.
|
|
49
51
|
* @param {number} tEnd s
|
|
50
|
-
* @param {{ tol?: number, dt0?: number, dtMax?: number, budgetMs?: number, maxSteps?: number, method?: 'bdf2' | 'be'
|
|
52
|
+
* @param {{ tol?: number, dt0?: number, dtMax?: number, budgetMs?: number, maxSteps?: number, method?: 'bdf2' | 'be',
|
|
53
|
+
* probes?: { x: number, species: string, quantity?: 'c' | 'V', region?: string | number }[] }} [opts]
|
|
51
54
|
* @returns {Solution}
|
|
52
55
|
*/
|
|
53
56
|
advance(tEnd: number, opts?: {
|
|
@@ -57,6 +60,12 @@ export class Device {
|
|
|
57
60
|
budgetMs?: number;
|
|
58
61
|
maxSteps?: number;
|
|
59
62
|
method?: "bdf2" | "be";
|
|
63
|
+
probes?: {
|
|
64
|
+
x: number;
|
|
65
|
+
species: string;
|
|
66
|
+
quantity?: "c" | "V";
|
|
67
|
+
region?: string | number;
|
|
68
|
+
}[];
|
|
60
69
|
}): Solution;
|
|
61
70
|
/**
|
|
62
71
|
* Small-signal impedance Z(f) about the steady state (solved first), at one terminal: its
|
package/types/kit.d.ts
CHANGED
|
@@ -57,5 +57,6 @@ export type VacuumSide = {
|
|
|
57
57
|
export { build, combine, layer, ohmic, bath } from "./stack.js";
|
|
58
58
|
export { parseEquation, stoichiometry, half, SHE, level } from "./equation.js";
|
|
59
59
|
export { traces, speciesRole, typeset } from "./traces.js";
|
|
60
|
+
export { pulse, square, triangle, ramp, injector, recombination } from "./sources.js";
|
|
60
61
|
export { describe, unitWarnings } from "./describe.js";
|
|
61
62
|
export { IONS, H2O, WATER_EPSR, SEMICONDUCTORS, METALS, aqueous, semiconductor, metal } from "./data.js";
|
package/types/pow.d.ts
ADDED
package/types/solver.d.ts
CHANGED
|
@@ -120,9 +120,9 @@ export class Solver {
|
|
|
120
120
|
/** η_i/RT that a fixed contact link imposes (or NaN if the link isn't fixed). */
|
|
121
121
|
contactEta(side: any, i: any): number;
|
|
122
122
|
/**
|
|
123
|
-
* Cold start.
|
|
124
|
-
*
|
|
125
|
-
*
|
|
123
|
+
* Cold start. Each species takes its region's c0 where one is given (for a spectator, it fixes
|
|
124
|
+
* the conserved amount), else its contact's level. φ in each region is then chosen for local neutrality (node by node where a
|
|
125
|
+
* profile varies), or continued across the interface dipole if nothing there responds.
|
|
126
126
|
*/
|
|
127
127
|
initFromComposition(): void;
|
|
128
128
|
_materialAt(mat: any, background: any, eta: any, mode: any, cFix: any, ph: any, zeta: any, cc: any): void;
|
|
@@ -216,6 +216,7 @@ export class Solver {
|
|
|
216
216
|
rejected: number;
|
|
217
217
|
iterations: number;
|
|
218
218
|
trace: {
|
|
219
|
+
probes?: any;
|
|
219
220
|
t: any[];
|
|
220
221
|
current: any[];
|
|
221
222
|
voltage: any[];
|
|
@@ -227,6 +228,11 @@ export class Solver {
|
|
|
227
228
|
scale: number;
|
|
228
229
|
order: number;
|
|
229
230
|
};
|
|
231
|
+
_probes(probes: any): {
|
|
232
|
+
out: any;
|
|
233
|
+
read: () => any;
|
|
234
|
+
push: (values: any) => any;
|
|
235
|
+
};
|
|
230
236
|
_errorNorm(ref: any): number;
|
|
231
237
|
_snapshot(): {
|
|
232
238
|
u: Float64Array<ArrayBuffer>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rectangular pulse, as a waveform for a terminal's `V` or `I`: `base` until `start`, then
|
|
3
|
+
* `base + amplitude` for `width`, then `base` again. With a `rise` > 0 its edges are ramps of
|
|
4
|
+
* that length, placed so the area stays `amplitude · width`; without one they're jumps, which
|
|
5
|
+
* the time stepping handles exactly (so a pulse with no rise must start after t = 0, the time a
|
|
6
|
+
* device starts at and solve() reads: it's off then).
|
|
7
|
+
* @param {{ start?: number, width: number, amplitude: number, rise?: number, base?: number }} opts s, s, V or A/m², s, V or A/m²
|
|
8
|
+
* @returns {{ t: number[], values: number[] }}
|
|
9
|
+
*/
|
|
10
|
+
export function pulse({ start, width, amplitude, rise, base }?: {
|
|
11
|
+
start?: number;
|
|
12
|
+
width: number;
|
|
13
|
+
amplitude: number;
|
|
14
|
+
rise?: number;
|
|
15
|
+
base?: number;
|
|
16
|
+
}): {
|
|
17
|
+
t: number[];
|
|
18
|
+
values: number[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A square wave, repeating: `high` for `duty · period`, then `low`, from t = 0.
|
|
22
|
+
* @param {{ high: number, low: number, period: number, duty?: number }} opts
|
|
23
|
+
* @returns {{ t: number[], values: number[], repeat: true }}
|
|
24
|
+
*/
|
|
25
|
+
export function square({ high, low, period, duty }?: {
|
|
26
|
+
high: number;
|
|
27
|
+
low: number;
|
|
28
|
+
period: number;
|
|
29
|
+
duty?: number;
|
|
30
|
+
}): {
|
|
31
|
+
t: number[];
|
|
32
|
+
values: number[];
|
|
33
|
+
repeat: true;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* A triangle wave, repeating: from `from` to `to` and back in each `period`, from t = 0 (a
|
|
37
|
+
* cyclic voltammogram's sweep, from its starting potential).
|
|
38
|
+
* @param {{ from: number, to: number, period: number }} opts
|
|
39
|
+
* @returns {{ t: number[], values: number[], repeat: true }}
|
|
40
|
+
*/
|
|
41
|
+
export function triangle({ from, to, period }?: {
|
|
42
|
+
from: number;
|
|
43
|
+
to: number;
|
|
44
|
+
period: number;
|
|
45
|
+
}): {
|
|
46
|
+
t: number[];
|
|
47
|
+
values: number[];
|
|
48
|
+
repeat: true;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A ramp from `from` to `to` over `duration`, starting at `start`, constant on either side.
|
|
52
|
+
* @param {{ from: number, to: number, duration: number, start?: number }} opts
|
|
53
|
+
* @returns {{ t: number[], values: number[] }}
|
|
54
|
+
*/
|
|
55
|
+
export function ramp({ from, to, duration, start }?: {
|
|
56
|
+
from: number;
|
|
57
|
+
to: number;
|
|
58
|
+
duration: number;
|
|
59
|
+
start?: number;
|
|
60
|
+
}): {
|
|
61
|
+
t: number[];
|
|
62
|
+
values: number[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* A port that injects a species into a window of a region at a driven current `I` (A/m², a
|
|
66
|
+
* number or a waveform), spread evenly over the window. It's an ordinary port: driven by `I`,
|
|
67
|
+
* its terminal the species, linked by a conductance small enough that at the peak current the
|
|
68
|
+
* port sits `headroom` volts above the window's level of that species, so every node of the
|
|
69
|
+
* window takes the same share (like a current source). At I = 0 it still links the window,
|
|
70
|
+
* weakly.
|
|
71
|
+
* @param {{ name?: string, region: string | number, from: number, to: number, species: string,
|
|
72
|
+
* I: number | { t: number[], values: number[], repeat?: boolean }, headroom?: number }} opts
|
|
73
|
+
* @returns {object} a port, for the definition's `ports`
|
|
74
|
+
*/
|
|
75
|
+
export function injector({ name, region, from, to, species, I, headroom }?: {
|
|
76
|
+
name?: string;
|
|
77
|
+
region: string | number;
|
|
78
|
+
from: number;
|
|
79
|
+
to: number;
|
|
80
|
+
species: string;
|
|
81
|
+
I: number | {
|
|
82
|
+
t: number[];
|
|
83
|
+
values: number[];
|
|
84
|
+
repeat?: boolean;
|
|
85
|
+
};
|
|
86
|
+
headroom?: number;
|
|
87
|
+
}): object;
|
|
88
|
+
/**
|
|
89
|
+
* Band-to-band recombination e⁻ + h⁺ ⇌ 0 in a material, from the minority-carrier lifetime it
|
|
90
|
+
* should give at a majority density: kf = 1/(τ · majority). (The rate is kf (np − n_i²), so τ is
|
|
91
|
+
* the low-injection lifetime of whichever carrier is the minority.)
|
|
92
|
+
* @param {{ material: string, tau: number, majority: number }} opts material name, s, mol/m³
|
|
93
|
+
* @returns {{ equation: string, kf: Record<string, number> }} a bulk reaction
|
|
94
|
+
*/
|
|
95
|
+
export function recombination({ material, tau, majority }?: {
|
|
96
|
+
material: string;
|
|
97
|
+
tau: number;
|
|
98
|
+
majority: number;
|
|
99
|
+
}): {
|
|
100
|
+
equation: string;
|
|
101
|
+
kf: Record<string, number>;
|
|
102
|
+
};
|
package/types/types.d.ts
CHANGED
|
@@ -130,10 +130,14 @@ export type RegionDef = {
|
|
|
130
130
|
*/
|
|
131
131
|
fixedCharge?: number;
|
|
132
132
|
/**
|
|
133
|
-
* initial concentrations,
|
|
134
|
-
* not connected to a contact: it fixes the amount they conserve)
|
|
133
|
+
* initial concentrations,
|
|
134
|
+
* mol/m³ (required for species not connected to a contact: it fixes the amount they conserve);
|
|
135
|
+
* or a profile against the device's x (m), piecewise linear; either is the starting state
|
|
135
136
|
*/
|
|
136
|
-
c0?: Record<string, number
|
|
137
|
+
c0?: Record<string, number | {
|
|
138
|
+
x: number[];
|
|
139
|
+
c: number[];
|
|
140
|
+
}>;
|
|
137
141
|
/**
|
|
138
142
|
* imposed flow toward +x, m/s, carrying every mobile species
|
|
139
143
|
*/
|
|
@@ -538,13 +542,15 @@ export type Solution = {
|
|
|
538
542
|
*/
|
|
539
543
|
rejected?: number;
|
|
540
544
|
/**
|
|
541
|
-
* advance():
|
|
542
|
-
* current (A/m², toward +x) and voltage after each accepted step
|
|
545
|
+
* advance():
|
|
546
|
+
* terminal current (A/m², toward +x) and voltage after each accepted step, and each probe's
|
|
547
|
+
* reading (mol/m³, or V for quantity 'V'), interpolated between the nodes around its x
|
|
543
548
|
*/
|
|
544
549
|
trace?: {
|
|
545
550
|
t: number[];
|
|
546
551
|
current: number[];
|
|
547
552
|
voltage: number[];
|
|
553
|
+
probes?: number[][];
|
|
548
554
|
};
|
|
549
555
|
};
|
|
550
556
|
export type ImpedanceResult = {
|