22 for (
const auto& dom : domains) {
31 for (
size_t n = 0; n <
m_dom.size(); n++) {
32 if (
domain(n).
id() == name) {
36 throw CanteraError(
"OneDim::domainIndex",
"Domain '{}' not found", name);
49 const auto& [dom, pt, comp] =
component(i);
50 return fmt::format(
"domain {}, component {} at point {}", dom, comp, pt);
55 return {
"",
"Domain Pt. Component"};
60 const auto& [dom, pt, comp] =
component(i);
61 return fmt::format(
"{:8s} {:3d} {:<12s}", dom, pt, comp);
82 size_t n =
m_dom.size();
84 m_dom.back()->append(d.get());
97 d->setContainer(
this,
m_dom.size()-1);
104 const double* x =
m_state->data();
106 for (
size_t n = 0; n < nd; n++) {
111 size_t dstart =
start(n);
113 for (
size_t i = 0; i < nv; i++) {
115 for (
size_t j = 0; j < np; j++) {
116 esum += fabs(x[dstart + nv*j + i]);
118 double ewt = dom.
rtol(i)*esum/np + dom.
atol(i);
119 for (
size_t j = 0; j < np; j++) {
120 double f = step[dstart + nv*j + i]/ewt;
126 return sqrt(sum /
size());
132 auto& gridpts =
m_stats[
"grid_points"].asVector<
long int>();
133 auto& steps =
m_stats[
"steps"].asVector<
long int>();
134 auto& fevals =
m_stats[
"residual_evals"].asVector<
long int>();
135 auto& ftime =
m_stats[
"residual_time"].asVector<
double>();
136 auto& jevals =
m_stats[
"jacobian_evals"].asVector<
long int>();
137 auto& jtime =
m_stats[
"jacobian_time"].asVector<
double>();
138 writelog(
"\nStatistics:\n\n Grid Timesteps Functions Time Jacobians Time\n");
139 for (
size_t i = 0; i < gridpts.size(); i++) {
141 writelog(
"{:5d} {:5d} {:6d} {:9.4f} {:5d} {:9.4f}\n",
142 gridpts[i], steps[i], fevals[i], ftime[i], jevals[i], jtime[i]);
144 writelog(
"{:5d} {:5d} {:6d} NA {:5d} NA\n",
145 gridpts[i], steps[i], fevals[i], jevals[i]);
165 for (
size_t i = 0; i <
nDomains(); i++) {
166 const auto& d =
m_dom[i];
168 size_t np = d->nPoints();
169 size_t nv = d->nComponents();
170 for (
size_t n = 0; n < np; n++) {
175 for (
size_t k = 0; k < nv; k++) {
183 size_t bw1 = d->bandwidth();
185 bw1 = std::max<size_t>(2*d->nComponents(), 1) - 1;
192 size_t bw2 =
m_dom[i-1]->bandwidth();
194 bw2 =
m_dom[i-1]->nComponents();
196 bw2 += d->nComponents() - 1;
199 m_size = d->loc() + d->size();
219void OneDim::eval(
size_t j, span<const double> x, span<double> r,
double rdt,
int count)
221 auto t0 = std::chrono::steady_clock::now();
225 fill(r.begin(), r.end(), 0.0);
234 for (
const auto& d :
m_bulk) {
246 std::chrono::steady_clock::now() - t0).count();
254 auto t0 = std::chrono::steady_clock::now();
256 m_work2.resize(
size());
262 for (
auto& dom :
m_dom) {
263 dom->checkAnalyticJacobian();
265 vector<double> perturbed(x0.begin(), x0.end());
267 for (
size_t j = 0; j <
points(); j++) {
268 size_t nv =
nVars(j);
271 for (
size_t n = 0; n < nv; n++) {
278 double xsave = x0[ipt];
283 perturbed[ipt] = xsave + dx;
284 double rdx = 1.0 / (perturbed[ipt] - xsave);
287 eval(j, perturbed, m_work2, 0.0, 0);
290 for (
size_t i = j - 1; i != j+2; i++) {
292 size_t mv =
nVars(i);
293 size_t iloc =
loc(i);
294 for (
size_t m = 0; m < mv; m++) {
295 double delta = m_work2[m+iloc] -
m_work1[m+iloc];
297 m_jac->setValue(m + iloc, ipt, delta * rdx);
302 perturbed[ipt] = xsave;
308 for (
auto& dom :
m_dom) {
309 dom->evalJacobianAnalytic(x0, *
m_jac);
312 m_jac->updateElapsed(std::chrono::duration<double>(
313 std::chrono::steady_clock::now() - t0).count());
314 m_jac->incrementEvals();
357 for (
auto dom :
m_dom) {
358 dom->resetBadValues(x);
Base class for exceptions thrown by Cantera classes.
Base class for one-dimensional domains.
void initTimeInteg(double dt, span< const double > x0)
Performs the setup required before starting a time-stepping solution.
size_t nComponents() const
Number of components at each grid point.
double rtol(size_t n)
Relative tolerance of the nth component.
Domain1D * left() const
Return a pointer to the left neighbor.
string id() const
Returns the identifying tag for this domain.
virtual bool hasAnalyticJacobian(size_t j, size_t n) const
Returns true if this domain computes the Jacobian column for component n at (domain-local) grid point...
size_t nPoints() const
Number of grid points in this domain.
double lowerBound(size_t n) const
Lower bound on the nth component.
double upperBound(size_t n) const
Upper bound on the nth component.
Domain1D * right() const
Return a pointer to the right neighbor.
virtual string componentName(size_t n) const
Name of component n. May be overloaded.
virtual void init()
Initialize.
double atol(size_t n)
Absolute tolerance of the nth component.
void setSteadyMode()
Set the internally-stored reciprocal of the time step to 0.0, which is used to indicate that the prob...
size_t firstPoint() const
The index of the first (that is, left-most) grid point belonging to this domain.
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector.
void locate()
Find the index of the first grid point in this domain, and the start of its variables in the global s...
virtual double eval(double t) const
Evaluate the function.
An array index is out of range.
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
void init()
Initialize all domains.
double weightedNorm(span< const double > step) const override
Compute the weighted norm of a step vector.
void resize() override
Call to set the size of internal data structures after first defining the system or if the problem si...
string componentName(size_t i) const override
Get the name of the i-th component of the state vector.
pair< string, string > componentTableHeader() const override
Get header lines describing the column names included in a component label.
void initTimeInteg(double dt, span< const double > x) override
Prepare for time stepping beginning with solution x and timestep dt.
size_t loc(size_t jg)
Location in the solution vector of the first component of global point jg.
double upperBound(size_t i) const override
Get the upper bound for global component i in the state vector.
void addDomain(shared_ptr< Domain1D > d)
Add a domain. Domains are added left-to-right.
string componentTableLabel(size_t i) const override
Get elements of the component name, aligned with the column headings given by componentTableHeader().
size_t nDomains() const
Number of domains.
Domain1D * right()
Pointer to right-most domain (last added).
size_t domainIndex(const string &name) const
Get the index of the domain named name.
OneDim()=default
Default constructor.
void setSteadyMode() override
Prepare to solve the steady-state problem.
vector< shared_ptr< Domain1D > > m_connect
All connector and boundary domains.
vector< std::tuple< size_t, size_t, size_t > > m_componentInfo
Domain, grid point, and component indices for each element of the global state vector.
vector< shared_ptr< Domain1D > > m_bulk
All bulk/flow domains.
vector< size_t > m_loc
Location in the state vector of the first component of each point, across all domains.
size_t nVars(size_t jg)
Number of solution components at global point jg.
void evalJacobian(span< const double > x0) override
Evaluates the Jacobian at x0 using finite differences.
std::tuple< string, size_t, string > component(size_t i) const
Return the domain, local point index, and component name for the i-th component of the global solutio...
Domain1D * pointDomain(size_t i)
Return a pointer to the domain global point i belongs to.
size_t points()
Total number of points.
vector< size_t > m_nvars
Number of variables at each point, across all domains.
bool m_init
Indicates whether one-time initialization for each domain has been completed.
void writeStats(int printTime=1)
Write statistics about the number of iterations and Jacobians at each grid level.
size_t m_pts
Total number of points.
void resetBadValues(span< double > x) override
Reset values such as negative species concentrations.
Domain1D & domain(size_t i) const
Return a reference to domain i.
vector< shared_ptr< Domain1D > > m_dom
All domains comprising the system.
Domain1D * left()
Pointer to left-most domain (first added).
double lowerBound(size_t i) const override
Get the lower bound for global component i in the state vector.
void eval(size_t j, span< const double > x, span< double > r, double rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
size_t m_size
Solution vector size
virtual void resize()
Call to set the size of internal data structures after first defining the system or if the problem si...
virtual void saveStats()
Commit statistics for the current grid into m_stats and reset the staging counters.
double m_jacobianAbsPerturb
Absolute perturbation of each component in finite difference Jacobian.
size_t size() const
Total solution vector length;.
double rdt() const
Reciprocal of the time step.
virtual void initTimeInteg(double dt, span< const double > x)
Prepare for time stepping beginning with solution x and timestep dt.
AnyMap m_stats
Committed per-grid statistics.
double m_rdt
Reciprocal of time step.
double m_jacobianThreshold
Threshold for ignoring small elements in Jacobian.
shared_ptr< SystemJacobian > m_jac
Jacobian evaluator.
shared_ptr< vector< double > > m_state
Solution vector.
vector< int > m_mask
Transient mask.
Func1 * m_interrupt
Function called at the start of every call to eval.
double m_evaltime
Wall time [s] in standalone residual evals.
size_t m_bw
Jacobian bandwidth.
int m_nevals
Standalone residual evaluations (not Jacobian fill)
virtual void setSteadyMode()
Prepare to solve the steady-state problem.
double m_jacobianRelPerturb
Relative perturbation of each component in finite difference Jacobian.
vector< double > m_work1
Work arrays used during Jacobian evaluation.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
shared_ptr< SystemJacobian > newSystemJacobian(const string &type)
Create a SystemJacobian object of the specified type.