14 #ifdef MFEM_USE_SUNDIALS
22 #include <nvector/nvector_serial.h>
24 #include <nvector/nvector_cuda.h>
27 #include <nvector/nvector_mpiplusx.h>
28 #include <nvector/nvector_parallel.h>
32 #include <sunlinsol/sunlinsol_spgmr.h>
33 #include <sunlinsol/sunlinsol_spfgmr.h>
36 #define GET_CONTENT(X) ( X->content )
40 #if (SUNDIALS_VERSION_MAJOR < 6)
88 MFEM_DEPRECATED
void*
ARKStepCreate(ARKRhsFn fe, ARKRhsFn fi, realtype t0,
106 sunindextype local_length,
107 sunindextype global_length,
113 #endif // MFEM_USE_MPI
120 booleantype use_managed_mem,
121 SUNMemoryHelper helper,
134 #endif // MFEM_USE_CUDA
136 #if defined(MFEM_USE_MPI) && defined(MFEM_USE_CUDA)
146 #endif // MFEM_USE_MPI && MFEM_USE_CUDA
148 #endif // SUNDIALS_VERSION_MAJOR < 6
154 void Sundials::Init()
156 Sundials::Instance();
167 return Sundials::Instance().context;
172 return Sundials::Instance().memHelper;
175 #if (SUNDIALS_VERSION_MAJOR >= 6)
180 MPI_Comm communicator = MPI_COMM_WORLD;
181 int return_val = SUNContext_Create((
void*) &communicator, &context);
183 int return_val = SUNContext_Create(
nullptr, &context);
185 MFEM_VERIFY(return_val == 0,
"Call to SUNContext_Create failed");
187 memHelper = std::move(actual_helper);
190 Sundials::~Sundials()
192 SUNContext_Free(&context);
195 #else // SUNDIALS_VERSION_MAJOR >= 6
202 Sundials::~Sundials()
207 #endif // SUNDIALS_VERSION_MAJOR >= 6
216 h->ops->alloc = SundialsMemHelper_Alloc;
217 h->ops->dealloc = SundialsMemHelper_Dealloc;
218 h->ops->copy = SUNMemoryHelper_Copy_Cuda;
219 h->ops->copyasync = SUNMemoryHelper_CopyAsync_Cuda;
224 this->h = that_helper.h;
225 that_helper.h =
nullptr;
235 int SundialsMemHelper::SundialsMemHelper_Alloc(SUNMemoryHelper helper,
236 SUNMemory* memptr,
size_t memsize,
237 SUNMemoryType mem_type
238 #
if (SUNDIALS_VERSION_MAJOR >= 6)
243 int length = memsize/
sizeof(double);
244 SUNMemory sunmem = SUNMemoryNewEmpty();
247 sunmem->own = SUNTRUE;
249 if (mem_type == SUNMEMTYPE_HOST)
254 sunmem->type = SUNMEMTYPE_HOST;
257 else if (mem_type == SUNMEMTYPE_DEVICE || mem_type == SUNMEMTYPE_UVM)
262 sunmem->type = mem_type;
275 int SundialsMemHelper::SundialsMemHelper_Dealloc(SUNMemoryHelper helper,
277 #
if (SUNDIALS_VERSION_MAJOR >= 6)
282 if (sunmem->ptr && sunmem->own && !
mm.
IsKnown(sunmem->ptr))
284 if (sunmem->type == SUNMEMTYPE_HOST)
287 Device::GetHostMemoryType(),
true);
290 else if (sunmem->type == SUNMEMTYPE_DEVICE || sunmem->type == SUNMEMTYPE_UVM)
293 Device::GetDeviceMemoryType(),
true);
298 MFEM_ABORT(
"Invalid SUNMEMTYPE");
306 #endif // MFEM_USE_CUDA
313 void SundialsNVector::_SetNvecDataAndSize_(
long glob_size)
316 N_Vector local_x = MPIPlusX() ? N_VGetLocalVector_MPIPlusX(x) : x;
318 N_Vector local_x = x;
320 N_Vector_ID
id = N_VGetVectorID(local_x);
325 case SUNDIALS_NVEC_SERIAL:
327 MFEM_ASSERT(NV_OWN_DATA_S(local_x) == SUNFALSE,
"invalid serial N_Vector");
329 NV_LENGTH_S(local_x) = size;
333 case SUNDIALS_NVEC_CUDA:
336 N_VSetDeviceArrayPointer_Cuda(
ReadWrite(), local_x);
337 static_cast<N_VectorContent_Cuda
>(GET_CONTENT(local_x))->length = size;
342 case SUNDIALS_NVEC_PARALLEL:
344 MFEM_ASSERT(NV_OWN_DATA_P(x) == SUNFALSE,
"invalid parallel N_Vector");
346 NV_LOCLENGTH_P(x) = size;
349 glob_size = GlobalSize();
351 if (glob_size == 0 && glob_size != size)
353 long local_size = size;
354 MPI_Allreduce(&local_size, &glob_size, 1, MPI_LONG,
358 NV_GLOBLENGTH_P(x) = glob_size;
363 MFEM_ABORT(
"N_Vector type " <<
id <<
" is not supported");
371 glob_size = GlobalSize();
373 if (glob_size == 0 && glob_size != size)
375 long local_size = size;
376 MPI_Allreduce(&local_size, &glob_size, 1, MPI_LONG,
380 static_cast<N_VectorContent_MPIManyVector
>(GET_CONTENT(x))->global_length =
386 void SundialsNVector::_SetDataAndSize_()
389 N_Vector local_x = MPIPlusX() ? N_VGetLocalVector_MPIPlusX(x) : x;
391 N_Vector local_x = x;
393 N_Vector_ID
id = N_VGetVectorID(local_x);
398 case SUNDIALS_NVEC_SERIAL:
400 const bool known =
mm.
IsKnown(NV_DATA_S(local_x));
401 size = NV_LENGTH_S(local_x);
402 data.Wrap(NV_DATA_S(local_x), size,
false);
403 if (known) { data.ClearOwnerFlags(); }
407 case SUNDIALS_NVEC_CUDA:
409 double *h_ptr = N_VGetHostArrayPointer_Cuda(local_x);
410 double *d_ptr = N_VGetDeviceArrayPointer_Cuda(local_x);
412 size = N_VGetLength_Cuda(local_x);
413 data.Wrap(h_ptr, d_ptr, size, Device::GetHostMemoryType(),
false);
414 if (known) { data.ClearOwnerFlags(); }
420 case SUNDIALS_NVEC_PARALLEL:
422 const bool known =
mm.
IsKnown(NV_DATA_P(x));
423 size = NV_LENGTH_S(x);
424 data.Wrap(NV_DATA_P(x), NV_LOCLENGTH_P(x),
false);
425 if (known) { data.ClearOwnerFlags(); }
430 MFEM_ABORT(
"N_Vector type " <<
id <<
" is not supported");
434 SundialsNVector::SundialsNVector()
489 :
SundialsNVector(vec.GetComm(), vec.GetData(), vec.Size(), vec.GlobalSize())
500 N_VDestroy(N_VGetLocalVector_MPIPlusX(
x));
542 MFEM_VERIFY(x,
"Error in SundialsNVector::MakeNVector.");
552 if (comm == MPI_COMM_NULL)
572 #endif // MFEM_USE_CUDA
575 MFEM_VERIFY(x,
"Error in SundialsNVector::MakeNVector.");
579 #endif // MFEM_USE_MPI
587 static SUNMatrix_ID MatGetID(SUNMatrix)
589 return (SUNMATRIX_CUSTOM);
592 static void MatDestroy(SUNMatrix A)
594 if (A->content) { A->content = NULL; }
595 if (A->ops) { free(A->ops); A->ops = NULL; }
605 static SUNLinearSolver_Type LSGetType(SUNLinearSolver)
607 return (SUNLINEARSOLVER_MATRIX_ITERATIVE);
610 static int LSFree(SUNLinearSolver LS)
612 if (LS->content) { LS->content = NULL; }
613 if (LS->ops) { free(LS->ops); LS->ops = NULL; }
632 self->f->Mult(mfem_y, mfem_ydot);
642 if (!self->root_func) {
return CV_RTFUNC_FAIL; }
647 return self->root_func(t, mfem_y, mfem_gout,
self);
655 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in SetRootFinder()");
659 booleantype jok, booleantype *jcur, realtype gamma,
660 void*, N_Vector, N_Vector, N_Vector)
669 return (self->f->SUNImplicitSetup(mfem_y, mfem_fy, jok, jcur, gamma));
673 N_Vector
b, realtype tol)
679 return (self->f->SUNImplicitSolve(mfem_b, mfem_x, tol));
683 : lmm_type(lmm), step_mode(CV_NORMAL)
690 : lmm_type(lmm), step_mode(CV_NORMAL)
702 long local_size = f_.
Height();
705 long global_size = 0;
708 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
722 resize = (
Y->
Size() != local_size);
727 int l_resize = (
Y->
Size() != local_size) ||
729 MPI_Allreduce(&l_resize, &resize, 1, MPI_INT, MPI_LOR,
755 Y->
SetSize(local_size, global_size);
766 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeInit()");
770 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetUserData()");
774 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetSStolerances()");
787 MFEM_VERIFY(
Y->
Size() == x.
Size(),
"size mismatch");
793 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeReInit()");
799 double tout = t + dt;
801 MFEM_VERIFY(
flag >= 0,
"error in CVode()");
808 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetLastStep()");
814 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
815 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
819 MFEM_VERIFY(
LSA,
"error in SUNLinSolNewEmpty()");
822 LSA->ops->gettype = LSGetType;
824 LSA->ops->free = LSFree;
827 MFEM_VERIFY(A,
"error in SUNMatNewEmpty()");
830 A->ops->getid = MatGetID;
831 A->ops->destroy = MatDestroy;
835 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinearSolver()");
839 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinSysFn()");
845 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
846 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
850 MFEM_VERIFY(
LSA,
"error in SUNLinSol_SPGMR()");
854 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinearSolver()");
865 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSStolerances()");
871 "abs tolerance is not the same size.");
877 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSVtolerances()");
883 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetMaxStep()");
889 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetMaxNumSteps()");
896 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetNumSteps()");
903 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetMaxOrd()");
908 long int nsteps, nfevals, nlinsetups, netfails;
910 double hinused, hlast, hcur, tcur;
911 long int nniters, nncfails;
925 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetIntegratorStats()");
931 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetNonlinSolvStats()");
935 "num steps: " << nsteps <<
"\n"
936 "num rhs evals: " << nfevals <<
"\n"
937 "num lin setups: " << nlinsetups <<
"\n"
938 "num nonlin sol iters: " << nniters <<
"\n"
939 "num nonlin conv fail: " << nncfails <<
"\n"
940 "num error test fails: " << netfails <<
"\n"
941 "last order: " << qlast <<
"\n"
942 "current order: " << qcur <<
"\n"
943 "initial dt: " << hinused <<
"\n"
944 "last dt: " << hlast <<
"\n"
945 "current dt: " << hcur <<
"\n"
946 "current t: " << tcur <<
"\n" << endl;
956 SUNNonlinSolFree(
NLS);
994 MFEM_VERIFY(t <= f->GetTime(),
"t > current forward solver time");
997 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetQuad()");
1004 MFEM_VERIFY(t <= f->GetTime(),
"t > current forward solver time");
1007 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetQuadB()");
1009 dG_dp.
Set(-1., *
qB);
1017 MFEM_VERIFY(
flag >= 0,
"error in CVodeGetAdjY()");
1037 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeCreateB()");
1041 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeInit()");
1045 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetUserDataB()");
1050 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetSStolerancesB()");
1062 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeAdjInit");
1068 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeSetMaxNumStepsB()");
1077 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeQuadInit()");
1080 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeSetQuadErrCon");
1083 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeQuadSStolerances");
1092 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeQuadInitB()");
1095 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeSetQuadErrConB");
1098 MFEM_VERIFY(
flag == CV_SUCCESS,
"Error in CVodeQuadSStolerancesB");
1104 if (
AB != NULL) { SUNMatDestroy(
AB);
AB = NULL; }
1105 if (
LSB != NULL) { SUNLinSolFree(
LSB);
LSB = NULL; }
1109 MFEM_VERIFY(
LSB,
"error in SUNLinSolNewEmpty()");
1111 LSB->content =
this;
1112 LSB->ops->gettype = LSGetType;
1114 LSB->ops->free = LSFree;
1117 MFEM_VERIFY(
AB,
"error in SUNMatNewEmpty()");
1120 AB->ops->getid = MatGetID;
1121 AB->ops->destroy = MatDestroy;
1125 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinearSolverB()");
1130 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinSysFn()");
1136 if (
AB != NULL) { SUNMatDestroy(
AB);
AB = NULL; }
1137 if (
LSB != NULL) { SUNLinSolFree(
LSB);
LSB = NULL; }
1141 MFEM_VERIFY(
LSB,
"error in SUNLinSol_SPGMR()");
1145 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSetLinearSolverB()");
1149 N_Vector fyB, SUNMatrix AB,
1150 booleantype jokB, booleantype *jcurB,
1151 realtype gammaB,
void *user_data, N_Vector tmp1,
1152 N_Vector tmp2, N_Vector tmp3)
1168 N_Vector Rb, realtype tol)
1183 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSStolerancesB()");
1189 "abs tolerance is not the same size.");
1195 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeSVtolerancesB()");
1256 return self->ewt_func(mfem_y, mfem_w,
self);
1263 MFEM_VERIFY(
Y->
Size() == x.
Size(),
"size mismatch");
1269 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeReInit()");
1276 double tout = t + dt;
1278 MFEM_VERIFY(
flag >= 0,
"error in CVodeF()");
1285 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeGetLastStep()");
1297 MFEM_VERIFY(
flag == CV_SUCCESS,
"error in CVodeReInit()");
1304 double tout = tB - dtB;
1306 MFEM_VERIFY(
flag >= 0,
"error in CVodeB()");
1310 MFEM_VERIFY(
flag >= 0,
"error in CVodeGetB()");
1341 if (self->rk_type ==
IMEX)
1345 self->f->Mult(mfem_y, mfem_ydot);
1362 self->f->Mult(mfem_y, mfem_ydot);
1369 SUNMatrix, booleantype jok, booleantype *jcur,
1371 void*, N_Vector, N_Vector, N_Vector)
1380 if (self->rk_type ==
IMEX)
1384 return (self->f->SUNImplicitSetup(mfem_y, mfem_fy, jok, jcur, gamma));
1388 N_Vector
b, realtype tol)
1395 if (self->rk_type ==
IMEX)
1399 return (self->f->SUNImplicitSolve(mfem_b, mfem_x, tol));
1403 void*, N_Vector, N_Vector, N_Vector)
1409 return (self->f->SUNMassSetup());
1413 N_Vector
b, realtype tol)
1420 return (self->f->SUNMassSolve(mfem_b, mfem_x, tol));
1430 return (self->f->SUNMassMult(mfem_x, mfem_v));
1442 return (self->f->SUNMassMult(mfem_x, mfem_v));
1446 : rk_type(type), step_mode(ARK_NORMAL),
1447 use_implicit(type == IMPLICIT || type == IMEX)
1454 : rk_type(type), step_mode(ARK_NORMAL),
1455 use_implicit(type == IMPLICIT || type == IMEX)
1467 long local_size = f_.
Height();
1475 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
1489 resize = (
Y->
Size() != local_size);
1494 int l_resize = (
Y->
Size() != local_size) ||
1496 MPI_Allreduce(&l_resize, &resize, 1, MPI_INT, MPI_LOR,
1518 Y->
SetSize(local_size, global_size);
1543 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetUserData()");
1547 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetSStolerances()");
1560 MFEM_VERIFY(
Y->
Size() == x.
Size(),
"size mismatch");
1578 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepReInit()");
1585 double tout = t + dt;
1587 MFEM_VERIFY(
flag >= 0,
"error in ARKStepEvolve()");
1594 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepGetLastStep()");
1600 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
1601 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
1605 MFEM_VERIFY(
LSA,
"error in SUNLinSolNewEmpty()");
1607 LSA->content =
this;
1608 LSA->ops->gettype = LSGetType;
1610 LSA->ops->free = LSFree;
1613 MFEM_VERIFY(A,
"error in SUNMatNewEmpty()");
1616 A->ops->getid = MatGetID;
1617 A->ops->destroy = MatDestroy;
1621 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetLinearSolver()");
1625 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetLinSysFn()");
1631 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
1632 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
1636 MFEM_VERIFY(
LSA,
"error in SUNLinSol_SPGMR()");
1640 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetLinearSolver()");
1646 if (
M != NULL) { SUNMatDestroy(
M);
M = NULL; }
1647 if (
LSM != NULL) { SUNLinSolFree(
LSM);
LSM = NULL; }
1651 MFEM_VERIFY(
LSM,
"error in SUNLinSolNewEmpty()");
1653 LSM->content =
this;
1654 LSM->ops->gettype = LSGetType;
1656 LSA->ops->free = LSFree;
1659 MFEM_VERIFY(
M,
"error in SUNMatNewEmpty()");
1662 M->ops->getid = SUNMatGetID;
1664 M->ops->destroy = MatDestroy;
1668 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetLinearSolver()");
1672 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetMassFn()");
1678 if (
M != NULL) { SUNMatDestroy(A);
M = NULL; }
1679 if (
LSM != NULL) { SUNLinSolFree(
LSM);
LSM = NULL; }
1683 MFEM_VERIFY(
LSM,
"error in SUNLinSol_SPGMR()");
1687 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetMassLinearSolver()");
1692 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetMassTimes()");
1703 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSStolerances()");
1709 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetMaxStep()");
1715 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetOrder()");
1721 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetTableNum()");
1727 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetTableNum()");
1734 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetTableNum()");
1740 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepSetFixedStep()");
1745 long int nsteps, expsteps, accsteps, step_attempts;
1746 long int nfe_evals, nfi_evals;
1747 long int nlinsetups, netfails;
1748 double hinused, hlast, hcur, tcur;
1749 long int nniters, nncfails;
1760 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepGetTimestepperStats()");
1773 MFEM_VERIFY(
flag == ARK_SUCCESS,
"error in ARKStepGetNonlinSolvStats()");
1777 "num steps: " << nsteps <<
"\n"
1778 "num exp rhs evals: " << nfe_evals <<
"\n"
1779 "num imp rhs evals: " << nfi_evals <<
"\n"
1780 "num lin setups: " << nlinsetups <<
"\n"
1781 "num nonlin sol iters: " << nniters <<
"\n"
1782 "num nonlin conv fail: " << nncfails <<
"\n"
1783 "num steps attempted: " << step_attempts <<
"\n"
1784 "num acc limited steps: " << accsteps <<
"\n"
1785 "num exp limited stepfails: " << expsteps <<
"\n"
1786 "num error test fails: " << netfails <<
"\n"
1787 "initial dt: " << hinused <<
"\n"
1788 "last dt: " << hlast <<
"\n"
1789 "current dt: " << hcur <<
"\n"
1790 "current t: " << tcur <<
"\n" << endl;
1800 SUNNonlinSolFree(
NLS);
1824 booleantype *new_u,
void *user_data)
1834 self->jacobian = &
self->oper->GetGradient(mfem_u);
1839 self->jacobian->Mult(mfem_v, mfem_Jv);
1847 void *, N_Vector, N_Vector )
1856 self->prec->SetOperator(*self->jacobian);
1864 N_Vector
b, realtype)
1889 self->prec->SetOperator(*self->jacobian);
1907 self->prec->Mult(mfem_v, self->wrk);
1915 : global_strategy(strategy), use_oper_grad(oper_grad), y_scale(NULL),
1916 f_scale(NULL), jacobian(NULL), maa(0)
1923 abs_tol = pow(UNIT_ROUNDOFF, 1.0/3.0);
1929 : global_strategy(strategy), use_oper_grad(oper_grad), y_scale(NULL),
1930 f_scale(NULL), jacobian(NULL), maa(0)
1937 abs_tol = pow(UNIT_ROUNDOFF, 1.0/3.0);
1950 long local_size =
height;
1958 MPI_Allreduce(&local_size, &global_size, 1, MPI_LONG, MPI_SUM,
1969 resize = (
Y->
Size() != local_size);
1974 int l_resize = (
Y->
Size() != local_size) ||
1976 MPI_Allreduce(&l_resize, &resize, 1, MPI_INT, MPI_LOR,
1998 Y->
SetSize(local_size, global_size);
2013 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetMAA()");
2018 MFEM_VERIFY(
flag == KIN_SUCCESS,
"error in KINInit()");
2022 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetUserData()");
2032 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
2033 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
2036 MFEM_VERIFY(
LSA,
"error in SUNLinSol_SPGMR()");
2039 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetLinearSolver()");
2045 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetJacTimesVecFn()");
2063 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
2064 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
2068 MFEM_VERIFY(
LSA,
"error in SUNLinSolNewEmpty()");
2070 LSA->content =
this;
2071 LSA->ops->gettype = LSGetType;
2073 LSA->ops->free = LSFree;
2076 MFEM_VERIFY(A,
"error in SUNMatNewEmpty()");
2079 A->ops->getid = MatGetID;
2080 A->ops->destroy = MatDestroy;
2084 MFEM_VERIFY(
flag == KIN_SUCCESS,
"error in KINSetLinearSolver()");
2088 MFEM_VERIFY(
flag == KIN_SUCCESS,
"error in KINSetJacFn()");
2100 if (A != NULL) { SUNMatDestroy(A); A = NULL; }
2101 if (
LSA != NULL) { SUNLinSolFree(
LSA);
LSA = NULL; }
2106 MFEM_VERIFY(
LSA,
"error in SUNLinSol_SPFGMR()");
2109 MFEM_VERIFY(
flag == SUNLS_SUCCESS,
"error in SUNLinSol_SPFGMR()");
2112 MFEM_VERIFY(
flag == KIN_SUCCESS,
"error in KINSetLinearSolver()");
2119 MFEM_VERIFY(
flag == KIN_SUCCESS,
"error in KINSetPreconditioner()");
2126 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetScaledStepTol()");
2132 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetMaxSetupCalls()");
2143 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetMAA()");
2149 MFEM_ABORT(
"this method is not supported! Use SetPrintLevel(int) instead.");
2174 double lnorm = norm;
2175 MPI_Allreduce(&lnorm, &norm, 1, MPI_DOUBLE, MPI_MAX,
2198 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINSetFuncNormTol()");
2209 MFEM_ASSERT(
flag == KIN_SUCCESS,
"KINSetNumMaxIters() failed!");
2223 MPI_Comm_rank(
Y->
GetComm(), &rank);
2230 MFEM_VERIFY(
flag == KIN_SUCCESS,
"KINSetPrintLevel() failed!");
2232 #ifdef SUNDIALS_BUILD_WITH_MONITORING
2235 flag = SUNLinSolSetInfoFile_SPFGMR(
LSA, stdout);
2236 MFEM_VERIFY(
flag == SUNLS_SUCCESS,
2237 "error in SUNLinSolSetInfoFile_SPFGMR()");
2239 flag = SUNLinSolSetPrintLevel_SPFGMR(
LSA, 1);
2240 MFEM_VERIFY(
flag == SUNLS_SUCCESS,
2241 "error in SUNLinSolSetPrintLevel_SPFGMR()");
2258 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINGetNumNonlinSolvIters()");
2263 MFEM_ASSERT(
flag == KIN_SUCCESS,
"error in KINGetFuncNorm()");
2278 #endif // MFEM_USE_SUNDIALS
static int RHSQ(realtype t, const N_Vector y, N_Vector qdot, void *user_data)
Wrapper to compute the ODE RHS Quadrature function.
void SetSize(int s, long glob_size=0)
Resize the vector to size s.
virtual double GetTime() const
Read the currently set time.
void Init(TimeDependentOperator &f_)
Initialize CVODE: calls CVodeCreate() to create the CVODE memory and set some defaults.
static bool IsAvailable()
Return true if an actual device (e.g. GPU) has been configured.
MFEM_DEPRECATED void * CVodeCreate(int lmm, SUNContext)
void SetJFNKSolver(Solver &solver)
MFEM_DEPRECATED SUNLinearSolver SUNLinSolNewEmpty(SUNContext)
SundialsNVector * q
Quadrature vector.
void GetForwardSolution(double tB, mfem::Vector &yy)
Get Interpolated Forward solution y at backward integration time tB.
virtual void StepB(Vector &w, double &t, double &dt)
Solve one adjoint time step.
virtual int SUNImplicitSolveB(Vector &x, const Vector &b, double tol)
Solve the ODE linear system as setup by the method SUNImplicitSetup().
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
std::function< int(Vector y, Vector w, CVODESolver *)> EWTFunction
Typedef declaration for error weight functions.
static int LinSysSolveB(SUNLinearSolver LS, SUNMatrix A, N_Vector x, N_Vector b, realtype tol)
Solve the linear system A x = b.
MFEM_DEPRECATED void * KINCreate(SUNContext)
MFEM_DEPRECATED void * ARKStepCreate(ARKRhsFn fe, ARKRhsFn fi, realtype t0, N_Vector y0, SUNContext)
virtual void QuadratureSensitivityMult(const Vector &y, const Vector &yB, Vector &qBdot) const
Provides the sensitivity of the quadrature w.r.t to primal and adjoint solutions. ...
~SundialsNVector()
Calls SUNDIALS N_VDestroy function if the N_Vector is owned by 'this'.
void SetScaledStepTol(double sstol)
Set KINSOL's scaled step tolerance.
RootFunction root_func
A class member to facilitate pointing to a user-specified root function.
void SetSize(int s)
Resize the vector to size s.
SundialsNVector * Y
State vector.
void SetStepMode(int itask)
Select the ARKode step mode: ARK_NORMAL (default) or ARK_ONE_STEP.
void Delete()
Delete the owned pointers and reset the Memory object.
void SetERKTableNum(ARKODE_ERKTableID table_id)
Choose a specific Butcher table for an explicit RK method.
void SetIRKTableNum(ARKODE_DIRKTableID table_id)
Choose a specific Butcher table for a diagonally implicit RK method.
Base abstract class for first order 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 ...
virtual void Step(Vector &x, double &t, double &dt)
Integrate the ODE with CVODE using the specified step mode.
static constexpr double default_abs_tolB
Default scalar backward absolute tolerance.
virtual void AdjointRateMult(const Vector &y, Vector &yB, Vector &yBdot) const =0
Perform the action of the operator: yBdot = k = f(y,@2 yB, t), where.
SundialsNVector * f_scale
scaling vectors
void SetSVtolerances(double reltol, Vector abstol)
Set the scalar relative and vector of absolute tolerances.
static int RHSB(realtype t, N_Vector y, N_Vector yB, N_Vector yBdot, void *user_dataB)
Wrapper to compute the ODE RHS backward function.
void MakeRef(Vector &base, int offset, int s)
Reset the Vector to be a reference to a sub-vector of base.
int indexB
backward problem index
virtual ~CVODESolver()
Destroy the associated CVODE memory and SUNDIALS objects.
bool use_oper_grad
use the Jv prod function
int Size() const
Returns the size of the vector.
void SetDevicePtrOwner(bool own) const
Set/clear the ownership flag for the device pointer. Ownership indicates whether the pointer will be ...
void EvalQuadIntegration(double t, Vector &q)
Evaluate Quadrature.
MFEM_DEPRECATED SUNLinearSolver SUNLinSol_SPGMR(N_Vector y, int pretype, int maxl, SUNContext)
virtual void SetPrintLevel(int print_lvl)
Set the print level for the KINSetPrintLevel function.
static int LinSysSetup(realtype t, N_Vector y, N_Vector fy, SUNMatrix A, SUNMatrix M, booleantype jok, booleantype *jcur, realtype gamma, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
Setup the linear system .
void SetMaxStep(double dt_max)
Set the maximum time step.
void SetOrder(int order)
Chooses integration order for all explicit / implicit / IMEX methods.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void SetTime(const double t_)
Set the current time.
void * sundials_mem
SUNDIALS mem structure.
double Normlinf() const
Returns the l_infinity norm of the vector.
static int PrecSolve(N_Vector uu, N_Vector uscale, N_Vector fval, N_Vector fscale, N_Vector vv, void *user_data)
Solve the preconditioner equation .
long saved_global_size
Global vector length on last initialization.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
virtual void Step(Vector &x, double &t, double &dt)
SundialsNVector()
Creates an empty SundialsNVector.
void UseSundialsLinearSolverB()
Use built in SUNDIALS Newton solver.
static int MassSysSetup(realtype t, SUNMatrix M, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
Setup the linear system .
MFEM_DEPRECATED SUNMatrix SUNMatNewEmpty(SUNContext)
void SetSStolerancesB(double reltol, double abstol)
Tolerance specification functions for the adjoint problem.
int print_level
(DEPRECATED) Legacy print level definition, which is left for compatibility with custom iterative sol...
void SetMaxSetupCalls(int max_calls)
Set maximum number of nonlinear iterations without a Jacobian update.
void _SetDataAndSize_()
Set data and length from the internal N_Vector x.
ARKStepSolver(Type type=EXPLICIT)
Construct a serial wrapper to SUNDIALS' ARKode integrator.
void SetIMEXTableNum(ARKODE_ERKTableID etable_id, ARKODE_DIRKTableID itable_id)
Choose a specific Butcher table for an IMEX RK method.
void InitAdjointSolve(int steps, int interpolation)
Initialize Adjoint.
MFEM_DEPRECATED N_Vector N_VNewEmpty_Parallel(MPI_Comm comm, sunindextype local_length, sunindextype global_length, SUNContext)
MFEM_DEPRECATED SUNMemoryHelper SUNMemoryHelper_NewEmpty(SUNContext)
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
int global_strategy
KINSOL solution strategy.
SUNLinearSolver LSA
Linear solver for A.
static int MassMult1(SUNMatrix M, N_Vector x, N_Vector v)
Compute the matrix-vector product .
MFEM_DEPRECATED N_Vector N_VNewEmpty_Serial(sunindextype vec_length, SUNContext)
virtual void SetEvalMode(const EvalMode new_eval_mode)
Set the evaluation mode of the time-dependent operator.
SUNMatrix M
Mass matrix M.
virtual void SetSolver(Solver &solver)
Set the linear solver for inverting the Jacobian.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetSVtolerancesB(double reltol, Vector abstol)
Tolerance specification functions for the adjoint problem.
MFEM_DEPRECATED SUNLinearSolver SUNLinSol_SPFGMR(N_Vector y, int pretype, int maxl, SUNContext)
int lmm_type
Linear multistep method type.
Interface to the CVODE library – linear multi-step methods.
void InitQuadIntegration(mfem::Vector &q0, double reltolQ=1e-3, double abstolQ=1e-8)
void InitQuadIntegrationB(mfem::Vector &qB0, double reltolQB=1e-3, double abstolQB=1e-8)
Initialize Quadrature Integration (Adjoint)
Interface to the KINSOL library – nonlinear solver methods.
static constexpr double default_rel_tolB
Default scalar backward relative tolerance.
SundialsNVector * yy
State vector.
Vector interface for SUNDIALS N_Vectors.
int GetAdjointHeight()
Returns the size of the adjoint problem state space.
void SetMaxStep(double dt_max)
Set the maximum time step.
Type
Types of ARKODE solvers.
Type rk_type
Runge-Kutta type.
virtual ~ARKStepSolver()
Destroy the associated ARKode memory and SUNDIALS objects.
SundialsNVector * qB
State vector.
bool use_implicit
True for implicit or imex integration.
SUNNonlinearSolver NLS
Nonlinear solver.
constexpr ARKODE_DIRKTableID ARKODE_DIRK_NONE
CVODESolver(int lmm)
Construct a serial wrapper to SUNDIALS' CVODE integrator.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
static int Mult(const N_Vector u, N_Vector fu, void *user_data)
Wrapper to compute the nonlinear residual .
int step_mode
ARKStep step mode (ARK_NORMAL or ARK_ONE_STEP).
SundialsNVector * y_scale
Wrapper for hypre's parallel vector class.
static int LinSysSetup(N_Vector u, N_Vector fu, SUNMatrix J, void *user_data, N_Vector tmp1, N_Vector tmp2)
Setup the linear system .
SUNLinearSolver LSM
Linear solver for M.
int ncheck
number of checkpoints used so far
static int RHS1(realtype t, const N_Vector y, N_Vector ydot, void *user_data)
N_Vector x
The actual SUNDIALS object.
MFEM_DEPRECATED N_Vector N_VMake_MPIPlusX(MPI_Comm comm, N_Vector local_vector, SUNContext)
void UseMFEMLinearSolver()
Attach the linear system setup and solve methods from the TimeDependentOperator i.e., SUNImplicitSetup() and SUNImplicitSolve() to CVODE.
virtual void SetOperator(const Operator &op)
Set the nonlinear Operator of the system and initialize KINSOL.
virtual ~KINSolver()
Destroy the associated KINSOL memory.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
int max_iter
Limit for the number of iterations the solver is allowed to do.
void SetRootFinder(int components, RootFunction func)
Initialize Root Finder.
Vector wrk
Work vector needed for the JFNK PC.
EWTFunction ewt_func
A class member to facilitate pointing to a user-specified error weight function.
void SetFixedStep(double dt)
Use a fixed time step size (disable temporal adaptivity).
static int root(realtype t, N_Vector y, realtype *gout, void *user_data)
Prototype to define root finding for CVODE.
bool IsKnown(const void *h_ptr)
Return true if the pointer is known by the memory manager.
bool reinit
Flag to signal memory reinitialization is need.
int maa
number of acceleration vectors
static N_Vector MakeNVector(bool use_device)
Create a N_Vector.
void UseMFEMLinearSolverB()
Set Linear Solver for the backward problem.
constexpr ARKODE_ERKTableID ARKODE_ERK_NONE
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
std::function< int(realtype t, Vector y, Vector gout, CVODESolver *)> RootFunction
Typedef for root finding functions.
void _SetNvecDataAndSize_(long glob_size=0)
Set data and length of internal N_Vector x from 'this'.
Vector & Set(const double a, const Vector &x)
(*this) = a * x
int height
Dimension of the output / number of rows in the matrix.
void SetMAA(int maa)
Set the number of acceleration vectors to use with KIN_FP or KIN_PICARD.
virtual void QuadratureIntegration(const Vector &y, Vector &qdot) const
Provide the operator integration of a quadrature equation.
int maxli
Maximum linear iterations.
MemoryManager mm
The (single) global memory manager object.
long GetNumSteps()
Get the number of internal steps taken so far.
double rel_tol
Relative tolerance.
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true, or the mfem::Device's HostMemoryClass, otherwise.
MPI_Comm GetComm() const
Returns the MPI communicator for the internal N_Vector x.
void SetDataAndSize(double *d, int s, long glob_size=0)
Set the vector data and size.
MFEM_DEPRECATED N_Vector N_VNewWithMemHelp_Cuda(sunindextype length, booleantype use_managed_mem, SUNMemoryHelper helper, SUNContext)
static int LinSysSetup(realtype t, N_Vector y, N_Vector fy, SUNMatrix A, booleantype jok, booleantype *jcur, realtype gamma, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
Setup the linear system .
void PrintInfo() const
Print various ARKStep statistics.
static int RHS2(realtype t, const N_Vector y, N_Vector ydot, void *user_data)
static int GradientMult(N_Vector v, N_Vector Jv, N_Vector u, booleantype *new_u, void *user_data)
Wrapper to compute the Jacobian-vector product .
const Operator * jacobian
stores oper->GetGradient()
void InitB(TimeDependentAdjointOperator &f_)
Initialize the adjoint problem.
static int LinSysSetupB(realtype t, N_Vector y, N_Vector yB, N_Vector fyB, SUNMatrix A, booleantype jok, booleantype *jcur, realtype gamma, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
Setup the linear system A x = b.
SUNLinearSolver LSB
Linear solver for A.
Singleton class for SUNContext and SundialsMemHelper objects.
SundialsNVector * yB
State vector.
static constexpr double default_rel_tol
Default scalar relative tolerance.
void SetWFTolerances(EWTFunction func)
Set multiplicative error weights.
SUNMatrix AB
Linear system A = I - gamma J, M - gamma J, or J.
static bool UseManagedMemory()
int step_mode
CVODE step mode (CV_NORMAL or CV_ONE_STEP).
static int MassMult2(N_Vector x, N_Vector v, realtype t, void *mtimes_data)
Compute the matrix-vector product at time t.
KINSolver(int strategy, bool oper_grad=true)
Construct a serial wrapper to SUNDIALS' KINSOL nonlinear solver.
Implicit-explicit ARK method.
static constexpr double default_abs_tol
Default scalar absolute tolerance.
int flag
Last flag returned from a call to SUNDIALS.
static SundialsMemHelper & GetMemHelper()
Provides access to the SundialsMemHelper object.
void UseMFEMLinearSolver()
Attach the linear system setup and solve methods from the TimeDependentOperator i.e., SUNImplicitSetup() and SUNImplicitSolve() to ARKode.
virtual bool UseDevice() const
Return the device flag of the Memory object used by the Vector.
static int LinSysSolve(SUNLinearSolver LS, SUNMatrix A, N_Vector x, N_Vector b, realtype tol)
Solve the linear system .
static SUNContext & GetContext()
Provides access to the SUNContext object.
static int LinSysSolve(SUNLinearSolver LS, SUNMatrix A, N_Vector x, N_Vector b, realtype tol)
Solve the linear system .
void PrintInfo() const
Print various CVODE statistics.
void Init(TimeDependentAdjointOperator &f_)
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
static int PrecSetup(N_Vector uu, N_Vector uscale, N_Vector fval, N_Vector fscale, void *user_data)
Setup the preconditioner.
void SetMaxOrder(int max_order)
Set the maximum method order.
virtual ~CVODESSolver()
Destroy the associated CVODES memory and SUNDIALS objects.
static int ewt(N_Vector y, N_Vector w, void *user_data)
Error control function.
double u(const Vector &xvec)
void UseMFEMMassLinearSolver(int tdep)
Attach mass matrix linear system setup, solve, and matrix-vector product methods from the TimeDepende...
void SetMaxNStepsB(int mxstepsB)
Set the maximum number of backward steps.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void Init(TimeDependentOperator &f_)
Initialize ARKode: calls ARKStepCreate() to create the ARKStep memory and set some defaults...
T * HostReadWrite(Memory< T > &mem, int size)
Shortcut to ReadWrite(Memory<T> &mem, int size, false)
static int RHS(realtype t, const N_Vector y, N_Vector ydot, void *user_data)
Number of components in gout.
int maxlrs
Maximum linear solver restarts.
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
void UseSundialsLinearSolver()
Attach a SUNDIALS GMRES linear solver to ARKode.
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
static int LinSysSolve(SUNLinearSolver LS, SUNMatrix J, N_Vector u, N_Vector b, realtype tol)
Solve the linear system .
static int MassSysSolve(SUNLinearSolver LS, SUNMatrix M, N_Vector x, N_Vector b, realtype tol)
Solve the linear system .
virtual int SUNImplicitSetupB(const double t, const Vector &x, const Vector &xB, const Vector &fxB, int jokB, int *jcurB, double gammaB)
Setup the ODE linear system or , where .
Settings for the output behavior of the IterativeSolver.
virtual void Step(Vector &x, double &t, double &dt)
Integrate the ODE with ARKode using the specified step mode.
static int RHSQB(realtype t, N_Vector y, N_Vector yB, N_Vector qBdot, void *user_dataB)
Wrapper to compute the ODE RHS Backwards Quadrature function.
void EvalQuadIntegrationB(double t, Vector &dG_dp)
Evaluate Quadrature solution.
double abs_tol
Absolute tolerance.
void UseSundialsLinearSolver()
Attach SUNDIALS GMRES linear solver to CVODE.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void SetMaxNSteps(int steps)
Set the maximum number of time steps.
void SetStepMode(int itask)
Select the CVODE step mode: CV_NORMAL (default) or CV_ONE_STEP.
void UseSundialsMassLinearSolver(int tdep)
Attach the SUNDIALS GMRES linear solver and the mass matrix matrix-vector product method from the Tim...