示例#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
}