Cantera  3.1.0a2
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
31void Domain1D::setSolution(shared_ptr<Solution> sol)
32{
33 if (!sol || !(sol->thermo())) {
34 throw CanteraError("Domain1D::setSolution",
35 "Missing or incomplete Solution object.");
36 }
37 if (m_solution) {
38 m_solution->thermo()->removeSpeciesLock();
39 }
40 m_solution = sol;
41 m_solution->thermo()->addSpeciesLock();
42}
43
44void Domain1D::resize(size_t nv, size_t np)
45{
46 // if the number of components is being changed, then a
47 // new grid refiner is required.
48 if (nv != m_nv || !m_refiner) {
49 m_nv = nv;
50 m_refiner = make_unique<Refiner>(*this);
51 }
52 m_nv = nv;
53 m_name.resize(m_nv,"");
54 m_max.resize(m_nv, 0.0);
55 m_min.resize(m_nv, 0.0);
56 // Default error tolerances for all domains
57 m_rtol_ss.resize(m_nv, 1.0e-4);
58 m_atol_ss.resize(m_nv, 1.0e-9);
59 m_rtol_ts.resize(m_nv, 1.0e-4);
60 m_atol_ts.resize(m_nv, 1.0e-11);
61 m_points = np;
62 m_z.resize(np, 0.0);
63 m_slast.resize(m_nv * m_points, 0.0);
64 locate();
65}
66
67string Domain1D::componentName(size_t n) const
68{
69 if (m_name[n] != "") {
70 return m_name[n];
71 } else {
72 return fmt::format("component {}", n);
73 }
74}
75
76size_t Domain1D::componentIndex(const string& name) const
77{
78 for (size_t n = 0; n < nComponents(); n++) {
79 if (name == componentName(n)) {
80 return n;
81 }
82 }
83 throw CanteraError("Domain1D::componentIndex",
84 "no component named "+name);
85}
86
87void Domain1D::setTransientTolerances(double rtol, double atol, size_t n)
88{
89 if (n == npos) {
90 for (n = 0; n < m_nv; n++) {
91 m_rtol_ts[n] = rtol;
92 m_atol_ts[n] = atol;
93 }
94 } else {
95 m_rtol_ts[n] = rtol;
96 m_atol_ts[n] = atol;
97 }
98}
99
100void Domain1D::setSteadyTolerances(double rtol, double atol, size_t n)
101{
102 if (n == npos) {
103 for (n = 0; n < m_nv; n++) {
104 m_rtol_ss[n] = rtol;
105 m_atol_ss[n] = atol;
106 }
107 } else {
108 m_rtol_ss[n] = rtol;
109 m_atol_ss[n] = atol;
110 }
111}
112
114{
115 if (m_container) {
116 m_container->jacobian().setAge(10000);
117 m_container->saveStats();
118 }
119}
120
122{
123 auto wrap_tols = [this](const vector<double>& tols) {
124 // If all tolerances are the same, just store the scalar value.
125 // Otherwise, store them by component name
126 set<double> unique_tols(tols.begin(), tols.end());
127 if (unique_tols.size() == 1) {
128 return AnyValue(tols[0]);
129 } else {
130 AnyMap out;
131 for (size_t i = 0; i < tols.size(); i++) {
132 out[componentName(i)] = tols[i];
133 }
134 return AnyValue(out);
135 }
136 };
137 AnyMap state;
138 state["type"] = type();
139 state["points"] = static_cast<long int>(nPoints());
140 if (nComponents() && nPoints()) {
141 state["tolerances"]["transient-abstol"] = wrap_tols(m_atol_ts);
142 state["tolerances"]["steady-abstol"] = wrap_tols(m_atol_ss);
143 state["tolerances"]["transient-reltol"] = wrap_tols(m_rtol_ts);
144 state["tolerances"]["steady-reltol"] = wrap_tols(m_rtol_ss);
145 }
146 return state;
147}
148
149shared_ptr<SolutionArray> Domain1D::toArray(bool normalize) const {
150 if (!m_state) {
151 throw CanteraError("Domain1D::toArray",
152 "Domain needs to be installed in a container before calling asArray.");
153 }
154 auto ret = asArray(m_state->data() + m_iloc);
155 if (normalize) {
156 ret->normalize();
157 }
158 return ret;
159}
160
161void Domain1D::fromArray(const shared_ptr<SolutionArray>& arr)
162{
163 if (!m_state) {
164 throw CanteraError("Domain1D::fromArray",
165 "Domain needs to be installed in a container before calling fromArray.");
166 }
167 resize(nComponents(), arr->size());
168 m_container->resize();
169 fromArray(*arr, m_state->data() + m_iloc);
170 _finalize(m_state->data() + m_iloc);
171}
172
173void Domain1D::setMeta(const AnyMap& meta)
174{
175 auto set_tols = [&](const AnyValue& tols, const string& which, vector<double>& out)
176 {
177 if (!tols.hasKey(which)) {
178 return;
179 }
180 const auto& tol = tols[which];
181 if (tol.isScalar()) {
182 out.assign(nComponents(), tol.asDouble());
183 } else {
184 for (size_t i = 0; i < nComponents(); i++) {
185 string name = componentName(i);
186 if (tol.hasKey(name)) {
187 out[i] = tol[name].asDouble();
188 } else {
189 warn_user("Domain1D::setMeta", "No {} found for component '{}'",
190 which, name);
191 }
192 }
193 }
194 };
195
196 if (meta.hasKey("tolerances")) {
197 const auto& tols = meta["tolerances"];
198 set_tols(tols, "transient-abstol", m_atol_ts);
199 set_tols(tols, "transient-reltol", m_rtol_ts);
200 set_tols(tols, "steady-abstol", m_atol_ss);
201 set_tols(tols, "steady-reltol", m_rtol_ss);
202 }
203}
204
206{
207 if (m_left) {
208 // there is a domain on the left, so the first grid point in this domain
209 // is one more than the last one on the left
210 m_jstart = m_left->lastPoint() + 1;
211
212 // the starting location in the solution vector
213 m_iloc = m_left->loc() + m_left->size();
214 } else {
215 // this is the left-most domain
216 m_jstart = 0;
217 m_iloc = 0;
218 }
219 // if there is a domain to the right of this one, then repeat this for it
220 if (m_right) {
221 m_right->locate();
222 }
223}
224
225void Domain1D::setupGrid(size_t n, const double* z)
226{
227 if (n > 1) {
228 resize(m_nv, n);
229 for (size_t j = 0; j < m_points; j++) {
230 m_z[j] = z[j];
231 }
232 }
233}
234
235void Domain1D::show(const double* x)
236{
237 size_t nn = m_nv/5;
238 for (size_t i = 0; i < nn; i++) {
239 writeline('-', 79, false, true);
240 writelog("\n z ");
241 for (size_t n = 0; n < 5; n++) {
242 writelog(" {:>10s} ", componentName(i*5 + n));
243 }
244 writeline('-', 79, false, true);
245 for (size_t j = 0; j < m_points; j++) {
246 writelog("\n {:10.4g} ", m_z[j]);
247 for (size_t n = 0; n < 5; n++) {
248 double v = value(x, i*5+n, j);
249 writelog(" {:10.4g} ", v);
250 }
251 }
252 writelog("\n");
253 }
254 size_t nrem = m_nv - 5*nn;
255 writeline('-', 79, false, true);
256 writelog("\n z ");
257 for (size_t n = 0; n < nrem; n++) {
258 writelog(" {:>10s} ", componentName(nn*5 + n));
259 }
260 writeline('-', 79, false, true);
261 for (size_t j = 0; j < m_points; j++) {
262 writelog("\n {:10.4g} ", m_z[j]);
263 for (size_t n = 0; n < nrem; n++) {
264 double v = value(x, nn*5+n, j);
265 writelog(" {:10.4g} ", v);
266 }
267 }
268 writelog("\n");
269}
270
271void Domain1D::setProfile(const string& name, double* values, double* soln)
272{
273 for (size_t n = 0; n < m_nv; n++) {
274 if (name == componentName(n)) {
275 for (size_t j = 0; j < m_points; j++) {
276 soln[index(n, j) + m_iloc] = values[j];
277 }
278 return;
279 }
280 }
281 throw CanteraError("Domain1D::setProfile", "unknown component: "+name);
282}
283
285{
286 for (size_t j = 0; j < m_points; j++) {
287 for (size_t n = 0; n < m_nv; n++) {
288 x[index(n,j)] = initialValue(n,j);
289 }
290 }
291}
292
293double Domain1D::initialValue(size_t n, size_t j)
294{
295 throw NotImplementedError("Domain1D::initialValue");
296}
297
298} // 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: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.
void setTransientTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for time-stepping mode.
Definition Domain1D.cpp:87
size_t lastPoint() const
The index of the last (that is, right-most) grid point belonging to this domain.
Definition Domain1D.h:398
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition Domain1D.h:550
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
Definition Domain1D.h:565
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:222
virtual void setMeta(const AnyMap &meta)
Retrieve meta data.
Definition Domain1D.cpp:173
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:507
size_t nPoints() const
Number of grid points in this domain.
Definition Domain1D.h:165
shared_ptr< vector< double > > m_state
data pointer shared from OneDim
Definition Domain1D.h:531
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition Domain1D.cpp:44
void setSteadyTolerances(double rtol, double atol, size_t n=npos)
Set tolerances for steady-state mode.
Definition Domain1D.cpp:100
virtual shared_ptr< SolutionArray > asArray(const double *soln) const
Save the state of this domain as a SolutionArray.
Definition Domain1D.h:329
virtual string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition Domain1D.cpp:67
void setSolution(shared_ptr< Solution > sol)
Set the solution manager.
Definition Domain1D.cpp:31
double atol(size_t n)
Absolute tolerance of the nth component.
Definition Domain1D.h:227
shared_ptr< SolutionArray > toArray(bool normalize=false) const
Save the state of this domain to a SolutionArray.
Definition Domain1D.cpp:149
size_t m_points
Number of grid points.
Definition Domain1D.h:535
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:293
virtual size_t componentIndex(const string &name) const
index of component with name name.
Definition Domain1D.cpp:76
virtual void fromArray(SolutionArray &arr, double *soln)
Restore the solution for this domain from a SolutionArray.
Definition Domain1D.h:350
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
Definition Domain1D.cpp:113
virtual void _getInitialSoln(double *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition Domain1D.cpp:284
Domain1D(size_t nv=1, size_t points=1, double time=0.0)
Constructor.
Definition Domain1D.cpp:19
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:382
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:205
virtual AnyMap getMeta() const
Retrieve meta data.
Definition Domain1D.cpp:121
virtual void show(std::ostream &s, const double *x)
Print the solution.
Definition Domain1D.h:457
virtual void setupGrid(size_t n, const double *z)
called to set up initial grid, and after grid refinement
Definition Domain1D.cpp:225
void setAge(int age)
Set the Jacobian age.
Definition MultiJac.h:59
An error indicating that an unimplemented function has been called.
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