46 for (
int i = 0; i < n; i++) {
52 bool NonlinearSolver::s_TurnOffTiming(
false);
55 bool NonlinearSolver::s_print_NumJac(
true);
57 bool NonlinearSolver::s_print_NumJac(
false);
61 bool NonlinearSolver::s_print_DogLeg(
false);
67 bool NonlinearSolver::s_doBothSolvesAndCompare(
false);
73 bool NonlinearSolver::s_alwaysAssumeNewtonGood(
false);
80 m_manualDeltaStepSet(0),
81 m_deltaStepMinimum(0),
96 m_normResid_Bound(0.0),
98 m_normDeltaSoln_Newton(0.0),
99 m_normDeltaSoln_CP(0.0),
100 m_normResidTrial(0.0),
101 m_resid_scaled(false),
110 m_numTotalLinearSolves(0),
111 m_numTotalNewtIts(0),
114 m_jacFormMethod(NSOLN_JAC_NUM),
117 m_matrixConditioning(0),
123 userResidRtol_(1.0E-3),
124 checkUserResidualTols_(0),
126 m_ScaleSolnNormToResNorm(0.001),
131 residNorm2Cauchy_(0.0),
138 norm_deltaX_trust_(0.0),
140 trustRegionInitializationMethod_(2),
141 trustRegionInitializationFactor_(1.0),
148 normTrust_Newton_(0.0),
152 CurrentTrustFactor_(1.0),
153 NextTrustFactor_(1.0),
154 ResidWtsReevaluated_(false),
155 ResidDecreaseSDExp_(0.0),
156 ResidDecreaseSD_(0.0),
157 ResidDecreaseNewtExp_(0.0),
158 ResidDecreaseNewt_(0.0)
182 doublereal hb = std::numeric_limits<double>::max();
186 for (
size_t i = 0; i <
neq_; i++) {
194 Jd_.resize(neq_, 0.0);
199 m_func(right.m_func),
203 m_manualDeltaStepSet(0),
204 m_deltaStepMinimum(0),
220 m_normResid_Bound(0.0),
222 m_normDeltaSoln_Newton(0.0),
223 m_normDeltaSoln_CP(0.0),
224 m_normResidTrial(0.0),
225 m_resid_scaled(false),
234 m_numTotalLinearSolves(0),
235 m_numTotalNewtIts(0),
238 m_jacFormMethod(NSOLN_JAC_NUM),
241 m_matrixConditioning(0),
247 userResidRtol_(1.0E-3),
248 checkUserResidualTols_(0),
250 m_ScaleSolnNormToResNorm(0.001),
255 residNorm2Cauchy_(0.0),
262 norm_deltaX_trust_(0.0),
264 trustRegionInitializationMethod_(2),
265 trustRegionInitializationFactor_(1.0),
272 normTrust_Newton_(0.0),
276 CurrentTrustFactor_(1.0),
277 NextTrustFactor_(1.0),
278 ResidWtsReevaluated_(false),
279 ResidDecreaseSDExp_(0.0),
280 ResidDecreaseSD_(0.0),
281 ResidDecreaseNewtExp_(0.0),
282 ResidDecreaseNewt_(0.0)
295 if (
this == &right) {
396 for (
size_t i = 0; i <
neq_; i++) {
399 if (
m_ewt[i] <= 0.0) {
400 throw CanteraError(
" NonlinearSolver::createSolnWeights()",
"ewts <= 0.0");
407 const doublereal*
const y_high_bounds)
409 for (
size_t i = 0; i <
neq_; i++) {
432 const doublereal dampFactor)
const
434 doublereal sum_norm = 0.0,
error;
435 for (
size_t i = 0; i <
neq_; i++) {
439 sum_norm = sqrt(sum_norm / neq_);
443 printf(
"\t\t solnErrorNorm(): ");
447 printf(
" Delta soln norm ");
449 printf(
" = %-11.4E\n", sum_norm);
454 const int num_entries = printLargest;
457 printf(
"\t\t solnErrorNorm(): ");
461 printf(
" Delta soln norm ");
463 printf(
" = %-11.4E\n", sum_norm);
465 doublereal dmax1, normContrib;
467 std::vector<size_t> imax(num_entries,
npos);
468 printf(
"\t\t Printout of Largest Contributors: (damp = %g)\n", dampFactor);
469 printf(
"\t\t I weightdeltaY/sqtN| deltaY "
470 "ysolnOld ysolnNew Soln_Weights\n");
474 for (
int jnum = 0; jnum < num_entries; jnum++) {
476 for (
size_t i = 0; i <
neq_; i++) {
478 for (j = 0; j < jnum; j++) {
486 if (normContrib > dmax1) {
492 size_t i = imax[jnum];
496 printf(
"\t\t %4s %12.4e | %12.4e %12.4e %12.4e %12.4e\n",
int2str(i).c_str(), normContrib/sqrt((
double)neq_),
509 const doublereal*
const y)
const
511 doublereal sum_norm = 0.0,
error;
513 for (
size_t i = 0; i <
neq_; i++) {
523 sum_norm = sqrt(sum_norm / neq_);
528 const int num_entries = printLargest;
529 doublereal dmax1, normContrib;
531 std::vector<size_t> imax(num_entries,
npos);
534 printf(
"\t\t residErrorNorm():");
536 printf(
" %s ", title);
538 printf(
" residual L2 norm ");
540 printf(
"= %12.4E\n", sum_norm);
545 printf(
"\t\t residErrorNorm(): ");
547 printf(
" %s ", title);
549 printf(
" residual L2 norm ");
551 printf(
"= %12.4E\n", sum_norm);
552 printf(
"\t\t Printout of Largest Contributors to norm:\n");
553 printf(
"\t\t I |Resid/ResWt| UnsclRes ResWt | y_curr\n");
556 for (
int jnum = 0; jnum < num_entries; jnum++) {
558 for (
size_t i = 0; i <
neq_; i++) {
560 for (j = 0; j < jnum; j++) {
568 if (normContrib > dmax1) {
574 size_t i = imax[jnum];
578 printf(
"\t\t %4s %12.4e %12.4e %12.4e | %12.4e\n",
int2str(i).c_str(), normContrib, resid[i],
m_residWts[i], y[i]);
594 for (
size_t i = 0; i <
neq_; i++) {
597 throw CanteraError(
"NonlinearSolver::setColumnScaling() ERROR",
"Bad column scale factor");
616 for (
size_t i = 0; i <
neq_; i++) {
620 for (
size_t i = 0; i <
neq_; i++) {
639 doublereal time_curr,
int num_newt_its)
662 doublereal* jptr = &(*(jac.
begin()));
663 for (jcol = 0; jcol < (int)
neq_; jcol++) {
664 for (irow = 0; irow < (int)
neq_; irow++) {
670 int kl =
static_cast<int>(ivec[0]);
671 int ku =
static_cast<int>(ivec[1]);
672 for (jcol = 0; jcol < (int)
neq_; jcol++) {
673 colP_j = (doublereal*) jac.
ptrColumn(jcol);
674 for (irow = jcol - ku; irow <= jcol + kl; irow++) {
675 if (irow >= 0 && irow < (
int)
neq_) {
676 colP_j[kl + ku + irow - jcol] *=
m_colScales[jcol];
693 doublereal* jptr = &(*(jac.
begin()));
694 for (irow = 0; irow < (int)
neq_; irow++) {
699 for (jcol = 0; jcol < (int)
neq_; jcol++) {
700 for (irow = 0; irow < (int)
neq_; irow++) {
718 int kl =
static_cast<int>(ivec[0]);
719 int ku =
static_cast<int>(ivec[1]);
720 for (jcol = 0; jcol < (int)
neq_; jcol++) {
721 colP_j = (doublereal*) jac.
ptrColumn(jcol);
722 for (irow = jcol - ku; irow <= jcol + kl; irow++) {
723 if (irow >= 0 && irow < (
int)
neq_) {
724 double vv = fabs(colP_j[kl + ku + irow - jcol]);
743 for (irow = 0; irow < (int)
neq_; irow++) {
747 for (irow = 0; irow < (int)
neq_; irow++) {
756 jptr = &(*(jac.
begin()));
757 for (jcol = 0; jcol < (int)
neq_; jcol++) {
758 for (irow = 0; irow < (int)
neq_; irow++) {
764 int kl =
static_cast<int>(ivec[0]);
765 int ku =
static_cast<int>(ivec[1]);
766 for (jcol = 0; jcol < (int)
neq_; jcol++) {
767 colP_j = (doublereal*) jac.
ptrColumn(jcol);
768 for (irow = jcol - ku; irow <= jcol + kl; irow++) {
769 if (irow >= 0 && irow < (
int)
neq_) {
770 colP_j[kl + ku + irow - jcol] *=
m_rowScales[irow];
777 if (num_newt_its % 5 == 1) {
789 doublereal sum = 0.0;
790 for (
size_t irow = 0; irow <
neq_; irow++) {
795 for (
size_t irow = 0; irow <
neq_; irow++) {
799 for (
size_t irow = 0; irow <
neq_; irow++) {
804 for (
size_t irow = 0; irow <
neq_; irow++) {
810 for (
size_t irow = 0; irow <
neq_; irow++) {
813 doublereal* jptr = &(
jacCopyPtr_->operator()(0,0));
814 for (
size_t jcol = 0; jcol <
neq_; jcol++) {
815 for (
size_t irow = 0; irow <
neq_; irow++) {
820 doublereal resNormOld = 0.0;
823 for (
size_t irow = 0; irow <
neq_; irow++) {
825 resNormOld += error *
error;
827 resNormOld = sqrt(resNormOld / neq_);
829 if (resNormOld > 0.0) {
839 throw CanteraError(
"NonlinearSolver::calcSolnToResNormVector()" ,
"Logic error");
844 const doublereal*
const ydot_curr, doublereal*
const delta_y,
849 for (
size_t n = 0; n <
neq_; n++) {
854 for (
size_t n = 0; n <
neq_; n++) {
872 for (
size_t irow = 0; irow <
neq_; irow++) {
878 if (printJacContributions) {
879 for (
size_t iNum = 0; iNum < numRows; iNum++) {
883 doublereal dsum = 0.0;
885 doublereal dRow = Jdata[
neq_ * focusRow + focusRow];
886 printf(
"\n Details on delta_Y for row %d \n", focusRow);
887 printf(
" Value before = %15.5e, delta = %15.5e,"
888 "value after = %15.5e\n", y_curr[focusRow],
889 delta_y[focusRow], y_curr[focusRow] + delta_y[focusRow]);
891 printf(
" Old Jacobian\n");
893 printf(
" col delta_y aij "
895 printf(
"--------------------------------------------------"
896 "---------------------------------------------\n");
897 printf(
" Res(%d) %15.5e %15.5e %15.5e (Res = %g)\n",
898 focusRow, delta_y[focusRow],
899 dRow, RRow[iNum] / dRow, RRow[iNum]);
900 dsum += RRow[iNum] / dRow;
901 for (
size_t ii = 0; ii <
neq_; ii++) {
902 if (ii != focusRow) {
903 doublereal aij = Jdata[neq_ * ii + focusRow];
904 doublereal contrib = aij * delta_y[ii] * (-1.0) / dRow;
906 if (fabs(contrib) > Pcutoff) {
907 printf(
"%6d %15.5e %15.5e %15.5e\n", ii,
908 delta_y[ii] , aij, contrib);
912 printf(
"--------------------------------------------------"
913 "---------------------------------------------\n");
914 printf(
" %15.5e %15.5e\n",
915 delta_y[focusRow], dsum);
935 bool newtonGood =
true;
942 for (
size_t n = 0; n <
neq_; n++) {
947 for (
size_t n = 0; n <
neq_; n++) {
967 doublereal rcond = 0.0;
971 doublereal a1norm = jac.
oneNorm();
972 rcond = jac.
rcond(a1norm);
981 printf(
"\t\t doAffineNewtonSolve: ");
983 printf(
"factorQR()");
987 printf(
" returned with info = %d, indicating a zero row or column\n", info);
990 bool doHessian =
false;
996 printf(
"\t\t doAffineNewtonSolve: Condition number = %g during regular solve\n",
m_conditionNumber);
1005 printf(
"\t\t doAffineNewtonSolve() ERROR: QRSolve returned INFO = %d. Switching to Hessian solve\n", info);
1014 for (
size_t irow = 0; irow <
neq_; irow++) {
1015 delta_y[irow] = delta_y[irow] *
m_colScales[irow];
1023 printf(
"\t\t doAffineNewtonSolve() WARNING: Condition number too large, %g, But Banded Hessian solve "
1030 printf(
"\t\t doAffineNewtonSolve() WARNING: Condition number too large, %g. Doing a Hessian solve \n",
m_conditionNumber);
1038 for (
size_t irow = 0; irow <
neq_; irow++) {
1039 delyNewton[irow] = delta_y[irow];
1054 for (
size_t i = 0; i <
neq_; i++) {
1055 for (
size_t j = i; j <
neq_; j++) {
1056 for (
size_t k = 0; k <
neq_; k++) {
1059 hessian(j,i) = hessian(i,j);
1063 for (
size_t i = 0; i <
neq_; i++) {
1064 for (
size_t j = i; j <
neq_; j++) {
1065 for (
size_t k = 0; k <
neq_; k++) {
1066 hessian(i,j) += jacCopy(k,i) * jacCopy(k,j);
1068 hessian(j,i) = hessian(i,j);
1076 doublereal hnorm = 0.0;
1077 doublereal hcol = 0.0;
1079 for (
size_t i = 0; i <
neq_; i++) {
1080 for (
size_t j = i; j <
neq_; j++) {
1083 for (
size_t j = i+1; j <
neq_; j++) {
1092 for (
size_t i = 0; i <
neq_; i++) {
1093 for (
size_t j = i; j <
neq_; j++) {
1094 hcol += fabs(hessian(j,i));
1096 for (
size_t j = i+1; j <
neq_; j++) {
1097 hcol += fabs(hessian(i,j));
1108 hcol = sqrt(static_cast<double>(neq_)) * 1.0E-7 * hnorm;
1109 #ifdef DEBUG_HKM_NOT
1115 for (
size_t i = 0; i <
neq_; i++) {
1119 for (
size_t i = 0; i <
neq_; i++) {
1120 hessian(i,i) += hcol;
1131 printf(
"\t\t doAffineNewtonSolve() ERROR: Hessian isn't positive definate DPOTRF returned INFO = %d\n", info);
1140 for (
size_t n = 0; n <
neq_; n++) {
1144 for (
size_t n = 0; n <
neq_; n++) {
1150 for (
size_t j = 0; j <
neq_; j++) {
1152 for (
size_t i = 0; i <
neq_; i++) {
1153 delta_y[j] += delyH[i] * jacCopy(i,j) *
m_rowScales[i];
1157 for (
size_t j = 0; j <
neq_; j++) {
1159 for (
size_t i = 0; i <
neq_; i++) {
1160 delta_y[j] += delyH[i] * jacCopy(i,j);
1169 ct_dpotrs(ctlapack::UpperTriangular, neq_, 1,&(*(hessian.
begin())),
neq_, delta_y,
neq_, info);
1172 printf(
"\t\t NonlinearSolver::doAffineNewtonSolve() ERROR: DPOTRS returned INFO = %d\n", info);
1180 for (
size_t irow = 0; irow <
neq_; irow++) {
1181 delta_y[irow] = delta_y[irow] *
m_colScales[irow];
1189 printf(
"\t\t doAffineNewtonSolve(): Printout Comparison between Hessian deltaX and Newton deltaX\n");
1191 printf(
"\t\t I Hessian+Junk Newton");
1193 printf(
" (USING NEWTON DIRECTION)\n");
1195 printf(
" (USING HESSIAN DIRECTION)\n");
1197 printf(
"\t\t Norm: %12.4E %12.4E\n", normHess, normNewt);
1199 printf(
"\t\t --------------------------------------------------------\n");
1200 for (
size_t i = 0; i <
neq_; i++) {
1201 printf(
"\t\t %3s %13.5E %13.5E\n",
int2str(i).c_str(), delta_y[i], delyNewton[i]);
1203 printf(
"\t\t --------------------------------------------------------\n");
1207 printf(
"\t\t doAffineNewtonSolve(): Hessian update norm = %12.4E \n"
1208 "\t\t Newton update norm = %12.4E \n", normHess, normNewt);
1210 printf(
"\t\t (USING NEWTON DIRECTION)\n");
1212 printf(
"\t\t (USING HESSIAN DIRECTION)\n");
1220 copy(delyNewton.begin(), delyNewton.end(), delta_y);
1225 if (printJacContributions) {
1226 for (
int iNum = 0; iNum < numRows; iNum++) {
1230 doublereal dsum = 0.0;
1232 doublereal dRow = Jdata[
neq_ * focusRow + focusRow];
1233 printf(
"\n Details on delta_Y for row %d \n", focusRow);
1234 printf(
" Value before = %15.5e, delta = %15.5e,"
1235 "value after = %15.5e\n", y_curr[focusRow],
1236 delta_y[focusRow], y_curr[focusRow] + delta_y[focusRow]);
1238 printf(
" Old Jacobian\n");
1240 printf(
" col delta_y aij "
1242 printf(
"-----------------------------------------------------------------------------------------------\n");
1243 printf(
" Res(%d) %15.5e %15.5e %15.5e (Res = %g)\n",
1244 focusRow, delta_y[focusRow],
1245 dRow, RRow[iNum] / dRow, RRow[iNum]);
1246 dsum += RRow[iNum] / dRow;
1247 for (
int ii = 0; ii <
neq_; ii++) {
1248 if (ii != focusRow) {
1249 doublereal aij = Jdata[neq_ * ii + focusRow];
1250 doublereal contrib = aij * delta_y[ii] * (-1.0) / dRow;
1252 if (fabs(contrib) > Pcutoff) {
1253 printf(
"%6d %15.5e %15.5e %15.5e\n", ii,
1254 delta_y[ii] , aij, contrib);
1258 printf(
"-----------------------------------------------------------------------------------------------\n");
1259 printf(
" %15.5e %15.5e\n",
1260 delta_y[focusRow], dsum);
1274 doublereal rowFac = 1.0;
1275 doublereal colFac = 1.0;
1276 doublereal normSoln;
1287 for (
size_t j = 0; j <
neq_; j++) {
1292 for (
size_t i = 0; i <
neq_; i++) {
1307 for (
size_t i = 0; i <
neq_; i++) {
1314 for (
size_t j = 0; j <
neq_; j++) {
1328 for (
size_t i = 0; i <
neq_; i++) {
1339 throw CanteraError(
"NonlinearSolver::doCauchyPointSolve()",
"Unexpected condition: norms are zero");
1350 for (
size_t i = 0; i <
neq_; i++) {
1370 doublereal residCauchy = 0.0;
1387 printf(
"\t\t doCauchyPointSolve: Steepest descent to Cauchy point: \n");
1389 printf(
"\t\t\t Rpred = %g\n", residCauchy);
1392 printf(
"\t\t\t deltaX = %g\n", normSoln);
1404 doublereal ff = 1.0E-5;
1405 doublereal ffNewt = 1.0E-5;
1408 if (cauchyDistanceNorm < 1.0E-2) {
1409 ff = 1.0E-9 / cauchyDistanceNorm;
1414 for (
size_t i = 0; i <
neq_; i++) {
1429 doublereal residSteep2 = residSteep * residSteep *
neq_;
1430 doublereal funcDecreaseSD = 0.5 * (residSteep2 - normResid02) / (ff * cauchyDistanceNorm);
1434 ffNewt = ffNewt / sNewt;
1436 for (
size_t i = 0; i <
neq_; i++) {
1452 doublereal residNewt2 = residNewt * residNewt *
neq_;
1454 doublereal funcDecreaseNewt2 = 0.5 * (residNewt2 - normResid02) / (ffNewt * sNewt);
1460 doublereal funcDecreaseNewtExp2 = - normResid02 / sNewt;
1486 printf(
"\t\t descentComparison: initial rate of decrease of func in cauchy dir (expected) = %g\n", funcDecreaseSDExp);
1487 printf(
"\t\t descentComparison: initial rate of decrease of func in cauchy dir = %g\n", funcDecreaseSD);
1488 printf(
"\t\t descentComparison: initial rate of decrease of func in newton dir (expected) = %g\n", funcDecreaseNewtExp2);
1489 printf(
"\t\t descentComparison: initial rate of decrease of func in newton dir = %g\n", funcDecreaseNewt2);
1492 printf(
"\t\t descentComparison: initial rate of decrease of Resid in cauchy dir (expected) = %g\n",
ResidDecreaseSDExp_);
1493 printf(
"\t\t descentComparison: initial rate of decrease of Resid in cauchy dir = %g\n",
ResidDecreaseSD_);
1494 printf(
"\t\t descentComparison: initial rate of decrease of Resid in newton dir (expected) = %g\n",
ResidDecreaseNewtExp_);
1495 printf(
"\t\t descentComparison: initial rate of decrease of Resid in newton dir = %g\n",
ResidDecreaseNewt_);
1499 if (funcDecreaseNewt2 >= 0.0) {
1500 printf(
"\t\t %13.5E %22.16E\n", funcDecreaseNewtExp2,
m_normResid_0);
1501 double ff = ffNewt * 1.0E-5;
1502 for (
int ii = 0; ii < 13; ii++) {
1507 for (
size_t i = 0; i <
neq_; i++) {
1517 residNewt2 = residNewt * residNewt *
neq_;
1518 funcDecreaseNewt2 = 0.5 * (residNewt2 - normResid02) / (ff * sNewt);
1519 printf(
"\t\t %10.3E %13.5E %22.16E\n", ff, funcDecreaseNewt2, residNewt);
1557 doublereal Nres2CP = residSteepLin * residSteepLin *
neq_;
1559 doublereal a = Nres2CP / Nres2_o;
1560 doublereal betaEqual = (2.0 - sqrt(4.0 - 4 * (1.0 - a))) / 2.0;
1561 doublereal beta = (1.0 + betaEqual) / 2.0;
1567 for (
size_t i = 0; i <
neq_; i++) {
1597 doublereal resD2, res2, resNorm;
1607 doublereal tmp = - 2.0 * alpha + alpha * alpha;
1611 }
else if (leg == 1) {
1617 doublereal RdotJS = - tmp2;
1618 doublereal JsJs = tmp2;
1623 res2 = res0_2 + (1.0 - alpha) * 2 * RdotJS - 2 * alpha *
Nuu_ * res0_2
1624 + (1.0 - alpha) * (1.0 - alpha) * JsJs
1625 + alpha * alpha *
Nuu_ *
Nuu_ * res0_2
1626 - 2 * alpha *
Nuu_ * (1.0 - alpha) * RdotJS;
1628 return sqrt(res2 / neq_);
1631 doublereal beta =
Nuu_ + alpha * (1.0 -
Nuu_);
1632 doublereal tmp2 = normResid02;
1633 doublereal tmp = 1.0 - 2.0 * beta + 1.0 * beta * beta - 1.0;
1641 resNorm = sqrt(res2 / neq_);
1649 doublereal& alphaBest)
const
1654 doublereal alpha = 0;
1656 doublereal residSteepBest = 1.0E300;
1657 doublereal residSteepLinBest = 0.0;
1659 printf(
"\t\t residualComparisonLeg() \n");
1660 printf(
"\t\t Point StepLen Residual_Actual Residual_Linear RelativeMatch\n");
1663 std::vector<doublereal> alphaT;
1664 alphaT.push_back(0.00);
1665 alphaT.push_back(0.01);
1666 alphaT.push_back(0.1);
1667 alphaT.push_back(0.25);
1668 alphaT.push_back(0.50);
1669 alphaT.push_back(0.75);
1670 alphaT.push_back(1.0);
1671 for (
size_t iteration = 0; iteration < alphaT.size(); iteration++) {
1672 alpha = alphaT[iteration];
1673 for (
size_t i = 0; i <
neq_; i++) {
1693 if (residSteep < residSteepBest) {
1696 residSteepBest = residSteep;
1697 residSteepLinBest = residSteepLin;
1700 doublereal relFit = (residSteep - residSteepLin) / (fabs(residSteepLin) + 1.0E-10);
1702 printf(
"\t\t (%2d - % 10.3g) % 15.8E % 15.8E % 15.8E % 15.8E\n", 0, alpha, sLen, residSteep, residSteepLin , relFit);
1706 for (
size_t iteration = 0; iteration < alphaT.size(); iteration++) {
1707 doublereal alpha = alphaT[iteration];
1708 for (
size_t i = 0; i <
neq_; i++) {
1725 for (
size_t i = 0; i <
neq_; i++) {
1732 if (residSteep < residSteepBest) {
1735 residSteepBest = residSteep;
1736 residSteepLinBest = residSteepLin;
1739 doublereal relFit = (residSteep - residSteepLin) / (fabs(residSteepLin) + 1.0E-10);
1741 printf(
"\t\t (%2d - % 10.3g) % 15.8E % 15.8E % 15.8E % 15.8E\n", 1, alpha, sLen, residSteep, residSteepLin , relFit);
1745 for (
size_t iteration = 0; iteration < alphaT.size(); iteration++) {
1746 doublereal alpha = alphaT[iteration];
1747 for (
size_t i = 0; i <
neq_; i++) {
1768 if (residSteep < residSteepBest) {
1771 residSteepBest = residSteep;
1772 residSteepLinBest = residSteepLin;
1774 doublereal relFit = (residSteep - residSteepLin) / (fabs(residSteepLin) + 1.0E-10);
1776 printf(
"\t\t (%2d - % 10.3g) % 15.8E % 15.8E % 15.8E % 15.8E\n", 2, alpha, sLen, residSteep, residSteepLin , relFit);
1780 printf(
"\t\t Best Result: \n");
1781 doublereal relFit = (residSteepBest - residSteepLinBest) / (fabs(residSteepLinBest) + 1.0E-10);
1783 printf(
"\t\t Leg %2d alpha %5g: NonlinResid = %g LinResid = %g, relfit = %g\n",
1784 legBest, alphaBest, residSteepBest, residSteepLinBest, relFit);
1788 }
else if (legBest == 1) {
1789 for (
size_t i = 0; i <
neq_; i++) {
1797 printf(
"\t\t (%2d - % 10.3g) % 15.8E % 15.8E % 15.8E % 15.8E\n", legBest, alphaBest, sLen,
1798 residSteepBest, residSteepLinBest , relFit);
1812 for (
size_t i = 0; i <
neq_; i++) {
1820 for (
size_t i = 0; i <
neq_; i++) {
1831 for (
size_t i = 0; i <
neq_; i++) {
1840 size_t i_fbounds = 0;
1843 doublereal UPFAC = 2.0;
1845 doublereal sameSign = 0.0;
1847 doublereal f_delta_bounds = 1.0;
1849 for (
size_t i = 0; i <
neq_; i++) {
1850 doublereal y_new = y_n_curr[i] + step_1[i];
1851 sameSign = y_new * y_n_curr[i];
1861 if (sameSign >= 0.0) {
1862 if ((fabs(y_new) > UPFAC * fabs(y_n_curr[i])) &&
1864 ff = (UPFAC - 1.0) * fabs(y_n_curr[i]/(y_new - y_n_curr[i]));
1866 ff = std::max(ff, ff_alt);
1869 if ((fabs(2.0 * y_new) < fabs(y_n_curr[i])) &&
1871 ff = y_n_curr[i]/(y_new - y_n_curr[i]) * (1.0 - 2.0)/2.0;
1873 ff = std::max(ff, ff_alt);
1882 ff = y_n_curr[i]/(y_new - y_n_curr[i]) * (1.0 - 2.0)/2.0;
1884 ff = std::max(ff, ff_alt);
1885 if (y_n_curr[i] >= 0.0) {
1894 else if (fabs(y_new) > 0.5 * fabs(y_n_curr[i])) {
1895 ff = y_n_curr[i]/(y_new - y_n_curr[i]) * (-1.5);
1897 ff = std::max(ff, ff_alt);
1902 if (ff < f_delta_bounds) {
1903 f_delta_bounds = ff;
1916 if (f_delta_bounds < 1.0) {
1918 printf(
"\t\tdeltaBoundStep: Increase of Variable %s causing "
1919 "delta damping of %g: origVal = %10.3g, undampedNew = %10.3g, dampedNew = %10.3g\n",
1920 int2str(i_fbounds).c_str(), f_delta_bounds, y_n_curr[i_fbounds], y_n_curr[i_fbounds] + step_1[i_fbounds],
1921 y_n_curr[i_fbounds] + f_delta_bounds * step_1[i_fbounds]);
1923 printf(
"\t\tdeltaBoundStep: Decrease of variable %s causing"
1924 "delta damping of %g: origVal = %10.3g, undampedNew = %10.3g, dampedNew = %10.3g\n",
1925 int2str(i_fbounds).c_str(), f_delta_bounds, y_n_curr[i_fbounds], y_n_curr[i_fbounds] + step_1[i_fbounds],
1926 y_n_curr[i_fbounds] + f_delta_bounds * step_1[i_fbounds]);
1932 return f_delta_bounds;
1938 doublereal wtSum = 0.0;
1939 for (
size_t i = 0; i <
neq_; i++) {
1944 doublereal deltaXSizeOld = trustNorm;
1945 doublereal trustNormGoal = trustNorm *
trustDelta_;
1952 for (
size_t i = 0; i <
neq_; i++) {
1958 doublereal newValue = trustNormGoal *
m_ewt[i];
1959 if (newValue > 0.5 * fabsy) {
1966 if (newValue > 4.0 * oldVal) {
1967 newValue = 4.0 * oldVal;
1968 }
else if (newValue < 0.25 * oldVal) {
1969 newValue = 0.25 * oldVal;
1984 doublereal sum = trustNormGoal / trustNorm;
1985 for (
size_t i = 0; i <
neq_; i++) {
1992 printf(
"\t\t reajustTrustVector(): Trust size = %11.3E: Old deltaX size = %11.3E trustDelta_ = %11.3E\n"
1993 "\t\t new deltaX size = %11.3E trustdelta_ = %11.3E\n",
2004 for (
size_t i = 0; i <
neq_; i++) {
2010 for (
size_t i = 0; i <
neq_; i++) {
2015 printf(
"\t\t initializeTrustRegion(): Relative Distance of Cauchy Vector wrt Trust Vector = %g\n", cpd);
2021 printf(
"\t\t initializeTrustRegion(): Relative Distance of Cauchy Vector wrt Trust Vector = %g\n", cpd);
2025 for (
size_t i = 0; i <
neq_; i++) {
2030 printf(
"\t\t initializeTrustRegion(): Relative Distance of Newton Vector wrt Trust Vector = %g\n", cpd);
2036 printf(
"\t\t initializeTrustRegion(): Relative Distance of Newton Vector wrt Trust Vector = %g\n", cpd);
2044 for (
size_t i = 0; i <
neq_; i++) {
2047 }
else if (leg == 2) {
2048 for (
size_t i = 0; i <
neq_; i++) {
2052 for (
size_t i = 0; i <
neq_; i++) {
2060 doublereal sum = 0.0;
2061 doublereal tmp = 0.0;
2062 for (
size_t i = 0; i <
neq_; i++) {
2091 doublereal sumv = 0.0;
2092 for (
size_t i = 0; i <
neq_; i++) {
2097 doublereal b = 2.0 * Nuu_ * sumv;
2100 alpha =(-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
2110 size_t i_lower =
npos;
2111 doublereal f_bounds = 1.0;
2112 doublereal ff, y_new;
2114 for (
size_t i = 0; i <
neq_; i++) {
2115 y_new = y[i] + step0[i];
2119 if (step0[i] < 0.0) {
2122 ff = legalDelta / step0[i];
2123 if (ff < f_bounds) {
2132 if (step0[i] > 0.0) {
2135 ff = legalDelta / step0[i];
2136 if (ff < f_bounds) {
2149 if (f_bounds != 1.0) {
2150 printf(
"\t\tboundStep: Variable %s causing bounds damping of %g\n",
int2str(i_lower).c_str(), f_bounds);
2155 return std::min(f_bounds, f_delta_bounds);
2159 const doublereal*
const ydot_n_curr, doublereal*
const step_1,
2160 doublereal*
const y_n_1, doublereal*
const ydot_n_1, doublereal*
const step_2,
2161 doublereal& stepNorm_2,
GeneralMatrix& jac,
bool writetitle,
int& num_backtracks)
2170 for (
size_t j = 0; j <
neq_; j++) {
2171 step_1_orig[j] = step_1[j];
2184 printf(
"\t\t\tdampStep(): At limits.\n");
2198 for (m = 0; m <
NDAMP; m++) {
2207 for (
size_t j = 0; j <
neq_; j++) {
2208 step_1[j] = ff * step_1_orig[j];
2209 y_n_1[j] = y_n_curr[j] + step_1[j];
2226 printf(
"\t\t\tdampStep(): current trial step and damping led to Residual Calc ERROR %d. Bailing\n", info);
2241 printf(
"\t dampStep(): Current trial step and damping"
2242 " coefficient accepted because residTrial test step < 1:\n");
2244 }
else if (steepEnough) {
2245 printf(
"\t dampStep(): Current trial step and damping"
2246 " coefficient accepted because resid0 > residTrial and steep enough:\n");
2249 printf(
"\t dampStep(): Current trial step and damping"
2250 " coefficient accepted because residual solution damping is turned off:\n");
2274 info =
doNewtonSolve(time_curr, y_n_1, ydot_n_1, step_2, jac);
2276 info =
doNewtonSolve(time_curr, y_n_1, ydot_n_curr, step_2, jac);
2280 printf(
"\t\t\tdampStep: current trial step and damping led to LAPACK ERROR %d. Bailing\n", info);
2291 (
const doublereal*) step_2,
"DeltaSolnTrial",
2292 "dampNewt: Important Entries for Weighted Soln Updates:",
2293 y_n_curr, y_n_1, ff, 5);
2296 printf(
"\t\t\tdampStep(): s1 = %g, s2 = %g, dampBound = %g,"
2297 "dampRes = %g\n", stepNorm_1, stepNorm_2,
m_dampBound, m_dampRes);
2306 if (stepNorm_2 < 0.8 || stepNorm_2 < stepNorm_1) {
2307 if (stepNorm_2 < 1.0) {
2309 if (stepNorm_2 < 1.0) {
2310 printf(
"\t\t\tdampStep: current trial step and damping coefficient accepted because test step < 1\n");
2311 printf(
"\t\t\t s2 = %g, s1 = %g\n", stepNorm_2, stepNorm_1);
2321 printf(
"\t\t\tdampStep: current step rejected: (s1 = %g > "
2322 "s0 = %g)", stepNorm_2, stepNorm_1);
2323 if (m < (NDAMP-1)) {
2324 printf(
" Decreasing damping factor and retrying");
2326 printf(
" Giving up!!!");
2341 printf(
"\t dampStep(): current trial step accepted retnTrial = %d, its = %d, damp = %g\n", retnTrial, m+1, ff);
2345 if (stepNorm_2 < 0.5 && (stepNorm_1 < 0.5)) {
2347 printf(
"\t dampStep(): current trial step accepted kindof retnTrial = %d, its = %d, damp = %g\n", 2, m+1, ff);
2351 if (stepNorm_2 < 1.0) {
2353 printf(
"\t dampStep(): current trial step accepted and soln converged retnTrial ="
2354 "%d, its = %d, damp = %g\n", 0, m+1, ff);
2360 printf(
"\t dampStep(): current direction is rejected! retnTrial = %d, its = %d, damp = %g\n",
2367 const doublereal* ydot_n_curr, std::vector<doublereal> & step_1,
2368 doublereal*
const y_n_1, doublereal*
const ydot_n_1,
2369 doublereal& stepNorm_1, doublereal& stepNorm_2,
GeneralMatrix& jac,
int& numTrials)
2374 bool success =
false;
2375 bool haveASuccess =
false;
2388 for (m = 0; m <
NDAMP; m++) {
2396 printf(
"\t\t dampDogLeg: trust region with length %13.5E has intersection at leg = %d, alpha = %g, lambda = %g\n",
2413 for (
size_t j = 0; j <
neq_; j++) {
2420 for (
size_t j = 0; j <
neq_; j++) {
2421 y_n_1[j] = y_n_curr[j] + step_1[j];
2434 y_n_1, ydot_n_1, trustDeltaOld);
2444 printf(
"\t\t dampDogLeg: Current direction rejected, update became too small %g\n", stepNorm);
2451 printf(
"\t\t dampDogLeg: current trial step and damping led to LAPACK ERROR %d. Bailing\n", info);
2462 haveASuccess =
true;
2464 copy(step_1.begin(), step_1.end(), stepLastGood);
2475 copy(stepLastGood, stepLastGood+neq_, step_1.begin());
2476 for (
size_t j = 0; j <
neq_; j++) {
2477 y_n_1[j] = y_n_curr[j] + step_1[j];
2494 stepNorm_2 = stepNorm_1;
2498 stepNorm_2 /= lambda;
2516 const doublereal*
const y_n_curr,
2517 const doublereal*
const ydot_n_curr,
const std::vector<doublereal> & step_1,
2518 const doublereal*
const y_n_1,
const doublereal*
const ydot_n_1,
2519 doublereal trustDeltaOld)
2536 if (funcDecreaseSDExp > 0.0) {
2538 printf(
"\t\tdecideStep(): Unexpected condition -> cauchy slope is positive\n");
2557 printf(
"\t\tdecideStep: current trial step and damping led to Residual Calc ERROR %d. Bailing\n", info);
2572 doublereal funcDecrease = 0.5 * (normResidTrial_2 - normResid0_2);
2573 doublereal acceptableDelF = funcDecreaseSDExp * stepNorm * 1.0E-4;
2574 if (funcDecrease < acceptableDelF) {
2579 printf(
"\t\t decideStep: Norm Residual(leg=%1d, alpha=%10.2E) = %11.4E passes\n",
2584 printf(
"\t\t decideStep: Norm Residual(leg=%1d, alpha=%10.2E) = %11.4E failes\n",
2591 if (
rtol_ * stepNorm < 1.0E-6) {
2614 doublereal expectedFuncDecrease = 0.5 * (neq_ * expectedNormRes * expectedNormRes - normResid0_2);
2615 if (funcDecrease > 0.1 * expectedFuncDecrease) {
2616 if ((m_normResidTrial > 0.5 *
m_normResid_0) && (m_normResidTrial > 0.1)) {
2621 printf(
"\t\t decideStep: Trust region decreased from %g to %g due to bad quad approximation\n",
2629 if (funcDecrease < 0.8 * expectedFuncDecrease || (m_normResidTrial < 0.33 *
m_normResid_0)) {
2630 if (
trustDelta_ <= trustDeltaOld && (leg != 2 || alpha < 0.75)) {
2637 printf(
"\t\t decideStep: Redo line search with trust region increased from %g to %g due to good nonlinear behavior\n",
2640 printf(
"\t\t decideStep: Redi line search with trust region increased from %g to %g due to good linear model approximation\n",
2649 if (m_normResidTrial < 0.99 * expectedNormRes || (m_normResidTrial < 0.20 *
m_normResid_0) ||
2650 (funcDecrease < -1.0E-50 && (funcDecrease < 0.9 *expectedFuncDecrease))) {
2651 if (leg == 2 && alpha == 1.0) {
2659 printf(
"\t\t decideStep: Trust region further increased from %g to %g next step due to good linear model behavior\n",
2670 printf(
"\t\t decideStep: Trust region further increased from %g to %g next step due to good linear model behavior\n",
2684 int& num_newt_its,
int& num_linear_solves,
2685 int& num_backtracks,
int loglevelInput)
2698 bool forceNewJac =
false;
2703 doublereal stepNorm_1;
2704 doublereal stepNorm_2;
2707 doublereal alphaBest;
2709 bool trInit =
false;
2737 printf(
"\tsolve_nonlinear_problem():\n\n");
2739 printf(
"\tWt Iter Resid NewJac log(CN)| dRdS_CDexp dRdS_CD dRdS_Newtexp dRdS_Newt |"
2740 "DS_Cauchy DS_Newton DS_Trust | legID legAlpha Fbound | CTF NTF | nTr|"
2741 "DS_Final ResidLag ResidFull\n");
2742 printf(
"\t---------------------------------------------------------------------------------------------------"
2743 "--------------------------------------------------------------------------------\n");
2745 printf(
"\t Wt Iter Resid NewJac | Fbound ResidBound | DampIts Fdamp DS_Step1 DS_Step2"
2746 "ResidLag | DS_Damp DS_Newton ResidFull\n");
2747 printf(
"\t--------------------------------------------------------------------------------------------------"
2748 "----------------------------------\n");
2768 printf(
"\tsolve_nonlinear_problem(): iteration %d:\n",
2787 if ((num_newt_its % 5) == 1) {
2814 printf(
"\t solve_nonlinear_problem(): Getting a new Jacobian\n");
2820 printf(
"\t solve_nonlinear_problem(): Jacobian Formation Error: %d Bailing\n", info);
2827 printf(
"\t solve_nonlinear_problem(): Solving system with old jacobian\n");
2840 printf(
"\t solve_nonlinear_problem(): Calculate the base residual\n");
2845 printf(
"\t solve_nonlinear_problem(): Residual Calc ERROR %d. Bailing\n", info);
2866 printf(
"\t solve_nonlinear_problem(): Initial Residual Norm = %13.4E\n",
m_normResid_0);
2873 printf(
"\t solve_nonlinear_problem(): Calculate the steepest descent direction and Cauchy Point\n");
2880 printf(
"\t solve_nonlinear_problem(): Calculate the steepest descent direction and Cauchy Point\n");
2889 printf(
"\t solve_nonlinear_problem(): Calculate the Newton direction via an Affine solve\n");
2894 printf(
"\t solve_nonlinear_problem(): Calculate the Newton direction via a Newton solve\n");
2902 printf(
"\t solve_nonlinear_problem(): Matrix Inversion Error: %d Bailing\n", info);
2918 printf(
"\t solve_nonlinear_problem(): Initialize the trust region size as the length of the Cauchy Vector times %f\n",
2921 printf(
"\t solve_nonlinear_problem(): Initialize the trust region size as the length of the Newton Vector times %f\n",
2939 printf(
"\t\t Newton's method step size, %g trustVectorUnits, larger than trust region, %g trustVectorUnits\n",
2941 printf(
"\t\t Newton's method step size, %g trustVectorUnits, larger than trust region, %g trustVectorUnits\n",
2944 printf(
"\t\t Newton's method step size, %g trustVectorUnits, smaller than trust region, %g trustVectorUnits\n",
2959 printf(
"\t solve_nonlinear_problem(): Compare descent rates for Cauchy and Newton directions\n");
2973 printf(
"\t solve_nonlinear_problem(): Compare Linear and nonlinear residuals along double dog-leg path\n");
2978 printf(
"\t solve_nonlinear_problem(): Calculate damping along dog-leg path to ensure residual decrease\n");
2986 printf(
"\t solve_nonlinear_problem(): Compare Linear and nonlinear residuals along double dog-leg path\n");
3007 num_backtracks += i_numTrials;
3018 printf(
"\t solve_nonlinear_problem(): Damped Newton successful (m=%d) but minimum newton"
3019 "iterations not attained. Resolving ...\n", retnDamp);
3031 printf(
"\t solve_nonlinear_problem(): Damped newton unsuccessful (max newts exceeded) sfinal = %g\n",
3043 printf(
"\t solve_nonlinear_problem(): current trial step and damping led to Residual Calc "
3044 "ERROR %d. Bailing\n", info);
3053 printf(
"\t solve_nonlinear_problem(): Full residual norm changed from %g to %g due to "
3072 bool m_filterIntermediate =
false;
3073 if (m_filterIntermediate) {
3096 bool m_jacAge =
false;
3110 printf(
" %2d ", i_numTrials);
3115 printf(
"%2d %10.2E %10.3E %10.3E %10.3E", i_numTrials + 1,
m_dampRes,
3125 printf(
"\t solve_nonlinear_problem(): Problem Converged, stepNorm = %11.3E, reduction of res from %11.3E to %11.3E\n",
3130 printf(
"\t solve_nonlinear_problem(): Successfull step taken with stepNorm = %11.3E, reduction of res from %11.3E to %11.3E\n",
3135 printf(
"\t solve_nonlinear_problem(): Damped Newton iteration successful, nonlin "
3136 "converged, final estimate of the next solution update norm = %-12.4E\n", stepNorm_2);
3140 printf(
"\t solve_nonlinear_problem(): Damped Newton iteration successful, "
3141 "estimate of the next solution update norm = %-12.4E\n", stepNorm_2);
3143 printf(
"\t solve_nonlinear_problem(): Damped Newton unsuccessful, final estimate "
3144 "of the next solution update norm = %-12.4E\n", stepNorm_2);
3157 printf(
"\t solve_nonlinear_problem(): Final ShowSolution residual eval returned an error! "
3158 "ERROR %d. Bailing\n", info);
3187 " | | converged = 3 |(%11.3E) \n", stepNorm_2);
3190 " | | converged = %1d | %10.3E %10.3E\n", convRes,
3193 printf(
"\t-----------------------------------------------------------------------------------------------------"
3194 "------------------------------------------------------------------------------\n");
3198 " | converged = 3 | (%11.3E) \n", stepNorm_2);
3201 " | converged = %1d | %10.3E %10.3E\n", convRes,
3204 printf(
"\t------------------------------------------------------------------------------------"
3205 "-----------------------------------------------\n");
3220 doublereal time_elapsed = wc.
secondsWC();
3224 printf(
"\tNonlinear problem solved successfully in %d its\n",
3227 printf(
"\tNonlinear problem solved successfully in %d its, time elapsed = %g sec\n",
3228 num_newt_its, time_elapsed);
3231 printf(
"\tNonlinear problem failed to solve after %d its\n", num_newt_its);
3234 retnCode = retnDamp;
3252 const char*
const stepNorm_1,
3253 const doublereal*
const step_2,
3254 const char*
const stepNorm_2,
3255 const char*
const title,
3256 const doublereal*
const y_n_curr,
3257 const doublereal*
const y_n_1,
3262 doublereal dmax0, dmax1,
error, rel_norm;
3263 printf(
"\t\t%s currentDamp = %g\n", title, damp);
3264 printf(
"\t\t I ysolnOld %13s ysolnNewRaw | ysolnNewTrial "
3265 "%10s ysolnNewTrialRaw | solnWeight wtDelSoln wtDelSolnTrial\n", stepNorm_1, stepNorm_2);
3266 std::vector<size_t> imax(num_entries,
npos);
3269 for (
size_t jnum = 0; jnum < num_entries; jnum++) {
3271 for (
size_t i = 0; i <
neq_; i++) {
3273 for (
size_t j = 0; j < jnum; j++) {
3279 error = step_1[i] /
m_ewt[i];
3280 rel_norm = sqrt(error * error);
3281 error = step_2[i] /
m_ewt[i];
3282 rel_norm += sqrt(error * error);
3283 if (rel_norm > dmax1) {
3289 if (imax[jnum] !=
npos) {
3290 size_t i = imax[jnum];
3291 error = step_1[i] /
m_ewt[i];
3292 dmax0 = sqrt(error * error);
3293 error = step_2[i] /
m_ewt[i];
3294 dmax1 = sqrt(error * error);
3295 printf(
"\t\t %4s %12.4e %12.4e %12.4e | %12.4e %12.4e %12.4e |%12.4e %12.4e %12.4e\n",
3296 int2str(i).c_str(), y_n_curr[i], step_1[i], y_n_curr[i] + step_1[i], y_n_1[i],
3297 step_2[i], y_n_1[i]+ step_2[i],
m_ewt[i], dmax0, dmax1);
3323 static inline doublereal
subtractRD(doublereal a, doublereal b)
3325 doublereal diff = a - b;
3326 doublereal d = std::min(fabs(a), fabs(b));
3328 doublereal ad = fabs(diff);
3329 if (ad < 1.0E-300) {
3339 doublereal time_curr, doublereal CJ,
3340 doublereal*
const y, doublereal*
const ydot,
3345 doublereal ysave, dy;
3346 doublereal ydotsave = 0;
3380 for (
int ii = 0; ii <
neq_; ii++) {
3395 printf(
"\t\t beuler_jac ERROR! calcDeltaSolnVariables() returned an error flag\n");
3396 printf(
"\t\t We will bail from the nonlinear solver after calculating the jacobian");
3399 printf(
"\t\tUnk m_ewt y dyVector ResN\n");
3400 for (
size_t iii = 0; iii <
neq_; iii++) {
3401 printf(
"\t\t %4s %16.8e %16.8e %16.8e %16.8e \n",
3402 int2str(iii).c_str(),
m_ewt[iii], y[iii], dyVector[iii], f[iii]);
3419 for (
size_t j = 0; j <
neq_; j++) {
3448 if (fabs(dy) < 1.0E-300) {
3449 throw CanteraError(
"NonlinearSolver::beuler_jac",
"dy is equal to zero");
3451 for (
int ii = 0; ii <
neq_; ii++) {
3461 for (
size_t i = 0; i <
neq_; i++) {
3463 col_j[i] = diff / dy;
3478 printf(
"we have probs\n");
3496 printf(
"\t\t beuler_jac ERROR! calcDeltaSolnVariables() returned an error flag\n");
3497 printf(
"\t\t We will bail from the nonlinear solver after calculating the jacobian");
3500 printf(
"\t\tUnk m_ewt y dyVector ResN\n");
3501 for (
size_t iii = 0; iii <
neq_; iii++) {
3502 printf(
"\t\t %4s %16.8e %16.8e %16.8e %16.8e \n",
3503 int2str(iii).c_str(),
m_ewt[iii], y[iii], dyVector[iii], f[iii]);
3510 for (
size_t j = 0; j <
neq_; j++) {
3528 if (fabs(dy) < 1.0E-300) {
3529 throw CanteraError(
"NonlinearSolver::beuler_jac",
"dy is equal to zero");
3531 for (
int ii = 0; ii <
neq_; ii++) {
3543 for (
int i = (
int) j - ku; i <= (int) j + kl; i++) {
3544 if (i >= 0 && i < (
int)
neq_) {
3546 col_j[kl + ku + i - j] = diff / dy;
3558 if (vSmall < 1.0E-100) {
3559 printf(
"WE have a zero row, %s\n",
int2str(ismall).c_str());
3563 if (vSmall < 1.0E-100) {
3564 printf(
"WE have a zero column, %s\n",
int2str(ismall).c_str());
3574 printf(
"\t\tCurrent Matrix and Residual:\n");
3575 printf(
"\t\t I,J | ");
3576 for (
size_t j = 0; j <
neq_; j++) {
3577 printf(
" %5s ",
int2str(j).c_str());
3579 printf(
"| Residual \n");
3581 for (
size_t j = 0; j <
neq_; j++) {
3582 printf(
"------------");
3584 printf(
"| -----------\n");
3587 for (
size_t i = 0; i <
neq_; i++) {
3588 printf(
"\t\t %4s |",
int2str(i).c_str());
3589 for (
size_t j = 0; j <
neq_; j++) {
3590 printf(
" % 11.4E", J(i,j));
3592 printf(
" | % 11.4E\n", f[i]);
3596 for (
size_t j = 0; j <
neq_; j++) {
3597 printf(
"------------");
3599 printf(
"--------------\n");
3612 calc_ydot(
const int order,
const doublereal*
const y_curr, doublereal*
const ydot_curr)
const
3622 for (
size_t i = 0; i <
neq_; i++) {
3623 ydot_curr[i] = c1 * (y_curr[i] -
m_y_nm1[i]);
3628 for (
size_t i = 0; i <
neq_; i++) {
3639 const doublereal*
const ybase, doublereal*
const step0)
3645 doublereal*
const y_current, doublereal*
const ydot_current)
3654 for (
size_t i = 0; i <
neq_; i++) {
3661 doublereal sum = 0.0;
3662 for (
size_t i = 0; i <
neq_; i++) {
3670 for (
size_t i = 0; i <
neq_; i++) {
3674 for (
size_t i = 0; i <
neq_; i++) {
3684 for (
size_t i = 0; i <
neq_; i++) {
3698 if (dampCode <= 0) {
3701 if (dampCode == 3) {
3715 if (dampCode == 4) {
3730 if (dampCode == 1 || dampCode == 2) {
3742 for (
size_t i = 0; i <
neq_; i++) {
3743 if (atol[i] <= 0.0) {
3745 "Atol is less than or equal to zero");
3762 if (residNormHandling < 0 || residNormHandling > 2) {
3763 throw CanteraError(
"NonlinearSolver::setResidualTols()",
3764 "Unknown int for residNormHandling");
3770 for (
size_t i = 0; i <
neq_; i++) {
3774 if (residNormHandling ==1 || residNormHandling == 2) {
3775 throw CanteraError(
"NonlinearSolver::setResidualTols()",
3776 "Must set residATol vector");
static bool s_alwaysAssumeNewtonGood
This toggle turns off the use of the Hessian when it is warranted by the condition number...
virtual int factorQR()=0
Factors the A matrix using the QR algorithm, overwriting A.
virtual doublereal * ptrColumn(size_t j)=0
Return a pointer to the top of column j, columns are assumed to be contiguous in memory.
int matrixType_
Matrix type.
int trustRegionInitializationMethod_
Method for handling the trust region initialization.
void computeResidWts()
Compute the Residual Weights.
std::vector< doublereal > m_y_low_bounds
Lower bounds vector for each species.
Dense, Square (not sparse) matrices.
virtual void useFactorAlgorithm(int fAlgorithm)=0
Change the way the matrix is factored.
doublereal ResidDecreaseSDExp_
Expected DResid_dS for the steepest descent path - output variable.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
#define NSOLN_RETN_SUCCESS
The nonlinear solve is successful.
void readjustTrustVector()
Readjust the trust region vectors.
int beuler_jac(GeneralMatrix &J, doublereal *const f, doublereal time_curr, doublereal CJ, doublereal *const y, doublereal *const ydot, int num_newt_its)
Function called to evaluate the jacobian matrix and the current residual vector at the current time s...
int m_matrixConditioning
Boolean indicating matrix conditioning.
Base residual calculation for the showSolution routine.
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
doublereal Nuu_
Relative distance down the Newton step that the second dogleg starts.
int m_rowScaling
int indicating whether row scaling is turned on (1) or not (0)
virtual int nEquations() const
Return the number of equations in the equation system.
int convergenceCheck(int dampCode, doublereal s1)
Check to see if the nonlinear problem has converged.
doublereal solnErrorNorm(const doublereal *const delta_y, const char *title=0, int printLargest=0, const doublereal dampFactor=1.0) const
L2 norm of the delta of the solution vector.
std::vector< doublereal > atolk_
absolute tolerance in the solution unknown
doublereal boundStep(const doublereal *const y, const doublereal *const step0)
Bound the step.
doublereal m_normResidTrial
Norm of the residual for a trial calculation which may or may not be used.
doublereal lambdaStar_
Value of lambdaStar_ which is used to calculate the Cauchy point.
doublereal ResidDecreaseNewtExp_
Expected DResid_dS for the Newton path - output variable.
std::vector< doublereal > m_colScales
Vector of column scaling factors.
doublereal normTrust_Newton_
Norm of the Newton Step wrt trust region.
std::vector< doublereal > userResidAtol_
absolute tolerance in the unscaled solution unknowns
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
virtual GeneralMatrix * duplMyselfAsGeneralMatrix() const =0
Duplicator member function.
doublereal userResidRtol_
absolute tolerance in the unscaled solution unknowns
doublereal m_normResid_Bound
Norm of the residual after it has been bounded.
const size_t npos
index returned by functions to indicate "no position"
virtual doublereal oneNorm() const =0
Calculate the one norm of the matrix.
virtual void setPreviousTimeStep(const std::vector< doublereal > &y_nm1, const std::vector< doublereal > &ydot_nm1)
Set the values for the previous time step.
#define NSOLN_RETN_MATRIXINVERSIONERROR
The nonlinear problem's jacobian is singular.
int doResidualCalc(const doublereal time_curr, const int typeCalc, const doublereal *const y_curr, const doublereal *const ydot_curr, const ResidEval_Type_Enum evalType=Base_ResidEval) const
Compute the current residual.
virtual int evalResidNJ(const doublereal t, const doublereal delta_t, const doublereal *const y, const doublereal *const ydot, doublereal *const resid, const ResidEval_Type_Enum evalType=Base_ResidEval, const int id_x=-1, const doublereal delta_x=0.0)
Evaluate the residual function.
int dogLegID_
Current leg.
virtual doublereal rcond(doublereal a1norm)=0
Returns an estimate of the inverse of the condition number for the matrix.
virtual int evalJacobian(const doublereal t, const doublereal delta_t, doublereal cj, const doublereal *const y, const doublereal *const ydot, GeneralMatrix &J, doublereal *const resid)
Calculate an analytical jacobian and the residual at the current time and values. ...
std::vector< doublereal > m_ydot_nm1
Vector containing the solution derivative at the previous time step.
void setupDoubleDogleg()
Setup the parameters for the double dog leg.
#define NSOLN_RETN_CONTINUE
Problem isn't solved yet.
virtual vector_fp::iterator begin()=0
Return an iterator pointing to the first element.
void calcSolnToResNormVector()
Calculate the scaling factor for translating residual norms into solution norms.
#define NSOLN_TYPE_STEADY_STATE
The nonlinear problem is part of a steady state calculation.
std::vector< doublereal > deltaX_trust_
Vector of trust region values.
const double DampFactor
Dampfactor is the factor by which the damping factor is reduced by when a reduction in step length is...
int dampStep(const doublereal time_curr, const doublereal *const y_n_curr, const doublereal *const ydot_n_curr, doublereal *const step_1, doublereal *const y_n_1, doublereal *const ydot_n_1, doublereal *step_2, doublereal &stepNorm_2, GeneralMatrix &jac, bool writetitle, int &num_backtracks)
Find a damping coefficient through a look-ahead mechanism.
Base residual calculation for the Jacobian calculation.
#define NSOLN_RETN_FAIL_DAMPSTEP
The nonlinear problem didn't solve the problem.
The class provides the wall clock timer in seconds.
int m_print_flag
Determines the level of printing for each time step.
int m_nfe
Counter for the total number of function evaluations.
virtual int factorAlgorithm() const =0
Return the factor algorithm used.
NonlinearSolver & operator=(const NonlinearSolver &right)
Assignment operator.
doublereal m_normDeltaSoln_CP
Norm of the distance to the cauchy point using the solution norm.
std::vector< doublereal > deltaX_Newton_
Newton Step - This is the newton step determined from the straight Jacobian.
doublereal residErrorNorm(const doublereal *const resid, const char *title=0, const int printLargest=0, const doublereal *const y=0) const
L2 norm of the residual of the equation system.
doublereal NextTrustFactor_
Factor indicating how much trust region has been changed next iteration - output variable.
doublereal filterNewSolution(const doublereal timeCurrent, doublereal *const y_current, doublereal *const ydot_current)
Apply a filter to the solution.
#define NSOLN_JAC_ANAL
The jacobian is calculated from an analytical function.
virtual int factor()=0
Factors the A matrix, overwriting A.
#define NSOLN_RETN_MAXIMUMITERATIONSEXCEEDED
The nonlinear problem's max number of iterations has been exceeded.
double subtractRD(double a, double b)
This routine subtracts two numbers for one another.
std::vector< doublereal > m_rowScales
Weights for normalizing the values of the residuals.
virtual ResidJacEval * duplMyselfAsResidJacEval() const
Duplication routine for objects derived from residJacEval.
std::vector< doublereal > m_ewt
Soln error weights.
ResidEval_Type_Enum
Differentiates the type of residual evaluations according to functionality.
doublereal dogLegAlpha_
Current Alpha param along the leg.
int m_min_newt_its
Minimum number of newton iterations to use.
void setDefaultDeltaBoundsMagnitudes()
Set default deulta bounds amounts.
std::vector< doublereal > Jd_
Jacobian times the steepest descent direction in the normalized coordinates.
doublereal m_normDeltaSoln_Newton
Norm of the solution update created by the iteration in its raw, undamped form, using the solution no...
static bool s_print_NumJac
Turn on or off printing of the Jacobian.
int checkUserResidualTols_
Check the residual tolerances explicitly against user input.
NonlinearSolver(ResidJacEval *func)
Default constructor.
Wrappers for the function evaluators for Nonlinear solvers and Time steppers.
std::vector< doublereal > deltaX_CP_
Steepest descent direction. This is also the distance to the Cauchy Point.
static void print_line(const char *str, int n)
Print a line of a single repeated character string.
doublereal m_dampBound
Damping factor imposed by hard bounds and by delta bounds.
doublereal trustDelta_
Current value of trust radius.
int m_colScaling
The type of column scaling used in the matrix inversion of the problem.
virtual int calcDeltaSolnVariables(const doublereal t, const doublereal *const y, const doublereal *const ydot, doublereal *const delta_y, const doublereal *const solnWeights=0)
Return a vector of delta y's for calculation of the numerical Jacobian.
void createSolnWeights(const doublereal *const y)
Create solution weights for convergence criteria.
std::vector< doublereal > m_deltaStepMaximum
Value of the delta step magnitudes.
int m_numLocalLinearSolves
Number of local linear solves done during the current iteration.
virtual void zero()=0
Zero the matrix elements.
void print_solnDelta_norm_contrib(const doublereal *const step_1, const char *const stepNorm_1, const doublereal *const step_2, const char *const stepNorm_2, const char *const title, const doublereal *const y_n_curr, const doublereal *const y_n_1, doublereal damp, size_t num_entries)
Print solution norm contribution.
int doNewtonSolve(const doublereal time_curr, const doublereal *const y_curr, const doublereal *const ydot_curr, doublereal *const delta_y, GeneralMatrix &jac)
Compute the undamped Newton step.
void adjustUpStepMinimums()
Adjust the step minimums.
doublereal calcTrustDistance(std::vector< doublereal > const &deltaX) const
Calculate the trust distance of a step in the solution variables.
Class that calculates the solution to a nonlinear, dense, set of equations (see Numerical Utilities w...
std::vector< doublereal > m_residWts
Vector of residual weights.
doublereal trustRegionLength() const
Calculate the length of the current trust region in terms of the solution error norm.
void calcColumnScales()
Set the column scaling vector at the current time.
bool m_resid_scaled
Boolean indicating whether we should scale the residual.
doublereal ResidDecreaseNewt_
Actual DResid_dS for the newton path - output variable.
void setAtol(const doublereal *const atol)
Set the absolute tolerances for the solution variables.
int dampDogLeg(const doublereal time_curr, const doublereal *y_n_curr, const doublereal *ydot_n_curr, std::vector< doublereal > &step_1, doublereal *const y_n_1, doublereal *const ydot_n_1, doublereal &stepNorm_1, doublereal &stepNorm_2, GeneralMatrix &jac, int &num_backtracks)
Damp using the dog leg approach.
double secondsWC()
Returns the wall clock time in seconds since the last reset.
void error(const std::string &msg)
Write an error message and quit.
void initializeTrustRegion()
Initialize the size of the trust vector.
int m_nJacEval
Number of Jacobian evaluations.
std::vector< doublereal > m_y_n_curr
Vector containing the current solution vector within the nonlinear solver.
doublereal ResidDecreaseSD_
Actual DResid_dS for the steepest descent path - output variable.
void setDeltaBoundsMagnitudes(const doublereal *const deltaBoundsMagnitudes)
Set the delta Bounds magnitudes by hand.
size_t neq_
Local copy of the number of equations.
virtual bool factored() const =0
true if the current factorization is up to date with the matrix
int doAffineNewtonSolve(const doublereal *const y_curr, const doublereal *const ydot_curr, doublereal *const delta_y, GeneralMatrix &jac)
Compute the newton step, either by direct newton's or by solving a close problem that is represented ...
std::vector< doublereal > m_ydot_trial
Value of the solution time derivative at the new point that is to be considered.
void fillDogLegStep(int leg, doublereal alpha, std::vector< doublereal > &deltaX) const
Fill a dogleg solution step vector.
virtual size_t checkRows(doublereal &valueSmall) const =0
Check to see if we have any zero rows in the jacobian.
Base class for exceptions thrown by Cantera classes.
Class that calculates the solution to a nonlinear system.
doublereal m_dampRes
Additional damping factor due to bounds on the residual and solution norms.
#define NSOLN_RETN_JACOBIANFORMATIONERROR
The nonlinear problem's jacobian formation produced an error.
void setResidualTols(double residRtol, double *residAtol, int residNormHandling=2)
Set the relative and absolute tolerances for the Residual norm comparisons, if used.
std::vector< doublereal > m_y_high_bounds
Bounds vector for each species.
doublereal rtol_
value of the relative tolerance to use in solving the equation set
const int NDAMP
Number of damping steps that are carried out before the solution is deemed a failure.
virtual void clearFactorFlag()=0
clear the factored flag
static bool s_print_DogLeg
Turn on extra printing of dogleg information.
doublereal dist_R2_
Distance of the second leg of the dogleg in terms of the solution norm.
doublereal dist_R1_
Distance of the first leg of the dogleg in terms of the solution norm.
void scaleMatrix(GeneralMatrix &jac, doublereal *const y_comm, doublereal *const ydot_comm, doublereal time_curr, int num_newt_its)
Scale the matrix.
bool ResidWtsReevaluated_
Boolean indicating that the residual weights have been reevaluated this iteration - output variable...
doublereal RJd_norm_
Residual dot Jd norm.
void setRowScaling(bool useRowScaling)
Set the rowscaling that are used for the inversion of the matrix.
std::vector< doublereal > m_ydot_n_curr
Vector containing the time derivative of the current solution vector within the nonlinear solver (whe...
void descentComparison(doublereal time_curr, doublereal *ydot0, doublereal *ydot1, int &numTrials)
This is a utility routine that can be used to print out the rates of the initial residual decline...
doublereal filterNewStep(const doublereal timeCurrent, const doublereal *const ybase, doublereal *const step0)
Apply a filtering process to the step.
static bool s_TurnOffTiming
Turn off printing of time.
int m_numTotalLinearSolves
Total number of linear solves taken by the solver object.
virtual void calcSolnScales(const doublereal t, const doublereal *const y, const doublereal *const y_old, doublereal *const yScales)
Returns a vector of column scale factors that can be used to column scale Jacobians.
int m_manualDeltaStepSet
Boolean indicating whether a manual delta bounds has been input.
Cantera::GeneralMatrix * jacCopyPtr_
Copy of the jacobian that doesn't get overwritten when the inverse is determined. ...
#define NSOLN_RETN_RESIDUALFORMATIONERROR
The nonlinear problem's base residual produced an error.
~NonlinearSolver()
Destructor.
std::vector< doublereal > m_resid
Value of the residual for the nonlinear problem.
int m_jacFormMethod
Jacobian formation method.
int solve_nonlinear_problem(int SolnType, doublereal *const y_comm, doublereal *const ydot_comm, doublereal CJ, doublereal time_curr, GeneralMatrix &jac, int &num_newt_its, int &num_linear_solves, int &num_backtracks, int loglevelInput)
Find the solution to F(X) = 0 by damped Newton iteration.
int lambdaToLeg(const doublereal lambda, doublereal &alpha) const
Change the global lambda coordinate into the (leg,alpha) coordinate for the double dogleg...
std::vector< doublereal > m_deltaStepMinimum
Soln Delta bounds magnitudes.
std::vector< doublereal > m_y_n_trial
Vector containing the solution at the new point that is to be considered.
std::vector< doublereal > m_y_nm1
Vector containing the solution at the previous time step.
doublereal m_normResid_full
Norm of the residual at the end of the first leg of the current iteration.
doublereal m_normResid_0
Norm of the residual at the start of each nonlinear iteration.
doublereal time_n
Current system time.
int decideStep(const doublereal time_curr, int leg, doublereal alpha, const doublereal *const y_n_curr, const doublereal *const ydot_n_curr, const std::vector< doublereal > &step_1, const doublereal *const y_n_1, const doublereal *const ydot_n_1, doublereal trustDeltaOld)
Decide whether the current step is acceptable and adjust the trust region size.
int m_numTotalNewtIts
Total number of newton iterations.
virtual size_t nRowsAndStruct(size_t *const iStruct=0) const =0
Return the size and structure of the matrix.
int m_order
Order of the time step method = 1.
virtual void copyData(const GeneralMatrix &y)=0
Copy the data from one array into another without doing any checking.
Cantera::GeneralMatrix * HessianPtr_
Hessian.
virtual size_t checkColumns(doublereal &valueSmall) const =0
Check to see if we have any zero columns in the jacobian.
doublereal delta_t_n
Delta t for the current step.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
int solnType_
Solution type.
Templates for operations on vector-like objects.
void residualComparisonLeg(const doublereal time_curr, const doublereal *const ydot0, int &legBest, doublereal &alphaBest) const
Here we print out the residual at various points along the double dogleg, comparing against the quadr...
doublereal expectedResidLeg(int leg, doublereal alpha) const
Calculated the expected residual along the double dogleg curve.
void setRtol(const doublereal rtol)
Set the relative tolerances for the solution variables.
virtual int solve(doublereal *b)=0
Solves the Ax = b system returning x in the b spot.
void setBoundsConstraints(const doublereal *const y_low_bounds, const doublereal *const y_high_bounds)
Set bounds constraints for all variables in the problem.
Delta residual calculation for the Jacbobian calculation.
void calc_ydot(const int order, const doublereal *const y_curr, doublereal *const ydot_curr) const
Internal function to calculate the time derivative of the solution at the new step.
doublereal normTrust_CP_
Norm of the Cauchy Step direction wrt trust region.
doublereal CurrentTrustFactor_
Factor indicating how much trust region has been changed this iteration - output variable.
doublereal JdJd_norm_
Dot product of the Jd_ variable defined above with itself.
Contains declarations for string manipulation functions within Cantera.
void getResidWts(doublereal *const residWts) const
Return the residual weights.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
int calcTrustIntersection(doublereal trustVal, doublereal &lambda, doublereal &alpha) const
Given a trust distance, this routine calculates the intersection of the this distance with the double...
doublereal m_conditionNumber
Condition number of the matrix.
Declarations for the class GeneralMatrix which is a virtual base class for matrices handled by solver...
std::vector< doublereal > m_wksp_2
Workspace of length neq_.
virtual doublereal filterSolnPrediction(const doublereal t, doublereal *const y)
Filter the solution predictions.
void setSolverScheme(int doDogLeg, int doAffineSolve)
Parameter to turn on solution solver schemes.
doublereal norm_deltaX_trust_
Current norm of the vector deltaX_trust_ in terms of the solution norm.
int doAffineSolve_
General toggle for turning on Affine solve with Hessian.
ResidJacEval * m_func
Pointer to the residual and jacobian evaluator for the function.
doublereal deltaBoundStep(const doublereal *const y, const doublereal *const step0)
Return the factor by which the undamped Newton step 'step0' must be multiplied in order to keep the u...
doublereal trustRegionInitializationFactor_
Factor used to set the initial trust region.
doublereal m_normResid_1
Norm of the residual at the end of the first leg of the current iteration.
std::vector< doublereal > m_rowWtScales
Weights for normalizing the values of the residuals.
void setPrintLvl(int printLvl)
Set the print level from the nonlinear solver.
static bool s_doBothSolvesAndCompare
Turn on solving both the Newton and Hessian systems and comparing the results.
doublereal residNorm2Cauchy_
Expected value of the residual norm at the Cauchy point if the quadratic model were valid...
doublereal dist_R0_
Distance of the zeroeth leg of the dogleg in terms of the solution norm.
doublereal atolBase_
Base value of the absolute tolerance.
std::vector< doublereal > m_wksp
Workspace of length neq_.
int maxNewtIts_
Maximum number of newton iterations.
doublereal m_ScaleSolnNormToResNorm
Scale factor for turning residual norms into solution norms.
virtual doublereal filterNewStep(const doublereal t, const doublereal *const ybase, doublereal *const step)
Filter the solution predictions.
Base residual calculation containing any lagged components.
int doDogLeg_
General toggle for turning on dog leg damping.
virtual doublereal rcondQR()=0
Returns an estimate of the inverse of the condition number for the matrix.
doublereal dist_Total_
Distance of the sum of all legs of the doglegs in terms of the solution norm.
std::vector< doublereal > & lowBoundsConstraintVector()
Return an editable vector of the low bounds constraints.
std::vector< doublereal > m_step_1
Value of the step to be taken in the solution.
std::vector< doublereal > & highBoundsConstraintVector()
Return an editable vector of the high bounds constraints.
doublereal doCauchyPointSolve(GeneralMatrix &jac)
Calculate the steepest descent direction and the Cauchy Point where the quadratic formulation of the ...
void setColumnScaling(bool useColScaling, const double *const scaleFactors=0)
Set the column scaling that are used for the inversion of the matrix.