OGS
MathLib::ODE::CVodeSolverImpl Class Referencefinal

Detailed Description

This class provides concrete access to Sundials' CVode solver.

This class is the implementation part in the pimpl idiom used by the CVodeSolver class. Therefore all if this classes methods are only forwarded from CVodeSolver.

Definition at line 84 of file CVodeSolver.cpp.

Public Member Functions

 CVodeSolverImpl (BaseLib::ConfigTree const &config, unsigned const num_equations)
 
void setFunction (std::unique_ptr< detail::FunctionHandles > &&f)
 
void preSolve ()
 
bool solve (const double t_end)
 
double const * getSolution () const
 
double getTime () const
 
void getYDot (const double t, double const *const y, double *const y_dot)
 
void setTolerance (const double *abstol, const double reltol)
 
void setTolerance (const double abstol, const double reltol)
 
void setIC (const double t0, double const *const y0)
 
 ~CVodeSolverImpl ()
 

Private Attributes

N_Vector _y = nullptr
 The solution vector. More...
 
realtype _t
 
N_Vector _abstol = nullptr
 current time More...
 
realtype _reltol
 Relative tolerance. More...
 
unsigned _num_equations
 Number of equations in the ODE system. More...
 
void * _cvode_mem
 CVode's internal memory. More...
 
std::unique_ptr< detail::FunctionHandles_f
 
int _linear_multistep_method = CV_ADAMS
 The multistep method used for solving the ODE. More...
 
int _nonlinear_solver_iteration = CV_FUNCTIONAL
 Either solve via fixed-point iteration or via Newton-Raphson method. More...
 

Constructor & Destructor Documentation

◆ CVodeSolverImpl()

MathLib::ODE::CVodeSolverImpl::CVodeSolverImpl ( BaseLib::ConfigTree const &  config,
unsigned const  num_equations 
)
Input File Parameter:
ode_solver__CVODE__linear_multistep_method
Input File Parameter:
ode_solver__CVODE__nonlinear_solver_iteration

Definition at line 131 of file CVodeSolver.cpp.

133 {
134  if (auto const param =
136  config.getConfigParameterOptional<std::string>("linear_multistep_method"))
137  {
138  DBUG("setting linear multistep method (config: {:s})", param->c_str());
139 
140  if (*param == "Adams")
141  {
142  _linear_multistep_method = CV_ADAMS;
143  }
144  else if (*param == "BDF")
145  {
146  _linear_multistep_method = CV_BDF;
147  }
148  else
149  {
150  OGS_FATAL("unknown linear multistep method: {:s}", param->c_str());
151  }
152  }
153 
154  if (auto const param =
156  config.getConfigParameterOptional<std::string>("nonlinear_solver_iteration"))
157  {
158  DBUG("setting nonlinear solver iteration (config: {:s})",
159  param->c_str());
160 
161  if (*param == "Functional")
162  {
163  _nonlinear_solver_iteration = CV_FUNCTIONAL;
164  }
165  else if (*param == "Newton")
166  {
167  _nonlinear_solver_iteration = CV_NEWTON;
168  }
169  else
170  {
171  OGS_FATAL("unknown nonlinear solver iteration: {:s}",
172  param->c_str());
173  }
174  }
175 
176  _y = N_VNew_Serial(num_equations);
177  _abstol = N_VNew_Serial(num_equations);
178  _num_equations = num_equations;
179 
180  _cvode_mem =
182 
183  if (_cvode_mem == nullptr || _y == nullptr || _abstol == nullptr)
184  {
185  OGS_FATAL("couldn't allocate storage for CVode solver.");
186  }
187 
188  auto f_wrapped = [](const realtype t, const N_Vector y, N_Vector ydot,
189  void* function_handles) -> int
190  {
191  bool successful =
192  static_cast<detail::FunctionHandles*>(function_handles)
193  ->call(t, NV_DATA_S(y), NV_DATA_S(ydot));
194  return successful ? 0 : 1;
195  };
196 
197  check_error("CVodeInit", CVodeInit(_cvode_mem, f_wrapped, 0.0, _y));
198 }

References _abstol, _cvode_mem, _linear_multistep_method, _nonlinear_solver_iteration, _num_equations, _y, check_error(), DBUG(), BaseLib::ConfigTree::getConfigParameterOptional(), and OGS_FATAL.

◆ ~CVodeSolverImpl()

MathLib::ODE::CVodeSolverImpl::~CVodeSolverImpl ( )

Definition at line 301 of file CVodeSolver.cpp.

302 {
304 
305  N_VDestroy_Serial(_y);
306  N_VDestroy_Serial(_abstol);
307  CVodeFree(&_cvode_mem);
308 }

References _abstol, _cvode_mem, _y, and printStats().

Member Function Documentation

