Skip to content

Commit

Permalink
Added counter for the number of recoverable failures reported by the …
Browse files Browse the repository at this point in the history
…MRIStepInnerStepper
  • Loading branch information
drreynolds committed Nov 1, 2024
1 parent d7e6198 commit 8b71729
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 29 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ Added support for multirate time step adaptivity controllers, based on the
recently introduced `SUNAdaptController` base class, to ARKODE's MRIStep module.
As a part of this, we added embeddings for existing MRI-GARK methods, as well as
support for embedded MERK and IMEX-MRI-SR methods. Added new default MRI methods
for temporally adaptive versus fixed-step runs.
for temporally adaptive versus fixed-step runs. Added the function
`MRIStepGetNumInnerStepperFails` to retrieve the number of recoverable
failures reported by the MRIStepInnerStepper.

Added functionality to ARKODE to accumulate a temporal error
estimate over multiple time steps. See the routines `ARKodeSetAccumulatedErrorType`,
Expand Down
15 changes: 14 additions & 1 deletion doc/arkode/guide/source/Usage/MRIStep/User_callable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ MRIStep solver function
:retval ARK_ROOT_RETURN: if :c:func:`MRIStepEvolve()` succeeded, and
found one or more roots. If the number of root
functions, *nrtfn*, is greater than 1, call
:c:func:`MRIStepGetRootInfo()` to see which
:c:func:`ARKodeGetRootInfo()` to see which
:math:`g_i` were found to have a root at (*\*tret*).
:retval ARK_TSTOP_RETURN: if :c:func:`MRIStepEvolve()` succeeded and
returned at *tstop*.
Expand Down Expand Up @@ -1547,6 +1547,19 @@ Main solver optional output functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


.. c:function:: int MRIStepGetNumInnerStepperFails(void* arkode_mem, long int* inner_fails)
Returns the number of recoverable failures reported by the inner stepper (so far).
:param arkode_mem: pointer to the MRIStep memory block.
:param inner_fails: number of slow steps taken in the solver.
:retval ARK_SUCCESS: if successful
:retval ARK_MEM_NULL: if the MRIStep memory was ``NULL``
.. versionadded:: x.y.z
.. c:function:: int MRIStepGetWorkSpace(void* arkode_mem, long int* lenrw, long int* leniw)
Returns the MRIStep real and integer workspace sizes.
Expand Down
4 changes: 3 additions & 1 deletion doc/shared/RecentChanges.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ Added support for multirate time step adaptivity controllers, based on the
recently introduced :c:type:`SUNAdaptController` base class, to ARKODE's MRIStep module.
As a part of this, we added embeddings for existing MRI-GARK methods, as well as
support for embedded MERK and IMEX-MRI-SR methods. Added new default MRI methods
for temporally adaptive versus fixed-step runs.
for temporally adaptive versus fixed-step runs. Added the function
:c:func:`MRIStepGetNumInnerStepperFails` to retrieve the number of recoverable
failures reported by the MRIStepInnerStepper.

Added functionality to ARKODE to accumulate a temporal error
estimate over multiple time steps. See the routines
Expand Down
12 changes: 8 additions & 4 deletions examples/arkode/CXX_serial/ark_kpr_nestedmri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ int main(int argc, char* argv[])
//

// Get some slow integrator statistics
long int nsts, natts, netfs, nfse, nfsi;
long int nsts, natts, netfs, nfse, nfsi, nifs;
retval = ARKodeGetNumSteps(arkode_mem, &nsts);
check_flag(retval, "ARKodeGetNumSteps");
retval = ARKodeGetNumStepAttempts(arkode_mem, &natts);
Expand All @@ -1024,9 +1024,11 @@ int main(int argc, char* argv[])
check_flag(retval, "ARKodeGetNumRhsEvals");
retval = ARKodeGetNumRhsEvals(arkode_mem, 1, &nfsi);
check_flag(retval, "ARKodeGetNumRhsEvals");
retval = MRIStepGetNumInnerStepperFails(arkode_mem, &nifs);
check_flag(retval, "MRIStepGetNumInnerStepperFails");

// Get some intermediate integrator statistics
long int nstm, nattm, netfm, nfme, nfmi;
long int nstm, nattm, netfm, nfme, nfmi, nifm;
retval = ARKodeGetNumSteps(mid_arkode_mem, &nstm);
check_flag(retval, "ARKodeGetNumSteps");
retval = ARKodeGetNumStepAttempts(mid_arkode_mem, &nattm);
Expand All @@ -1037,6 +1039,8 @@ int main(int argc, char* argv[])
check_flag(retval, "ARKodeGetNumRhsEvals");
retval = ARKodeGetNumRhsEvals(mid_arkode_mem, 1, &nfmi);
check_flag(retval, "ARKodeGetNumRhsEvals");
retval = MRIStepGetNumInnerStepperFails(mid_arkode_mem, &nifm);
check_flag(retval, "MRIStepGetNumInnerStepperFails");

