Cantera 2.6.0
Domain1D.h
Go to the documentation of this file.
1 //! @file Domain1D.h
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
6#ifndef CT_DOMAIN1D_H
7#define CT_DOMAIN1D_H
8
10
11namespace Cantera
12{
13
14// domain types
15const int cFlowType = 50;
16const int cFreeFlow = 51;
17const int cAxisymmetricStagnationFlow = 52;
18const int cConnectorType = 100;
19const int cSurfType = 102;
20const int cInletType = 104;
21const int cSymmType = 105;
22const int cOutletType = 106;
23const int cEmptyType = 107;
24const int cOutletResType = 108;
25const int cPorousType = 109;
26
27class MultiJac;
28class OneDim;
29class Refiner;
30class AnyMap;
31class XML_Node;
32
33/**
34 * Base class for one-dimensional domains.
35 * @ingroup onedim
36 */
38{
39public:
40 /**
41 * Constructor.
42 * @param nv Number of variables at each grid point.
43 * @param points Number of grid points.
44 * @param time (unused)
45 */
46 Domain1D(size_t nv=1, size_t points=1, double time=0.0);
47
48 virtual ~Domain1D();
49 Domain1D(const Domain1D&) = delete;
50 Domain1D& operator=(const Domain1D&) = delete;
51
52 //! Domain type flag.
53 int domainType() {
54 return m_type;
55 }
56
57 //! The left-to-right location of this domain.
58 size_t domainIndex() {
59 return m_index;
60 }
61
62 //! True if the domain is a connector domain.
63 bool isConnector() {
64 return (m_type >= cConnectorType);
65 }
66
67 //! The container holding this domain.
68 const OneDim& container() const {
69 return *m_container;
70 }
71
72 //! Specify the container object for this domain, and the position of this
73 //! domain in the list.
74 void setContainer(OneDim* c, size_t index) {
75 m_container = c;
76 m_index = index;
77 }
78
79 //! Set the Jacobian bandwidth. See the discussion of method bandwidth().
80 void setBandwidth(int bw = -1) {
81 m_bw = bw;
82 }
83
84 //! Set the Jacobian bandwidth for this domain.
85 /**
86 * When class OneDim computes the bandwidth of the overall multi-domain
87 * problem (in OneDim::resize()), it calls this method for the bandwidth
88 * of each domain. If setBandwidth has not been called, then a negative
89 * bandwidth is returned, in which case OneDim assumes that this domain is
90 * dense -- that is, at each point, all components depend on the value of
91 * all other components at that point. In this case, the bandwidth is bw =
92 * 2*nComponents() - 1. However, if this domain contains some components
93 * that are uncoupled from other components at the same point, then this
94 * default bandwidth may greatly overestimate the true bandwidth, with a
95 * substantial penalty in performance. For such domains, use method
96 * setBandwidth to specify the bandwidth before passing this domain to the
97 * Sim1D or OneDim constructor.
98 */
99 size_t bandwidth() {
100 return m_bw;
101 }
102
103 /*!
104 * Initialize. This method is called by OneDim::init() for each domain once
105 * at the beginning of a simulation. Base class method does nothing, but may
106 * be overloaded.
107 */
108 virtual void init() { }
109
110 virtual void setInitialState(doublereal* xlocal = 0) {}
111 virtual void setState(size_t point, const doublereal* state, doublereal* x) {}
112
113 /*!
114 * When called, this function should reset "bad" values in the state vector
115 * such as negative species concentrations. This function may be called
116 * after a failed solution attempt.
117 */
118 virtual void resetBadValues(double* xg) {}
119
120 /*!
121 * Resize the domain to have nv components and np grid points. This method
122 * is virtual so that subclasses can perform other actions required to
123 * resize the domain.
124 */
125 virtual void resize(size_t nv, size_t np);
126
127 //! Return a reference to the grid refiner.
129 return *m_refiner;
130 }
131
132 //! Number of components at each grid point.
133 size_t nComponents() const {
134 return m_nv;
135 }
136
137 //! Check that the specified component index is in range.
138 //! Throws an exception if n is greater than nComponents()-1
139 void checkComponentIndex(size_t n) const {
140 if (n >= m_nv) {
141 throw IndexError("Domain1D::checkComponentIndex", "points", n, m_nv-1);
142 }
143 }
144
145 //! Check that an array size is at least nComponents().
146 //! Throws an exception if nn is less than nComponents(). Used before calls
147 //! which take an array pointer.
148 void checkComponentArraySize(size_t nn) const {
149 if (m_nv > nn) {
150 throw ArraySizeError("Domain1D::checkComponentArraySize", nn, m_nv);
151 }
152 }
153
154 //! Number of grid points in this domain.
155 size_t nPoints() const {
156 return m_points;
157 }
158
159 //! Check that the specified point index is in range.
160 //! Throws an exception if n is greater than nPoints()-1
161 void checkPointIndex(size_t n) const {
162 if (n >= m_points) {
163 throw IndexError("Domain1D::checkPointIndex", "points", n, m_points-1);
164 }
165 }
166
167 //! Check that an array size is at least nPoints().
168 //! Throws an exception if nn is less than nPoints(). Used before calls
169 //! which take an array pointer.
170 void checkPointArraySize(size_t nn) const {
171 if (m_points > nn) {
172 throw ArraySizeError("Domain1D::checkPointArraySize", nn, m_points);
173 }
174 }
175
176 //! Name of the nth component. May be overloaded.
177 virtual std::string componentName(size_t n) const;
178
179 void setComponentName(size_t n, const std::string& name) {
180 m_name[n] = name;
181 }
182
183 //! index of component with name \a name.
184 virtual size_t componentIndex(const std::string& name) const;
185
186 void setBounds(size_t n, doublereal lower, doublereal upper) {
187 m_min[n] = lower;
188 m_max[n] = upper;
189 }
190
191 //! Set tolerances for time-stepping mode
192 /*!
193 * @param rtol Relative tolerance
194 * @param atol Absolute tolerance
195 * @param n component index these tolerances apply to. If set to -1 (the
196 * default), these tolerances will be applied to all solution
197 * components.
198 */
199 void setTransientTolerances(doublereal rtol, doublereal atol, size_t n=npos);
200
201 //! Set tolerances for steady-state mode
202 /*!
203 * @param rtol Relative tolerance
204 * @param atol Absolute tolerance
205 * @param n component index these tolerances apply to. If set to -1 (the
206 * default), these tolerances will be applied to all solution
207 * components.
208 */
209 void setSteadyTolerances(doublereal rtol, doublereal atol, size_t n=npos);
210
211 //! Relative tolerance of the nth component.
212 doublereal rtol(size_t n) {
213 return (m_rdt == 0.0 ? m_rtol_ss[n] : m_rtol_ts[n]);
214 }
215
216 //! Absolute tolerance of the nth component.
217 doublereal atol(size_t n) {
218 return (m_rdt == 0.0 ? m_atol_ss[n] : m_atol_ts[n]);
219 }
220
221 //! Steady relative tolerance of the nth component
222 double steady_rtol(size_t n) {
223 return m_rtol_ss[n];
224 }
225
226 //! Steady absolute tolerance of the nth component
227 double steady_atol(size_t n) {
228 return m_atol_ss[n];
229 }
230
231 //! Transient relative tolerance of the nth component
232 double transient_rtol(size_t n) {
233 return m_rtol_ts[n];
234 }
235
236 //! Transient absolute tolerance of the nth component
237 double transient_atol(size_t n) {
238 return m_atol_ts[n];
239 }
240
241 //! Upper bound on the nth component.
242 doublereal upperBound(size_t n) const {
243 return m_max[n];
244 }
245
246 //! Lower bound on the nth component
247 doublereal lowerBound(size_t n) const {
248 return m_min[n];
249 }
250
251 //! Prepare to do time stepping with time step dt
252 /*!
253 * Copy the internally-stored solution at the last time step to array x0.
254 */
255 void initTimeInteg(doublereal dt, const doublereal* x0) {
256 std::copy(x0 + loc(), x0 + loc() + size(), m_slast.begin());
257 m_rdt = 1.0/dt;
258 }
259
260 //! Prepare to solve the steady-state problem
261 /*!
262 * Set the internally-stored reciprocal of the time step to 0.0
263 */
265 m_rdt = 0.0;
266 }
267
268 //! True if in steady-state mode
269 bool steady() {
270 return (m_rdt == 0.0);
271 }
272
273 //! True if not in steady-state mode
274 bool transient() {
275 return (m_rdt != 0.0);
276 }
277
278 /*!
279 * Set this if something has changed in the governing
280 * equations (for example, the value of a constant has been changed,
281 * so that the last-computed Jacobian is no longer valid.
282 */
283 void needJacUpdate();
284
285 //! Evaluate the residual function at point j. If j == npos,
286 //! evaluate the residual function at all points.
287 /*!
288 * This function must be implemented in classes derived from Domain1D.
289 *
290 * @param j Grid point at which to update the residual
291 * @param[in] x State vector
292 * @param[out] r residual vector
293 * @param[out] mask Boolean mask indicating whether each solution
294 * component has a time derivative (1) or not (0).
295 * @param[in] rdt Reciprocal of the timestep (`rdt=0` implies steady-
296 * state.)
297 */
298 virtual void eval(size_t j, doublereal* x, doublereal* r,
299 integer* mask, doublereal rdt=0.0) {
300 throw NotImplementedError("Domain1D::eval");
301 }
302
303 size_t index(size_t n, size_t j) const {
304 return m_nv*j + n;
305 }
306 doublereal value(const doublereal* x, size_t n, size_t j) const {
307 return x[index(n,j)];
308 }
309
310 virtual void setJac(MultiJac* jac) {}
311
312 //! Save the current solution for this domain into an XML_Node
313 /*!
314 * Base class version of the general domain1D save function. Derived classes
315 * should call the base class method in addition to saving their own data.
316 *
317 * @param o XML_Node to save the solution to.
318 * @param sol Current value of the solution vector. The object will pick
319 * out which part of the solution vector pertains to this
320 * object.
321 * @return XML_Node created to represent this domain
322 *
323 * @deprecated The XML output format is deprecated and will be removed in
324 * Cantera 3.0.
325 */
326 virtual XML_Node& save(XML_Node& o, const doublereal* const sol);
327
328 //! Restore the solution for this domain from an XML_Node
329 /*!
330 * Base class version of the general Domain1D restore function. Derived
331 * classes should call the base class method in addition to restoring
332 * their own data.
333 *
334 * @param dom XML_Node for this domain
335 * @param soln Current value of the solution vector, local to this object.
336 * @param loglevel 0 to suppress all output; 1 to show warnings; 2 for
337 * verbose output
338 *
339 * @deprecated The XML input format is deprecated and will be removed in
340 * Cantera 3.0.
341 */
342 virtual void restore(const XML_Node& dom, doublereal* soln, int loglevel);
343
344 //! Save the state of this domain as an AnyMap
345 /*!
346 * @param soln local solution vector for this domain
347 */
348 virtual AnyMap serialize(const double* soln) const;
349
350 //! Restore the solution for this domain from an AnyMap
351 /*!
352 * @param[in] state AnyMap defining the state of this domain
353 * @param[out] soln Value of the solution vector, local to this domain
354 * @param[in] loglevel 0 to suppress all output; 1 to show warnings; 2 for
355 * verbose output
356 */
357 virtual void restore(const AnyMap& state, double* soln, int loglevel);
358
359 size_t size() const {
360 return m_nv*m_points;
361 }
362
363 /**
364 * Find the index of the first grid point in this domain, and
365 * the start of its variables in the global solution vector.
366 */
367 void locate();
368
369 /**
370 * Location of the start of the local solution vector in the global
371 * solution vector,
372 */
373 virtual size_t loc(size_t j = 0) const {
374 return m_iloc;
375 }
376
377 /**
378 * The index of the first (that is, left-most) grid point belonging to this
379 * domain.
380 */
381 size_t firstPoint() const {
382 return m_jstart;
383 }
384
385 /**
386 * The index of the last (that is, right-most) grid point belonging to this
387 * domain.
388 */
389 size_t lastPoint() const {
390 return m_jstart + m_points - 1;
391 }
392
393 /**
394 * Set the left neighbor to domain 'left.' Method 'locate' is called to
395 * update the global positions of this domain and all those to its right.
396 */
398 m_left = left;
399 locate();
400 }
401
402 //! Set the right neighbor to domain 'right.'
404 m_right = right;
405 }
406
407 //! Append domain 'right' to this one, and update all links.
410 right->linkLeft(this);
411 }
412
413 //! Return a pointer to the left neighbor.
414 Domain1D* left() const {
415 return m_left;
416 }
417
418 //! Return a pointer to the right neighbor.
419 Domain1D* right() const {
420 return m_right;
421 }
422
423 //! Value of component n at point j in the previous solution.
424 double prevSoln(size_t n, size_t j) const {
425 return m_slast[m_nv*j + n];
426 }
427
428 //! Specify an identifying tag for this domain.
429 void setID(const std::string& s) {
430 m_id = s;
431 }
432
433 std::string id() const {
434 if (m_id != "") {
435 return m_id;
436 } else {
437 return fmt::format("domain {}", m_index);
438 }
439 }
440
441 virtual void showSolution_s(std::ostream& s, const doublereal* x) {}
442
443 //! Print the solution.
444 virtual void showSolution(const doublereal* x);
445
446 doublereal z(size_t jlocal) const {
447 return m_z[jlocal];
448 }
449 doublereal zmin() const {
450 return m_z[0];
451 }
452 doublereal zmax() const {
453 return m_z[m_points - 1];
454 }
455
456 void setProfile(const std::string& name, double* values, double* soln);
457
458 vector_fp& grid() {
459 return m_z;
460 }
461 const vector_fp& grid() const {
462 return m_z;
463 }
464 doublereal grid(size_t point) const {
465 return m_z[point];
466 }
467
468 //! called to set up initial grid, and after grid refinement
469 virtual void setupGrid(size_t n, const doublereal* z);
470
471 /**
472 * Writes some or all initial solution values into the global solution
473 * array, beginning at the location pointed to by x. This method is called
474 * by the Sim1D constructor, and allows default values or ones that have
475 * been set locally prior to installing this domain into the container to be
476 * written to the global solution vector.
477 */
478 virtual void _getInitialSoln(doublereal* x);
479
480 //! Initial value of solution component \a n at grid point \a j.
481 virtual doublereal initialValue(size_t n, size_t j);
482
483 /**
484 * In some cases, a domain may need to set parameters that depend on the
485 * initial solution estimate. In such cases, the parameters may be set in
486 * method _finalize. This method is called just before the Newton solver is
487 * called, and the x array is guaranteed to be the local solution vector for
488 * this domain that will be used as the initial guess. If no such parameters
489 * need to be set, then method _finalize does not need to be overloaded.
490 */
491 virtual void _finalize(const doublereal* x) {}
492
493 /**
494 * In some cases, for computational efficiency some properties (such as
495 * transport coefficients) may not be updated during Jacobian evaluations.
496 * Set this to `true` to force these properties to be udpated even while
497 * calculating Jacobian elements.
498 */
499 void forceFullUpdate(bool update) {
500 m_force_full_update = update;
501 }
502
503protected:
504 doublereal m_rdt;
505 size_t m_nv;
506 size_t m_points;
507 vector_fp m_slast;
508 vector_fp m_max;
509 vector_fp m_min;
510 vector_fp m_rtol_ss, m_rtol_ts;
511 vector_fp m_atol_ss, m_atol_ts;
512 vector_fp m_z;
513 OneDim* m_container;
514 size_t m_index;
515 int m_type;
516
517 //! Starting location within the solution vector for unknowns that
518 //! correspond to this domain
519 /*!
520 * Remember there may be multiple domains associated with this problem
521 */
522 size_t m_iloc;
523
524 size_t m_jstart;
525
526 Domain1D* m_left, *m_right;
527
528 //! Identity tag for the domain
529 std::string m_id;
530 std::unique_ptr<Refiner> m_refiner;
531 std::vector<std::string> m_name;
532 int m_bw;
533 bool m_force_full_update;
534};
535}
536
537#endif
Array size error.
Definition: ctexceptions.h:128
Base class for one-dimensional domains.
Definition: Domain1D.h:38
virtual void resetBadValues(double *xg)
Definition: Domain1D.h:118
size_t lastPoint() const
The index of the last (that is, right-most) grid point belonging to this domain.
Definition: Domain1D.h:389
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition: Domain1D.h:522
void checkPointArraySize(size_t nn) const
Check that an array size is at least nPoints().
Definition: Domain1D.h:170
size_t domainIndex()
The left-to-right location of this domain.
Definition: Domain1D.h:58
size_t nComponents() const
Number of components at each grid point.
Definition: Domain1D.h:133
size_t bandwidth()
Set the Jacobian bandwidth for this domain.
Definition: Domain1D.h:99
virtual doublereal initialValue(size_t n, size_t j)
Initial value of solution component n at grid point j.
Definition: Domain1D.cpp:319
virtual AnyMap serialize(const double *soln) const
Save the state of this domain as an AnyMap.
Definition: Domain1D.cpp:172
virtual void showSolution(const doublereal *x)
Print the solution.
Definition: Domain1D.cpp:261
doublereal atol(size_t n)
Absolute tolerance of the nth component.
Definition: Domain1D.h:217
Domain1D * left() const
Return a pointer to the left neighbor.
Definition: Domain1D.h:414
std::string m_id
Identity tag for the domain.
Definition: Domain1D.h:529
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
Definition: Domain1D.h:491
void setContainer(OneDim *c, size_t index)
Specify the container object for this domain, and the position of this domain in the list.
Definition: Domain1D.h:74
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:155
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: Domain1D.cpp:64
void setSteadyTolerances(doublereal rtol, doublereal atol, size_t n=npos)
Set tolerances for steady-state mode.
Definition: Domain1D.cpp:97
void checkComponentIndex(size_t n) const
Check that the specified component index is in range.
Definition: Domain1D.h:139
void linkLeft(Domain1D *left)
Set the left neighbor to domain 'left.
Definition: Domain1D.h:397
virtual XML_Node & save(XML_Node &o, const doublereal *const sol)
Save the current solution for this domain into an XML_Node.
Definition: Domain1D.cpp:118
virtual void resize(size_t nv, size_t np)
Definition: Domain1D.cpp:41
bool isConnector()
True if the domain is a connector domain.
Definition: Domain1D.h:63
void initTimeInteg(doublereal dt, const doublereal *x0)
Prepare to do time stepping with time step dt.
Definition: Domain1D.h:255
Refiner & refiner()
Return a reference to the grid refiner.
Definition: Domain1D.h:128
Domain1D * right() const
Return a pointer to the right neighbor.
Definition: Domain1D.h:419
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: Domain1D.cpp:131
doublereal upperBound(size_t n) const
Upper bound on the nth component.
Definition: Domain1D.h:242
double steady_atol(size_t n)
Steady absolute tolerance of the nth component.
Definition: Domain1D.h:227
double transient_atol(size_t n)
Transient absolute tolerance of the nth component.
Definition: Domain1D.h:237
doublereal lowerBound(size_t n) const
Lower bound on the nth component.
Definition: Domain1D.h:247
virtual void init()
Definition: Domain1D.h:108
virtual void eval(size_t j, doublereal *x, doublereal *r, integer *mask, doublereal rdt=0.0)
Evaluate the residual function at point j.
Definition: Domain1D.h:298
void forceFullUpdate(bool update)
In some cases, for computational efficiency some properties (such as transport coefficients) may not ...
Definition: Domain1D.h:499
const OneDim & container() const
The container holding this domain.
Definition: Domain1D.h:68
bool steady()
True if in steady-state mode.
Definition: Domain1D.h:269
virtual void _getInitialSoln(doublereal *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition: Domain1D.cpp:310
void setBandwidth(int bw=-1)
Set the Jacobian bandwidth. See the discussion of method bandwidth().
Definition: Domain1D.h:80
double steady_rtol(size_t n)
Steady relative tolerance of the nth component.
Definition: Domain1D.h:222
void append(Domain1D *right)
Append domain 'right' to this one, and update all links.
Definition: Domain1D.h:408
void setSteadyMode()
Prepare to solve the steady-state problem.
Definition: Domain1D.h:264
int domainType()
Domain type flag.
Definition: Domain1D.h:53
void setID(const std::string &s)
Specify an identifying tag for this domain.
Definition: Domain1D.h:429
void checkPointIndex(size_t n) const
Check that the specified point index is in range.
Definition: Domain1D.h:161
double prevSoln(size_t n, size_t j) const
Value of component n at point j in the previous solution.
Definition: Domain1D.h:424
size_t firstPoint() const
The index of the first (that is, left-most) grid point belonging to this domain.
Definition: Domain1D.h:381
void needJacUpdate()
Definition: Domain1D.cpp:110
void linkRight(Domain1D *right)
Set the right neighbor to domain 'right.'.
Definition: Domain1D.h:403
Domain1D(size_t nv=1, size_t points=1, double time=0.0)
Constructor.
Definition: Domain1D.cpp:21
void checkComponentArraySize(size_t nn) const
Check that an array size is at least nComponents().
Definition: Domain1D.h:148
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
Definition: Domain1D.cpp:251
doublereal rtol(size_t n)
Relative tolerance of the nth component.
Definition: Domain1D.h:212
double transient_rtol(size_t n)
Transient relative tolerance of the nth component.
Definition: Domain1D.h:232
virtual size_t componentIndex(const std::string &name) const
index of component with name name.
Definition: Domain1D.cpp:73
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector,.
Definition: Domain1D.h:373
void locate()
Find the index of the first grid point in this domain, and the start of its variables in the global s...
Definition: Domain1D.cpp:231
void setTransientTolerances(doublereal rtol, doublereal atol, size_t n=npos)
Set tolerances for time-stepping mode.
Definition: Domain1D.cpp:84
An array index is out of range.
Definition: ctexceptions.h:158
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:187
Container class for multiple-domain 1D problems.
Definition: OneDim.h:27
Refine Domain1D grids so that profiles satisfy adaptation tolerances.
Definition: refine.h:17
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:192
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