Cantera  3.2.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->linearSolver()->setAge(10000);
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());
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(const vector<double>& grid)
226{
227 setupGrid(grid.size(), grid.data());
228}
229
230void Domain1D::setupGrid(size_t n, const double* z)
231{
232 if (n > 1) {
233 resize(m_nv, n);
234 for (size_t j = 0; j < m_points; j++) {
235 m_z[j] = z[j];
236 }
237 }
238}
239
240void Domain1D::setupUniformGrid(size_t points, double length, double start)
241{
242 vector<double> grid(points);
243 double dz = length / (double)(points - 1);
244 for (int iz = 0; iz < points; iz++) {
245 grid[iz] = start + iz * dz;
246 }
248}
249
250void Domain1D::show(const double* x)
251{
252 size_t nn = m_nv/5;
253 for (size_t i = 0; i < nn; i++) {
254 writeline('-', 79, false, true);
255 writelog("\n z ");
256 for (size_t n = 0; n < 5; n++) {
257 writelog(" {:>10s} ", componentName(i*5 + n));
258 }
259 writeline('-', 79, false, true);
260 for (size_t j = 0; j < m_points; j++) {
261 writelog("\n {:10.4g} ", m_z[j]);
262 for (size_t n = 0; n < 5; n++) {
263 double v = value(x, i*5+n, j);
264 writelog(" {:10.4g} ", v);
265 }
266 }
267 writelog("\n");
268 }
269 size_t nrem = m_nv - 5*nn;
270 writeline('-', 79, false, true);
271 writelog("\n z ");
272 for (size_t n = 0; n < nrem; n++) {
273 writelog(" {:>10s} ", componentName(nn*5 + n));
274 }
275 writeline('-', 79, false, true);
276 for (size_t j = 0; j < m_points; j++) {
277 writelog("\n {:10.4g} ", m_z[j]);
278 for (size_t n = 0; n < nrem; n++) {
279 double v = value(x, nn*5+n, j);
280 writelog(" {:10.4g} ", v);
281 }
282 }
283 writelog("\n");
284}
285
286void Domain1D::setProfile(const string& name, double* values, double* soln)
287{
288 for (size_t n = 0; n < m_nv; n++) {
289 if (name == componentName(n)) {
290 for (size_t j = 0; j < m_points; j++) {
291 soln[index(n, j) + m_iloc] = values[j];
292 }
293 return;
294 }
295 }
296 throw CanteraError("Domain1D::setProfile", "unknown component: "+name);
297}
298
300{
301 for (size_t j = 0; j < m_points; j++) {
302 for (size_t n = 0; n < m_nv; n++) {
303 x[index(n,j)] = initialValue(n,j);
304 }
305 }
306}
307
308double Domain1D::initialValue(size_t n, size_t j)
309{
310 throw NotImplementedError("Domain1D::initialValue");
311}
312
313} // 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:87
size_t lastPoint() const
The index of the last (that is, right-most) grid point belonging to this domain.
Definition Domain1D.h:420
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition Domain1D.h:596
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
Definition Domain1D.h:613
Domain1D * m_left
Pointer to the domain to the left.
Definition Domain1D.h:602
OneDim * m_container
Parent OneDim simulation containing this and adjacent domains.
Definition Domain1D.h:587
size_t nComponents() const
Number of components at each grid point.
Definition Domain1D.h:148
double rtol(size_t n)
Relative tolerance of the nth component.
Definition Domain1D.h:235
vector< double > m_atol_ss
Absolute tolerances for steady mode.
Definition Domain1D.h:582
void setupUniformGrid(size_t points, double length, double start=0.)
Set up uniform grid.
Definition Domain1D.cpp:240
vector< double > m_rtol_ts
Relative tolerances for transient mode.
Definition Domain1D.h:581
size_t size() const
Return the size of the solution vector (the product of m_nv and m_points).
Definition Domain1D.h:399
vector< double > m_atol_ts
Absolute tolerances for transient mode.
Definition Domain1D.h:583
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:548
void setupGrid(const vector< double > &grid)
Set up initial grid.
Definition Domain1D.cpp:225
vector< double > & grid()
Access the array of grid coordinates [m].
Definition Domain1D.h:505
size_t m_jstart
Index of the first point in this domain in the global point list.
Definition Domain1D.h:600
size_t m_nv
Number of solution components.
Definition Domain1D.h:575
size_t nPoints() const
Number of grid points in this domain.
Definition Domain1D.h:170
vector< string > m_name
Names of solution components.
Definition Domain1D.h:608
shared_ptr< vector< double > > m_state
data pointer shared from OneDim
Definition Domain1D.h:572
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition Domain1D.cpp:44
double z(size_t jlocal) const
Get the coordinate [m] of the point with local index jlocal
Definition Domain1D.h:484
virtual void show(const double *x)
Print the solution.
Definition Domain1D.cpp:250
vector< double > m_rtol_ss
Relative tolerances for steady mode.
Definition Domain1D.h:580
vector< double > m_slast
Solution vector at the last time step.
Definition Domain1D.h:577
Domain1D * m_right
Pointer to the domain to the right.
Definition Domain1D.h:603
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:359
virtual string componentName(size_t n) const
Name of component n. 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:240
void setProfile(const string &name, double *values, double *soln)
Set initial values for a component at each grid point.
Definition Domain1D.cpp:286
vector< double > m_z
1D spatial grid coordinates
Definition Domain1D.h:584
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:576
string type() const
String indicating the domain implemented.
Definition Domain1D.h:50
vector< double > m_max
Upper bounds on solution components.
Definition Domain1D.h:578
unique_ptr< Refiner > m_refiner
Refiner object used for placing grid points.
Definition Domain1D.h:607
vector< double > m_min
Lower bounds on solution components.
Definition Domain1D.h:579
double value(const double *x, size_t n, size_t j) const
Returns the value of solution component n at grid point j of the solution vector x.
Definition Domain1D.h:347
virtual double initialValue(size_t n, size_t j)
Initial value of solution component n at grid point j.
Definition Domain1D.cpp:308
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:380
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:299
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:335
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:410
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
An error indicating that an unimplemented function has been called.
void resize() override
Call to set the size of internal data structures after first defining the system or if the problem si...
Definition OneDim.cpp:186
void saveStats()
Save statistics on function and Jacobian evaluation, and reset the counters.
Definition OneDim.cpp:155
shared_ptr< SystemJacobian > linearSolver() const
Get the the linear solver being used to hold the Jacobian matrix and solve linear systems as part of ...
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:180