@@ -92,7 +92,7 @@ cdef extern from "cvode/cvode.h":
92
92
ctypedef int (* CVRootFn)(realtype t, N_Vector y, realtype * gout, void * user_data)
93
93
94
94
void * CVodeCreate(int lmm, SUNContext sunctx)
95
- int CVodeStep " CVode" (void * cvode_mem, realtype tout, N_Vector yout, realtype * tret, int itask) nogil
95
+ int CVode " CVode" (void * cvode_mem, realtype tout, N_Vector yout, realtype * tret, int itask) nogil
96
96
int CVodeSetUserData(void * cvode_mem, void * user_data)
97
97
int CVodeSetMaxOrd(void * cvode_mem, int maxord)
98
98
int CVodeSetMaxNumSteps(void * cvode_mem, long int mxsteps)
@@ -146,7 +146,7 @@ cdef extern from "cvode/cvode.h":
146
146
147
147
int CVDlsGetNumJacEvals(void * cvode_mem, long int * njevals)
148
148
int CVDlsGetNumRhsEvals(void * cvode_mem, long int * nrevalsLS)
149
- int CVSpilsGetNumJtimesEvals (void * cvode_mem, long int * njevals)
149
+ int CVodeGetNumJtimesEvals (void * cvode_mem, long int * njevals)
150
150
151
151
cdef extern from " sunlinsol/sunlinsol_spgmr.h" :
152
152
int CVSpgmr(void * cvode_mem, int pretype, int max1)
@@ -177,10 +177,10 @@ cdef extern from "cvode/cvode_ls.h":
177
177
# int CVSpilsSetJacTimesVecFn(void *cvode_mem, CVSpilsJacTimesVecFn jtv)
178
178
179
179
cdef extern from " sundials/sundials_iterative.h" :
180
- int PREC_NONE
181
- int PREC_LEFT
182
- int PREC_RIGHT
183
- int PREC_BOTH
180
+ int SUN_PREC_NONE
181
+ int SUN_PREC_LEFT
182
+ int SUN_PREC_RIGHT
183
+ int SUN_PREC_BOTH
184
184
185
185
int MODIFIED_GS
186
186
int CLASSICAL_GS
@@ -290,16 +290,15 @@ cdef int cv_jtimes_openmp(N_Vector v, N_Vector Jv, double t, N_Vector y, N_Vecto
290
290
return 0
291
291
292
292
293
- cdef int psolve(double t, N_Vector y, N_Vector fy,
294
- N_Vector r, N_Vector z, double gamma, double delta, int lr,
295
- void * user_data, N_Vector tmp):
293
+ # static int PSolve(realtype tn, N_Vector u, N_Vector fu, N_Vector r, N_Vector z,
294
+ # realtype gamma, realtype delta, int lr, void *user_data);
295
+ cdef int psolve(double t, N_Vector y, N_Vector fy, N_Vector r, N_Vector z,
296
+ double gamma, double delta, int lr, void * user_data):
296
297
copy_nv2nv(z, r)
297
298
return 0
298
299
299
- cdef int psolve_openmp(double t, N_Vector y, N_Vector fy,
300
- N_Vector r, N_Vector z, double gamma,
301
- double delta, int lr,
302
- void * user_data, N_Vector tmp):
300
+ cdef int psolve_openmp(double t, N_Vector y, N_Vector fy, N_Vector r, N_Vector z,
301
+ double gamma, double delta, int lr, void * user_data):
303
302
copy_nv2nv_openmp(z, r)
304
303
return 0
305
304
@@ -401,13 +400,35 @@ cdef class CvodeSolver(object):
401
400
self .check_flag(flag, " CVDiag" )
402
401
elif self .linear_solver == " spgmr" :
403
402
if self .has_jtimes:
403
+ # The Jacobian preconditioner is set here based on the
404
+ # cvDiurnal_kry.c example from Sundials 6.1.1
405
+
404
406
# CVSpgmr(cvode_mem, pretype, maxl) p. 27 of CVODE 2.7 manual
405
- flag = CVSpgmr(self .cvode_mem, PREC_LEFT, 300 )
406
- self .check_flag(flag, " CVSpgmr" )
407
+ # flag = CVSpgmr(self.cvode_mem, PREC_LEFT, 300)
408
+ # self.check_flag(flag, "CVSpgmr")
409
+
410
+ # Call SUNLinSol_SPGMR to specify the linear solver SPGMR
411
+ # with left preconditioning and the default Krylov dimension
412
+ LS = SUNLinSol_SPGMR(u, SUN_PREC_LEFT, 0 , sunctx);
413
+ # TODO:
414
+ # if(check_retval((void *)LS, "SUNLinSol_SPGMR", 0)) return(1);
415
+
416
+ # Call CVodeSetLinearSolver to attach the linear sovler to CVode
417
+ flag = CVodeSetLinearSolver(cvode_mem, LS, NULL );
418
+ self .check_flag(flag, " CVodeSetLinearSolver" )
419
+ # if (check_retval(&retval, "CVodeSetLinearSolver", 1)) return 1;
420
+
421
+ # Set the Jacobian-times-vector function */
422
+ flag = CVodeSetJacTimes(cvode_mem, NULL , jtv);
423
+ self .check_flag(flag, " CVodeSetJacTimes" )
424
+
407
425
# functions below in p. 37 CVODE 2.7 manual
408
- flag = CVodeSetJacTimes(self .cvode_mem, NULL , < CVSpilsJacTimesVecFn > self .jvn_fun)
409
- self .check_flag(flag, " CVSpilsSetJacTimesVecFn" )
410
- flag = CVodeSetPreconditioner(self .cvode_mem, < CVSpilsPrecSetupFn > self .psetup, < CVSpilsPrecSolveFn > psolve)
426
+ # flag = CVodeSetJacTimes(self.cvode_mem, NULL, < CVSpilsJacTimesVecFn > self.jvn_fun)
427
+ # self.check_flag(flag, "CVSpilsSetJacTimesVecFn")
428
+
429
+ flag = CVodeSetPreconditioner(self .cvode_mem,
430
+ < CVLsPrecSetupFn > self .Precond,
431
+ < CVLsPrecSolveFn > psolve)
411
432
self .check_flag(flag, " CVodeSetPreconditioner" )
412
433
else :
413
434
# this will use the SPGMR without preconditioner and without
@@ -417,8 +438,9 @@ cdef class CvodeSolver(object):
417
438
# Actually, it's the same Jacobian approximation as used
418
439
# in CVDiag (only difference is CVDiag is a direct linear
419
440
# solver).
420
- flag = CVSpgmr(self .cvode_mem, PREC_NONE, 300 )
421
- self .check_flag(flag, " CVSpgmr" )
441
+ flag = SUNLinSol_SPGMR(self .cvode_mem, SUN_PREC_NONE, 300 )
442
+ # TODO:
443
+ # self.check_flag(flag, "SUNLinSol_SPGMR")
422
444
else :
423
445
raise RuntimeError (
424
446
" linear_solver is {}, should be spgmr or diag" .format(self .linear_solver))
@@ -446,17 +468,21 @@ cdef class CvodeSolver(object):
446
468
flag = CVodeReInit(self .cvode_mem, self .t, self .u_y)
447
469
self .check_flag(flag, " CVodeReInit" )
448
470
471
+ # TODO: Instead of using flags we should use Sundials internal flag
472
+ # like CV_SUCCESS
449
473
cpdef int run_until(self , double t_final) except - 1 :
450
474
cdef int flag
451
475
cdef double t_returned
452
- flag = CVodeStep (self .cvode_mem, t_final, self .u_y, & t_returned, CV_NORMAL)
453
- self .check_flag(flag, " CVodeStep " )
476
+ flag = CVode (self .cvode_mem, t_final, self .u_y, & t_returned, CV_NORMAL)
477
+ self .check_flag(flag, " CVode " )
454
478
self .t = t_returned
455
479
return 0
456
480
457
- cdef int psetup(self , double t, N_Vector y, N_Vector fy,
458
- booleantype jok, booleantype * jcurPtr, double gamma,
459
- void * user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3):
481
+ # From exmaples: cvDiurnal_kry.c in Sundials repo:
482
+ # static int Precond(realtype tn, N_Vector u, N_Vector fu, booleantype jok,
483
+ # booleantype *jcurPtr, realtype gamma, void *user_data)
484
+ cdef int Precond(self , double t, N_Vector y, N_Vector fy, booleantype jok,
485
+ booleantype * jcurPtr, double gamma, void * user_data):
460
486
if not jok:
461
487
copy_nv2arr(y, self .y)
462
488
return 0
@@ -472,7 +498,7 @@ cdef class CvodeSolver(object):
472
498
def stat (self ):
473
499
CVodeGetNumSteps(self .cvode_mem, & self .nsteps)
474
500
CVodeGetNumRhsEvals(self .cvode_mem, & self .nfevals)
475
- CVSpilsGetNumJtimesEvals (self .cvode_mem, & self .njevals)
501
+ CVodeGetNumJtimesEvals (self .cvode_mem, & self .njevals)
476
502
return self .nsteps, self .nfevals, self .njevals
477
503
478
504
def get_current_step (self ):
@@ -592,14 +618,20 @@ cdef class CvodeSolver_OpenMP(object):
592
618
self .check_flag(flag, " CVDiag" )
593
619
elif self .linear_solver == " spgmr" :
594
620
if self .has_jtimes:
595
- # CVSpgmr(cvode_mem, pretype, maxl) p. 27 of CVODE 2.7 manual
596
- flag = CVSpgmr(self .cvode_mem, PREC_LEFT, 300 )
597
- self .check_flag(flag, " CVSpgmr" )
598
- # functions below in p. 37 CVODE 2.7 manual
599
- flag = CVSpilsSetJacTimesVecFn(self .cvode_mem, < CVSpilsJacTimesVecFn > self .jvn_fun)
600
- self .check_flag(flag, " CVSpilsSetJacTimesVecFn" )
601
- flag = CVSpilsSetPreconditioner(self .cvode_mem, < CVSpilsPrecSetupFn > self .psetup, < CVSpilsPrecSolveFn > psolve_openmp)
602
- self .check_flag(flag, " CVSpilsSetPreconditioner" )
621
+
622
+ LS = SUNLinSol_SPGMR(u, SUN_PREC_LEFT, 0 , sunctx);
623
+
624
+ flag = CVodeSetLinearSolver(cvode_mem, LS, NULL );
625
+ self .check_flag(flag, " CVodeSetLinearSolver" )
626
+
627
+ flag = CVodeSetJacTimes(cvode_mem, NULL , jtv);
628
+ self .check_flag(flag, " CVodeSetJacTimes" )
629
+
630
+ flag = CVodeSetPreconditioner(self .cvode_mem,
631
+ < CVLsPrecSetupFn > self .Precond,
632
+ < CVLsPrecSolveFn > psolve_openmp)
633
+ self .check_flag(flag, " CVodeSetPreconditioner" )
634
+
603
635
else :
604
636
# this will use the SPGMR without preconditioner and without
605
637
# our computation of the product J * m'. Instead, it uses
@@ -608,8 +640,8 @@ cdef class CvodeSolver_OpenMP(object):
608
640
# Actually, it's the same Jacobian approximation as used
609
641
# in CVDiag (only difference is CVDiag is a direct linear
610
642
# solver).
611
- flag = CVSpgmr (self .cvode_mem, PREC_NONE , 300 )
612
- self .check_flag(flag, " CVSpgmr" )
643
+ flag = SUNLinSol_SPGMR (self .cvode_mem, SUN_PREC_NONE , 300 )
644
+ # self.check_flag(flag, "CVSpgmr")
613
645
else :
614
646
raise RuntimeError (
615
647
" linear_solver is {}, should be spgmr or diag" .format(self .linear_solver))
@@ -640,14 +672,14 @@ cdef class CvodeSolver_OpenMP(object):
640
672
cpdef int run_until(self , double t_final) except - 1 :
641
673
cdef int flag
642
674
cdef double t_returned
643
- flag = CVodeStep (self .cvode_mem, t_final, self .u_y, & t_returned, CV_NORMAL)
644
- self .check_flag(flag, " CVodeStep " )
675
+ flag = CVode (self .cvode_mem, t_final, self .u_y, & t_returned, CV_NORMAL)
676
+ self .check_flag(flag, " CVode " )
645
677
self .t = t_returned
646
678
return 0
647
679
648
- cdef int psetup (self , double t, N_Vector y, N_Vector fy,
649
- booleantype jok, booleantype * jcurPtr, double gamma,
650
- void * user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3 ):
680
+ cdef int Precond (self , double t, N_Vector y, N_Vector fy,
681
+ booleantype jok, booleantype * jcurPtr, double gamma,
682
+ void * user_data):
651
683
if not jok:
652
684
copy_nv2arr_openmp(y, self .y)
653
685
return 0
0 commit comments