OGS  master
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  bool successful =
193  static_cast<detail::FunctionHandles*>(function_handles)
194  ->call(t, NV_DATA_S(y), NV_DATA_S(ydot));
195  return successful ? 0 : 1;
196  };
197 
198  check_error("CVodeInit", CVodeInit(cvode_mem_, f_wrapped, 0.0, y_));
199 }
#define OGS_FATAL(...)
Definition: Error.h:25
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 301 of file CVodeSolver.cpp.

302 {
304 
305  N_VDestroy_Serial(y_);
306  N_VDestroy_Serial(abstol_);
307  CVodeFree(&cvode_mem_);
308 }
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 294 of file CVodeSolver.cpp.

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

References f_.

◆ preSolve()

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

Definition at line 237 of file CVodeSolver.cpp.

238 {
239  assert(f_ != nullptr && "ode function handle was not provided");
240 
241  // sets initial conditions
242  check_error("CVodeReInit", CVodeReInit(cvode_mem_, t_, y_));
243 
244  check_error("CVodeSetUserData",
245  CVodeSetUserData(cvode_mem_, static_cast<void*>(f_.get())));
246 
247  /* Call CVodeSVtolerances to specify the scalar relative tolerance
248  * and vector absolute tolerances */
249  check_error("CVodeSVtolerances",
250  CVodeSVtolerances(cvode_mem_, reltol_, abstol_));
251 
252  /* Call CVDense to specify the CVDENSE dense linear solver */
253  check_error("CVDense", CVDense(cvode_mem_, num_equations_));
254 
255  if (f_->hasJacobian())
256  {
257  auto df_wrapped = [](const long N, const realtype t, const N_Vector y,
258  const N_Vector ydot, const DlsMat jac,
259  void* function_handles, N_Vector /*tmp1*/,
260  N_Vector /*tmp2*/, N_Vector /*tmp3*/
261  ) -> int {
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 }
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 221 of file CVodeSolver.cpp.

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

References f_, and num_equations_.

◆ setIC()

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

Definition at line 227 of file CVodeSolver.cpp.

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

References num_equations_, t_, and y_.

◆ setTolerance() [1/2]

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

Definition at line 201 of file CVodeSolver.cpp.

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

References abstol_, num_equations_, and reltol_.

◆ setTolerance() [2/2]

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

Definition at line 211 of file CVodeSolver.cpp.

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

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 safely return true.
291  return true;
292 }

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: