19 BEulerErr::BEulerErr(
const std::string& msg) :
26 m_method(BEulerVarStep),
27 m_jacFormMethod(BEULER_JAC_NUM),
30 m_matrixConditioning(false),
39 m_time_step_attempts(0),
40 m_max_time_step_attempts(11000000),
41 m_numInitialConstantDeltaTSteps(0),
44 m_printSolnStepInterval(1),
45 m_printSolnNumberToTout(1),
46 m_printSolnFirstSteps(0),
47 m_dumpJacobians(false),
75 m_numTotalLinearSolves(0),
76 m_numTotalConvFails(0),
77 m_numTotalTruncFails(0),
83 BEulerInt::~BEulerInt()
92 if (static_cast<int>(n) !=
m_neq) {
93 printf(
"ERROR n is wrong\n");
96 for (
int i = 0; i <
m_neq; i++) {
114 void BEulerInt::setMethodBEMT(BEulerMethodType t)
119 void BEulerInt::setMaxStep(doublereal hmax)
124 void BEulerInt::setMaxNumTimeSteps(
int maxNumTimeSteps)
129 void BEulerInt::setNumInitialConstantDeltaTSteps(
int num)
135 int printSolnNumberToTout,
136 int printSolnFirstSteps,
151 bool colScaling,
bool rowScaling)
158 m_colScales.assign(
m_neq, 1.0);
161 m_rowScales.assign(
m_neq, 1.0);
165 void BEulerInt::setInitialTimeStep(
double deltaT)
167 delta_t_np1 = deltaT;
170 void BEulerInt::setPrintFlag(
int print_flag)
199 void BEulerInt::reinitializeRJE(
double t0,
ResidJacEval& func)
226 tnext =
m_t0 + dt * i;
227 if (tnext >= time_current) {
243 m_y_n.assign(
m_neq, 0.0);
244 m_y_nm1.assign(
m_neq, 0.0);
245 m_y_pred_n.assign(
m_neq, 0.0);
246 m_ydot_n.assign(
m_neq, 0.0);
247 m_ydot_nm1.assign(
m_neq, 0.0);
248 m_resid.assign(
m_neq, 0.0);
249 m_residWts.assign(
m_neq, 0.0);
250 m_wksp.assign(
m_neq, 0.0);
252 m_rowScales.assign(
m_neq, 1.0);
255 m_colScales.assign(
m_neq, 1.0);
270 for (i = 0; i <
m_neq; i++) {
272 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
275 for (i = 0; i <
m_neq; i++) {
277 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
284 m_func->
calcSolnScales(time_n, &m_y_n[0], &m_y_nm1[0], &m_colScales[0]);
300 double* data = &(*(jac.
begin()));
302 for (i = 0; i <
m_neq; i++) {
303 m_residWts[i] = fabs(data[i] *
m_ewt[0]);
304 for (j = 1; j <
m_neq; j++) {
305 value = fabs(data[j*m_neq + i] * m_ewt[j]);
306 m_residWts[i] = std::max(m_residWts[i], value);
316 static void print_line(
const char* str,
int n)
318 for (
int i = 0; i < n; i++) {
327 static void print_time_step1(
int order,
int n_time_step,
double time,
328 double delta_t_n,
double delta_t_nm1,
329 bool step_failed,
int num_failures)
331 const char*
string = 0;
333 string =
"Backward Euler";
334 }
else if (order == 1) {
335 string =
"Forward/Backward Euler";
336 }
else if (order == 2) {
337 string =
"Adams-Bashforth/TR";
341 printf(
"\nStart of Time Step: %5d Time_n = %9.5g Time_nm1 = %9.5g\n",
342 n_time_step, time, time - delta_t_n);
343 printf(
"\tIntegration method = %s\n",
string);
345 printf(
"\tPreviously attempted step was a failure\n");
347 if (delta_t_n > delta_t_nm1) {
348 string =
"(Increased from previous iteration)";
349 }
else if (delta_t_n < delta_t_nm1) {
350 string =
"(Decreased from previous iteration)";
352 string =
"(same as previous iteration)";
354 printf(
"\tdelta_t_n = %8.5e %s", delta_t_n,
string);
355 if (num_failures > 0) {
356 printf(
"\t(Bad_History Failure Counter = %d)", num_failures);
358 printf(
"\n\tdelta_t_nm1 = %8.5e\n", delta_t_nm1);
364 static void print_time_step2(
int time_step_num,
int order,
365 double time,
double time_error_factor,
366 double delta_t_n,
double delta_t_np1)
368 printf(
"\tTime Step Number %5d was a success: time = %10g\n", time_step_num,
370 printf(
"\t\tEstimated Error\n");
371 printf(
"\t\t-------------------- = %8.5e\n", time_error_factor);
372 printf(
"\t\tTolerated Error\n\n");
373 printf(
"\t- Recommended next delta_t (not counting history) = %g\n",
383 static void print_time_fail(
bool convFailure,
int time_step_num,
384 double time,
double delta_t_n,
385 double delta_t_np1,
double time_error_factor)
390 printf(
"\tTime Step Number %5d experienced a convergence "
391 "failure\n", time_step_num);
392 printf(
"\tin the non-linear or linear solver\n");
393 printf(
"\t\tValue of time at failed step = %g\n", time);
394 printf(
"\t\tdelta_t of the failed step = %g\n",
396 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
399 printf(
"\tTime Step Number %5d experienced a truncation error "
400 "failure!\n", time_step_num);
401 printf(
"\t\tValue of time at failed step = %g\n", time);
402 printf(
"\t\tdelta_t of the failed step = %g\n",
404 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
406 printf(
"\t\tCalculated truncation error factor = %g\n",
416 static void print_final(
double time,
int step_failed,
417 int time_step_num,
int num_newt_its,
418 int total_linear_solves,
int numConvFails,
419 int numTruncFails,
int nfe,
int nJacEval)
423 printf(
"TIME INTEGRATION ROUTINE HAS FINISHED: ");
425 printf(
" IT WAS A FAILURE\n");
427 printf(
" IT WAS A SUCCESS\n");
429 printf(
"\tEnding time = %g\n", time);
430 printf(
"\tNumber of time steps = %d\n", time_step_num);
431 printf(
"\tNumber of newt its = %d\n", num_newt_its);
432 printf(
"\tNumber of linear solves = %d\n", total_linear_solves);
433 printf(
"\tNumber of convergence failures= %d\n", numConvFails);
434 printf(
"\tNumber of TimeTruncErr fails = %d\n", numTruncFails);
435 printf(
"\tNumber of Function evals = %d\n", nfe);
436 printf(
"\tNumber of Jacobian evals/solvs= %d\n", nJacEval);
444 static void print_lvl1_Header(
int nTimes)
450 printf(
"time Time Time Time ");
454 printf(
" (continued)");
458 printf(
"step (sec) step Newt Aztc bktr trunc ");
461 printf(
" No. Rslt size Its Its stps error |");
471 static void print_lvl1_summary(
472 int time_step_num,
double time,
const char* rslt,
double delta_t_n,
473 int newt_its,
int aztec_its,
int bktr_stps,
double time_error_factor,
476 printf(
"%6d %11.6g %4s %10.4g %4d %4d %4d %11.4g",
477 time_step_num, time, rslt, delta_t_n, newt_its, aztec_its,
478 bktr_stps, time_error_factor);
480 printf(
" | %s", comment);
503 double d = std::min(fabs(a), fabs(b));
505 double ad = fabs(diff);
516 double time_curr,
double CJ,
523 double ysave, ydotsave, dy;
534 m_func->
evalJacobian(time_curr, delta_t_n, CJ, y, ydot, J, f);
564 bool print_NumJac =
false;
566 FILE* idy = fopen(
"NumJac.csv",
"w");
567 fprintf(idy,
"Unk m_ewt y "
569 for (
int iii = 0; iii <
m_neq; iii++) {
570 fprintf(idy,
" %4d %16.8e %16.8e %16.8e %16.8e \n",
571 iii,
m_ewt[iii], y[iii], dyVector[iii], f[iii]);
587 for (j = 0; j <
m_neq; j++) {
609 m_func->
evalResidNJ(time_curr, delta_t_n, y, ydot, &m_wksp[0],
613 for (i = 0; i <
m_neq; i++) {
615 col_j[i] = diff / dy;
636 for (i = 0; i <
m_neq; i++) {
637 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i];
641 c1 = delta_t_n * (2.0 + delta_t_n / delta_t_nm1) / 2.0;
642 c2 = (delta_t_n * delta_t_n) / (delta_t_nm1 * 2.0);
643 for (i = 0; i <
m_neq; i++) {
644 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i] - c2 * m_ydot_nm1[i];
664 c1 = 1.0 / delta_t_n;
665 for (i = 0; i <
m_neq; i++) {
666 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]);
670 c1 = 2.0 / delta_t_n;
671 for (i = 0; i <
m_neq; i++) {
672 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]) - m_ydot_nm1[i];
681 double rel_norm,
error;
683 #define NUM_ENTRIES 5
685 int imax[NUM_ENTRIES], j, jnum;
688 printf(
"\t\ttime step truncation error contributors:\n");
689 printf(
"\t\t I entry actual predicted "
693 for (j = 0; j < NUM_ENTRIES; j++) {
696 for (jnum = 0; jnum < NUM_ENTRIES; jnum++) {
698 for (i = 0; i <
m_neq; i++) {
700 for (j = 0; j < jnum; j++) {
706 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
707 rel_norm = sqrt(error * error);
708 if (rel_norm > dmax) {
714 if (imax[jnum] >= 0) {
716 printf(
"\t\t%4d %12.4e %12.4e %12.4e %12.4e %12.4e\n",
717 i, dmax, m_y_n[i], m_y_pred_n[i],
m_ewt[i], m_ydot_n[i]);
725 for (i = 0; i <
m_neq; i++) {
726 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
727 rel_norm += (error *
error);
729 return sqrt(rel_norm / m_neq);
734 double factor = 0.0, power = 0.0, delta_t;
735 const char* yo =
"time_step_control";
740 time_error_factor = std::max(1.0E-50, time_error_factor);
747 factor = 1.0/(2.0 *(time_error_factor));
751 factor = 1.0/(3.0 * (1.0 + delta_t_nm1 / delta_t_n)
752 * (time_error_factor));
753 power = 0.3333333333333333;
755 factor = pow(factor, power);
758 printf(
"\t%s: WARNING - Current time step will be chucked\n", yo);
759 printf(
"\t\tdue to a time step truncation error failure.\n");
761 delta_t = - 0.5 * delta_t_n;
763 factor = std::min(factor, 1.5);
764 delta_t = factor * delta_t_n;
769 double BEulerInt::integrateRJE(
double tout,
double time_init)
772 bool weAreNotFinished =
true;
787 bool doPrintSoln =
false;
788 time_current = time_init;
790 time_nm1 = time_init;
791 time_nm2 = time_init;
794 if (print_time == time_current) {
796 istep, &m_y_n[0], &m_ydot_n[0]);
802 print_lvl1_Header(0);
808 m_func->
user_out2(0, time_current, 0.0, &m_y_n[0], &m_ydot_n[0]);
813 if (print_time >= tout) {
820 time_current =
step(tout);
824 if (time_current < 0.0) {
825 if (time_current == -1234.) {
828 time_current = -time_current;
833 if (flag != FAILURE) {
836 &m_y_n[0], &m_ydot_n[0]);
838 weAreNotFinished =
false;
846 if (time_current >= print_time) {
860 if (flag != FAILURE) {
862 &m_y_n[0], &m_ydot_n[0]);
870 istep, &m_y_n[0], &m_ydot_n[0]);
874 print_lvl1_Header(1);
881 if (flag == FAILURE) {
882 m_func->
user_out2(-1, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
884 m_func->
user_out2(1, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
887 }
while (time_current < tout &&
889 flag == SUCCESS && weAreNotFinished);
894 if (time_current >= tout) {
895 printf(
"Simulation completed time integration in %d time steps\n",
897 printf(
"Final Time: %e\n\n", time_current);
899 printf(
"Simulation ran into time step attempt limit in"
902 printf(
"Final Time: %e\n\n", time_current);
903 }
else if (flag == FAILURE) {
904 printf(
"ERROR: time stepper failed at time = %g\n", time_current);
918 m_func->
user_out2(2, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
921 if (flag != SUCCESS) {
922 throw BEulerErr(
" BEuler error encountered.");
930 bool step_failed =
false;
932 bool convFailure =
false;
934 double time_error_factor = 0.0;
935 double normFilter = 0.0;
936 int numTSFailures = 0;
939 int num_newt_its = 0;
953 m_time_step_attempts++;
962 if ((time_n + delta_t_np1) >= t_max) {
963 delta_t_np1 =t_max - time_n;
975 delta_t_nm2 = delta_t_nm1;
976 delta_t_nm1 = delta_t_n;
977 delta_t_n = delta_t_np1;
1005 }
else if (step_failed) {
1061 m_ydot_nm1 = m_ydot_n;
1076 CJ = 1.0 / delta_t_n;
1078 CJ = 2.0 / delta_t_n;
1093 aztec_its, bktr_stps,
1105 printf(
"\tStep is Rejected, nonlinear problem didn't converge,"
1106 "ierror = %d\n", ierror);
1109 convFailure =
false;
1110 step_failed =
false;
1116 normFilter =
filterNewStep(time_n, &m_y_n[0], &m_ydot_n[0]);
1117 if (normFilter > 1.0) {
1122 printf(
"\tStep is Rejected, too large filter adjustment = %g\n",
1125 }
else if (normFilter > 0.0) {
1126 if (normFilter > 0.3) {
1128 printf(
"\tStep was filtered, norm = %g, next "
1129 "time step adjusted\n", normFilter);
1133 printf(
"\tStep was filtered, norm = %g\n", normFilter);
1145 time_error_factor = 1000.;
1156 delta_t_np1 = 0.25 * delta_t_n;
1157 }
else if (
m_method == BEulerVarStep) {
1168 if (normFilter > 0.1) {
1169 if (delta_t_np1 > delta_t_n) {
1170 delta_t_np1 = delta_t_n;
1179 if (delta_t_np1 < 0.0) {
1182 delta_t_np1 = -delta_t_np1;
1184 comment +=
"TIME TRUNC FAILURE";
1194 delta_t_np1 = std::min(delta_t_np1, delta_t_n);
1197 delta_t_np1 = delta_t_n;
1211 int max_Newton_steps = 10000;
1212 int target_num_iter = 5;
1213 if (num_newt_its > 3000 && !step_failed) {
1214 if (max_Newton_steps != target_num_iter) {
1215 double iter_diff = num_newt_its - target_num_iter;
1216 double iter_adjust_zone = max_Newton_steps - target_num_iter;
1217 double target_time_step = delta_t_n
1218 *(1.0 - iter_diff*fabs(iter_diff)/
1219 ((2.0*iter_adjust_zone*iter_adjust_zone)));
1220 target_time_step = std::max(0.5*delta_t_n, target_time_step);
1221 if (target_time_step < delta_t_np1) {
1222 printf(
"\tNext time step will be decreased from %g to %g"
1223 " because of new its restraint\n",
1224 delta_t_np1, target_time_step);
1225 delta_t_np1 = target_time_step;
1248 delta_t_np1, time_error_factor);
1251 num_newt_its, aztec_its, bktr_stps,
1261 time_n -= delta_t_n;
1262 delta_t_n = delta_t_nm1;
1263 delta_t_nm1 = delta_t_nm2;
1269 m_ydot_n = m_ydot_nm1;
1273 if (numTSFailures > 35) {
1293 delta_t_n, delta_t_np1);
1296 num_newt_its, aztec_its, bktr_stps, time_error_factor,
1309 }
while (step_failed && !giveUp);
1315 if (time_n == 0.0) {
1338 double sum_norm = 0.0,
error;
1339 for (i = 0; i <
m_neq; i++) {
1343 sum_norm = sqrt(sum_norm / m_neq);
1345 const int num_entries = 8;
1346 double dmax1, normContrib;
1349 printf(
"\t\tPrintout of Largest Contributors to norm "
1350 "of value (%g)\n", sum_norm);
1351 printf(
"\t\t I ysoln deltaY weightY "
1354 print_line(
"-", 80);
1355 for (
int jnum = 0; jnum < num_entries; jnum++) {
1357 for (i = 0; i <
m_neq; i++) {
1359 for (j = 0; j < jnum; j++) {
1367 if (normContrib > dmax1) {
1369 dmax1 = normContrib;
1375 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e\n",
1376 i, m_y_n[i], delta_y[i],
m_ewt[i], dmax1);
1380 print_line(
"-", 80);
1384 #ifdef DEBUG_HKM_JAC
1389 double* ydot_curr,
double* delta_y,
1398 for (
int n = 0; n < sz; n++) {
1399 delta_y[n] = -delta_y[n];
1417 double* jptr = &(*(jac.
begin()));
1418 for (jcol = 0; jcol <
m_neq; jcol++) {
1419 for (irow = 0; irow <
m_neq; irow++) {
1420 *jptr *= m_colScales[jcol];
1431 double* jptr = &(*(jac.
begin()));
1448 double* jptr = &(*(jac.
begin()));
1449 for (irow = 0; irow <
m_neq; irow++) {
1450 m_rowScales[irow] = 0.0;
1452 for (jcol = 0; jcol <
m_neq; jcol++) {
1453 for (irow = 0; irow <
m_neq; irow++) {
1454 m_rowScales[irow] += fabs(*jptr);
1459 jptr = &(*(jac.
begin()));
1460 for (jcol = 0; jcol <
m_neq; jcol++) {
1461 for (irow = 0; irow <
m_neq; irow++) {
1462 *jptr /= m_rowScales[irow];
1467 for (irow = 0; irow <
m_neq; irow++) {
1468 delta_y[irow] /= m_rowScales[irow];
1472 #ifdef DEBUG_HKM_JAC
1473 bool printJacContributions =
false;
1475 printJacContributions =
false;
1480 bool freshJac =
true;
1481 RRow[0] = delta_y[focusRow];
1482 RRow[1] = delta_y[focusRow+1];
1483 double Pcutoff = 1.0E-70;
1484 if (!jac.m_factored) {
1494 (void) jac.
solve(delta_y);
1501 for (irow = 0; irow <
m_neq; irow++) {
1502 delta_y[irow] *= m_colScales[irow];
1506 #ifdef DEBUG_HKM_JAC
1507 if (printJacContributions) {
1508 for (
int iNum = 0; iNum < numRows; iNum++) {
1514 double dRow = Jdata[
m_neq * focusRow + focusRow];
1515 printf(
"\n Details on delta_Y for row %d \n", focusRow);
1516 printf(
" Value before = %15.5e, delta = %15.5e,"
1517 "value after = %15.5e\n", y_curr[focusRow],
1519 y_curr[focusRow] + delta_y[focusRow]);
1521 printf(
" Old Jacobian\n");
1523 printf(
" col delta_y aij "
1525 printf(
"--------------------------------------------------"
1526 "---------------------------------------------\n");
1527 printf(
" Res(%d) %15.5e %15.5e %15.5e (Res = %g)\n",
1528 focusRow, delta_y[focusRow],
1529 dRow, RRow[iNum] / dRow, RRow[iNum]);
1530 dsum += RRow[iNum] / dRow;
1531 for (
int ii = 0; ii <
m_neq; ii++) {
1532 if (ii != focusRow) {
1533 double aij = Jdata[m_neq * ii + focusRow];
1534 double contrib = aij * delta_y[ii] * (-1.0) / dRow;
1536 if (fabs(contrib) > Pcutoff) {
1537 printf(
"%6d %15.5e %15.5e %15.5e\n", ii,
1538 delta_y[ii] , aij, contrib);
1542 printf(
"--------------------------------------------------"
1543 "---------------------------------------------\n");
1544 printf(
" %15.5e %15.5e\n",
1545 delta_y[focusRow], dsum);
1555 const double*
const step0,
int loglevel)
1557 int i, i_lower = -1, ifbd = 0, i_fbd = 0;
1558 double fbound = 1.0, f_lowbounds = 1.0, f_delta_bounds = 1.0;
1559 double ff, y_new, ff_alt;
1560 for (i = 0; i <
m_neq; i++) {
1561 y_new = y[i] + step0[i];
1562 if ((y_new < (-0.01 *
m_ewt[i])) && y[i] >= 0.0) {
1563 ff = 0.9 * (y[i] / (y[i] - y_new));
1564 if (ff < f_lowbounds) {
1575 if ((fabs(y_new) > 2.0 * fabs(y[i])) &&
1576 (fabs(y_new-y[i]) >
m_ewt[i])) {
1577 ff = fabs(y[i]/(y_new - y[i]));
1578 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1579 ff = std::max(ff, ff_alt);
1582 if ((fabs(5.0 * y_new) < fabs(y[i])) &&
1583 (fabs(y_new - y[i]) >
m_ewt[i])) {
1584 ff = y[i]/(y_new-y[i]) * (1.0 - 5.0)/5.0;
1585 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1586 ff = std::max(ff, ff_alt);
1589 if (ff < f_delta_bounds) {
1590 f_delta_bounds = ff;
1593 f_delta_bounds = std::min(f_delta_bounds, ff);
1595 fbound = std::min(f_lowbounds, f_delta_bounds);
1600 if (fbound != 1.0) {
1601 if (f_lowbounds < f_delta_bounds) {
1602 printf(
"\t\tboundStep: Variable %d causing lower bounds "
1604 i_lower, f_lowbounds);
1607 printf(
"\t\tboundStep: Decrease of Variable %d causing "
1608 "delta damping of %g\n",
1609 i_fbd, f_delta_bounds);
1611 printf(
"\t\tboundStep: Increase of variable %d causing"
1612 "delta damping of %g\n",
1613 i_fbd, f_delta_bounds);
1622 const double* ydot0,
const double* step0,
1623 double* y1,
double* ydot1,
double* step1,
1625 int& loglevel,
bool writetitle,
1626 int& num_backtracks)
1636 double fbound =
boundStep(y0, step0, loglevel);
1642 if (fbound < 1.e-10) {
1644 printf(
"\t\t\tdampStep: At limits.\n");
1658 for (m = 0; m <
NDAMP; m++) {
1667 for (j = 0; j <
m_neq; j++) {
1668 y1[j] = y0[j] + ff*step0[j];
1683 for (j = 0; j <
m_neq; j++) {
1693 print_solnDelta_norm_contrib((
const double*) step0,
1695 (
const double*) step1,
1696 "DeltaSolnTrialTest",
1697 "dampNewt: Important Entries for "
1698 "Weighted Soln Updates:",
1702 printf(
"\t\t\tdampNewt: s0 = %g, s1 = %g, fbound = %g,"
1703 "damp = %g\n", s0, s1, fbound, damp);
1707 if (s1 > 1.00000001 * s0 && s1 > 1.0E-5) {
1708 printf(
"WARNING: Possible Jacobian Problem "
1709 "-> turning on more debugging for this step!!!\n");
1710 print_solnDelta_norm_contrib((
const double*) step0,
1712 (
const double*) step1,
1713 "DeltaSolnTrialTest",
1714 "dampNewt: Important Entries for "
1715 "Weighted Soln Updates:",
1727 if (s1 < 1.0E-5 || s1 < s0) {
1731 printf(
"\t\t\tdampStep: current trial step and damping"
1732 " coefficient accepted because test step < 1\n");
1733 printf(
"\t\t\t s1 = %g, s0 = %g\n", s1, s0);
1740 printf(
"\t\t\tdampStep: current step rejected: (s1 = %g > "
1741 "s0 = %g)", s1, s0);
1742 if (m < (NDAMP-1)) {
1743 printf(
" Decreasing damping factor and retrying");
1745 printf(
" Giving up!!!");
1765 if (s1 < 0.5 && (s0 < 0.5)) {
1776 double*
const ydot_comm,
double CJ,
1780 int& num_linear_solves,
1781 int& num_backtracks,
1785 bool forceNewJac =
false;
1811 printf(
"\t\tSolve_Nonlinear_Problem: iteration %d:\n",
1821 printf(
"\t\t\tGetting a new Jacobian and solving system\n");
1823 beuler_jac(jac, &m_resid[0], time_curr, CJ, &y_curr[0], &ydot_curr[0],
1827 printf(
"\t\t\tSolving system with old jacobian\n");
1832 doNewtonSolve(time_curr, &y_curr[0], &ydot_curr[0], &stp[0], jac, loglevel);
1835 m =
dampStep(time_curr, &y_curr[0], &ydot_curr[0], &stp[0], &y_new[0], &ydot_new[0],
1836 &stp1[0], s1, jac, loglevel, frst, i_backtracks);
1838 num_backtracks += i_backtracks;
1851 if (num_newt_its > 20) {
1854 printf(
"\t\t\tDampnewton unsuccessful (max newts exceeded) sfinal = %g\n", s1);
1860 printf(
"\t\t\tDampNewton iteration successful, nonlin "
1861 "converged sfinal = %g\n", s1);
1862 }
else if (m == 0) {
1863 printf(
"\t\t\tDampNewton iteration successful, get new"
1864 "direction, sfinal = %g\n", s1);
1866 printf(
"\t\t\tDampnewton unsuccessful sfinal = %g\n", s1);
1888 bool m_filterIntermediate =
false;
1889 if (m_filterIntermediate) {
1895 if (m == 0 || m == 1) {
1915 copy(y_curr.begin(), y_curr.end(), y_comm);
1916 copy(ydot_curr.begin(), ydot_curr.end(), ydot_comm);
1920 double time_elapsed = 0.0;
1923 printf(
"\t\tNonlinear problem solved successfully in "
1924 "%d its, time elapsed = %g sec\n",
1925 num_newt_its, time_elapsed);
1932 print_solnDelta_norm_contrib(
const double*
const solnDelta0,
1933 const char*
const s0,
1934 const double*
const solnDelta1,
1935 const char*
const s1,
1936 const char*
const title,
1937 const double*
const y0,
1938 const double*
const y1,
1944 double dmax0, dmax1,
error, rel_norm;
1945 printf(
"\t\t%s currentDamp = %g\n", title, damp);
1946 printf(
"\t\t I ysoln %10s ysolnTrial "
1947 "%10s weight relSoln0 relSoln1\n", s0, s1);
1950 print_line(
"-", 90);
1951 for (jnum = 0; jnum < num_entries; jnum++) {
1953 for (i = 0; i <
m_neq; i++) {
1955 for (j = 0; j < jnum; j++) {
1961 error = solnDelta0[i] /
m_ewt[i];
1962 rel_norm = sqrt(error * error);
1963 error = solnDelta1[i] /
m_ewt[i];
1964 rel_norm += sqrt(error * error);
1965 if (rel_norm > dmax1) {
1971 if (imax[jnum] >= 0) {
1973 error = solnDelta0[i] /
m_ewt[i];
1974 dmax0 = sqrt(error * error);
1975 error = solnDelta1[i] /
m_ewt[i];
1976 dmax1 = sqrt(error * error);
1977 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e "
1978 "%12.4e %12.4e %12.4e\n",
1979 i, y0[i], solnDelta0[i], y1[i],
1980 solnDelta1[i],
m_ewt[i], dmax0, dmax1);
1984 print_line(
"-", 90);
virtual void setPrintSolnOptions(int printSolnStepInterval, int printSolnNumberToTout, int printSolnFirstSteps=0, bool dumpJacobians=false)
This routine controls when the solution is printed.
double m_time_final
Final time.
virtual doublereal * ptrColumn(size_t j)=0
Return a pointer to the top of column j, columns are assumed to be contiguous in memory.
virtual void user_out2(const int ifunc, const doublereal t, const doublereal delta_t, const doublereal *const y, const doublereal *const ydot)
This function may be used to create output at various points in the execution of an application...
int m_numTotalTruncFails
Total Number of time truncation error failures.
virtual void setProblemType(int probtype)
Set the problem type.
int m_printSolnNumberToTout
Number of evenly spaced printouts of the solution If zero, there is no printout from this option defa...
double getPrintTime(double time_current)
Get the next time to print out.
virtual void setIterator(IterType t)
Set the linear iterator.
int m_printSolnStepInterval
Step Interval at which to print out the solution default = 1; If set to zero, there is no printout...
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
virtual int nEquations() const
Return the number of equations in the equation system.
int m_numTotalNewtIts
Number of total newton iterations.
int m_neq
Number of equations in the ode integrator.
virtual double soln_error_norm(const double *const, bool printLargest=false)
Calculate the solution error norm.
void doNewtonSolve(double, double *, double *, double *, GeneralMatrix &, int)
Compute the undamped Newton step.
int m_failure_counter
Failure Counter -> keeps track of the number of consecutive failures.
BEulerMethodType m_method
MethodType is used to specify how the time step is to be chosen.
bool m_rowScaling
m_rowScaling is a boolean.
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.
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. ...
virtual vector_fp::iterator begin()=0
Return an iterator pointing to the first element.
void beuler_jac(GeneralMatrix &J, double *const f, double, double, double *const, double *const, int)
double m_reltol
Relative time truncation error tolerances.
double m_t0
Initial time at the start of the integration.
const double DampFactor
Dampfactor is the factor by which the damping factor is reduced by when a reduction in step length is...
virtual void writeSolution(int ievent, const double time, const double deltaT, const int time_step_num, const double *y, const double *ydot)
Write out to a file or to standard output the current solution.
Base residual calculation for the Jacobian calculation.
virtual int getInitialConditions(const doublereal t0, doublereal *const y, doublereal *const ydot)
Fill in the initial conditions.
bool m_matrixConditioning
m_matrixConditioning is a boolean.
int m_min_newt_its
Minimum Number of Newton Iterations per nonlinear step. default = 0.
int m_print_flag
Determines the level of printing for each time step.
double subtractRD(double a, double b)
This routine subtracts two numbers for one another.
vector_fp m_abstol
Vector of absolute time truncation error tolerance when not uniform for all variables.
IterType m_iter
IterType is used to specify how the nonlinear equations are to be relaxed at each time step...
Wrappers for the function evaluators for Nonlinear solvers and Time steppers.
std::vector< int > vector_int
Vector of ints.
double delta_t_max
Maximum permissible time step.
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.
int solve_nonlinear_problem(double *const y_comm, double *const ydot_comm, double CJ, double time_curr, GeneralMatrix &jac, int &num_newt_its, int &num_linear_solves, int &num_backtracks, int loglevel)
Solve a nonlinear system.
int m_numTotalLinearSolves
Total number of linear iterations.
GeneralMatrix * tdjac_ptr
Pointer to the jacobian representing the time dependent problem.
virtual void setSolnWeights()
Set the solution weights.
virtual int matrixConditioning(doublereal *const matrix, const int nrows, doublereal *const rhs)
Multiply the matrix by another matrix that leads to better conditioning.
int m_printSolnFirstSteps
Number of initial steps that the solution is printed out. default = 0.
virtual void setColumnScales()
Set the column scaling vector at the current time.
int m_numInitialConstantDeltaTSteps
Number of initial time steps to take where the time truncation error tolerances are not checked...
void error(const std::string &msg)
Write an error message and quit.
int m_order
Current integration order.
int m_nfe
Number of function evaluations.
A class for full (non-sparse) matrices with Fortran-compatible data storage.
virtual void initializeRJE(double t0, ResidJacEval &func)
Find the initial conditions for y and ydot.
virtual void setTolerances(double reltol, size_t n, double *abstol)
Set or reset the number of equations.
virtual bool factored() const =0
true if the current factorization is up to date with the matrix
Base class for exceptions thrown by Cantera classes.
const int NDAMP
Number of damping steps that are carried out before the solution is deemed a failure.
double m_abstols
Absolute time truncation error tolerances, when uniform for all variables.
virtual void clearFactorFlag()=0
clear the factored flag
double time_step_control(int m_order, double time_error_factor)
virtual int evalTimeTrackingEqns(const doublereal t, const doublereal delta_t, const doublereal *const y, const doublereal *const ydot)
Evaluate the time tracking equations, if any.
int dampStep(double, const double *, const double *, const double *, double *, double *, double *, double &, GeneralMatrix &, int &, bool, int &)
int m_max_time_step_attempts
Max time steps allowed.
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.
double filterNewStep(double, double *, double *)
Filter a new step.
int m_jacFormMethod
m_jacFormMethod determines how a matrix is formed.
int m_numTotalConvFails
Total number of convergence failures.
virtual int nEvals() const
Return the total number of function evaluations.
double boundStep(const double *const y, const double *const step0, int loglevel)
Bound the Newton step while relaxing the solution.
bool m_colScaling
m_colScaling is a boolean.
IterType
Specifies the method used for iteration.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
void internalMalloc()
Internal routine that sets up the fixed length storage based on the size of the problem to solve...
bool m_dumpJacobians
Dump Jacobians to disk. default false.
virtual int solve(doublereal *b)=0
Solves the Ax = b system returning x in the b spot.
virtual doublereal step(double tout)
Integrate the system of equations.
Delta residual calculation for the Jacbobian calculation.
int m_nJacEval
Number of Jacobian Evaluations and factorization steps (they are the same)
virtual doublereal filterSolnPrediction(const doublereal t, doublereal *const y)
Filter the solution predictions.
void setNonLinOptions(int min_newt_its=0, bool matrixConditioning=false, bool colScaling=false, bool rowScaling=true)
Set the options for the nonlinear method.
void calc_ydot(int, double *, double *)
double m_hmax
Maximum step size.
int m_itol
If m_itol =1 then each component has an individual value of atol.
virtual bool evalStoppingCritera(const doublereal t, const doublereal delta_t, const doublereal *const y, const doublereal *const ydot)
Evaluate any stopping criteria other than a final time limit.
Base residual calculation for the time-stepping function.
vector_fp m_ewt
Error Weights. This is a surprisingly important quantity.
int m_time_step_num
Time step number.
void computeResidWts(GeneralMatrix &jac)
Compute Residual Weights.