21 BEulerErr::BEulerErr(
const std::string& msg) :
28 m_method(BEulerVarStep),
29 m_jacFormMethod(BEULER_JAC_NUM),
32 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),
65 m_numTotalLinearSolves(0),
66 m_numTotalConvFails(0),
67 m_numTotalTruncFails(0),
73 BEulerInt::~BEulerInt()
82 if (static_cast<int>(n) !=
m_neq) {
83 printf(
"ERROR n is wrong\n");
86 for (
int i = 0; i <
m_neq; i++) {
104 void BEulerInt::setMethodBEMT(BEulerMethodType t)
109 void BEulerInt::setMaxStep(doublereal hmax)
114 void BEulerInt::setMaxNumTimeSteps(
int maxNumTimeSteps)
119 void BEulerInt::setNumInitialConstantDeltaTSteps(
int num)
125 int printSolnNumberToTout,
126 int printSolnFirstSteps,
141 bool colScaling,
bool rowScaling)
148 m_colScales.assign(
m_neq, 1.0);
151 m_rowScales.assign(
m_neq, 1.0);
155 void BEulerInt::setInitialTimeStep(
double deltaT)
157 delta_t_np1 = deltaT;
160 void BEulerInt::setPrintFlag(
int print_flag)
189 void BEulerInt::reinitializeRJE(
double t0,
ResidJacEval& func)
216 tnext =
m_t0 + dt * i;
217 if (tnext >= time_current) {
233 m_y_n.assign(
m_neq, 0.0);
234 m_y_nm1.assign(
m_neq, 0.0);
235 m_y_pred_n.assign(
m_neq, 0.0);
236 m_ydot_n.assign(
m_neq, 0.0);
237 m_ydot_nm1.assign(
m_neq, 0.0);
238 m_resid.assign(
m_neq, 0.0);
239 m_residWts.assign(
m_neq, 0.0);
240 m_wksp.assign(
m_neq, 0.0);
242 m_rowScales.assign(
m_neq, 1.0);
245 m_colScales.assign(
m_neq, 1.0);
254 for (i = 0; i <
m_neq; i++) {
256 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
259 for (i = 0; i <
m_neq; i++) {
261 (fabs(m_y_n[i]) + fabs(m_y_pred_n[i]));
268 m_func->
calcSolnScales(time_n, &m_y_n[0], &m_y_nm1[0], &m_colScales[0]);
284 double* data = &(*(jac.
begin()));
286 for (i = 0; i <
m_neq; i++) {
287 m_residWts[i] = fabs(data[i] *
m_ewt[0]);
288 for (j = 1; j <
m_neq; j++) {
289 value = fabs(data[j*m_neq + i] * m_ewt[j]);
290 m_residWts[i] = std::max(m_residWts[i], value);
303 static void print_time_step1(
int order,
int n_time_step,
double time,
304 double delta_t_n,
double delta_t_nm1,
305 bool step_failed,
int num_failures)
307 const char*
string = 0;
309 string =
"Backward Euler";
310 }
else if (order == 1) {
311 string =
"Forward/Backward Euler";
312 }
else if (order == 2) {
313 string =
"Adams-Bashforth/TR";
315 writeline(
'=', 80,
true,
true);
316 printf(
"\nStart of Time Step: %5d Time_n = %9.5g Time_nm1 = %9.5g\n",
317 n_time_step, time, time - delta_t_n);
318 printf(
"\tIntegration method = %s\n",
string);
320 printf(
"\tPreviously attempted step was a failure\n");
322 if (delta_t_n > delta_t_nm1) {
323 string =
"(Increased from previous iteration)";
324 }
else if (delta_t_n < delta_t_nm1) {
325 string =
"(Decreased from previous iteration)";
327 string =
"(same as previous iteration)";
329 printf(
"\tdelta_t_n = %8.5e %s", delta_t_n,
string);
330 if (num_failures > 0) {
331 printf(
"\t(Bad_History Failure Counter = %d)", num_failures);
333 printf(
"\n\tdelta_t_nm1 = %8.5e\n", delta_t_nm1);
339 static void print_time_step2(
int time_step_num,
int order,
340 double time,
double time_error_factor,
341 double delta_t_n,
double delta_t_np1)
343 printf(
"\tTime Step Number %5d was a success: time = %10g\n", time_step_num,
345 printf(
"\t\tEstimated Error\n");
346 printf(
"\t\t-------------------- = %8.5e\n", time_error_factor);
347 printf(
"\t\tTolerated Error\n\n");
348 printf(
"\t- Recommended next delta_t (not counting history) = %g\n",
350 writeline(
'=', 80,
true,
true);
356 static void print_time_fail(
bool convFailure,
int time_step_num,
357 double time,
double delta_t_n,
358 double delta_t_np1,
double time_error_factor)
360 writeline(
'=', 80,
true,
true);
362 printf(
"\tTime Step Number %5d experienced a convergence "
363 "failure\n", time_step_num);
364 printf(
"\tin the non-linear or linear solver\n");
365 printf(
"\t\tValue of time at failed step = %g\n", time);
366 printf(
"\t\tdelta_t of the failed step = %g\n",
368 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
371 printf(
"\tTime Step Number %5d experienced a truncation error "
372 "failure!\n", time_step_num);
373 printf(
"\t\tValue of time at failed step = %g\n", time);
374 printf(
"\t\tdelta_t of the failed step = %g\n",
376 printf(
"\t\tSuggested value of delta_t to try next = %g\n",
378 printf(
"\t\tCalculated truncation error factor = %g\n",
381 writeline(
'=', 80,
true,
true);
387 static void print_final(
double time,
int step_failed,
388 int time_step_num,
int num_newt_its,
389 int total_linear_solves,
int numConvFails,
390 int numTruncFails,
int nfe,
int nJacEval)
392 writeline(
'=', 80,
true,
true);
393 printf(
"TIME INTEGRATION ROUTINE HAS FINISHED: ");
395 printf(
" IT WAS A FAILURE\n");
397 printf(
" IT WAS A SUCCESS\n");
399 printf(
"\tEnding time = %g\n", time);
400 printf(
"\tNumber of time steps = %d\n", time_step_num);
401 printf(
"\tNumber of newt its = %d\n", num_newt_its);
402 printf(
"\tNumber of linear solves = %d\n", total_linear_solves);
403 printf(
"\tNumber of convergence failures= %d\n", numConvFails);
404 printf(
"\tNumber of TimeTruncErr fails = %d\n", numTruncFails);
405 printf(
"\tNumber of Function evals = %d\n", nfe);
406 printf(
"\tNumber of Jacobian evals/solvs= %d\n", nJacEval);
407 writeline(
'=', 80,
true,
true);
413 static void print_lvl1_Header(
int nTimes)
419 printf(
"time Time Time Time ");
423 printf(
" (continued)");
427 printf(
"step (sec) step Newt Aztc bktr trunc ");
430 printf(
" No. Rslt size Its Its stps error |");
432 writeline(
'-', 80,
true);
439 static void print_lvl1_summary(
440 int time_step_num,
double time,
const char* rslt,
double delta_t_n,
441 int newt_its,
int aztec_its,
int bktr_stps,
double time_error_factor,
444 printf(
"%6d %11.6g %4s %10.4g %4d %4d %4d %11.4g",
445 time_step_num, time, rslt, delta_t_n, newt_its, aztec_its,
446 bktr_stps, time_error_factor);
448 printf(
" | %s", comment);
471 double d = std::min(fabs(a), fabs(b));
473 double ad = fabs(diff);
484 double time_curr,
double CJ,
491 double ysave, ydotsave, dy;
502 m_func->
evalJacobian(time_curr, delta_t_n, CJ, y, ydot, J, f);
528 bool print_NumJac =
false;
530 FILE* idy = fopen(
"NumJac.csv",
"w");
531 fprintf(idy,
"Unk m_ewt y "
533 for (
int iii = 0; iii <
m_neq; iii++) {
534 fprintf(idy,
" %4d %16.8e %16.8e %16.8e %16.8e \n",
535 iii,
m_ewt[iii], y[iii], dyVector[iii], f[iii]);
551 for (j = 0; j <
m_neq; j++) {
572 m_func->
evalResidNJ(time_curr, delta_t_n, y, ydot, &m_wksp[0],
576 for (i = 0; i <
m_neq; i++) {
578 col_j[i] = diff / dy;
598 for (i = 0; i <
m_neq; i++) {
599 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i];
603 c1 = delta_t_n * (2.0 + delta_t_n / delta_t_nm1) / 2.0;
604 c2 = (delta_t_n * delta_t_n) / (delta_t_nm1 * 2.0);
605 for (i = 0; i <
m_neq; i++) {
606 m_y_pred_n[i] = m_y_n[i] + c1 * m_ydot_n[i] - c2 * m_ydot_nm1[i];
625 c1 = 1.0 / delta_t_n;
626 for (i = 0; i <
m_neq; i++) {
627 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]);
631 c1 = 2.0 / delta_t_n;
632 for (i = 0; i <
m_neq; i++) {
633 ydot_curr[i] = c1 * (y_curr[i] - m_y_nm1[i]) - m_ydot_nm1[i];
642 double rel_norm,
error;
644 #define NUM_ENTRIES 5
646 int imax[NUM_ENTRIES], j, jnum;
649 printf(
"\t\ttime step truncation error contributors:\n");
650 printf(
"\t\t I entry actual predicted "
654 for (j = 0; j < NUM_ENTRIES; j++) {
657 for (jnum = 0; jnum < NUM_ENTRIES; jnum++) {
659 for (i = 0; i <
m_neq; i++) {
661 for (j = 0; j < jnum; j++) {
667 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
668 rel_norm = sqrt(error * error);
669 if (rel_norm > dmax) {
675 if (imax[jnum] >= 0) {
677 printf(
"\t\t%4d %12.4e %12.4e %12.4e %12.4e %12.4e\n",
678 i, dmax, m_y_n[i], m_y_pred_n[i],
m_ewt[i], m_ydot_n[i]);
686 for (i = 0; i <
m_neq; i++) {
687 error = (m_y_n[i] - m_y_pred_n[i]) /
m_ewt[i];
688 rel_norm += (error *
error);
690 return sqrt(rel_norm / m_neq);
695 double factor = 0.0, power = 0.0, delta_t;
696 const char* yo =
"time_step_control";
701 time_error_factor = std::max(1.0E-50, time_error_factor);
708 factor = 1.0/(2.0 *(time_error_factor));
712 factor = 1.0/(3.0 * (1.0 + delta_t_nm1 / delta_t_n)
713 * (time_error_factor));
714 power = 0.3333333333333333;
716 factor = pow(factor, power);
719 printf(
"\t%s: WARNING - Current time step will be chucked\n", yo);
720 printf(
"\t\tdue to a time step truncation error failure.\n");
722 delta_t = - 0.5 * delta_t_n;
724 factor = std::min(factor, 1.5);
725 delta_t = factor * delta_t_n;
730 double BEulerInt::integrateRJE(
double tout,
double time_init)
733 bool weAreNotFinished =
true;
748 bool doPrintSoln =
false;
749 time_current = time_init;
751 time_nm1 = time_init;
752 time_nm2 = time_init;
755 if (print_time == time_current) {
757 istep, &m_y_n[0], &m_ydot_n[0]);
763 print_lvl1_Header(0);
769 m_func->
user_out2(0, time_current, 0.0, &m_y_n[0], &m_ydot_n[0]);
774 if (print_time >= tout) {
781 time_current =
step(tout);
785 if (time_current < 0.0) {
786 if (time_current == -1234.) {
789 time_current = -time_current;
794 if (flag != FAILURE) {
797 &m_y_n[0], &m_ydot_n[0]);
799 weAreNotFinished =
false;
807 if (time_current >= print_time) {
821 if (flag != FAILURE) {
823 &m_y_n[0], &m_ydot_n[0]);
831 istep, &m_y_n[0], &m_ydot_n[0]);
835 print_lvl1_Header(1);
842 if (flag == FAILURE) {
843 m_func->
user_out2(-1, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
845 m_func->
user_out2(1, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
848 }
while (time_current < tout &&
850 flag == SUCCESS && weAreNotFinished);
855 if (time_current >= tout) {
856 printf(
"Simulation completed time integration in %d time steps\n",
858 printf(
"Final Time: %e\n\n", time_current);
860 printf(
"Simulation ran into time step attempt limit in"
863 printf(
"Final Time: %e\n\n", time_current);
864 }
else if (flag == FAILURE) {
865 printf(
"ERROR: time stepper failed at time = %g\n", time_current);
879 m_func->
user_out2(2, time_current, delta_t_n, &m_y_n[0], &m_ydot_n[0]);
882 if (flag != SUCCESS) {
883 throw BEulerErr(
" BEuler error encountered.");
891 bool step_failed =
false;
893 bool convFailure =
false;
895 double time_error_factor = 0.0;
896 double normFilter = 0.0;
897 int numTSFailures = 0;
900 int num_newt_its = 0;
914 m_time_step_attempts++;
923 if ((time_n + delta_t_np1) >= t_max) {
924 delta_t_np1 =t_max - time_n;
936 delta_t_nm2 = delta_t_nm1;
937 delta_t_nm1 = delta_t_n;
938 delta_t_n = delta_t_np1;
966 }
else if (step_failed) {
1022 m_ydot_nm1 = m_ydot_n;
1037 CJ = 1.0 / delta_t_n;
1039 CJ = 2.0 / delta_t_n;
1054 aztec_its, bktr_stps,
1066 printf(
"\tStep is Rejected, nonlinear problem didn't converge,"
1067 "ierror = %d\n", ierror);
1070 convFailure =
false;
1071 step_failed =
false;
1077 normFilter =
filterNewStep(time_n, &m_y_n[0], &m_ydot_n[0]);
1078 if (normFilter > 1.0) {
1083 printf(
"\tStep is Rejected, too large filter adjustment = %g\n",
1086 }
else if (normFilter > 0.0) {
1087 if (normFilter > 0.3) {
1089 printf(
"\tStep was filtered, norm = %g, next "
1090 "time step adjusted\n", normFilter);
1094 printf(
"\tStep was filtered, norm = %g\n", normFilter);
1106 time_error_factor = 1000.;
1117 delta_t_np1 = 0.25 * delta_t_n;
1118 }
else if (
m_method == BEulerVarStep) {
1129 if (normFilter > 0.1) {
1130 if (delta_t_np1 > delta_t_n) {
1131 delta_t_np1 = delta_t_n;
1140 if (delta_t_np1 < 0.0) {
1143 delta_t_np1 = -delta_t_np1;
1145 comment +=
"TIME TRUNC FAILURE";
1155 delta_t_np1 = std::min(delta_t_np1, delta_t_n);
1158 delta_t_np1 = delta_t_n;
1172 int max_Newton_steps = 10000;
1173 int target_num_iter = 5;
1174 if (num_newt_its > 3000 && !step_failed) {
1175 if (max_Newton_steps != target_num_iter) {
1176 double iter_diff = num_newt_its - target_num_iter;
1177 double iter_adjust_zone = max_Newton_steps - target_num_iter;
1178 double target_time_step = delta_t_n
1179 *(1.0 - iter_diff*fabs(iter_diff)/
1180 ((2.0*iter_adjust_zone*iter_adjust_zone)));
1181 target_time_step = std::max(0.5*delta_t_n, target_time_step);
1182 if (target_time_step < delta_t_np1) {
1183 printf(
"\tNext time step will be decreased from %g to %g"
1184 " because of new its restraint\n",
1185 delta_t_np1, target_time_step);
1186 delta_t_np1 = target_time_step;
1209 delta_t_np1, time_error_factor);
1212 num_newt_its, aztec_its, bktr_stps,
1222 time_n -= delta_t_n;
1223 delta_t_n = delta_t_nm1;
1224 delta_t_nm1 = delta_t_nm2;
1230 m_ydot_n = m_ydot_nm1;
1234 if (numTSFailures > 35) {
1254 delta_t_n, delta_t_np1);
1257 num_newt_its, aztec_its, bktr_stps, time_error_factor,
1270 }
while (step_failed && !giveUp);
1276 if (time_n == 0.0) {
1299 double sum_norm = 0.0,
error;
1300 for (i = 0; i <
m_neq; i++) {
1304 sum_norm = sqrt(sum_norm / m_neq);
1306 const int num_entries = 8;
1307 double dmax1, normContrib;
1310 printf(
"\t\tPrintout of Largest Contributors to norm "
1311 "of value (%g)\n", sum_norm);
1312 printf(
"\t\t I ysoln deltaY weightY "
1316 for (
int jnum = 0; jnum < num_entries; jnum++) {
1318 for (i = 0; i <
m_neq; i++) {
1320 for (j = 0; j < jnum; j++) {
1328 if (normContrib > dmax1) {
1330 dmax1 = normContrib;
1336 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e\n",
1337 i, m_y_n[i], delta_y[i],
m_ewt[i], dmax1);
1345 #ifdef DEBUG_HKM_JAC
1350 double* ydot_curr,
double* delta_y,
1359 for (
int n = 0; n < sz; n++) {
1360 delta_y[n] = -delta_y[n];
1378 double* jptr = &(*(jac.
begin()));
1379 for (jcol = 0; jcol <
m_neq; jcol++) {
1380 for (irow = 0; irow <
m_neq; irow++) {
1381 *jptr *= m_colScales[jcol];
1392 double* jptr = &(*(jac.
begin()));
1409 double* jptr = &(*(jac.
begin()));
1410 for (irow = 0; irow <
m_neq; irow++) {
1411 m_rowScales[irow] = 0.0;
1413 for (jcol = 0; jcol <
m_neq; jcol++) {
1414 for (irow = 0; irow <
m_neq; irow++) {
1415 m_rowScales[irow] += fabs(*jptr);
1420 jptr = &(*(jac.
begin()));
1421 for (jcol = 0; jcol <
m_neq; jcol++) {
1422 for (irow = 0; irow <
m_neq; irow++) {
1423 *jptr /= m_rowScales[irow];
1428 for (irow = 0; irow <
m_neq; irow++) {
1429 delta_y[irow] /= m_rowScales[irow];
1433 #ifdef DEBUG_HKM_JAC
1434 bool printJacContributions =
false;
1436 printJacContributions =
false;
1441 bool freshJac =
true;
1442 RRow[0] = delta_y[focusRow];
1443 RRow[1] = delta_y[focusRow+1];
1444 double Pcutoff = 1.0E-70;
1455 (void) jac.
solve(delta_y);
1462 for (irow = 0; irow <
m_neq; irow++) {
1463 delta_y[irow] *= m_colScales[irow];
1467 #ifdef DEBUG_HKM_JAC
1468 if (printJacContributions) {
1469 for (
int iNum = 0; iNum < numRows; iNum++) {
1475 double dRow = Jdata[
m_neq * focusRow + focusRow];
1476 printf(
"\n Details on delta_Y for row %d \n", focusRow);
1477 printf(
" Value before = %15.5e, delta = %15.5e,"
1478 "value after = %15.5e\n", y_curr[focusRow],
1480 y_curr[focusRow] + delta_y[focusRow]);
1482 printf(
" Old Jacobian\n");
1484 printf(
" col delta_y aij "
1486 printf(
"--------------------------------------------------"
1487 "---------------------------------------------\n");
1488 printf(
" Res(%d) %15.5e %15.5e %15.5e (Res = %g)\n",
1489 focusRow, delta_y[focusRow],
1490 dRow, RRow[iNum] / dRow, RRow[iNum]);
1491 dsum += RRow[iNum] / dRow;
1492 for (
int ii = 0; ii <
m_neq; ii++) {
1493 if (ii != focusRow) {
1494 double aij = Jdata[m_neq * ii + focusRow];
1495 double contrib = aij * delta_y[ii] * (-1.0) / dRow;
1497 if (fabs(contrib) > Pcutoff) {
1498 printf(
"%6d %15.5e %15.5e %15.5e\n", ii,
1499 delta_y[ii] , aij, contrib);
1503 printf(
"--------------------------------------------------"
1504 "---------------------------------------------\n");
1505 printf(
" %15.5e %15.5e\n",
1506 delta_y[focusRow], dsum);
1516 const double*
const step0,
int loglevel)
1518 int i, i_lower = -1, ifbd = 0, i_fbd = 0;
1519 double fbound = 1.0, f_lowbounds = 1.0, f_delta_bounds = 1.0;
1520 double ff, y_new, ff_alt;
1521 for (i = 0; i <
m_neq; i++) {
1522 y_new = y[i] + step0[i];
1523 if ((y_new < (-0.01 *
m_ewt[i])) && y[i] >= 0.0) {
1524 ff = 0.9 * (y[i] / (y[i] - y_new));
1525 if (ff < f_lowbounds) {
1536 if ((fabs(y_new) > 2.0 * fabs(y[i])) &&
1537 (fabs(y_new-y[i]) >
m_ewt[i])) {
1538 ff = fabs(y[i]/(y_new - y[i]));
1539 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1540 ff = std::max(ff, ff_alt);
1543 if ((fabs(5.0 * y_new) < fabs(y[i])) &&
1544 (fabs(y_new - y[i]) >
m_ewt[i])) {
1545 ff = y[i]/(y_new-y[i]) * (1.0 - 5.0)/5.0;
1546 ff_alt = fabs(
m_ewt[i] / (y_new - y[i]));
1547 ff = std::max(ff, ff_alt);
1550 if (ff < f_delta_bounds) {
1551 f_delta_bounds = ff;
1554 f_delta_bounds = std::min(f_delta_bounds, ff);
1556 fbound = std::min(f_lowbounds, f_delta_bounds);
1561 if (fbound != 1.0) {
1562 if (f_lowbounds < f_delta_bounds) {
1563 printf(
"\t\tboundStep: Variable %d causing lower bounds "
1565 i_lower, f_lowbounds);
1568 printf(
"\t\tboundStep: Decrease of Variable %d causing "
1569 "delta damping of %g\n",
1570 i_fbd, f_delta_bounds);
1572 printf(
"\t\tboundStep: Increase of variable %d causing"
1573 "delta damping of %g\n",
1574 i_fbd, f_delta_bounds);
1583 const double* ydot0,
const double* step0,
1584 double* y1,
double* ydot1,
double* step1,
1586 int& loglevel,
bool writetitle,
1587 int& num_backtracks)
1597 double fbound =
boundStep(y0, step0, loglevel);
1603 if (fbound < 1.e-10) {
1605 printf(
"\t\t\tdampStep: At limits.\n");
1619 for (m = 0; m <
NDAMP; m++) {
1628 for (j = 0; j <
m_neq; j++) {
1629 y1[j] = y0[j] + ff*step0[j];
1639 for (j = 0; j <
m_neq; j++) {
1649 print_solnDelta_norm_contrib((
const double*) step0,
1651 (
const double*) step1,
1652 "DeltaSolnTrialTest",
1653 "dampNewt: Important Entries for "
1654 "Weighted Soln Updates:",
1658 printf(
"\t\t\tdampNewt: s0 = %g, s1 = %g, fbound = %g,"
1659 "damp = %g\n", s0, s1, fbound, damp);
1663 if (s1 > 1.00000001 * s0 && s1 > 1.0E-5) {
1664 printf(
"WARNING: Possible Jacobian Problem "
1665 "-> turning on more debugging for this step!!!\n");
1666 print_solnDelta_norm_contrib((
const double*) step0,
1668 (
const double*) step1,
1669 "DeltaSolnTrialTest",
1670 "dampNewt: Important Entries for "
1671 "Weighted Soln Updates:",
1683 if (s1 < 1.0E-5 || s1 < s0) {
1687 printf(
"\t\t\tdampStep: current trial step and damping"
1688 " coefficient accepted because test step < 1\n");
1689 printf(
"\t\t\t s1 = %g, s0 = %g\n", s1, s0);
1696 printf(
"\t\t\tdampStep: current step rejected: (s1 = %g > "
1697 "s0 = %g)", s1, s0);
1698 if (m < (NDAMP-1)) {
1699 printf(
" Decreasing damping factor and retrying");
1701 printf(
" Giving up!!!");
1721 if (s1 < 0.5 && (s0 < 0.5)) {
1732 double*
const ydot_comm,
double CJ,
1736 int& num_linear_solves,
1737 int& num_backtracks,
1741 bool forceNewJac =
false;
1767 printf(
"\t\tSolve_Nonlinear_Problem: iteration %d:\n",
1777 printf(
"\t\t\tGetting a new Jacobian and solving system\n");
1779 beuler_jac(jac, &m_resid[0], time_curr, CJ, &y_curr[0], &ydot_curr[0],
1783 printf(
"\t\t\tSolving system with old Jacobian\n");
1788 doNewtonSolve(time_curr, &y_curr[0], &ydot_curr[0], &stp[0], jac, loglevel);
1791 m =
dampStep(time_curr, &y_curr[0], &ydot_curr[0], &stp[0], &y_new[0], &ydot_new[0],
1792 &stp1[0], s1, jac, loglevel, frst, i_backtracks);
1794 num_backtracks += i_backtracks;
1807 if (num_newt_its > 20) {
1810 printf(
"\t\t\tDampnewton unsuccessful (max newts exceeded) sfinal = %g\n", s1);
1816 printf(
"\t\t\tDampNewton iteration successful, nonlin "
1817 "converged sfinal = %g\n", s1);
1818 }
else if (m == 0) {
1819 printf(
"\t\t\tDampNewton iteration successful, get new"
1820 "direction, sfinal = %g\n", s1);
1822 printf(
"\t\t\tDampnewton unsuccessful sfinal = %g\n", s1);
1826 bool m_filterIntermediate =
false;
1827 if (m_filterIntermediate) {
1833 if (m == 0 || m == 1) {
1853 copy(y_curr.begin(), y_curr.end(), y_comm);
1854 copy(ydot_curr.begin(), ydot_curr.end(), ydot_comm);
1858 double time_elapsed = 0.0;
1861 printf(
"\t\tNonlinear problem solved successfully in "
1862 "%d its, time elapsed = %g sec\n",
1863 num_newt_its, time_elapsed);
1869 void BEulerInt::print_solnDelta_norm_contrib(
const double*
const solnDelta0,
1870 const char*
const s0,
1871 const double*
const solnDelta1,
1872 const char*
const s1,
1873 const char*
const title,
1874 const double*
const y0,
1875 const double*
const y1,
1881 double dmax0, dmax1,
error, rel_norm;
1882 printf(
"\t\t%s currentDamp = %g\n", title, damp);
1883 printf(
"\t\t I ysoln %10s ysolnTrial "
1884 "%10s weight relSoln0 relSoln1\n", s0, s1);
1888 for (jnum = 0; jnum < num_entries; jnum++) {
1890 for (i = 0; i <
m_neq; i++) {
1892 for (j = 0; j < jnum; j++) {
1898 error = solnDelta0[i] /
m_ewt[i];
1899 rel_norm = sqrt(error * error);
1900 error = solnDelta1[i] /
m_ewt[i];
1901 rel_norm += sqrt(error * error);
1902 if (rel_norm > dmax1) {
1908 if (imax[jnum] >= 0) {
1910 error = solnDelta0[i] /
m_ewt[i];
1911 dmax0 = sqrt(error * error);
1912 error = solnDelta1[i] /
m_ewt[i];
1913 dmax1 = sqrt(error * error);
1914 printf(
"\t\t %4d %12.4e %12.4e %12.4e %12.4e "
1915 "%12.4e %12.4e %12.4e\n",
1916 i, y0[i], solnDelta0[i], y1[i],
1917 solnDelta1[i],
m_ewt[i], dmax0, dmax1);
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.
Dense, Square (not sparse) matrices.
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.
virtual void clearFactorFlag()
clear the factored flag
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.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
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.
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, (see Input File Handling, Diagnostic Output, and Writing messages to the screen).
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.
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.
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 bool factored() const
true if the current factorization is up to date with the matrix
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.
virtual int solve(doublereal *b, size_t nrhs=1, size_t ldb=0)=0
Solves the Ax = b system returning x in the b spot.
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 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.