diff --git a/doc/shared/sunstepper/SUNStepper_Description.rst b/doc/shared/sunstepper/SUNStepper_Description.rst index 304f8820b6..7d987937c6 100644 --- a/doc/shared/sunstepper/SUNStepper_Description.rst +++ b/doc/shared/sunstepper/SUNStepper_Description.rst @@ -81,7 +81,9 @@ from an ARKODE integrator. .. c:function:: SUNErrCode SUNStepper_Destroy(SUNStepper *stepper) - This function destroys a :c:type:`SUNStepper` object. + This function frees memory allocated by the :c:type:`SUNStepper` base class + and uses the function pointer optionally specified with + :c:type:`SUNStepper_SetDestroyFn` to free the content. :param stepper: a pointer to a stepper object. :return: A :c:type:`SUNErrCode` indicating success or failure. @@ -284,6 +286,17 @@ determined by the "consumer" of the :c:type:`SUNStepper`. :return: A :c:type:`SUNErrCode` indicating success or failure. +.. c:function:: SUNErrCode SUNStepper_SetDestroyFn(SUNStepper stepper, SUNStepperDestroyFn fn) + + This function attaches a :c:type:`SUNStepperDestroyFn` function to a + :c:type:`SUNStepper`. The provided function is responsible for freeing any + memory allocated for the :c:type:`SUNStepper` content. + + :param stepper: a stepper object. + :param fn: the :c:type:`SUNStepperDestroyFn` function to attach. + :return: A :c:type:`SUNErrCode` indicating success or failure. + + .. _SUNStepper.Description.ImplMethods: Implementation Specific Methods @@ -322,3 +335,9 @@ abstract base class. This type represents a function with the signature of :c:func:`SUNStepper_SetForcing`. + +.. c:type:: SUNErrCode (*SUNStepperDestroyFn)(SUNStepper stepper) + + This type represents a function with the signature similar to + :c:func:`SUNStepper_Destroy` for freeing the content associated with a + :c:type:`SUNStepper`. diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 24a973f32a..09ffbd4fd3 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -45,6 +45,8 @@ typedef SUNErrCode (*SUNStepperSetForcingFn)(SUNStepper stepper, sunrealtype tscale, N_Vector* forcing, int nforcing); +typedef SUNErrCode (*SUNStepperDestroyFn)(SUNStepper stepper); + SUNDIALS_EXPORT SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper); @@ -98,6 +100,9 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn); +SUNDIALS_EXPORT SUNErrCode SUNStepper_SetDestroyFn(SUNStepper stepper, + SUNStepperDestroyFn fn); + #ifdef __cplusplus } #endif diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index a7e4c73d50..565ab074bf 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2882,4 +2882,18 @@ SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingF } +SWIGEXPORT int _wrap_FSUNStepper_SetDestroyFn(void *farg1, SUNStepperDestroyFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperDestroyFn arg2 = (SUNStepperDestroyFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperDestroyFn)(farg2); + result = (SUNErrCode)SUNStepper_SetDestroyFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index aa6eeb9285..d9671dafcc 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -559,6 +559,7 @@ module fsundials_core_mod public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetDestroyFn ! WRAPPER DECLARATIONS interface @@ -2208,6 +2209,15 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetDestroyFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetDestroyFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + end interface @@ -5226,5 +5236,21 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function +function FSUNStepper_SetDestroyFn(stepper, fn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +type(C_FUNPTR), intent(in), value :: fn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_FUNPTR) :: farg2 + +farg1 = stepper +farg2 = fn +fresult = swigc_FSUNStepper_SetDestroyFn(farg1, farg2) +swig_result = fresult +end function + end module diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 652893a13f..11475a93c3 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2882,4 +2882,18 @@ SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingF } +SWIGEXPORT int _wrap_FSUNStepper_SetDestroyFn(void *farg1, SUNStepperDestroyFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperDestroyFn arg2 = (SUNStepperDestroyFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperDestroyFn)(farg2); + result = (SUNErrCode)SUNStepper_SetDestroyFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 8f2be2bcbd..3837176437 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -559,6 +559,7 @@ module fsundials_core_mod public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetDestroyFn ! WRAPPER DECLARATIONS interface @@ -2208,6 +2209,15 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetDestroyFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetDestroyFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + end interface @@ -5226,5 +5236,21 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function +function FSUNStepper_SetDestroyFn(stepper, fn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +type(C_FUNPTR), intent(in), value :: fn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_FUNPTR) :: farg2 + +farg1 = stepper +farg2 = fn +fresult = swigc_FSUNStepper_SetDestroyFn(farg1, farg2) +swig_result = fresult +end function + end module diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 81e7fddfe6..aa0dd05b3d 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -50,7 +50,9 @@ SUNErrCode SUNStepper_Destroy(SUNStepper* stepper_ptr) { if (stepper_ptr != NULL) { - free((*stepper_ptr)->ops); + const SUNStepper_Ops ops = (*stepper_ptr)->ops; + if (ops && ops->destroy) { ops->destroy(*stepper_ptr); } + free(ops); free(*stepper_ptr); *stepper_ptr = NULL; } diff --git a/src/sundials/sundials_stepper_impl.h b/src/sundials/sundials_stepper_impl.h index fb801cd57e..c5447c5cc1 100644 --- a/src/sundials/sundials_stepper_impl.h +++ b/src/sundials/sundials_stepper_impl.h @@ -20,16 +20,15 @@ extern "C" { #endif -typedef struct SUNStepper_Ops_* SUNStepper_Ops; - -struct SUNStepper_Ops_ +typedef struct { SUNStepperEvolveFn evolve; SUNStepperFullRhsFn fullrhs; SUNStepperResetFn reset; SUNStepperSetStopTimeFn setstoptime; SUNStepperSetForcingFn setforcing; -}; + SUNStepperDestroyFn destroy; +}* SUNStepper_Ops; struct SUNStepper_ {