示例#1
0
void MultiNewton::step(doublereal* x, doublereal* step,
                       OneDim& r, MultiJac& jac, int loglevel)
{
    size_t iok;
    size_t sz = r.size();
    r.eval(npos, x, step);
#undef DEBUG_STEP
#ifdef DEBUG_STEP
    vector_fp ssave(sz, 0.0);
    for (size_t n = 0; n < sz; n++) {
        step[n] = -step[n];
        ssave[n] = step[n];
    }
#else
    for (size_t n = 0; n < sz; n++) {
        step[n] = -step[n];
    }
#endif

    iok = jac.solve(step, step);

    // if iok is non-zero, then solve failed
    if (iok != 0) {
        iok--;
        size_t nd = r.nDomains();
        size_t n;
        for (n = nd-1; n != npos; n--)
            if (iok >= r.start(n)) {
                break;
            }
        Domain1D& dom = r.domain(n);
        size_t offset = iok - r.start(n);
        size_t pt = offset/dom.nComponents();
        size_t comp = offset - pt*dom.nComponents();
        throw CanteraError("MultiNewton::step",
                           "Jacobian is singular for domain "+
                           dom.id() + ", component "
                           +dom.componentName(comp)+" at point "
                           +int2str(pt)+"\n(Matrix row "
                           +int2str(iok)+") \nsee file bandmatrix.csv\n");
    } else if (int(iok) < 0)
        throw CanteraError("MultiNewton::step",
                           "iok = "+int2str(iok));

#ifdef DEBUG_STEP
    bool ok = false;
    Domain1D* d;
    if (!ok) {
        for (size_t n = 0; n < sz; n++) {
            d = r.pointDomain(n);
            int nvd = d->nComponents();
            int pt = (n - d->loc())/nvd;
            cout << "step: " << pt << "  " <<
                 r.pointDomain(n)->componentName(n - d->loc() - nvd*pt)
                 << "    " << x[n] << "     " << ssave[n] << "   " << step[n] << endl;
        }
    }
#endif
}
示例#2
0
 /**
  * Return the factor by which the undamped Newton step 'step0'
  * must be multiplied in order to keep all solution components in
  * all domains between their specified lower and upper bounds.
  */
 doublereal MultiNewton::boundStep(const doublereal* x0, 
     const doublereal* step0, const OneDim& r, int loglevel) {
     doublereal fbound = 1.0;
     for (size_t i = 0; i < r.nDomains(); i++) {
         fbound = fminn(fbound, 
             bound_step(x0 + r.start(i), step0 + r.start(i),
             r.domain(i), loglevel));
     }
     return fbound;
 }
示例#3
0
 /**
  * Compute the weighted 2-norm of 'step'.
  */
 doublereal MultiNewton::norm2(const doublereal* x, 
     const doublereal* step, OneDim& r) const {
     doublereal f, sum = 0.0;//, fmx = 0.0;
     size_t nd = r.nDomains();
     for (size_t n = 0; n < nd; n++) {
         f = norm_square(x + r.start(n), step + r.start(n),
             r.domain(n));
         sum += f;
     }
     sum /= r.size();
     return sqrt(sum);
 }