Cantera
Loading...
Searching...
No Matches
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"
15
16namespace Cantera
17{
18
19Domain1D::Domain1D(size_t nv, size_t points, double time)
20{
21 resize(nv, points);
22}
23
24Domain1D::~Domain1D()
25{
26 if (m_solution) {
27 m_solution->thermo()->removeSpeciesLock();
28 }
29}
30
31string Domain1D::info(const vector<string>& keys, int rows, int width)
32{
33 return toArray()->info(keys, rows, width);
34}
35
36void Domain1D::resize(size_t nv, size_t np)
37{
38 // if the number of components is being changed, then a
39 // new grid refiner is required.
40 if (nv != m_nv || !m_refiner) {
41 m_nv = nv;
42 m_refiner = make_unique<Refiner>(*this);
43 }
44 m_nv = nv;
45 m_name.resize(m_nv,"");
46 m_max.resize(m_nv, 0.0);
47 m_min.resize(m_nv, 0.0);
48 // Default error tolerances for all domains
49 m_rtol_ss.resize(m_nv, 1.0e-4);
50 m_atol_ss.resize(m_nv, 1.0e-9);
51 m_rtol_ts.resize(m_nv, 1.0e-4);
52 m_atol_ts.resize(m_nv, 1.0e-11);
53 m_points = np;
54 m_z.resize(np, 0.0);
55 m_slast.resize(m_nv * m_points, 0.0);
56 locate();
57}
58
59string Domain1D::componentName(size_t n) const
60{
61 if (n < m_nv) {
62 if (m_name[n] != "") {
63 return m_name[n];
64 } else {
65 return fmt::format("component {}", n);
66 }
67 }
68 throw IndexError("Domain1D::componentName", "component", n, m_nv);
69}
70
71size_t Domain1D::componentIndex(const string& name, bool checkAlias) const
72{
73 for (size_t n = 0; n < m_nv; n++) {
74 if (name == componentName(n)) {
75 return n;
76 }
77 }
78 throw CanteraError("Domain1D::componentIndex",
79 "Component '{}' not found", name);
80}
81
82bool Domain1D::hasComponent(const string& name, bool checkAlias) const
83{
84 for (size_t n = 0; n < m_nv; n++) {
85 if (name == componentName(n)) {
86 return true;
87 }
88 }
89 throw CanteraError("Domain1D::hasComponent",
90 "Component '{}' not found", name);
91}
92
93void Domain1D::setTransientTolerances(double rtol, double atol, size_t n)
94{
95 if (n == npos) {
96 for (n = 0; n < m_nv; n++) {
97 m_rtol_ts[n] = rtol;
98 m_atol_ts[n] = atol;
99 }
100 } else {
101 m_rtol_ts[n] = rtol;
102 m_atol_ts[n] = atol;
103 }
104}
105
106void Domain1D::setSteadyTolerances(double rtol, double atol, size_t n)
107{
108 if (n == npos) {
109 for (n = 0; n < m_nv; n++) {
110 m_rtol_ss[n] = rtol;
111 m_atol_ss[n] = atol;
112 }
113 } else {
114 m_rtol_ss[n] = rtol;
115 m_atol_ss[n] = atol;
116 }
117}
118
120{
121 if (m_container) {
122 m_container->linearSolver()->setAge(10000);
123 m_container->saveStats();
124 }
125}
126
128{
129 auto wrap_tols = [this](const vector<double>& tols) {
130 // If all tolerances are the same, just store the scalar value.
131 // Otherwise, store them by component name
132 set<double> unique_tols(tols.begin(), tols.end());
133 if (unique_tols.size() == 1) {
134 return AnyValue(tols[0]);
135 } else {
136 AnyMap out;
137 for (size_t i = 0; i < tols.size(); i++) {
138 out[componentName(i)] = tols[i];
139 }
140 return AnyValue(out);
141 }
142 };
143 AnyMap state;
144 state["type"] = domainType();
145 state["points"] = static_cast<long int>(nPoints());
146 if (nComponents() && nPoints()) {
147 state["tolerances"]["transient-abstol"] = wrap_tols(m_atol_ts);
148 state["tolerances"]["steady-abstol"] = wrap_tols(m_atol_ss);
149 state["tolerances"]["transient-reltol"] = wrap_tols(m_rtol_ts);
150 state["tolerances"]["steady-reltol"] = wrap_tols(m_rtol_ss);
151 }
152 return state;
153}
154
155void 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
207void Domain1D::setupGrid(span<const double> z)
208{
209 m_z.assign(z.begin(), z.end());
210 m_points = z.size();
211 m_slast.resize(m_nv * m_points, 0.0);
212}
213
214void Domain1D::setupUniformGrid(size_t points, double length, double start)
215{
216 vector<double> grid(points);
217 double dz = length / static_cast<double>(points - 1);
218 for (size_t iz = 0; iz < points; iz++) {
219 grid[iz] = start + iz * dz;
220 }
222}
223
224void Domain1D::show(span<const double> x)
225{
226 size_t nn = m_nv/5;
227 for (size_t i = 0; i < nn; i++) {
228 writeline('-', 79, false, true);
229 writelog("\n z ");
230 for (size_t n = 0; n < 5; n++) {
231 writelog(" {:>10s} ", componentName(i*5 + n));
232 }
233 writeline('-', 79, false, true);
234 for (size_t j = 0; j < m_points; j++) {
235 writelog("\n {:10.4g} ", m_z[j]);
236 for (size_t n = 0; n < 5; n++) {
237 writelog(" {:10.4g} ", x[index(i*5 + n, j)]);
238 }
239 }
240 writelog("\n");
241 }
242 size_t nrem = m_nv - 5*nn;
243 writeline('-', 79, false, true);
244 writelog("\n z ");
245 for (size_t n = 0; n < nrem; n++) {
246 writelog(" {:>10s} ", componentName(nn*5 + n));
247 }
248 writeline('-', 79, false, true);
249 for (size_t j = 0; j < m_points; j++) {
250 writelog("\n {:10.4g} ", m_z[j]);
251 for (size_t n = 0; n < nrem; n++) {
252 writelog(" {:10.4g} ", x[index(nn*5 + n, j)]);
253 }
254 }
255 writelog("\n");
256}
257
258void Domain1D::setRefineCriteria(double ratio, double slope, double curve, double prune)
259{
260 m_refiner->setCriteria(ratio, slope, curve, prune);
261}
262
264{
265 return m_refiner->getCriteria();
266}
267
268void Domain1D::_getInitialSoln(span<double> x)
269{
270 for (size_t j = 0; j < m_points; j++) {
271 for (size_t n = 0; n < m_nv; n++) {
272 x[index(n,j)] = initialValue(n,j);
273 }
274 }
275}
276
277double Domain1D::initialValue(size_t n, size_t j)
278{
279 throw NotImplementedError("Domain1D::initialValue");
280}
281
282void Domain1D::appendResiduals(SolutionArray& arr, span<const double> res) const
283{
284 // Skip domains with no data points in the SolutionArray
285 if (arr.size() == 0) {
286 return;
287 }
288 for (size_t i = 0; i < nComponents(); i++) {
289 string rname = "residual-" + componentName(i);
290 arr.addExtra(rname);
291 vector<double> data(nPoints());
292 for (size_t j = 0; j < nPoints(); j++) {
293 data[j] = res[index(i, j)];
294 }
296 value = data;
297 arr.setComponent(rname, value);
298 }
299}
300
301} // namespace
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
A map of string keys to values whose type can vary at runtime.
Definition AnyMap.h:431
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition AnyMap.cpp:1477
A wrapper for a variable whose type is determined at runtime.
Definition AnyMap.h:88
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:660
Base class for exceptions thrown by Cantera classes.
void setTransientTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for time-stepping mode.
Definition Domain1D.cpp:93
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition Domain1D.h:760
virtual void _getInitialSoln(span< double > x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition Domain1D.cpp:268
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
Definition Domain1D.h:778
Domain1D * m_left
Pointer to the domain to the left.
Definition Domain1D.h:766
OneDim * m_container
Parent OneDim simulation containing this and adjacent domains.
Definition Domain1D.h:751
virtual void setupGrid(span< const double > z)
Set up initial grid.
Definition Domain1D.cpp:207
size_t nComponents() const
Number of components at each grid point.
Definition Domain1D.h:143
double rtol(size_t n)
Relative tolerance of the nth component.
Definition Domain1D.h:224
vector< double > m_atol_ss
Absolute tolerances for steady mode.
Definition Domain1D.h:746
void setupUniformGrid(size_t points, double length, double start=0.)
Set up uniform grid.
Definition Domain1D.cpp:214
vector< double > m_rtol_ts
Relative tolerances for transient mode.
Definition Domain1D.h:745
vector< double > m_atol_ts
Absolute tolerances for transient mode.
Definition Domain1D.h:747
virtual void setMeta(const AnyMap &meta)
Retrieve meta data.
Definition Domain1D.cpp:155
span< double > grid()
Access the array of grid coordinates [m].
Definition Domain1D.h:669
size_t m_jstart
Index of the first point in this domain in the global point list.
Definition Domain1D.h:764
size_t m_nv
Number of solution components.
Definition Domain1D.h:739
size_t nPoints() const
Number of grid points in this domain.
Definition Domain1D.h:148
vector< string > m_name
Names of solution components.
Definition Domain1D.h:772
virtual string domainType() const
Domain type flag.
Definition Domain1D.h:47
string info(const vector< string > &keys, int rows=10, int width=80)
Return a concise summary of a Domain.
Definition Domain1D.cpp:31
virtual size_t componentIndex(const string &name, bool checkAlias=true) const
Index of component with name name.
Definition Domain1D.cpp:71
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition Domain1D.cpp:36
double z(size_t jlocal) const
Get the coordinate [m] of the point with local index jlocal.
Definition Domain1D.h:654
virtual void appendResiduals(SolutionArray &arr, span< const double > res) const
Append residual data to a SolutionArray as extra components.
Definition Domain1D.cpp:282
vector< double > m_rtol_ss
Relative tolerances for steady mode.
Definition Domain1D.h:744
vector< double > m_slast
Solution vector at the last time step.
Definition Domain1D.h:741
virtual double value(const string &component) const
Set a single component value at a boundary.
Definition Domain1D.h:400
Domain1D * m_right
Pointer to the domain to the right.
Definition Domain1D.h:767
void setSteadyTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for steady-state mode.
Definition Domain1D.cpp:106
virtual string componentName(size_t n) const
Name of component n. May be overloaded.
Definition Domain1D.cpp:59
double atol(size_t n)
Absolute tolerance of the nth component.
Definition Domain1D.h:229
vector< double > m_z
1D spatial grid coordinates
Definition Domain1D.h:748
size_t m_points
Number of grid points.
Definition Domain1D.h:740
virtual void show(span< const double > x)
Print the solution.
Definition Domain1D.cpp:224
vector< double > m_max
Upper bounds on solution components.
Definition Domain1D.h:742
unique_ptr< Refiner > m_refiner
Refiner object used for placing grid points.
Definition Domain1D.h:771
vector< double > m_min
Lower bounds on solution components.
Definition Domain1D.h:743
virtual double initialValue(size_t n, size_t j)
Initial value of solution component n at grid point j.
Definition Domain1D.cpp:277
virtual shared_ptr< SolutionArray > toArray(bool normalize=false)
Save the state of this domain to a SolutionArray.
Definition Domain1D.h:525
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
Definition Domain1D.cpp:119
Domain1D(size_t nv=1, size_t points=1, double time=0.0)
Constructor.
Definition Domain1D.cpp:19
size_t index(size_t n, size_t j) const
Returns the index of the solution vector, which corresponds to component n at grid point j.
Definition Domain1D.h:390
vector< double > getRefineCriteria()
Get the grid refinement criteria.
Definition Domain1D.cpp:263
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:127
virtual bool hasComponent(const string &name, bool checkAlias=true) const
Check whether the Domain contains a component.
Definition Domain1D.cpp:82
void setRefineCriteria(double ratio=10.0, double slope=0.8, double curve=0.8, double prune=-0.1)
Set grid refinement criteria.
Definition Domain1D.cpp:258
An array index is out of range.
An error indicating that an unimplemented function has been called.
A container class holding arrays of state information.
void setComponent(const string &name, const AnyValue &data)
Set a component of the SolutionArray by name.
void addExtra(const string &name, bool back=true)
Add auxiliary component to SolutionArray.
int size() const
Size of SolutionArray (number of entries).
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition global.h:171
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition global.h:263
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:183