diff-grok 1.1.0 → 1.2.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 (231) hide show
  1. package/.claude/skills/license-updater/SKILL.md +149 -0
  2. package/.claude/skills/license-updater/references/compatibility.md +68 -0
  3. package/.claude/skills/license-updater/references/templates.md +151 -0
  4. package/.claude/skills/license-updater/scripts/generate_license_files.py +467 -0
  5. package/CLAUDE.md +10 -4
  6. package/LICENSE +1 -1
  7. package/README.MD +41 -23
  8. package/THIRD_PARTY_LICENSES +135 -0
  9. package/docs/.nojekyll +1 -0
  10. package/docs/assets/hierarchy.js +1 -0
  11. package/docs/assets/highlight.css +99 -0
  12. package/docs/assets/icons.js +18 -0
  13. package/docs/assets/icons.svg +1 -0
  14. package/docs/assets/main.js +60 -0
  15. package/docs/assets/navigation.js +1 -0
  16. package/docs/assets/search.js +1 -0
  17. package/docs/assets/style.css +1633 -0
  18. package/docs/classes/BasicModelPipelineCreator.html +10 -0
  19. package/docs/classes/Callback.html +7 -0
  20. package/docs/classes/CyclicModelPipelineCreator.html +10 -0
  21. package/docs/classes/IterCheckerCallback.html +8 -0
  22. package/docs/classes/PipelineCreator.html +6 -0
  23. package/docs/classes/TimeCheckerCallback.html +8 -0
  24. package/docs/classes/UpdatesModelPipelineCreator.html +10 -0
  25. package/docs/functions/ab4.html +8 -0
  26. package/docs/functions/ab5.html +8 -0
  27. package/docs/functions/applyPipeline.html +9 -0
  28. package/docs/functions/getCallback.html +3 -0
  29. package/docs/functions/getIVP.html +6 -0
  30. package/docs/functions/getInputVector.html +2 -0
  31. package/docs/functions/getIvp2WebWorker.html +6 -0
  32. package/docs/functions/getJScode.html +6 -0
  33. package/docs/functions/getOutputNames.html +4 -0
  34. package/docs/functions/getPipelineCreator.html +7 -0
  35. package/docs/functions/lsoda.html +8 -0
  36. package/docs/functions/mrt.html +11 -0
  37. package/docs/functions/printE5.html +76 -0
  38. package/docs/functions/printHires.html +76 -0
  39. package/docs/functions/printOrego.html +66 -0
  40. package/docs/functions/printPollution.html +163 -0
  41. package/docs/functions/printRobertson.html +60 -0
  42. package/docs/functions/printVdpol.html +66 -0
  43. package/docs/functions/rk3.html +8 -0
  44. package/docs/functions/rk4.html +8 -0
  45. package/docs/functions/rkdp.html +8 -0
  46. package/docs/functions/ros34prw.html +8 -0
  47. package/docs/functions/ros3prw.html +8 -0
  48. package/docs/functions/solveIvp.html +5 -0
  49. package/docs/hierarchy.html +1 -0
  50. package/docs/index.html +768 -0
  51. package/docs/media/CONTRIBUTING.md +74 -0
  52. package/docs/media/E5.png +0 -0
  53. package/docs/media/HIRES.png +0 -0
  54. package/docs/media/OREGO.png +0 -0
  55. package/docs/media/POLL-full.png +0 -0
  56. package/docs/media/POLL.png +0 -0
  57. package/docs/media/ROBER.png +0 -0
  58. package/docs/media/VDP0L.png +0 -0
  59. package/docs/media/VDPOL.png +0 -0
  60. package/docs/media/acid-prod.gif +0 -0
  61. package/docs/media/basic-use.js +40 -0
  62. package/docs/media/basic-use.js.map +1 -0
  63. package/docs/media/basic-use.ts +44 -0
  64. package/docs/media/check-methods.js +59 -0
  65. package/docs/media/check-methods.js.map +1 -0
  66. package/docs/media/check-methods.ts +81 -0
  67. package/docs/media/corr-probs.js +132 -0
  68. package/docs/media/corr-probs.js.map +1 -0
  69. package/docs/media/corr-probs.ts +155 -0
  70. package/docs/media/cyclic-model.js +102 -0
  71. package/docs/media/cyclic-model.js.map +1 -0
  72. package/docs/media/cyclic-model.ts +112 -0
  73. package/docs/media/e5.js +36 -0
  74. package/docs/media/e5.js.map +1 -0
  75. package/docs/media/e5.ts +36 -0
  76. package/docs/media/hires.js +39 -0
  77. package/docs/media/hires.js.map +1 -0
  78. package/docs/media/hires.ts +40 -0
  79. package/docs/media/model-updates.js +112 -0
  80. package/docs/media/model-updates.js.map +1 -0
  81. package/docs/media/model-updates.ts +122 -0
  82. package/docs/media/orego.js +24 -0
  83. package/docs/media/orego.js.map +1 -0
  84. package/docs/media/orego.ts +25 -0
  85. package/docs/media/pipeline-use.js +87 -0
  86. package/docs/media/pipeline-use.js.map +1 -0
  87. package/docs/media/pipeline-use.ts +98 -0
  88. package/docs/media/pollution.js +132 -0
  89. package/docs/media/pollution.js.map +1 -0
  90. package/docs/media/pollution.ts +133 -0
  91. package/docs/media/print-benchmark.js +581 -0
  92. package/docs/media/print-benchmark.js.map +1 -0
  93. package/docs/media/print-benchmark.ts +594 -0
  94. package/docs/media/robertson.js +19 -0
  95. package/docs/media/robertson.js.map +1 -0
  96. package/docs/media/robertson.ts +19 -0
  97. package/docs/media/scripting.js +30 -0
  98. package/docs/media/scripting.js.map +1 -0
  99. package/docs/media/scripting.ts +35 -0
  100. package/docs/media/vdpol.js +17 -0
  101. package/docs/media/vdpol.js.map +1 -0
  102. package/docs/media/vdpol.ts +17 -0
  103. package/docs/modules.html +1 -0
  104. package/docs/types/Arg.html +12 -0
  105. package/docs/types/DifEqs.html +8 -0
  106. package/docs/types/Func.html +7 -0
  107. package/docs/types/IVP.html +40 -0
  108. package/docs/types/IVP2WebWorker.html +12 -0
  109. package/docs/types/Input.html +8 -0
  110. package/docs/types/Loop.html +7 -0
  111. package/docs/types/ODEs.html +31 -0
  112. package/docs/types/Output.html +6 -0
  113. package/docs/types/Pipeline.html +6 -0
  114. package/docs/types/SolverOptions.html +8 -0
  115. package/docs/types/Update.html +9 -0
  116. package/docs/types/Wrapper.html +8 -0
  117. package/index.js +1 -1
  118. package/index.js.map +1 -1
  119. package/index.ts +1 -1
  120. package/package.json +4 -2
  121. package/src/examples/check-methods.js +15 -3
  122. package/src/examples/check-methods.js.map +1 -1
  123. package/src/examples/check-methods.ts +18 -3
  124. package/src/solver-tools/cvode/common.js +487 -0
  125. package/src/solver-tools/cvode/common.js.map +1 -0
  126. package/src/solver-tools/cvode/common.ts +549 -0
  127. package/src/solver-tools/cvode/cvode.js +1062 -0
  128. package/src/solver-tools/cvode/cvode.js.map +1 -0
  129. package/src/solver-tools/cvode/cvode.ts +1226 -0
  130. package/src/solver-tools/cvode/cvode_adams.js +124 -0
  131. package/src/solver-tools/cvode/cvode_adams.js.map +1 -0
  132. package/src/solver-tools/cvode/cvode_adams.ts +142 -0
  133. package/src/solver-tools/cvode/cvode_bdf.js +153 -0
  134. package/src/solver-tools/cvode/cvode_bdf.js.map +1 -0
  135. package/src/solver-tools/cvode/cvode_bdf.ts +164 -0
  136. package/src/solver-tools/cvode/cvode_class.js +158 -0
  137. package/src/solver-tools/cvode/cvode_class.js.map +1 -0
  138. package/src/solver-tools/cvode/cvode_class.ts +271 -0
  139. package/src/solver-tools/cvode/cvode_hin.js +119 -0
  140. package/src/solver-tools/cvode/cvode_hin.js.map +1 -0
  141. package/src/solver-tools/cvode/cvode_hin.ts +150 -0
  142. package/src/solver-tools/cvode/cvode_io.js +203 -0
  143. package/src/solver-tools/cvode/cvode_io.js.map +1 -0
  144. package/src/solver-tools/cvode/cvode_io.ts +258 -0
  145. package/src/solver-tools/cvode/cvode_ls.js +210 -0
  146. package/src/solver-tools/cvode/cvode_ls.js.map +1 -0
  147. package/src/solver-tools/cvode/cvode_ls.ts +249 -0
  148. package/src/solver-tools/cvode/cvode_nls.js +220 -0
  149. package/src/solver-tools/cvode/cvode_nls.js.map +1 -0
  150. package/src/solver-tools/cvode/cvode_nls.ts +259 -0
  151. package/src/solver-tools/cvode/cvode_root.js +415 -0
  152. package/src/solver-tools/cvode/cvode_root.js.map +1 -0
  153. package/src/solver-tools/cvode/cvode_root.ts +503 -0
  154. package/src/solver-tools/cvode/dense_linalg.js +131 -0
  155. package/src/solver-tools/cvode/dense_linalg.js.map +1 -0
  156. package/src/solver-tools/cvode/dense_linalg.ts +144 -0
  157. package/src/solver-tools/cvode/index.js +26 -0
  158. package/src/solver-tools/cvode/index.js.map +1 -0
  159. package/src/solver-tools/cvode/index.ts +64 -0
  160. package/src/solver-tools/cvode-method.js +114 -0
  161. package/src/solver-tools/cvode-method.js.map +1 -0
  162. package/src/solver-tools/cvode-method.ts +129 -0
  163. package/src/solver-tools/index.js +1 -0
  164. package/src/solver-tools/index.js.map +1 -1
  165. package/src/solver-tools/index.ts +1 -0
  166. package/src/solver-tools/lsoda/blas.js +11 -0
  167. package/src/solver-tools/lsoda/blas.js.map +1 -1
  168. package/src/solver-tools/lsoda/blas.ts +12 -0
  169. package/src/solver-tools/lsoda/cfode.js +11 -0
  170. package/src/solver-tools/lsoda/cfode.js.map +1 -1
  171. package/src/solver-tools/lsoda/cfode.ts +12 -0
  172. package/src/solver-tools/lsoda/corfailure.js +11 -0
  173. package/src/solver-tools/lsoda/corfailure.js.map +1 -1
  174. package/src/solver-tools/lsoda/corfailure.ts +12 -0
  175. package/src/solver-tools/lsoda/correction.js +11 -0
  176. package/src/solver-tools/lsoda/correction.js.map +1 -1
  177. package/src/solver-tools/lsoda/correction.ts +12 -0
  178. package/src/solver-tools/lsoda/dense.js +11 -0
  179. package/src/solver-tools/lsoda/dense.js.map +1 -1
  180. package/src/solver-tools/lsoda/dense.ts +12 -0
  181. package/src/solver-tools/lsoda/index.js +11 -0
  182. package/src/solver-tools/lsoda/index.js.map +1 -1
  183. package/src/solver-tools/lsoda/index.ts +12 -0
  184. package/src/solver-tools/lsoda/intdy.js +11 -0
  185. package/src/solver-tools/lsoda/intdy.js.map +1 -1
  186. package/src/solver-tools/lsoda/intdy.ts +12 -0
  187. package/src/solver-tools/lsoda/lsoda.js +11 -0
  188. package/src/solver-tools/lsoda/lsoda.js.map +1 -1
  189. package/src/solver-tools/lsoda/lsoda.ts +12 -0
  190. package/src/solver-tools/lsoda/methodswitch.js +11 -0
  191. package/src/solver-tools/lsoda/methodswitch.js.map +1 -1
  192. package/src/solver-tools/lsoda/methodswitch.ts +12 -0
  193. package/src/solver-tools/lsoda/orderswitch.js +11 -0
  194. package/src/solver-tools/lsoda/orderswitch.js.map +1 -1
  195. package/src/solver-tools/lsoda/orderswitch.ts +12 -0
  196. package/src/solver-tools/lsoda/prja.js +11 -0
  197. package/src/solver-tools/lsoda/prja.js.map +1 -1
  198. package/src/solver-tools/lsoda/prja.ts +12 -0
  199. package/src/solver-tools/lsoda/scaleh.js +11 -0
  200. package/src/solver-tools/lsoda/scaleh.js.map +1 -1
  201. package/src/solver-tools/lsoda/scaleh.ts +12 -0
  202. package/src/solver-tools/lsoda/solsy.js +11 -0
  203. package/src/solver-tools/lsoda/solsy.js.map +1 -1
  204. package/src/solver-tools/lsoda/solsy.ts +12 -0
  205. package/src/solver-tools/lsoda/stoda.js +11 -0
  206. package/src/solver-tools/lsoda/stoda.js.map +1 -1
  207. package/src/solver-tools/lsoda/stoda.ts +12 -0
  208. package/src/solver-tools/lsoda-method.js +23 -9
  209. package/src/solver-tools/lsoda-method.js.map +1 -1
  210. package/src/solver-tools/lsoda-method.ts +27 -9
  211. package/src/solver-tools/solver-defs.js +1 -0
  212. package/src/solver-tools/solver-defs.js.map +1 -1
  213. package/src/solver-tools/solver-defs.ts +1 -0
  214. package/src/tests/cvode-lib-correctness.test.js +404 -0
  215. package/src/tests/cvode-lib-correctness.test.js.map +1 -0
  216. package/src/tests/cvode-lib-correctness.test.ts +505 -0
  217. package/src/tests/cvode-lib-performance.test.js +103 -0
  218. package/src/tests/cvode-lib-performance.test.js.map +1 -0
  219. package/src/tests/cvode-lib-performance.test.ts +128 -0
  220. package/src/tests/performance.test.js +4 -2
  221. package/src/tests/performance.test.js.map +1 -1
  222. package/src/tests/performance.test.ts +4 -2
  223. package/src/tests/test-defs.js +7 -1
  224. package/src/tests/test-defs.js.map +1 -1
  225. package/src/tests/test-defs.ts +8 -1
  226. package/src/worker-tools/solving.js +3 -1
  227. package/src/worker-tools/solving.js.map +1 -1
  228. package/src/worker-tools/solving.ts +4 -1
  229. package/src/examples/bioreactor.js +0 -125
  230. package/src/examples/bioreactor.js.map +0 -1
  231. package/src/examples/bioreactor.ts +0 -132
