41 #include "AbstractCvodeSystem.hpp"
45 #include "TimeStepper.hpp"
46 #include "CvodeAdaptor.hpp"
49 #include <cvode/cvode.h>
50 #include <sundials/sundials_nvector.h>
51 #include <cvode/cvode_dense.h>
74 int AbstractCvodeSystemRhsAdaptor(realtype t,
N_Vector y,
N_Vector ydot,
void *pData)
76 assert(pData != NULL);
84 #if CHASTE_SUNDIALS_VERSION <= 20300
92 std::cerr <<
"CVODE RHS Exception: " << e.
GetMessage()
93 << std::endl << std::flush;
115 #if CHASTE_SUNDIALS_VERSION >= 20500
117 int AbstractCvodeSystemJacAdaptor(
long int N, realtype t,
N_Vector y,
N_Vector ydot, DlsMat jacobian,
118 #elif CHASTE_SUNDIALS_VERSION >= 20400
120 int AbstractCvodeSystemJacAdaptor(
int N, realtype t,
N_Vector y,
N_Vector ydot, DlsMat jacobian,
123 int AbstractCvodeSystemJacAdaptor(
long int N, DenseMat jacobian, realtype t,
N_Vector y,
N_Vector ydot,
127 assert(pData != NULL);
135 std::cerr <<
"CVODE Jacobian Exception: " << e.
GetMessage() << std::endl << std::flush;
143 mLastSolutionState(NULL),
144 mLastSolutionTime(0.0),
145 #if CHASTE_SUNDIALS_VERSION >=20400
152 mForceMinimalReset(false),
153 mHasAnalyticJacobian(false),
154 mUseAnalyticJacobian(false),
157 mLastInternalStepSize(0)
194 assert(tEnd >= tStart);
219 double cvode_stopped_at = stepper.
GetTime();
221 &cvode_stopped_at, CV_NORMAL);
225 CvodeError(ierr,
"CVODE failed to solve system", cvode_stopped_at);
228 assert(fabs(cvode_stopped_at - stepper.
GetNextTime()) < DBL_EPSILON);
234 solutions.
rGetTimes().push_back(cvode_stopped_at);
253 assert(tEnd >= tStart);
258 int ierr = CVodeSetStopTime(
mpCvodeMem, tEnd);
261 double cvode_stopped_at = tStart;
266 CvodeError(ierr,
"CVODE failed to solve system", cvode_stopped_at);
269 assert(fabs(cvode_stopped_at - tEnd) < DBL_EPSILON);
364 assert(maxDt >= 0.0);
372 for (
unsigned i=0; i<size; i++)
389 CVodeSetErrHandlerFn(
mpCvodeMem, CvodeErrorHandler, NULL);
391 #if CHASTE_SUNDIALS_VERSION >= 20400
397 #if CHASTE_SUNDIALS_VERSION >= 20400
398 CVodeInit(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions);
401 CVodeMalloc(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions,
405 CVDense(
mpCvodeMem, NV_LENGTH_S(initialConditions));
409 #if CHASTE_SUNDIALS_VERSION >= 20400
410 CVDlsSetDenseJacFn(
mpCvodeMem, AbstractCvodeSystemJacAdaptor);
412 CVDenseSetJacFn(
mpCvodeMem, AbstractCvodeSystemJacAdaptor, (
void*)(
this));
419 #if CHASTE_SUNDIALS_VERSION >= 20400
420 CVodeReInit(
mpCvodeMem, tStart, initialConditions);
423 CVodeReInit(
mpCvodeMem, AbstractCvodeSystemRhsAdaptor, tStart, initialConditions,
451 for (
unsigned i=0; i<size; i++)
471 std::stringstream err;
472 char* p_flag_name = CVodeGetReturnFlagName(flag);
473 err << msg <<
": " << p_flag_name;
475 if (flag == CV_LSETUP_FAIL)
477 #if CHASTE_SUNDIALS_VERSION >= 20500
482 char* p_ls_flag_name;
483 #if CHASTE_SUNDIALS_VERSION >= 20400
485 p_ls_flag_name = CVDlsGetReturnFlagName(ls_flag);
488 p_ls_flag_name = CVDenseGetReturnFlagName(ls_flag);
490 err <<
" (LS flag=" << ls_flag <<
":" << p_ls_flag_name <<
")";
491 free(p_ls_flag_name);
494 err <<
"\nGot to time " << rTime <<
"\n";
495 err <<
"\nState variables are now:\n";
498 for (
unsigned i=0; i<state_vars.size(); i++)
500 err <<
"\t" << state_var_names[i] <<
"\t:\t" << state_vars[i] << std::endl;
504 std::cerr << err.str() << std::endl << std::flush;
523 EXCEPTION(
"Analytic Jacobian requested, but this ODE system doesn't have one. You can check this with HasAnalyticJacobian().");
586 #endif // CHASTE_CVODE
double GetAbsoluteTolerance()
void SetMinimalReset(bool minimalReset)
void SetTolerances(double relTol=1e-5, double absTol=1e-7)
std::vector< double > MakeStdVec(N_Vector v)
static bool WithinAnyTolerance(double number1, double number2, double relTol=DBL_EPSILON, double absTol=DBL_EPSILON, bool printError=false)
std::vector< std::vector< double > > & rGetSolutions()
bool GetUseAnalyticJacobian() const
void RecordStoppingPoint(double stopTime)
#define EXCEPTION(message)
double mLastInternalStepSize
void SetupCvode(N_Vector initialConditions, realtype tStart, realtype maxDt)
const std::vector< std::string > & rGetStateVariableNames() const
void AdvanceOneTimeStep()
unsigned GetNumberOfStateVariables() const
N_Vector GetInitialConditions() const
void CreateVectorIfEmpty(VECTOR &rVec, unsigned size)
void SetOdeSystemInformation(boost::shared_ptr< const AbstractOdeSystemInformation > pOdeSystemInfo)
bool mUseAnalyticJacobian
bool HasAnalyticJacobian() const
virtual void EvaluateAnalyticJacobian(long int N, realtype time, N_Vector y, N_Vector ydot, CHASTE_CVODE_DENSE_MATRIX jacobian, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
void SetForceReset(bool autoReset)
virtual void EvaluateYDerivatives(realtype time, const N_Vector y, N_Vector ydot)=0
std::string GetMessage() const
void SetVectorComponent(VECTOR &rVec, unsigned index, double value)
unsigned GetTotalTimeStepsTaken() const
void SetMaxSteps(long int numSteps)
virtual void VerifyStateVariables()
virtual ~AbstractCvodeSystem()
std::vector< double > & rGetTimes()
unsigned EstimateTimeSteps() const
double GetRelativeTolerance()
boost::shared_ptr< AbstractOdeSystemInformation > mpSystemInfo
OdeSolution Solve(realtype tStart, realtype tEnd, realtype maxDt, realtype tSamp)
N_Vector mLastSolutionState
std::string CheckShortMessageContains(std::string expected) const
double GetNextTime() const
double GetVectorComponent(const VECTOR &rVec, unsigned index)
void CvodeError(int flag, const char *msg, const double &rTime)
void ForceUseOfNumericalJacobian(bool useNumericalJacobian=true)
AbstractCvodeSystem(unsigned numberOfStateVariables)
bool mHasAnalyticJacobian
void SetNumberOfTimeSteps(unsigned numTimeSteps)
const std::vector< std::string > & rGetParameterNames() const
void DeleteVector(VECTOR &rVec)