Modest improvements to the routine. Still has a long way to go

This commit is contained in:
Harry Moffat 2010-09-29 23:01:05 +00:00
parent fd62251e6f
commit 1522cded0a
2 changed files with 290 additions and 108 deletions

View file

@ -72,6 +72,9 @@ namespace Cantera {
m_func(func), m_func(func),
solnType_(NSOLN_TYPE_STEADY_STATE), solnType_(NSOLN_TYPE_STEADY_STATE),
neq_(0), neq_(0),
m_ewt(0),
m_manualDeltaBoundsSet(0),
m_deltaBoundsMagnitudes(0),
delta_t_n(-1.0), delta_t_n(-1.0),
m_nfe(0), m_nfe(0),
m_colScaling(0), m_colScaling(0),
@ -91,6 +94,7 @@ namespace Cantera {
neq_ = m_func->nEquations(); neq_ = m_func->nEquations();
m_ewt.resize(neq_, rtol_); m_ewt.resize(neq_, rtol_);
m_deltaBoundsMagnitudes.resize(neq_, 0.001);
m_y_n.resize(neq_, 0.0); m_y_n.resize(neq_, 0.0);
m_y_nm1.resize(neq_, 0.0); m_y_nm1.resize(neq_, 0.0);
ydot_new.resize(neq_, 0.0); ydot_new.resize(neq_, 0.0);
@ -112,6 +116,9 @@ namespace Cantera {
m_func(right.m_func), m_func(right.m_func),
solnType_(NSOLN_TYPE_STEADY_STATE), solnType_(NSOLN_TYPE_STEADY_STATE),
neq_(0), neq_(0),
m_ewt(0),
m_manualDeltaBoundsSet(0),
m_deltaBoundsMagnitudes(0),
delta_t_n(-1.0), delta_t_n(-1.0),
m_nfe(0), m_nfe(0),
m_colScaling(0), m_colScaling(0),
@ -146,6 +153,8 @@ namespace Cantera {
solnType_ = right.solnType_; solnType_ = right.solnType_;
neq_ = right.neq_; neq_ = right.neq_;
m_ewt = right.m_ewt; m_ewt = right.m_ewt;
m_manualDeltaBoundsSet = right.m_manualDeltaBoundsSet;
m_deltaBoundsMagnitudes = right.m_deltaBoundsMagnitudes;
m_y_n = right.m_y_n; m_y_n = right.m_y_n;
m_y_nm1 = right.m_y_nm1; m_y_nm1 = right.m_y_nm1;
ydot_new = right.ydot_new; ydot_new = right.ydot_new;
@ -335,13 +344,13 @@ namespace Cantera {
// Calculate the current residual // Calculate the current residual
// Put the current residual into the vector, delta_y[] // Put the current residual into the vector, residual
// We need to pull this out of this function and carry it in. // We need to pull this out of this function and carry it in.
m_func->evalResidNJ(time_curr, delta_t_n, y_curr, ydot_curr, residual); m_func->evalResidNJ(time_curr, delta_t_n, y_curr, ydot_curr, residual);
m_nfe++; m_nfe++;
} }
//==================================================================================================================== //====================================================================================================================
// Compute the undamped Newton step // Compute the undamped Newton step
/* /*
* Compute the undamped Newton step. The residual function is * Compute the undamped Newton step. The residual function is
@ -356,7 +365,7 @@ namespace Cantera {
* scaling has been implemented. * scaling has been implemented.
*/ */
void NonlinearSolver::doNewtonSolve(const double time_curr, const double * const y_curr, void NonlinearSolver::doNewtonSolve(const double time_curr, const double * const y_curr,
const double * const ydot_curr, double* const delta_y, const double * const ydot_curr, double * const delta_y,
SquareMatrix& jac, int loglevel) SquareMatrix& jac, int loglevel)
{ {
int irow, jcol; int irow, jcol;
@ -393,15 +402,7 @@ namespace Cantera {
} }
} }
// if (m_matrixConditioning) {
// if (jac.m_factored) {
// m_func->matrixConditioning(0, neq_, delta_y);
// } else {
//double *jptr = &(*(jac.begin()));
// m_func->matrixConditioning(jptr, neq_, delta_y);
// }
//}
/* /*
* row sum scaling -> Note, this is an unequivical success * row sum scaling -> Note, this is an unequivical success
* at keeping the small numbers well balanced and * at keeping the small numbers well balanced and
@ -501,7 +502,138 @@ namespace Cantera {
m_numTotalLinearSolves++; m_numTotalLinearSolves++;
} }
//==================================================================================================================== //====================================================================================================================
/************************************************************************** void NonlinearSolver::setDefaultDeltaBoundsMagnitudes()
{
for (int i = 0; i < neq_; i++) {
m_deltaBoundsMagnitudes[i] = MAX(m_deltaBoundsMagnitudes[i], 1000. * atolk_[i]);
m_deltaBoundsMagnitudes[i] = MAX(m_deltaBoundsMagnitudes[i], 0.1 * fabs(m_y_n[i]));
}
}
//====================================================================================================================
void NonlinearSolver::setDeltaBoundsMagnitudes(const double * const deltaBoundsMagnitudes)
{
for (int i = 0; i < neq_; i++) {
m_deltaBoundsMagnitudes[i] = deltaBoundsMagnitudes[i];
}
m_manualDeltaBoundsSet = 1;
}
//====================================================================================================================
/*
*
* Return the factor by which the undamped Newton step 'step0'
* must be multiplied in order to keep the update within the bounds of an accurate jacobian.
*
* The idea behind these is that the Jacobian couldn't possibly be representative, if the
* variable is changed by a lot. (true for nonlinear systems, false for linear systems)
* Maximum increase in variable in any one newton iteration:
* factor of 1.5
* Maximum decrease in variable in any one newton iteration:
* factor of 2
*
* @param y Initial value of the solution vector
* @param step0 initial proposed step size
* @param loglevel log level
*
* @return returns the damping factor
*/
double
NonlinearSolver::deltaBoundStep(const double * const y, const double * const step0, const int loglevel) {
int i_fbounds = 0;
int ifbd = 0;
int i_fbd = 0;
double sameSign = 0.0;
double ff;
double f_delta_bounds = 1.0;
double ff_alt;
for (int i = 0; i < neq_; i++) {
double y_new = y[i] + step0[i];
sameSign = y_new * y[i];
/*
* Now do a delta bounds
* Increase variables by a factor of 1.5 only
* decrease variables by a factor of 2 only
*/
ff = 1.0;
if (sameSign >= 0.0) {
if ((fabs(y_new) > 1.5 * fabs(y[i])) &&
(fabs(y_new - y[i]) > m_deltaBoundsMagnitudes[i])) {
ff = 0.5 * fabs(y[i]/(y_new - y[i]));
ff_alt = fabs(m_deltaBoundsMagnitudes[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
ifbd = 1;
}
if ((fabs(2.0 * y_new) < fabs(y[i])) &&
(fabs(y_new - y[i]) > m_deltaBoundsMagnitudes[i])) {
ff = y[i]/(y_new - y[i]) * (1.0 - 2.0)/2.0;
ff_alt = fabs(m_deltaBoundsMagnitudes[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
ifbd = 0;
}
} else {
/*
* This handles the case where the value crosses the origin.
* - First we don't let it cross the origin until its shrunk to the size of m_deltaBoundsMagnitudes[i]
*/
if (fabs(y[i]) > m_deltaBoundsMagnitudes[i]) {
ff = y[i]/(y_new - y[i]) * (1.0 - 2.0)/2.0;
ff_alt = fabs(m_deltaBoundsMagnitudes[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
if (y[i] >= 0.0) {
ifbd = 0;
} else {
ifbd = 1;
}
}
/*
* Second when it does cross the origin, we make sure that its magnitude is only 50% of the previous value.
*/
else if (fabs(y_new) > 0.5 * fabs(y[i])) {
ff = y[i]/(y_new - y[i]) * (-1.5);
ff_alt = fabs(m_deltaBoundsMagnitudes[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
ifbd = 0;
}
}
if (ff < f_delta_bounds) {
f_delta_bounds = ff;
i_fbounds = i;
i_fbd = ifbd;
}
}
/*
* Report on any corrections
*/
if (loglevel > 1) {
if (f_delta_bounds < 1.0) {
if (i_fbd) {
printf("\t\tdeltaBoundStep: Increase of Variable %d causing "
"delta damping of %g\n",
i_fbounds, f_delta_bounds);
} else {
printf("\t\tdeltaBoundStep: Decrease of variable %d causing"
"delta damping of %g\n",
i_fbounds, f_delta_bounds);
}
}
}
return f_delta_bounds;
}
//====================================================================================================================
/*
* *
* boundStep(): * boundStep():
* *
@ -528,11 +660,10 @@ namespace Cantera {
* Maximum decrease in variable in any one newton iteration: * Maximum decrease in variable in any one newton iteration:
* factor of 5 * factor of 5
*/ */
double NonlinearSolver::boundStep(const double* const y, double NonlinearSolver::boundStep(const double * const y, const double * const step0, const int loglevel) {
const double* const step0, const int loglevel) { int i, i_lower = -1;
int i, i_lower = -1, i_fbounds, ifbd = 0, i_fbd = 0; double fbound = 1.0, f_bounds = 1.0;
double fbound = 1.0, f_bounds = 1.0, f_delta_bounds = 1.0; double ff, y_new;
double ff, y_new, ff_alt;
for (i = 0; i < neq_; i++) { for (i = 0; i < neq_; i++) {
y_new = y[i] + step0[i]; y_new = y[i] + step0[i];
@ -562,61 +693,26 @@ namespace Cantera {
} }
} }
} }
/*
* Now do a delta bounds
* Increase variables by a factor of 1.5 only
* decrease variables by a factor of 2 only
*/
ff = 1.0;
if ((fabs(y_new) > 1.5 * fabs(y[i])) &&
(fabs(y_new-y[i]) > m_ewt[i])) {
ff = 0.5 * fabs(y[i]/(y_new - y[i]));
ff_alt = fabs(m_ewt[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
ifbd = 1;
}
if ((fabs(2.0 * y_new) < fabs(y[i])) &&
(fabs(y_new - y[i]) > m_ewt[i])) {
ff = y[i]/(y_new - y[i]) * (1.0 - 2.0)/2.0;
ff_alt = fabs(m_ewt[i] / (y_new - y[i]));
ff = MAX(ff, ff_alt);
ifbd = 0;
}
if (ff < f_delta_bounds) {
f_delta_bounds = ff;
i_fbounds = i;
i_fbd = ifbd;
}
f_delta_bounds = MIN(f_delta_bounds, ff);
} }
fbound = MIN(f_bounds, f_delta_bounds);
/* /*
* Report on any corrections * Report on any corrections
*/ */
if (loglevel > 1) { if (loglevel > 1) {
if (fbound != 1.0) { if (f_bounds != 1.0) {
if (f_bounds < f_delta_bounds) { printf("\t\tboundStep: Variable %d causing bounds damping of %g\n", i_lower, f_bounds);
printf("\t\tboundStep: Variable %d causing bounds "
"damping of %g\n",
i_lower, f_bounds);
} else {
if (ifbd) {
printf("\t\tboundStep: Decrease of Variable %d causing "
"delta damping of %g\n",
i_fbounds, f_delta_bounds);
} else {
printf("\t\tboundStep: Increase of variable %d causing"
"delta damping of %g\n",
i_fbounds, f_delta_bounds);
}
}
} }
} }
//return fbound;
return 1.0; double f_delta_bounds = deltaBoundStep(y, step0, loglevel);
fbound = MIN(f_bounds, f_delta_bounds);
return fbound;
} }
//==================================================================================================================== //====================================================================================================================
/************************************************************************** /*
* *
* dampStep(): * dampStep():
* *
@ -678,14 +774,22 @@ namespace Cantera {
if (solnType_ != NSOLN_TYPE_STEADY_STATE) { if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
calc_ydot(m_order, y1, ydot1); calc_ydot(m_order, y1, ydot1);
} } else {
doResidualCalc(time_curr, NSOLN_TYPE_STEADY_STATE, y1, ydot1, step1, loglevel); }
if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
doResidualCalc(time_curr, solnType_, y1, ydot1, step1, loglevel);
} else {
doResidualCalc(time_curr, solnType_, y1, ydot0, step1, loglevel);
}
// compute the next undamped step, step1[], that would result // compute the next undamped step, step1[], that would result
// if y1[] were accepted. // if y1[] were accepted.
if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
doNewtonSolve(time_curr, y1, ydot1, step1, jac, loglevel); doNewtonSolve(time_curr, y1, ydot1, step1, jac, loglevel);
} else {
doNewtonSolve(time_curr, y1, ydot0, step1, jac, loglevel);
}
// compute the weighted norm of step1 // compute the weighted norm of step1
s1 = solnErrorNorm(step1); s1 = solnErrorNorm(step1);
@ -693,9 +797,9 @@ namespace Cantera {
// write log information // write log information
if (loglevel > 3) { if (loglevel > 3) {
print_solnDelta_norm_contrib((const double *) step0, print_solnDelta_norm_contrib((const double *) step0,
"DeltaSolnTrial", "DeltaSoln",
(const double *) step1, (const double *) step1,
"DeltaSolnTrialTest", "DeltaSolnTrial",
"dampNewt: Important Entries for " "dampNewt: Important Entries for "
"Weighted Soln Updates:", "Weighted Soln Updates:",
y0, y1, ff, 5); y0, y1, ff, 5);
@ -793,8 +897,9 @@ namespace Cantera {
mdp::mdp_copy_dbl_1(DATA_PTR(y_curr), y_comm, neq_); mdp::mdp_copy_dbl_1(DATA_PTR(y_curr), y_comm, neq_);
// copyn((size_t)neq_, y_comm, y_curr); // copyn((size_t)neq_, y_comm, y_curr);
if (SolnType != NSOLN_TYPE_STEADY_STATE) { if (SolnType != NSOLN_TYPE_STEADY_STATE || ydot_comm) {
mdp::mdp_copy_dbl_1(DATA_PTR(ydot_curr), ydot_comm, neq_); mdp::mdp_copy_dbl_1(DATA_PTR(ydot_curr), ydot_comm, neq_);
mdp::mdp_copy_dbl_1(DATA_PTR(ydot_new), ydot_comm, neq_);
} }
@ -805,6 +910,9 @@ namespace Cantera {
int i_backtracks; int i_backtracks;
int loglevel = loglevelInput; int loglevel = loglevelInput;
while (1 > 0) { while (1 > 0) {
/* /*
@ -813,6 +921,13 @@ namespace Cantera {
m_numTotalNewtIts++; m_numTotalNewtIts++;
num_newt_its++; num_newt_its++;
mdp::mdp_copy_dbl_1(DATA_PTR(m_y_n), DATA_PTR(y_curr), neq_);
/*
* Set default values of Delta bounds constraints
*/
if (!m_manualDeltaBoundsSet) {
setDefaultDeltaBoundsMagnitudes();
}
if (loglevel > 1) { if (loglevel > 1) {
printf("\t\tSolve_Nonlinear_Problem: iteration %d:\n", printf("\t\tSolve_Nonlinear_Problem: iteration %d:\n",
@ -930,8 +1045,9 @@ namespace Cantera {
done: done:
mdp::mdp_copy_dbl_1(y_comm, DATA_PTR(y_curr), neq_); mdp::mdp_copy_dbl_1(y_comm, DATA_PTR(y_curr), neq_);
mdp::mdp_copy_dbl_1(ydot_comm, DATA_PTR(ydot_curr), neq_); if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
mdp::mdp_copy_dbl_1(ydot_comm, DATA_PTR(ydot_curr), neq_);
}
num_linear_solves += m_numTotalLinearSolves; num_linear_solves += m_numTotalLinearSolves;
@ -945,8 +1061,8 @@ namespace Cantera {
} }
return m; return m;
} }
//==================================================================================================================== //====================================================================================================================
/***************************************************************8 /*
* *
* *
*/ */
@ -964,10 +1080,10 @@ namespace Cantera {
bool used; bool used;
double dmax0, dmax1, error, rel_norm; double dmax0, dmax1, error, rel_norm;
printf("\t\t%s currentDamp = %g\n", title, damp); printf("\t\t%s currentDamp = %g\n", title, damp);
printf("\t\t I ysoln %10s ysolnTrial " printf("\t\t I ysolnOld %10s ysolnNewRaw ysolnNewTrial "
"%10s weight relSoln0 relSoln1\n", s0, s1); "%10s ysolnNewTrialRaw solnWeight wtDelSoln wtDelSolnTrial\n", s0, s1);
int *imax = mdp::mdp_alloc_int_1(num_entries, -1); int *imax = mdp::mdp_alloc_int_1(num_entries, -1);
printf("\t\t "); print_line("-", 90); printf("\t\t "); print_line("-", 120);
for (jnum = 0; jnum < num_entries; jnum++) { for (jnum = 0; jnum < num_entries; jnum++) {
dmax1 = -1.0; dmax1 = -1.0;
for (i = 0; i < neq_; i++) { for (i = 0; i < neq_; i++) {
@ -992,13 +1108,12 @@ namespace Cantera {
dmax0 = sqrt(error * error); dmax0 = sqrt(error * error);
error = solnDelta1[i] / m_ewt[i]; error = solnDelta1[i] / m_ewt[i];
dmax1 = sqrt(error * error); dmax1 = sqrt(error * error);
printf("\t\t %4d %12.4e %12.4e %12.4e %12.4e " printf("\t\t %4d %12.4e %12.4e %12.4e | %12.4e %12.4e %12.4e | %12.4e %12.4e %12.4e\n",
"%12.4e %12.4e %12.4e\n", i, y0[i], solnDelta0[i], y0[i] + solnDelta0[i], y1[i],
i, y0[i], solnDelta0[i], y1[i], solnDelta1[i], y1[i]+ solnDelta1[i], m_ewt[i], dmax0, dmax1);
solnDelta1[i], m_ewt[i], dmax0, dmax1);
} }
} }
printf("\t\t "); print_line("-", 90); printf("\t\t "); print_line("-", 120);
mdp::mdp_safe_free((void **) &imax); mdp::mdp_safe_free((void **) &imax);
} }
//==================================================================================================================== //====================================================================================================================
@ -1032,7 +1147,7 @@ namespace Cantera {
} }
return diff; return diff;
} }
//================================================================================================ //====================================================================================================================
/* /*
* *
* Function called by BEuler to evaluate the Jacobian matrix and the * Function called by BEuler to evaluate the Jacobian matrix and the
@ -1130,8 +1245,10 @@ namespace Cantera {
y[j] = ysave + dy; y[j] = ysave + dy;
dy = y[j] - ysave; dy = y[j] - ysave;
ydotsave = ydot[j]; if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
ydot[j] += dy * CJ; ydotsave = ydot[j];
ydot[j] += dy * CJ;
}
/* /*
* Call the functon * Call the functon
*/ */
@ -1146,9 +1263,10 @@ namespace Cantera {
col_j[i] = diff / dy; col_j[i] = diff / dy;
//col_j[i] = (m_wksp[i] - f[i])/dy; //col_j[i] = (m_wksp[i] - f[i])/dy;
} }
y[j] = ysave;
y[j] = ysave; if (solnType_ != NSOLN_TYPE_STEADY_STATE) {
ydot[j] = ydotsave; ydot[j] = ydotsave;
}
} }
/* /*
@ -1160,8 +1278,14 @@ namespace Cantera {
} }
//==================================================================================================================== //====================================================================================================================
// Internal function to calculate the time derivative at the new step
/*
* @param order of the BDF method
* @param y_curr current value of the solution
* @param ydot_curr Calculated value of the solution derivative that is consistent with y_curr
*/
void NonlinearSolver:: void NonlinearSolver::
calc_ydot(int order, double *y_curr, double *ydot_curr) calc_ydot(const int order, const double * const y_curr, double * const ydot_curr)
{ {
if (!ydot_curr) { if (!ydot_curr) {
return; return;
@ -1185,17 +1309,18 @@ namespace Cantera {
return; return;
} }
} }
//================================================================================================ //====================================================================================================================
// Apply a filtering step
/* /*
* filterNewStep(): * @param timeCurrent Current value of the time
* * @param y_current current value of the solution
* void BEulerInt:: * @param ydot_current Current value of the solution derivative.
* *
* @return Returns the norm of the value of the amount filtered
*/ */
double NonlinearSolver::filterNewStep(double timeCurrent, double *y_current, double *ydot_current) { double NonlinearSolver::filterNewStep(const double timeCurrent, double * const y_current, double *const ydot_current) {
return 0.0; return 0.0;
} }
//==================================================================================================================== //====================================================================================================================
} }

View file

@ -144,12 +144,33 @@ namespace Cantera {
* recomputed. The row scales are recomputed here, after column * recomputed. The row scales are recomputed here, after column
* scaling has been implemented. * scaling has been implemented.
* *
* @param timeCurrent Current value of the time
* @param y_current Current value of the solution
* @param ydot_current Current value of the solution derivative.
*
*/ */
void doNewtonSolve(const double time_curr, const double * const y_curr, void doNewtonSolve(const double time_curr, const double * const y_curr,
const double * const ydot_curr, double* const delta_y, const double * const ydot_curr, double* const delta_y,
SquareMatrix& jac, int loglevel); SquareMatrix& jac, int loglevel);
//! Set default deulta bounds amounts
/*!
* Delta bounds are set to 0.01 for all unknowns arbitrarily and capriciously
* Then, for each call to the nonlinear solver
* Then, they are increased to 1000 x atol
* then, they are increased to 0.1 fab(y[i])
*/
void setDefaultDeltaBoundsMagnitudes();
//! Set the delta Bounds magnitudes by hand
/*!
* @param deltaboundsMagnitudes
*/
void setDeltaBoundsMagnitudes(const double * const deltaBoundsMagnitudes);
//! //! Bound the step
/*! /*!
* *
* Return the factor by which the undamped Newton step 'step0' * Return the factor by which the undamped Newton step 'step0'
@ -194,13 +215,14 @@ namespace Cantera {
*/ */
void calc_y_pred(int); void calc_y_pred(int);
/**
* Internal function to calculate the time derivative at the //! Internal function to calculate the time derivative at the new step
* new step /*!
*/ * @param order of the BDF method
void calc_ydot(int, double *, double *); * @param y_curr current value of the solution
* @param ydot_curr Calculated value of the solution derivative that is consistent with y_curr
*/
void calc_ydot(const int order, const double * const y_curr, double * const ydot_curr);
//! Function called to evaluate the jacobian matrix and the curent //! Function called to evaluate the jacobian matrix and the curent
//! residual vector. //! residual vector.
@ -213,8 +235,36 @@ namespace Cantera {
double * const ydot, int num_newt_its); double * const ydot, int num_newt_its);
double filterNewStep(double, double *, double *); //! Apply a filtering step
/*!
* @param timeCurrent Current value of the time
* @param y_current current value of the solution
* @param ydot_current Current value of the solution derivative.
*
* @return Returns the norm of the value of the amount filtered
*/
double filterNewStep(const double timeCurrent, double * const y_current, double * const ydot_current);
//! Return the factor by which the undamped Newton step 'step0'
//! must be multiplied in order to keep the update within the bounds of an accurate jacobian.
/*!
*
* The idea behind these is that the Jacobian couldn't possibly be representative, if the
* variable is changed by a lot. (true for nonlinear systems, false for linear systems)
* Maximum increase in variable in any one newton iteration:
* factor of 1.5
* Maximum decrease in variable in any one newton iteration:
* factor of 2
*
* @param y Initial value of the solution vector
* @param step0 initial proposed step size
* @param loglevel log level
*
* @return returns the damping factor
*/
double deltaBoundStep(const double * const y, const double * const step0, const int loglevel);
//! Find a damping coefficient through a look-ahead mechanism //! Find a damping coefficient through a look-ahead mechanism
/*! /*!
* On entry, step0 must contain an undamped Newton step for the * On entry, step0 must contain an undamped Newton step for the
@ -242,8 +292,6 @@ namespace Cantera {
// Compute the weighted norm of the undamped step size step0
//! Find the solution to F(X) = 0 by damped Newton iteration. //! Find the solution to F(X) = 0 by damped Newton iteration.
/*! /*!
* On * On
@ -265,8 +313,11 @@ namespace Cantera {
int loglevelInput); int loglevelInput);
//! Set the column scales
void setColumnScales(); void setColumnScales();
//! Print solution norm contribution
void void
print_solnDelta_norm_contrib(const double * const solnDelta0, print_solnDelta_norm_contrib(const double * const solnDelta0,
const char * const s0, const char * const s0,
@ -296,6 +347,12 @@ namespace Cantera {
//! Soln error weights //! Soln error weights
std::vector<doublereal> m_ewt; std::vector<doublereal> m_ewt;
//! Boolean indicating whether a manual delta bounds has been input.
int m_manualDeltaBoundsSet;
//! Soln Delta bounds magnitudes
std::vector<doublereal> m_deltaBoundsMagnitudes;
std::vector<doublereal> m_y_n; std::vector<doublereal> m_y_n;
std::vector<doublereal> m_y_nm1; std::vector<doublereal> m_y_nm1;