4 #include <cvodes/cvodes.h>
5 #include <nvector/nvector_serial.h>
6 #include <sunmatrix/sunmatrix_dense.h>
7 #include <sunlinsol/sunlinsol_dense.h>
8 #include <sunnonlinsol/sunnonlinsol_newton.h>
9 #include <sunnonlinsol/sunnonlinsol_fixedpoint.h>
11 #include <sunlinsol/sunlinsol_spgmr.h>
12 #include <sunlinsol/sunlinsol_spfgmr.h>
13 #include <sunlinsol/sunlinsol_spbcgs.h>
14 #include <sunlinsol/sunlinsol_sptfqmr.h>
15 #include <sunlinsol/sunlinsol_pcg.h>
24 ODE::ODE(std::shared_ptr<ModPiece>
const& rhsIn,
25 Eigen::VectorXd
const& evalTimesIn,
27 boost::property_tree::ptree opts) :
ModPiece(GetInputSizes(rhsIn, isAuto),
28 GetOutputSizes(rhsIn, evalTimesIn)),
30 startTime(GetStartTime(evalTimesIn, opts)),
31 evalTimes(evalTimesIn),
35 if(opts.count(
"NonlinearSolver")>0)
39 if(opts.count(
"LinearSolver")>0)
43 if(opts.count(
"Integrator")>0)
49 boost::property_tree::ptree
const& opts)
52 for(
int i=0; i<evalTimesIn.size()-1; ++i){
53 if(evalTimesIn(i+1)<=evalTimesIn(i)){
54 std::stringstream msg;
55 msg <<
"ERROR: Evaluation times are not strictly increasing: t_{" << i+1 <<
"}-t_{" << i <<
"}=" << evalTimesIn(i+1)-evalTimesIn(i);
56 throw std::runtime_error(msg.str());
62 if(opts.count(
"StartTime")>0){
63 startTime = opts.get<
double>(
"StartTime");
66 if(
startTime>evalTimesIn(0) + std::numeric_limits<double>::epsilon()){
67 throw std::runtime_error(
"ERROR: Start time specified in options to ODE is after first evaluation time.");
81 return rhsIn->inputSizes;
83 return rhsIn->inputSizes.tail(rhsIn->inputSizes.size()-1);
88 Eigen::VectorXd
const& evalTimes)
91 int stateDim = rhsIn->outputSizes(0);
93 Eigen::VectorXi output(1);
94 output(0) = numTimes*stateDim;
104 method = opts.get(
"Method",
"Newton");
105 maxIters = opts.get(
"MaximumIterations", -1);
110 method = opts.get(
"Method",
"Dense");
111 maxIters = opts.get(
"MaximumIterations", -1);
116 method = opts.get(
"Method",
"BDF");
117 reltol = opts.get(
"RelativeTolerance", 1
e-5);
118 abstol = opts.get(
"AbsoluteTolerance", 1
e-5);
120 sensRelTol = opts.get(
"SensRelTol", -1);
121 sensAbsTol = opts.get(
"SensAbsTol", -1);
123 adjRelTol = opts.get(
"SensRelTol", -1);
124 adjAbsTol = opts.get(
"SensAbsTol", -1);
126 maxStepSize = opts.get(
"MaximumStepSize", -1);
127 maxNumSteps = opts.get(
"MaximumSteps", -1);
129 checkPtGap = opts.get(
"CheckPointSteps", 100);
136 int stateSize = NV_LENGTH_S(state);
138 SUNMatrix rhsJac = NULL;
139 SUNLinearSolver LS = NULL;
145 rhsJac = SUNDenseMatrix(stateSize, stateSize);
148 LS = SUNLinSol_Dense(state, rhsJac);
149 CheckFlag((
void *)LS,
"SUNLinSol_Dense", 0);
153 CheckFlag((
void *)LS,
"SUNLinSol_SPGMR", 0);
156 CheckFlag((
void *)LS,
"SUNLinSol_SPFGMR", 0);
159 CheckFlag((
void *)LS,
"SUNLinSol_SPBCGS", 0);
162 CheckFlag((
void *)LS,
"SUNLinSol_SPTFQMR", 0);
165 CheckFlag((
void *)LS,
"SUNLinSol_PGC", 0);
167 std::stringstream msg;
168 msg <<
"ERROR: Invalid linear solver method \"" <<
linOpts.
method <<
"\". Valid options are \"Dense\", \"SPGMR\", \"SPFGMR\", \"SPBCGS\", \"SPTFQMR\", or \"PCG\"\n";
169 throw std::runtime_error(msg.str());
172 flag = CVodeSetLinearSolver(cvode_mem, LS, rhsJac);
173 CheckFlag(&flag,
"CVodeSetLinearSolver", 1);
186 return std::make_pair(LS, rhsJac);
193 SUNNonlinearSolver NLS = NULL;
195 NLS = SUNNonlinSol_Newton(state);
196 CheckFlag( (
void *)NLS,
"SUNNonlinSol_Newton", 0);
201 NLS = SUNNonlinSol_FixedPoint(state, 0);
202 CheckFlag((
void *)NLS,
"SUNNonlinSol_FixedPoint", 0);
208 CheckFlag(&flag,
"SUNNonlinSolSetMaxIters", 1);
211 flag = CVodeSetNonlinearSolver(cvode_mem, NLS);
212 CheckFlag(&flag,
"CVodeSetNonlinearSolver", 1);
221 int stateSize = NV_LENGTH_S(state);
223 SUNMatrix rhsJac = NULL;
224 SUNLinearSolver LS = NULL;
230 rhsJac = SUNDenseMatrix(stateSize, stateSize);
233 LS = SUNLinSol_Dense(state, rhsJac);
234 CheckFlag((
void *)LS,
"SUNLinSol_Dense", 0);
238 CheckFlag((
void *)LS,
"SUNLinSol_SPGMR", 0);
241 CheckFlag((
void *)LS,
"SUNLinSol_SPFGMR", 0);
244 CheckFlag((
void *)LS,
"SUNLinSol_SPBCGS", 0);
247 CheckFlag((
void *)LS,
"SUNLinSol_SPTFQMR", 0);
250 CheckFlag((
void *)LS,
"SUNLinSol_PGC", 0);
252 std::stringstream msg;
253 msg <<
"ERROR: Invalid linear solver method \"" <<
linOpts.
method <<
"\". Valid options are \"Dense\", \"SPGMR\", \"SPFGMR\", \"SPBCGS\", \"SPTFQMR\", or \"PCG\"\n";
254 throw std::runtime_error(msg.str());
257 flag = CVodeSetLinearSolverB(cvode_mem, indexB, LS, rhsJac);
258 CheckFlag(&flag,
"CVodeSetLinearSolverB", 1);
262 flag = CVodeSetJacFnB(cvode_mem, indexB, &Interface::AdjointJacobian);
265 flag = CVodeSetJacTimesB(cvode_mem, indexB, NULL, &Interface::AdjointJacobianAction);
266 CheckFlag(&flag,
"CVodeSetJacTimesB", 1);
270 return std::make_pair(LS, rhsJac);
277 SUNNonlinearSolver NLS = NULL;
279 NLS = SUNNonlinSol_Newton(state);
280 CheckFlag( (
void *)NLS,
"SUNNonlinSol_Newton", 0);
285 NLS = SUNNonlinSol_FixedPoint(state, 0);
286 CheckFlag((
void *)NLS,
"SUNNonlinSol_FixedPoint", 0);
292 CheckFlag(&flag,
"SUNNonlinSolSetMaxIters", 1);
295 flag = CVodeSetNonlinearSolverB(cvode_mem, indexB, NLS);
296 CheckFlag(&flag,
"CVodeSetNonlinearSolverB", 1);
308 Eigen::VectorXd
const& x0 = inputs.at(0).get();
309 const unsigned int stateSize = x0.size();
311 auto rhsData = std::make_shared<ODEData>(
rhs,
318 N_Vector state = N_VNew_Serial(stateSize);
319 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), stateSize);
325 void *cvode_mem = NULL;
327 cvode_mem = CVodeCreate(CV_BDF);
329 cvode_mem = CVodeCreate(CV_ADAMS);
331 std::stringstream msg;
332 msg <<
"ERROR: Invalid integrator method \"" <<
intOpts.
method <<
"\". Valid options are \"BDF\" or \"ADAMS\"\n";
333 throw std::runtime_error(msg.str());
341 CheckFlag(&flag,
"CVodeSStolerances", 1);
343 flag = CVodeSetUserData(cvode_mem, rhsData.get());
350 SUNMatrix rhsJac = NULL;
355 SUNNonlinearSolver NLS = NULL;
361 CheckFlag(&flag,
"CVodeSetMaxNumSteps", 1);
374 outputs.at(0).segment(tind*stateSize, stateSize) = x0;
381 flag = CVode(cvode_mem,
evalTimes(tind), state, &t, CV_NORMAL);
384 outputs.at(0).segment(tind*stateSize, stateSize) = stateMap;
389 SUNMatDestroy(rhsJac);
391 CVodeFree(&cvode_mem);
396 SUNNonlinSolFree(NLS);
402 Eigen::VectorXd
const& sens)
408 Eigen::VectorXd
const& x0 = inputs.at(0).get();
409 const unsigned int stateSize = x0.size();
411 auto rhsData = std::make_shared<ODEData>(
rhs,
418 N_Vector state = N_VNew_Serial(stateSize);
419 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), stateSize);
425 void *cvode_mem = NULL;
427 cvode_mem = CVodeCreate(CV_BDF);
429 cvode_mem = CVodeCreate(CV_ADAMS);
431 std::stringstream msg;
432 msg <<
"ERROR: Invalid integrator method \"" <<
intOpts.
method <<
"\". Valid options are \"BDF\" or \"ADAMS\"\n";
433 throw std::runtime_error(msg.str());
441 CheckFlag(&flag,
"CVodeSStolerances", 1);
443 flag = CVodeSetUserData(cvode_mem, rhsData.get());
451 SUNMatrix rhsJac = NULL;
456 SUNNonlinearSolver NLS = NULL;
462 CheckFlag(&flag,
"CVodeSetMaxNumSteps", 1);
483 outputs.at(0).segment(tind*stateSize, stateSize) = x0;
490 flag = CVodeF(cvode_mem,
evalTimes(tind), state, &t, CV_NORMAL, &ncheck);
493 outputs.at(0).segment(tind*stateSize, stateSize) = stateMap;
498 const unsigned int paramSize =
inputSizes(inWrt);
500 N_Vector lambda = N_VNew_Serial(stateSize);
503 N_Vector nvGrad = N_VNew_Serial(paramSize);
506 Eigen::Map<Eigen::VectorXd> lambdaMap(NV_DATA_S(lambda), stateSize);
507 Eigen::Map<Eigen::VectorXd> nvGradMap(NV_DATA_S(nvGrad), paramSize);
509 lambdaMap = -1.0*sens.tail(stateSize);
510 nvGradMap = Eigen::VectorXd::Zero(paramSize);
515 flag = CVodeCreateB(cvode_mem, CV_BDF, &indexB);
517 flag = CVodeCreateB(cvode_mem, CV_ADAMS, &indexB);
519 std::stringstream msg;
520 msg <<
"ERROR: Invalid integrator method \"" <<
intOpts.
method <<
"\". Valid options are \"BDF\" or \"ADAMS\"\n";
521 throw std::runtime_error(msg.str());
527 flag = CVodeInitB(cvode_mem, indexB, Interface::AdjointRHS, finalTime, lambda);
532 CheckFlag(&flag,
"CVodeSStolerancesB", 1);
535 flag = CVodeSetUserDataB(cvode_mem, indexB, rhsData.get());
536 CheckFlag(&flag,
"CVodeSetUserDataB", 1);
540 SUNMatrix adjRhsJac = NULL;
541 SUNLinearSolver adjLS;
544 SUNNonlinearSolver adjNLS = NULL;
548 flag = CVodeQuadInitB(cvode_mem, indexB, &Interface::AdjointQuad, nvGrad);
552 flag = CVodeSetQuadErrConB(cvode_mem, indexB,
true);
553 CheckFlag(&flag,
"CVodeSetQuadErrConB", 1);
557 CheckFlag(&flag,
"CVodeQuadSStolerancesB", 1);
561 for(tind=
evalTimes.size()-2; tind>=0; --tind ) {
564 flag = CVodeB(cvode_mem,
evalTimes(tind), CV_NORMAL);
568 flag = CVodeGetB(cvode_mem, indexB, &t, lambda);
572 flag = CVodeGetQuadB(cvode_mem, indexB, &t, nvGrad);
576 lambdaMap -= sens.segment(tind*stateSize, stateSize);
579 flag = CVodeReInitB(cvode_mem, indexB,
evalTimes(tind), lambda);
581 flag = CVodeQuadReInitB(cvode_mem, indexB, nvGrad);
588 flag = CVodeB(cvode_mem,
startTime, CV_NORMAL);
592 flag = CVodeGetB(cvode_mem, indexB, &t, lambda);
597 flag = CVodeGetQuadB(cvode_mem, indexB, &t, nvGrad);
604 for(tind=0; tind<
evalTimes.size(); ++tind ) {
605 gradient += sens.segment(tind*stateSize, paramSize);
613 CVodeFree(&cvode_mem);
615 SUNNonlinSolFree(NLS);
616 SUNNonlinSolFree(adjNLS);
621 SUNLinSolFree(adjLS);
624 SUNMatDestroy(rhsJac);
625 if(adjRhsJac != NULL)
626 SUNMatDestroy(adjRhsJac);
631 for(
int i=0; i<inputs.size(); ++i)
646 Eigen::VectorXd
const& x0 = inputs.at(0).get();
647 const unsigned int stateSize = x0.size();
649 auto rhsData = std::make_shared<ODEData>(
rhs,
656 N_Vector state = N_VNew_Serial(stateSize);
657 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), stateSize);
663 void *cvode_mem = NULL;
665 cvode_mem = CVodeCreate(CV_BDF);
667 cvode_mem = CVodeCreate(CV_ADAMS);
669 std::stringstream msg;
670 msg <<
"ERROR: Invalid integrator method \"" <<
intOpts.
method <<
"\". Valid options are \"BDF\" or \"ADAMS\"\n";
671 throw std::runtime_error(msg.str());
679 CheckFlag(&flag,
"CVodeSStolerances", 1);
681 flag = CVodeSetUserData(cvode_mem, rhsData.get());
690 CheckFlag(&flag,
"CVodeSetMaxNumSteps", 1);
694 SUNMatrix rhsJac = NULL;
699 SUNNonlinearSolver NLS = NULL;
703 const unsigned int paramSize =
inputSizes(inWrt);
705 N_Vector *sensState =
nullptr;
706 sensState = N_VCloneVectorArray_Serial(paramSize, state);
707 CheckFlag((
void *)sensState,
"N_VCloneVectorArray_Serial", 0);
710 for(
int is=0; is<paramSize; ++is )
711 N_VConst(0.0, sensState[is]);
714 for(
int is=0; is<paramSize; ++is){
715 NV_Ith_S(sensState[is],is) = 1.0;
719 flag = CVodeSensInit(cvode_mem, paramSize, CV_SIMULTANEOUS, Interface::SensitivityRHS, sensState);
722 SUNNonlinearSolver sensNLS = NULL;
724 sensNLS = SUNNonlinSol_NewtonSens(paramSize+1,state);
726 sensNLS = SUNNonlinSol_FixedPointSens(paramSize+1, state, 0);
729 flag = CVodeSetNonlinearSolverSensSim(cvode_mem, sensNLS);
730 CheckFlag((
void *)sensState,
"CVodeSetNonlinearSolverSensSim", 0);
734 flag = CVodeSensEEtolerances(cvode_mem);
735 CheckFlag(&flag,
"CVodeSensEEtolerances", 1);
737 Eigen::VectorXd sensAbsTol =
intOpts.
sensAbsTol*Eigen::VectorXd::Ones(paramSize);
764 outputs.at(0).segment(tind*stateSize, stateSize) = x0;
768 jacobian.block(tind*stateSize, 0, stateSize, paramSize) = Eigen::MatrixXd::Identity(stateSize, paramSize);
779 flag = CVode(cvode_mem,
evalTimes(tind), state, &t, CV_NORMAL);
783 outputs.at(0).segment(tind*stateSize, stateSize) = stateMap;
786 int flag = CVodeGetSens(cvode_mem, &t, sensState);
789 for(
unsigned int i=0; i<stateSize; ++i ) {
790 for(
unsigned int j=0; j<paramSize; ++j ) {
791 jacobian(tind*stateSize+i, j) += NV_Ith_S(sensState[j], i);
799 N_VDestroyVectorArray_Serial(sensState, paramSize);
802 SUNMatDestroy(rhsJac);
804 CVodeFree(&cvode_mem);
809 SUNNonlinSolFree(NLS);
810 SUNNonlinSolFree(sensNLS);
815 for(
int i=0; i<inputs.size(); ++i)
825 Eigen::VectorXd
const& vec)
831 Eigen::VectorXd
const& x0 = inputs.at(0).get();
832 const unsigned int stateSize = x0.size();
834 auto rhsData = std::make_shared<ODEData>(
rhs,
842 N_Vector state = N_VNew_Serial(stateSize);
843 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), stateSize);
849 void *cvode_mem = NULL;
851 cvode_mem = CVodeCreate(CV_BDF);
853 cvode_mem = CVodeCreate(CV_ADAMS);
855 std::stringstream msg;
856 msg <<
"ERROR: Invalid integrator method \"" <<
intOpts.
method <<
"\". Valid options are \"BDF\" or \"ADAMS\"\n";
857 throw std::runtime_error(msg.str());
865 CheckFlag(&flag,
"CVodeSStolerances", 1);
867 flag = CVodeSetUserData(cvode_mem, rhsData.get());
876 CheckFlag(&flag,
"CVodeSetMaxNumSteps", 1);
880 SUNMatrix rhsJac = NULL;
885 SUNNonlinearSolver NLS = NULL;
889 const unsigned int paramSize = 1;
891 N_Vector *sensState =
nullptr;
892 sensState = N_VCloneVectorArray_Serial(paramSize, state);
893 CheckFlag((
void *)sensState,
"N_VCloneVectorArray_Serial", 0);
896 N_VConst(0.0, sensState[0]);
899 for(
int ind=0; ind<stateSize; ++ind){
900 NV_Ith_S(sensState[0],ind) = vec(ind);
904 flag = CVodeSensInit(cvode_mem, paramSize, CV_SIMULTANEOUS, Interface::SensitivityRHS, sensState);
907 SUNNonlinearSolver sensNLS = NULL;
909 sensNLS = SUNNonlinSol_NewtonSens(paramSize+1,state);
911 sensNLS = SUNNonlinSol_FixedPointSens(paramSize+1, state, 0);
914 flag = CVodeSetNonlinearSolverSensSim(cvode_mem, sensNLS);
915 CheckFlag((
void *)sensState,
"CVodeSetNonlinearSolverSensSim", 0);
918 flag = CVodeSensEEtolerances(cvode_mem);
919 CheckFlag(&flag,
"CVodeSensEEtolerances", 1);
944 outputs.at(0).segment(tind*stateSize, stateSize) = x0;
959 flag = CVode(cvode_mem,
evalTimes(tind), state, &t, CV_NORMAL);
963 outputs.at(0).segment(tind*stateSize, stateSize) = stateMap;
966 int flag = CVodeGetSens(cvode_mem, &t, sensState);
969 for(
unsigned int i=0; i<stateSize; ++i ) {
977 N_VDestroyVectorArray_Serial(sensState, paramSize);
980 SUNMatDestroy(rhsJac);
982 CVodeFree(&cvode_mem);
987 SUNNonlinSolFree(NLS);
988 SUNNonlinSolFree(sensNLS);
993 for(
int i=0; i<inputs.size(); ++i)
1007 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), NV_LENGTH_S(state));
1011 Eigen::Map<Eigen::VectorXd> timeDerivMap(NV_DATA_S(timeDeriv), NV_LENGTH_S(timeDeriv));
1012 timeDerivMap = data->
rhs->Evaluate(data->
inputs) [0];
1033 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(state), NV_LENGTH_S(state));
1036 Eigen::VectorXd vEig = Eigen::Map<Eigen::VectorXd>(NV_DATA_S(
v), NV_LENGTH_S(
v));
1039 Eigen::Map<Eigen::VectorXd> JvMap(NV_DATA_S(Jv), NV_LENGTH_S(Jv));
1050 N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) {
1057 Eigen::Map<Eigen::VectorXd> stateMap(NV_DATA_S(state), NV_LENGTH_S(state));
1061 Eigen::Map<Eigen::MatrixXd> jacMap(SUNDenseMatrix_Data(jac),
1062 SUNDenseMatrix_Rows(jac),
1063 SUNDenseMatrix_Columns(jac));
1071 int ODE::Interface::SensitivityRHS(
int Ns, realtype time, N_Vector y, N_Vector ydot, N_Vector *ys, N_Vector *ySdot,
void *user_data, N_Vector tmp1, N_Vector tmp2) {
1077 unsigned int stateWrt = data->
autonomous? 0 : 1;
1080 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(y), NV_LENGTH_S(y));
1083 for(
unsigned int i=0; i<Ns; ++i ) {
1084 Eigen::Map<Eigen::VectorXd> rhsMap(NV_DATA_S(ySdot[i]), stateref.size());
1085 Eigen::Map<Eigen::VectorXd> sensMap(NV_DATA_S(ys[i]), stateref.size());
1088 rhsMap = data->
rhs->ApplyJacobian(0, stateWrt, data->
inputs, (Eigen::VectorXd)sensMap);
1101 Eigen::Map<Eigen::VectorXd> rhsMap(NV_DATA_S(ySdot[0]), stateref.size());
1106 const Eigen::MatrixXd& dfdp = data->
rhs->Jacobian(0, rhsWrt, data->
inputs);
1109 for(
unsigned int i=0; i<Ns; ++i ) {
1110 Eigen::Map<Eigen::VectorXd> rhsMap(NV_DATA_S(ySdot[i]), stateref.size());
1113 rhsMap += dfdp.col(i);
1123 int ODE::Interface::AdjointRHS(realtype time, N_Vector state, N_Vector lambda, N_Vector deriv,
void *user_data) {
1131 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(state), NV_LENGTH_S(state));
1134 Eigen::Map<Eigen::VectorXd> lambdaMap(NV_DATA_S(lambda), NV_LENGTH_S(lambda));
1135 Eigen::VectorXd lam = lambdaMap;
1137 Eigen::Map<Eigen::VectorXd> derivMap(NV_DATA_S(deriv), NV_LENGTH_S(deriv));
1145 int ODE::Interface::AdjointJacobianAction(N_Vector target, N_Vector output, realtype time, N_Vector state, N_Vector lambda, N_Vector adjRhs,
void *user_data, N_Vector tmp) {
1153 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(state), NV_LENGTH_S(state));
1156 Eigen::Map<Eigen::VectorXd> targetMap(NV_DATA_S(target), NV_LENGTH_S(target));
1157 Eigen::VectorXd targ = targetMap;
1159 Eigen::Map<Eigen::VectorXd> outputMap(NV_DATA_S(output), NV_LENGTH_S(output));
1167 int ODE::Interface::AdjointJacobian(
double time, N_Vector state, N_Vector lambda, N_Vector
rhs, SUNMatrix jac,
void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) {
1175 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(state), NV_LENGTH_S(state));
1179 Eigen::Map<Eigen::MatrixXd> jacMap(SUNDenseMatrix_Data(jac),
1180 SUNDenseMatrix_Rows(jac),
1181 SUNDenseMatrix_Columns(jac));
1188 int ODE::Interface::AdjointQuad(realtype time, N_Vector state, N_Vector lambda, N_Vector quadRhs,
void *user_data) {
1196 Eigen::Map<Eigen::VectorXd> stateref(NV_DATA_S(state), NV_LENGTH_S(state));
1199 Eigen::Map<Eigen::VectorXd> lambdaMap(NV_DATA_S(lambda), NV_LENGTH_S(lambda));
1200 Eigen::VectorXd lam = lambdaMap;
1202 Eigen::Map<Eigen::VectorXd> nvQuadMap(NV_DATA_S(quadRhs), NV_LENGTH_S(quadRhs));
1215 std::stringstream msg;
1218 if (opt == 0 && returnvalue == NULL) {
1219 msg <<
"SUNDIALS_ERROR: " << funcname <<
" failed - returned NULL pointer";
1220 throw std::runtime_error(msg.str());
1223 }
else if (opt == 1) {
1224 retval = (
int *) returnvalue;
1227 msg <<
"SUNDIALS_ERROR: " << funcname <<
" failed with retval = " << *retval;
1228 throw std::runtime_error(msg.str());
1232 }
else if (opt == 2 && returnvalue == NULL) {
1233 msg <<
"MEMORY_ERROR: " << funcname <<
" failed - returned NULL pointer";
1234 throw std::runtime_error(msg.str());
Provides an abstract interface for defining vector-valued model components.
const Eigen::VectorXi inputSizes
std::vector< Eigen::VectorXd > outputs
const Eigen::VectorXi outputSizes
std::vector< Eigen::VectorXd > cacheInput
Eigen::VectorXd jacobianAction
A helper class for Sundial's time integration.
const bool autonomous
Is the RHS autonomous?
ref_vector< Eigen::VectorXd > inputs
Eigen::VectorXd actionVec
void UpdateInputs(Eigen::Ref< const Eigen::VectorXd > const &newState, double const time)
Update the time and state inputs.
const int wrtIn
The input we are computing the derivative wrt — negative indicates no derivative is being computed.
std::shared_ptr< ModPiece > rhs
The right hand side of the ODE.
const double startTime
The time when this simulation starts – either set in the opts ptree or set to the minimum of evalTime...
static Eigen::VectorXi GetInputSizes(std::shared_ptr< ModPiece > const &rhsIn, bool isAuto)
static void CheckFlag(void *returnvalue, const char *funcname, int opt)
Checks the return value produced by CVODES. Throws and exception if error occured.
SUNNonlinearSolver CreateNonlinearSolver(void *cvode_mem, N_Vector const &state)
std::pair< SUNLinearSolver, SUNMatrix > CreateAdjointLinearSolver(void *cvode_mem, N_Vector const &state, int indexB)
virtual void JacobianImpl(unsigned int outWrt, unsigned int inWrt, ref_vector< Eigen::VectorXd > const &inputs) override
static Eigen::VectorXi GetOutputSizes(std::shared_ptr< ModPiece > const &rhsIn, Eigen::VectorXd const &evalTimes)
virtual void GradientImpl(unsigned int outWrt, unsigned int inWrt, ref_vector< Eigen::VectorXd > const &inputs, Eigen::VectorXd const &sens) override
IntegratorOptions intOpts
std::shared_ptr< ModPiece > rhs
LinearSolverOptions linOpts
std::pair< SUNLinearSolver, SUNMatrix > CreateLinearSolver(void *cvode_mem, N_Vector const &state)
virtual void ApplyJacobianImpl(unsigned int outWrt, unsigned int inWrt, ref_vector< Eigen::VectorXd > const &inputs, Eigen::VectorXd const &vec) override
SUNNonlinearSolver CreateAdjointNonlinearSolver(void *cvode_mem, N_Vector const &state, int indexB)
const bool isAutonomous
Does the RHS explicitly depend on time?
ODE(std::shared_ptr< ModPiece > const &rhsIn, Eigen::VectorXd const &evalTimesIn, boost::property_tree::ptree opts=boost::property_tree::ptree())
const Eigen::VectorXd evalTimes
NonlinearSolverOptions nonlinOpts
static double GetStartTime(Eigen::VectorXd const &evalTimesIn, boost::property_tree::ptree const &opts)
virtual void EvaluateImpl(ref_vector< Eigen::VectorXd > const &inputs) override
Integrates the ODE forward in time.
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
void SetOptions(boost::property_tree::ptree const &opts)
static int RHSJacobianAction(N_Vector v, N_Vector Jv, realtype time, N_Vector state, N_Vector rhs, void *user_data, N_Vector tmp)
static int RHSJacobian(realtype time, N_Vector state, N_Vector rhs, SUNMatrix jac, void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
static int RHS(realtype time, N_Vector state, N_Vector deriv, void *user_data)
void SetOptions(boost::property_tree::ptree const &opts)
void SetOptions(boost::property_tree::ptree const &opts)