14 #ifdef MFEM_USE_SUNDIALS
21 #include <nvector/nvector_serial.h>
23 #include <nvector/nvector_parallel.h>
26 #include <cvode/cvode_impl.h>
27 #include <cvode/cvode_spgmr.h>
34 #include <arkode/arkode_impl.h>
35 #include <arkode/arkode_spgmr.h>
37 #include <kinsol/kinsol_impl.h>
38 #include <kinsol/kinsol_spgmr.h>
45 double SundialsODELinearSolver::GetTimeStep(
void *sundials_mem)
47 return (type == CVODE) ?
48 ((CVodeMem)sundials_mem)->cv_gamma :
49 ((ARKodeMem)sundials_mem)->ark_gamma;
53 SundialsODELinearSolver::GetTimeDependentOperator(
void *sundials_mem)
55 void *user_data = (type == CVODE) ?
56 ((CVodeMem)sundials_mem)->cv_user_data :
57 ((ARKodeMem)sundials_mem)->ark_user_data;
66 static int cvLinSysInit(CVodeMem cv_mem)
68 return to_solver(cv_mem->cv_lmem)->
InitSystem(cv_mem);
71 static int cvLinSysSetup(CVodeMem cv_mem,
int convfail,
72 N_Vector ypred, N_Vector fpred, booleantype *jcurPtr,
73 N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3)
75 Vector yp(ypred), fp(fpred), vt1(vtemp1), vt2(vtemp2), vt3(vtemp3);
76 return to_solver(cv_mem->cv_lmem)->
SetupSystem(cv_mem, convfail, yp, fp,
77 *jcurPtr, vt1, vt2, vt3);
80 static int cvLinSysSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight,
81 N_Vector ycur, N_Vector fcur)
83 Vector bb(b), w(weight), yc(ycur), fc(fcur);
84 return to_solver(cv_mem->cv_lmem)->
SolveSystem(cv_mem, bb, w, yc, fc);
87 static int cvLinSysFree(CVodeMem cv_mem)
89 return to_solver(cv_mem->cv_lmem)->
FreeSystem(cv_mem);
92 static int arkLinSysInit(ARKodeMem ark_mem)
94 return to_solver(ark_mem->ark_lmem)->
InitSystem(ark_mem);
97 static int arkLinSysSetup(ARKodeMem ark_mem,
int convfail,
98 N_Vector ypred, N_Vector fpred, booleantype *jcurPtr,
99 N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3)
101 Vector yp(ypred), fp(fpred), vt1(vtemp1), vt2(vtemp2), vt3(vtemp3);
102 return to_solver(ark_mem->ark_lmem)->
SetupSystem(ark_mem, convfail, yp, fp,
103 *jcurPtr, vt1, vt2, vt3);
106 static int arkLinSysSolve(ARKodeMem ark_mem, N_Vector b, N_Vector weight,
107 N_Vector ycur, N_Vector fcur)
109 Vector bb(b), w(weight), yc(ycur), fc(fcur);
110 return to_solver(ark_mem->ark_lmem)->
SolveSystem(ark_mem, bb, w, yc, fc);
113 static int arkLinSysFree(ARKodeMem ark_mem)
115 return to_solver(ark_mem->ark_lmem)->
FreeSystem(ark_mem);
118 const double SundialsSolver::default_rel_tol = 1e-4;
119 const double SundialsSolver::default_abs_tol = 1e-9;
122 int SundialsSolver::ODEMult(realtype t,
const N_Vector y,
123 N_Vector ydot,
void *td_oper)
131 f->
Mult(mfem_y, mfem_ydot);
135 static inline CVodeMem Mem(
const CVODESolver *
self)
137 return CVodeMem(self->SundialsMem());
140 CVODESolver::CVODESolver(
int lmm,
int iter)
143 y = N_VNewEmpty_Serial(0);
144 MFEM_ASSERT(y,
"error in N_VNewEmpty_Serial()");
147 sundials_mem = CVodeCreate(lmm, iter);
148 MFEM_ASSERT(sundials_mem,
"error in CVodeCreate()");
150 SetStepMode(CV_NORMAL);
153 SetSStolerances(default_rel_tol, default_abs_tol);
160 CVODESolver::CVODESolver(MPI_Comm comm,
int lmm,
int iter)
162 if (comm == MPI_COMM_NULL)
165 y = N_VNewEmpty_Serial(0);
166 MFEM_ASSERT(y,
"error in N_VNewEmpty_Serial()");
171 y = N_VNewEmpty_Parallel(comm, 0, 0);
172 MFEM_ASSERT(y,
"error in N_VNewEmpty_Parallel()");
176 sundials_mem = CVodeCreate(lmm, iter);
177 MFEM_ASSERT(sundials_mem,
"error in CVodeCreate()");
179 SetStepMode(CV_NORMAL);
182 SetSStolerances(default_rel_tol, default_abs_tol);
187 #endif // MFEM_USE_MPI
189 void CVODESolver::SetSStolerances(
double reltol,
double abstol)
191 CVodeMem mem = Mem(
this);
193 mem->cv_reltol = reltol;
194 mem->cv_Sabstol = abstol;
200 CVodeMem mem = Mem(
this);
201 MFEM_ASSERT(mem->cv_iter == CV_NEWTON,
202 "The function is applicable only to CV_NEWTON iteration type.");
204 if (mem->cv_lfree != NULL) { (mem->cv_lfree)(mem); }
208 mem->cv_linit = cvLinSysInit;
209 mem->cv_lsetup = cvLinSysSetup;
210 mem->cv_lsolve = cvLinSysSolve;
211 mem->cv_lfree = cvLinSysFree;
212 mem->cv_lmem = &ls_spec;
213 mem->cv_setupNonNull = TRUE;
214 ls_spec.
type = SundialsODELinearSolver::CVODE;
217 void CVODESolver::SetStepMode(
int itask)
219 Mem(
this)->cv_taskc = itask;
222 void CVODESolver::SetMaxOrder(
int max_order)
224 flag = CVodeSetMaxOrd(sundials_mem, max_order);
225 if (flag == CV_ILL_INPUT)
227 MFEM_WARNING(
"CVodeSetMaxOrd() did not change the maximum order!");
232 static inline void cvCopyInit(CVodeMem src, CVodeMem dest)
234 dest->cv_lmm = src->cv_lmm;
235 dest->cv_iter = src->cv_iter;
237 dest->cv_linit = src->cv_linit;
238 dest->cv_lsetup = src->cv_lsetup;
239 dest->cv_lsolve = src->cv_lsolve;
240 dest->cv_lfree = src->cv_lfree;
241 dest->cv_lmem = src->cv_lmem;
242 dest->cv_setupNonNull = src->cv_setupNonNull;
244 dest->cv_reltol = src->cv_reltol;
245 dest->cv_Sabstol = src->cv_Sabstol;
247 dest->cv_taskc = src->cv_taskc;
248 dest->cv_qmax = src->cv_qmax;
255 CVodeMem mem = Mem(
this);
258 if (mem->cv_MallocDone == TRUE)
261 cvCopyInit(mem, &backup);
262 CVodeFree(&sundials_mem);
263 sundials_mem = CVodeCreate(backup.cv_lmm, backup.cv_iter);
264 MFEM_ASSERT(sundials_mem,
"error in CVodeCreate()");
265 cvCopyInit(&backup, mem);
271 int loc_size = f_.
Height();
274 NV_LENGTH_S(y) = loc_size;
275 NV_DATA_S(y) =
new double[loc_size]();
280 long local_size = loc_size, global_size;
281 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
283 NV_LOCLENGTH_P(y) = local_size;
284 NV_GLOBLENGTH_P(y) = global_size;
285 NV_DATA_P(y) =
new double[loc_size]();
290 cvCopyInit(mem, &backup);
291 flag = CVodeInit(mem, ODEMult, f_.
GetTime(), y);
292 MFEM_ASSERT(flag >= 0,
"CVodeInit() failed!");
293 cvCopyInit(&backup, mem);
298 delete [] NV_DATA_S(y);
304 delete [] NV_DATA_P(y);
310 flag = CVodeSetUserData(sundials_mem, f);
311 MFEM_ASSERT(flag >= 0,
"CVodeSetUserData() failed!");
313 flag = CVodeSStolerances(mem, mem->cv_reltol, mem->cv_Sabstol);
314 MFEM_ASSERT(flag >= 0,
"CVodeSStolerances() failed!");
317 void CVODESolver::Step(
Vector &x,
double &t,
double &dt)
319 CVodeMem mem = Mem(
this);
324 MFEM_VERIFY(NV_LENGTH_S(y) == x.
Size(),
"");
330 MFEM_VERIFY(NV_LOCLENGTH_P(y) == x.
Size(),
"");
334 if (mem->cv_nst == 0)
337 if (mem->cv_iter == CV_NEWTON && mem->cv_lsolve == NULL)
339 flag = CVSpgmr(sundials_mem, PREC_NONE, 0);
343 N_VScale(ONE, y, mem->cv_zn[0]);
346 double tout = t + dt;
348 flag = CVode(sundials_mem, tout, y, &t, mem->cv_taskc);
349 MFEM_ASSERT(flag >= 0,
"CVode() failed!");
355 void CVODESolver::PrintInfo()
const
357 CVodeMem mem = Mem(
this);
361 "num steps: " << mem->cv_nst <<
", "
362 "num evals: " << mem->cv_nfe <<
", "
363 "num lin setups: " << mem->cv_nsetups <<
", "
364 "num nonlin sol iters: " << mem->cv_nni <<
"\n "
365 "last order: " << mem->cv_qu <<
", "
366 "next order: " << mem->cv_next_q <<
", "
367 "last dt: " << mem->cv_hu <<
", "
368 "next dt: " << mem->cv_next_h
372 CVODESolver::~CVODESolver()
375 CVodeFree(&sundials_mem);
380 return ARKodeMem(self->SundialsMem());
383 ARKODESolver::ARKODESolver(
Type type)
384 : use_implicit(type == IMPLICIT), irk_table(-1), erk_table(-1)
387 y = N_VNewEmpty_Serial(0);
388 MFEM_ASSERT(
y,
"error in N_VNewEmpty_Serial()");
404 : use_implicit(type == IMPLICIT), irk_table(-1), erk_table(-1)
406 if (comm == MPI_COMM_NULL)
409 y = N_VNewEmpty_Serial(0);
410 MFEM_ASSERT(
y,
"error in N_VNew_Serial()");
415 y = N_VNewEmpty_Parallel(comm, 0, 0);
416 MFEM_ASSERT(
y,
"error in N_VNewEmpty_Parallel()");
434 ARKodeMem mem = Mem(
this);
436 mem->ark_reltol = reltol;
437 mem->ark_Sabstol = abstol;
443 ARKodeMem mem = Mem(
this);
445 "The function is applicable only to implicit time integration.");
447 if (mem->ark_lfree != NULL) { mem->ark_lfree(mem); }
450 mem->ark_lsolve_type = 4;
453 mem->ark_linit = arkLinSysInit;
454 mem->ark_lsetup = arkLinSysSetup;
455 mem->ark_lsolve = arkLinSysSolve;
456 mem->ark_lfree = arkLinSysFree;
457 mem->ark_lmem = &ls_spec;
458 mem->ark_setupNonNull = TRUE;
464 Mem(
this)->ark_taskc = itask;
469 ARKodeMem mem = Mem(
this);
490 MFEM_ASSERT(
flag >= 0,
"ARKodeSetFixedStep() failed!");
494 static inline void arkCopyInit(ARKodeMem src, ARKodeMem dest)
496 dest->ark_lsolve_type = src->ark_lsolve_type;
497 dest->ark_linit = src->ark_linit;
498 dest->ark_lsetup = src->ark_lsetup;
499 dest->ark_lsolve = src->ark_lsolve;
500 dest->ark_lfree = src->ark_lfree;
501 dest->ark_lmem = src->ark_lmem;
502 dest->ark_setupNonNull = src->ark_setupNonNull;
504 dest->ark_reltol = src->ark_reltol;
505 dest->ark_Sabstol = src->ark_Sabstol;
507 dest->ark_taskc = src->ark_taskc;
508 dest->ark_q = src->ark_q;
509 dest->ark_fixedstep = src->ark_fixedstep;
510 dest->ark_hin = src->ark_hin;
515 ARKodeMem mem = Mem(
this);
519 if (mem->ark_MallocDone == TRUE)
522 arkCopyInit(mem, &backup);
526 arkCopyInit(&backup, mem);
532 int loc_size = f_.
Height();
535 NV_LENGTH_S(
y) = loc_size;
536 NV_DATA_S(
y) =
new double[loc_size]();
541 long local_size = loc_size, global_size;
542 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
544 NV_LOCLENGTH_P(
y) = local_size;
545 NV_GLOBLENGTH_P(
y) = global_size;
546 NV_DATA_P(
y) =
new double[loc_size]();
551 arkCopyInit(mem, &backup);
557 MFEM_ASSERT(
flag >= 0,
"CVodeInit() failed!");
558 arkCopyInit(&backup, mem);
563 delete [] NV_DATA_S(
y);
569 delete [] NV_DATA_P(
y);
576 MFEM_ASSERT(
flag >= 0,
"ARKodeSetUserData() failed!");
578 flag = ARKodeSStolerances(mem, mem->ark_reltol, mem->ark_Sabstol);
579 MFEM_ASSERT(
flag >= 0,
"CVodeSStolerances() failed!");
582 MFEM_ASSERT(
flag >= 0,
"ARKodeSetOrder() failed!");
587 MFEM_ASSERT(
flag >= 0,
"ARKodeSetIRKTableNum() failed!");
592 MFEM_ASSERT(
flag >= 0,
"ARKodeSetERKTableNum() failed!");
598 ARKodeMem mem = Mem(
this);
603 MFEM_VERIFY(NV_LENGTH_S(
y) == x.
Size(),
"");
609 MFEM_VERIFY(NV_LOCLENGTH_P(
y) == x.
Size(),
"");
613 if (mem->ark_nst == 0)
616 if (mem->ark_implicit && mem->ark_linit == NULL)
624 N_VScale(ONE,
y, mem->ark_ycur);
627 double tout = t + dt;
630 MFEM_ASSERT(
flag >= 0,
"ARKode() failed!");
638 ARKodeMem mem = Mem(
this);
642 "num steps: " << mem->ark_nst <<
", "
643 "num evals: " << mem->ark_nfe <<
", "
644 "num lin setups: " << mem->ark_nsetups <<
", "
645 "num nonlin sol iters: " << mem->ark_nni <<
"\n "
646 "method order: " << mem->ark_q <<
", "
647 "last dt: " << mem->ark_h <<
", "
648 "next dt: " << mem->ark_next_h
659 static inline KINMem Mem(
const KinSolver *
self)
661 return KINMem(self->SundialsMem());
677 booleantype *new_u,
void *user_data)
685 self->jacobian = &
self->oper->GetGradient(mfem_u);
688 self->jacobian->Mult(mfem_v, mfem_Jv);
695 const Vector u(kin_mem->kin_uu);
700 self->prec->SetOperator(*self->jacobian);
707 realtype *sJpnorm, realtype *sFdotJp)
716 if ( (kin_mem->kin_globalstrategy == KIN_LINESEARCH) ||
717 (kin_mem->kin_globalstrategy != KIN_FP &&
718 kin_mem->kin_etaflag == KIN_ETACHOICE1) )
721 self->jacobian->Mult(mx, mb);
723 *sJpnorm = N_VWL2Norm(b, kin_mem->kin_fscale);
724 N_VProd(b, kin_mem->kin_fscale, b);
725 N_VProd(b, kin_mem->kin_fscale, b);
726 *sFdotJp = N_VDotProd(kin_mem->kin_fval, b);
734 : use_oper_grad(oper_grad), jacobian(NULL)
737 y = N_VNewEmpty_Serial(0);
738 y_scale = N_VNewEmpty_Serial(0);
739 f_scale = N_VNewEmpty_Serial(0);
740 MFEM_ASSERT(
y &&
y_scale &&
f_scale,
"Error in N_VNewEmpty_Serial().");
745 Mem(
this)->kin_globalstrategy = strategy;
747 abs_tol = Mem(
this)->kin_fnormtol;
756 : use_oper_grad(oper_grad), jacobian(NULL)
758 if (comm == MPI_COMM_NULL)
761 y = N_VNewEmpty_Serial(0);
762 y_scale = N_VNewEmpty_Serial(0);
763 f_scale = N_VNewEmpty_Serial(0);
764 MFEM_ASSERT(
y &&
y_scale &&
f_scale,
"Error in N_VNewEmpty_Serial().");
769 y = N_VNewEmpty_Parallel(comm, 0, 0);
770 y_scale = N_VNewEmpty_Parallel(comm, 0, 0);
771 f_scale = N_VNewEmpty_Parallel(comm, 0, 0);
772 MFEM_ASSERT(
y &&
y_scale &&
f_scale,
"Error in N_VNewEmpty_Parallel().");
778 Mem(
this)->kin_globalstrategy = strategy;
780 abs_tol = Mem(
this)->kin_fnormtol;
789 static inline void kinCopyInit(KINMem src, KINMem dest)
791 dest->kin_linit = src->kin_linit;
792 dest->kin_lsetup = src->kin_lsetup;
793 dest->kin_lsolve = src->kin_lsolve;
794 dest->kin_lfree = src->kin_lfree;
795 dest->kin_lmem = src->kin_lmem;
796 dest->kin_setupNonNull = src->kin_setupNonNull;
797 dest->kin_msbset = src->kin_msbset;
799 dest->kin_globalstrategy = src->kin_globalstrategy;
800 dest->kin_printfl = src->kin_printfl;
801 dest->kin_mxiter = src->kin_mxiter;
802 dest->kin_scsteptol = src->kin_scsteptol;
803 dest->kin_fnormtol = src->kin_fnormtol;
808 KINMem mem = Mem(
this);
812 if (mem->kin_MallocDone == TRUE)
815 kinCopyInit(mem, &backup);
819 kinCopyInit(&backup, mem);
829 NV_DATA_S(
y) =
new double[
height]();
838 long local_size =
height, global_size;
839 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
841 NV_LOCLENGTH_P(
y) = local_size;
842 NV_GLOBLENGTH_P(
y) = global_size;
843 NV_DATA_P(
y) =
new double[local_size]();
844 NV_LOCLENGTH_P(
y_scale) = local_size;
845 NV_GLOBLENGTH_P(
y_scale) = global_size;
847 NV_LOCLENGTH_P(
f_scale) = local_size;
848 NV_GLOBLENGTH_P(
f_scale) = global_size;
853 kinCopyInit(mem, &backup);
858 N_VConst(ZERO, mem->kin_pp);
859 MFEM_ASSERT(
flag >= 0,
"KINInit() failed!");
860 kinCopyInit(&backup, mem);
865 delete [] NV_DATA_S(
y);
871 delete [] NV_DATA_P(
y);
878 MFEM_ASSERT(
flag >= 0,
"KINSetUserData() failed!");
884 MFEM_ASSERT(
flag >= 0,
"KINSpgmr() failed!");
889 MFEM_ASSERT(
flag >= 0,
"KINSpilsSetJacTimesVecFn() failed!");
898 KINMem mem = Mem(
this);
900 mem->kin_linit = NULL;
903 mem->kin_lfree = NULL;
904 mem->kin_lmem =
this;
905 mem->kin_setupNonNull = TRUE;
911 Mem(
this)->kin_scsteptol = sstol;
916 Mem(
this)->kin_msbset = max_calls;
937 MPI_Allreduce(&lnorm, &norm, 1, MPI_DOUBLE, MPI_MAX, NV_COMM_P(
y));
948 Mem(
this)->kin_fnormtol =
abs_tol;
953 Mem(
this)->kin_fnormtol =
rel_tol;
958 Mem(
this)->kin_fnormtol =
abs_tol;
968 KINMem mem = Mem(
this);
971 MFEM_ASSERT(
flag >= 0,
"KINSetPrintLevel() failed!");
974 MFEM_ASSERT(
flag >= 0,
"KINSetNumMaxIters() failed!");
977 MFEM_ASSERT(
flag >= 0,
"KINSetScaledStepTol() failed!");
980 MFEM_ASSERT(
flag >= 0,
"KINSetFuncNormTol() failed!");
985 MFEM_VERIFY(NV_LENGTH_S(
y) == x.
Size(),
"");
993 MFEM_VERIFY(NV_LOCLENGTH_P(
y) == x.
Size(),
"");
void SetFixedStep(double dt)
Use a fixed time step size, instead of performing any form of temporal adaptivity.
virtual double GetTime() const
Read the currently set time.
virtual int FreeSystem(void *sundials_mem)=0
static const double default_abs_tol
virtual void Init(TimeDependentOperator &f_)
Set the ODE right-hand-side operator.
void SetMaxSetupCalls(int max_calls)
Set maximum number of nonlinear iterations without a Jacobian update.
virtual void Init(TimeDependentOperator &f)
Associate a TimeDependentOperator with the ODE solver.
static int Mult(const N_Vector u, N_Vector fu, void *user_data)
Base abstract class for time dependent operators.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
static int ODEMult(realtype t, const N_Vector y, N_Vector ydot, void *td_oper)
Callback function used in CVODESolver and ARKODESolver.
virtual ~KinSolver()
Destroy the associated KINSOL memory.
void SetStepMode(int itask)
ARKode supports two modes, specified by itask: ARK_NORMAL (default) and ARK_ONE_STEP.
virtual void SetTime(const double _t)
Set the current time.
int Size() const
Returns the size of the vector.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
void * sundials_mem
Pointer to the SUNDIALS mem object.
double Normlinf() const
Returns the l_infinity norm of the vector.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
Type
Types of ARKODE solvers.
void SetSStolerances(double reltol, double abstol)
Specify the scalar relative and scalar absolute tolerances.
void SetERKTableNum(int table_num)
Choose a specific Butcher table for explicit RK method.
virtual int InitSystem(void *sundials_mem)=0
virtual int SetupSystem(void *sundials_mem, int conv_fail, const Vector &y_pred, const Vector &f_pred, int &jac_cur, Vector &v_temp1, Vector &v_temp2, Vector &v_temp3)=0
ARKODESolver(Type type=EXPLICIT)
Construct a serial ARKODESolver, a wrapper for SUNDIALS' ARKODE solver.
enum mfem::SundialsODELinearSolver::@0 type
Is CVODE or ARKODE using this object?
Wrapper for SUNDIALS' KINSOL library – Nonlinear solvers.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Wrapper for SUNDIALS' CVODE library – Multi-step time integration.
static int GradientMult(N_Vector v, N_Vector Jv, N_Vector u, booleantype *new_u, void *user_data)
virtual void SetOperator(const Operator &op)
Set the nonlinear Operator of the system. This method calls KINInit().
Wrapper for SUNDIALS' ARKODE library – Runge-Kutta time integration.
void SetLinearSolver(SundialsODELinearSolver &ls_spec)
Set a custom Jacobian system solver for implicit methods.
void SetIRKTableNum(int table_num)
Choose a specific Butcher table for implicit RK method.
const Operator * jacobian
virtual int SolveSystem(void *sundials_mem, Vector &b, const Vector &weight, const Vector &y_cur, const Vector &f_cur)=0
static int LinSysSolve(KINMemRec *kin_mem, N_Vector x, N_Vector b, realtype *sJpnorm, realtype *sFdotJp)
virtual void Mult(const Vector &x, Vector &y) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x...
void SetOrder(int order)
Chooses integration order for all explicit / implicit / IMEX methods.
Abstract base class, wrapping the custom linear solvers interface in SUNDIALS' CVODE and ARKODE solve...
int height
Dimension of the output / number of rows in the matrix.
virtual ~ARKODESolver()
Destroy the associated ARKODE memory.
virtual void SetSolver(Solver &solver)
Set the linear solver for inverting the Jacobian.
int flag
Flag returned by the last call to SUNDIALS.
void SetScaledStepTol(double sstol)
Set KINSOL's scaled step tolerance.
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
N_Vector y
Auxiliary N_Vector.
KinSolver(int strategy, bool oper_grad=true)
Construct a serial KinSolver, a wrapper for SUNDIALS' KINSOL solver.
static int LinSysSetup(KINMemRec *kin_mem)
void PrintInfo() const
Print ARKODE statistics.
static const double default_rel_tol
virtual void Step(Vector &x, double &t, double &dt)
Use ARKODE to integrate over [t, t + dt], with the specified step mode.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.