Cantera 2.6.0
CVodesIntegrator.cpp
Go to the documentation of this file.
1//! @file CVodesIntegrator.cpp
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
8
9#include <iostream>
10using namespace std;
11
12#include "sundials/sundials_types.h"
13#include "sundials/sundials_math.h"
14#include "sundials/sundials_nvector.h"
15#include "nvector/nvector_serial.h"
16#include "cvodes/cvodes.h"
17#if CT_SUNDIALS_VERSION >= 30
18 #if CT_SUNDIALS_USE_LAPACK
19 #include "sunlinsol/sunlinsol_lapackdense.h"
20 #include "sunlinsol/sunlinsol_lapackband.h"
21 #else
22 #include "sunlinsol/sunlinsol_dense.h"
23 #include "sunlinsol/sunlinsol_band.h"
24 #endif
25 #include "sunlinsol/sunlinsol_spgmr.h"
26 #include "cvodes/cvodes_direct.h"
27 #include "cvodes/cvodes_diag.h"
28 #include "cvodes/cvodes_spils.h"
29#else
30 #if CT_SUNDIALS_USE_LAPACK
31 #include "cvodes/cvodes_lapack.h"
32 #else
33 #include "cvodes/cvodes_dense.h"
34 #include "cvodes/cvodes_band.h"
35 #endif
36 #include "cvodes/cvodes_diag.h"
37 #include "cvodes/cvodes_spgmr.h"
38#endif
39
40#define CV_SS 1
41#define CV_SV 2
42
43#if CT_SUNDIALS_VERSION < 25
44typedef int sd_size_t;
45#else
46typedef long int sd_size_t;
47#endif
48
49namespace {
50
51N_Vector newNVector(size_t N, Cantera::SundialsContext& context)
52{
53#if CT_SUNDIALS_VERSION >= 60
54 return N_VNew_Serial(static_cast<sd_size_t>(N), context.get());
55#else
56 return N_VNew_Serial(static_cast<sd_size_t>(N));
57#endif
58}
59
60} // end anonymous namespace
61
62namespace Cantera
63{
64
65extern "C" {
66 /**
67 * Function called by cvodes to evaluate ydot given y. The CVODE integrator
68 * allows passing in a void* pointer to access external data. This pointer
69 * is cast to a pointer to a instance of class FuncEval. The equations to be
70 * integrated should be specified by deriving a class from FuncEval that
71 * evaluates the desired equations.
72 * @ingroup odeGroup
73 */
74 static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot, void* f_data)
75 {
76 FuncEval* f = (FuncEval*) f_data;
77 return f->eval_nothrow(t, NV_DATA_S(y), NV_DATA_S(ydot));
78 }
79
80 //! Function called by CVodes when an error is encountered instead of
81 //! writing to stdout. Here, save the error message provided by CVodes so
82 //! that it can be included in the subsequently raised CanteraError.
83 static void cvodes_err(int error_code, const char* module,
84 const char* function, char* msg, void* eh_data)
85 {
86 CVodesIntegrator* integrator = (CVodesIntegrator*) eh_data;
87 integrator->m_error_message = msg;
88 integrator->m_error_message += "\n";
89 }
90}
91
93 m_neq(0),
94 m_cvode_mem(0),
95 m_linsol(0),
96 m_linsol_matrix(0),
97 m_func(0),
98 m_t0(0.0),
99 m_y(0),
100 m_abstol(0),
101 m_dky(0),
102 m_type(DENSE+NOJAC),
103 m_itol(CV_SS),
104 m_method(CV_BDF),
105 m_maxord(0),
106 m_reltol(1.e-9),
107 m_abstols(1.e-15),
108 m_reltolsens(1.0e-5),
109 m_abstolsens(1.0e-4),
110 m_nabs(0),
111 m_hmax(0.0),
112 m_hmin(0.0),
113 m_maxsteps(20000),
114 m_maxErrTestFails(0),
115 m_yS(nullptr),
116 m_np(0),
117 m_mupper(0), m_mlower(0),
118 m_sens_ok(false)
119{
120}
121
122CVodesIntegrator::~CVodesIntegrator()
123{
124 if (m_cvode_mem) {
125 if (m_np > 0) {
126 CVodeSensFree(m_cvode_mem);
127 }
128 CVodeFree(&m_cvode_mem);
129 }
130
131 #if CT_SUNDIALS_VERSION >= 30
132 SUNLinSolFree((SUNLinearSolver) m_linsol);
133 SUNMatDestroy((SUNMatrix) m_linsol_matrix);
134 #endif
135
136 if (m_y) {
137 N_VDestroy_Serial(m_y);
138 }
139 if (m_abstol) {
140 N_VDestroy_Serial(m_abstol);
141 }
142 if (m_dky) {
143 N_VDestroy_Serial(m_dky);
144 }
145 if (m_yS) {
146 #if CT_SUNDIALS_VERSION >= 60
147 N_VDestroyVectorArray(m_yS, static_cast<sd_size_t>(m_np));
148 #else
149 N_VDestroyVectorArray_Serial(m_yS, static_cast<sd_size_t>(m_np));
150 #endif
151 }
152}
153
154
156{
157 return NV_Ith_S(m_y, k);
158}
159
161{
162 return NV_DATA_S(m_y);
163}
164
165void CVodesIntegrator::setTolerances(double reltol, size_t n, double* abstol)
166{
167 m_itol = CV_SV;
168 m_nabs = n;
169 if (n != m_neq) {
170 if (m_abstol) {
171 N_VDestroy_Serial(m_abstol);
172 }
173 m_abstol = newNVector(n, m_sundials_ctx);
174 }
175 for (size_t i=0; i<n; i++) {
176 NV_Ith_S(m_abstol, i) = abstol[i];
177 }
178 m_reltol = reltol;
179}
180
181void CVodesIntegrator::setTolerances(double reltol, double abstol)
182{
183 m_itol = CV_SS;
184 m_reltol = reltol;
185 m_abstols = abstol;
186}
187
188void CVodesIntegrator::setSensitivityTolerances(double reltol, double abstol)
189{
190 m_reltolsens = reltol;
191 m_abstolsens = abstol;
192}
193
195{
196 m_type = probtype;
197}
198
200{
201 if (t == BDF_Method) {
202 m_method = CV_BDF;
203 } else if (t == Adams_Method) {
204 m_method = CV_ADAMS;
205 } else {
206 throw CanteraError("CVodesIntegrator::setMethod", "unknown method");
207 }
208}
209
211{
212 m_hmax = hmax;
213 if (m_cvode_mem) {
214 CVodeSetMaxStep(m_cvode_mem, hmax);
215 }
216}
217
219{
220 m_hmin = hmin;
221 if (m_cvode_mem) {
222 CVodeSetMinStep(m_cvode_mem, hmin);
223 }
224}
225
227{
228 m_maxsteps = nmax;
229 if (m_cvode_mem) {
230 CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
231 }
232}
233
235{
236 return m_maxsteps;
237}
238
240{
241 m_maxErrTestFails = n;
242 if (m_cvode_mem) {
243 CVodeSetMaxErrTestFails(m_cvode_mem, n);
244 }
245}
246
247void CVodesIntegrator::sensInit(double t0, FuncEval& func)
248{
249 m_np = func.nparams();
250 m_sens_ok = false;
251
252 N_Vector y = newNVector(func.neq(), m_sundials_ctx);
253 #if CT_SUNDIALS_VERSION >= 60
254 m_yS = N_VCloneVectorArray(static_cast<sd_size_t>(m_np), y);
255 #else
256 m_yS = N_VCloneVectorArray_Serial(static_cast<sd_size_t>(m_np), y);
257 #endif
258 for (size_t n = 0; n < m_np; n++) {
259 N_VConst(0.0, m_yS[n]);
260 }
261 N_VDestroy_Serial(y);
262
263 int flag = CVodeSensInit(m_cvode_mem, static_cast<sd_size_t>(m_np),
264 CV_STAGGERED, CVSensRhsFn(0), m_yS);
265
266 if (flag != CV_SUCCESS) {
267 throw CanteraError("CVodesIntegrator::sensInit", "Error in CVodeSensInit");
268 }
269 vector_fp atol(m_np);
270 for (size_t n = 0; n < m_np; n++) {
271 // This scaling factor is tuned so that reaction and species enthalpy
272 // sensitivities can be computed simultaneously with the same abstol.
273 atol[n] = m_abstolsens / func.m_paramScales[n];
274 }
275 flag = CVodeSensSStolerances(m_cvode_mem, m_reltolsens, atol.data());
276}
277
279{
280 m_neq = func.neq();
281 m_t0 = t0;
282 m_time = t0;
283 m_func = &func;
284 func.clearErrors();
285
286 if (m_y) {
287 N_VDestroy_Serial(m_y); // free solution vector if already allocated
288 }
289 m_y = newNVector(m_neq, m_sundials_ctx); // allocate solution vector
290 N_VConst(0.0, m_y);
291 if (m_dky) {
292 N_VDestroy_Serial(m_dky); // free derivative vector if already allocated
293 }
294 m_dky = newNVector(m_neq, m_sundials_ctx); // allocate derivative vector
295 N_VConst(0.0, m_dky);
296 // check abs tolerance array size
297 if (m_itol == CV_SV && m_nabs < m_neq) {
298 throw CanteraError("CVodesIntegrator::initialize",
299 "not enough absolute tolerance values specified.");
300 }
301
302 func.getState(NV_DATA_S(m_y));
303
304 if (m_cvode_mem) {
305 CVodeFree(&m_cvode_mem);
306 }
307
308 //! Specify the method and the iteration type. Cantera Defaults:
309 //! CV_BDF - Use BDF methods
310 //! CV_NEWTON - use Newton's method
311 #if CT_SUNDIALS_VERSION < 40
312 m_cvode_mem = CVodeCreate(m_method, CV_NEWTON);
313 #elif CT_SUNDIALS_VERSION < 60
314 m_cvode_mem = CVodeCreate(m_method);
315 #else
316 m_cvode_mem = CVodeCreate(m_method, m_sundials_ctx.get());
317 #endif
318 if (!m_cvode_mem) {
319 throw CanteraError("CVodesIntegrator::initialize",
320 "CVodeCreate failed.");
321 }
322
323 int flag = CVodeInit(m_cvode_mem, cvodes_rhs, m_t0, m_y);
324 if (flag != CV_SUCCESS) {
325 if (flag == CV_MEM_FAIL) {
326 throw CanteraError("CVodesIntegrator::initialize",
327 "Memory allocation failed.");
328 } else if (flag == CV_ILL_INPUT) {
329 throw CanteraError("CVodesIntegrator::initialize",
330 "Illegal value for CVodeInit input argument.");
331 } else {
332 throw CanteraError("CVodesIntegrator::initialize",
333 "CVodeInit failed.");
334 }
335 }
336 CVodeSetErrHandlerFn(m_cvode_mem, &cvodes_err, this);
337
338 if (m_itol == CV_SV) {
339 flag = CVodeSVtolerances(m_cvode_mem, m_reltol, m_abstol);
340 } else {
341 flag = CVodeSStolerances(m_cvode_mem, m_reltol, m_abstols);
342 }
343 if (flag != CV_SUCCESS) {
344 if (flag == CV_MEM_FAIL) {
345 throw CanteraError("CVodesIntegrator::initialize",
346 "Memory allocation failed.");
347 } else if (flag == CV_ILL_INPUT) {
348 throw CanteraError("CVodesIntegrator::initialize",
349 "Illegal value for CVodeInit input argument.");
350 } else {
351 throw CanteraError("CVodesIntegrator::initialize",
352 "CVodeInit failed.");
353 }
354 }
355
356 flag = CVodeSetUserData(m_cvode_mem, &func);
357 if (flag != CV_SUCCESS) {
358 throw CanteraError("CVodesIntegrator::initialize",
359 "CVodeSetUserData failed.");
360 }
361 if (func.nparams() > 0) {
362 sensInit(t0, func);
363 flag = CVodeSetSensParams(m_cvode_mem, func.m_sens_params.data(),
364 func.m_paramScales.data(), NULL);
365 if (flag != CV_SUCCESS) {
366 throw CanteraError("CVodesIntegrator::initialize",
367 "CVodeSetSensParams failed.");
368 }
369 }
370 applyOptions();
371}
372
373void CVodesIntegrator::reinitialize(double t0, FuncEval& func)
374{
375 m_t0 = t0;
376 m_time = t0;
377 func.getState(NV_DATA_S(m_y));
378 m_func = &func;
379 func.clearErrors();
380
381 int result = CVodeReInit(m_cvode_mem, m_t0, m_y);
382 if (result != CV_SUCCESS) {
383 throw CanteraError("CVodesIntegrator::reinitialize",
384 "CVodeReInit failed. result = {}", result);
385 }
386 applyOptions();
387}
388
390{
391 if (m_type == DENSE + NOJAC) {
392 sd_size_t N = static_cast<sd_size_t>(m_neq);
393 #if CT_SUNDIALS_VERSION >= 30
394 SUNLinSolFree((SUNLinearSolver) m_linsol);
395 SUNMatDestroy((SUNMatrix) m_linsol_matrix);
396 #if CT_SUNDIALS_VERSION >= 60
397 m_linsol_matrix = SUNDenseMatrix(N, N, m_sundials_ctx.get());
398 #else
399 m_linsol_matrix = SUNDenseMatrix(N, N);
400 #endif
401 if (m_linsol_matrix == nullptr) {
402 throw CanteraError("CVodesIntegrator::applyOptions",
403 "Unable to create SUNDenseMatrix of size {0} x {0}", N);
404 }
405 int flag;
406 #if CT_SUNDIALS_VERSION >= 60
407 #if CT_SUNDIALS_USE_LAPACK
408 m_linsol = SUNLinSol_LapackDense(m_y, (SUNMatrix) m_linsol_matrix,
409 m_sundials_ctx.get());
410 #else
411 m_linsol = SUNLinSol_Dense(m_y, (SUNMatrix) m_linsol_matrix,
412 m_sundials_ctx.get());
413 #endif
414 flag = CVodeSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol,
415 (SUNMatrix) m_linsol_matrix);
416 #else
417 #if CT_SUNDIALS_USE_LAPACK
418 m_linsol = SUNLapackDense(m_y, (SUNMatrix) m_linsol_matrix);
419 #else
420 m_linsol = SUNDenseLinearSolver(m_y, (SUNMatrix) m_linsol_matrix);
421 #endif
422 flag = CVDlsSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol,
423 (SUNMatrix) m_linsol_matrix);
424 #endif
425 if (m_linsol == nullptr) {
426 throw CanteraError("CVodesIntegrator::applyOptions",
427 "Error creating Sundials dense linear solver object");
428 } else if (flag != CV_SUCCESS) {
429 throw CanteraError("CVodesIntegrator::applyOptions",
430 "Error connecting linear solver to CVODES. "
431 "Sundials error code: {}", flag);
432 }
433 #else
434 #if CT_SUNDIALS_USE_LAPACK
435 CVLapackDense(m_cvode_mem, N);
436 #else
437 CVDense(m_cvode_mem, N);
438 #endif
439
440 #endif
441 } else if (m_type == DIAG) {
442 CVDiag(m_cvode_mem);
443 } else if (m_type == GMRES) {
444 #if CT_SUNDIALS_VERSION >= 30
445 #if CT_SUNDIALS_VERSION >= 60
446 m_linsol = SUNLinSol_SPGMR(m_y, PREC_NONE, 0, m_sundials_ctx.get());
447 CVodeSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol, nullptr);
448 #elif CT_SUNDIALS_VERSION >= 40
449 m_linsol = SUNLinSol_SPGMR(m_y, PREC_NONE, 0);
450 CVSpilsSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol);
451 # else
452 m_linsol = SUNSPGMR(m_y, PREC_NONE, 0);
453 CVSpilsSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol);
454 #endif
455
456 #else
457 CVSpgmr(m_cvode_mem, PREC_NONE, 0);
458 #endif
459 } else if (m_type == BAND + NOJAC) {
460 sd_size_t N = static_cast<sd_size_t>(m_neq);
461 long int nu = m_mupper;
462 long int nl = m_mlower;
463 #if CT_SUNDIALS_VERSION >= 30
464 SUNLinSolFree((SUNLinearSolver) m_linsol);
465 SUNMatDestroy((SUNMatrix) m_linsol_matrix);
466 #if CT_SUNDIALS_VERSION >= 60
467 m_linsol_matrix = SUNBandMatrix(N, nu, nl, m_sundials_ctx.get());
468 #elif CT_SUNDIALS_VERSION >= 40
469 m_linsol_matrix = SUNBandMatrix(N, nu, nl);
470 #else
471 m_linsol_matrix = SUNBandMatrix(N, nu, nl, nu+nl);
472 #endif
473 if (m_linsol_matrix == nullptr) {
474 throw CanteraError("CVodesIntegrator::applyOptions",
475 "Unable to create SUNBandMatrix of size {} with bandwidths "
476 "{} and {}", N, nu, nl);
477 }
478 #if CT_SUNDIALS_VERSION >= 60
479 #if CT_SUNDIALS_USE_LAPACK
480 m_linsol = SUNLinSol_LapackBand(m_y, (SUNMatrix) m_linsol_matrix,
481 m_sundials_ctx.get());
482 #else
483 m_linsol = SUNLinSol_Band(m_y, (SUNMatrix) m_linsol_matrix,
484 m_sundials_ctx.get());
485 #endif
486 CVodeSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol,
487 (SUNMatrix) m_linsol_matrix);
488 #else
489 #if CT_SUNDIALS_USE_LAPACK
490 m_linsol = SUNLapackBand(m_y, (SUNMatrix) m_linsol_matrix);
491 #else
492 m_linsol = SUNBandLinearSolver(m_y, (SUNMatrix) m_linsol_matrix);
493 #endif
494 CVDlsSetLinearSolver(m_cvode_mem, (SUNLinearSolver) m_linsol,
495 (SUNMatrix) m_linsol_matrix);
496 #endif
497 #else
498 #if CT_SUNDIALS_USE_LAPACK
499 CVLapackBand(m_cvode_mem, N, nu, nl);
500 #else
501 CVBand(m_cvode_mem, N, nu, nl);
502 #endif
503 #endif
504 } else {
505 throw CanteraError("CVodesIntegrator::applyOptions",
506 "unsupported option");
507 }
508
509 if (m_maxord > 0) {
510 CVodeSetMaxOrd(m_cvode_mem, m_maxord);
511 }
512 if (m_maxsteps > 0) {
513 CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
514 }
515 if (m_hmax > 0) {
516 CVodeSetMaxStep(m_cvode_mem, m_hmax);
517 }
518 if (m_hmin > 0) {
519 CVodeSetMinStep(m_cvode_mem, m_hmin);
520 }
521 if (m_maxErrTestFails > 0) {
522 CVodeSetMaxErrTestFails(m_cvode_mem, m_maxErrTestFails);
523 }
524}
525
527{
528 if (tout == m_time) {
529 return;
530 }
531 int flag = CVode(m_cvode_mem, tout, m_y, &m_time, CV_NORMAL);
532 if (flag != CV_SUCCESS) {
533 string f_errs = m_func->getErrors();
534 if (!f_errs.empty()) {
535 f_errs = "Exceptions caught during RHS evaluation:\n" + f_errs;
536 }
537 throw CanteraError("CVodesIntegrator::integrate",
538 "CVodes error encountered. Error code: {}\n{}\n"
539 "{}"
540 "Components with largest weighted error estimates:\n{}",
541 flag, m_error_message, f_errs, getErrorInfo(10));
542 }
543 m_sens_ok = false;
544}
545
546double CVodesIntegrator::step(double tout)
547{
548 int flag = CVode(m_cvode_mem, tout, m_y, &m_time, CV_ONE_STEP);
549 if (flag != CV_SUCCESS) {
550 string f_errs = m_func->getErrors();
551 if (!f_errs.empty()) {
552 f_errs = "Exceptions caught during RHS evaluation:\n" + f_errs;
553 }
554 throw CanteraError("CVodesIntegrator::step",
555 "CVodes error encountered. Error code: {}\n{}\n"
556 "{}"
557 "Components with largest weighted error estimates:\n{}",
558 flag, f_errs, m_error_message, getErrorInfo(10));
559
560 }
561 m_sens_ok = false;
562 return m_time;
563}
564
565double* CVodesIntegrator::derivative(double tout, int n)
566{
567 int flag = CVodeGetDky(m_cvode_mem, tout, n, m_dky);
568 if (flag != CV_SUCCESS) {
569 string f_errs = m_func->getErrors();
570 if (!f_errs.empty()) {
571 f_errs = "Exceptions caught evaluating derivative:\n" + f_errs;
572 }
573 throw CanteraError("CVodesIntegrator::derivative",
574 "CVodes error encountered. Error code: {}\n{}\n"
575 "{}",
576 flag, m_error_message, f_errs);
577 }
578 return NV_DATA_S(m_dky);
579}
580
582{
583 int ord;
584 CVodeGetLastOrder(m_cvode_mem, &ord);
585 return ord;
586}
587
589{
590 long int ne;
591 CVodeGetNumRhsEvals(m_cvode_mem, &ne);
592 return ne;
593}
594
595double CVodesIntegrator::sensitivity(size_t k, size_t p)
596{
597 if (m_time == m_t0) {
598 // calls to CVodeGetSens are only allowed after a successful time step.
599 return 0.0;
600 }
601 if (!m_sens_ok && m_np) {
602 int flag = CVodeGetSens(m_cvode_mem, &m_time, m_yS);
603 if (flag != CV_SUCCESS) {
604 throw CanteraError("CVodesIntegrator::sensitivity",
605 "CVodeGetSens failed. Error code: {}", flag);
606 }
607 m_sens_ok = true;
608 }
609
610 if (k >= m_neq) {
611 throw CanteraError("CVodesIntegrator::sensitivity",
612 "sensitivity: k out of range ({})", k);
613 }
614 if (p >= m_np) {
615 throw CanteraError("CVodesIntegrator::sensitivity",
616 "sensitivity: p out of range ({})", p);
617 }
618 return NV_Ith_S(m_yS[p],k);
619}
620
622{
623 N_Vector errs = newNVector(m_neq, m_sundials_ctx);
624 N_Vector errw = newNVector(m_neq, m_sundials_ctx);
625 CVodeGetErrWeights(m_cvode_mem, errw);
626 CVodeGetEstLocalErrors(m_cvode_mem, errs);
627
628 vector<tuple<double, double, size_t> > weightedErrors;
629 for (size_t i=0; i<m_neq; i++) {
630 double err = NV_Ith_S(errs, i) * NV_Ith_S(errw, i);
631 weightedErrors.emplace_back(-abs(err), err, i);
632 }
633 N_VDestroy(errs);
634 N_VDestroy(errw);
635
636 N = std::min(N, static_cast<int>(m_neq));
637 sort(weightedErrors.begin(), weightedErrors.end());
638 fmt::memory_buffer s;
639 for (int i=0; i<N; i++) {
640 fmt_append(s, "{}: {}\n",
641 get<2>(weightedErrors[i]), get<1>(weightedErrors[i]));
642 }
643 return to_string(s);
644}
645
646}
Wrapper class for 'cvodes' integrator from LLNL.
virtual int nEvals() const
The number of function evaluations.
virtual int lastOrder() const
Order used during the last solution step.
virtual void setMinStepSize(double hmin)
Set the minimum step size.
void * m_linsol
Sundials linear solver object.
std::string m_error_message
Error message information provide by CVodes.
double m_time
The current integrator time.
bool m_sens_ok
Indicates whether the sensitivities stored in m_yS have been updated for at the current integrator ti...
virtual void initialize(double t0, FuncEval &func)
Initialize the integrator for a new problem.
SundialsContext m_sundials_ctx
SUNContext object for Sundials>=6.0.
virtual void integrate(double tout)
Integrate the system of equations.
virtual void setMaxSteps(int nmax)
Set the maximum number of time-steps the integrator can take before reaching the next output time.
virtual doublereal step(double tout)
Integrate the system of equations.
virtual void setSensitivityTolerances(double reltol, double abstol)
Set the sensitivity error tolerances.
virtual double * solution()
The current value of the solution of the system of equations.
virtual void setTolerances(double reltol, size_t n, double *abstol)
Set error tolerances.
virtual int maxSteps()
Returns the maximum number of time-steps the integrator can take before reaching the next output time...
virtual void setMaxStepSize(double hmax)
Set the maximum step size.
void applyOptions()
Applies user-specified options to the underlying CVODES solver.
virtual double * derivative(double tout, int n)
n-th derivative of the output function at time tout.
virtual void setProblemType(int probtype)
Set the problem type.
virtual void setMethod(MethodType t)
Set the solution method.
void * m_linsol_matrix
matrix used by Sundials
virtual void setMaxErrTestFails(int n)
Set the maximum permissible number of error test failures.
virtual std::string getErrorInfo(int N)
Returns a string listing the weighted error estimates associated with each solution component.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Virtual base class for ODE right-hand-side function evaluators.
Definition: FuncEval.h:27
virtual size_t nparams()
Number of sensitivity parameters.
Definition: FuncEval.h:61
vector_fp m_sens_params
Values for the problem parameters for which sensitivities are computed This is the array which is per...
Definition: FuncEval.h:81
void clearErrors()
Clear any previously-stored suppressed errors.
Definition: FuncEval.h:79
virtual size_t neq()=0
Number of equations.
std::string getErrors() const
Return a string containing the text of any suppressed errors.
Definition: FuncEval.cpp:45
int eval_nothrow(double t, double *y, double *ydot)
Evaluate the right-hand side using return code to indicate status.
Definition: FuncEval.cpp:12
vector_fp m_paramScales
Scaling factors for each sensitivity parameter.
Definition: FuncEval.h:89
virtual void getState(double *y)
Fill in the vector y with the current state of the system.
Definition: FuncEval.h:53
A wrapper for managing a SUNContext object, need for Sundials >= 6.0.
static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot, void *f_data)
Function called by cvodes to evaluate ydot given y.
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
MethodType
Specifies the method used to integrate the system of equations.
Definition: Integrator.h:32
@ BDF_Method
Backward Differentiation.
Definition: Integrator.h:33
@ Adams_Method
Adams.
Definition: Integrator.h:34
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:184
static void cvodes_err(int error_code, const char *module, const char *function, char *msg, void *eh_data)
Function called by CVodes when an error is encountered instead of writing to stdout.
Contains declarations for string manipulation functions within Cantera.