102 lines
3.1 KiB
C++
Executable file
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;
|
|
}
|
|
}
|