driftlet 1.2.4 → 1.3.2
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 +1 -1
- package/docs/conventions.md +8 -3
- package/docs/device.md +38 -9
- package/docs/internals.md +33 -14
- package/docs/numerics.md +65 -15
- package/docs/reliability.md +25 -16
- package/docs/statistics.md +13 -0
- package/llms.txt +11 -8
- package/package.json +1 -1
- package/src/assemble.js +206 -0
- package/src/bernoulli.js +32 -0
- package/src/boundaries.js +795 -0
- package/src/describe.js +2 -0
- package/src/device.js +32 -6
- package/src/impedance.js +857 -0
- package/src/index.js +25 -1
- package/src/newton.js +605 -0
- package/src/regions.js +1009 -0
- package/src/solution.js +24 -2
- package/src/solver.js +178 -3643
- package/src/start.js +508 -0
- package/src/steady.js +817 -0
- package/src/timeSteps.js +17 -2
- package/src/types.js +3 -0
- package/types/assemble.d.ts +18 -0
- package/types/bernoulli.d.ts +9 -0
- package/types/boundaries.d.ts +24 -0
- package/types/impedance.d.ts +53 -0
- package/types/newton.d.ts +7 -0
- package/types/regions.d.ts +61 -0
- package/types/solver.d.ts +14 -220
- package/types/start.d.ts +14 -0
- package/types/steady.d.ts +81 -0
- package/types/types.d.ts +6 -0
package/src/solution.js
CHANGED
|
@@ -239,7 +239,11 @@ export function makeSolution(solver, result = {}) {
|
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
});
|
|
242
|
-
const cond = solver.conditioning, un = solver.unreached, ch = solver.charging;
|
|
242
|
+
const cond = solver.conditioning, un = solver.unreached, ch = solver.charging, lost = result.unsolved ? solver.drifted : null; // (a failed steady solve's: see Device.solve)
|
|
243
|
+
// A failed solve with a reaction that a steady state needs at equilibrium, left far from it (see
|
|
244
|
+
// stuckReactions): one too slow for the steady solve's time steps, which reach ~1e12 of the
|
|
245
|
+
// slowest diffusion time (Y = Z at kf 1e-10/s failed with nothing said).
|
|
246
|
+
const slow = result.unsolved && !ch && !un && !lost ? solver.stuckReactions() : [];
|
|
243
247
|
if (result.converged === false && ch) {
|
|
244
248
|
const A = model.geometry.type === 'planar' ? 'A/m²' : 'A';
|
|
245
249
|
sol.warnings.push(
|
|
@@ -261,6 +265,19 @@ export function makeSolution(solver, result = {}) {
|
|
|
261
265
|
? ' It passes almost nothing steadily at any voltage, so it may only store what comes in (a host filling, a capacitor charging), which has no steady state at a current: advance() in time instead.'
|
|
262
266
|
: ''),
|
|
263
267
|
);
|
|
268
|
+
} else if (lost) {
|
|
269
|
+
sol.warnings.push(
|
|
270
|
+
`the solve did not converge: the amount of ${lost.join(' + ')}, which no row of the steady system keeps (it runs through a species ` +
|
|
271
|
+
'that moves in part of the device only), is kept by time steps alone, and steps long enough for the slowest species lost it to round-off. ' +
|
|
272
|
+
'advance() in time instead, or give the still species a small D where it is still.',
|
|
273
|
+
);
|
|
274
|
+
} else if (slow.length > 0) {
|
|
275
|
+
for (const { where, affinity } of slow) {
|
|
276
|
+
sol.warnings.push(
|
|
277
|
+
`the solve did not converge, likely because ${where} is out of equilibrium by ${(affinity * solver.VT * 1e3).toPrecision(3)} mV of affinity, yet nothing else makes or uses what it changes, so a steady state needs it at equilibrium: ` +
|
|
278
|
+
'it is too slow for the steady solve to wait out. Raise its rate constant (the steady state does not depend on it), or advance() in time.',
|
|
279
|
+
);
|
|
280
|
+
}
|
|
264
281
|
} else if (result.converged === false && cond && cond.digits > 12) {
|
|
265
282
|
const digits = Number.isFinite(cond.digits) ? `lost ${cond.digits.toFixed(0)} of its ~16 digits` : 'was exactly singular';
|
|
266
283
|
// An ion there so scarce beside the others (a minority swept out of a junction by a large
|
|
@@ -294,7 +311,12 @@ export function makeSolution(solver, result = {}) {
|
|
|
294
311
|
`the solve did not converge from a start far from equilibrium: ${solver.violent.join('; ')}, its double layer uncharged. ` +
|
|
295
312
|
'Hold that terminal at a voltage first, solve(), then let it float (set its I: 0): it keeps the state the held one gave it.',
|
|
296
313
|
);
|
|
297
|
-
} else if (result.converged === false && !result.stopped && !un && !ch && !(cond && cond.digits > 12)) {
|
|
314
|
+
} else if (result.converged === false && !result.stopped && !un && !ch && !lost && slow.length === 0 && !(cond && cond.digits > 12) && solver.modelError) {
|
|
315
|
+
sol.warnings.push(
|
|
316
|
+
`the solve did not converge: the states it reached were refused by a statistics model: ${solver.modelError}. ` +
|
|
317
|
+
'The model doesn\'t hold there: a smaller concentration or drive, or a model for it (lattice for crowding).',
|
|
318
|
+
);
|
|
319
|
+
} else if (result.converged === false && !result.stopped && !un && !ch && !lost && slow.length === 0 && !(cond && cond.digits > 12)) {
|
|
298
320
|
sol.warnings.push(
|
|
299
321
|
'the solve did not converge, and nothing specific showed why. ' +
|
|
300
322
|
'Check the definition with describe() (from driftlet/kit); approach this state in smaller steps (a sweep, or advance() in time); or refine the grid.',
|