Skip to content

Commit bcb1e63

Browse files
committed
jacobians logic and config implemented but failing to converge
1 parent d3e36d2 commit bcb1e63

File tree

8 files changed

+288
-129
lines changed

8 files changed

+288
-129
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ There are three types of input files that must be provided:
159159

160160
- **tolerances:** rtol and atol used by the cvodes library.
161161
- **ode_expr:** ODE model expression or identifier.
162+
- **jacobian_provider:** Jacobian provider defined in Rust identifier.
162163
- **time_scaling:** Scaling factor for time. Using negative powers of 10 helps cvodes speed.
163164
- **y0:** Initial conditions of the ODE.
164165
- **states_transformer:** Transformations expressions or identidier applied to the different states in case of the
@@ -191,6 +192,7 @@ There are three types of input files that must be provided:
191192
p1 * y11 * y7 - p24 * p22 * y14
192193
p28 + p27 * y7 - p29 * y15
193194
</ode_expr>
195+
<jacobian_provider>nfkb</jacobian_provider> <!-- Optional -->
194196
<time_scaling>0.001</time_scaling> <!-- Optional (Defaults to 1.0) -->
195197
<y0> <!-- Optional (Defaults to the first row of the data file) -->
196198
0.200000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000316, 0.002296, 0.004783, 0.000003, 0.002507, 0.003436, 0.000003, 0.060000, 0.000079, 0.000003
@@ -273,3 +275,6 @@ used indicating the identifier in the XML config file like this:
273275
```
274276

275277
Note that y_count and p_count are still present.
278+
279+
The software also provides a way to define a Jacobian provider and a states transformer inside the
280+
Rust module. See the respective Rust modules `jacobians.rs` and `states_transformers.rs`.

modules/cuqdyn-c/include/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct
3232
{
3333
Tolerances tolerances;
3434
OdeExpr ode_expr;
35+
int jacobian_provider_present;
3536
double time_scaling;
3637
Y0 y0;
3738
StatesTransformer states_transformer;
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#ifndef LOTKA_VOLTERRA_H
22
#define LOTKA_VOLTERRA_H
3-
#include <sundials/sundials_direct.h>
43
#include <sundials/sundials_nvector.h>
4+
#include "sundials/sundials_matrix.h"
55

66
/// Function used to solve the ODE using cvodes
77
int ode_model_fun(sunrealtype t, N_Vector y, N_Vector ydot, void *data);
8-
/// Objetive function for the lotka_volterra problem used by the sacess library
8+
/// Default obj function used by the sacess library
99
void *obj_func(double *x, void *data);
10+
/// Jacobian function used to solve the ODE using cvodes
11+
int get_jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2,
12+
N_Vector tmp3);
1013

1114
#endif // LOTKA_VOLTERRA_H

modules/cuqdyn-c/src/functions.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
#include "cuqdyn.h"
1010
#include "ode_solver.h"
1111
#include "states_transformer.h"
12+
#include "sundials/sundials_types.h"
1213

1314
extern void eval_f_exprs(sunrealtype t, sunrealtype *y, sunrealtype *ydot, sunrealtype *params, CuqDynContext context);
15+
extern void jacobian(sunrealtype t, sunrealtype *y, sunrealtype *fy, sunrealtype *J, sunrealtype *params,
16+
sunrealtype *tmp1, sunrealtype *tmp2, sunrealtype *tmp3, CuqDynContext context);
1417

1518
int ode_model_fun(sunrealtype t, N_Vector y, N_Vector ydot, void *user_data)
1619
{
@@ -94,3 +97,24 @@ void *obj_func(double *x, void *data)
9497

9598
return res;
9699
}
100+
101+
int get_jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2,
102+
N_Vector tmp3)
103+
{
104+
#ifndef JE
105+
#define JE(J, i, j) SM_ELEMENT_D((J), (i), (j))
106+
#endif
107+
108+
for (int j = 0; j < SM_COLUMNS_D(J); ++j)
109+
{
110+
for (int i = 0; i < SM_ROWS_D(J); ++i)
111+
{
112+
SM_ELEMENT_D(J, i, j) = 0.0;
113+
}
114+
}
115+
116+
jacobian(t, NV_DATA_S(y), NV_DATA_S(fy), NV_DATA_S(J), (sunrealtype *) user_data, NV_DATA_S(tmp1), NV_DATA_S(tmp2),
117+
NV_DATA_S(tmp3), get_cuqdyn_context());
118+
119+
return 0; // éxito
120+
}

modules/cuqdyn-c/src/ode_solver.c

Lines changed: 6 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -12,121 +12,8 @@
1212
#include "cvodes/cvodes_ls.h"
1313
#include "sundials/sundials_types.h"
1414

15-
#ifndef JE
16-
#define JE(J,i,j) SM_ELEMENT_D((J),(i),(j))
17-
#endif
18-
1915
static int check_retval(void *, const char *, int);
2016

21-
int nfk_jac(sunrealtype t, N_Vector y, N_Vector fy,
22-
SUNMatrix J, void *user_data,
23-
N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
24-
{
25-
(void)t; (void)fy; (void)tmp1; (void)tmp2; (void)tmp3;
26-
27-
const sunrealtype *Y = NV_DATA_S(y);
28-
const sunrealtype y1=Y[0], y2=Y[1], y3=Y[2], y4=Y[3], y5=Y[4],
29-
y6=Y[5], y7=Y[6], y8=Y[7], y9=Y[8], y10=Y[9],
30-
y11=Y[10], y12=Y[11], y13=Y[12], y14=Y[13], y15=Y[14];
31-
32-
const sunrealtype *p = (const sunrealtype*) user_data;
33-
const sunrealtype p1 = p[0], p2 = p[1], p3 = p[2], p4 = p[3], p5 = p[4],
34-
p6 = p[5], p7 = p[6], p8 = p[7], p9 = p[8], p10= p[9],
35-
p11= p[10], p12= p[11], p13= p[12], p14= p[13], p15= p[14],
36-
p16= p[15], p17= p[16], p18= p[17], p19= p[18], p20= p[19],
37-
p21= p[20], p22= p[21], p23= p[22], p24= p[23], p25= p[24],
38-
p26= p[25], p27= p[26], p28= p[27], p29= p[28];
39-
40-
// Limpia la matriz (si tu versión de SUNDIALS no garantiza cero)
41-
for (int j = 0; j < SM_COLUMNS_D(J); ++j)
42-
{
43-
for (int i = 0; i < SM_ROWS_D(J); ++i)
44-
{
45-
SM_ELEMENT_D(J,i,j) = 0.0;
46-
}
47-
}
48-
49-
// f1
50-
JE(J, 0, 0) = -p21 -p17;
51-
52-
// f2
53-
JE(J, 1, 0) = p17;
54-
JE(J, 1, 1) = -p19 - p18*y8 - p21 - p2*y10 - p4*y13;
55-
JE(J, 1, 3) = p3;
56-
JE(J, 1, 4) = p5;
57-
JE(J, 1, 7) = -p18*y2;
58-
JE(J, 1, 9) = -p2*y2;
59-
JE(J, 1, 12) = -p4*y2;
60-
61-
// f3
62-
JE(J, 2, 1) = p19 + p18*y8;
63-
JE(J, 2, 2) = -p21;
64-
JE(J, 2, 7) = p18*y2;
65-
66-
// f4
67-
JE(J, 3, 1) = p2*y10;
68-
JE(J, 3, 3) = -p3;
69-
JE(J, 3, 9) = p2*y2;
70-
71-
// f5
72-
JE(J, 4, 1) = p4*y13;
73-
JE(J, 4, 4) = -p5;
74-
JE(J, 4, 12) = p4*y2;
75-
76-
// f6
77-
JE(J, 5, 4) = p5;
78-
JE(J, 5, 5) = -p1*y10 -p23;
79-
JE(J, 5, 9) = -p1*y6;
80-
JE(J, 5, 12) = p11;
81-
82-
// f7
83-
JE(J, 6, 5) = p23*p22;
84-
JE(J, 6, 6) = -p1*y11;
85-
JE(J, 6, 10) = -p1*y7;
86-
87-
// f8
88-
JE(J, 7, 7) = -p16;
89-
JE(J, 7, 8) = p15;
90-
91-
// f9
92-
JE(J, 8, 6) = p12;
93-
JE(J, 8, 8) = -p14;
94-
95-
// f10
96-
JE(J, 9, 1) = -p2*y10;
97-
JE(J, 9, 5) = -p1*y10;
98-
JE(J, 9, 9) = -p2*y2 - p1*y6 - p10 - p25;
99-
JE(J, 9, 10) = p26;
100-
JE(J, 9, 11) = p9;
101-
102-
// f11
103-
JE(J, 10, 6) = -p1*y11;
104-
JE(J, 10, 9) = p25*p22;
105-
JE(J, 10, 10) = -p1*y7 - p26*p22;
106-
107-
// f12
108-
JE(J, 11, 6) = p6;
109-
JE(J, 11, 11) = -p8;
110-
111-
// f13
112-
JE(J, 12, 1) = -p4*y13;
113-
JE(J, 12, 5) = p1*y10;
114-
JE(J, 12, 9) = p1*y6;
115-
JE(J, 12, 12) = -p11 -p4*y2;
116-
JE(J, 12, 13) = p24;
117-
118-
// f14
119-
JE(J, 13, 6) = p1*y11;
120-
JE(J, 13, 10) = p1*y7;
121-
JE(J, 13, 13) = -p24*p22;
122-
123-
// f15
124-
JE(J, 14, 6) = p27;
125-
JE(J, 14, 14) = -p29;
126-
127-
return 0; // éxito
128-
}
129-
13017

13118
TransposedStates solve_ode(N_Vector parameters, N_Vector initial_values, sunrealtype t0, N_Vector times)
13219
{
@@ -170,10 +57,13 @@ TransposedStates solve_ode(N_Vector parameters, N_Vector initial_values, sunreal
17057
return NULL;
17158
}
17259

173-
retval = CVodeSetJacFn(cvode_mem, nfk_jac);
174-
if (check_retval(&retval, "CVodeSetJacFn", 1))
60+
if (cuqdyn_conf->jacobian_provider_present)
17561
{
176-
return NULL;
62+
retval = CVodeSetJacFn(cvode_mem, get_jac);
63+
if (check_retval(&retval, "CVodeSetJacFn", 1))
64+
{
65+
return NULL;
66+
}
17767
}
17868

17969
char *min_step_s = getenv("SACESS_CVODES_MIN_STEP");

0 commit comments

Comments
 (0)