◆ getSolution()

double const* MathLib::ODE::CVodeSolverImpl::getSolution ( ) const
inline

Definition at line 98 of file CVodeSolver.cpp.

98 { return NV_DATA_S(_y); }

References _y.

◆ getTime()

double MathLib::ODE::CVodeSolverImpl::getTime ( ) const
inline

Definition at line 99 of file CVodeSolver.cpp.

99 { return _t; }

References _t.

◆ getYDot()

void MathLib::ODE::CVodeSolverImpl::getYDot ( const double  t,
double const *const  y,
double *const  y_dot 
)

Definition at line 294 of file CVodeSolver.cpp.

296 {
297  assert(_f != nullptr);
298  _f->call(t, y, y_dot);
299 }

References _f.

◆ preSolve()

void MathLib::ODE::CVodeSolverImpl::preSolve ( )

Definition at line 236 of file CVodeSolver.cpp.

237 {
238  assert(_f != nullptr && "ode function handle was not provided");
239 
240  // sets initial conditions
241  check_error("CVodeReInit", CVodeReInit(_cvode_mem, _t, _y));
242 
243  check_error("CVodeSetUserData",
244  CVodeSetUserData(_cvode_mem, static_cast<void*>(_f.get())));
245 
246  /* Call CVodeSVtolerances to specify the scalar relative tolerance
247  * and vector absolute tolerances */
248  check_error("CVodeSVtolerances",
249  CVodeSVtolerances(_cvode_mem, _reltol, _abstol));
250 
251  /* Call CVDense to specify the CVDENSE dense linear solver */
252  check_error("CVDense", CVDense(_cvode_mem, _num_equations));
253 
254  if (_f->hasJacobian())
255  {
256  auto df_wrapped = [](const long N, const realtype t, const N_Vector y,
257  const N_Vector ydot, const DlsMat jac,
258  void* function_handles, N_Vector /*tmp1*/,
259  N_Vector /*tmp2*/, N_Vector /*tmp3*/
260  ) -> int
261  {
262  (void)N; // prevent warnings during non-debug build
263  auto* fh = static_cast<detail::FunctionHandles*>(function_handles);
264  assert(N == fh->getNumberOfEquations());
265 
266  // Caution: by calling the DENSE_COL() macro we assume that matrices
267  // are stored contiguously in memory!
268  // See also the header files sundials_direct.h and cvode_direct.h in
269  // the Sundials source code. The comments about the macro DENSE_COL
270  // in those files indicate that matrices are stored column-wise.
271  bool successful = fh->callJacobian(t, NV_DATA_S(y), NV_DATA_S(ydot),
272  DENSE_COL(jac, 0));
273  return successful ? 0 : 1;
274  };
275 
276  check_error("CVDlsSetDenseJacFn",
277  CVDlsSetDenseJacFn(_cvode_mem, df_wrapped));
278  }
279 }

References _abstol, _cvode_mem, _f, _num_equations, _reltol, _t, _y, and check_error().

◆ setFunction()

void MathLib::ODE::CVodeSolverImpl::setFunction ( std::unique_ptr< detail::FunctionHandles > &&  f)

Definition at line 220 of file CVodeSolver.cpp.

221 {
222  _f = std::move(f);
223  assert(_num_equations == _f->getNumberOfEquations());
224 }

References _f, and _num_equations.

◆ setIC()

void MathLib::ODE::CVodeSolverImpl::setIC ( const double  t0,
double const *const  y0 
)

Definition at line 226 of file CVodeSolver.cpp.

227 {
228  for (unsigned i = 0; i < _num_equations; ++i)
229  {
230  NV_Ith_S(_y, i) = y0[i];
231  }
232 
233  _t = t0;
234 }

References _num_equations, _t, and _y.

◆ setTolerance() [1/2]

void MathLib::ODE::CVodeSolverImpl::setTolerance ( const double *  abstol,
const double  reltol 
)

Definition at line 200 of file CVodeSolver.cpp.

201 {
202  for (unsigned i = 0; i < _num_equations; ++i)
203  {
204  NV_Ith_S(_abstol, i) = abstol[i];
205  }
206 
207  _reltol = reltol;
208 }

References _abstol, _num_equations, and _reltol.

◆ setTolerance() [2/2]

void MathLib::ODE::CVodeSolverImpl::setTolerance ( const double  abstol,
const double  reltol 
)

Definition at line 210 of file CVodeSolver.cpp.

211 {
212  for (unsigned i = 0; i < _num_equations; ++i)
213  {
214  NV_Ith_S(_abstol, i) = abstol;
215  }
216 
217  _reltol = reltol;
218 }

References _abstol, _num_equations, and _reltol.

◆ solve()

bool MathLib::ODE::CVodeSolverImpl::solve ( const double  t_end)

