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");
 
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.