5 #include "cantera/oneD/refine.h"
13 bool has_key(
const M& m,
size_t j)
15 if (m.find(j) != m.end()) {
21 static void r_drawline()
31 static doublereal
eps()
34 while (1.0 + e != 1.0) {
41 Refiner::Refiner(Domain1D& domain) :
42 m_ratio(10.0), m_slope(0.8), m_curve(0.8), m_prune(-0.001),
43 m_min_range(0.01), m_domain(&domain), m_npmax(3000),
46 m_nv = m_domain->nComponents();
47 m_active.resize(m_nv,
true);
52 int Refiner::analyze(
size_t n,
const doublereal* z,
61 if (m_domain->nPoints() <= 1) {
73 m_nv = m_domain->nComponents();
76 if (n != m_domain->nPoints()) {
77 throw CanteraError(
"analyze",
"inconsistent");
86 doublereal vmin, vmax, smin, smax, aa, ss;
88 vector_fp v(n), s(n-1);
91 for (j = 0; j < n-1; j++) {
92 dz[j] = z[j+1] - z[j];
95 for (
size_t i = 0; i < m_nv; i++) {
97 name = m_domain->componentName(i);
100 for (j = 0; j < n; j++) {
101 v[j] = value(x, i, j);
105 for (j = 0; j < n-1; j++)
106 s[j] = (value(x, i, j+1) - value(x, i, j))/
111 vmin = *min_element(v.begin(), v.end());
112 vmax = *max_element(v.begin(), v.end());
113 smin = *min_element(s.begin(), s.end());
114 smax = *max_element(s.begin(), s.end());
117 aa =
std::max(fabs(vmax), fabs(vmin));
118 ss =
std::max(fabs(smax), fabs(smin));
125 if ((vmax - vmin) > m_min_range*aa) {
130 dmax = m_slope*(vmax - vmin) + m_thresh;
131 for (j = 0; j < n-1; j++) {
132 r = fabs(v[j+1] - v[j])/dmax;
133 if (r > 1.0 && dz[j] >= 2 * m_gridmin) {
143 if (m_keep[j] == 0) {
158 if ((smax - smin) > m_min_range*ss) {
162 dmax = m_curve*(smax - smin);
163 for (j = 0; j < n-2; j++) {
164 r = fabs(s[j+1] - s[j]) / (dmax + m_thresh/dz[j]);
165 if (r > 1.0 && dz[j] >= 2 * m_gridmin &&
166 dz[j+1] >= 2 * m_gridmin) {
176 if (m_keep[j+1] == 0) {
187 for (j = 1; j < n-1; j++) {
188 if (dz[j] > m_ratio*dz[j-1]) {
192 if (dz[j] < dz[j-1]/m_ratio) {
194 m_c[
"point "+
int2str(j-1)] = 1;
201 return int(m_loc.size());
204 double Refiner::value(
const double* x,
size_t i,
size_t j)
206 return x[m_domain->index(i,j)];
211 int nnew =
static_cast<int>(m_loc.size());
214 writelog(
string(
"Refining grid in ") +
216 +
" New points inserted after grid points ");
217 map<size_t, int>::const_iterator b = m_loc.begin();
218 for (; b != m_loc.end(); ++b) {
223 map<string, int>::const_iterator bb = m_c.begin();
224 for (; bb != m_c.end(); ++bb) {
228 }
else if (m_domain->nPoints() > 1) {
229 writelog(
"no new points needed in "+m_domain->id()+
"\n");
237 int Refiner::getNewGrid(
int n,
const doublereal* z,
238 int nn, doublereal* zn)
241 int nnew =
static_cast<int>(m_loc.size());
243 throw CanteraError(
"Refine::getNewGrid",
244 "array size too small.");
254 for (j = 0; j < n - 1; j++) {
257 if (has_key(m_loc, j)) {
258 zn[jn] = 0.5*(z[j] + z[j+1]);