// Get some fast integrator statistics
long int nstf, nattf, netff, nff;
Expand All @@ -1056,9 +1060,9 @@ int main(int argc, char* argv[])
errtot = std::sqrt(errtot / SUN_RCONST(3.0) / (sunrealtype)nsts);
std::cout << "\nFinal Solver Statistics:\n";
std::cout << " Slow steps = " << nsts << " (attempts = " << natts
<< ", fails = " << netfs << ")\n";
<< ", fails = " << netfs << ", innerfails = " << nifs << ")\n";
std::cout << " Intermediate steps = " << nstm << " (attempts = " << nattm
<< ", fails = " << netfm << ")\n";
<< ", fails = " << netfm << ", innerfails = " << nifm << ")\n";
std::cout << " Fast steps = " << nstf << " (attempts = " << nattf
<< ", fails = " << netff << ")\n";
std::cout << " u error = " << uerrtot << ", v error = " << verrtot
Expand Down
4 changes: 2 additions & 2 deletions examples/arkode/CXX_serial/ark_kpr_nestedmri.out
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ Adaptive nested multirate nonlinear Kvaerno-Prothero-Robinson test problem:
----------------------------------------------------------------------------

Final Solver Statistics:
Slow steps = 25 (attempts = 29, fails = 4)
Intermediate steps = 769 (attempts = 975, fails = 206)
Slow steps = 25 (attempts = 29, fails = 4, innerfails = 0)
Intermediate steps = 769 (attempts = 975, fails = 206, innerfails = 0)
Fast steps = 193380 (attempts = 215494, fails = 22114)
u error = 0.00784081, v error = 0.0203181, total error = 0.0150336
Relative accuracy = 674.105
Expand Down
2 changes: 2 additions & 0 deletions include/arkode/arkode_mristep.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ SUNDIALS_EXPORT int MRIStepSetPostInnerFn(void* arkode_mem,
SUNDIALS_EXPORT int MRIStepGetCurrentCoupling(void* arkode_mem,
MRIStepCoupling* MRIC);
SUNDIALS_EXPORT int MRIStepGetLastInnerStepFlag(void* arkode_mem, int* flag);
SUNDIALS_EXPORT int MRIStepGetNumInnerStepperFails(void* arkode_mem,
long int* inner_fails);

/* Custom inner stepper functions */
SUNDIALS_EXPORT int MRIStepInnerStepper_Create(SUNContext sunctx,
Expand Down
38 changes: 26 additions & 12 deletions src/arkode/arkode_mristep.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,13 @@ void* MRIStepCreate(ARKRhsFn fse, ARKRhsFn fsi, sunrealtype t0, N_Vector y0,
step_mem->eRNrm = ONE;

/* Initialize all the counters */
step_mem->nfse = 0;
step_mem->nfsi = 0;
step_mem->nsetups = 0;
step_mem->nstlp = 0;
step_mem->nls_iters = 0;
step_mem->nls_fails = 0;
step_mem->nfse = 0;
step_mem->nfsi = 0;
step_mem->nsetups = 0;
step_mem->nstlp = 0;
step_mem->nls_iters = 0;
step_mem->nls_fails = 0;
step_mem->inner_fails = 0;

/* Initialize fused op work space */
step_mem->cvals = NULL;
Expand Down Expand Up @@ -352,11 +353,13 @@ int MRIStepReInit(void* arkode_mem, ARKRhsFn fse, ARKRhsFn fsi, sunrealtype t0,
step_mem->fsi_is_current = SUNFALSE;

/* Initialize all the counters */
step_mem->nfse = 0;
step_mem->nfsi = 0;
step_mem->nsetups = 0;
step_mem->nstlp = 0;
step_mem->nls_iters = 0;
step_mem->nfse = 0;
step_mem->nfsi = 0;
step_mem->nsetups = 0;
step_mem->nstlp = 0;
step_mem->nls_iters = 0;
step_mem->nls_fails = 0;
step_mem->inner_fails = 0;

return (ARK_SUCCESS);
}
Expand Down Expand Up @@ -701,6 +704,8 @@ void mriStep_PrintMem(ARKodeMem ark_mem, FILE* outfile)
fprintf(outfile, "MRIStep: nsetups = %li\n", step_mem->nsetups);
fprintf(outfile, "MRIStep: nstlp = %li\n", step_mem->nstlp);
fprintf(outfile, "MRIStep: nls_iters = %li\n", step_mem->nls_iters);
fprintf(outfile, "MRIStep: nls_fails = %li\n", step_mem->nls_fails);
fprintf(outfile, "MRIStep: inner_fails = %li\n", step_mem->inner_fails);

/* output boolean quantities */
fprintf(outfile, "MRIStep: user_linear = %i\n", step_mem->linear);
Expand Down Expand Up @@ -3453,7 +3458,16 @@ int mriStep_StageERKFast(ARKodeMem ark_mem, ARKodeMRIStepMem step_mem,
"Failure when evolving the inner stepper");
return (ARK_INNERSTEP_FAIL);
}
if (retval > 0) { return TRY_AGAIN; }
if (retval > 0)
{
/* increment stepper-specific counter, and decrement ARKODE-level nonlinear
solver counter (since that will be incremented automatically by ARKODE).
Return with "TRY_AGAIN" which should cause ARKODE to cut the step size
and retry the step. */
step_mem->inner_fails++;
ark_mem->ncfn--;
return TRY_AGAIN;
}

/* for normal stages (i.e., not the embedding) with MRI adaptivity enabled, get an
estimate for the fast time scale error */
Expand Down
13 changes: 7 additions & 6 deletions src/arkode/arkode_mristep_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,13 @@ typedef struct ARKodeMRIStepMemRec
sunrealtype inner_rtol_factor_new; /* upcoming control parameter */

/* Counters */
long int nfse; /* num fse calls */
long int nfsi; /* num fsi calls */
long int nsetups; /* num linear solver setup calls */
long int nls_iters; /* num nonlinear solver iters */
long int nls_fails; /* num nonlinear solver fails */
int nfusedopvecs; /* length of cvals and Xvecs arrays */
long int nfse; /* num fse calls */
long int nfsi; /* num fsi calls */
long int nsetups; /* num linear solver setup calls */
long int nls_iters; /* num nonlinear solver iters */
long int nls_fails; /* num nonlinear solver fails */
long int inner_fails; /* num recov. inner solver fails */
int nfusedopvecs; /* length of cvals and Xvecs arrays */

/* Data for using MRIStep with external polynomial forcing */
sunbooleantype expforcing; /* add forcing to explicit RHS */
Expand Down
29 changes: 27 additions & 2 deletions src/arkode/arkode_mristep_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,28 @@ int MRIStepGetLastInnerStepFlag(void* arkode_mem, int* flag)
return (ARK_SUCCESS);
}

/*---------------------------------------------------------------
MRIStepGetNumInnerStepperFails:
Returns the number of recoverable failures encountered by the
inner stepper.
---------------------------------------------------------------*/
int MRIStepGetNumInnerStepperFails(void* arkode_mem, long int* inner_fails)
{
ARKodeMem ark_mem;
ARKodeMRIStepMem step_mem;
int retval;

/* access ARKodeMem and ARKodeMRIStepMem structures */
retval = mriStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem);
if (retval != ARK_SUCCESS) { return (retval); }

/* set output from step_mem */
*inner_fails = step_mem->inner_fails;

return (ARK_SUCCESS);
}

