2 #include "cantera/oneD/refine.h"
12 static void r_drawline()
19 Refiner::Refiner(Domain1D& domain) :
20 m_ratio(10.0), m_slope(0.8), m_curve(0.8), m_prune(-0.001),
21 m_min_range(0.01), m_domain(&domain), m_npmax(3000),
24 m_nv = m_domain->nComponents();
25 m_active.resize(m_nv,
true);
26 m_thresh = std::sqrt(std::numeric_limits<double>::epsilon());
29 int Refiner::analyze(
size_t n,
const doublereal* z,
52 throw CanteraError(
"analyze",
"inconsistent");
59 for (
size_t j = 0; j < n-1; j++) {
60 dz[j] = z[j+1] - z[j];
63 for (
size_t i = 0; i < m_nv; i++) {
67 for (
size_t j = 0; j < n; j++) {
68 v[j] = value(x, i, j);
72 for (
size_t j = 0; j < n-1; j++) {
73 s[j] = (value(x, i, j+1) - value(x, i, j))/(z[j+1] - z[j]);
77 doublereal vmin = *min_element(v.begin(), v.end());
78 doublereal vmax = *max_element(v.begin(), v.end());
79 doublereal smin = *min_element(s.begin(), s.end());
80 doublereal smax = *max_element(s.begin(), s.end());
83 doublereal aa = std::max(fabs(vmax), fabs(vmin));
84 doublereal ss = std::max(fabs(smax), fabs(smin));
90 if ((vmax - vmin) > m_min_range*aa) {
93 doublereal dmax = m_slope*(vmax - vmin) + m_thresh;
94 for (
size_t j = 0; j < n-1; j++) {
95 doublereal r = fabs(v[j+1] - v[j])/dmax;
103 }
else if (m_keep[j] == 0) {
113 if ((smax - smin) > m_min_range*ss) {
116 doublereal dmax = m_curve*(smax - smin);
117 for (
size_t j = 0; j < n-2; j++) {
118 doublereal r = fabs(s[j+1] - s[j]) / (dmax + m_thresh/dz[j]);
127 }
else if (m_keep[j+1] == 0) {
136 for (
size_t j = 1; j < n-1; j++) {
138 if (dz[j] > m_ratio*dz[j-1]) {
148 if (dz[j] < dz[j-1]/m_ratio) {
150 m_c[
"point "+
int2str(j-1)] = 1;
159 if (j > 1 && z[j+1]-z[j-1] > m_ratio * dz[j-2]) {
165 if (j < n-2 && z[j+1]-z[j-1] > m_ratio * dz[j+1]) {
170 if (z[j] == m_domain->m_zfixed) {
177 for (
size_t j = 2; j < n-1; j++) {
178 if (m_keep[j] == -1 && m_keep[j-1] == -1) {
183 return int(m_loc.size());
186 double Refiner::value(
const double* x,
size_t i,
size_t j)
188 return x[m_domain->index(i,j)];
193 if (!m_loc.empty()) {
195 writelog(
string(
"Refining grid in ") +
197 +
" New points inserted after grid points ");
198 map<size_t, int>::const_iterator b = m_loc.begin();
199 for (; b != m_loc.end(); ++b) {
204 map<string, int>::const_iterator bb = m_c.begin();
205 for (; bb != m_c.end(); ++bb) {
210 }
else if (m_domain->
nPoints() > 1) {
211 writelog(
"no new points needed in "+m_domain->id()+
"\n");
215 int Refiner::getNewGrid(
int n,
const doublereal* z,
216 int nn, doublereal* zn)
218 int nnew =
static_cast<int>(m_loc.size());
220 throw CanteraError(
"Refine::getNewGrid",
"array size too small.");
229 for (
int j = 0; j < n - 1; j++) {
232 if (m_loc.count(j)) {
233 zn[jn] = 0.5*(z[j] + z[j+1]);
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
size_t nPoints() const
Number of grid points in this domain.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
doublereal m_gridmin
minimum grid spacing [m]
size_t nComponents() const
Number of components at each grid point.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
void writelog(const std::string &msg)
Write a message to the screen.