Definition at line 281 of file CVodeSolver.cpp.

282 {
283  realtype t_reached;
284  check_error("CVode solve",
285  CVode(_cvode_mem, t_end, _y, &t_reached, CV_NORMAL));
286  _t = t_reached;
287 
288  // check_error asserts that t_end == t_reached and that solving the ODE
289  // went fine. Otherwise the program will be aborted. Therefore, we don't
290  // have to check manually for errors here and can always savely return true.
291  return true;
292 }

References _cvode_mem, _t, _y, and check_error().

Member Data Documentation

◆ _abstol

N_Vector MathLib::ODE::CVodeSolverImpl::_abstol = nullptr
private

current time

Array of absolute tolerances.

Definition at line 112 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl(), preSolve(), setTolerance(), and ~CVodeSolverImpl().

◆ _cvode_mem

void* MathLib::ODE::CVodeSolverImpl::_cvode_mem
private

CVode's internal memory.

Definition at line 116 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl(), preSolve(), solve(), and ~CVodeSolverImpl().

◆ _f

std::unique_ptr<detail::FunctionHandles> MathLib::ODE::CVodeSolverImpl::_f
private

Function handles that compute \(\partial \dot y/\partial y\) and \(\dot y\).

Definition at line 120 of file CVodeSolver.cpp.

Referenced by getYDot(), preSolve(), and setFunction().

◆ _linear_multistep_method

int MathLib::ODE::CVodeSolverImpl::_linear_multistep_method = CV_ADAMS
private

The multistep method used for solving the ODE.

Definition at line 123 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl().

◆ _nonlinear_solver_iteration

int MathLib::ODE::CVodeSolverImpl::_nonlinear_solver_iteration = CV_FUNCTIONAL
private

Either solve via fixed-point iteration or via Newton-Raphson method.

Definition at line 126 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl().

◆ _num_equations

unsigned MathLib::ODE::CVodeSolverImpl::_num_equations
private

Number of equations in the ODE system.

Definition at line 115 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl(), preSolve(), setFunction(), setIC(), and setTolerance().

◆ _reltol

realtype MathLib::ODE::CVodeSolverImpl::_reltol
private

Relative tolerance.

Definition at line 113 of file CVodeSolver.cpp.

Referenced by preSolve(), and setTolerance().

◆ _t

realtype MathLib::ODE::CVodeSolverImpl::_t
private

Definition at line 110 of file CVodeSolver.cpp.

Referenced by getTime(), preSolve(), setIC(), and solve().

◆ _y

N_Vector MathLib::ODE::CVodeSolverImpl::_y = nullptr
private

The solution vector.

Definition at line 108 of file CVodeSolver.cpp.

Referenced by CVodeSolverImpl(), getSolution(), preSolve(), setIC(), solve(), and ~CVodeSolverImpl().


The documentation for this class was generated from the following file:
MathLib::ODE::CVodeSolverImpl::_num_equations
unsigned _num_equations
Number of equations in the ODE system.
Definition: CVodeSolver.cpp:115
MathLib::ODE::CVodeSolverImpl::_t
realtype _t
Definition: CVodeSolver.cpp:110
MathLib::ODE::CVodeSolverImpl::_cvode_mem
void * _cvode_mem
CVode's internal memory.
Definition: CVodeSolver.cpp:116
MathLib::ODE::CVodeSolverImpl::_nonlinear_solver_iteration
int _nonlinear_solver_iteration
Either solve via fixed-point iteration or via Newton-Raphson method.
Definition: CVodeSolver.cpp:126
printStats
void printStats(void *cvode_mem)
Prints some statistics about an ODE solver run.
Definition: CVodeSolver.cpp:42
OGS_FATAL
#define OGS_FATAL(...)
Definition: Error.h:25
DBUG
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
MathLib::ODE::CVodeSolverImpl::_linear_multistep_method
int _linear_multistep_method
The multistep method used for solving the ODE.
Definition: CVodeSolver.cpp:123
MathLib::ODE::CVodeSolverImpl::_y
N_Vector _y
The solution vector.
Definition: CVodeSolver.cpp:108
MathLib::ODE::CVodeSolverImpl::_reltol
realtype _reltol
Relative tolerance.
Definition: CVodeSolver.cpp:113
NumLib::ShapeMatrixType::N
@ N
calculates N
MathLib::ODE::CVodeSolverImpl::_f
std::unique_ptr< detail::FunctionHandles > _f
Definition: CVodeSolver.cpp:120
MathLib::ODE::CVodeSolverImpl::_abstol
N_Vector _abstol
current time
Definition: CVodeSolver.cpp:112
check_error
void check_error(std::string const &f_name, int const error_flag)
Definition: CVodeSolver.cpp:32