15 #include "cantera/base/mdp_allo.h"
21 #define SAFE_DELETE(a) if (a) { delete (a); a = 0; }
28 extern void dcopy_(
int*,
double*,
int*,
double*,
int*);
38 BEulerErr::BEulerErr(std::string msg) :
39 CanteraError(
"BEulerInt", msg)
48 BEulerInt::BEulerInt() :
50 m_method(BEulerVarStep),
51 m_jacFormMethod(BEULER_JAC_NUM),
54 m_matrixConditioning(false),
63 m_time_step_attempts(0),
64 m_max_time_step_attempts(11000000),
65 m_numInitialConstantDeltaTSteps(0),
68 m_printSolnStepInterval(1),
69 m_printSolnNumberToTout(1),
70 m_printSolnFirstSteps(0),
71 m_dumpJacobians(false),
99 m_numTotalLinearSolves(0),
100 m_numTotalConvFails(0),
101 m_numTotalTruncFails(0),
133 if (static_cast<int>(n) !=
m_neq) {
134 printf(
"ERROR n is wrong\n");
137 for (
int i = 0; i <
m_neq; i++) {
155 void BEulerInt::setMethodBEMT(BEulerMethodType t)
160 void BEulerInt::setMaxStep(doublereal hmax)
165 void BEulerInt::setMaxNumTimeSteps(
int maxNumTimeSteps)
170 void BEulerInt::setNumInitialConstantDeltaTSteps(
int num)
200 void BEulerInt::setPrintSolnOptions(
int printSolnStepInterval,
201 int printSolnNumberToTout,
202 int printSolnFirstSteps,
228 void BEulerInt::setNonLinOptions(
int min_newt_its,
bool matrixConditioning,
229 bool colScaling,
bool rowScaling)
237 m_colScales = mdp_alloc_dbl_1(
m_neq, 1.0);
242 m_rowScales = mdp_alloc_dbl_1(
m_neq, 1.0);
254 void BEulerInt::setInitialTimeStep(
double deltaT)
256 delta_t_np1 = deltaT;
263 void BEulerInt::setPrintFlag(
int print_flag)
274 void BEulerInt::initializeRJE(
double t0, ResidJacEval& func)
276 m_neq = func.nEquations();
283 func.getInitialConditions(
m_t0, m_y_n, m_ydot_n);
303 void BEulerInt::reinitializeRJE(
double t0, ResidJacEval& func)
305 m_neq = func.nEquations();
313 func.getInitialConditions(
m_t0, m_y_n, m_ydot_n);
329 double BEulerInt::getPrintTime(
double time_current)
335 tnext =
m_t0 + dt * i;
336 if (tnext >= time_current) {
364 mdp_realloc_dbl_1(&m_y_n,
m_neq, 0, 0.0);
365 mdp_realloc_dbl_1(&m_y_nm1,
m_neq, 0, 0.0);
366 mdp_realloc_dbl_1(&m_y_pred_n,
m_neq, 0, 0.0);
367 mdp_realloc_dbl_1(&m_ydot_n,
m_neq, 0, 0.0);
368 mdp_realloc_dbl_1(&m_ydot_nm1,
m_neq, 0, 0.0);
369 mdp_realloc_dbl_1(&m_resid,
m_neq, 0, 0.0);
370 mdp_realloc_dbl_1(&m_residWts,
m_neq, 0, 0.0);
371 mdp_realloc_dbl_1(&m_wksp,
m_neq, 0, 0.0);
373 mdp_realloc_dbl_1(&m_rowScales,
m_neq, 0, 1.0);
376 mdp_realloc_dbl_1(&m_colScales,
m_neq, 0, 1.0);
389 void BEulerInt::setSolnWeights()
399 for (i = 0; i <
m_neq; i++) {
401 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
404 for (i = 0; i <
m_neq; i++) {
406 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
417 void BEulerInt::setColumnScales()
434 void BEulerInt::computeResidWts(GeneralMatrix& jac)
437 double* data = &(*(jac.begin()));
439 for (i = 0; i <
m_neq; i++) {
440 m_residWts[i] = fabs(data[i] *
m_ewt[0]);
441 for (j = 1; j <
m_neq; j++) {
442 value = fabs(data[j*m_neq + i] *
m_ewt[j]);
443 m_residWts[i] =
std::max(m_residWts[i], value);
454 double BEulerInt::filterNewStep(
double timeCurrent,
double* y_current,
double* ydot_current)
459 static void print_line(
const char* str,
int n)
461 for (
int i = 0; i < n; i++) {
470 static void print_time_step1(
int order,
int n_time_step,
double time,
471 double delta_t_n,
double delta_t_nm1,
472 bool step_failed,
int num_failures)
474 const char*
string = 0;
476 string =
"Backward Euler";
477 }
else if (order == 1) {
478 string =
"Forward/Backward Euler";
479 }
else if (order == 2) {
480 string =
"Adams-Bashforth/TR";
484 printf(
"\nStart of Time Step: %5d Time_n = %9.5g Time_nm1 = %9.5g\n",
485 n_time_step, time, time - delta_t_n);
486 printf(
"\tIntegration method = %s\n",
string);
488 printf(
"\tPreviously attempted step was a failure\n");
490 if (delta_t_n > delta_t_nm1) {
491 string =
"(Increased from previous iteration)";
492 }
else if (delta_t_n < delta_t_nm1) {
493 string =
"(Decreased from previous iteration)";
495 string =
"(same as previous iteration)";
497 printf(
"\tdelta_t_n = %8.5e %s", delta_t_n,
string);
498 if (num_failures > 0) {
499 printf(
"\t(Bad_History Failure Counter = %d)", num_failures);
501 printf(
"\n\tdelta_t_nm1 = %8.5e\n", delta_t_nm1);
507 static void print_time_step2(
int time_step_num,
int order,
508 double time,
double time_error_factor,
509 double delta_t_n,
double delta_t_np1)
511 printf(
"\tTime Step Number %5d was a success: time = %10g\n", time_step_num,
513 printf(
"\t\tEstimated Error\n");
514 printf(
"\t\t-------------------- = %8.5e\n", time_error_factor);
515 printf(
"\t\tTolerated Error\n\n");
516 printf(
"\t- Recommended next delta_t (not counting history) = %g\n",
526 static void print_time_fail(
bool convFailure,
int time_step_num,
527 double time,
double delta_t_n,
528 double delta_t_np1,
double time_error_factor)
533 printf(
"\tTime Step Number %5d experienced a convergence "
534 "failure\n", time_step_num);
535 printf(
"\tin the non-linear or linear solver\n");
536 printf(
"\t\tValue of time at failed step = %g\n", time);
537 printf(
"\t\tdelta_t of the failed step = %g\n",
539 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
542 printf(
"\tTime Step Number %5d experienced a truncation error "
543 "failure!\n", time_step_num);
544 printf(
"\t\tValue of time at failed step = %g\n", time);
545 printf(
"\t\tdelta_t of the failed step = %g\n",
547 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
549 printf(
"\t\tCalculated truncation error factor = %g\n",
559 static void print_final(
double time,
int step_failed,
560 int time_step_num,
int num_newt_its,
561 int total_linear_solves,
int numConvFails,
562 int numTruncFails,
int nfe,
int nJacEval)
566 printf(
"TIME INTEGRATION ROUTINE HAS FINISHED: ");
568 printf(
" IT WAS A FAILURE\n");
570 printf(
" IT WAS A SUCCESS\n");
572 printf(
"\tEnding time = %g\n", time);
573 printf(
"\tNumber of time steps = %d\n", time_step_num);
574 printf(
"\tNumber of newt its = %d\n", num_newt_its);
575 printf(
"\tNumber of linear solves = %d\n", total_linear_solves);
576 printf(
"\tNumber of convergence failures= %d\n", numConvFails);
577 printf(
"\tNumber of TimeTruncErr fails = %d\n", numTruncFails);
578 printf(
"\tNumber of Function evals = %d\n", nfe);
579 printf(
"\tNumber of Jacobian evals/solvs= %d\n", nJacEval);
587 static void print_lvl1_Header(
int nTimes)
593 printf(
"time Time Time Time ");
597 printf(
" (continued)");
601 printf(
"step (sec) step Newt Aztc bktr trunc ");
604 printf(
" No. Rslt size Its Its stps error |");
614 static void print_lvl1_summary(
615 int time_step_num,
double time,
const char* rslt,
double delta_t_n,
616 int newt_its,
int aztec_its,
int bktr_stps,
double time_error_factor,
619 printf(
"%6d %11.6g %4s %10.4g %4d %4d %4d %11.4g",
620 time_step_num, time, rslt, delta_t_n, newt_its, aztec_its,
621 bktr_stps, time_error_factor);
623 printf(
" | %s", comment);
647 double d =
std::min(fabs(a), fabs(b));
649 double ad = fabs(diff);
670 void BEulerInt::beuler_jac(GeneralMatrix& J,
double*
const f,
671 double time_curr,
double CJ,
678 double ysave, ydotsave, dy;
689 m_func->
evalJacobian(time_curr, delta_t_n, CJ, y, ydot, J, f);
719 bool print_NumJac =
false;
721 FILE* idy = fopen(
"NumJac.csv",
"w");
722 fprintf(idy,
"Unk m_ewt y "
724 for (
int iii = 0; iii <
m_neq; iii++) {
725 fprintf(idy,
" %4d %16.8e %16.8e %16.8e %16.8e \n",
726 iii,
m_ewt[iii], y[iii], dyVector[iii], f[iii]);
742 for (j = 0; j <
m_neq; j++) {
750 col_j = (
double*) J.ptrColumn(j);
764 m_func->
evalResidNJ(time_curr, delta_t_n, y, ydot, m_wksp,
768 for (i = 0; i <
m_neq; i++) {
770 col_j[i] = diff / dy;
825 for (i = 0; i <
m_neq; i++) {
826 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i];
830 c1 = delta_t_n * (2.0 + delta_t_n / delta_t_nm1) / 2.0;
831 c2 = (delta_t_n * delta_t_n) / (delta_t_nm1 * 2.0);
832 for (i = 0; i <
m_neq; i++) {
833 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i] - c2 * m_ydot_nm1[i];
887 c1 = 1.0 / delta_t_n;
888 for (i = 0; i <
m_neq; i++) {
889 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]);
893 c1 = 2.0 / delta_t_n;
894 for (i = 0; i <
m_neq; i++) {
895 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]) - m_ydot_nm1[i];
928 double rel_norm,
error;
930 #define NUM_ENTRIES 5
932 int imax[NUM_ENTRIES], j, jnum;
935 printf(
"\t\ttime step truncation error contributors:\n");
936 printf(
"\t\t I entry actual predicted "
940 for (j = 0; j < NUM_ENTRIES; j++) {
943 for (jnum = 0; jnum < NUM_ENTRIES; jnum++) {
945 for (i = 0; i <
m_neq; i++) {
947 for (j = 0; j < jnum; j++) {
953 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
954 rel_norm = sqrt(error * error);
955 if (rel_norm > dmax) {
961 if (imax[jnum] >= 0) {
963 printf(
"\t\t%4d %12.4e %12.4e %12.4e %12.4e %12.4e\n",
964 i, dmax, m_y_n[i], m_y_pred_n[i],
m_ewt[i], m_ydot_n[i]);
972 for (i = 0; i <
m_neq; i++) {
973 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
974 rel_norm += (error *
error);
976 rel_norm = sqrt(rel_norm / m_neq);
1023 double factor = 0.0, power = 0.0, delta_t;
1024 const char* yo =
"time_step_control";
1029 time_error_factor =
std::max(1.0E-50, time_error_factor);
1036 factor = 1.0/(2.0 *(time_error_factor));
1040 factor = 1.0/(3.0 * (1.0 + delta_t_nm1 / delta_t_n)
1041 * (time_error_factor));
1042 power = 0.3333333333333333;
1044 factor = pow(factor, power);
1047 printf(
"\t%s: WARNING - Current time step will be chucked\n", yo);
1048 printf(
"\t\tdue to a time step truncation error failure.\n");
1050 delta_t = - 0.5 * delta_t_n;
1053 delta_t = factor * delta_t_n;
1065 double BEulerInt::integrateRJE(
double tout,
double time_init)
1067 double time_current;
1068 bool weAreNotFinished =
true;
1083 bool doPrintSoln =
false;
1084 time_current = time_init;
1086 time_nm1 = time_init;
1087 time_nm2 = time_init;
1089 double print_time = getPrintTime(time_current);
1090 if (print_time == time_current) {
1092 istep, m_y_n, m_ydot_n);
1098 print_lvl1_Header(0);
1104 m_func->
user_out2(0, time_current, 0.0, m_y_n, m_ydot_n);
1108 print_time = getPrintTime(time_current);
1109 if (print_time >= tout) {
1116 time_current =
step(tout);
1120 if (time_current < 0.0) {
1121 if (time_current == -1234.) {
1124 time_current = -time_current;
1129 if (flag != FAILURE) {
1134 weAreNotFinished =
false;
1142 if (time_current >= print_time) {
1156 if (flag != FAILURE) {
1166 istep, m_y_n, m_ydot_n);
1168 doPrintSoln =
false;
1170 print_lvl1_Header(1);
1177 if (flag == FAILURE) {
1178 m_func->
user_out2(-1, time_current, delta_t_n, m_y_n, m_ydot_n);
1180 m_func->
user_out2(1, time_current, delta_t_n, m_y_n, m_ydot_n);
1183 }
while (time_current < tout &&
1185 flag == SUCCESS && weAreNotFinished);
1190 if (time_current >= tout) {
1191 printf(
"Simulation completed time integration in %d time steps\n",
1193 printf(
"Final Time: %e\n\n", time_current);
1195 printf(
"Simulation ran into time step attempt limit in"
1198 printf(
"Final Time: %e\n\n", time_current);
1199 }
else if (flag == FAILURE) {
1200 printf(
"ERROR: time stepper failed at time = %g\n", time_current);
1214 m_func->
user_out2(2, time_current, delta_t_n, m_y_n, m_ydot_n);
1217 if (flag != SUCCESS) {
1218 throw BEulerErr(
" BEuler error encountered.");
1220 return time_current;
1235 bool step_failed =
false;
1236 bool giveUp =
false;
1237 bool convFailure =
false;
1239 double time_error_factor = 0.0;
1240 double normFilter = 0.0;
1241 int numTSFailures = 0;
1244 int num_newt_its = 0;
1258 m_time_step_attempts++;
1267 if ((time_n + delta_t_np1) >= t_max) {
1268 delta_t_np1 =t_max - time_n;
1280 delta_t_nm2 = delta_t_nm1;
1281 delta_t_nm1 = delta_t_n;
1282 delta_t_n = delta_t_np1;
1283 time_n += delta_t_n;
1310 }
else if (step_failed) {
1381 CJ = 1.0 / delta_t_n;
1383 CJ = 2.0 / delta_t_n;
1398 aztec_its, bktr_stps,
1410 printf(
"\tStep is Rejected, nonlinear problem didn't converge,"
1411 "ierror = %d\n", ierror);
1414 convFailure =
false;
1415 step_failed =
false;
1421 normFilter = filterNewStep(time_n, m_y_n, m_ydot_n);
1422 if (normFilter > 1.0) {
1427 printf(
"\tStep is Rejected, too large filter adjustment = %g\n",
1430 }
else if (normFilter > 0.0) {
1431 if (normFilter > 0.3) {
1433 printf(
"\tStep was filtered, norm = %g, next "
1434 "time step adjusted\n", normFilter);
1438 printf(
"\tStep was filtered, norm = %g\n", normFilter);
1450 time_error_factor = 1000.;
1461 delta_t_np1 = 0.25 * delta_t_n;
1462 }
else if (
m_method == BEulerVarStep) {
1473 if (normFilter > 0.1) {
1474 if (delta_t_np1 > delta_t_n) {
1475 delta_t_np1 = delta_t_n;
1484 if (delta_t_np1 < 0.0) {
1487 delta_t_np1 = -delta_t_np1;
1489 comment +=
"TIME TRUNC FAILURE";
1499 delta_t_np1 =
std::min(delta_t_np1, delta_t_n);
1502 delta_t_np1 = delta_t_n;
1516 int max_Newton_steps = 10000;
1517 int target_num_iter = 5;
1518 if (num_newt_its > 3000 && !step_failed) {
1519 if (max_Newton_steps != target_num_iter) {
1520 double iter_diff = num_newt_its - target_num_iter;
1521 double iter_adjust_zone = max_Newton_steps - target_num_iter;
1522 double target_time_step = delta_t_n
1523 *(1.0 - iter_diff*fabs(iter_diff)/
1524 ((2.0*iter_adjust_zone*iter_adjust_zone)));
1525 target_time_step =
std::max(0.5*delta_t_n, target_time_step);
1526 if (target_time_step < delta_t_np1) {
1527 printf(
"\tNext time step will be decreased from %g to %g"
1528 " because of new its restraint\n",
1529 delta_t_np1, target_time_step);
1530 delta_t_np1 = target_time_step;
1553 delta_t_np1, time_error_factor);
1556 num_newt_its, aztec_its, bktr_stps,
1566 time_n -= delta_t_n;
1567 delta_t_n = delta_t_nm1;
1568 delta_t_nm1 = delta_t_nm2;
1573 dcopy_(&m_neq, m_y_nm1, &one, m_y_n, &one);
1574 dcopy_(&m_neq, m_ydot_nm1, &one, m_ydot_n, &one);
1578 if (numTSFailures > 35) {
1598 delta_t_n, delta_t_np1);
1601 num_newt_its, aztec_its, bktr_stps, time_error_factor,
1614 }
while (step_failed && !giveUp);
1620 if (time_n == 0.0) {
1652 double sum_norm = 0.0,
error;
1653 for (i = 0; i <
m_neq; i++) {
1657 sum_norm = sqrt(sum_norm / m_neq);
1659 const int num_entries = 8;
1660 double dmax1, normContrib;
1662 int* imax = mdp_alloc_int_1(num_entries, -1);
1663 printf(
"\t\tPrintout of Largest Contributors to norm "
1664 "of value (%g)\n", sum_norm);
1665 printf(
"\t\t I ysoln deltaY weightY "
1668 print_line(
"-", 80);
1669 for (
int jnum = 0; jnum < num_entries; jnum++) {
1671 for (i = 0; i <
m_neq; i++) {
1673 for (j = 0; j < jnum; j++) {
1681 if (normContrib > dmax1) {
1683 dmax1 = normContrib;
1689 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e\n",
1690 i, m_y_n[i], delta_y[i],
m_ewt[i], dmax1);
1694 print_line(
"-", 80);
1695 mdp_safe_free((
void**) &imax);
1699 #ifdef DEBUG_HKM_JAC
1712 double* ydot_curr,
double* delta_y,
1721 for (
int n = 0; n < sz; n++) {
1722 delta_y[n] = -delta_y[n];
1740 double* jptr = &(*(jac.
begin()));
1741 for (jcol = 0; jcol <
m_neq; jcol++) {
1742 for (irow = 0; irow <
m_neq; irow++) {
1743 *jptr *= m_colScales[jcol];
1754 double* jptr = &(*(jac.
begin()));
1771 double* jptr = &(*(jac.
begin()));
1772 for (irow = 0; irow <
m_neq; irow++) {
1773 m_rowScales[irow] = 0.0;
1775 for (jcol = 0; jcol <
m_neq; jcol++) {
1776 for (irow = 0; irow <
m_neq; irow++) {
1777 m_rowScales[irow] += fabs(*jptr);
1782 jptr = &(*(jac.
begin()));
1783 for (jcol = 0; jcol <
m_neq; jcol++) {
1784 for (irow = 0; irow <
m_neq; irow++) {
1785 *jptr /= m_rowScales[irow];
1790 for (irow = 0; irow <
m_neq; irow++) {
1791 delta_y[irow] /= m_rowScales[irow];
1795 #ifdef DEBUG_HKM_JAC
1796 bool printJacContributions =
false;
1798 printJacContributions =
false;
1803 bool freshJac =
true;
1804 RRow[0] = delta_y[focusRow];
1805 RRow[1] = delta_y[focusRow+1];
1806 double Pcutoff = 1.0E-70;
1807 if (!jac.m_factored) {
1817 (void) jac.
solve(delta_y);
1824 for (irow = 0; irow <
m_neq; irow++) {
1825 delta_y[irow] *= m_colScales[irow];
1829 #ifdef DEBUG_HKM_JAC
1830 if (printJacContributions) {
1831 for (
int iNum = 0; iNum < numRows; iNum++) {
1837 double dRow = Jdata[m_neq * focusRow + focusRow];
1838 printf(
"\n Details on delta_Y for row %d \n", focusRow);
1839 printf(
" Value before = %15.5e, delta = %15.5e,"
1840 "value after = %15.5e\n", y_curr[focusRow],
1842 y_curr[focusRow] + delta_y[focusRow]);
1844 printf(
" Old Jacobian\n");
1846 printf(
" col delta_y aij "
1848 printf(
"--------------------------------------------------"
1849 "---------------------------------------------\n");
1850 printf(
" Res(%d) %15.5e %15.5e %15.5e (Res = %g)\n",
1851 focusRow, delta_y[focusRow],
1852 dRow, RRow[iNum] / dRow, RRow[iNum]);
1853 dsum += RRow[iNum] / dRow;
1854 for (
int ii = 0; ii <
m_neq; ii++) {
1855 if (ii != focusRow) {
1856 double aij = Jdata[m_neq * ii + focusRow];
1857 double contrib = aij * delta_y[ii] * (-1.0) / dRow;
1859 if (fabs(contrib) > Pcutoff) {
1860 printf(
"%6d %15.5e %15.5e %15.5e\n", ii,
1861 delta_y[ii] , aij, contrib);
1865 printf(
"--------------------------------------------------"
1866 "---------------------------------------------\n");
1867 printf(
" %15.5e %15.5e\n",
1868 delta_y[focusRow], dsum);
1911 const double*
const step0,
int loglevel)
1913 int i, i_lower = -1, ifbd = 0, i_fbd = 0;
1914 double fbound = 1.0, f_lowbounds = 1.0, f_delta_bounds = 1.0;
1915 double ff, y_new, ff_alt;
1916 for (i = 0; i <
m_neq; i++) {
1917 y_new = y[i] + step0[i];
1918 if ((y_new < (-0.01 *
m_ewt[i])) && y[i] >= 0.0) {
1919 ff = 0.9 * (y[i] / (y[i] - y_new));
1920 if (ff < f_lowbounds) {
1931 if ((fabs(y_new) > 2.0 * fabs(y[i])) &&
1932 (fabs(y_new-y[i]) >
m_ewt[i])) {
1933 ff = fabs(y[i]/(y_new - y[i]));
1934 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1938 if ((fabs(5.0 * y_new) < fabs(y[i])) &&
1939 (fabs(y_new - y[i]) >
m_ewt[i])) {
1940 ff = y[i]/(y_new-y[i]) * (1.0 - 5.0)/5.0;
1941 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1945 if (ff < f_delta_bounds) {
1946 f_delta_bounds = ff;
1949 f_delta_bounds =
std::min(f_delta_bounds, ff);
1951 fbound =
std::min(f_lowbounds, f_delta_bounds);
1956 if (fbound != 1.0) {
1957 if (f_lowbounds < f_delta_bounds) {
1958 printf(
"\t\tboundStep: Variable %d causing lower bounds "
1960 i_lower, f_lowbounds);
1963 printf(
"\t\tboundStep: Decrease of Variable %d causing "
1964 "delta damping of %g\n",
1965 i_fbd, f_delta_bounds);
1967 printf(
"\t\tboundStep: Increase of variable %d causing"
1968 "delta damping of %g\n",
1969 i_fbd, f_delta_bounds);
1988 int BEulerInt::dampStep(
double time_curr,
const double* y0,
1989 const double* ydot0,
const double* step0,
1990 double* y1,
double* ydot1,
double* step1,
1992 int& loglevel,
bool writetitle,
1993 int& num_backtracks)
2005 double fbound =
boundStep(y0, step0, loglevel);
2011 if (fbound < 1.e-10) {
2013 printf(
"\t\t\tdampStep: At limits.\n");
2027 for (m = 0; m <
NDAMP; m++) {
2036 for (j = 0; j <
m_neq; j++) {
2037 y1[j] = y0[j] + ff*step0[j];
2052 for (j = 0; j <
m_neq; j++) {
2062 print_solnDelta_norm_contrib((
const double*) step0,
2064 (
const double*) step1,
2065 "DeltaSolnTrialTest",
2066 "dampNewt: Important Entries for "
2067 "Weighted Soln Updates:",
2071 printf(
"\t\t\tdampNewt: s0 = %g, s1 = %g, fbound = %g,"
2072 "damp = %g\n", s0, s1, fbound, damp);
2076 if (s1 > 1.00000001 * s0 && s1 > 1.0E-5) {
2077 printf(
"WARNING: Possible Jacobian Problem "
2078 "-> turning on more debugging for this step!!!\n");
2079 print_solnDelta_norm_contrib((
const double*) step0,
2081 (
const double*) step1,
2082 "DeltaSolnTrialTest",
2083 "dampNewt: Important Entries for "
2084 "Weighted Soln Updates:",
2096 if (s1 < 1.0E-5 || s1 < s0) {
2100 printf(
"\t\t\tdampStep: current trial step and damping"
2101 " coefficient accepted because test step < 1\n");
2102 printf(
"\t\t\t s1 = %g, s0 = %g\n", s1, s0);
2109 printf(
"\t\t\tdampStep: current step rejected: (s1 = %g > "
2110 "s0 = %g)", s1, s0);
2111 if (m < (NDAMP-1)) {
2112 printf(
" Decreasing damping factor and retrying");
2114 printf(
" Giving up!!!");
2134 if (s1 < 0.5 && (s0 < 0.5)) {
2166 double*
const ydot_comm,
double CJ,
2170 int& num_linear_solves,
2171 int& num_backtracks,
2175 bool forceNewJac =
false;
2178 double* y_curr = mdp_alloc_dbl_1(m_neq, 0.0);
2179 double* ydot_curr = mdp_alloc_dbl_1(m_neq, 0.0);
2180 double* stp = mdp_alloc_dbl_1(m_neq, 0.0);
2181 double* stp1 = mdp_alloc_dbl_1(m_neq, 0.0);
2182 double* y_new = mdp_alloc_dbl_1(m_neq, 0.0);
2183 double* ydot_new = mdp_alloc_dbl_1(m_neq, 0.0);
2204 printf(
"\t\tSolve_Nonlinear_Problem: iteration %d:\n",
2214 printf(
"\t\t\tGetting a new Jacobian and solving system\n");
2216 beuler_jac(jac, m_resid, time_curr, CJ, y_curr, ydot_curr,
2220 printf(
"\t\t\tSolving system with old jacobian\n");
2225 doNewtonSolve(time_curr, y_curr, ydot_curr, stp, jac, loglevel);
2228 m = dampStep(time_curr, y_curr, ydot_curr, stp, y_new, ydot_new,
2229 stp1, s1, jac, loglevel, frst, i_backtracks);
2231 num_backtracks += i_backtracks;
2244 if (num_newt_its > 20) {
2247 printf(
"\t\t\tDampnewton unsuccessful (max newts exceeded) sfinal = %g\n", s1);
2253 printf(
"\t\t\tDampNewton iteration successful, nonlin "
2254 "converged sfinal = %g\n", s1);
2255 }
else if (m == 0) {
2256 printf(
"\t\t\tDampNewton iteration successful, get new"
2257 "direction, sfinal = %g\n", s1);
2259 printf(
"\t\t\tDampnewton unsuccessful sfinal = %g\n", s1);
2281 bool m_filterIntermediate =
false;
2282 if (m_filterIntermediate) {
2284 (void) filterNewStep(time_n, y_new, ydot_new);
2288 if (m == 0 || m == 1) {
2313 mdp_safe_free((
void**) &y_curr);
2314 mdp_safe_free((
void**) &ydot_curr);
2315 mdp_safe_free((
void**) &stp);
2316 mdp_safe_free((
void**) &stp1);
2317 mdp_safe_free((
void**) &y_new);
2318 mdp_safe_free((
void**) &ydot_new);
2320 double time_elapsed = 0.0;
2323 printf(
"\t\tNonlinear problem solved successfully in "
2324 "%d its, time elapsed = %g sec\n",
2325 num_newt_its, time_elapsed);
2336 print_solnDelta_norm_contrib(
const double*
const solnDelta0,
2337 const char*
const s0,
2338 const double*
const solnDelta1,
2339 const char*
const s1,
2340 const char*
const title,
2341 const double*
const y0,
2342 const double*
const y1,
2348 double dmax0, dmax1,
error, rel_norm;
2349 printf(
"\t\t%s currentDamp = %g\n", title, damp);
2350 printf(
"\t\t I ysoln %10s ysolnTrial "
2351 "%10s weight relSoln0 relSoln1\n", s0, s1);
2352 int* imax = mdp_alloc_int_1(num_entries, -1);
2354 print_line(
"-", 90);
2355 for (jnum = 0; jnum < num_entries; jnum++) {
2357 for (i = 0; i <
m_neq; i++) {
2359 for (j = 0; j < jnum; j++) {
2365 error = solnDelta0[i] /
m_ewt[i];
2366 rel_norm = sqrt(error * error);
2367 error = solnDelta1[i] /
m_ewt[i];
2368 rel_norm += sqrt(error * error);
2369 if (rel_norm > dmax1) {
2375 if (imax[jnum] >= 0) {
2377 error = solnDelta0[i] /
m_ewt[i];
2378 dmax0 = sqrt(error * error);
2379 error = solnDelta1[i] /
m_ewt[i];
2380 dmax1 = sqrt(error * error);
2381 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e "
2382 "%12.4e %12.4e %12.4e\n",
2383 i, y0[i], solnDelta0[i], y1[i],
2384 solnDelta1[i],
m_ewt[i], dmax0, dmax1);
2388 print_line(
"-", 90);
2389 mdp_safe_free((
void**) &imax);