6#include "cantera/oneD/refine.h"
14Refiner::Refiner(Domain1D& domain) :
17 m_nv = m_domain->nComponents();
18 m_active.resize(m_nv,
true);
21void Refiner::setCriteria(
double ratio,
double slope,
double curve,
double prune)
25 "'ratio' must be greater than 2.0 ({} was specified).", ratio);
26 }
else if (slope < 0.0 || slope > 1.0) {
28 "'slope' must be between 0.0 and 1.0 ({} was specified).", slope);
29 }
else if (curve < 0.0 || curve > 1.0) {
31 "'curve' must be between 0.0 and 1.0 ({} was specified).", curve);
32 }
else if (prune > curve || prune > slope) {
34 "'prune' must be less than 'curve' and 'slope' ({} was specified).",
43int Refiner::analyze(
size_t n,
const double* z,
const double* x)
46 throw CanteraError(
"Refiner::analyze",
"max number of grid points reached ({}).", m_npmax);
49 if (m_domain->nPoints() <= 1) {
54 if (n != m_domain->nPoints()) {
55 throw CanteraError(
"Refiner::analyze",
"number of grid points provided does not match domain size.");
60 m_componentNames.clear();
67 m_nv = m_domain->nComponents();
70 vector<double> val(n);
71 vector<double> slope(n-1);
73 vector<double> dz(n-1);
74 for (
size_t j = 0; j < n-1; j++) {
75 dz[j] = z[j+1] - z[j];
78 for (
size_t i = 0; i < m_nv; i++) {
80 string name = m_domain->componentName(i);
82 for (
size_t j = 0; j < n; j++) {
83 val[j] = value(x, i, j);
87 for (
size_t j = 0; j < n-1; j++) {
88 slope[j] = (val[j+1] - val[j]) / dz[j];
92 double valMin = *min_element(val.begin(), val.end());
93 double valMax = *max_element(val.begin(), val.end());
94 double slopeMin = *min_element(slope.begin(), slope.end());
95 double slopeMax = *max_element(slope.begin(), slope.end());
98 double valMagnitude = std::max(fabs(valMax), fabs(valMin));
99 double slopeMagnitude = std::max(fabs(slopeMax), fabs(slopeMin));
104 if (valMax - valMin > m_min_range*valMagnitude) {
107 double max_change = m_slope*(valMax - valMin);
108 for (
size_t j = 0; j < n-1; j++) {
109 double ratio = fabs(val[j+1] - val[j]) / (max_change + m_thresh);
110 if (ratio > 1.0 && dz[j] >= 2 * m_gridmin) {
111 m_insertPts.insert(j);
112 m_componentNames.insert(name);
114 if (ratio >= m_prune) {
117 }
else if (m_keep[j] == UNSET) {
127 if (slopeMax - slopeMin > m_min_range*slopeMagnitude) {
129 double max_change = m_curve*(slopeMax - slopeMin);
130 for (
size_t j = 0; j < n-2; j++) {
134 double ratio = fabs(slope[j+1] - slope[j]) / (max_change + m_thresh/dz[j]);
135 if (ratio > 1.0 && dz[j] >= 2*m_gridmin && dz[j+1] >= 2*m_gridmin) {
136 m_componentNames.insert(name);
137 m_insertPts.insert(j);
138 m_insertPts.insert(j+1);
140 if (ratio >= m_prune) {
142 }
else if (m_keep[j+1] == UNSET) {
143 m_keep[j+1] = REMOVE;
151 for (
size_t j = 1; j < n-1; j++) {
154 if (dz[j] > m_ratio*dz[j-1]) {
155 m_insertPts.insert(j);
156 m_componentNames.insert(fmt::format(
"point {}", j));
164 if (dz[j-1] > m_ratio*dz[j]) {
165 m_insertPts.insert(j-1);
166 m_componentNames.insert(fmt::format(
"point {}", j-1));
175 if (j > 1 && z[j+1]-z[j-1] > m_ratio * dz[j-2]) {
181 if (j < n-2 && z[j+1]-z[j-1] > m_ratio * dz[j+1]) {
202 for (
size_t j = 2; j < n-1; j++) {
203 if (m_keep[j] == REMOVE && m_keep[j-1] == REMOVE) {
208 return int(m_insertPts.size());
211double Refiner::value(
const double* x,
size_t n,
size_t j)
213 return x[m_domain->index(n,j)];
218 if (!m_insertPts.empty()) {
220 writelog(
string(
"Refining grid in ") +
222 +
" New points inserted after grid points ");
223 for (
const auto& loc : m_insertPts) {
228 for (
const auto& c : m_componentNames) {
233 }
else if (m_domain->nPoints() > 1) {
234 writelog(
"no new points needed in "+m_domain->id()+
"\n");
238int Refiner::getNewGrid(
int n,
const double* z,
int nn,
double* zn)
241 "Refiner::getNewGrid",
242 "Deprecated in Cantera 3.1; unused function that will be removed.");
244 int nnew =
static_cast<int>(m_insertPts.size());
246 throw CanteraError(
"Refine::getNewGrid",
"array size too small.");
249 if (m_insertPts.empty()) {
255 for (
int j = 0; j < n - 1; j++) {
258 if (m_insertPts.count(j)) {
259 zn[jn] = 0.5*(z[j] + z[j+1]);
Base class for exceptions thrown by Cantera classes.
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
bool twoPointControlEnabled() const
Returns the status of the two-point control.
double m_zfixed
Location of the point where temperature is fixed.
double leftControlPointCoordinate() const
Returns the z-coordinate of the left control point.
bool isFree() const
Retrieve flag indicating whether flow is freely propagating.
double rightControlPointCoordinate() const
Returns the z-coordinate of the right control point.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.