Cantera  3.1.0a1
Domain1D.cpp
Go to the documentation of this file.
1 /**
2  * @file Domain1D.cpp
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 
10 #include "cantera/oneD/refine.h"
11 #include "cantera/base/AnyMap.h"
13 
14 namespace Cantera
15 {
16 
17 Domain1D::Domain1D(size_t nv, size_t points, double time)
18 {
19  resize(nv, points);
20 }
21 
22 Domain1D::~Domain1D()
23 {
24 }
25 
26 void Domain1D::resize(size_t nv, size_t np)
27 {
28  // if the number of components is being changed, then a
29  // new grid refiner is required.
30  if (nv != m_nv || !m_refiner) {
31  m_nv = nv;
32  m_refiner = make_unique<Refiner>(*this);
33  }
34  m_nv = nv;
35  m_name.resize(m_nv,"");
36  m_max.resize(m_nv, 0.0);
37  m_min.resize(m_nv, 0.0);
38  // Default error tolerances for all domains
39  m_rtol_ss.resize(m_nv, 1.0e-4);
40  m_atol_ss.resize(m_nv, 1.0e-9);
41  m_rtol_ts.resize(m_nv, 1.0e-4);
42  m_atol_ts.resize(m_nv, 1.0e-11);
43  m_points = np;
44  m_z.resize(np, 0.0);
45  m_slast.resize(m_nv * m_points, 0.0);
46  locate();
47 }
48 
49 string Domain1D::componentName(size_t n) const
50 {
51  if (m_name[n] != "") {
52  return m_name[n];
53  } else {
54  return fmt::format("component {}", n);
55  }
56 }
57 
58 size_t Domain1D::componentIndex(const string& name) const
59 {
60  for (size_t n = 0; n < nComponents(); n++) {
61  if (name == componentName(n)) {
62  return n;
63  }
64  }
65  throw CanteraError("Domain1D::componentIndex",
66  "no component named "+name);
67 }
68 
69 void Domain1D::setTransientTolerances(double rtol, double atol, size_t n)
70 {
71  if (n == npos) {
72  for (n = 0; n < m_nv; n++) {
73  m_rtol_ts[n] = rtol;
74  m_atol_ts[n] = atol;
75  }
76  } else {
77  m_rtol_ts[n] = rtol;
78  m_atol_ts[n] = atol;
79  }
80 }
81 
82 void Domain1D::setSteadyTolerances(double rtol, double atol, size_t n)
83 {
84  if (n == npos) {
85  for (n = 0; n < m_nv; n++) {
86  m_rtol_ss[n] = rtol;
87  m_atol_ss[n] = atol;
88  }
89  } else {
90  m_rtol_ss[n] = rtol;
91  m_atol_ss[n] = atol;
92  }
93 }
94 
96 {
97  if (m_container) {
98  m_container->jacobian().setAge(10000);
99  m_container->saveStats();
100  }
101 }
102 
104 {
105  auto wrap_tols = [this](const vector<double>& tols) {
106  // If all tolerances are the same, just store the scalar value.
107  // Otherwise, store them by component name
108  set<double> unique_tols(tols.begin(), tols.end());
109  if (unique_tols.size() == 1) {
110  return AnyValue(tols[0]);
111  } else {
112  AnyMap out;
113  for (size_t i = 0; i < tols.size(); i++) {
114  out[componentName(i)] = tols[i];
115  }
116  return AnyValue(out);
117  }
118  };
119  AnyMap state;
120  state["type"] = type();
121  state["points"] = static_cast<long int>(nPoints());
122  if (nComponents() && nPoints()) {
123  state["tolerances"]["transient-abstol"] = wrap_tols(m_atol_ts);
124  state["tolerances"]["steady-abstol"] = wrap_tols(m_atol_ss);
125  state["tolerances"]["transient-reltol"] = wrap_tols(m_rtol_ts);
126  state["tolerances"]["steady-reltol"] = wrap_tols(m_rtol_ss);
127  }
128  return state;
129 }
130 
131 shared_ptr<SolutionArray> Domain1D::toArray(bool normalize) const {
132  if (!m_state) {
133  throw CanteraError("Domain1D::toArray",
134  "Domain needs to be installed in a container before calling asArray.");
135  }
136  auto ret = asArray(m_state->data() + m_iloc);
137  if (normalize) {
138  ret->normalize();
139  }
140  return ret;
141 }
142 
143 void Domain1D::fromArray(const shared_ptr<SolutionArray>& arr)
144 {
145  if (!m_state) {
146  throw CanteraError("Domain1D::fromArray",
147  "Domain needs to be installed in a container before calling fromArray.");
148  }
149  resize(nComponents(), arr->size());
150  m_container->resize();
151  fromArray(*arr, m_state->data() + m_iloc);
152  _finalize(m_state->data() + m_iloc);
153 }
154 
155 void Domain1D::setMeta(const AnyMap& meta)
156 {
157  auto set_tols = [&](const AnyValue& tols, const string& which, vector<double>& out)
158  {
159  if (!tols.hasKey(which)) {
160  return;
161  }
162  const auto& tol = tols[which];
163  if (tol.isScalar()) {
164  out.assign(nComponents(), tol.asDouble());
165  } else {
166  for (size_t i = 0; i < nComponents(); i++) {
167  string name = componentName(i);
168  if (tol.hasKey(name)) {
169  out[i] = tol[name].asDouble();
170  } else {
171  warn_user("Domain1D::setMeta", "No {} found for component '{}'",
172  which, name);
173  }
174  }
175  }
176  };
177 
178  if (meta.hasKey("tolerances")) {
179  const auto& tols = meta["tolerances"];
180  set_tols(tols, "transient-abstol", m_atol_ts);
181  set_tols(tols, "transient-reltol", m_rtol_ts);
182  set_tols(tols, "steady-abstol", m_atol_ss);
183  set_tols(tols, "steady-reltol", m_rtol_ss);
184  }
185 }
186 
188 {
189  if (m_left) {
190  // there is a domain on the left, so the first grid point in this domain
191  // is one more than the last one on the left
192  m_jstart = m_left->lastPoint() + 1;
193 
194  // the starting location in the solution vector
195  m_iloc = m_left->loc() + m_left->size();
196  } else {
197  // this is the left-most domain
198  m_jstart = 0;
199  m_iloc = 0;
200  }
201  // if there is a domain to the right of this one, then repeat this for it
202  if (m_right) {
203  m_right->locate();
204  }
205 }
206 
207 void Domain1D::setupGrid(size_t n, const double* z)
208 {
209  if (n > 1) {
210  resize(m_nv, n);
211  for (size_t j = 0; j < m_points; j++) {
212  m_z[j] = z[j];
213  }
214  }
215 }
216 
217 void Domain1D::show(const double* x)
218 {
219  size_t nn = m_nv/5;
220  for (size_t i = 0; i < nn; i++) {
221  writeline('-', 79, false, true);
222  writelog("\n z ");
223  for (size_t n = 0; n < 5; n++) {
224  writelog(" {:>10s} ", componentName(i*5 + n));
225  }
226  writeline('-', 79, false, true);
227  for (size_t j = 0; j < m_points; j++) {
228  writelog("\n {:10.4g} ", m_z[j]);
229  for (size_t n = 0; n < 5; n++) {
230  double v = value(x, i*5+n, j);
231  writelog(" {:10.4g} ", v);
232  }
233  }
234  writelog("\n");
235  }
236  size_t nrem = m_nv - 5*nn;
237  writeline('-', 79, false, true);
238  writelog("\n z ");
239  for (size_t n = 0; n < nrem; n++) {
240  writelog(" {:>10s} ", componentName(nn*5 + n));
241  }
242  writeline('-', 79, false, true);
243  for (size_t j = 0; j < m_points; j++) {
244  writelog("\n {:10.4g} ", m_z[j]);
245  for (size_t n = 0; n < nrem; n++) {
246  double v = value(x, nn*5+n, j);
247  writelog(" {:10.4g} ", v);
248  }
249  }
250  writelog("\n");
251 }
252 
253 void Domain1D::setProfile(const string& name, double* values, double* soln)
254 {
255  for (size_t n = 0; n < m_nv; n++) {
256  if (name == componentName(n)) {
257  for (size_t j = 0; j < m_points; j++) {
258  soln[index(n, j) + m_iloc] = values[j];
259  }
260  return;
261  }
262  }
263  throw CanteraError("Domain1D::setProfile", "unknown component: "+name);
264 }
265 
267 {
268  for (size_t j = 0; j < m_points; j++) {
269  for (size_t n = 0; n < m_nv; n++) {
270  x[index(n,j)] = initialValue(n,j);
271  }
272  }
273 }
274 
275 double Domain1D::initialValue(size_t n, size_t j)
276 {
277  throw NotImplementedError("Domain1D::initialValue");
278 }
279 
280 } // namespace
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:427
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1423
A wrapper for a variable whose type is determined at runtime.
Definition: AnyMap.h:86
bool hasKey(const string &key) const
Returns true if this AnyValue is an AnyMap and that map contains a key with the given name.
Definition: AnyMap.cpp:617
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:66
void setTransientTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for time-stepping mode.
Definition: Domain1D.cpp:69
size_t lastPoint() const
The index of the last (that is, right-most) grid point belonging to this domain.
Definition: Domain1D.h:400
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition: Domain1D.h:552
size_t nComponents() const
Number of components at each grid point.
Definition: Domain1D.h:145
double rtol(size_t n)
Relative tolerance of the nth component.
Definition: Domain1D.h:224
virtual void setMeta(const AnyMap &meta)
Retrieve meta data.
Definition: Domain1D.cpp:155
virtual shared_ptr< SolutionArray > asArray(const double *soln) const
Save the state of this domain as a SolutionArray.
Definition: Domain1D.h:331
virtual void _finalize(const double *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
Definition: Domain1D.h:509
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:167
shared_ptr< vector< double > > m_state
data pointer shared from OneDim
Definition: Domain1D.h:533
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition: Domain1D.cpp:26
void setSteadyTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for steady-state mode.
Definition: Domain1D.cpp:82
virtual string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: Domain1D.cpp:49
double atol(size_t n)
Absolute tolerance of the nth component.
Definition: Domain1D.h:229
shared_ptr< SolutionArray > toArray(bool normalize=false) const
Save the state of this domain to a SolutionArray.
Definition: Domain1D.cpp:131
size_t m_points
Number of grid points.
Definition: Domain1D.h:537
string type() const
String indicating the domain implemented.
Definition: Domain1D.h:49
virtual double initialValue(size_t n, size_t j)
Initial value of solution component n at grid point j.
Definition: Domain1D.cpp:275
virtual size_t componentIndex(const string &name) const
index of component with name name.
Definition: Domain1D.cpp:58
virtual void fromArray(SolutionArray &arr, double *soln)
Restore the solution for this domain from a SolutionArray.
Definition: Domain1D.h:352
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
Definition: Domain1D.cpp:95
virtual void _getInitialSoln(double *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition: Domain1D.cpp:266
Domain1D(size_t nv=1, size_t points=1, double time=0.0)
Constructor.
Definition: Domain1D.cpp:17
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:384
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:187
virtual AnyMap getMeta() const
Retrieve meta data.
Definition: Domain1D.cpp:103
virtual void show(std::ostream &s, const double *x)
Print the solution.
Definition: Domain1D.h:459
virtual void setupGrid(size_t n, const double *z)
called to set up initial grid, and after grid refinement
Definition: Domain1D.cpp:207
void setAge(int age)
Set the Jacobian age.
Definition: MultiJac.h:59
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:195
virtual void resize()
Call after one or more grids has changed size, for example after being refined.
Definition: OneDim.cpp:154
void saveStats()
Save statistics on function and Jacobian evaluation, and reset the counters.
Definition: OneDim.cpp:123
MultiJac & jacobian()
Return a reference to the Jacobian evaluator of an OneDim object.
Definition: OneDim.cpp:87
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:175
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition: global.h:267
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:180