Cantera 2.6.0
OneDim.h
Go to the documentation of this file.
1/**
2 * @file OneDim.h
3 */
4
5// This file is part of Cantera. See License.txt in the top-level directory or
6// at https://cantera.org/license.txt for license and copyright information.
7
8#ifndef CT_ONEDIM_H
9#define CT_ONEDIM_H
10
11#include "Domain1D.h"
12#include "MultiJac.h"
13
14namespace Cantera
15{
16
17class Func1;
18class MultiNewton;
19class AnyMap;
20
21/**
22 * Container class for multiple-domain 1D problems. Each domain is
23 * represented by an instance of Domain1D.
24 * @ingroup onedim
25 */
26class OneDim
27{
28public:
29 OneDim();
30
31 //! Construct a OneDim container for the domains in the list *domains*.
32 OneDim(std::vector<Domain1D*> domains);
33 virtual ~OneDim();
34 OneDim(const OneDim&) = delete;
35 OneDim& operator=(const OneDim&) = delete;
36
37 /// Add a domain. Domains are added left-to-right.
38 void addDomain(Domain1D* d);
39
40 //! Return a reference to the Jacobian evaluator.
42
43 /// Return a reference to the Newton iterator.
45
46 /**
47 * Solve F(x) = 0, where F(x) is the multi-domain residual function.
48 * @param x0 Starting estimate of solution.
49 * @param x1 Final solution satisfying F(x1) = 0.
50 * @param loglevel Controls amount of diagnostic output.
51 */
52 int solve(doublereal* x0, doublereal* x1, int loglevel);
53
54 /// Number of domains.
55 size_t nDomains() const {
56 return m_dom.size();
57 }
58
59 /// Return a reference to domain i.
60 Domain1D& domain(size_t i) const {
61 return *m_dom[i];
62 }
63
64 size_t domainIndex(const std::string& name);
65
66 //! Check that the specified domain index is in range.
67 //! Throws an exception if n is greater than nDomains()-1
68 void checkDomainIndex(size_t n) const {
69 if (n >= m_dom.size()) {
70 throw IndexError("OneDim::checkDomainIndex", "domains", n,
71 m_dom.size()-1);
72 }
73 }
74
75 //! Check that an array size is at least nDomains().
76 //! Throws an exception if nn is less than nDomains(). Used before calls
77 //! which take an array pointer.
78 void checkDomainArraySize(size_t nn) const {
79 if (m_dom.size() > nn) {
80 throw ArraySizeError("OneDim::checkDomainArraySize", nn,
81 m_dom.size());
82 }
83 }
84
85 /// The index of the start of domain i in the solution vector.
86 size_t start(size_t i) const {
87 if (m_dom[i]->nComponents()) {
88 return m_dom[i]->loc();
89 } else {
90 // Special case for domains with no solution components to avoid
91 // spurious out-of-bounds memory access
92 return 0;
93 }
94 }
95
96 /// Total solution vector length;
97 size_t size() const {
98 return m_size;
99 }
100
101 /// Pointer to left-most domain (first added).
103 return m_dom[0];
104 }
105
106 /// Pointer to right-most domain (last added).
108 return m_dom.back();
109 }
110
111 /// Number of solution components at global point jg.
112 size_t nVars(size_t jg) {
113 return m_nvars[jg];
114 }
115
116 //! Location in the solution vector of the first component of global point
117 //! jg.
118 size_t loc(size_t jg) {
119 return m_loc[jg];
120 }
121
122 //! Return the domain, local point index, and component name for the i-th
123 //! component of the global solution vector
124 std::tuple<std::string, size_t, std::string> component(size_t i);
125
126 /// Jacobian bandwidth.
127 size_t bandwidth() const {
128 return m_bw;
129 }
130
131 /*!
132 * Initialize all domains. On the first call, this methods calls the init
133 * method of each domain, proceeding from left to right. Subsequent calls
134 * do nothing.
135 */
136 void init();
137
138 /// Total number of points.
139 size_t points() {
140 return m_pts;
141 }
142
143 /**
144 * Steady-state max norm (infinity norm) of the residual evaluated using
145 * solution x. On return, array r contains the steady-state residual
146 * values. Used only for diagnostic output.
147 */
148 doublereal ssnorm(doublereal* x, doublereal* r);
149
150 /// Reciprocal of the time step.
151 doublereal rdt() const {
152 return m_rdt;
153 }
154
155 //! Prepare for time stepping beginning with solution *x* and timestep *dt*.
156 void initTimeInteg(doublereal dt, doublereal* x);
157
158 /// True if transient mode.
159 bool transient() const {
160 return (m_rdt != 0.0);
161 }
162
163 /// True if steady mode.
164 bool steady() const {
165 return (m_rdt == 0.0);
166 }
167
168 /*!
169 * Prepare to solve the steady-state problem. After invoking this method,
170 * subsequent calls to solve() will solve the steady-state problem. Sets
171 * the reciprocal of the time step to zero, and, if it was previously non-
172 * zero, signals that a new Jacobian will be needed.
173 */
174 void setSteadyMode();
175
176 /**
177 * Evaluate the multi-domain residual function
178 *
179 * @param j if j != npos, only evaluate residual for points j-1, j,
180 * and j + 1; otherwise, evaluate at all grid points.
181 * @param x solution vector
182 * @param r on return, contains the residual vector
183 * @param rdt Reciprocal of the time step. if omitted, then
184 * the default value is used.
185 * @param count Set to zero to omit this call from the statistics
186 */
187 void eval(size_t j, double* x, double* r, doublereal rdt=-1.0,
188 int count = 1);
189
190 //! Return a pointer to the domain global point *i* belongs to.
191 /*!
192 * The domains are scanned right-to-left, and the first one with starting
193 * location less or equal to i is returned.
194 */
195 Domain1D* pointDomain(size_t i);
196
197 //! Call after one or more grids has changed size, for example after being refined.
198 virtual void resize();
199
200 vector_int& transientMask() {
201 return m_mask;
202 }
203
204 /*!
205 * Take time steps using Backward Euler.
206 *
207 * @param nsteps number of steps
208 * @param dt initial step size
209 * @param x current solution vector
210 * @param r solution vector after time stepping
211 * @param loglevel controls amount of printed diagnostics
212 * @returns size of last timestep taken
213 */
214 double timeStep(int nsteps, double dt, double* x,
215 double* r, int loglevel);
216
217 void resetBadValues(double* x);
218
219 //! Write statistics about the number of iterations and Jacobians at each
220 //! grid level
221 /*!
222 * @param printTime Boolean that indicates whether time should be printed
223 * out The default is true. It's turned off for test
224 * problems where we don't want to print any times
225 */
226 void writeStats(int printTime = 1);
227
228 void save(const std::string& fname, std::string id,
229 const std::string& desc, doublereal* sol, int loglevel);
230
231 AnyMap serialize(const double* soln) const;
232
233 // options
234 void setMinTimeStep(doublereal tmin) {
235 m_tmin = tmin;
236 }
237 void setMaxTimeStep(doublereal tmax) {
238 m_tmax = tmax;
239 }
240 void setTimeStepFactor(doublereal tfactor) {
241 m_tfactor = tfactor;
242 }
243
244 //! Set the maximum number of timeteps allowed before successful
245 //! steady-state solve
246 void setMaxTimeStepCount(int nmax) {
247 m_nsteps_max = nmax;
248 }
249
250 //! Return the maximum number of timeteps allowed before successful
251 //! steady-state solve
252 int maxTimeStepCount() const {
253 return m_nsteps_max;
254 }
255
256 void setJacAge(int ss_age, int ts_age=-1);
257
258 /**
259 * Save statistics on function and Jacobian evaluation, and reset the
260 * counters. Statistics are saved only if the number of Jacobian
261 * evaluations is greater than zero. The statistics saved are:
262 *
263 * - number of grid points
264 * - number of Jacobian evaluations
265 * - CPU time spent evaluating Jacobians
266 * - number of non-Jacobian function evaluations
267 * - CPU time spent evaluating functions
268 * - number of time steps
269 */
270 void saveStats();
271
272 //! Clear saved statistics
273 void clearStats();
274
275 //! Return total grid size in each call to solve()
276 const std::vector<size_t>& gridSizeStats() {
277 saveStats();
278 return m_gridpts;
279 }
280
281 //! Return CPU time spent evaluating Jacobians in each call to solve()
283 saveStats();
284 return m_jacElapsed;
285 }
286
287 //! Return CPU time spent on non-Jacobian function evaluations in each call
288 //! to solve()
290 saveStats();
291 return m_funcElapsed;
292 }
293
294 //! Return number of Jacobian evaluations made in each call to solve()
296 saveStats();
297 return m_jacEvals;
298 }
299
300 //! Return number of non-Jacobian function evaluations made in each call to
301 //! solve()
303 saveStats();
304 return m_funcEvals;
305 }
306
307 //! Return number of time steps taken in each call to solve()
309 saveStats();
310 return m_timeSteps;
311 }
312
313 //! Set a function that will be called every time #eval is called.
314 //! Can be used to provide keyboard interrupt support in the high-level
315 //! language interfaces.
316 void setInterrupt(Func1* interrupt) {
317 m_interrupt = interrupt;
318 }
319
320 //! Set a function that will be called after each successful timestep. The
321 //! function will be called with the size of the timestep as the argument.
322 //! Intended to be used for observing solver progress for debugging
323 //! purposes.
324 void setTimeStepCallback(Func1* callback) {
325 m_time_step_callback = callback;
326 }
327
328protected:
329 void evalSSJacobian(doublereal* x, doublereal* xnew);
330
331 doublereal m_tmin; //!< minimum timestep size
332 doublereal m_tmax; //!< maximum timestep size
333
334 //! factor time step is multiplied by if time stepping fails ( < 1 )
335 doublereal m_tfactor;
336
337 std::unique_ptr<MultiJac> m_jac; //!< Jacobian evaluator
338 std::unique_ptr<MultiNewton> m_newt; //!< Newton iterator
339 doublereal m_rdt; //!< reciprocal of time step
340 bool m_jac_ok; //!< if true, Jacobian is current
341
342 size_t m_bw; //!< Jacobian bandwidth
343 size_t m_size; //!< solution vector size
344
345 std::vector<Domain1D*> m_dom, m_connect, m_bulk;
346
347 bool m_init;
348 std::vector<size_t> m_nvars;
349 std::vector<size_t> m_loc;
350 vector_int m_mask;
351 size_t m_pts;
352
353 // options
354 int m_ss_jac_age, m_ts_jac_age;
355
356 //! Function called at the start of every call to #eval.
358
359 //! User-supplied function called after each successful timestep.
361
362 //! Number of time steps taken in the current call to solve()
364
365 //! Maximum number of timesteps allowed per call to solve()
367
368private:
369 // statistics
370 int m_nevals;
371 doublereal m_evaltime;
372 std::vector<size_t> m_gridpts;
373 vector_int m_jacEvals;
374 vector_fp m_jacElapsed;
375 vector_int m_funcEvals;
376 vector_fp m_funcElapsed;
377
378 //! Number of time steps taken in each call to solve() (for example, for each
379 //! successive grid refinement)
381};
382
383}
384
385#endif
Array size error.
Definition: ctexceptions.h:128
Base class for one-dimensional domains.
Definition: Domain1D.h:38
Base class for 'functor' classes that evaluate a function of one variable.
Definition: Func1.h:44
An array index is out of range.
Definition: ctexceptions.h:158
Class MultiJac evaluates the Jacobian of a system of equations defined by a residual function supplie...
Definition: MultiJac.h:23
Newton iterator for multi-domain, one-dimensional problems.
Definition: MultiNewton.h:20
Container class for multiple-domain 1D problems.
Definition: OneDim.h:27
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
Definition: OneDim.h:86
int m_nsteps
Number of time steps taken in the current call to solve()
Definition: OneDim.h:363
void checkDomainIndex(size_t n) const
Check that the specified domain index is in range.
Definition: OneDim.h:68
vector_int m_timeSteps
Number of time steps taken in each call to solve() (for example, for each successive grid refinement)
Definition: OneDim.h:380
doublereal m_rdt
reciprocal of time step
Definition: OneDim.h:339
size_t m_size
solution vector size
Definition: OneDim.h:343
int m_nsteps_max
Maximum number of timesteps allowed per call to solve()
Definition: OneDim.h:366
virtual void resize()
Call after one or more grids has changed size, for example after being refined.
Definition: OneDim.cpp:169
const vector_int & evalCountStats()
Return number of non-Jacobian function evaluations made in each call to solve()
Definition: OneDim.h:302
std::unique_ptr< MultiJac > m_jac
Jacobian evaluator.
Definition: OneDim.h:337
void saveStats()
Save statistics on function and Jacobian evaluation, and reset the counters.
Definition: OneDim.cpp:138
size_t size() const
Total solution vector length;.
Definition: OneDim.h:97
doublereal ssnorm(doublereal *x, doublereal *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
Definition: OneDim.cpp:291
size_t loc(size_t jg)
Location in the solution vector of the first component of global point jg.
Definition: OneDim.h:118
size_t nDomains() const
Number of domains.
Definition: OneDim.h:55
const vector_fp & evalTimeStats()
Return CPU time spent on non-Jacobian function evaluations in each call to solve()
Definition: OneDim.h:289
Domain1D * right()
Pointer to right-most domain (last added).
Definition: OneDim.h:107
std::tuple< std::string, size_t, std::string > component(size_t i)
Return the domain, local point index, and component name for the i-th component of the global solutio...
Definition: OneDim.cpp:66
doublereal m_tmin
minimum timestep size
Definition: OneDim.h:331
const vector_int & jacobianCountStats()
Return number of Jacobian evaluations made in each call to solve()
Definition: OneDim.h:295
size_t bandwidth() const
Jacobian bandwidth.
Definition: OneDim.h:127
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
Definition: OneDim.cpp:349
void eval(size_t j, double *x, double *r, doublereal rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
Definition: OneDim.cpp:259
const vector_int & timeStepStats()
Return number of time steps taken in each call to solve()
Definition: OneDim.h:308
void setTimeStepCallback(Func1 *callback)
Set a function that will be called after each successful timestep.
Definition: OneDim.h:324
Func1 * m_interrupt
Function called at the start of every call to eval.
Definition: OneDim.h:357
void checkDomainArraySize(size_t nn) const
Check that an array size is at least nDomains().
Definition: OneDim.h:78
void setMaxTimeStepCount(int nmax)
Set the maximum number of timeteps allowed before successful steady-state solve.
Definition: OneDim.h:246
void initTimeInteg(doublereal dt, doublereal *x)
Prepare for time stepping beginning with solution x and timestep dt.
Definition: OneDim.cpp:301
size_t nVars(size_t jg)
Number of solution components at global point jg.
Definition: OneDim.h:112
std::unique_ptr< MultiNewton > m_newt
Newton iterator.
Definition: OneDim.h:338
size_t m_bw
Jacobian bandwidth.
Definition: OneDim.h:342
bool m_jac_ok
if true, Jacobian is current
Definition: OneDim.h:340
int maxTimeStepCount() const
Return the maximum number of timeteps allowed before successful steady-state solve.
Definition: OneDim.h:252
Domain1D * pointDomain(size_t i)
Return a pointer to the domain global point i belongs to.
Definition: OneDim.cpp:247
doublereal m_tmax
maximum timestep size
Definition: OneDim.h:332
void addDomain(Domain1D *d)
Add a domain. Domains are added left-to-right.
Definition: OneDim.cpp:80
size_t points()
Total number of points.
Definition: OneDim.h:139
MultiJac & jacobian()
Return a reference to the Jacobian evaluator.
Definition: OneDim.cpp:102
void writeStats(int printTime=1)
Write statistics about the number of iterations and Jacobians at each grid level.
Definition: OneDim.cpp:121
void clearStats()
Clear saved statistics.
Definition: OneDim.cpp:156
void setSteadyMode()
Definition: OneDim.cpp:320
const std::vector< size_t > & gridSizeStats()
Return total grid size in each call to solve()
Definition: OneDim.h:276
Func1 * m_time_step_callback
User-supplied function called after each successful timestep.
Definition: OneDim.h:360
doublereal m_tfactor
factor time step is multiplied by if time stepping fails ( < 1 )
Definition: OneDim.h:335
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition: OneDim.h:60
int solve(doublereal *x0, doublereal *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
Definition: OneDim.cpp:225
Domain1D * left()
Pointer to left-most domain (first added).
Definition: OneDim.h:102
bool steady() const
True if steady mode.
Definition: OneDim.h:164
const vector_fp & jacobianTimeStats()
Return CPU time spent evaluating Jacobians in each call to solve()
Definition: OneDim.h:282
MultiNewton & newton()
Return a reference to the Newton iterator.
Definition: OneDim.cpp:106
void setInterrupt(Func1 *interrupt)
Set a function that will be called every time eval is called.
Definition: OneDim.h:316
doublereal rdt() const
Reciprocal of the time step.
Definition: OneDim.h:151
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:186
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