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.
Files changed (47) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +285 -0
  3. package/llms.txt +299 -0
  4. package/package.json +54 -0
  5. package/src/bernoulli.js +29 -0
  6. package/src/blockTridiagonal.js +492 -0
  7. package/src/constants.js +36 -0
  8. package/src/data.js +127 -0
  9. package/src/describe.js +190 -0
  10. package/src/device.js +954 -0
  11. package/src/equation.js +188 -0
  12. package/src/errors.js +8 -0
  13. package/src/fermi.js +106 -0
  14. package/src/grid.js +111 -0
  15. package/src/index.js +207 -0
  16. package/src/kit.js +76 -0
  17. package/src/live.js +217 -0
  18. package/src/merge.js +11 -0
  19. package/src/plot.js +267 -0
  20. package/src/solution.js +246 -0
  21. package/src/solver.js +2884 -0
  22. package/src/stack.js +172 -0
  23. package/src/statistics.js +593 -0
  24. package/src/traces.js +125 -0
  25. package/src/types.js +221 -0
  26. package/src/worker.js +24 -0
  27. package/types/bernoulli.d.ts +4 -0
  28. package/types/blockTridiagonal.d.ts +92 -0
  29. package/types/constants.d.ts +33 -0
  30. package/types/data.d.ts +73 -0
  31. package/types/describe.d.ts +15 -0
  32. package/types/device.d.ts +20 -0
  33. package/types/equation.d.ts +102 -0
  34. package/types/errors.d.ts +3 -0
  35. package/types/fermi.d.ts +3 -0
  36. package/types/grid.d.ts +28 -0
  37. package/types/index.d.ts +103 -0
  38. package/types/kit.d.ts +61 -0
  39. package/types/live.d.ts +101 -0
  40. package/types/merge.d.ts +1 -0
  41. package/types/plot.d.ts +60 -0
  42. package/types/solution.d.ts +18 -0
  43. package/types/solver.d.ts +342 -0
  44. package/types/stack.d.ts +59 -0
  45. package/types/statistics.d.ts +10 -0
  46. package/types/traces.d.ts +118 -0
  47. package/types/types.d.ts +574 -0
