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.
 
realtype t_
 
N_Vector abstol_ = nullptr
 current time
 
realtype reltol_
 Relative tolerance.
 
unsigned num_equations_
 Number of equations in the ODE system.
 
void * cvode_mem_
 CVode's internal memory.
 
std::unique_ptr< detail::FunctionHandlesf_
 
int linear_multistep_method_ = CV_ADAMS
 The multistep method used for solving the ODE.
 
int nonlinear_solver_iteration_ = CV_FUNCTIONAL
 Either solve via fixed-point iteration or via Newton-Raphson method.
 

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 {
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(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
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)
static const double t

References abstol_, check_error(), cvode_mem_, DBUG(), BaseLib::ConfigTree::getConfigParameterOptional(), linear_multistep_method_, nonlinear_solver_iteration_, num_equations_, OGS_FATAL, MathLib::t, 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.

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_, and MathLib::t.

◆ 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_, MathLib::t, 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(), setTolerance(), 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(), setTolerance(), and setTolerance().

◆ reltol_

realtype MathLib::ODE::CVodeSolverImpl::reltol_
private

Relative tolerance.

Definition at line 113 of file CVodeSolver.cpp.

Referenced by preSolve(), setTolerance(), 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: