6#include "cantera/oneD/refine.h"
14Refiner::Refiner(Domain1D& domain) :
15 m_ratio(10.0), m_slope(0.8), m_curve(0.8), m_prune(-0.001),
16 m_min_range(0.01), m_domain(&domain), m_npmax(1000),
19 m_nv = m_domain->nComponents();
20 m_active.resize(m_nv,
true);
21 m_thresh = std::sqrt(std::numeric_limits<double>::epsilon());
24void Refiner::setCriteria(doublereal ratio, doublereal slope,
25 doublereal curve, doublereal prune)
29 "'ratio' must be greater than 2.0 ({} was specified).", ratio);
30 }
else if (slope < 0.0 || slope > 1.0) {
32 "'slope' must be between 0.0 and 1.0 ({} was specified).", slope);
33 }
else if (curve < 0.0 || curve > 1.0) {
35 "'curve' must be between 0.0 and 1.0 ({} was specified).", curve);
36 }
else if (prune > curve || prune > slope) {
38 "'prune' must be less than 'curve' and 'slope' ({} was specified).",
47int Refiner::analyze(
size_t n,
const doublereal* z,
51 throw CanteraError(
"Refiner::analyze",
"max number of grid points reached ({}).", m_npmax);
54 if (m_domain->nPoints() <= 1) {
65 m_nv = m_domain->nComponents();
68 if (n != m_domain->nPoints()) {
69 throw CanteraError(
"Refiner::analyze",
"inconsistent");
76 for (
size_t j = 0; j < n-1; j++) {
77 dz[j] = z[j+1] - z[j];
80 for (
size_t i = 0; i < m_nv; i++) {
82 string name = m_domain->componentName(i);
84 for (
size_t j = 0; j < n; j++) {
85 v[j] = value(x, i, j);
89 for (
size_t j = 0; j < n-1; j++) {
90 s[j] = (value(x, i, j+1) - value(x, i, j))/(z[j+1] - z[j]);
94 doublereal vmin = *min_element(v.begin(), v.end());
95 doublereal vmax = *max_element(v.begin(), v.end());
96 doublereal smin = *min_element(s.begin(), s.end());
97 doublereal smax = *max_element(s.begin(), s.end());
100 doublereal aa = std::max(fabs(vmax), fabs(vmin));
101 doublereal ss = std::max(fabs(smax), fabs(smin));
107 if ((vmax - vmin) > m_min_range*aa) {
110 doublereal dmax = m_slope*(vmax - vmin) + m_thresh;
111 for (
size_t j = 0; j < n-1; j++) {
112 doublereal r = fabs(v[j+1] - v[j])/dmax;
113 if (r > 1.0 && dz[j] >= 2 * m_gridmin) {
120 }
else if (m_keep[j] == 0) {
130 if ((smax - smin) > m_min_range*ss) {
133 doublereal dmax = m_curve*(smax - smin);
134 for (
size_t j = 0; j < n-2; j++) {
135 doublereal r = fabs(s[j+1] - s[j]) / (dmax + m_thresh/dz[j]);
136 if (r > 1.0 && dz[j] >= 2 * m_gridmin &&
137 dz[j+1] >= 2 * m_gridmin) {
144 }
else if (m_keep[j+1] == 0) {
152 StFlow* fflame =
dynamic_cast<StFlow*
>(m_domain);
155 for (
size_t j = 1; j < n-1; j++) {
157 if (dz[j] > m_ratio*dz[j-1]) {
159 m_c[fmt::format(
"point {}", j)] = 1;
167 if (dz[j] < dz[j-1]/m_ratio) {
169 m_c[fmt::format(
"point {}", j-1)] = 1;
178 if (j > 1 && z[j+1]-z[j-1] > m_ratio * dz[j-2]) {
184 if (j < n-2 && z[j+1]-z[j-1] > m_ratio * dz[j+1]) {
189 if (fflame && fflame->domainType() == cFreeFlow && z[j] == fflame->m_zfixed) {
196 for (
size_t j = 2; j < n-1; j++) {
197 if (m_keep[j] == -1 && m_keep[j-1] == -1) {
202 return int(m_loc.size());
205double Refiner::value(
const double* x,
size_t i,
size_t j)
207 return x[m_domain->index(i,j)];
212 if (!m_loc.empty()) {
214 writelog(
string(
"Refining grid in ") +
216 +
" New points inserted after grid points ");
217 for (
const auto& loc : m_loc) {
222 for (
const auto& c : m_c) {
227 }
else if (m_domain->nPoints() > 1) {
228 writelog(
"no new points needed in "+m_domain->id()+
"\n");
232int Refiner::getNewGrid(
int n,
const doublereal* z,
233 int nn, doublereal* zn)
235 int nnew =
static_cast<int>(m_loc.size());
237 throw CanteraError(
"Refine::getNewGrid",
"array size too small.");
246 for (
int j = 0; j < n - 1; j++) {
249 if (m_loc.count(j)) {
250 zn[jn] = 0.5*(z[j] + z[j+1]);
Base class for exceptions thrown by Cantera classes.
This file contains definitions for utility functions and text for modules, inputfiles,...
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.