Skip to content

Commit 3fe0bcd

Browse files
Feature: Various ARKODE updates (pre/post functions, remove extra copies, LSRKStep updates, Preallocate, GetStageIndex) (#897)
Combined updates from several PRs: * #813: step pre/post functions, stage postprocessing, and pre RHS functions * #814: removed an extraneous copy of `yn` into `yout` when running in ONE_STEP mode for ARKODE * #815: various cleanup to the LSRKStep module * #819: user-callable routine to retrieve the current stage index * #886: user-callable `ARKodeInit` routine to finalize ARKODE and allocate remaining memory before `ARKodeEvolve` is called --------- Co-authored-by: David Gardner <gardner48@llnl.gov>
1 parent 178eae8 commit 3fe0bcd

123 files changed

Lines changed: 9754 additions & 1884 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/test-driver/action.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ inputs:
1111
tpls:
1212
description: "enable/disable TPLs"
1313
required: true
14+
phase:
15+
description: "Optional phase passed to test_driver.sh as --phase <PHASE> (e.g., BUILD)"
16+
required: false
17+
default: ""
1418

1519
runs:
1620
using: composite
@@ -29,10 +33,15 @@ runs:
2933
run: |
3034
git config --global --add safe.directory $GITHUB_WORKSPACE
3135
cd test
36+
extra_args=""
37+
if [ -n "${{ inputs.phase }}" ]; then
38+
extra_args=" --phase ${{ inputs.phase }}"
39+
fi
3240
./test_driver.sh \
3341
--testtype CUSTOM \
3442
--env env/docker.sh \
3543
--tpls ${{ inputs.tpls }} \
3644
--sunrealtype ${{ inputs.precision }} \
37-
--indexsize ${{ inputs.indexsize }}
45+
--indexsize ${{ inputs.indexsize }} \
46+
${extra_args}
3847
shell: bash

.github/workflows/ubuntu-latest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
indexsize: ${{ matrix.indexsize }}
5353
precision: ${{ matrix.precision }}
5454
tpls: ${{ matrix.tpls }}
55+
phase: ${{ matrix.precision == 'extended' && 'BUILD' || '' }}
5556
env:
5657
CMAKE_BUILD_TYPE: ${{ matrix.buildtype }}
5758
- name: Archive build files from failed build

CHANGELOG.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,44 @@ Updated the Kokkos N_Vector to support Kokkos 5.x versions.
1111
Added `SUNLogger_Set{Error,Warning,Info,Debug}File` functions to allow setting
1212
logger output streams with a `FILE*`.
1313

14+
ARKODE now allows users to supply functions that will be called before each
15+
internal time step attempt (`ARKodeSetPreStepFn`), after each successful time
16+
step (`ARKodeSetPostStepFn`), before right-hand side routines are called on an
17+
updated state (`ARKodeSetPreRhsFn`), and/or once each internal step/stage is
18+
computed (`ARKodeSetPostprocessStepFn`/ `ARKodeSetPostprocessStageFn`). These
19+
are considered **advanced** functions, as they should treat the state vector as
20+
read-only, otherwise all theoretical guarantees of solution accuracy and
21+
stability will be lost. As a result of these new functions, the values of
22+
multiple ARKODE return codes (e.g., ``ARK_INTERP_FAIL``) have been updated;
23+
users who key off of the named constants will not be affected, but users who
24+
rely on the values themselves should update their codes accordingly.
25+
26+
Note to users utilizing the previously undocumented `ARKodeSetPostprocessStepFn`
27+
function, the supplied function is now called on the newly computed state vector
28+
for all step attempts not just successful steps. To obtain the previous behavior
29+
of only calling a function on successful steps, switch to using
30+
`ARKodeSetPostStepFn`.
31+
32+
Removed extraneous copy of output vector when using ARKODE in ``ARK_ONE_STEP`` mode.
33+
34+
The default number of stages for the SSP Runge-Kutta methods `ARKODE_LSRK_SSP_S_2`
35+
and `ARKODE_LSRK_SSP_S_3` in LSRKStep were changed from 10 and 9, respectively, to
36+
their minimum allowable values of 2 and 4. Users may revert to the previous values
37+
by calling `LSRKStepSetNumSSPStages`.
38+
39+
Added the optional function `ARKodeInit` to ARKODE to enable
40+
data allocation before the first call to `ARKodeEvolve`
41+
(but after all other optional input routines have been called), to support
42+
users who measure memory usage before beginning a simulation.
43+
44+
Added the function `ARKodeGetStageIndex` that returns the index of the stage
45+
currently being processed, and the total number of stages in the method, for users
46+
who wish to compute auxiliary quantities in their IVP right-hand side functions
47+
during some stages and not others (e.g., in all but the first or last stage).
48+
49+
Added the functions `ARKodeGetLastTime` and `ARKodeGetLastState` to return the last
50+
successful time and state achieved by ARKODE, respectively.
51+
1452
### Bug Fixes
1553

1654
Fixed a CMake bug where the SuperLU_MT interface would not be built and
@@ -22,6 +60,37 @@ Fixed a bug where passing an empty string to `SUNLogger_Set{Error,Warning,Info,D
2260
did not disable the corresponding logging stream ([Issue
2361
#844](https://github.com/llnl/sundials/issues/844)).
2462

63+
Fixed a bug in logging output from ARKODE, where for some time stepping modules,
64+
the current "time" output in the logger was incorrect.
65+
66+
Fixed a bug in the ARKODE discrete adjoint checkpointing where an incorrect
67+
state would be stored on the first step if the output vector passed to
68+
`ARKodeEvolve` did not contain the initial condition on the first call.
69+
70+
Fixed a bug in MRIStep when using a custom inner integrator that relies on the
71+
input state being the initial condition for the fast integration rather than
72+
retaining the result from the last inner integration or most recent reset call
73+
and the output vector passed to `ARKodeEvolve` does not contain the initial
74+
condition on the first call or the last returned solution on subsequent calls.
75+
76+
Removed an extraneous copy of the output vector in each step with SplittingStep.
77+
78+
Added a missing call to `SUNNonlinSolSetup` in MRIStep when using an
79+
IMEX-MRI-SR method.
80+
81+
Fixed a potential bug in LSRKStep's `ARKODE_LSRK_SSP_S_3` method, where a real
82+
number was used instead of an integer, potentially resulting in a rounding error.
83+
84+
Fixed a bug in LSRKStep where an incorrect state vector could be passed to a
85+
user-supplied dominant eigenvalue function on the first step unless the output
86+
vector passed to `ARKodeEvolve` contained the initial condition and when an
87+
eigenvalue estimate is requested on the first step in a subsequent call to
88+
`ARKodeEvolve` unless the output vector passed contained the most recently returned
89+
solution.
90+
91+
Fixed a bug in MRIStep for estimating the first "slow" time step in an adaptive
92+
multirate calculation.
93+
2594
### Deprecation Notices
2695

2796
Several CMake options have been deprecated in favor of namespaced versions

bindings/sundials4py/arkode/arkode.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ void bind_arkode(nb::module_& m)
137137
arkode_relaxjacfn_wrapper, nb::arg("arkode_mem"),
138138
nb::arg("rfn").none(), nb::arg("rjacfn").none());
139139

140+
BIND_ARKODE_CALLBACK(ARKodeSetPreStepFn, ARKPreStepFn, prestepfn,
141+
arkode_prestepfn_wrapper, nb::arg("arkode_mem"),
142+
nb::arg("prestep").none());
143+
144+
BIND_ARKODE_CALLBACK(ARKodeSetPostStepFn, ARKPostStepFn, poststepfn,
145+
arkode_poststepfn_wrapper, nb::arg("arkode_mem"),
146+
nb::arg("poststep").none());
147+
148+
BIND_ARKODE_CALLBACK(ARKodeSetPreRhsFn, ARKPreRhsFn, prerhsfn,
149+
arkode_prerhsfn_wrapper, nb::arg("arkode_mem"),
150+
nb::arg("prerhs").none());
151+
140152
BIND_ARKODE_CALLBACK(ARKodeSetPostprocessStepFn, ARKPostProcessFn,
141153
postprocessstepfn, arkode_postprocessstepfn_wrapper,
142154
nb::arg("arkode_mem"), nb::arg("postprocessstep").none());

bindings/sundials4py/arkode/arkode_generated.hpp

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,28 @@ m.attr("ARK_INNERTOOUTER_FAIL") = -36;
6262
m.attr("ARK_POSTPROCESS_FAIL") = -37;
6363
m.attr("ARK_POSTPROCESS_STEP_FAIL") = -37;
6464
m.attr("ARK_POSTPROCESS_STAGE_FAIL") = -38;
65-
m.attr("ARK_USER_PREDICT_FAIL") = -39;
66-
m.attr("ARK_INTERP_FAIL") = -40;
67-
m.attr("ARK_INVALID_TABLE") = -41;
68-
m.attr("ARK_CONTEXT_ERR") = -42;
69-
m.attr("ARK_RELAX_FAIL") = -43;
70-
m.attr("ARK_RELAX_MEM_NULL") = -44;
71-
m.attr("ARK_RELAX_FUNC_FAIL") = -45;
72-
m.attr("ARK_RELAX_JAC_FAIL") = -46;
73-
m.attr("ARK_CONTROLLER_ERR") = -47;
74-
m.attr("ARK_STEPPER_UNSUPPORTED") = -48;
75-
m.attr("ARK_DOMEIG_FAIL") = -49;
76-
m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -50;
77-
m.attr("ARK_SUNSTEPPER_ERR") = -51;
78-
m.attr("ARK_STEP_DIRECTION_ERR") = -52;
79-
m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -53;
80-
m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -54;
81-
m.attr("ARK_SUNADJSTEPPER_ERR") = -55;
82-
m.attr("ARK_DEE_FAIL") = -56;
65+
m.attr("ARK_PRESTEPFN_FAIL") = -39;
66+
m.attr("ARK_POSTSTEPFN_FAIL") = -40;
67+
m.attr("ARK_PRERHSFN_FAIL") = -41;
68+
m.attr("ARK_USER_PREDICT_FAIL") = -42;
69+
m.attr("ARK_INTERP_FAIL") = -43;
70+
m.attr("ARK_INVALID_TABLE") = -44;
71+
m.attr("ARK_CONTEXT_ERR") = -45;
72+
m.attr("ARK_RELAX_FAIL") = -46;
73+
m.attr("ARK_RELAX_MEM_NULL") = -47;
74+
m.attr("ARK_RELAX_FUNC_FAIL") = -48;
75+
m.attr("ARK_RELAX_JAC_FAIL") = -49;
76+
m.attr("ARK_CONTROLLER_ERR") = -50;
77+
m.attr("ARK_STEPPER_UNSUPPORTED") = -51;
78+
m.attr("ARK_DOMEIG_FAIL") = -52;
79+
m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -53;
80+
m.attr("ARK_SUNSTEPPER_ERR") = -54;
81+
m.attr("ARK_STEP_DIRECTION_ERR") = -55;
82+
m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -56;
83+
m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -57;
84+
m.attr("ARK_SUNADJSTEPPER_ERR") = -58;
85+
m.attr("ARK_DEE_FAIL") = -59;
86+
m.attr("ARK_STEP_H0_FAIL") = -60;
8387
m.attr("ARK_UNRECOGNIZED_ERROR") = -99;
8488

8589
auto pyEnumARKRelaxSolver = nb::enum_<ARKRelaxSolver>(m, "ARKRelaxSolver",
@@ -107,6 +111,9 @@ auto pyEnumARKAccumError =
107111
m.def("ARKodeReset", ARKodeReset, nb::arg("arkode_mem"), nb::arg("tR"),
108112
nb::arg("yR"));
109113

114+
m.def("ARKodeInit", ARKodeInit, nb::arg("arkode_mem"),
115+
"Optional data allocation function");
116+
110117
m.def(
111118
"ARKodeCreateMRIStepInnerStepper",
112119
[](void* arkode_mem)
@@ -497,6 +504,26 @@ m.def("ARKodeGetReturnFlagName", ARKodeGetReturnFlagName, nb::arg("flag"));
497504
m.def("ARKodeWriteParameters", ARKodeWriteParameters, nb::arg("arkode_mem"),
498505
nb::arg("fp"));
499506

507+
m.def(
508+
"ARKodeGetStageIndex",
509+
[](void* arkode_mem) -> std::tuple<int, int, int>
510+
{
511+
auto ARKodeGetStageIndex_adapt_modifiable_immutable_to_return =
512+
[](void* arkode_mem) -> std::tuple<int, int, int>
513+
{
514+
int stage_adapt_modifiable;
515+
int max_stages_adapt_modifiable;
516+
517+
int r = ARKodeGetStageIndex(arkode_mem, &stage_adapt_modifiable,
518+
&max_stages_adapt_modifiable);
519+
return std::make_tuple(r, stage_adapt_modifiable,
520+
max_stages_adapt_modifiable);
521+
};
522+
523+
return ARKodeGetStageIndex_adapt_modifiable_immutable_to_return(arkode_mem);
524+
},
525+
nb::arg("arkode_mem"));
526+
500527
m.def(
501528
"ARKodeGetNumExpSteps",
502529
[](void* arkode_mem) -> std::tuple<int, long>
@@ -671,6 +698,40 @@ m.def(
671698
},
672699
nb::arg("arkode_mem"));
673700

701+
m.def(
702+
"ARKodeGetLastTime",
703+
[](void* arkode_mem) -> std::tuple<int, sunrealtype>
704+
{
705+
auto ARKodeGetLastTime_adapt_modifiable_immutable_to_return =
706+
[](void* arkode_mem) -> std::tuple<int, sunrealtype>
707+
{
708+
sunrealtype tn_adapt_modifiable;
709+
710+
int r = ARKodeGetLastTime(arkode_mem, &tn_adapt_modifiable);
711+
return std::make_tuple(r, tn_adapt_modifiable);
712+
};
713+
714+
return ARKodeGetLastTime_adapt_modifiable_immutable_to_return(arkode_mem);
715+
},
716+
nb::arg("arkode_mem"));
717+
718+
m.def(
719+
"ARKodeGetLastState",
720+
[](void* arkode_mem) -> std::tuple<int, N_Vector>
721+
{
722+
auto ARKodeGetLastState_adapt_modifiable_immutable_to_return =
723+
[](void* arkode_mem) -> std::tuple<int, N_Vector>
724+
{
725+
N_Vector state_adapt_modifiable;
726+
727+
int r = ARKodeGetLastState(arkode_mem, &state_adapt_modifiable);
728+
return std::make_tuple(r, state_adapt_modifiable);
729+
};
730+
731+
return ARKodeGetLastState_adapt_modifiable_immutable_to_return(arkode_mem);
732+
},
733+
nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference);
734+
674735
m.def(
675736
"ARKodeGetCurrentTime",
676737
[](void* arkode_mem) -> std::tuple<int, sunrealtype>

bindings/sundials4py/arkode/arkode_usersupplied.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ struct arkode_user_supplied_fn_table
4545
nb::object ewtn;
4646
nb::object rwtn;
4747
nb::object vecresizefn;
48+
nb::object prerhsfn;
49+
nb::object prestepfn;
50+
nb::object poststepfn;
4851
nb::object postprocessstepfn;
4952
nb::object postprocessstagefn;
5053
nb::object stagepredictfn;
@@ -159,6 +162,30 @@ inline int arkode_vecresizefn_wrapper(Args... args)
159162
ARKodeMem, 1>(&arkode_user_supplied_fn_table::vecresizefn, args...);
160163
}
161164

165+
template<typename... Args>
166+
inline int arkode_prerhsfn_wrapper(Args... args)
167+
{
168+
return sundials4py::user_supplied_fn_caller<
169+
std::remove_pointer_t<ARKPreRhsFn>, arkode_user_supplied_fn_table,
170+
ARKodeMem, 1>(&arkode_user_supplied_fn_table::prerhsfn, args...);
171+
}
172+
173+
template<typename... Args>
174+
inline int arkode_prestepfn_wrapper(Args... args)
175+
{
176+
return sundials4py::user_supplied_fn_caller<
177+
std::remove_pointer_t<ARKPreStepFn>, arkode_user_supplied_fn_table,
178+
ARKodeMem, 1>(&arkode_user_supplied_fn_table::prestepfn, args...);
179+
}
180+
181+
template<typename... Args>
182+
inline int arkode_poststepfn_wrapper(Args... args)
183+
{
184+
return sundials4py::user_supplied_fn_caller<
185+
std::remove_pointer_t<ARKPostStepFn>, arkode_user_supplied_fn_table,
186+
ARKodeMem, 1>(&arkode_user_supplied_fn_table::poststepfn, args...);
187+
}
188+
162189
template<typename... Args>
163190
inline int arkode_postprocessstepfn_wrapper(Args... args)
164191
{

0 commit comments

Comments
 (0)