/*===============================================================
Private functions attached to ARKODE
===============================================================*/
Expand Down Expand Up @@ -811,7 +833,9 @@ int mriStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, SUNOutputFormat fmt)
fprintf(outfile, "Explicit slow RHS fn evals = %ld\n", step_mem->nfse);
fprintf(outfile, "Implicit slow RHS fn evals = %ld\n", step_mem->nfsi);

/* nonlinear solver stats */
/* inner stepper and nonlinear solver stats */
fprintf(outfile, "Inner stepper failures = %ld\n",
step_mem->inner_fails);
fprintf(outfile, "NLS iters = %ld\n", step_mem->nls_iters);
fprintf(outfile, "NLS fails = %ld\n", step_mem->nls_fails);
if (ark_mem->nst > 0)
Expand Down Expand Up @@ -852,7 +876,8 @@ int mriStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, SUNOutputFormat fmt)
fprintf(outfile, ",Explicit slow RHS fn evals,%ld", step_mem->nfse);
fprintf(outfile, ",Implicit slow RHS fn evals,%ld", step_mem->nfsi);

/* nonlinear solver stats */
/* inner stepper and nonlinear solver stats */
fprintf(outfile, ",Inner stepper failures,%ld", step_mem->inner_fails);
fprintf(outfile, ",NLS iters,%ld", step_mem->nls_iters);
fprintf(outfile, ",NLS fails,%ld", step_mem->nls_fails);
if (ark_mem->nst > 0)
Expand Down

0 comments on commit 8b71729

Please sign in to comment.