@@ -0,0 +1,210 @@
1
+ /**
2
+ * TypeScript port of SUNDIALS CVODE v7.5.0 (https://github.com/LLNL/sundials)
3
+ *
4
+ * Copyright (c) 2025, Lawrence Livermore National Security, University of
5
+ * Maryland Baltimore County, and the SUNDIALS contributors.
6
+ * Copyright (c) 2013-2025, Lawrence Livermore National Security and
7
+ * Southern Methodist University.
8
+ * Copyright (c) 2002-2013, Lawrence Livermore National Security.
9
+ * Copyright (c) 2026 Datagrok.
10
+ *
11
+ * Licensed under the BSD-3-Clause License. See THIRD_PARTY_LICENSES
12
+ * for the full license text and provenance chain of the original code.
13
+ */
14
+ // CVODE TypeScript port - Dense linear solver interface
15
+ // Translated from SUNDIALS cvode_ls.c
16
+ //
17
+ // Instead of SUNDIALS' SUNLinearSolver / SUNMatrix abstraction, we use
18
+ // direct Float64Array[] matrices and dgefa / dgesl from dense_linalg.ts.
19
+ import { CvLsMem, wrmsNorm, CV_SUCCESS, CV_FAIL_BAD_J, CVLS_MSBJ, CVLS_DGMAX } from './common';
20
+ import { dgefa, dgesl } from './dense_linalg';
21
+ /**
22
+ * cvodeSetLinearSolver - Initialize the dense linear solver.
23
+ * Sets up CvLsMem, allocates matrix, sets function pointers on CvodeMem.
24
+ */
25
+ export function cvodeSetLinearSolver(mem) {
26
+ const N = mem.cv_N;
27
+ const lmem = new CvLsMem();
28
+ // Allocate dense matrix A (N x N, row-major)
29
+ lmem.A = new Array(N);
30
+ lmem.savedJ = new Array(N);
31
+ for (let i = 0; i < N; i++) {
32
+ lmem.A[i] = new Float64Array(N);
33
+ lmem.savedJ[i] = new Float64Array(N);
34
+ }
35
+ lmem.pivots = new Int32Array(N);
36
+ // Set defaults
37
+ lmem.jacDQ = true;
38
+ lmem.jacFn = null;
39
+ lmem.jbad = true;
40
+ lmem.nje = 0;
41
+ lmem.nfeDQ = 0;
42
+ lmem.nstlj = 0;
43
+ lmem.tnlj = 0;
44
+ lmem.msbj = CVLS_MSBJ;
45
+ lmem.dgmax_jbad = CVLS_DGMAX;
46
+ // Attach to CvodeMem
47
+ mem.cv_lmem = lmem;
48
+ mem.cv_linit = cvLsInitialize;
49
+ mem.cv_lsetup = cvLsSetup;
50
+ mem.cv_lsolve = cvLsSolve;
51
+ mem.cv_lfree = cvLsFree;
52
+ return CV_SUCCESS;
53
+ }
54
+ /**
55
+ * cvodeSetJacFn - Set a user-supplied Jacobian function.
56
+ */
57
+ export function cvodeSetJacFn(mem, jac) {
58
+ const lmem = mem.cv_lmem;
59
+ if (!lmem)
60
+ return -1;
61
+ if (jac) {
62
+ lmem.jacDQ = false;
63
+ lmem.jacFn = jac;
64
+ }
65
+ else {
66
+ lmem.jacDQ = true;
67
+ lmem.jacFn = null;
68
+ }
69
+ return CV_SUCCESS;
70
+ }
71
+ /**
72
+ * cvLsInitialize - Initialize linear solver counters.
73
+ */
74
+ function cvLsInitialize(mem) {
75
+ const lmem = mem.cv_lmem;
76
+ lmem.nje = 0;
77
+ lmem.nfeDQ = 0;
78
+ lmem.nstlj = 0;
79
+ lmem.jbad = true;
80
+ return CV_SUCCESS;
81
+ }
82
+ /**
83
+ * cvLsSetup - Compute Jacobian and form/factor the linear system matrix A = I - gamma*J.
84
+ *
85
+ * Heuristic for when to recompute Jacobian:
86
+ * - On first call (nstlj == 0)
87
+ * - If convfail is CV_FAIL_BAD_J (NLS flagged Jacobian as bad)
88
+ * - If enough steps since last eval (nst >= nstlj + msbj)
89
+ * - If gamma changed significantly (|gamrat - 1| > dgmax_jbad)
90
+ */
91
+ function cvLsSetup(mem, convfail, ypred, fpred, jcurPtr, tmp1, tmp2, tmp3) {
92
+ const lmem = mem.cv_lmem;
93
+ const N = mem.cv_N;
94
+ let retval;
95
+ // Determine if Jacobian needs updating
96
+ const jbad = lmem.jbad;
97
+ let jok = !jbad;
98
+ if (!jbad) {
99
+ // Check gamma ratio
100
+ if (Math.abs(mem.cv_gamrat - 1.0) > lmem.dgmax_jbad)
101
+ jok = false;
102
+ // Check steps since last Jacobian
103
+ if (mem.cv_nst >= lmem.nstlj + lmem.msbj)
104
+ jok = false;
105
+ // Check convfail
106
+ if (convfail === CV_FAIL_BAD_J)
107
+ jok = false;
108
+ }
109
+ if (jok) {
110
+ // Reuse saved Jacobian, just form A = I - gamma*J
111
+ jcurPtr.value = false;
112
+ // Copy savedJ to A and form I - gamma*J
113
+ for (let i = 0; i < N; i++) {
114
+ for (let j = 0; j < N; j++)
115
+ lmem.A[i][j] = -mem.cv_gamma * lmem.savedJ[i][j];
116
+ lmem.A[i][i] += 1.0;
117
+ }
118
+ }
119
+ else {
120
+ // Recompute Jacobian
121
+ lmem.nje++;
122
+ lmem.nstlj = mem.cv_nst;
123
+ lmem.jbad = false;
124
+ jcurPtr.value = true;
125
+ // Evaluate Jacobian
126
+ if (lmem.jacDQ)
127
+ retval = cvLsDQJac(mem, mem.cv_tn, ypred, fpred, lmem.savedJ, tmp1, tmp2);
128
+ else
129
+ retval = lmem.jacFn(mem.cv_tn, ypred, fpred, lmem.savedJ, mem.cv_user_data);
130
+ if (retval < 0) {
131
+ lmem.jbad = true;
132
+ return -1;
133
+ }
134
+ if (retval > 0) {
135
+ lmem.jbad = true;
136
+ return 1;
137
+ }
138
+ // Form A = I - gamma*J
139
+ for (let i = 0; i < N; i++) {
140
+ for (let j = 0; j < N; j++)
141
+ lmem.A[i][j] = -mem.cv_gamma * lmem.savedJ[i][j];
142
+ lmem.A[i][i] += 1.0;
143
+ }
144
+ }
145
+ // Factor A using LU decomposition
146
+ const info = dgefa(lmem.A, N, lmem.pivots);
147
+ if (info !== 0) {
148
+ lmem.jbad = true;
149
+ return 1; // recoverable
150
+ }
151
+ return CV_SUCCESS;
152
+ }
153
+ /**
154
+ * cvLsSolve - Solve the linear system A*x = b using LU factors.
155
+ */
156
+ function cvLsSolve(mem, b, weight, ycur, fcur) {
157
+ const lmem = mem.cv_lmem;
158
+ const N = mem.cv_N;
159
+ dgesl(lmem.A, N, lmem.pivots, b);
160
+ // Apply gamma/gammap correction if gamma has changed since last setup
161
+ if (mem.cv_gamrat !== 1.0) {
162
+ const factor = 2.0 / (1.0 + mem.cv_gamrat);
163
+ for (let i = 0; i < N; i++)
164
+ b[i] *= factor;
165
+ }
166
+ return CV_SUCCESS;
167
+ }
168
+ /**
169
+ * cvLsDQJac - Compute difference-quotient Jacobian approximation.
170
+ *
171
+ * For each column j:
172
+ * sigma_j = max(|y_j|, 1/ewt_j) * sqrt(uround)
173
+ * J[:,j] = (f(t, y + sigma_j*e_j) - f(t, y)) / sigma_j
174
+ */
175
+ function cvLsDQJac(mem, t, y, fy, J, tmp1, tmp2) {
176
+ const N = mem.cv_N;
177
+ const lmem = mem.cv_lmem;
178
+ const uround = 2.2204460492503131e-16;
179
+ const srur = Math.sqrt(uround);
180
+ const fnorm_val = wrmsNorm(N, fy, mem.cv_ewt);
181
+ const minInc = (fnorm_val !== 0.0) ? (1000.0 * Math.abs(mem.cv_h) * uround * N * fnorm_val) : 1.0;
182
+ // Use tmp1 as perturbed y, tmp2 as perturbed f
183
+ for (let j = 0; j < N; j++) {
184
+ const yjsaved = y[j];
185
+ let inc = Math.max(srur * Math.abs(yjsaved), minInc / mem.cv_ewt[j]);
186
+ // Ensure inc has same sign (positive since we want to increase)
187
+ // Perturb y[j]
188
+ tmp1.set(y);
189
+ tmp1[j] = yjsaved + inc;
190
+ inc = tmp1[j] - yjsaved; // exact increment after rounding
191
+ // Evaluate f(t, y + inc*e_j)
192
+ const retval = mem.cv_f(t, tmp1, tmp2, mem.cv_user_data);
193
+ lmem.nfeDQ++;
194
+ mem.cv_nfe++;
195
+ if (retval !== 0)
196
+ return retval;
197
+ // Compute column j of Jacobian: (f_perturbed - f) / inc
198
+ const inc_inv = 1.0 / inc;
199
+ for (let i = 0; i < N; i++)
200
+ J[i][j] = (tmp2[i] - fy[i]) * inc_inv;
201
+ }
202
+ return CV_SUCCESS;
203
+ }
204
+ /**
205
+ * cvLsFree - Free linear solver memory (no-op in TS, GC handles it).
206
+ */
207
+ function cvLsFree(mem) {
208
+ mem.cv_lmem = null;
209
+ }
210
+ //# sourceMappingURL=cvode_ls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cvode_ls.js","sourceRoot":"","sources":["cvode_ls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,wDAAwD;AACxD,sCAAsC;AACtC,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AAEzE,OAAO,EAAW,OAAO,EAAc,QAAQ,EAC7C,UAAU,EACM,aAAa,EAC7B,SAAS,EAAE,UAAU,EAAS,MAAM,UAAU,CAAC;AACjD,OAAO,EAAC,KAAK,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAa;IAChD,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;IAE3B,6CAA6C;IAC7C,IAAI,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAEhC,eAAe;IACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACjB,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACb,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACd,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAE7B,qBAAqB;IACrB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;IACnB,GAAG,CAAC,QAAQ,GAAG,cAAc,CAAC;IAC9B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAExB,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAa,EAAE,GAAsB;IACjE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC;IACzB,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC,CAAC;IAErB,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAa;IACnC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAQ,CAAC;IAC1B,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACb,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACjB,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,GAAa,EAAE,QAAgB,EAAE,KAAmB,EACrE,KAAmB,EAAE,OAA2B,EAChD,IAAkB,EAAE,IAAkB,EACtC,IAAkB;IAClB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAQ,CAAC;IAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IACnB,IAAI,MAAc,CAAC;IAEnB,uCAAuC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAEhB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,oBAAoB;QACpB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU;YACjD,GAAG,GAAG,KAAK,CAAC;QAEd,kCAAkC;QAClC,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI;YACtC,GAAG,GAAG,KAAK,CAAC;QAEd,iBAAiB;QACjB,IAAI,QAAQ,KAAK,aAAa;YAC5B,GAAG,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,IAAI,GAAG,EAAE,CAAC;QACR,kDAAkD;QAClD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;QAEtB,wCAAwC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACxB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACtB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,qBAAqB;QACrB,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;QAErB,oBAAoB;QACpB,IAAI,IAAI,CAAC,KAAK;YACZ,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;;YAE1E,MAAM,GAAG,IAAI,CAAC,KAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;QAG/E,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,uBAAuB;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACxB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACtB,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,CAAC,CAAC,CAAC,cAAc;IAC1B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,GAAa,EAAE,CAAe,EAAE,MAAoB,EACrE,IAAkB,EAAE,IAAkB;IACtC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAQ,CAAC;IAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IAEnB,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEjC,sEAAsE;IACtE,IAAI,GAAG,CAAC,SAAS,KAAK,GAAG,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACxB,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACnB,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,GAAa,EAAE,CAAS,EAAE,CAAe,EAAE,EAAgB,EAC5E,CAAiB,EAAE,IAAkB,EAAE,IAAkB;IACzD,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IACnB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAQ,CAAC;IAC1B,MAAM,MAAM,GAAG,sBAAsB,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAElG,+CAA+C;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,gEAAgE;QAEhE,eAAe;QACf,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACZ,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC;QACxB,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,iCAAiC;QAE1D,6BAA6B;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAK,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,EAAE,CAAC;QACb,IAAI,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAEhC,wDAAwD;QACxD,MAAM,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACxB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAC1C,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,GAAa;IAC7B,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * TypeScript port of SUNDIALS CVODE v7.5.0 (https://github.com/LLNL/sundials)
3
+ *
4
+ * Copyright (c) 2025, Lawrence Livermore National Security, University of
5
+ * Maryland Baltimore County, and the SUNDIALS contributors.
6
+ * Copyright (c) 2013-2025, Lawrence Livermore National Security and
7
+ * Southern Methodist University.
8
+ * Copyright (c) 2002-2013, Lawrence Livermore National Security.
9
+ * Copyright (c) 2026 Datagrok.
10
+ *
11
+ * Licensed under the BSD-3-Clause License. See THIRD_PARTY_LICENSES
12
+ * for the full license text and provenance chain of the original code.
13
+ */
14
+
15
+ // CVODE TypeScript port - Dense linear solver interface
16
+ // Translated from SUNDIALS cvode_ls.c
17
+ //
18
+ // Instead of SUNDIALS' SUNLinearSolver / SUNMatrix abstraction, we use
19
+ // direct Float64Array[] matrices and dgefa / dgesl from dense_linalg.ts.
20
+
21
+ import {CvodeMem, CvLsMem, CvodeJacFn, wrmsNorm,
22
+ CV_SUCCESS, CV_RHSFUNC_FAIL, RHSFUNC_RECVR,
23
+ CV_NO_FAILURES, CV_FAIL_BAD_J, CV_FAIL_OTHER,
24
+ CVLS_MSBJ, CVLS_DGMAX, ONEPSM} from './common';
25
+ import {dgefa, dgesl} from './dense_linalg';
26
+
27
+ /**
28
+ * cvodeSetLinearSolver - Initialize the dense linear solver.
29
+ * Sets up CvLsMem, allocates matrix, sets function pointers on CvodeMem.
30
+ */
31
+ export function cvodeSetLinearSolver(mem: CvodeMem): number {
32
+ const N = mem.cv_N;
33
+ const lmem = new CvLsMem();
34
+
35
+ // Allocate dense matrix A (N x N, row-major)
36
+ lmem.A = new Array(N);
37
+ lmem.savedJ = new Array(N);
38
+ for (let i = 0; i < N; i++) {
39
+ lmem.A[i] = new Float64Array(N);
40
+ lmem.savedJ[i] = new Float64Array(N);
41
+ }
42
+ lmem.pivots = new Int32Array(N);
43
+
44
+ // Set defaults
45
+ lmem.jacDQ = true;
46
+ lmem.jacFn = null;
47
+ lmem.jbad = true;
48
+ lmem.nje = 0;
49
+ lmem.nfeDQ = 0;
50
+ lmem.nstlj = 0;
51
+ lmem.tnlj = 0;
52
+ lmem.msbj = CVLS_MSBJ;
53
+ lmem.dgmax_jbad = CVLS_DGMAX;
54
+
55
+ // Attach to CvodeMem
56
+ mem.cv_lmem = lmem;
57
+ mem.cv_linit = cvLsInitialize;
58
+ mem.cv_lsetup = cvLsSetup;
59
+ mem.cv_lsolve = cvLsSolve;
60
+ mem.cv_lfree = cvLsFree;
61
+
62
+ return CV_SUCCESS;
63
+ }
64
+
65
+ /**
66
+ * cvodeSetJacFn - Set a user-supplied Jacobian function.
67
+ */
68
+ export function cvodeSetJacFn(mem: CvodeMem, jac: CvodeJacFn | null): number {
69
+ const lmem = mem.cv_lmem;
70
+ if (!lmem) return -1;
71
+
72
+ if (jac) {
73
+ lmem.jacDQ = false;
74
+ lmem.jacFn = jac;
75
+ } else {
76
+ lmem.jacDQ = true;
77
+ lmem.jacFn = null;
78
+ }
79
+ return CV_SUCCESS;
80
+ }
81
+
82
+ /**
83
+ * cvLsInitialize - Initialize linear solver counters.
84
+ */
85
+ function cvLsInitialize(mem: CvodeMem): number {
86
+ const lmem = mem.cv_lmem!;
87
+ lmem.nje = 0;
88
+ lmem.nfeDQ = 0;
89
+ lmem.nstlj = 0;
90
+ lmem.jbad = true;
91
+ return CV_SUCCESS;
92
+ }
93
+
94
+ /**
95
+ * cvLsSetup - Compute Jacobian and form/factor the linear system matrix A = I - gamma*J.
96
+ *
97
+ * Heuristic for when to recompute Jacobian:
98
+ * - On first call (nstlj == 0)
99
+ * - If convfail is CV_FAIL_BAD_J (NLS flagged Jacobian as bad)
100
+ * - If enough steps since last eval (nst >= nstlj + msbj)
101
+ * - If gamma changed significantly (|gamrat - 1| > dgmax_jbad)
102
+ */
103
+ function cvLsSetup(mem: CvodeMem, convfail: number, ypred: Float64Array,
104
+ fpred: Float64Array, jcurPtr: { value: boolean },
105
+ tmp1: Float64Array, tmp2: Float64Array,
106
+ tmp3: Float64Array): number {
107
+ const lmem = mem.cv_lmem!;
108
+ const N = mem.cv_N;
109
+ let retval: number;
110
+
111
+ // Determine if Jacobian needs updating
112
+ const jbad = lmem.jbad;
113
+ let jok = !jbad;
114
+
115
+ if (!jbad) {
116
+ // Check gamma ratio
117
+ if (Math.abs(mem.cv_gamrat - 1.0) > lmem.dgmax_jbad)
118
+ jok = false;
119
+
120
+ // Check steps since last Jacobian
121
+ if (mem.cv_nst >= lmem.nstlj + lmem.msbj)
122
+ jok = false;
123
+
124
+ // Check convfail
125
+ if (convfail === CV_FAIL_BAD_J)
126
+ jok = false;
127
+ }
128
+
129
+ if (jok) {
130
+ // Reuse saved Jacobian, just form A = I - gamma*J
131
+ jcurPtr.value = false;
132
+
133
+ // Copy savedJ to A and form I - gamma*J
134
+ for (let i = 0; i < N; i++) {
135
+ for (let j = 0; j < N; j++)
136
+ lmem.A[i][j] = -mem.cv_gamma * lmem.savedJ[i][j];
137
+
138
+ lmem.A[i][i] += 1.0;
139
+ }
140
+ } else {
141
+ // Recompute Jacobian
142
+ lmem.nje++;
143
+ lmem.nstlj = mem.cv_nst;
144
+ lmem.jbad = false;
145
+ jcurPtr.value = true;
146
+
147
+ // Evaluate Jacobian
148
+ if (lmem.jacDQ)
149
+ retval = cvLsDQJac(mem, mem.cv_tn, ypred, fpred, lmem.savedJ, tmp1, tmp2);
150
+ else
151
+ retval = lmem.jacFn!(mem.cv_tn, ypred, fpred, lmem.savedJ, mem.cv_user_data);
152
+
153
+
154
+ if (retval < 0) {
155
+ lmem.jbad = true;
156
+ return -1;
157
+ }
158
+ if (retval > 0) {
159
+ lmem.jbad = true;
160
+ return 1;
161
+ }
162
+
163
+ // Form A = I - gamma*J
164
+ for (let i = 0; i < N; i++) {
165
+ for (let j = 0; j < N; j++)
166
+ lmem.A[i][j] = -mem.cv_gamma * lmem.savedJ[i][j];
167
+
168
+ lmem.A[i][i] += 1.0;
169
+ }
170
+ }
171
+
172
+ // Factor A using LU decomposition
173
+ const info = dgefa(lmem.A, N, lmem.pivots);
174
+ if (info !== 0) {
175
+ lmem.jbad = true;
176
+ return 1; // recoverable
177
+ }
178
+
179
+ return CV_SUCCESS;
180
+ }
181
+
182
+ /**
183
+ * cvLsSolve - Solve the linear system A*x = b using LU factors.
184
+ */
185
+ function cvLsSolve(mem: CvodeMem, b: Float64Array, weight: Float64Array,
186
+ ycur: Float64Array, fcur: Float64Array): number {
187
+ const lmem = mem.cv_lmem!;
188
+ const N = mem.cv_N;
189
+
190
+ dgesl(lmem.A, N, lmem.pivots, b);
191
+
192
+ // Apply gamma/gammap correction if gamma has changed since last setup
193
+ if (mem.cv_gamrat !== 1.0) {
194
+ const factor = 2.0 / (1.0 + mem.cv_gamrat);
195
+ for (let i = 0; i < N; i++)
196
+ b[i] *= factor;
197
+ }
198
+
199
+ return CV_SUCCESS;
200
+ }
201
+
202
+ /**
203
+ * cvLsDQJac - Compute difference-quotient Jacobian approximation.
204
+ *
205
+ * For each column j:
206
+ * sigma_j = max(|y_j|, 1/ewt_j) * sqrt(uround)
207
+ * J[:,j] = (f(t, y + sigma_j*e_j) - f(t, y)) / sigma_j
208
+ */
209
+ function cvLsDQJac(mem: CvodeMem, t: number, y: Float64Array, fy: Float64Array,
210
+ J: Float64Array[], tmp1: Float64Array, tmp2: Float64Array): number {
211
+ const N = mem.cv_N;
212
+ const lmem = mem.cv_lmem!;
213
+ const uround = 2.2204460492503131e-16;
214
+ const srur = Math.sqrt(uround);
215
+ const fnorm_val = wrmsNorm(N, fy, mem.cv_ewt);
216
+ const minInc = (fnorm_val !== 0.0) ? (1000.0 * Math.abs(mem.cv_h) * uround * N * fnorm_val) : 1.0;
217
+
218
+ // Use tmp1 as perturbed y, tmp2 as perturbed f
219
+ for (let j = 0; j < N; j++) {
220
+ const yjsaved = y[j];
221
+ let inc = Math.max(srur * Math.abs(yjsaved), minInc / mem.cv_ewt[j]);
222
+ // Ensure inc has same sign (positive since we want to increase)
223
+
224
+ // Perturb y[j]
225
+ tmp1.set(y);
226
+ tmp1[j] = yjsaved + inc;
227
+ inc = tmp1[j] - yjsaved; // exact increment after rounding
228
+
229
+ // Evaluate f(t, y + inc*e_j)
230
+ const retval = mem.cv_f!(t, tmp1, tmp2, mem.cv_user_data);
231
+ lmem.nfeDQ++;
232
+ mem.cv_nfe++;
233
+ if (retval !== 0) return retval;
234
+
235
+ // Compute column j of Jacobian: (f_perturbed - f) / inc
236
+ const inc_inv = 1.0 / inc;
237
+ for (let i = 0; i < N; i++)
238
+ J[i][j] = (tmp2[i] - fy[i]) * inc_inv;
239
+ }
240
+
241
+ return CV_SUCCESS;
242
+ }
243
+
244
+ /**
245
+ * cvLsFree - Free linear solver memory (no-op in TS, GC handles it).
246
+ */
247
+ function cvLsFree(mem: CvodeMem): void {
248
+ mem.cv_lmem = null;
249
+ }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * TypeScript port of SUNDIALS CVODE v7.5.0 (https://github.com/LLNL/sundials)
3
+ *
4
+ * Copyright (c) 2025, Lawrence Livermore National Security, University of
5
+ * Maryland Baltimore County, and the SUNDIALS contributors.
6
+ * Copyright (c) 2013-2025, Lawrence Livermore National Security and
7
+ * Southern Methodist University.
8
+ * Copyright (c) 2002-2013, Lawrence Livermore National Security.
9
+ * Copyright (c) 2026 Datagrok.
10
+ *
11
+ * Licensed under the BSD-3-Clause License. See THIRD_PARTY_LICENSES
12
+ * for the full license text and provenance chain of the original code.
13
+ */
14
+ import { wrmsNorm, vLinearSum, vScale, vConst, CV_SUCCESS, CV_BDF, CV_RHSFUNC_FAIL, CV_LSETUP_FAIL, CV_LSOLVE_FAIL, RHSFUNC_RECVR, SUN_NLS_CONV_RECVR, SUN_NLS_CONTINUE, CV_NO_FAILURES, CV_FAIL_OTHER, FIRST_CALL, PREV_CONV_FAIL, PREV_ERR_FAIL, NLS_MAXCOR, CRDOWN, RDIV } from './common';
15
+ /**
16
+ * cvNls - Solve the nonlinear system for one step.
17
+ *
18
+ * For BDF: Newton iteration solving G(ycor) = 0 where
19
+ * G(ycor) = rl1*zn[1] + ycor - gamma*f(tn, zn[0]+ycor)
20
+ * The Newton update is: (I - gamma*J) * delta = -G(ycor)
21
+ *
22
+ * For Adams: Fixed-point iteration
23
+ * ycor_new = h * rl1 * f(tn, zn[0]+ycor) - rl1*zn[1]
24
+ */
25
+ export function cvNls(mem, nflag) {
26
+ const N = mem.cv_N;
27
+ let callSetup;
28
+ // Decide whether to call linear solver setup
29
+ if (mem.cv_lsetup) {
30
+ mem.convfail = (nflag === FIRST_CALL || nflag === PREV_ERR_FAIL) ?
31
+ CV_NO_FAILURES :
32
+ CV_FAIL_OTHER;
33
+ callSetup = (nflag === PREV_CONV_FAIL) || (nflag === PREV_ERR_FAIL) ||
34
+ (mem.cv_nst === 0) || (mem.first_step_after_resize) ||
35
+ (mem.cv_nst >= mem.cv_nstlp + mem.cv_msbp) ||
36
+ (Math.abs(mem.cv_gamrat - 1.0) > mem.cv_dgmax_lsetup);
37
+ }
38
+ else {
39
+ mem.cv_crate = 1.0;
40
+ callSetup = false;
41
+ }
42
+ // Initial guess for correction: acor = 0
43
+ vConst(0.0, mem.cv_acor, N);
44
+ // Set acnrmcur to false
45
+ mem.cv_acnrmcur = false;
46
+ // Dispatch to Newton or fixed-point
47
+ let flag;
48
+ if (mem.cv_lmm === CV_BDF)
49
+ flag = cvNewtonIteration(mem, callSetup);
50
+ else
51
+ flag = cvFixedPointIteration(mem);
52
+ if (flag !== CV_SUCCESS)
53
+ return flag;
54
+ // Solve successful - update y = zn[0] + acor
55
+ vLinearSum(1.0, mem.cv_zn[0], 1.0, mem.cv_acor, mem.cv_y, N);
56
+ // Compute acnrm if not already done
57
+ if (!mem.cv_acnrmcur)
58
+ mem.cv_acnrm = wrmsNorm(N, mem.cv_acor, mem.cv_ewt);
59
+ // Update Jacobian status
60
+ mem.cv_jcur = false;
61
+ return CV_SUCCESS;
62
+ }
63
+ /**
64
+ * Newton iteration for BDF method.
65
+ * Solves: (I - gamma*J) * delta = -G(ycor)
66
+ * where G(ycor) = rl1*zn[1] + ycor - gamma*f(tn, zn[0]+ycor)
67
+ */
68
+ function cvNewtonIteration(mem, callSetup) {
69
+ const N = mem.cv_N;
70
+ let retval;
71
+ // Call linear solver setup if needed
72
+ if (callSetup && mem.cv_lsetup) {
73
+ // y = zn[0] + acor (current approximation)
74
+ vLinearSum(1.0, mem.cv_zn[0], 1.0, mem.cv_acor, mem.cv_y, N);
75
+ // Evaluate f at current approximation
76
+ retval = mem.cv_f(mem.cv_tn, mem.cv_y, mem.cv_ftemp, mem.cv_user_data);
77
+ mem.cv_nfe++;
78
+ if (retval < 0)
79
+ return CV_RHSFUNC_FAIL;
80
+ if (retval > 0)
81
+ return RHSFUNC_RECVR;
82
+ // Call lsetup
83
+ const jcurPtr = { value: false };
84
+ retval = mem.cv_lsetup(mem, mem.convfail, mem.cv_y, mem.cv_ftemp, jcurPtr, mem.cv_vtemp1, mem.cv_vtemp2, mem.cv_vtemp3);
85
+ mem.cv_nsetups++;
86
+ mem.cv_jcur = jcurPtr.value;
87
+ mem.cv_gamrat = 1.0;
88
+ mem.cv_gammap = mem.cv_gamma;
89
+ mem.cv_crate = 1.0;
90
+ mem.cv_nstlp = mem.cv_nst;
91
+ if (retval < 0)
92
+ return CV_LSETUP_FAIL;
93
+ if (retval > 0)
94
+ return SUN_NLS_CONV_RECVR;
95
+ }
96
+ // Newton iteration loop
97
+ for (let m = 0; m < NLS_MAXCOR; m++) {
98
+ mem.cv_nni++;
99
+ // y = zn[0] + acor
100
+ vLinearSum(1.0, mem.cv_zn[0], 1.0, mem.cv_acor, mem.cv_y, N);
101
+ // Evaluate f(tn, y)
102
+ retval = mem.cv_f(mem.cv_tn, mem.cv_y, mem.cv_ftemp, mem.cv_user_data);
103
+ mem.cv_nfe++;
104
+ if (retval < 0)
105
+ return CV_RHSFUNC_FAIL;
106
+ if (retval > 0)
107
+ return RHSFUNC_RECVR;
108
+ // Compute residual: b = rl1*zn[1] + acor - gamma*ftemp
109
+ // Store in tempv as the RHS for the linear solve
110
+ const b = mem.cv_tempv;
111
+ for (let i = 0; i < N; i++)
112
+ b[i] = mem.cv_rl1 * mem.cv_zn[1][i] + mem.cv_acor[i] - mem.cv_gamma * mem.cv_ftemp[i];
113
+ // Solve: (I - gamma*J) * delta = -b, so pass b (which is G, so we negate)
114
+ // Actually the convention is lsolve solves (I-gamma*J)*x = b
115
+ // and b here is -G so we negate
116
+ for (let i = 0; i < N; i++)
117
+ b[i] = -b[i];
118
+ retval = mem.cv_lsolve(mem, b, mem.cv_ewt, mem.cv_y, mem.cv_ftemp);
119
+ if (retval < 0)
120
+ return CV_LSOLVE_FAIL;
121
+ if (retval > 0)
122
+ return SUN_NLS_CONV_RECVR;
123
+ // Update acor += delta (delta is in b after solve)
124
+ for (let i = 0; i < N; i++)
125
+ mem.cv_acor[i] += b[i];
126
+ // Convergence test
127
+ const del = wrmsNorm(N, b, mem.cv_ewt);
128
+ const convTestResult = cvNlsConvTest(mem, del, m, mem.cv_tq[4]);
129
+ if (convTestResult === CV_SUCCESS)
130
+ return CV_SUCCESS;
131
+ if (convTestResult === SUN_NLS_CONV_RECVR) {
132
+ mem.cv_nnf++;
133
+ return SUN_NLS_CONV_RECVR;
134
+ }
135
+ // SUN_NLS_CONTINUE: continue iterating
136
+ }
137
+ // Max iterations reached without convergence
138
+ mem.cv_nnf++;
139
+ return SUN_NLS_CONV_RECVR;
140
+ }
141
+ /**
142
+ * Fixed-point iteration for Adams method.
143
+ * ycor = rl1 * (h * f(tn, zn[0]+ycor) - zn[1])
144
+ */
145
+ function cvFixedPointIteration(mem) {
146
+ const N = mem.cv_N;
147
+ let retval;
148
+ for (let m = 0; m < NLS_MAXCOR; m++) {
149
+ mem.cv_nni++;
150
+ // y = zn[0] + acor
151
+ vLinearSum(1.0, mem.cv_zn[0], 1.0, mem.cv_acor, mem.cv_y, N);
152
+ // Evaluate f(tn, y) -> store in tempv
153
+ retval = mem.cv_f(mem.cv_tn, mem.cv_y, mem.cv_tempv, mem.cv_user_data);
154
+ mem.cv_nfe++;
155
+ if (retval < 0)
156
+ return CV_RHSFUNC_FAIL;
157
+ if (retval > 0)
158
+ return RHSFUNC_RECVR;
159
+ // Compute new ycor: rl1 * (h * f - zn[1])
160
+ // First: tempv = h * tempv - zn[1]
161
+ for (let i = 0; i < N; i++)
162
+ mem.cv_tempv[i] = mem.cv_h * mem.cv_tempv[i] - mem.cv_zn[1][i];
163
+ // Then scale by rl1
164
+ const newAcor = mem.cv_vtemp1;
165
+ vScale(mem.cv_rl1, mem.cv_tempv, newAcor, N);
166
+ // Compute delta = newAcor - acor
167
+ const delta = mem.cv_tempv;
168
+ for (let i = 0; i < N; i++)
169
+ delta[i] = newAcor[i] - mem.cv_acor[i];
170
+ // Update acor
171
+ for (let i = 0; i < N; i++)
172
+ mem.cv_acor[i] = newAcor[i];
173
+ // Convergence test
174
+ const del = wrmsNorm(N, delta, mem.cv_ewt);
175
+ const convTestResult = cvNlsConvTest(mem, del, m, mem.cv_tq[4]);
176
+ if (convTestResult === CV_SUCCESS)
177
+ return CV_SUCCESS;
178
+ if (convTestResult === SUN_NLS_CONV_RECVR) {
179
+ mem.cv_nnf++;
180
+ return SUN_NLS_CONV_RECVR;
181
+ }
182
+ // SUN_NLS_CONTINUE: continue iterating
183
+ }
184
+ // Max iterations reached
185
+ mem.cv_nnf++;
186
+ return SUN_NLS_CONV_RECVR;
187
+ }
188
+ /**
189
+ * cvNlsConvTest - Test for convergence of the nonlinear iteration.
190
+ *
191
+ * del: WRMS norm of the current update
192
+ * m: iteration count (0-based)
193
+ * tol: tolerance (tq[4])
194
+ *
195
+ * Returns: CV_SUCCESS if converged, SUN_NLS_CONV_RECVR if diverging,
196
+ * SUN_NLS_CONTINUE if not yet converged
197
+ */
198
+ function cvNlsConvTest(mem, del, m, tol) {
199
+ // Update convergence rate estimate
200
+ if (m > 0)
201
+ mem.cv_crate = Math.max(CRDOWN * mem.cv_crate, del / mem.cv_delp);
202
+ // Test for convergence
203
+ const dcon = del * Math.min(1.0, mem.cv_crate) / tol;
204
+ if (dcon <= 1.0) {
205
+ // Converged
206
+ if (m === 0)
207
+ mem.cv_acnrm = del;
208
+ else
209
+ mem.cv_acnrm = wrmsNorm(mem.cv_N, mem.cv_acor, mem.cv_ewt);
210
+ mem.cv_acnrmcur = true;
211
+ return CV_SUCCESS;
212
+ }
213
+ // Check for divergence
214
+ if (m >= 1 && del > RDIV * mem.cv_delp)
215
+ return SUN_NLS_CONV_RECVR;
216
+ // Save del and continue
217
+ mem.cv_delp = del;
218
+ return SUN_NLS_CONTINUE;
219
+ }
220
+ //# sourceMappingURL=cvode_nls.js.map