cantera/Cantera/src/newton_utils.cpp
2003-04-14 17:57:48 +00:00

102 lines
3.1 KiB
C++
Executable file

/**
* @file newton_utils.cpp
*/
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif
#include "ct_defs.h"
#include "Resid1D.h"
namespace Cantera {
class Indx {
public:
Indx(int nv, int np) : m_nv(nv), m_np(np) {}
int m_nv, m_np;
int operator()(int m, int j) { return j*m_nv + m; }
};
doublereal bound_step(const doublereal* x, const doublereal* step,
Resid1D& r, int loglevel=0) {
char buf[100];
int np = r.nPoints();
int nv = r.nComponents();
Indx index(nv, np);
doublereal above, below, val, newval;
int m, j;
doublereal fbound = 1.0;
bool wroteTitle = false;
for (m = 0; m < nv; m++) {
above = r.upperBound(m);
below = r.lowerBound(m);
for (j = 0; j < np; j++) {
val = x[index(m,j)];
if (loglevel > 0) {
if (val > above + Tiny || val < below - Tiny)
cout << "ERROR: solution out of bounds. "
<< r.componentName(m) << "(" << j << ") = " << val
<< " (" << below << ", " << above << ")" << endl;
}
newval = val + step[index(m,j)];
if (newval > above) {
fbound = fmaxx( 0.0, fminn( fbound,
(above - val)/(newval - val)));
}
else if (newval < below) {
fbound = fminn(fbound, (val - below)/(val - newval));
}
if (loglevel > 1 && (newval > above || newval < below)) {
if (!wroteTitle) {
writelog("\nNewton step takes solution out of bounds.\n\n");
sprintf(buf," %12s %4s %10s %10s %10s %10s\n",
"component","pt","value","step","min","max");
wroteTitle = true;
writelog(buf);
}
sprintf(buf, " %12s %4i %10.3e %10.3e %10.3e %10.3e\n",
r.componentName(m).c_str(), j, val,
step[index(m,j)], below, above);
writelog(buf);
}
}
}
return fbound;
}
doublereal norm_square(const doublereal* x,
const doublereal* step, Resid1D& r) {
doublereal f, ewt, esum, sum = 0.0;
int n, j;
int nv = r.nComponents();
int np = r.nPoints();
//int jmx = 0, nmx = 0;
//doublereal fmx = -1.0;
for (n = 0; n < nv; n++) {
esum = 0.0;
for (j = 0; j < np; j++) esum += fabs(x[nv*j + n]);
ewt = r.rtol(n)*esum/np + r.atol(n);
for (j = 0; j < np; j++) {
f = step[nv*j + n]/ewt;
sum += f*f;
// if (fabs(f) > fmx) {
// fmx = fabs(f);
// jmx = j;
// nmx = n;
// }
}
}
return sum;
}
}