12 #include <cvode/cvode.h>
13 #include <nvector/nvector_serial.h>
14 #include <sundials/sundials_types.h>
15 #include <sunlinsol/sunlinsol_spgmr.h>
19 #define PMC_CONDENSE_SOLVER_SUCCESS 0
22 #define PMC_CONDENSE_SOLVER_INIT_Y 1
25 #define PMC_CONDENSE_SOLVER_INIT_ABSTOL 2
28 #define PMC_CONDENSE_SOLVER_INIT_CVODE_MEM 3
31 #define PMC_CONDENSE_SOLVER_INIT_CVODE 4
34 #define PMC_CONDENSE_SOLVER_SVTOL 5
37 #define PMC_CONDENSE_SOLVER_SET_MAX_STEPS 6
40 #define PMC_CONDENSE_SOLVER_FAIL 7
43 #define PMC_CONDENSE_SOLVER_LINSOL_CTOR 8
46 #define PMC_CONDENSE_SOLVER_LINSOL_SET 9
49 #define PMC_CONDENSE_SOLVER_LINSOL_PREC 10
52 #define PMC_CONDENSE_SOLVER_INIT_SUNDIALS 11
54 static int condense_vf(realtype t, N_Vector y, N_Vector ydot,
void *user_data);
62 N_Vector r, N_Vector b,
double gamma,
63 double delta,
int lr,
void *user_data);
69 double *b_f,
double gamma);
85 double t_initial_f,
double t_final_f)
87 realtype reltol, t_initial, t_final, t;
91 realtype *y_data, *abstol_data;
96 #if SUNDIALS_VERSION_MAJOR >= 6
97 SUNContext sunctx = NULL;
98 flag = SUNContext_Create(NULL, &sunctx);
103 #if SUNDIALS_VERSION_MAJOR >= 6
104 y = N_VNew_Serial(neq, sunctx);
106 y = N_VNew_Serial(neq);
111 #if SUNDIALS_VERSION_MAJOR >= 6
112 abstol = N_VNew_Serial(neq, sunctx);
114 abstol = N_VNew_Serial(neq);
119 y_data = NV_DATA_S(y);
120 abstol_data = NV_DATA_S(abstol);
121 for (i = 0; i < neq; i++) {
123 abstol_data[i] = abstol_f[i];
127 t_initial = t_initial_f;
130 #if SUNDIALS_VERSION_MAJOR >= 6
131 cvode_mem = CVodeCreate(CV_BDF, sunctx);
133 cvode_mem = CVodeCreate(CV_BDF);
138 flag = CVodeInit(cvode_mem,
condense_vf, t_initial, y);
142 flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
146 flag = CVodeSetMaxNumSteps(cvode_mem, 100000);
151 #if SUNDIALS_VERSION_MAJOR >= 6
152 SUNLinearSolver LS = SUNLinSol_SPGMR(y, PREC_LEFT, 0, sunctx);
154 SUNLinearSolver LS = SUNLinSol_SPGMR(y, PREC_LEFT, 0);
158 flag = CVodeSetLinearSolver(cvode_mem, LS, NULL);
166 flag = CVode(cvode_mem, t_final, y, &t, CV_NORMAL);
170 for (i = 0; i < neq; i++) {
174 N_VDestroy_Serial(y);
175 N_VDestroy_Serial(abstol);
176 CVodeFree(&cvode_mem);
177 #if SUNDIALS_VERSION_MAJOR >= 6
178 SUNContext_Free(&sunctx);
191 #pragma GCC diagnostic push
192 #pragma GCC diagnostic ignored "-Wunused-parameter"
193 static int condense_vf(realtype t, N_Vector y, N_Vector ydot,
void *user_data)
195 realtype *y_data, *ydot_data;
197 double *y_f, *ydot_f;
199 neq = NV_LENGTH_S(y);
200 y_data = NV_DATA_S(y);
201 ydot_data = NV_DATA_S(ydot);
203 y_f = malloc(neq *
sizeof(
double));
204 ydot_f = malloc(neq *
sizeof(
double));
206 for (i = 0; i < neq; i++) {
210 for (i = 0; i < neq; i++) {
211 ydot_data[i] = ydot_f[i];
218 #pragma GCC diagnostic pop
244 if (opt == 0 && flagvalue == NULL) {
246 "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n",
252 errflag = (
int *) flagvalue;
254 fprintf(stderr,
"\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n",
259 else if (opt == 2 && flagvalue == NULL) {
260 fprintf(stderr,
"\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n",
274 #pragma GCC diagnostic push
275 #pragma GCC diagnostic ignored "-Wunused-parameter"
277 N_Vector b, N_Vector z,
double gamma,
278 double delta,
int lr,
void *user_data)
280 realtype *b_data, *ycur_data, *fcur_data, *z_data;
282 double *b_f, *ycur_f, *fcur_f;
284 neq = NV_LENGTH_S(b);
285 b_data = NV_DATA_S(b);
286 z_data = NV_DATA_S(z);
287 ycur_data = NV_DATA_S(ycur);
288 fcur_data = NV_DATA_S(fcur);
290 b_f = malloc(neq *
sizeof(
double));
291 ycur_f = malloc(neq *
sizeof(
double));
292 fcur_f = malloc(neq *
sizeof(
double));
294 for (i = 0; i < neq; i++) {
296 ycur_f[i] = ycur_data[i];
297 fcur_f[i] = fcur_data[i];
300 for (i = 0; i < neq; i++) {
309 #pragma GCC diagnostic pop