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::FunctionHandlesf_
 
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>(
137  "linear_multistep_method"))
138  {
139  DBUG("setting linear multistep method (config: {:s})", param->c_str());
140 
141  if (*param == "Adams")
142  {
143  linear_multistep_method_ = CV_ADAMS;
144  }
145  else if (*param == "BDF")
146  {
147  linear_multistep_method_ = CV_BDF;
148  }
149  else
150  {
151  OGS_FATAL("unknown linear multistep method: {:s}", param->c_str());
152  }
153  }
154 
155  if (auto const param =
157  config.getConfigParameterOptional<std::string>(
158  "nonlinear_solver_iteration"))
159  {
160  DBUG("setting nonlinear solver iteration (config: {:s})",
161  param->c_str());
162 
163  if (*param == "Functional")
164  {
165  nonlinear_solver_iteration_ = CV_FUNCTIONAL;
166  }
167  else if (*param == "Newton")
168  {
169  nonlinear_solver_iteration_ = CV_NEWTON;
170  }
171  else
172  {
173  OGS_FATAL("unknown nonlinear solver iteration: {:s}",
174  param->c_str());
175  }
176  }
177 
178  y_ = N_VNew_Serial(num_equations);
179  abstol_ = N_VNew_Serial(num_equations);
180  num_equations_ = num_equations;
181 
182  cvode_mem_ =
184 
185  if (cvode_mem_ == nullptr || y_ == nullptr || abstol_ == nullptr)
186  {
187  OGS_FATAL("couldn't allocate storage for CVode solver.");
188  }
189 
190  auto f_wrapped = [](const realtype t, const N_Vector y, N_Vector ydot,
191  void* function_handles) -> int
192  {
193  bool successful =
194  static_cast<detail::FunctionHandles*>(function_handles)
195  ->call(t, NV_DATA_S(y), NV_DATA_S(ydot));
196  return successful ? 0 : 1;
197  };
198 
199  check_error("CVodeInit", CVodeInit(cvode_mem_, f_wrapped, 0.0, y_));
200 }
#define OGS_FATAL(...)
Definition: Error.h:26
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
N_Vector abstol_
current time
void * cvode_mem_
CVode's internal memory.
N_Vector y_
The solution vector.
int linear_multistep_method_
The multistep method used for solving the ODE.
unsigned num_equations_
Number of equations in the ODE system.
int nonlinear_solver_iteration_
Either solve via fixed-point iteration or via Newton-Raphson method.
void check_error(std::string const &f_name, int const error_flag)
Definition: CVodeSolver.cpp:32

References abstol_, check_error(), cvode_mem_, DBUG(), BaseLib::ConfigTree::getConfigParameterOptional(), linear_multistep_method_, nonlinear_solver_iteration_, num_equations_, OGS_FATAL, and y_.

◆ ~CVodeSolverImpl()

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

Definition at line 303 of file CVodeSolver.cpp.

304 {
306 
307  N_VDestroy_Serial(y_);
308  N_VDestroy_Serial(abstol_);
309  CVodeFree(&cvode_mem_);
310 }
void printStats(void *cvode_mem)
Prints some statistics about an ODE solver run.
Definition: CVodeSolver.cpp:42

References abstol_, cvode_mem_, printStats(), and y_.

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 296 of file CVodeSolver.cpp.

298 {
299  assert(f_ != nullptr);
300  f_->call(t, y, y_dot);
301 }
std::unique_ptr< detail::FunctionHandles > f_

References f_.

◆ preSolve()

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

Definition at line 238 of file CVodeSolver.cpp.

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

References abstol_, check_error(), cvode_mem_, f_, num_equations_, reltol_, t_, and y_.

◆ setFunction()

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

Definition at line 222 of file CVodeSolver.cpp.

223 {
224  f_ = std::move(f);
225  assert(num_equations_ == f_->getNumberOfEquations());
226 }

References f_, and num_equations_.

◆ setIC()

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

Definition at line 228 of file CVodeSolver.cpp.

229 {
230  for (unsigned i = 0; i < num_equations_; ++i)
231  {
232  NV_Ith_S(y_, i) = y0[i];
233  }
234 
235  t_ = t0;
236 }

References num_equations_, t_, and y_.

◆ setTolerance() [1/2]

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

Definition at line 202 of file CVodeSolver.cpp.

203 {
204  for (unsigned i = 0; i < num_equations_; ++i)
205  {
206  NV_Ith_S(abstol_, i) = abstol[i];
207  }
208 
209  reltol_ = reltol;
210 }

References abstol_, num_equations_, and reltol_.

◆ setTolerance() [2/2]

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

Definition at line 212 of file CVodeSolver.cpp.

213 {
214  for (unsigned i = 0; i < num_equations_; ++i)
215  {
216  NV_Ith_S(abstol_, i) = abstol;
217  }
218 
219  reltol_ = reltol;
220 }

References abstol_, num_equations_, and reltol_.

◆ solve()

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

Definition at line 283 of file CVodeSolver.cpp.

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

References check_error(), cvode_mem_, t_, and y_.

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(), ~CVodeSolverImpl(), preSolve(), and setTolerance().

◆ cvode_mem_

void* MathLib::ODE::CVodeSolverImpl::cvode_mem_
private

CVode's internal memory.

Definition at line 116 of file CVodeSolver.cpp.

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

◆ 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(), ~CVodeSolverImpl(), getSolution(), preSolve(), setIC(), and solve().


The documentation for this class was generated from the following file: