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