@@ -0,0 +1,574 @@
1
+ export type SpeciesDef = {
2
+ name: string;
3
+ /**
4
+ * charge number (integer; 0 for neutral species)
5
+ */
6
+ z: number;
7
+ /**
8
+ * default reference concentration, mol/m³
9
+ */
10
+ cRef?: number;
11
+ };
12
+ export type MaterialSpeciesDef = {
13
+ /**
14
+ * coefficient in N = −(D c/RT)∇μ̄, m²/s
15
+ */
16
+ D: number;
17
+ /**
18
+ * standard chemical potential, J/mol
19
+ */
20
+ mu0: number;
21
+ /**
22
+ * concentration that mu0 refers to, mol/m³
23
+ */
24
+ cRef?: number;
25
+ };
26
+ /**
27
+ * Statistics model: how the listed species' concentrations follow from their reduced
28
+ * potentials ζ = (μ̄ − zFφ − μ°)/RT. Species not in any model are ideal, c = c_ref e^ζ.
29
+ */
30
+ export type StatisticsDef = ({
31
+ type: "fermi-dirac";
32
+ species: string[];
33
+ order?: 0.5 | 0;
34
+ } | {
35
+ type: "lattice";
36
+ species: string[];
37
+ cMax: number;
38
+ } | {
39
+ type: "redlich-kister";
40
+ species: [string];
41
+ cMax: number;
42
+ A?: number[];
43
+ } | {
44
+ type: "debye-huckel";
45
+ species: string[];
46
+ epsr?: number;
47
+ a?: number;
48
+ } | {
49
+ type: "insertion";
50
+ species: [string, string];
51
+ cMax: number;
52
+ A?: number[];
53
+ ocv?: {
54
+ x: number[];
55
+ E: number[];
56
+ muRef: number;
57
+ };
58
+ } | {
59
+ type: "custom";
60
+ species: string[];
61
+ evaluate: (zeta: number[]) => {
62
+ c: number[];
63
+ dcdzeta: number[][];
64
+ };
65
+ });
66
+ /**
67
+ * A material: either ordinary (epsr, species, optional statistics) or a conductor.
68
+ */
69
+ export type MaterialDef = {
70
+ /**
71
+ * relative permittivity; 0 makes the material strictly neutral
72
+ */
73
+ epsr?: number;
74
+ /**
75
+ * species present in this material
76
+ */
77
+ species?: Record<string, MaterialSpeciesDef>;
78
+ /**
79
+ * non-ideal statistics (default: all ideal)
80
+ */
81
+ statistics?: StatisticsDef[];
82
+ /**
83
+ * a metal or fast ion
84
+ * conductor: its one carrier and conductivity (S/m); its only level is the carrier's (a metal's
85
+ * Fermi level), and φ is undefined inside
86
+ */
87
+ conductor?: {
88
+ species: string;
89
+ conductivity: number;
90
+ };
91
+ };
92
+ export type GridOptions = {
93
+ /**
94
+ * cell size at region ends, m
95
+ */
96
+ hmin?: number;
97
+ /**
98
+ * largest cell size, m
99
+ */
100
+ hmax?: number;
101
+ /**
102
+ * geometric growth ratio (default 1.2)
103
+ */
104
+ ratio?: number;
105
+ /**
106
+ * minimum cells per region (default 8)
107
+ */
108
+ minCells?: number;
109
+ /**
110
+ * left-end cell size, overriding hmin
111
+ */
112
+ hLeft?: number;
113
+ /**
114
+ * right-end cell size, overriding hmin
115
+ */
116
+ hRight?: number;
117
+ };
118
+ export type RegionDef = {
119
+ /**
120
+ * material name
121
+ */
122
+ material: string;
123
+ /**
124
+ * m
125
+ */
126
+ length: number;
127
+ name?: string;
128
+ /**
129
+ * immobile charge density, C/m³
130
+ */
131
+ fixedCharge?: number;
132
+ /**
133
+ * initial concentrations, mol/m³ (required for species
134
+ * not connected to a contact: it fixes the amount they conserve)
135
+ */
136
+ c0?: Record<string, number>;
137
+ /**
138
+ * imposed flow toward +x, m/s, carrying every mobile species
139
+ */
140
+ velocity?: number;
141
+ /**
142
+ * eddy (turbulent) mixing diffusivity, m²/s; current-free
143
+ */
144
+ mixing?: number;
145
+ grid?: GridOptions;
146
+ };
147
+ export type InterfacePhiLaw = "pinned" | "neutral" | {
148
+ type: "capacitive";
149
+ C: number;
150
+ };
151
+ export type InterfaceSpeciesLink = "equilibrium" | "blocked" | {
152
+ type: "conductance";
153
+ G: number;
154
+ };
155
+ /**
156
+ * A reaction at a face: participants on each side with signed stoichiometric coefficients
157
+ * (ν < 0 consumed by the forward reaction), Butler–Volmer kinetics.
158
+ */
159
+ export type FaceReactionDef = {
160
+ /**
161
+ * the reaction as an equation, e.g. 'Ag+ + e- = Ag(s)', each
162
+ * participant on the side that holds it ('Li+(left)' where both do); or give left and right
163
+ */
164
+ equation?: string;
165
+ /**
166
+ * participants on the left side (species present there, or fixed neutrals)
167
+ */
168
+ left?: Record<string, number>;
169
+ /**
170
+ * participants on the right side
171
+ */
172
+ right?: Record<string, number>;
173
+ /**
174
+ * μ (J/mol) of fixed-activity participants that aren't species
175
+ */
176
+ fixed?: Record<string, number>;
177
+ /**
178
+ * standard rate constant, mol/(m²·s)
179
+ */
180
+ k0: number;
181
+ /**
182
+ * transfer coefficient, 0…1 (default 0.5)
183
+ */
184
+ alpha?: number;
185
+ };
186
+ /**
187
+ * One face between consecutive regions. For different materials under a 'pinned' or
188
+ * 'capacitive' law, exactly one alignment (step or dipole) is required.
189
+ */
190
+ export type InterfaceDef = {
191
+ /**
192
+ * standard-level step right − left, J/mol
193
+ */
194
+ step?: {
195
+ species: string;
196
+ value: number;
197
+ };
198
+ /**
199
+ * φ jump right − left, V
200
+ */
201
+ dipole?: number;
202
+ /**
203
+ * beside a conductor region: V_F − φ_edge at zero charge, V
204
+ */
205
+ zeroCharge?: number;
206
+ /**
207
+ * electrostatic law (default 'pinned'; 'neutral' between ε = 0 materials)
208
+ */
209
+ phi?: InterfacePhiLaw;
210
+ /**
211
+ * C/m²
212
+ */
213
+ sheetCharge?: number;
214
+ /**
215
+ * per-species laws (default equilibrium
216
+ * where present on both sides and not reacting at the face)
217
+ */
218
+ species?: Record<string, InterfaceSpeciesLink>;
219
+ /**
220
+ * reactions at the face
221
+ */
222
+ reactions?: FaceReactionDef[];
223
+ };
224
+ export type BulkReactionDef = {
225
+ /**
226
+ * signed stoichiometric coefficients (ν < 0 consumed)
227
+ */
228
+ nu?: Record<string, number>;
229
+ /**
230
+ * the reaction as an equation, e.g. 'e- + h+ = 0' (instead of nu)
231
+ */
232
+ equation?: string;
233
+ /**
234
+ * μ (J/mol) of fixed-activity participants that aren't species
235
+ */
236
+ fixed?: Record<string, number>;
237
+ /**
238
+ * forward rate constant per material name
239
+ */
240
+ kf: Record<string, number>;
241
+ };
242
+ /**
243
+ * Contacts use the same laws as internal faces; the outside is a phase with known levels
244
+ * V_i = V + offset_i (a rigid ladder that the circuit slides by V).
245
+ */
246
+ export type ContactSpeciesLink = "blocked" | "equilibrium" | {
247
+ type: "equilibrium";
248
+ offset?: number;
249
+ mu?: number;
250
+ } | {
251
+ type: "conductance";
252
+ G: number;
253
+ offset?: number;
254
+ } | {
255
+ type: "exchange";
256
+ k: number;
257
+ mu: number;
258
+ };
259
+ /**
260
+ * 'bulk': the end node is plain bulk (locally neutral, no double layer); 'neutral': no charge at
261
+ * the face (D = 0); capacitive: Stern layer or gate; 'pinned': φ_edge = V − zeroCharge. The last
262
+ * two take the contact's zeroCharge.
263
+ */
264
+ export type ContactPhiLink = "bulk" | "neutral" | "pinned" | {
265
+ type: "capacitive";
266
+ C: number;
267
+ };
268
+ export type ContactDef = {
269
+ /**
270
+ * held terminal voltage, V (default 0, if no I)
271
+ */
272
+ V?: Source;
273
+ /**
274
+ * or: the current driven into the device, A/m² (the voltage floats)
275
+ */
276
+ I?: Source;
277
+ /**
278
+ * with V: a series resistance, Ω·m² (a source behind a resistor)
279
+ */
280
+ R?: number;
281
+ /**
282
+ * species whose voltage V is
283
+ */
284
+ terminal?: string;
285
+ /**
286
+ * per-species links (default blocked)
287
+ */
288
+ species?: Record<string, ContactSpeciesLink>;
289
+ /**
290
+ * a neutral
291
+ * composition held at the contact, anchored through a charged reference species
292
+ */
293
+ bath?: {
294
+ c: Record<string, number>;
295
+ reference: string;
296
+ offset?: number;
297
+ };
298
+ /**
299
+ * required when any species connects (default 'neutral')
300
+ */
301
+ phi?: ContactPhiLink;
302
+ /**
303
+ * for a capacitive or pinned law: V − φ_edge at zero charge, V
304
+ */
305
+ zeroCharge?: number;
306
+ };
307
+ /**
308
+ * A terminal's source: a constant, or a piecewise-linear waveform through (t, value), constant
309
+ * beyond the points, or periodic with period t_last − t_0 if repeat is true.
310
+ */
311
+ export type Source = number | {
312
+ t: number[];
313
+ values: number[];
314
+ repeat?: boolean;
315
+ };
316
+ /**
317
+ * An internal port: an outside phase exchanging with a window of one region's nodes. On a
318
+ * conductor region it attaches to the whole conductor (no window), and a conductance G is per area
319
+ * (S/m²) instead of per volume (S/m³).
320
+ */
321
+ export type PortDef = {
322
+ name?: string;
323
+ /**
324
+ * region name or index
325
+ */
326
+ region: string | number;
327
+ /**
328
+ * window start, m from the region's left end (default 0)
329
+ */
330
+ from?: number;
331
+ /**
332
+ * window end, m (default: the region's length)
333
+ */
334
+ to?: number;
335
+ /**
336
+ * held terminal voltage, V (default 0, if no I)
337
+ */
338
+ V?: Source;
339
+ /**
340
+ * or: the current driven into the device, A/m² (e.g. 0 for a reference electrode)
341
+ */
342
+ I?: Source;
343
+ /**
344
+ * with V: a series resistance, Ω·m²
345
+ */
346
+ R?: number;
347
+ /**
348
+ * species whose offset defaults to 0
349
+ */
350
+ terminal?: string;
351
+ species: Record<string, "blocked" | "equilibrium" | {
352
+ type: "equilibrium";
353
+ offset?: number;
354
+ mu?: number;
355
+ } | {
356
+ type: "conductance";
357
+ G: number;
358
+ offset?: number;
359
+ } | {
360
+ type: "exchange";
361
+ k: number;
362
+ mu: number;
363
+ }>;
364
+ };
365
+ /**
366
+ * A device definition: plain, serialisable data.
367
+ */
368
+ export type DeviceDefinition = {
369
+ /**
370
+ * temperature, K (default 298.15)
371
+ */
372
+ T?: number;
373
+ species: SpeciesDef[];
374
+ materials: Record<string, MaterialDef>;
375
+ /**
376
+ * left to right
377
+ */
378
+ regions: RegionDef[];
379
+ /**
380
+ * one per face, interfaces[f] between regions f and f+1
381
+ */
382
+ interfaces?: (InterfaceDef | null | undefined)[];
383
+ bulkReactions?: BulkReactionDef[];
384
+ contacts?: {
385
+ left?: ContactDef;
386
+ right?: ContactDef;
387
+ };
388
+ /**
389
+ * internal ports
390
+ */
391
+ ports?: PortDef[];
392
+ grid?: GridOptions;
393
+ };
394
+ export type ContactResult = {
395
+ /**
396
+ * terminal voltage, V
397
+ */
398
+ V: number;
399
+ /**
400
+ * particle flux toward +x through this contact, mol/(m²·s)
401
+ */
402
+ flux: Record<string, number>;
403
+ /**
404
+ * displacement toward +x at this contact, C/m²
405
+ */
406
+ D: number;
407
+ /**
408
+ * total current toward +x, A/m²
409
+ */
410
+ current: number;
411
+ };
412
+ export type Solution = {
413
+ /**
414
+ * node positions, m (interface positions appear twice)
415
+ */
416
+ x: Float64Array;
417
+ /**
418
+ * region index per node
419
+ */
420
+ region: Int32Array;
421
+ /**
422
+ * the species, in order, with their charge numbers
423
+ */
424
+ species: {
425
+ name: string;
426
+ z: number;
427
+ }[];
428
+ /**
429
+ * each region's name, material and extent, m
430
+ */
431
+ regions: {
432
+ name: string;
433
+ material: string;
434
+ x0: number;
435
+ x1: number;
436
+ }[];
437
+ /**
438
+ * bookkeeping φ, V (NaN where undefined)
439
+ */
440
+ phi: Float64Array;
441
+ /**
442
+ * concentrations, mol/m³ (NaN where absent)
443
+ */
444
+ c: Record<string, Float64Array>;
445
+ /**
446
+ * electrochemical potentials μ̄, J/mol
447
+ */
448
+ mu: Record<string, Float64Array>;
449
+ /**
450
+ * standard levels μ° + zFφ, J/mol
451
+ */
452
+ muStd: Record<string, Float64Array>;
453
+ /**
454
+ * species voltages μ̄/(zF), V (charged species)
455
+ */
456
+ V: Record<string, Float64Array>;
457
+ /**
458
+ * standard levels as voltages, V
459
+ */
460
+ Vstd: Record<string, Float64Array>;
461
+ /**
462
+ * current toward +x through the device, A/m²
463
+ */
464
+ current: number;
465
+ /**
466
+ * V_right − V_left, V
467
+ */
468
+ terminalVoltage: number;
469
+ /**
470
+ * each terminal (left, right,
471
+ * then the ports by name): its voltage, and its current into the device (A/m²)
472
+ */
473
+ terminals: Record<string, {
474
+ V: number;
475
+ current: number;
476
+ }>;
477
+ contacts: {
478
+ left: ContactResult;
479
+ right: ContactResult;
480
+ };
481
+ gates: {
482
+ left?: {
483
+ V: number;
484
+ D: number;
485
+ charge: number;
486
+ };
487
+ right?: {
488
+ V: number;
489
+ D: number;
490
+ charge: number;
491
+ };
492
+ };
493
+ /**
494
+ * what each
495
+ * internal port brings into the device
496
+ */
497
+ ports: {
498
+ name: string;
499
+ V: number;
500
+ flux: Record<string, number>;
501
+ current: number;
502
+ }[];
503
+ interfaces: {
504
+ dipole: number;
505
+ sheetCharge: number;
506
+ D: number;
507
+ N: Record<string, number>;
508
+ rates: number[];
509
+ }[];
510
+ /**
511
+ * total charge in the device, C/m²
512
+ */
513
+ charge: number;
514
+ conservation: {
515
+ species: string;
516
+ regions: number[];
517
+ spectator: boolean;
518
+ connected: boolean;
519
+ reactive: boolean;
520
+ amount: number;
521
+ reference: number;
522
+ intake: number;
523
+ drift: number;
524
+ }[];
525
+ warnings: string[];
526
+ converged: boolean;
527
+ iterations: number;
528
+ /**
529
+ * s
530
+ */
531
+ time: number;
532
+ /**
533
+ * advance(): whether tEnd was reached (false if the frame budget ran out)
534
+ */
535
+ done?: boolean;
536
+ /**
537
+ * advance(): steps rejected by error control or Newton failure
538
+ */
539
+ rejected?: number;
540
+ /**
541
+ * advance(): terminal
542
+ * current (A/m², toward +x) and voltage after each accepted step
543
+ */
544
+ trace?: {
545
+ t: number[];
546
+ current: number[];
547
+ voltage: number[];
548
+ };
549
+ };
550
+ export type ImpedanceResult = {
551
+ /**
552
+ * frequencies, Hz
553
+ */
554
+ f: Float64Array;
555
+ /**
556
+ * impedance −δV/δI, Ω·m²
557
+ */
558
+ Z: {
559
+ re: Float64Array;
560
+ im: Float64Array;
561
+ };
562
+ /**
563
+ * per frequency, per unit excitation (volt, or A/m² in current mode)
564
+ */
565
+ profiles?: {
566
+ phi: ComplexProfile;
567
+ mu: Record<string, ComplexProfile>;
568
+ c: Record<string, ComplexProfile>;
569
+ }[];
570
+ };
571
+ export type ComplexProfile = {
572
+ re: Float64Array;
573
+ im: Float64Array;
574
+ };