Modest improvements to the routine. Still has a long way to go
This commit is contained in:
parent
fd62251e6f
commit
1522cded0a
2 changed files with 290 additions and 108 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================================================================================================================
|
//====================================================================================================================
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue