diff-grok 1.0.10 → 1.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/.claude/settings.local.json +11 -0
- package/CLAUDE.md +98 -0
- package/README.MD +100 -24
- package/images/E5.png +0 -0
- package/images/HIRES.png +0 -0
- package/images/OREGO.png +0 -0
- package/images/POLL-full.png +0 -0
- package/images/ROBER.png +0 -0
- package/images/VDP0L.png +0 -0
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/index.ts +2 -1
- package/jest.config.js +1 -0
- package/package.json +1 -1
- package/src/examples/bioreactor.js +125 -0
- package/src/examples/bioreactor.js.map +1 -0
- package/src/examples/bioreactor.ts +132 -0
- package/src/examples/cyclic-model.js +3 -1
- package/src/examples/cyclic-model.js.map +1 -1
- package/src/examples/cyclic-model.ts +3 -1
- package/src/solver-tools/ab4-method.js +332 -0
- package/src/solver-tools/ab4-method.js.map +1 -0
- package/src/solver-tools/ab4-method.ts +395 -0
- package/src/solver-tools/ab5-method.js +334 -0
- package/src/solver-tools/ab5-method.js.map +1 -0
- package/src/solver-tools/ab5-method.ts +397 -0
- package/src/solver-tools/index.js +6 -0
- package/src/solver-tools/index.js.map +1 -1
- package/src/solver-tools/index.ts +6 -0
- package/src/solver-tools/lsoda/blas.js +246 -0
- package/src/solver-tools/lsoda/blas.js.map +1 -0
- package/src/solver-tools/lsoda/blas.ts +267 -0
- package/src/solver-tools/lsoda/cfode.js +73 -0
- package/src/solver-tools/lsoda/cfode.js.map +1 -0
- package/src/solver-tools/lsoda/cfode.ts +83 -0
- package/src/solver-tools/lsoda/common.js +94 -0
- package/src/solver-tools/lsoda/common.js.map +1 -0
- package/src/solver-tools/lsoda/common.ts +135 -0
- package/src/solver-tools/lsoda/corfailure.js +25 -0
- package/src/solver-tools/lsoda/corfailure.js.map +1 -0
- package/src/solver-tools/lsoda/corfailure.ts +30 -0
- package/src/solver-tools/lsoda/correction.js +101 -0
- package/src/solver-tools/lsoda/correction.js.map +1 -0
- package/src/solver-tools/lsoda/correction.ts +119 -0
- package/src/solver-tools/lsoda/dense.js +110 -0
- package/src/solver-tools/lsoda/dense.js.map +1 -0
- package/src/solver-tools/lsoda/dense.ts +129 -0
- package/src/solver-tools/lsoda/index.js +4 -0
- package/src/solver-tools/lsoda/index.js.map +1 -0
- package/src/solver-tools/lsoda/index.ts +5 -0
- package/src/solver-tools/lsoda/intdy.js +43 -0
- package/src/solver-tools/lsoda/intdy.js.map +1 -0
- package/src/solver-tools/lsoda/intdy.ts +50 -0
- package/src/solver-tools/lsoda/lsoda.js +567 -0
- package/src/solver-tools/lsoda/lsoda.js.map +1 -0
- package/src/solver-tools/lsoda/lsoda.ts +632 -0
- package/src/solver-tools/lsoda/methodswitch.js +97 -0
- package/src/solver-tools/lsoda/methodswitch.js.map +1 -0
- package/src/solver-tools/lsoda/methodswitch.ts +107 -0
- package/src/solver-tools/lsoda/orderswitch.js +86 -0
- package/src/solver-tools/lsoda/orderswitch.js.map +1 -0
- package/src/solver-tools/lsoda/orderswitch.ts +95 -0
- package/src/solver-tools/lsoda/prja.js +43 -0
- package/src/solver-tools/lsoda/prja.js.map +1 -0
- package/src/solver-tools/lsoda/prja.ts +49 -0
- package/src/solver-tools/lsoda/scaleh.js +30 -0
- package/src/solver-tools/lsoda/scaleh.js.map +1 -0
- package/src/solver-tools/lsoda/scaleh.ts +33 -0
- package/src/solver-tools/lsoda/solsy.js +14 -0
- package/src/solver-tools/lsoda/solsy.js.map +1 -0
- package/src/solver-tools/lsoda/solsy.ts +18 -0
- package/src/solver-tools/lsoda/stoda.js +259 -0
- package/src/solver-tools/lsoda/stoda.js.map +1 -0
- package/src/solver-tools/lsoda/stoda.ts +286 -0
- package/src/solver-tools/lsoda-method.js +120 -0
- package/src/solver-tools/lsoda-method.js.map +1 -0
- package/src/solver-tools/lsoda-method.ts +136 -0
- package/src/solver-tools/mrt-method.js +81 -18
- package/src/solver-tools/mrt-method.js.map +1 -1
- package/src/solver-tools/mrt-method.ts +111 -21
- package/src/solver-tools/rk3-method.js +210 -0
- package/src/solver-tools/rk3-method.js.map +1 -0
- package/src/solver-tools/rk3-method.ts +257 -0
- package/src/solver-tools/rk4-method.js +236 -0
- package/src/solver-tools/rk4-method.js.map +1 -0
- package/src/solver-tools/rk4-method.ts +286 -0
- package/src/solver-tools/rkdp-method.js +247 -0
- package/src/solver-tools/rkdp-method.js.map +1 -0
- package/src/solver-tools/rkdp-method.ts +300 -0
- package/src/solver-tools/ros34prw-method.js +1 -1
- package/src/solver-tools/ros34prw-method.js.map +1 -1
- package/src/solver-tools/ros34prw-method.ts +1 -1
- package/src/solver-tools/ros3prw-method.js +1 -1
- package/src/solver-tools/ros3prw-method.js.map +1 -1
- package/src/solver-tools/ros3prw-method.ts +1 -1
- package/src/solver-tools/solver-defs.js +6 -0
- package/src/solver-tools/solver-defs.js.map +1 -1
- package/src/solver-tools/solver-defs.ts +6 -0
- package/src/tests/correctness.test.js +6 -4
- package/src/tests/correctness.test.js.map +1 -1
- package/src/tests/correctness.test.ts +6 -4
- package/src/tests/lsoda-lib-correctness.test.js +223 -0
- package/src/tests/lsoda-lib-correctness.test.js.map +1 -0
- package/src/tests/lsoda-lib-correctness.test.ts +283 -0
- package/src/tests/lsoda-lib-performance.test.js +95 -0
- package/src/tests/lsoda-lib-performance.test.js.map +1 -0
- package/src/tests/lsoda-lib-performance.test.ts +126 -0
- package/src/tests/performance.test.js +10 -8
- package/src/tests/performance.test.js.map +1 -1
- package/src/tests/performance.test.ts +10 -8
- package/src/tests/test-defs.js +14 -1
- package/src/tests/test-defs.js.map +1 -1
- package/src/tests/test-defs.ts +15 -1
- package/src/worker-tools/solving.js +13 -1
- package/src/worker-tools/solving.js.map +1 -1
- package/src/worker-tools/solving.ts +20 -1
- package/docs/.nojekyll +0 -1
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -99
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/classes/BasicModelPipelineCreator.html +0 -10
- package/docs/classes/Callback.html +0 -7
- package/docs/classes/CyclicModelPipelineCreator.html +0 -10
- package/docs/classes/IterCheckerCallback.html +0 -8
- package/docs/classes/PipelineCreator.html +0 -6
- package/docs/classes/TimeCheckerCallback.html +0 -8
- package/docs/classes/UpdatesModelPipelineCreator.html +0 -10
- package/docs/functions/applyPipeline.html +0 -9
- package/docs/functions/getCallback.html +0 -3
- package/docs/functions/getIVP.html +0 -6
- package/docs/functions/getInputVector.html +0 -2
- package/docs/functions/getIvp2WebWorker.html +0 -6
- package/docs/functions/getJScode.html +0 -6
- package/docs/functions/getOutputNames.html +0 -4
- package/docs/functions/getPipelineCreator.html +0 -7
- package/docs/functions/mrt.html +0 -11
- package/docs/functions/printE5.html +0 -76
- package/docs/functions/printHires.html +0 -76
- package/docs/functions/printOrego.html +0 -66
- package/docs/functions/printPollution.html +0 -163
- package/docs/functions/printRobertson.html +0 -60
- package/docs/functions/printVdpol.html +0 -66
- package/docs/functions/ros34prw.html +0 -8
- package/docs/functions/ros3prw.html +0 -8
- package/docs/functions/solveIvp.html +0 -5
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -683
- package/docs/media/CONTRIBUTING.md +0 -74
- package/docs/media/POLL.png +0 -0
- package/docs/media/VDPOL.png +0 -0
- package/docs/media/acid-prod.gif +0 -0
- package/docs/media/basic-use.js +0 -40
- package/docs/media/basic-use.js.map +0 -1
- package/docs/media/basic-use.ts +0 -44
- package/docs/media/check-methods.js +0 -59
- package/docs/media/check-methods.js.map +0 -1
- package/docs/media/check-methods.ts +0 -81
- package/docs/media/corr-probs.js +0 -132
- package/docs/media/corr-probs.js.map +0 -1
- package/docs/media/corr-probs.ts +0 -155
- package/docs/media/cyclic-model.js +0 -100
- package/docs/media/cyclic-model.js.map +0 -1
- package/docs/media/cyclic-model.ts +0 -110
- package/docs/media/e5.js +0 -36
- package/docs/media/e5.js.map +0 -1
- package/docs/media/e5.ts +0 -36
- package/docs/media/hires.js +0 -39
- package/docs/media/hires.js.map +0 -1
- package/docs/media/hires.ts +0 -40
- package/docs/media/model-updates.js +0 -112
- package/docs/media/model-updates.js.map +0 -1
- package/docs/media/model-updates.ts +0 -122
- package/docs/media/orego.js +0 -24
- package/docs/media/orego.js.map +0 -1
- package/docs/media/orego.ts +0 -25
- package/docs/media/pipeline-use.js +0 -87
- package/docs/media/pipeline-use.js.map +0 -1
- package/docs/media/pipeline-use.ts +0 -98
- package/docs/media/pollution.js +0 -132
- package/docs/media/pollution.js.map +0 -1
- package/docs/media/pollution.ts +0 -133
- package/docs/media/print-benchmark.js +0 -581
- package/docs/media/print-benchmark.js.map +0 -1
- package/docs/media/print-benchmark.ts +0 -594
- package/docs/media/robertson.js +0 -19
- package/docs/media/robertson.js.map +0 -1
- package/docs/media/robertson.ts +0 -19
- package/docs/media/scripting.js +0 -30
- package/docs/media/scripting.js.map +0 -1
- package/docs/media/scripting.ts +0 -35
- package/docs/media/vdpol.js +0 -17
- package/docs/media/vdpol.js.map +0 -1
- package/docs/media/vdpol.ts +0 -17
- package/docs/modules.html +0 -1
- package/docs/types/Arg.html +0 -12
- package/docs/types/DifEqs.html +0 -8
- package/docs/types/Func.html +0 -7
- package/docs/types/IVP.html +0 -40
- package/docs/types/IVP2WebWorker.html +0 -12
- package/docs/types/Input.html +0 -8
- package/docs/types/Loop.html +0 -7
- package/docs/types/ODEs.html +0 -31
- package/docs/types/Output.html +0 -6
- package/docs/types/Pipeline.html +0 -6
- package/docs/types/SolverOptions.html +0 -8
- package/docs/types/Update.html +0 -9
- package/docs/types/Wrapper.html +0 -8
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**diff-grok** is a zero-dependency TypeScript library for solving initial value problems (IVPs) for ordinary differential equations (ODEs), focused on stiff equations. It implements Rosenbrock-Wanner type numerical methods and includes a declarative model scripting system.
|
|
8
|
+
|
|
9
|
+
## Build & Development Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install # Install dev dependencies
|
|
13
|
+
npm run build # Compile TypeScript (tsc)
|
|
14
|
+
npm run lint # ESLint check: eslint "./src/**/*.ts"
|
|
15
|
+
npm run lint-fix # Auto-fix lint issues
|
|
16
|
+
npm test # Run Jest test suite
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Run a single test file:
|
|
20
|
+
```bash
|
|
21
|
+
npx jest src/tests/correctness.test.ts
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Module Structure
|
|
27
|
+
|
|
28
|
+
- **`index.ts`** — Single entry point; re-exports everything from the four modules below.
|
|
29
|
+
|
|
30
|
+
- **`src/solver-tools/`** — Core numerical solvers
|
|
31
|
+
- **Implicit methods** (for stiff ODEs): `mrt` (Modified Rosenbrock Triple), `ros3prw`, `ros34prw`
|
|
32
|
+
- Require Jacobian computation and linear system solves
|
|
33
|
+
- Use LU decomposition for solving W*k = b at each stage
|
|
34
|
+
- **Automatic methods** (stiffness-detecting): `lsoda` (variable-order Nordsieck Adams/BDF with automatic switching)
|
|
35
|
+
- Automatically switch between non-stiff (Adams) and stiff (BDF) modes
|
|
36
|
+
- Use consecutive rejection counting (Adams→BDF) and periodic trial steps (BDF→Adams)
|
|
37
|
+
- **Explicit methods** (for non-stiff ODEs): `rk3` (Bogacki-Shampine 3(2)), `rk4` (Runge-Kutta-Fehlberg 4(5)), `ab5` (Adams-Bashforth-Moulton 5), `ab4` (Adams-Bashforth-Moulton 4), `rkdp` (Dormand-Prince 5(4))
|
|
38
|
+
- Only require function evaluations (no Jacobian)
|
|
39
|
+
- Include `hMax` constraint to prevent poor interpolation
|
|
40
|
+
- `ab5` and `ab4` are multistep predictor-corrector methods bootstrapped with RKF45
|
|
41
|
+
- Key types: `ODEs` (problem definition), `Func` (RHS function signature), `SolverMethod`
|
|
42
|
+
- `solver-defs.ts` — Type definitions, adaptive step constants, Jacobian/derivative computation
|
|
43
|
+
- `lin-alg-tools.ts` — Linear algebra routines (LU decomposition, matrix ops)
|
|
44
|
+
- `callbacks/` — Flow control during solving (iteration limits, time limits)
|
|
45
|
+
|
|
46
|
+
- **`src/scripting-tools/`** — Declarative model parsing and JS code generation
|
|
47
|
+
- `scripting-tools.ts` — Main parser: converts model DSL text → `IVP` object → JavaScript code
|
|
48
|
+
- Model DSL uses `#name`, `#equations`, `#argument`, `#inits`, `#parameters`, `#constants`, `#expressions` blocks
|
|
49
|
+
- Entry functions: `getIVP()` (parse model string), `getJScode()` (generate JS from IVP)
|
|
50
|
+
|
|
51
|
+
- **`src/pipeline/`** — Multi-stage simulation orchestration
|
|
52
|
+
- Three pipeline creators for different model types:
|
|
53
|
+
- `BasicModelPipelineCreator` — Single-stage models
|
|
54
|
+
- `CyclicModelPipelineCreator` — Loop/dosing models (PK-PD)
|
|
55
|
+
- `UpdatesModelPipelineCreator` — Multi-stage models with state transitions
|
|
56
|
+
- `applyPipeline()` runs the full computation pipeline
|
|
57
|
+
|
|
58
|
+
- **`src/worker-tools/`** — WebWorker integration for browser parallel computation
|
|
59
|
+
- `getIvp2WebWorker()` serializes IVP for worker transfer; `solveIvp()` runs in worker
|
|
60
|
+
|
|
61
|
+
### Data Flow
|
|
62
|
+
|
|
63
|
+
1. Define problem as `ODEs` object (programmatic) or parse model string via `getIVP()`
|
|
64
|
+
2. Call solver method (`mrt`/`ros3prw`/`ros34prw`/`rk3`/`rk4`/`ab5`/`ab4`/`rkdp`/`lsoda`) → returns `Float64Array[]` (argument values + solution columns)
|
|
65
|
+
3. For complex models: create pipeline via `getPipelineCreator()` → `applyPipeline()`
|
|
66
|
+
|
|
67
|
+
### Performance Patterns
|
|
68
|
+
|
|
69
|
+
- Uses `Float64Array` throughout for memory efficiency
|
|
70
|
+
- Pre-allocated buffers to minimize GC pressure
|
|
71
|
+
- RHS function signature `(t, y, output) => void` writes to pre-allocated output array
|
|
72
|
+
|
|
73
|
+
## Code Style
|
|
74
|
+
|
|
75
|
+
- **ESLint config**: Google style base, 2-space indent, 120 char max line length
|
|
76
|
+
- **Curly braces**: `"multi-or-nest"` — single-statement bodies don't need braces, multi-line do
|
|
77
|
+
- **TypeScript strict mode** enabled
|
|
78
|
+
- Commit messages: `feat:`, `fix:`, `docs:` prefixes (conventional style)
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
Tests are in `src/tests/` using Jest with ts-jest:
|
|
83
|
+
- `correctness.test.ts` — Validates solver accuracy against reference solutions (threshold: MAX_MAD = 0.1)
|
|
84
|
+
- Tests all methods (implicit + explicit + automatic) against 6 problems with known exact solutions (11 methods total)
|
|
85
|
+
- 3 non-stiff problems (1D, 2D, 3D) + 3 stiff problems (1D, 2D, 3D)
|
|
86
|
+
- `performance.test.ts` — Benchmarks solver speed on stiff problems (timeout: 10,000ms)
|
|
87
|
+
- Tests implicit and automatic methods (MRT, ROS3PRw, ROS34PRw, LSODA)
|
|
88
|
+
- Test problems: Robertson, HIRES, VDPOL, OREGO, E5, Pollution
|
|
89
|
+
- `pipeline.test.ts` — Pipeline integration tests (3 model types)
|
|
90
|
+
- Method definitions in `test-defs.ts`: `methods` map (all 11 solvers), `implicitMethods` map (stiff-capable only)
|
|
91
|
+
|
|
92
|
+
## Key Types
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
type Func = (t: number, y: Float64Array, output: Float64Array) => void;
|
|
96
|
+
type ODEs = { name, arg: {name, start, finish, step}, initial, func: Func, tolerance, solutionColNames };
|
|
97
|
+
type SolverMethod = (odes: ODEs, callback?: Callback) => Float64Array[];
|
|
98
|
+
```
|
package/README.MD
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
# Diff Grok
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://doi.org/10.5281/zenodo.17974378)
|
|
4
|
+
[](https://datagrok-ai.github.io/diff-grok/)
|
|
5
|
+
[](https://github.com/datagrok-ai/diff-grok/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/datagrok-ai/diff-grok/actions/workflows/libraries.yaml)
|
|
7
|
+
[](https://github.com/datagrok-ai/diff-grok/actions/workflows/test.yaml)
|
|
8
|
+
|
|
9
|
+
A lightweight TypeScript library for solving initial value problem ([IVP](https://en.wikipedia.org/wiki/Initial_value_problem)) for ordinary differential equations ([ODEs](https://en.wikipedia.org/wiki/Ordinary_differential_equation)) using numerical methods. The primary solver is [LSODA](https://doi.org/10.1137/0904010) — a variable-order method that automatically detects stiffness and switches between Adams (non-stiff) and BDF (stiff) formulations.
|
|
4
10
|
|
|
5
11
|
## Features
|
|
6
12
|
|
|
7
13
|
* Solving both [stiff](https://en.wikipedia.org/wiki/Stiff_equation) and non-stiff equations
|
|
8
14
|
* Fast computations
|
|
9
|
-
*
|
|
15
|
+
* Automatic stiffness-detecting method:
|
|
16
|
+
* [LSODA](https://doi.org/10.1137/0904010) - variable-order Nordsieck-based solver with automatic switching between Adams (non-stiff) and BDF (stiff) methods ([Petzold, 1983](https://doi.org/10.1137/0904010); [Hindmarsh, 1983](https://computing.llnl.gov/sites/default/files/ODEPACK_pub1_u88007.pdf)). Ported to TypeScript from the C library [liblsoda](https://github.com/sdwfrost/liblsoda)
|
|
17
|
+
* Implicit methods (for stiff ODEs) - Rosenbrock–Wanner type:
|
|
10
18
|
* The modified Rosenbrock triple ([MRT](https://doi.org/10.1137/S1064827594276424))
|
|
11
19
|
* The [ROS3PRw](https://doi.org/10.1016/j.cam.2015.03.010) method
|
|
12
20
|
* The [ROS34PRw](https://doi.org/10.1016/j.cam.2015.03.010) method
|
|
21
|
+
* Explicit methods (for non-stiff ODEs):
|
|
22
|
+
* Runge-Kutta type:
|
|
23
|
+
* The Bogacki-Shampine 3(2) method ([RK3](https://en.wikipedia.org/wiki/Bogacki%E2%80%93Shampine_method))
|
|
24
|
+
* The Runge-Kutta-Fehlberg method ([RK4](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method))
|
|
25
|
+
* The Dormand-Prince 5(4) method ([RKDP](https://en.wikipedia.org/wiki/Dormand%E2%80%93Prince_method))
|
|
26
|
+
* Adams-Bashforth type:
|
|
27
|
+
* The predictor-corrector method of order 4 ([AB4](https://en.wikipedia.org/wiki/Linear_multistep_method))
|
|
28
|
+
* The predictor-corrector method of order 5 ([AB5](https://en.wikipedia.org/wiki/Linear_multistep_method))
|
|
13
29
|
* Scripting:
|
|
14
30
|
* declarative specification of models
|
|
15
31
|
* auto-generated JavaScript code
|
|
@@ -61,10 +77,23 @@ on the segment $[t_0, t_1]$ with the step $h$:
|
|
|
61
77
|
|
|
62
78
|
1. Import `ODEs` and a desired numerical method:
|
|
63
79
|
|
|
80
|
+
Automatic method:
|
|
81
|
+
* `lsoda` - [LSODA](https://doi.org/10.1137/0904010) variable-order solver with automatic switching between Adams (non-stiff) and BDF (stiff)
|
|
82
|
+
|
|
83
|
+
Implicit methods (for stiff ODEs):
|
|
64
84
|
* `mrt` - the [MRT](https://doi.org/10.1137/S1064827594276424) method
|
|
65
85
|
* `ros3prw`- the [ROS3PRw](https://doi.org/10.1016/j.cam.2015.03.010) method
|
|
66
86
|
* `ros34prw` - the [ROS34PRw](https://doi.org/10.1016/j.cam.2015.03.010) method
|
|
67
87
|
|
|
88
|
+
Explicit methods (for non-stiff ODEs) — Runge-Kutta type:
|
|
89
|
+
* `rk3` - the Bogacki-Shampine 3(2) method
|
|
90
|
+
* `rk4` - the Runge-Kutta-Fehlberg 4(5) method
|
|
91
|
+
* `rkdp` - the Dormand-Prince 5(4) method
|
|
92
|
+
|
|
93
|
+
Explicit methods (for non-stiff ODEs) — Adams-Bashforth type:
|
|
94
|
+
* `ab4` - the predictor-corrector method of order 4
|
|
95
|
+
* `ab5` - the predictor-corrector method of order 5
|
|
96
|
+
|
|
68
97
|
2. Specify `ODEs` object that defines a problem:
|
|
69
98
|
|
|
70
99
|
* `name` - name of a model
|
|
@@ -97,10 +126,10 @@ x(0) = 1 \\
|
|
|
97
126
|
y(0) = -1
|
|
98
127
|
\end{cases}$$
|
|
99
128
|
|
|
100
|
-
To solve it on the segment $[0, 2]$ with the step $0.01$ using
|
|
129
|
+
To solve it on the segment $[0, 2]$ with the step $0.01$ using [LSODA](https://doi.org/10.1137/0904010) with the tolerance $10^{-7}$, we start with imports:
|
|
101
130
|
|
|
102
131
|
```typescript
|
|
103
|
-
import {ODEs,
|
|
132
|
+
import {ODEs, lsoda} from 'diff-grok';
|
|
104
133
|
```
|
|
105
134
|
|
|
106
135
|
Next, we create
|
|
@@ -127,7 +156,7 @@ const task: ODEs = {
|
|
|
127
156
|
Finally, we call the specified numerical method to solve `task`:
|
|
128
157
|
|
|
129
158
|
```typescript
|
|
130
|
-
const solution =
|
|
159
|
+
const solution = lsoda(task);
|
|
131
160
|
```
|
|
132
161
|
|
|
133
162
|
Currently, `solution` contains:
|
|
@@ -167,38 +196,70 @@ The following [classic problems](https://archimede.uniba.it/~testset/testsetivps
|
|
|
167
196
|
* describes a chemical reaction part of the air pollution model designed at The Dutch National Institute of Public Health and Environmental Protection
|
|
168
197
|
* [pollution.ts](./src/examples/pollution.ts)
|
|
169
198
|
|
|
170
|
-
The MRT, ROS3PRw and ROS34PRw methods demonstrate the following time performance (AMD Ryzen 5 5600H 3.30 GHz CPU):
|
|
199
|
+
The LSODA, MRT, ROS3PRw and ROS34PRw methods demonstrate the following time performance (AMD Ryzen 5 5600H 3.30 GHz CPU):
|
|
171
200
|
|
|
172
|
-
|Problem|Segment|Points|Tolerance|MRT, ms|ROS3PRw, ms|ROS34PRw, ms|
|
|
173
|
-
|
|
174
|
-
|[Rober](https://archimede.uniba.it/~testset/report/rober.pdf)|[0, 10E+11]|40K|1E-7|
|
|
175
|
-
|[HIRES](https://archimede.uniba.it/~testset/report/hires.pdf)|[0, 321.8122]|32K|1E-10|
|
|
176
|
-
|[VDPOL](https://archimede.uniba.it/~testset/report/vdpol.pdf)|[0, 2000]|20K|1E-12|
|
|
177
|
-
|[OREGO](https://archimede.uniba.it/~testset/report/orego.pdf)|[0, 360]|36K|1E-8|
|
|
178
|
-
|[E5](https://archimede.uniba.it/~testset/report/e5.pdf)|[0, 10E+13]|40K|1E-6|
|
|
179
|
-
|[Pollution](https://archimede.uniba.it/~testset/report/pollu.pdf)|[0, 60]|30K|1E-6|
|
|
201
|
+
|Problem|Segment|Points|Tolerance|LSODA, ms|MRT, ms|ROS3PRw, ms|ROS34PRw, ms|
|
|
202
|
+
|-|-|-|-|-|-|-|-|
|
|
203
|
+
|[Rober](https://archimede.uniba.it/~testset/report/rober.pdf)|[0, 10E+11]|40K|1E-7|67|175|446|285|
|
|
204
|
+
|[HIRES](https://archimede.uniba.it/~testset/report/hires.pdf)|[0, 321.8122]|32K|1E-10|125|122|362|215|
|
|
205
|
+
|[VDPOL](https://archimede.uniba.it/~testset/report/vdpol.pdf)|[0, 2000]|20K|1E-12|268|492|1576|760|
|
|
206
|
+
|[OREGO](https://archimede.uniba.it/~testset/report/orego.pdf)|[0, 360]|36K|1E-8|76|205|483|199|
|
|
207
|
+
|[E5](https://archimede.uniba.it/~testset/report/e5.pdf)|[0, 10E+13]|40K|1E-6|7|6|17|8|
|
|
208
|
+
|[Pollution](https://archimede.uniba.it/~testset/report/pollu.pdf)|[0, 60]|30K|1E-6|12|18|50|23|
|
|
180
209
|
|
|
181
210
|
Maximum absolute deviations (MADs) from the reference solutions obtained using SciPy (Radau) are summarized in the table below:
|
|
182
211
|
|
|
183
|
-
|Problem|MRT|ROS3PRw|ROS34PRw|
|
|
184
|
-
|
|
185
|
-
|[Rober](https://archimede.uniba.it/~testset/report/rober.pdf)|1.87e-8|1.88e-8|1.88e-8|
|
|
186
|
-
|[HIRES](https://archimede.uniba.it/~testset/report/hires.pdf)|4.80e-11|1.05e-14|2.87e-14|
|
|
187
|
-
|[VDPOL](https://archimede.uniba.it/~testset/report/vdpol.pdf)|5.12e-4|5.12e-4|5.12e-4|
|
|
188
|
-
|[OREGO](https://archimede.uniba.it/~testset/report/orego.pdf)|3.05e-5|3.45e-7|2.31e-6|
|
|
189
|
-
|[E5](https://archimede.uniba.it/~testset/report/e5.pdf)|1.12e-19| 1.33e-19|3.40e-17|
|
|
190
|
-
|[Pollution](https://archimede.uniba.it/~testset/report/pollu.pdf)|4.06e-10|9.16e-12|1.58e-10|
|
|
212
|
+
|Problem|LSODA|MRT|ROS3PRw|ROS34PRw|
|
|
213
|
+
|-|-|-|-|-|
|
|
214
|
+
|[Rober](https://archimede.uniba.it/~testset/report/rober.pdf)|1.87e-8|1.87e-8|1.88e-8|1.88e-8|
|
|
215
|
+
|[HIRES](https://archimede.uniba.it/~testset/report/hires.pdf)|1.51e-11|4.80e-11|1.05e-14|2.87e-14|
|
|
216
|
+
|[VDPOL](https://archimede.uniba.it/~testset/report/vdpol.pdf)|5.12e-4|5.12e-4|5.12e-4|5.12e-4|
|
|
217
|
+
|[OREGO](https://archimede.uniba.it/~testset/report/orego.pdf)|3.84e-6|3.05e-5|3.45e-7|2.31e-6|
|
|
218
|
+
|[E5](https://archimede.uniba.it/~testset/report/e5.pdf)|3.02e-19|1.12e-19| 1.33e-19|3.40e-17|
|
|
219
|
+
|[Pollution](https://archimede.uniba.it/~testset/report/pollu.pdf)|1.23e-10|4.06e-10|9.16e-12|1.58e-10|
|
|
191
220
|
|
|
192
221
|
Run [check-methods.ts](./src/examples/check-methods.ts) to reproduce these results (see [here](#examples) how to run scripts standalone).
|
|
193
222
|
|
|
194
223
|
The following charts compare the Diff Grok and Radau solutions for the **van der Pol** system:
|
|
195
224
|
|
|
196
|
-

|
|
197
226
|
|
|
198
227
|
The following graphs present a comparison of the Diff Grok and Radau solutions for the **Pollution** model, highlighting a portion of the functions:
|
|
199
228
|
|
|
200
229
|

|
|
201
230
|
|
|
231
|
+
<details>
|
|
232
|
+
<summary><strong>Gallery</strong></summary>
|
|
233
|
+
|
|
234
|
+
**VDPOL**
|
|
235
|
+
|
|
236
|
+

|
|
237
|
+
|
|
238
|
+
**HIRES**
|
|
239
|
+
|
|
240
|
+

|
|
241
|
+
|
|
242
|
+
**E5**
|
|
243
|
+
|
|
244
|
+

|
|
245
|
+
|
|
246
|
+
**POLL**
|
|
247
|
+
|
|
248
|
+

|
|
249
|
+
|
|
250
|
+
**OREGO**
|
|
251
|
+
|
|
252
|
+

|
|
253
|
+
|
|
254
|
+
**Rober**
|
|
255
|
+
|
|
256
|
+

|
|
257
|
+
|
|
258
|
+
</details>
|
|
259
|
+
|
|
260
|
+
<details>
|
|
261
|
+
<summary><strong>Run benchmarks</strong></summary>
|
|
262
|
+
|
|
202
263
|
Run benchmark models and find the reference solutions via the following links to the [Datagrok](https://public.datagrok.ai) platform:
|
|
203
264
|
|
|
204
265
|
|Problem|Diff Grok|Radau|
|
|
@@ -212,6 +273,8 @@ Run benchmark models and find the reference solutions via the following links to
|
|
|
212
273
|
|
|
213
274
|
In the file [print-benchmark.ts](./src/examples/print-benchmark.ts), you can find standalone functions that print the solutions of these problems to the console, as well as Python scripts for computing the solutions using SciPy.
|
|
214
275
|
|
|
276
|
+
</details>
|
|
277
|
+
|
|
215
278
|
## Scripting
|
|
216
279
|
|
|
217
280
|
The library provides tools for declarative specifying models defined by IVPs. This feature enables a development of "no-code" modeling tools seamlessly integrated with the [Datagrok](https://datagrok.ai) platform.
|
|
@@ -522,7 +585,7 @@ Diff Grok contains a set of examples located in the folder [src/examples](./src/
|
|
|
522
585
|
|
|
523
586
|
|File|Features|
|
|
524
587
|
|-|-|
|
|
525
|
-
|[basic-use.ts](./src/examples/basic-use.ts)|Minimal "Hello World" example. Illustrates the use of the [
|
|
588
|
+
|[basic-use.ts](./src/examples/basic-use.ts)|Minimal "Hello World" example. Illustrates the use of the [LSODA](https://doi.org/10.1137/0904010) method.|
|
|
526
589
|
|[check-methods.ts](./src/examples/check-methods.ts)| Checks the [performance](#performance) of numerical methods.|
|
|
527
590
|
|[corr-probs.ts](./src/examples/corr-probs.ts)|Solves a set of problems with exact solutions and evaluate the deviation.|
|
|
528
591
|
|[cyclic-model.ts](./src/examples/cyclic-model.ts)| Considers pharmacokinetic-pharmacodynamic (PK-PD) simulation and shows how to apply pipelines and cyclic models.|
|
|
@@ -530,6 +593,9 @@ Diff Grok contains a set of examples located in the folder [src/examples](./src/
|
|
|
530
593
|
|[pipeline-use.ts](./src/examples/pipeline-use.ts)|Considers modeling queues and shows shows how to apply pipelines and models with customized outputs.|
|
|
531
594
|
|[scripting.ts](./src/examples/scripting.ts)|Shows how to generate JS-script from Diff Grok model.|
|
|
532
595
|
|
|
596
|
+
<details>
|
|
597
|
+
<summary><strong>Run examples</strong></summary>
|
|
598
|
+
|
|
533
599
|
To run examples standalone:
|
|
534
600
|
|
|
535
601
|
1. Install TypeScript locally. If your project does not already include TypeScript:
|
|
@@ -567,6 +633,16 @@ tsc src/examples/basic-use.ts
|
|
|
567
633
|
node src/examples/basic-use.js
|
|
568
634
|
```
|
|
569
635
|
|
|
636
|
+
</details>
|
|
637
|
+
|
|
638
|
+
## References
|
|
639
|
+
|
|
640
|
+
* L. Petzold, "Automatic Selection of Methods for Solving Stiff and Nonstiff Systems of Ordinary Differential Equations," *SIAM J. Sci. Stat. Comput.*, 4(1), 136–148, 1983. [doi:10.1137/0904010](https://doi.org/10.1137/0904010)
|
|
641
|
+
* A. C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE Solvers," *Scientific Computing*, R. S. Stepleman et al. (eds.), North-Holland, Amsterdam, pp. 55–64, 1983. [link](https://computing.llnl.gov/sites/default/files/ODEPACK_pub1_u88007.pdf)
|
|
642
|
+
* The LSODA solver is ported to TypeScript from the C library [liblsoda](https://github.com/sdwfrost/liblsoda)
|
|
643
|
+
* T. Rang and L. Angermann, "New Rosenbrock W-Methods of Order 3 for Partial Differential Algebraic Equations of Index 1," *BIT Numer. Math.*, 45, 761–787, 2005. [doi:10.1007/s10543-005-0035-y](https://doi.org/10.1016/j.cam.2015.03.010)
|
|
644
|
+
* E. Hairer and G. Wanner, *Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems*, Springer, 1996. [doi:10.1137/S1064827594276424](https://doi.org/10.1137/S1064827594276424)
|
|
645
|
+
|
|
570
646
|
## Contributing
|
|
571
647
|
|
|
572
648
|
We welcome contributions of all kinds - bug reports, feature requests, documentation updates, and pull requests.
|
package/images/E5.png
ADDED
|
Binary file
|
package/images/HIRES.png
ADDED
|
Binary file
|
package/images/OREGO.png
ADDED
|
Binary file
|
|
Binary file
|
package/images/ROBER.png
ADDED
|
Binary file
|
package/images/VDP0L.png
ADDED
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { mrt, ros3prw, ros34prw, CallbackAction, DEFAULT_OPTIONS, getCallback, Callback, IterCheckerCallback, TimeCheckerCallback } from './src/solver-tools';
|
|
1
|
+
export { mrt, ros3prw, ros34prw, rk4, ab5, ab4, rkdp, rk3, lsoda, CallbackAction, DEFAULT_OPTIONS, getCallback, Callback, IterCheckerCallback, TimeCheckerCallback } from './src/solver-tools';
|
|
2
2
|
export { perfProbs, corrProbs, refPoints, printRobertson, printHires, printOrego, printE5, printVdpol, printPollution } from './src/examples';
|
|
3
3
|
export { DF_NAME, CONTROL_EXPR, MAX_LINE_CHART, getIVP, getScriptLines, getScriptParams, getJScode, SCRIPTING, BRACE_OPEN, BRACE_CLOSE, BRACKET_OPEN, BRACKET_CLOSE, ANNOT_SEPAR, CONTROL_SEP, STAGE_COL_NAME, ARG_INPUT_KEYS, DEFAULT_SOLVER_SETTINGS, ModelError, getFunc4worker } from './src/scripting-tools';
|
|
4
4
|
export { getIvp2WebWorker, solveIvp } from './src/worker-tools';
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EACzE,cAAc,EAAE,eAAe,EAC/B,WAAW,EAAgB,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAE3G,OAAO,EAAC,SAAS,EAAE,SAAS,EAAe,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAC1F,OAAO,EAAE,UAAU,EAAE,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAC3E,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAChG,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,uBAAuB,EAAE,UAAU,EAChF,cAAc,EAA4B,MAAM,uBAAuB,CAAC;AAE1E,OAAO,EAAgB,gBAAgB,EAAE,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAoB,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EACtF,yBAAyB,EAAE,cAAc,EAAE,kBAAkB,EAAE,0BAA0B,EACzF,2BAA2B,EAAC,MAAM,gBAAgB,CAAC"}
|
package/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export {Func, ODEs, mrt, ros3prw, ros34prw,
|
|
1
|
+
export {Func, ODEs, mrt, ros3prw, ros34prw, rk4, ab5, ab4, rkdp, rk3, lsoda,
|
|
2
|
+
CallbackAction, DEFAULT_OPTIONS, SolverOptions,
|
|
2
3
|
getCallback, SolverMethod, Callback, IterCheckerCallback, TimeCheckerCallback} from './src/solver-tools';
|
|
3
4
|
|
|
4
5
|
export {perfProbs, corrProbs, CorrProblem, refPoints, printRobertson, printHires, printOrego,
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/** Example. Solve the following initial value problem
|
|
2
|
+
|
|
3
|
+
dx / dt = x + y - t
|
|
4
|
+
dy / dt = x * y + t
|
|
5
|
+
x(0) = 1
|
|
6
|
+
y(0) = -1
|
|
7
|
+
|
|
8
|
+
on [0, 2] with the step 0.01.
|
|
9
|
+
*/
|
|
10
|
+
import { lsoda } from '../../index';
|
|
11
|
+
// constants
|
|
12
|
+
const VLinit = 7.2;
|
|
13
|
+
const VTV = 10;
|
|
14
|
+
const speed = 400;
|
|
15
|
+
const diam = 6;
|
|
16
|
+
const power = 2.1;
|
|
17
|
+
const pH = 7.4;
|
|
18
|
+
const k1red = 0.05604;
|
|
19
|
+
const k1ox = 0.0108;
|
|
20
|
+
const k2Fd = 1.35;
|
|
21
|
+
const k2Fa = 110400000;
|
|
22
|
+
const k2Kd = 0.04038;
|
|
23
|
+
const k2Ka = 120000000;
|
|
24
|
+
const k3FKa = 181200000;
|
|
25
|
+
const k3FKd = 0.01188;
|
|
26
|
+
const k4ox = 0.0108;
|
|
27
|
+
const k4red = 0.05604;
|
|
28
|
+
const ktox = 0.005;
|
|
29
|
+
const krcyst = 0;
|
|
30
|
+
const pO2sat = 100;
|
|
31
|
+
const pKa2MEA = 8.18;
|
|
32
|
+
const H = 1.072069378;
|
|
33
|
+
const R = 0.082;
|
|
34
|
+
const _t0 = 0;
|
|
35
|
+
const _t1 = 1000;
|
|
36
|
+
const _h = 1;
|
|
37
|
+
const FFox = 0.2;
|
|
38
|
+
const KKox = 0.2;
|
|
39
|
+
const FFred = 0.1;
|
|
40
|
+
const KKred = 0.1;
|
|
41
|
+
const Ffree = 0;
|
|
42
|
+
const Kfree = 0;
|
|
43
|
+
const FKred = 0;
|
|
44
|
+
const FKox = 0;
|
|
45
|
+
const MEAthiol = 15;
|
|
46
|
+
const CO2 = 0.12;
|
|
47
|
+
const yO2P = 0.209;
|
|
48
|
+
const CYST = 0;
|
|
49
|
+
const VL = 7.2;
|
|
50
|
+
const qin = 1;
|
|
51
|
+
const yO2in = 0.21;
|
|
52
|
+
const T = 300;
|
|
53
|
+
const P = 1;
|
|
54
|
+
const switchTime = 135;
|
|
55
|
+
// the problem definition
|
|
56
|
+
const task = {
|
|
57
|
+
name: 'Bioreactor',
|
|
58
|
+
arg: { name: 't', start: _t0, finish: _t1, step: _h },
|
|
59
|
+
initial: [FFox, KKox, FFred, KKred, Ffree, Kfree, FKred, FKox, MEAthiol, CO2, yO2P, CYST, VL],
|
|
60
|
+
func: (t, _y, _output) => {
|
|
61
|
+
// extract function values
|
|
62
|
+
const FFox = _y[0];
|
|
63
|
+
const KKox = _y[1];
|
|
64
|
+
const FFred = _y[2];
|
|
65
|
+
const KKred = _y[3];
|
|
66
|
+
const Ffree = _y[4];
|
|
67
|
+
const Kfree = _y[5];
|
|
68
|
+
const FKred = _y[6];
|
|
69
|
+
const FKox = _y[7];
|
|
70
|
+
const MEAthiol = _y[8];
|
|
71
|
+
const CO2 = _y[9];
|
|
72
|
+
const yO2P = _y[10];
|
|
73
|
+
const CYST = _y[11];
|
|
74
|
+
const VL = _y[12];
|
|
75
|
+
// evaluate expressions
|
|
76
|
+
const KF = pow(VL, -0.65) * 0.065 * pow(Math.pow(speed, 3) * Math.pow(diam, 5) * power / 2.16e12, 0.361);
|
|
77
|
+
const MA = MEAthiol * pow(10, pH - pKa2MEA);
|
|
78
|
+
const qout = qin - KF * (yO2P * H - CO2) * VL * R * T / (P * 1000);
|
|
79
|
+
const OTR = KF * (yO2P * H - CO2);
|
|
80
|
+
const Fin = t < switchTime ? 0 : 0.025;
|
|
81
|
+
const Fper = t < switchTime ? 0.025 : Fin;
|
|
82
|
+
const E0 = VLinit / VL;
|
|
83
|
+
const E1 = Math.pow((MA * E0), 2);
|
|
84
|
+
const E11 = k1red * FFox * E0 * E1;
|
|
85
|
+
const E12 = k1ox * FFred * E0;
|
|
86
|
+
const E31 = k2Fd * FFred * E0;
|
|
87
|
+
const E32 = k2Fa * Math.pow((Ffree * E0), 2) * E1;
|
|
88
|
+
const E21 = k1red * KKox * E0 * E1;
|
|
89
|
+
const E22 = k1ox * KKred * E0;
|
|
90
|
+
const E41 = k2Kd * KKred * E0;
|
|
91
|
+
const E42 = k2Ka * Math.pow((Kfree * E0), 2) * E1;
|
|
92
|
+
const E51 = k3FKa * Ffree * E0 * Kfree * E0;
|
|
93
|
+
const E52 = k3FKd * FKred * E0;
|
|
94
|
+
const E61 = k4ox * FKred * E0 * Math.pow((CYST * E0), 2);
|
|
95
|
+
const E62 = k4red * FKox * E0 * E1;
|
|
96
|
+
const E70 = E0 * CO2;
|
|
97
|
+
const E71 = Math.pow((MEAthiol * E0), 2);
|
|
98
|
+
const E72 = (E70 >= 0) ? sqrt(E70) : 0;
|
|
99
|
+
// compute output
|
|
100
|
+
_output[0] = -E11 + E12;
|
|
101
|
+
_output[1] = -E21 + E22;
|
|
102
|
+
_output[2] = E11 - E12 - E31 + E32;
|
|
103
|
+
_output[3] = E21 - E22 - E41 + E42;
|
|
104
|
+
_output[4] = 2 * (E31 - E32) - E51 + E52;
|
|
105
|
+
_output[5] = 2 * (E41 - E42) - E51 + E52;
|
|
106
|
+
_output[6] = E51 - E52 - E61 + E62;
|
|
107
|
+
_output[7] = E61 - E62;
|
|
108
|
+
_output[8] = 2 * (-E11 + E12 - E21 + E22 + E31 + E41 - E32 - E42 - E62 - ktox * E71 * E72) -
|
|
109
|
+
(MEAthiol + MA) * (Fin + Fper) / VL;
|
|
110
|
+
_output[9] = (Fin * pO2sat * 0.0022 - 2 * Fper * CO2) / VL + OTR - 0.5 * ktox * E71 * E72;
|
|
111
|
+
_output[10] = -OTR * (VL / (VTV - VL)) * R * T * P + yO2in * qin - yO2P * qout;
|
|
112
|
+
_output[11] = ktox * E71 * E72 - krcyst * CYST * E0 - (Fin + Fper) * CYST / VL;
|
|
113
|
+
_output[12] = Fin - Fper;
|
|
114
|
+
},
|
|
115
|
+
tolerance: 0.00005,
|
|
116
|
+
solutionColNames: ['FFox', 'KKox', 'FFred', 'KKred', 'Ffree', 'Kfree', 'FKred',
|
|
117
|
+
'FKox', 'MEAthiol', 'CO2', 'yO2P', 'CYST', 'VL'],
|
|
118
|
+
};
|
|
119
|
+
// used Math-functions
|
|
120
|
+
const pow = (x, y) => Math.pow(x, y);
|
|
121
|
+
const tan = (x) => Math.tan(x);
|
|
122
|
+
const sqrt = (x) => Math.sqrt(x);
|
|
123
|
+
const exp = (x) => Math.exp(x);
|
|
124
|
+
const solution = lsoda(task);
|
|
125
|
+
//# sourceMappingURL=bioreactor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bioreactor.js","sourceRoot":"","sources":["bioreactor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** Example. Solve the following initial value problem
|
|
2
|
+
|
|
3
|
+
dx / dt = x + y - t
|
|
4
|
+
dy / dt = x * y + t
|
|
5
|
+
x(0) = 1
|
|
6
|
+
y(0) = -1
|
|
7
|
+
|
|
8
|
+
on [0, 2] with the step 0.01.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {ODEs, lsoda, mrt} from '../../index';
|
|
12
|
+
|
|
13
|
+
// constants
|
|
14
|
+
const VLinit = 7.2;
|
|
15
|
+
const VTV = 10;
|
|
16
|
+
const speed = 400;
|
|
17
|
+
const diam = 6;
|
|
18
|
+
const power = 2.1;
|
|
19
|
+
const pH = 7.4;
|
|
20
|
+
const k1red = 0.05604;
|
|
21
|
+
const k1ox = 0.0108;
|
|
22
|
+
const k2Fd = 1.35;
|
|
23
|
+
const k2Fa = 110400000;
|
|
24
|
+
const k2Kd = 0.04038;
|
|
25
|
+
const k2Ka = 120000000;
|
|
26
|
+
const k3FKa = 181200000;
|
|
27
|
+
const k3FKd = 0.01188;
|
|
28
|
+
const k4ox = 0.0108;
|
|
29
|
+
const k4red = 0.05604;
|
|
30
|
+
const ktox = 0.005;
|
|
31
|
+
const krcyst = 0;
|
|
32
|
+
const pO2sat = 100;
|
|
33
|
+
const pKa2MEA = 8.18;
|
|
34
|
+
const H = 1.072069378;
|
|
35
|
+
const R = 0.082;
|
|
36
|
+
|
|
37
|
+
const _t0 = 0;
|
|
38
|
+
const _t1 = 1000;
|
|
39
|
+
const _h = 1;
|
|
40
|
+
const FFox = 0.2;
|
|
41
|
+
const KKox = 0.2;
|
|
42
|
+
const FFred = 0.1;
|
|
43
|
+
const KKred = 0.1;
|
|
44
|
+
const Ffree = 0;
|
|
45
|
+
const Kfree = 0;
|
|
46
|
+
const FKred = 0;
|
|
47
|
+
const FKox = 0;
|
|
48
|
+
const MEAthiol = 15;
|
|
49
|
+
const CO2 = 0.12;
|
|
50
|
+
const yO2P = 0.209;
|
|
51
|
+
const CYST = 0;
|
|
52
|
+
const VL = 7.2;
|
|
53
|
+
const qin = 1;
|
|
54
|
+
const yO2in = 0.21;
|
|
55
|
+
const T = 300;
|
|
56
|
+
const P = 1;
|
|
57
|
+
const switchTime = 135;
|
|
58
|
+
|
|
59
|
+
// the problem definition
|
|
60
|
+
const task = {
|
|
61
|
+
name: 'Bioreactor',
|
|
62
|
+
arg: {name: 't', start: _t0, finish: _t1, step: _h},
|
|
63
|
+
initial: [FFox, KKox, FFred, KKred, Ffree, Kfree, FKred, FKox, MEAthiol, CO2, yO2P, CYST, VL],
|
|
64
|
+
func: (t: number, _y: Float64Array, _output: Float64Array) => {
|
|
65
|
+
// extract function values
|
|
66
|
+
const FFox = _y[0];
|
|
67
|
+
const KKox = _y[1];
|
|
68
|
+
const FFred = _y[2];
|
|
69
|
+
const KKred = _y[3];
|
|
70
|
+
const Ffree = _y[4];
|
|
71
|
+
const Kfree = _y[5];
|
|
72
|
+
const FKred = _y[6];
|
|
73
|
+
const FKox = _y[7];
|
|
74
|
+
const MEAthiol = _y[8];
|
|
75
|
+
const CO2 = _y[9];
|
|
76
|
+
const yO2P = _y[10];
|
|
77
|
+
const CYST = _y[11];
|
|
78
|
+
const VL = _y[12];
|
|
79
|
+
|
|
80
|
+
// evaluate expressions
|
|
81
|
+
const KF = pow(VL, -0.65) * 0.065 * pow(speed**3 * diam**5 * power / 2.16e12, 0.361);
|
|
82
|
+
const MA = MEAthiol * pow(10, pH - pKa2MEA);
|
|
83
|
+
const qout = qin - KF * (yO2P * H - CO2) * VL * R * T / (P * 1000);
|
|
84
|
+
const OTR = KF * (yO2P * H - CO2);
|
|
85
|
+
const Fin = t < switchTime ? 0 : 0.025;
|
|
86
|
+
const Fper = t < switchTime ? 0.025 : Fin;
|
|
87
|
+
const E0 = VLinit / VL;
|
|
88
|
+
const E1 = (MA * E0)**2;
|
|
89
|
+
const E11 = k1red * FFox * E0 * E1;
|
|
90
|
+
const E12 = k1ox * FFred * E0;
|
|
91
|
+
const E31 = k2Fd * FFred * E0;
|
|
92
|
+
const E32 = k2Fa * (Ffree * E0)**2 * E1;
|
|
93
|
+
const E21 = k1red * KKox * E0 * E1;
|
|
94
|
+
const E22 = k1ox * KKred * E0;
|
|
95
|
+
const E41 = k2Kd * KKred * E0;
|
|
96
|
+
const E42 = k2Ka * (Kfree * E0)**2 * E1;
|
|
97
|
+
const E51 = k3FKa * Ffree * E0 * Kfree * E0;
|
|
98
|
+
const E52 = k3FKd * FKred * E0;
|
|
99
|
+
const E61 = k4ox * FKred * E0 * (CYST * E0)**2;
|
|
100
|
+
const E62 = k4red * FKox * E0 * E1;
|
|
101
|
+
const E70 = E0 * CO2;
|
|
102
|
+
const E71 = (MEAthiol * E0)**2;
|
|
103
|
+
const E72 = (E70 >= 0) ? sqrt(E70) : 0;
|
|
104
|
+
|
|
105
|
+
// compute output
|
|
106
|
+
_output[0] = -E11 + E12;
|
|
107
|
+
_output[1] = -E21 + E22;
|
|
108
|
+
_output[2] = E11 - E12 - E31 + E32;
|
|
109
|
+
_output[3] = E21 - E22 - E41 + E42;
|
|
110
|
+
_output[4] = 2 * (E31 - E32) - E51 + E52;
|
|
111
|
+
_output[5] = 2 * (E41 - E42) - E51 + E52;
|
|
112
|
+
_output[6] = E51 - E52 - E61 + E62;
|
|
113
|
+
_output[7] = E61 - E62;
|
|
114
|
+
_output[8] = 2 * (-E11 + E12 - E21 + E22 + E31 + E41 - E32 - E42 - E62 - ktox * E71 * E72) -
|
|
115
|
+
(MEAthiol + MA) * (Fin + Fper) / VL;
|
|
116
|
+
_output[9] = (Fin * pO2sat * 0.0022 - 2 * Fper * CO2) / VL + OTR - 0.5 * ktox * E71 * E72;
|
|
117
|
+
_output[10] = -OTR * (VL / (VTV - VL)) * R * T * P + yO2in * qin - yO2P * qout;
|
|
118
|
+
_output[11] = ktox * E71 * E72 - krcyst * CYST * E0 - (Fin + Fper) * CYST / VL;
|
|
119
|
+
_output[12] = Fin - Fper;
|
|
120
|
+
},
|
|
121
|
+
tolerance: 0.00005,
|
|
122
|
+
solutionColNames: ['FFox', 'KKox', 'FFred', 'KKred', 'Ffree', 'Kfree', 'FKred',
|
|
123
|
+
'FKox', 'MEAthiol', 'CO2', 'yO2P', 'CYST', 'VL'],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// used Math-functions
|
|
127
|
+
const pow = (x: number, y: number) => Math.pow(x, y);
|
|
128
|
+
const tan = (x: number) => Math.tan(x);
|
|
129
|
+
const sqrt = (x: number) => Math.sqrt(x);
|
|
130
|
+
const exp = (x: number) => Math.exp(x);
|
|
131
|
+
|
|
132
|
+
const solution = lsoda(task);
|