From 5f8ff596f73384a37849c937994f71c08b44bc01 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 12 Aug 2024 10:41:57 -0700 Subject: [PATCH 001/180] Initial commit after rebase --- include/arkode/arkode_splittingstep.h | 125 +++++ src/arkode/CMakeLists.txt | 4 + src/arkode/arkode_splitting_coefficients.c | 350 +++++++++++++ src/arkode/arkode_splitting_coefficients.def | 38 ++ src/arkode/arkode_splittingstep.c | 465 ++++++++++++++++++ .../arkode_splittingstep_executionpolicy.c | 158 ++++++ src/arkode/arkode_splittingstep_impl.h | 34 ++ .../arkode/C_serial/ark_test_splittingstep.c | 101 ++++ 8 files changed, 1275 insertions(+) create mode 100644 include/arkode/arkode_splittingstep.h create mode 100644 src/arkode/arkode_splitting_coefficients.c create mode 100644 src/arkode/arkode_splitting_coefficients.def create mode 100644 src/arkode/arkode_splittingstep.c create mode 100644 src/arkode/arkode_splittingstep_executionpolicy.c create mode 100644 src/arkode/arkode_splittingstep_impl.h create mode 100644 test/unit_tests/arkode/C_serial/ark_test_splittingstep.c diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h new file mode 100644 index 0000000000..5a4b98ca80 --- /dev/null +++ b/include/arkode/arkode_splittingstep.h @@ -0,0 +1,125 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#ifndef ARKODE_SPLITTINGSTEP_H_ +#define ARKODE_SPLITTINGSTEP_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/*--------------------------------------------------------------- + Types : struct ARKodeSplittingCoefficientsMem, ARKodeSplittingCoefficients + ---------------------------------------------------------------*/ +struct ARKodeSplittingCoefficientsMem +{ + sunrealtype* alpha; /* weights for sum over sequential splitting methods */ + sunrealtype*** beta; /* length of each flow, indexed by the sequential method, stage, and partition */ + int sequential_methods; /* number of sequential splitting methods */ + int stages; /* number of stages within each sequential splitting method */ + int partitions; /* number of RHS partitions */ + int order; /* order of convergence */ +}; + +typedef _SUNDIALS_STRUCT_ ARKodeSplittingCoefficientsMem* ARKodeSplittingCoefficients; + +typedef enum +{ + ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ + ARKODE_MIN_SPLITTING_NUM = 300, + ARKODE_SPLITTING_LIE_TROTTER = ARKODE_MIN_SPLITTING_NUM, + ARKODE_SPLITTING_STRANG, + ARKODE_SPLITTING_YOSHIDA, + ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA +} ARKODE_SplittingCoefficientsID; + +/* TODO: remove once SUNStepper is ready */ +typedef MRIStepInnerStepper SUNStepper; + +/* Coefficient memory management */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( + int sequential_methods, int stages, int partitions, int order); +SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients B); +SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Space( + ARKodeSplittingCoefficients B, sunindextype* liw, sunindextype* lrw); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Copy(ARKodeSplittingCoefficients B); + +/* Constructors for splitting coefficients */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_LieTrotter(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Strang(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Parallel(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_SymmetricParallel(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_TripleJump(int partitions, int order); + +/* Other coefficient functions */ +SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Write( + ARKodeSplittingCoefficients B, FILE* outfile); +SUNDIALS_EXPORT sunbooleantype +ARKodeSplittingCoefficients_(ARKodeSplittingCoefficients B); + +/* Parallelization Policy */ +typedef int (*ARKParallelExecuteFn)(int i, N_Vector y, void* user_data); + +typedef _SUNDIALS_STRUCT_ ARKodeSplittingExecutionPolicyMem* ARKodeSplittingExecutionPolicy; + +struct ARKodeSplittingExecutionPolicyMem +{ + // TODO: make ops struct for these functions? + int (*setup)(ARKodeSplittingExecutionPolicy policy, N_Vector y, + int sequential_methods); + + int (*execute)(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, + N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, + const int sequential_methods, void* user_data); + + void (*free)(ARKodeSplittingExecutionPolicy policy); + + void* data; +}; + +SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy +ARKodeSplittingExecutionPolicy_Serial(); + +SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicyFree( + ARKodeSplittingExecutionPolicy* policy); + +/* ARKODE functions */ +SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, + sunrealtype t0, N_Vector y0, + SUNContext sunctx); + +SUNDIALS_EXPORT int SplittingStep_SetCoefficients( + void* arkode_mem, ARKodeSplittingCoefficients coefficients); + +SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( + void* arkode_mem, ARKodeSplittingExecutionPolicy policy); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index f8a0f4be63..5938c63dd6 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -38,6 +38,9 @@ set(arkode_SOURCES arkode_mristep.c arkode_relaxation.c arkode_root.c + arkode_splitting_coefficients.c + arkode_splittingstep_executionpolicy.c + arkode_splittingstep.c arkode_sprkstep_io.c arkode_sprkstep.c arkode_sprk.c @@ -56,6 +59,7 @@ set(arkode_HEADERS arkode_erkstep.h arkode_ls.h arkode_mristep.h + arkode_splittingstep.h arkode_sprk.h arkode_sprkstep.h) diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c new file mode 100644 index 0000000000..fe46d2e47d --- /dev/null +++ b/src/arkode/arkode_splitting_coefficients.c @@ -0,0 +1,350 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include +#include + +#include "arkode_impl.h" + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( + const int sequential_methods, const int stages, const int partitions, + const int order) +{ + if (sequential_methods < 1 || stages < 1 || partitions < 1) { return NULL; } + + const ARKodeSplittingCoefficients coefficients = + (ARKodeSplittingCoefficients)malloc(sizeof(*coefficients)); + if (coefficients == NULL) { return NULL; } + + coefficients->sequential_methods = sequential_methods; + coefficients->stages = stages; + coefficients->partitions = partitions; + coefficients->order = order; + + coefficients->alpha = (sunrealtype*)calloc(sequential_methods, + sizeof(*coefficients->alpha)); + if (coefficients->alpha == NULL) + { + ARKodeSplittingCoefficients_Free(coefficients); + return NULL; + } + + /* In order for beta to be indexed like beta[i][j][k], we can't use a single + malloc. The j index requires allocating a matrix of pointers into beta. The + i index requires allocating an array of pointers into that matrix. */ + + /* Array of pointers for index i */ + coefficients->beta = + (sunrealtype***)malloc(sequential_methods * sizeof(*coefficients->beta)); + if (coefficients->beta == NULL) + { + ARKodeSplittingCoefficients_Free(coefficients); + return NULL; + } + + /* Matrix of pointers for index j */ + sunrealtype** beta_cols = + (sunrealtype**)malloc(sequential_methods * (stages + 1) * sizeof(*beta_cols)); + if (beta_cols == NULL) + { + ARKodeSplittingCoefficients_Free(coefficients); + return NULL; + } + + /* Contiguous memory to store the beta tensor */ + sunrealtype* beta_mem = + (sunrealtype*)calloc(sequential_methods * (stages + 1) * partitions, + sizeof(*beta_mem)); + if (beta_mem == NULL) + { + ARKodeSplittingCoefficients_Free(coefficients); + return NULL; + } + + for (int i = 0; i < sequential_methods; i++) + { + coefficients->beta[i] = &beta_cols[i]; + for (int j = 0; j <= stages; j++) + { + coefficients->beta[i][j] = &beta_mem[(i * (stages + 1) + j) * partitions]; + } + } + + return coefficients; +} + +// TODO: should argument be a pointer? +void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients coefficients) +{ + if (coefficients != NULL) + { + free(coefficients->alpha); + if (coefficients->beta != NULL) + { + free(coefficients->beta[0][0]); + free(coefficients->beta[0]); + free(coefficients->beta); + } + } + + free(coefficients); +} + +void ARKodeSplittingCoefficients_Space(ARKodeSplittingCoefficients coefficients, + sunindextype* liw, sunindextype* lrw) +{ + /* initialize outputs and return if coefficients is not allocated */ + *liw = 0; + *lrw = 0; + if (coefficients == NULL) { return; } + + /* ints for # of sequential methods, stages, partitions, and order */ + *liw = 4; + + if (coefficients->beta) + { + /* pointers for index i of beta[i][j][k] */ + *liw += coefficients->sequential_methods; + } + + if (coefficients->beta[0]) + { + /* pointers for index j of beta[i][j][k] */ + *liw += coefficients->sequential_methods * (coefficients->stages + 1); + } + + if (coefficients->alpha) { *lrw += coefficients->sequential_methods; } + if (coefficients->beta[0][0]) + { + *lrw += coefficients->sequential_methods * (coefficients->stages + 1) * + coefficients->partitions; + } +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( + ARKodeSplittingCoefficients coefficients) +{ + if (coefficients == NULL) { return NULL; } + + ARKodeSplittingCoefficients coefficientsCopy = + ARKodeSplittingCoefficients_Alloc(coefficients->sequential_methods, + coefficients->stages, + coefficients->partitions, + coefficients->order); + if (coefficientsCopy == NULL) { return NULL; } + + memcpy(coefficientsCopy->alpha, coefficients->alpha, + coefficients->sequential_methods * sizeof(*coefficients->alpha)); + + /* beta[0][0] points to the contiguous memory allocation, so we can copy it + with a single memcpy */ + memcpy(coefficientsCopy->beta[0][0], coefficients->beta[0][0], + coefficients->sequential_methods * (coefficients->stages + 1) * + coefficients->partitions * sizeof(*coefficients->beta)); + + return coefficientsCopy; +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( + ARKODE_SplittingCoefficientsID method) +{ + switch (method) + { +#define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ + case name: coeff break; +#include "arkode_splitting_coefficients.def" +#undef ARK_SPLITTING_COEFFICIENTS + + default: + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Unknown splitting coefficients"); + return NULL; + } +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( + const char* method) +{ +#define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ + if (strcmp(#name, method) == 0) coeff +#include "arkode_splitting_coefficients.def" +#undef ARK_SPLITTING_COEFFICIENTS + + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Unknown splitting coefficients"); + + return NULL; +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LieTrotter(const int partitions) +{ + if (partitions < 1) { return NULL; } + const ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Alloc(1, 1, partitions, 1); + if (coefficients == NULL) { return NULL; } + + coefficients->alpha[0] = SUN_RCONST(1.0); + for (int i = 0; i < partitions; i++) + { + coefficients->beta[0][1][i] = SUN_RCONST(1.0); + } + + return coefficients; +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Strang(const int partitions) +{ + return ARKodeSplittingCoefficients_TripleJump(partitions, 2); +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int partitions) +{ + if (partitions < 1) { return NULL; } + + const ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Alloc(partitions + 1, 1, partitions, 1); + if (coefficients == NULL) { return NULL; } + + for (int i = 0; i < partitions; i++) + { + coefficients->alpha[i] = SUN_RCONST(1.0); + for (int j = i; j < partitions; j++) { + coefficients->beta[i][1][j] = SUN_RCONST(1.0); + } + } + + coefficients->alpha[partitions] = 1 - partitions; + + return coefficients; +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( + const int partitions) +{ + if (partitions < 1) { return NULL; } + + const ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Alloc(2, partitions, partitions, 2); + if (coefficients == NULL) { return NULL; } + + coefficients->alpha[0] = SUN_RCONST(0.5); + coefficients->alpha[1] = SUN_RCONST(0.5); + + for (int i = 0; i < partitions; i++) + { + coefficients->beta[0][1][i] = SUN_RCONST(1.0); + coefficients->beta[1][i + 1][partitions - i - 1] = SUN_RCONST(1.0); + } + + return coefficients; +} + +static sunrealtype** arkodeSplittingCoefficients_TripleJump( + const int partitions, const int order, sunrealtype** beta, + const sunrealtype parent_length) +{ + // The base case is an order 2 Strang splitting + if (order == 2) + { + for (int i = 0; i < partitions; i++) + { + // Use += here because the first integration may combine with the last + // integration of the previous stage + beta[1][i] += SUN_RCONST(0.5) * parent_length; + beta[i][partitions - i - 1] += SUN_RCONST(0.5) * parent_length; + } + + // Advance the beta pointer to the last stage of this Strang splitting + return &beta[partitions - 1]; + } + + // Length of jump 1 and 3 + sunrealtype z1 = SUN_RCONST(1.0) / + (SUN_RCONST(2.0) - + SUNRpowerR(SUN_RCONST(2.0), SUN_RCONST(1.0) / (order - 1))); + // Length of jump 2 + sunrealtype z0 = SUN_RCONST(1.0) - SUN_RCONST(2.0) * z1; + + // Perform the triple jump + beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z1); + beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z0); + beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z1); + + return beta; +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump( + const int partitions, const int order) +{ + if (partitions < 1 || order < 2 || order % 2 != 0) + { + // Only even orders allowed + return NULL; + } + + const int stages = 1 + (partitions - 1) * SUNRpowerI(3, order / 2 - 1); + const ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Alloc(1, stages, partitions, order); + if (coefficients == NULL) { return NULL; } + + coefficients->alpha[0] = SUN_RCONST(1.0); + arkodeSplittingCoefficients_TripleJump(partitions, order, + coefficients->beta[0], SUN_RCONST(1.0)); + + return coefficients; +} + +/*--------------------------------------------------------------- + Routine to print a Butcher table structure + ---------------------------------------------------------------*/ +void ARKodeSplittingCoefficients_Write(ARKodeSplittingCoefficients coefficients, + FILE* outfile) +{ + if (coefficients == NULL || coefficients->alpha == NULL || + coefficients->beta == NULL || coefficients->beta[0] == NULL || + coefficients->beta[0][0] == NULL) + { + return; + } + + fprintf(outfile, " sequential methods = %i\n", + coefficients->sequential_methods); + fprintf(outfile, " stages = %i\n", coefficients->stages); + fprintf(outfile, " partitions = %i\n", coefficients->partitions); + fprintf(outfile, " order = %i\n", coefficients->order); + fprintf(outfile, " alpha = \n"); + for (int i = 0; i < coefficients->sequential_methods; i++) + { + fprintf(outfile, "%" RSYM " ", coefficients->alpha[i]); + } + // TODO: fix formatting + + for (int i = 0; i < coefficients->sequential_methods; i++) + { + fprintf(outfile, " beta[%i] = \n", i); + for (int j = 0; j < coefficients->stages; j++) + { + fprintf(outfile, " "); + for (int k = 0; k < coefficients->partitions; k++) + { + fprintf(outfile, "%" RSYMW " ", coefficients->beta[i][j][k]); + } + fprintf(outfile, "\n"); + } + fprintf(outfile, "\n"); + } +} diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def new file mode 100644 index 0000000000..8f4cd326d2 --- /dev/null +++ b/src/arkode/arkode_splitting_coefficients.def @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * This file defines splitting coefficients using X-macros + *--------------------------------------------------------------*/ + +/* + When adding a new method, enter the coefficients below and add + a new enum entry to include/arkode/arkode_splitting_coeffs.h + + Method names and properties are listed in the table + below. The 'QP' column denotes whether the coefficients of the + method are known precisely enough for use in quad precision + (128-bit) calculations. + + imeth QP + -------------------------------------- + + -------------------------------------- +*/ + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { + return NULL; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER, { + return NULL; + }) \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c new file mode 100644 index 0000000000..c498d36d11 --- /dev/null +++ b/src/arkode/arkode_splittingstep.c @@ -0,0 +1,465 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include +#include + +#include "arkode_impl.h" +#include "arkode_mristep_impl.h" +#include "arkode_splittingstep_impl.h" + +#define DEFAULT_ORDER 2 + +// TODO: check the 2nd argument of arkProcessError is correct +// TODO: workspace size + +static int splittingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, + ARKodeSplittingStepMem* step_mem) +{ + /* access ARKodeSPRKStepMem structure */ + if (ark_mem->step_mem == NULL) + { + arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, fname, __FILE__, + "Time step module memory is NULL."); + return (ARK_MEM_NULL); + } + *step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; + return ARK_SUCCESS; +} + +static int splittingStep_AccessARKODEStepMem(void* arkode_mem, const char* fname, + ARKodeMem* ark_mem, + ARKodeSplittingStepMem* step_mem) +{ + /* access ARKodeMem structure */ + if (arkode_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, fname, __FILE__, + MSG_ARK_NO_MEM); + return (ARK_MEM_NULL); + } + *ark_mem = (ARKodeMem)arkode_mem; + + return splittingStep_AccessStepMem(*ark_mem, __func__, step_mem); +} + +static sunbooleantype splittingStep_CheckNVector(const N_Vector y) +{ + // TODO: check all ops are correct + return y->ops->nvclone != NULL && y->ops->nvdestroy != NULL && + y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; +} + +static int splittingStep_Init(ARKodeMem ark_mem, const int init_type) +{ + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + /* immediately return if reset */ + if (init_type == RESET_INIT) { return ARK_SUCCESS; } + + /* initializations/checks for (re-)initialization call */ + if (init_type == FIRST_INIT) + { + if (step_mem->coefficients == NULL) + { + if (step_mem->order <= 1) + { + step_mem->coefficients = + ARKodeSplittingCoefficients_LieTrotter(step_mem->partitions); + // TODO: check if non-NULL? + } + else + { + // TODO consider extrapolation for odd orders + const int next_even_order = step_mem->order + (step_mem->order % 2); + step_mem->coefficients = + ARKodeSplittingCoefficients_TripleJump(step_mem->partitions, + next_even_order); + // TODO: check if non-NULL? + } + } + + if (step_mem->policy == NULL) + { + step_mem->policy = ARKodeSplittingExecutionPolicy_Serial(); + step_mem->own_policy = SUNTRUE; + } + } + + ark_mem->interp_degree = + SUNMAX(1, SUNMIN(step_mem->order - 1, ark_mem->interp_degree)); + + return ARK_SUCCESS; +} + +static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, + const N_Vector y, const N_Vector f, + const int mode) +{ + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + // retval = innerStepper_FullRhs(step_mem->steppers[0], t, y, f, + // ARK_FULLRHS_OTHER); + if (retval != 0) + { + arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_RHSFUNC_FAILED, t); + return (ARK_RHSFUNC_FAIL); + } + + for (int i = 1; i < step_mem->partitions; i++) + { + // retval = innerStepper_FullRhs(step_mem->steppers[i], t, y, ark_mem->tempv1, + // ARK_FULLRHS_OTHER); + if (retval != 0) + { + arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_RHSFUNC_FAILED, t); + return (ARK_RHSFUNC_FAIL); + } + N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); + } + + return ARK_SUCCESS; +} + +static int splittingStep_Stage(const int i, const N_Vector y, void* user_data) +{ + // Note: this should not write to user_data to avoid race conditions when executed in parallel + + ARKodeMem ark_mem = (ARKodeMem)user_data; + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + ARKodeSplittingCoefficients coefficients = step_mem->coefficients; + + for (int j = 0; j < coefficients->stages; j++) + { + for (int k = 0; k < coefficients->partitions; k++) + { + const sunrealtype tcur = ark_mem->tn + + coefficients->beta[i][j][k] * ark_mem->h; + const sunrealtype tnext = ark_mem->tn + coefficients->beta[i][j + 1][k] * + ark_mem->h; + if (tcur != tnext) + { + SUNStepper stepper = step_mem->steppers[k]; + if (SUNTRUE) + { // TODO: condition for FSAL. Consider special cases where the + // coefficients have changed, it's the first step, or reset is called + // TODO: what about backward integration? + stepper->ops->reset(stepper, tcur, y); + } + retval = stepper->ops->evolve(stepper, tcur, tnext, y); + + if (retval != ARK_SUCCESS) { return retval; } + } + } + } + + return ARK_SUCCESS; +} + +static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, + int* nflagPtr) +{ + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + *nflagPtr = ARK_SUCCESS; + *dsmPtr = ZERO; + + ARKodeSplittingCoefficients coefficients = step_mem->coefficients; + + return step_mem->policy->execute(step_mem->policy, splittingStep_Stage, + ark_mem->yn, ark_mem->ycur, + ark_mem->tempv1, coefficients->alpha, + coefficients->sequential_methods, ark_mem); +} + +int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, + SUNOutputFormat fmt) +{ + ARKodeSplittingStepMem step_mem; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + switch (fmt) + { + case SUN_OUTPUTFORMAT_TABLE: + fprintf(outfile, "Stepper evolves = %ld\n", step_mem->n_stepper_evolves); + break; + case SUN_OUTPUTFORMAT_CSV: + fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); + break; + default: + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Invalid formatting option."); + return (ARK_ILL_INPUT); + } + + return ARK_SUCCESS; +} + +int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) +{ + ARKodeSplittingStepMem step_mem; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + fprintf(fp, "SplittingStep time step module parameters:\n Method order %i\n\n", + step_mem->order); + + return ARK_SUCCESS; +} + +static int splittingStep_Resize(ARKodeMem ark_mem, N_Vector ynew, + sunrealtype hscale, sunrealtype t0, + ARKVecResizeFn resize, void* resize_data) +{ + // TODO: update lrw, liw? + return ARK_SUCCESS; +} + +static void splittingStep_Free(ARKodeMem ark_mem) +{ + ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; + if (step_mem == NULL) { return; } + + // TODO keep track of workspace size + if (step_mem->own_policy) + { + ARKodeSplittingExecutionPolicyFree(&step_mem->policy); + } + + ARKodeSplittingCoefficients_Free(step_mem->coefficients); + free(step_mem); + ark_mem->step_mem = NULL; +} + +void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) +{ + ARKodeSplittingStepMem step_mem; + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return; } + + /* output integer quantities */ + fprintf(outfile, "SplittingStep: partitions = %i\n", step_mem->partitions); + fprintf(outfile, "SplittingStep: order = %i\n", step_mem->order); + + /* output long integer quantities */ + fprintf(outfile, "SplittingStep: n_stepper_evolves = %li\n", + step_mem->n_stepper_evolves); + + /* output sunrealtype quantities */ + fprintf(outfile, "SplittingStep: Coefficients:\n"); + ARKodeSplittingCoefficients_Write(step_mem->coefficients, outfile); + + //TODO: consider printing policy +} + +int splittingStep_SetDefaults(ARKodeMem ark_mem) +{ + ARKodeSplittingStepMem step_mem; + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + step_mem->order = DEFAULT_ORDER; + step_mem->coefficients = NULL; + step_mem->policy = NULL; + return ARK_SUCCESS; +} + +static int splittingStep_SetOrder(ARKodeMem ark_mem, const int order) +{ + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + /* set user-provided value, or default, depending on argument */ + if (order <= 0) { step_mem->order = 1; } + else { step_mem->order = order; } + + if (step_mem->coefficients) + { + ARKodeSplittingCoefficients_Free(step_mem->coefficients); + step_mem->coefficients = NULL; + } + + return ARK_SUCCESS; +} + +void* SplittingStepCreate(SUNStepper* steppers, const int partitions, + const sunrealtype t0, N_Vector y0, SUNContext sunctx) +{ + if (steppers == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "steppers = NULL illegal."); + return NULL; + } + + for (int i = 0; i < partitions; i++) + { + if (steppers[i] == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "steppers[i] = NULL illegal.", i); + return NULL; + } + } + + if (y0 == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_NULL_Y0); + return NULL; + } + + if (sunctx == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_NULL_SUNCTX); + return NULL; + } + + /* Test if all required vector operations are implemented */ + if (!splittingStep_CheckNVector(y0)) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_BAD_NVECTOR); + return (NULL); + } + + /* Create ark_mem structure and set default values */ + ARKodeMem ark_mem = arkCreate(sunctx); + if (ark_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_ARK_NO_MEM); + return (NULL); + } + + ARKodeSplittingStepMem step_mem = + (ARKodeSplittingStepMem)malloc(sizeof(*step_mem)); + if (step_mem == NULL) + { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_ARKMEM_FAIL); + ARKodeFree((void**)&ark_mem); + return NULL; + } + + step_mem->steppers = steppers; + step_mem->coefficients = NULL; + step_mem->policy = NULL; // TODO: when to initialize? + step_mem->n_stepper_evolves = 0; + step_mem->partitions = partitions; + step_mem->order = 0; + step_mem->own_policy = SUNFALSE; + + /* Attach step_mem structure and function pointers to ark_mem */ + ark_mem->step_init = splittingStep_Init; + ark_mem->step_fullrhs = splittingStep_FullRHS; + ark_mem->step = splittingStep_TakeStep; + ark_mem->step_printallstats = splittingStep_PrintAllStats; + ark_mem->step_writeparameters = splittingStep_WriteParameters; + ark_mem->step_resize = splittingStep_Resize; + ark_mem->step_free = splittingStep_Free; + ark_mem->step_printmem = splittingStep_PrintMem; + ark_mem->step_setdefaults = splittingStep_SetDefaults; + ark_mem->step_setorder = splittingStep_SetOrder; + ark_mem->step_mem = (void*)step_mem; + ark_mem->interp_type = ARK_INTERP_LAGRANGE; + + /* Set default values for ARKStep optional inputs */ + int retval = splittingStep_SetDefaults(ark_mem); + if (retval != ARK_SUCCESS) + { + arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, + "Error setting default solver options"); + ARKodeFree((void**)&ark_mem); + return (NULL); + } + + // TODO update liw, lrw + + /* Initialize main ARKODE infrastructure */ + // TODO will this create interpolation then have it immediately replaced? + retval = arkInit(ark_mem, t0, y0, FIRST_INIT); + if (retval != ARK_SUCCESS) + { + arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, + "Unable to initialize main ARKODE infrastructure"); + ARKodeFree((void**)&ark_mem); + return (NULL); + } + + return ark_mem; +} + +int SplittingStep_SetCoefficients(void* arkode_mem, + ARKodeSplittingCoefficients coefficients) +{ + ARKodeMem ark_mem; + ARKodeSplittingStepMem step_mem; + int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + if (step_mem->partitions != coefficients->partitions) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "The splitting method has %i partitions but the coefficients have %i.", + step_mem->partitions, coefficients->partitions); + return ARK_ILL_INPUT; + } + + ARKodeSplittingCoefficients_Free(step_mem->coefficients); + step_mem->coefficients = ARKodeSplittingCoefficients_Copy(coefficients); + // TODO adjust workspace size + + return ARK_SUCCESS; +} + +int SplittingStep_SetExecutionPolicy(void* arkode_mem, + ARKodeSplittingExecutionPolicy policy) +{ + ARKodeMem ark_mem; + ARKodeSplittingStepMem step_mem; + int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + // TODO Error if policy is NULL? + + if (step_mem->own_policy) + { + ARKodeSplittingExecutionPolicyFree(&step_mem->policy); + } + step_mem->policy = policy; + + // TODO: adjust workspace size + + return ARK_SUCCESS; +} \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c new file mode 100644 index 0000000000..f21e2b30c9 --- /dev/null +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -0,0 +1,158 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include +#include + +static int setup_serial(ARKodeSplittingExecutionPolicy policy, N_Vector y, + const int sequential_methods) +{ + // Nothing needed + return ARK_SUCCESS; +} + +static int execute_serial(ARKodeSplittingExecutionPolicy policy, + ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, + N_Vector tmp, sunrealtype* alpha, + const int sequential_methods, void* user_data) +{ + N_VScale(1, yn, ycur); + fn(0, ycur, user_data); + + // For many methods alpha[0] == 1, so this is redundant. TODO: add check or + // hope compiler optimized this out + // N_VScale(alpha[0], ycur, ycur); + + // for (int i = 1; i < sequential_methods; i++) + // { + // N_VScale(1, yn, tmp); + // int retval = fn(i, tmp, user_data); + // if (retval != ARK_SUCCESS) + // // TODO: error handling of fn + // N_VLinearSum(1, ycur, alpha[i], tmp, yn); + // } + + return ARK_SUCCESS; +} + +static void free_serial(ARKodeSplittingExecutionPolicy policy) +{ + // Nothing needed +} + +ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() +{ + ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); + if (policy == NULL) { return NULL; } + policy->setup = setup_serial; + policy->execute = execute_serial; + policy->free = free_serial; + policy->data = NULL; + return policy; +} + +void ARKodeSplittingExecutionPolicyFree(ARKodeSplittingExecutionPolicy* policy) +{} + +// #include + +// ARKodeSplittingExecutionPolicy SplittingStepExecutionPolicy_MPI(SUNComm comm) { +// ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); +// policy->setup = setup_mpi; +// policy->exectute = execute_mpi; +// policy->free = free_mpi; +// SUNComm *data = malloc(sizeof(*data)); +// data[0] = comm; +// policy->data = data; +// } + +// static int mpi_reduce(void *in, void *inout, int *len, MPI_Datatype *datatype) { +// // Is there any way +// } + +// static int setup_mpi(ARKodeSplittingExecutionPolicy policy, N_Vector y, const int sequential_methods) { +// MPI_Op_create(mpi_reduce, SUNTRUE, ) +// } + +// static int execute_mpi(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// SUNComm comm = *((SUNComm*) policy->data); +// int rank; +// MPI_Comm_rank(comm, &rank); + +// N_VScale(1, yn, ycur); +// fn(rank, y, user_data); +// N_VScale(alpha[rank], ycur, ycur); + +// for (int i = 2 * rank; i < sequential_methods; rank++) { +// N_VScale(1, yn, tmp); +// fn(i, tmp, user_data); +// NN_VLinearSum(1, ycur, alpha[i], tmp); +// } + +// sunindextype bufferSize; +// N_VBufSize(ycur, &bufferSize); +// } + +// static void free_mpi(ARKodeSplittingExecutionPolicy policy) { +// MPI_op_free(); +// free(policy->data); +// } + +// int execute_openmp(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// #pragma omp parallel default(none) private(i) shared(fn, y, alpha, sequential_methods, user_data) +// { +// #pragma omp for schedule(static) num_threads(?) +// for (int i = 1; i < sequential_methods; i++) { +// // We assume that the "true" version of y_n is stored in y[0], then +// // distribute it to the other y[i]. It might be possible to remove this if +// // we can ensure the y[i] are always identical even after a reset, +// // reinit, etc. +// N_VScale(1, y[0], y[i]); +// } + +// #pragma omp for schedule(dynamic) num_threads(?) +// for (int i = 0; i < sequential_methods; i++) { +// fn(i, y[i], user_data); +// } +// } + +// // This could be done as a parallel reduction. The benefit appears minimal as +// // it would require at least 4 sequential methods to theoretically get a +// // speedup. +// N_VLinearCombination(sequential_methods, alpha, y, y[0]); +// } + +// int execute_mpi(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// MPI_Bcast() + +// MPI_Barrier(comm); + +// int rank; +// MPI_Comm_rank(comm, &rank); + +// for (int i = rank; i < sequential_methods; i+=rank) { +// fn(i, y[i], user_data); +// } + +// // This could be done as a parallel reduction. The benefit appears minimal as +// // it would require at least 4 sequential methods to theoretically get a +// // speedup. +// N_VLinearCombination(sequential_methods, alpha, y, y[0]); +// } diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h new file mode 100644 index 0000000000..0c8b5875c2 --- /dev/null +++ b/src/arkode/arkode_splittingstep_impl.h @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#ifndef ARKODE_SPLITTINGSTEP_IMPL_H_ +#define ARKODE_SPLITTINGSTEP_IMPL_H_ + +#include + +typedef struct ARKodeSplittingStepMemRec +{ + SUNStepper *steppers; + ARKodeSplittingCoefficients coefficients; + ARKodeSplittingExecutionPolicy policy; + long int n_stepper_evolves; + + int partitions; + int order; + sunbooleantype own_policy; +}* ARKodeSplittingStepMem; + +#endif diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c new file mode 100644 index 0000000000..e663951e19 --- /dev/null +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -0,0 +1,101 @@ +/* Things to test +Custom inner stepper with exact solution +Orders 1-4 +Resizing +Changing coefficients +~3 partitions +Check n_stepper_evolves +*/ + +/* +Examples +- Fractional Step RK +*/ + +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2023, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * TODO + * ---------------------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include +#include + +#define DT_1 (0.125) +#define DT_2 (0.03125) +#define T_END 1.0 +#define LAMBDA 2.0 + +static int f1(sunrealtype t, N_Vector y, N_Vector yp, void *data) { + printf("%e %e\n", t, NV_Ith_S(y, 0)); + N_VScale(-LAMBDA, y, yp); + return 0; +} + +static int f2(sunrealtype t, N_Vector y, N_Vector yp, void *data) { + printf(" %e %e\n", t, NV_Ith_S(y, 0)); + N_VProd(y, y, yp); + return 0; +} + +static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) { + return LAMBDA * y0 / (y0 - (y0 - LAMBDA) * exp(LAMBDA * t)); +} + +int main(int argc, char* argv[]) +{ + SUNContext sunctx; + SUNContext_Create(SUN_COMM_NULL, &sunctx); + + N_Vector y = N_VNew_Serial(1, sunctx); + N_VConst(1, y); + const sunrealtype sol = exact_sol(T_END, NV_Ith_S(y, 0)); + + void *arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); + ARKodeSetOrder(arkode_mem1, 1); + ARKodeSetFixedStep(arkode_mem1, DT_1); + + void *arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); + ARKodeSetOrder(arkode_mem2, 1); + ARKodeSetFixedStep(arkode_mem2, DT_2); + + SUNStepper steppers[2]; + ARKStepCreateMRIStepInnerStepper(arkode_mem1, &steppers[0]); + ARKStepCreateMRIStepInnerStepper(arkode_mem2, &steppers[1]); + + void *split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); + ARKodeSplittingCoefficients coeffs = ARKodeSplittingCoefficients_LieTrotter(2); + SplittingStep_SetCoefficients(split_mem, coeffs); + ARKodeSplittingCoefficients_Free(coeffs); + ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error is this is not called + sunrealtype tret; + ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); + printf("%e %e\n", T_END, NV_Ith_S(y, 0)); + + N_VPrint(y); // TODO: why is valgrind showing errors for these prints? + printf("Error: %e\n", sol - NV_Ith_S(y, 0)); + + ARKodeFree(&split_mem); + N_VDestroy(y); + MRIStepInnerStepper_Free(&steppers[0]); + MRIStepInnerStepper_Free(&steppers[1]); + ARKodeFree(&arkode_mem1); + ARKodeFree(&arkode_mem2); + SUNContext_Free(&sunctx); +} From 960351523dbf73a03a3da6356835c6e9d91ddde6 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 15 Aug 2024 20:58:41 -0700 Subject: [PATCH 002/180] Bug fixes for coefficients --- include/arkode/arkode_splittingstep.h | 9 +- src/arkode/arkode_splitting_coefficients.c | 149 +++++++++--------- src/arkode/arkode_splittingstep.c | 66 ++++---- .../arkode_splittingstep_executionpolicy.c | 9 +- .../unit_tests/arkode/C_serial/CMakeLists.txt | 1 + .../arkode/C_serial/ark_test_splittingstep.c | 7 +- 6 files changed, 123 insertions(+), 118 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 5a4b98ca80..57f90cf756 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -58,8 +58,6 @@ typedef MRIStepInnerStepper SUNStepper; SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( int sequential_methods, int stages, int partitions, int order); SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients B); -SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Space( - ARKodeSplittingCoefficients B, sunindextype* liw, sunindextype* lrw); SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy(ARKodeSplittingCoefficients B); @@ -74,6 +72,8 @@ SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel(int partitions); SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump(int partitions, int order); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_SuzukiFractal(int partitions, int order); /* Other coefficient functions */ SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Write( @@ -94,7 +94,7 @@ struct ARKodeSplittingExecutionPolicyMem int (*execute)(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, - const int sequential_methods, void* user_data); + int sequential_methods, void* user_data); void (*free)(ARKodeSplittingExecutionPolicy policy); @@ -104,7 +104,8 @@ struct ARKodeSplittingExecutionPolicyMem SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial(); -SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicyFree( +// TODO: Return error code? +SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( ARKodeSplittingExecutionPolicy* policy); /* ARKODE functions */ diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index fe46d2e47d..0c8b1d0213 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -48,6 +48,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( i index requires allocating an array of pointers into that matrix. */ /* Array of pointers for index i */ + coefficients->beta = (sunrealtype***)malloc(sequential_methods * sizeof(*coefficients->beta)); if (coefficients->beta == NULL) @@ -57,8 +58,8 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( } /* Matrix of pointers for index j */ - sunrealtype** beta_cols = - (sunrealtype**)malloc(sequential_methods * (stages + 1) * sizeof(*beta_cols)); + sunrealtype** beta_cols = (sunrealtype**)malloc( + sequential_methods * (stages + 1) * sizeof(*beta_cols)); if (beta_cols == NULL) { ARKodeSplittingCoefficients_Free(coefficients); @@ -75,9 +76,10 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( return NULL; } + /* Set pointers into the beta tensor */ for (int i = 0; i < sequential_methods; i++) { - coefficients->beta[i] = &beta_cols[i]; + coefficients->beta[i] = &beta_cols[i * (stages + 1)]; for (int j = 0; j <= stages; j++) { coefficients->beta[i][j] = &beta_mem[(i * (stages + 1) + j) * partitions]; @@ -87,9 +89,9 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( return coefficients; } -// TODO: should argument be a pointer? -void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients coefficients) +void ARKodeSplittingCoefficients_Free(const ARKodeSplittingCoefficients coefficients) { + // TODO: should argument be a pointer? if (coefficients != NULL) { free(coefficients->alpha); @@ -104,37 +106,6 @@ void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients coefficients) free(coefficients); } -void ARKodeSplittingCoefficients_Space(ARKodeSplittingCoefficients coefficients, - sunindextype* liw, sunindextype* lrw) -{ - /* initialize outputs and return if coefficients is not allocated */ - *liw = 0; - *lrw = 0; - if (coefficients == NULL) { return; } - - /* ints for # of sequential methods, stages, partitions, and order */ - *liw = 4; - - if (coefficients->beta) - { - /* pointers for index i of beta[i][j][k] */ - *liw += coefficients->sequential_methods; - } - - if (coefficients->beta[0]) - { - /* pointers for index j of beta[i][j][k] */ - *liw += coefficients->sequential_methods * (coefficients->stages + 1); - } - - if (coefficients->alpha) { *lrw += coefficients->sequential_methods; } - if (coefficients->beta[0][0]) - { - *lrw += coefficients->sequential_methods * (coefficients->stages + 1) * - coefficients->partitions; - } -} - ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( ARKodeSplittingCoefficients coefficients) { @@ -160,7 +131,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( } ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( - ARKODE_SplittingCoefficientsID method) + const ARKODE_SplittingCoefficientsID method) { switch (method) { @@ -177,7 +148,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( } ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( - const char* method) + const char* const method) { #define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ if (strcmp(#name, method) == 0) coeff @@ -221,10 +192,8 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int parti for (int i = 0; i < partitions; i++) { - coefficients->alpha[i] = SUN_RCONST(1.0); - for (int j = i; j < partitions; j++) { - coefficients->beta[i][1][j] = SUN_RCONST(1.0); - } + coefficients->alpha[i] = SUN_RCONST(1.0); + coefficients->beta[i][1][i] = SUN_RCONST(1.0); } coefficients->alpha[partitions] = 1 - partitions; @@ -246,49 +215,59 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( for (int i = 0; i < partitions; i++) { - coefficients->beta[0][1][i] = SUN_RCONST(1.0); - coefficients->beta[1][i + 1][partitions - i - 1] = SUN_RCONST(1.0); + coefficients->beta[0][partitions][i] = SUN_RCONST(1.0); + for (int j = partitions - i - 1; j < partitions; j++) { + coefficients->beta[1][i + 1][j] = SUN_RCONST(1.0); + } } return coefficients; } -static sunrealtype** arkodeSplittingCoefficients_TripleJump( - const int partitions, const int order, sunrealtype** beta, - const sunrealtype parent_length) +static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( + const int partitions, const int order, const int composition_stages, + const sunrealtype start, const sunrealtype end, sunrealtype* const* const beta) { - // The base case is an order 2 Strang splitting + const sunrealtype diff = end - start; if (order == 2) { - for (int i = 0; i < partitions; i++) + /* The base case is an order 2 Strang splitting */ + const sunrealtype mid = start + diff / SUN_RCONST(2.0); + for (int j = 1; j <= partitions; j++) { - // Use += here because the first integration may combine with the last - // integration of the previous stage - beta[1][i] += SUN_RCONST(0.5) * parent_length; - beta[i][partitions - i - 1] += SUN_RCONST(0.5) * parent_length; + for (int k = 0; k < partitions; k++) + { + beta[j][k] = (partitions - j > k) ? mid : end; + } } - // Advance the beta pointer to the last stage of this Strang splitting return &beta[partitions - 1]; } - // Length of jump 1 and 3 - sunrealtype z1 = SUN_RCONST(1.0) / - (SUN_RCONST(2.0) - - SUNRpowerR(SUN_RCONST(2.0), SUN_RCONST(1.0) / (order - 1))); - // Length of jump 2 - sunrealtype z0 = SUN_RCONST(1.0) - SUN_RCONST(2.0) * z1; - - // Perform the triple jump - beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z1); - beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z0); - beta = arkodeSplittingCoefficients_TripleJump(partitions, order - 2, beta, z1); + sunrealtype* const* beta_cur = beta; + sunrealtype start_cur = start; + /* This is essentially the gamma coefficient from Geometric Numerical + * Integration (https://doi.org/10.1007/3-540-30666-8) pg 44-45 scaled by the + * current interval */ + const sunrealtype gamma = diff / (composition_stages - 1 - SUNRpowerR(composition_stages - 1, SUN_RCONST(1.0) / (order - 1))); + for (int i = 1; i <= composition_stages; i++) + { + /* To avoid roundoff issues, this ensures end_cur=1 for the last value of i*/ + const sunrealtype end_cur = 2 * i < composition_stages ? (start + i * gamma) : (end + (i - composition_stages) * gamma); + /* Recursively generate coefficients and shift beta_cur */ + beta_cur = + arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order - 2, + composition_stages, + start_cur, end_cur, + beta_cur); + start_cur = end_cur; + } - return beta; + return beta_cur; } -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump( - const int partitions, const int order) +static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( + const int partitions, const int order, const int composition_stages) { if (partitions < 1 || order < 2 || order % 2 != 0) { @@ -296,24 +275,40 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump( return NULL; } - const int stages = 1 + (partitions - 1) * SUNRpowerI(3, order / 2 - 1); + const int stages = 1 + (partitions - 1) * + SUNRpowerI(composition_stages, order / 2 - 1); const ARKodeSplittingCoefficients coefficients = ARKodeSplittingCoefficients_Alloc(1, stages, partitions, order); if (coefficients == NULL) { return NULL; } - coefficients->alpha[0] = SUN_RCONST(1.0); - arkodeSplittingCoefficients_TripleJump(partitions, order, - coefficients->beta[0], SUN_RCONST(1.0)); + arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order, + composition_stages, + SUN_RCONST(0.0), + SUN_RCONST(1.0), + coefficients->beta[0]); return coefficients; } +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump( + const int partitions, const int order) +{ + return arkodeSplittingCoefficients_ComposeStrang(partitions, order, 3); +} + +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SuzukiFractal( + const int partitions, const int order) +{ + return arkodeSplittingCoefficients_ComposeStrang(partitions, order, 5); +} + /*--------------------------------------------------------------- - Routine to print a Butcher table structure + Routine to print a splitting coefficients structure ---------------------------------------------------------------*/ void ARKodeSplittingCoefficients_Write(ARKodeSplittingCoefficients coefficients, FILE* outfile) { + // TODO: update when https://github.com/LLNL/sundials/pull/517 merged if (coefficients == NULL || coefficients->alpha == NULL || coefficients->beta == NULL || coefficients->beta[0] == NULL || coefficients->beta[0][0] == NULL) @@ -326,22 +321,22 @@ void ARKodeSplittingCoefficients_Write(ARKodeSplittingCoefficients coefficients, fprintf(outfile, " stages = %i\n", coefficients->stages); fprintf(outfile, " partitions = %i\n", coefficients->partitions); fprintf(outfile, " order = %i\n", coefficients->order); - fprintf(outfile, " alpha = \n"); + fprintf(outfile, " alpha = "); for (int i = 0; i < coefficients->sequential_methods; i++) { fprintf(outfile, "%" RSYM " ", coefficients->alpha[i]); } - // TODO: fix formatting + fprintf(outfile, "\n"); for (int i = 0; i < coefficients->sequential_methods; i++) { fprintf(outfile, " beta[%i] = \n", i); - for (int j = 0; j < coefficients->stages; j++) + for (int j = 0; j <= coefficients->stages; j++) { fprintf(outfile, " "); for (int k = 0; k < coefficients->partitions; k++) { - fprintf(outfile, "%" RSYMW " ", coefficients->beta[i][j][k]); + fprintf(outfile, "%" RSYM " ", coefficients->beta[i][j][k]); } fprintf(outfile, "\n"); } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index c498d36d11..a17355f54c 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -24,13 +24,9 @@ #define DEFAULT_ORDER 2 -// TODO: check the 2nd argument of arkProcessError is correct -// TODO: workspace size - static int splittingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, ARKodeSplittingStepMem* step_mem) { - /* access ARKodeSPRKStepMem structure */ if (ark_mem->step_mem == NULL) { arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, fname, __FILE__, @@ -116,6 +112,7 @@ static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } + // TODO: uncomment once inner stepper finalized // retval = innerStepper_FullRhs(step_mem->steppers[0], t, y, f, // ARK_FULLRHS_OTHER); if (retval != 0) @@ -143,8 +140,7 @@ static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, static int splittingStep_Stage(const int i, const N_Vector y, void* user_data) { - // Note: this should not write to user_data to avoid race conditions when executed in parallel - + // Note: this should not write to ark_mem and step_mem to avoid race conditions when executed in parallel ARKodeMem ark_mem = (ARKodeMem)user_data; ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -197,9 +193,10 @@ static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, coefficients->sequential_methods, ark_mem); } -int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, +static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, SUNOutputFormat fmt) { + // TODO: update when https://github.com/LLNL/sundials/pull/517 merged ARKodeSplittingStepMem step_mem; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -221,7 +218,7 @@ int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, return ARK_SUCCESS; } -int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) +static int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) { ARKodeSplittingStepMem step_mem; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -237,7 +234,7 @@ static int splittingStep_Resize(ARKodeMem ark_mem, N_Vector ynew, sunrealtype hscale, sunrealtype t0, ARKVecResizeFn resize, void* resize_data) { - // TODO: update lrw, liw? + // TODO: explain why resizing needs to be done on the inner methods return ARK_SUCCESS; } @@ -246,10 +243,9 @@ static void splittingStep_Free(ARKodeMem ark_mem) ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; if (step_mem == NULL) { return; } - // TODO keep track of workspace size if (step_mem->own_policy) { - ARKodeSplittingExecutionPolicyFree(&step_mem->policy); + ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); } ARKodeSplittingCoefficients_Free(step_mem->coefficients); @@ -257,7 +253,7 @@ static void splittingStep_Free(ARKodeMem ark_mem) ark_mem->step_mem = NULL; } -void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) +static void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) { ARKodeSplittingStepMem step_mem; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -278,22 +274,10 @@ void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) //TODO: consider printing policy } -int splittingStep_SetDefaults(ARKodeMem ark_mem) -{ - ARKodeSplittingStepMem step_mem; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } - - step_mem->order = DEFAULT_ORDER; - step_mem->coefficients = NULL; - step_mem->policy = NULL; - return ARK_SUCCESS; -} - static int splittingStep_SetOrder(ARKodeMem ark_mem, const int order) { ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } /* set user-provided value, or default, depending on argument */ @@ -309,6 +293,23 @@ static int splittingStep_SetOrder(ARKodeMem ark_mem, const int order) return ARK_SUCCESS; } +static int splittingStep_SetDefaults(ARKodeMem ark_mem) +{ + ARKodeSplittingStepMem step_mem; + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + retval = splittingStep_SetOrder(ark_mem, 0); + if (retval != ARK_SUCCESS) { return retval; } + + retval = SplittingStep_SetExecutionPolicy(ark_mem, NULL); + if (retval != ARK_SUCCESS) { return retval; } + + ark_mem->interp_type = ARK_INTERP_LAGRANGE; + + return ARK_SUCCESS; +} + void* SplittingStepCreate(SUNStepper* steppers, const int partitions, const sunrealtype t0, N_Vector y0, SUNContext sunctx) { @@ -372,7 +373,7 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, step_mem->steppers = steppers; step_mem->coefficients = NULL; - step_mem->policy = NULL; // TODO: when to initialize? + step_mem->policy = NULL; step_mem->n_stepper_evolves = 0; step_mem->partitions = partitions; step_mem->order = 0; @@ -390,7 +391,6 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, ark_mem->step_setdefaults = splittingStep_SetDefaults; ark_mem->step_setorder = splittingStep_SetOrder; ark_mem->step_mem = (void*)step_mem; - ark_mem->interp_type = ARK_INTERP_LAGRANGE; /* Set default values for ARKStep optional inputs */ int retval = splittingStep_SetDefaults(ark_mem); @@ -423,7 +423,7 @@ int SplittingStep_SetCoefficients(void* arkode_mem, { ARKodeMem ark_mem; ARKodeSplittingStepMem step_mem; - int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + const int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -437,7 +437,11 @@ int SplittingStep_SetCoefficients(void* arkode_mem, ARKodeSplittingCoefficients_Free(step_mem->coefficients); step_mem->coefficients = ARKodeSplittingCoefficients_Copy(coefficients); - // TODO adjust workspace size + if (step_mem->coefficients == NULL) { + arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_ARK_NO_MEM); // TODO: not relevant message but consistent with ARKStep and ERKStep + return (ARK_MEM_NULL); + } return ARK_SUCCESS; } @@ -455,11 +459,9 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, if (step_mem->own_policy) { - ARKodeSplittingExecutionPolicyFree(&step_mem->policy); + ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); } step_mem->policy = policy; - // TODO: adjust workspace size - return ARK_SUCCESS; } \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c index f21e2b30c9..42d3418f78 100644 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -65,8 +65,13 @@ ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() return policy; } -void ARKodeSplittingExecutionPolicyFree(ARKodeSplittingExecutionPolicy* policy) -{} +void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) +{ + // TODO: should argument be a pointer? + if (policy != NULL) { + free(*policy); + } +} // #include diff --git a/test/unit_tests/arkode/C_serial/CMakeLists.txt b/test/unit_tests/arkode/C_serial/CMakeLists.txt index 6794a213b4..5c83d00c54 100644 --- a/test/unit_tests/arkode/C_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/C_serial/CMakeLists.txt @@ -32,6 +32,7 @@ set(ARKODE_unit_tests "ark_test_interp\;-1000000" "ark_test_mass\;" "ark_test_reset\;" + "ark_test_splittingstep\;" "ark_test_tstop\;") # Add the build and install targets for each test diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index e663951e19..b231acfd8b 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -80,15 +80,16 @@ int main(int argc, char* argv[]) ARKStepCreateMRIStepInnerStepper(arkode_mem2, &steppers[1]); void *split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); - ARKodeSplittingCoefficients coeffs = ARKodeSplittingCoefficients_LieTrotter(2); + ARKodeSplittingCoefficients coeffs = ARKodeSplittingCoefficients_SuzukiFractal(3, 6); + ARKodeSplittingCoefficients_Write(coeffs, stdout); SplittingStep_SetCoefficients(split_mem, coeffs); ARKodeSplittingCoefficients_Free(coeffs); - ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error is this is not called + ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error if this is not called sunrealtype tret; ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); printf("%e %e\n", T_END, NV_Ith_S(y, 0)); - N_VPrint(y); // TODO: why is valgrind showing errors for these prints? + N_VPrint(y); printf("Error: %e\n", sol - NV_Ith_S(y, 0)); ARKodeFree(&split_mem); From 4e39e52c42bafca4e794d2b59fc062a5b478324e Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 19 Aug 2024 19:10:38 -0700 Subject: [PATCH 003/180] Finish splitting coefficient tests --- include/arkode/arkode_splittingstep.h | 83 +---------- src/arkode/arkode_splitting_coefficients.c | 137 +++++++++++++++--- src/arkode/arkode_splitting_coefficients.def | 24 ++- src/arkode/arkode_splittingstep.c | 66 +++++---- .../arkode_splittingstep_executionpolicy.c | 109 ++------------ src/arkode/arkode_splittingstep_impl.h | 2 +- .../unit_tests/arkode/C_serial/CMakeLists.txt | 1 + .../arkode/C_serial/ark_test_splittingstep.c | 38 +++-- 8 files changed, 203 insertions(+), 257 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 57f90cf756..ef878b31fd 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -17,8 +17,8 @@ #ifndef ARKODE_SPLITTINGSTEP_H_ #define ARKODE_SPLITTINGSTEP_H_ -#include -#include +#include +#include #include #include @@ -26,88 +26,9 @@ extern "C" { #endif -/*--------------------------------------------------------------- - Types : struct ARKodeSplittingCoefficientsMem, ARKodeSplittingCoefficients - ---------------------------------------------------------------*/ -struct ARKodeSplittingCoefficientsMem -{ - sunrealtype* alpha; /* weights for sum over sequential splitting methods */ - sunrealtype*** beta; /* length of each flow, indexed by the sequential method, stage, and partition */ - int sequential_methods; /* number of sequential splitting methods */ - int stages; /* number of stages within each sequential splitting method */ - int partitions; /* number of RHS partitions */ - int order; /* order of convergence */ -}; - -typedef _SUNDIALS_STRUCT_ ARKodeSplittingCoefficientsMem* ARKodeSplittingCoefficients; - -typedef enum -{ - ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ - ARKODE_MIN_SPLITTING_NUM = 300, - ARKODE_SPLITTING_LIE_TROTTER = ARKODE_MIN_SPLITTING_NUM, - ARKODE_SPLITTING_STRANG, - ARKODE_SPLITTING_YOSHIDA, - ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA -} ARKODE_SplittingCoefficientsID; - /* TODO: remove once SUNStepper is ready */ typedef MRIStepInnerStepper SUNStepper; -/* Coefficient memory management */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( - int sequential_methods, int stages, int partitions, int order); -SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients B); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Copy(ARKodeSplittingCoefficients B); - -/* Constructors for splitting coefficients */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_LieTrotter(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Strang(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Parallel(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_SymmetricParallel(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_TripleJump(int partitions, int order); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_SuzukiFractal(int partitions, int order); - -/* Other coefficient functions */ -SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Write( - ARKodeSplittingCoefficients B, FILE* outfile); -SUNDIALS_EXPORT sunbooleantype -ARKodeSplittingCoefficients_(ARKodeSplittingCoefficients B); - -/* Parallelization Policy */ -typedef int (*ARKParallelExecuteFn)(int i, N_Vector y, void* user_data); - -typedef _SUNDIALS_STRUCT_ ARKodeSplittingExecutionPolicyMem* ARKodeSplittingExecutionPolicy; - -struct ARKodeSplittingExecutionPolicyMem -{ - // TODO: make ops struct for these functions? - int (*setup)(ARKodeSplittingExecutionPolicy policy, N_Vector y, - int sequential_methods); - - int (*execute)(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, - N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, - int sequential_methods, void* user_data); - - void (*free)(ARKodeSplittingExecutionPolicy policy); - - void* data; -}; - -SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy -ARKodeSplittingExecutionPolicy_Serial(); - -// TODO: Return error code? -SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( - ARKodeSplittingExecutionPolicy* policy); - /* ARKODE functions */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index 0c8b1d0213..d5baac954d 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -11,18 +11,20 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This is the implementation file for splitting coefficients *--------------------------------------------------------------*/ -#include -#include +#include #include #include "arkode_impl.h" +/*--------------------------------------------------------------- + Routine to allocate splitting coefficients with zero values for + alpha and beta + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( - const int sequential_methods, const int stages, const int partitions, - const int order) + const int sequential_methods, const int stages, const int partitions) { if (sequential_methods < 1 || stages < 1 || partitions < 1) { return NULL; } @@ -33,7 +35,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( coefficients->sequential_methods = sequential_methods; coefficients->stages = stages; coefficients->partitions = partitions; - coefficients->order = order; + coefficients->order = 0; coefficients->alpha = (sunrealtype*)calloc(sequential_methods, sizeof(*coefficients->alpha)); @@ -89,6 +91,31 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( return coefficients; } +/*--------------------------------------------------------------- + Routine to create splitting coefficients which performs a copy + of the alpha and beta parameters + ---------------------------------------------------------------*/ +ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Create( + const int sequential_methods, const int stages, const int partitions, + const int order, sunrealtype* const alpha, sunrealtype* const beta) +{ + if (alpha == NULL || beta == NULL) { return NULL; } + + ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Alloc(sequential_methods, stages, partitions); + if (coefficients == NULL) { return NULL; } + + coefficients->order = order; + memcpy(coefficients->alpha, alpha, sequential_methods * sizeof(*alpha)); + memcpy(coefficients->beta[0][0], beta, + sequential_methods * (stages + 1) * partitions * sizeof(*beta)); + + return coefficients; +} + +/*--------------------------------------------------------------- + Routine to free splitting coefficients + ---------------------------------------------------------------*/ void ARKodeSplittingCoefficients_Free(const ARKodeSplittingCoefficients coefficients) { // TODO: should argument be a pointer? @@ -106,6 +133,9 @@ void ARKodeSplittingCoefficients_Free(const ARKodeSplittingCoefficients coeffici free(coefficients); } +/*--------------------------------------------------------------- + Routine to create a copy of splitting coefficients + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( ARKodeSplittingCoefficients coefficients) { @@ -114,10 +144,10 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( ARKodeSplittingCoefficients coefficientsCopy = ARKodeSplittingCoefficients_Alloc(coefficients->sequential_methods, coefficients->stages, - coefficients->partitions, - coefficients->order); + coefficients->partitions); if (coefficientsCopy == NULL) { return NULL; } + coefficientsCopy->order = coefficients->order; memcpy(coefficientsCopy->alpha, coefficients->alpha, coefficients->sequential_methods * sizeof(*coefficients->alpha)); @@ -130,6 +160,9 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( return coefficientsCopy; } +/*--------------------------------------------------------------- + Routine to load coefficients from an ID + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( const ARKODE_SplittingCoefficientsID method) { @@ -147,6 +180,10 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( } } +/*--------------------------------------------------------------- + Routine to load coefficients using a string representation of + an enum entry in ARKODE_SplittingCoefficientsID + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( const char* const method) { @@ -161,13 +198,39 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( return NULL; } +/*--------------------------------------------------------------- + Routine to convert a coefficient enum value to its string + representation + ---------------------------------------------------------------*/ +const char* ARKodeSplittingCoefficients_IDToName( + const ARKODE_SplittingCoefficientsID id) +{ + /* Use X-macro to test each coefficient name */ + switch (id) + { +#define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ + case name: return #name; +#include "arkode_splitting_coefficients.def" +#undef ARK_SPLITTING_COEFFICIENTS + + default: + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Unknown splitting coefficients"); + return NULL; + } +} + +/*--------------------------------------------------------------- + Routine to construct the standard Lie-Trotter splitting + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LieTrotter(const int partitions) { if (partitions < 1) { return NULL; } const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(1, 1, partitions, 1); + ARKodeSplittingCoefficients_Alloc(1, 1, partitions); if (coefficients == NULL) { return NULL; } + coefficients->order = 1; coefficients->alpha[0] = SUN_RCONST(1.0); for (int i = 0; i < partitions; i++) { @@ -177,22 +240,31 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LieTrotter(const int par return coefficients; } +/*--------------------------------------------------------------- + Routine to construct the standard Stang splitting + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Strang(const int partitions) { return ARKodeSplittingCoefficients_TripleJump(partitions, 2); } +/*--------------------------------------------------------------- + Routine to construct a parallel splitting method + Phi_1(h) + Phi_2(h) + ... + Phi_p(h) - (p - 1) * y_n + where Phi_i is the flow of partition i and p = partitions. + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int partitions) { if (partitions < 1) { return NULL; } const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(partitions + 1, 1, partitions, 1); + ARKodeSplittingCoefficients_Alloc(partitions + 1, 1, partitions); if (coefficients == NULL) { return NULL; } + coefficients->order = 1; for (int i = 0; i < partitions; i++) { - coefficients->alpha[i] = SUN_RCONST(1.0); + coefficients->alpha[i] = SUN_RCONST(1.0); coefficients->beta[i][1][i] = SUN_RCONST(1.0); } @@ -201,22 +273,28 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int parti return coefficients; } +/*--------------------------------------------------------------- + Routine to construct a symmetric parallel splitting which is + the average of the Lie-Trotter method and its adjoint + ---------------------------------------------------------------*/ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( const int partitions) { if (partitions < 1) { return NULL; } const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(2, partitions, partitions, 2); + ARKodeSplittingCoefficients_Alloc(2, partitions, partitions); if (coefficients == NULL) { return NULL; } + coefficients->order = 2; coefficients->alpha[0] = SUN_RCONST(0.5); coefficients->alpha[1] = SUN_RCONST(0.5); for (int i = 0; i < partitions; i++) { coefficients->beta[0][partitions][i] = SUN_RCONST(1.0); - for (int j = partitions - i - 1; j < partitions; j++) { + for (int j = partitions - i - 1; j < partitions; j++) + { coefficients->beta[1][i + 1][j] = SUN_RCONST(1.0); } } @@ -224,6 +302,13 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( return coefficients; } +/*--------------------------------------------------------------- + Routine to construct a composition method of the form + S(gamma_0 h)^c * S(gamma_1 h) * S(gamma_0)^c + where S is a lower order splitting (with Stang as the base case), + * and ^ denote composition, and c = composition_stages. This + covers both the triple jump (c=1) and Suzuki fractal (c=2). + ---------------------------------------------------------------*/ static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( const int partitions, const int order, const int composition_stages, const sunrealtype start, const sunrealtype end, sunrealtype* const* const beta) @@ -245,15 +330,19 @@ static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( } sunrealtype* const* beta_cur = beta; - sunrealtype start_cur = start; + sunrealtype start_cur = start; /* This is essentially the gamma coefficient from Geometric Numerical * Integration (https://doi.org/10.1007/3-540-30666-8) pg 44-45 scaled by the * current interval */ - const sunrealtype gamma = diff / (composition_stages - 1 - SUNRpowerR(composition_stages - 1, SUN_RCONST(1.0) / (order - 1))); + const sunrealtype gamma = + diff / (composition_stages - 1 - + SUNRpowerR(composition_stages - 1, SUN_RCONST(1.0) / (order - 1))); for (int i = 1; i <= composition_stages; i++) { /* To avoid roundoff issues, this ensures end_cur=1 for the last value of i*/ - const sunrealtype end_cur = 2 * i < composition_stages ? (start + i * gamma) : (end + (i - composition_stages) * gamma); + const sunrealtype end_cur = 2 * i < composition_stages + ? (start + i * gamma) + : (end + (i - composition_stages) * gamma); /* Recursively generate coefficients and shift beta_cur */ beta_cur = arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order - 2, @@ -266,6 +355,11 @@ static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( return beta_cur; } +/*--------------------------------------------------------------- + Routine which does validation and setup before calling + arkodeSplittingCoefficients_ComposeStrangHelper to fill in the + beta coefficients + ---------------------------------------------------------------*/ static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( const int partitions, const int order, const int composition_stages) { @@ -278,9 +372,12 @@ static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( const int stages = 1 + (partitions - 1) * SUNRpowerI(composition_stages, order / 2 - 1); const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(1, stages, partitions, order); + ARKodeSplittingCoefficients_Alloc(1, stages, partitions); if (coefficients == NULL) { return NULL; } + coefficients->order = order; + coefficients->alpha[0] = SUN_RCONST(1.0); + arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order, composition_stages, SUN_RCONST(0.0), @@ -303,10 +400,10 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SuzukiFractal( } /*--------------------------------------------------------------- - Routine to print a splitting coefficients structure + Routine to print a splitting coefficient structure ---------------------------------------------------------------*/ -void ARKodeSplittingCoefficients_Write(ARKodeSplittingCoefficients coefficients, - FILE* outfile) +void ARKodeSplittingCoefficients_Write( + const ARKodeSplittingCoefficients coefficients, FILE* const outfile) { // TODO: update when https://github.com/LLNL/sundials/pull/517 merged if (coefficients == NULL || coefficients->alpha == NULL || diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index 8f4cd326d2..d9f142160b 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -16,23 +16,21 @@ /* When adding a new method, enter the coefficients below and add - a new enum entry to include/arkode/arkode_splitting_coeffs.h - - Method names and properties are listed in the table - below. The 'QP' column denotes whether the coefficients of the - method are known precisely enough for use in quad precision - (128-bit) calculations. - - imeth QP - -------------------------------------- - - -------------------------------------- + a new enum entry to include/arkode/arkode_splitting_coefficients.h */ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { return NULL; }) -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER, { - return NULL; +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_2_1, { + return ARKodeSplittingCoefficients_LieTrotter(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2, { + return ARKodeSplittingCoefficients_Strang(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_2_4, { + return ARKodeSplittingCoefficients_TripleJump(2, 4); }) \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index a17355f54c..67710ee5c1 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -16,6 +16,7 @@ #include #include +#include #include #include "arkode_impl.h" @@ -24,8 +25,9 @@ #define DEFAULT_ORDER 2 -static int splittingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, - ARKodeSplittingStepMem* step_mem) +static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, + const char* const fname, + ARKodeSplittingStepMem* const step_mem) { if (ark_mem->step_mem == NULL) { @@ -37,9 +39,10 @@ static int splittingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, return ARK_SUCCESS; } -static int splittingStep_AccessARKODEStepMem(void* arkode_mem, const char* fname, - ARKodeMem* ark_mem, - ARKodeSplittingStepMem* step_mem) +static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, + const char* const fname, + ARKodeMem* const ark_mem, + ARKodeSplittingStepMem* const step_mem) { /* access ARKodeMem structure */ if (arkode_mem == NULL) @@ -60,7 +63,7 @@ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; } -static int splittingStep_Init(ARKodeMem ark_mem, const int init_type) +static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -106,7 +109,7 @@ static int splittingStep_Init(ARKodeMem ark_mem, const int init_type) static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, const N_Vector y, const N_Vector f, - const int mode) + SUNDIALS_MAYBE_UNUSED const int mode) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -154,8 +157,8 @@ static int splittingStep_Stage(const int i, const N_Vector y, void* user_data) { const sunrealtype tcur = ark_mem->tn + coefficients->beta[i][j][k] * ark_mem->h; - const sunrealtype tnext = ark_mem->tn + coefficients->beta[i][j + 1][k] * - ark_mem->h; + const sunrealtype tnext = ark_mem->tn + + coefficients->beta[i][j + 1][k] * ark_mem->h; if (tcur != tnext) { SUNStepper stepper = step_mem->steppers[k]; @@ -188,16 +191,16 @@ static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, ARKodeSplittingCoefficients coefficients = step_mem->coefficients; return step_mem->policy->execute(step_mem->policy, splittingStep_Stage, - ark_mem->yn, ark_mem->ycur, - ark_mem->tempv1, coefficients->alpha, - coefficients->sequential_methods, ark_mem); + ark_mem->yn, ark_mem->ycur, ark_mem->tempv1, + coefficients->alpha, + coefficients->sequential_methods, ark_mem); } static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, - SUNOutputFormat fmt) + SUNOutputFormat fmt) { // TODO: update when https://github.com/LLNL/sundials/pull/517 merged - ARKodeSplittingStepMem step_mem; + ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -220,7 +223,7 @@ static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, static int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) { - ARKodeSplittingStepMem step_mem; + ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -230,9 +233,12 @@ static int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) return ARK_SUCCESS; } -static int splittingStep_Resize(ARKodeMem ark_mem, N_Vector ynew, - sunrealtype hscale, sunrealtype t0, - ARKVecResizeFn resize, void* resize_data) +static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, + SUNDIALS_MAYBE_UNUSED const N_Vector ynew, + SUNDIALS_MAYBE_UNUSED const sunrealtype hscale, + SUNDIALS_MAYBE_UNUSED const sunrealtype t0, + SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, + SUNDIALS_MAYBE_UNUSED void* const resize_data) { // TODO: explain why resizing needs to be done on the inner methods return ARK_SUCCESS; @@ -255,7 +261,7 @@ static void splittingStep_Free(ARKodeMem ark_mem) static void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) { - ARKodeSplittingStepMem step_mem; + ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return; } @@ -295,7 +301,7 @@ static int splittingStep_SetOrder(ARKodeMem ark_mem, const int order) static int splittingStep_SetDefaults(ARKodeMem ark_mem) { - ARKodeSplittingStepMem step_mem; + ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -306,7 +312,7 @@ static int splittingStep_SetDefaults(ARKodeMem ark_mem) if (retval != ARK_SUCCESS) { return retval; } ark_mem->interp_type = ARK_INTERP_LAGRANGE; - + return ARK_SUCCESS; } @@ -421,10 +427,10 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, int SplittingStep_SetCoefficients(void* arkode_mem, ARKodeSplittingCoefficients coefficients) { - ARKodeMem ark_mem; - ARKodeSplittingStepMem step_mem; - const int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, - &step_mem); + ARKodeMem ark_mem = NULL; + ARKodeSplittingStepMem step_mem = NULL; + const int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, + &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } if (step_mem->partitions != coefficients->partitions) @@ -437,7 +443,8 @@ int SplittingStep_SetCoefficients(void* arkode_mem, ARKodeSplittingCoefficients_Free(step_mem->coefficients); step_mem->coefficients = ARKodeSplittingCoefficients_Copy(coefficients); - if (step_mem->coefficients == NULL) { + if (step_mem->coefficients == NULL) + { arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, __func__, __FILE__, MSG_ARK_NO_MEM); // TODO: not relevant message but consistent with ARKStep and ERKStep return (ARK_MEM_NULL); @@ -449,8 +456,8 @@ int SplittingStep_SetCoefficients(void* arkode_mem, int SplittingStep_SetExecutionPolicy(void* arkode_mem, ARKodeSplittingExecutionPolicy policy) { - ARKodeMem ark_mem; - ARKodeSplittingStepMem step_mem; + ARKodeMem ark_mem = NULL; + ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -461,7 +468,8 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, { ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); } - step_mem->policy = policy; + step_mem->policy = policy; + step_mem->own_policy = SUNFALSE; return ARK_SUCCESS; } \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c index 42d3418f78..f2783f7ea8 100644 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -18,15 +18,18 @@ #include #include -static int setup_serial(ARKodeSplittingExecutionPolicy policy, N_Vector y, - const int sequential_methods) +#include "sundials_macros.h" + +static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, + SUNDIALS_MAYBE_UNUSED const N_Vector y, + SUNDIALS_MAYBE_UNUSED const int sequential_methods) { // Nothing needed return ARK_SUCCESS; } static int execute_serial(ARKodeSplittingExecutionPolicy policy, - ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, + ARKExecutionPolicyFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, const int sequential_methods, void* user_data) { @@ -58,106 +61,18 @@ ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() { ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); if (policy == NULL) { return NULL; } - policy->setup = setup_serial; + policy->setup = setup_serial; policy->execute = execute_serial; - policy->free = free_serial; - policy->data = NULL; + policy->free = free_serial; + policy->data = NULL; return policy; } void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) { - // TODO: should argument be a pointer? - if (policy != NULL) { + if (policy != NULL) + { free(*policy); + *policy = NULL; } } - -// #include - -// ARKodeSplittingExecutionPolicy SplittingStepExecutionPolicy_MPI(SUNComm comm) { -// ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); -// policy->setup = setup_mpi; -// policy->exectute = execute_mpi; -// policy->free = free_mpi; -// SUNComm *data = malloc(sizeof(*data)); -// data[0] = comm; -// policy->data = data; -// } - -// static int mpi_reduce(void *in, void *inout, int *len, MPI_Datatype *datatype) { -// // Is there any way -// } - -// static int setup_mpi(ARKodeSplittingExecutionPolicy policy, N_Vector y, const int sequential_methods) { -// MPI_Op_create(mpi_reduce, SUNTRUE, ) -// } - -// static int execute_mpi(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// SUNComm comm = *((SUNComm*) policy->data); -// int rank; -// MPI_Comm_rank(comm, &rank); - -// N_VScale(1, yn, ycur); -// fn(rank, y, user_data); -// N_VScale(alpha[rank], ycur, ycur); - -// for (int i = 2 * rank; i < sequential_methods; rank++) { -// N_VScale(1, yn, tmp); -// fn(i, tmp, user_data); -// NN_VLinearSum(1, ycur, alpha[i], tmp); -// } - -// sunindextype bufferSize; -// N_VBufSize(ycur, &bufferSize); -// } - -// static void free_mpi(ARKodeSplittingExecutionPolicy policy) { -// MPI_op_free(); -// free(policy->data); -// } - -// int execute_openmp(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// #pragma omp parallel default(none) private(i) shared(fn, y, alpha, sequential_methods, user_data) -// { -// #pragma omp for schedule(static) num_threads(?) -// for (int i = 1; i < sequential_methods; i++) { -// // We assume that the "true" version of y_n is stored in y[0], then -// // distribute it to the other y[i]. It might be possible to remove this if -// // we can ensure the y[i] are always identical even after a reset, -// // reinit, etc. -// N_VScale(1, y[0], y[i]); -// } - -// #pragma omp for schedule(dynamic) num_threads(?) -// for (int i = 0; i < sequential_methods; i++) { -// fn(i, y[i], user_data); -// } -// } - -// // This could be done as a parallel reduction. The benefit appears minimal as -// // it would require at least 4 sequential methods to theoretically get a -// // speedup. -// N_VLinearCombination(sequential_methods, alpha, y, y[0]); -// } - -// int execute_mpi(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// MPI_Bcast() - -// MPI_Barrier(comm); - -// int rank; -// MPI_Comm_rank(comm, &rank); - -// for (int i = rank; i < sequential_methods; i+=rank) { -// fn(i, y[i], user_data); -// } - -// // This could be done as a parallel reduction. The benefit appears minimal as -// // it would require at least 4 sequential methods to theoretically get a -// // speedup. -// N_VLinearCombination(sequential_methods, alpha, y, y[0]); -// } diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index 0c8b5875c2..1f5eaf26d6 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -21,7 +21,7 @@ typedef struct ARKodeSplittingStepMemRec { - SUNStepper *steppers; + SUNStepper* steppers; ARKodeSplittingCoefficients coefficients; ARKodeSplittingExecutionPolicy policy; long int n_stepper_evolves; diff --git a/test/unit_tests/arkode/C_serial/CMakeLists.txt b/test/unit_tests/arkode/C_serial/CMakeLists.txt index 5c83d00c54..1c86d9b798 100644 --- a/test/unit_tests/arkode/C_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/C_serial/CMakeLists.txt @@ -32,6 +32,7 @@ set(ARKODE_unit_tests "ark_test_interp\;-1000000" "ark_test_mass\;" "ark_test_reset\;" + "ark_test_splitting_coefficients\;" "ark_test_splittingstep\;" "ark_test_tstop\;") diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index b231acfd8b..b07657894b 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -16,7 +16,7 @@ Examples * Programmer(s): Steven B. Roberts @ LLNL * ----------------------------------------------------------------------------- * SUNDIALS Copyright Start - * Copyright (c) 2002-2023, Lawrence Livermore National Security + * Copyright (c) 2002-2024, Lawrence Livermore National Security * and Southern Methodist University. * All rights reserved. * @@ -28,33 +28,36 @@ Examples * TODO * ---------------------------------------------------------------------------*/ +#include #include #include -#include #include -#include #include +#include #include -#define DT_1 (0.125) -#define DT_2 (0.03125) -#define T_END 1.0 +#define DT_1 (0.125) +#define DT_2 (0.03125) +#define T_END 1.0 #define LAMBDA 2.0 -static int f1(sunrealtype t, N_Vector y, N_Vector yp, void *data) { +static int f1(sunrealtype t, N_Vector y, N_Vector yp, void* data) +{ printf("%e %e\n", t, NV_Ith_S(y, 0)); N_VScale(-LAMBDA, y, yp); return 0; } -static int f2(sunrealtype t, N_Vector y, N_Vector yp, void *data) { +static int f2(sunrealtype t, N_Vector y, N_Vector yp, void* data) +{ printf(" %e %e\n", t, NV_Ith_S(y, 0)); N_VProd(y, y, yp); return 0; } -static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) { +static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) +{ return LAMBDA * y0 / (y0 - (y0 - LAMBDA) * exp(LAMBDA * t)); } @@ -67,11 +70,11 @@ int main(int argc, char* argv[]) N_VConst(1, y); const sunrealtype sol = exact_sol(T_END, NV_Ith_S(y, 0)); - void *arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); + void* arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); ARKodeSetOrder(arkode_mem1, 1); ARKodeSetFixedStep(arkode_mem1, DT_1); - void *arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); + void* arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); ARKodeSetOrder(arkode_mem2, 1); ARKodeSetFixedStep(arkode_mem2, DT_2); @@ -79,14 +82,17 @@ int main(int argc, char* argv[]) ARKStepCreateMRIStepInnerStepper(arkode_mem1, &steppers[0]); ARKStepCreateMRIStepInnerStepper(arkode_mem2, &steppers[1]); - void *split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); - ARKodeSplittingCoefficients coeffs = ARKodeSplittingCoefficients_SuzukiFractal(3, 6); - ARKodeSplittingCoefficients_Write(coeffs, stdout); + void* split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); + ARKodeSplittingCoefficients coeffs = + ARKodeSplittingCoefficients_SuzukiFractal(2, 6); + // ARKodeSplittingCoefficients_Write(coeffs, stdout); SplittingStep_SetCoefficients(split_mem, coeffs); + ARKodePrintMem(split_mem, stdout); ARKodeSplittingCoefficients_Free(coeffs); - ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error if this is not called + ARKodeSetFixedStep(split_mem, + DT_1); // TODO: fix valgrind error if this is not called sunrealtype tret; - ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); + // ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); printf("%e %e\n", T_END, NV_Ith_S(y, 0)); N_VPrint(y); From 280d369327f25e4d50f7d6f218ef5e2d1d1a89c2 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 20 Aug 2024 14:04:25 -0700 Subject: [PATCH 004/180] Add mathematical description to docs --- doc/arkode/guide/source/Mathematics.rst | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 9d9835c53d..9cda23d12e 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -572,6 +572,76 @@ using a fixed time-step size. .. The `ark_kepler.c` example demonstrates an implementation of such controller. + +.. _ARKODE.Mathematics.SplittingStep: + +SplittingStep -- Operator splitting methods +================================================ + +The SplittingStep time-stepping module in ARKODE is designed for IVPs of the +form + +.. TODO: SPRK uses subscript for function number. Make consistent +.. math:: + \dot{y} = f^1(t,y) + f^2(t,y) + \dots + f^P(t,y), \qquad y(t_0) = y_0, + :label: ARKODE_IVP_partitioned + +with :math:`P > 1` additive partitions. Operator splitting methods, such as +those implemented in SplittingStep, allow each partition to be integrated +separately, possibly with different numerical integrators or exact solution +procedures. Coupling is only performed though initial conditions which are +passed from the flow of one partition to the next. + +The following algorithmic procedure is used in the Splitting-Step module: + +#. For :math:`i = 1, \dots, r` do: + + #. Set :math:`y_{n, i} = y_{n - 1}`. + + #. For :math:`j = 0, \dots, s` do: + + #. For :math:`k = 1, \dots, P` do: + + #. Let :math:`t_{\text{start}} = t_{n-1} + \beta_{i,j-1,k} h_n` and + :math:`t_{\text{end}} = t_{n-1} + \beta_{i,j,k} h_n`. + + #. Let :math:`v(t_{\text{start}}) = y_{n,i}`. + + #. For :math:`t \in [t_{\text{start}}, t_{\text{end}}]` solve + :math:`\dot{v} = f^{k}(t, v)`. + + #. Set :math:`y_{n, i} = v(t_{\text{end}})`. + +#. Set :math:`y_n = \sum_{i=1}^r \alpha_i y_{n,i}` + +Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number +of sequential methods within the overall operator splitting scheme. Each of the +sequential methods are independent can can be run in parallel. The real +coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` determine the particular +scheme and properties such as the order. + +An alternative representation of the SplittingStep solution is + +.. math:: + y_n = \sum_{i=1}^P \alpha_i \left( \phi^1_{\gamma_{i,1,1} h} \circ + \phi^2_{\gamma_{i,1,2} h} \circ \dots \circ \phi^P_{\gamma_{i,1,P} h} \circ + \phi^1_{\gamma_{i,2,1} h} \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \circ + \dots \circ \phi^P_{\gamma_{i,s,P} h} \right) + (y_{n-1}) + +where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and +:math:`\phi^j_{h}` is the flow map for partition :math:`j`. + +SplittingStep provides standard operator splitting methods such as Lie--Trotter +and Strang splitting, as well as schemes of arbitrarily high order. +Alternatively, users may construct their own coefficients (see TODO). Generally, +methods of order three and higher with real coefficients require backward +integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. +Currently, a fixed time step must be specified for SplittingStep, but +sub-integrations are free to use adaptive time steps. See TODO for +additional details. + + .. _ARKODE.Mathematics.MRIStep: MRIStep -- Multirate infinitesimal step methods From 663a7aebc3133a23efae80c3444f533dec7f3d00 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 20 Aug 2024 14:04:56 -0700 Subject: [PATCH 005/180] Add missing execution policy files --- include/arkode/arkode_execution_policy.h | 51 +++++ .../arkode/arkode_splitting_coefficients.h | 95 ++++++++ .../arkode_execution_policy_serial.h | 33 +++ src/arkode/arkode_splittingstep.c | 2 +- .../arkode_execution_policy_mpi.c | 83 +++++++ .../arkode_execution_policy_openmp.c | 45 ++++ .../arkode_execution_policy_serial.c | 68 ++++++ .../ark_test_splitting_coefficients.c | 208 ++++++++++++++++++ 8 files changed, 584 insertions(+), 1 deletion(-) create mode 100644 include/arkode/arkode_execution_policy.h create mode 100644 include/arkode/arkode_splitting_coefficients.h create mode 100644 include/arkode/execution_policy/arkode_execution_policy_serial.h create mode 100644 src/arkode/execution_policy/arkode_execution_policy_mpi.c create mode 100644 src/arkode/execution_policy/arkode_execution_policy_openmp.c create mode 100644 src/arkode/execution_policy/arkode_execution_policy_serial.c create mode 100644 test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c diff --git a/include/arkode/arkode_execution_policy.h b/include/arkode/arkode_execution_policy.h new file mode 100644 index 0000000000..18321ca05c --- /dev/null +++ b/include/arkode/arkode_execution_policy.h @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * TODO + * ---------------------------------------------------------------------------*/ + +#ifndef ARKODE_EXECUTION_POLICY_H_ +#define ARKODE_EXECUTION_POLICY_H_ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* Parallelization Policy */ +typedef int (*ARKExecutionPolicyFn)(int i, N_Vector y, void* user_data); + +typedef _SUNDIALS_STRUCT_ ARKodeSplittingExecutionPolicyMem* ARKodeSplittingExecutionPolicy; + +struct ARKodeSplittingExecutionPolicyMem +{ + int (*setup)(ARKodeSplittingExecutionPolicy policy, N_Vector y, + int sequential_methods); + + int (*execute)(ARKodeSplittingExecutionPolicy policy, ARKExecutionPolicyFn fn, + N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, + int sequential_methods, void* user_data); + + void (*free)(ARKodeSplittingExecutionPolicy policy); + + void* data; +}; + +// TODO: Return error code? Accept pointer? +SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( + ARKodeSplittingExecutionPolicy* policy); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h new file mode 100644 index 0000000000..0cc3ccbb36 --- /dev/null +++ b/include/arkode/arkode_splitting_coefficients.h @@ -0,0 +1,95 @@ +// TODO: should filename be arkode_splittingcoefficients.h instead? + +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- +* This is the header file for ARKode splitting coefficient structures. + * ---------------------------------------------------------------------------*/ + +#ifndef ARKODE_SPLITTING_COEFFICIENTS_H_ +#define ARKODE_SPLITTING_COEFFICIENTS_H_ + +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/*--------------------------------------------------------------- + Types : struct ARKodeSplittingCoefficientsMem, ARKodeSplittingCoefficients + ---------------------------------------------------------------*/ +struct ARKodeSplittingCoefficientsMem +{ + sunrealtype* alpha; /* weights for sum over sequential splitting methods */ + sunrealtype*** beta; /* subintegration nodes, indexed by the sequential method, stage, and partition */ + int sequential_methods; /* number of sequential splitting methods */ + int stages; /* number of stages within each sequential splitting method */ + int partitions; /* number of RHS partitions */ + int order; /* order of convergence */ +}; + +typedef _SUNDIALS_STRUCT_ ARKodeSplittingCoefficientsMem* ARKodeSplittingCoefficients; + +/* Splitting names use the convention ARKODE_SPLITTING___ */ +typedef enum +{ + ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ + ARKODE_MIN_SPLITTING_NUM = 300, + ARKODE_SPLITTING_LIE_TROTTER_2_1 = ARKODE_MIN_SPLITTING_NUM, + ARKODE_SPLITTING_STRANG_2_2, + ARKODE_SPLITTING_YOSHIDA_2_4, + ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_2_4 +} ARKODE_SplittingCoefficientsID; + +/* Coefficient memory management */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( + int sequential_methods, int stages, int partitions); +/* TODO: Ideally, alpha and beta would be const, but that would be inconsistent + * with other ARKODE function which accept arrays */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Create( + int sequential_methods, int stages, int partitions, int order, + sunrealtype* alpha, sunrealtype* beta); +SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients B); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Copy(ARKodeSplittingCoefficients B); +SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Write( + ARKodeSplittingCoefficients coefficients, FILE* outfile); + +/* Load splitting coefficients */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID id); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_LoadCoefficientsByName(const char* name); +SUNDIALS_EXPORT const char* ARKodeSplittingCoefficients_IDToName( + ARKODE_SplittingCoefficientsID id); + +/* Constructors for splitting coefficients */ +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_LieTrotter(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Strang(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_Parallel(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_SymmetricParallel(int partitions); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_TripleJump(int partitions, int order); +SUNDIALS_EXPORT ARKodeSplittingCoefficients +ARKodeSplittingCoefficients_SuzukiFractal(int partitions, int order); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/arkode/execution_policy/arkode_execution_policy_serial.h b/include/arkode/execution_policy/arkode_execution_policy_serial.h new file mode 100644 index 0000000000..2f6d20b2a4 --- /dev/null +++ b/include/arkode/execution_policy/arkode_execution_policy_serial.h @@ -0,0 +1,33 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * TODO + * ---------------------------------------------------------------------------*/ + +#ifndef ARKODE_EXECUTION_POLICY_SERIAL_H_ +#define ARKODE_EXECUTION_POLICY_SERIAL_H_ + +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy +ARKodeSplittingExecutionPolicy_Serial(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 67710ee5c1..7f4475027a 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -240,7 +240,7 @@ static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, SUNDIALS_MAYBE_UNUSED void* const resize_data) { - // TODO: explain why resizing needs to be done on the inner methods + // TODO: explain why resizing needs to be done on the inner methods by users and not here return ARK_SUCCESS; } diff --git a/src/arkode/execution_policy/arkode_execution_policy_mpi.c b/src/arkode/execution_policy/arkode_execution_policy_mpi.c new file mode 100644 index 0000000000..715cdd1660 --- /dev/null +++ b/src/arkode/execution_policy/arkode_execution_policy_mpi.c @@ -0,0 +1,83 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include + +#include "sundials_macros.h" +// #include + +// ARKodeSplittingExecutionPolicy SplittingStepExecutionPolicy_MPI(SUNComm comm) { +// ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); +// policy->setup = setup_mpi; +// policy->exectute = execute_mpi; +// policy->free = free_mpi; +// SUNComm *data = malloc(sizeof(*data)); +// data[0] = comm; +// policy->data = data; +// } + +// static int mpi_reduce(void *in, void *inout, int *len, MPI_Datatype *datatype) { +// // Is there any way +// } + +// static int setup_mpi(ARKodeSplittingExecutionPolicy policy, N_Vector y, const int sequential_methods) { +// MPI_Op_create(mpi_reduce, SUNTRUE, ) +// } + +// static int execute_mpi(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// SUNComm comm = *((SUNComm*) policy->data); +// int rank; +// MPI_Comm_rank(comm, &rank); + +// N_VScale(1, yn, ycur); +// fn(rank, y, user_data); +// N_VScale(alpha[rank], ycur, ycur); + +// for (int i = 2 * rank; i < sequential_methods; rank++) { +// N_VScale(1, yn, tmp); +// fn(i, tmp, user_data); +// NN_VLinearSum(1, ycur, alpha[i], tmp); +// } + +// sunindextype bufferSize; +// N_VBufSize(ycur, &bufferSize); +// } + +// static void free_mpi(ARKodeSplittingExecutionPolicy policy) { +// MPI_op_free(); +// free(policy->data); +// } + +// int execute_mpi(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// MPI_Bcast() + +// MPI_Barrier(comm); + +// int rank; +// MPI_Comm_rank(comm, &rank); + +// for (int i = rank; i < sequential_methods; i+=rank) { +// fn(i, y[i], user_data); +// } + +// // This could be done as a parallel reduction. The benefit appears minimal as +// // it would require at least 4 sequential methods to theoretically get a +// // speedup. +// N_VLinearCombination(sequential_methods, alpha, y, y[0]); +// } \ No newline at end of file diff --git a/src/arkode/execution_policy/arkode_execution_policy_openmp.c b/src/arkode/execution_policy/arkode_execution_policy_openmp.c new file mode 100644 index 0000000000..e5eeb7580b --- /dev/null +++ b/src/arkode/execution_policy/arkode_execution_policy_openmp.c @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include + +#include "sundials_macros.h" + +// int execute_openmp(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) +// { +// #pragma omp parallel default(none) private(i) shared(fn, y, alpha, sequential_methods, user_data) +// { +// #pragma omp for schedule(static) num_threads(?) +// for (int i = 1; i < sequential_methods; i++) { +// // We assume that the "true" version of y_n is stored in y[0], then +// // distribute it to the other y[i]. It might be possible to remove this if +// // we can ensure the y[i] are always identical even after a reset, +// // reinit, etc. +// N_VScale(1, y[0], y[i]); +// } + +// #pragma omp for schedule(dynamic) num_threads(?) +// for (int i = 0; i < sequential_methods; i++) { +// fn(i, y[i], user_data); +// } +// } + +// // This could be done as a parallel reduction. The benefit appears minimal as +// // it would require at least 4 sequential methods to theoretically get a +// // speedup. +// N_VLinearCombination(sequential_methods, alpha, y, y[0]); +// } diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c new file mode 100644 index 0000000000..cca4f62048 --- /dev/null +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * TODO + *--------------------------------------------------------------*/ + +#include +#include + +#include "sundials_macros.h" + +static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, + SUNDIALS_MAYBE_UNUSED const N_Vector y, + SUNDIALS_MAYBE_UNUSED const int sequential_methods) +{ + // Nothing needed + return ARK_SUCCESS; +} + +static int execute_serial(ARKodeSplittingExecutionPolicy policy, + ARKExecutionPolicyFn fn, N_Vector yn, N_Vector ycur, + N_Vector tmp, sunrealtype* alpha, + const int sequential_methods, void* user_data) +{ + N_VScale(1, yn, ycur); + fn(0, ycur, user_data); + + // For many methods alpha[0] == 1, so this is redundant. TODO: add check or + // hope compiler optimized this out + // N_VScale(alpha[0], ycur, ycur); + + // for (int i = 1; i < sequential_methods; i++) + // { + // N_VScale(1, yn, tmp); + // int retval = fn(i, tmp, user_data); + // if (retval != ARK_SUCCESS) + // // TODO: error handling of fn + // N_VLinearSum(1, ycur, alpha[i], tmp, yn); + // } + + return ARK_SUCCESS; +} + +static void free_serial(ARKodeSplittingExecutionPolicy policy) +{ + // Nothing needed +} + +ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() +{ + ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); + if (policy == NULL) { return NULL; } + policy->setup = setup_serial; + policy->execute = execute_serial; + policy->free = free_serial; + policy->data = NULL; + return policy; +} \ No newline at end of file diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c new file mode 100644 index 0000000000..64bfb6ffee --- /dev/null +++ b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c @@ -0,0 +1,208 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * Unit test that checks splitting coefficients constructors and loading + * functions + * ---------------------------------------------------------------------------*/ + +#include +#include + +#include "arkode/arkode_splitting_coefficients.h" +#include "sundials/sundials_math.h" + +#define ZERO SUN_RCONST(0.0) +#define ONE SUN_RCONST(1.0) +#define TWO SUN_RCONST(2.0) +#define HALF SUN_RCONST(0.5) +#define GAMMA (SUN_RCONST(1.0) / (SUN_RCONST(4.0) - SUNRpowerR(SUN_RCONST(4.0), SUN_RCONST(1.0) / SUN_RCONST(3.0)))) + +static int check_coefficients(const char* const name, + const ARKodeSplittingCoefficients coefficients, + const int expected_sequential_methods, + const int expected_stages, + const int expected_partitions, + const int expected_order, + const sunrealtype* const expected_alpha, + const sunrealtype* const expected_beta) +{ + printf("Testing %s\n", name); + + if (coefficients == NULL) + { + fprintf(stderr, "Expected non-NULL coefficients\n"); + } + + if (coefficients->sequential_methods != expected_sequential_methods) + { + fprintf(stderr, "Expected %d sequential methods, but there are %d\n", + expected_sequential_methods, coefficients->sequential_methods); + return 1; + } + + if (coefficients->stages != expected_stages) + { + fprintf(stderr, "Expected %d stages, but there are %d\n", expected_stages, + coefficients->stages); + return 1; + } + + if (coefficients->partitions != expected_partitions) + { + fprintf(stderr, "Expected %d partitions, but there are %d\n", + expected_partitions, coefficients->partitions); + return 1; + } + + if (coefficients->order != expected_order) + { + fprintf(stderr, "Expected order %d, but is %d\n", expected_order, + coefficients->order); + return 1; + } + + int retval = 0; + + for (int i = 0; i < expected_sequential_methods; i++) + { + if (SUNRCompare(coefficients->alpha[i], expected_alpha[i])) + { + fprintf(stderr, "alpha[%d] incorrect\n", i); + retval++; + } + } + + for (int i = 0; i < expected_sequential_methods; i++) + { + for (int j = 0; j <= expected_stages; j++) + { + for (int k = 0; k < expected_partitions; k++) + { + if (SUNRCompare(coefficients->beta[i][j][k], + expected_beta[(i * (expected_stages + 1) + j) * expected_partitions + + k])) + { + fprintf(stderr, "beta[%d][%d][%d] incorrect\n", i, j, k); + retval++; + } + } + } + } + + if (retval > 0) { + ARKodeSplittingCoefficients_Write(coefficients, stderr); + } + + return retval; +} + +/* Main program */ +int main(int argc, char* argv[]) +{ + int retval = 0; + + printf("Testing Splitting Coefficients\n"); + + ARKodeSplittingCoefficients coefficients = + ARKodeSplittingCoefficients_Create(1, 2, 2, 1, NULL, NULL); + if (coefficients != NULL) + { + fprintf(stderr, "Coefficients created with NULL coefficients\n"); + retval++; + } + + sunrealtype alpha_lie_trotter[] = {ONE}; + sunrealtype beta_lie_trotter[] = {ZERO, ZERO, ONE, ONE}; + + coefficients = ARKodeSplittingCoefficients_Create(0, 0, 0, 1, alpha_lie_trotter, + beta_lie_trotter); + if (coefficients != NULL) + { + fprintf(stderr, "Coefficients created with invalid sizes\n"); + retval++; + } + + coefficients = ARKodeSplittingCoefficients_Create(1, 1, 2, 1, alpha_lie_trotter, + beta_lie_trotter); + retval += check_coefficients("Lie-Trotter (manually created)", coefficients, + 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); + + ARKodeSplittingCoefficients coefficients_copy = + ARKodeSplittingCoefficients_Copy(coefficients); + retval += check_coefficients("Lie-Trotter (copy)", coefficients_copy, 1, 1, 2, + 1, alpha_lie_trotter, beta_lie_trotter); + ARKodeSplittingCoefficients_Free(coefficients); + ARKodeSplittingCoefficients_Free(coefficients_copy); + + coefficients = ARKodeSplittingCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_2_1); + retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, 2, 1, + alpha_lie_trotter, beta_lie_trotter); + ARKodeSplittingCoefficients_Free(coefficients); + + coefficients = ARKodeSplittingCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_2_1"); + retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, 2, 1, + alpha_lie_trotter, beta_lie_trotter); + ARKodeSplittingCoefficients_Free(coefficients); + + coefficients = ARKodeSplittingCoefficients_LieTrotter(2); + retval += check_coefficients("Lie-Trotter (constructor)", coefficients, 1, 1, 2, 1, + alpha_lie_trotter, beta_lie_trotter); + ARKodeSplittingCoefficients_Free(coefficients); + + sunrealtype alpha_strang[] = {ONE}; + sunrealtype beta_strang[] = {ZERO, ZERO, ZERO, HALF, HALF, ONE, + HALF, ONE, ONE, ONE, ONE, ONE}; + + coefficients = ARKodeSplittingCoefficients_Strang(3); + retval += check_coefficients("Strang", coefficients, 1, 3, 3, 2, alpha_strang, + beta_strang); + ARKodeSplittingCoefficients_Free(coefficients); + + sunrealtype alpha_parallel[] = {ONE, ONE, -ONE}; + sunrealtype beta_parallel[] = {ZERO, ZERO, ONE, ZERO, ZERO, ZERO, + ZERO, ONE, ZERO, ZERO, ZERO, ZERO}; + + coefficients = ARKodeSplittingCoefficients_Parallel(2); + retval += check_coefficients("Parallel", coefficients, 3, 1, 2, 1, + alpha_parallel, beta_parallel); + ARKodeSplittingCoefficients_Free(coefficients); + + sunrealtype alpha_symmetric_parallel[] = {HALF, HALF, -ONE}; + sunrealtype beta_symmetric_parallel[] = {ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ONE, ONE, ONE, + ZERO, ZERO, ZERO, ZERO, ZERO, ONE, + ZERO, ONE, ONE, ONE, ONE, ONE}; + + coefficients = ARKodeSplittingCoefficients_SymmetricParallel(3); + retval += check_coefficients("Symmetric Parallel", coefficients, 2, 3, 3, 2, + alpha_symmetric_parallel, beta_symmetric_parallel); + ARKodeSplittingCoefficients_Free(coefficients); + + sunrealtype alpha_suzuki_fractal[] = {ONE}; + sunrealtype beta_suzuki_fractal[] = {ZERO, ZERO, + HALF * GAMMA, GAMMA, + (ONE + HALF) * GAMMA, TWO * GAMMA, + HALF, ONE - TWO * GAMMA, + ONE - (ONE + HALF) * GAMMA, ONE - GAMMA, + ONE - HALF * GAMMA, ONE, + ONE, ONE}; + + coefficients = ARKodeSplittingCoefficients_SuzukiFractal(2, 4); + retval += check_coefficients("Suzuki Fractal", coefficients, 1, 6, 2, 4, alpha_suzuki_fractal, + beta_suzuki_fractal); + ARKodeSplittingCoefficients_Free(coefficients); + + printf("%d test failures\n", retval); + + return retval; +} From 8e5c5f082198f258423b4577ed53e702762e5222 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 20 Aug 2024 15:22:12 -0700 Subject: [PATCH 006/180] Template SplittingStep docs --- .../ARKodeSplittingCoefficients.rst | 24 ++++++ .../Usage/SplittingStep/User_callable.rst | 78 +++++++++++++++++++ .../source/Usage/SplittingStep/index.rst | 31 ++++++++ doc/arkode/guide/source/Usage/index.rst | 1 + include/arkode/arkode_splittingstep.h | 2 + 5 files changed, 136 insertions(+) create mode 100644 doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst create mode 100644 doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst create mode 100644 doc/arkode/guide/source/Usage/SplittingStep/index.rst diff --git a/doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst new file mode 100644 index 0000000000..3442c35730 --- /dev/null +++ b/doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst @@ -0,0 +1,24 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.SplittingStep.ARKodeSplittingCoefficients: + +========================================= +Operator Splitting Coefficients Structure +========================================= + +To store the coefficients representing an operator splitting method, ARKODE +provides the :c:type:`ARKodeSplittingCoefficients` type and several related +utility routines. We use the following notation + diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst new file mode 100644 index 0000000000..eab450389d --- /dev/null +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -0,0 +1,78 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.SplittingStep.UserCallable: + +SplittingStep User-callable functions +===================================== + +This section describes the SplittingStep-specific functions that may be called +by the user to setup and then solve an IVP using the SplittingStep time-stepping +module. + +As discussed in the main :ref:`ARKODE user-callable function introduction +`, each of ARKODE's time-stepping modules +clarifies the categories of user-callable functions that it supports. +SplittingStep supports the following categories: + + +.. _ARKODE.Usage.SplittingStep.Initialization: + +SplittingStep initialization functions +------------------------------------------------------ +.. c:function:: void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx) + + This function allocates and initializes memory for a problem to + be solved using the SplittingStep time-stepping module in ARKODE. + + **Arguments:** + * *steppers* -- ? + * *partitions* -- ? + * *t0* -- the initial value of :math:`t`. + * *y0* -- the initial condition vector :math:`y(t_0)`. + * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) + + **Return value:** + If successful, a pointer to initialized problem memory of type ``void*``, to + be passed to all user-facing SplittingStep routines listed below. If unsuccessful, + a ``NULL`` pointer will be returned, and an error message will be printed to + ``stderr``. + + **Example usage:** + + .. code-block:: C + + /* fast (inner) and slow (outer) ARKODE objects */ + void *inner_arkode_mem = NULL; + void *outer_arkode_mem = NULL; + + /* MRIStepInnerStepper to wrap the inner (fast) ARKStep object */ + MRIStepInnerStepper stepper = NULL; + + /* create an ARKStep object, setting fast (inner) right-hand side + functions and the initial condition */ + inner_arkode_mem = ARKStepCreate(ffe, ffi, t0, y0, sunctx); + + /* setup ARKStep */ + . . . + + /* create MRIStepInnerStepper wrapper for the ARKStep memory block */ + flag = ARKStepCreateMRIStepInnerStepper(inner_arkode_mem, &stepper); + + /* create an MRIStep object, setting the slow (outer) right-hand side + functions and the initial condition */ + outer_arkode_mem = MRIStepCreate(fse, fsi, t0, y0, stepper, sunctx) + + **Example codes:** + * ``examples/arkode/C_serial/TODO.c`` diff --git a/doc/arkode/guide/source/Usage/SplittingStep/index.rst b/doc/arkode/guide/source/Usage/SplittingStep/index.rst new file mode 100644 index 0000000000..901d037f69 --- /dev/null +++ b/doc/arkode/guide/source/Usage/SplittingStep/index.rst @@ -0,0 +1,31 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.SplittingStep: + +============================================ +Using the SplittingStep time-stepping module +============================================ + +This section is concerned with the use of the SplittingStep time-stepping +module for the solution of initial value problems (IVPs) in a C or C++ +language setting. Usage of ERKStep follows that of the rest of ARKODE, +and so in this section we primarily focus on those usage aspects that +are specific to ERKStep. + +.. toctree:: + :maxdepth: 1 + + User_callable + ARKodeSplittingCoefficients diff --git a/doc/arkode/guide/source/Usage/index.rst b/doc/arkode/guide/source/Usage/index.rst index 93b63d84b8..4d7ba36cb4 100644 --- a/doc/arkode/guide/source/Usage/index.rst +++ b/doc/arkode/guide/source/Usage/index.rst @@ -78,4 +78,5 @@ ARKBBDPRE can only be used with NVECTOR_PARALLEL. ARKStep/index.rst ERKStep/index.rst SPRKStep/index.rst + SplittingStep/index.rst MRIStep/index.rst diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index ef878b31fd..f243b27ca7 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -30,6 +30,8 @@ extern "C" { typedef MRIStepInnerStepper SUNStepper; /* ARKODE functions */ +/* TODO: can we use `const SUNStepper* steppers` since we don't make copies? */ +/* TODO: would (t0, y0, steppers, partitions, sunctx) be a better arg order? Seems slightly more consistent with MRIStepCreate */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx); From bede6b516bf3e48ea8d84681ef31398eb29f2fda Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 22 Aug 2024 13:34:43 -0700 Subject: [PATCH 007/180] Rename to SplittingStepCoefficients --- ...ents.rst => SplittingStepCoefficients.rst} | 4 +- .../source/Usage/SplittingStep/index.rst | 2 +- .../arkode/arkode_splitting_coefficients.h | 60 +++--- include/arkode/arkode_splittingstep.h | 7 +- include/sundials/sundials_stepper.h | 2 +- src/arkode/arkode_splitting_coefficients.c | 84 ++++----- src/arkode/arkode_splitting_coefficients.def | 6 +- src/arkode/arkode_splittingstep.c | 173 ++++++++++-------- .../arkode_splittingstep_executionpolicy.c | 25 +-- src/arkode/arkode_splittingstep_impl.h | 2 +- .../arkode_execution_policy_serial.c | 24 +-- .../ark_test_splitting_coefficients.c | 48 ++--- .../arkode/C_serial/ark_test_splittingstep.c | 53 ++++-- 13 files changed, 259 insertions(+), 231 deletions(-) rename doc/arkode/guide/source/Usage/SplittingStep/{ARKodeSplittingCoefficients.rst => SplittingStepCoefficients.rst} (85%) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst similarity index 85% rename from doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst rename to doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 3442c35730..cf419fab0d 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/ARKodeSplittingCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -12,13 +12,13 @@ SUNDIALS Copyright End ---------------------------------------------------------------- -.. _ARKODE.Usage.SplittingStep.ARKodeSplittingCoefficients: +.. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients: ========================================= Operator Splitting Coefficients Structure ========================================= To store the coefficients representing an operator splitting method, ARKODE -provides the :c:type:`ARKodeSplittingCoefficients` type and several related +provides the :c:type:`SplittingStepCoefficients` type and several related utility routines. We use the following notation diff --git a/doc/arkode/guide/source/Usage/SplittingStep/index.rst b/doc/arkode/guide/source/Usage/SplittingStep/index.rst index 901d037f69..e94b1f8b97 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/index.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/index.rst @@ -28,4 +28,4 @@ are specific to ERKStep. :maxdepth: 1 User_callable - ARKodeSplittingCoefficients + SplittingStepCoefficients diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index 0cc3ccbb36..d38a4acf12 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -1,4 +1,4 @@ -// TODO: should filename be arkode_splittingcoefficients.h instead? +/* TODO: merge this header into arkode_splittingstep.h? MRI uses one header, but ARK uses two */ /* ----------------------------------------------------------------------------- * Programmer(s): Steven B. Roberts @ LLNL @@ -16,8 +16,8 @@ * This is the header file for ARKode splitting coefficient structures. * ---------------------------------------------------------------------------*/ -#ifndef ARKODE_SPLITTING_COEFFICIENTS_H_ -#define ARKODE_SPLITTING_COEFFICIENTS_H_ +#ifndef ARKODE_SPLITTING_STEP_COEFFICIENTS_H_ +#define ARKODE_SPLITTING_STEP_COEFFICIENTS_H_ #include #include @@ -27,9 +27,9 @@ extern "C" { #endif /*--------------------------------------------------------------- - Types : struct ARKodeSplittingCoefficientsMem, ARKodeSplittingCoefficients + Types : struct SplittingStepCoefficientsMem, SplittingStepCoefficients ---------------------------------------------------------------*/ -struct ARKodeSplittingCoefficientsMem +struct SplittingStepCoefficientsMem { sunrealtype* alpha; /* weights for sum over sequential splitting methods */ sunrealtype*** beta; /* subintegration nodes, indexed by the sequential method, stage, and partition */ @@ -39,7 +39,7 @@ struct ARKodeSplittingCoefficientsMem int order; /* order of convergence */ }; -typedef _SUNDIALS_STRUCT_ ARKodeSplittingCoefficientsMem* ARKodeSplittingCoefficients; +typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; /* Splitting names use the convention ARKODE_SPLITTING___ */ typedef enum @@ -53,40 +53,40 @@ typedef enum } ARKODE_SplittingCoefficientsID; /* Coefficient memory management */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( +SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( int sequential_methods, int stages, int partitions); /* TODO: Ideally, alpha and beta would be const, but that would be inconsistent * with other ARKODE function which accept arrays */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Create( +SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); -SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Free(ARKodeSplittingCoefficients B); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Copy(ARKodeSplittingCoefficients B); -SUNDIALS_EXPORT void ARKodeSplittingCoefficients_Write( - ARKodeSplittingCoefficients coefficients, FILE* outfile); +SUNDIALS_EXPORT void SplittingStepCoefficients_Free(SplittingStepCoefficients B); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Copy(SplittingStepCoefficients B); +SUNDIALS_EXPORT void SplittingStepCoefficients_Write( + SplittingStepCoefficients coefficients, FILE* outfile); /* Load splitting coefficients */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID id); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_LoadCoefficientsByName(const char* name); -SUNDIALS_EXPORT const char* ARKodeSplittingCoefficients_IDToName( +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID id); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LoadCoefficientsByName(const char* name); +SUNDIALS_EXPORT const char* SplittingStepCoefficients_IDToName( ARKODE_SplittingCoefficientsID id); /* Constructors for splitting coefficients */ -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_LieTrotter(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Strang(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_Parallel(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_SymmetricParallel(int partitions); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_TripleJump(int partitions, int order); -SUNDIALS_EXPORT ARKodeSplittingCoefficients -ARKodeSplittingCoefficients_SuzukiFractal(int partitions, int order); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LieTrotter(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Strang(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Parallel(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_SymmetricParallel(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_TripleJump(int partitions, int order); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_SuzukiFractal(int partitions, int order); #ifdef __cplusplus } diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index f243b27ca7..8b9f86d88d 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -17,6 +17,7 @@ #ifndef ARKODE_SPLITTINGSTEP_H_ #define ARKODE_SPLITTINGSTEP_H_ +#include #include #include #include @@ -26,10 +27,6 @@ extern "C" { #endif -/* TODO: remove once SUNStepper is ready */ -typedef MRIStepInnerStepper SUNStepper; - -/* ARKODE functions */ /* TODO: can we use `const SUNStepper* steppers` since we don't make copies? */ /* TODO: would (t0, y0, steppers, partitions, sunctx) be a better arg order? Seems slightly more consistent with MRIStepCreate */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, @@ -37,7 +34,7 @@ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, SUNContext sunctx); SUNDIALS_EXPORT int SplittingStep_SetCoefficients( - void* arkode_mem, ARKodeSplittingCoefficients coefficients); + void* arkode_mem, SplittingStepCoefficients coefficients); SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( void* arkode_mem, ARKodeSplittingExecutionPolicy policy); diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index e552976864..8cb3200626 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -97,7 +97,7 @@ SUNErrCode SUNStepper_GetForcingData(SUNStepper stepper, sunrealtype* tshift, int* nforcing); SUNDIALS_EXPORT -SUNErrCode SUNStepper_Advance(SUNStepper stepper, sunrealtype t0, +SUNErrCode SUNStepper_Evolve(SUNStepper stepper, sunrealtype t0, sunrealtype tout, N_Vector y, N_Vector yp, sunrealtype* tret, int* stop_reason); diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index d5baac954d..bf1cb8c439 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -23,13 +23,13 @@ Routine to allocate splitting coefficients with zero values for alpha and beta ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( +SplittingStepCoefficients SplittingStepCoefficients_Alloc( const int sequential_methods, const int stages, const int partitions) { if (sequential_methods < 1 || stages < 1 || partitions < 1) { return NULL; } - const ARKodeSplittingCoefficients coefficients = - (ARKodeSplittingCoefficients)malloc(sizeof(*coefficients)); + const SplittingStepCoefficients coefficients = + (SplittingStepCoefficients)malloc(sizeof(*coefficients)); if (coefficients == NULL) { return NULL; } coefficients->sequential_methods = sequential_methods; @@ -41,7 +41,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( sizeof(*coefficients->alpha)); if (coefficients->alpha == NULL) { - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); return NULL; } @@ -55,7 +55,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( (sunrealtype***)malloc(sequential_methods * sizeof(*coefficients->beta)); if (coefficients->beta == NULL) { - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); return NULL; } @@ -64,7 +64,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( sequential_methods * (stages + 1) * sizeof(*beta_cols)); if (beta_cols == NULL) { - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); return NULL; } @@ -74,7 +74,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( sizeof(*beta_mem)); if (beta_mem == NULL) { - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); return NULL; } @@ -95,14 +95,14 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Alloc( Routine to create splitting coefficients which performs a copy of the alpha and beta parameters ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Create( +SplittingStepCoefficients SplittingStepCoefficients_Create( const int sequential_methods, const int stages, const int partitions, const int order, sunrealtype* const alpha, sunrealtype* const beta) { if (alpha == NULL || beta == NULL) { return NULL; } - ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(sequential_methods, stages, partitions); + SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(sequential_methods, stages, partitions); if (coefficients == NULL) { return NULL; } coefficients->order = order; @@ -116,7 +116,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Create( /*--------------------------------------------------------------- Routine to free splitting coefficients ---------------------------------------------------------------*/ -void ARKodeSplittingCoefficients_Free(const ARKodeSplittingCoefficients coefficients) +void SplittingStepCoefficients_Free(const SplittingStepCoefficients coefficients) { // TODO: should argument be a pointer? if (coefficients != NULL) @@ -136,13 +136,13 @@ void ARKodeSplittingCoefficients_Free(const ARKodeSplittingCoefficients coeffici /*--------------------------------------------------------------- Routine to create a copy of splitting coefficients ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( - ARKodeSplittingCoefficients coefficients) +SplittingStepCoefficients SplittingStepCoefficients_Copy( + SplittingStepCoefficients coefficients) { if (coefficients == NULL) { return NULL; } - ARKodeSplittingCoefficients coefficientsCopy = - ARKodeSplittingCoefficients_Alloc(coefficients->sequential_methods, + SplittingStepCoefficients coefficientsCopy = + SplittingStepCoefficients_Alloc(coefficients->sequential_methods, coefficients->stages, coefficients->partitions); if (coefficientsCopy == NULL) { return NULL; } @@ -163,7 +163,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Copy( /*--------------------------------------------------------------- Routine to load coefficients from an ID ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( +SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficients( const ARKODE_SplittingCoefficientsID method) { switch (method) @@ -184,7 +184,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficients( Routine to load coefficients using a string representation of an enum entry in ARKODE_SplittingCoefficientsID ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( +SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficientsByName( const char* const method) { #define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ @@ -202,7 +202,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LoadCoefficientsByName( Routine to convert a coefficient enum value to its string representation ---------------------------------------------------------------*/ -const char* ARKodeSplittingCoefficients_IDToName( +const char* SplittingStepCoefficients_IDToName( const ARKODE_SplittingCoefficientsID id) { /* Use X-macro to test each coefficient name */ @@ -223,11 +223,11 @@ const char* ARKodeSplittingCoefficients_IDToName( /*--------------------------------------------------------------- Routine to construct the standard Lie-Trotter splitting ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LieTrotter(const int partitions) +SplittingStepCoefficients SplittingStepCoefficients_LieTrotter(const int partitions) { if (partitions < 1) { return NULL; } - const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(1, 1, partitions); + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(1, 1, partitions); if (coefficients == NULL) { return NULL; } coefficients->order = 1; @@ -243,9 +243,9 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_LieTrotter(const int par /*--------------------------------------------------------------- Routine to construct the standard Stang splitting ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Strang(const int partitions) +SplittingStepCoefficients SplittingStepCoefficients_Strang(const int partitions) { - return ARKodeSplittingCoefficients_TripleJump(partitions, 2); + return SplittingStepCoefficients_TripleJump(partitions, 2); } /*--------------------------------------------------------------- @@ -253,12 +253,12 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Strang(const int partiti Phi_1(h) + Phi_2(h) + ... + Phi_p(h) - (p - 1) * y_n where Phi_i is the flow of partition i and p = partitions. ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int partitions) +SplittingStepCoefficients SplittingStepCoefficients_Parallel(const int partitions) { if (partitions < 1) { return NULL; } - const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(partitions + 1, 1, partitions); + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(partitions + 1, 1, partitions); if (coefficients == NULL) { return NULL; } coefficients->order = 1; @@ -277,13 +277,13 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_Parallel(const int parti Routine to construct a symmetric parallel splitting which is the average of the Lie-Trotter method and its adjoint ---------------------------------------------------------------*/ -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( +SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel( const int partitions) { if (partitions < 1) { return NULL; } - const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(2, partitions, partitions); + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(2, partitions, partitions); if (coefficients == NULL) { return NULL; } coefficients->order = 2; @@ -309,7 +309,7 @@ ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SymmetricParallel( * and ^ denote composition, and c = composition_stages. This covers both the triple jump (c=1) and Suzuki fractal (c=2). ---------------------------------------------------------------*/ -static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( +static sunrealtype* const* SplittingStepCoefficients_ComposeStrangHelper( const int partitions, const int order, const int composition_stages, const sunrealtype start, const sunrealtype end, sunrealtype* const* const beta) { @@ -345,7 +345,7 @@ static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( : (end + (i - composition_stages) * gamma); /* Recursively generate coefficients and shift beta_cur */ beta_cur = - arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order - 2, + SplittingStepCoefficients_ComposeStrangHelper(partitions, order - 2, composition_stages, start_cur, end_cur, beta_cur); @@ -357,10 +357,10 @@ static sunrealtype* const* arkodeSplittingCoefficients_ComposeStrangHelper( /*--------------------------------------------------------------- Routine which does validation and setup before calling - arkodeSplittingCoefficients_ComposeStrangHelper to fill in the + SplittingStepCoefficients_ComposeStrangHelper to fill in the beta coefficients ---------------------------------------------------------------*/ -static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( +static SplittingStepCoefficients SplittingStepCoefficients_ComposeStrang( const int partitions, const int order, const int composition_stages) { if (partitions < 1 || order < 2 || order % 2 != 0) @@ -371,14 +371,14 @@ static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( const int stages = 1 + (partitions - 1) * SUNRpowerI(composition_stages, order / 2 - 1); - const ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Alloc(1, stages, partitions); + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(1, stages, partitions); if (coefficients == NULL) { return NULL; } coefficients->order = order; coefficients->alpha[0] = SUN_RCONST(1.0); - arkodeSplittingCoefficients_ComposeStrangHelper(partitions, order, + SplittingStepCoefficients_ComposeStrangHelper(partitions, order, composition_stages, SUN_RCONST(0.0), SUN_RCONST(1.0), @@ -387,23 +387,23 @@ static ARKodeSplittingCoefficients arkodeSplittingCoefficients_ComposeStrang( return coefficients; } -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_TripleJump( +SplittingStepCoefficients SplittingStepCoefficients_TripleJump( const int partitions, const int order) { - return arkodeSplittingCoefficients_ComposeStrang(partitions, order, 3); + return SplittingStepCoefficients_ComposeStrang(partitions, order, 3); } -ARKodeSplittingCoefficients ARKodeSplittingCoefficients_SuzukiFractal( +SplittingStepCoefficients SplittingStepCoefficients_SuzukiFractal( const int partitions, const int order) { - return arkodeSplittingCoefficients_ComposeStrang(partitions, order, 5); + return SplittingStepCoefficients_ComposeStrang(partitions, order, 5); } /*--------------------------------------------------------------- Routine to print a splitting coefficient structure ---------------------------------------------------------------*/ -void ARKodeSplittingCoefficients_Write( - const ARKodeSplittingCoefficients coefficients, FILE* const outfile) +void SplittingStepCoefficients_Write( + const SplittingStepCoefficients coefficients, FILE* const outfile) { // TODO: update when https://github.com/LLNL/sundials/pull/517 merged if (coefficients == NULL || coefficients->alpha == NULL || diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index d9f142160b..2ae549ced1 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -24,13 +24,13 @@ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { }) ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_2_1, { - return ARKodeSplittingCoefficients_LieTrotter(2); + return SplittingStepCoefficients_LieTrotter(2); }) ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2, { - return ARKodeSplittingCoefficients_Strang(2); + return SplittingStepCoefficients_Strang(2); }) ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_2_4, { - return ARKodeSplittingCoefficients_TripleJump(2, 4); + return SplittingStepCoefficients_TripleJump(2, 4); }) \ No newline at end of file diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 7f4475027a..c710fb88fc 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -11,7 +11,8 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This is the implementation file for ARKODE's operator + * splitting module *--------------------------------------------------------------*/ #include @@ -77,26 +78,24 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) { if (step_mem->coefficients == NULL) { - if (step_mem->order <= 1) - { - step_mem->coefficients = - ARKodeSplittingCoefficients_LieTrotter(step_mem->partitions); - // TODO: check if non-NULL? - } - else - { - // TODO consider extrapolation for odd orders - const int next_even_order = step_mem->order + (step_mem->order % 2); - step_mem->coefficients = - ARKodeSplittingCoefficients_TripleJump(step_mem->partitions, - next_even_order); - // TODO: check if non-NULL? + step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order <= 1 ? DEFAULT_ORDER : (step_mem->order + (step_mem->order % 2))); + if (step_mem->coefficients == NULL) { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, + __FILE__, "Failed to allocate splitting coefficients"); + return ARK_MEM_FAIL; } } if (step_mem->policy == NULL) { step_mem->policy = ARKodeSplittingExecutionPolicy_Serial(); + if (step_mem->policy == NULL) { + if (step_mem->coefficients == NULL) { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, + __FILE__, "Failed to allocate execution policy"); + return ARK_MEM_FAIL; + } + } step_mem->own_policy = SUNTRUE; } } @@ -107,7 +106,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } -static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, +static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const N_Vector y, const N_Vector f, SUNDIALS_MAYBE_UNUSED const int mode) { @@ -115,9 +114,7 @@ static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - // TODO: uncomment once inner stepper finalized - // retval = innerStepper_FullRhs(step_mem->steppers[0], t, y, f, - // ARK_FULLRHS_OTHER); + retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -127,68 +124,73 @@ static int splittingStep_FullRHS(ARKodeMem ark_mem, const sunrealtype t, for (int i = 1; i < step_mem->partitions; i++) { - // retval = innerStepper_FullRhs(step_mem->steppers[i], t, y, ark_mem->tempv1, - // ARK_FULLRHS_OTHER); + retval = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); return (ARK_RHSFUNC_FAIL); } - N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); + N_VLinearSum(SUN_RCONST(1.0), f, SUN_RCONST(1.0), ark_mem->tempv1, f); } return ARK_SUCCESS; } -static int splittingStep_Stage(const int i, const N_Vector y, void* user_data) +static int splittingStep_Stage(const int i, const N_Vector y, void* const user_data) { - // Note: this should not write to ark_mem and step_mem to avoid race conditions when executed in parallel ARKodeMem ark_mem = (ARKodeMem)user_data; ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - ARKodeSplittingCoefficients coefficients = step_mem->coefficients; + const SplittingStepCoefficients coefficients = step_mem->coefficients; for (int j = 0; j < coefficients->stages; j++) { for (int k = 0; k < coefficients->partitions; k++) { - const sunrealtype tcur = ark_mem->tn + + const sunrealtype t_start = ark_mem->tn + coefficients->beta[i][j][k] * ark_mem->h; - const sunrealtype tnext = ark_mem->tn + + const sunrealtype t_end = ark_mem->tn + coefficients->beta[i][j + 1][k] * ark_mem->h; - if (tcur != tnext) - { - SUNStepper stepper = step_mem->steppers[k]; - if (SUNTRUE) - { // TODO: condition for FSAL. Consider special cases where the - // coefficients have changed, it's the first step, or reset is called - // TODO: what about backward integration? - stepper->ops->reset(stepper, tcur, y); - } - retval = stepper->ops->evolve(stepper, tcur, tnext, y); - if (retval != ARK_SUCCESS) { return retval; } + if (t_start == t_end) + { + continue; } + + const SUNStepper stepper = step_mem->steppers[k]; + SUNErrCode err = stepper->ops->reset(stepper, t_start, y, NULL); + if (err != SUN_SUCCESS) { return err; } + + err = stepper->ops->setstoptime(stepper, t_end); + if (err != SUN_SUCCESS) { return err; } + + sunrealtype tret = 0; + int stop_reason = 0; + err = SUNStepper_Evolve(stepper, t_start, t_end, y, NULL, &tret, &stop_reason); + step_mem->n_stepper_evolves++; + + if (err != SUN_SUCCESS) { return err; } + if (stop_reason < 0) { return stop_reason; } } } return ARK_SUCCESS; } -static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, - int* nflagPtr) +static int splittingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const dsmPtr, + int* const nflagPtr) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - *nflagPtr = ARK_SUCCESS; - *dsmPtr = ZERO; + *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ + *dsmPtr = ZERO; /* No error estimate */ - ARKodeSplittingCoefficients coefficients = step_mem->coefficients; + const SplittingStepCoefficients coefficients = step_mem->coefficients; return step_mem->policy->execute(step_mem->policy, splittingStep_Stage, ark_mem->yn, ark_mem->ycur, ark_mem->tempv1, @@ -196,12 +198,12 @@ static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, coefficients->sequential_methods, ark_mem); } -static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, - SUNOutputFormat fmt) +static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfile, + const SUNOutputFormat fmt) { // TODO: update when https://github.com/LLNL/sundials/pull/517 merged ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } switch (fmt) @@ -221,10 +223,10 @@ static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, return ARK_SUCCESS; } -static int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) +static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp) { ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } fprintf(fp, "SplittingStep time step module parameters:\n Method order %i\n\n", @@ -240,26 +242,26 @@ static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, SUNDIALS_MAYBE_UNUSED void* const resize_data) { - // TODO: explain why resizing needs to be done on the inner methods by users and not here return ARK_SUCCESS; } -static void splittingStep_Free(ARKodeMem ark_mem) +static void splittingStep_Free(const ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; if (step_mem == NULL) { return; } + free(step_mem->steppers); if (step_mem->own_policy) { ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); } - ARKodeSplittingCoefficients_Free(step_mem->coefficients); + SplittingStepCoefficients_Free(step_mem->coefficients); free(step_mem); ark_mem->step_mem = NULL; } -static void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) +static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) { ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -275,31 +277,25 @@ static void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) /* output sunrealtype quantities */ fprintf(outfile, "SplittingStep: Coefficients:\n"); - ARKodeSplittingCoefficients_Write(step_mem->coefficients, outfile); - - //TODO: consider printing policy + SplittingStepCoefficients_Write(step_mem->coefficients, outfile); } -static int splittingStep_SetOrder(ARKodeMem ark_mem, const int order) +static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) { ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } /* set user-provided value, or default, depending on argument */ - if (order <= 0) { step_mem->order = 1; } - else { step_mem->order = order; } + step_mem->order = order <= 0 ? 1 : order; - if (step_mem->coefficients) - { - ARKodeSplittingCoefficients_Free(step_mem->coefficients); - step_mem->coefficients = NULL; - } + SplittingStepCoefficients_Free(step_mem->coefficients); + step_mem->coefficients = NULL; return ARK_SUCCESS; } -static int splittingStep_SetDefaults(ARKodeMem ark_mem) +static int splittingStep_SetDefaults(const ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -308,16 +304,18 @@ static int splittingStep_SetDefaults(ARKodeMem ark_mem) retval = splittingStep_SetOrder(ark_mem, 0); if (retval != ARK_SUCCESS) { return retval; } - retval = SplittingStep_SetExecutionPolicy(ark_mem, NULL); - if (retval != ARK_SUCCESS) { return retval; } - + if (step_mem->own_policy) { + free(step_mem->policy); + } + step_mem->own_policy = SUNFALSE; + ark_mem->interp_type = ARK_INTERP_LAGRANGE; return ARK_SUCCESS; } -void* SplittingStepCreate(SUNStepper* steppers, const int partitions, - const sunrealtype t0, N_Vector y0, SUNContext sunctx) +void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, + const sunrealtype t0, const N_Vector y0, const SUNContext sunctx) { if (steppers == NULL) { @@ -377,7 +375,15 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, return NULL; } - step_mem->steppers = steppers; + step_mem->steppers = malloc(partitions * sizeof(*steppers)); + if (step_mem->steppers == NULL) { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_ARKMEM_FAIL); + ARKodeFree((void**)&ark_mem); + return NULL; + } + memcpy(step_mem->steppers, steppers, partitions * sizeof(*steppers)); + step_mem->coefficients = NULL; step_mem->policy = NULL; step_mem->n_stepper_evolves = 0; @@ -408,10 +414,7 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, return (NULL); } - // TODO update liw, lrw - /* Initialize main ARKODE infrastructure */ - // TODO will this create interpolation then have it immediately replaced? retval = arkInit(ark_mem, t0, y0, FIRST_INIT); if (retval != ARK_SUCCESS) { @@ -425,7 +428,7 @@ void* SplittingStepCreate(SUNStepper* steppers, const int partitions, } int SplittingStep_SetCoefficients(void* arkode_mem, - ARKodeSplittingCoefficients coefficients) + SplittingStepCoefficients coefficients) { ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; @@ -433,6 +436,12 @@ int SplittingStep_SetCoefficients(void* arkode_mem, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } + if (coefficients == NULL) { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "Splitting coefficients must be non-NULL"); + return ARK_ILL_INPUT; + } + if (step_mem->partitions != coefficients->partitions) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, @@ -441,12 +450,12 @@ int SplittingStep_SetCoefficients(void* arkode_mem, return ARK_ILL_INPUT; } - ARKodeSplittingCoefficients_Free(step_mem->coefficients); - step_mem->coefficients = ARKodeSplittingCoefficients_Copy(coefficients); + SplittingStepCoefficients_Free(step_mem->coefficients); + step_mem->coefficients = SplittingStepCoefficients_Copy(coefficients); if (step_mem->coefficients == NULL) { - arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, __func__, __FILE__, - MSG_ARK_NO_MEM); // TODO: not relevant message but consistent with ARKStep and ERKStep + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + "Failed to copy splitting coefficients"); return (ARK_MEM_NULL); } @@ -462,7 +471,11 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - // TODO Error if policy is NULL? + if (policy == NULL) { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "The execution policy must be non-NULL"); + return ARK_ILL_INPUT; + } if (step_mem->own_policy) { diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c index f2783f7ea8..66179aa268 100644 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -34,20 +34,20 @@ static int execute_serial(ARKodeSplittingExecutionPolicy policy, const int sequential_methods, void* user_data) { N_VScale(1, yn, ycur); - fn(0, ycur, user_data); + int retval = fn(0, ycur, user_data); + if (retval != ARK_SUCCESS) { return retval; } - // For many methods alpha[0] == 1, so this is redundant. TODO: add check or - // hope compiler optimized this out - // N_VScale(alpha[0], ycur, ycur); + if (alpha[0] != SUN_RCONST(1.0)) { + N_VScale(alpha[0], ycur, ycur); + } - // for (int i = 1; i < sequential_methods; i++) - // { - // N_VScale(1, yn, tmp); - // int retval = fn(i, tmp, user_data); - // if (retval != ARK_SUCCESS) - // // TODO: error handling of fn - // N_VLinearSum(1, ycur, alpha[i], tmp, yn); - // } + for (int i = 1; i < sequential_methods; i++) + { + N_VScale(SUN_RCONST(1.0), yn, tmp); + retval = fn(i, tmp, user_data); + if (retval != ARK_SUCCESS) { return retval; } + N_VLinearSum(SUN_RCONST(1.0), ycur, alpha[i], tmp, ycur); + } return ARK_SUCCESS; } @@ -72,6 +72,7 @@ void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) { if (policy != NULL) { + (*policy)->free(*policy); free(*policy); *policy = NULL; } diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index 1f5eaf26d6..f955086ca6 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -22,7 +22,7 @@ typedef struct ARKodeSplittingStepMemRec { SUNStepper* steppers; - ARKodeSplittingCoefficients coefficients; + SplittingStepCoefficients coefficients; ARKodeSplittingExecutionPolicy policy; long int n_stepper_evolves; diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index cca4f62048..ff367f636a 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -33,20 +33,20 @@ static int execute_serial(ARKodeSplittingExecutionPolicy policy, const int sequential_methods, void* user_data) { N_VScale(1, yn, ycur); - fn(0, ycur, user_data); + int retval = fn(0, ycur, user_data); + if (retval != ARK_SUCCESS) { return retval; } - // For many methods alpha[0] == 1, so this is redundant. TODO: add check or - // hope compiler optimized this out - // N_VScale(alpha[0], ycur, ycur); + if (alpha[0] != SUN_RCONST(1.0)) { + N_VScale(alpha[0], ycur, ycur); + } - // for (int i = 1; i < sequential_methods; i++) - // { - // N_VScale(1, yn, tmp); - // int retval = fn(i, tmp, user_data); - // if (retval != ARK_SUCCESS) - // // TODO: error handling of fn - // N_VLinearSum(1, ycur, alpha[i], tmp, yn); - // } + for (int i = 1; i < sequential_methods; i++) + { + N_VScale(SUN_RCONST(1), yn, tmp); + int retval = fn(i, tmp, user_data); + if (retval != ARK_SUCCESS) + N_VLinearSum(1, ycur, alpha[i], tmp, ycur); + } return ARK_SUCCESS; } diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c index 64bfb6ffee..00c60156eb 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c @@ -28,7 +28,7 @@ #define GAMMA (SUN_RCONST(1.0) / (SUN_RCONST(4.0) - SUNRpowerR(SUN_RCONST(4.0), SUN_RCONST(1.0) / SUN_RCONST(3.0)))) static int check_coefficients(const char* const name, - const ARKodeSplittingCoefficients coefficients, + const SplittingStepCoefficients coefficients, const int expected_sequential_methods, const int expected_stages, const int expected_partitions, @@ -100,7 +100,7 @@ static int check_coefficients(const char* const name, } if (retval > 0) { - ARKodeSplittingCoefficients_Write(coefficients, stderr); + SplittingStepCoefficients_Write(coefficients, stderr); } return retval; @@ -113,8 +113,8 @@ int main(int argc, char* argv[]) printf("Testing Splitting Coefficients\n"); - ARKodeSplittingCoefficients coefficients = - ARKodeSplittingCoefficients_Create(1, 2, 2, 1, NULL, NULL); + SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Create(1, 2, 2, 1, NULL, NULL); if (coefficients != NULL) { fprintf(stderr, "Coefficients created with NULL coefficients\n"); @@ -124,7 +124,7 @@ int main(int argc, char* argv[]) sunrealtype alpha_lie_trotter[] = {ONE}; sunrealtype beta_lie_trotter[] = {ZERO, ZERO, ONE, ONE}; - coefficients = ARKodeSplittingCoefficients_Create(0, 0, 0, 1, alpha_lie_trotter, + coefficients = SplittingStepCoefficients_Create(0, 0, 0, 1, alpha_lie_trotter, beta_lie_trotter); if (coefficients != NULL) { @@ -132,50 +132,50 @@ int main(int argc, char* argv[]) retval++; } - coefficients = ARKodeSplittingCoefficients_Create(1, 1, 2, 1, alpha_lie_trotter, + coefficients = SplittingStepCoefficients_Create(1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); retval += check_coefficients("Lie-Trotter (manually created)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - ARKodeSplittingCoefficients coefficients_copy = - ARKodeSplittingCoefficients_Copy(coefficients); + SplittingStepCoefficients coefficients_copy = + SplittingStepCoefficients_Copy(coefficients); retval += check_coefficients("Lie-Trotter (copy)", coefficients_copy, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - ARKodeSplittingCoefficients_Free(coefficients); - ARKodeSplittingCoefficients_Free(coefficients_copy); + SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients_copy); - coefficients = ARKodeSplittingCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_2_1); + coefficients = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_2_1); retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); - coefficients = ARKodeSplittingCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_2_1"); + coefficients = SplittingStepCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_2_1"); retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); - coefficients = ARKodeSplittingCoefficients_LieTrotter(2); + coefficients = SplittingStepCoefficients_LieTrotter(2); retval += check_coefficients("Lie-Trotter (constructor)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_strang[] = {ONE}; sunrealtype beta_strang[] = {ZERO, ZERO, ZERO, HALF, HALF, ONE, HALF, ONE, ONE, ONE, ONE, ONE}; - coefficients = ARKodeSplittingCoefficients_Strang(3); + coefficients = SplittingStepCoefficients_Strang(3); retval += check_coefficients("Strang", coefficients, 1, 3, 3, 2, alpha_strang, beta_strang); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_parallel[] = {ONE, ONE, -ONE}; sunrealtype beta_parallel[] = {ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ZERO}; - coefficients = ARKodeSplittingCoefficients_Parallel(2); + coefficients = SplittingStepCoefficients_Parallel(2); retval += check_coefficients("Parallel", coefficients, 3, 1, 2, 1, alpha_parallel, beta_parallel); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_symmetric_parallel[] = {HALF, HALF, -ONE}; sunrealtype beta_symmetric_parallel[] = {ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, @@ -183,10 +183,10 @@ int main(int argc, char* argv[]) ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ONE, ONE, ONE, ONE, ONE}; - coefficients = ARKodeSplittingCoefficients_SymmetricParallel(3); + coefficients = SplittingStepCoefficients_SymmetricParallel(3); retval += check_coefficients("Symmetric Parallel", coefficients, 2, 3, 3, 2, alpha_symmetric_parallel, beta_symmetric_parallel); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_suzuki_fractal[] = {ONE}; sunrealtype beta_suzuki_fractal[] = {ZERO, ZERO, @@ -197,10 +197,10 @@ int main(int argc, char* argv[]) ONE - HALF * GAMMA, ONE, ONE, ONE}; - coefficients = ARKodeSplittingCoefficients_SuzukiFractal(2, 4); + coefficients = SplittingStepCoefficients_SuzukiFractal(2, 4); retval += check_coefficients("Suzuki Fractal", coefficients, 1, 6, 2, 4, alpha_suzuki_fractal, beta_suzuki_fractal); - ARKodeSplittingCoefficients_Free(coefficients); + SplittingStepCoefficients_Free(coefficients); printf("%d test failures\n", retval); diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index b07657894b..8090609ba7 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -32,13 +32,13 @@ Examples #include #include +#include #include -#include #include #include -#define DT_1 (0.125) -#define DT_2 (0.03125) +#define DT_1 (0.5/8) +#define DT_2 (0.125/8) #define T_END 1.0 #define LAMBDA 2.0 @@ -61,6 +61,26 @@ static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) return LAMBDA * y0 / (y0 - (y0 - LAMBDA) * exp(LAMBDA * t)); } +static void test() { +SUNContext sunctx; + SUNContext_Create(SUN_COMM_NULL, &sunctx); + + N_Vector y = N_VNew_Serial(1, sunctx); + N_VConst(1, y); + + void *mem = ARKStepCreate(f1, NULL, 0, y, sunctx); + + ARKodeSetFixedStep(mem, 0.25); + + sunrealtype tret = 0; + ARKodeEvolve(mem, 1, y, &tret, ARK_NORMAL); + + ARKodeReset(mem, 1, y); + ARKodeEvolve(mem, 1.5, y, &tret, ARK_NORMAL); + + N_VPrint(y); +} + int main(int argc, char* argv[]) { SUNContext sunctx; @@ -71,37 +91,34 @@ int main(int argc, char* argv[]) const sunrealtype sol = exact_sol(T_END, NV_Ith_S(y, 0)); void* arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem1, 1); + ARKodeSetOrder(arkode_mem1, 2); ARKodeSetFixedStep(arkode_mem1, DT_1); void* arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem2, 1); + ARKodeSetOrder(arkode_mem2, 2); ARKodeSetFixedStep(arkode_mem2, DT_2); SUNStepper steppers[2]; - ARKStepCreateMRIStepInnerStepper(arkode_mem1, &steppers[0]); - ARKStepCreateMRIStepInnerStepper(arkode_mem2, &steppers[1]); + ARKStepCreateSUNStepper(arkode_mem1, &steppers[0]); + ARKStepCreateSUNStepper(arkode_mem2, &steppers[1]); void* split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); - ARKodeSplittingCoefficients coeffs = - ARKodeSplittingCoefficients_SuzukiFractal(2, 6); - // ARKodeSplittingCoefficients_Write(coeffs, stdout); + SplittingStepCoefficients coeffs = SplittingStepCoefficients_Parallel(2); + // SplittingStepCoefficients_Write(coeffs, stdout); SplittingStep_SetCoefficients(split_mem, coeffs); - ARKodePrintMem(split_mem, stdout); - ARKodeSplittingCoefficients_Free(coeffs); - ARKodeSetFixedStep(split_mem, - DT_1); // TODO: fix valgrind error if this is not called + SplittingStepCoefficients_Free(coeffs); + ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error if this is not called sunrealtype tret; - // ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); - printf("%e %e\n", T_END, NV_Ith_S(y, 0)); + ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); + printf("Final Solution: %e %e\n", T_END, NV_Ith_S(y, 0)); N_VPrint(y); printf("Error: %e\n", sol - NV_Ith_S(y, 0)); ARKodeFree(&split_mem); N_VDestroy(y); - MRIStepInnerStepper_Free(&steppers[0]); - MRIStepInnerStepper_Free(&steppers[1]); + SUNStepper_Destroy(&steppers[0]); + SUNStepper_Destroy(&steppers[1]); ARKodeFree(&arkode_mem1); ARKodeFree(&arkode_mem2); SUNContext_Free(&sunctx); From 19724c5627071d99e417357bfe10971a271cddad Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 27 Aug 2024 18:46:31 -0700 Subject: [PATCH 008/180] Finish ADR example --- examples/arkode/C_serial/CMakeLists.txt | 1 + src/arkode/arkode_splittingstep.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index fbba99ffb9..5cbe236109 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -23,6 +23,7 @@ set(ARKODE_examples # tests that are always run "ark_analytic\;\;" # develop tests + "ark_advection_diffusion_reaction_splitting\;\;develop" "ark_analytic_mels\;\;develop" "ark_analytic_nonlin\;\;develop" "ark_brusselator_1D_mri\;\;develop" diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index c710fb88fc..8aff06e87a 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -209,7 +209,7 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outf switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - fprintf(outfile, "Stepper evolves = %ld\n", step_mem->n_stepper_evolves); + fprintf(outfile, "Stepper evolves = %ld\n", step_mem->n_stepper_evolves); break; case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); From ac927084e13da788a44c6bdcb1ccaea644518385 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 27 Aug 2024 18:46:48 -0700 Subject: [PATCH 009/180] Finish ADR example --- ...k_advection_diffusion_reaction_splitting.c | 339 ++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c new file mode 100644 index 0000000000..bd42c2ff37 --- /dev/null +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -0,0 +1,339 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * Example problem: + * + * The following test simulates a simple 1D advection-diffusion- + * reaction equation, + * u_t = a*(u^2/2)_x + b*u_xx + c*(u - u^3) + * for t in [0, 10], x in [0, 1], with initial conditions + * u(0,x) = u_0 + * and Dirichlet boundary condition at x=1 + * u(0,t) = u(1,t) = u_0 + * + * The spatial derivatives are computed using second-order + * centered differences, with the data distributed over N + * points (excluding boundary points) on a uniform spatial grid. + * + * This program solves the problem with an operator splitting + * method where advection is treated with a strong stability + * preserving ERK method, diffusion is treated with a DIRK + * method, and reaction is treated with a different ERK method. + * + * Outputs are printed at equal intervals, and run statistics are + * printed at the end. + *---------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(SUNDIALS_EXTENDED_PRECISION) +#define GSYM "Lg" +#define FSYM "Lf" +#else +#define GSYM "g" +#define FSYM "f" +#endif + +/* user data structure */ +typedef struct +{ + sunindextype N; /* number of grid points (excluding boundaries) */ + sunrealtype dx; /* mesh spacing */ + sunrealtype a; /* advection coefficient */ + sunrealtype b; /* diffusion coefficient */ + sunrealtype c; /* reaction coefficient */ + sunrealtype u0; /* initial and boundary values */ +} UserData; + +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} + +/* f routine to compute the advection RHS function. */ +static int f_advection(const sunrealtype t, const N_Vector y, const N_Vector ydot, void* const user_data) +{ + const UserData * const udata = (UserData*) user_data; + sunrealtype *Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype *Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); + const sunrealtype u0_sqr = udata->u0 * udata->u0; + + /* Left boundary */ + Ydot[0] = coeff * (Y[1] * Y[1] - u0_sqr); + /* Interior */ + for (sunindextype i = 1; i < udata->N - 1; i++) { + Ydot[i] = coeff * (Y[i + 1] * Y[i + 1] - Y[i - 1] * Y[i - 1]); + } + /* Right boundary */ + Ydot[udata->N - 1] = coeff * (u0_sqr - Y[udata->N - 1] * Y[udata->N - 1]); + + return 0; +} + +/* f routine to compute the diffusion RHS function. */ +static int f_diffusion(const sunrealtype t, const N_Vector y, const N_Vector ydot, void * const user_data) +{ + const UserData * const udata = (UserData *) user_data; + sunrealtype *Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype *Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + + /* Left boundary */ + Ydot[0] = coeff * (udata->u0 - 2 * Y[0] + Y[1]); + /* Interior */ + for (sunindextype i = 1; i < udata->N - 1; i++) { + Ydot[i] = coeff * (Y[i + 1] - 2 * Y[i] + Y[i - 1]); + } + /* Right boundary */ + Ydot[udata->N - 1] = coeff * (Y[udata->N - 2] - 2 * Y[udata->N - 1] + udata->u0); + + return 0; +} + +/* Routine to compute the diffusion Jacobian function. */ +static int jac_diffusion(const sunrealtype t, const N_Vector y, const N_Vector fy, const SUNMatrix Jac, + void* const user_data, const N_Vector tmp1, const N_Vector tmp2, + const N_Vector tmp3) +{ + const UserData * const udata = (UserData *) user_data; + const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + + SM_ELEMENT_B(Jac, 0, 0) = -2 * coeff; + for (int i = 1; i < udata->N; i++) { + SM_ELEMENT_B(Jac, i - 1, i) = coeff; + SM_ELEMENT_B(Jac, i, i) = -2 * coeff; + SM_ELEMENT_B(Jac, i, i - 1) = coeff; + } + + return 0; +} + +/* f routine to compute the reaction RHS function. */ +static int f_reaction(const sunrealtype t, const N_Vector y, const N_Vector ydot, void * const user_data) +{ + const UserData * const udata = (UserData *) user_data; + sunrealtype *Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype *Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + for (sunindextype i = 0; i < udata->N; i++) { + Ydot[i] = udata->c * Y[i] * (SUN_RCONST(1.0) - Y[i] * Y[i]); + } + + return 0; +} + +int main() { + /* Problem parameters */ + const sunrealtype T0 = SUN_RCONST(0.0); + const sunrealtype Tf = SUN_RCONST(1.0); + const sunrealtype DT = SUN_RCONST(0.06); + UserData udata = { + .N = 128, + .dx = SUN_RCONST(1.0) / (udata.N + 1), + .a = SUN_RCONST(1.0), + .b = SUN_RCONST(0.125), + .c = SUN_RCONST(4.0), + .u0 = SUN_RCONST(0.1) + }; + + printf("\n1D Advection-Diffusion-Reaction PDE test problem:\n"); + printf(" N = %li\n", (long int) udata.N); + printf(" advection coefficient = %" GSYM "\n", udata.a); + printf(" diffusion coefficient = %" GSYM "\n", udata.b); + printf(" reaction coefficient = %" GSYM "\n\n", udata.c); + + /* Create the SUNDIALS context object for this simulation */ + SUNContext ctx; + int flag = SUNContext_Create(SUN_COMM_NULL, &ctx); + if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } + + /* Initialize vector with initial condition */ + N_Vector y = N_VNew_Serial(udata.N, ctx); + if (check_flag(y, "N_VNew_Serial", 0)) { return 1; } + N_VConst(udata.u0, y); + + /* Create advection integrator */ + void *advection_mem = ARKStepCreate(f_advection, NULL, T0, y, ctx); + if (check_flag(advection_mem, "ARKStepCreate", 0)) { return 1; } + + flag = ARKodeSetUserData(advection_mem, &udata); + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + /* Choose a strong stability preserving method for advecton */ + flag = ARKStepSetTableNum(advection_mem, ARKODE_DIRK_NONE, ARKODE_SHU_OSHER_3_2_3); + if (check_flag(&flag, "ARKStepSetTableNum", 1)) { return 1; } + + SUNStepper advection_stepper; + flag = ARKStepCreateSUNStepper(advection_mem, &advection_stepper); + if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + + /* Create diffusion integrator */ + void *diffusion_mem = ARKStepCreate(NULL, f_diffusion, T0, y, ctx); + if (check_flag(diffusion_mem, "ARKStepCreate", 0)) { return 1; } + + flag = ARKodeSetUserData(diffusion_mem, &udata); + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + flag = ARKodeSetOrder(diffusion_mem, 3); + if (check_flag(&flag, "ARKStepSetOrder", 1)) { return 1; } + + SUNMatrix jac_mat = SUNBandMatrix(udata.N, 1, 1, ctx); + if (check_flag(jac_mat, "SUNBandMatrix", 0)) { return 1; } + + SUNLinearSolver ls = SUNLinSol_Band(y, jac_mat, ctx); + if (check_flag(ls, "SUNLinSol_Band", 0)) { return 1; } + + flag = ARKodeSetLinearSolver(diffusion_mem, ls, jac_mat); + if (check_flag(&flag, "ARKStepSetOrder", 1)) { return 1; } + + flag = ARKodeSetJacFn(diffusion_mem, jac_diffusion); + if (check_flag(&flag, "ARKodeSetJacFn", 1)) { return 1; } + + flag = ARKodeSetLinear(diffusion_mem, SUNFALSE); + if (check_flag(&flag, "ARKodeSetLinear", 1)) { return 1; } + + SUNStepper diffusion_stepper; + flag = ARKStepCreateSUNStepper(diffusion_mem, &diffusion_stepper); + if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + + /* Create reaction integrator */ + void *reaction_mem = ARKStepCreate(f_reaction, NULL, T0, y, ctx); + if (check_flag(reaction_mem, "ARKStepCreate", 0)) { return 1; } + + flag = ARKodeSetUserData(reaction_mem, &udata); + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + flag = ARKodeSetOrder(reaction_mem, 3); + if (check_flag(&flag, "ARKodeSetOrder", 1)) { return 1; } + + SUNStepper reaction_stepper; + flag = ARKStepCreateSUNStepper(reaction_mem, &reaction_stepper); + if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + + /* Create operator splitting integrator */ + SUNStepper steppers[] = {advection_stepper, diffusion_stepper, reaction_stepper}; + void *arkode_mem = SplittingStepCreate(steppers, 3, T0, y, ctx); + if (check_flag(arkode_mem, "SplittingStepCreate", 0)) { return 1; } + + flag = ARKodeSetFixedStep(arkode_mem, DT); + if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + + flag = ARKodeSetStopTime(arkode_mem, Tf); + if (check_flag(&flag, "ARKodeSetStopTime", 1)) { return 1; } + + /* Evolve solution in time */ + sunrealtype tret = T0; + printf(" t ||u||_rms\n"); + printf(" ----------------------\n"); + printf(" %10.6" FSYM " %10.6f\n", tret, sqrt(N_VDotProd(y, y) / udata.N)); + while (tret < Tf) { + flag = ARKodeEvolve(arkode_mem, Tf, y, &tret, ARK_ONE_STEP); + if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } + printf(" %10.6" FSYM " %10.6f\n", tret, sqrt(N_VDotProd(y, y) / udata.N)); + } + printf(" ----------------------\n"); + + /* Print statistics */ + printf("\nSplitting Stepper Statistics:\n"); + flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + printf("\nAdvection Stepper Statistics:\n"); + flag = ARKodePrintAllStats(advection_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + printf("\nDiffusion Stepper Statistics:\n"); + flag = ARKodePrintAllStats(diffusion_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + printf("\nReaction Stepper Statistics:\n"); + flag = ARKodePrintAllStats(reaction_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + /* Clean up and return with successful completion */ + N_VDestroy(y); + ARKodeFree(&advection_mem); + SUNStepper_Destroy(&advection_stepper); + ARKodeFree(&diffusion_mem); + SUNStepper_Destroy(&diffusion_stepper); + ARKodeFree(&reaction_mem); + SUNStepper_Destroy(&reaction_stepper); + ARKodeFree(&arkode_mem); + SUNLinSolFree(ls); + SUNMatDestroy(jac_mat); + SUNContext_Free(&ctx); + + return 0; +} From d72be7929a2ff1b5c7d9f74f100486cde6a21be3 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Sat, 31 Aug 2024 21:43:20 -0700 Subject: [PATCH 010/180] Add another example --- examples/arkode/C_serial/CMakeLists.txt | 1 + .../arkode/C_serial/ark_analytic_splitting.c | 183 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 examples/arkode/C_serial/ark_analytic_splitting.c diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 5cbe236109..27e5a53490 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,6 +26,7 @@ set(ARKODE_examples "ark_advection_diffusion_reaction_splitting\;\;develop" "ark_analytic_mels\;\;develop" "ark_analytic_nonlin\;\;develop" + "ark_analytic_splitting\;\;develop" "ark_brusselator_1D_mri\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator_mri\;\;develop" diff --git a/examples/arkode/C_serial/ark_analytic_splitting.c b/examples/arkode/C_serial/ark_analytic_splitting.c new file mode 100644 index 0000000000..78c2c55ae1 --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_splitting.c @@ -0,0 +1,183 @@ +/*----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * Example problem: + * + * The following is a simple example problem with analytical + * solution, + * dy/dt = lambda*y + 1/(1+t^2) - lambda*atan(t) + * for t in the interval [0.0, 10.0], with initial condition: y=0. + * + * The stiffness of the problem is directly proportional to the + * value of "lambda". The value of lambda should be negative to + * result in a well-posed ODE; for values with magnitude larger + * than 100 the problem becomes quite stiff. + * + * This program solves the problem with the DIRK method, + * Newton iteration with the dense SUNLinearSolver, and a + * user-supplied Jacobian routine. + * Output is printed every 1.0 units of time (10 total). + * Run statistics (optional outputs) are printed at the end. + *-----------------------------------------------------------------*/ + +/* Header files */ +#include +#include +#include + +#if defined(SUNDIALS_EXTENDED_PRECISION) +#define GSYM "Lg" +#define ESYM "Le" +#define FSYM "Lf" +#else +#define GSYM "g" +#define ESYM "e" +#define FSYM "f" +#endif + +typedef struct +{ + sunrealtype lambda; +} UserData; + + +static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) +{ + sunrealtype lambda = ((UserData*) user_data)->lambda; + N_VScale(-lambda, y, ydot); + return 0; +} + +static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) +{ + N_VProd(y, y, ydot); + return 0; +} + +static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, const UserData* const user_data) +{ + N_Vector sol = N_VClone(y0); + const sunrealtype y0_val = NV_Ith_S(y0, 0); + const sunrealtype lambda = user_data->lambda; + NV_Ith_S(sol, 0) = lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); + return sol; +} +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} + +int main() +{ + /* Problem parameters */ + const sunrealtype t0 = SUN_RCONST(0.0); + const sunrealtype tf = SUN_RCONST(1.0); + const sunrealtype dt = SUN_RCONST(0.01); + const sunrealtype dt_linear = dt / 5; + const sunrealtype dt_nonlinear = dt / 10; + + UserData user_data = { + .lambda = SUN_RCONST(2.0) + }; + + /* Create the SUNDIALS context object for this simulation */ + SUNContext ctx; + int flag = SUNContext_Create(SUN_COMM_NULL, &ctx); + if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } + + /* Initialize vector with initial condition */ + N_Vector y = N_VNew_Serial(1, ctx); + if (check_flag(y, "N_VNew_Serial", 0)) { return 1; } + N_VConst(SUN_RCONST(1.0), y); + + N_Vector y_exact = exact_sol(y, tf, &user_data); + + printf("\nAnalytical ODE test problem:\n"); + printf(" lambda = %" GSYM "\n", user_data.lambda); + + void *linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); + if (check_flag(linear_mem, "N_VNew_Serial", 0)) { return 1; } + + flag = ARKodeSetUserData(linear_mem, &user_data); + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + flag = ARKodeSetFixedStep(linear_mem, dt_linear); + if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + + void *nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); + if (check_flag(nonlinear_mem, "N_VNew_Serial", 0)) { return 1; } + + flag = ARKodeSetFixedStep(nonlinear_mem, dt_nonlinear); + if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + + SUNStepper steppers[2]; + ARKStepCreateSUNStepper(linear_mem, &steppers[0]); + ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); + + void *splitting_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); + if (check_flag(splitting_mem, "SplittingStepCreate", 0)) { return 1; } + + flag = ARKodeSetFixedStep(splitting_mem, dt); + if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + + sunrealtype tret; + flag = ARKodeEvolve(splitting_mem, tf, y, &tret, ARK_NORMAL); + if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } + + N_Vector y_err = N_VClone(y); + if (check_flag(y_err, "N_VClone", 0)) { return 1; } + + N_VLinearSum(SUN_RCONST(1.0), y, -SUN_RCONST(1.0), y_exact, y_err); + + printf("Error: %" GSYM "\n", NV_Ith_S(y_err, 0)); + + return 0; +} From cb039ea7b1e40508ac44b13425de66e749ad050a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Sat, 31 Aug 2024 21:43:31 -0700 Subject: [PATCH 011/180] Add 3rd order Suzuki method --- .../arkode/arkode_splitting_coefficients.h | 19 +++++--- src/arkode/CMakeLists.txt | 2 + src/arkode/arkode_splitting_coefficients.c | 45 ++++++++++++++++--- src/arkode/arkode_splitting_coefficients.def | 38 ++++++++++++++-- .../arkode_execution_policy_serial.c | 12 ++--- .../ark_test_splitting_coefficients.c | 6 ++- 6 files changed, 98 insertions(+), 24 deletions(-) diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index d38a4acf12..7072dde60f 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -41,15 +41,20 @@ struct SplittingStepCoefficientsMem typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; -/* Splitting names use the convention ARKODE_SPLITTING___ */ +/* Splitting names use the convention + * ARKODE_SPLITTING____ */ typedef enum { ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ - ARKODE_MIN_SPLITTING_NUM = 300, - ARKODE_SPLITTING_LIE_TROTTER_2_1 = ARKODE_MIN_SPLITTING_NUM, - ARKODE_SPLITTING_STRANG_2_2, - ARKODE_SPLITTING_YOSHIDA_2_4, - ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_2_4 + ARKODE_MIN_SPLITTING_NUM = 0, + ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM, + ARKODE_SPLITTING_STRANG_2_2_2, + ARKODE_SPLITTING_OPTIMAL_2_2_2, + ARKODE_SPLITTING_SUZUKI_3_3_2, + ARKODE_SPLITTING_RUTH_3_3_2, + ARKODE_SPLITTING_YOSHIDA_4_4_2, + ARKODE_SPLITTING_YOSHIDA_8_6_2, + ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_8_6_2 } ARKODE_SplittingCoefficientsID; /* Coefficient memory management */ @@ -84,6 +89,8 @@ SplittingStepCoefficients_Parallel(int partitions); SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel(int partitions); SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_ThirdOrderSuzuki(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_TripleJump(int partitions, int order); SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_SuzukiFractal(int partitions, int order); diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index 5938c63dd6..a4f840fd35 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -66,6 +66,8 @@ set(arkode_HEADERS # Add prefix with complete path to the ARKODE header files add_prefix(${SUNDIALS_SOURCE_DIR}/include/arkode/ arkode_HEADERS) +add_subdirectory(execution_policy) + # Create the sundials_arkode library sundials_add_library( sundials_arkode diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index bf1cb8c439..382077abbd 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -225,7 +225,6 @@ const char* SplittingStepCoefficients_IDToName( ---------------------------------------------------------------*/ SplittingStepCoefficients SplittingStepCoefficients_LieTrotter(const int partitions) { - if (partitions < 1) { return NULL; } const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 1, partitions); if (coefficients == NULL) { return NULL; } @@ -255,8 +254,6 @@ SplittingStepCoefficients SplittingStepCoefficients_Strang(const int partitions) ---------------------------------------------------------------*/ SplittingStepCoefficients SplittingStepCoefficients_Parallel(const int partitions) { - if (partitions < 1) { return NULL; } - const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(partitions + 1, 1, partitions); if (coefficients == NULL) { return NULL; } @@ -280,8 +277,6 @@ SplittingStepCoefficients SplittingStepCoefficients_Parallel(const int partition SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel( const int partitions) { - if (partitions < 1) { return NULL; } - const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(2, partitions, partitions); if (coefficients == NULL) { return NULL; } @@ -302,6 +297,42 @@ SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel( return coefficients; } +/*--------------------------------------------------------------- + Routine to construct a 3rd order method of Suzuki of the form + L(p1 h) * L*(p2 h) * L(p3 h) * L*(p4 h) * L(p5 h) + where L is a Lie-Trotter splitting and L* is its adjoint. + Composition is denoted by *. + ---------------------------------------------------------------*/ +SplittingStepCoefficients SplittingStepCoefficients_ThirdOrderSuzuki( + const int partitions) +{ + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_Alloc(1, 2 * partitions - 1, partitions); + if (coefficients == NULL) { return NULL; } + + coefficients->order = 3; + coefficients->alpha[0] = SUN_RCONST(1.0); + + for (int i = 1; i < partitions; i++) + { + for (int j = 0; j < partitions; j++) { + // Constants from https://doi.org/10.1143/JPSJ.61.3015 pg. 3019 + const sunrealtype p1 = SUN_RCONST(0.2683300957817599249569552299254991394812); + const sunrealtype p2 = SUN_RCONST(0.6513314272356399320939424082278836500821); + const sunrealtype p = i + j < partitions ? p1 : (p1 + p2); + + coefficients->beta[0][i][j] = p; + coefficients->beta[0][partitions + i - 1][j] = SUN_RCONST(1.0) - p; + } + } + + for (int i = 0; i < partitions; i++) { + coefficients->beta[0][2 * partitions - 1][i] = SUN_RCONST(1.0); + } + + return coefficients; +} + /*--------------------------------------------------------------- Routine to construct a composition method of the form S(gamma_0 h)^c * S(gamma_1 h) * S(gamma_0)^c @@ -322,7 +353,7 @@ static sunrealtype* const* SplittingStepCoefficients_ComposeStrangHelper( { for (int k = 0; k < partitions; k++) { - beta[j][k] = (partitions - j > k) ? mid : end; + beta[j][k] = (k + j < partitions) ? mid : end; } } @@ -363,7 +394,7 @@ static sunrealtype* const* SplittingStepCoefficients_ComposeStrangHelper( static SplittingStepCoefficients SplittingStepCoefficients_ComposeStrang( const int partitions, const int order, const int composition_stages) { - if (partitions < 1 || order < 2 || order % 2 != 0) + if (order < 2 || order % 2 != 0) { // Only even orders allowed return NULL; diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index 2ae549ced1..cac3c59714 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -23,14 +23,46 @@ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { return NULL; }) -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_2_1, { +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_1_1_2, { return SplittingStepCoefficients_LieTrotter(2); }) -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2, { +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2_2, { return SplittingStepCoefficients_Strang(2); }) -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_2_4, { +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_OPTIMAL_2_2_2, { + const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 2, 2); + coefficients->order = 2; + coefficients->alpha[0] = SUN_RCONST(1.0); + coefficients->beta[0][1][0] = SUN_RCONST(1.0) - SUNRsqrt(SUN_RCONST(0.5)); + coefficients->beta[0][1][1] = SUNRsqrt(SUN_RCONST(0.5)); + coefficients->beta[0][2][0] = SUN_RCONST(1.0); + coefficients->beta[0][2][1] = SUN_RCONST(1.0); + return coefficients; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_SUZUKI_3_3_2, { + return SplittingStepCoefficients_ThirdOrderSuzuki(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_RUTH_3_3_2, { + const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 3, 2); + coefficients->order = 3; + coefficients->alpha[0] = SUN_RCONST(1.0); + coefficients->beta[0][1][0] = SUN_RCONST(1.0); + coefficients->beta[0][1][1] = -SUN_RCONST(1.0) / SUN_RCONST(24.0); + coefficients->beta[0][2][0] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + coefficients->beta[0][2][1] = SUN_RCONST(17.0) / SUN_RCONST(24.0); + coefficients->beta[0][3][0] = SUN_RCONST(1.0); + coefficients->beta[0][3][1] = SUN_RCONST(1.0); + return coefficients; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_4_4_2, { return SplittingStepCoefficients_TripleJump(2, 4); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_8_6_2, { + return SplittingStepCoefficients_TripleJump(2, 6); }) \ No newline at end of file diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index ff367f636a..5f8221498e 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -27,7 +27,7 @@ static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy pol return ARK_SUCCESS; } -static int execute_serial(ARKodeSplittingExecutionPolicy policy, +static int execute_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, ARKExecutionPolicyFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, const int sequential_methods, void* user_data) @@ -42,16 +42,16 @@ static int execute_serial(ARKodeSplittingExecutionPolicy policy, for (int i = 1; i < sequential_methods; i++) { - N_VScale(SUN_RCONST(1), yn, tmp); - int retval = fn(i, tmp, user_data); - if (retval != ARK_SUCCESS) - N_VLinearSum(1, ycur, alpha[i], tmp, ycur); + N_VScale(SUN_RCONST(1.0), yn, tmp); + retval = fn(i, tmp, user_data); + if (retval != ARK_SUCCESS) { return retval; } + N_VLinearSum(SUN_RCONST(1.0), ycur, alpha[i], tmp, ycur); } return ARK_SUCCESS; } -static void free_serial(ARKodeSplittingExecutionPolicy policy) +static void free_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy) { // Nothing needed } diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c index 00c60156eb..7ea1eb2320 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c @@ -144,12 +144,12 @@ int main(int argc, char* argv[]) SplittingStepCoefficients_Free(coefficients); SplittingStepCoefficients_Free(coefficients_copy); - coefficients = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_2_1); + coefficients = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_1_1_2); retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); SplittingStepCoefficients_Free(coefficients); - coefficients = SplittingStepCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_2_1"); + coefficients = SplittingStepCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_1_1_2"); retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); SplittingStepCoefficients_Free(coefficients); @@ -204,5 +204,7 @@ int main(int argc, char* argv[]) printf("%d test failures\n", retval); + SplittingStepCoefficients_Write(SplittingStepCoefficients_ThirdOrderSuzuki(3), stdout); + return retval; } From 08ba24bc617795c78e6230bc7c9ac72556eba01a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Sat, 31 Aug 2024 21:52:23 -0700 Subject: [PATCH 012/180] 3rd order Suzuki bug fix --- src/arkode/arkode_splitting_coefficients.c | 7 +++---- .../arkode/C_serial/ark_test_splitting_coefficients.c | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index 382077abbd..d3137421ad 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -319,10 +319,9 @@ SplittingStepCoefficients SplittingStepCoefficients_ThirdOrderSuzuki( // Constants from https://doi.org/10.1143/JPSJ.61.3015 pg. 3019 const sunrealtype p1 = SUN_RCONST(0.2683300957817599249569552299254991394812); const sunrealtype p2 = SUN_RCONST(0.6513314272356399320939424082278836500821); - const sunrealtype p = i + j < partitions ? p1 : (p1 + p2); - - coefficients->beta[0][i][j] = p; - coefficients->beta[0][partitions + i - 1][j] = SUN_RCONST(1.0) - p; + + coefficients->beta[0][i][j] = i + j < partitions ? p1 : (p1 + p2); + coefficients->beta[0][partitions + i - 1][j] = SUN_RCONST(1.0) - (i + j < partitions ? (p1 + p2) : p1); } } diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c index 7ea1eb2320..180d1c0749 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c @@ -204,7 +204,5 @@ int main(int argc, char* argv[]) printf("%d test failures\n", retval); - SplittingStepCoefficients_Write(SplittingStepCoefficients_ThirdOrderSuzuki(3), stdout); - return retval; } From eacb38e3cf86b5cdd5b259edc06ae5e732f65994 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 2 Sep 2024 10:24:20 -0700 Subject: [PATCH 013/180] Add skeleton docs --- doc/arkode/guide/source/Mathematics.rst | 13 +- .../source/Usage/SplittingStep/Skeleton.rst | 114 ++++++++++++++++++ .../source/Usage/SplittingStep/index.rst | 1 + 3 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 9cda23d12e..72fc4e3957 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -615,10 +615,11 @@ The following algorithmic procedure is used in the Splitting-Step module: #. Set :math:`y_n = \sum_{i=1}^r \alpha_i y_{n,i}` Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number -of sequential methods within the overall operator splitting scheme. Each of the -sequential methods are independent can can be run in parallel. The real -coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` determine the particular -scheme and properties such as the order. +of sequential methods within the overall operator splitting scheme. The +sequential methods have independent flows which are combined in a linear +combination to produce the next step. The real coefficients :math:`\alpha_i` and +:math:`\beta_{i,j,k}` determine the particular scheme and properties such as the +order. An alternative representation of the SplittingStep solution is @@ -637,8 +638,8 @@ and Strang splitting, as well as schemes of arbitrarily high order. Alternatively, users may construct their own coefficients (see TODO). Generally, methods of order three and higher with real coefficients require backward integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. -Currently, a fixed time step must be specified for SplittingStep, but -sub-integrations are free to use adaptive time steps. See TODO for +Currently, a fixed time step must be specified for the outer SplittingStep, but +inner integrators are free to use adaptive time steps. See TODO for additional details. diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst new file mode 100644 index 0000000000..bff9d31edd --- /dev/null +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -0,0 +1,114 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + Based on MRIStep by David J. Gardner @ LLNL + Daniel R. Reynolds @ SMU + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.SplittingStep.Skeleton: + +A skeleton of the user's main program +============================================ + +While SplittingStep usage generally follows the same pattern as the rest of +ARKODE, since it is the composition of other steppers, we summarize the +differences in using SplittingStep here. Steps that are unchanged from the +skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. + +.. index:: SplittingStep user main program + +#. *Initialize parallel or multi-threaded environment, if appropriate.* + +#. *Create the SUNDIALS simulation context object* + +#. *Set problem dimensions, etc.* + +#. *Set vector of initial values* + +#. Create a stepper object for each problem partition + + * If using ARKStep as an inner integrator, create the ARKStep object with + :c:func:`ARKStepCreate` and configure the integrator as desired for + evolving the partition. See sections :numref:`ARKODE.Usage.Skeleton`, + :numref:`ARKODE.Usage.OptionalInputs`, and + :numref:`ARKODE.Usage.ARKStep.OptionalInputs` for details on configuring + ARKStep. + + Once the ARKStep object is setup, create a ``SUNStepper`` object with + :c:func:`ARKStepCreateSUNStepper`. + + * If supplying a user-defined inner integrator, create the ``SUNStepper`` + object as described in section TODO(SBR). + + .. note:: + + When using ARKStep as an inner integrator it is the user's responsibility + to create and configure the integrator. User-specified options regarding + how the integration should be performed (e.g., adaptive vs. fixed time + step, explicit/implicit/ImEx partitioning, algebraic solvers, etc.) will + be respected during evolution of a partition during SplittingStep + integration. + + If a *user_data* pointer needs to be passed to user functions called by + an inner integrator then it should be attached here by calling + :c:func:`ARKodeSetUserData()`. This *user_data* pointer will only be + passed to user-supplied functions that are attached to an inner + integrator. To supply a *user_data* pointer to user-supplied functions + called by the outer integrator the desired pointer should be attached be + calling :c:func:`ARKodeSetUserData()` after creating the SplittingStep + memory below. The *user_data* pointers attached to the inner and outer + integrators may be the same or different depending on what is required by + the user code. + + Specifying a rootfinding problem for an inner integrator is not supported. + Rootfinding problems should be created and initialized with the outer + integrator. See the steps below and :c:func:`ARKodeRootInit()` for more + details. + +#. Create a SplittingStep object for the outer integration + + Create the SplittingStep object by calling :c:func:`SplittingStepCreate`. One + of the inputs to :c:func:`SplittingStepCreate` is an array of ``SUNStepper`` + objects with one to evolve each partition. + +#. Set the SplittingStep step size + + Call :c:func:`ARKodeSetFixedStep()` on the SplittingStep object to specify + the outer time step size. + +#. *Set optional inputs* + +#. *Specify rootfinding problem* + +#. *Advance solution in time* + +#. *Get optional outputs* + +#. *Deallocate memory for solution vector* + +#. Free solver memory + + * If ARKStep was used as the inner IVP integrator, call + :c:func:`SUNStepper_Free` and :c:func:`ARKodeFree` to free the memory + allocated for the fast (inner) integrator. + + * If a user-defined inner integrator was supplied, free the integrator + content and call :c:func:`SUNStepper_Free` to free the ``SUNStepper`` + object. + + * Call :c:func:`ARKodeFree` to free the memory allocated for the + SplittingStep outer integration object. + +#. *Free the SUNContext object* + +#. *Finalize MPI, if used* diff --git a/doc/arkode/guide/source/Usage/SplittingStep/index.rst b/doc/arkode/guide/source/Usage/SplittingStep/index.rst index e94b1f8b97..3c3d1b0dcb 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/index.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/index.rst @@ -27,5 +27,6 @@ are specific to ERKStep. .. toctree:: :maxdepth: 1 + Skeleton User_callable SplittingStepCoefficients From 3ad9763ef9e717032ed408239eef84ec23c862f4 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 2 Sep 2024 10:26:49 -0700 Subject: [PATCH 014/180] Add missing CMake file --- src/arkode/execution_policy/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/arkode/execution_policy/CMakeLists.txt diff --git a/src/arkode/execution_policy/CMakeLists.txt b/src/arkode/execution_policy/CMakeLists.txt new file mode 100644 index 0000000000..ae32570916 --- /dev/null +++ b/src/arkode/execution_policy/CMakeLists.txt @@ -0,0 +1,16 @@ +# --------------------------------------------------------------- +# Programmer(s): Steven B. Roberts @ LLNL +# --------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2002-2024, Lawrence Livermore National Security +# and Southern Methodist University. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# --------------------------------------------------------------- +# CMakeLists.txt file for +# --------------------------------------------------------------- + From a77f98945090dd025b805e2e3069c4d33f2aa682 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 2 Sep 2024 21:36:14 -0700 Subject: [PATCH 015/180] Finish coefficient docs --- doc/arkode/guide/source/Mathematics.rst | 10 +- .../SplittingStepCoefficients.rst | 429 +++++++++++++++++- doc/arkode/guide/source/Usage/index.rst | 5 +- doc/shared/sundials.bib | 70 +++ .../arkode/arkode_splitting_coefficients.h | 8 +- src/arkode/arkode_splitting_coefficients.c | 2 +- src/arkode/arkode_splitting_coefficients.def | 2 +- 7 files changed, 507 insertions(+), 19 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 72fc4e3957..acb41f7172 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -624,16 +624,16 @@ order. An alternative representation of the SplittingStep solution is .. math:: - y_n = \sum_{i=1}^P \alpha_i \left( \phi^1_{\gamma_{i,1,1} h} \circ - \phi^2_{\gamma_{i,1,2} h} \circ \dots \circ \phi^P_{\gamma_{i,1,P} h} \circ - \phi^1_{\gamma_{i,2,1} h} \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \circ - \dots \circ \phi^P_{\gamma_{i,s,P} h} \right) + y_n = \sum_{i=1}^P \alpha_i \left( \phi^P_{\gamma_{i,1,P} h} \circ + \phi^{P-1}_{\gamma_{i,1,P-1} h} \circ \dots \circ \phi^1_{\gamma_{i,1,1} h} + \circ \phi^P_{\gamma_{i,2,P} h} \circ \dots \circ \phi^P_{\gamma_{i,s,P} h} + \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right) (y_{n-1}) where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and :math:`\phi^j_{h}` is the flow map for partition :math:`j`. -SplittingStep provides standard operator splitting methods such as Lie--Trotter +SplittingStep provides standard operator splitting methods such as Lie-Trotter and Strang splitting, as well as schemes of arbitrarily high order. Alternatively, users may construct their own coefficients (see TODO). Generally, methods of order three and higher with real coefficients require backward diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index cf419fab0d..adef211116 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -14,11 +14,428 @@ .. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients: -========================================= -Operator Splitting Coefficients Structure -========================================= +Operator Splitting Coefficients Data Structure +---------------------------------------------- -To store the coefficients representing an operator splitting method, ARKODE -provides the :c:type:`SplittingStepCoefficients` type and several related -utility routines. We use the following notation +SplittingStep supplies several functions to construct operator splitting +coefficients of various orders and partitions. There are also a number of +built-in methods of fixed orders and partitions (see +:numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`). +Finally, a user may construct a custom set of coefficients and attach it with +:c:func:`SplittingStepSetCoefficients`. The operator splitting coefficients are +stored in a :c:func:`SplittingStepCoefficients` object which is a pointer to a +:c:struct:`SplittingStepCoefficientsMem` structure: +.. c:type:: SplittingStepCoefficientsMem *SplittingStepCoefficients + +.. c:struct:: SplittingStepCoefficientsMem + + Structure for storing the coefficients defining an operator splitting method. + + As described in :numref:`ARKODE.Mathematics.SplittingStep`, an operator + splitting method is defined by a vector :math:`\alpha \in \mathbb{R}^{r}` and + a tensor :math:`\beta \in \mathbb{R}^{r \times (s + 1) \times P}`. + + .. c:member:: sunrealtype *alpha + + An array of length ``[sequential_methods]`` containing the weight of each + sequential method used to produce the overall operator splitting solution + + .. c:member:: sunrealtype ***beta + + A three-dimensional array with dimensions + ``[sequential_methods][stages+1][partitions]`` containing the time nodes + of the inner integrations. + + .. c:member:: int sequential_methods + + The number :math:`r` of sequential methods combined to produce the overall + operator splitting solution + + .. c:member:: int stages + + The number :math:`s` of stages + + .. c:member:: int partitions + + The number :math:`P` of partitions in the IVP + + .. c:member:: int order + + The method order of accuracy + + +.. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Functions: + +SplittingStepCoefficients Functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +This section describes the functions for creating and interacting with operator +splitting coefficients. The function prototypes and as well as the relevant +integer constants are defined ``arkode/arkode_splitting_coefficients.h``. + +.. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Functions.Table: +.. table:: SplittingStepCoefficients functions + + +--------------------------------------------------------------+-------------------------------------------------------------+ + | Function name | Description | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LoadCoefficients()` | Load a pre-defined SplittingStepCoefficients by ID | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LoadCoefficientsByName()` | Load a pre-defined SplittingStepCoefficients by name | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_IDToName()` | Convert a pre-defined SplittingStepCoefficients to its name | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LieTrotter()` | Create a Lie-Trotter splitting method | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Strang()` | Create a Strang splitting method | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_SymmetricParallel()` | Create a symmetrization of the Lie-Trotter splitting method | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_ThirdOrderSuzuki()` | Create a third order composition method of Suzuki | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_TripleJump()` | Create an arbitrary order, three-jump composition method | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_SuzukiFractal()` | Create an arbitrary order, five-jump composition method | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Alloc()` | Allocate an empty SplittingStepCoefficient | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Create()` | Create a new SplittingStepCoefficient from coefficients | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a SplittingStepCoefficients | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Free()` | Deallocate a SplittingStepCoefficients | + +--------------------------------------------------------------+-------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Write()` | Write the SplittingStepCoefficients to an output file | + +--------------------------------------------------------------+-------------------------------------------------------------+ + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID method) + + Retrieves specified splitting coefficients. For further information on the + current set of splitting coefficients and their corresponding identifiers, + see + :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. + + + **Arguments:** + * ``method`` -- the splitting coefficients identifier. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * A ``NULL`` pointer if *method* was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficientsByName(const char *method) + + Retrieves specified splitting coefficients. For further information on the + current set of splitting coefficients and their corresponding name, see + :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. + + + **Arguments:** + * ``method`` -- the splitting coefficients identifier. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * A ``NULL`` pointer if *method* was invalid, *method* was + ``"ARKODE_SPLITTING_NONE"``, or an allocation error occurred. + + .. note:: + + This function is case sensitive. + + .. versionadded:: x.y.z + + +.. c:function:: const char* SplittingStepCoefficients_LoadCoefficientsByName(ARKODE_SplittingCoefficientsID method) + + Converts specified splitting coefficients ID to a string of the same name. + For further information on the current set of splitting coefficients and + their corresponding name, see + :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. + + **Arguments:** + * *method* -- the splitting coefficients identifier. + + **Return value:** + * The name associated with *method*. + * ``NULL`` pointer if *method* was invalid. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_LieTrotter(int partitions) + + Create the coefficients for the first order Lie-Trotter splitting + + .. math:: + y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} + \circ \dots \circ \phi^1_{h} \right) (y_{n-1}) + :label: ARKODE_Lie-Trotter + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Strang(int partitions) + + Create the coefficients for the second order Strang splitting + + .. math:: + y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), + :label: ARKODE_Strang + + where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and + :math:`L*_h = L^{-1}_{-h}` is its adjoint. + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Parallel(int partitions) + + Create the coefficients for the first order splitting method + + .. math:: + y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + + (1 - p) y_{n-1}, + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel(int partitions) + + Create the coefficients for the second order, symmetrized Lie-Trotter + splitting + + .. math:: + y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), + + where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and + :math:`L^*_h = L^{-1}_{-h}` is its adjoint. + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_ThirdOrderSuzuki(int partitions) + + Create the coefficients for a splitting method of Suzuki :cite:p:`Suzuki:92` + + .. math:: + y_n = \left( L_{p_1 h} \circ L^*_{p_2 h} \circ L_{p_3 h} \circ L^*_{p_4 h} + \circ L_{p_5 h} \right) (y_{n-1}), + + where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and + :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters + :math:`p_1, \dots, p_5` are selected to give third order. + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_TripleJump(int partitions, int order) + + Create the coefficients for the triple jump splitting method + :cite:p:`CrGo:89` + + .. math:: + \begin{align*} + T_h^{[2]} &= S, \\ + T_h^{[i+2]} &= T_{\gamma_1 h}^{[i]} \circ T_{(1 - 2 \gamma_1) h}^{[i]} + \circ T_{\gamma_1 h}^{[i]}, \\ + y_n &= T_h^{[order]}(y_{n-1}), + \end{align*} + + where :math:`S` is the Strang splitting :eq:`ARKODE_Stang` and parameter + :math:`\gamma_1` selected to increase the order by two each recursion. + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + * *order* -- A positive even number for the method order of accuracy. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` or ``order`` was invalid or an allocation + error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_SuzukiFractal(int partitions, int order) + + Create the coefficients for the quintuple jump splitting method + :cite:p:`Suzuki:90` + + .. math:: + \begin{align*} + Q_h^{[2]} &= S, \\ + Q_h^{[i+2]} &= Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]} \circ + Q_{(1 - 4 \gamma_1) h}^i \circ Q_{\gamma_1 h}^{[i]} \circ + Q_{\gamma_1 h}^{[i]}, \\ + y_n &= Q_h^{[order]}(y_{n-1}), + \end{align*} + + where :math:`S` is the Strang splitting :eq:`ARKODE_Stang` and parameter + :math:`\gamma_1` selected to increase the order by two each recursion. + + **Arguments:** + * *partitions* -- The number :math:`P > 1` of partitions in the IVP. + * *order* -- A positive even number for the method order of accuracy. + + **Return value:** + * A :c:type:`SplittingStepCoefficients` structure if successful. + * ``NULL`` if ``partitions`` or ``order`` was invalid or an allocation + error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Alloc(int sequential_methods, int stages, int partitions) + + Allocates an empty SplittingStepCoefficients. + + **Arguments:** + * *sequential_methods* -- The number :math:`r` of sequential methods + combined to produce the overall operator splitting solution. + * *stages* -- The number :math:`s` of stages. + * *partitions* -- The number :math:`P` of partitions in the IVP. + + **Return value:** + * An :c:type:`SplittingStepCoefficients` structure if successful. + * A ``NULL`` pointer if *sequential_methods*, *stages* or *partitions* was + invalid or an allocation error occurred. + + .. versionadded:: x.y.z + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Create(int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta) + + Allocates a SplittingStepCoefficients and fills it with the given values. + + **Arguments:** + * *sequential_methods* -- The number :math:`r` of sequential methods + combined to produce the overall operator splitting solution. + * *stages* -- The number :math:`s` of stages. + * *partitions* -- The number :math:`P` of partitions in the IVP. + * *order* -- The method order of accuracy. + * *alpha* -- An array of length ``sequential_methods`` containing the + weight of each sequential method used to produce the overall operator + splitting solution. + * *beta* -- An array of length + ``sequential_methods * (stages+1) * partitions`` containing the time nodes + of the inner integrations in the order + + .. math:: + \beta_{1,0,1}, \dots, \beta_{1,0,P}, \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, \beta_{2,0,1}, \dots, \beta_{r,s,P}. + + **Return value:** + * An :c:type:`SplittingStepCoefficients` structure if successful. + * A ``NULL`` pointer if an argument was invalid or an allocation error + occurred. + + +.. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients) + + Creates copy of the given splitting coefficients. + + **Arguments:** + * ``coefficients`` -- The splitting coefficients to copy. + + **Return value:** + * An :c:type:`SplittingStepCoefficients` structure if successful. + * A ``NULL`` pointer if an allocation error occurred. + + +.. c:function:: void SplittingStepCoefficients_Free(SplittingStepCoefficients coefficients) + + Deallocate the splitting coefficients memory. + + **Arguments:** + * ``coefficients`` -- The splitting coefficients. + + +.. c:function:: void SplittingStepCoefficients_Write(SplittingStepCoefficients coefficients, FILE* outfile) + + Write the splitting coefficients to the provided file pointer. + + **Arguments:** + * ``coefficients`` -- The splitting coefficients. + * ``outfile`` -- Pointer to use for printing the splitting coefficients. + + .. note:: + + The *outfile* argument can be ``stdout`` or ``stderr``, or it may point to + a specific file created using ``fopen``. + + +.. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients: + +Operator Splitting Coefficients +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SplittingStep currently provides several pre-defined coefficients for problems +with two partitions. We list the identifiers, order of accuracy, and relevant +references for each in the table below. We use the naming convention + +.. code-block:: text + + ___ + +Each of the splitting coefficients that are packaged with SplittingStep are +specified by a unique ID having type: + +.. c:type:: int ARKODE_SplittingCoefficientsID + +with values specified for each method below (e.g., +``ARKODE_SPLITTING_LIE_TROTTER_1_1_2``). + +.. table:: Operator splitting coefficients. + + ====================================== ===== ===================== + Table name Order Reference + ====================================== ===== ===================== + ``ARKODE_SPLITTING_LIE_TROTTER_1_1_2`` 1 + ``ARKODE_SPLITTING_STRANG_2_2_2`` 2 :cite:p:`Strang:68` + ``ARKODE_SPLITTING_BEST_2_2_2`` 2 :cite:p:`AuHoKeKo:16` + ``ARKODE_SPLITTING_SUZUKI_3_3_2`` 3 :cite:p:`Suzuki:92` + ``ARKODE_SPLITTING_RUTH_3_3_2`` 3 :cite:p:`Ruth:93` + ``ARKODE_SPLITTING_YOSHIDA_4_4_2`` 4 :cite:p:`Yoshida:90` + ``ARKODE_SPLITTING_YOSHIDA_8_6_2`` 6 :cite:p:`Yoshida:90` + ====================================== ===== ===================== diff --git a/doc/arkode/guide/source/Usage/index.rst b/doc/arkode/guide/source/Usage/index.rst index 4d7ba36cb4..1ef8ae5df6 100644 --- a/doc/arkode/guide/source/Usage/index.rst +++ b/doc/arkode/guide/source/Usage/index.rst @@ -37,8 +37,9 @@ ARKODE's time stepping modules, including "relaxation" methods and preconitioners. Following our discussion of these commonalities, we separately discuss the usage details that that are specific to each of ARKODE's time stepping modules: :ref:`ARKStep `, -:ref:`ERKStep `, :ref:`SPRKStep ` -and :ref:`MRIStep `. +:ref:`ERKStep `, :ref:`SPRKStep `, +:ref:`SplittingStep `, and +:ref:`MRIStep `. ARKODE also uses various input and output constants; these are defined as needed throughout this chapter, but for convenience the full list is provided diff --git a/doc/shared/sundials.bib b/doc/shared/sundials.bib index b000f2c3dc..4ca73e1c23 100644 --- a/doc/shared/sundials.bib +++ b/doc/shared/sundials.bib @@ -1689,6 +1689,20 @@ @inproceedings{Caliper:2016 % FROM ARKODE %--------------------------------------------------------- +@article{AuHoKeKo:16, + title = {Practical splitting methods for the adaptive integration of nonlinear evolution equations. {P}art {I}: {C}onstruction of optimized schemes and pairs of schemes}, + volume = {57}, + ISSN = {1572-9125}, + DOI = {10.1007/s10543-016-0626-9}, + number = {1}, + journal = {BIT Numerical Mathematics}, + publisher = {Springer Science and Business Media LLC}, + author = {Auzinger, Winfried and Hofst\"{a}tter, Harald and Ketcheson, David and Koch, Othmar}, + year = {2016}, + month = jul, + pages = {55–74} +} + @article{Bank:85, author = {Bank, R.E. and Coughran, W.M. and Fichtner, W. and Grosse, E.H. and Rose, D.J. and Smith, R.K.}, journal = {IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems}, @@ -1772,6 +1786,20 @@ @article{ChiRen:21 doi = {10.1137/20M1354349} } +@article{CrGo:89, + title = {Higher-order hybrid Monte Carlo algorithms}, + author = {Creutz, Michael and Gocksch, Andreas}, + journal = {Phys. Rev. Lett.}, + volume = {63}, + issue = {1}, + pages = {9--12}, + numpages = {0}, + year = {1989}, + month = {Jul}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevLett.63.9} +} + @article{Diele:11, year = {2011}, title = {{Explicit symplectic partitioned Runge–Kutta–Nyström methods for non-autonomous dynamics}}, @@ -2141,6 +2169,48 @@ @article{Sof:04 doi = {10.1016/j.mcm.2005.01.010} } +@article{Strang:68, + title = {On the Construction and Comparison of Difference Schemes}, + volume = {5}, + ISSN = {1095-7170}, + DOI = {10.1137/0705041}, + number = {3}, + journal = {SIAM Journal on Numerical Analysis}, + publisher = {Society for Industrial & Applied Mathematics (SIAM)}, + author = {Strang, Gilbert}, + year = {1968}, + month = sep, + pages = {506–517} +} + +@article{Suzuki:90, + title = {Fractal decomposition of exponential operators with applications to many-body theories and {M}onte {C}arlo simulations}, + volume = {146}, + ISSN = {0375-9601}, + DOI = {10.1016/0375-9601(90)90962-n}, + number = {6}, + journal = {Physics Letters A}, + publisher = {Elsevier BV}, + author = {Suzuki, Masuo}, + year = {1990}, + month = jun, + pages = {319–323} +} + +@article{Suzuki:92, + title = {General Nonsymmetric Higher-Order Decomposition of Exponential Operators and Symplectic Integrators}, + volume = {61}, + ISSN = {1347-4073}, + DOI = {10.1143/jpsj.61.3015}, + number = {9}, + journal = {Journal of the Physical Society of Japan}, + publisher = {Physical Society of Japan}, + author = {Suzuki, Masuo}, + year = {1992}, + month = sep, + pages = {3015–3019} +} + @article{Ver:10, author = {Verner, J.H}, title = {Numerically optimal {Runge–Kutta} pairs with interpolants}, diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index 7072dde60f..bee23fc675 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -1,4 +1,4 @@ -/* TODO: merge this header into arkode_splittingstep.h? MRI uses one header, but ARK uses two */ +/* TODO: merge this header into arkode_splittingstep.h? MRI uses one header, but ARK/SPRK uses two */ /* ----------------------------------------------------------------------------- * Programmer(s): Steven B. Roberts @ LLNL @@ -49,7 +49,7 @@ typedef enum ARKODE_MIN_SPLITTING_NUM = 0, ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM, ARKODE_SPLITTING_STRANG_2_2_2, - ARKODE_SPLITTING_OPTIMAL_2_2_2, + ARKODE_SPLITTING_BEST_2_2_2, ARKODE_SPLITTING_SUZUKI_3_3_2, ARKODE_SPLITTING_RUTH_3_3_2, ARKODE_SPLITTING_YOSHIDA_4_4_2, @@ -65,9 +65,9 @@ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); -SUNDIALS_EXPORT void SplittingStepCoefficients_Free(SplittingStepCoefficients B); +SUNDIALS_EXPORT void SplittingStepCoefficients_Free(SplittingStepCoefficients coefficients); SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_Copy(SplittingStepCoefficients B); +SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients); SUNDIALS_EXPORT void SplittingStepCoefficients_Write( SplittingStepCoefficients coefficients, FILE* outfile); diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index d3137421ad..f46112cf8a 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -137,7 +137,7 @@ void SplittingStepCoefficients_Free(const SplittingStepCoefficients coefficients Routine to create a copy of splitting coefficients ---------------------------------------------------------------*/ SplittingStepCoefficients SplittingStepCoefficients_Copy( - SplittingStepCoefficients coefficients) + const SplittingStepCoefficients coefficients) { if (coefficients == NULL) { return NULL; } diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index cac3c59714..5de86c65db 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -31,7 +31,7 @@ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2_2, { return SplittingStepCoefficients_Strang(2); }) -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_OPTIMAL_2_2_2, { +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_BEST_2_2_2, { const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 2, 2); coefficients->order = 2; coefficients->alpha[0] = SUN_RCONST(1.0); From 082e5ee9517d7038269519452f4a1639c795f67e Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 10:14:00 -0700 Subject: [PATCH 016/180] Clear up execution policy structure --- .../Usage/SplittingStep/User_callable.rst | 1 + .../source/Usage/SplittingStep/index.rst | 10 ++-- include/arkode/arkode_execution_policy.h | 4 +- include/arkode/arkode_splittingstep.h | 2 +- .../arkode_execution_policy_serial.h | 4 +- src/arkode/CMakeLists.txt | 5 +- src/arkode/arkode_splittingstep.c | 6 +-- .../arkode_splittingstep_executionpolicy.c | 50 +------------------ src/arkode/arkode_splittingstep_impl.h | 2 +- src/arkode/execution_policy/CMakeLists.txt | 16 ------ .../arkode_execution_policy_serial.c | 18 ++++--- 11 files changed, 28 insertions(+), 90 deletions(-) delete mode 100644 src/arkode/execution_policy/CMakeLists.txt diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index eab450389d..e07fbbb7ce 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -76,3 +76,4 @@ SplittingStep initialization functions **Example codes:** * ``examples/arkode/C_serial/TODO.c`` + * ``examples/arkode/C_serial/TODO.c`` diff --git a/doc/arkode/guide/source/Usage/SplittingStep/index.rst b/doc/arkode/guide/source/Usage/SplittingStep/index.rst index 3c3d1b0dcb..1a8719e36f 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/index.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/index.rst @@ -18,11 +18,11 @@ Using the SplittingStep time-stepping module ============================================ -This section is concerned with the use of the SplittingStep time-stepping -module for the solution of initial value problems (IVPs) in a C or C++ -language setting. Usage of ERKStep follows that of the rest of ARKODE, -and so in this section we primarily focus on those usage aspects that -are specific to ERKStep. +This section is concerned with the use of the SplittingStep time-stepping module +for the solution of initial value problems (IVPs) in a C or C++ language +setting. Usage of SplittingStep follows that of the rest of ARKODE, and so in +this section we primarily focus on those usage aspects that are specific to +SplittingStep. .. toctree:: :maxdepth: 1 diff --git a/include/arkode/arkode_execution_policy.h b/include/arkode/arkode_execution_policy.h index 18321ca05c..0a255279c4 100644 --- a/include/arkode/arkode_execution_policy.h +++ b/include/arkode/arkode_execution_policy.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * TODO + * This header defines execution policy data structures and functions. * ---------------------------------------------------------------------------*/ #ifndef ARKODE_EXECUTION_POLICY_H_ @@ -48,4 +48,4 @@ SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( } #endif -#endif \ No newline at end of file +#endif diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 8b9f86d88d..7119ba9246 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This is the header file for the ARKODE SplittingStep module. *--------------------------------------------------------------*/ #ifndef ARKODE_SPLITTINGSTEP_H_ diff --git a/include/arkode/execution_policy/arkode_execution_policy_serial.h b/include/arkode/execution_policy/arkode_execution_policy_serial.h index 2f6d20b2a4..e43586541d 100644 --- a/include/arkode/execution_policy/arkode_execution_policy_serial.h +++ b/include/arkode/execution_policy/arkode_execution_policy_serial.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * TODO + * The header file for the serial execution policy * ---------------------------------------------------------------------------*/ #ifndef ARKODE_EXECUTION_POLICY_SERIAL_H_ @@ -24,7 +24,7 @@ extern "C" { #endif SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy -ARKodeSplittingExecutionPolicy_Serial(); +ARKodeSplittingExecutionPolicy_New_Serial(); #ifdef __cplusplus } diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index a4f840fd35..7caaddf7c6 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -45,7 +45,8 @@ set(arkode_SOURCES arkode_sprkstep.c arkode_sprk.c arkode_user_controller.c - arkode.c) + arkode.c + execution_policy/arkode_execution_policy_serial.c) # Add variable arkode_HEADERS with the exported ARKODE header files set(arkode_HEADERS @@ -66,8 +67,6 @@ set(arkode_HEADERS # Add prefix with complete path to the ARKODE header files add_prefix(${SUNDIALS_SOURCE_DIR}/include/arkode/ arkode_HEADERS) -add_subdirectory(execution_policy) - # Create the sundials_arkode library sundials_add_library( sundials_arkode diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 8aff06e87a..72a3a2c14e 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -88,7 +88,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) if (step_mem->policy == NULL) { - step_mem->policy = ARKodeSplittingExecutionPolicy_Serial(); + step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); if (step_mem->policy == NULL) { if (step_mem->coefficients == NULL) { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, @@ -161,7 +161,7 @@ static int splittingStep_Stage(const int i, const N_Vector y, void* const user_d } const SUNStepper stepper = step_mem->steppers[k]; - SUNErrCode err = stepper->ops->reset(stepper, t_start, y, NULL); + SUNErrCode err = stepper->ops->reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return err; } err = stepper->ops->setstoptime(stepper, t_end); @@ -169,7 +169,7 @@ static int splittingStep_Stage(const int i, const N_Vector y, void* const user_d sunrealtype tret = 0; int stop_reason = 0; - err = SUNStepper_Evolve(stepper, t_start, t_end, y, NULL, &tret, &stop_reason); + err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret, &stop_reason); step_mem->n_stepper_evolves++; if (err != SUN_SUCCESS) { return err; } diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c index 66179aa268..824559e2dd 100644 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This is the implementation file for execution policy. *--------------------------------------------------------------*/ #include @@ -20,54 +20,6 @@ #include "sundials_macros.h" -static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, - SUNDIALS_MAYBE_UNUSED const N_Vector y, - SUNDIALS_MAYBE_UNUSED const int sequential_methods) -{ - // Nothing needed - return ARK_SUCCESS; -} - -static int execute_serial(ARKodeSplittingExecutionPolicy policy, - ARKExecutionPolicyFn fn, N_Vector yn, N_Vector ycur, - N_Vector tmp, sunrealtype* alpha, - const int sequential_methods, void* user_data) -{ - N_VScale(1, yn, ycur); - int retval = fn(0, ycur, user_data); - if (retval != ARK_SUCCESS) { return retval; } - - if (alpha[0] != SUN_RCONST(1.0)) { - N_VScale(alpha[0], ycur, ycur); - } - - for (int i = 1; i < sequential_methods; i++) - { - N_VScale(SUN_RCONST(1.0), yn, tmp); - retval = fn(i, tmp, user_data); - if (retval != ARK_SUCCESS) { return retval; } - N_VLinearSum(SUN_RCONST(1.0), ycur, alpha[i], tmp, ycur); - } - - return ARK_SUCCESS; -} - -static void free_serial(ARKodeSplittingExecutionPolicy policy) -{ - // Nothing needed -} - -ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() -{ - ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); - if (policy == NULL) { return NULL; } - policy->setup = setup_serial; - policy->execute = execute_serial; - policy->free = free_serial; - policy->data = NULL; - return policy; -} - void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) { if (policy != NULL) diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index f955086ca6..59d2c6b8f9 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This header defines the step memory for SplittingStep. *--------------------------------------------------------------*/ #ifndef ARKODE_SPLITTINGSTEP_IMPL_H_ diff --git a/src/arkode/execution_policy/CMakeLists.txt b/src/arkode/execution_policy/CMakeLists.txt deleted file mode 100644 index ae32570916..0000000000 --- a/src/arkode/execution_policy/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Steven B. Roberts @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2024, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for -# --------------------------------------------------------------- - diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index 5f8221498e..9a0217aae0 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -11,15 +11,17 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * TODO + * This is the implementation file for the serial execution + * policy. *--------------------------------------------------------------*/ #include #include +#include #include "sundials_macros.h" -static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, +static int setup_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, SUNDIALS_MAYBE_UNUSED const N_Vector y, SUNDIALS_MAYBE_UNUSED const int sequential_methods) { @@ -27,10 +29,10 @@ static int setup_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy pol return ARK_SUCCESS; } -static int execute_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy, - ARKExecutionPolicyFn fn, N_Vector yn, N_Vector ycur, - N_Vector tmp, sunrealtype* alpha, - const int sequential_methods, void* user_data) +static int execute_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, + const ARKExecutionPolicyFn fn, const N_Vector yn, const N_Vector ycur, + const N_Vector tmp, sunrealtype* const alpha, + const int sequential_methods, void* const user_data) { N_VScale(1, yn, ycur); int retval = fn(0, ycur, user_data); @@ -51,12 +53,12 @@ static int execute_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy p return ARK_SUCCESS; } -static void free_serial(SUNDIALS_MAYBE_UNUSED ARKodeSplittingExecutionPolicy policy) +static void free_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy) { // Nothing needed } -ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_Serial() +ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial() { ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); if (policy == NULL) { return NULL; } From a3dfce71ad10ef1a21ad64887715646cba4b0808 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 10:48:17 -0700 Subject: [PATCH 017/180] Make helper function for default integrator --- src/arkode/arkode_splittingstep.c | 45 +++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 72a3a2c14e..98462142ad 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -24,8 +24,6 @@ #include "arkode_mristep_impl.h" #include "arkode_splittingstep_impl.h" -#define DEFAULT_ORDER 2 - static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, const char* const fname, ARKodeSplittingStepMem* const step_mem) @@ -64,6 +62,36 @@ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; } +static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, const ARKodeSplittingStepMem step_mem) +{ + if (step_mem->coefficients == NULL) { + return ARK_SUCCESS; + } + + if (step_mem->order <= 0) { /* Default to order 2 Strang splitting */ + step_mem->coefficients = SplittingStepCoefficients_Strang(step_mem->partitions); + } else if (step_mem->order == 1) { + step_mem->coefficients = SplittingStepCoefficients_LieTrotter(step_mem->partitions); + } else if (step_mem->order == 3) { + step_mem->coefficients = SplittingStepCoefficients_ThirdOrderSuzuki(step_mem->partitions); + } else if (step_mem->order % 2 == 0) { + step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order); + } else { + const int new_order = step_mem->order + 1; + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "No splitting method at requested order, using q=%i.", new_order); + step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, new_order); + } + + if (step_mem->coefficients == NULL) { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, + __FILE__, "Failed to allocate splitting coefficients"); + return ARK_MEM_FAIL; + } + + return ARK_SUCCESS; +} + static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) { ARKodeSplittingStepMem step_mem = NULL; @@ -76,19 +104,14 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) /* initializations/checks for (re-)initialization call */ if (init_type == FIRST_INIT) { - if (step_mem->coefficients == NULL) - { - step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order <= 1 ? DEFAULT_ORDER : (step_mem->order + (step_mem->order % 2))); - if (step_mem->coefficients == NULL) { - arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, - __FILE__, "Failed to allocate splitting coefficients"); - return ARK_MEM_FAIL; - } + retval = splittingStep_SetCoefficients(ark_mem, step_mem); + if (retval != ARK_SUCCESS) { + return retval; } if (step_mem->policy == NULL) { - step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); + step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); if (step_mem->policy == NULL) { if (step_mem->coefficients == NULL) { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, From 2255ff8923826514233883b3221c8cf6766eca2d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 14:24:38 -0700 Subject: [PATCH 018/180] Add splitting step comments --- src/arkode/arkode_splittingstep.c | 102 +++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 10 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 98462142ad..c9710a6cf2 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -38,6 +38,10 @@ static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Shortcut routine to unpack ark_mem and step_mem structures from + void* pointer. If either is missing it returns ARK_MEM_NULL. + ---------------------------------------------------------------*/ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, const char* const fname, ARKodeMem* const ark_mem, @@ -57,26 +61,31 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, static sunbooleantype splittingStep_CheckNVector(const N_Vector y) { - // TODO: check all ops are correct + // TODO(SBR): check all ops are correct return y->ops->nvclone != NULL && y->ops->nvdestroy != NULL && y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; } +/*--------------------------------------------------------------- + This routine determines the splitting coefficients to use, + based on the desired accuracy. + ---------------------------------------------------------------*/ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, const ARKodeSplittingStepMem step_mem) { if (step_mem->coefficients == NULL) { return ARK_SUCCESS; } - if (step_mem->order <= 0) { /* Default to order 2 Strang splitting */ - step_mem->coefficients = SplittingStepCoefficients_Strang(step_mem->partitions); - } else if (step_mem->order == 1) { + if (step_mem->order <= 1) { + /* Lie-Trotter is the default (order < 1) */ step_mem->coefficients = SplittingStepCoefficients_LieTrotter(step_mem->partitions); } else if (step_mem->order == 3) { step_mem->coefficients = SplittingStepCoefficients_ThirdOrderSuzuki(step_mem->partitions); } else if (step_mem->order % 2 == 0) { + /* Triple jump only works for even order */ step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order); } else { + /* Bump the order up to be even but with an error */ const int new_order = step_mem->order + 1; arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, "No splitting method at requested order, using q=%i.", new_order); @@ -92,6 +101,17 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, const ARKodeSp return ARK_SUCCESS; } +/*--------------------------------------------------------------- + This routine is called just prior to performing internal time + steps (after all user "set" routines have been called) from + within arkInitialSetup. + + With initialization types FIRST_INIT this routine: + - sets/checks the splitting coefficients to be used + - sets/checks the execution policy to be used + + With other initialization types, this routine does nothing. + ---------------------------------------------------------------*/ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) { ARKodeSplittingStepMem step_mem = NULL; @@ -129,6 +149,27 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } +/*------------------------------------------------------------------------------ + This is just a wrapper to call the user-supplied RHS function, + f^1(t,y) + f^2(t,y) + ... + f^P(t,y). + + This will be called in one of three 'modes': + + ARK_FULLRHS_START -> called at the beginning of a simulation i.e., at + (tn, yn) = (t0, y0) or (tR, yR) + + ARK_FULLRHS_END -> called at the end of a successful step i.e, at + (tcur, ycur) or the start of the subsequent step i.e., + at (tn, yn) = (tcur, ycur) from the end of the last + step + + ARK_FULLRHS_OTHER -> called elsewhere (e.g. for dense output) + + In SplittingStep, we accumulate the RHS functions in ARK_FULLRHS_OTHER mode. + Generally, inner steppers will not have the correct yn when this function is + called and will not be able to reuse a function evaluation since their state + resets at the next ARKodeEvolve call. + ----------------------------------------------------------------------------*/ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const N_Vector y, const N_Vector f, SUNDIALS_MAYBE_UNUSED const int mode) @@ -160,7 +201,10 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return ARK_SUCCESS; } -static int splittingStep_Stage(const int i, const N_Vector y, void* const user_data) +/*--------------------------------------------------------------- + This routine performs a sequential operator splitting method + ---------------------------------------------------------------*/ +static int splittingStep_SequentialMethod(const int i, const N_Vector y, void* const user_data) { ARKodeMem ark_mem = (ARKodeMem)user_data; ARKodeSplittingStepMem step_mem = NULL; @@ -203,6 +247,10 @@ static int splittingStep_Stage(const int i, const N_Vector y, void* const user_d return ARK_SUCCESS; } + +/*--------------------------------------------------------------- + This routine performs a single step of the splitting method. + ---------------------------------------------------------------*/ static int splittingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const dsmPtr, int* const nflagPtr) { @@ -215,16 +263,19 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const ds const SplittingStepCoefficients coefficients = step_mem->coefficients; - return step_mem->policy->execute(step_mem->policy, splittingStep_Stage, + return step_mem->policy->execute(step_mem->policy, splittingStep_SequentialMethod, ark_mem->yn, ark_mem->ycur, ark_mem->tempv1, coefficients->alpha, coefficients->sequential_methods, ark_mem); } +/*--------------------------------------------------------------- + Prints integrator statistics + ---------------------------------------------------------------*/ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfile, const SUNOutputFormat fmt) { - // TODO: update when https://github.com/LLNL/sundials/pull/517 merged + // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } @@ -245,7 +296,9 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outf return ARK_SUCCESS; } - +/*--------------------------------------------------------------- + Outputs all solver parameters to the provided file pointer. + ---------------------------------------------------------------*/ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp) { ARKodeSplittingStepMem step_mem = NULL; @@ -258,6 +311,9 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp return ARK_SUCCESS; } +/*--------------------------------------------------------------- + This routine resizes the memory within the SplittingStep module. + ---------------------------------------------------------------*/ static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED const N_Vector ynew, SUNDIALS_MAYBE_UNUSED const sunrealtype hscale, @@ -265,9 +321,14 @@ static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, SUNDIALS_MAYBE_UNUSED void* const resize_data) { + /* Nothing to do since the step_mem has no vectors. Users are responsible for + * resizing the SUNSteppers. */ return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Frees all SplittingStep memory. + ---------------------------------------------------------------*/ static void splittingStep_Free(const ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; @@ -284,6 +345,10 @@ static void splittingStep_Free(const ARKodeMem ark_mem) ark_mem->step_mem = NULL; } +/*--------------------------------------------------------------- + This routine outputs the memory from the SplittingStep + structure to a specified file pointer (useful when debugging). + ---------------------------------------------------------------*/ static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) { ARKodeSplittingStepMem step_mem = NULL; @@ -303,6 +368,9 @@ static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) SplittingStepCoefficients_Write(step_mem->coefficients, outfile); } +/*--------------------------------------------------------------- + Specifies the method order + ---------------------------------------------------------------*/ static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) { ARKodeSplittingStepMem step_mem = NULL; @@ -318,6 +386,11 @@ static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Resets all SplittingStep optional inputs to their default + values. Does not change problem-defining function pointers or + user_data pointer. + ---------------------------------------------------------------*/ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = NULL; @@ -337,6 +410,9 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Creates the SplittingStep integrator + ---------------------------------------------------------------*/ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, const sunrealtype t0, const N_Vector y0, const SUNContext sunctx) { @@ -380,7 +456,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, } /* Create ark_mem structure and set default values */ - ARKodeMem ark_mem = arkCreate(sunctx); + const ARKodeMem ark_mem = arkCreate(sunctx); if (ark_mem == NULL) { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, @@ -388,7 +464,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, return (NULL); } - ARKodeSplittingStepMem step_mem = + const ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)malloc(sizeof(*step_mem)); if (step_mem == NULL) { @@ -450,6 +526,9 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, return ark_mem; } +/*--------------------------------------------------------------- + Sets the SplittingStep coefficients. + ---------------------------------------------------------------*/ int SplittingStep_SetCoefficients(void* arkode_mem, SplittingStepCoefficients coefficients) { @@ -485,6 +564,9 @@ int SplittingStep_SetCoefficients(void* arkode_mem, return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Sets the exection policy. + ---------------------------------------------------------------*/ int SplittingStep_SetExecutionPolicy(void* arkode_mem, ARKodeSplittingExecutionPolicy policy) { From 4a7bd60c12a0c77b40de23e5310a205da0731117 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 16:28:26 -0700 Subject: [PATCH 019/180] Comments in analytic splitting example --- .../arkode/C_serial/ark_analytic_splitting.c | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_splitting.c b/examples/arkode/C_serial/ark_analytic_splitting.c index 78c2c55ae1..f35dbd7555 100644 --- a/examples/arkode/C_serial/ark_analytic_splitting.c +++ b/examples/arkode/C_serial/ark_analytic_splitting.c @@ -1,5 +1,5 @@ /*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU + * Programmer(s): Steven B. Roberts @ LLNL *--------------------------------------------------------------- * SUNDIALS Copyright Start * Copyright (c) 2002-2024, Lawrence Livermore National Security @@ -50,7 +50,7 @@ typedef struct sunrealtype lambda; } UserData; - +/* RHS for f^1(t, y) = -lambda * y */ static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) { sunrealtype lambda = ((UserData*) user_data)->lambda; @@ -58,12 +58,14 @@ static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* return 0; } +/* RHS for f^2(t, y) = y^2 */ static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) { N_VProd(y, y, ydot); return 0; } +/* Compute the exact analytic solution */ static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, const UserData* const user_data) { N_Vector sol = N_VClone(y0); @@ -72,6 +74,7 @@ static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, const UserDat NV_Ith_S(sol, 0) = lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); return sol; } + /* Check function return value... opt == 0 means SUNDIALS function allocates memory so check if returned NULL pointer @@ -118,11 +121,11 @@ static int check_flag(void* flagvalue, const char* funcname, int opt) int main() { /* Problem parameters */ - const sunrealtype t0 = SUN_RCONST(0.0); - const sunrealtype tf = SUN_RCONST(1.0); - const sunrealtype dt = SUN_RCONST(0.01); - const sunrealtype dt_linear = dt / 5; - const sunrealtype dt_nonlinear = dt / 10; + const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ + const sunrealtype tf = SUN_RCONST(1.0); /* final time */ + const sunrealtype dt = SUN_RCONST(0.01); /* operator splitting time step */ + const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ + const sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ UserData user_data = { .lambda = SUN_RCONST(2.0) @@ -143,6 +146,7 @@ int main() printf("\nAnalytical ODE test problem:\n"); printf(" lambda = %" GSYM "\n", user_data.lambda); + /* Create the integrator for the linear partition */ void *linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); if (check_flag(linear_mem, "N_VNew_Serial", 0)) { return 1; } @@ -152,32 +156,46 @@ int main() flag = ARKodeSetFixedStep(linear_mem, dt_linear); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + /* Create the integrator for the nonlinear partition */ void *nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); if (check_flag(nonlinear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetFixedStep(nonlinear_mem, dt_nonlinear); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + /* Create SUNSteppers out of the integrators */ SUNStepper steppers[2]; ARKStepCreateSUNStepper(linear_mem, &steppers[0]); ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); + /* Create the operator splitting method */ void *splitting_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); if (check_flag(splitting_mem, "SplittingStepCreate", 0)) { return 1; } flag = ARKodeSetFixedStep(splitting_mem, dt); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + /* Compute the operator splitting solution */ sunrealtype tret; flag = ARKodeEvolve(splitting_mem, tf, y, &tret, ARK_NORMAL); if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } + /* Print the numerical error */ N_Vector y_err = N_VClone(y); if (check_flag(y_err, "N_VClone", 0)) { return 1; } - N_VLinearSum(SUN_RCONST(1.0), y, -SUN_RCONST(1.0), y_exact, y_err); - - printf("Error: %" GSYM "\n", NV_Ith_S(y_err, 0)); + printf("Error: %" GSYM "\n", N_VMaxNorm(y_err)); + + /* Free memory */ + N_VDestroy(y); + N_VDestroy(y_exact); + N_VDestroy(y_err); + ARKodeFree(&linear_mem); + SUNStepper_Destroy(&steppers[0]); + ARKodeFree(&nonlinear_mem); + SUNStepper_Destroy(&steppers[1]); + ARKodeFree(&splitting_mem); + SUNContext_Free(&ctx); return 0; } From b812411a3c5ab0c9427c1ec947e398be06c1d7e4 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 16:28:41 -0700 Subject: [PATCH 020/180] Fix default coefficients bug --- src/arkode/arkode_splitting_coefficients.def | 2 +- src/arkode/arkode_splittingstep.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index 5de86c65db..f0550acf97 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -65,4 +65,4 @@ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_4_4_2, { ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_8_6_2, { return SplittingStepCoefficients_TripleJump(2, 6); - }) \ No newline at end of file + }) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index c9710a6cf2..37817324f2 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -24,6 +24,10 @@ #include "arkode_mristep_impl.h" #include "arkode_splittingstep_impl.h" +/*--------------------------------------------------------------- + Shortcut routine to unpack step_mem structure from ark_mem. + If missing it returns ARK_MEM_NULL. + ---------------------------------------------------------------*/ static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, const char* const fname, ARKodeSplittingStepMem* const step_mem) @@ -59,6 +63,10 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, return splittingStep_AccessStepMem(*ark_mem, __func__, step_mem); } +/*--------------------------------------------------------------- + This routine checks if all required vector operations are + present. If any of them is missing it returns SUNFALSE. + ---------------------------------------------------------------*/ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) { // TODO(SBR): check all ops are correct @@ -72,7 +80,7 @@ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) ---------------------------------------------------------------*/ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, const ARKodeSplittingStepMem step_mem) { - if (step_mem->coefficients == NULL) { + if (step_mem->coefficients != NULL) { return ARK_SUCCESS; } @@ -456,7 +464,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, } /* Create ark_mem structure and set default values */ - const ARKodeMem ark_mem = arkCreate(sunctx); + ARKodeMem ark_mem = arkCreate(sunctx); if (ark_mem == NULL) { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, @@ -470,7 +478,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_ARKMEM_FAIL); - ARKodeFree((void**)&ark_mem); + ARKodeFree((void **)&ark_mem); return NULL; } @@ -590,4 +598,4 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, step_mem->own_policy = SUNFALSE; return ARK_SUCCESS; -} \ No newline at end of file +} From 9e93ffe2920efb2e1bab58627ae6f28c4498ca29 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 16:33:22 -0700 Subject: [PATCH 021/180] Add docs for execution policy --- src/arkode/arkode_splittingstep_executionpolicy.c | 4 ++++ .../arkode_execution_policy_serial.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c index 824559e2dd..c85e622003 100644 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ b/src/arkode/arkode_splittingstep_executionpolicy.c @@ -20,6 +20,10 @@ #include "sundials_macros.h" +/*--------------------------------------------------------------- + This routine frees all the ARKodeSplittingExecutionPolicy + memory + ---------------------------------------------------------------*/ void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) { if (policy != NULL) diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index 9a0217aae0..dd9a886efa 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -21,11 +21,14 @@ #include "sundials_macros.h" +/*--------------------------------------------------------------- + This routine does the setup for serial execution for which + nothing is needed. + ---------------------------------------------------------------*/ static int setup_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, SUNDIALS_MAYBE_UNUSED const N_Vector y, SUNDIALS_MAYBE_UNUSED const int sequential_methods) { - // Nothing needed return ARK_SUCCESS; } @@ -53,11 +56,18 @@ static int execute_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPo return ARK_SUCCESS; } +/*--------------------------------------------------------------- + This routine does the freeing for serial execution which happens + to be nothing + ---------------------------------------------------------------*/ static void free_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy) { // Nothing needed } +/*--------------------------------------------------------------- + This routine creates a serial execution policy + ---------------------------------------------------------------*/ ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial() { ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); From 4267f4a629a018c7276c4e108cf713ee7cae93c6 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 16:48:45 -0700 Subject: [PATCH 022/180] Add coefficient ids to docs --- doc/arkode/guide/source/Constants.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/arkode/guide/source/Constants.rst b/doc/arkode/guide/source/Constants.rst index 22363ef243..9546c81921 100644 --- a/doc/arkode/guide/source/Constants.rst +++ b/doc/arkode/guide/source/Constants.rst @@ -317,6 +317,30 @@ contains the ARKODE output constants. +-----------------------------------------------+------------------------------------------------------------+ | | | +-----------------------------------------------+------------------------------------------------------------+ + | **Splitting Coefficients specification** | | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_LIE_TROTTER_1_1_2` | 1st order Lie-Trotter splitting for problems with two | + | | partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_STRANG_2_2_2` | 2nd order Strang splitting for problems with two | + | | partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_BEST_2_2_2` | 2nd order splitting with optimal error for problems with | + | | two partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_SUZUKI_3_3_2` | 3rd order Suzuki splitting for problems with two | + | | partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_RUTH_3_3_2` | 3rd order Ruth splitting for problems with two partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_YOSHIDA_4_4_2` | 4th order Yoshida splitting for problems with two | + | | partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | :index:`ARKODE_SPLITTING_YOSHIDA_8_6_2` | 6th order Yoshida splitting for problems with two | + | | partitions. | + +-----------------------------------------------+------------------------------------------------------------+ + | | | + +-----------------------------------------------+------------------------------------------------------------+ | **MRI method types** | | +-----------------------------------------------+------------------------------------------------------------+ | :index:`MRISTEP_EXPLICIT` | Use an explicit (at the slow time scale) MRI method. | From fe44bdfc5b3a6c50b366a682a749cd123c5ff9ce Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 3 Sep 2024 17:03:46 -0700 Subject: [PATCH 023/180] Apply formatter --- .../Usage/SplittingStep/User_callable.rst | 18 +-- .../guide/source/Usage/User_callable.rst | 7 +- ...k_advection_diffusion_reaction_splitting.c | 121 +++++++++------- .../arkode/C_serial/ark_analytic_splitting.c | 32 +++-- .../arkode/arkode_splitting_coefficients.h | 7 +- include/arkode/arkode_splittingstep.h | 2 +- src/arkode/arkode_splitting_coefficients.c | 54 +++---- src/arkode/arkode_splittingstep.c | 134 ++++++++++-------- .../arkode_execution_policy_serial.c | 23 +-- .../ark_test_splitting_coefficients.c | 56 +++++--- .../arkode/C_serial/ark_test_splittingstep.c | 18 +-- 11 files changed, 263 insertions(+), 209 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index e07fbbb7ce..35a46fd959 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -24,17 +24,19 @@ module. As discussed in the main :ref:`ARKODE user-callable function introduction `, each of ARKODE's time-stepping modules clarifies the categories of user-callable functions that it supports. -SplittingStep supports the following categories: +SplittingStep does not support any of the categories beyond the functions that +apply for all time-stepping modules. .. _ARKODE.Usage.SplittingStep.Initialization: SplittingStep initialization functions ------------------------------------------------------- +-------------------------------------- + .. c:function:: void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx) - This function allocates and initializes memory for a problem to - be solved using the SplittingStep time-stepping module in ARKODE. + This function allocates and initializes memory for a problem to be solved + using the SplittingStep time-stepping module in ARKODE. **Arguments:** * *steppers* -- ? @@ -44,10 +46,10 @@ SplittingStep initialization functions * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) **Return value:** - If successful, a pointer to initialized problem memory of type ``void*``, to - be passed to all user-facing SplittingStep routines listed below. If unsuccessful, - a ``NULL`` pointer will be returned, and an error message will be printed to - ``stderr``. + If successful, a pointer to initialized problem memory of type ``void*``, + to be passed to all user-facing SplittingStep routines listed below. If + unsuccessful, a ``NULL`` pointer will be returned, and an error message + will be printed to ``stderr``. **Example usage:** diff --git a/doc/arkode/guide/source/Usage/User_callable.rst b/doc/arkode/guide/source/Usage/User_callable.rst index fd9b572382..e0832142c9 100644 --- a/doc/arkode/guide/source/Usage/User_callable.rst +++ b/doc/arkode/guide/source/Usage/User_callable.rst @@ -47,8 +47,11 @@ E. functions that apply for time-stepping modules that support relaxation Runge- In the function descriptions below, we identify those that have any of the restrictions B-E above. Then in the introduction for each of the stepper-specific documentation sections -(:numref:`ARKODE.Usage.ARKStep.UserCallable`, :numref:`ARKODE.Usage.ERKStep.UserCallable`, -:numref:`ARKODE.Usage.MRIStep.UserCallable`, and :numref:`ARKODE.Usage.SPRKStep.UserCallable`) +(:numref:`ARKODE.Usage.ARKStep.UserCallable`, +:numref:`ARKODE.Usage.ERKStep.UserCallable`, +:numref:`ARKODE.Usage.SplittingStep.UserCallable`, +:numref:`ARKODE.Usage.MRIStep.UserCallable`, +and :numref:`ARKODE.Usage.SPRKStep.UserCallable`) we clarify the categories of these functions that are supported. diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index bd42c2ff37..4a88cb2f92 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -34,13 +34,13 @@ * printed at the end. *---------------------------------------------------------------*/ +#include +#include #include -#include #include -#include +#include #include -#include -#include +#include #if defined(SUNDIALS_EXTENDED_PRECISION) #define GSYM "Lg" @@ -105,24 +105,26 @@ static int check_flag(void* flagvalue, const char* funcname, int opt) } /* f routine to compute the advection RHS function. */ -static int f_advection(const sunrealtype t, const N_Vector y, const N_Vector ydot, void* const user_data) +static int f_advection(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) { - const UserData * const udata = (UserData*) user_data; - sunrealtype *Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } - sunrealtype *Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); + const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); const sunrealtype u0_sqr = udata->u0 * udata->u0; /* Left boundary */ Ydot[0] = coeff * (Y[1] * Y[1] - u0_sqr); /* Interior */ - for (sunindextype i = 1; i < udata->N - 1; i++) { + for (sunindextype i = 1; i < udata->N - 1; i++) + { Ydot[i] = coeff * (Y[i + 1] * Y[i + 1] - Y[i - 1] * Y[i - 1]); } /* Right boundary */ @@ -132,15 +134,16 @@ static int f_advection(const sunrealtype t, const N_Vector y, const N_Vector ydo } /* f routine to compute the diffusion RHS function. */ -static int f_diffusion(const sunrealtype t, const N_Vector y, const N_Vector ydot, void * const user_data) +static int f_diffusion(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) { - const UserData * const udata = (UserData *) user_data; - sunrealtype *Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } - sunrealtype *Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } const sunrealtype coeff = udata->b / (udata->dx * udata->dx); @@ -148,27 +151,31 @@ static int f_diffusion(const sunrealtype t, const N_Vector y, const N_Vector ydo /* Left boundary */ Ydot[0] = coeff * (udata->u0 - 2 * Y[0] + Y[1]); /* Interior */ - for (sunindextype i = 1; i < udata->N - 1; i++) { + for (sunindextype i = 1; i < udata->N - 1; i++) + { Ydot[i] = coeff * (Y[i + 1] - 2 * Y[i] + Y[i - 1]); } /* Right boundary */ - Ydot[udata->N - 1] = coeff * (Y[udata->N - 2] - 2 * Y[udata->N - 1] + udata->u0); + Ydot[udata->N - 1] = coeff * + (Y[udata->N - 2] - 2 * Y[udata->N - 1] + udata->u0); return 0; } /* Routine to compute the diffusion Jacobian function. */ -static int jac_diffusion(const sunrealtype t, const N_Vector y, const N_Vector fy, const SUNMatrix Jac, - void* const user_data, const N_Vector tmp1, const N_Vector tmp2, - const N_Vector tmp3) +static int jac_diffusion(const sunrealtype t, const N_Vector y, + const N_Vector fy, const SUNMatrix Jac, + void* const user_data, const N_Vector tmp1, + const N_Vector tmp2, const N_Vector tmp3) { - const UserData * const udata = (UserData *) user_data; - const sunrealtype coeff = udata->b / (udata->dx * udata->dx); - + const UserData* const udata = (UserData*)user_data; + const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + SM_ELEMENT_B(Jac, 0, 0) = -2 * coeff; - for (int i = 1; i < udata->N; i++) { + for (int i = 1; i < udata->N; i++) + { SM_ELEMENT_B(Jac, i - 1, i) = coeff; - SM_ELEMENT_B(Jac, i, i) = -2 * coeff; + SM_ELEMENT_B(Jac, i, i) = -2 * coeff; SM_ELEMENT_B(Jac, i, i - 1) = coeff; } @@ -176,40 +183,41 @@ static int jac_diffusion(const sunrealtype t, const N_Vector y, const N_Vector f } /* f routine to compute the reaction RHS function. */ -static int f_reaction(const sunrealtype t, const N_Vector y, const N_Vector ydot, void * const user_data) +static int f_reaction(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) { - const UserData * const udata = (UserData *) user_data; - sunrealtype *Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } - sunrealtype *Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - for (sunindextype i = 0; i < udata->N; i++) { + for (sunindextype i = 0; i < udata->N; i++) + { Ydot[i] = udata->c * Y[i] * (SUN_RCONST(1.0) - Y[i] * Y[i]); } return 0; } -int main() { +int main() +{ /* Problem parameters */ const sunrealtype T0 = SUN_RCONST(0.0); const sunrealtype Tf = SUN_RCONST(1.0); const sunrealtype DT = SUN_RCONST(0.06); - UserData udata = { - .N = 128, - .dx = SUN_RCONST(1.0) / (udata.N + 1), - .a = SUN_RCONST(1.0), - .b = SUN_RCONST(0.125), - .c = SUN_RCONST(4.0), - .u0 = SUN_RCONST(0.1) - }; + UserData udata = {.N = 128, + .dx = SUN_RCONST(1.0) / (udata.N + 1), + .a = SUN_RCONST(1.0), + .b = SUN_RCONST(0.125), + .c = SUN_RCONST(4.0), + .u0 = SUN_RCONST(0.1)}; printf("\n1D Advection-Diffusion-Reaction PDE test problem:\n"); - printf(" N = %li\n", (long int) udata.N); + printf(" N = %li\n", (long int)udata.N); printf(" advection coefficient = %" GSYM "\n", udata.a); printf(" diffusion coefficient = %" GSYM "\n", udata.b); printf(" reaction coefficient = %" GSYM "\n\n", udata.c); @@ -225,14 +233,15 @@ int main() { N_VConst(udata.u0, y); /* Create advection integrator */ - void *advection_mem = ARKStepCreate(f_advection, NULL, T0, y, ctx); + void* advection_mem = ARKStepCreate(f_advection, NULL, T0, y, ctx); if (check_flag(advection_mem, "ARKStepCreate", 0)) { return 1; } flag = ARKodeSetUserData(advection_mem, &udata); if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } /* Choose a strong stability preserving method for advecton */ - flag = ARKStepSetTableNum(advection_mem, ARKODE_DIRK_NONE, ARKODE_SHU_OSHER_3_2_3); + flag = ARKStepSetTableNum(advection_mem, ARKODE_DIRK_NONE, + ARKODE_SHU_OSHER_3_2_3); if (check_flag(&flag, "ARKStepSetTableNum", 1)) { return 1; } SUNStepper advection_stepper; @@ -240,7 +249,7 @@ int main() { if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } /* Create diffusion integrator */ - void *diffusion_mem = ARKStepCreate(NULL, f_diffusion, T0, y, ctx); + void* diffusion_mem = ARKStepCreate(NULL, f_diffusion, T0, y, ctx); if (check_flag(diffusion_mem, "ARKStepCreate", 0)) { return 1; } flag = ARKodeSetUserData(diffusion_mem, &udata); @@ -269,7 +278,7 @@ int main() { if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } /* Create reaction integrator */ - void *reaction_mem = ARKStepCreate(f_reaction, NULL, T0, y, ctx); + void* reaction_mem = ARKStepCreate(f_reaction, NULL, T0, y, ctx); if (check_flag(reaction_mem, "ARKStepCreate", 0)) { return 1; } flag = ARKodeSetUserData(reaction_mem, &udata); @@ -283,8 +292,9 @@ int main() { if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } /* Create operator splitting integrator */ - SUNStepper steppers[] = {advection_stepper, diffusion_stepper, reaction_stepper}; - void *arkode_mem = SplittingStepCreate(steppers, 3, T0, y, ctx); + SUNStepper steppers[] = {advection_stepper, diffusion_stepper, + reaction_stepper}; + void* arkode_mem = SplittingStepCreate(steppers, 3, T0, y, ctx); if (check_flag(arkode_mem, "SplittingStepCreate", 0)) { return 1; } flag = ARKodeSetFixedStep(arkode_mem, DT); @@ -298,7 +308,8 @@ int main() { printf(" t ||u||_rms\n"); printf(" ----------------------\n"); printf(" %10.6" FSYM " %10.6f\n", tret, sqrt(N_VDotProd(y, y) / udata.N)); - while (tret < Tf) { + while (tret < Tf) + { flag = ARKodeEvolve(arkode_mem, Tf, y, &tret, ARK_ONE_STEP); if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } printf(" %10.6" FSYM " %10.6f\n", tret, sqrt(N_VDotProd(y, y) / udata.N)); @@ -309,15 +320,15 @@ int main() { printf("\nSplitting Stepper Statistics:\n"); flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } - + printf("\nAdvection Stepper Statistics:\n"); flag = ARKodePrintAllStats(advection_mem, stdout, SUN_OUTPUTFORMAT_TABLE); if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } - + printf("\nDiffusion Stepper Statistics:\n"); flag = ARKodePrintAllStats(diffusion_mem, stdout, SUN_OUTPUTFORMAT_TABLE); if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } - + printf("\nReaction Stepper Statistics:\n"); flag = ARKodePrintAllStats(reaction_mem, stdout, SUN_OUTPUTFORMAT_TABLE); if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } diff --git a/examples/arkode/C_serial/ark_analytic_splitting.c b/examples/arkode/C_serial/ark_analytic_splitting.c index f35dbd7555..62ca2329ff 100644 --- a/examples/arkode/C_serial/ark_analytic_splitting.c +++ b/examples/arkode/C_serial/ark_analytic_splitting.c @@ -31,9 +31,9 @@ *-----------------------------------------------------------------*/ /* Header files */ -#include #include #include +#include #if defined(SUNDIALS_EXTENDED_PRECISION) #define GSYM "Lg" @@ -51,27 +51,31 @@ typedef struct } UserData; /* RHS for f^1(t, y) = -lambda * y */ -static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) +static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, + void* const user_data) { - sunrealtype lambda = ((UserData*) user_data)->lambda; + sunrealtype lambda = ((UserData*)user_data)->lambda; N_VScale(-lambda, y, ydot); return 0; } /* RHS for f^2(t, y) = y^2 */ -static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, void* const user_data) +static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, + void* const user_data) { N_VProd(y, y, ydot); return 0; } /* Compute the exact analytic solution */ -static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, const UserData* const user_data) +static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, + const UserData* const user_data) { - N_Vector sol = N_VClone(y0); + N_Vector sol = N_VClone(y0); const sunrealtype y0_val = NV_Ith_S(y0, 0); const sunrealtype lambda = user_data->lambda; - NV_Ith_S(sol, 0) = lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); + NV_Ith_S(sol, 0) = lambda * y0_val / + (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); return sol; } @@ -124,12 +128,10 @@ int main() const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ const sunrealtype tf = SUN_RCONST(1.0); /* final time */ const sunrealtype dt = SUN_RCONST(0.01); /* operator splitting time step */ - const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ + const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ const sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ - UserData user_data = { - .lambda = SUN_RCONST(2.0) - }; + UserData user_data = {.lambda = SUN_RCONST(2.0)}; /* Create the SUNDIALS context object for this simulation */ SUNContext ctx; @@ -147,7 +149,7 @@ int main() printf(" lambda = %" GSYM "\n", user_data.lambda); /* Create the integrator for the linear partition */ - void *linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); + void* linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); if (check_flag(linear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetUserData(linear_mem, &user_data); @@ -157,7 +159,7 @@ int main() if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } /* Create the integrator for the nonlinear partition */ - void *nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); + void* nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); if (check_flag(nonlinear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetFixedStep(nonlinear_mem, dt_nonlinear); @@ -169,7 +171,7 @@ int main() ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); /* Create the operator splitting method */ - void *splitting_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); + void* splitting_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); if (check_flag(splitting_mem, "SplittingStepCreate", 0)) { return 1; } flag = ARKodeSetFixedStep(splitting_mem, dt); @@ -196,6 +198,6 @@ int main() SUNStepper_Destroy(&steppers[1]); ARKodeFree(&splitting_mem); SUNContext_Free(&ctx); - + return 0; } diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index bee23fc675..92604fdff4 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -45,8 +45,8 @@ typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficient * ARKODE_SPLITTING____ */ typedef enum { - ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ - ARKODE_MIN_SPLITTING_NUM = 0, + ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ + ARKODE_MIN_SPLITTING_NUM = 0, ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM, ARKODE_SPLITTING_STRANG_2_2_2, ARKODE_SPLITTING_BEST_2_2_2, @@ -65,7 +65,8 @@ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); -SUNDIALS_EXPORT void SplittingStepCoefficients_Free(SplittingStepCoefficients coefficients); +SUNDIALS_EXPORT void SplittingStepCoefficients_Free( + SplittingStepCoefficients coefficients); SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients); SUNDIALS_EXPORT void SplittingStepCoefficients_Write( diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 7119ba9246..055599c4e0 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -17,10 +17,10 @@ #ifndef ARKODE_SPLITTINGSTEP_H_ #define ARKODE_SPLITTINGSTEP_H_ -#include #include #include #include +#include #include #ifdef __cplusplus /* wrapper to enable C++ usage */ diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index f46112cf8a..9d15106520 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -143,8 +143,8 @@ SplittingStepCoefficients SplittingStepCoefficients_Copy( SplittingStepCoefficients coefficientsCopy = SplittingStepCoefficients_Alloc(coefficients->sequential_methods, - coefficients->stages, - coefficients->partitions); + coefficients->stages, + coefficients->partitions); if (coefficientsCopy == NULL) { return NULL; } coefficientsCopy->order = coefficients->order; @@ -229,7 +229,7 @@ SplittingStepCoefficients SplittingStepCoefficients_LieTrotter(const int partiti SplittingStepCoefficients_Alloc(1, 1, partitions); if (coefficients == NULL) { return NULL; } - coefficients->order = 1; + coefficients->order = 1; coefficients->alpha[0] = SUN_RCONST(1.0); for (int i = 0; i < partitions; i++) { @@ -281,7 +281,7 @@ SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel( SplittingStepCoefficients_Alloc(2, partitions, partitions); if (coefficients == NULL) { return NULL; } - coefficients->order = 2; + coefficients->order = 2; coefficients->alpha[0] = SUN_RCONST(0.5); coefficients->alpha[1] = SUN_RCONST(0.5); @@ -310,22 +310,27 @@ SplittingStepCoefficients SplittingStepCoefficients_ThirdOrderSuzuki( SplittingStepCoefficients_Alloc(1, 2 * partitions - 1, partitions); if (coefficients == NULL) { return NULL; } - coefficients->order = 3; + coefficients->order = 3; coefficients->alpha[0] = SUN_RCONST(1.0); for (int i = 1; i < partitions; i++) { - for (int j = 0; j < partitions; j++) { + for (int j = 0; j < partitions; j++) + { // Constants from https://doi.org/10.1143/JPSJ.61.3015 pg. 3019 - const sunrealtype p1 = SUN_RCONST(0.2683300957817599249569552299254991394812); - const sunrealtype p2 = SUN_RCONST(0.6513314272356399320939424082278836500821); - + const sunrealtype p1 = + SUN_RCONST(0.2683300957817599249569552299254991394812); + const sunrealtype p2 = + SUN_RCONST(0.6513314272356399320939424082278836500821); + coefficients->beta[0][i][j] = i + j < partitions ? p1 : (p1 + p2); - coefficients->beta[0][partitions + i - 1][j] = SUN_RCONST(1.0) - (i + j < partitions ? (p1 + p2) : p1); + coefficients->beta[0][partitions + i - 1][j] = + SUN_RCONST(1.0) - (i + j < partitions ? (p1 + p2) : p1); } } - for (int i = 0; i < partitions; i++) { + for (int i = 0; i < partitions; i++) + { coefficients->beta[0][2 * partitions - 1][i] = SUN_RCONST(1.0); } @@ -374,11 +379,11 @@ static sunrealtype* const* SplittingStepCoefficients_ComposeStrangHelper( ? (start + i * gamma) : (end + (i - composition_stages) * gamma); /* Recursively generate coefficients and shift beta_cur */ - beta_cur = - SplittingStepCoefficients_ComposeStrangHelper(partitions, order - 2, - composition_stages, - start_cur, end_cur, - beta_cur); + beta_cur = SplittingStepCoefficients_ComposeStrangHelper(partitions, + order - 2, + composition_stages, + start_cur, end_cur, + beta_cur); start_cur = end_cur; } @@ -405,20 +410,19 @@ static SplittingStepCoefficients SplittingStepCoefficients_ComposeStrang( SplittingStepCoefficients_Alloc(1, stages, partitions); if (coefficients == NULL) { return NULL; } - coefficients->order = order; + coefficients->order = order; coefficients->alpha[0] = SUN_RCONST(1.0); SplittingStepCoefficients_ComposeStrangHelper(partitions, order, - composition_stages, - SUN_RCONST(0.0), - SUN_RCONST(1.0), - coefficients->beta[0]); + composition_stages, + SUN_RCONST(0.0), SUN_RCONST(1.0), + coefficients->beta[0]); return coefficients; } -SplittingStepCoefficients SplittingStepCoefficients_TripleJump( - const int partitions, const int order) +SplittingStepCoefficients SplittingStepCoefficients_TripleJump(const int partitions, + const int order) { return SplittingStepCoefficients_ComposeStrang(partitions, order, 3); } @@ -432,8 +436,8 @@ SplittingStepCoefficients SplittingStepCoefficients_SuzukiFractal( /*--------------------------------------------------------------- Routine to print a splitting coefficient structure ---------------------------------------------------------------*/ -void SplittingStepCoefficients_Write( - const SplittingStepCoefficients coefficients, FILE* const outfile) +void SplittingStepCoefficients_Write(const SplittingStepCoefficients coefficients, + FILE* const outfile) { // TODO: update when https://github.com/LLNL/sundials/pull/517 merged if (coefficients == NULL || coefficients->alpha == NULL || diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 37817324f2..5446bcd547 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -78,31 +78,43 @@ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) This routine determines the splitting coefficients to use, based on the desired accuracy. ---------------------------------------------------------------*/ -static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, const ARKodeSplittingStepMem step_mem) +static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, + const ARKodeSplittingStepMem step_mem) { - if (step_mem->coefficients != NULL) { - return ARK_SUCCESS; - } + if (step_mem->coefficients != NULL) { return ARK_SUCCESS; } - if (step_mem->order <= 1) { + if (step_mem->order <= 1) + { /* Lie-Trotter is the default (order < 1) */ - step_mem->coefficients = SplittingStepCoefficients_LieTrotter(step_mem->partitions); - } else if (step_mem->order == 3) { - step_mem->coefficients = SplittingStepCoefficients_ThirdOrderSuzuki(step_mem->partitions); - } else if (step_mem->order % 2 == 0) { + step_mem->coefficients = + SplittingStepCoefficients_LieTrotter(step_mem->partitions); + } + else if (step_mem->order == 3) + { + step_mem->coefficients = + SplittingStepCoefficients_ThirdOrderSuzuki(step_mem->partitions); + } + else if (step_mem->order % 2 == 0) + { /* Triple jump only works for even order */ - step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order); - } else { + step_mem->coefficients = + SplittingStepCoefficients_TripleJump(step_mem->partitions, step_mem->order); + } + else + { /* Bump the order up to be even but with an error */ const int new_order = step_mem->order + 1; arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "No splitting method at requested order, using q=%i.", new_order); - step_mem->coefficients = SplittingStepCoefficients_TripleJump(step_mem->partitions, new_order); + "No splitting method at requested order, using q=%i.", + new_order); + step_mem->coefficients = + SplittingStepCoefficients_TripleJump(step_mem->partitions, new_order); } - - if (step_mem->coefficients == NULL) { - arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, - __FILE__, "Failed to allocate splitting coefficients"); + + if (step_mem->coefficients == NULL) + { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + "Failed to allocate splitting coefficients"); return ARK_MEM_FAIL; } @@ -133,17 +145,17 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) if (init_type == FIRST_INIT) { retval = splittingStep_SetCoefficients(ark_mem, step_mem); - if (retval != ARK_SUCCESS) { - return retval; - } + if (retval != ARK_SUCCESS) { return retval; } if (step_mem->policy == NULL) { step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); - if (step_mem->policy == NULL) { - if (step_mem->coefficients == NULL) { - arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, - __FILE__, "Failed to allocate execution policy"); + if (step_mem->policy == NULL) + { + if (step_mem->coefficients == NULL) + { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + "Failed to allocate execution policy"); return ARK_MEM_FAIL; } } @@ -186,7 +198,8 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f, ARK_FULLRHS_OTHER); + retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f, + ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -196,7 +209,9 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, for (int i = 1; i < step_mem->partitions; i++) { - retval = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); + retval = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, + ark_mem->tempv1, + ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -212,7 +227,8 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, /*--------------------------------------------------------------- This routine performs a sequential operator splitting method ---------------------------------------------------------------*/ -static int splittingStep_SequentialMethod(const int i, const N_Vector y, void* const user_data) +static int splittingStep_SequentialMethod(const int i, const N_Vector y, + void* const user_data) { ARKodeMem ark_mem = (ARKodeMem)user_data; ARKodeSplittingStepMem step_mem = NULL; @@ -226,24 +242,21 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, void* c for (int k = 0; k < coefficients->partitions; k++) { const sunrealtype t_start = ark_mem->tn + - coefficients->beta[i][j][k] * ark_mem->h; + coefficients->beta[i][j][k] * ark_mem->h; const sunrealtype t_end = ark_mem->tn + coefficients->beta[i][j + 1][k] * ark_mem->h; - if (t_start == t_end) - { - continue; - } + if (t_start == t_end) { continue; } const SUNStepper stepper = step_mem->steppers[k]; - SUNErrCode err = stepper->ops->reset(stepper, t_start, y); + SUNErrCode err = stepper->ops->reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return err; } - + err = stepper->ops->setstoptime(stepper, t_end); if (err != SUN_SUCCESS) { return err; } - + sunrealtype tret = 0; - int stop_reason = 0; + int stop_reason = 0; err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret, &stop_reason); step_mem->n_stepper_evolves++; @@ -255,24 +268,24 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, void* c return ARK_SUCCESS; } - /*--------------------------------------------------------------- This routine performs a single step of the splitting method. ---------------------------------------------------------------*/ -static int splittingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const dsmPtr, - int* const nflagPtr) +static int splittingStep_TakeStep(const ARKodeMem ark_mem, + sunrealtype* const dsmPtr, int* const nflagPtr) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ - *dsmPtr = ZERO; /* No error estimate */ + *dsmPtr = ZERO; /* No error estimate */ const SplittingStepCoefficients coefficients = step_mem->coefficients; - return step_mem->policy->execute(step_mem->policy, splittingStep_SequentialMethod, - ark_mem->yn, ark_mem->ycur, ark_mem->tempv1, + return step_mem->policy->execute(step_mem->policy, + splittingStep_SequentialMethod, ark_mem->yn, + ark_mem->ycur, ark_mem->tempv1, coefficients->alpha, coefficients->sequential_methods, ark_mem); } @@ -280,7 +293,8 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const ds /*--------------------------------------------------------------- Prints integrator statistics ---------------------------------------------------------------*/ -static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfile, +static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, + FILE* const outfile, const SUNOutputFormat fmt) { // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged @@ -291,7 +305,8 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outf switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - fprintf(outfile, "Stepper evolves = %ld\n", step_mem->n_stepper_evolves); + fprintf(outfile, "Stepper evolves = %ld\n", + step_mem->n_stepper_evolves); break; case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); @@ -304,6 +319,7 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outf return ARK_SUCCESS; } + /*--------------------------------------------------------------- Outputs all solver parameters to the provided file pointer. ---------------------------------------------------------------*/ @@ -408,11 +424,9 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) retval = splittingStep_SetOrder(ark_mem, 0); if (retval != ARK_SUCCESS) { return retval; } - if (step_mem->own_policy) { - free(step_mem->policy); - } + if (step_mem->own_policy) { free(step_mem->policy); } step_mem->own_policy = SUNFALSE; - + ark_mem->interp_type = ARK_INTERP_LAGRANGE; return ARK_SUCCESS; @@ -422,7 +436,8 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) Creates the SplittingStep integrator ---------------------------------------------------------------*/ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, - const sunrealtype t0, const N_Vector y0, const SUNContext sunctx) + const sunrealtype t0, const N_Vector y0, + const SUNContext sunctx) { if (steppers == NULL) { @@ -478,12 +493,13 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_ARKMEM_FAIL); - ARKodeFree((void **)&ark_mem); + ARKodeFree((void**)&ark_mem); return NULL; } - step_mem->steppers = malloc(partitions * sizeof(*steppers)); - if (step_mem->steppers == NULL) { + step_mem->steppers = malloc(partitions * sizeof(*steppers)); + if (step_mem->steppers == NULL) + { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_ARKMEM_FAIL); ARKodeFree((void**)&ark_mem); @@ -546,9 +562,10 @@ int SplittingStep_SetCoefficients(void* arkode_mem, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - if (coefficients == NULL) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, - __FILE__, "Splitting coefficients must be non-NULL"); + if (coefficients == NULL) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Splitting coefficients must be non-NULL"); return ARK_ILL_INPUT; } @@ -584,9 +601,10 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - if (policy == NULL) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, - __FILE__, "The execution policy must be non-NULL"); + if (policy == NULL) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "The execution policy must be non-NULL"); return ARK_ILL_INPUT; } diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index dd9a886efa..60754ada1e 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -25,25 +25,25 @@ This routine does the setup for serial execution for which nothing is needed. ---------------------------------------------------------------*/ -static int setup_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, - SUNDIALS_MAYBE_UNUSED const N_Vector y, - SUNDIALS_MAYBE_UNUSED const int sequential_methods) +static int setup_serial( + SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, + SUNDIALS_MAYBE_UNUSED const N_Vector y, + SUNDIALS_MAYBE_UNUSED const int sequential_methods) { return ARK_SUCCESS; } -static int execute_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, - const ARKExecutionPolicyFn fn, const N_Vector yn, const N_Vector ycur, - const N_Vector tmp, sunrealtype* const alpha, - const int sequential_methods, void* const user_data) +static int execute_serial( + SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, + const ARKExecutionPolicyFn fn, const N_Vector yn, const N_Vector ycur, + const N_Vector tmp, sunrealtype* const alpha, const int sequential_methods, + void* const user_data) { N_VScale(1, yn, ycur); int retval = fn(0, ycur, user_data); if (retval != ARK_SUCCESS) { return retval; } - if (alpha[0] != SUN_RCONST(1.0)) { - N_VScale(alpha[0], ycur, ycur); - } + if (alpha[0] != SUN_RCONST(1.0)) { N_VScale(alpha[0], ycur, ycur); } for (int i = 1; i < sequential_methods; i++) { @@ -60,7 +60,8 @@ static int execute_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPo This routine does the freeing for serial execution which happens to be nothing ---------------------------------------------------------------*/ -static void free_serial(SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy) +static void free_serial( + SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy) { // Nothing needed } diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c index 180d1c0749..41cd75f28f 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c @@ -25,7 +25,10 @@ #define ONE SUN_RCONST(1.0) #define TWO SUN_RCONST(2.0) #define HALF SUN_RCONST(0.5) -#define GAMMA (SUN_RCONST(1.0) / (SUN_RCONST(4.0) - SUNRpowerR(SUN_RCONST(4.0), SUN_RCONST(1.0) / SUN_RCONST(3.0)))) +#define GAMMA \ + (SUN_RCONST(1.0) / \ + (SUN_RCONST(4.0) - \ + SUNRpowerR(SUN_RCONST(4.0), SUN_RCONST(1.0) / SUN_RCONST(3.0)))) static int check_coefficients(const char* const name, const SplittingStepCoefficients coefficients, @@ -99,9 +102,7 @@ static int check_coefficients(const char* const name, } } - if (retval > 0) { - SplittingStepCoefficients_Write(coefficients, stderr); - } + if (retval > 0) { SplittingStepCoefficients_Write(coefficients, stderr); } return retval; } @@ -125,7 +126,7 @@ int main(int argc, char* argv[]) sunrealtype beta_lie_trotter[] = {ZERO, ZERO, ONE, ONE}; coefficients = SplittingStepCoefficients_Create(0, 0, 0, 1, alpha_lie_trotter, - beta_lie_trotter); + beta_lie_trotter); if (coefficients != NULL) { fprintf(stderr, "Coefficients created with invalid sizes\n"); @@ -133,7 +134,7 @@ int main(int argc, char* argv[]) } coefficients = SplittingStepCoefficients_Create(1, 1, 2, 1, alpha_lie_trotter, - beta_lie_trotter); + beta_lie_trotter); retval += check_coefficients("Lie-Trotter (manually created)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); @@ -144,19 +145,21 @@ int main(int argc, char* argv[]) SplittingStepCoefficients_Free(coefficients); SplittingStepCoefficients_Free(coefficients_copy); - coefficients = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_LIE_TROTTER_1_1_2); - retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, 2, 1, - alpha_lie_trotter, beta_lie_trotter); + coefficients = SplittingStepCoefficients_LoadCoefficients( + ARKODE_SPLITTING_LIE_TROTTER_1_1_2); + retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, + 2, 1, alpha_lie_trotter, beta_lie_trotter); SplittingStepCoefficients_Free(coefficients); - coefficients = SplittingStepCoefficients_LoadCoefficientsByName("ARKODE_SPLITTING_LIE_TROTTER_1_1_2"); - retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, 2, 1, - alpha_lie_trotter, beta_lie_trotter); + coefficients = SplittingStepCoefficients_LoadCoefficientsByName( + "ARKODE_SPLITTING_LIE_TROTTER_1_1_2"); + retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, + 2, 1, alpha_lie_trotter, beta_lie_trotter); SplittingStepCoefficients_Free(coefficients); coefficients = SplittingStepCoefficients_LieTrotter(2); - retval += check_coefficients("Lie-Trotter (constructor)", coefficients, 1, 1, 2, 1, - alpha_lie_trotter, beta_lie_trotter); + retval += check_coefficients("Lie-Trotter (constructor)", coefficients, 1, 1, + 2, 1, alpha_lie_trotter, beta_lie_trotter); SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_strang[] = {ONE}; @@ -189,17 +192,24 @@ int main(int argc, char* argv[]) SplittingStepCoefficients_Free(coefficients); sunrealtype alpha_suzuki_fractal[] = {ONE}; - sunrealtype beta_suzuki_fractal[] = {ZERO, ZERO, - HALF * GAMMA, GAMMA, - (ONE + HALF) * GAMMA, TWO * GAMMA, - HALF, ONE - TWO * GAMMA, - ONE - (ONE + HALF) * GAMMA, ONE - GAMMA, - ONE - HALF * GAMMA, ONE, - ONE, ONE}; + sunrealtype beta_suzuki_fractal[] = {ZERO, + ZERO, + HALF * GAMMA, + GAMMA, + (ONE + HALF) * GAMMA, + TWO * GAMMA, + HALF, + ONE - TWO * GAMMA, + ONE - (ONE + HALF) * GAMMA, + ONE - GAMMA, + ONE - HALF * GAMMA, + ONE, + ONE, + ONE}; coefficients = SplittingStepCoefficients_SuzukiFractal(2, 4); - retval += check_coefficients("Suzuki Fractal", coefficients, 1, 6, 2, 4, alpha_suzuki_fractal, - beta_suzuki_fractal); + retval += check_coefficients("Suzuki Fractal", coefficients, 1, 6, 2, 4, + alpha_suzuki_fractal, beta_suzuki_fractal); SplittingStepCoefficients_Free(coefficients); printf("%d test failures\n", retval); diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index 8090609ba7..46044fa324 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -32,13 +32,13 @@ Examples #include #include -#include #include #include #include +#include -#define DT_1 (0.5/8) -#define DT_2 (0.125/8) +#define DT_1 (0.5 / 8) +#define DT_2 (0.125 / 8) #define T_END 1.0 #define LAMBDA 2.0 @@ -61,14 +61,15 @@ static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) return LAMBDA * y0 / (y0 - (y0 - LAMBDA) * exp(LAMBDA * t)); } -static void test() { -SUNContext sunctx; +static void test() +{ + SUNContext sunctx; SUNContext_Create(SUN_COMM_NULL, &sunctx); N_Vector y = N_VNew_Serial(1, sunctx); N_VConst(1, y); - - void *mem = ARKStepCreate(f1, NULL, 0, y, sunctx); + + void* mem = ARKStepCreate(f1, NULL, 0, y, sunctx); ARKodeSetFixedStep(mem, 0.25); @@ -107,7 +108,8 @@ int main(int argc, char* argv[]) // SplittingStepCoefficients_Write(coeffs, stdout); SplittingStep_SetCoefficients(split_mem, coeffs); SplittingStepCoefficients_Free(coeffs); - ARKodeSetFixedStep(split_mem, DT_1); // TODO: fix valgrind error if this is not called + ARKodeSetFixedStep(split_mem, + DT_1); // TODO: fix valgrind error if this is not called sunrealtype tret; ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); printf("Final Solution: %e %e\n", T_END, NV_Ith_S(y, 0)); From 1485fc4ed2296bf1e6615becfab851d39bb06211 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 13:18:40 -0700 Subject: [PATCH 024/180] Bring over forced splitting method --- .../SplittingStepCoefficients.rst | 16 + .../Usage/SplittingStep/User_callable.rst | 38 +- include/arkode/arkode_forcingstep.h | 37 ++ include/arkode/arkode_splittingstep.h | 7 +- src/arkode/CMakeLists.txt | 2 + src/arkode/arkode_forcingstep.c | 387 ++++++++++++++++++ src/arkode/arkode_forcingstep_impl.h | 29 ++ src/arkode/arkode_splittingstep.c | 35 +- 8 files changed, 530 insertions(+), 21 deletions(-) create mode 100644 include/arkode/arkode_forcingstep.h create mode 100644 src/arkode/arkode_forcingstep.c create mode 100644 src/arkode/arkode_forcingstep_impl.h diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index adef211116..b40f53ad5a 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -369,6 +369,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. * An :c:type:`SplittingStepCoefficients` structure if successful. * A ``NULL`` pointer if an argument was invalid or an allocation error occurred. + + .. versionadded:: x.y.z .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients) @@ -381,6 +383,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. **Return value:** * An :c:type:`SplittingStepCoefficients` structure if successful. * A ``NULL`` pointer if an allocation error occurred. + + .. versionadded:: x.y.z .. c:function:: void SplittingStepCoefficients_Free(SplittingStepCoefficients coefficients) @@ -389,6 +393,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. **Arguments:** * ``coefficients`` -- The splitting coefficients. + + .. versionadded:: x.y.z .. c:function:: void SplittingStepCoefficients_Write(SplittingStepCoefficients coefficients, FILE* outfile) @@ -403,6 +409,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. The *outfile* argument can be ``stdout`` or ``stderr``, or it may point to a specific file created using ``fopen``. + + .. versionadded:: x.y.z .. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients: @@ -439,3 +447,11 @@ with values specified for each method below (e.g., ``ARKODE_SPLITTING_YOSHIDA_4_4_2`` 4 :cite:p:`Yoshida:90` ``ARKODE_SPLITTING_YOSHIDA_8_6_2`` 6 :cite:p:`Yoshida:90` ====================================== ===== ===================== + + +.. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Default: + +Default Operator Splitting Coefficients +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default SplittingStep \ No newline at end of file diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 35a46fd959..d3c3199d08 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -77,5 +77,39 @@ SplittingStep initialization functions outer_arkode_mem = MRIStepCreate(fse, fsi, t0, y0, stepper, sunctx) **Example codes:** - * ``examples/arkode/C_serial/TODO.c`` - * ``examples/arkode/C_serial/TODO.c`` + * ``examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c`` + * ``examples/arkode/C_serial/ark_analytic_splitting.c`` + + .. versionadded:: x.y.z + + +Optional inputs for IVP method selection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. c:function:: int SplittingStep_SetCoefficients(void* arkode_mem, SplittingStepCoefficients coefficients) + + Specifies a customized set of coefficients for the operator splitting method. + + **Arguments:** + + * *arkode_mem* -- pointer to the SplittingStep memory block. + + * *coefficients* -- the table of coupling coefficients for the MRI method. + + **Return value:** + + * *ARK_SUCCESS* if successful + + * *ARK_MEM_NULL* if the SplittingStep memory is ``NULL`` + + * *ARK_ILL_INPUT* if an argument has an illegal value + + **Notes:** + + For a description of the :c:type:`SplittingStepCoefficients` type and related + functions for creating splitting coefficients see + :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`. + + **Warning:** + + This should not be used with :c:func:`ARKodeSetOrder`. diff --git a/include/arkode/arkode_forcingstep.h b/include/arkode/arkode_forcingstep.h new file mode 100644 index 0000000000..d2d95e5bba --- /dev/null +++ b/include/arkode/arkode_forcingstep.h @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * This is the header file for the ARKODE ForcingStep module. + *--------------------------------------------------------------*/ + +#ifndef ARKODE_FORCINGINGSTEP_H_ +#define ARKODE_FORCINGINGSTEP_H_ + +#include +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +SUNDIALS_EXPORT void *ForcingStepCreate(SUNStepper stepper1, + SUNStepper stepper2, + sunrealtype t0, N_Vector y0, + SUNContext sunctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 055599c4e0..a6766e380f 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -27,12 +27,17 @@ extern "C" { #endif -/* TODO: can we use `const SUNStepper* steppers` since we don't make copies? */ +/* TODO: can we use `const SUNStepper* steppers`? */ /* TODO: would (t0, y0, steppers, partitions, sunctx) be a better arg order? Seems slightly more consistent with MRIStepCreate */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx); +SUNDIALS_EXPORT int SplittingStepCreateForcing(SUNStepper stepper1, + SUNStepper stepper2, + sunrealtype t0, N_Vector y0, + SUNContext sunctx); + SUNDIALS_EXPORT int SplittingStep_SetCoefficients( void* arkode_mem, SplittingStepCoefficients coefficients); diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index 7caaddf7c6..b254ec9c54 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -29,6 +29,7 @@ set(arkode_SOURCES arkode_butcher.c arkode_erkstep_io.c arkode_erkstep.c + arkode_forcingstep.c arkode_interp.c arkode_io.c arkode_ls.c @@ -58,6 +59,7 @@ set(arkode_HEADERS arkode_butcher_dirk.h arkode_butcher_erk.h arkode_erkstep.h + arkode_forcingstep.h arkode_ls.h arkode_mristep.h arkode_splittingstep.h diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c new file mode 100644 index 0000000000..707bbbbfe0 --- /dev/null +++ b/src/arkode/arkode_forcingstep.c @@ -0,0 +1,387 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * This is the implementation file for ARKODE's forcing method + *--------------------------------------------------------------*/ + +#include +#include +#include + +#include "arkode_impl.h" +#include "arkode_mristep_impl.h" +#include "arkode_forcingstep_impl.h" + +/*--------------------------------------------------------------- + Shortcut routine to unpack step_mem structure from ark_mem. + If missing it returns ARK_MEM_NULL. + ---------------------------------------------------------------*/ +static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, + const char* const fname, + ARKodeForcingStepMem* const step_mem) +{ + if (ark_mem->step_mem == NULL) + { + arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, fname, __FILE__, + "Time step module memory is NULL."); + return (ARK_MEM_NULL); + } + *step_mem = (ARKodeForcingStepMem)ark_mem->step_mem; + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + This routine checks if all required vector operations are + present. If any of them is missing it returns SUNFALSE. + ---------------------------------------------------------------*/ +static sunbooleantype forcingStep_CheckNVector(const N_Vector y) +{ + // TODO(SBR): check all ops are correct + return y->ops->nvlinearsum != NULL; +} + +/*--------------------------------------------------------------- + This routine is called just prior to performing internal time + steps (after all user "set" routines have been called) from + within arkInitialSetup. + + With initialization types FIRST_INIT this routine: + - sets/checks the splitting coefficients to be used + - sets/checks the execution policy to be used + + With other initialization types, this routine does nothing. + ---------------------------------------------------------------*/ +static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) +{ + ARKodeForcingStepMem step_mem = NULL; + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + + /* immediately return if resize or reset */ + if (init_type == RESIZE_INIT || init_type == RESET_INIT) + { + return ARK_SUCCESS; + } + + /* Only one forcing vector is needed which come from the already allocated + * tempv1 */ + step_mem->stepper2->nforcing = 1; + step_mem->stepper2->nforcing_allocated = 1; + step_mem->stepper2->forcing = &ark_mem->tempv1; + + ark_mem->interp_degree = 1; + + return ARK_SUCCESS; +} + +/*------------------------------------------------------------------------------ + This is just a wrapper to call the user-supplied RHS function, + f^1(t,y) + f^2(t,y). + + This will be called in one of three 'modes': + + ARK_FULLRHS_START -> called at the beginning of a simulation i.e., at + (tn, yn) = (t0, y0) or (tR, yR) + + ARK_FULLRHS_END -> called at the end of a successful step i.e, at + (tcur, ycur) or the start of the subsequent step i.e., + at (tn, yn) = (tcur, ycur) from the end of the last + step + + ARK_FULLRHS_OTHER -> called elsewhere (e.g. for dense output) + + In ForcingStep, we accumulate the RHS functions in ARK_FULLRHS_OTHER mode. + Generally, inner steppers will not have the correct yn when this function is + called and will not be able to reuse a function evaluation since their state + resets at the next ARKodeEvolve call. + ----------------------------------------------------------------------------*/ +static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, + const N_Vector y, const N_Vector f, + SUNDIALS_MAYBE_UNUSED const int mode) +{ + ARKodeForcingStepMem step_mem = NULL; + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + retval = step_mem->stepper1->ops->fullrhs(step_mem->stepper1, t, y, f, + ARK_FULLRHS_OTHER); + if (retval != 0) + { + arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_RHSFUNC_FAILED, t); + return (ARK_RHSFUNC_FAIL); + } + + retval = step_mem->stepper2->ops->fullrhs(step_mem->stepper2, t, y, + ark_mem->tempv1, + ARK_FULLRHS_OTHER); + if (retval != 0) + { + arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_RHSFUNC_FAILED, t); + return (ARK_RHSFUNC_FAIL); + } + N_VLinearSum(SUN_RCONST(1.0), f, SUN_RCONST(1.0), ark_mem->tempv1, f); + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + This routine performs a single step of the splitting method. + ---------------------------------------------------------------*/ +static int forcingStep_TakeStep(const ARKodeMem ark_mem, + sunrealtype* const dsmPtr, int* const nflagPtr) +{ + ARKodeForcingStepMem step_mem = NULL; + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ + *dsmPtr = ZERO; /* No error estimate */ + + const SUNStepper s1 = step_mem->stepper1; + const sunrealtype tout = ark_mem->tn + ark_mem->h; + sunrealtype tret = 0; + int stop_reason = 0; + + SUNErrCode err = s1->ops->reset(s1, ark_mem->tn, ark_mem->yn); + if (err != SUN_SUCCESS) { return err; } + + err = s1->ops->evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + if (err != SUN_SUCCESS) { return err; } + if (stop_reason < 0) { return stop_reason; } + step_mem->n_stepper_evolves++; + + /* Write tendency into the SUNStepper forcing */ + const SUNStepper s2 = step_mem->stepper2; + const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; + N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s2->forcing[0]); + + err = s2->ops->reset(s2, ark_mem->tn, ark_mem->ycur); + if (err != SUN_SUCCESS) { return err; } + + err = s2->ops->evolve(s2, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + if (err != SUN_SUCCESS) { return err; } + if (stop_reason < 0) { return stop_reason; } + step_mem->n_stepper_evolves++; + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + Prints integrator statistics + ---------------------------------------------------------------*/ +static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, + FILE* const outfile, + const SUNOutputFormat fmt) +{ + // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged + ARKodeForcingStepMem step_mem = NULL; + const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + switch (fmt) + { + case SUN_OUTPUTFORMAT_TABLE: + fprintf(outfile, "Stepper evolves = %ld\n", + step_mem->n_stepper_evolves); + break; + case SUN_OUTPUTFORMAT_CSV: + fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); + break; + default: + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Invalid formatting option."); + return (ARK_ILL_INPUT); + } + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + Outputs all solver parameters to the provided file pointer. + ---------------------------------------------------------------*/ +static int forcingStep_WriteParameters(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED FILE* const fp) +{ + // This method has no extra parameters + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + This routine resizes the memory within the ForcingStep module. + ---------------------------------------------------------------*/ +static int forcingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, + SUNDIALS_MAYBE_UNUSED const N_Vector ynew, + SUNDIALS_MAYBE_UNUSED const sunrealtype hscale, + SUNDIALS_MAYBE_UNUSED const sunrealtype t0, + SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, + SUNDIALS_MAYBE_UNUSED void* const resize_data) +{ + /* Nothing to do since the step_mem has no vectors. Users are responsible for + * resizing the SUNSteppers. */ + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + Frees all ForcingStep memory. + ---------------------------------------------------------------*/ +static void forcingStep_Free(const ARKodeMem ark_mem) +{ + ARKodeForcingStepMem step_mem = (ARKodeForcingStepMem)ark_mem->step_mem; + if (step_mem == NULL) { return; } + free(step_mem); + ark_mem->step_mem = NULL; +} + +/*--------------------------------------------------------------- + This routine outputs the memory from the ForcingStep + structure to a specified file pointer (useful when debugging). + ---------------------------------------------------------------*/ +static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) +{ + ARKodeForcingStepMem step_mem = NULL; + const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return; } + + /* output long integer quantities */ + fprintf(outfile, "ForcingStep: n_stepper_evolves = %li\n", + step_mem->n_stepper_evolves); +} + +/*--------------------------------------------------------------- + Specifies the method order + ---------------------------------------------------------------*/ +static int forcingStep_SetOrder(const ARKodeMem ark_mem, const int order) +{ + if (order > 1) { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "ForcingStep only supports an order of 1"); + } + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + Resets all ForcingStep optional inputs to their default + values. Does not change problem-defining function pointers or + user_data pointer. + ---------------------------------------------------------------*/ +static int forcingStep_SetDefaults(const ARKodeMem ark_mem) +{ + ark_mem->interp_type = ARK_INTERP_LAGRANGE; + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + Creates the ForcingStep integrator + ---------------------------------------------------------------*/ +void* ForcingStepCreate(SUNStepper stepper1, + SUNStepper stepper2, + sunrealtype t0, N_Vector y0, + SUNContext sunctx) +{ + if (stepper1 == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "stepper1 = NULL illegal."); + return NULL; + } + + if (stepper2 == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "stepper2 = NULL illegal."); + return NULL; + } + + if (y0 == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_NULL_Y0); + return NULL; + } + + if (sunctx == NULL) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_NULL_SUNCTX); + return NULL; + } + + /* Test if all required vector operations are implemented */ + if (!forcingStep_CheckNVector(y0)) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + MSG_ARK_BAD_NVECTOR); + return (NULL); + } + + /* Create ark_mem structure and set default values */ + ARKodeMem ark_mem = arkCreate(sunctx); + if (ark_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_ARK_NO_MEM); + return (NULL); + } + + const ARKodeForcingStepMem step_mem = + (ARKodeForcingStepMem)malloc(sizeof(*step_mem)); + if (step_mem == NULL) + { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_ARKMEM_FAIL); + ARKodeFree((void**)&ark_mem); + return NULL; + } + + step_mem->stepper1 = stepper1; + step_mem->stepper2 = stepper2; + step_mem->n_stepper_evolves = 0; + + /* Attach step_mem structure and function pointers to ark_mem */ + ark_mem->step_init = forcingStep_Init; + ark_mem->step_fullrhs = forcingStep_FullRHS; + ark_mem->step = forcingStep_TakeStep; + ark_mem->step_printallstats = forcingStep_PrintAllStats; + ark_mem->step_writeparameters = forcingStep_WriteParameters; + ark_mem->step_resize = forcingStep_Resize; + ark_mem->step_free = forcingStep_Free; + ark_mem->step_printmem = forcingStep_PrintMem; + ark_mem->step_setdefaults = forcingStep_SetDefaults; + ark_mem->step_setorder = forcingStep_SetOrder; + ark_mem->step_mem = (void*)step_mem; + + /* Set default values for ARKStep optional inputs */ + int retval = forcingStep_SetDefaults(ark_mem); + if (retval != ARK_SUCCESS) + { + arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, + "Error setting default solver options"); + ARKodeFree((void**)&ark_mem); + return (NULL); + } + + /* Initialize main ARKODE infrastructure */ + retval = arkInit(ark_mem, t0, y0, FIRST_INIT); + if (retval != ARK_SUCCESS) + { + arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, + "Unable to initialize main ARKODE infrastructure"); + ARKodeFree((void**)&ark_mem); + return (NULL); + } + + return ark_mem; +} diff --git a/src/arkode/arkode_forcingstep_impl.h b/src/arkode/arkode_forcingstep_impl.h new file mode 100644 index 0000000000..863ea6e0e5 --- /dev/null +++ b/src/arkode/arkode_forcingstep_impl.h @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * This header defines the step memory for SplittingStep. + *--------------------------------------------------------------*/ + +#ifndef ARKODE_SPLITTINGSTEP_IMPL_H_ +#define ARKODE_SPLITTINGSTEP_IMPL_H_ + +#include + +typedef struct ARKodeForcingStepMemRec +{ + SUNStepper stepper1; + SUNStepper stepper2; + long int n_stepper_evolves; +}* ARKodeForcingStepMem; + +#endif diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 5446bcd547..6679b60260 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -138,29 +138,28 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - /* immediately return if reset */ - if (init_type == RESET_INIT) { return ARK_SUCCESS; } - - /* initializations/checks for (re-)initialization call */ - if (init_type == FIRST_INIT) + /* immediately return if resize or reset */ + if (init_type == RESIZE_INIT || init_type == RESET_INIT) { - retval = splittingStep_SetCoefficients(ark_mem, step_mem); - if (retval != ARK_SUCCESS) { return retval; } + return ARK_SUCCESS; + } + retval = splittingStep_SetCoefficients(ark_mem, step_mem); + if (retval != ARK_SUCCESS) { return retval; } + + if (step_mem->policy == NULL) + { + step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); if (step_mem->policy == NULL) { - step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); - if (step_mem->policy == NULL) + if (step_mem->coefficients == NULL) { - if (step_mem->coefficients == NULL) - { - arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, - "Failed to allocate execution policy"); - return ARK_MEM_FAIL; - } + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + "Failed to allocate execution policy"); + return ARK_MEM_FAIL; } - step_mem->own_policy = SUNTRUE; } + step_mem->own_policy = SUNTRUE; } ark_mem->interp_degree = @@ -258,10 +257,10 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, sunrealtype tret = 0; int stop_reason = 0; err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret, &stop_reason); - step_mem->n_stepper_evolves++; - if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } + + step_mem->n_stepper_evolves++; } } From 7bd615c560d1898b6316c84fe249a9fa8945bb43 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 17:30:25 -0700 Subject: [PATCH 025/180] Add cli to ark analytic partitioned --- examples/arkode/C_serial/CMakeLists.txt | 4 +- ...splitting.c => ark_analytic_partitioned.c} | 107 ++++++++++++------ src/arkode/arkode_forcingstep.c | 79 +++++-------- src/arkode/arkode_splittingstep.c | 20 +--- src/sundials/sundials_stepper.c | 2 +- 5 files changed, 106 insertions(+), 106 deletions(-) rename examples/arkode/C_serial/{ark_analytic_splitting.c => ark_analytic_partitioned.c} (61%) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 27e5a53490..1464cf69ee 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,7 +26,9 @@ set(ARKODE_examples "ark_advection_diffusion_reaction_splitting\;\;develop" "ark_analytic_mels\;\;develop" "ark_analytic_nonlin\;\;develop" - "ark_analytic_splitting\;\;develop" + "ark_analytic_partitioned\;forcing\;develop" + "ark_analytic_partitioned\;splitting\;develop" + "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_BEST_2_2_2\;develop" "ark_brusselator_1D_mri\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator_mri\;\;develop" diff --git a/examples/arkode/C_serial/ark_analytic_splitting.c b/examples/arkode/C_serial/ark_analytic_partitioned.c similarity index 61% rename from examples/arkode/C_serial/ark_analytic_splitting.c rename to examples/arkode/C_serial/ark_analytic_partitioned.c index 62ca2329ff..ec4f5da5af 100644 --- a/examples/arkode/C_serial/ark_analytic_splitting.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -1,6 +1,6 @@ -/*----------------------------------------------------------------- +/*------------------------------------------------------------------------------ * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- + *------------------------------------------------------------------------------ * SUNDIALS Copyright Start * Copyright (c) 2002-2024, Lawrence Livermore National Security * and Southern Methodist University. @@ -10,30 +10,37 @@ * * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End - *--------------------------------------------------------------- - * Example problem: + *------------------------------------------------------------------------------ + * We consider the initial value problem + * y' + lambda*y = y^2, y(0) = 1 + * proposed in + * + * Estep, D., et al. "An a posteriori–a priori analysis of multiscale operator + * splitting." SIAM Journal on Numerical Analysis 46.3 (2008): 1116-1146. * - * The following is a simple example problem with analytical - * solution, - * dy/dt = lambda*y + 1/(1+t^2) - lambda*atan(t) - * for t in the interval [0.0, 10.0], with initial condition: y=0. + * The parameter lambda is positive, t is in [0, 1], and the exact solution is + * + * y(t) = lambda*y / (y(0) - (y(0) - lambda)*exp(lambda*t)) * - * The stiffness of the problem is directly proportional to the - * value of "lambda". The value of lambda should be negative to - * result in a well-posed ODE; for values with magnitude larger - * than 100 the problem becomes quite stiff. - * - * This program solves the problem with the DIRK method, - * Newton iteration with the dense SUNLinearSolver, and a - * user-supplied Jacobian routine. - * Output is printed every 1.0 units of time (10 total). - * Run statistics (optional outputs) are printed at the end. - *-----------------------------------------------------------------*/ + * This program solves the problem with a splitting or forcing method which can + * be specified with the command line syntax + * + * ./ark_analytic_partitioned + * integrator: either 'splitting' or 'forcing' + * coefficients (splitting only): the SplittingStepCoefficients to load + * + * The linear term lambda*y and nonlinear term y^2 are treated as the two + * partitions. The former is integrated with a time step 5x smaller than the + * outer method, while the later uses a 10x smaller time step. Once solved, the + * program prints the error and statistics. + *----------------------------------------------------------------------------*/ /* Header files */ #include #include +#include #include +#include #if defined(SUNDIALS_EXTENDED_PRECISION) #define GSYM "Lg" @@ -122,12 +129,20 @@ static int check_flag(void* flagvalue, const char* funcname, int opt) return 0; } -int main() +int main(const int argc, char* const argv[]) { + /* Parse arguments */ + const char *const integrator_name = (argc > 1) ? argv[1] : "splitting"; + if (strcmp(integrator_name, "splitting") != 0 && strcmp(integrator_name, "forcing") != 0) { + fprintf(stderr, "Invalid integrator: %s\nMust be 'splitting' or 'forcing'\n", integrator_name); + return 1; + } + const char *const coefficients_name = (argc > 2) ? argv[2] : NULL; + /* Problem parameters */ const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ const sunrealtype tf = SUN_RCONST(1.0); /* final time */ - const sunrealtype dt = SUN_RCONST(0.01); /* operator splitting time step */ + const sunrealtype dt = SUN_RCONST(0.01); /* outer time step */ const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ const sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ @@ -139,14 +154,18 @@ int main() if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } /* Initialize vector with initial condition */ - N_Vector y = N_VNew_Serial(1, ctx); + const N_Vector y = N_VNew_Serial(1, ctx); if (check_flag(y, "N_VNew_Serial", 0)) { return 1; } N_VConst(SUN_RCONST(1.0), y); - N_Vector y_exact = exact_sol(y, tf, &user_data); + const N_Vector y_exact = exact_sol(y, tf, &user_data); printf("\nAnalytical ODE test problem:\n"); - printf(" lambda = %" GSYM "\n", user_data.lambda); + printf(" integrator = %s method\n", integrator_name); + if (coefficients_name != NULL) { + printf(" coefficients = %s\n", coefficients_name); + } + printf(" lambda = %" GSYM "\n", user_data.lambda); /* Create the integrator for the linear partition */ void* linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); @@ -170,23 +189,43 @@ int main() ARKStepCreateSUNStepper(linear_mem, &steppers[0]); ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); - /* Create the operator splitting method */ - void* splitting_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); - if (check_flag(splitting_mem, "SplittingStepCreate", 0)) { return 1; } + /* Create the outer integrator */ + void *arkode_mem; + if (strcmp(integrator_name, "splitting") == 0) { + arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); + if (check_flag(arkode_mem, "SplittingStepCreate", 0)) { return 1; } + + if (coefficients_name != NULL) { + const SplittingStepCoefficients coefficients = SplittingStepCoefficients_LoadCoefficientsByName(coefficients_name); + if (check_flag(coefficients, "SplittingStepCoefficients_LoadCoefficientsByName", 0)) { return 1; } - flag = ARKodeSetFixedStep(splitting_mem, dt); + flag = SplittingStep_SetCoefficients(arkode_mem, coefficients); + if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } + + SplittingStepCoefficients_Free(coefficients); + } + } else { + arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); + if (check_flag(arkode_mem, "ForcingStepCreate", 0)) { return 1; } + } + + flag = ARKodeSetFixedStep(arkode_mem, dt); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } - /* Compute the operator splitting solution */ + /* Compute the numerical solution */ sunrealtype tret; - flag = ARKodeEvolve(splitting_mem, tf, y, &tret, ARK_NORMAL); + flag = ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } - /* Print the numerical error */ - N_Vector y_err = N_VClone(y); + /* Print the numerical error and statistics */ + const N_Vector y_err = N_VClone(y); if (check_flag(y_err, "N_VClone", 0)) { return 1; } N_VLinearSum(SUN_RCONST(1.0), y, -SUN_RCONST(1.0), y_exact, y_err); - printf("Error: %" GSYM "\n", N_VMaxNorm(y_err)); + printf("\nError: %" GSYM "\n", N_VMaxNorm(y_err)); + + printf("Final Solver Statistics:\n"); + flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } /* Free memory */ N_VDestroy(y); @@ -196,7 +235,7 @@ int main() SUNStepper_Destroy(&steppers[0]); ARKodeFree(&nonlinear_mem); SUNStepper_Destroy(&steppers[1]); - ARKodeFree(&splitting_mem); + ARKodeFree(&arkode_mem); SUNContext_Free(&ctx); return 0; diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 707bbbbfe0..3be84278ff 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -56,8 +56,7 @@ static sunbooleantype forcingStep_CheckNVector(const N_Vector y) within arkInitialSetup. With initialization types FIRST_INIT this routine: - - sets/checks the splitting coefficients to be used - - sets/checks the execution policy to be used + - sets the forcing for stepper2 With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ @@ -74,11 +73,7 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } - /* Only one forcing vector is needed which come from the already allocated - * tempv1 */ - step_mem->stepper2->nforcing = 1; - step_mem->stepper2->nforcing_allocated = 1; - step_mem->stepper2->forcing = &ark_mem->tempv1; + SUNStepper_SetForcing(step_mem->stepper2, 1, ark_mem->yn); ark_mem->interp_degree = 1; @@ -155,23 +150,27 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype tret = 0; int stop_reason = 0; - SUNErrCode err = s1->ops->reset(s1, ark_mem->tn, ark_mem->yn); + /* Evolve partition 1 on its own */ + SUNErrCode err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); if (err != SUN_SUCCESS) { return err; } - - err = s1->ops->evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + err = SUNStepper_SetStopTime(s1, tout); + if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } step_mem->n_stepper_evolves++; - /* Write tendency into the SUNStepper forcing */ + /* Write tendency into stepper 2 forcing */ const SUNStepper s2 = step_mem->stepper2; const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s2->forcing[0]); - err = s2->ops->reset(s2, ark_mem->tn, ark_mem->ycur); + /* No need to reset stepper 2 since its trajectory is continuous and in sync + * with the outer forcing method */ + err = SUNStepper_SetStopTime(s2, tout); if (err != SUN_SUCCESS) { return err; } - err = s2->ops->evolve(s2, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + err = SUNStepper_Evolve(s2, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } step_mem->n_stepper_evolves++; @@ -209,30 +208,6 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, return ARK_SUCCESS; } -/*--------------------------------------------------------------- - Outputs all solver parameters to the provided file pointer. - ---------------------------------------------------------------*/ -static int forcingStep_WriteParameters(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED FILE* const fp) -{ - // This method has no extra parameters - return ARK_SUCCESS; -} - -/*--------------------------------------------------------------- - This routine resizes the memory within the ForcingStep module. - ---------------------------------------------------------------*/ -static int forcingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, - SUNDIALS_MAYBE_UNUSED const N_Vector ynew, - SUNDIALS_MAYBE_UNUSED const sunrealtype hscale, - SUNDIALS_MAYBE_UNUSED const sunrealtype t0, - SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, - SUNDIALS_MAYBE_UNUSED void* const resize_data) -{ - /* Nothing to do since the step_mem has no vectors. Users are responsible for - * resizing the SUNSteppers. */ - return ARK_SUCCESS; -} - /*--------------------------------------------------------------- Frees all ForcingStep memory. ---------------------------------------------------------------*/ @@ -259,18 +234,6 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) step_mem->n_stepper_evolves); } -/*--------------------------------------------------------------- - Specifies the method order - ---------------------------------------------------------------*/ -static int forcingStep_SetOrder(const ARKodeMem ark_mem, const int order) -{ - if (order > 1) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "ForcingStep only supports an order of 1"); - } - return ARK_SUCCESS; -} - /*--------------------------------------------------------------- Resets all ForcingStep optional inputs to their default values. Does not change problem-defining function pointers or @@ -283,6 +246,20 @@ static int forcingStep_SetDefaults(const ARKodeMem ark_mem) return ARK_SUCCESS; } +static int forcingStep_Reset(ARKodeMem ark_mem, sunrealtype tR, N_Vector yR) +{ + ARKodeForcingStepMem step_mem = NULL; + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return retval; } + + /* Reset stepper 2 to be consistent. No need to reset stepper 1 since that + * happens at the start of a step anyway. */ + retval = SUNStepper_Reset(step_mem->stepper2, tR, yR); + if (retval != ARK_SUCCESS) { return ARK_INNERSTEP_FAIL; } + + return ARK_SUCCESS; +} + /*--------------------------------------------------------------- Creates the ForcingStep integrator ---------------------------------------------------------------*/ @@ -355,12 +332,10 @@ void* ForcingStepCreate(SUNStepper stepper1, ark_mem->step_fullrhs = forcingStep_FullRHS; ark_mem->step = forcingStep_TakeStep; ark_mem->step_printallstats = forcingStep_PrintAllStats; - ark_mem->step_writeparameters = forcingStep_WriteParameters; - ark_mem->step_resize = forcingStep_Resize; ark_mem->step_free = forcingStep_Free; ark_mem->step_printmem = forcingStep_PrintMem; ark_mem->step_setdefaults = forcingStep_SetDefaults; - ark_mem->step_setorder = forcingStep_SetOrder; + ark_mem->step_reset = forcingStep_Reset; ark_mem->step_mem = (void*)step_mem; /* Set default values for ARKStep optional inputs */ diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 6679b60260..e35124bec4 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -248,10 +248,10 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, if (t_start == t_end) { continue; } const SUNStepper stepper = step_mem->steppers[k]; - SUNErrCode err = stepper->ops->reset(stepper, t_start, y); + SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return err; } - err = stepper->ops->setstoptime(stepper, t_end); + err = SUNStepper_SetStopTime(stepper, t_end); if (err != SUN_SUCCESS) { return err; } sunrealtype tret = 0; @@ -334,21 +334,6 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp return ARK_SUCCESS; } -/*--------------------------------------------------------------- - This routine resizes the memory within the SplittingStep module. - ---------------------------------------------------------------*/ -static int splittingStep_Resize(SUNDIALS_MAYBE_UNUSED const ARKodeMem ark_mem, - SUNDIALS_MAYBE_UNUSED const N_Vector ynew, - SUNDIALS_MAYBE_UNUSED const sunrealtype hscale, - SUNDIALS_MAYBE_UNUSED const sunrealtype t0, - SUNDIALS_MAYBE_UNUSED const ARKVecResizeFn resize, - SUNDIALS_MAYBE_UNUSED void* const resize_data) -{ - /* Nothing to do since the step_mem has no vectors. Users are responsible for - * resizing the SUNSteppers. */ - return ARK_SUCCESS; -} - /*--------------------------------------------------------------- Frees all SplittingStep memory. ---------------------------------------------------------------*/ @@ -519,7 +504,6 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, ark_mem->step = splittingStep_TakeStep; ark_mem->step_printallstats = splittingStep_PrintAllStats; ark_mem->step_writeparameters = splittingStep_WriteParameters; - ark_mem->step_resize = splittingStep_Resize; ark_mem->step_free = splittingStep_Free; ark_mem->step_printmem = splittingStep_PrintMem; ark_mem->step_setdefaults = splittingStep_SetDefaults; diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index d1ba8f9782..67b3aff97c 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -54,7 +54,7 @@ SUNErrCode SUNStepper_Destroy(SUNStepper* stepper_ptr) if (stepper->forcing) { N_VDestroyVectorArray(stepper->forcing, stepper->nforcing); - N_VDestroyVectorArray(stepper->fused_vectors, stepper->nforcing); + free(stepper->fused_vectors); free(stepper->fused_scalars); } From 61ff2be5945e59b31837a5877402b0622bca1e49 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 18:10:18 -0700 Subject: [PATCH 026/180] Simplify setter freeing --- src/arkode/arkode_forcingstep.c | 9 +++------ src/arkode/arkode_splittingstep.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 3be84278ff..551afa0aa1 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -46,7 +46,6 @@ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, ---------------------------------------------------------------*/ static sunbooleantype forcingStep_CheckNVector(const N_Vector y) { - // TODO(SBR): check all ops are correct return y->ops->nvlinearsum != NULL; } @@ -74,7 +73,6 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) } SUNStepper_SetForcing(step_mem->stepper2, 1, ark_mem->yn); - ark_mem->interp_degree = 1; return ARK_SUCCESS; @@ -133,7 +131,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, } /*--------------------------------------------------------------- - This routine performs a single step of the splitting method. + This routine performs a single step of the forcing method. ---------------------------------------------------------------*/ static int forcingStep_TakeStep(const ARKodeMem ark_mem, sunrealtype* const dsmPtr, int* const nflagPtr) @@ -170,6 +168,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, err = SUNStepper_SetStopTime(s2, tout); if (err != SUN_SUCCESS) { return err; } + /* Eolve partition 2 with the forcing */ err = SUNStepper_Evolve(s2, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } @@ -213,9 +212,7 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, ---------------------------------------------------------------*/ static void forcingStep_Free(const ARKodeMem ark_mem) { - ARKodeForcingStepMem step_mem = (ARKodeForcingStepMem)ark_mem->step_mem; - if (step_mem == NULL) { return; } - free(step_mem); + free(ark_mem->step_mem); ark_mem->step_mem = NULL; } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index e35124bec4..952d48a7eb 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -339,17 +339,17 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp ---------------------------------------------------------------*/ static void splittingStep_Free(const ARKodeMem ark_mem) { - ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; - if (step_mem == NULL) { return; } + const ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; + if (step_mem != NULL) { + free(step_mem->steppers); + if (step_mem->own_policy) + { + ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); + } - free(step_mem->steppers); - if (step_mem->own_policy) - { - ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); + SplittingStepCoefficients_Free(step_mem->coefficients); + free(step_mem); } - - SplittingStepCoefficients_Free(step_mem->coefficients); - free(step_mem); ark_mem->step_mem = NULL; } From 18da8463f342eca71d14658154c96d799c651ef0 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 18:10:48 -0700 Subject: [PATCH 027/180] Add doc on default coefficients --- .../SplittingStep/SplittingStepCoefficients.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index b40f53ad5a..54f77386d8 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -454,4 +454,19 @@ with values specified for each method below (e.g., Default Operator Splitting Coefficients ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The default SplittingStep \ No newline at end of file +The default SplittingStep coefficients are Lie-Trotter. If a particular order is +requested with :c:func:`ARKodeSetOrder`, the following are the default for each +order + +.. table:: Default operator splitting coefficients by order. + + ============ ========================================================== + Order Default operator splitting coefficients + ============ ========================================================== + 1 :c:func:`SplittingStepCoefficients_LieTrotter` + 2 :c:func:`SplittingStepCoefficients_Strang` + 3 :c:func:`SplittingStepCoefficients_ThirdOrderSuzuki` + 4, 6, 8, ... :c:func:`SplittingStepCoefficients_TripleJump` + 5, 7, 9, ... Warning: this will select a triple jump method of the next + even order + ============ ========================================================== From 239d75a28cf1eb108528193a5897a0984d352d13 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 18:34:56 -0700 Subject: [PATCH 028/180] Finish first draft of user callable --- .../Usage/SplittingStep/User_callable.rst | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index d3c3199d08..d5cc6a0627 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -39,8 +39,9 @@ SplittingStep initialization functions using the SplittingStep time-stepping module in ARKODE. **Arguments:** - * *steppers* -- ? - * *partitions* -- ? + * *steppers* -- an array of :c:type:`SUNStepper` with one for each + partition of the IVP. + * *partitions* -- the number :math:`P > 1` of partitions in the IVP. * *t0* -- the initial value of :math:`t`. * *y0* -- the initial condition vector :math:`y(t_0)`. * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) @@ -55,30 +56,30 @@ SplittingStep initialization functions .. code-block:: C - /* fast (inner) and slow (outer) ARKODE objects */ - void *inner_arkode_mem = NULL; - void *outer_arkode_mem = NULL; + /* inner ARKODE objects for integrating individual partitions */ + void *partition_mem[] = {NULL, NULL}; - /* MRIStepInnerStepper to wrap the inner (fast) ARKStep object */ - MRIStepInnerStepper stepper = NULL; + /* SUNSteppers to wrap the inner ARKStep objects */ + SUNStepper steppers[] = {NULL, NULL}; - /* create an ARKStep object, setting fast (inner) right-hand side - functions and the initial condition */ - inner_arkode_mem = ARKStepCreate(ffe, ffi, t0, y0, sunctx); + /* create ARKStep objects, setting right-hand side functions and the + initial condition */ + partition_mem[0] = ARKStepCreate(ffe1, ffi1, t0, y0, sunctx); + partition_mem[1] = ARKStepCreate(ffe2, ffi2, t0, y0, sunctx); /* setup ARKStep */ . . . - /* create MRIStepInnerStepper wrapper for the ARKStep memory block */ - flag = ARKStepCreateMRIStepInnerStepper(inner_arkode_mem, &stepper); + /* create SUNStepper wrappers for the ARKStep memory blocks */ + flag = ARKStepCreateSUNStepper(partition_mem[0], &stepper[0]); + flag = ARKStepCreateSUNStepper(partition_mem[1], &stepper[1]); - /* create an MRIStep object, setting the slow (outer) right-hand side - functions and the initial condition */ - outer_arkode_mem = MRIStepCreate(fse, fsi, t0, y0, stepper, sunctx) + /* create a SplittingStep object with two partitions */ + arkode_mem = SplittingStepCreate(steppers, 2, t0, y0, sunctx); **Example codes:** * ``examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c`` - * ``examples/arkode/C_serial/ark_analytic_splitting.c`` + * ``examples/arkode/C_serial/ark_analytic_partitioned.c`` .. versionadded:: x.y.z @@ -94,7 +95,7 @@ Optional inputs for IVP method selection * *arkode_mem* -- pointer to the SplittingStep memory block. - * *coefficients* -- the table of coupling coefficients for the MRI method. + * *coefficients* -- the splitting coefficients for the method. **Return value:** From 3b76690eaff26de53ed700dc397a661d075a4146 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 18:41:53 -0700 Subject: [PATCH 029/180] Fix coefficient docs warnings --- .../SplittingStepCoefficients.rst | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 54f77386d8..cc4ea0de03 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -22,7 +22,7 @@ coefficients of various orders and partitions. There are also a number of built-in methods of fixed orders and partitions (see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`). Finally, a user may construct a custom set of coefficients and attach it with -:c:func:`SplittingStepSetCoefficients`. The operator splitting coefficients are +:c:func:`SplittingStep_SetCoefficients`. The operator splitting coefficients are stored in a :c:func:`SplittingStepCoefficients` object which is a pointer to a :c:struct:`SplittingStepCoefficientsMem` structure: @@ -152,7 +152,7 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. versionadded:: x.y.z -.. c:function:: const char* SplittingStepCoefficients_LoadCoefficientsByName(ARKODE_SplittingCoefficientsID method) +.. c:function:: const char* SplittingStepCoefficients_IDToName(ARKODE_SplittingCoefficientsID method) Converts specified splitting coefficients ID to a string of the same name. For further information on the current set of splitting coefficients and @@ -176,7 +176,6 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} \circ \dots \circ \phi^1_{h} \right) (y_{n-1}) - :label: ARKODE_Lie-Trotter **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -194,10 +193,9 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), - :label: ARKODE_Strang - where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and - :math:`L*_h = L^{-1}_{-h}` is its adjoint. + where :math:`L` is the Lie-Trotter splitting and :math:`L*_h = L^{-1}_{-h}` + is its adjoint. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -235,8 +233,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), - where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and - :math:`L^*_h = L^{-1}_{-h}` is its adjoint. + where :math:`L` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` + is its adjoint. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -256,9 +254,9 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. y_n = \left( L_{p_1 h} \circ L^*_{p_2 h} \circ L_{p_3 h} \circ L^*_{p_4 h} \circ L_{p_5 h} \right) (y_{n-1}), - where :math:`L` is the Lie-Trotter splitting :eq:`ARKODE_Lie` and - :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters - :math:`p_1, \dots, p_5` are selected to give third order. + where :math:`L` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` + is its adjoint. The parameters :math:`p_1, \dots, p_5` are selected to give + third order. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -283,8 +281,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. y_n &= T_h^{[order]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting :eq:`ARKODE_Stang` and parameter - :math:`\gamma_1` selected to increase the order by two each recursion. + where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is + selected to increase the order by two each recursion. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -312,8 +310,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. y_n &= Q_h^{[order]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting :eq:`ARKODE_Stang` and parameter - :math:`\gamma_1` selected to increase the order by two each recursion. + where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is + selected to increase the order by two each recursion. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. From 5164e7d0a608ed66842940430003781675b067fc Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 4 Sep 2024 18:48:24 -0700 Subject: [PATCH 030/180] Update changelogs --- CHANGELOG.md | 3 +++ doc/shared/RecentChanges.rst | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a82dd8621..9e174d0969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Major Features +Added an operator splitting module, SplittingStep, and forcing method module, +ForcingStep. to ARKODE. + ### New Features and Enhancements The default value of `CMAKE_CUDA_ARCHITECTURES` is no longer set to `70` and is diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 0cd3986ee3..e77f45909d 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -1,5 +1,9 @@ **Major Features** +Added an operator splitting module, +:ref:`SplittingStep `, and forcing method module, +:ref:`ForcingStep `, to ARKODE. + **New Features and Enhancements** The default value of :cmakeop:`CMAKE_CUDA_ARCHITECTURES` is no longer set to From 9eda8e12e7a7194e41fb0115e44fd5bf774c05ab Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 10:41:12 -0700 Subject: [PATCH 031/180] Polish math section --- doc/arkode/guide/source/Mathematics.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index acb41f7172..e1f45e2dcf 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -572,7 +572,6 @@ using a fixed time-step size. .. The `ark_kepler.c` example demonstrates an implementation of such controller. - .. _ARKODE.Mathematics.SplittingStep: SplittingStep -- Operator splitting methods @@ -627,20 +626,26 @@ An alternative representation of the SplittingStep solution is y_n = \sum_{i=1}^P \alpha_i \left( \phi^P_{\gamma_{i,1,P} h} \circ \phi^{P-1}_{\gamma_{i,1,P-1} h} \circ \dots \circ \phi^1_{\gamma_{i,1,1} h} \circ \phi^P_{\gamma_{i,2,P} h} \circ \dots \circ \phi^P_{\gamma_{i,s,P} h} - \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right) + \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right), (y_{n-1}) where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and -:math:`\phi^j_{h}` is the flow map for partition :math:`j`. +:math:`\phi^j_{h}` is the flow map for partition :math:`j`: + +.. math:: + \phi^j_{h}(y_{n_1}) = v(t_n), + \quad \begin{cases} + v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f^j(t, v). + \end{cases} SplittingStep provides standard operator splitting methods such as Lie-Trotter and Strang splitting, as well as schemes of arbitrarily high order. -Alternatively, users may construct their own coefficients (see TODO). Generally, +Alternatively, users may construct their own coefficients (see +:numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`). Generally, methods of order three and higher with real coefficients require backward integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. Currently, a fixed time step must be specified for the outer SplittingStep, but -inner integrators are free to use adaptive time steps. See TODO for -additional details. +inner integrators are free to use adaptive time steps. .. _ARKODE.Mathematics.MRIStep: From 1c400716dd68677ca65a26587f5bbb6222b3e854 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 11:03:26 -0700 Subject: [PATCH 032/180] Polish splitting step docs --- .../SplittingStepCoefficients.rst | 24 +++++++++---------- .../Usage/SplittingStep/User_callable.rst | 4 ++-- .../arkode/arkode_splitting_coefficients.h | 1 + 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index cc4ea0de03..91c8382850 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -23,7 +23,7 @@ built-in methods of fixed orders and partitions (see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`). Finally, a user may construct a custom set of coefficients and attach it with :c:func:`SplittingStep_SetCoefficients`. The operator splitting coefficients are -stored in a :c:func:`SplittingStepCoefficients` object which is a pointer to a +stored in a :c:type:`SplittingStepCoefficients` object which is a pointer to a :c:struct:`SplittingStepCoefficientsMem` structure: .. c:type:: SplittingStepCoefficientsMem *SplittingStepCoefficients @@ -175,7 +175,7 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} - \circ \dots \circ \phi^1_{h} \right) (y_{n-1}) + \circ \dots \circ \phi^1_{h} \right) (y_{n-1}). **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -194,8 +194,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), - where :math:`L` is the Lie-Trotter splitting and :math:`L*_h = L^{-1}_{-h}` - is its adjoint. + where :math:`L_h` is the Lie-Trotter splitting and + :math:`L^*_h = L^{-1}_{-h}` is its adjoint. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -213,7 +213,7 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + - (1 - p) y_{n-1}, + (1 - p) y_{n-1}. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -233,8 +233,8 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), - where :math:`L` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` - is its adjoint. + where :math:`L_h` is the Lie-Trotter splitting and + :math:`L^*_h = L^{-1}_{-h}` is its adjoint. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -254,9 +254,9 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. y_n = \left( L_{p_1 h} \circ L^*_{p_2 h} \circ L_{p_3 h} \circ L^*_{p_4 h} \circ L_{p_5 h} \right) (y_{n-1}), - where :math:`L` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` - is its adjoint. The parameters :math:`p_1, \dots, p_5` are selected to give - third order. + where :math:`L_h` is the Lie-Trotter splitting and + :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters + :math:`p_1, \dots, p_5` are selected to give third order. **Arguments:** * *partitions* -- The number :math:`P > 1` of partitions in the IVP. @@ -275,7 +275,7 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: \begin{align*} - T_h^{[2]} &= S, \\ + T_h^{[2]} &= S_h, \\ T_h^{[i+2]} &= T_{\gamma_1 h}^{[i]} \circ T_{(1 - 2 \gamma_1) h}^{[i]} \circ T_{\gamma_1 h}^{[i]}, \\ y_n &= T_h^{[order]}(y_{n-1}), @@ -303,7 +303,7 @@ integer constants are defined ``arkode/arkode_splitting_coefficients.h``. .. math:: \begin{align*} - Q_h^{[2]} &= S, \\ + Q_h^{[2]} &= S_h, \\ Q_h^{[i+2]} &= Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]} \circ Q_{(1 - 4 \gamma_1) h}^i \circ Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]}, \\ diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index d5cc6a0627..d06fa02109 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -64,8 +64,8 @@ SplittingStep initialization functions /* create ARKStep objects, setting right-hand side functions and the initial condition */ - partition_mem[0] = ARKStepCreate(ffe1, ffi1, t0, y0, sunctx); - partition_mem[1] = ARKStepCreate(ffe2, ffi2, t0, y0, sunctx); + partition_mem[0] = ARKStepCreate(fe1, fi1, t0, y0, sunctx); + partition_mem[1] = ARKStepCreate(fe2, fi2, t0, y0, sunctx); /* setup ARKStep */ . . . diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index 92604fdff4..191784ceee 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -36,6 +36,7 @@ struct SplittingStepCoefficientsMem int sequential_methods; /* number of sequential splitting methods */ int stages; /* number of stages within each sequential splitting method */ int partitions; /* number of RHS partitions */ + /* TODO(SBR): q to be more consistent? */ int order; /* order of convergence */ }; From 9387de0678706c4612113d005e4f9e94a5d95362 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 11:49:55 -0700 Subject: [PATCH 033/180] Add ForcingStep math docs --- doc/arkode/guide/source/Mathematics.rst | 43 +++++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index e1f45e2dcf..9bbce05061 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -580,10 +580,8 @@ SplittingStep -- Operator splitting methods The SplittingStep time-stepping module in ARKODE is designed for IVPs of the form -.. TODO: SPRK uses subscript for function number. Make consistent .. math:: - \dot{y} = f^1(t,y) + f^2(t,y) + \dots + f^P(t,y), \qquad y(t_0) = y_0, - :label: ARKODE_IVP_partitioned + \dot{y} = f_1(t,y) + f_2(t,y) + \dots + f_P(t,y), \qquad y(t_0) = y_0, with :math:`P > 1` additive partitions. Operator splitting methods, such as those implemented in SplittingStep, allow each partition to be integrated @@ -607,7 +605,7 @@ The following algorithmic procedure is used in the Splitting-Step module: #. Let :math:`v(t_{\text{start}}) = y_{n,i}`. #. For :math:`t \in [t_{\text{start}}, t_{\text{end}}]` solve - :math:`\dot{v} = f^{k}(t, v)`. + :math:`\dot{v} = f_{k}(t, v)`. #. Set :math:`y_{n, i} = v(t_{\text{end}})`. @@ -630,12 +628,12 @@ An alternative representation of the SplittingStep solution is (y_{n-1}) where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and -:math:`\phi^j_{h}` is the flow map for partition :math:`j`: +:math:`\phi^k_{h}` is the flow map for partition :math:`k`: .. math:: - \phi^j_{h}(y_{n_1}) = v(t_n), + \phi^k_{h}(y_{n_1}) = v(t_n), \quad \begin{cases} - v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f^j(t, v). + v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f_k(t, v). \end{cases} SplittingStep provides standard operator splitting methods such as Lie-Trotter @@ -648,6 +646,37 @@ Currently, a fixed time step must be specified for the outer SplittingStep, but inner integrators are free to use adaptive time steps. +.. _ARKODE.Mathematics.ForcingStep: + +ForcingStep -- Forcing method +============================= + +The ForcingStep time-stepping module in ARKODE is designed for IVPs of the form + +.. math:: + \dot{y} = f_1(t,y) + f_2(t,y), \qquad y(t_0) = y_0, + +with two additive partitions. One step of the forcing method implemented in +ForcingStep is given by + +.. math:: + v_1(t_{n-1}) &= y_{n-1}, \\ + \dot{v}_1 &= f_1(t, v_1), \\ + f_1^* &= \frac{v_1(t_n) - y_{n-1}}{h_n}, \\ + v_2(t_{n-1}) &= y_{n-1}, \\ + \dot{v}_2 &= f_1^* + f_2(t, v_2), \\ + y_n &= v_2(t_n). + +Like a Lie-Trotter method from SplittingStep, the partitions are evolved through +a sequence of inner IVPs which can be solve with an arbitrary integrator or +exact solution procedure. However, the IVP for partition two includes a +"forcing" or "tendency" term :math:`f_1^*` to strengthen the coupling. This +coupling leads to a first order method provided :math:`v_1` and :math:`v_2` are +integrated to at least first order accuracy. Currently, a fixed time step must +be specified for the outer ForcingStep, but inner integrators are free to use +adaptive time steps. + + .. _ARKODE.Mathematics.MRIStep: MRIStep -- Multirate infinitesimal step methods From e8816509e3e8b109c08143e48d595ac5f7b8c831 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 11:55:19 -0700 Subject: [PATCH 034/180] Add forcingstep to doc index --- doc/arkode/guide/source/Usage/User_callable.rst | 1 + doc/arkode/guide/source/Usage/index.rst | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/User_callable.rst b/doc/arkode/guide/source/Usage/User_callable.rst index e0832142c9..b310753b66 100644 --- a/doc/arkode/guide/source/Usage/User_callable.rst +++ b/doc/arkode/guide/source/Usage/User_callable.rst @@ -50,6 +50,7 @@ Then in the introduction for each of the stepper-specific documentation sections (:numref:`ARKODE.Usage.ARKStep.UserCallable`, :numref:`ARKODE.Usage.ERKStep.UserCallable`, :numref:`ARKODE.Usage.SplittingStep.UserCallable`, +:numref:`ARKODE.Usage.ForcingStep.UserCallable`, :numref:`ARKODE.Usage.MRIStep.UserCallable`, and :numref:`ARKODE.Usage.SPRKStep.UserCallable`) we clarify the categories of these functions that are supported. diff --git a/doc/arkode/guide/source/Usage/index.rst b/doc/arkode/guide/source/Usage/index.rst index 1ef8ae5df6..08d4fb43d3 100644 --- a/doc/arkode/guide/source/Usage/index.rst +++ b/doc/arkode/guide/source/Usage/index.rst @@ -38,7 +38,8 @@ preconitioners. Following our discussion of these commonalities, we separately discuss the usage details that that are specific to each of ARKODE's time stepping modules: :ref:`ARKStep `, :ref:`ERKStep `, :ref:`SPRKStep `, -:ref:`SplittingStep `, and +:ref:`SplittingStep `, +:ref:`ForcingStep `, and :ref:`MRIStep `. ARKODE also uses various input and output constants; these are defined as @@ -80,4 +81,5 @@ ARKBBDPRE can only be used with NVECTOR_PARALLEL. ERKStep/index.rst SPRKStep/index.rst SplittingStep/index.rst + ForcingStep/index.rst MRIStep/index.rst From c40dda34fe50c2759782e45556e0ec2d0b87bd7d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 12:30:26 -0700 Subject: [PATCH 035/180] Fix tspan in comments --- .../C_serial/ark_advection_diffusion_reaction_splitting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 4a88cb2f92..3811f5fd80 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -16,7 +16,7 @@ * The following test simulates a simple 1D advection-diffusion- * reaction equation, * u_t = a*(u^2/2)_x + b*u_xx + c*(u - u^3) - * for t in [0, 10], x in [0, 1], with initial conditions + * for t in [0, 1], x in [0, 1], with initial conditions * u(0,x) = u_0 * and Dirichlet boundary condition at x=1 * u(0,t) = u(1,t) = u_0 From ce71f148a2a7b3171fdfee655ab6195a224ee461 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 12:32:17 -0700 Subject: [PATCH 036/180] Align printfs --- .../C_serial/ark_advection_diffusion_reaction_splitting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 3811f5fd80..f619dc4538 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -220,7 +220,7 @@ int main() printf(" N = %li\n", (long int)udata.N); printf(" advection coefficient = %" GSYM "\n", udata.a); printf(" diffusion coefficient = %" GSYM "\n", udata.b); - printf(" reaction coefficient = %" GSYM "\n\n", udata.c); + printf(" reaction coefficient = %" GSYM "\n\n", udata.c); /* Create the SUNDIALS context object for this simulation */ SUNContext ctx; From cf2aad287bb60d5e2c287c56748c920b7b9443ab Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 13:19:35 -0700 Subject: [PATCH 037/180] Add ForcingStep docs --- .../Usage/ForcingStep/User_callable.rst | 83 +++++++++++++++++++ .../guide/source/Usage/ForcingStep/index.rst | 32 +++++++ 2 files changed, 115 insertions(+) create mode 100644 doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst create mode 100644 doc/arkode/guide/source/Usage/ForcingStep/index.rst diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst new file mode 100644 index 0000000000..1fdf1ab8d5 --- /dev/null +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -0,0 +1,83 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.ForcingStep.UserCallable: + +ForcingStep User-callable functions +=================================== + +This section describes the ForcingStep-specific functions that may be called +by the user to setup and then solve an IVP using the ForcingStep time-stepping +module. + +As discussed in the main :ref:`ARKODE user-callable function introduction +`, each of ARKODE's time-stepping modules +clarifies the categories of user-callable functions that it supports. +ForcingStep does not support any of the categories beyond the functions that +apply for all time-stepping modules. + + +.. _ARKODE.Usage.ForcingStep.Initialization: + +ForcingStep initialization functions +------------------------------------ + +.. c:function:: void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, sunrealtype t0, N_Vector y0, SUNContext sunctx) + + This function allocates and initializes memory for a problem to be solved + using the ForcingStep time-stepping module in ARKODE. + + **Arguments:** + * *stepper1* -- a :c:type:`SUNStepper` to integrate partition one. + * *stepper2* -- a :c:type:`SUNStepper` to integrate partition two + including the forcing from partition one. + * *t0* -- the initial value of :math:`t`. + * *y0* -- the initial condition vector :math:`y(t_0)`. + * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) + + **Return value:** + If successful, a pointer to initialized problem memory of type ``void*``, + to be passed to all user-facing ForcingStep routines listed below. If + unsuccessful, a ``NULL`` pointer will be returned, and an error message + will be printed to ``stderr``. + + **Example usage:** + + .. code-block:: C + + /* inner ARKODE objects for integrating individual partitions */ + void *partition_mem[] = {NULL, NULL}; + + /* SUNSteppers to wrap the inner ARKStep objects */ + SUNStepper steppers[] = {NULL, NULL}; + + /* create ARKStep objects, setting right-hand side functions and the + initial condition */ + partition_mem[0] = ARKStepCreate(fe1, fi1, t0, y0, sunctx); + partition_mem[1] = ARKStepCreate(fe2, fi2, t0, y0, sunctx); + + /* setup ARKStep */ + . . . + + /* create SUNStepper wrappers for the ARKStep memory blocks */ + flag = ARKStepCreateSUNStepper(partition_mem[0], &stepper[0]); + flag = ARKStepCreateSUNStepper(partition_mem[1], &stepper[1]); + + /* create a ForcingStep object */ + arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y0, sunctx); + + **Example codes:** + * ``examples/arkode/C_serial/ark_analytic_partitioned.c`` + + .. versionadded:: x.y.z diff --git a/doc/arkode/guide/source/Usage/ForcingStep/index.rst b/doc/arkode/guide/source/Usage/ForcingStep/index.rst new file mode 100644 index 0000000000..820f4f1d14 --- /dev/null +++ b/doc/arkode/guide/source/Usage/ForcingStep/index.rst @@ -0,0 +1,32 @@ +.. ---------------------------------------------------------------- + Programmer(s): Steven B. Roberts @ LLNL + ---------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2024, Lawrence Livermore National Security + and Southern Methodist University. + All rights reserved. + + See the top-level LICENSE and NOTICE files for details. + + SPDX-License-Identifier: BSD-3-Clause + SUNDIALS Copyright End + ---------------------------------------------------------------- + +.. _ARKODE.Usage.ForcingStep: + +========================================== +Using the ForcingStep time-stepping module +========================================== + +This section is concerned with the use of the ForcingStep time-stepping module +for the solution of initial value problems (IVPs) in a C or C++ language +setting. Usage of ForcingStep follows that of the rest of ARKODE, and so in +this section we primarily focus on those usage aspects that are specific to +ForcingStep. A skeleton of a program using ForcingStep follows essentially the +same structure as SplittingStep +(see :numref:`ARKODE.Usage.SplittingStep.Skeleton`). + +.. toctree:: + :maxdepth: 1 + + User_callable From 6a41a5c6715af3b0b488c10e1709cdb56b88691f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 18:01:12 -0700 Subject: [PATCH 038/180] Raise error if not using fixed dt --- include/sundials/sundials_stepper.h | 2 ++ src/arkode/arkode_forcingstep.c | 7 +++++++ src/arkode/arkode_splittingstep.c | 10 +++++++++- .../arkode/C_serial/ark_test_splittingstep.c | 6 ++++-- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 055df192ec..dd58d5fc9f 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -54,6 +54,8 @@ typedef SUNErrCode (*SUNStepperResetFn)(SUNStepper stepper, sunrealtype tR, typedef SUNErrCode (*SUNStepperSetStopTimeFn)(SUNStepper stepper, sunrealtype tstop); +typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper,) + SUNDIALS_EXPORT SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper); diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 551afa0aa1..d1bcd944bb 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -65,6 +65,13 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } + /* assume fixed outer step size */ + if (!ark_mem->fixedstep) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "Adaptive outer time stepping is not currently supported"); + return ARK_ILL_INPUT; + } /* immediately return if resize or reset */ if (init_type == RESIZE_INIT || init_type == RESET_INIT) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 952d48a7eb..2d880243f4 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -144,6 +144,14 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } + /* assume fixed outer step size */ + if (!ark_mem->fixedstep) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "Adaptive outer time stepping is not currently supported"); + return ARK_ILL_INPUT; + } + retval = splittingStep_SetCoefficients(ark_mem, step_mem); if (retval != ARK_SUCCESS) { return retval; } @@ -573,7 +581,7 @@ int SplittingStep_SetCoefficients(void* arkode_mem, } /*--------------------------------------------------------------- - Sets the exection policy. + Sets the execution policy. ---------------------------------------------------------------*/ int SplittingStep_SetExecutionPolicy(void* arkode_mem, ARKodeSplittingExecutionPolicy policy) diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index 46044fa324..14ff8b02f2 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -77,13 +77,15 @@ static void test() ARKodeEvolve(mem, 1, y, &tret, ARK_NORMAL); ARKodeReset(mem, 1, y); - ARKodeEvolve(mem, 1.5, y, &tret, ARK_NORMAL); + ARKodeEvolve(mem, 0.5, y, &tret, ARK_NORMAL); N_VPrint(y); } int main(int argc, char* argv[]) { + test(); + return 0; SUNContext sunctx; SUNContext_Create(SUN_COMM_NULL, &sunctx); @@ -109,7 +111,7 @@ int main(int argc, char* argv[]) SplittingStep_SetCoefficients(split_mem, coeffs); SplittingStepCoefficients_Free(coeffs); ARKodeSetFixedStep(split_mem, - DT_1); // TODO: fix valgrind error if this is not called + DT_1); sunrealtype tret; ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); printf("Final Solution: %e %e\n", T_END, NV_Ith_S(y, 0)); From b38d1d2900a48434f3bb8afae510450dd6a7ee0e Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 5 Sep 2024 18:42:59 -0700 Subject: [PATCH 039/180] Add function to set step direction --- include/sundials/sundials_stepper.h | 9 ++++++++- src/sundials/sundials_stepper.c | 18 ++++++++++++++++++ src/sundials/sundials_stepper_impl.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index dd58d5fc9f..bc5f2ff8e1 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -54,7 +54,7 @@ typedef SUNErrCode (*SUNStepperResetFn)(SUNStepper stepper, sunrealtype tR, typedef SUNErrCode (*SUNStepperSetStopTimeFn)(SUNStepper stepper, sunrealtype tstop); -typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper,) +typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed); SUNDIALS_EXPORT SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper); @@ -87,6 +87,10 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn fn); +SUNDIALS_EXPORT +SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, + SUNStepperSetStepDirectionFn fn); + SUNDIALS_EXPORT SUNErrCode SUNStepper_AddForcing(SUNStepper stepper, sunrealtype t, N_Vector f); @@ -118,6 +122,9 @@ SUNErrCode SUNStepper_Reset(SUNStepper stepper, sunrealtype tR, N_Vector yR); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop); +SUNDIALS_EXPORT +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed); + #ifdef __cplusplus } #endif diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index c43998de60..30c3a59cf8 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -38,6 +38,7 @@ SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper_ptr) stepper->ops->fullrhs = NULL; stepper->ops->reset = NULL; stepper->ops->setstoptime = NULL; + stepper->ops->setstepdirection = NULL; *stepper_ptr = stepper; @@ -163,6 +164,13 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn return SUN_SUCCESS; } +SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) +{ + SUNFunctionBegin(stepper->sunctx); + stepper->ops->setstepdirection = fn; + return SUN_SUCCESS; +} + SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, int count, N_Vector tmpl) { SUNFunctionBegin(stepper->sunctx); @@ -246,3 +254,13 @@ SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop) } else { return SUN_ERR_NOT_IMPLEMENTED; } } + +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed) +{ + SUNFunctionBegin(stepper->sunctx); + if (stepper->ops->setstepdirection) + { + return stepper->ops->setstepdirection(stepper, dir, dir_changed); + } + else { return SUN_ERR_NOT_IMPLEMENTED; } +} diff --git a/src/sundials/sundials_stepper_impl.h b/src/sundials/sundials_stepper_impl.h index 25bb9e5cfa..da1b23e267 100644 --- a/src/sundials/sundials_stepper_impl.h +++ b/src/sundials/sundials_stepper_impl.h @@ -30,6 +30,7 @@ struct SUNStepper_Ops_ SUNStepperFullRhsFn fullrhs; SUNStepperResetFn reset; SUNStepperSetStopTimeFn setstoptime; + SUNStepperSetStepDirectionFn setstepdirection; }; struct SUNStepper_ From 653ffe99b8071e640052893ed4b49364a8cf21bf Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 6 Sep 2024 16:06:01 -0700 Subject: [PATCH 040/180] Make invalid order a warning --- src/arkode/arkode_splittingstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 2d880243f4..edcb761453 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -104,7 +104,7 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, { /* Bump the order up to be even but with an error */ const int new_order = step_mem->order + 1; - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + arkProcessError(ark_mem, ARK_WARNING, __LINE__, __func__, __FILE__, "No splitting method at requested order, using q=%i.", new_order); step_mem->coefficients = From 10db02b63659ae542412f19a4f2e1570e7d51d73 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 10 Sep 2024 19:04:41 -0700 Subject: [PATCH 041/180] Add getter and setter for step direction --- examples/arkode/C_serial/CMakeLists.txt | 2 + include/arkode/arkode.h | 2 + include/sundials/sundials_stepper.h | 15 +++- src/arkode/arkode_arkstep.c | 48 +++++++++++++ src/arkode/arkode_arkstep_impl.h | 2 + src/arkode/arkode_io.c | 69 +++++++++++++++++++ src/arkode/arkode_splittingstep.c | 4 ++ src/sundials/sundials_stepper.c | 13 +++- src/sundials/sundials_stepper_impl.h | 1 + .../arkode/C_serial/ark_test_splittingstep.c | 36 ++++++---- 10 files changed, 174 insertions(+), 18 deletions(-) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 1464cf69ee..aac6df0dc0 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -29,6 +29,8 @@ set(ARKODE_examples "ark_analytic_partitioned\;forcing\;develop" "ark_analytic_partitioned\;splitting\;develop" "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_BEST_2_2_2\;develop" + "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_RUTH_3_3_2\;develop" + "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_YOSHIDA_8_6_2\;develop" "ark_brusselator_1D_mri\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator_mri\;\;develop" diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index f4e0667d72..d6e12762f0 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -228,6 +228,7 @@ SUNDIALS_EXPORT int ARKodeSetInterpolateStopTime(void* arkode_mem, SUNDIALS_EXPORT int ARKodeSetStopTime(void* arkode_mem, sunrealtype tstop); SUNDIALS_EXPORT int ARKodeClearStopTime(void* arkode_mem); SUNDIALS_EXPORT int ARKodeSetFixedStep(void* arkode_mem, sunrealtype hfixed); +SUNDIALS_EXPORT int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir); SUNDIALS_EXPORT int ARKodeSetUserData(void* arkode_mem, void* user_data); SUNDIALS_EXPORT int ARKodeSetPostprocessStepFn(void* arkode_mem, ARKPostProcessFn ProcessStep); @@ -301,6 +302,7 @@ SUNDIALS_EXPORT int ARKodeGetWorkSpace(void* arkode_mem, long int* lenrw, SUNDIALS_EXPORT int ARKodeGetNumSteps(void* arkode_mem, long int* nsteps); SUNDIALS_EXPORT int ARKodeGetLastStep(void* arkode_mem, sunrealtype* hlast); SUNDIALS_EXPORT int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur); +SUNDIALS_EXPORT int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir); SUNDIALS_EXPORT int ARKodeGetErrWeights(void* arkode_mem, N_Vector eweight); SUNDIALS_EXPORT int ARKodeGetNumGEvals(void* arkode_mem, long int* ngevals); SUNDIALS_EXPORT int ARKodeGetRootInfo(void* arkode_mem, int* rootsfound); diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index bc5f2ff8e1..56e9b0d9f2 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -54,7 +54,9 @@ typedef SUNErrCode (*SUNStepperResetFn)(SUNStepper stepper, sunrealtype tR, typedef SUNErrCode (*SUNStepperSetStopTimeFn)(SUNStepper stepper, sunrealtype tstop); -typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed); +typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype stepdir); + +typedef SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, sunrealtype* stepdir); SUNDIALS_EXPORT SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper); @@ -88,9 +90,13 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn fn); SUNDIALS_EXPORT -SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, +SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn); +SUNDIALS_EXPORT +SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, + SUNStepperGetStepDirectionFn fn); + SUNDIALS_EXPORT SUNErrCode SUNStepper_AddForcing(SUNStepper stepper, sunrealtype t, N_Vector f); @@ -123,7 +129,10 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop); SUNDIALS_EXPORT -SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed); +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir); + +SUNDIALS_EXPORT +SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir); #ifdef __cplusplus } diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 81141a1eb4..670b101c43 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3162,6 +3162,12 @@ int ARKStepCreateSUNStepper(void* inner_arkode_mem, SUNStepper* stepper) retval = SUNStepper_SetStopTimeFn(*stepper, arkStep_SUNStepperSetStopTime); if (retval != ARK_SUCCESS) { return (retval); } + retval = SUNStepper_SetSetStepDirectionFn(*stepper, arkStep_SUNStepperSetStepDirection); + if (retval != ARK_SUCCESS) { return (retval); } + + retval = SUNStepper_SetGetStepDirectionFn(*stepper, arkStep_SUNStepperGetStepDirection); + if (retval != ARK_SUCCESS) { return (retval); } + return (ARK_SUCCESS); } @@ -3339,6 +3345,48 @@ int arkStep_SUNStepperSetStopTime(SUNStepper stepper, sunrealtype tstop) return retval; } +/*------------------------------------------------------------------------------ + arkStep_SUNStepperSetStepDirection + + TODO(SBR) + ----------------------------------------------------------------------------*/ + +int arkStep_SUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir) +{ + void* arkode_mem; + int retval; + + /* extract the ARKODE memory struct */ + retval = SUNStepper_GetContent(stepper, &arkode_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + retval = ARKodeSetStepDirection(arkode_mem, stepdir); + if (retval != ARK_SUCCESS) { return (retval); } + + return retval; +} + +/*------------------------------------------------------------------------------ + arkStep_SUNStepperGetStepDirection + + TODO(SBR) + ----------------------------------------------------------------------------*/ + +int arkStep_SUNStepperGetStepDirection(SUNStepper stepper, sunrealtype* stepdir) +{ + void* arkode_mem; + int retval; + + /* extract the ARKODE memory struct */ + retval = SUNStepper_GetContent(stepper, &arkode_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + retval = ARKodeGetStepDirection(arkode_mem, stepdir); + if (retval != ARK_SUCCESS) { return (retval); } + + return retval; +} + /*--------------------------------------------------------------- Utility routines for interfacing with MRIStep ---------------------------------------------------------------*/ diff --git a/src/arkode/arkode_arkstep_impl.h b/src/arkode/arkode_arkstep_impl.h index 408b3b769c..33206713bd 100644 --- a/src/arkode/arkode_arkstep_impl.h +++ b/src/arkode/arkode_arkstep_impl.h @@ -281,6 +281,8 @@ int arkStep_SUNStepperFullRhs(SUNStepper stepper, sunrealtype t, N_Vector y, N_Vector f, int mode); int arkStep_SUNStepperReset(SUNStepper stepper, sunrealtype tR, N_Vector yR); int arkStep_SUNStepperSetStopTime(SUNStepper stepper, sunrealtype tstop); +int arkStep_SUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir); +int arkStep_SUNStepperGetStepDirection(SUNStepper stepper, sunrealtype* stepdir); /* private functions for interfacing with MRIStep */ int arkStep_SetInnerForcing(void* arkode_mem, sunrealtype tshift, diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index 357912409d..66c747a650 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1280,6 +1280,55 @@ int ARKodeSetFixedStep(void* arkode_mem, sunrealtype hfixed) return (ARK_SUCCESS); } +/*--------------------------------------------------------------- + ARKodeSetStepDirection: + + TODO(SBR) + ---------------------------------------------------------------*/ +int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) +{ + int retval; + ARKodeMem ark_mem; + sunrealtype h; + if (arkode_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_ARK_NO_MEM); + return (ARK_MEM_NULL); + } + ark_mem = (ARKodeMem)arkode_mem; + + if (stepdir == ZERO) { + return ARK_SUCCESS; + } + + h = ark_mem->h == ZERO ? ark_mem->hin : ark_mem->h; + + // TODO(SBR): use SUNRcopysign once merged from other PR + // if (SUNRcopysign(h, stepdir) == h) { + if (h == ZERO || ((h > 0) == (stepdir > 0))) { + return ARK_SUCCESS; + } + + /* Reverse the sign of h. If adaptive, h will be overwritten anyway by the + * initial step estimation since ARKodeReset must be called before this. + * However, the sign of h will be used to check if the integration direction + * and stop time are consistent, e.g., in ARKodeSetStopTime, so we should not + * set h = 0. */ + ark_mem->h = -h; + /* Clear previous initial step */ + ark_mem->h0u = ZERO; + /* Reverse the step if in fixed mode. If adaptive, reset to 0 to clear any old + * value from a call to ARKodeSetInit */ + ark_mem->hin = ark_mem->fixedstep ? -h : ZERO; + + /* Reset error controller (e.g., error and step size history) */ + retval = SUNAdaptController_Reset(ark_mem->hadapt_mem->hcontroller); + if (retval != SUN_SUCCESS) { return (ARK_CONTROLLER_ERR); } + + return ARK_SUCCESS; +} + /*--------------------------------------------------------------- ARKodeSetRootDirection: @@ -2085,6 +2134,26 @@ int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur) return (ARK_SUCCESS); } +/*--------------------------------------------------------------- + ARKodeGetStepDirection: + + TODO(SBR) + ---------------------------------------------------------------*/ +int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir) +{ + ARKodeMem ark_mem; + if (arkode_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_ARK_NO_MEM); + return (ARK_MEM_NULL); + } + ark_mem = (ARKodeMem)arkode_mem; + + *stepdir = ark_mem->h == ZERO ? ark_mem->hin : ark_mem->h; + return (ARK_SUCCESS); +} + /*--------------------------------------------------------------- ARKodeGetCurrentState: diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index edcb761453..094ca6d249 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -145,6 +145,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) } /* assume fixed outer step size */ + /* TODO(SBR): Should this validation be done by ARKODE? */ if (!ark_mem->fixedstep) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, @@ -259,6 +260,9 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_SetStepDirection(stepper, t_end - t_start); + if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_SetStopTime(stepper, t_end); if (err != SUN_SUCCESS) { return err; } diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 30c3a59cf8..95d4918092 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -164,13 +164,20 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn return SUN_SUCCESS; } -SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) +SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) { SUNFunctionBegin(stepper->sunctx); stepper->ops->setstepdirection = fn; return SUN_SUCCESS; } +SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, SUNStepperGetStepDirectionFn fn) +{ + SUNFunctionBegin(stepper->sunctx); + stepper->ops->getstepdirection = fn; + return SUN_SUCCESS; +} + SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, int count, N_Vector tmpl) { SUNFunctionBegin(stepper->sunctx); @@ -255,12 +262,12 @@ SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop) else { return SUN_ERR_NOT_IMPLEMENTED; } } -SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir, sunbooleantype *dir_changed) +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir) { SUNFunctionBegin(stepper->sunctx); if (stepper->ops->setstepdirection) { - return stepper->ops->setstepdirection(stepper, dir, dir_changed); + return stepper->ops->setstepdirection(stepper, dir); } else { return SUN_ERR_NOT_IMPLEMENTED; } } diff --git a/src/sundials/sundials_stepper_impl.h b/src/sundials/sundials_stepper_impl.h index da1b23e267..1f721a75d5 100644 --- a/src/sundials/sundials_stepper_impl.h +++ b/src/sundials/sundials_stepper_impl.h @@ -31,6 +31,7 @@ struct SUNStepper_Ops_ SUNStepperResetFn reset; SUNStepperSetStopTimeFn setstoptime; SUNStepperSetStepDirectionFn setstepdirection; + SUNStepperGetStepDirectionFn getstepdirection; }; struct SUNStepper_ diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c index 14ff8b02f2..7dddf2336c 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c @@ -33,12 +33,13 @@ Examples #include #include +#include #include #include #include -#define DT_1 (0.5 / 8) -#define DT_2 (0.125 / 8) +#define DT_1 (0.5 / 4) +#define DT_2 (DT_1 / 4) #define T_END 1.0 #define LAMBDA 2.0 @@ -71,21 +72,30 @@ static void test() void* mem = ARKStepCreate(f1, NULL, 0, y, sunctx); - ARKodeSetFixedStep(mem, 0.25); + // ARKodeSetFixedStep(mem, 0.25); + ARKodeSetInitStep(mem, -0.25); sunrealtype tret = 0; ARKodeEvolve(mem, 1, y, &tret, ARK_NORMAL); - ARKodeReset(mem, 1, y); - ARKodeEvolve(mem, 0.5, y, &tret, ARK_NORMAL); + printf("-------------------------\n"); + + // ARKodeReset(mem, 1, y); + // ARKodeSetStepDirection(mem, -1); + // ARKodeSetStopTime(mem, -2); + // ARKodeEvolve(mem, 0.0, y, &tret, ARK_NORMAL); + + long steps = 0; + ARKodeGetNumSteps(mem, &steps); + printf("Steps: %li\n", steps); N_VPrint(y); } int main(int argc, char* argv[]) { - test(); - return 0; + // test(); + // return 0; SUNContext sunctx; SUNContext_Create(SUN_COMM_NULL, &sunctx); @@ -94,26 +104,28 @@ int main(int argc, char* argv[]) const sunrealtype sol = exact_sol(T_END, NV_Ith_S(y, 0)); void* arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem1, 2); + ARKodeSetOrder(arkode_mem1, 5); + // ARKodeSStolerances(arkode_mem1, 1e-13, 1e-13); ARKodeSetFixedStep(arkode_mem1, DT_1); void* arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem2, 2); - ARKodeSetFixedStep(arkode_mem2, DT_2); + ARKodeSetOrder(arkode_mem2, 5); + ARKodeSStolerances(arkode_mem2, 1e-13, 1e-13); + // ARKodeSetFixedStep(arkode_mem2, DT_2); SUNStepper steppers[2]; ARKStepCreateSUNStepper(arkode_mem1, &steppers[0]); ARKStepCreateSUNStepper(arkode_mem2, &steppers[1]); void* split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); - SplittingStepCoefficients coeffs = SplittingStepCoefficients_Parallel(2); + SplittingStepCoefficients coeffs = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_RUTH_3_3_2); // SplittingStepCoefficients_Write(coeffs, stdout); SplittingStep_SetCoefficients(split_mem, coeffs); SplittingStepCoefficients_Free(coeffs); ARKodeSetFixedStep(split_mem, DT_1); sunrealtype tret; - ARKodeEvolve(split_mem, 1, y, &tret, ARK_NORMAL); + ARKodeEvolve(split_mem, T_END, y, &tret, ARK_NORMAL); printf("Final Solution: %e %e\n", T_END, NV_Ith_S(y, 0)); N_VPrint(y); From 5417f850f96dc2c937c8d71f87a17b09e00585a5 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 17:26:21 -0700 Subject: [PATCH 042/180] Finish splittingstep test --- .../arkode/CXX_serial/CMakeLists.txt | 3 +- .../CXX_serial/ark_test_splittingstep.cpp | 370 ++++++++++++++++++ .../unit_tests/arkode/C_serial/CMakeLists.txt | 1 - .../arkode/C_serial/ark_test_splittingstep.c | 141 ------- 4 files changed, 372 insertions(+), 143 deletions(-) create mode 100644 test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp delete mode 100644 test/unit_tests/arkode/C_serial/ark_test_splittingstep.c diff --git a/test/unit_tests/arkode/CXX_serial/CMakeLists.txt b/test/unit_tests/arkode/CXX_serial/CMakeLists.txt index c1f22fc6bc..fa35269ba7 100644 --- a/test/unit_tests/arkode/CXX_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/CXX_serial/CMakeLists.txt @@ -41,7 +41,8 @@ set(unit_tests "ark_test_dahlquist_mri.cpp\;1" "ark_test_butcher.cpp\;" "ark_test_getjac.cpp\;" - "ark_test_getjac_mri.cpp\;") + "ark_test_getjac_mri.cpp\;" + "ark_test_splittingstep.cpp\;") # Add the build and install targets for each test foreach(test_tuple ${unit_tests}) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp new file mode 100644 index 0000000000..c8b47a4a81 --- /dev/null +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -0,0 +1,370 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * TODO + * ---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Integrates the ODE + * + * y' = \sum_{i=0}^{P-1} 2^i / (1 - 2^P) * y, y(0) = 1 + * + * with a 3rd order operator splitting method. Each partition is solved by an + * ERK method. Using the exact solution y(t) = exp(-t), we confirm the numerical + * solution is sufficiently accurate. + */ +static int test_forward(sundials::Context &ctx, const int partitions) { + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto tf = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(0.01); + constexpr auto local_tol = SUN_RCONST(1.0e-8); + constexpr auto global_tol = local_tol; + const auto y = N_VNew_Serial(1, ctx); + N_VConst(SUN_RCONST(1.0), y); + + const ARKRhsFn f = [](const sunrealtype, const N_Vector z, const N_Vector zdot, void *const user_data) { + const auto lambda = *static_cast(user_data); + N_VScale(lambda, z, zdot); + return 0; + }; + + std::vector partition_mem(partitions); + std::vector lambda(partitions); + std::vector steppers(partitions); + for (int i = 0; i < partitions; i++) { + partition_mem[i] = ARKStepCreate(f, nullptr, t0, y, ctx); + /* The lambdas sum up to 1 */ + lambda[i] = std::pow(SUN_RCONST(2.0), i) / (1 - std::pow(SUN_RCONST(2.0), partitions)); + ARKodeSetUserData(partition_mem[i], &lambda[i]); + ARKodeSStolerances(partition_mem[i], local_tol, local_tol); + ARKStepCreateSUNStepper(partition_mem[i], &steppers[i]); + } + + auto arkode_mem = SplittingStepCreate(steppers.data(), partitions, t0, y, ctx); + ARKodeSetFixedStep(arkode_mem, dt); + const auto coefficients = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); + SplittingStep_SetCoefficients(arkode_mem, coefficients); + SplittingStepCoefficients_Free(coefficients); + + auto tret = t0; + ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); + + /* Check that the solution matches the exact solution */ + const auto exact_solution = std::exp(t0 - tf); + if (SUNRCompareTol(exact_solution, NV_Ith_S(y, 0), global_tol)) { + std::cerr << "Forward solution with " << partitions << " partitions is not within the tolerance\n"; + return 1; + } + + N_VDestroy(y); + for (int i = 0; i global_tol) { + std::cerr << "Mixed direction solution failed with an error of " << max_err << "\n"; + return 1; + } + + N_VDestroy(y); + N_VDestroy(err); + ARKodeFree(&parititon_mem[0]); + SUNStepper_Destroy(&steppers[0]); + ARKodeFree(&parititon_mem[1]); + SUNStepper_Destroy(&steppers[1]); + ARKodeFree(&arkode_mem); + + return 0; +} + +/* Integrates the ODE + * + * y' = [y^2] - [y*(y - 1)] = -y + * + * with initial condition y(0) = 1 and partitioning specified by the square + * brackets. Powers and products are done componentwise. At t = 0.5, we resize + * from 1D to 2D: + * + * y_new = [1, y_old]^T + * + * Then we integrate to t = 1 and check the error against the exact solution + * y(1) = [exp(-0.5), exp(-1)]. + */ +static int test_resize(const sundials::Context &ctx) { + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto t1 = SUN_RCONST(0.5); + constexpr auto t2 = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(7.0e-5); + constexpr auto local_tol = SUN_RCONST(1.0e-5); + constexpr auto global_tol = local_tol; + const auto y = N_VNew_Serial(1, ctx); + N_VConst(SUN_RCONST(1.0), y); + + const ARKRhsFn f1 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void *const) { + N_VProd(z, z, zdot); + return 0; + }; + + const ARKRhsFn f2 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void *const) { + N_VConst(-SUN_RCONST(1.0), zdot); + N_VLinearSum(SUN_RCONST(1.0), zdot, -SUN_RCONST(1.0), z, zdot); + N_VProd(zdot, z, zdot); + return 0; + }; + + void* parititon_mem[] = { + ARKStepCreate(f1, nullptr, t0, y, ctx), + ARKStepCreate(f2, nullptr, t0, y, ctx) + }; + ARKodeSStolerances(parititon_mem[0], local_tol, local_tol); + ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); + + SUNStepper steppers[] = {nullptr, nullptr}; + ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); + ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); + + auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); + ARKodeSetFixedStep(arkode_mem, dt); + ARKodeSetMaxNumSteps(arkode_mem, -1); + + /* Integrate from 0 to 0.5 */ + auto tret = t0; + ARKodeEvolve(arkode_mem, t1, y, &tret, ARK_NORMAL); + + /* Resize */ + const auto y_new = N_VNew_Serial(2, ctx); + NV_Ith_S(y_new, 0) = SUN_RCONST(1.0); + NV_Ith_S(y_new, 1) = NV_Ith_S(y, 0); + N_VDestroy(y); + ARKodeResize(arkode_mem, y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); + ARKodeResize(parititon_mem[0], y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); + ARKodeResize(parititon_mem[1], y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); + + /* Integrate from 0.5 to 1 */ + ARKodeEvolve(arkode_mem, t2, y_new, &tret, ARK_NORMAL); + + const auto err = N_VClone(y_new); + NV_Ith_S(err, 0) = std::exp(t1 - t2); + NV_Ith_S(err, 1) = std::exp(t0 - t2); + N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y_new, err); + const auto max_err = N_VMaxNorm(err); + + if (max_err > global_tol) { + std::cerr << "Resized solution failed with an error of " << max_err << "\n"; + return 1; + } + + N_VDestroy(y_new); + N_VDestroy(err); + ARKodeFree(&parititon_mem[0]); + SUNStepper_Destroy(&steppers[0]); + ARKodeFree(&parititon_mem[1]); + SUNStepper_Destroy(&steppers[1]); + ARKodeFree(&arkode_mem); + + return 0; +} + +/* Creates a custom SUNStepper for the linear, scalar ODE y' = lambda*y */ +static SUNStepper create_exp_stepper(const sundials::Context &ctx, const sunrealtype &lambda) { + SUNStepper stepper = nullptr; + SUNStepper_Create(ctx, &stepper); + + const auto empty_func = [](auto... args) { + return 0; + }; + SUNStepper_SetResetFn(stepper, empty_func); + SUNStepper_SetStopTimeFn(stepper, empty_func); + SUNStepper_SetSetStepDirectionFn(stepper, empty_func); + SUNStepper_SetFullRhsFn(stepper, empty_func); + SUNStepper_SetEvolveFn(stepper, [](const SUNStepper s, const sunrealtype t0, + const sunrealtype tout, const N_Vector y, + sunrealtype* const tret, int* const stop_reason) { + void *content = nullptr; + SUNStepper_GetContent(s, &content); + const auto lam = *static_cast(content); + N_VScale(std::exp(lam * (tout - t0)), y, y); + *tret = tout; + *stop_reason = 0; + return 0; + }); + SUNStepper_SetContent(stepper, static_cast(const_cast(&lambda))); + return stepper; +} + +/* Integrates the ODE + * + * y' = -0.6*y - 0.4*y + * + * with initial condition y(0) = 1 with a sixth order splitting method and + * exact, custom SUNSteppers for the two partitions. We integrate to t = 1 and + * compare the numerical solution to the exact solution y(t) = exp(-t). + */ +static int test_custom_stepper(const sundials::Context &ctx) { + constexpr auto lambda1 = SUN_RCONST(-0.6); + constexpr auto lambda2 = SUN_RCONST(-0.4); + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto tf = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(5.0e-2); + constexpr auto global_tol = SUN_RCONST(1.0e-12); + const auto y = N_VNew_Serial(1, ctx); + N_VConst(SUN_RCONST(1.0), y); + + SUNStepper steppers[] = { + create_exp_stepper(ctx, lambda1), + create_exp_stepper(ctx, lambda2) + }; + + auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); + ARKodeSetFixedStep(arkode_mem, dt); + const auto coefficients = SplittingStepCoefficients_SuzukiFractal(2, 6); + SplittingStep_SetCoefficients(arkode_mem, coefficients); + SplittingStepCoefficients_Free(coefficients); + + auto tret = t0; + ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); + + /* Check that the solution matches the exact solution */ + const auto exact_solution = std::exp(t0 - tf); + if (SUNRCompareTol(exact_solution, NV_Ith_S(y, 0), global_tol)) { + std::cerr << "Custom SUNStepper is not within the tolerance\n"; + return 1; + } + + N_VDestroy(y); + SUNStepper_Destroy(&steppers[0]); + SUNStepper_Destroy(&steppers[1]); + ARKodeFree(&arkode_mem); + return 0; +} + +/* Error handling function which prints the error and exits the program */ +static void err_fn(const int line, const char* const func, const char* const file, + const char* const msg, const SUNErrCode err_code, + void* const, const SUNContext) +{ + std::cerr << "Error at line " << line << " of " << func << " in " << file << ": " << msg << "\n"; + exit(err_code); +} + +int main() { + sundials::Context ctx; + SUNContext_PushErrHandler(ctx, err_fn, nullptr); + + int errors = 0; + + /* Run the tests */ + constexpr auto min_partitions = 2; + constexpr auto max_partitions = 8; + for (auto p = min_partitions; p <= max_partitions; p++) { + errors += test_forward(ctx, p); + } + + errors += test_mixed_directions(ctx); + errors += test_resize(ctx); + errors += test_custom_stepper(ctx); + + if (errors == 0) { + std::cout << "Success\n"; + } else { + std::cout << errors << " Test Failures\n"; + } + + return errors; +} diff --git a/test/unit_tests/arkode/C_serial/CMakeLists.txt b/test/unit_tests/arkode/C_serial/CMakeLists.txt index 1c86d9b798..db0e6fdd4d 100644 --- a/test/unit_tests/arkode/C_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/C_serial/CMakeLists.txt @@ -33,7 +33,6 @@ set(ARKODE_unit_tests "ark_test_mass\;" "ark_test_reset\;" "ark_test_splitting_coefficients\;" - "ark_test_splittingstep\;" "ark_test_tstop\;") # Add the build and install targets for each test diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c deleted file mode 100644 index 7dddf2336c..0000000000 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Things to test -Custom inner stepper with exact solution -Orders 1-4 -Resizing -Changing coefficients -~3 partitions -Check n_stepper_evolves -*/ - -/* -Examples -- Fractional Step RK -*/ - -/* ----------------------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------------------- - * TODO - * ---------------------------------------------------------------------------*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#define DT_1 (0.5 / 4) -#define DT_2 (DT_1 / 4) -#define T_END 1.0 -#define LAMBDA 2.0 - -static int f1(sunrealtype t, N_Vector y, N_Vector yp, void* data) -{ - printf("%e %e\n", t, NV_Ith_S(y, 0)); - N_VScale(-LAMBDA, y, yp); - return 0; -} - -static int f2(sunrealtype t, N_Vector y, N_Vector yp, void* data) -{ - printf(" %e %e\n", t, NV_Ith_S(y, 0)); - N_VProd(y, y, yp); - return 0; -} - -static sunrealtype exact_sol(sunrealtype t, sunrealtype y0) -{ - return LAMBDA * y0 / (y0 - (y0 - LAMBDA) * exp(LAMBDA * t)); -} - -static void test() -{ - SUNContext sunctx; - SUNContext_Create(SUN_COMM_NULL, &sunctx); - - N_Vector y = N_VNew_Serial(1, sunctx); - N_VConst(1, y); - - void* mem = ARKStepCreate(f1, NULL, 0, y, sunctx); - - // ARKodeSetFixedStep(mem, 0.25); - ARKodeSetInitStep(mem, -0.25); - - sunrealtype tret = 0; - ARKodeEvolve(mem, 1, y, &tret, ARK_NORMAL); - - printf("-------------------------\n"); - - // ARKodeReset(mem, 1, y); - // ARKodeSetStepDirection(mem, -1); - // ARKodeSetStopTime(mem, -2); - // ARKodeEvolve(mem, 0.0, y, &tret, ARK_NORMAL); - - long steps = 0; - ARKodeGetNumSteps(mem, &steps); - printf("Steps: %li\n", steps); - - N_VPrint(y); -} - -int main(int argc, char* argv[]) -{ - // test(); - // return 0; - SUNContext sunctx; - SUNContext_Create(SUN_COMM_NULL, &sunctx); - - N_Vector y = N_VNew_Serial(1, sunctx); - N_VConst(1, y); - const sunrealtype sol = exact_sol(T_END, NV_Ith_S(y, 0)); - - void* arkode_mem1 = ARKStepCreate(f1, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem1, 5); - // ARKodeSStolerances(arkode_mem1, 1e-13, 1e-13); - ARKodeSetFixedStep(arkode_mem1, DT_1); - - void* arkode_mem2 = ARKStepCreate(f2, NULL, 0, y, sunctx); - ARKodeSetOrder(arkode_mem2, 5); - ARKodeSStolerances(arkode_mem2, 1e-13, 1e-13); - // ARKodeSetFixedStep(arkode_mem2, DT_2); - - SUNStepper steppers[2]; - ARKStepCreateSUNStepper(arkode_mem1, &steppers[0]); - ARKStepCreateSUNStepper(arkode_mem2, &steppers[1]); - - void* split_mem = SplittingStepCreate(steppers, 2, 0, y, sunctx); - SplittingStepCoefficients coeffs = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_RUTH_3_3_2); - // SplittingStepCoefficients_Write(coeffs, stdout); - SplittingStep_SetCoefficients(split_mem, coeffs); - SplittingStepCoefficients_Free(coeffs); - ARKodeSetFixedStep(split_mem, - DT_1); - sunrealtype tret; - ARKodeEvolve(split_mem, T_END, y, &tret, ARK_NORMAL); - printf("Final Solution: %e %e\n", T_END, NV_Ith_S(y, 0)); - - N_VPrint(y); - printf("Error: %e\n", sol - NV_Ith_S(y, 0)); - - ARKodeFree(&split_mem); - N_VDestroy(y); - SUNStepper_Destroy(&steppers[0]); - SUNStepper_Destroy(&steppers[1]); - ARKodeFree(&arkode_mem1); - ARKodeFree(&arkode_mem2); - SUNContext_Free(&sunctx); -} From 42e5a60289d7c4849ee3adf75e753fa108c79d5a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 18:09:30 -0700 Subject: [PATCH 043/180] Add logging messages --- src/arkode/arkode_splittingstep.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 094ca6d249..d41a35b3df 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -245,8 +245,21 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, const SplittingStepCoefficients coefficients = step_mem->coefficients; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, + "ARKODE::splittingStep_SequentialMethod", "start-sequential-method", + "step = %li, sequential method = %i", + ark_mem->nst, i); +#endif + for (int j = 0; j < coefficients->stages; j++) { +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, + "ARKODE::splittingStep_SequentialMethod", "start-stage", + "step = %li, sequential method = %i, stage = %i", + ark_mem->nst, i, j); +#endif for (int k = 0; k < coefficients->partitions; k++) { const sunrealtype t_start = ark_mem->tn + @@ -254,6 +267,13 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, const sunrealtype t_end = ark_mem->tn + coefficients->beta[i][j + 1][k] * ark_mem->h; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, + "ARKODE::splittingStep_SequentialMethod", "start-inner-evolve", + "step = %li, sequential method = %i, stage = %i, partition = %i, t0 = %" RSYM ", tout = %" RSYM, + ark_mem->nst, i, j, k, t_start, t_end); +#endif + if (t_start == t_end) { continue; } const SUNStepper stepper = step_mem->steppers[k]; @@ -423,6 +443,7 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) if (step_mem->own_policy) { free(step_mem->policy); } step_mem->own_policy = SUNFALSE; + // TODO(SBR): This is ignored currently. Possible ARKODE bug? ark_mem->interp_type = ARK_INTERP_LAGRANGE; return ARK_SUCCESS; From 419c5b8ece8dd70e7b7dd138a26c4cd54fe54737 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 19:06:16 -0700 Subject: [PATCH 044/180] Make per partitions evolve stats --- include/arkode/arkode_splittingstep.h | 2 + src/arkode/arkode_splittingstep.c | 59 ++++++++++++++++++++------ src/arkode/arkode_splittingstep_impl.h | 2 +- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index a6766e380f..8b2a21b627 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -44,6 +44,8 @@ SUNDIALS_EXPORT int SplittingStep_SetCoefficients( SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( void* arkode_mem, ARKodeSplittingExecutionPolicy policy); +SUNDIALS_EXPORT long int SplittingStep_GetNumEvolves(void* arkode_mem, int partition); + #ifdef __cplusplus } #endif diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index d41a35b3df..d78e072a85 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -292,7 +292,7 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } - step_mem->n_stepper_evolves++; + step_mem->n_stepper_evolves[k]++; } } @@ -336,11 +336,15 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - fprintf(outfile, "Stepper evolves = %ld\n", - step_mem->n_stepper_evolves); + for (int k = 0; k < step_mem->partitions; k++) { + fprintf(outfile, "Partition %i evolves = %ld\n", + k, step_mem->n_stepper_evolves[k]); + } break; case SUN_OUTPUTFORMAT_CSV: - fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); + for (int k = 0; k < step_mem->partitions; k++) { + fprintf(outfile, "Partition %i evolves,%ld\n", k, step_mem->n_stepper_evolves[k]); + } break; default: arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, @@ -374,6 +378,7 @@ static void splittingStep_Free(const ARKodeMem ark_mem) const ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; if (step_mem != NULL) { free(step_mem->steppers); + free(step_mem->n_stepper_evolves); if (step_mem->own_policy) { ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); @@ -400,8 +405,9 @@ static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) fprintf(outfile, "SplittingStep: order = %i\n", step_mem->order); /* output long integer quantities */ - fprintf(outfile, "SplittingStep: n_stepper_evolves = %li\n", - step_mem->n_stepper_evolves); + for (int k = 0; k < step_mem->partitions; k++) { + fprintf(outfile, "SplittingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); + } /* output sunrealtype quantities */ fprintf(outfile, "SplittingStep: Coefficients:\n"); @@ -443,8 +449,9 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) if (step_mem->own_policy) { free(step_mem->policy); } step_mem->own_policy = SUNFALSE; - // TODO(SBR): This is ignored currently. Possible ARKODE bug? - ark_mem->interp_type = ARK_INTERP_LAGRANGE; + /* TODO(SBR): This may cause issues if a user calls ARKodeSetDefaults. This + * issues affects other ARKODE steppers as well */ + ARKodeSetInterpolantType(ark_mem, ARK_INTERP_LAGRANGE); return ARK_SUCCESS; } @@ -526,7 +533,13 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, step_mem->coefficients = NULL; step_mem->policy = NULL; - step_mem->n_stepper_evolves = 0; + step_mem->n_stepper_evolves = calloc(partitions, sizeof(*step_mem->n_stepper_evolves)); + if (step_mem->n_stepper_evolves == NULL) { + arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, + MSG_ARK_ARKMEM_FAIL); + ARKodeFree((void**)&ark_mem); + return NULL; + } step_mem->partitions = partitions; step_mem->order = 0; step_mem->own_policy = SUNFALSE; @@ -569,8 +582,8 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, /*--------------------------------------------------------------- Sets the SplittingStep coefficients. ---------------------------------------------------------------*/ -int SplittingStep_SetCoefficients(void* arkode_mem, - SplittingStepCoefficients coefficients) +int SplittingStep_SetCoefficients(void* const arkode_mem, + const SplittingStepCoefficients coefficients) { ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; @@ -608,7 +621,7 @@ int SplittingStep_SetCoefficients(void* arkode_mem, /*--------------------------------------------------------------- Sets the execution policy. ---------------------------------------------------------------*/ -int SplittingStep_SetExecutionPolicy(void* arkode_mem, +int SplittingStep_SetExecutionPolicy(void* const arkode_mem, ARKodeSplittingExecutionPolicy policy) { ARKodeMem ark_mem = NULL; @@ -633,3 +646,25 @@ int SplittingStep_SetExecutionPolicy(void* arkode_mem, return ARK_SUCCESS; } + +long int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition) { + ARKodeMem ark_mem = NULL; + ARKodeSplittingStepMem step_mem = NULL; + int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + if (partition < 0) { + long int total = 0; + for (int k = 0; k < step_mem->partitions; k++) { + total += step_mem->n_stepper_evolves[k]; + } + return total; + } else if (partition >= step_mem->partitions) { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "The partition index is %i but there are only %i partitions", partition, step_mem->partitions); + return ARK_ILL_INPUT; + } else { + return step_mem->n_stepper_evolves[partition]; + } +} diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index 59d2c6b8f9..721ccce204 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -24,7 +24,7 @@ typedef struct ARKodeSplittingStepMemRec SUNStepper* steppers; SplittingStepCoefficients coefficients; ARKodeSplittingExecutionPolicy policy; - long int n_stepper_evolves; + long int *n_stepper_evolves; int partitions; int order; From 9f5c77a86eaccc0b70461e9bb2e75392ac708d9f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 19:14:16 -0700 Subject: [PATCH 045/180] Switch to output argument style --- include/arkode/arkode_splittingstep.h | 2 +- src/arkode/arkode_splittingstep.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 8b2a21b627..667898e031 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -44,7 +44,7 @@ SUNDIALS_EXPORT int SplittingStep_SetCoefficients( SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( void* arkode_mem, ARKodeSplittingExecutionPolicy policy); -SUNDIALS_EXPORT long int SplittingStep_GetNumEvolves(void* arkode_mem, int partition); +SUNDIALS_EXPORT int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves); #ifdef __cplusplus } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index d78e072a85..1bd6533222 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -647,24 +647,28 @@ int SplittingStep_SetExecutionPolicy(void* const arkode_mem, return ARK_SUCCESS; } -long int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition) { +int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, long int * const evolves) { ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - if (partition < 0) { - long int total = 0; - for (int k = 0; k < step_mem->partitions; k++) { - total += step_mem->n_stepper_evolves[k]; - } - return total; - } else if (partition >= step_mem->partitions) { + if (partition >= step_mem->partitions) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, "The partition index is %i but there are only %i partitions", partition, step_mem->partitions); return ARK_ILL_INPUT; + } + + if (partition < 0) { + *evolves = 0; + for (int k = 0; k < step_mem->partitions; k++) { + *evolves += step_mem->n_stepper_evolves[k]; + } + return ARK_SUCCESS; } else { - return step_mem->n_stepper_evolves[partition]; + *evolves = step_mem->n_stepper_evolves[partition]; } + + return ARK_SUCCESS; } From ac2e830a1aa352f0c01bd599aaddc3bb43bace26 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 20:11:18 -0700 Subject: [PATCH 046/180] Clean up forcingstep --- include/arkode/arkode_forcingstep.h | 2 + src/arkode/arkode_forcingstep.c | 141 +++++++++++++++++---------- src/arkode/arkode_forcingstep_impl.h | 5 +- src/arkode/arkode_splittingstep.c | 1 - 4 files changed, 96 insertions(+), 53 deletions(-) diff --git a/include/arkode/arkode_forcingstep.h b/include/arkode/arkode_forcingstep.h index d2d95e5bba..1df14751c8 100644 --- a/include/arkode/arkode_forcingstep.h +++ b/include/arkode/arkode_forcingstep.h @@ -30,6 +30,8 @@ SUNDIALS_EXPORT void *ForcingStepCreate(SUNStepper stepper1, sunrealtype t0, N_Vector y0, SUNContext sunctx); +SUNDIALS_EXPORT int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves); + #ifdef __cplusplus } #endif diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index d1bcd944bb..0df431b4c8 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -22,6 +22,8 @@ #include "arkode_mristep_impl.h" #include "arkode_forcingstep_impl.h" +#define PARTITIONS 2 + /*--------------------------------------------------------------- Shortcut routine to unpack step_mem structure from ark_mem. If missing it returns ARK_MEM_NULL. @@ -40,6 +42,27 @@ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, return ARK_SUCCESS; } +/*--------------------------------------------------------------- + Shortcut routine to unpack ark_mem and step_mem structures from + void* pointer. If either is missing it returns ARK_MEM_NULL. + ---------------------------------------------------------------*/ +static int forcingStep_AccessARKODEStepMem(void* const arkode_mem, + const char* const fname, + ARKodeMem* const ark_mem, + ARKodeForcingStepMem* const step_mem) +{ + /* access ARKodeMem structure */ + if (arkode_mem == NULL) + { + arkProcessError(NULL, ARK_MEM_NULL, __LINE__, fname, __FILE__, + MSG_ARK_NO_MEM); + return (ARK_MEM_NULL); + } + *ark_mem = (ARKodeMem)arkode_mem; + + return forcingStep_AccessStepMem(*ark_mem, __func__, step_mem); +} + /*--------------------------------------------------------------- This routine checks if all required vector operations are present. If any of them is missing it returns SUNFALSE. @@ -55,7 +78,7 @@ static sunbooleantype forcingStep_CheckNVector(const N_Vector y) within arkInitialSetup. With initialization types FIRST_INIT this routine: - - sets the forcing for stepper2 + - sets the forcing for stepper[1] With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ @@ -79,7 +102,7 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } - SUNStepper_SetForcing(step_mem->stepper2, 1, ark_mem->yn); + SUNStepper_SetForcing(step_mem->stepper[1], 1, ark_mem->yn); ark_mem->interp_degree = 1; return ARK_SUCCESS; @@ -114,8 +137,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - retval = step_mem->stepper1->ops->fullrhs(step_mem->stepper1, t, y, f, - ARK_FULLRHS_OTHER); + // TODO(SBR): switch to SUNStepper_FullRHS() + retval = step_mem->stepper[0]->ops->fullrhs(step_mem->stepper[0], t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -123,9 +146,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return (ARK_RHSFUNC_FAIL); } - retval = step_mem->stepper2->ops->fullrhs(step_mem->stepper2, t, y, - ark_mem->tempv1, - ARK_FULLRHS_OTHER); + // TODO(SBR): confirm this doesn't include forcing + retval = step_mem->stepper[1]->ops->fullrhs(step_mem->stepper[1], t, y, f, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -141,7 +163,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, This routine performs a single step of the forcing method. ---------------------------------------------------------------*/ static int forcingStep_TakeStep(const ARKodeMem ark_mem, - sunrealtype* const dsmPtr, int* const nflagPtr) + sunrealtype* const dsmPtr, int* const nflagPtr) { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -150,36 +172,44 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ - const SUNStepper s1 = step_mem->stepper1; + const SUNStepper s0 = step_mem->stepper[0]; const sunrealtype tout = ark_mem->tn + ark_mem->h; sunrealtype tret = 0; int stop_reason = 0; - /* Evolve partition 1 on its own */ - SUNErrCode err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); + /* Evolve stepper 0 on its own */ + SUNErrCode err = SUNStepper_Reset(s0, ark_mem->tn, ark_mem->yn); if (err != SUN_SUCCESS) { return err; } - err = SUNStepper_SetStopTime(s1, tout); + err = SUNStepper_SetStepDirection(s0, ark_mem->h); if (err != SUN_SUCCESS) { return err; } - err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + err = SUNStepper_SetStopTime(s0, tout); + if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } - step_mem->n_stepper_evolves++; + step_mem->n_stepper_evolves[0]++; + + /* Reset stepper 1. It may be possible to avoid the reset here (like explicit + * MRIStep), but that would be very fragile. If the step direction ever + * changes or a resize is performed, the stepper and outer forcing method + * could become out of sync. */ + const SUNStepper s1 = step_mem->stepper[1]; + err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); + if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_SetStepDirection(s1, ark_mem->h); + if (err != SUN_SUCCESS) { return err; } + err = SUNStepper_SetStopTime(s1, tout); + if (err != SUN_SUCCESS) { return err; } - /* Write tendency into stepper 2 forcing */ - const SUNStepper s2 = step_mem->stepper2; + /* Write tendency (ycur - yn)/h into stepper 1 forcing */ const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; - N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s2->forcing[0]); + N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s1->forcing[0]); - /* No need to reset stepper 2 since its trajectory is continuous and in sync - * with the outer forcing method */ - err = SUNStepper_SetStopTime(s2, tout); - if (err != SUN_SUCCESS) { return err; } - - /* Eolve partition 2 with the forcing */ - err = SUNStepper_Evolve(s2, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + /* Evolve stepper 1 with the forcing */ + err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } - step_mem->n_stepper_evolves++; + step_mem->n_stepper_evolves[1]++; return ARK_SUCCESS; } @@ -199,11 +229,15 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - fprintf(outfile, "Stepper evolves = %ld\n", - step_mem->n_stepper_evolves); + for (int k = 0; k < PARTITIONS; k++) { + fprintf(outfile, "Partition %i evolves = %ld\n", + k, step_mem->n_stepper_evolves[k]); + } break; case SUN_OUTPUTFORMAT_CSV: - fprintf(outfile, "Stepper evolves,%ld\n", step_mem->n_stepper_evolves); + for (int k = 0; k < PARTITIONS; k++) { + fprintf(outfile, "Partition %i evolves,%ld\n", k, step_mem->n_stepper_evolves[k]); + } break; default: arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, @@ -234,8 +268,9 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) if (retval != ARK_SUCCESS) { return; } /* output long integer quantities */ - fprintf(outfile, "ForcingStep: n_stepper_evolves = %li\n", - step_mem->n_stepper_evolves); + for (int k = 0; k < 2; k++) { + fprintf(outfile, "ForcingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); + } } /*--------------------------------------------------------------- @@ -245,21 +280,7 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) ---------------------------------------------------------------*/ static int forcingStep_SetDefaults(const ARKodeMem ark_mem) { - ark_mem->interp_type = ARK_INTERP_LAGRANGE; - - return ARK_SUCCESS; -} - -static int forcingStep_Reset(ARKodeMem ark_mem, sunrealtype tR, N_Vector yR) -{ - ARKodeForcingStepMem step_mem = NULL; - int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return retval; } - - /* Reset stepper 2 to be consistent. No need to reset stepper 1 since that - * happens at the start of a step anyway. */ - retval = SUNStepper_Reset(step_mem->stepper2, tR, yR); - if (retval != ARK_SUCCESS) { return ARK_INNERSTEP_FAIL; } + ARKodeSetInterpolantType(ark_mem, ARK_INTERP_LAGRANGE); return ARK_SUCCESS; } @@ -327,9 +348,10 @@ void* ForcingStepCreate(SUNStepper stepper1, return NULL; } - step_mem->stepper1 = stepper1; - step_mem->stepper2 = stepper2; - step_mem->n_stepper_evolves = 0; + step_mem->stepper[0] = stepper1; + step_mem->stepper[1] = stepper2; + step_mem->n_stepper_evolves[0] = 0; + step_mem->n_stepper_evolves[1] = 0; /* Attach step_mem structure and function pointers to ark_mem */ ark_mem->step_init = forcingStep_Init; @@ -339,7 +361,6 @@ void* ForcingStepCreate(SUNStepper stepper1, ark_mem->step_free = forcingStep_Free; ark_mem->step_printmem = forcingStep_PrintMem; ark_mem->step_setdefaults = forcingStep_SetDefaults; - ark_mem->step_reset = forcingStep_Reset; ark_mem->step_mem = (void*)step_mem; /* Set default values for ARKStep optional inputs */ @@ -364,3 +385,25 @@ void* ForcingStepCreate(SUNStepper stepper1, return ark_mem; } + +int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves) { + ARKodeMem ark_mem = NULL; + ARKodeForcingStepMem step_mem = NULL; + int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); + if (retval != ARK_SUCCESS) { return (retval); } + + if (partition >= PARTITIONS) { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "The partition index is %i but there are only 2 partitions", partition); + return ARK_ILL_INPUT; + } + + if (partition < 0) { + *evolves = step_mem->n_stepper_evolves[0] + step_mem->n_stepper_evolves[1]; + } else { + *evolves = step_mem->n_stepper_evolves[partition]; + } + + return ARK_SUCCESS; +} diff --git a/src/arkode/arkode_forcingstep_impl.h b/src/arkode/arkode_forcingstep_impl.h index 863ea6e0e5..1222c90922 100644 --- a/src/arkode/arkode_forcingstep_impl.h +++ b/src/arkode/arkode_forcingstep_impl.h @@ -21,9 +21,8 @@ typedef struct ARKodeForcingStepMemRec { - SUNStepper stepper1; - SUNStepper stepper2; - long int n_stepper_evolves; + SUNStepper stepper[2]; + long int n_stepper_evolves[2]; }* ARKodeForcingStepMem; #endif diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 1bd6533222..dc90e5ea5a 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -665,7 +665,6 @@ int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, lon for (int k = 0; k < step_mem->partitions; k++) { *evolves += step_mem->n_stepper_evolves[k]; } - return ARK_SUCCESS; } else { *evolves = step_mem->n_stepper_evolves[partition]; } From bfb298ff77370423c7008485faf158340dc5d881 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 20:17:10 -0700 Subject: [PATCH 047/180] Add missing comments to execution policy --- src/arkode/execution_policy/arkode_execution_policy_serial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index 60754ada1e..2ddf6cde26 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -33,6 +33,10 @@ static int setup_serial( return ARK_SUCCESS; } +/*--------------------------------------------------------------- + This routine evaluates the policy function fn in serial over + the range of sequential methods + ---------------------------------------------------------------*/ static int execute_serial( SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, const ARKExecutionPolicyFn fn, const N_Vector yn, const N_Vector ycur, From 2d1558b22dd7a0987b675e1069ca47c317b2fa69 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 20:38:27 -0700 Subject: [PATCH 048/180] Add a parallel method to test --- .../arkode/CXX_serial/ark_test_splittingstep.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index c8b47a4a81..4f52a9e112 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -62,10 +62,7 @@ static int test_forward(sundials::Context &ctx, const int partitions) { auto arkode_mem = SplittingStepCreate(steppers.data(), partitions, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); - const auto coefficients = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); - SplittingStep_SetCoefficients(arkode_mem, coefficients); - SplittingStepCoefficients_Free(coefficients); - + ARKodeSetOrder(arkode_mem, 3); auto tret = t0; ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); @@ -190,7 +187,7 @@ static int test_resize(const sundials::Context &ctx) { constexpr auto t0 = SUN_RCONST(0.0); constexpr auto t1 = SUN_RCONST(0.5); constexpr auto t2 = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(7.0e-5); + constexpr auto dt = SUN_RCONST(7.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-5); constexpr auto global_tol = local_tol; const auto y = N_VNew_Serial(1, ctx); @@ -221,7 +218,9 @@ static int test_resize(const sundials::Context &ctx) { auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); - ARKodeSetMaxNumSteps(arkode_mem, -1); + const auto coefficients = SplittingStepCoefficients_SymmetricParallel(2); + SplittingStep_SetCoefficients(arkode_mem, coefficients); + SplittingStepCoefficients_Free(coefficients); /* Integrate from 0 to 0.5 */ auto tret = t0; @@ -351,7 +350,7 @@ int main() { /* Run the tests */ constexpr auto min_partitions = 2; - constexpr auto max_partitions = 8; + constexpr auto max_partitions = 7; for (auto p = min_partitions; p <= max_partitions; p++) { errors += test_forward(ctx, p); } From 277cf111690b0b5a3a712b8a94205f03fb3a33be Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 21:11:54 -0700 Subject: [PATCH 049/180] Fix copy size --- src/arkode/arkode_splitting_coefficients.c | 8 +++--- .../CXX_serial/ark_test_splittingstep.cpp | 27 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splitting_coefficients.c index 9d15106520..aa9f800a49 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splitting_coefficients.c @@ -106,9 +106,9 @@ SplittingStepCoefficients SplittingStepCoefficients_Create( if (coefficients == NULL) { return NULL; } coefficients->order = order; - memcpy(coefficients->alpha, alpha, sequential_methods * sizeof(*alpha)); + memcpy(coefficients->alpha, alpha, sequential_methods * sizeof(sunrealtype)); memcpy(coefficients->beta[0][0], beta, - sequential_methods * (stages + 1) * partitions * sizeof(*beta)); + sequential_methods * (stages + 1) * partitions * sizeof(sunrealtype)); return coefficients; } @@ -149,13 +149,13 @@ SplittingStepCoefficients SplittingStepCoefficients_Copy( coefficientsCopy->order = coefficients->order; memcpy(coefficientsCopy->alpha, coefficients->alpha, - coefficients->sequential_methods * sizeof(*coefficients->alpha)); + coefficients->sequential_methods * sizeof(sunrealtype)); /* beta[0][0] points to the contiguous memory allocation, so we can copy it with a single memcpy */ memcpy(coefficientsCopy->beta[0][0], coefficients->beta[0][0], coefficients->sequential_methods * (coefficients->stages + 1) * - coefficients->partitions * sizeof(*coefficients->beta)); + coefficients->partitions * sizeof(sunrealtype)); return coefficientsCopy; } diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 4f52a9e112..75f9d5aec8 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -36,9 +36,9 @@ static int test_forward(sundials::Context &ctx, const int partitions) { constexpr auto t0 = SUN_RCONST(0.0); constexpr auto tf = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(0.01); - constexpr auto local_tol = SUN_RCONST(1.0e-8); - constexpr auto global_tol = local_tol; + constexpr auto dt = SUN_RCONST(0.008); + constexpr auto local_tol = SUN_RCONST(1.0e-6); + constexpr auto global_tol = 10 * local_tol; const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); @@ -98,9 +98,9 @@ static int test_mixed_directions(const sundials::Context &ctx) { constexpr auto t1 = SUN_RCONST(-1.0); constexpr auto t2 = SUN_RCONST(0.4); constexpr auto t3 = t0; - constexpr auto dt = -SUN_RCONST(7.0e-4); - constexpr auto local_tol = SUN_RCONST(1.0e-6); - constexpr auto global_tol = local_tol; + constexpr auto dt = -SUN_RCONST(1.00001e-3); + constexpr auto local_tol = SUN_RCONST(5.0e-7); + constexpr auto global_tol = 1 * local_tol; const auto y = N_VNew_Serial(2, ctx); N_VConst(SUN_RCONST(1.0), y); const auto err = N_VClone(y); @@ -154,6 +154,7 @@ static int test_mixed_directions(const sundials::Context &ctx) { N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y, err); const auto max_err = N_VMaxNorm(err); + std::cout << max_err << std::endl; if (max_err > global_tol) { std::cerr << "Mixed direction solution failed with an error of " << max_err << "\n"; return 1; @@ -349,15 +350,15 @@ int main() { int errors = 0; /* Run the tests */ - constexpr auto min_partitions = 2; - constexpr auto max_partitions = 7; - for (auto p = min_partitions; p <= max_partitions; p++) { - errors += test_forward(ctx, p); - } + // constexpr auto min_partitions = 2; + // constexpr auto max_partitions = 7; + // for (auto p = min_partitions; p <= max_partitions; p++) { + // errors += test_forward(ctx, p); + // } errors += test_mixed_directions(ctx); - errors += test_resize(ctx); - errors += test_custom_stepper(ctx); + // errors += test_resize(ctx); + // errors += test_custom_stepper(ctx); if (errors == 0) { std::cout << "Success\n"; From e471a2c17d3026bdf31c6250405538a19f640e68 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 21:14:53 -0700 Subject: [PATCH 050/180] Remove todo --- src/arkode/arkode_forcingstep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 0df431b4c8..23df5319e4 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -146,7 +146,6 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return (ARK_RHSFUNC_FAIL); } - // TODO(SBR): confirm this doesn't include forcing retval = step_mem->stepper[1]->ops->fullrhs(step_mem->stepper[1], t, y, f, ARK_FULLRHS_OTHER); if (retval != 0) { From be43b2eb66ffc275e53df73edec3bd7852504699 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 21:17:53 -0700 Subject: [PATCH 051/180] Remove todo --- src/arkode/arkode_forcingstep.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 23df5319e4..924862f1e5 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -137,8 +137,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - // TODO(SBR): switch to SUNStepper_FullRHS() - retval = step_mem->stepper[0]->ops->fullrhs(step_mem->stepper[0], t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); + const SUNStepper s0 = step_mem->stepper[0]; + retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -146,7 +146,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return (ARK_RHSFUNC_FAIL); } - retval = step_mem->stepper[1]->ops->fullrhs(step_mem->stepper[1], t, y, f, ARK_FULLRHS_OTHER); + const SUNStepper s1 = step_mem->stepper[1]; + retval = s1->ops->fullrhs(s1, t, y, f, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, From d332da3b8851b633a4bb16b2f19e9c6036e8d064 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 21:28:00 -0700 Subject: [PATCH 052/180] Disable single precision for some tests --- examples/arkode/C_serial/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index aac6df0dc0..ebcd0c39d0 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -29,8 +29,8 @@ set(ARKODE_examples "ark_analytic_partitioned\;forcing\;develop" "ark_analytic_partitioned\;splitting\;develop" "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_BEST_2_2_2\;develop" - "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_RUTH_3_3_2\;develop" - "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_YOSHIDA_8_6_2\;develop" + "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_RUTH_3_3_2\;exclude-single" + "ark_analytic_partitioned\;splitting ARKODE_SPLITTING_YOSHIDA_8_6_2\;exclude-single" "ark_brusselator_1D_mri\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator_mri\;\;develop" From f30bf90279816186343a0e0b19058a9173d15173 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 21:38:18 -0700 Subject: [PATCH 053/180] Fix interp degree --- src/arkode/arkode_splittingstep.c | 4 ++-- test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index dc90e5ea5a..7490c1dabd 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -171,8 +171,8 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) step_mem->own_policy = SUNTRUE; } - ark_mem->interp_degree = - SUNMAX(1, SUNMIN(step_mem->order - 1, ark_mem->interp_degree)); + ark_mem->interp_degree = + SUNMAX(1, SUNMIN(step_mem->coefficients->order - 1, ark_mem->interp_degree)); return ARK_SUCCESS; } diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 75f9d5aec8..c7dc84cb8a 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -98,7 +98,7 @@ static int test_mixed_directions(const sundials::Context &ctx) { constexpr auto t1 = SUN_RCONST(-1.0); constexpr auto t2 = SUN_RCONST(0.4); constexpr auto t3 = t0; - constexpr auto dt = -SUN_RCONST(1.00001e-3); + constexpr auto dt = -SUN_RCONST(1.001e-3); constexpr auto local_tol = SUN_RCONST(5.0e-7); constexpr auto global_tol = 1 * local_tol; const auto y = N_VNew_Serial(2, ctx); From ce4adfa3635b354325ee324e978fef331847c1ec Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 11 Sep 2024 22:07:32 -0700 Subject: [PATCH 054/180] Fix tests for non-double precision --- .../CXX_serial/ark_test_splittingstep.cpp | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index c7dc84cb8a..2c71a0cdc8 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -36,7 +36,7 @@ static int test_forward(sundials::Context &ctx, const int partitions) { constexpr auto t0 = SUN_RCONST(0.0); constexpr auto tf = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(0.008); + constexpr auto dt = SUN_RCONST(8.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-6); constexpr auto global_tol = 10 * local_tol; const auto y = N_VNew_Serial(1, ctx); @@ -98,9 +98,9 @@ static int test_mixed_directions(const sundials::Context &ctx) { constexpr auto t1 = SUN_RCONST(-1.0); constexpr auto t2 = SUN_RCONST(0.4); constexpr auto t3 = t0; - constexpr auto dt = -SUN_RCONST(1.001e-3); - constexpr auto local_tol = SUN_RCONST(5.0e-7); - constexpr auto global_tol = 1 * local_tol; + constexpr auto dt = -SUN_RCONST(1.23e-3); + constexpr auto local_tol = SUN_RCONST(1.0e-6); + constexpr auto global_tol = 10 * local_tol; const auto y = N_VNew_Serial(2, ctx); N_VConst(SUN_RCONST(1.0), y); const auto err = N_VClone(y); @@ -154,7 +154,6 @@ static int test_mixed_directions(const sundials::Context &ctx) { N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y, err); const auto max_err = N_VMaxNorm(err); - std::cout << max_err << std::endl; if (max_err > global_tol) { std::cerr << "Mixed direction solution failed with an error of " << max_err << "\n"; return 1; @@ -188,7 +187,7 @@ static int test_resize(const sundials::Context &ctx) { constexpr auto t0 = SUN_RCONST(0.0); constexpr auto t1 = SUN_RCONST(0.5); constexpr auto t2 = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(7.0e-3); + constexpr auto dt = SUN_RCONST(8.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-5); constexpr auto global_tol = local_tol; const auto y = N_VNew_Serial(1, ctx); @@ -301,8 +300,7 @@ static int test_custom_stepper(const sundials::Context &ctx) { constexpr auto lambda2 = SUN_RCONST(-0.4); constexpr auto t0 = SUN_RCONST(0.0); constexpr auto tf = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(5.0e-2); - constexpr auto global_tol = SUN_RCONST(1.0e-12); + constexpr auto dt = SUN_RCONST(0.1); const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); @@ -322,7 +320,7 @@ static int test_custom_stepper(const sundials::Context &ctx) { /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); - if (SUNRCompareTol(exact_solution, NV_Ith_S(y, 0), global_tol)) { + if (SUNRCompare(exact_solution, NV_Ith_S(y, 0))) { std::cerr << "Custom SUNStepper is not within the tolerance\n"; return 1; } @@ -350,15 +348,15 @@ int main() { int errors = 0; /* Run the tests */ - // constexpr auto min_partitions = 2; - // constexpr auto max_partitions = 7; - // for (auto p = min_partitions; p <= max_partitions; p++) { - // errors += test_forward(ctx, p); - // } + constexpr auto min_partitions = 2; + constexpr auto max_partitions = 7; + for (auto p = min_partitions; p <= max_partitions; p++) { + errors += test_forward(ctx, p); + } errors += test_mixed_directions(ctx); - // errors += test_resize(ctx); - // errors += test_custom_stepper(ctx); + errors += test_resize(ctx); + errors += test_custom_stepper(ctx); if (errors == 0) { std::cout << "Success\n"; From 1d589a875b72da4f283d9a7c3bdebf880524a93b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 13:22:12 -0700 Subject: [PATCH 055/180] Add comments to step direction functions --- src/arkode/arkode_io.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index 66c747a650..d932c35cb5 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1283,7 +1283,13 @@ int ARKodeSetFixedStep(void* arkode_mem, sunrealtype hfixed) /*--------------------------------------------------------------- ARKodeSetStepDirection: - TODO(SBR) + Specifies the direction of integration (forward or backward) + based on the sign of stepdir. If 0, the direction will remain + unchanged. Note that if a fixed step size was previously set, + this function can change the sign of that. + + This should only be called after ARKodeReset, or between + creating a stepper and ARKodeEvolve. ---------------------------------------------------------------*/ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) { @@ -2137,7 +2143,9 @@ int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur) /*--------------------------------------------------------------- ARKodeGetStepDirection: - TODO(SBR) + Gets the direction of integration (forward or backward) based + on the sign of stepdir. A value of 0 indicates integration can + procede in either direction. ---------------------------------------------------------------*/ int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir) { From 12da914a532ca3dfcf244645a099d1dd1097e733 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 13:44:33 -0700 Subject: [PATCH 056/180] Correct comment times --- test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 2c71a0cdc8..7dc0daff00 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -141,12 +141,12 @@ static int test_mixed_directions(const sundials::Context &ctx) { auto tret = t0; ARKodeEvolve(arkode_mem, t1, y, &tret, ARK_NORMAL); - /* Integrate from -1 to 2 */ + /* Integrate from -1 to 0.4 */ ARKodeReset(arkode_mem, t1, y); ARKodeSetStepDirection(arkode_mem, t2 - t1); ARKodeEvolve(arkode_mem, t2, y, &tret, ARK_NORMAL); - /* Integrate from 2 to 0 */ + /* Integrate from 0.4 to 0 */ ARKodeReset(arkode_mem, t2, y); ARKodeSetStepDirection(arkode_mem, t3 - t2); ARKodeEvolve(arkode_mem, t3, y, &tret, ARK_NORMAL); From 1f2c7c57a7d4fa7bf56e6db4424a460314f46f1d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 14:17:14 -0700 Subject: [PATCH 057/180] Add ARKodeGetStepDirection docs --- .../guide/source/Usage/User_callable.rst | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/doc/arkode/guide/source/Usage/User_callable.rst b/doc/arkode/guide/source/Usage/User_callable.rst index b310753b66..c014f003a4 100644 --- a/doc/arkode/guide/source/Usage/User_callable.rst +++ b/doc/arkode/guide/source/Usage/User_callable.rst @@ -880,6 +880,7 @@ Set dense output interpolation type (SPRKStep) :c:func:`ARKodeSetInterpolantT Set dense output interpolation type (others) :c:func:`ARKodeSetInterpolantType` ``ARK_INTERP_HERMITE`` Set dense output polynomial degree :c:func:`ARKodeSetInterpolantDegree` 5 Disable time step adaptivity (fixed-step mode) :c:func:`ARKodeSetFixedStep` disabled +Set forward or backward integration direction :c:func:`ARKodeSetStepDirection` 0.0 Supply an initial step size to attempt :c:func:`ARKodeSetInitStep` estimated Maximum no. of warnings for :math:`t_n+h = t_n` :c:func:`ARKodeSetMaxHnilWarns` 10 Maximum no. of internal steps before *tout* :c:func:`ARKodeSetMaxNumSteps` 500 @@ -1098,6 +1099,30 @@ Set max number of constraint failures :c:func:`ARKodeSetMaxNumConstr .. versionadded:: 6.1.0 +.. c:function:: int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) + + Specifies the direction of integration (forward or backward). + + :param arkode_mem: pointer to the ARKODE memory block. + :param stepdir: value whose sign determines the direction. A positive value + selects forward integration, a negative value selects + backward integration, and zero leaves the current direction + unchanged. + + + :retval ARK_SUCCESS: the function exited successfully. + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL``. + :retval ARK_ILL_INPUT: an argument had an illegal value. + + .. note:: + + The step direction can only be set after a call to either ``*Create``, + ``*StepReInit``, or :c:func:`ARKodeReset` but before a call to + :c:func:`ARKodeEvolve`. + + .. versionadded:: x.y.z + + .. c:function:: int ARKodeSetInitStep(void* arkode_mem, sunrealtype hin) @@ -3157,6 +3182,7 @@ Cumulative number of internal steps :c:func:`ARKodeGetNumStep Actual initial time step size used :c:func:`ARKodeGetActualInitStep` Step size used for the last successful step :c:func:`ARKodeGetLastStep` Step size to be attempted on the next step :c:func:`ARKodeGetCurrentStep` +Integration direction, e.g., forward or backward :c:func:`ARKodeGetStepDirection` Current internal time reached by the solver :c:func:`ARKodeGetCurrentTime` Current internal solution reached by the solver :c:func:`ARKodeGetCurrentState` Current :math:`\gamma` value used by the solver :c:func:`ARKodeGetCurrentGamma` @@ -3257,6 +3283,22 @@ Retrieve a pointer for user data :c:func:`ARKodeGetUserDat .. versionadded:: 6.1.0 +.. c:function:: int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir) + + Returns the direction of integration that will be used on the next internal + step. + + :param arkode_mem: pointer to the ARKODE memory block. + :param stepdir: a positive number if integrating forward, a negative number + if integrating backward, or zero if the direction has not + been set. + + :retval ARK_SUCCESS: the function exited successfully. + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL``. + + .. versionadded:: x.y.z + + .. c:function:: int ARKodeGetCurrentTime(void* arkode_mem, sunrealtype* tcur) Returns the current internal time reached by the solver. From 626318a72345ef776f228db98bb3288f7d235584 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 14:21:04 -0700 Subject: [PATCH 058/180] Add step dir functions to changelog --- CHANGELOG.md | 3 +++ doc/shared/RecentChanges.rst | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e174d0969..267f33618b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ ForcingStep. to ARKODE. ### New Features and Enhancements +Added the `ARKodeSetStepDirection` and `ARKodeGetStepDirection` functions to +change and query the direction of integration. + The default value of `CMAKE_CUDA_ARCHITECTURES` is no longer set to `70` and is now determined automatically by CMake. The previous default was only valid for Volta GPUs while the automatically selected value will vary across compilers and diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index e77f45909d..0514f8b4d0 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -6,6 +6,9 @@ Added an operator splitting module, **New Features and Enhancements** +Added the :c:func:`ARKodeSetStepDirection` and :c:func:`ARKodeGetStepDirection` +functions to change and query the direction of integration. + The default value of :cmakeop:`CMAKE_CUDA_ARCHITECTURES` is no longer set to ``70`` and is now determined automatically by CMake. The previous default was only valid for Volta GPUs while the automatically selected value will vary From 49d5bd6f9d1566edec5703ccdd460cc2afb03276 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 15:30:12 -0700 Subject: [PATCH 059/180] Add SplittingStep_GetNumEvolves docs --- .../Usage/SplittingStep/User_callable.rst | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index d06fa02109..6b2eda86e8 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -114,3 +114,37 @@ Optional inputs for IVP method selection **Warning:** This should not be used with :c:func:`ARKodeSetOrder`. + + .. versionadded:: x.y.z + + +.. _ARKODE.Usage.SplittingStep.OptionalOutputs: + + +Optional output functions +------------------------------ + +.. c:function:: int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves) + + Returns the number of times the :c:type:`SUNStepper` for the given partition + index has been evolved (so far). + + **Arguments:** + + * *arkode_mem* -- pointer to the SplittingStep memory block. + + * *partition* -- index of the partition between 0 and :math:`P - 1` or a + negative number to indicate the total number across all + partitions. + + * *evolves* -- number of :c:type:`SUNStepper` evolves. + + **Return value:** + + * *ARK_SUCCESS* if successful + + * *ARK_MEM_NULL* if the SplittingStep memory was ``NULL`` + + * *ARK_ILL_INPUT* if *evolves* is out of bounds + + .. versionadded:: x.y.z From 486a91d8d9c957ea35fba4f39dc1b15bcc97736b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 15:39:54 -0700 Subject: [PATCH 060/180] Add ForcingStep_GetNumEvolves docs --- .../Usage/ForcingStep/User_callable.rst | 31 +++++++++++++++++++ .../Usage/SplittingStep/User_callable.rst | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst index 1fdf1ab8d5..63184a7640 100644 --- a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -81,3 +81,34 @@ ForcingStep initialization functions * ``examples/arkode/C_serial/ark_analytic_partitioned.c`` .. versionadded:: x.y.z + + +.. _ARKODE.Usage.ForcingStep.OptionalOutputs: + + +Optional output functions +------------------------------ + +.. c:function:: int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves) + + Returns the number of times the :c:type:`SUNStepper` for the given partition + index has been evolved (so far). + + **Arguments:** + + * *arkode_mem* -- pointer to the ForcingStep memory block. + + * *partition* -- index of the partition (0 or 1) or a negative number to + indicate the total number across both partitions. + + * *evolves* -- number of :c:type:`SUNStepper` evolves. + + **Return value:** + + * *ARK_SUCCESS* if successful + + * *ARK_MEM_NULL* if the ForcingStep memory was ``NULL`` + + * *ARK_ILL_INPUT* if *evolves* was out of bounds + + .. versionadded:: x.y.z \ No newline at end of file diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 6b2eda86e8..c2da9180c2 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -145,6 +145,6 @@ Optional output functions * *ARK_MEM_NULL* if the SplittingStep memory was ``NULL`` - * *ARK_ILL_INPUT* if *evolves* is out of bounds + * *ARK_ILL_INPUT* if *evolves* was out of bounds .. versionadded:: x.y.z From 769552f9ad75f16d0b93b9a6fa182e9f6342de73 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 15:54:38 -0700 Subject: [PATCH 061/180] Code cleanup --- test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 7dc0daff00..07e011e896 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -11,12 +11,12 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * TODO + * Unit tests on several ODEs with analytical solutions to verify the + * SplittingStep module. * ---------------------------------------------------------------------------*/ #include #include -#include #include #include #include From 1eb6166297b6ea6a57b9fd4a51e5a3940691e9fc Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 16:41:54 -0700 Subject: [PATCH 062/180] Add forcingstep unit test --- .../CXX_serial/ark_test_splittingstep.cpp | 12 +- .../unit_tests/arkode/C_serial/CMakeLists.txt | 1 + .../arkode/C_serial/ark_test_forcingstep.c | 129 ++++++++++++++++++ 3 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 test/unit_tests/arkode/C_serial/ark_test_forcingstep.c diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 07e011e896..0e2cecb1dd 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -68,8 +68,10 @@ static int test_forward(sundials::Context &ctx, const int partitions) { /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); - if (SUNRCompareTol(exact_solution, NV_Ith_S(y, 0), global_tol)) { - std::cerr << "Forward solution with " << partitions << " partitions is not within the tolerance\n"; + const auto numerical_solution = NV_Ith_S(y, 0); + if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { + const auto err = numerical_solution - exact_solution; + std::cerr << "Forward solution with " << partitions << " partitions failed with an error of" << err << "\n"; return 1; } @@ -320,8 +322,10 @@ static int test_custom_stepper(const sundials::Context &ctx) { /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); - if (SUNRCompare(exact_solution, NV_Ith_S(y, 0))) { - std::cerr << "Custom SUNStepper is not within the tolerance\n"; + const auto numerical_solution = NV_Ith_S(y, 0); + if (SUNRCompare(exact_solution, numerical_solution)) { + const auto err = numerical_solution - exact_solution; + std::cerr << "Custom SUNStepper failed with an error of" << err << "\n"; return 1; } diff --git a/test/unit_tests/arkode/C_serial/CMakeLists.txt b/test/unit_tests/arkode/C_serial/CMakeLists.txt index db0e6fdd4d..d523e56f5e 100644 --- a/test/unit_tests/arkode/C_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/C_serial/CMakeLists.txt @@ -25,6 +25,7 @@ set(ARKODE_unit_tests "ark_test_arkstepsetforcing\;1 3 2.0 10.0" "ark_test_arkstepsetforcing\;1 3 2.0 10.0 2.0 8.0" "ark_test_arkstepsetforcing\;1 3 2.0 10.0 1.0 5.0" + "ark_test_forcingstep\;" "ark_test_getuserdata\;" "ark_test_innerstepper\;" "ark_test_interp\;-100" diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c new file mode 100644 index 0000000000..c804566101 --- /dev/null +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -0,0 +1,129 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * Unit tests on several ODEs with analytical solutions to verify the + * ForcingStep module. + * ---------------------------------------------------------------------------*/ + +#include +#include +#include + +#if defined(SUNDIALS_EXTENDED_PRECISION) +#define GSYM "Lg" +#else +#define GSYM "g" +#endif + +/* RHS function for f_1(t, y) = t / y */ +static int f_forward_1(const sunrealtype t, const N_Vector y, const N_Vector ydot, void *const user_data) { + N_VInv(y, ydot); + N_VScale(t, ydot, ydot); + return 0; +} + +/* RHS function for f_2(t, y) = 1 / y */ +static int f_forward_2(const sunrealtype t, const N_Vector y, const N_Vector ydot, void *const user_data) { + N_VInv(y, ydot); + return 0; +} + +/* Integrates the ODE + * + * y' = [t / y] - [1 / y] + * + * with initial condition y(0) = 1 and partitioning specified by the square + * brackets. We integrate to t = 1 and check the error against the exact + * solution y(t) = |t + 1|. + */ +static int test_forward(SUNContext ctx) { + const sunrealtype t0 = SUN_RCONST(0.0); + const sunrealtype tf = SUN_RCONST(1.0); + const sunrealtype dt = SUN_RCONST(1.0e-4); + const sunrealtype local_tol = SUN_RCONST(1.0e-6); + const sunrealtype global_tol = 10 * local_tol; + + const N_Vector y = N_VNew_Serial(1, ctx); + N_VConst(SUN_RCONST(1.0), y); + + void* parititon_mem[] = { + ARKStepCreate(f_forward_1, NULL, t0, y, ctx), + ARKStepCreate(f_forward_2, NULL, t0, y, ctx) + }; + ARKodeSStolerances(parititon_mem[0], local_tol, local_tol); + ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); + + SUNStepper steppers[] = {NULL, NULL}; + ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); + ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); + + void *arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); + ARKodeSetFixedStep(arkode_mem, dt); + ARKodeSetMaxNumSteps(arkode_mem, -1); + + sunrealtype tret = t0; + ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); + + const sunrealtype exact_solution = SUN_RCONST(2.0); + const sunrealtype numerical_solution = NV_Ith_S(y, 0); + if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { + const sunrealtype err = numerical_solution - exact_solution; + fprintf(stderr, "Forward direction solution failed with an error of %" GSYM "\n", err); + return 1; + } + + N_VDestroy(y); + ARKodeFree(&parititon_mem[0]); + SUNStepper_Destroy(&steppers[0]); + ARKodeFree(&parititon_mem[1]); + SUNStepper_Destroy(&steppers[1]); + ARKodeFree(&arkode_mem); + + return 0; +} + +/* Error handling function which prints the error and exits the program */ +static void err_fn(const int line, const char* const func, const char* const file, + const char* const msg, const SUNErrCode err_code, + void* const err_user_data, const SUNContext ctx) +{ + fprintf(stderr, "Error at line %i of %s in %s: %s\n", line, func, file, msg); + exit(err_code); +} + +int main() { + SUNContext ctx = NULL; + SUNErrCode err = SUNContext_Create(SUN_COMM_NULL, &ctx); + if (err != SUN_SUCCESS) { + fprintf(stderr, "Failed to create the SUNContext\n"); + return 1; + } + + err = SUNContext_PushErrHandler(ctx, err_fn, NULL); + if (err != SUN_SUCCESS) { + fprintf(stderr, "Failed to add error handler\n"); + return 1; + } + + err = test_forward(ctx); + + SUNContext_Free(&ctx); + + if (err == 0) { + printf("Success\n"); + } else { + printf("%d Test Failures\n", err); + } + + return 0; +} \ No newline at end of file From f2f80a3a0b5ed487a92f3a77fbd66d5e903dfd92 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 16:46:03 -0700 Subject: [PATCH 063/180] Apply formatter --- .../C_serial/ark_analytic_partitioned.c | 43 ++-- include/arkode/arkode.h | 3 +- include/arkode/arkode_forcingstep.h | 10 +- .../arkode/arkode_splitting_coefficients.h | 2 +- include/arkode/arkode_splittingstep.h | 3 +- include/sundials/sundials_stepper.h | 10 +- src/arkode/arkode_arkstep.c | 6 +- src/arkode/arkode_forcingstep.c | 105 ++++----- src/arkode/arkode_io.c | 12 +- src/arkode/arkode_splittingstep.c | 84 +++++--- src/arkode/arkode_splittingstep_impl.h | 2 +- src/sundials/sundials_stepper.c | 18 +- .../CXX_serial/ark_test_splittingstep.cpp | 201 ++++++++++-------- .../arkode/C_serial/ark_test_forcingstep.c | 54 ++--- 14 files changed, 310 insertions(+), 243 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index ec4f5da5af..6c6c41a3cf 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -37,8 +37,8 @@ /* Header files */ #include -#include #include +#include #include #include @@ -132,17 +132,20 @@ static int check_flag(void* flagvalue, const char* funcname, int opt) int main(const int argc, char* const argv[]) { /* Parse arguments */ - const char *const integrator_name = (argc > 1) ? argv[1] : "splitting"; - if (strcmp(integrator_name, "splitting") != 0 && strcmp(integrator_name, "forcing") != 0) { - fprintf(stderr, "Invalid integrator: %s\nMust be 'splitting' or 'forcing'\n", integrator_name); + const char* const integrator_name = (argc > 1) ? argv[1] : "splitting"; + if (strcmp(integrator_name, "splitting") != 0 && + strcmp(integrator_name, "forcing") != 0) + { + fprintf(stderr, "Invalid integrator: %s\nMust be 'splitting' or 'forcing'\n", + integrator_name); return 1; } - const char *const coefficients_name = (argc > 2) ? argv[2] : NULL; + const char* const coefficients_name = (argc > 2) ? argv[2] : NULL; /* Problem parameters */ - const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ - const sunrealtype tf = SUN_RCONST(1.0); /* final time */ - const sunrealtype dt = SUN_RCONST(0.01); /* outer time step */ + const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ + const sunrealtype tf = SUN_RCONST(1.0); /* final time */ + const sunrealtype dt = SUN_RCONST(0.01); /* outer time step */ const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ const sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ @@ -162,7 +165,8 @@ int main(const int argc, char* const argv[]) printf("\nAnalytical ODE test problem:\n"); printf(" integrator = %s method\n", integrator_name); - if (coefficients_name != NULL) { + if (coefficients_name != NULL) + { printf(" coefficients = %s\n", coefficients_name); } printf(" lambda = %" GSYM "\n", user_data.lambda); @@ -190,21 +194,30 @@ int main(const int argc, char* const argv[]) ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); /* Create the outer integrator */ - void *arkode_mem; - if (strcmp(integrator_name, "splitting") == 0) { + void* arkode_mem; + if (strcmp(integrator_name, "splitting") == 0) + { arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); if (check_flag(arkode_mem, "SplittingStepCreate", 0)) { return 1; } - if (coefficients_name != NULL) { - const SplittingStepCoefficients coefficients = SplittingStepCoefficients_LoadCoefficientsByName(coefficients_name); - if (check_flag(coefficients, "SplittingStepCoefficients_LoadCoefficientsByName", 0)) { return 1; } + if (coefficients_name != NULL) + { + const SplittingStepCoefficients coefficients = + SplittingStepCoefficients_LoadCoefficientsByName(coefficients_name); + if (check_flag(coefficients, + "SplittingStepCoefficients_LoadCoefficientsByName", 0)) + { + return 1; + } flag = SplittingStep_SetCoefficients(arkode_mem, coefficients); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } SplittingStepCoefficients_Free(coefficients); } - } else { + } + else + { arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); if (check_flag(arkode_mem, "ForcingStepCreate", 0)) { return 1; } } diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index d6e12762f0..e94c4dc479 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -302,7 +302,8 @@ SUNDIALS_EXPORT int ARKodeGetWorkSpace(void* arkode_mem, long int* lenrw, SUNDIALS_EXPORT int ARKodeGetNumSteps(void* arkode_mem, long int* nsteps); SUNDIALS_EXPORT int ARKodeGetLastStep(void* arkode_mem, sunrealtype* hlast); SUNDIALS_EXPORT int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur); -SUNDIALS_EXPORT int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir); +SUNDIALS_EXPORT int ARKodeGetStepDirection(void* arkode_mem, + sunrealtype* stepdir); SUNDIALS_EXPORT int ARKodeGetErrWeights(void* arkode_mem, N_Vector eweight); SUNDIALS_EXPORT int ARKodeGetNumGEvals(void* arkode_mem, long int* ngevals); SUNDIALS_EXPORT int ARKodeGetRootInfo(void* arkode_mem, int* rootsfound); diff --git a/include/arkode/arkode_forcingstep.h b/include/arkode/arkode_forcingstep.h index 1df14751c8..16296b4422 100644 --- a/include/arkode/arkode_forcingstep.h +++ b/include/arkode/arkode_forcingstep.h @@ -25,12 +25,12 @@ extern "C" { #endif -SUNDIALS_EXPORT void *ForcingStepCreate(SUNStepper stepper1, - SUNStepper stepper2, - sunrealtype t0, N_Vector y0, - SUNContext sunctx); +SUNDIALS_EXPORT void* ForcingStepCreate(SUNStepper stepper1, + SUNStepper stepper2, sunrealtype t0, + N_Vector y0, SUNContext sunctx); -SUNDIALS_EXPORT int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves); +SUNDIALS_EXPORT int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, + long int* evolves); #ifdef __cplusplus } diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splitting_coefficients.h index 191784ceee..7532a3d495 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splitting_coefficients.h @@ -37,7 +37,7 @@ struct SplittingStepCoefficientsMem int stages; /* number of stages within each sequential splitting method */ int partitions; /* number of RHS partitions */ /* TODO(SBR): q to be more consistent? */ - int order; /* order of convergence */ + int order; /* order of convergence */ }; typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 667898e031..1a72d9cb98 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -44,7 +44,8 @@ SUNDIALS_EXPORT int SplittingStep_SetCoefficients( SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( void* arkode_mem, ARKodeSplittingExecutionPolicy policy); -SUNDIALS_EXPORT int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves); +SUNDIALS_EXPORT int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, + long int* evolves); #ifdef __cplusplus } diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 56e9b0d9f2..f490fa03f0 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -54,9 +54,11 @@ typedef SUNErrCode (*SUNStepperResetFn)(SUNStepper stepper, sunrealtype tR, typedef SUNErrCode (*SUNStepperSetStopTimeFn)(SUNStepper stepper, sunrealtype tstop); -typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype stepdir); +typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, + sunrealtype stepdir); -typedef SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, sunrealtype* stepdir); +typedef SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, + sunrealtype* stepdir); SUNDIALS_EXPORT SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper); @@ -91,11 +93,11 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNDIALS_EXPORT SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, - SUNStepperSetStepDirectionFn fn); + SUNStepperSetStepDirectionFn fn); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, - SUNStepperGetStepDirectionFn fn); + SUNStepperGetStepDirectionFn fn); SUNDIALS_EXPORT SUNErrCode SUNStepper_AddForcing(SUNStepper stepper, sunrealtype t, N_Vector f); diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 670b101c43..08316406a6 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3162,10 +3162,12 @@ int ARKStepCreateSUNStepper(void* inner_arkode_mem, SUNStepper* stepper) retval = SUNStepper_SetStopTimeFn(*stepper, arkStep_SUNStepperSetStopTime); if (retval != ARK_SUCCESS) { return (retval); } - retval = SUNStepper_SetSetStepDirectionFn(*stepper, arkStep_SUNStepperSetStepDirection); + retval = SUNStepper_SetSetStepDirectionFn(*stepper, + arkStep_SUNStepperSetStepDirection); if (retval != ARK_SUCCESS) { return (retval); } - retval = SUNStepper_SetGetStepDirectionFn(*stepper, arkStep_SUNStepperGetStepDirection); + retval = SUNStepper_SetGetStepDirectionFn(*stepper, + arkStep_SUNStepperGetStepDirection); if (retval != ARK_SUCCESS) { return (retval); } return (ARK_SUCCESS); diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 924862f1e5..bc4e4553b6 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -18,9 +18,9 @@ #include #include +#include "arkode_forcingstep_impl.h" #include "arkode_impl.h" #include "arkode_mristep_impl.h" -#include "arkode_forcingstep_impl.h" #define PARTITIONS 2 @@ -29,8 +29,8 @@ If missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, - const char* const fname, - ARKodeForcingStepMem* const step_mem) + const char* const fname, + ARKodeForcingStepMem* const step_mem) { if (ark_mem->step_mem == NULL) { @@ -47,9 +47,9 @@ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, void* pointer. If either is missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ static int forcingStep_AccessARKODEStepMem(void* const arkode_mem, - const char* const fname, - ARKodeMem* const ark_mem, - ARKodeForcingStepMem* const step_mem) + const char* const fname, + ARKodeMem* const ark_mem, + ARKodeForcingStepMem* const step_mem) { /* access ARKodeMem structure */ if (arkode_mem == NULL) @@ -91,8 +91,8 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) /* assume fixed outer step size */ if (!ark_mem->fixedstep) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, - __FILE__, "Adaptive outer time stepping is not currently supported"); + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Adaptive outer time stepping is not currently supported"); return ARK_ILL_INPUT; } @@ -130,8 +130,8 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) resets at the next ARKodeEvolve call. ----------------------------------------------------------------------------*/ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, - const N_Vector y, const N_Vector f, - SUNDIALS_MAYBE_UNUSED const int mode) + const N_Vector y, const N_Vector f, + SUNDIALS_MAYBE_UNUSED const int mode) { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -147,7 +147,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, } const SUNStepper s1 = step_mem->stepper[1]; - retval = s1->ops->fullrhs(s1, t, y, f, ARK_FULLRHS_OTHER); + retval = s1->ops->fullrhs(s1, t, y, f, ARK_FULLRHS_OTHER); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -172,10 +172,10 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ - const SUNStepper s0 = step_mem->stepper[0]; + const SUNStepper s0 = step_mem->stepper[0]; const sunrealtype tout = ark_mem->tn + ark_mem->h; - sunrealtype tret = 0; - int stop_reason = 0; + sunrealtype tret = 0; + int stop_reason = 0; /* Evolve stepper 0 on its own */ SUNErrCode err = SUNStepper_Reset(s0, ark_mem->tn, ark_mem->yn); @@ -184,7 +184,8 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, if (err != SUN_SUCCESS) { return err; } err = SUNStepper_SetStopTime(s0, tout); if (err != SUN_SUCCESS) { return err; } - err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret, + &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } step_mem->n_stepper_evolves[0]++; @@ -194,7 +195,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, * changes or a resize is performed, the stepper and outer forcing method * could become out of sync. */ const SUNStepper s1 = step_mem->stepper[1]; - err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); + err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); if (err != SUN_SUCCESS) { return err; } err = SUNStepper_SetStepDirection(s1, ark_mem->h); if (err != SUN_SUCCESS) { return err; } @@ -206,7 +207,8 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s1->forcing[0]); /* Evolve stepper 1 with the forcing */ - err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); + err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, + &stop_reason); if (err != SUN_SUCCESS) { return err; } if (stop_reason < 0) { return stop_reason; } step_mem->n_stepper_evolves[1]++; @@ -217,9 +219,8 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, /*--------------------------------------------------------------- Prints integrator statistics ---------------------------------------------------------------*/ -static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, - FILE* const outfile, - const SUNOutputFormat fmt) +static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfile, + const SUNOutputFormat fmt) { // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeForcingStepMem step_mem = NULL; @@ -229,14 +230,17 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - for (int k = 0; k < PARTITIONS; k++) { - fprintf(outfile, "Partition %i evolves = %ld\n", - k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < PARTITIONS; k++) + { + fprintf(outfile, "Partition %i evolves = %ld\n", k, + step_mem->n_stepper_evolves[k]); } break; case SUN_OUTPUTFORMAT_CSV: - for (int k = 0; k < PARTITIONS; k++) { - fprintf(outfile, "Partition %i evolves,%ld\n", k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < PARTITIONS; k++) + { + fprintf(outfile, "Partition %i evolves,%ld\n", k, + step_mem->n_stepper_evolves[k]); } break; default: @@ -268,8 +272,10 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) if (retval != ARK_SUCCESS) { return; } /* output long integer quantities */ - for (int k = 0; k < 2; k++) { - fprintf(outfile, "ForcingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < 2; k++) + { + fprintf(outfile, "ForcingStep: partition %i: n_stepper_evolves = %li\n", k, + step_mem->n_stepper_evolves[k]); } } @@ -288,10 +294,8 @@ static int forcingStep_SetDefaults(const ARKodeMem ark_mem) /*--------------------------------------------------------------- Creates the ForcingStep integrator ---------------------------------------------------------------*/ -void* ForcingStepCreate(SUNStepper stepper1, - SUNStepper stepper2, - sunrealtype t0, N_Vector y0, - SUNContext sunctx) +void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, + sunrealtype t0, N_Vector y0, SUNContext sunctx) { if (stepper1 == NULL) { @@ -348,20 +352,20 @@ void* ForcingStepCreate(SUNStepper stepper1, return NULL; } - step_mem->stepper[0] = stepper1; - step_mem->stepper[1] = stepper2; + step_mem->stepper[0] = stepper1; + step_mem->stepper[1] = stepper2; step_mem->n_stepper_evolves[0] = 0; step_mem->n_stepper_evolves[1] = 0; /* Attach step_mem structure and function pointers to ark_mem */ - ark_mem->step_init = forcingStep_Init; - ark_mem->step_fullrhs = forcingStep_FullRHS; - ark_mem->step = forcingStep_TakeStep; - ark_mem->step_printallstats = forcingStep_PrintAllStats; - ark_mem->step_free = forcingStep_Free; - ark_mem->step_printmem = forcingStep_PrintMem; - ark_mem->step_setdefaults = forcingStep_SetDefaults; - ark_mem->step_mem = (void*)step_mem; + ark_mem->step_init = forcingStep_Init; + ark_mem->step_fullrhs = forcingStep_FullRHS; + ark_mem->step = forcingStep_TakeStep; + ark_mem->step_printallstats = forcingStep_PrintAllStats; + ark_mem->step_free = forcingStep_Free; + ark_mem->step_printmem = forcingStep_PrintMem; + ark_mem->step_setdefaults = forcingStep_SetDefaults; + ark_mem->step_mem = (void*)step_mem; /* Set default values for ARKStep optional inputs */ int retval = forcingStep_SetDefaults(ark_mem); @@ -386,24 +390,27 @@ void* ForcingStepCreate(SUNStepper stepper1, return ark_mem; } -int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int *evolves) { - ARKodeMem ark_mem = NULL; +int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves) +{ + ARKodeMem ark_mem = NULL; ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, - &step_mem); + &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - if (partition >= PARTITIONS) { + if (partition >= PARTITIONS) + { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "The partition index is %i but there are only 2 partitions", partition); + "The partition index is %i but there are only 2 partitions", + partition); return ARK_ILL_INPUT; } - if (partition < 0) { + if (partition < 0) + { *evolves = step_mem->n_stepper_evolves[0] + step_mem->n_stepper_evolves[1]; - } else { - *evolves = step_mem->n_stepper_evolves[partition]; } + else { *evolves = step_mem->n_stepper_evolves[partition]; } return ARK_SUCCESS; } diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index d932c35cb5..3c84163d46 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1304,17 +1304,13 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) } ark_mem = (ARKodeMem)arkode_mem; - if (stepdir == ZERO) { - return ARK_SUCCESS; - } + if (stepdir == ZERO) { return ARK_SUCCESS; } h = ark_mem->h == ZERO ? ark_mem->hin : ark_mem->h; // TODO(SBR): use SUNRcopysign once merged from other PR // if (SUNRcopysign(h, stepdir) == h) { - if (h == ZERO || ((h > 0) == (stepdir > 0))) { - return ARK_SUCCESS; - } + if (h == ZERO || ((h > 0) == (stepdir > 0))) { return ARK_SUCCESS; } /* Reverse the sign of h. If adaptive, h will be overwritten anyway by the * initial step estimation since ARKodeReset must be called before this. @@ -1331,7 +1327,7 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) /* Reset error controller (e.g., error and step size history) */ retval = SUNAdaptController_Reset(ark_mem->hadapt_mem->hcontroller); if (retval != SUN_SUCCESS) { return (ARK_CONTROLLER_ERR); } - + return ARK_SUCCESS; } @@ -2147,7 +2143,7 @@ int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur) on the sign of stepdir. A value of 0 indicates integration can procede in either direction. ---------------------------------------------------------------*/ -int ARKodeGetStepDirection(void *arkode_mem, sunrealtype *stepdir) +int ARKodeGetStepDirection(void* arkode_mem, sunrealtype* stepdir) { ARKodeMem ark_mem; if (arkode_mem == NULL) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 7490c1dabd..ecb68f68e9 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -148,8 +148,8 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) /* TODO(SBR): Should this validation be done by ARKODE? */ if (!ark_mem->fixedstep) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, - __FILE__, "Adaptive outer time stepping is not currently supported"); + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "Adaptive outer time stepping is not currently supported"); return ARK_ILL_INPUT; } @@ -171,7 +171,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) step_mem->own_policy = SUNTRUE; } - ark_mem->interp_degree = + ark_mem->interp_degree = SUNMAX(1, SUNMIN(step_mem->coefficients->order - 1, ark_mem->interp_degree)); return ARK_SUCCESS; @@ -247,18 +247,18 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, - "ARKODE::splittingStep_SequentialMethod", "start-sequential-method", - "step = %li, sequential method = %i", - ark_mem->nst, i); + "ARKODE::splittingStep_SequentialMethod", + "start-sequential-method", + "step = %li, sequential method = %i", ark_mem->nst, i); #endif for (int j = 0; j < coefficients->stages; j++) { #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, - "ARKODE::splittingStep_SequentialMethod", "start-stage", - "step = %li, sequential method = %i, stage = %i", - ark_mem->nst, i, j); + "ARKODE::splittingStep_SequentialMethod", "start-stage", + "step = %li, sequential method = %i, stage = %i", + ark_mem->nst, i, j); #endif for (int k = 0; k < coefficients->partitions; k++) { @@ -269,9 +269,11 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, - "ARKODE::splittingStep_SequentialMethod", "start-inner-evolve", - "step = %li, sequential method = %i, stage = %i, partition = %i, t0 = %" RSYM ", tout = %" RSYM, - ark_mem->nst, i, j, k, t_start, t_end); + "ARKODE::splittingStep_SequentialMethod", + "start-inner-evolve", + "step = %li, sequential method = %i, stage = %i, " + "partition = %i, t0 = %" RSYM ", tout = %" RSYM, + ark_mem->nst, i, j, k, t_start, t_end); #endif if (t_start == t_end) { continue; } @@ -336,14 +338,17 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - for (int k = 0; k < step_mem->partitions; k++) { - fprintf(outfile, "Partition %i evolves = %ld\n", - k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < step_mem->partitions; k++) + { + fprintf(outfile, "Partition %i evolves = %ld\n", k, + step_mem->n_stepper_evolves[k]); } break; case SUN_OUTPUTFORMAT_CSV: - for (int k = 0; k < step_mem->partitions; k++) { - fprintf(outfile, "Partition %i evolves,%ld\n", k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < step_mem->partitions; k++) + { + fprintf(outfile, "Partition %i evolves,%ld\n", k, + step_mem->n_stepper_evolves[k]); } break; default: @@ -375,8 +380,10 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp ---------------------------------------------------------------*/ static void splittingStep_Free(const ARKodeMem ark_mem) { - const ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; - if (step_mem != NULL) { + const ARKodeSplittingStepMem step_mem = + (ARKodeSplittingStepMem)ark_mem->step_mem; + if (step_mem != NULL) + { free(step_mem->steppers); free(step_mem->n_stepper_evolves); if (step_mem->own_policy) @@ -405,8 +412,10 @@ static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) fprintf(outfile, "SplittingStep: order = %i\n", step_mem->order); /* output long integer quantities */ - for (int k = 0; k < step_mem->partitions; k++) { - fprintf(outfile, "SplittingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); + for (int k = 0; k < step_mem->partitions; k++) + { + fprintf(outfile, "SplittingStep: partition %i: n_stepper_evolves = %li\n", + k, step_mem->n_stepper_evolves[k]); } /* output sunrealtype quantities */ @@ -533,16 +542,18 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, step_mem->coefficients = NULL; step_mem->policy = NULL; - step_mem->n_stepper_evolves = calloc(partitions, sizeof(*step_mem->n_stepper_evolves)); - if (step_mem->n_stepper_evolves == NULL) { + step_mem->n_stepper_evolves = calloc(partitions, + sizeof(*step_mem->n_stepper_evolves)); + if (step_mem->n_stepper_evolves == NULL) + { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_ARKMEM_FAIL); ARKodeFree((void**)&ark_mem); return NULL; } - step_mem->partitions = partitions; - step_mem->order = 0; - step_mem->own_policy = SUNFALSE; + step_mem->partitions = partitions; + step_mem->order = 0; + step_mem->own_policy = SUNFALSE; /* Attach step_mem structure and function pointers to ark_mem */ ark_mem->step_init = splittingStep_Init; @@ -647,27 +658,32 @@ int SplittingStep_SetExecutionPolicy(void* const arkode_mem, return ARK_SUCCESS; } -int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, long int * const evolves) { +int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, + long int* const evolves) +{ ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - if (partition >= step_mem->partitions) { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "The partition index is %i but there are only %i partitions", partition, step_mem->partitions); + if (partition >= step_mem->partitions) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, + __FILE__, "The partition index is %i but there are only %i partitions", + partition, step_mem->partitions); return ARK_ILL_INPUT; } - if (partition < 0) { + if (partition < 0) + { *evolves = 0; - for (int k = 0; k < step_mem->partitions; k++) { + for (int k = 0; k < step_mem->partitions; k++) + { *evolves += step_mem->n_stepper_evolves[k]; } - } else { - *evolves = step_mem->n_stepper_evolves[partition]; } + else { *evolves = step_mem->n_stepper_evolves[partition]; } return ARK_SUCCESS; } diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index 721ccce204..1900978ece 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -24,7 +24,7 @@ typedef struct ARKodeSplittingStepMemRec SUNStepper* steppers; SplittingStepCoefficients coefficients; ARKodeSplittingExecutionPolicy policy; - long int *n_stepper_evolves; + long int* n_stepper_evolves; int partitions; int order; diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 95d4918092..ca83d36bd9 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -32,12 +32,12 @@ SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper_ptr) stepper->ops = malloc(sizeof(*(stepper->ops))); SUNAssert(stepper->ops, SUN_ERR_MALLOC_FAIL); - stepper->ops->evolve = NULL; - stepper->ops->onestep = NULL; - stepper->ops->trystep = NULL; - stepper->ops->fullrhs = NULL; - stepper->ops->reset = NULL; - stepper->ops->setstoptime = NULL; + stepper->ops->evolve = NULL; + stepper->ops->onestep = NULL; + stepper->ops->trystep = NULL; + stepper->ops->fullrhs = NULL; + stepper->ops->reset = NULL; + stepper->ops->setstoptime = NULL; stepper->ops->setstepdirection = NULL; *stepper_ptr = stepper; @@ -164,14 +164,16 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn return SUN_SUCCESS; } -SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) +SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, + SUNStepperSetStepDirectionFn fn) { SUNFunctionBegin(stepper->sunctx); stepper->ops->setstepdirection = fn; return SUN_SUCCESS; } -SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, SUNStepperGetStepDirectionFn fn) +SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, + SUNStepperGetStepDirectionFn fn) { SUNFunctionBegin(stepper->sunctx); stepper->ops->getstepdirection = fn; diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 0e2cecb1dd..0594d47dc8 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -15,15 +15,15 @@ * SplittingStep module. * ---------------------------------------------------------------------------*/ -#include #include #include #include +#include #include +#include #include #include -#include /* Integrates the ODE * @@ -33,28 +33,33 @@ * ERK method. Using the exact solution y(t) = exp(-t), we confirm the numerical * solution is sufficiently accurate. */ -static int test_forward(sundials::Context &ctx, const int partitions) { - constexpr auto t0 = SUN_RCONST(0.0); - constexpr auto tf = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(8.0e-3); - constexpr auto local_tol = SUN_RCONST(1.0e-6); +static int test_forward(sundials::Context& ctx, const int partitions) +{ + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto tf = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(8.0e-3); + constexpr auto local_tol = SUN_RCONST(1.0e-6); constexpr auto global_tol = 10 * local_tol; - const auto y = N_VNew_Serial(1, ctx); + const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - const ARKRhsFn f = [](const sunrealtype, const N_Vector z, const N_Vector zdot, void *const user_data) { + const ARKRhsFn f = [](const sunrealtype, const N_Vector z, + const N_Vector zdot, void* const user_data) + { const auto lambda = *static_cast(user_data); N_VScale(lambda, z, zdot); return 0; }; - std::vector partition_mem(partitions); + std::vector partition_mem(partitions); std::vector lambda(partitions); std::vector steppers(partitions); - for (int i = 0; i < partitions; i++) { + for (int i = 0; i < partitions; i++) + { partition_mem[i] = ARKStepCreate(f, nullptr, t0, y, ctx); /* The lambdas sum up to 1 */ - lambda[i] = std::pow(SUN_RCONST(2.0), i) / (1 - std::pow(SUN_RCONST(2.0), partitions)); + lambda[i] = std::pow(SUN_RCONST(2.0), i) / + (1 - std::pow(SUN_RCONST(2.0), partitions)); ARKodeSetUserData(partition_mem[i], &lambda[i]); ARKodeSStolerances(partition_mem[i], local_tol, local_tol); ARKStepCreateSUNStepper(partition_mem[i], &steppers[i]); @@ -67,16 +72,19 @@ static int test_forward(sundials::Context &ctx, const int partitions) { ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); /* Check that the solution matches the exact solution */ - const auto exact_solution = std::exp(t0 - tf); + const auto exact_solution = std::exp(t0 - tf); const auto numerical_solution = NV_Ith_S(y, 0); - if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { + if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) + { const auto err = numerical_solution - exact_solution; - std::cerr << "Forward solution with " << partitions << " partitions failed with an error of" << err << "\n"; + std::cerr << "Forward solution with " << partitions + << " partitions failed with an error of" << err << "\n"; return 1; } N_VDestroy(y); - for (int i = 0; i global_tol) { - std::cerr << "Mixed direction solution failed with an error of " << max_err << "\n"; + if (max_err > global_tol) + { + std::cerr << "Mixed direction solution failed with an error of " << max_err + << "\n"; return 1; } @@ -185,35 +199,38 @@ static int test_mixed_directions(const sundials::Context &ctx) { * Then we integrate to t = 1 and check the error against the exact solution * y(1) = [exp(-0.5), exp(-1)]. */ -static int test_resize(const sundials::Context &ctx) { - constexpr auto t0 = SUN_RCONST(0.0); - constexpr auto t1 = SUN_RCONST(0.5); - constexpr auto t2 = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(8.0e-3); - constexpr auto local_tol = SUN_RCONST(1.0e-5); +static int test_resize(const sundials::Context& ctx) +{ + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto t1 = SUN_RCONST(0.5); + constexpr auto t2 = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(8.0e-3); + constexpr auto local_tol = SUN_RCONST(1.0e-5); constexpr auto global_tol = local_tol; - const auto y = N_VNew_Serial(1, ctx); + const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - const ARKRhsFn f1 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void *const) { + const ARKRhsFn f1 = + [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + { N_VProd(z, z, zdot); return 0; }; - const ARKRhsFn f2 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void *const) { + const ARKRhsFn f2 = + [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + { N_VConst(-SUN_RCONST(1.0), zdot); N_VLinearSum(SUN_RCONST(1.0), zdot, -SUN_RCONST(1.0), z, zdot); N_VProd(zdot, z, zdot); return 0; }; - void* parititon_mem[] = { - ARKStepCreate(f1, nullptr, t0, y, ctx), - ARKStepCreate(f2, nullptr, t0, y, ctx) - }; + void* parititon_mem[] = {ARKStepCreate(f1, nullptr, t0, y, ctx), + ARKStepCreate(f2, nullptr, t0, y, ctx)}; ARKodeSStolerances(parititon_mem[0], local_tol, local_tol); ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); - + SUNStepper steppers[] = {nullptr, nullptr}; ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); @@ -229,7 +246,7 @@ static int test_resize(const sundials::Context &ctx) { ARKodeEvolve(arkode_mem, t1, y, &tret, ARK_NORMAL); /* Resize */ - const auto y_new = N_VNew_Serial(2, ctx); + const auto y_new = N_VNew_Serial(2, ctx); NV_Ith_S(y_new, 0) = SUN_RCONST(1.0); NV_Ith_S(y_new, 1) = NV_Ith_S(y, 0); N_VDestroy(y); @@ -240,13 +257,14 @@ static int test_resize(const sundials::Context &ctx) { /* Integrate from 0.5 to 1 */ ARKodeEvolve(arkode_mem, t2, y_new, &tret, ARK_NORMAL); - const auto err = N_VClone(y_new); + const auto err = N_VClone(y_new); NV_Ith_S(err, 0) = std::exp(t1 - t2); NV_Ith_S(err, 1) = std::exp(t0 - t2); N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y_new, err); const auto max_err = N_VMaxNorm(err); - if (max_err > global_tol) { + if (max_err > global_tol) + { std::cerr << "Resized solution failed with an error of " << max_err << "\n"; return 1; } @@ -263,29 +281,32 @@ static int test_resize(const sundials::Context &ctx) { } /* Creates a custom SUNStepper for the linear, scalar ODE y' = lambda*y */ -static SUNStepper create_exp_stepper(const sundials::Context &ctx, const sunrealtype &lambda) { +static SUNStepper create_exp_stepper(const sundials::Context& ctx, + const sunrealtype& lambda) +{ SUNStepper stepper = nullptr; SUNStepper_Create(ctx, &stepper); - const auto empty_func = [](auto... args) { - return 0; - }; + const auto empty_func = [](auto... args) { return 0; }; SUNStepper_SetResetFn(stepper, empty_func); SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetSetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); - SUNStepper_SetEvolveFn(stepper, [](const SUNStepper s, const sunrealtype t0, - const sunrealtype tout, const N_Vector y, - sunrealtype* const tret, int* const stop_reason) { - void *content = nullptr; - SUNStepper_GetContent(s, &content); - const auto lam = *static_cast(content); - N_VScale(std::exp(lam * (tout - t0)), y, y); - *tret = tout; - *stop_reason = 0; - return 0; - }); - SUNStepper_SetContent(stepper, static_cast(const_cast(&lambda))); + SUNStepper_SetEvolveFn(stepper, + [](const SUNStepper s, const sunrealtype t0, + const sunrealtype tout, const N_Vector y, + sunrealtype* const tret, int* const stop_reason) + { + void* content = nullptr; + SUNStepper_GetContent(s, &content); + const auto lam = *static_cast(content); + N_VScale(std::exp(lam * (tout - t0)), y, y); + *tret = tout; + *stop_reason = 0; + return 0; + }); + SUNStepper_SetContent(stepper, + static_cast(const_cast(&lambda))); return stepper; } @@ -297,19 +318,18 @@ static SUNStepper create_exp_stepper(const sundials::Context &ctx, const sunreal * exact, custom SUNSteppers for the two partitions. We integrate to t = 1 and * compare the numerical solution to the exact solution y(t) = exp(-t). */ -static int test_custom_stepper(const sundials::Context &ctx) { +static int test_custom_stepper(const sundials::Context& ctx) +{ constexpr auto lambda1 = SUN_RCONST(-0.6); constexpr auto lambda2 = SUN_RCONST(-0.4); - constexpr auto t0 = SUN_RCONST(0.0); - constexpr auto tf = SUN_RCONST(1.0); - constexpr auto dt = SUN_RCONST(0.1); - const auto y = N_VNew_Serial(1, ctx); + constexpr auto t0 = SUN_RCONST(0.0); + constexpr auto tf = SUN_RCONST(1.0); + constexpr auto dt = SUN_RCONST(0.1); + const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - SUNStepper steppers[] = { - create_exp_stepper(ctx, lambda1), - create_exp_stepper(ctx, lambda2) - }; + SUNStepper steppers[] = {create_exp_stepper(ctx, lambda1), + create_exp_stepper(ctx, lambda2)}; auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); @@ -321,9 +341,10 @@ static int test_custom_stepper(const sundials::Context &ctx) { ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); /* Check that the solution matches the exact solution */ - const auto exact_solution = std::exp(t0 - tf); + const auto exact_solution = std::exp(t0 - tf); const auto numerical_solution = NV_Ith_S(y, 0); - if (SUNRCompare(exact_solution, numerical_solution)) { + if (SUNRCompare(exact_solution, numerical_solution)) + { const auto err = numerical_solution - exact_solution; std::cerr << "Custom SUNStepper failed with an error of" << err << "\n"; return 1; @@ -337,15 +358,17 @@ static int test_custom_stepper(const sundials::Context &ctx) { } /* Error handling function which prints the error and exits the program */ -static void err_fn(const int line, const char* const func, const char* const file, - const char* const msg, const SUNErrCode err_code, - void* const, const SUNContext) +static void err_fn(const int line, const char* const func, + const char* const file, const char* const msg, + const SUNErrCode err_code, void* const, const SUNContext) { - std::cerr << "Error at line " << line << " of " << func << " in " << file << ": " << msg << "\n"; + std::cerr << "Error at line " << line << " of " << func << " in " << file + << ": " << msg << "\n"; exit(err_code); } -int main() { +int main() +{ sundials::Context ctx; SUNContext_PushErrHandler(ctx, err_fn, nullptr); @@ -354,7 +377,8 @@ int main() { /* Run the tests */ constexpr auto min_partitions = 2; constexpr auto max_partitions = 7; - for (auto p = min_partitions; p <= max_partitions; p++) { + for (auto p = min_partitions; p <= max_partitions; p++) + { errors += test_forward(ctx, p); } @@ -362,11 +386,8 @@ int main() { errors += test_resize(ctx); errors += test_custom_stepper(ctx); - if (errors == 0) { - std::cout << "Success\n"; - } else { - std::cout << errors << " Test Failures\n"; - } - + if (errors == 0) { std::cout << "Success\n"; } + else { std::cout << errors << " Test Failures\n"; } + return errors; } diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index c804566101..654364d601 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -26,14 +26,18 @@ #endif /* RHS function for f_1(t, y) = t / y */ -static int f_forward_1(const sunrealtype t, const N_Vector y, const N_Vector ydot, void *const user_data) { +static int f_forward_1(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) +{ N_VInv(y, ydot); N_VScale(t, ydot, ydot); return 0; } /* RHS function for f_2(t, y) = 1 / y */ -static int f_forward_2(const sunrealtype t, const N_Vector y, const N_Vector ydot, void *const user_data) { +static int f_forward_2(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) +{ N_VInv(y, ydot); return 0; } @@ -46,39 +50,41 @@ static int f_forward_2(const sunrealtype t, const N_Vector y, const N_Vector ydo * brackets. We integrate to t = 1 and check the error against the exact * solution y(t) = |t + 1|. */ -static int test_forward(SUNContext ctx) { - const sunrealtype t0 = SUN_RCONST(0.0); - const sunrealtype tf = SUN_RCONST(1.0); - const sunrealtype dt = SUN_RCONST(1.0e-4); - const sunrealtype local_tol = SUN_RCONST(1.0e-6); +static int test_forward(SUNContext ctx) +{ + const sunrealtype t0 = SUN_RCONST(0.0); + const sunrealtype tf = SUN_RCONST(1.0); + const sunrealtype dt = SUN_RCONST(1.0e-4); + const sunrealtype local_tol = SUN_RCONST(1.0e-6); const sunrealtype global_tol = 10 * local_tol; const N_Vector y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - void* parititon_mem[] = { - ARKStepCreate(f_forward_1, NULL, t0, y, ctx), - ARKStepCreate(f_forward_2, NULL, t0, y, ctx) - }; + void* parititon_mem[] = {ARKStepCreate(f_forward_1, NULL, t0, y, ctx), + ARKStepCreate(f_forward_2, NULL, t0, y, ctx)}; ARKodeSStolerances(parititon_mem[0], local_tol, local_tol); ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); - + SUNStepper steppers[] = {NULL, NULL}; ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); - void *arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); + void* arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); ARKodeSetMaxNumSteps(arkode_mem, -1); sunrealtype tret = t0; ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); - const sunrealtype exact_solution = SUN_RCONST(2.0); + const sunrealtype exact_solution = SUN_RCONST(2.0); const sunrealtype numerical_solution = NV_Ith_S(y, 0); - if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { + if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) + { const sunrealtype err = numerical_solution - exact_solution; - fprintf(stderr, "Forward direction solution failed with an error of %" GSYM "\n", err); + fprintf(stderr, + "Forward direction solution failed with an error of %" GSYM "\n", + err); return 1; } @@ -101,16 +107,19 @@ static void err_fn(const int line, const char* const func, const char* const fil exit(err_code); } -int main() { +int main() +{ SUNContext ctx = NULL; SUNErrCode err = SUNContext_Create(SUN_COMM_NULL, &ctx); - if (err != SUN_SUCCESS) { + if (err != SUN_SUCCESS) + { fprintf(stderr, "Failed to create the SUNContext\n"); return 1; } err = SUNContext_PushErrHandler(ctx, err_fn, NULL); - if (err != SUN_SUCCESS) { + if (err != SUN_SUCCESS) + { fprintf(stderr, "Failed to add error handler\n"); return 1; } @@ -119,11 +128,8 @@ int main() { SUNContext_Free(&ctx); - if (err == 0) { - printf("Success\n"); - } else { - printf("%d Test Failures\n", err); - } + if (err == 0) { printf("Success\n"); } + else { printf("%d Test Failures\n", err); } return 0; } \ No newline at end of file From 59bf685c8a711717d17d5e58428a0772af009116 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 17:25:02 -0700 Subject: [PATCH 064/180] Add splittingstep test output file --- .../CXX_serial/ark_test_splittingstep.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 0594d47dc8..f9e22e1b6c 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -74,6 +74,7 @@ static int test_forward(sundials::Context& ctx, const int partitions) /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); const auto numerical_solution = NV_Ith_S(y, 0); + if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { const auto err = numerical_solution - exact_solution; @@ -81,6 +82,13 @@ static int test_forward(sundials::Context& ctx, const int partitions) << " partitions failed with an error of" << err << "\n"; return 1; } + else + { + std::cout << "Forward solution with " << partitions + << " partitions passed with these stats:\n"; + ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + std::cout << "\n"; + } N_VDestroy(y); for (int i = 0; i < partitions; i++) @@ -174,6 +182,12 @@ static int test_mixed_directions(const sundials::Context& ctx) << "\n"; return 1; } + else + { + std::cout << "Mixed direction solution passed with these stats:\n"; + ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + std::cout << "\n"; + } N_VDestroy(y); N_VDestroy(err); @@ -268,6 +282,12 @@ static int test_resize(const sundials::Context& ctx) std::cerr << "Resized solution failed with an error of " << max_err << "\n"; return 1; } + else + { + std::cout << "Resized solution passed with these stats:\n"; + ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + std::cout << "\n"; + } N_VDestroy(y_new); N_VDestroy(err); @@ -349,6 +369,12 @@ static int test_custom_stepper(const sundials::Context& ctx) std::cerr << "Custom SUNStepper failed with an error of" << err << "\n"; return 1; } + else + { + std::cout << "Custom SUNStepper passed with these stats:\n"; + ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + std::cout << "\n"; + } N_VDestroy(y); SUNStepper_Destroy(&steppers[0]); From 4990a3bb9f6e64506f01c14cb02c26d4479f8c1a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 17:26:32 -0700 Subject: [PATCH 065/180] Add splittingstep test output file --- .../CXX_serial/ark_test_splittingstep.out | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.out diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.out b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.out new file mode 100644 index 0000000000..388df87020 --- /dev/null +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.out @@ -0,0 +1,151 @@ +Forward solution with 2 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 375 + +Forward solution with 3 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 625 +Partition 2 evolves = 375 + +Forward solution with 4 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 625 +Partition 2 evolves = 625 +Partition 3 evolves = 375 + +Forward solution with 5 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 625 +Partition 2 evolves = 625 +Partition 3 evolves = 625 +Partition 4 evolves = 375 + +Forward solution with 6 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 625 +Partition 2 evolves = 625 +Partition 3 evolves = 625 +Partition 4 evolves = 625 +Partition 5 evolves = 375 + +Forward solution with 7 partitions passed with these stats: +Current time = 1.000000000000001 +Steps = 125 +Step attempts = 125 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 375 +Partition 1 evolves = 625 +Partition 2 evolves = 625 +Partition 3 evolves = 625 +Partition 4 evolves = 625 +Partition 5 evolves = 625 +Partition 6 evolves = 375 + +Mixed direction solution passed with these stats: +Current time = -0.0009800000000017288 +Steps = 2279 +Step attempts = 2279 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = -0.00123 +Last step size = -0.00123 +Current step size = -0.00123 +Partition 0 evolves = 6837 +Partition 1 evolves = 6837 + +Resized solution passed with these stats: +Current time = 1.004 +Steps = 126 +Step attempts = 126 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.008 +Last step size = 0.008 +Current step size = 0.008 +Partition 0 evolves = 252 +Partition 1 evolves = 252 + +Custom SUNStepper passed with these stats: +Current time = 1.1 +Steps = 11 +Step attempts = 11 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.1 +Last step size = 0.1 +Current step size = 0.1 +Partition 0 evolves = 286 +Partition 1 evolves = 275 + +Success From d5f366990ab48bf3cc54fab762a67232c9d98971 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 19:43:58 -0700 Subject: [PATCH 066/180] Add missing getter --- src/sundials/sundials_stepper.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index ca83d36bd9..d3232195b0 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -264,12 +264,22 @@ SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop) else { return SUN_ERR_NOT_IMPLEMENTED; } } -SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype dir) +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) { SUNFunctionBegin(stepper->sunctx); if (stepper->ops->setstepdirection) { - return stepper->ops->setstepdirection(stepper, dir); + return stepper->ops->setstepdirection(stepper, stepdir); + } + else { return SUN_ERR_NOT_IMPLEMENTED; } +} + +SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype *stepdir) +{ + SUNFunctionBegin(stepper->sunctx); + if (stepper->ops->setstepdirection) + { + return stepper->ops->getstepdirection(stepper, stepdir); } else { return SUN_ERR_NOT_IMPLEMENTED; } } From dbf86d4fe08fceb788678cda7a1111a356b87c7d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 19:44:34 -0700 Subject: [PATCH 067/180] Improve skipping of evolves --- src/arkode/arkode_splittingstep.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index ecb68f68e9..1e50f1dea9 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -262,10 +262,13 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, #endif for (int k = 0; k < coefficients->partitions; k++) { - const sunrealtype t_start = ark_mem->tn + - coefficients->beta[i][j][k] * ark_mem->h; - const sunrealtype t_end = ark_mem->tn + - coefficients->beta[i][j + 1][k] * ark_mem->h; + const sunrealtype beta_start = coefficients->beta[i][j][k]; + const sunrealtype beta_end = coefficients->beta[i][j + 1][k]; + + if (beta_start == beta_end) { continue; } + + const sunrealtype t_start = ark_mem->tn + beta_start * ark_mem->h; + const sunrealtype t_end = ark_mem->tn + beta_end * ark_mem->h; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, @@ -276,8 +279,6 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, ark_mem->nst, i, j, k, t_start, t_end); #endif - if (t_start == t_end) { continue; } - const SUNStepper stepper = step_mem->steppers[k]; SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return err; } From 5a5b5b25aaaa9b35b1ff5654143724088335495b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 19:56:28 -0700 Subject: [PATCH 068/180] Fix step direction for fixed step --- src/arkode/arkode_io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index f62e791eeb..a04d9b0b0e 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1312,7 +1312,8 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) if (stepdir == ZERO) { return ARK_SUCCESS; } - h = ark_mem->h == ZERO ? ark_mem->hin : ark_mem->h; + retval = ARKodeGetStepDirection(arkode_mem, &h); + if (retval != SUN_SUCCESS) { return retval; } // TODO(SBR): use SUNRcopysign once merged from other PR // if (SUNRcopysign(h, stepdir) == h) { @@ -2168,7 +2169,7 @@ int ARKodeGetStepDirection(void* arkode_mem, sunrealtype* stepdir) } ark_mem = (ARKodeMem)arkode_mem; - *stepdir = ark_mem->h == ZERO ? ark_mem->hin : ark_mem->h; + *stepdir = (ark_mem->fixedstep || ark_mem->h == ZERO) ? ark_mem->hin : ark_mem->h; return (ARK_SUCCESS); } From 00c518d295419dec5f5850d5a84b607bc500cdee Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 19:59:06 -0700 Subject: [PATCH 069/180] Add example output files --- ...advection_diffusion_reaction_splitting.out | 112 ++++++++++++++++++ .../ark_analytic_partitioned_forcing.out | 20 ++++ .../ark_analytic_partitioned_splitting.out | 20 ++++ ..._splitting_ARKODE_SPLITTING_BEST_2_2_2.out | 21 ++++ ..._splitting_ARKODE_SPLITTING_RUTH_3_3_2.out | 21 ++++ ...litting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out | 21 ++++ 6 files changed, 215 insertions(+) create mode 100644 examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out create mode 100644 examples/arkode/C_serial/ark_analytic_partitioned_forcing.out create mode 100644 examples/arkode/C_serial/ark_analytic_partitioned_splitting.out create mode 100644 examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out create mode 100644 examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out create mode 100644 examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out new file mode 100644 index 0000000000..c214a6deab --- /dev/null +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out @@ -0,0 +1,112 @@ + +1D Advection-Diffusion-Reaction PDE test problem: + N = 128 + advection coefficient = 1 + diffusion coefficient = 0.125 + reaction coefficient = 4 + + t ||u||_rms + ---------------------- + 0.000000 0.100000 + 0.060000 0.126734 + 0.120000 0.154228 + 0.180000 0.185715 + 0.240000 0.221941 + 0.300000 0.263180 + 0.360000 0.309219 + 0.420000 0.359242 + 0.480000 0.411734 + 0.540000 0.464560 + 0.600000 0.515252 + 0.660000 0.561484 + 0.720000 0.601560 + 0.780000 0.634693 + 0.840000 0.660980 + 0.900000 0.681152 + 0.960000 0.696244 + 1.000000 0.702992 + ---------------------- + +Splitting Stepper Statistics: +Current time = 1 +Steps = 17 +Step attempts = 17 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.06 +Last step size = 0.03999999999999956 +Current step size = 0.06 +Partition 0 evolves = 17 +Partition 1 evolves = 17 +Partition 2 evolves = 17 + +Advection Stepper Statistics: +Current time = 1 +Steps = 53 +Step attempts = 54 +Stability limited steps = 0 +Accuracy limited steps = 54 +Error test fails = 1 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 2.059355438929501e-06 +Last step size = 0.008743161639560786 +Current step size = 0.008743161639560786 +Explicit RHS fn evals = 163 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Diffusion Stepper Statistics: +Current time = 1 +Steps = 246 +Step attempts = 302 +Stability limited steps = 0 +Accuracy limited steps = 302 +Error test fails = 56 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 2.059355438929501e-06 +Last step size = 0.004572821688115565 +Current step size = 0.004572821688115565 +Explicit RHS fn evals = 0 +Implicit RHS fn evals = 1831 +NLS iters = 906 +NLS fails = 0 +NLS iters per step = 3.682926829268293 +LS setups = 213 +Jac fn evals = 73 +LS RHS fn evals = 0 +Prec setup evals = 0 +Prec solves = 0 +LS iters = 0 +LS fails = 0 +Jac-times setups = 0 +Jac-times evals = 0 +LS iters per NLS iter = 0 +Jac evals per NLS iter = 0.08057395143487858 +Prec evals per NLS iter = 0 + +Reaction Stepper Statistics: +Current time = 1 +Steps = 38 +Step attempts = 38 +Stability limited steps = 0 +Accuracy limited steps = 38 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.00180442856879795 +Last step size = 0.03999999999999956 +Current step size = 0.03999999999999956 +Explicit RHS fn evals = 133 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out new file mode 100644 index 0000000000..8360493c92 --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out @@ -0,0 +1,20 @@ + +Analytical ODE test problem: + integrator = forcing method + lambda = 2 + +Error: 0.00185186 +Final Solver Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 100 +Partition 1 evolves = 100 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out new file mode 100644 index 0000000000..deb36c804b --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out @@ -0,0 +1,20 @@ + +Analytical ODE test problem: + integrator = splitting method + lambda = 2 + +Error: 0.001796 +Final Solver Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 100 +Partition 1 evolves = 100 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out new file mode 100644 index 0000000000..e38f4de508 --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out @@ -0,0 +1,21 @@ + +Analytical ODE test problem: + integrator = splitting method + coefficients = ARKODE_SPLITTING_BEST_2_2_2 + lambda = 2 + +Error: 7.26922e-07 +Final Solver Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 200 +Partition 1 evolves = 200 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out new file mode 100644 index 0000000000..8c6b193f33 --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out @@ -0,0 +1,21 @@ + +Analytical ODE test problem: + integrator = splitting method + coefficients = ARKODE_SPLITTING_RUTH_3_3_2 + lambda = 2 + +Error: 6.72016e-09 +Final Solver Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 300 +Partition 1 evolves = 300 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out new file mode 100644 index 0000000000..d3a022d248 --- /dev/null +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out @@ -0,0 +1,21 @@ + +Analytical ODE test problem: + integrator = splitting method + coefficients = ARKODE_SPLITTING_YOSHIDA_8_6_2 + lambda = 2 + +Error: 1.4436e-12 +Final Solver Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 1000 +Partition 1 evolves = 900 From 6051370459c4666775da62eb92d026feb512c842 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 20:01:19 -0700 Subject: [PATCH 070/180] Apply formatter --- src/arkode/arkode_io.c | 3 ++- src/arkode/arkode_splittingstep.c | 4 ++-- src/sundials/sundials_stepper.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index a04d9b0b0e..b846c38f8f 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -2169,7 +2169,8 @@ int ARKodeGetStepDirection(void* arkode_mem, sunrealtype* stepdir) } ark_mem = (ARKodeMem)arkode_mem; - *stepdir = (ark_mem->fixedstep || ark_mem->h == ZERO) ? ark_mem->hin : ark_mem->h; + *stepdir = (ark_mem->fixedstep || ark_mem->h == ZERO) ? ark_mem->hin + : ark_mem->h; return (ARK_SUCCESS); } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 1e50f1dea9..48344c97dc 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -263,12 +263,12 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, for (int k = 0; k < coefficients->partitions; k++) { const sunrealtype beta_start = coefficients->beta[i][j][k]; - const sunrealtype beta_end = coefficients->beta[i][j + 1][k]; + const sunrealtype beta_end = coefficients->beta[i][j + 1][k]; if (beta_start == beta_end) { continue; } const sunrealtype t_start = ark_mem->tn + beta_start * ark_mem->h; - const sunrealtype t_end = ark_mem->tn + beta_end * ark_mem->h; + const sunrealtype t_end = ark_mem->tn + beta_end * ark_mem->h; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index d3232195b0..e588cc2c26 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -274,7 +274,7 @@ SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) else { return SUN_ERR_NOT_IMPLEMENTED; } } -SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype *stepdir) +SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) { SUNFunctionBegin(stepper->sunctx); if (stepper->ops->setstepdirection) From e935dfa47ce95b4b3fa7c74f9ee1a36322d45194 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 20:04:50 -0700 Subject: [PATCH 071/180] Remove parallel exec policies for now --- .../arkode_execution_policy_mpi.c | 83 ------------------- .../arkode_execution_policy_openmp.c | 45 ---------- 2 files changed, 128 deletions(-) delete mode 100644 src/arkode/execution_policy/arkode_execution_policy_mpi.c delete mode 100644 src/arkode/execution_policy/arkode_execution_policy_openmp.c diff --git a/src/arkode/execution_policy/arkode_execution_policy_mpi.c b/src/arkode/execution_policy/arkode_execution_policy_mpi.c deleted file mode 100644 index 715cdd1660..0000000000 --- a/src/arkode/execution_policy/arkode_execution_policy_mpi.c +++ /dev/null @@ -1,83 +0,0 @@ -/*--------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *--------------------------------------------------------------- - * TODO - *--------------------------------------------------------------*/ - -#include -#include - -#include "sundials_macros.h" -// #include - -// ARKodeSplittingExecutionPolicy SplittingStepExecutionPolicy_MPI(SUNComm comm) { -// ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); -// policy->setup = setup_mpi; -// policy->exectute = execute_mpi; -// policy->free = free_mpi; -// SUNComm *data = malloc(sizeof(*data)); -// data[0] = comm; -// policy->data = data; -// } - -// static int mpi_reduce(void *in, void *inout, int *len, MPI_Datatype *datatype) { -// // Is there any way -// } - -// static int setup_mpi(ARKodeSplittingExecutionPolicy policy, N_Vector y, const int sequential_methods) { -// MPI_Op_create(mpi_reduce, SUNTRUE, ) -// } - -// static int execute_mpi(ARKodeSplittingExecutionPolicy policy, ARKParallelExecuteFn fn, N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// SUNComm comm = *((SUNComm*) policy->data); -// int rank; -// MPI_Comm_rank(comm, &rank); - -// N_VScale(1, yn, ycur); -// fn(rank, y, user_data); -// N_VScale(alpha[rank], ycur, ycur); - -// for (int i = 2 * rank; i < sequential_methods; rank++) { -// N_VScale(1, yn, tmp); -// fn(i, tmp, user_data); -// NN_VLinearSum(1, ycur, alpha[i], tmp); -// } - -// sunindextype bufferSize; -// N_VBufSize(ycur, &bufferSize); -// } - -// static void free_mpi(ARKodeSplittingExecutionPolicy policy) { -// MPI_op_free(); -// free(policy->data); -// } - -// int execute_mpi(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// MPI_Bcast() - -// MPI_Barrier(comm); - -// int rank; -// MPI_Comm_rank(comm, &rank); - -// for (int i = rank; i < sequential_methods; i+=rank) { -// fn(i, y[i], user_data); -// } - -// // This could be done as a parallel reduction. The benefit appears minimal as -// // it would require at least 4 sequential methods to theoretically get a -// // speedup. -// N_VLinearCombination(sequential_methods, alpha, y, y[0]); -// } \ No newline at end of file diff --git a/src/arkode/execution_policy/arkode_execution_policy_openmp.c b/src/arkode/execution_policy/arkode_execution_policy_openmp.c deleted file mode 100644 index e5eeb7580b..0000000000 --- a/src/arkode/execution_policy/arkode_execution_policy_openmp.c +++ /dev/null @@ -1,45 +0,0 @@ -/*--------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *--------------------------------------------------------------- - * TODO - *--------------------------------------------------------------*/ - -#include -#include - -#include "sundials_macros.h" - -// int execute_openmp(ARKParallelExecuteFn fn, N_Vector *y, sunrealtype *alpha, const int sequential_methods, void *user_data) -// { -// #pragma omp parallel default(none) private(i) shared(fn, y, alpha, sequential_methods, user_data) -// { -// #pragma omp for schedule(static) num_threads(?) -// for (int i = 1; i < sequential_methods; i++) { -// // We assume that the "true" version of y_n is stored in y[0], then -// // distribute it to the other y[i]. It might be possible to remove this if -// // we can ensure the y[i] are always identical even after a reset, -// // reinit, etc. -// N_VScale(1, y[0], y[i]); -// } - -// #pragma omp for schedule(dynamic) num_threads(?) -// for (int i = 0; i < sequential_methods; i++) { -// fn(i, y[i], user_data); -// } -// } - -// // This could be done as a parallel reduction. The benefit appears minimal as -// // it would require at least 4 sequential methods to theoretically get a -// // speedup. -// N_VLinearCombination(sequential_methods, alpha, y, y[0]); -// } From 459297b77a83fe92133fb17b5e7fef5611c9ccfa Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 20:28:06 -0700 Subject: [PATCH 072/180] Rename splitting coefficients files --- .../Usage/SplittingStep/SplittingStepCoefficients.rst | 2 +- include/arkode/arkode_splittingstep.h | 2 +- ...fficients.h => arkode_splittingstep_coefficients.h} | 10 +++++----- src/arkode/CMakeLists.txt | 2 +- ...fficients.c => arkode_splittingstep_coefficients.c} | 2 +- test/unit_tests/arkode/C_serial/CMakeLists.txt | 2 +- ...icients.c => ark_test_splittingstep_coefficients.c} | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) rename include/arkode/{arkode_splitting_coefficients.h => arkode_splittingstep_coefficients.h} (92%) rename src/arkode/{arkode_splitting_coefficients.c => arkode_splittingstep_coefficients.c} (99%) rename test/unit_tests/arkode/C_serial/{ark_test_splitting_coefficients.c => ark_test_splittingstep_coefficients.c} (99%) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 91c8382850..acc4b901a3 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -73,7 +73,7 @@ SplittingStepCoefficients Functions This section describes the functions for creating and interacting with operator splitting coefficients. The function prototypes and as well as the relevant -integer constants are defined ``arkode/arkode_splitting_coefficients.h``. +integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. .. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Functions.Table: .. table:: SplittingStepCoefficients functions diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 1a72d9cb98..2dbaba1d8b 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -18,7 +18,7 @@ #define ARKODE_SPLITTINGSTEP_H_ #include -#include +#include #include #include #include diff --git a/include/arkode/arkode_splitting_coefficients.h b/include/arkode/arkode_splittingstep_coefficients.h similarity index 92% rename from include/arkode/arkode_splitting_coefficients.h rename to include/arkode/arkode_splittingstep_coefficients.h index 7532a3d495..a6ddf34ddc 100644 --- a/include/arkode/arkode_splitting_coefficients.h +++ b/include/arkode/arkode_splittingstep_coefficients.h @@ -1,4 +1,4 @@ -/* TODO: merge this header into arkode_splittingstep.h? MRI uses one header, but ARK/SPRK uses two */ +/* TODO(SBR): merge this header into arkode_splittingstep.h? MRI uses one header, but ARK/SPRK uses two */ /* ----------------------------------------------------------------------------- * Programmer(s): Steven B. Roberts @ LLNL @@ -16,8 +16,8 @@ * This is the header file for ARKode splitting coefficient structures. * ---------------------------------------------------------------------------*/ -#ifndef ARKODE_SPLITTING_STEP_COEFFICIENTS_H_ -#define ARKODE_SPLITTING_STEP_COEFFICIENTS_H_ +#ifndef ARKODE_SPLITTINGSTEP_COEFFICIENTS_H_ +#define ARKODE_SPLITTINGSTEP_COEFFICIENTS_H_ #include #include @@ -61,8 +61,8 @@ typedef enum /* Coefficient memory management */ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( int sequential_methods, int stages, int partitions); -/* TODO: Ideally, alpha and beta would be const, but that would be inconsistent - * with other ARKODE function which accept arrays */ +/* TODO(SBR): Ideally, alpha and beta would be const, but that would be + * inconsistent with other ARKODE function which accept arrays */ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index b254ec9c54..cbc870b761 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -39,7 +39,7 @@ set(arkode_SOURCES arkode_mristep.c arkode_relaxation.c arkode_root.c - arkode_splitting_coefficients.c + arkode_splittingstep_coefficients.c arkode_splittingstep_executionpolicy.c arkode_splittingstep.c arkode_sprkstep_io.c diff --git a/src/arkode/arkode_splitting_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c similarity index 99% rename from src/arkode/arkode_splitting_coefficients.c rename to src/arkode/arkode_splittingstep_coefficients.c index aa9f800a49..6a23898fc5 100644 --- a/src/arkode/arkode_splitting_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -14,7 +14,7 @@ * This is the implementation file for splitting coefficients *--------------------------------------------------------------*/ -#include +#include #include #include "arkode_impl.h" diff --git a/test/unit_tests/arkode/C_serial/CMakeLists.txt b/test/unit_tests/arkode/C_serial/CMakeLists.txt index d523e56f5e..f8b9425fe2 100644 --- a/test/unit_tests/arkode/C_serial/CMakeLists.txt +++ b/test/unit_tests/arkode/C_serial/CMakeLists.txt @@ -33,7 +33,7 @@ set(ARKODE_unit_tests "ark_test_interp\;-1000000" "ark_test_mass\;" "ark_test_reset\;" - "ark_test_splitting_coefficients\;" + "ark_test_splittingstep_coefficients\;" "ark_test_tstop\;") # Add the build and install targets for each test diff --git a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c similarity index 99% rename from test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c rename to test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c index 41cd75f28f..ae6fcb1091 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splitting_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c @@ -18,7 +18,7 @@ #include #include -#include "arkode/arkode_splitting_coefficients.h" +#include "arkode/arkode_splittingstep_coefficients.h" #include "sundials/sundials_math.h" #define ZERO SUN_RCONST(0.0) From 3f1a50da55276417c9eb8e54b84040fe8368f451 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 20:38:42 -0700 Subject: [PATCH 073/180] Add new header files to docs --- doc/arkode/guide/source/Usage/General.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/arkode/guide/source/Usage/General.rst b/doc/arkode/guide/source/Usage/General.rst index c0980dfcee..0d1645cc30 100644 --- a/doc/arkode/guide/source/Usage/General.rst +++ b/doc/arkode/guide/source/Usage/General.rst @@ -51,11 +51,13 @@ to the SUNDIALS core header file. .. code:: c - #include // Provides core SUNDIALS types - #include // ERKStep provides explicit RK methods. - #include // ARKStep provides explicit, implicit, IMEX additive RK methods. - #include // MRIStep provides mutlirate RK methods. - #include // SPRKStep provides symplectic partition RK methods. + #include // Provides core SUNDIALS types + #include // ARKStep provides explicit, implicit, IMEX additive RK methods. + #include // ERKStep provides explicit RK methods. + #include // SPRKStep provides symplectic partition RK methods. + #include // SPRKStep provides symplectic partition RK methods. + #include // SPRKStep provides symplectic partition RK methods. + #include // MRIStep provides mutlirate RK methods. Each of these define several types and various constants, include function prototypes, and include the shared ``arkode/arkode.h`` and From 0e92844d0ecece1cf09eb13710f25e4f66965ef4 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 20:53:18 -0700 Subject: [PATCH 074/180] Generate fortran interface --- src/arkode/fmod_int32/farkode_arkstep_mod.c | 45 +++ src/arkode/fmod_int32/farkode_arkstep_mod.f90 | 38 ++ .../fmod_int32/farkode_forcingstep_mod.c | 275 ++++++++++++++ .../fmod_int32/farkode_forcingstep_mod.f90 | 118 ++++++ src/arkode/fmod_int32/farkode_mod.c | 28 ++ src/arkode/fmod_int32/farkode_mod.f90 | 52 +++ src/arkode/fmod_int32/farkode_mristep_mod.c | 15 + src/arkode/fmod_int32/farkode_mristep_mod.f90 | 30 ++ .../fmod_int32/farkode_splittingstep_mod.c | 335 ++++++++++++++++++ .../fmod_int32/farkode_splittingstep_mod.f90 | 217 ++++++++++++ src/arkode/fmod_int64/farkode_arkstep_mod.c | 45 +++ src/arkode/fmod_int64/farkode_arkstep_mod.f90 | 38 ++ .../fmod_int64/farkode_forcingstep_mod.c | 275 ++++++++++++++ .../fmod_int64/farkode_forcingstep_mod.f90 | 118 ++++++ src/arkode/fmod_int64/farkode_mod.c | 28 ++ src/arkode/fmod_int64/farkode_mod.f90 | 52 +++ src/arkode/fmod_int64/farkode_mristep_mod.c | 15 + src/arkode/fmod_int64/farkode_mristep_mod.f90 | 30 ++ .../fmod_int64/farkode_splittingstep_mod.c | 335 ++++++++++++++++++ .../fmod_int64/farkode_splittingstep_mod.f90 | 217 ++++++++++++ swig/Makefile | 2 +- swig/arkode/farkode_forcingstep_mod.i | 30 ++ swig/arkode/farkode_splittingstep_mod.i | 30 ++ 23 files changed, 2367 insertions(+), 1 deletion(-) create mode 100644 src/arkode/fmod_int32/farkode_forcingstep_mod.c create mode 100644 src/arkode/fmod_int32/farkode_forcingstep_mod.f90 create mode 100644 src/arkode/fmod_int32/farkode_splittingstep_mod.c create mode 100644 src/arkode/fmod_int32/farkode_splittingstep_mod.f90 create mode 100644 src/arkode/fmod_int64/farkode_forcingstep_mod.c create mode 100644 src/arkode/fmod_int64/farkode_forcingstep_mod.f90 create mode 100644 src/arkode/fmod_int64/farkode_splittingstep_mod.c create mode 100644 src/arkode/fmod_int64/farkode_splittingstep_mod.f90 create mode 100644 swig/arkode/farkode_forcingstep_mod.i create mode 100644 swig/arkode/farkode_splittingstep_mod.i diff --git a/src/arkode/fmod_int32/farkode_arkstep_mod.c b/src/arkode/fmod_int32/farkode_arkstep_mod.c index 4791bedcdc..587e4a983e 100644 --- a/src/arkode/fmod_int32/farkode_arkstep_mod.c +++ b/src/arkode/fmod_int32/farkode_arkstep_mod.c @@ -178,6 +178,22 @@ { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if ((SWIG_CLASS_WRAPPER).cmemflags & SWIG_MEM_CONST) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass const " TYPENAME " (class " FNAME ") " \ + "as a mutable reference", \ + RETURNNULL); \ + } + + #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -231,6 +247,20 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() { } +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + + #include SWIGEXPORT void * _wrap_FARKStepCreate(ARKRhsFn farg1, ARKRhsFn farg2, double const *farg3, N_Vector farg4, void *farg5) { @@ -433,6 +463,21 @@ SWIGEXPORT int _wrap_FARKStepCreateMRIStepInnerStepper(void *farg1, void *farg2) } +SWIGEXPORT int _wrap_FARKStepCreateSUNStepper(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + SUNStepper *arg2 = (SUNStepper *) 0 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_mutable(*farg2, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "ARKStepCreateSUNStepper(void *,SUNStepper *)", return 0); + arg2 = (SUNStepper *)(farg2->cptr); + result = (int)ARKStepCreateSUNStepper(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKStepResize(void *farg1, N_Vector farg2, double const *farg3, double const *farg4, ARKVecResizeFn farg5, void *farg6) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int32/farkode_arkstep_mod.f90 b/src/arkode/fmod_int32/farkode_arkstep_mod.f90 index cc0373f1eb..356c547daa 100644 --- a/src/arkode/fmod_int32/farkode_arkstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_arkstep_mod.f90 @@ -64,6 +64,18 @@ module farkode_arkstep_mod public :: FARKStepGetCurrentButcherTables public :: FARKStepGetTimestepperStats public :: FARKStepCreateMRIStepInnerStepper + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FARKStepCreateSUNStepper public :: FARKStepResize public :: FARKStepReset public :: FARKStepSStolerances @@ -346,6 +358,16 @@ function swigc_FARKStepCreateMRIStepInnerStepper(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKStepCreateSUNStepper(farg1, farg2) & +bind(C, name="_wrap_FARKStepCreateSUNStepper") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKStepResize(farg1, farg2, farg3, farg4, farg5, farg6) & bind(C, name="_wrap_FARKStepResize") & result(fresult) @@ -2038,6 +2060,22 @@ function FARKStepCreateMRIStepInnerStepper(arkode_mem, stepper) & swig_result = fresult end function +function FARKStepCreateSUNStepper(arkode_mem, stepper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +class(SWIGTYPE_p_SUNStepper), intent(in) :: stepper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = stepper%swigdata +fresult = swigc_FARKStepCreateSUNStepper(farg1, farg2) +swig_result = fresult +end function + function FARKStepResize(arkode_mem, ynew, hscale, t0, resize, resize_data) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int32/farkode_forcingstep_mod.c b/src/arkode/fmod_int32/farkode_forcingstep_mod.c new file mode 100644 index 0000000000..09f5a679e7 --- /dev/null +++ b/src/arkode/fmod_int32/farkode_forcingstep_mod.c @@ -0,0 +1,275 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.0 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------- + * Programmer(s): Auto-generated by swig. + * --------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* qualifier for exported *const* global data variables*/ +#ifndef SWIGEXTERN +# ifdef __cplusplus +# define SWIGEXTERN extern +# else +# define SWIGEXTERN +# endif +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +#include +#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ + { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } + + +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if (!(SWIG_CLASS_WRAPPER).cptr) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass null " TYPENAME " (class " FNAME ") " \ + "as a reference", RETURNNULL); \ + } + + +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif + + +/* Support for the `contract` feature. + * + * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in + * the fortran.cxx file. + */ +#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ + if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } + + +#define SWIGVERSION 0x040000 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "arkode/arkode_forcingstep.h" + + +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + +SWIGEXPORT void * _wrap_FForcingStepCreate(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + void * fresult ; + SUNStepper arg1 ; + SUNStepper arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + void *result = 0 ; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg2 = *(SUNStepper *)(farg2->cptr); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (void *)ForcingStepCreate(arg1,arg2,arg3,arg4,arg5); + fresult = result; + return fresult; +} + + +SWIGEXPORT int _wrap_FForcingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + long *arg3 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + arg3 = (long *)(farg3); + result = (int)ForcingStep_GetNumEvolves(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + + diff --git a/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 b/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 new file mode 100644 index 0000000000..99c8932478 --- /dev/null +++ b/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 @@ -0,0 +1,118 @@ +! This file was automatically generated by SWIG (http://www.swig.org). +! Version 4.0.0 +! +! Do not make changes to this file unless you know what you are doing--modify +! the SWIG interface file instead. + +! --------------------------------------------------------------- +! Programmer(s): Auto-generated by swig. +! --------------------------------------------------------------- +! SUNDIALS Copyright Start +! Copyright (c) 2002-2024, Lawrence Livermore National Security +! and Southern Methodist University. +! All rights reserved. +! +! See the top-level LICENSE and NOTICE files for details. +! +! SPDX-License-Identifier: BSD-3-Clause +! SUNDIALS Copyright End +! --------------------------------------------------------------- + +module farkode_forcingstep_mod + use, intrinsic :: ISO_C_BINDING + use farkode_mod + use fsundials_core_mod + implicit none + private + + ! DECLARATION CONSTRUCTS + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FForcingStepCreate + public :: FForcingStep_GetNumEvolves + +! WRAPPER DECLARATIONS +interface +function swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FForcingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR) :: fresult +end function + +function swigc_FForcingStep_GetNumEvolves(farg1, farg2, farg3) & +bind(C, name="_wrap_FForcingStep_GetNumEvolves") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +type(C_PTR), value :: farg3 +integer(C_INT) :: fresult +end function + +end interface + + +contains + ! MODULE SUBPROGRAMS +function FForcingStepCreate(stepper1, stepper2, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = stepper1%swigdata +farg2 = stepper2%swigdata +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FForcingStep_GetNumEvolves(arkode_mem, partition, evolves) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: partition +integer(C_LONG), dimension(*), target, intent(inout) :: evolves +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 +type(C_PTR) :: farg3 + +farg1 = arkode_mem +farg2 = partition +farg3 = c_loc(evolves(1)) +fresult = swigc_FForcingStep_GetNumEvolves(farg1, farg2, farg3) +swig_result = fresult +end function + + +end module diff --git a/src/arkode/fmod_int32/farkode_mod.c b/src/arkode/fmod_int32/farkode_mod.c index 1423d2e582..e107239a3f 100644 --- a/src/arkode/fmod_int32/farkode_mod.c +++ b/src/arkode/fmod_int32/farkode_mod.c @@ -605,6 +605,20 @@ SWIGEXPORT int _wrap_FARKodeSetFixedStep(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FARKodeSetStepDirection(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKodeSetStepDirection(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKodeSetUserData(void *farg1, void *farg2) { int fresult ; void *arg1 = (void *) 0 ; @@ -1265,6 +1279,20 @@ SWIGEXPORT int _wrap_FARKodeGetCurrentStep(void *farg1, double *farg2) { } +SWIGEXPORT int _wrap_FARKodeGetStepDirection(void *farg1, double *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype *)(farg2); + result = (int)ARKodeGetStepDirection(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKodeGetErrWeights(void *farg1, N_Vector farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int32/farkode_mod.f90 b/src/arkode/fmod_int32/farkode_mod.f90 index 366867f40a..8913072c4c 100644 --- a/src/arkode/fmod_int32/farkode_mod.f90 +++ b/src/arkode/fmod_int32/farkode_mod.f90 @@ -122,6 +122,7 @@ module farkode_mod public :: FARKodeSetStopTime public :: FARKodeClearStopTime public :: FARKodeSetFixedStep + public :: FARKodeSetStepDirection public :: FARKodeSetUserData public :: FARKodeSetPostprocessStepFn public :: FARKodeSetPostprocessStageFn @@ -168,6 +169,7 @@ module farkode_mod public :: FARKodeGetNumSteps public :: FARKodeGetLastStep public :: FARKodeGetCurrentStep + public :: FARKodeGetStepDirection public :: FARKodeGetErrWeights public :: FARKodeGetNumGEvals public :: FARKodeGetRootInfo @@ -643,6 +645,15 @@ function swigc_FARKodeSetFixedStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKodeSetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FARKodeSetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKodeSetUserData(farg1, farg2) & bind(C, name="_wrap_FARKodeSetUserData") & result(fresult) @@ -1065,6 +1076,15 @@ function swigc_FARKodeGetCurrentStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKodeGetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FARKodeGetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKodeGetErrWeights(farg1, farg2) & bind(C, name="_wrap_FARKodeGetErrWeights") & result(fresult) @@ -2704,6 +2724,22 @@ function FARKodeSetFixedStep(arkode_mem, hfixed) & swig_result = fresult end function +function FARKodeSetStepDirection(arkode_mem, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = stepdir +fresult = swigc_FARKodeSetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FARKodeSetUserData(arkode_mem, user_data) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -3464,6 +3500,22 @@ function FARKodeGetCurrentStep(arkode_mem, hcur) & swig_result = fresult end function +function FARKodeGetStepDirection(arkode_mem, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(stepdir(1)) +fresult = swigc_FARKodeGetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FARKodeGetErrWeights(arkode_mem, eweight) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int32/farkode_mristep_mod.c b/src/arkode/fmod_int32/farkode_mristep_mod.c index 35721938c4..1a6086fda2 100644 --- a/src/arkode/fmod_int32/farkode_mristep_mod.c +++ b/src/arkode/fmod_int32/farkode_mristep_mod.c @@ -771,6 +771,21 @@ SWIGEXPORT int _wrap_FMRIStepInnerStepper_Create(void *farg1, void *farg2) { } +SWIGEXPORT int _wrap_FMRIStepInnerStepper_CreateFromSUNStepper(SwigClassWrapper const *farg1, void *farg2) { + int fresult ; + SUNStepper arg1 ; + MRIStepInnerStepper *arg2 = (MRIStepInnerStepper *) 0 ; + int result; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "MRIStepInnerStepper_CreateFromSUNStepper(SUNStepper,MRIStepInnerStepper *)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + arg2 = (MRIStepInnerStepper *)(farg2); + result = (int)MRIStepInnerStepper_CreateFromSUNStepper(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FMRIStepInnerStepper_Free(void *farg1) { int fresult ; MRIStepInnerStepper *arg1 = (MRIStepInnerStepper *) 0 ; diff --git a/src/arkode/fmod_int32/farkode_mristep_mod.f90 b/src/arkode/fmod_int32/farkode_mristep_mod.f90 index 74a3de5637..defd9f4596 100644 --- a/src/arkode/fmod_int32/farkode_mristep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_mristep_mod.f90 @@ -133,6 +133,10 @@ module farkode_mristep_mod public :: FMRIStepGetCurrentCoupling public :: FMRIStepGetLastInnerStepFlag public :: FMRIStepInnerStepper_Create + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FMRIStepInnerStepper_CreateFromSUNStepper public :: FMRIStepInnerStepper_Free public :: FMRIStepInnerStepper_SetContent public :: FMRIStepInnerStepper_GetContent @@ -540,6 +544,16 @@ function swigc_FMRIStepInnerStepper_Create(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FMRIStepInnerStepper_CreateFromSUNStepper(farg1, farg2) & +bind(C, name="_wrap_FMRIStepInnerStepper_CreateFromSUNStepper") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FMRIStepInnerStepper_Free(farg1) & bind(C, name="_wrap_FMRIStepInnerStepper_Free") & result(fresult) @@ -1950,6 +1964,22 @@ function FMRIStepInnerStepper_Create(sunctx, stepper) & swig_result = fresult end function +function FMRIStepInnerStepper_CreateFromSUNStepper(sunstepper, stepper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: sunstepper +type(C_PTR), target, intent(inout) :: stepper +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = sunstepper%swigdata +farg2 = c_loc(stepper) +fresult = swigc_FMRIStepInnerStepper_CreateFromSUNStepper(farg1, farg2) +swig_result = fresult +end function + function FMRIStepInnerStepper_Free(stepper) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.c b/src/arkode/fmod_int32/farkode_splittingstep_mod.c new file mode 100644 index 0000000000..e0bb4d8ddf --- /dev/null +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.c @@ -0,0 +1,335 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.0 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------- + * Programmer(s): Auto-generated by swig. + * --------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* qualifier for exported *const* global data variables*/ +#ifndef SWIGEXTERN +# ifdef __cplusplus +# define SWIGEXTERN extern +# else +# define SWIGEXTERN +# endif +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +#include +#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ + { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } + + +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if ((SWIG_CLASS_WRAPPER).cmemflags & SWIG_MEM_CONST) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass const " TYPENAME " (class " FNAME ") " \ + "as a mutable reference", \ + RETURNNULL); \ + } + + +#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if (!(SWIG_CLASS_WRAPPER).cptr) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass null " TYPENAME " (class " FNAME ") " \ + "as a reference", RETURNNULL); \ + } + + +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif + + +/* Support for the `contract` feature. + * + * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in + * the fortran.cxx file. + */ +#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ + if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } + + +#define SWIGVERSION 0x040000 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "arkode/arkode_splittingstep.h" + + +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + +SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + void * fresult ; + SUNStepper *arg1 = (SUNStepper *) 0 ; + int arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + void *result = 0 ; + + SWIG_check_mutable(*farg1, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "SplittingStepCreate(SUNStepper *,int,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = (SUNStepper *)(farg1->cptr); + arg2 = (int)(*farg2); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (void *)SplittingStepCreate(arg1,arg2,arg3,arg4,arg5); + fresult = result; + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStepCreateForcing(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + int fresult ; + SUNStepper arg1 ; + SUNStepper arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + int result; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg2 = *(SUNStepper *)(farg2->cptr); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (int)SplittingStepCreateForcing(arg1,arg2,arg3,arg4,arg5); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + SplittingStepCoefficients arg2 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_nonnull(*farg2, "SplittingStepCoefficients", "SWIGTYPE_p_SplittingStepCoefficients", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); + arg2 = *(SplittingStepCoefficients *)(farg2->cptr); + result = (int)SplittingStep_SetCoefficients(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_SetExecutionPolicy(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKodeSplittingExecutionPolicy arg2 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_nonnull(*farg2, "ARKodeSplittingExecutionPolicy", "SWIGTYPE_p_ARKodeSplittingExecutionPolicy", "SplittingStep_SetExecutionPolicy(void *,ARKodeSplittingExecutionPolicy)", return 0); + arg2 = *(ARKodeSplittingExecutionPolicy *)(farg2->cptr); + result = (int)SplittingStep_SetExecutionPolicy(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + long *arg3 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + arg3 = (long *)(farg3); + result = (int)SplittingStep_GetNumEvolves(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + + diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 new file mode 100644 index 0000000000..7cc2d19050 --- /dev/null +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 @@ -0,0 +1,217 @@ +! This file was automatically generated by SWIG (http://www.swig.org). +! Version 4.0.0 +! +! Do not make changes to this file unless you know what you are doing--modify +! the SWIG interface file instead. + +! --------------------------------------------------------------- +! Programmer(s): Auto-generated by swig. +! --------------------------------------------------------------- +! SUNDIALS Copyright Start +! Copyright (c) 2002-2024, Lawrence Livermore National Security +! and Southern Methodist University. +! All rights reserved. +! +! See the top-level LICENSE and NOTICE files for details. +! +! SPDX-License-Identifier: BSD-3-Clause +! SUNDIALS Copyright End +! --------------------------------------------------------------- + +module farkode_splittingstep_mod + use, intrinsic :: ISO_C_BINDING + use farkode_mod + use fsundials_core_mod + implicit none + private + + ! DECLARATION CONSTRUCTS + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStepCreate + public :: FSplittingStepCreateForcing + type, public :: SWIGTYPE_p_SplittingStepCoefficients + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStep_SetCoefficients + type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStep_SetExecutionPolicy + public :: FSplittingStep_GetNumEvolves + +! WRAPPER DECLARATIONS +interface +function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR) :: fresult +end function + +function swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreateForcing") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & +bind(C, name="_wrap_FSplittingStep_SetCoefficients") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) & +bind(C, name="_wrap_FSplittingStep_SetExecutionPolicy") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & +bind(C, name="_wrap_FSplittingStep_GetNumEvolves") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +type(C_PTR), value :: farg3 +integer(C_INT) :: fresult +end function + +end interface + + +contains + ! MODULE SUBPROGRAMS +function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +integer(C_INT), intent(in) :: partitions +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = steppers%swigdata +farg2 = partitions +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FSplittingStepCreateForcing(stepper1, stepper2, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = stepper1%swigdata +farg2 = stepper2%swigdata +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(SWIGTYPE_p_SplittingStepCoefficients), intent(in) :: coefficients +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = coefficients%swigdata +fresult = swigc_FSplittingStep_SetCoefficients(farg1, farg2) +swig_result = fresult +end function + +function FSplittingStep_SetExecutionPolicy(arkode_mem, policy) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(SWIGTYPE_p_ARKodeSplittingExecutionPolicy), intent(in) :: policy +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = policy%swigdata +fresult = swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) +swig_result = fresult +end function + +function FSplittingStep_GetNumEvolves(arkode_mem, partition, evolves) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: partition +integer(C_LONG), dimension(*), target, intent(inout) :: evolves +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 +type(C_PTR) :: farg3 + +farg1 = arkode_mem +farg2 = partition +farg3 = c_loc(evolves(1)) +fresult = swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) +swig_result = fresult +end function + + +end module diff --git a/src/arkode/fmod_int64/farkode_arkstep_mod.c b/src/arkode/fmod_int64/farkode_arkstep_mod.c index 4791bedcdc..587e4a983e 100644 --- a/src/arkode/fmod_int64/farkode_arkstep_mod.c +++ b/src/arkode/fmod_int64/farkode_arkstep_mod.c @@ -178,6 +178,22 @@ { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if ((SWIG_CLASS_WRAPPER).cmemflags & SWIG_MEM_CONST) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass const " TYPENAME " (class " FNAME ") " \ + "as a mutable reference", \ + RETURNNULL); \ + } + + #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -231,6 +247,20 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() { } +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + + #include SWIGEXPORT void * _wrap_FARKStepCreate(ARKRhsFn farg1, ARKRhsFn farg2, double const *farg3, N_Vector farg4, void *farg5) { @@ -433,6 +463,21 @@ SWIGEXPORT int _wrap_FARKStepCreateMRIStepInnerStepper(void *farg1, void *farg2) } +SWIGEXPORT int _wrap_FARKStepCreateSUNStepper(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + SUNStepper *arg2 = (SUNStepper *) 0 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_mutable(*farg2, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "ARKStepCreateSUNStepper(void *,SUNStepper *)", return 0); + arg2 = (SUNStepper *)(farg2->cptr); + result = (int)ARKStepCreateSUNStepper(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKStepResize(void *farg1, N_Vector farg2, double const *farg3, double const *farg4, ARKVecResizeFn farg5, void *farg6) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int64/farkode_arkstep_mod.f90 b/src/arkode/fmod_int64/farkode_arkstep_mod.f90 index cc0373f1eb..356c547daa 100644 --- a/src/arkode/fmod_int64/farkode_arkstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_arkstep_mod.f90 @@ -64,6 +64,18 @@ module farkode_arkstep_mod public :: FARKStepGetCurrentButcherTables public :: FARKStepGetTimestepperStats public :: FARKStepCreateMRIStepInnerStepper + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FARKStepCreateSUNStepper public :: FARKStepResize public :: FARKStepReset public :: FARKStepSStolerances @@ -346,6 +358,16 @@ function swigc_FARKStepCreateMRIStepInnerStepper(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKStepCreateSUNStepper(farg1, farg2) & +bind(C, name="_wrap_FARKStepCreateSUNStepper") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKStepResize(farg1, farg2, farg3, farg4, farg5, farg6) & bind(C, name="_wrap_FARKStepResize") & result(fresult) @@ -2038,6 +2060,22 @@ function FARKStepCreateMRIStepInnerStepper(arkode_mem, stepper) & swig_result = fresult end function +function FARKStepCreateSUNStepper(arkode_mem, stepper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +class(SWIGTYPE_p_SUNStepper), intent(in) :: stepper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = stepper%swigdata +fresult = swigc_FARKStepCreateSUNStepper(farg1, farg2) +swig_result = fresult +end function + function FARKStepResize(arkode_mem, ynew, hscale, t0, resize, resize_data) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int64/farkode_forcingstep_mod.c b/src/arkode/fmod_int64/farkode_forcingstep_mod.c new file mode 100644 index 0000000000..09f5a679e7 --- /dev/null +++ b/src/arkode/fmod_int64/farkode_forcingstep_mod.c @@ -0,0 +1,275 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.0 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------- + * Programmer(s): Auto-generated by swig. + * --------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* qualifier for exported *const* global data variables*/ +#ifndef SWIGEXTERN +# ifdef __cplusplus +# define SWIGEXTERN extern +# else +# define SWIGEXTERN +# endif +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +#include +#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ + { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } + + +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if (!(SWIG_CLASS_WRAPPER).cptr) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass null " TYPENAME " (class " FNAME ") " \ + "as a reference", RETURNNULL); \ + } + + +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif + + +/* Support for the `contract` feature. + * + * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in + * the fortran.cxx file. + */ +#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ + if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } + + +#define SWIGVERSION 0x040000 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "arkode/arkode_forcingstep.h" + + +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + +SWIGEXPORT void * _wrap_FForcingStepCreate(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + void * fresult ; + SUNStepper arg1 ; + SUNStepper arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + void *result = 0 ; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg2 = *(SUNStepper *)(farg2->cptr); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (void *)ForcingStepCreate(arg1,arg2,arg3,arg4,arg5); + fresult = result; + return fresult; +} + + +SWIGEXPORT int _wrap_FForcingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + long *arg3 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + arg3 = (long *)(farg3); + result = (int)ForcingStep_GetNumEvolves(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + + diff --git a/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 b/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 new file mode 100644 index 0000000000..99c8932478 --- /dev/null +++ b/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 @@ -0,0 +1,118 @@ +! This file was automatically generated by SWIG (http://www.swig.org). +! Version 4.0.0 +! +! Do not make changes to this file unless you know what you are doing--modify +! the SWIG interface file instead. + +! --------------------------------------------------------------- +! Programmer(s): Auto-generated by swig. +! --------------------------------------------------------------- +! SUNDIALS Copyright Start +! Copyright (c) 2002-2024, Lawrence Livermore National Security +! and Southern Methodist University. +! All rights reserved. +! +! See the top-level LICENSE and NOTICE files for details. +! +! SPDX-License-Identifier: BSD-3-Clause +! SUNDIALS Copyright End +! --------------------------------------------------------------- + +module farkode_forcingstep_mod + use, intrinsic :: ISO_C_BINDING + use farkode_mod + use fsundials_core_mod + implicit none + private + + ! DECLARATION CONSTRUCTS + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FForcingStepCreate + public :: FForcingStep_GetNumEvolves + +! WRAPPER DECLARATIONS +interface +function swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FForcingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR) :: fresult +end function + +function swigc_FForcingStep_GetNumEvolves(farg1, farg2, farg3) & +bind(C, name="_wrap_FForcingStep_GetNumEvolves") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +type(C_PTR), value :: farg3 +integer(C_INT) :: fresult +end function + +end interface + + +contains + ! MODULE SUBPROGRAMS +function FForcingStepCreate(stepper1, stepper2, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = stepper1%swigdata +farg2 = stepper2%swigdata +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FForcingStep_GetNumEvolves(arkode_mem, partition, evolves) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: partition +integer(C_LONG), dimension(*), target, intent(inout) :: evolves +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 +type(C_PTR) :: farg3 + +farg1 = arkode_mem +farg2 = partition +farg3 = c_loc(evolves(1)) +fresult = swigc_FForcingStep_GetNumEvolves(farg1, farg2, farg3) +swig_result = fresult +end function + + +end module diff --git a/src/arkode/fmod_int64/farkode_mod.c b/src/arkode/fmod_int64/farkode_mod.c index 7b2c3c9811..90f73c6af6 100644 --- a/src/arkode/fmod_int64/farkode_mod.c +++ b/src/arkode/fmod_int64/farkode_mod.c @@ -605,6 +605,20 @@ SWIGEXPORT int _wrap_FARKodeSetFixedStep(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FARKodeSetStepDirection(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKodeSetStepDirection(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKodeSetUserData(void *farg1, void *farg2) { int fresult ; void *arg1 = (void *) 0 ; @@ -1265,6 +1279,20 @@ SWIGEXPORT int _wrap_FARKodeGetCurrentStep(void *farg1, double *farg2) { } +SWIGEXPORT int _wrap_FARKodeGetStepDirection(void *farg1, double *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype *)(farg2); + result = (int)ARKodeGetStepDirection(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKodeGetErrWeights(void *farg1, N_Vector farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int64/farkode_mod.f90 b/src/arkode/fmod_int64/farkode_mod.f90 index e627472572..356d583a98 100644 --- a/src/arkode/fmod_int64/farkode_mod.f90 +++ b/src/arkode/fmod_int64/farkode_mod.f90 @@ -122,6 +122,7 @@ module farkode_mod public :: FARKodeSetStopTime public :: FARKodeClearStopTime public :: FARKodeSetFixedStep + public :: FARKodeSetStepDirection public :: FARKodeSetUserData public :: FARKodeSetPostprocessStepFn public :: FARKodeSetPostprocessStageFn @@ -168,6 +169,7 @@ module farkode_mod public :: FARKodeGetNumSteps public :: FARKodeGetLastStep public :: FARKodeGetCurrentStep + public :: FARKodeGetStepDirection public :: FARKodeGetErrWeights public :: FARKodeGetNumGEvals public :: FARKodeGetRootInfo @@ -643,6 +645,15 @@ function swigc_FARKodeSetFixedStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKodeSetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FARKodeSetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKodeSetUserData(farg1, farg2) & bind(C, name="_wrap_FARKodeSetUserData") & result(fresult) @@ -1065,6 +1076,15 @@ function swigc_FARKodeGetCurrentStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKodeGetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FARKodeGetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKodeGetErrWeights(farg1, farg2) & bind(C, name="_wrap_FARKodeGetErrWeights") & result(fresult) @@ -2704,6 +2724,22 @@ function FARKodeSetFixedStep(arkode_mem, hfixed) & swig_result = fresult end function +function FARKodeSetStepDirection(arkode_mem, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = stepdir +fresult = swigc_FARKodeSetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FARKodeSetUserData(arkode_mem, user_data) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -3464,6 +3500,22 @@ function FARKodeGetCurrentStep(arkode_mem, hcur) & swig_result = fresult end function +function FARKodeGetStepDirection(arkode_mem, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(stepdir(1)) +fresult = swigc_FARKodeGetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FARKodeGetErrWeights(arkode_mem, eweight) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int64/farkode_mristep_mod.c b/src/arkode/fmod_int64/farkode_mristep_mod.c index c2e254fa54..136a64edf2 100644 --- a/src/arkode/fmod_int64/farkode_mristep_mod.c +++ b/src/arkode/fmod_int64/farkode_mristep_mod.c @@ -771,6 +771,21 @@ SWIGEXPORT int _wrap_FMRIStepInnerStepper_Create(void *farg1, void *farg2) { } +SWIGEXPORT int _wrap_FMRIStepInnerStepper_CreateFromSUNStepper(SwigClassWrapper const *farg1, void *farg2) { + int fresult ; + SUNStepper arg1 ; + MRIStepInnerStepper *arg2 = (MRIStepInnerStepper *) 0 ; + int result; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "MRIStepInnerStepper_CreateFromSUNStepper(SUNStepper,MRIStepInnerStepper *)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + arg2 = (MRIStepInnerStepper *)(farg2); + result = (int)MRIStepInnerStepper_CreateFromSUNStepper(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FMRIStepInnerStepper_Free(void *farg1) { int fresult ; MRIStepInnerStepper *arg1 = (MRIStepInnerStepper *) 0 ; diff --git a/src/arkode/fmod_int64/farkode_mristep_mod.f90 b/src/arkode/fmod_int64/farkode_mristep_mod.f90 index 782c3c1df9..bb9861d99e 100644 --- a/src/arkode/fmod_int64/farkode_mristep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_mristep_mod.f90 @@ -133,6 +133,10 @@ module farkode_mristep_mod public :: FMRIStepGetCurrentCoupling public :: FMRIStepGetLastInnerStepFlag public :: FMRIStepInnerStepper_Create + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FMRIStepInnerStepper_CreateFromSUNStepper public :: FMRIStepInnerStepper_Free public :: FMRIStepInnerStepper_SetContent public :: FMRIStepInnerStepper_GetContent @@ -540,6 +544,16 @@ function swigc_FMRIStepInnerStepper_Create(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FMRIStepInnerStepper_CreateFromSUNStepper(farg1, farg2) & +bind(C, name="_wrap_FMRIStepInnerStepper_CreateFromSUNStepper") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FMRIStepInnerStepper_Free(farg1) & bind(C, name="_wrap_FMRIStepInnerStepper_Free") & result(fresult) @@ -1950,6 +1964,22 @@ function FMRIStepInnerStepper_Create(sunctx, stepper) & swig_result = fresult end function +function FMRIStepInnerStepper_CreateFromSUNStepper(sunstepper, stepper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: sunstepper +type(C_PTR), target, intent(inout) :: stepper +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = sunstepper%swigdata +farg2 = c_loc(stepper) +fresult = swigc_FMRIStepInnerStepper_CreateFromSUNStepper(farg1, farg2) +swig_result = fresult +end function + function FMRIStepInnerStepper_Free(stepper) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.c b/src/arkode/fmod_int64/farkode_splittingstep_mod.c new file mode 100644 index 0000000000..e0bb4d8ddf --- /dev/null +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.c @@ -0,0 +1,335 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 4.0.0 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------- + * Programmer(s): Auto-generated by swig. + * --------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -------------------------------------------------------------*/ + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* qualifier for exported *const* global data variables*/ +#ifndef SWIGEXTERN +# ifdef __cplusplus +# define SWIGEXTERN extern +# else +# define SWIGEXTERN +# endif +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +#include +#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ + { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } + + +enum { + SWIG_MEM_OWN = 0x01, + SWIG_MEM_RVALUE = 0x02, + SWIG_MEM_CONST = 0x04 +}; + + +#define SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if ((SWIG_CLASS_WRAPPER).cmemflags & SWIG_MEM_CONST) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass const " TYPENAME " (class " FNAME ") " \ + "as a mutable reference", \ + RETURNNULL); \ + } + + +#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + if (!(SWIG_CLASS_WRAPPER).cptr) { \ + SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ + "Cannot pass null " TYPENAME " (class " FNAME ") " \ + "as a reference", RETURNNULL); \ + } + + +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif + + +/* Support for the `contract` feature. + * + * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in + * the fortran.cxx file. + */ +#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ + if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } + + +#define SWIGVERSION 0x040000 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "arkode/arkode_splittingstep.h" + + +typedef struct { + void* cptr; + int cmemflags; +} SwigClassWrapper; + + +SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { + SwigClassWrapper result; + result.cptr = NULL; + result.cmemflags = 0; + return result; +} + +SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + void * fresult ; + SUNStepper *arg1 = (SUNStepper *) 0 ; + int arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + void *result = 0 ; + + SWIG_check_mutable(*farg1, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "SplittingStepCreate(SUNStepper *,int,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = (SUNStepper *)(farg1->cptr); + arg2 = (int)(*farg2); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (void *)SplittingStepCreate(arg1,arg2,arg3,arg4,arg5); + fresult = result; + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStepCreateForcing(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { + int fresult ; + SUNStepper arg1 ; + SUNStepper arg2 ; + sunrealtype arg3 ; + N_Vector arg4 = (N_Vector) 0 ; + SUNContext arg5 = (SUNContext) 0 ; + int result; + + SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg1 = *(SUNStepper *)(farg1->cptr); + SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); + arg2 = *(SUNStepper *)(farg2->cptr); + arg3 = (sunrealtype)(*farg3); + arg4 = (N_Vector)(farg4); + arg5 = (SUNContext)(farg5); + result = (int)SplittingStepCreateForcing(arg1,arg2,arg3,arg4,arg5); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + SplittingStepCoefficients arg2 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_nonnull(*farg2, "SplittingStepCoefficients", "SWIGTYPE_p_SplittingStepCoefficients", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); + arg2 = *(SplittingStepCoefficients *)(farg2->cptr); + result = (int)SplittingStep_SetCoefficients(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_SetExecutionPolicy(void *farg1, SwigClassWrapper const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKodeSplittingExecutionPolicy arg2 ; + int result; + + arg1 = (void *)(farg1); + SWIG_check_nonnull(*farg2, "ARKodeSplittingExecutionPolicy", "SWIGTYPE_p_ARKodeSplittingExecutionPolicy", "SplittingStep_SetExecutionPolicy(void *,ARKodeSplittingExecutionPolicy)", return 0); + arg2 = *(ARKodeSplittingExecutionPolicy *)(farg2->cptr); + result = (int)SplittingStep_SetExecutionPolicy(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSplittingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + long *arg3 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + arg3 = (long *)(farg3); + result = (int)SplittingStep_GetNumEvolves(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + + diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 new file mode 100644 index 0000000000..7cc2d19050 --- /dev/null +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 @@ -0,0 +1,217 @@ +! This file was automatically generated by SWIG (http://www.swig.org). +! Version 4.0.0 +! +! Do not make changes to this file unless you know what you are doing--modify +! the SWIG interface file instead. + +! --------------------------------------------------------------- +! Programmer(s): Auto-generated by swig. +! --------------------------------------------------------------- +! SUNDIALS Copyright Start +! Copyright (c) 2002-2024, Lawrence Livermore National Security +! and Southern Methodist University. +! All rights reserved. +! +! See the top-level LICENSE and NOTICE files for details. +! +! SPDX-License-Identifier: BSD-3-Clause +! SUNDIALS Copyright End +! --------------------------------------------------------------- + +module farkode_splittingstep_mod + use, intrinsic :: ISO_C_BINDING + use farkode_mod + use fsundials_core_mod + implicit none + private + + ! DECLARATION CONSTRUCTS + + integer, parameter :: swig_cmem_own_bit = 0 + integer, parameter :: swig_cmem_rvalue_bit = 1 + integer, parameter :: swig_cmem_const_bit = 2 + type, bind(C) :: SwigClassWrapper + type(C_PTR), public :: cptr = C_NULL_PTR + integer(C_INT), public :: cmemflags = 0 + end type + type, public :: SWIGTYPE_p_SUNStepper + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStepCreate + public :: FSplittingStepCreateForcing + type, public :: SWIGTYPE_p_SplittingStepCoefficients + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStep_SetCoefficients + type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy + type(SwigClassWrapper), public :: swigdata + end type + public :: FSplittingStep_SetExecutionPolicy + public :: FSplittingStep_GetNumEvolves + +! WRAPPER DECLARATIONS +interface +function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR) :: fresult +end function + +function swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreateForcing") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +type(C_PTR), value :: farg4 +type(C_PTR), value :: farg5 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & +bind(C, name="_wrap_FSplittingStep_SetCoefficients") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) & +bind(C, name="_wrap_FSplittingStep_SetExecutionPolicy") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(C_PTR), value :: farg1 +type(SwigClassWrapper) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & +bind(C, name="_wrap_FSplittingStep_GetNumEvolves") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +type(C_PTR), value :: farg3 +integer(C_INT) :: fresult +end function + +end interface + + +contains + ! MODULE SUBPROGRAMS +function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +integer(C_INT), intent(in) :: partitions +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = steppers%swigdata +farg2 = partitions +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FSplittingStepCreateForcing(stepper1, stepper2, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 +type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +real(C_DOUBLE), intent(in) :: t0 +type(N_Vector), target, intent(inout) :: y0 +type(C_PTR) :: sunctx +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 +real(C_DOUBLE) :: farg3 +type(C_PTR) :: farg4 +type(C_PTR) :: farg5 + +farg1 = stepper1%swigdata +farg2 = stepper2%swigdata +farg3 = t0 +farg4 = c_loc(y0) +farg5 = sunctx +fresult = swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) +swig_result = fresult +end function + +function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(SWIGTYPE_p_SplittingStepCoefficients), intent(in) :: coefficients +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = coefficients%swigdata +fresult = swigc_FSplittingStep_SetCoefficients(farg1, farg2) +swig_result = fresult +end function + +function FSplittingStep_SetExecutionPolicy(arkode_mem, policy) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(SWIGTYPE_p_ARKodeSplittingExecutionPolicy), intent(in) :: policy +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = arkode_mem +farg2 = policy%swigdata +fresult = swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) +swig_result = fresult +end function + +function FSplittingStep_GetNumEvolves(arkode_mem, partition, evolves) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: partition +integer(C_LONG), dimension(*), target, intent(inout) :: evolves +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 +type(C_PTR) :: farg3 + +farg1 = arkode_mem +farg2 = partition +farg3 = c_loc(evolves(1)) +fresult = swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) +swig_result = fresult +end function + + +end module diff --git a/swig/Makefile b/swig/Makefile index eb772623e9..a80fba8204 100644 --- a/swig/Makefile +++ b/swig/Makefile @@ -16,7 +16,7 @@ SWIG ?= swig -ARKODE=farkode_mod farkode_arkstep_mod farkode_erkstep_mod farkode_sprkstep_mod farkode_mristep_mod +ARKODE=farkode_mod farkode_arkstep_mod farkode_erkstep_mod farkode_sprkstep_mod farkode_mristep_mod farkode_splittingstep_mod farkode_forcingstep_mod CVODE=fcvode_mod CVODES=fcvodes_mod IDA=fida_mod diff --git a/swig/arkode/farkode_forcingstep_mod.i b/swig/arkode/farkode_forcingstep_mod.i new file mode 100644 index 0000000000..94ff80cccb --- /dev/null +++ b/swig/arkode/farkode_forcingstep_mod.i @@ -0,0 +1,30 @@ +// --------------------------------------------------------------- +// Programmer: Steven B. Roberts @ LLNL +// --------------------------------------------------------------- +// SUNDIALS Copyright Start +// Copyright (c) 2002-2024, Lawrence Livermore National Security +// and Southern Methodist University. +// All rights reserved. +// +// See the top-level LICENSE and NOTICE files for details. +// +// SPDX-License-Identifier: BSD-3-Clause +// SUNDIALS Copyright End +// --------------------------------------------------------------- +// Swig interface file +// --------------------------------------------------------------- + +%module farkode_forcingstep_mod + +%include "../sundials/fsundials.i" + +// include the header file(s) in the c wrapper that is generated +%{ +#include "arkode/arkode_forcingstep.h" +%} + +// Load the typedefs and generate a "use" statements in the module +%import "farkode_mod.i" + +// Process definitions from these files +%include "arkode/arkode_forcingstep.h" diff --git a/swig/arkode/farkode_splittingstep_mod.i b/swig/arkode/farkode_splittingstep_mod.i new file mode 100644 index 0000000000..38a9b71b25 --- /dev/null +++ b/swig/arkode/farkode_splittingstep_mod.i @@ -0,0 +1,30 @@ +// --------------------------------------------------------------- +// Programmer: Steven B. Roberts @ LLNL +// --------------------------------------------------------------- +// SUNDIALS Copyright Start +// Copyright (c) 2002-2024, Lawrence Livermore National Security +// and Southern Methodist University. +// All rights reserved. +// +// See the top-level LICENSE and NOTICE files for details. +// +// SPDX-License-Identifier: BSD-3-Clause +// SUNDIALS Copyright End +// --------------------------------------------------------------- +// Swig interface file +// --------------------------------------------------------------- + +%module farkode_splittingstep_mod + +%include "../sundials/fsundials.i" + +// include the header file(s) in the c wrapper that is generated +%{ +#include "arkode/arkode_splittingstep.h" +%} + +// Load the typedefs and generate a "use" statements in the module +%import "farkode_mod.i" + +// Process definitions from these files +%include "arkode/arkode_splittingstep.h" From 87e1e2e7a9ccc7516fa1fbf7a7bab8faedcaa4f2 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 21:02:27 -0700 Subject: [PATCH 075/180] Comment cleanup --- include/arkode/arkode_splittingstep.h | 4 ++-- src/arkode/arkode_splitting_coefficients.def | 2 +- src/arkode/arkode_splittingstep_coefficients.c | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 2dbaba1d8b..880d9de75f 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -27,8 +27,8 @@ extern "C" { #endif -/* TODO: can we use `const SUNStepper* steppers`? */ -/* TODO: would (t0, y0, steppers, partitions, sunctx) be a better arg order? Seems slightly more consistent with MRIStepCreate */ +/* TODO(SBR): would (t0, y0, steppers, partitions, sunctx) be a better arg + order? That would be more consistent with MRIStep but less with others */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx); diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def index f0550acf97..2bc7e154d3 100644 --- a/src/arkode/arkode_splitting_coefficients.def +++ b/src/arkode/arkode_splitting_coefficients.def @@ -16,7 +16,7 @@ /* When adding a new method, enter the coefficients below and add - a new enum entry to include/arkode/arkode_splitting_coefficients.h + a new enum entry to include/arkode/arkode_splittingstep_coefficients.h */ ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index 6a23898fc5..9a701bea12 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -50,7 +50,6 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( i index requires allocating an array of pointers into that matrix. */ /* Array of pointers for index i */ - coefficients->beta = (sunrealtype***)malloc(sequential_methods * sizeof(*coefficients->beta)); if (coefficients->beta == NULL) From 0810067be1594da3aafc9b99d8460319dec75c24 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 21:17:03 -0700 Subject: [PATCH 076/180] Typo fixes --- doc/arkode/guide/source/Mathematics.rst | 2 +- .../guide/source/Usage/ForcingStep/User_callable.rst | 2 +- doc/arkode/guide/source/Usage/General.rst | 12 ++++++------ .../source/Usage/SplittingStep/User_callable.rst | 2 +- include/arkode/arkode_execution_policy.h | 1 - src/arkode/arkode_arkstep.c | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 9bbce05061..c2b51db3b3 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -668,7 +668,7 @@ ForcingStep is given by y_n &= v_2(t_n). Like a Lie-Trotter method from SplittingStep, the partitions are evolved through -a sequence of inner IVPs which can be solve with an arbitrary integrator or +a sequence of inner IVPs which can be solved with an arbitrary integrator or exact solution procedure. However, the IVP for partition two includes a "forcing" or "tendency" term :math:`f_1^*` to strengthen the coupling. This coupling leads to a first order method provided :math:`v_1` and :math:`v_2` are diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst index 63184a7640..f24e9623c3 100644 --- a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -109,6 +109,6 @@ Optional output functions * *ARK_MEM_NULL* if the ForcingStep memory was ``NULL`` - * *ARK_ILL_INPUT* if *evolves* was out of bounds + * *ARK_ILL_INPUT* if *partition* was out of bounds .. versionadded:: x.y.z \ No newline at end of file diff --git a/doc/arkode/guide/source/Usage/General.rst b/doc/arkode/guide/source/Usage/General.rst index 0d1645cc30..bfd20569d2 100644 --- a/doc/arkode/guide/source/Usage/General.rst +++ b/doc/arkode/guide/source/Usage/General.rst @@ -51,13 +51,13 @@ to the SUNDIALS core header file. .. code:: c - #include // Provides core SUNDIALS types - #include // ARKStep provides explicit, implicit, IMEX additive RK methods. - #include // ERKStep provides explicit RK methods. - #include // SPRKStep provides symplectic partition RK methods. + #include // Provides core SUNDIALS types + #include // ARKStep provides explicit, implicit, IMEX additive RK methods. + #include // ERKStep provides explicit RK methods. + #include // SPRKStep provides symplectic partition RK methods. #include // SPRKStep provides symplectic partition RK methods. - #include // SPRKStep provides symplectic partition RK methods. - #include // MRIStep provides mutlirate RK methods. + #include // SPRKStep provides symplectic partition RK methods. + #include // MRIStep provides mutlirate RK methods. Each of these define several types and various constants, include function prototypes, and include the shared ``arkode/arkode.h`` and diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index c2da9180c2..ea482b8a12 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -145,6 +145,6 @@ Optional output functions * *ARK_MEM_NULL* if the SplittingStep memory was ``NULL`` - * *ARK_ILL_INPUT* if *evolves* was out of bounds + * *ARK_ILL_INPUT* if *partition* was out of bounds .. versionadded:: x.y.z diff --git a/include/arkode/arkode_execution_policy.h b/include/arkode/arkode_execution_policy.h index 0a255279c4..1897dc333c 100644 --- a/include/arkode/arkode_execution_policy.h +++ b/include/arkode/arkode_execution_policy.h @@ -40,7 +40,6 @@ struct ARKodeSplittingExecutionPolicyMem void* data; }; -// TODO: Return error code? Accept pointer? SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( ARKodeSplittingExecutionPolicy* policy); diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 85c1ae4125..ccd216bed1 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3350,7 +3350,7 @@ int arkStep_SUNStepperSetStopTime(SUNStepper stepper, sunrealtype tstop) /*------------------------------------------------------------------------------ arkStep_SUNStepperSetStepDirection - TODO(SBR) + Implementation of SetStepDirectionFn to set the integration direction. ----------------------------------------------------------------------------*/ int arkStep_SUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir) @@ -3371,7 +3371,7 @@ int arkStep_SUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir) /*------------------------------------------------------------------------------ arkStep_SUNStepperGetStepDirection - TODO(SBR) + Implementation of GetStepDirectionFn to get the integration direction. ----------------------------------------------------------------------------*/ int arkStep_SUNStepperGetStepDirection(SUNStepper stepper, sunrealtype* stepdir) From 64614f8c3492da3e32de1a4dd4ed38b7e5ac374f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 21:24:55 -0700 Subject: [PATCH 077/180] Remove todos --- include/arkode/arkode_splittingstep_coefficients.h | 2 -- src/arkode/arkode_splittingstep.c | 4 ++-- src/arkode/arkode_splittingstep_coefficients.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/arkode/arkode_splittingstep_coefficients.h b/include/arkode/arkode_splittingstep_coefficients.h index a6ddf34ddc..cf94a6e99c 100644 --- a/include/arkode/arkode_splittingstep_coefficients.h +++ b/include/arkode/arkode_splittingstep_coefficients.h @@ -61,8 +61,6 @@ typedef enum /* Coefficient memory management */ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( int sequential_methods, int stages, int partitions); -/* TODO(SBR): Ideally, alpha and beta would be const, but that would be - * inconsistent with other ARKODE function which accept arrays */ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 48344c97dc..15ae7aff88 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -70,8 +70,8 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, static sunbooleantype splittingStep_CheckNVector(const N_Vector y) { // TODO(SBR): check all ops are correct - return y->ops->nvclone != NULL && y->ops->nvdestroy != NULL && - y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; + return y->ops->nvdestroy != NULL && y->ops->nvlinearsum != NULL && + y->ops->nvscale != NULL; } /*--------------------------------------------------------------- diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index 9a701bea12..ccc8696d40 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -117,7 +117,6 @@ SplittingStepCoefficients SplittingStepCoefficients_Create( ---------------------------------------------------------------*/ void SplittingStepCoefficients_Free(const SplittingStepCoefficients coefficients) { - // TODO: should argument be a pointer? if (coefficients != NULL) { free(coefficients->alpha); @@ -438,7 +437,7 @@ SplittingStepCoefficients SplittingStepCoefficients_SuzukiFractal( void SplittingStepCoefficients_Write(const SplittingStepCoefficients coefficients, FILE* const outfile) { - // TODO: update when https://github.com/LLNL/sundials/pull/517 merged + // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged if (coefficients == NULL || coefficients->alpha == NULL || coefficients->beta == NULL || coefficients->beta[0] == NULL || coefficients->beta[0][0] == NULL) From ed889da8b731772c1e615b2d82fe55429ba78f8f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 21:51:15 -0700 Subject: [PATCH 078/180] Fix copy paste error --- include/arkode/arkode_splittingstep_coefficients.h | 2 +- .../execution_policy/arkode_execution_policy_serial.h | 2 +- src/arkode/arkode_forcingstep_impl.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/arkode/arkode_splittingstep_coefficients.h b/include/arkode/arkode_splittingstep_coefficients.h index cf94a6e99c..543ab9a7bf 100644 --- a/include/arkode/arkode_splittingstep_coefficients.h +++ b/include/arkode/arkode_splittingstep_coefficients.h @@ -99,4 +99,4 @@ SplittingStepCoefficients_SuzukiFractal(int partitions, int order); } #endif -#endif \ No newline at end of file +#endif diff --git a/include/arkode/execution_policy/arkode_execution_policy_serial.h b/include/arkode/execution_policy/arkode_execution_policy_serial.h index e43586541d..fa641bec79 100644 --- a/include/arkode/execution_policy/arkode_execution_policy_serial.h +++ b/include/arkode/execution_policy/arkode_execution_policy_serial.h @@ -30,4 +30,4 @@ ARKodeSplittingExecutionPolicy_New_Serial(); } #endif -#endif \ No newline at end of file +#endif diff --git a/src/arkode/arkode_forcingstep_impl.h b/src/arkode/arkode_forcingstep_impl.h index 1222c90922..e57bc82925 100644 --- a/src/arkode/arkode_forcingstep_impl.h +++ b/src/arkode/arkode_forcingstep_impl.h @@ -11,13 +11,13 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * This header defines the step memory for SplittingStep. + * This header defines the step memory for ForcingStep. *--------------------------------------------------------------*/ -#ifndef ARKODE_SPLITTINGSTEP_IMPL_H_ -#define ARKODE_SPLITTINGSTEP_IMPL_H_ +#ifndef ARKODE_FORCINGSTEP_IMPL_H_ +#define ARKODE_FORCINGSTEP_IMPL_H_ -#include +#include typedef struct ARKodeForcingStepMemRec { From 6aefac946362c1142cbaad7923db6d0643f993f0 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 21:54:34 -0700 Subject: [PATCH 079/180] Reword splittingstep method description --- doc/arkode/guide/source/Mathematics.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index c2b51db3b3..14866fddba 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -613,10 +613,9 @@ The following algorithmic procedure is used in the Splitting-Step module: Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number of sequential methods within the overall operator splitting scheme. The -sequential methods have independent flows which are combined in a linear -combination to produce the next step. The real coefficients :math:`\alpha_i` and -:math:`\beta_{i,j,k}` determine the particular scheme and properties such as the -order. +sequential methods have independent flows which are linearly combined to produce +the next step. The real coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` +determine the particular scheme and properties such as the order. An alternative representation of the SplittingStep solution is From 9a802560c53502069712e81aeb8fdcc92fe5a753 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:10:51 -0700 Subject: [PATCH 080/180] Move partitions macro to header --- src/arkode/arkode_forcingstep.c | 2 -- src/arkode/arkode_forcingstep_impl.h | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index bc4e4553b6..53dfe15382 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -22,8 +22,6 @@ #include "arkode_impl.h" #include "arkode_mristep_impl.h" -#define PARTITIONS 2 - /*--------------------------------------------------------------- Shortcut routine to unpack step_mem structure from ark_mem. If missing it returns ARK_MEM_NULL. diff --git a/src/arkode/arkode_forcingstep_impl.h b/src/arkode/arkode_forcingstep_impl.h index e57bc82925..77c542b7f4 100644 --- a/src/arkode/arkode_forcingstep_impl.h +++ b/src/arkode/arkode_forcingstep_impl.h @@ -19,10 +19,12 @@ #include +#define PARTITIONS 2 + typedef struct ARKodeForcingStepMemRec { - SUNStepper stepper[2]; - long int n_stepper_evolves[2]; + SUNStepper stepper[PARTITIONS]; + long int n_stepper_evolves[PARTITIONS]; }* ARKodeForcingStepMem; #endif From 6b33c4b37798c2afeb6c104a8adb68fca40be47d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:12:39 -0700 Subject: [PATCH 081/180] Replace with constant --- src/arkode/arkode_forcingstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 53dfe15382..7e6915652f 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -270,7 +270,7 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) if (retval != ARK_SUCCESS) { return; } /* output long integer quantities */ - for (int k = 0; k < 2; k++) + for (int k = 0; k < PARTITIONS; k++) { fprintf(outfile, "ForcingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); From 45b7aee6e262e8db65201f6ef972955aff4df62d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:21:02 -0700 Subject: [PATCH 082/180] Fix typo --- src/arkode/arkode_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index b846c38f8f..4b83894617 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -2156,7 +2156,7 @@ int ARKodeGetCurrentStep(void* arkode_mem, sunrealtype* hcur) Gets the direction of integration (forward or backward) based on the sign of stepdir. A value of 0 indicates integration can - procede in either direction. + proceed in either direction. ---------------------------------------------------------------*/ int ARKodeGetStepDirection(void* arkode_mem, sunrealtype* stepdir) { From 8ac2486b7da7e2486a20329c08d247d7e7302a38 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:25:50 -0700 Subject: [PATCH 083/180] Add missing newline --- src/arkode/execution_policy/arkode_execution_policy_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index 2ddf6cde26..ec34252227 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -82,4 +82,4 @@ ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial() policy->free = free_serial; policy->data = NULL; return policy; -} \ No newline at end of file +} From d7f0e7eea9ef263e62c16d075e55ad7a8bd1b608 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:30:07 -0700 Subject: [PATCH 084/180] Add missing void argument for mac compilation --- .../arkode/execution_policy/arkode_execution_policy_serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/arkode/execution_policy/arkode_execution_policy_serial.h b/include/arkode/execution_policy/arkode_execution_policy_serial.h index fa641bec79..4afff57847 100644 --- a/include/arkode/execution_policy/arkode_execution_policy_serial.h +++ b/include/arkode/execution_policy/arkode_execution_policy_serial.h @@ -24,7 +24,7 @@ extern "C" { #endif SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy -ARKodeSplittingExecutionPolicy_New_Serial(); +ARKodeSplittingExecutionPolicy_New_Serial(void); #ifdef __cplusplus } From 9e13ac740dbe6a99c3af7c17012c414320be9521 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:32:03 -0700 Subject: [PATCH 085/180] Add missing void argument for mac compilation --- src/arkode/execution_policy/arkode_execution_policy_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index ec34252227..887e92d57f 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -73,7 +73,7 @@ static void free_serial( /*--------------------------------------------------------------- This routine creates a serial execution policy ---------------------------------------------------------------*/ -ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial() +ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial(void) { ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); if (policy == NULL) { return NULL; } From 79f737d0093da5109f7e4109b484b0199e25af47 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 22:35:28 -0700 Subject: [PATCH 086/180] Add missing void argument for mac compilation --- .../C_serial/ark_advection_diffusion_reaction_splitting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index f619dc4538..4b4180dfb0 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -203,7 +203,7 @@ static int f_reaction(const sunrealtype t, const N_Vector y, return 0; } -int main() +int main(void) { /* Problem parameters */ const sunrealtype T0 = SUN_RCONST(0.0); From 058dc2f8cd06d850529959fd0e4c4541a3da1b1b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 23:00:55 -0700 Subject: [PATCH 087/180] Format cmake files --- external/CMakeLists.txt | 27 ++++++++++++++------------- src/sundials/CMakeLists.txt | 6 ++---- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 4f4bc0edb5..8befa78cb1 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -10,22 +10,23 @@ # SUNDIALS Copyright End # --------------------------------------------------------------- -# Steps to add an external addon to SUNDIALS: -# WARNING: external addons are not maintained by the SUNDIALS team -# and may come with their own license with different rules. +# Steps to add an external addon to SUNDIALS: WARNING: external addons are not +# maintained by the SUNDIALS team and may come with their own license with +# different rules. # -# 1. Clone/copy the addon into /external/ -# (the same directory as this file you are reading). -# 2. Copy the sundials-addon-example block for your own external project. -# 3. When building SUNDIALS, set the CMake option SUNDIALS_ENABLE_EXTERNAL_ADDONS to ON -# 4. Build SUNDIALS as usual. +# 1. Clone/copy the addon into /external/ (the same directory as +# this file you are reading). +# 2. Copy the sundials-addon-example block for your own external project. +# 3. When building SUNDIALS, set the CMake option SUNDIALS_ENABLE_EXTERNAL_ADDONS +# to ON +# 4. Build SUNDIALS as usual. include(FetchContent) -# COPY THE FetchContent BLOCK BELOW FOR YOUR OWN EXTERNAL ADDON -# COMMENT THESE LINES OUT TO DISABLE THE EXAMPLE ADDON -FetchContent_Declare(sundials-addon-example - SOURCE_DIR ${PROJECT_SOURCE_DIR}/external/sundials-addon-example -) +# COPY THE FetchContent BLOCK BELOW FOR YOUR OWN EXTERNAL ADDON COMMENT THESE +# LINES OUT TO DISABLE THE EXAMPLE ADDON +FetchContent_Declare( + sundials-addon-example SOURCE_DIR + ${PROJECT_SOURCE_DIR}/external/sundials-addon-example) FetchContent_MakeAvailable(sundials-addon-example) # COPY THE BLOCK ABOVE FOR YOUR OWN EXTERNAL ADDON diff --git a/src/sundials/CMakeLists.txt b/src/sundials/CMakeLists.txt index a3ac1a1574..e3d82d88a3 100644 --- a/src/sundials/CMakeLists.txt +++ b/src/sundials/CMakeLists.txt @@ -52,8 +52,7 @@ set(sundials_HEADERS sundials_stepper.h sundials_types_deprecated.h sundials_types.h - sundials_version.h - ) + sundials_version.h) if(ENABLE_MPI) list(APPEND sundials_HEADERS sundials_mpi_errors.h) @@ -99,8 +98,7 @@ set(sundials_SOURCES sundials_nvector.c sundials_stepper.c sundials_profiler.c - sundials_version.c - ) + sundials_version.c) if(ENABLE_MPI) list(APPEND sundials_SOURCES sundials_mpi_errors.c) From 3387de85faefc738de8f9ca15a0a85f7ad3bf037 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 23:30:54 -0700 Subject: [PATCH 088/180] Fix conversion error --- include/sundials/sundials_math.h | 15 ++++ src/arkode/arkode_splitting_coefficients.def | 68 ------------------- .../arkode_splittingstep_coefficients.c | 8 +-- src/sundials/sundials_math.c | 9 +++ 4 files changed, 28 insertions(+), 72 deletions(-) delete mode 100644 src/arkode/arkode_splitting_coefficients.def diff --git a/include/sundials/sundials_math.h b/include/sundials/sundials_math.h index 4585c7c7f4..0cb09e4275 100644 --- a/include/sundials/sundials_math.h +++ b/include/sundials/sundials_math.h @@ -158,6 +158,21 @@ extern "C" { #endif #endif +/* + * ----------------------------------------------------------------- + * Function : SUNIpowerI + * ----------------------------------------------------------------- + * Usage : int exponent; + * int base, ans; + * ans = SUNIpowerI(base,exponent); + * ----------------------------------------------------------------- + * SUNIpowerI returns the value of base^exponent, where base and + * exponent are positive ints. + * ----------------------------------------------------------------- + */ + +SUNDIALS_EXPORT int SUNIpowerI(int base, int exponent); + /* * ----------------------------------------------------------------- * Function : SUNRpowerI diff --git a/src/arkode/arkode_splitting_coefficients.def b/src/arkode/arkode_splitting_coefficients.def deleted file mode 100644 index 2bc7e154d3..0000000000 --- a/src/arkode/arkode_splitting_coefficients.def +++ /dev/null @@ -1,68 +0,0 @@ -/*--------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *--------------------------------------------------------------- - * This file defines splitting coefficients using X-macros - *--------------------------------------------------------------*/ - -/* - When adding a new method, enter the coefficients below and add - a new enum entry to include/arkode/arkode_splittingstep_coefficients.h -*/ - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { - return NULL; - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_1_1_2, { - return SplittingStepCoefficients_LieTrotter(2); - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2_2, { - return SplittingStepCoefficients_Strang(2); - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_BEST_2_2_2, { - const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 2, 2); - coefficients->order = 2; - coefficients->alpha[0] = SUN_RCONST(1.0); - coefficients->beta[0][1][0] = SUN_RCONST(1.0) - SUNRsqrt(SUN_RCONST(0.5)); - coefficients->beta[0][1][1] = SUNRsqrt(SUN_RCONST(0.5)); - coefficients->beta[0][2][0] = SUN_RCONST(1.0); - coefficients->beta[0][2][1] = SUN_RCONST(1.0); - return coefficients; - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_SUZUKI_3_3_2, { - return SplittingStepCoefficients_ThirdOrderSuzuki(2); - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_RUTH_3_3_2, { - const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 3, 2); - coefficients->order = 3; - coefficients->alpha[0] = SUN_RCONST(1.0); - coefficients->beta[0][1][0] = SUN_RCONST(1.0); - coefficients->beta[0][1][1] = -SUN_RCONST(1.0) / SUN_RCONST(24.0); - coefficients->beta[0][2][0] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - coefficients->beta[0][2][1] = SUN_RCONST(17.0) / SUN_RCONST(24.0); - coefficients->beta[0][3][0] = SUN_RCONST(1.0); - coefficients->beta[0][3][1] = SUN_RCONST(1.0); - return coefficients; - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_4_4_2, { - return SplittingStepCoefficients_TripleJump(2, 4); - }) - -ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_8_6_2, { - return SplittingStepCoefficients_TripleJump(2, 6); - }) diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index ccc8696d40..7d45abbf48 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -168,7 +168,7 @@ SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficients( { #define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ case name: coeff break; -#include "arkode_splitting_coefficients.def" +#include "arkode_splittingstep_coefficients.def" #undef ARK_SPLITTING_COEFFICIENTS default: @@ -187,7 +187,7 @@ SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficientsByName( { #define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ if (strcmp(#name, method) == 0) coeff -#include "arkode_splitting_coefficients.def" +#include "arkode_splittingstep_coefficients.def" #undef ARK_SPLITTING_COEFFICIENTS arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, @@ -208,7 +208,7 @@ const char* SplittingStepCoefficients_IDToName( { #define ARK_SPLITTING_COEFFICIENTS(name, coeff) \ case name: return #name; -#include "arkode_splitting_coefficients.def" +#include "arkode_splittingstep_coefficients.def" #undef ARK_SPLITTING_COEFFICIENTS default: @@ -403,7 +403,7 @@ static SplittingStepCoefficients SplittingStepCoefficients_ComposeStrang( } const int stages = 1 + (partitions - 1) * - SUNRpowerI(composition_stages, order / 2 - 1); + SUNIpowerI(composition_stages, order / 2 - 1); const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, stages, partitions); if (coefficients == NULL) { return NULL; } diff --git a/src/sundials/sundials_math.c b/src/sundials/sundials_math.c index b60e9c2540..9b2f5a17f3 100644 --- a/src/sundials/sundials_math.c +++ b/src/sundials/sundials_math.c @@ -22,6 +22,15 @@ #include #include +int SUNIpowerI(int base, int exponent) +{ + int i; + int prod = 1; + + for (i = 1; i <= exponent; i++) { prod *= base; } + return (prod); +} + sunrealtype SUNRpowerI(sunrealtype base, int exponent) { int i, expt; From 2a7cb93bb8d0f41c959588bddbc93840ca7836ea Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 23:32:12 -0700 Subject: [PATCH 089/180] Add missing file --- .../arkode_splittingstep_coefficients.def | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/arkode/arkode_splittingstep_coefficients.def diff --git a/src/arkode/arkode_splittingstep_coefficients.def b/src/arkode/arkode_splittingstep_coefficients.def new file mode 100644 index 0000000000..2bc7e154d3 --- /dev/null +++ b/src/arkode/arkode_splittingstep_coefficients.def @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------- + * Programmer(s): Steven B. Roberts @ LLNL + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * This file defines splitting coefficients using X-macros + *--------------------------------------------------------------*/ + +/* + When adding a new method, enter the coefficients below and add + a new enum entry to include/arkode/arkode_splittingstep_coefficients.h +*/ + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_NONE, { + return NULL; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_LIE_TROTTER_1_1_2, { + return SplittingStepCoefficients_LieTrotter(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_STRANG_2_2_2, { + return SplittingStepCoefficients_Strang(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_BEST_2_2_2, { + const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 2, 2); + coefficients->order = 2; + coefficients->alpha[0] = SUN_RCONST(1.0); + coefficients->beta[0][1][0] = SUN_RCONST(1.0) - SUNRsqrt(SUN_RCONST(0.5)); + coefficients->beta[0][1][1] = SUNRsqrt(SUN_RCONST(0.5)); + coefficients->beta[0][2][0] = SUN_RCONST(1.0); + coefficients->beta[0][2][1] = SUN_RCONST(1.0); + return coefficients; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_SUZUKI_3_3_2, { + return SplittingStepCoefficients_ThirdOrderSuzuki(2); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_RUTH_3_3_2, { + const SplittingStepCoefficients coefficients = SplittingStepCoefficients_Alloc(1, 3, 2); + coefficients->order = 3; + coefficients->alpha[0] = SUN_RCONST(1.0); + coefficients->beta[0][1][0] = SUN_RCONST(1.0); + coefficients->beta[0][1][1] = -SUN_RCONST(1.0) / SUN_RCONST(24.0); + coefficients->beta[0][2][0] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + coefficients->beta[0][2][1] = SUN_RCONST(17.0) / SUN_RCONST(24.0); + coefficients->beta[0][3][0] = SUN_RCONST(1.0); + coefficients->beta[0][3][1] = SUN_RCONST(1.0); + return coefficients; + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_4_4_2, { + return SplittingStepCoefficients_TripleJump(2, 4); + }) + +ARK_SPLITTING_COEFFICIENTS(ARKODE_SPLITTING_YOSHIDA_8_6_2, { + return SplittingStepCoefficients_TripleJump(2, 6); + }) From e1771b5be4a297659d21023bb18a4bec37b2f935 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 12 Sep 2024 23:35:20 -0700 Subject: [PATCH 090/180] SUNIpowerI docs cleanup --- include/sundials/sundials_math.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/sundials/sundials_math.h b/include/sundials/sundials_math.h index 0cb09e4275..74a8918a1a 100644 --- a/include/sundials/sundials_math.h +++ b/include/sundials/sundials_math.h @@ -162,12 +162,11 @@ extern "C" { * ----------------------------------------------------------------- * Function : SUNIpowerI * ----------------------------------------------------------------- - * Usage : int exponent; - * int base, ans; + * Usage : int exponent, base, ans; * ans = SUNIpowerI(base,exponent); * ----------------------------------------------------------------- * SUNIpowerI returns the value of base^exponent, where base and - * exponent are positive ints. + * exponent are of type int and exponent is nonnegative. * ----------------------------------------------------------------- */ From 4d44c70d4e2d1b07222e94669cf27e1728b6cf38 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 15:40:23 -0700 Subject: [PATCH 091/180] Apply suggestions from code review Co-authored-by: Daniel R. Reynolds --- doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index bff9d31edd..467000a398 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -64,7 +64,7 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. :c:func:`ARKodeSetUserData()`. This *user_data* pointer will only be passed to user-supplied functions that are attached to an inner integrator. To supply a *user_data* pointer to user-supplied functions - called by the outer integrator the desired pointer should be attached be + called by the outer integrator the desired pointer should be attached by calling :c:func:`ARKodeSetUserData()` after creating the SplittingStep memory below. The *user_data* pointers attached to the inner and outer integrators may be the same or different depending on what is required by @@ -98,9 +98,9 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Free solver memory - * If ARKStep was used as the inner IVP integrator, call + * If ARKStep was used as an inner IVP integrator, call :c:func:`SUNStepper_Free` and :c:func:`ARKodeFree` to free the memory - allocated for the fast (inner) integrator. + allocated for that inner integrator. * If a user-defined inner integrator was supplied, free the integrator content and call :c:func:`SUNStepper_Free` to free the ``SUNStepper`` From 24a6456aedb30f29f78d7fa9920ce0200739365f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 17:35:07 -0700 Subject: [PATCH 092/180] Add new modules to top of math considerations --- doc/arkode/guide/source/Mathematics.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 14866fddba..fbaa663227 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -61,13 +61,15 @@ for interpolated solution output. We then discuss the current suite of time-stepping modules supplied with ARKODE, including the ARKStep module for :ref:`additive Runge--Kutta methods `, the ERKStep module that is optimized for :ref:`explicit Runge--Kutta -methods `, and the MRIStep module for :ref:`multirate -infinitesimal step (MIS), multirate infinitesimal GARK (MRI-GARK), and -implicit-explicit MRI-GARK (IMEX-MRI-GARK) methods `. -We then discuss the :ref:`adaptive temporal error controllers -` shared by the time-stepping modules, including -discussion of our choice of norms for measuring errors within various components -of the solver. +methods `, SplittingStep for :ref:`operator splitting +methods `, ForcingStep for :ref:`a forcing +method `, and the MRIStep module for +:ref:`multirate infinitesimal step (MIS), multirate infinitesimal GARK +(MRI-GARK), and implicit-explicit MRI-GARK (IMEX-MRI-GARK) methods +`. We then discuss the :ref:`adaptive temporal error +controllers ` shared by the time-stepping +modules, including discussion of our choice of norms for measuring errors within +various components of the solver. We then discuss the nonlinear and linear solver strategies used by ARKODE for solving implicit algebraic systems that arise in computing each From cb770edf4c8b02f5abb357b0fce15b03b98196d1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 17:39:44 -0700 Subject: [PATCH 093/180] Update changelog following @drreynolds suggestion --- CHANGELOG.md | 3 ++- doc/shared/RecentChanges.rst | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5ac57e8a0..a6cd5dc55e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ### Major Features Added an operator splitting module, SplittingStep, and forcing method module, -ForcingStep. to ARKODE. +ForcingStep, to ARKODE. These modules support a broad range of operator-split +time integration methods for multiphysics applications. ### New Features and Enhancements diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 2fb82cc854..706c9de505 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -2,7 +2,9 @@ Added an operator splitting module, :ref:`SplittingStep `, and forcing method module, -:ref:`ForcingStep `, to ARKODE. +:ref:`ForcingStep `, to ARKODE. These modules support +a broad range of operator-split time integration methods for multiphysics +applications. **New Features and Enhancements** From 4c0d5050e39973ceee2ff6a87f71eb0e4473d750 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 17:40:53 -0700 Subject: [PATCH 094/180] Clarify order in splittingstep description --- doc/arkode/guide/source/Mathematics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index fbaa663227..d7656b322a 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -617,7 +617,7 @@ Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number of sequential methods within the overall operator splitting scheme. The sequential methods have independent flows which are linearly combined to produce the next step. The real coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` -determine the particular scheme and properties such as the order. +determine the particular scheme and properties such as the order of accuracy. An alternative representation of the SplittingStep solution is From 512c60062b5765c427aa4e0239cde883e45d14f4 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 17:42:32 -0700 Subject: [PATCH 095/180] Correct header file descriptions in docs --- doc/arkode/guide/source/Usage/General.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/arkode/guide/source/Usage/General.rst b/doc/arkode/guide/source/Usage/General.rst index bfd20569d2..17da17d57e 100644 --- a/doc/arkode/guide/source/Usage/General.rst +++ b/doc/arkode/guide/source/Usage/General.rst @@ -54,9 +54,9 @@ to the SUNDIALS core header file. #include // Provides core SUNDIALS types #include // ARKStep provides explicit, implicit, IMEX additive RK methods. #include // ERKStep provides explicit RK methods. - #include // SPRKStep provides symplectic partition RK methods. - #include // SPRKStep provides symplectic partition RK methods. - #include // SPRKStep provides symplectic partition RK methods. + #include // SPRKStep provides symplectic partitioned RK methods. + #include // SplittingStep provides operator splitting methods. + #include // ForcingStep provides a forcing method. #include // MRIStep provides mutlirate RK methods. Each of these define several types and various constants, include function From 92572961de5ebedeb58b38cf724cff38e7d3278a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 17:54:32 -0700 Subject: [PATCH 096/180] Typo fixes --- .../Usage/SplittingStep/SplittingStepCoefficients.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index acc4b901a3..42424ae424 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -209,7 +209,7 @@ integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Parallel(int partitions) - Create the coefficients for the first order splitting method + Create the coefficients for the first order parallel splitting method .. math:: y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + @@ -336,7 +336,7 @@ integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. * *partitions* -- The number :math:`P` of partitions in the IVP. **Return value:** - * An :c:type:`SplittingStepCoefficients` structure if successful. + * A :c:type:`SplittingStepCoefficients` structure if successful. * A ``NULL`` pointer if *sequential_methods*, *stages* or *partitions* was invalid or an allocation error occurred. @@ -364,7 +364,7 @@ integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. \beta_{1,0,1}, \dots, \beta_{1,0,P}, \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, \beta_{2,0,1}, \dots, \beta_{r,s,P}. **Return value:** - * An :c:type:`SplittingStepCoefficients` structure if successful. + * A :c:type:`SplittingStepCoefficients` structure if successful. * A ``NULL`` pointer if an argument was invalid or an allocation error occurred. @@ -379,7 +379,7 @@ integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. * ``coefficients`` -- The splitting coefficients to copy. **Return value:** - * An :c:type:`SplittingStepCoefficients` structure if successful. + * A :c:type:`SplittingStepCoefficients` structure if successful. * A ``NULL`` pointer if an allocation error occurred. .. versionadded:: x.y.z From 5cbdab801755a2772d9e76e9c21bae33e836892f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 17 Sep 2024 19:24:38 -0700 Subject: [PATCH 097/180] Switch ARKODE_SplittingCoefficientsID to enum in docs --- .../source/Usage/SplittingStep/SplittingStepCoefficients.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 42424ae424..747dc6a9cd 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -427,7 +427,7 @@ references for each in the table below. We use the naming convention Each of the splitting coefficients that are packaged with SplittingStep are specified by a unique ID having type: -.. c:type:: int ARKODE_SplittingCoefficientsID +.. c:enum:: ARKODE_SplittingCoefficientsID with values specified for each method below (e.g., ``ARKODE_SPLITTING_LIE_TROTTER_1_1_2``). From 1b7468df69b1b9d18bf37a8d4841f175cb8982fd Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:05:45 -0700 Subject: [PATCH 098/180] Apply suggestions from code review Co-authored-by: Daniel R. Reynolds --- doc/arkode/guide/source/Usage/General.rst | 2 +- .../C_serial/ark_advection_diffusion_reaction_splitting.c | 2 +- src/arkode/arkode_forcingstep.c | 2 +- src/arkode/arkode_splittingstep.c | 2 +- src/arkode/execution_policy/arkode_execution_policy_serial.c | 2 +- test/unit_tests/arkode/C_serial/ark_test_forcingstep.c | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/arkode/guide/source/Usage/General.rst b/doc/arkode/guide/source/Usage/General.rst index 17da17d57e..6b04ed758a 100644 --- a/doc/arkode/guide/source/Usage/General.rst +++ b/doc/arkode/guide/source/Usage/General.rst @@ -57,7 +57,7 @@ to the SUNDIALS core header file. #include // SPRKStep provides symplectic partitioned RK methods. #include // SplittingStep provides operator splitting methods. #include // ForcingStep provides a forcing method. - #include // MRIStep provides mutlirate RK methods. + #include // MRIStep provides multirate RK methods. Each of these define several types and various constants, include function prototypes, and include the shared ``arkode/arkode.h`` and diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 4b4180dfb0..fc1c33dada 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -18,7 +18,7 @@ * u_t = a*(u^2/2)_x + b*u_xx + c*(u - u^3) * for t in [0, 1], x in [0, 1], with initial conditions * u(0,x) = u_0 - * and Dirichlet boundary condition at x=1 + * and Dirichlet boundary conditions at x=0 and x=1 * u(0,t) = u(1,t) = u_0 * * The spatial derivatives are computed using second-order diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 7e6915652f..492443b691 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -125,7 +125,7 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) In ForcingStep, we accumulate the RHS functions in ARK_FULLRHS_OTHER mode. Generally, inner steppers will not have the correct yn when this function is called and will not be able to reuse a function evaluation since their state - resets at the next ARKodeEvolve call. + resets at the next SUNStepper_Evolve call. ----------------------------------------------------------------------------*/ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const N_Vector y, const N_Vector f, diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 15ae7aff88..e76b4eaa16 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -196,7 +196,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) In SplittingStep, we accumulate the RHS functions in ARK_FULLRHS_OTHER mode. Generally, inner steppers will not have the correct yn when this function is called and will not be able to reuse a function evaluation since their state - resets at the next ARKodeEvolve call. + resets at the next SUNStepper_Evolve call. ----------------------------------------------------------------------------*/ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const N_Vector y, const N_Vector f, diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c index 887e92d57f..cfcd2da1ed 100644 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ b/src/arkode/execution_policy/arkode_execution_policy_serial.c @@ -43,7 +43,7 @@ static int execute_serial( const N_Vector tmp, sunrealtype* const alpha, const int sequential_methods, void* const user_data) { - N_VScale(1, yn, ycur); + N_VScale(SUN_RCONST(1.0), yn, ycur); int retval = fn(0, ycur, user_data); if (retval != ARK_SUCCESS) { return retval; } diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index 654364d601..0037e976d4 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -44,7 +44,7 @@ static int f_forward_2(const sunrealtype t, const N_Vector y, /* Integrates the ODE * - * y' = [t / y] - [1 / y] + * y' = [t / y] + [1 / y] * * with initial condition y(0) = 1 and partitioning specified by the square * brackets. We integrate to t = 1 and check the error against the exact @@ -132,4 +132,4 @@ int main() else { printf("%d Test Failures\n", err); } return 0; -} \ No newline at end of file +} From dc6127871db8d36bebd2e7c8085868068b533562 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:15:25 -0700 Subject: [PATCH 099/180] Remove SplittingStepCreate todo --- include/arkode/arkode_splittingstep.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 880d9de75f..1dcf2f6e9a 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -27,8 +27,6 @@ extern "C" { #endif -/* TODO(SBR): would (t0, y0, steppers, partitions, sunctx) be a better arg - order? That would be more consistent with MRIStep but less with others */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx); From bc6b2af9821cadc147bea0b789f53f5754919834 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:16:02 -0700 Subject: [PATCH 100/180] Remove coefficient order todo --- include/arkode/arkode_splittingstep_coefficients.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/arkode/arkode_splittingstep_coefficients.h b/include/arkode/arkode_splittingstep_coefficients.h index 543ab9a7bf..33cd5d0b2f 100644 --- a/include/arkode/arkode_splittingstep_coefficients.h +++ b/include/arkode/arkode_splittingstep_coefficients.h @@ -36,7 +36,6 @@ struct SplittingStepCoefficientsMem int sequential_methods; /* number of sequential splitting methods */ int stages; /* number of stages within each sequential splitting method */ int partitions; /* number of RHS partitions */ - /* TODO(SBR): q to be more consistent? */ int order; /* order of convergence */ }; From 8fc99ed7f94f42e250c64b8412b1b1a0b355a2c9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:18:09 -0700 Subject: [PATCH 101/180] Remove unnecessary includes --- src/arkode/arkode_forcingstep.c | 1 - src/arkode/arkode_splittingstep.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 7e6915652f..2fba65b40a 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -20,7 +20,6 @@ #include "arkode_forcingstep_impl.h" #include "arkode_impl.h" -#include "arkode_mristep_impl.h" /*--------------------------------------------------------------- Shortcut routine to unpack step_mem structure from ark_mem. diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 15ae7aff88..5da51fc663 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -21,7 +21,6 @@ #include #include "arkode_impl.h" -#include "arkode_mristep_impl.h" #include "arkode_splittingstep_impl.h" /*--------------------------------------------------------------- From 1b13066fabcd78a4c55dfbf5cb59e5a3e7213c69 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:20:22 -0700 Subject: [PATCH 102/180] Remove fixed step validation todo --- src/arkode/arkode_splittingstep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 5da51fc663..347aa577ce 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -144,7 +144,6 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) } /* assume fixed outer step size */ - /* TODO(SBR): Should this validation be done by ARKODE? */ if (!ark_mem->fixedstep) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, From 1629e58498442a334a60103b006c1a92515b5702 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:28:56 -0700 Subject: [PATCH 103/180] Add inner stepper stats to partitioned analytic test problem --- .../C_serial/ark_analytic_partitioned.c | 10 ++++- .../ark_analytic_partitioned_forcing.out | 41 +++++++++++++++++- .../ark_analytic_partitioned_splitting.out | 41 +++++++++++++++++- ..._splitting_ARKODE_SPLITTING_BEST_2_2_2.out | 41 +++++++++++++++++- ..._splitting_ARKODE_SPLITTING_RUTH_3_3_2.out | 43 ++++++++++++++++++- ...litting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out | 41 +++++++++++++++++- 6 files changed, 210 insertions(+), 7 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 6c6c41a3cf..930d1c5acb 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -236,10 +236,18 @@ int main(const int argc, char* const argv[]) N_VLinearSum(SUN_RCONST(1.0), y, -SUN_RCONST(1.0), y_exact, y_err); printf("\nError: %" GSYM "\n", N_VMaxNorm(y_err)); - printf("Final Solver Statistics:\n"); + printf("\nSplitting Stepper Statistics:\n"); flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + printf("\nLinear Stepper Statistics:\n"); + flag = ARKodePrintAllStats(linear_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + printf("\nNonlinear Stepper Statistics:\n"); + flag = ARKodePrintAllStats(nonlinear_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + /* Free memory */ N_VDestroy(y); N_VDestroy(y_exact); diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out index 8360493c92..345ef5752e 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out @@ -4,7 +4,8 @@ Analytical ODE test problem: lambda = 2 Error: 0.00185186 -Final Solver Statistics: + +Splitting Stepper Statistics: Current time = 1.000000000000001 Steps = 100 Step attempts = 100 @@ -18,3 +19,41 @@ Last step size = 0.01 Current step size = 0.01 Partition 0 evolves = 100 Partition 1 evolves = 100 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 500 +Step attempts = 500 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.002 +Current step size = 0.002 +Explicit RHS fn evals = 2500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1000 +Step attempts = 1000 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.001 +Current step size = 0.001 +Explicit RHS fn evals = 5000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out index deb36c804b..86b8a99bd9 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out @@ -4,7 +4,8 @@ Analytical ODE test problem: lambda = 2 Error: 0.001796 -Final Solver Statistics: + +Splitting Stepper Statistics: Current time = 1.000000000000001 Steps = 100 Step attempts = 100 @@ -18,3 +19,41 @@ Last step size = 0.01 Current step size = 0.01 Partition 0 evolves = 100 Partition 1 evolves = 100 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 500 +Step attempts = 500 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.002 +Current step size = 0.002 +Explicit RHS fn evals = 2500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1000 +Step attempts = 1000 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.001 +Current step size = 0.001 +Explicit RHS fn evals = 5000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out index e38f4de508..4f93ca0df2 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out @@ -5,7 +5,8 @@ Analytical ODE test problem: lambda = 2 Error: 7.26922e-07 -Final Solver Statistics: + +Splitting Stepper Statistics: Current time = 1.000000000000001 Steps = 100 Step attempts = 100 @@ -19,3 +20,41 @@ Last step size = 0.01 Current step size = 0.01 Partition 0 evolves = 200 Partition 1 evolves = 200 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 600 +Step attempts = 600 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.0010710678118655 +Current step size = 0.002 +Explicit RHS fn evals = 3000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1100 +Step attempts = 1100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.0009289321881345005 +Current step size = 0.001 +Explicit RHS fn evals = 5500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out index 8c6b193f33..a5377ee61f 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out @@ -4,8 +4,9 @@ Analytical ODE test problem: coefficients = ARKODE_SPLITTING_RUTH_3_3_2 lambda = 2 -Error: 6.72016e-09 -Final Solver Statistics: +Error: 6.71891e-09 + +Splitting Stepper Statistics: Current time = 1.000000000000001 Steps = 100 Step attempts = 100 @@ -19,3 +20,41 @@ Last step size = 0.01 Current step size = 0.01 Partition 0 evolves = 300 Partition 1 evolves = 300 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1300 +Step attempts = 1300 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.0006666666666667037 +Current step size = 0.002 +Explicit RHS fn evals = 6500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1200 +Step attempts = 1200 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.0009166666666666759 +Current step size = 0.001 +Explicit RHS fn evals = 6000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out index d3a022d248..f361147975 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out @@ -5,7 +5,8 @@ Analytical ODE test problem: lambda = 2 Error: 1.4436e-12 -Final Solver Statistics: + +Splitting Stepper Statistics: Current time = 1.000000000000001 Steps = 100 Step attempts = 100 @@ -19,3 +20,41 @@ Last step size = 0.01 Current step size = 0.01 Partition 0 evolves = 1000 Partition 1 evolves = 900 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 2200 +Step attempts = 2200 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.001936124638611257 +Current step size = 0.002 +Explicit RHS fn evals = 11000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 16500 +Step attempts = 16500 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.0008722492772224025 +Current step size = 0.001 +Explicit RHS fn evals = 82500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 From d61f268f5092b274f6f1715383968072cc4ff4a7 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:32:52 -0700 Subject: [PATCH 104/180] Fix splitting step nvector check --- src/arkode/arkode_splittingstep.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 9db987602e..14369c4272 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -68,9 +68,7 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, ---------------------------------------------------------------*/ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) { - // TODO(SBR): check all ops are correct - return y->ops->nvdestroy != NULL && y->ops->nvlinearsum != NULL && - y->ops->nvscale != NULL; + return y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; } /*--------------------------------------------------------------- From eb3ad2acc5220668fe16b96e5d124fd7b3be0726 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 13:50:57 -0700 Subject: [PATCH 105/180] Remove coefficients headed --- .../SplittingStepCoefficients.rst | 2 +- include/arkode/arkode_execution_policy.h | 2 + include/arkode/arkode_splittingstep.h | 75 +- .../arkode_splittingstep_coefficients.h | 101 --- .../arkode_splittingstep_coefficients.c | 2 +- .../fmod_int32/farkode_splittingstep_mod.c | 476 ++++++++++- .../fmod_int32/farkode_splittingstep_mod.f90 | 801 +++++++++++++++++- .../fmod_int64/farkode_splittingstep_mod.c | 476 ++++++++++- .../fmod_int64/farkode_splittingstep_mod.f90 | 801 +++++++++++++++++- .../ark_test_splittingstep_coefficients.c | 2 +- 10 files changed, 2504 insertions(+), 234 deletions(-) delete mode 100644 include/arkode/arkode_splittingstep_coefficients.h diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 747dc6a9cd..9f6972c614 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -73,7 +73,7 @@ SplittingStepCoefficients Functions This section describes the functions for creating and interacting with operator splitting coefficients. The function prototypes and as well as the relevant -integer constants are defined ``arkode/arkode_splittingstep_coefficients.h``. +integer constants are defined ``arkode/arkode_splittingstep.h``. .. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Functions.Table: .. table:: SplittingStepCoefficients functions diff --git a/include/arkode/arkode_execution_policy.h b/include/arkode/arkode_execution_policy.h index 1897dc333c..526b27d3f3 100644 --- a/include/arkode/arkode_execution_policy.h +++ b/include/arkode/arkode_execution_policy.h @@ -21,6 +21,8 @@ extern "C" { #endif +#include + /* Parallelization Policy */ typedef int (*ARKExecutionPolicyFn)(int i, N_Vector y, void* user_data); diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 1dcf2f6e9a..a5cddb838b 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -18,7 +18,6 @@ #define ARKODE_SPLITTINGSTEP_H_ #include -#include #include #include #include @@ -27,15 +26,79 @@ extern "C" { #endif +/*--------------------------------------------------------------- + Types : struct SplittingStepCoefficientsMem, SplittingStepCoefficients + ---------------------------------------------------------------*/ +struct SplittingStepCoefficientsMem +{ + sunrealtype* alpha; /* weights for sum over sequential splitting methods */ + sunrealtype*** beta; /* subintegration nodes, indexed by the sequential method, stage, and partition */ + int sequential_methods; /* number of sequential splitting methods */ + int stages; /* number of stages within each sequential splitting method */ + int partitions; /* number of RHS partitions */ + int order; /* order of convergence */ +}; + +typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; + +/* Splitting names use the convention + * ARKODE_SPLITTING____ */ +typedef enum +{ + ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ + ARKODE_MIN_SPLITTING_NUM = 0, + ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM, + ARKODE_SPLITTING_STRANG_2_2_2, + ARKODE_SPLITTING_BEST_2_2_2, + ARKODE_SPLITTING_SUZUKI_3_3_2, + ARKODE_SPLITTING_RUTH_3_3_2, + ARKODE_SPLITTING_YOSHIDA_4_4_2, + ARKODE_SPLITTING_YOSHIDA_8_6_2, + ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_8_6_2 +} ARKODE_SplittingCoefficientsID; + +/* Coefficient memory management */ +SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( + int sequential_methods, int stages, int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( + int sequential_methods, int stages, int partitions, int order, + sunrealtype* alpha, sunrealtype* beta); +SUNDIALS_EXPORT void SplittingStepCoefficients_Free( + SplittingStepCoefficients coefficients); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients); +SUNDIALS_EXPORT void SplittingStepCoefficients_Write( + SplittingStepCoefficients coefficients, FILE* outfile); + +/* Load splitting coefficients */ +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID id); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LoadCoefficientsByName(const char* name); +SUNDIALS_EXPORT const char* SplittingStepCoefficients_IDToName( + ARKODE_SplittingCoefficientsID id); + +/* Constructors for splitting coefficients */ +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_LieTrotter(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Strang(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_Parallel(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_SymmetricParallel(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_ThirdOrderSuzuki(int partitions); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_TripleJump(int partitions, int order); +SUNDIALS_EXPORT SplittingStepCoefficients +SplittingStepCoefficients_SuzukiFractal(int partitions, int order); + +/* Functions for SplittingStep integrator */ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, N_Vector y0, SUNContext sunctx); -SUNDIALS_EXPORT int SplittingStepCreateForcing(SUNStepper stepper1, - SUNStepper stepper2, - sunrealtype t0, N_Vector y0, - SUNContext sunctx); - SUNDIALS_EXPORT int SplittingStep_SetCoefficients( void* arkode_mem, SplittingStepCoefficients coefficients); diff --git a/include/arkode/arkode_splittingstep_coefficients.h b/include/arkode/arkode_splittingstep_coefficients.h deleted file mode 100644 index 33cd5d0b2f..0000000000 --- a/include/arkode/arkode_splittingstep_coefficients.h +++ /dev/null @@ -1,101 +0,0 @@ -/* TODO(SBR): merge this header into arkode_splittingstep.h? MRI uses one header, but ARK/SPRK uses two */ - -/* ----------------------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------------------- -* This is the header file for ARKode splitting coefficient structures. - * ---------------------------------------------------------------------------*/ - -#ifndef ARKODE_SPLITTINGSTEP_COEFFICIENTS_H_ -#define ARKODE_SPLITTINGSTEP_COEFFICIENTS_H_ - -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*--------------------------------------------------------------- - Types : struct SplittingStepCoefficientsMem, SplittingStepCoefficients - ---------------------------------------------------------------*/ -struct SplittingStepCoefficientsMem -{ - sunrealtype* alpha; /* weights for sum over sequential splitting methods */ - sunrealtype*** beta; /* subintegration nodes, indexed by the sequential method, stage, and partition */ - int sequential_methods; /* number of sequential splitting methods */ - int stages; /* number of stages within each sequential splitting method */ - int partitions; /* number of RHS partitions */ - int order; /* order of convergence */ -}; - -typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; - -/* Splitting names use the convention - * ARKODE_SPLITTING____ */ -typedef enum -{ - ARKODE_SPLITTING_NONE = -1, /* ensure enum is signed int */ - ARKODE_MIN_SPLITTING_NUM = 0, - ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM, - ARKODE_SPLITTING_STRANG_2_2_2, - ARKODE_SPLITTING_BEST_2_2_2, - ARKODE_SPLITTING_SUZUKI_3_3_2, - ARKODE_SPLITTING_RUTH_3_3_2, - ARKODE_SPLITTING_YOSHIDA_4_4_2, - ARKODE_SPLITTING_YOSHIDA_8_6_2, - ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_8_6_2 -} ARKODE_SplittingCoefficientsID; - -/* Coefficient memory management */ -SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( - int sequential_methods, int stages, int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( - int sequential_methods, int stages, int partitions, int order, - sunrealtype* alpha, sunrealtype* beta); -SUNDIALS_EXPORT void SplittingStepCoefficients_Free( - SplittingStepCoefficients coefficients); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients); -SUNDIALS_EXPORT void SplittingStepCoefficients_Write( - SplittingStepCoefficients coefficients, FILE* outfile); - -/* Load splitting coefficients */ -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID id); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_LoadCoefficientsByName(const char* name); -SUNDIALS_EXPORT const char* SplittingStepCoefficients_IDToName( - ARKODE_SplittingCoefficientsID id); - -/* Constructors for splitting coefficients */ -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_LieTrotter(int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_Strang(int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_Parallel(int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_SymmetricParallel(int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_ThirdOrderSuzuki(int partitions); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_TripleJump(int partitions, int order); -SUNDIALS_EXPORT SplittingStepCoefficients -SplittingStepCoefficients_SuzukiFractal(int partitions, int order); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index 7d45abbf48..7837b8dc64 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -14,7 +14,7 @@ * This is the implementation file for splitting coefficients *--------------------------------------------------------------*/ -#include +#include #include #include "arkode_impl.h" diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.c b/src/arkode/fmod_int32/farkode_splittingstep_mod.c index e0bb4d8ddf..1025d29cca 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.c @@ -202,6 +202,11 @@ enum { } +#define SWIG_check_mutable_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL); \ + SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL); + + #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -243,6 +248,449 @@ SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { return result; } + +#include +#ifdef _MSC_VER +# ifndef strtoull +# define strtoull _strtoui64 +# endif +# ifndef strtoll +# define strtoll _strtoi64 +# endif +#endif + + +#include + + +SWIGINTERN void SWIG_assign(SwigClassWrapper* self, SwigClassWrapper other) { + if (self->cptr == NULL) { + /* LHS is unassigned */ + if (other.cmemflags & SWIG_MEM_RVALUE) { + /* Capture pointer from RHS, clear 'moving' flag */ + self->cptr = other.cptr; + self->cmemflags = other.cmemflags & (~SWIG_MEM_RVALUE); + } else { + /* Become a reference to the other object */ + self->cptr = other.cptr; + self->cmemflags = other.cmemflags & (~SWIG_MEM_OWN); + } + } else if (other.cptr == NULL) { + /* Replace LHS with a null pointer */ + free(self->cptr); + *self = SwigClassWrapper_uninitialized(); + } else { + if (self->cmemflags & SWIG_MEM_OWN) { + free(self->cptr); + } + self->cptr = other.cptr; + if (other.cmemflags & SWIG_MEM_RVALUE) { + /* Capture RHS */ + self->cmemflags = other.cmemflags & ~SWIG_MEM_RVALUE; + } else { + /* Point to RHS */ + self->cmemflags = other.cmemflags & ~SWIG_MEM_OWN; + } + } +} + + +typedef struct { + void* data; + size_t size; +} SwigArrayWrapper; + + +SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() { + SwigArrayWrapper result; + result.data = NULL; + result.size = 0; + return result; +} + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_alpha_set(SwigClassWrapper const *farg1, double *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::alpha", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (sunrealtype *)(farg2); + if (arg1) (arg1)->alpha = arg2; +} + + +SWIGEXPORT double * _wrap_SplittingStepCoefficientsMem_alpha_get(SwigClassWrapper const *farg1) { + double * fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype *result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::alpha", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (sunrealtype *) ((arg1)->alpha); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_beta_set(SwigClassWrapper const *farg1, void *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype ***arg2 = (sunrealtype ***) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::beta", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (sunrealtype ***)(farg2); + if (arg1) (arg1)->beta = arg2; +} + + +SWIGEXPORT void * _wrap_SplittingStepCoefficientsMem_beta_get(SwigClassWrapper const *farg1) { + void * fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype ***result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::beta", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (sunrealtype ***) ((arg1)->beta); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_sequential_methods_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::sequential_methods", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->sequential_methods = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_sequential_methods_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::sequential_methods", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->sequential_methods); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_stages_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::stages", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->stages = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_stages_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::stages", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->stages); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_partitions_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::partitions", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->partitions = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_partitions_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::partitions", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->partitions); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_order_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::order", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->order = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_order_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::order", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->order); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_new_SplittingStepCoefficientsMem() { + SwigClassWrapper fresult ; + struct SplittingStepCoefficientsMem *result = 0 ; + + result = (struct SplittingStepCoefficientsMem *)calloc(1, sizeof(struct SplittingStepCoefficientsMem)); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (1 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_delete_SplittingStepCoefficientsMem(SwigClassWrapper *farg1) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + + SWIG_check_mutable(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::~SplittingStepCoefficientsMem()", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + free((char *) arg1); +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_op_assign__(SwigClassWrapper *farg1, SwigClassWrapper const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + struct SplittingStepCoefficientsMem *arg2 = 0 ; + + (void)sizeof(arg1); + (void)sizeof(arg2); + SWIG_assign(farg1, *farg2); + +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Alloc(int const *farg1, int const *farg2, int const *farg3) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + int arg3 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + arg3 = (int)(*farg3); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Alloc(arg1,arg2,arg3); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Create(int const *farg1, int const *farg2, int const *farg3, int const *farg4, double *farg5, double *farg6) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + int arg3 ; + int arg4 ; + sunrealtype *arg5 = (sunrealtype *) 0 ; + sunrealtype *arg6 = (sunrealtype *) 0 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + arg3 = (int)(*farg3); + arg4 = (int)(*farg4); + arg5 = (sunrealtype *)(farg5); + arg6 = (sunrealtype *)(farg6); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Create(arg1,arg2,arg3,arg4,arg5,arg6); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Free(SwigClassWrapper const *farg1) { + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Free(SplittingStepCoefficients)", return ); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + SplittingStepCoefficients_Free(arg1); +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Copy(SwigClassWrapper const *farg1) { + SwigClassWrapper fresult ; + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + SplittingStepCoefficients result; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Copy(SplittingStepCoefficients)", return SwigClassWrapper_uninitialized()); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Copy(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Write(SwigClassWrapper const *farg1, void *farg2) { + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + FILE *arg2 = (FILE *) 0 ; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Write(SplittingStepCoefficients,FILE *)", return ); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + arg2 = (FILE *)(farg2); + SplittingStepCoefficients_Write(arg1,arg2); +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LoadCoefficients(int const *farg1) { + SwigClassWrapper fresult ; + ARKODE_SplittingCoefficientsID arg1 ; + SplittingStepCoefficients result; + + arg1 = (ARKODE_SplittingCoefficientsID)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LoadCoefficients(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LoadCoefficientsByName(SwigArrayWrapper *farg1) { + SwigClassWrapper fresult ; + char *arg1 = (char *) 0 ; + SplittingStepCoefficients result; + + arg1 = (char *)(farg1->data); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LoadCoefficientsByName((char const *)arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigArrayWrapper _wrap_FSplittingStepCoefficients_IDToName(int const *farg1) { + SwigArrayWrapper fresult ; + ARKODE_SplittingCoefficientsID arg1 ; + char *result = 0 ; + + arg1 = (ARKODE_SplittingCoefficientsID)(*farg1); + result = (char *)SplittingStepCoefficients_IDToName(arg1); + fresult.size = strlen((const char*)(result)); + fresult.data = (char *)(result); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LieTrotter(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LieTrotter(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Strang(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Strang(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Parallel(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Parallel(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SymmetricParallel(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_SymmetricParallel(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_ThirdOrderSuzuki(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_ThirdOrderSuzuki(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_TripleJump(int const *farg1, int const *farg2) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + result = (SplittingStepCoefficients)SplittingStepCoefficients_TripleJump(arg1,arg2); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SuzukiFractal(int const *farg1, int const *farg2) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + result = (SplittingStepCoefficients)SplittingStepCoefficients_SuzukiFractal(arg1,arg2); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; SUNStepper *arg1 = (SUNStepper *) 0 ; @@ -264,37 +712,15 @@ SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int } -SWIGEXPORT int _wrap_FSplittingStepCreateForcing(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { - int fresult ; - SUNStepper arg1 ; - SUNStepper arg2 ; - sunrealtype arg3 ; - N_Vector arg4 = (N_Vector) 0 ; - SUNContext arg5 = (SUNContext) 0 ; - int result; - - SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = *(SUNStepper *)(farg1->cptr); - SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg2 = *(SUNStepper *)(farg2->cptr); - arg3 = (sunrealtype)(*farg3); - arg4 = (N_Vector)(farg4); - arg5 = (SUNContext)(farg5); - result = (int)SplittingStepCreateForcing(arg1,arg2,arg3,arg4,arg5); - fresult = (int)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrapper const *farg2) { int fresult ; void *arg1 = (void *) 0 ; - SplittingStepCoefficients arg2 ; + SplittingStepCoefficients arg2 = (SplittingStepCoefficients) 0 ; int result; arg1 = (void *)(farg1); - SWIG_check_nonnull(*farg2, "SplittingStepCoefficients", "SWIGTYPE_p_SplittingStepCoefficients", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); - arg2 = *(SplittingStepCoefficients *)(farg2->cptr); + SWIG_check_mutable(*farg2, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); + arg2 = (SplittingStepCoefficients)(farg2->cptr); result = (int)SplittingStep_SetCoefficients(arg1,arg2); fresult = (int)(result); return fresult; diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 index 7cc2d19050..010112b6cb 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 @@ -34,14 +34,69 @@ module farkode_splittingstep_mod type(C_PTR), public :: cptr = C_NULL_PTR integer(C_INT), public :: cmemflags = 0 end type - type, public :: SWIGTYPE_p_SUNStepper + ! struct struct SplittingStepCoefficientsMem + type, public :: SplittingStepCoefficientsMem type(SwigClassWrapper), public :: swigdata + contains + procedure :: set_alpha => swigf_SplittingStepCoefficientsMem_alpha_set + procedure :: get_alpha => swigf_SplittingStepCoefficientsMem_alpha_get + procedure :: set_beta => swigf_SplittingStepCoefficientsMem_beta_set + procedure :: get_beta => swigf_SplittingStepCoefficientsMem_beta_get + procedure :: set_sequential_methods => swigf_SplittingStepCoefficientsMem_sequential_methods_set + procedure :: get_sequential_methods => swigf_SplittingStepCoefficientsMem_sequential_methods_get + procedure :: set_stages => swigf_SplittingStepCoefficientsMem_stages_set + procedure :: get_stages => swigf_SplittingStepCoefficientsMem_stages_get + procedure :: set_partitions => swigf_SplittingStepCoefficientsMem_partitions_set + procedure :: get_partitions => swigf_SplittingStepCoefficientsMem_partitions_get + procedure :: set_order => swigf_SplittingStepCoefficientsMem_order_set + procedure :: get_order => swigf_SplittingStepCoefficientsMem_order_get + procedure :: release => swigf_release_SplittingStepCoefficientsMem + procedure, private :: swigf_SplittingStepCoefficientsMem_op_assign__ + generic :: assignment(=) => swigf_SplittingStepCoefficientsMem_op_assign__ + end type SplittingStepCoefficientsMem + interface SplittingStepCoefficientsMem + module procedure swigf_create_SplittingStepCoefficientsMem + end interface + ! typedef enum ARKODE_SplittingCoefficientsID + enum, bind(c) + enumerator :: ARKODE_SPLITTING_NONE = -1 + enumerator :: ARKODE_MIN_SPLITTING_NUM = 0 + enumerator :: ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM + enumerator :: ARKODE_SPLITTING_STRANG_2_2_2 + enumerator :: ARKODE_SPLITTING_BEST_2_2_2 + enumerator :: ARKODE_SPLITTING_SUZUKI_3_3_2 + enumerator :: ARKODE_SPLITTING_RUTH_3_3_2 + enumerator :: ARKODE_SPLITTING_YOSHIDA_4_4_2 + enumerator :: ARKODE_SPLITTING_YOSHIDA_8_6_2 + enumerator :: ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_8_6_2 + end enum + integer, parameter, public :: ARKODE_SplittingCoefficientsID = kind(ARKODE_SPLITTING_NONE) + public :: ARKODE_SPLITTING_NONE, ARKODE_MIN_SPLITTING_NUM, ARKODE_SPLITTING_LIE_TROTTER_1_1_2, ARKODE_SPLITTING_STRANG_2_2_2, & + ARKODE_SPLITTING_BEST_2_2_2, ARKODE_SPLITTING_SUZUKI_3_3_2, ARKODE_SPLITTING_RUTH_3_3_2, ARKODE_SPLITTING_YOSHIDA_4_4_2, & + ARKODE_SPLITTING_YOSHIDA_8_6_2, ARKODE_MAX_SPLITTING_NUM + public :: FSplittingStepCoefficients_Alloc + public :: FSplittingStepCoefficients_Create + public :: FSplittingStepCoefficients_Free + public :: FSplittingStepCoefficients_Copy + public :: FSplittingStepCoefficients_Write + public :: FSplittingStepCoefficients_LoadCoefficients + type, bind(C) :: SwigArrayWrapper + type(C_PTR), public :: data = C_NULL_PTR + integer(C_SIZE_T), public :: size = 0 end type - public :: FSplittingStepCreate - public :: FSplittingStepCreateForcing - type, public :: SWIGTYPE_p_SplittingStepCoefficients + public :: FSplittingStepCoefficients_LoadCoefficientsByName + public :: FSplittingStepCoefficients_IDToName + public :: FSplittingStepCoefficients_LieTrotter + public :: FSplittingStepCoefficients_Strang + public :: FSplittingStepCoefficients_Parallel + public :: FSplittingStepCoefficients_SymmetricParallel + public :: FSplittingStepCoefficients_ThirdOrderSuzuki + public :: FSplittingStepCoefficients_TripleJump + public :: FSplittingStepCoefficients_SuzukiFractal + type, public :: SWIGTYPE_p_SUNStepper type(SwigClassWrapper), public :: swigdata end type + public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy type(SwigClassWrapper), public :: swigdata @@ -51,30 +106,289 @@ module farkode_splittingstep_mod ! WRAPPER DECLARATIONS interface -function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSplittingStepCreate") & +subroutine swigc_SplittingStepCoefficientsMem_alpha_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_alpha_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_alpha_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_alpha_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 -integer(C_INT), intent(in) :: farg2 -real(C_DOUBLE), intent(in) :: farg3 -type(C_PTR), value :: farg4 -type(C_PTR), value :: farg5 type(C_PTR) :: fresult end function -function swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSplittingStepCreateForcing") & +subroutine swigc_SplittingStepCoefficientsMem_beta_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_beta_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_beta_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_beta_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_sequential_methods_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_sequential_methods_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_sequential_methods_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_sequential_methods_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_stages_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_stages_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_stages_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_stages_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_partitions_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_partitions_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_partitions_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_partitions_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_order_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_order_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_order_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_order_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +function swigc_new_SplittingStepCoefficientsMem() & +bind(C, name="_wrap_new_SplittingStepCoefficientsMem") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_delete_SplittingStepCoefficientsMem(farg1) & +bind(C, name="_wrap_delete_SplittingStepCoefficientsMem") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper), intent(inout) :: farg1 +end subroutine + +subroutine swigc_SplittingStepCoefficientsMem_op_assign__(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_op_assign__") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper), intent(inout) :: farg1 type(SwigClassWrapper) :: farg2 +end subroutine + +function swigc_FSplittingStepCoefficients_Alloc(farg1, farg2, farg3) & +bind(C, name="_wrap_FSplittingStepCoefficients_Alloc") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT), intent(in) :: farg3 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, farg5, farg6) & +bind(C, name="_wrap_FSplittingStepCoefficients_Create") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT), intent(in) :: farg3 +integer(C_INT), intent(in) :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR), value :: farg6 +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_FSplittingStepCoefficients_Free(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Free") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +end subroutine + +function swigc_FSplittingStepCoefficients_Copy(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Copy") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_FSplittingStepCoefficients_Write(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_Write") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_FSplittingStepCoefficients_LoadCoefficients(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LoadCoefficients") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_LoadCoefficientsByName(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LoadCoefficientsByName") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +import :: swigarraywrapper +type(SwigArrayWrapper) :: farg1 +type(SwigClassWrapper) :: fresult +end function + + subroutine SWIG_free(cptr) & + bind(C, name="free") + use, intrinsic :: ISO_C_BINDING + type(C_PTR), value :: cptr +end subroutine +function swigc_FSplittingStepCoefficients_IDToName(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_IDToName") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigarraywrapper +integer(C_INT), intent(in) :: farg1 +type(SwigArrayWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_LieTrotter(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LieTrotter") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Strang(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Strang") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Parallel(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Parallel") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_SymmetricParallel(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_SymmetricParallel") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_ThirdOrderSuzuki(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_ThirdOrderSuzuki") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_TripleJump(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_TripleJump") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_SuzukiFractal(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_SuzukiFractal") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 type(C_PTR), value :: farg5 -integer(C_INT) :: fresult +type(C_PTR) :: fresult end function function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & @@ -112,53 +426,466 @@ function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & contains ! MODULE SUBPROGRAMS -function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +subroutine swigf_SplittingStepCoefficientsMem_alpha_set(self, alpha) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +real(C_DOUBLE), dimension(*), target, intent(inout) :: alpha +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(alpha(1)) +call swigc_SplittingStepCoefficientsMem_alpha_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_alpha_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING -type(C_PTR) :: swig_result -class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers -integer(C_INT), intent(in) :: partitions -real(C_DOUBLE), intent(in) :: t0 -type(N_Vector), target, intent(inout) :: y0 -type(C_PTR) :: sunctx +real(C_DOUBLE), dimension(:), pointer :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self type(C_PTR) :: fresult type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_alpha_get(farg1) +call c_f_pointer(fresult, swig_result, [1]) +end function + +subroutine swigf_SplittingStepCoefficientsMem_beta_set(self, beta) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +type(C_PTR), target, intent(inout) :: beta +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(beta) +call swigc_SplittingStepCoefficientsMem_beta_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_beta_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), pointer :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_beta_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SplittingStepCoefficientsMem_sequential_methods_set(self, sequential_methods) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: sequential_methods +type(SwigClassWrapper) :: farg1 integer(C_INT) :: farg2 -real(C_DOUBLE) :: farg3 -type(C_PTR) :: farg4 -type(C_PTR) :: farg5 -farg1 = steppers%swigdata +farg1 = self%swigdata +farg2 = sequential_methods +call swigc_SplittingStepCoefficientsMem_sequential_methods_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_sequential_methods_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_sequential_methods_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SplittingStepCoefficientsMem_stages_set(self, stages) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: stages +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = stages +call swigc_SplittingStepCoefficientsMem_stages_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_stages_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_stages_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SplittingStepCoefficientsMem_partitions_set(self, partitions) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata farg2 = partitions -farg3 = t0 -farg4 = c_loc(y0) -farg5 = sunctx -fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) +call swigc_SplittingStepCoefficientsMem_partitions_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_partitions_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_partitions_get(farg1) swig_result = fresult end function -function FSplittingStepCreateForcing(stepper1, stepper2, t0, y0, sunctx) & +subroutine swigf_SplittingStepCoefficientsMem_order_set(self, order) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = order +call swigc_SplittingStepCoefficientsMem_order_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_order_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_order_get(farg1) +swig_result = fresult +end function + +function swigf_create_SplittingStepCoefficientsMem() & +result(self) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: self +type(SwigClassWrapper) :: fresult + +fresult = swigc_new_SplittingStepCoefficientsMem() +self%swigdata = fresult +end function + +subroutine swigf_release_SplittingStepCoefficientsMem(self) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(inout) :: self +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +if (btest(farg1%cmemflags, swig_cmem_own_bit)) then +call swigc_delete_SplittingStepCoefficientsMem(farg1) +endif +farg1%cptr = C_NULL_PTR +farg1%cmemflags = 0 +self%swigdata = farg1 +end subroutine + +subroutine swigf_SplittingStepCoefficientsMem_op_assign__(self, other) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(inout) :: self +type(SplittingStepCoefficientsMem), intent(in) :: other +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = self%swigdata +farg2 = other%swigdata +call swigc_SplittingStepCoefficientsMem_op_assign__(farg1, farg2) +self%swigdata = farg1 +end subroutine + +function FSplittingStepCoefficients_Alloc(sequential_methods, stages, partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: sequential_methods +integer(C_INT), intent(in) :: stages +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 +integer(C_INT) :: farg3 + +farg1 = sequential_methods +farg2 = stages +farg3 = partitions +fresult = swigc_FSplittingStepCoefficients_Alloc(farg1, farg2, farg3) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Create(sequential_methods, stages, partitions, order, alpha, beta) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: sequential_methods +integer(C_INT), intent(in) :: stages +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +real(C_DOUBLE), dimension(*), target, intent(inout) :: alpha +real(C_DOUBLE), dimension(*), target, intent(inout) :: beta +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 +integer(C_INT) :: farg3 +integer(C_INT) :: farg4 +type(C_PTR) :: farg5 +type(C_PTR) :: farg6 + +farg1 = sequential_methods +farg2 = stages +farg3 = partitions +farg4 = order +farg5 = c_loc(alpha(1)) +farg6 = c_loc(beta(1)) +fresult = swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, farg5, farg6) +swig_result%swigdata = fresult +end function + +subroutine FSplittingStepCoefficients_Free(coefficients) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(SwigClassWrapper) :: farg1 + +farg1 = coefficients%swigdata +call swigc_FSplittingStepCoefficients_Free(farg1) +end subroutine + +function FSplittingStepCoefficients_Copy(coefficients) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(SwigClassWrapper) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = coefficients%swigdata +fresult = swigc_FSplittingStepCoefficients_Copy(farg1) +swig_result%swigdata = fresult +end function + +subroutine FSplittingStepCoefficients_Write(coefficients, outfile) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(C_PTR) :: outfile +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = coefficients%swigdata +farg2 = outfile +call swigc_FSplittingStepCoefficients_Write(farg1, farg2) +end subroutine + +function FSplittingStepCoefficients_LoadCoefficients(id) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(ARKODE_SplittingCoefficientsID), intent(in) :: id +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = id +fresult = swigc_FSplittingStepCoefficients_LoadCoefficients(farg1) +swig_result%swigdata = fresult +end function + + +subroutine SWIG_string_to_chararray(string, chars, wrap) + use, intrinsic :: ISO_C_BINDING + character(kind=C_CHAR, len=*), intent(IN) :: string + character(kind=C_CHAR), dimension(:), target, allocatable, intent(OUT) :: chars + type(SwigArrayWrapper), intent(OUT) :: wrap + integer :: i + + allocate(character(kind=C_CHAR) :: chars(len(string) + 1)) + do i=1,len(string) + chars(i) = string(i:i) + end do + i = len(string) + 1 + chars(i) = C_NULL_CHAR ! C string compatibility + wrap%data = c_loc(chars) + wrap%size = len(string) +end subroutine + +function FSplittingStepCoefficients_LoadCoefficientsByName(name) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +character(kind=C_CHAR, len=*), target :: name +character(kind=C_CHAR), dimension(:), allocatable, target :: farg1_chars +type(SwigClassWrapper) :: fresult +type(SwigArrayWrapper) :: farg1 + +call SWIG_string_to_chararray(name, farg1_chars, farg1) +fresult = swigc_FSplittingStepCoefficients_LoadCoefficientsByName(farg1) +swig_result%swigdata = fresult +end function + + +subroutine SWIG_chararray_to_string(wrap, string) + use, intrinsic :: ISO_C_BINDING + type(SwigArrayWrapper), intent(IN) :: wrap + character(kind=C_CHAR, len=:), allocatable, intent(OUT) :: string + character(kind=C_CHAR), dimension(:), pointer :: chars + integer(kind=C_SIZE_T) :: i + call c_f_pointer(wrap%data, chars, [wrap%size]) + allocate(character(kind=C_CHAR, len=wrap%size) :: string) + do i=1, wrap%size + string(i:i) = chars(i) + end do +end subroutine + +function FSplittingStepCoefficients_IDToName(id) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +character(kind=C_CHAR, len=:), allocatable :: swig_result +integer(ARKODE_SplittingCoefficientsID), intent(in) :: id +type(SwigArrayWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = id +fresult = swigc_FSplittingStepCoefficients_IDToName(farg1) +call SWIG_chararray_to_string(fresult, swig_result) +if (.false.) call SWIG_free(fresult%data) +end function + +function FSplittingStepCoefficients_LieTrotter(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_LieTrotter(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Strang(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_Strang(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Parallel(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_Parallel(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_SymmetricParallel(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_SymmetricParallel(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_ThirdOrderSuzuki(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_ThirdOrderSuzuki(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_TripleJump(partitions, order) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 + +farg1 = partitions +farg2 = order +fresult = swigc_FSplittingStepCoefficients_TripleJump(farg1, farg2) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_SuzukiFractal(partitions, order) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 + +farg1 = partitions +farg2 = order +fresult = swigc_FSplittingStepCoefficients_SuzukiFractal(farg1, farg2) +swig_result%swigdata = fresult +end function + +function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +integer(C_INT), intent(in) :: partitions real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx -integer(C_INT) :: fresult +type(C_PTR) :: fresult type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +integer(C_INT) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = stepper1%swigdata -farg2 = stepper2%swigdata +farg1 = steppers%swigdata +farg2 = partitions farg3 = t0 farg4 = c_loc(y0) farg5 = sunctx -fresult = swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) +fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) swig_result = fresult end function @@ -167,7 +894,7 @@ function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -type(SWIGTYPE_p_SplittingStepCoefficients), intent(in) :: coefficients +class(SplittingStepCoefficientsMem), intent(in) :: coefficients integer(C_INT) :: fresult type(C_PTR) :: farg1 type(SwigClassWrapper) :: farg2 diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.c b/src/arkode/fmod_int64/farkode_splittingstep_mod.c index e0bb4d8ddf..1025d29cca 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.c @@ -202,6 +202,11 @@ enum { } +#define SWIG_check_mutable_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ + SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL); \ + SWIG_check_mutable(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL); + + #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -243,6 +248,449 @@ SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { return result; } + +#include +#ifdef _MSC_VER +# ifndef strtoull +# define strtoull _strtoui64 +# endif +# ifndef strtoll +# define strtoll _strtoi64 +# endif +#endif + + +#include + + +SWIGINTERN void SWIG_assign(SwigClassWrapper* self, SwigClassWrapper other) { + if (self->cptr == NULL) { + /* LHS is unassigned */ + if (other.cmemflags & SWIG_MEM_RVALUE) { + /* Capture pointer from RHS, clear 'moving' flag */ + self->cptr = other.cptr; + self->cmemflags = other.cmemflags & (~SWIG_MEM_RVALUE); + } else { + /* Become a reference to the other object */ + self->cptr = other.cptr; + self->cmemflags = other.cmemflags & (~SWIG_MEM_OWN); + } + } else if (other.cptr == NULL) { + /* Replace LHS with a null pointer */ + free(self->cptr); + *self = SwigClassWrapper_uninitialized(); + } else { + if (self->cmemflags & SWIG_MEM_OWN) { + free(self->cptr); + } + self->cptr = other.cptr; + if (other.cmemflags & SWIG_MEM_RVALUE) { + /* Capture RHS */ + self->cmemflags = other.cmemflags & ~SWIG_MEM_RVALUE; + } else { + /* Point to RHS */ + self->cmemflags = other.cmemflags & ~SWIG_MEM_OWN; + } + } +} + + +typedef struct { + void* data; + size_t size; +} SwigArrayWrapper; + + +SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() { + SwigArrayWrapper result; + result.data = NULL; + result.size = 0; + return result; +} + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_alpha_set(SwigClassWrapper const *farg1, double *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::alpha", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (sunrealtype *)(farg2); + if (arg1) (arg1)->alpha = arg2; +} + + +SWIGEXPORT double * _wrap_SplittingStepCoefficientsMem_alpha_get(SwigClassWrapper const *farg1) { + double * fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype *result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::alpha", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (sunrealtype *) ((arg1)->alpha); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_beta_set(SwigClassWrapper const *farg1, void *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype ***arg2 = (sunrealtype ***) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::beta", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (sunrealtype ***)(farg2); + if (arg1) (arg1)->beta = arg2; +} + + +SWIGEXPORT void * _wrap_SplittingStepCoefficientsMem_beta_get(SwigClassWrapper const *farg1) { + void * fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + sunrealtype ***result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::beta", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (sunrealtype ***) ((arg1)->beta); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_sequential_methods_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::sequential_methods", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->sequential_methods = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_sequential_methods_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::sequential_methods", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->sequential_methods); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_stages_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::stages", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->stages = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_stages_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::stages", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->stages); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_partitions_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::partitions", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->partitions = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_partitions_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::partitions", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->partitions); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_order_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::order", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->order = arg2; +} + + +SWIGEXPORT int _wrap_SplittingStepCoefficientsMem_order_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::order", return 0); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + result = (int) ((arg1)->order); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_new_SplittingStepCoefficientsMem() { + SwigClassWrapper fresult ; + struct SplittingStepCoefficientsMem *result = 0 ; + + result = (struct SplittingStepCoefficientsMem *)calloc(1, sizeof(struct SplittingStepCoefficientsMem)); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (1 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_delete_SplittingStepCoefficientsMem(SwigClassWrapper *farg1) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + + SWIG_check_mutable(*farg1, "struct SplittingStepCoefficientsMem *", "SplittingStepCoefficientsMem", "SplittingStepCoefficientsMem::~SplittingStepCoefficientsMem()", return ); + arg1 = (struct SplittingStepCoefficientsMem *)(farg1->cptr); + free((char *) arg1); +} + + +SWIGEXPORT void _wrap_SplittingStepCoefficientsMem_op_assign__(SwigClassWrapper *farg1, SwigClassWrapper const *farg2) { + struct SplittingStepCoefficientsMem *arg1 = (struct SplittingStepCoefficientsMem *) 0 ; + struct SplittingStepCoefficientsMem *arg2 = 0 ; + + (void)sizeof(arg1); + (void)sizeof(arg2); + SWIG_assign(farg1, *farg2); + +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Alloc(int const *farg1, int const *farg2, int const *farg3) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + int arg3 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + arg3 = (int)(*farg3); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Alloc(arg1,arg2,arg3); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Create(int const *farg1, int const *farg2, int const *farg3, int const *farg4, double *farg5, double *farg6) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + int arg3 ; + int arg4 ; + sunrealtype *arg5 = (sunrealtype *) 0 ; + sunrealtype *arg6 = (sunrealtype *) 0 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + arg3 = (int)(*farg3); + arg4 = (int)(*farg4); + arg5 = (sunrealtype *)(farg5); + arg6 = (sunrealtype *)(farg6); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Create(arg1,arg2,arg3,arg4,arg5,arg6); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Free(SwigClassWrapper const *farg1) { + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Free(SplittingStepCoefficients)", return ); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + SplittingStepCoefficients_Free(arg1); +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Copy(SwigClassWrapper const *farg1) { + SwigClassWrapper fresult ; + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + SplittingStepCoefficients result; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Copy(SplittingStepCoefficients)", return SwigClassWrapper_uninitialized()); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Copy(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Write(SwigClassWrapper const *farg1, void *farg2) { + SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; + FILE *arg2 = (FILE *) 0 ; + + SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Write(SplittingStepCoefficients,FILE *)", return ); + arg1 = (SplittingStepCoefficients)(farg1->cptr); + arg2 = (FILE *)(farg2); + SplittingStepCoefficients_Write(arg1,arg2); +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LoadCoefficients(int const *farg1) { + SwigClassWrapper fresult ; + ARKODE_SplittingCoefficientsID arg1 ; + SplittingStepCoefficients result; + + arg1 = (ARKODE_SplittingCoefficientsID)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LoadCoefficients(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LoadCoefficientsByName(SwigArrayWrapper *farg1) { + SwigClassWrapper fresult ; + char *arg1 = (char *) 0 ; + SplittingStepCoefficients result; + + arg1 = (char *)(farg1->data); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LoadCoefficientsByName((char const *)arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigArrayWrapper _wrap_FSplittingStepCoefficients_IDToName(int const *farg1) { + SwigArrayWrapper fresult ; + ARKODE_SplittingCoefficientsID arg1 ; + char *result = 0 ; + + arg1 = (ARKODE_SplittingCoefficientsID)(*farg1); + result = (char *)SplittingStepCoefficients_IDToName(arg1); + fresult.size = strlen((const char*)(result)); + fresult.data = (char *)(result); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_LieTrotter(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_LieTrotter(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Strang(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Strang(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Parallel(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_Parallel(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SymmetricParallel(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_SymmetricParallel(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_ThirdOrderSuzuki(int const *farg1) { + SwigClassWrapper fresult ; + int arg1 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + result = (SplittingStepCoefficients)SplittingStepCoefficients_ThirdOrderSuzuki(arg1); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_TripleJump(int const *farg1, int const *farg2) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + result = (SplittingStepCoefficients)SplittingStepCoefficients_TripleJump(arg1,arg2); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + +SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SuzukiFractal(int const *farg1, int const *farg2) { + SwigClassWrapper fresult ; + int arg1 ; + int arg2 ; + SplittingStepCoefficients result; + + arg1 = (int)(*farg1); + arg2 = (int)(*farg2); + result = (SplittingStepCoefficients)SplittingStepCoefficients_SuzukiFractal(arg1,arg2); + fresult.cptr = result; + fresult.cmemflags = SWIG_MEM_RVALUE | (0 ? SWIG_MEM_OWN : 0); + return fresult; +} + + SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; SUNStepper *arg1 = (SUNStepper *) 0 ; @@ -264,37 +712,15 @@ SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int } -SWIGEXPORT int _wrap_FSplittingStepCreateForcing(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { - int fresult ; - SUNStepper arg1 ; - SUNStepper arg2 ; - sunrealtype arg3 ; - N_Vector arg4 = (N_Vector) 0 ; - SUNContext arg5 = (SUNContext) 0 ; - int result; - - SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = *(SUNStepper *)(farg1->cptr); - SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "SplittingStepCreateForcing(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg2 = *(SUNStepper *)(farg2->cptr); - arg3 = (sunrealtype)(*farg3); - arg4 = (N_Vector)(farg4); - arg5 = (SUNContext)(farg5); - result = (int)SplittingStepCreateForcing(arg1,arg2,arg3,arg4,arg5); - fresult = (int)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrapper const *farg2) { int fresult ; void *arg1 = (void *) 0 ; - SplittingStepCoefficients arg2 ; + SplittingStepCoefficients arg2 = (SplittingStepCoefficients) 0 ; int result; arg1 = (void *)(farg1); - SWIG_check_nonnull(*farg2, "SplittingStepCoefficients", "SWIGTYPE_p_SplittingStepCoefficients", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); - arg2 = *(SplittingStepCoefficients *)(farg2->cptr); + SWIG_check_mutable(*farg2, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStep_SetCoefficients(void *,SplittingStepCoefficients)", return 0); + arg2 = (SplittingStepCoefficients)(farg2->cptr); result = (int)SplittingStep_SetCoefficients(arg1,arg2); fresult = (int)(result); return fresult; diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 index 7cc2d19050..010112b6cb 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 @@ -34,14 +34,69 @@ module farkode_splittingstep_mod type(C_PTR), public :: cptr = C_NULL_PTR integer(C_INT), public :: cmemflags = 0 end type - type, public :: SWIGTYPE_p_SUNStepper + ! struct struct SplittingStepCoefficientsMem + type, public :: SplittingStepCoefficientsMem type(SwigClassWrapper), public :: swigdata + contains + procedure :: set_alpha => swigf_SplittingStepCoefficientsMem_alpha_set + procedure :: get_alpha => swigf_SplittingStepCoefficientsMem_alpha_get + procedure :: set_beta => swigf_SplittingStepCoefficientsMem_beta_set + procedure :: get_beta => swigf_SplittingStepCoefficientsMem_beta_get + procedure :: set_sequential_methods => swigf_SplittingStepCoefficientsMem_sequential_methods_set + procedure :: get_sequential_methods => swigf_SplittingStepCoefficientsMem_sequential_methods_get + procedure :: set_stages => swigf_SplittingStepCoefficientsMem_stages_set + procedure :: get_stages => swigf_SplittingStepCoefficientsMem_stages_get + procedure :: set_partitions => swigf_SplittingStepCoefficientsMem_partitions_set + procedure :: get_partitions => swigf_SplittingStepCoefficientsMem_partitions_get + procedure :: set_order => swigf_SplittingStepCoefficientsMem_order_set + procedure :: get_order => swigf_SplittingStepCoefficientsMem_order_get + procedure :: release => swigf_release_SplittingStepCoefficientsMem + procedure, private :: swigf_SplittingStepCoefficientsMem_op_assign__ + generic :: assignment(=) => swigf_SplittingStepCoefficientsMem_op_assign__ + end type SplittingStepCoefficientsMem + interface SplittingStepCoefficientsMem + module procedure swigf_create_SplittingStepCoefficientsMem + end interface + ! typedef enum ARKODE_SplittingCoefficientsID + enum, bind(c) + enumerator :: ARKODE_SPLITTING_NONE = -1 + enumerator :: ARKODE_MIN_SPLITTING_NUM = 0 + enumerator :: ARKODE_SPLITTING_LIE_TROTTER_1_1_2 = ARKODE_MIN_SPLITTING_NUM + enumerator :: ARKODE_SPLITTING_STRANG_2_2_2 + enumerator :: ARKODE_SPLITTING_BEST_2_2_2 + enumerator :: ARKODE_SPLITTING_SUZUKI_3_3_2 + enumerator :: ARKODE_SPLITTING_RUTH_3_3_2 + enumerator :: ARKODE_SPLITTING_YOSHIDA_4_4_2 + enumerator :: ARKODE_SPLITTING_YOSHIDA_8_6_2 + enumerator :: ARKODE_MAX_SPLITTING_NUM = ARKODE_SPLITTING_YOSHIDA_8_6_2 + end enum + integer, parameter, public :: ARKODE_SplittingCoefficientsID = kind(ARKODE_SPLITTING_NONE) + public :: ARKODE_SPLITTING_NONE, ARKODE_MIN_SPLITTING_NUM, ARKODE_SPLITTING_LIE_TROTTER_1_1_2, ARKODE_SPLITTING_STRANG_2_2_2, & + ARKODE_SPLITTING_BEST_2_2_2, ARKODE_SPLITTING_SUZUKI_3_3_2, ARKODE_SPLITTING_RUTH_3_3_2, ARKODE_SPLITTING_YOSHIDA_4_4_2, & + ARKODE_SPLITTING_YOSHIDA_8_6_2, ARKODE_MAX_SPLITTING_NUM + public :: FSplittingStepCoefficients_Alloc + public :: FSplittingStepCoefficients_Create + public :: FSplittingStepCoefficients_Free + public :: FSplittingStepCoefficients_Copy + public :: FSplittingStepCoefficients_Write + public :: FSplittingStepCoefficients_LoadCoefficients + type, bind(C) :: SwigArrayWrapper + type(C_PTR), public :: data = C_NULL_PTR + integer(C_SIZE_T), public :: size = 0 end type - public :: FSplittingStepCreate - public :: FSplittingStepCreateForcing - type, public :: SWIGTYPE_p_SplittingStepCoefficients + public :: FSplittingStepCoefficients_LoadCoefficientsByName + public :: FSplittingStepCoefficients_IDToName + public :: FSplittingStepCoefficients_LieTrotter + public :: FSplittingStepCoefficients_Strang + public :: FSplittingStepCoefficients_Parallel + public :: FSplittingStepCoefficients_SymmetricParallel + public :: FSplittingStepCoefficients_ThirdOrderSuzuki + public :: FSplittingStepCoefficients_TripleJump + public :: FSplittingStepCoefficients_SuzukiFractal + type, public :: SWIGTYPE_p_SUNStepper type(SwigClassWrapper), public :: swigdata end type + public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy type(SwigClassWrapper), public :: swigdata @@ -51,30 +106,289 @@ module farkode_splittingstep_mod ! WRAPPER DECLARATIONS interface -function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSplittingStepCreate") & +subroutine swigc_SplittingStepCoefficientsMem_alpha_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_alpha_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_alpha_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_alpha_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 -integer(C_INT), intent(in) :: farg2 -real(C_DOUBLE), intent(in) :: farg3 -type(C_PTR), value :: farg4 -type(C_PTR), value :: farg5 type(C_PTR) :: fresult end function -function swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSplittingStepCreateForcing") & +subroutine swigc_SplittingStepCoefficientsMem_beta_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_beta_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_beta_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_beta_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_sequential_methods_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_sequential_methods_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_sequential_methods_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_sequential_methods_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_stages_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_stages_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_stages_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_stages_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_partitions_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_partitions_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_partitions_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_partitions_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SplittingStepCoefficientsMem_order_set(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_order_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SplittingStepCoefficientsMem_order_get(farg1) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_order_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +function swigc_new_SplittingStepCoefficientsMem() & +bind(C, name="_wrap_new_SplittingStepCoefficientsMem") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_delete_SplittingStepCoefficientsMem(farg1) & +bind(C, name="_wrap_delete_SplittingStepCoefficientsMem") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper), intent(inout) :: farg1 +end subroutine + +subroutine swigc_SplittingStepCoefficientsMem_op_assign__(farg1, farg2) & +bind(C, name="_wrap_SplittingStepCoefficientsMem_op_assign__") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper), intent(inout) :: farg1 type(SwigClassWrapper) :: farg2 +end subroutine + +function swigc_FSplittingStepCoefficients_Alloc(farg1, farg2, farg3) & +bind(C, name="_wrap_FSplittingStepCoefficients_Alloc") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT), intent(in) :: farg3 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, farg5, farg6) & +bind(C, name="_wrap_FSplittingStepCoefficients_Create") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT), intent(in) :: farg3 +integer(C_INT), intent(in) :: farg4 +type(C_PTR), value :: farg5 +type(C_PTR), value :: farg6 +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_FSplittingStepCoefficients_Free(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Free") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +end subroutine + +function swigc_FSplittingStepCoefficients_Copy(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Copy") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +subroutine swigc_FSplittingStepCoefficients_Write(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_Write") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_FSplittingStepCoefficients_LoadCoefficients(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LoadCoefficients") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_LoadCoefficientsByName(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LoadCoefficientsByName") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +import :: swigarraywrapper +type(SwigArrayWrapper) :: farg1 +type(SwigClassWrapper) :: fresult +end function + + subroutine SWIG_free(cptr) & + bind(C, name="free") + use, intrinsic :: ISO_C_BINDING + type(C_PTR), value :: cptr +end subroutine +function swigc_FSplittingStepCoefficients_IDToName(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_IDToName") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigarraywrapper +integer(C_INT), intent(in) :: farg1 +type(SwigArrayWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_LieTrotter(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_LieTrotter") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Strang(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Strang") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_Parallel(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Parallel") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_SymmetricParallel(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_SymmetricParallel") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_ThirdOrderSuzuki(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_ThirdOrderSuzuki") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_TripleJump(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_TripleJump") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCoefficients_SuzukiFractal(farg1, farg2) & +bind(C, name="_wrap_FSplittingStepCoefficients_SuzukiFractal") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +integer(C_INT), intent(in) :: farg1 +integer(C_INT), intent(in) :: farg2 +type(SwigClassWrapper) :: fresult +end function + +function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & +bind(C, name="_wrap_FSplittingStepCreate") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 type(C_PTR), value :: farg5 -integer(C_INT) :: fresult +type(C_PTR) :: fresult end function function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & @@ -112,53 +426,466 @@ function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & contains ! MODULE SUBPROGRAMS -function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +subroutine swigf_SplittingStepCoefficientsMem_alpha_set(self, alpha) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +real(C_DOUBLE), dimension(*), target, intent(inout) :: alpha +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(alpha(1)) +call swigc_SplittingStepCoefficientsMem_alpha_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_alpha_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING -type(C_PTR) :: swig_result -class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers -integer(C_INT), intent(in) :: partitions -real(C_DOUBLE), intent(in) :: t0 -type(N_Vector), target, intent(inout) :: y0 -type(C_PTR) :: sunctx +real(C_DOUBLE), dimension(:), pointer :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self type(C_PTR) :: fresult type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_alpha_get(farg1) +call c_f_pointer(fresult, swig_result, [1]) +end function + +subroutine swigf_SplittingStepCoefficientsMem_beta_set(self, beta) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +type(C_PTR), target, intent(inout) :: beta +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(beta) +call swigc_SplittingStepCoefficientsMem_beta_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_beta_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), pointer :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_beta_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SplittingStepCoefficientsMem_sequential_methods_set(self, sequential_methods) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: sequential_methods +type(SwigClassWrapper) :: farg1 integer(C_INT) :: farg2 -real(C_DOUBLE) :: farg3 -type(C_PTR) :: farg4 -type(C_PTR) :: farg5 -farg1 = steppers%swigdata +farg1 = self%swigdata +farg2 = sequential_methods +call swigc_SplittingStepCoefficientsMem_sequential_methods_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_sequential_methods_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_sequential_methods_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SplittingStepCoefficientsMem_stages_set(self, stages) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: stages +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = stages +call swigc_SplittingStepCoefficientsMem_stages_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_stages_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_stages_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SplittingStepCoefficientsMem_partitions_set(self, partitions) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata farg2 = partitions -farg3 = t0 -farg4 = c_loc(y0) -farg5 = sunctx -fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) +call swigc_SplittingStepCoefficientsMem_partitions_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_partitions_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_partitions_get(farg1) swig_result = fresult end function -function FSplittingStepCreateForcing(stepper1, stepper2, t0, y0, sunctx) & +subroutine swigf_SplittingStepCoefficientsMem_order_set(self, order) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = order +call swigc_SplittingStepCoefficientsMem_order_set(farg1, farg2) +end subroutine + +function swigf_SplittingStepCoefficientsMem_order_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +class(SplittingStepCoefficientsMem), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SplittingStepCoefficientsMem_order_get(farg1) +swig_result = fresult +end function + +function swigf_create_SplittingStepCoefficientsMem() & +result(self) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: self +type(SwigClassWrapper) :: fresult + +fresult = swigc_new_SplittingStepCoefficientsMem() +self%swigdata = fresult +end function + +subroutine swigf_release_SplittingStepCoefficientsMem(self) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(inout) :: self +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +if (btest(farg1%cmemflags, swig_cmem_own_bit)) then +call swigc_delete_SplittingStepCoefficientsMem(farg1) +endif +farg1%cptr = C_NULL_PTR +farg1%cmemflags = 0 +self%swigdata = farg1 +end subroutine + +subroutine swigf_SplittingStepCoefficientsMem_op_assign__(self, other) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(inout) :: self +type(SplittingStepCoefficientsMem), intent(in) :: other +type(SwigClassWrapper) :: farg1 +type(SwigClassWrapper) :: farg2 + +farg1 = self%swigdata +farg2 = other%swigdata +call swigc_SplittingStepCoefficientsMem_op_assign__(farg1, farg2) +self%swigdata = farg1 +end subroutine + +function FSplittingStepCoefficients_Alloc(sequential_methods, stages, partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: sequential_methods +integer(C_INT), intent(in) :: stages +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 +integer(C_INT) :: farg3 + +farg1 = sequential_methods +farg2 = stages +farg3 = partitions +fresult = swigc_FSplittingStepCoefficients_Alloc(farg1, farg2, farg3) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Create(sequential_methods, stages, partitions, order, alpha, beta) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: sequential_methods +integer(C_INT), intent(in) :: stages +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +real(C_DOUBLE), dimension(*), target, intent(inout) :: alpha +real(C_DOUBLE), dimension(*), target, intent(inout) :: beta +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 +integer(C_INT) :: farg3 +integer(C_INT) :: farg4 +type(C_PTR) :: farg5 +type(C_PTR) :: farg6 + +farg1 = sequential_methods +farg2 = stages +farg3 = partitions +farg4 = order +farg5 = c_loc(alpha(1)) +farg6 = c_loc(beta(1)) +fresult = swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, farg5, farg6) +swig_result%swigdata = fresult +end function + +subroutine FSplittingStepCoefficients_Free(coefficients) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(SwigClassWrapper) :: farg1 + +farg1 = coefficients%swigdata +call swigc_FSplittingStepCoefficients_Free(farg1) +end subroutine + +function FSplittingStepCoefficients_Copy(coefficients) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(SwigClassWrapper) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = coefficients%swigdata +fresult = swigc_FSplittingStepCoefficients_Copy(farg1) +swig_result%swigdata = fresult +end function + +subroutine FSplittingStepCoefficients_Write(coefficients, outfile) +use, intrinsic :: ISO_C_BINDING +class(SplittingStepCoefficientsMem), intent(in) :: coefficients +type(C_PTR) :: outfile +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = coefficients%swigdata +farg2 = outfile +call swigc_FSplittingStepCoefficients_Write(farg1, farg2) +end subroutine + +function FSplittingStepCoefficients_LoadCoefficients(id) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(ARKODE_SplittingCoefficientsID), intent(in) :: id +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = id +fresult = swigc_FSplittingStepCoefficients_LoadCoefficients(farg1) +swig_result%swigdata = fresult +end function + + +subroutine SWIG_string_to_chararray(string, chars, wrap) + use, intrinsic :: ISO_C_BINDING + character(kind=C_CHAR, len=*), intent(IN) :: string + character(kind=C_CHAR), dimension(:), target, allocatable, intent(OUT) :: chars + type(SwigArrayWrapper), intent(OUT) :: wrap + integer :: i + + allocate(character(kind=C_CHAR) :: chars(len(string) + 1)) + do i=1,len(string) + chars(i) = string(i:i) + end do + i = len(string) + 1 + chars(i) = C_NULL_CHAR ! C string compatibility + wrap%data = c_loc(chars) + wrap%size = len(string) +end subroutine + +function FSplittingStepCoefficients_LoadCoefficientsByName(name) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +character(kind=C_CHAR, len=*), target :: name +character(kind=C_CHAR), dimension(:), allocatable, target :: farg1_chars +type(SwigClassWrapper) :: fresult +type(SwigArrayWrapper) :: farg1 + +call SWIG_string_to_chararray(name, farg1_chars, farg1) +fresult = swigc_FSplittingStepCoefficients_LoadCoefficientsByName(farg1) +swig_result%swigdata = fresult +end function + + +subroutine SWIG_chararray_to_string(wrap, string) + use, intrinsic :: ISO_C_BINDING + type(SwigArrayWrapper), intent(IN) :: wrap + character(kind=C_CHAR, len=:), allocatable, intent(OUT) :: string + character(kind=C_CHAR), dimension(:), pointer :: chars + integer(kind=C_SIZE_T) :: i + call c_f_pointer(wrap%data, chars, [wrap%size]) + allocate(character(kind=C_CHAR, len=wrap%size) :: string) + do i=1, wrap%size + string(i:i) = chars(i) + end do +end subroutine + +function FSplittingStepCoefficients_IDToName(id) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +character(kind=C_CHAR, len=:), allocatable :: swig_result +integer(ARKODE_SplittingCoefficientsID), intent(in) :: id +type(SwigArrayWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = id +fresult = swigc_FSplittingStepCoefficients_IDToName(farg1) +call SWIG_chararray_to_string(fresult, swig_result) +if (.false.) call SWIG_free(fresult%data) +end function + +function FSplittingStepCoefficients_LieTrotter(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_LieTrotter(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Strang(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_Strang(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_Parallel(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_Parallel(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_SymmetricParallel(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_SymmetricParallel(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_ThirdOrderSuzuki(partitions) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 + +farg1 = partitions +fresult = swigc_FSplittingStepCoefficients_ThirdOrderSuzuki(farg1) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_TripleJump(partitions, order) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 + +farg1 = partitions +farg2 = order +fresult = swigc_FSplittingStepCoefficients_TripleJump(farg1, farg2) +swig_result%swigdata = fresult +end function + +function FSplittingStepCoefficients_SuzukiFractal(partitions, order) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(SplittingStepCoefficientsMem) :: swig_result +integer(C_INT), intent(in) :: partitions +integer(C_INT), intent(in) :: order +type(SwigClassWrapper) :: fresult +integer(C_INT) :: farg1 +integer(C_INT) :: farg2 + +farg1 = partitions +farg2 = order +fresult = swigc_FSplittingStepCoefficients_SuzukiFractal(farg1, farg2) +swig_result%swigdata = fresult +end function + +function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +integer(C_INT), intent(in) :: partitions real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx -integer(C_INT) :: fresult +type(C_PTR) :: fresult type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +integer(C_INT) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = stepper1%swigdata -farg2 = stepper2%swigdata +farg1 = steppers%swigdata +farg2 = partitions farg3 = t0 farg4 = c_loc(y0) farg5 = sunctx -fresult = swigc_FSplittingStepCreateForcing(farg1, farg2, farg3, farg4, farg5) +fresult = swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) swig_result = fresult end function @@ -167,7 +894,7 @@ function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -type(SWIGTYPE_p_SplittingStepCoefficients), intent(in) :: coefficients +class(SplittingStepCoefficientsMem), intent(in) :: coefficients integer(C_INT) :: fresult type(C_PTR) :: farg1 type(SwigClassWrapper) :: farg2 diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c index ae6fcb1091..ba7d863488 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c @@ -18,7 +18,7 @@ #include #include -#include "arkode/arkode_splittingstep_coefficients.h" +#include "arkode/arkode_splittingstep.h" #include "sundials/sundials_math.h" #define ZERO SUN_RCONST(0.0) From 2c615ab0e6d8d62aabf2c9dbab92c19e6e0fceb0 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 14:29:15 -0700 Subject: [PATCH 106/180] Add reference for symmetric parallel method --- .../SplittingStep/SplittingStepCoefficients.rst | 2 +- doc/shared/sundials.bib | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 9f6972c614..e52984d74e 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -228,7 +228,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel(int partitions) Create the coefficients for the second order, symmetrized Lie-Trotter - splitting + splitting :cite:p:`Strang:63` .. math:: y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), diff --git a/doc/shared/sundials.bib b/doc/shared/sundials.bib index 4ca73e1c23..7902268178 100644 --- a/doc/shared/sundials.bib +++ b/doc/shared/sundials.bib @@ -2169,6 +2169,20 @@ @article{Sof:04 doi = {10.1016/j.mcm.2005.01.010} } +@article{Strang:63, + title = {Accurate partial difference methods {I}: {L}inear cauchy problems}, + volume = {12}, + ISSN = {1432-0673}, + DOI = {10.1007/bf00281235}, + number = {1}, + journal = {Archive for Rational Mechanics and Analysis}, + publisher = {Springer Science and Business Media LLC}, + author = {Strang, Gilbert}, + year = {1963}, + month = jan, + pages = {392–402} +} + @article{Strang:68, title = {On the Construction and Comparison of Difference Schemes}, volume = {5}, From 808d20fbb147134d7b74d401f86bc91fe5ea4932 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 16:41:25 -0700 Subject: [PATCH 107/180] Update SUNStepper links --- .../guide/source/Usage/SplittingStep/Skeleton.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index 467000a398..994e08419b 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -44,11 +44,12 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. :numref:`ARKODE.Usage.ARKStep.OptionalInputs` for details on configuring ARKStep. - Once the ARKStep object is setup, create a ``SUNStepper`` object with + Once the ARKStep object is setup, create a :c:type:`SUNStepper` object with :c:func:`ARKStepCreateSUNStepper`. - * If supplying a user-defined inner integrator, create the ``SUNStepper`` - object as described in section TODO(SBR). + * If supplying a user-defined inner integrator, create the + :c:type:`SUNStepper` object as described in section + :numref:`SUNStepper.Implementing`. .. note:: @@ -78,8 +79,8 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Create a SplittingStep object for the outer integration Create the SplittingStep object by calling :c:func:`SplittingStepCreate`. One - of the inputs to :c:func:`SplittingStepCreate` is an array of ``SUNStepper`` - objects with one to evolve each partition. + of the inputs to :c:func:`SplittingStepCreate` is an array of + :c:type:`SUNStepper` objects with one to evolve each partition. #. Set the SplittingStep step size @@ -99,11 +100,11 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Free solver memory * If ARKStep was used as an inner IVP integrator, call - :c:func:`SUNStepper_Free` and :c:func:`ARKodeFree` to free the memory + :c:func:`SUNStepper_Destroy` and :c:func:`ARKodeFree` to free the memory allocated for that inner integrator. * If a user-defined inner integrator was supplied, free the integrator - content and call :c:func:`SUNStepper_Free` to free the ``SUNStepper`` + content and call :c:func:`SUNStepper_Destroy` to free the :c:type:`SUNStepper` object. * Call :c:func:`ARKodeFree` to free the memory allocated for the From 46693c5905a01ef025d3916c57e53906c8263d27 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 18 Sep 2024 16:44:37 -0700 Subject: [PATCH 108/180] Apply formatter --- include/arkode/arkode_splittingstep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index a5cddb838b..9ff468e02c 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -36,7 +36,7 @@ struct SplittingStepCoefficientsMem int sequential_methods; /* number of sequential splitting methods */ int stages; /* number of stages within each sequential splitting method */ int partitions; /* number of RHS partitions */ - int order; /* order of convergence */ + int order; /* order of convergence */ }; typedef _SUNDIALS_STRUCT_ SplittingStepCoefficientsMem* SplittingStepCoefficients; From c83e15a22b2782762222bb9bc98957821f3aa36d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 20 Sep 2024 18:40:42 -0700 Subject: [PATCH 109/180] Make new ARKODE error for SUNStepper error --- ...rk_advection_diffusion_reaction_splitting.c | 5 +++-- include/arkode/arkode.h | 2 ++ src/arkode/arkode.c | 4 ++++ src/arkode/arkode_forcingstep.c | 18 ++++++++---------- src/arkode/arkode_splittingstep.c | 9 ++++----- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index fc1c33dada..390ae5f980 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -209,8 +209,9 @@ int main(void) const sunrealtype T0 = SUN_RCONST(0.0); const sunrealtype Tf = SUN_RCONST(1.0); const sunrealtype DT = SUN_RCONST(0.06); - UserData udata = {.N = 128, - .dx = SUN_RCONST(1.0) / (udata.N + 1), + const sunindextype N = 128; + UserData udata = {.N = N, + .dx = SUN_RCONST(1.0) / (N + 1), .a = SUN_RCONST(1.0), .b = SUN_RCONST(0.125), .c = SUN_RCONST(4.0), diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index e94c4dc479..ca492dc2c8 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -140,6 +140,8 @@ extern "C" { #define ARK_STEPPER_UNSUPPORTED -48 +#define ARK_SUNSTEPPER_ERR -49 + #define ARK_UNRECOGNIZED_ERROR -99 /* ------------------------------ diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 378471e507..04ff359d77 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -2669,6 +2669,10 @@ int arkHandleFailure(ARKodeMem ark_mem, int flag) arkProcessError(ark_mem, ARK_RELAX_JAC_FAIL, __LINE__, __func__, __FILE__, "The relaxation Jacobian failed unrecoverably"); break; + case ARK_SUNSTEPPER_ERR: + arkProcessError(ark_mem, ARK_RELAX_JAC_FAIL, __LINE__, __func__, __FILE__, + "An inner SUNStepper error occured"); + break; default: /* This return should never happen */ arkProcessError(ark_mem, ARK_UNRECOGNIZED_ERROR, __LINE__, __func__, __FILE__, diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index dd7e4a9efa..3d1f7e4b18 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -176,15 +176,14 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, /* Evolve stepper 0 on its own */ SUNErrCode err = SUNStepper_Reset(s0, ark_mem->tn, ark_mem->yn); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStepDirection(s0, ark_mem->h); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStopTime(s0, tout); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); - if (err != SUN_SUCCESS) { return err; } - if (stop_reason < 0) { return stop_reason; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[0]++; /* Reset stepper 1. It may be possible to avoid the reset here (like explicit @@ -193,11 +192,11 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, * could become out of sync. */ const SUNStepper s1 = step_mem->stepper[1]; err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStepDirection(s1, ark_mem->h); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStopTime(s1, tout); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } /* Write tendency (ycur - yn)/h into stepper 1 forcing */ const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; @@ -206,8 +205,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, /* Evolve stepper 1 with the forcing */ err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, &stop_reason); - if (err != SUN_SUCCESS) { return err; } - if (stop_reason < 0) { return stop_reason; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[1]++; return ARK_SUCCESS; diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 14369c4272..38d0134bb8 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -277,19 +277,18 @@ static int splittingStep_SequentialMethod(const int i, const N_Vector y, const SUNStepper stepper = step_mem->steppers[k]; SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStepDirection(stepper, t_end - t_start); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStopTime(stepper, t_end); - if (err != SUN_SUCCESS) { return err; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } sunrealtype tret = 0; int stop_reason = 0; err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret, &stop_reason); - if (err != SUN_SUCCESS) { return err; } - if (stop_reason < 0) { return stop_reason; } + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[k]++; } From 26ec38c067eb690dba4fc75fab3f46fee21759eb Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 20 Sep 2024 18:42:53 -0700 Subject: [PATCH 110/180] Update swig --- src/arkode/fmod_int32/farkode_mod.f90 | 1 + src/arkode/fmod_int64/farkode_mod.f90 | 1 + 2 files changed, 2 insertions(+) diff --git a/src/arkode/fmod_int32/farkode_mod.f90 b/src/arkode/fmod_int32/farkode_mod.f90 index 8913072c4c..0bcf67385f 100644 --- a/src/arkode/fmod_int32/farkode_mod.f90 +++ b/src/arkode/fmod_int32/farkode_mod.f90 @@ -94,6 +94,7 @@ module farkode_mod integer(C_INT), parameter, public :: ARK_RELAX_JAC_FAIL = -46_C_INT integer(C_INT), parameter, public :: ARK_CONTROLLER_ERR = -47_C_INT integer(C_INT), parameter, public :: ARK_STEPPER_UNSUPPORTED = -48_C_INT + integer(C_INT), parameter, public :: ARK_SUNSTEPPER_ERR = -49_C_INT integer(C_INT), parameter, public :: ARK_UNRECOGNIZED_ERROR = -99_C_INT ! typedef enum ARKRelaxSolver enum, bind(c) diff --git a/src/arkode/fmod_int64/farkode_mod.f90 b/src/arkode/fmod_int64/farkode_mod.f90 index 356d583a98..a037546aca 100644 --- a/src/arkode/fmod_int64/farkode_mod.f90 +++ b/src/arkode/fmod_int64/farkode_mod.f90 @@ -94,6 +94,7 @@ module farkode_mod integer(C_INT), parameter, public :: ARK_RELAX_JAC_FAIL = -46_C_INT integer(C_INT), parameter, public :: ARK_CONTROLLER_ERR = -47_C_INT integer(C_INT), parameter, public :: ARK_STEPPER_UNSUPPORTED = -48_C_INT + integer(C_INT), parameter, public :: ARK_SUNSTEPPER_ERR = -49_C_INT integer(C_INT), parameter, public :: ARK_UNRECOGNIZED_ERROR = -99_C_INT ! typedef enum ARKRelaxSolver enum, bind(c) From 5ba27fa12dfb01905bebc6334c556e6c9d8bad6f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 20 Sep 2024 18:50:49 -0700 Subject: [PATCH 111/180] Fix typo --- src/arkode/arkode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 04ff359d77..1db7064a2c 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -2671,7 +2671,7 @@ int arkHandleFailure(ARKodeMem ark_mem, int flag) break; case ARK_SUNSTEPPER_ERR: arkProcessError(ark_mem, ARK_RELAX_JAC_FAIL, __LINE__, __func__, __FILE__, - "An inner SUNStepper error occured"); + "An inner SUNStepper error occurred"); break; default: /* This return should never happen */ From 1d35b62811b9f4f47a0855b4ad15812d13ea749d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 20 Sep 2024 19:40:12 -0700 Subject: [PATCH 112/180] Remove execution policy following @drreynolds suggestion --- include/arkode/arkode_execution_policy.h | 52 ----------- include/arkode/arkode_splittingstep.h | 4 - .../arkode_execution_policy_serial.h | 33 ------- src/arkode/CMakeLists.txt | 4 +- src/arkode/arkode_splittingstep.c | 93 +++++-------------- .../arkode_splittingstep_executionpolicy.c | 35 ------- src/arkode/arkode_splittingstep_impl.h | 2 - .../arkode_execution_policy_serial.c | 85 ----------------- .../fmod_int32/farkode_splittingstep_mod.c | 15 --- .../fmod_int32/farkode_splittingstep_mod.f90 | 30 ------ .../fmod_int64/farkode_splittingstep_mod.c | 15 --- .../fmod_int64/farkode_splittingstep_mod.f90 | 30 ------ 12 files changed, 25 insertions(+), 373 deletions(-) delete mode 100644 include/arkode/arkode_execution_policy.h delete mode 100644 include/arkode/execution_policy/arkode_execution_policy_serial.h delete mode 100644 src/arkode/arkode_splittingstep_executionpolicy.c delete mode 100644 src/arkode/execution_policy/arkode_execution_policy_serial.c diff --git a/include/arkode/arkode_execution_policy.h b/include/arkode/arkode_execution_policy.h deleted file mode 100644 index 526b27d3f3..0000000000 --- a/include/arkode/arkode_execution_policy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------------------- - * This header defines execution policy data structures and functions. - * ---------------------------------------------------------------------------*/ - -#ifndef ARKODE_EXECUTION_POLICY_H_ -#define ARKODE_EXECUTION_POLICY_H_ - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -#include - -/* Parallelization Policy */ -typedef int (*ARKExecutionPolicyFn)(int i, N_Vector y, void* user_data); - -typedef _SUNDIALS_STRUCT_ ARKodeSplittingExecutionPolicyMem* ARKodeSplittingExecutionPolicy; - -struct ARKodeSplittingExecutionPolicyMem -{ - int (*setup)(ARKodeSplittingExecutionPolicy policy, N_Vector y, - int sequential_methods); - - int (*execute)(ARKodeSplittingExecutionPolicy policy, ARKExecutionPolicyFn fn, - N_Vector yn, N_Vector ycur, N_Vector tmp, sunrealtype* alpha, - int sequential_methods, void* user_data); - - void (*free)(ARKodeSplittingExecutionPolicy policy); - - void* data; -}; - -SUNDIALS_EXPORT void ARKodeSplittingExecutionPolicy_Free( - ARKodeSplittingExecutionPolicy* policy); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 9ff468e02c..006225e7d4 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -17,7 +17,6 @@ #ifndef ARKODE_SPLITTINGSTEP_H_ #define ARKODE_SPLITTINGSTEP_H_ -#include #include #include #include @@ -102,9 +101,6 @@ SUNDIALS_EXPORT void* SplittingStepCreate(SUNStepper* steppers, int partitions, SUNDIALS_EXPORT int SplittingStep_SetCoefficients( void* arkode_mem, SplittingStepCoefficients coefficients); -SUNDIALS_EXPORT int SplittingStep_SetExecutionPolicy( - void* arkode_mem, ARKodeSplittingExecutionPolicy policy); - SUNDIALS_EXPORT int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves); diff --git a/include/arkode/execution_policy/arkode_execution_policy_serial.h b/include/arkode/execution_policy/arkode_execution_policy_serial.h deleted file mode 100644 index 4afff57847..0000000000 --- a/include/arkode/execution_policy/arkode_execution_policy_serial.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------------------- - * The header file for the serial execution policy - * ---------------------------------------------------------------------------*/ - -#ifndef ARKODE_EXECUTION_POLICY_SERIAL_H_ -#define ARKODE_EXECUTION_POLICY_SERIAL_H_ - -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -SUNDIALS_EXPORT ARKodeSplittingExecutionPolicy -ARKodeSplittingExecutionPolicy_New_Serial(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index cbc870b761..b494c25ecb 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -40,14 +40,12 @@ set(arkode_SOURCES arkode_relaxation.c arkode_root.c arkode_splittingstep_coefficients.c - arkode_splittingstep_executionpolicy.c arkode_splittingstep.c arkode_sprkstep_io.c arkode_sprkstep.c arkode_sprk.c arkode_user_controller.c - arkode.c - execution_policy/arkode_execution_policy_serial.c) + arkode.c) # Add variable arkode_HEADERS with the exported ARKODE header files set(arkode_HEADERS diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 38d0134bb8..974af199b7 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -17,7 +17,6 @@ #include #include -#include #include #include "arkode_impl.h" @@ -125,7 +124,6 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, With initialization types FIRST_INIT this routine: - sets/checks the splitting coefficients to be used - - sets/checks the execution policy to be used With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ @@ -152,21 +150,6 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) retval = splittingStep_SetCoefficients(ark_mem, step_mem); if (retval != ARK_SUCCESS) { return retval; } - if (step_mem->policy == NULL) - { - step_mem->policy = ARKodeSplittingExecutionPolicy_New_Serial(); - if (step_mem->policy == NULL) - { - if (step_mem->coefficients == NULL) - { - arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, - "Failed to allocate execution policy"); - return ARK_MEM_FAIL; - } - } - step_mem->own_policy = SUNTRUE; - } - ark_mem->interp_degree = SUNMAX(1, SUNMIN(step_mem->coefficients->order - 1, ark_mem->interp_degree)); @@ -222,7 +205,7 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, MSG_ARK_RHSFUNC_FAILED, t); return (ARK_RHSFUNC_FAIL); } - N_VLinearSum(SUN_RCONST(1.0), f, SUN_RCONST(1.0), ark_mem->tempv1, f); + N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); } return ARK_SUCCESS; @@ -231,14 +214,10 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, /*--------------------------------------------------------------- This routine performs a sequential operator splitting method ---------------------------------------------------------------*/ -static int splittingStep_SequentialMethod(const int i, const N_Vector y, - void* const user_data) +static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, + const ARKodeSplittingStepMem step_mem, + const int i, const N_Vector y) { - ARKodeMem ark_mem = (ARKodeMem)user_data; - ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } - const SplittingStepCoefficients coefficients = step_mem->coefficients; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG @@ -312,11 +291,26 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, const SplittingStepCoefficients coefficients = step_mem->coefficients; - return step_mem->policy->execute(step_mem->policy, - splittingStep_SequentialMethod, ark_mem->yn, - ark_mem->ycur, ark_mem->tempv1, - coefficients->alpha, - coefficients->sequential_methods, ark_mem); + N_VScale(ONE, ark_mem->yn, ark_mem->ycur); + retval = splittingStep_SequentialMethod(ark_mem, step_mem, 0, ark_mem->ycur); + if (retval != ARK_SUCCESS) { return retval; } + + if (coefficients->alpha[0] != ONE) + { + N_VScale(coefficients->alpha[0], ark_mem->ycur, ark_mem->ycur); + } + + for (int i = 1; i < coefficients->sequential_methods; i++) + { + N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); + retval = splittingStep_SequentialMethod(ark_mem, step_mem, i, + ark_mem->tempv1); + if (retval != ARK_SUCCESS) { return retval; } + N_VLinearSum(ONE, ark_mem->ycur, coefficients->alpha[i], ark_mem->tempv1, + ark_mem->ycur); + } + + return ARK_SUCCESS; } /*--------------------------------------------------------------- @@ -382,11 +376,6 @@ static void splittingStep_Free(const ARKodeMem ark_mem) { free(step_mem->steppers); free(step_mem->n_stepper_evolves); - if (step_mem->own_policy) - { - ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); - } - SplittingStepCoefficients_Free(step_mem->coefficients); free(step_mem); } @@ -451,9 +440,6 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) retval = splittingStep_SetOrder(ark_mem, 0); if (retval != ARK_SUCCESS) { return retval; } - if (step_mem->own_policy) { free(step_mem->policy); } - step_mem->own_policy = SUNFALSE; - /* TODO(SBR): This may cause issues if a user calls ARKodeSetDefaults. This * issues affects other ARKODE steppers as well */ ARKodeSetInterpolantType(ark_mem, ARK_INTERP_LAGRANGE); @@ -537,7 +523,6 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, memcpy(step_mem->steppers, steppers, partitions * sizeof(*steppers)); step_mem->coefficients = NULL; - step_mem->policy = NULL; step_mem->n_stepper_evolves = calloc(partitions, sizeof(*step_mem->n_stepper_evolves)); if (step_mem->n_stepper_evolves == NULL) @@ -549,7 +534,6 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, } step_mem->partitions = partitions; step_mem->order = 0; - step_mem->own_policy = SUNFALSE; /* Attach step_mem structure and function pointers to ark_mem */ ark_mem->step_init = splittingStep_Init; @@ -625,35 +609,6 @@ int SplittingStep_SetCoefficients(void* const arkode_mem, return ARK_SUCCESS; } -/*--------------------------------------------------------------- - Sets the execution policy. - ---------------------------------------------------------------*/ -int SplittingStep_SetExecutionPolicy(void* const arkode_mem, - ARKodeSplittingExecutionPolicy policy) -{ - ARKodeMem ark_mem = NULL; - ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, - &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } - - if (policy == NULL) - { - arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "The execution policy must be non-NULL"); - return ARK_ILL_INPUT; - } - - if (step_mem->own_policy) - { - ARKodeSplittingExecutionPolicy_Free(&step_mem->policy); - } - step_mem->policy = policy; - step_mem->own_policy = SUNFALSE; - - return ARK_SUCCESS; -} - int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, long int* const evolves) { diff --git a/src/arkode/arkode_splittingstep_executionpolicy.c b/src/arkode/arkode_splittingstep_executionpolicy.c deleted file mode 100644 index c85e622003..0000000000 --- a/src/arkode/arkode_splittingstep_executionpolicy.c +++ /dev/null @@ -1,35 +0,0 @@ -/*--------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *--------------------------------------------------------------- - * This is the implementation file for execution policy. - *--------------------------------------------------------------*/ - -#include -#include -#include - -#include "sundials_macros.h" - -/*--------------------------------------------------------------- - This routine frees all the ARKodeSplittingExecutionPolicy - memory - ---------------------------------------------------------------*/ -void ARKodeSplittingExecutionPolicy_Free(ARKodeSplittingExecutionPolicy* policy) -{ - if (policy != NULL) - { - (*policy)->free(*policy); - free(*policy); - *policy = NULL; - } -} diff --git a/src/arkode/arkode_splittingstep_impl.h b/src/arkode/arkode_splittingstep_impl.h index 1900978ece..88988b4eb6 100644 --- a/src/arkode/arkode_splittingstep_impl.h +++ b/src/arkode/arkode_splittingstep_impl.h @@ -23,12 +23,10 @@ typedef struct ARKodeSplittingStepMemRec { SUNStepper* steppers; SplittingStepCoefficients coefficients; - ARKodeSplittingExecutionPolicy policy; long int* n_stepper_evolves; int partitions; int order; - sunbooleantype own_policy; }* ARKodeSplittingStepMem; #endif diff --git a/src/arkode/execution_policy/arkode_execution_policy_serial.c b/src/arkode/execution_policy/arkode_execution_policy_serial.c deleted file mode 100644 index cfcd2da1ed..0000000000 --- a/src/arkode/execution_policy/arkode_execution_policy_serial.c +++ /dev/null @@ -1,85 +0,0 @@ -/*--------------------------------------------------------------- - * Programmer(s): Steven B. Roberts @ LLNL - *--------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2024, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *--------------------------------------------------------------- - * This is the implementation file for the serial execution - * policy. - *--------------------------------------------------------------*/ - -#include -#include -#include - -#include "sundials_macros.h" - -/*--------------------------------------------------------------- - This routine does the setup for serial execution for which - nothing is needed. - ---------------------------------------------------------------*/ -static int setup_serial( - SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, - SUNDIALS_MAYBE_UNUSED const N_Vector y, - SUNDIALS_MAYBE_UNUSED const int sequential_methods) -{ - return ARK_SUCCESS; -} - -/*--------------------------------------------------------------- - This routine evaluates the policy function fn in serial over - the range of sequential methods - ---------------------------------------------------------------*/ -static int execute_serial( - SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy, - const ARKExecutionPolicyFn fn, const N_Vector yn, const N_Vector ycur, - const N_Vector tmp, sunrealtype* const alpha, const int sequential_methods, - void* const user_data) -{ - N_VScale(SUN_RCONST(1.0), yn, ycur); - int retval = fn(0, ycur, user_data); - if (retval != ARK_SUCCESS) { return retval; } - - if (alpha[0] != SUN_RCONST(1.0)) { N_VScale(alpha[0], ycur, ycur); } - - for (int i = 1; i < sequential_methods; i++) - { - N_VScale(SUN_RCONST(1.0), yn, tmp); - retval = fn(i, tmp, user_data); - if (retval != ARK_SUCCESS) { return retval; } - N_VLinearSum(SUN_RCONST(1.0), ycur, alpha[i], tmp, ycur); - } - - return ARK_SUCCESS; -} - -/*--------------------------------------------------------------- - This routine does the freeing for serial execution which happens - to be nothing - ---------------------------------------------------------------*/ -static void free_serial( - SUNDIALS_MAYBE_UNUSED const ARKodeSplittingExecutionPolicy policy) -{ - // Nothing needed -} - -/*--------------------------------------------------------------- - This routine creates a serial execution policy - ---------------------------------------------------------------*/ -ARKodeSplittingExecutionPolicy ARKodeSplittingExecutionPolicy_New_Serial(void) -{ - ARKodeSplittingExecutionPolicy policy = malloc(sizeof(*policy)); - if (policy == NULL) { return NULL; } - policy->setup = setup_serial; - policy->execute = execute_serial; - policy->free = free_serial; - policy->data = NULL; - return policy; -} diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.c b/src/arkode/fmod_int32/farkode_splittingstep_mod.c index 1025d29cca..f343e4ce69 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.c @@ -727,21 +727,6 @@ SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrappe } -SWIGEXPORT int _wrap_FSplittingStep_SetExecutionPolicy(void *farg1, SwigClassWrapper const *farg2) { - int fresult ; - void *arg1 = (void *) 0 ; - ARKodeSplittingExecutionPolicy arg2 ; - int result; - - arg1 = (void *)(farg1); - SWIG_check_nonnull(*farg2, "ARKodeSplittingExecutionPolicy", "SWIGTYPE_p_ARKodeSplittingExecutionPolicy", "SplittingStep_SetExecutionPolicy(void *,ARKodeSplittingExecutionPolicy)", return 0); - arg2 = *(ARKodeSplittingExecutionPolicy *)(farg2->cptr); - result = (int)SplittingStep_SetExecutionPolicy(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSplittingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 index 010112b6cb..da68d91177 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 @@ -98,10 +98,6 @@ module farkode_splittingstep_mod end type public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients - type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy - type(SwigClassWrapper), public :: swigdata - end type - public :: FSplittingStep_SetExecutionPolicy public :: FSplittingStep_GetNumEvolves ! WRAPPER DECLARATIONS @@ -401,16 +397,6 @@ function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) & -bind(C, name="_wrap_FSplittingStep_SetExecutionPolicy") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(C_PTR), value :: farg1 -type(SwigClassWrapper) :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & bind(C, name="_wrap_FSplittingStep_GetNumEvolves") & result(fresult) @@ -905,22 +891,6 @@ function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & swig_result = fresult end function -function FSplittingStep_SetExecutionPolicy(arkode_mem, policy) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: arkode_mem -type(SWIGTYPE_p_ARKodeSplittingExecutionPolicy), intent(in) :: policy -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(SwigClassWrapper) :: farg2 - -farg1 = arkode_mem -farg2 = policy%swigdata -fresult = swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) -swig_result = fresult -end function - function FSplittingStep_GetNumEvolves(arkode_mem, partition, evolves) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.c b/src/arkode/fmod_int64/farkode_splittingstep_mod.c index 1025d29cca..f343e4ce69 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.c @@ -727,21 +727,6 @@ SWIGEXPORT int _wrap_FSplittingStep_SetCoefficients(void *farg1, SwigClassWrappe } -SWIGEXPORT int _wrap_FSplittingStep_SetExecutionPolicy(void *farg1, SwigClassWrapper const *farg2) { - int fresult ; - void *arg1 = (void *) 0 ; - ARKodeSplittingExecutionPolicy arg2 ; - int result; - - arg1 = (void *)(farg1); - SWIG_check_nonnull(*farg2, "ARKodeSplittingExecutionPolicy", "SWIGTYPE_p_ARKodeSplittingExecutionPolicy", "SplittingStep_SetExecutionPolicy(void *,ARKodeSplittingExecutionPolicy)", return 0); - arg2 = *(ARKodeSplittingExecutionPolicy *)(farg2->cptr); - result = (int)SplittingStep_SetExecutionPolicy(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSplittingStep_GetNumEvolves(void *farg1, int const *farg2, long *farg3) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 index 010112b6cb..da68d91177 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 @@ -98,10 +98,6 @@ module farkode_splittingstep_mod end type public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients - type, public :: SWIGTYPE_p_ARKodeSplittingExecutionPolicy - type(SwigClassWrapper), public :: swigdata - end type - public :: FSplittingStep_SetExecutionPolicy public :: FSplittingStep_GetNumEvolves ! WRAPPER DECLARATIONS @@ -401,16 +397,6 @@ function swigc_FSplittingStep_SetCoefficients(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) & -bind(C, name="_wrap_FSplittingStep_SetExecutionPolicy") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(C_PTR), value :: farg1 -type(SwigClassWrapper) :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSplittingStep_GetNumEvolves(farg1, farg2, farg3) & bind(C, name="_wrap_FSplittingStep_GetNumEvolves") & result(fresult) @@ -905,22 +891,6 @@ function FSplittingStep_SetCoefficients(arkode_mem, coefficients) & swig_result = fresult end function -function FSplittingStep_SetExecutionPolicy(arkode_mem, policy) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: arkode_mem -type(SWIGTYPE_p_ARKodeSplittingExecutionPolicy), intent(in) :: policy -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(SwigClassWrapper) :: farg2 - -farg1 = arkode_mem -farg2 = policy%swigdata -fresult = swigc_FSplittingStep_SetExecutionPolicy(farg1, farg2) -swig_result = fresult -end function - function FSplittingStep_GetNumEvolves(arkode_mem, partition, evolves) & result(swig_result) use, intrinsic :: ISO_C_BINDING From 75ee9d0f40b43f159590659c2cc86099a34fcdd1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 26 Sep 2024 11:44:30 -0700 Subject: [PATCH 113/180] Fix ARK_SUNSTEPPER_ERR handling --- src/arkode/arkode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 1db7064a2c..f241becf5d 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -2670,7 +2670,7 @@ int arkHandleFailure(ARKodeMem ark_mem, int flag) "The relaxation Jacobian failed unrecoverably"); break; case ARK_SUNSTEPPER_ERR: - arkProcessError(ark_mem, ARK_RELAX_JAC_FAIL, __LINE__, __func__, __FILE__, + arkProcessError(ark_mem, ARK_SUNSTEPPER_ERR, __LINE__, __func__, __FILE__, "An inner SUNStepper error occurred"); break; default: From a46c34fb8c00bec7168798c6ffcfbc2be8cd475f Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 26 Sep 2024 14:17:01 -0700 Subject: [PATCH 114/180] Fix missing getstepdirection assignment in SUNStepper_Create --- src/sundials/sundials_stepper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index e588cc2c26..f1a9f5a97b 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -39,6 +39,7 @@ SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper_ptr) stepper->ops->reset = NULL; stepper->ops->setstoptime = NULL; stepper->ops->setstepdirection = NULL; + stepper->ops->getstepdirection = NULL; *stepper_ptr = stepper; From cb975f4a61223f91baf08b8381f9ca12c7c3500b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 20:01:06 -0700 Subject: [PATCH 115/180] Fix compilation errors after merge --- include/sundials/sundials_stepper.h | 3 +++ src/arkode/arkode_forcingstep.c | 11 ++++------- src/arkode/arkode_splittingstep.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 8aa7581630..bd3bce228c 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -114,6 +114,9 @@ SUNErrCode SUNStepper_Reset(SUNStepper stepper, sunrealtype tR, N_Vector yR); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop); +SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, + SUNStepperSetForcingFn fn); + SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir); diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 3d1f7e4b18..ff99bd43e1 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -99,7 +99,6 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } - SUNStepper_SetForcing(step_mem->stepper[1], 1, ark_mem->yn); ark_mem->interp_degree = 1; return ARK_SUCCESS; @@ -172,7 +171,6 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, const SUNStepper s0 = step_mem->stepper[0]; const sunrealtype tout = ark_mem->tn + ark_mem->h; sunrealtype tret = 0; - int stop_reason = 0; /* Evolve stepper 0 on its own */ SUNErrCode err = SUNStepper_Reset(s0, ark_mem->tn, ark_mem->yn); @@ -181,8 +179,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStopTime(s0, tout); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret, - &stop_reason); + err = SUNStepper_Evolve(s0, ark_mem->tn, tout, ark_mem->ycur, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[0]++; @@ -200,11 +197,11 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, /* Write tendency (ycur - yn)/h into stepper 1 forcing */ const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; - N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, s1->forcing[0]); + N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, ark_mem->tempv1); + err = SUNStepper_SetForcing(s1, ZERO, ZERO, &ark_mem->tempv1, 1); /* Evolve stepper 1 with the forcing */ - err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret, - &stop_reason); + err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[1]++; diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 974af199b7..d7e3380cb6 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -265,8 +265,7 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } sunrealtype tret = 0; - int stop_reason = 0; - err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret, &stop_reason); + err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[k]++; From 9d5d5f8fb06d3198b10663232defee4c538837fa Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 20:14:52 -0700 Subject: [PATCH 116/180] Fix remaining compilation errors --- ...k_advection_diffusion_reaction_splitting.c | 12 +++--- .../C_serial/ark_analytic_partitioned.c | 4 +- include/sundials/sundials_stepper.h | 8 ++++ src/arkode/arkode_sunstepper.c | 28 +++++++++++++ src/sundials/sundials_stepper.c | 42 +++++++++---------- .../CXX_serial/ark_test_splittingstep.cpp | 15 ++++--- .../arkode/C_serial/ark_test_forcingstep.c | 4 +- 7 files changed, 74 insertions(+), 39 deletions(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 390ae5f980..7ca53e6bd7 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -246,8 +246,8 @@ int main(void) if (check_flag(&flag, "ARKStepSetTableNum", 1)) { return 1; } SUNStepper advection_stepper; - flag = ARKStepCreateSUNStepper(advection_mem, &advection_stepper); - if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + flag = ARKodeCreateSUNStepper(advection_mem, &advection_stepper); + if (check_flag(&flag, "ARKodeCreateSUNStepper", 1)) { return 1; } /* Create diffusion integrator */ void* diffusion_mem = ARKStepCreate(NULL, f_diffusion, T0, y, ctx); @@ -275,8 +275,8 @@ int main(void) if (check_flag(&flag, "ARKodeSetLinear", 1)) { return 1; } SUNStepper diffusion_stepper; - flag = ARKStepCreateSUNStepper(diffusion_mem, &diffusion_stepper); - if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + flag = ARKodeCreateSUNStepper(diffusion_mem, &diffusion_stepper); + if (check_flag(&flag, "ARKodeCreateSUNStepper", 1)) { return 1; } /* Create reaction integrator */ void* reaction_mem = ARKStepCreate(f_reaction, NULL, T0, y, ctx); @@ -289,8 +289,8 @@ int main(void) if (check_flag(&flag, "ARKodeSetOrder", 1)) { return 1; } SUNStepper reaction_stepper; - flag = ARKStepCreateSUNStepper(reaction_mem, &reaction_stepper); - if (check_flag(&flag, "ARKStepCreateSUNStepper", 1)) { return 1; } + flag = ARKodeCreateSUNStepper(reaction_mem, &reaction_stepper); + if (check_flag(&flag, "ARKodeCreateSUNStepper", 1)) { return 1; } /* Create operator splitting integrator */ SUNStepper steppers[] = {advection_stepper, diffusion_stepper, diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 930d1c5acb..3fa2670311 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -190,8 +190,8 @@ int main(const int argc, char* const argv[]) /* Create SUNSteppers out of the integrators */ SUNStepper steppers[2]; - ARKStepCreateSUNStepper(linear_mem, &steppers[0]); - ARKStepCreateSUNStepper(nonlinear_mem, &steppers[1]); + ARKodeCreateSUNStepper(linear_mem, &steppers[0]); + ARKodeCreateSUNStepper(nonlinear_mem, &steppers[1]); /* Create the outer integrator */ void* arkode_mem; diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index bd3bce228c..c63122b6e0 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -96,6 +96,14 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn fn); +SUNDIALS_EXPORT +SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, + SUNStepperSetStepDirectionFn fn); + +SUNDIALS_EXPORT +SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, + SUNStepperGetStepDirectionFn fn); + SUNDIALS_EXPORT SUNErrCode SUNStepper_Evolve(SUNStepper stepper, sunrealtype t0, sunrealtype tout, N_Vector y, sunrealtype* tret); diff --git a/src/arkode/arkode_sunstepper.c b/src/arkode/arkode_sunstepper.c index 0384a328fa..73ce0605c8 100644 --- a/src/arkode/arkode_sunstepper.c +++ b/src/arkode/arkode_sunstepper.c @@ -124,6 +124,32 @@ static SUNErrCode arkSUNStepperSetStopTime(SUNStepper stepper, sunrealtype tstop return SUN_SUCCESS; } +static SUNErrCode arkSUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir) +{ + SUNFunctionBegin(stepper->sunctx); + /* extract the ARKODE memory struct */ + void* arkode_mem; + SUNCheckCall(SUNStepper_GetContent(stepper, &arkode_mem)); + + stepper->last_flag = ARKodeSetStepDirection(arkode_mem, stepdir); + if (stepper->last_flag != ARK_SUCCESS) { return SUN_ERR_OP_FAIL; } + + return SUN_SUCCESS; +} + +static SUNErrCode arkSUNStepperGetStepDirection(SUNStepper stepper, sunrealtype *stepdir) +{ + SUNFunctionBegin(stepper->sunctx); + /* extract the ARKODE memory struct */ + void* arkode_mem; + SUNCheckCall(SUNStepper_GetContent(stepper, &arkode_mem)); + + stepper->last_flag = ARKodeGetStepDirection(arkode_mem, stepdir); + if (stepper->last_flag != ARK_SUCCESS) { return SUN_ERR_OP_FAIL; } + + return SUN_SUCCESS; +} + static SUNErrCode arkSUNStepperSetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) @@ -161,6 +187,8 @@ int ARKodeCreateSUNStepper(void* arkode_mem, SUNStepper* stepper) SUNCheckCall(SUNStepper_SetFullRhsFn(*stepper, arkSUNStepperFullRhs)); SUNCheckCall(SUNStepper_SetResetFn(*stepper, arkSUNStepperReset)); SUNCheckCall(SUNStepper_SetStopTimeFn(*stepper, arkSUNStepperSetStopTime)); + SUNCheckCall(SUNStepper_SetStepDirectionFn(*stepper, arkSUNStepperSetStepDirection)); + SUNCheckCall(SUNStepper_SetGetStepDirectionFn(*stepper, arkSUNStepperGetStepDirection)); SUNCheckCall(SUNStepper_SetForcingFn(*stepper, arkSUNStepperSetForcing)); return ARK_SUCCESS; diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 57313bdd8c..740ff728b4 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -114,6 +114,26 @@ SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop) else { return SUN_ERR_NOT_IMPLEMENTED; } } +SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) +{ + SUNFunctionBegin(stepper->sunctx); + if (stepper->ops->setstepdirection) + { + return stepper->ops->setstepdirection(stepper, stepdir); + } + else { return SUN_ERR_NOT_IMPLEMENTED; } +} + +SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) +{ + SUNFunctionBegin(stepper->sunctx); + if (stepper->ops->setstepdirection) + { + return stepper->ops->getstepdirection(stepper, stepdir); + } + else { return SUN_ERR_NOT_IMPLEMENTED; } +} + SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) @@ -168,7 +188,7 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn return SUN_SUCCESS; } -SUNErrCode SUNStepper_SetSetStepDirectionFn(SUNStepper stepper, +SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) { SUNFunctionBegin(stepper->sunctx); @@ -190,23 +210,3 @@ SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn stepper->ops->setforcing = fn; return SUN_SUCCESS; } - -SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - if (stepper->ops->setstepdirection) - { - return stepper->ops->setstepdirection(stepper, stepdir); - } - else { return SUN_ERR_NOT_IMPLEMENTED; } -} - -SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - if (stepper->ops->setstepdirection) - { - return stepper->ops->getstepdirection(stepper, stepdir); - } - else { return SUN_ERR_NOT_IMPLEMENTED; } -} diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index f9e22e1b6c..c1e5635846 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -62,7 +62,7 @@ static int test_forward(sundials::Context& ctx, const int partitions) (1 - std::pow(SUN_RCONST(2.0), partitions)); ARKodeSetUserData(partition_mem[i], &lambda[i]); ARKodeSStolerances(partition_mem[i], local_tol, local_tol); - ARKStepCreateSUNStepper(partition_mem[i], &steppers[i]); + ARKodeCreateSUNStepper(partition_mem[i], &steppers[i]); } auto arkode_mem = SplittingStepCreate(steppers.data(), partitions, t0, y, ctx); @@ -147,8 +147,8 @@ static int test_mixed_directions(const sundials::Context& ctx) ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); SUNStepper steppers[] = {nullptr, nullptr}; - ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); - ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); + ARKodeCreateSUNStepper(parititon_mem[0], &steppers[0]); + ARKodeCreateSUNStepper(parititon_mem[1], &steppers[1]); auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); @@ -246,8 +246,8 @@ static int test_resize(const sundials::Context& ctx) ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); SUNStepper steppers[] = {nullptr, nullptr}; - ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); - ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); + ARKodeCreateSUNStepper(parititon_mem[0], &steppers[0]); + ARKodeCreateSUNStepper(parititon_mem[1], &steppers[1]); auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); @@ -310,19 +310,18 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, const auto empty_func = [](auto... args) { return 0; }; SUNStepper_SetResetFn(stepper, empty_func); SUNStepper_SetStopTimeFn(stepper, empty_func); - SUNStepper_SetSetStepDirectionFn(stepper, empty_func); + SUNStepper_SetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); SUNStepper_SetEvolveFn(stepper, [](const SUNStepper s, const sunrealtype t0, const sunrealtype tout, const N_Vector y, - sunrealtype* const tret, int* const stop_reason) + sunrealtype* const tret) { void* content = nullptr; SUNStepper_GetContent(s, &content); const auto lam = *static_cast(content); N_VScale(std::exp(lam * (tout - t0)), y, y); *tret = tout; - *stop_reason = 0; return 0; }); SUNStepper_SetContent(stepper, diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index 0037e976d4..149dcad1a1 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -67,8 +67,8 @@ static int test_forward(SUNContext ctx) ARKodeSStolerances(parititon_mem[1], local_tol, local_tol); SUNStepper steppers[] = {NULL, NULL}; - ARKStepCreateSUNStepper(parititon_mem[0], &steppers[0]); - ARKStepCreateSUNStepper(parititon_mem[1], &steppers[1]); + ARKodeCreateSUNStepper(parititon_mem[0], &steppers[0]); + ARKodeCreateSUNStepper(parititon_mem[1], &steppers[1]); void* arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); From 0984d3e93d229601bda1f381d5db1be486619623 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 20:16:58 -0700 Subject: [PATCH 117/180] Apply formatter --- include/sundials/sundials_stepper.h | 4 +-- src/arkode/arkode_splittingstep.c | 2 +- src/arkode/arkode_sunstepper.c | 12 +++++--- src/sundials/sundials_stepper.c | 2 +- .../CXX_serial/ark_test_splittingstep.cpp | 29 ++++++++++--------- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index c63122b6e0..7be02fa131 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -98,11 +98,11 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, - SUNStepperSetStepDirectionFn fn); + SUNStepperSetStepDirectionFn fn); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, - SUNStepperGetStepDirectionFn fn); + SUNStepperGetStepDirectionFn fn); SUNDIALS_EXPORT SUNErrCode SUNStepper_Evolve(SUNStepper stepper, sunrealtype t0, diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index d7e3380cb6..7322f16c28 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -265,7 +265,7 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } sunrealtype tret = 0; - err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret); + err = SUNStepper_Evolve(stepper, t_start, t_end, y, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[k]++; diff --git a/src/arkode/arkode_sunstepper.c b/src/arkode/arkode_sunstepper.c index 73ce0605c8..e8a733ba14 100644 --- a/src/arkode/arkode_sunstepper.c +++ b/src/arkode/arkode_sunstepper.c @@ -124,7 +124,8 @@ static SUNErrCode arkSUNStepperSetStopTime(SUNStepper stepper, sunrealtype tstop return SUN_SUCCESS; } -static SUNErrCode arkSUNStepperSetStepDirection(SUNStepper stepper, sunrealtype stepdir) +static SUNErrCode arkSUNStepperSetStepDirection(SUNStepper stepper, + sunrealtype stepdir) { SUNFunctionBegin(stepper->sunctx); /* extract the ARKODE memory struct */ @@ -137,7 +138,8 @@ static SUNErrCode arkSUNStepperSetStepDirection(SUNStepper stepper, sunrealtype return SUN_SUCCESS; } -static SUNErrCode arkSUNStepperGetStepDirection(SUNStepper stepper, sunrealtype *stepdir) +static SUNErrCode arkSUNStepperGetStepDirection(SUNStepper stepper, + sunrealtype* stepdir) { SUNFunctionBegin(stepper->sunctx); /* extract the ARKODE memory struct */ @@ -187,8 +189,10 @@ int ARKodeCreateSUNStepper(void* arkode_mem, SUNStepper* stepper) SUNCheckCall(SUNStepper_SetFullRhsFn(*stepper, arkSUNStepperFullRhs)); SUNCheckCall(SUNStepper_SetResetFn(*stepper, arkSUNStepperReset)); SUNCheckCall(SUNStepper_SetStopTimeFn(*stepper, arkSUNStepperSetStopTime)); - SUNCheckCall(SUNStepper_SetStepDirectionFn(*stepper, arkSUNStepperSetStepDirection)); - SUNCheckCall(SUNStepper_SetGetStepDirectionFn(*stepper, arkSUNStepperGetStepDirection)); + SUNCheckCall( + SUNStepper_SetStepDirectionFn(*stepper, arkSUNStepperSetStepDirection)); + SUNCheckCall( + SUNStepper_SetGetStepDirectionFn(*stepper, arkSUNStepperGetStepDirection)); SUNCheckCall(SUNStepper_SetForcingFn(*stepper, arkSUNStepperSetForcing)); return ARK_SUCCESS; diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 740ff728b4..4f624bb5d3 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -189,7 +189,7 @@ SUNErrCode SUNStepper_SetStopTimeFn(SUNStepper stepper, SUNStepperSetStopTimeFn } SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, - SUNStepperSetStepDirectionFn fn) + SUNStepperSetStepDirectionFn fn) { SUNFunctionBegin(stepper->sunctx); stepper->ops->setstepdirection = fn; diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index c1e5635846..97c3263530 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -306,26 +306,27 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, { SUNStepper stepper = nullptr; SUNStepper_Create(ctx, &stepper); + SUNStepper_SetContent(stepper, + static_cast(const_cast(&lambda))); const auto empty_func = [](auto... args) { return 0; }; SUNStepper_SetResetFn(stepper, empty_func); SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); - SUNStepper_SetEvolveFn(stepper, - [](const SUNStepper s, const sunrealtype t0, - const sunrealtype tout, const N_Vector y, - sunrealtype* const tret) - { - void* content = nullptr; - SUNStepper_GetContent(s, &content); - const auto lam = *static_cast(content); - N_VScale(std::exp(lam * (tout - t0)), y, y); - *tret = tout; - return 0; - }); - SUNStepper_SetContent(stepper, - static_cast(const_cast(&lambda))); + + const auto evolve = [](const SUNStepper s, const sunrealtype t0, + const sunrealtype tout, const N_Vector y, + sunrealtype* const tret) + { + void* content = nullptr; + SUNStepper_GetContent(s, &content); + const auto lam = *static_cast(content); + N_VScale(std::exp(lam * (tout - t0)), y, y); + *tret = tout; + return 0; + }; + SUNStepper_SetEvolveFn(stepper, evolve); return stepper; } From 2b4340826a9f17e205236b97b1e65f9ce2fbc654 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 20:30:07 -0700 Subject: [PATCH 118/180] ERKStep works as a SUNStepper using in SplittingStep! --- ...k_advection_diffusion_reaction_splitting.c | 14 ++-- ...advection_diffusion_reaction_splitting.out | 76 ++++++++----------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 7ca53e6bd7..d494aebb71 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -35,6 +35,7 @@ *---------------------------------------------------------------*/ #include +#include #include #include #include @@ -234,16 +235,15 @@ int main(void) N_VConst(udata.u0, y); /* Create advection integrator */ - void* advection_mem = ARKStepCreate(f_advection, NULL, T0, y, ctx); - if (check_flag(advection_mem, "ARKStepCreate", 0)) { return 1; } + void* advection_mem = ERKStepCreate(f_advection, T0, y, ctx); + if (check_flag(advection_mem, "ERKStepCreate", 0)) { return 1; } flag = ARKodeSetUserData(advection_mem, &udata); if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } /* Choose a strong stability preserving method for advecton */ - flag = ARKStepSetTableNum(advection_mem, ARKODE_DIRK_NONE, - ARKODE_SHU_OSHER_3_2_3); - if (check_flag(&flag, "ARKStepSetTableNum", 1)) { return 1; } + flag = ERKStepSetTableNum(advection_mem, ARKODE_SHU_OSHER_3_2_3); + if (check_flag(&flag, "ERKStepSetTableNum", 1)) { return 1; } SUNStepper advection_stepper; flag = ARKodeCreateSUNStepper(advection_mem, &advection_stepper); @@ -279,8 +279,8 @@ int main(void) if (check_flag(&flag, "ARKodeCreateSUNStepper", 1)) { return 1; } /* Create reaction integrator */ - void* reaction_mem = ARKStepCreate(f_reaction, NULL, T0, y, ctx); - if (check_flag(reaction_mem, "ARKStepCreate", 0)) { return 1; } + void* reaction_mem = ERKStepCreate(f_reaction, T0, y, ctx); + if (check_flag(reaction_mem, "ERKStepCreate", 0)) { return 1; } flag = ARKodeSetUserData(reaction_mem, &udata); if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out index c214a6deab..5e9e2912a0 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.out @@ -8,23 +8,23 @@ t ||u||_rms ---------------------- 0.000000 0.100000 - 0.060000 0.126734 - 0.120000 0.154228 - 0.180000 0.185715 - 0.240000 0.221941 - 0.300000 0.263180 - 0.360000 0.309219 + 0.060000 0.126735 + 0.120000 0.154225 + 0.180000 0.185713 + 0.240000 0.221939 + 0.300000 0.263178 + 0.360000 0.309221 0.420000 0.359242 - 0.480000 0.411734 - 0.540000 0.464560 - 0.600000 0.515252 - 0.660000 0.561484 - 0.720000 0.601560 + 0.480000 0.411736 + 0.540000 0.464562 + 0.600000 0.515253 + 0.660000 0.561485 + 0.720000 0.601561 0.780000 0.634693 - 0.840000 0.660980 - 0.900000 0.681152 + 0.840000 0.660982 + 0.900000 0.681150 0.960000 0.696244 - 1.000000 0.702992 + 1.000000 0.702991 ---------------------- Splitting Stepper Statistics: @@ -45,42 +45,37 @@ Partition 2 evolves = 17 Advection Stepper Statistics: Current time = 1 -Steps = 53 -Step attempts = 54 +Steps = 55 +Step attempts = 64 Stability limited steps = 0 -Accuracy limited steps = 54 -Error test fails = 1 +Accuracy limited steps = 64 +Error test fails = 9 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 2.059355438929501e-06 -Last step size = 0.008743161639560786 -Current step size = 0.008743161639560786 -Explicit RHS fn evals = 163 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +Last step size = 0.004032057223863014 +Current step size = 0.004032057223863014 +RHS fn evals = 185 Diffusion Stepper Statistics: Current time = 1 -Steps = 246 +Steps = 247 Step attempts = 302 Stability limited steps = 0 Accuracy limited steps = 302 -Error test fails = 56 +Error test fails = 55 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 2.059355438929501e-06 -Last step size = 0.004572821688115565 -Current step size = 0.004572821688115565 +Last step size = 0.006555275857754277 +Current step size = 0.006555275857754277 Explicit RHS fn evals = 0 Implicit RHS fn evals = 1831 NLS iters = 906 NLS fails = 0 -NLS iters per step = 3.682926829268293 +NLS iters per step = 3.668016194331984 LS setups = 213 -Jac fn evals = 73 +Jac fn evals = 72 LS RHS fn evals = 0 Prec setup evals = 0 Prec solves = 0 @@ -89,24 +84,19 @@ LS fails = 0 Jac-times setups = 0 Jac-times evals = 0 LS iters per NLS iter = 0 -Jac evals per NLS iter = 0.08057395143487858 +Jac evals per NLS iter = 0.07947019867549669 Prec evals per NLS iter = 0 Reaction Stepper Statistics: Current time = 1 -Steps = 38 -Step attempts = 38 +Steps = 42 +Step attempts = 49 Stability limited steps = 0 -Accuracy limited steps = 38 -Error test fails = 0 +Accuracy limited steps = 49 +Error test fails = 7 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 0.00180442856879795 Last step size = 0.03999999999999956 Current step size = 0.03999999999999956 -Explicit RHS fn evals = 133 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 166 From a1922436cb30beea4b7ae21633b588a0c98eb77c Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 20:55:41 -0700 Subject: [PATCH 119/180] swig --- .../fmod_int32/farkode_forcingstep_mod.c | 41 +------ .../fmod_int32/farkode_forcingstep_mod.f90 | 28 ++--- .../fmod_int32/farkode_splittingstep_mod.c | 5 +- .../fmod_int32/farkode_splittingstep_mod.f90 | 12 +- .../fmod_int64/farkode_forcingstep_mod.c | 41 +------ .../fmod_int64/farkode_forcingstep_mod.f90 | 28 ++--- .../fmod_int64/farkode_splittingstep_mod.c | 5 +- .../fmod_int64/farkode_splittingstep_mod.f90 | 12 +- src/sundials/fmod_int32/fsundials_core_mod.c | 64 +++++++++- .../fmod_int32/fsundials_core_mod.f90 | 114 +++++++++++++++++- src/sundials/fmod_int64/fsundials_core_mod.c | 64 +++++++++- .../fmod_int64/fsundials_core_mod.f90 | 114 +++++++++++++++++- 12 files changed, 376 insertions(+), 152 deletions(-) diff --git a/src/arkode/fmod_int32/farkode_forcingstep_mod.c b/src/arkode/fmod_int32/farkode_forcingstep_mod.c index 09f5a679e7..2c4fc34ed0 100644 --- a/src/arkode/fmod_int32/farkode_forcingstep_mod.c +++ b/src/arkode/fmod_int32/farkode_forcingstep_mod.c @@ -178,21 +178,6 @@ { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } -enum { - SWIG_MEM_OWN = 0x01, - SWIG_MEM_RVALUE = 0x02, - SWIG_MEM_CONST = 0x04 -}; - - -#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ - if (!(SWIG_CLASS_WRAPPER).cptr) { \ - SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ - "Cannot pass null " TYPENAME " (class " FNAME ") " \ - "as a reference", RETURNNULL); \ - } - - #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -220,33 +205,17 @@ enum { #include "arkode/arkode_forcingstep.h" - -typedef struct { - void* cptr; - int cmemflags; -} SwigClassWrapper; - - -SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { - SwigClassWrapper result; - result.cptr = NULL; - result.cmemflags = 0; - return result; -} - -SWIGEXPORT void * _wrap_FForcingStepCreate(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { +SWIGEXPORT void * _wrap_FForcingStepCreate(void *farg1, void *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; - SUNStepper arg1 ; - SUNStepper arg2 ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepper arg2 = (SUNStepper) 0 ; sunrealtype arg3 ; N_Vector arg4 = (N_Vector) 0 ; SUNContext arg5 = (SUNContext) 0 ; void *result = 0 ; - SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = *(SUNStepper *)(farg1->cptr); - SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg2 = *(SUNStepper *)(farg2->cptr); + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepper)(farg2); arg3 = (sunrealtype)(*farg3); arg4 = (N_Vector)(farg4); arg5 = (SUNContext)(farg5); diff --git a/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 b/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 index 99c8932478..ebeb517b66 100644 --- a/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_forcingstep_mod.f90 @@ -26,17 +26,6 @@ module farkode_forcingstep_mod private ! DECLARATION CONSTRUCTS - - integer, parameter :: swig_cmem_own_bit = 0 - integer, parameter :: swig_cmem_rvalue_bit = 1 - integer, parameter :: swig_cmem_const_bit = 2 - type, bind(C) :: SwigClassWrapper - type(C_PTR), public :: cptr = C_NULL_PTR - integer(C_INT), public :: cmemflags = 0 - end type - type, public :: SWIGTYPE_p_SUNStepper - type(SwigClassWrapper), public :: swigdata - end type public :: FForcingStepCreate public :: FForcingStep_GetNumEvolves @@ -46,9 +35,8 @@ function swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FForcingStepCreate") & result(fresult) use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 type(C_PTR), value :: farg5 @@ -74,20 +62,20 @@ function FForcingStepCreate(stepper1, stepper2, t0, y0, sunctx) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(C_PTR) :: swig_result -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +type(C_PTR) :: stepper1 +type(C_PTR) :: stepper2 real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx type(C_PTR) :: fresult -type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = stepper1%swigdata -farg2 = stepper2%swigdata +farg1 = stepper1 +farg2 = stepper2 farg3 = t0 farg4 = c_loc(y0) farg5 = sunctx diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.c b/src/arkode/fmod_int32/farkode_splittingstep_mod.c index f343e4ce69..413a87802e 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.c @@ -691,7 +691,7 @@ SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SuzukiFractal(int c } -SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { +SWIGEXPORT void * _wrap_FSplittingStepCreate(void *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; SUNStepper *arg1 = (SUNStepper *) 0 ; int arg2 ; @@ -700,8 +700,7 @@ SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int SUNContext arg5 = (SUNContext) 0 ; void *result = 0 ; - SWIG_check_mutable(*farg1, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "SplittingStepCreate(SUNStepper *,int,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = (SUNStepper *)(farg1->cptr); + arg1 = (SUNStepper *)(farg1); arg2 = (int)(*farg2); arg3 = (sunrealtype)(*farg3); arg4 = (N_Vector)(farg4); diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 index da68d91177..13f4e2b7be 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 @@ -93,9 +93,6 @@ module farkode_splittingstep_mod public :: FSplittingStepCoefficients_ThirdOrderSuzuki public :: FSplittingStepCoefficients_TripleJump public :: FSplittingStepCoefficients_SuzukiFractal - type, public :: SWIGTYPE_p_SUNStepper - type(SwigClassWrapper), public :: swigdata - end type public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients public :: FSplittingStep_GetNumEvolves @@ -378,8 +375,7 @@ function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSplittingStepCreate") & result(fresult) use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg1 integer(C_INT), intent(in) :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 @@ -854,19 +850,19 @@ function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(C_PTR) :: swig_result -class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +type(C_PTR), target, intent(inout) :: steppers integer(C_INT), intent(in) :: partitions real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx type(C_PTR) :: fresult -type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg1 integer(C_INT) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = steppers%swigdata +farg1 = c_loc(steppers) farg2 = partitions farg3 = t0 farg4 = c_loc(y0) diff --git a/src/arkode/fmod_int64/farkode_forcingstep_mod.c b/src/arkode/fmod_int64/farkode_forcingstep_mod.c index 09f5a679e7..2c4fc34ed0 100644 --- a/src/arkode/fmod_int64/farkode_forcingstep_mod.c +++ b/src/arkode/fmod_int64/farkode_forcingstep_mod.c @@ -178,21 +178,6 @@ { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } -enum { - SWIG_MEM_OWN = 0x01, - SWIG_MEM_RVALUE = 0x02, - SWIG_MEM_CONST = 0x04 -}; - - -#define SWIG_check_nonnull(SWIG_CLASS_WRAPPER, TYPENAME, FNAME, FUNCNAME, RETURNNULL) \ - if (!(SWIG_CLASS_WRAPPER).cptr) { \ - SWIG_exception_impl(FUNCNAME, SWIG_TypeError, \ - "Cannot pass null " TYPENAME " (class " FNAME ") " \ - "as a reference", RETURNNULL); \ - } - - #include #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) # ifndef snprintf @@ -220,33 +205,17 @@ enum { #include "arkode/arkode_forcingstep.h" - -typedef struct { - void* cptr; - int cmemflags; -} SwigClassWrapper; - - -SWIGINTERN SwigClassWrapper SwigClassWrapper_uninitialized() { - SwigClassWrapper result; - result.cptr = NULL; - result.cmemflags = 0; - return result; -} - -SWIGEXPORT void * _wrap_FForcingStepCreate(SwigClassWrapper const *farg1, SwigClassWrapper const *farg2, double const *farg3, N_Vector farg4, void *farg5) { +SWIGEXPORT void * _wrap_FForcingStepCreate(void *farg1, void *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; - SUNStepper arg1 ; - SUNStepper arg2 ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepper arg2 = (SUNStepper) 0 ; sunrealtype arg3 ; N_Vector arg4 = (N_Vector) 0 ; SUNContext arg5 = (SUNContext) 0 ; void *result = 0 ; - SWIG_check_nonnull(*farg1, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = *(SUNStepper *)(farg1->cptr); - SWIG_check_nonnull(*farg2, "SUNStepper", "SWIGTYPE_p_SUNStepper", "ForcingStepCreate(SUNStepper,SUNStepper,sunrealtype,N_Vector,SUNContext)", return 0); - arg2 = *(SUNStepper *)(farg2->cptr); + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepper)(farg2); arg3 = (sunrealtype)(*farg3); arg4 = (N_Vector)(farg4); arg5 = (SUNContext)(farg5); diff --git a/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 b/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 index 99c8932478..ebeb517b66 100644 --- a/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_forcingstep_mod.f90 @@ -26,17 +26,6 @@ module farkode_forcingstep_mod private ! DECLARATION CONSTRUCTS - - integer, parameter :: swig_cmem_own_bit = 0 - integer, parameter :: swig_cmem_rvalue_bit = 1 - integer, parameter :: swig_cmem_const_bit = 2 - type, bind(C) :: SwigClassWrapper - type(C_PTR), public :: cptr = C_NULL_PTR - integer(C_INT), public :: cmemflags = 0 - end type - type, public :: SWIGTYPE_p_SUNStepper - type(SwigClassWrapper), public :: swigdata - end type public :: FForcingStepCreate public :: FForcingStep_GetNumEvolves @@ -46,9 +35,8 @@ function swigc_FForcingStepCreate(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FForcingStepCreate") & result(fresult) use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 type(C_PTR), value :: farg5 @@ -74,20 +62,20 @@ function FForcingStepCreate(stepper1, stepper2, t0, y0, sunctx) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(C_PTR) :: swig_result -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper1 -type(SWIGTYPE_p_SUNStepper), intent(in) :: stepper2 +type(C_PTR) :: stepper1 +type(C_PTR) :: stepper2 real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx type(C_PTR) :: fresult -type(SwigClassWrapper) :: farg1 -type(SwigClassWrapper) :: farg2 +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = stepper1%swigdata -farg2 = stepper2%swigdata +farg1 = stepper1 +farg2 = stepper2 farg3 = t0 farg4 = c_loc(y0) farg5 = sunctx diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.c b/src/arkode/fmod_int64/farkode_splittingstep_mod.c index f343e4ce69..413a87802e 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.c @@ -691,7 +691,7 @@ SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_SuzukiFractal(int c } -SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { +SWIGEXPORT void * _wrap_FSplittingStepCreate(void *farg1, int const *farg2, double const *farg3, N_Vector farg4, void *farg5) { void * fresult ; SUNStepper *arg1 = (SUNStepper *) 0 ; int arg2 ; @@ -700,8 +700,7 @@ SWIGEXPORT void * _wrap_FSplittingStepCreate(SwigClassWrapper const *farg1, int SUNContext arg5 = (SUNContext) 0 ; void *result = 0 ; - SWIG_check_mutable(*farg1, "SUNStepper *", "SWIGTYPE_p_SUNStepper", "SplittingStepCreate(SUNStepper *,int,sunrealtype,N_Vector,SUNContext)", return 0); - arg1 = (SUNStepper *)(farg1->cptr); + arg1 = (SUNStepper *)(farg1); arg2 = (int)(*farg2); arg3 = (sunrealtype)(*farg3); arg4 = (N_Vector)(farg4); diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 index da68d91177..13f4e2b7be 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 @@ -93,9 +93,6 @@ module farkode_splittingstep_mod public :: FSplittingStepCoefficients_ThirdOrderSuzuki public :: FSplittingStepCoefficients_TripleJump public :: FSplittingStepCoefficients_SuzukiFractal - type, public :: SWIGTYPE_p_SUNStepper - type(SwigClassWrapper), public :: swigdata - end type public :: FSplittingStepCreate public :: FSplittingStep_SetCoefficients public :: FSplittingStep_GetNumEvolves @@ -378,8 +375,7 @@ function swigc_FSplittingStepCreate(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSplittingStepCreate") & result(fresult) use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg1 integer(C_INT), intent(in) :: farg2 real(C_DOUBLE), intent(in) :: farg3 type(C_PTR), value :: farg4 @@ -854,19 +850,19 @@ function FSplittingStepCreate(steppers, partitions, t0, y0, sunctx) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(C_PTR) :: swig_result -class(SWIGTYPE_p_SUNStepper), intent(in) :: steppers +type(C_PTR), target, intent(inout) :: steppers integer(C_INT), intent(in) :: partitions real(C_DOUBLE), intent(in) :: t0 type(N_Vector), target, intent(inout) :: y0 type(C_PTR) :: sunctx type(C_PTR) :: fresult -type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg1 integer(C_INT) :: farg2 real(C_DOUBLE) :: farg3 type(C_PTR) :: farg4 type(C_PTR) :: farg5 -farg1 = steppers%swigdata +farg1 = c_loc(steppers) farg2 = partitions farg3 = t0 farg4 = c_loc(y0) diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index cd93f56314..b0a7ed7876 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2782,15 +2782,29 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTimeFn(void *farg1, SUNStepperSetStopTim } -SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirectionFn(void *farg1, SUNStepperSetStepDirectionFn farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNStepperSetStepDirectionFn arg2 = (SUNStepperSetStepDirectionFn) 0 ; SUNErrCode result; arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperSetForcingFn)(farg2); - result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + arg2 = (SUNStepperSetStepDirectionFn)(farg2); + result = (SUNErrCode)SUNStepper_SetStepDirectionFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGetStepDirectionFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperGetStepDirectionFn arg2 = (SUNStepperGetStepDirectionFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperGetStepDirectionFn)(farg2); + result = (SUNErrCode)SUNStepper_SetGetStepDirectionFn(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } @@ -2886,6 +2900,48 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperSetForcingFn)(farg2); + result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNStepper_SetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_GetStepDirection(void *farg1, double *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype *)(farg2); + result = (SUNErrCode)SUNStepper_GetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_SetForcing(void *farg1, double const *farg2, double const *farg3, void *farg4, int const *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 42ab3464c8..fde9c4ba7b 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -553,12 +553,16 @@ module fsundials_core_mod public :: FSUNStepper_SetFullRhsFn public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn - public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetStepDirectionFn + public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_Evolve public :: FSUNStepper_OneStep public :: FSUNStepper_TryStep public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime + public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetStepDirection + public :: FSUNStepper_GetStepDirection public :: FSUNStepper_SetForcing ! WRAPPER DECLARATIONS @@ -2147,8 +2151,17 @@ function swigc_FSUNStepper_SetStopTimeFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +function swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirectionFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetGetStepDirectionFn") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -2211,6 +2224,33 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_GetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_GetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_SetForcing(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_SetForcing") & result(fresult) @@ -5121,7 +5161,7 @@ function FSUNStepper_SetStopTimeFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_SetForcingFn(stepper, fn) & +function FSUNStepper_SetStepDirectionFn(stepper, fn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -5133,7 +5173,23 @@ function FSUNStepper_SetForcingFn(stepper, fn) & farg1 = stepper farg2 = fn -fresult = swigc_FSUNStepper_SetForcingFn(farg1, farg2) +fresult = swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_SetGetStepDirectionFn(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_SetGetStepDirectionFn(farg1, farg2) swig_result = fresult end function @@ -5247,6 +5303,54 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function +function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_SetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = stepper +farg2 = stepdir +fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_GetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = stepper +farg2 = c_loc(stepdir(1)) +fresult = swigc_FSUNStepper_GetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_SetForcing(stepper, tshift, tscale, forcing, nforcing) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index a0e410c75b..814fda5df8 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2782,15 +2782,29 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTimeFn(void *farg1, SUNStepperSetStopTim } -SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirectionFn(void *farg1, SUNStepperSetStepDirectionFn farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNStepperSetStepDirectionFn arg2 = (SUNStepperSetStepDirectionFn) 0 ; SUNErrCode result; arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperSetForcingFn)(farg2); - result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + arg2 = (SUNStepperSetStepDirectionFn)(farg2); + result = (SUNErrCode)SUNStepper_SetStepDirectionFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGetStepDirectionFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperGetStepDirectionFn arg2 = (SUNStepperGetStepDirectionFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperGetStepDirectionFn)(farg2); + result = (SUNErrCode)SUNStepper_SetGetStepDirectionFn(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } @@ -2886,6 +2900,48 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperSetForcingFn)(farg2); + result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNStepper_SetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNStepper_GetStepDirection(void *farg1, double *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype *arg2 = (sunrealtype *) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype *)(farg2); + result = (SUNErrCode)SUNStepper_GetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_SetForcing(void *farg1, double const *farg2, double const *farg3, void *farg4, int const *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 34cc744eed..a9bfae9bfc 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -553,12 +553,16 @@ module fsundials_core_mod public :: FSUNStepper_SetFullRhsFn public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn - public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetStepDirectionFn + public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_Evolve public :: FSUNStepper_OneStep public :: FSUNStepper_TryStep public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime + public :: FSUNStepper_SetForcingFn + public :: FSUNStepper_SetStepDirection + public :: FSUNStepper_GetStepDirection public :: FSUNStepper_SetForcing ! WRAPPER DECLARATIONS @@ -2147,8 +2151,17 @@ function swigc_FSUNStepper_SetStopTimeFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +function swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirectionFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetGetStepDirectionFn") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -2211,6 +2224,33 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FSUNStepper_GetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_GetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_SetForcing(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_SetForcing") & result(fresult) @@ -5121,7 +5161,7 @@ function FSUNStepper_SetStopTimeFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_SetForcingFn(stepper, fn) & +function FSUNStepper_SetStepDirectionFn(stepper, fn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -5133,7 +5173,23 @@ function FSUNStepper_SetForcingFn(stepper, fn) & farg1 = stepper farg2 = fn -fresult = swigc_FSUNStepper_SetForcingFn(farg1, farg2) +fresult = swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_SetGetStepDirectionFn(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_SetGetStepDirectionFn(farg1, farg2) swig_result = fresult end function @@ -5247,6 +5303,54 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function +function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_SetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = stepper +farg2 = stepdir +fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) +swig_result = fresult +end function + +function FSUNStepper_GetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = stepper +farg2 = c_loc(stepdir(1)) +fresult = swigc_FSUNStepper_GetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_SetForcing(stepper, tshift, tscale, forcing, nforcing) & result(swig_result) use, intrinsic :: ISO_C_BINDING From aa1aff495f3944788a48ecd303c06c63a7dab0d8 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 27 Sep 2024 21:03:10 -0700 Subject: [PATCH 120/180] Reorder header for better diff --- include/sundials/sundials_stepper.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 7be02fa131..cc17fc9daf 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -104,6 +104,9 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, SUNStepperGetStepDirectionFn fn); +SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, + SUNStepperSetForcingFn fn); + SUNDIALS_EXPORT SUNErrCode SUNStepper_Evolve(SUNStepper stepper, sunrealtype t0, sunrealtype tout, N_Vector y, sunrealtype* tret); @@ -122,9 +125,6 @@ SUNErrCode SUNStepper_Reset(SUNStepper stepper, sunrealtype tR, N_Vector yR); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop); -SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, - SUNStepperSetForcingFn fn); - SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir); From 4fc99adf8762872cb7ab2d07c95c96bea0c5b977 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 30 Sep 2024 09:58:09 -0700 Subject: [PATCH 121/180] Swig update --- src/sundials/fmod_int32/fsundials_core_mod.c | 28 +++++----- .../fmod_int32/fsundials_core_mod.f90 | 52 +++++++++---------- src/sundials/fmod_int64/fsundials_core_mod.c | 28 +++++----- .../fmod_int64/fsundials_core_mod.f90 | 52 +++++++++---------- 4 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index b0a7ed7876..e4a6ad95a2 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2810,6 +2810,20 @@ SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGe } +SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperSetForcingFn)(farg2); + result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_Evolve(void *farg1, double const *farg2, double const *farg3, N_Vector farg4, double *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2900,20 +2914,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } -SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperSetForcingFn)(farg2); - result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index fde9c4ba7b..d4d5affc3c 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -555,12 +555,12 @@ module fsundials_core_mod public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetGetStepDirectionFn + public :: FSUNStepper_SetForcingFn public :: FSUNStepper_Evolve public :: FSUNStepper_OneStep public :: FSUNStepper_TryStep public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime - public :: FSUNStepper_SetForcingFn public :: FSUNStepper_SetStepDirection public :: FSUNStepper_GetStepDirection public :: FSUNStepper_SetForcing @@ -2169,6 +2169,15 @@ function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_Evolve(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_Evolve") & result(fresult) @@ -2224,15 +2233,6 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetForcingFn") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetStepDirection") & result(fresult) @@ -5193,6 +5193,22 @@ function FSUNStepper_SetGetStepDirectionFn(stepper, fn) & swig_result = fresult end function +function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_Evolve(stepper, t0, tout, y, tret) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5303,22 +5319,6 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function -function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) -swig_result = fresult -end function - function FSUNStepper_SetStepDirection(stepper, stepdir) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 814fda5df8..c1fcfa0b02 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2810,6 +2810,20 @@ SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGe } +SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (SUNStepperSetForcingFn)(farg2); + result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_Evolve(void *farg1, double const *farg2, double const *farg3, N_Vector farg4, double *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2900,20 +2914,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } -SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperSetForcingFn arg2 = (SUNStepperSetForcingFn) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperSetForcingFn)(farg2); - result = (SUNErrCode)SUNStepper_SetForcingFn(arg1,arg2); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index a9bfae9bfc..64a98b2ec4 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -555,12 +555,12 @@ module fsundials_core_mod public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetGetStepDirectionFn + public :: FSUNStepper_SetForcingFn public :: FSUNStepper_Evolve public :: FSUNStepper_OneStep public :: FSUNStepper_TryStep public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime - public :: FSUNStepper_SetForcingFn public :: FSUNStepper_SetStepDirection public :: FSUNStepper_GetStepDirection public :: FSUNStepper_SetForcing @@ -2169,6 +2169,15 @@ function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetForcingFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_Evolve(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_Evolve") & result(fresult) @@ -2224,15 +2233,6 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetForcingFn") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetStepDirection") & result(fresult) @@ -5193,6 +5193,22 @@ function FSUNStepper_SetGetStepDirectionFn(stepper, fn) & swig_result = fresult end function +function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_Evolve(stepper, t0, tout, y, tret) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5303,22 +5319,6 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function -function FSUNStepper_SetForcingFn(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_SetForcingFn(farg1, farg2) -swig_result = fresult -end function - function FSUNStepper_SetStepDirection(stepper, stepdir) & result(swig_result) use, intrinsic :: ISO_C_BINDING From 3daa9f5b6ee7873dea3b76e9e1117c1e56a126e9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 30 Sep 2024 18:28:34 -0700 Subject: [PATCH 122/180] Clear forcing after evolve --- src/arkode/arkode_forcingstep.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index ff99bd43e1..6f9eebb0d9 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -199,12 +199,17 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, ark_mem->tempv1); err = SUNStepper_SetForcing(s1, ZERO, ZERO, &ark_mem->tempv1, 1); + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } /* Evolve stepper 1 with the forcing */ err = SUNStepper_Evolve(s1, ark_mem->tn, tout, ark_mem->ycur, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } step_mem->n_stepper_evolves[1]++; + /* Clear the forcing so it doesn't get included in a fullRhs call */ + err = SUNStepper_SetForcing(s1, ZERO, ZERO, NULL, 0); + if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } + return ARK_SUCCESS; } From caeeaffa8236a7700ec8a984d87baabcede7d8c1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 17:32:23 -0700 Subject: [PATCH 123/180] Post merge compilation fixes --- src/arkode/arkode_forcingstep.c | 4 ++-- src/arkode/arkode_splittingstep.c | 6 ++---- src/sundials/sundials_stepper.c | 20 -------------------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 6f9eebb0d9..d912b2f498 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -134,7 +134,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, if (retval != ARK_SUCCESS) { return (retval); } const SUNStepper s0 = step_mem->stepper[0]; - retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1, ARK_FULLRHS_OTHER); + retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -143,7 +143,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, } const SUNStepper s1 = step_mem->stepper[1]; - retval = s1->ops->fullrhs(s1, t, y, f, ARK_FULLRHS_OTHER); + retval = s1->ops->fullrhs(s1, t, y, f); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 7322f16c28..88ec627232 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -185,8 +185,7 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return (retval); } - retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f, - ARK_FULLRHS_OTHER); + retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -197,8 +196,7 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, for (int i = 1; i < step_mem->partitions; i++) { retval = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, - ark_mem->tempv1, - ARK_FULLRHS_OTHER); + ark_mem->tempv1); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index 9ed89c12e3..e56952aff2 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -110,26 +110,6 @@ SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) return SUN_ERR_NOT_IMPLEMENTED; } -SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - if (stepper->ops->setstepdirection) - { - return stepper->ops->setstepdirection(stepper, stepdir); - } - else { return SUN_ERR_NOT_IMPLEMENTED; } -} - -SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - if (stepper->ops->setstepdirection) - { - return stepper->ops->getstepdirection(stepper, stepdir); - } - else { return SUN_ERR_NOT_IMPLEMENTED; } -} - SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) From 831d8848c6057c974bd7bc4c2498115371def14a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 17:40:33 -0700 Subject: [PATCH 124/180] Apply formatter --- src/arkode/arkode_forcingstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index d912b2f498..35224aca27 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -134,7 +134,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, if (retval != ARK_SUCCESS) { return (retval); } const SUNStepper s0 = step_mem->stepper[0]; - retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1); + retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1); if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, From c52c645f735647956272631bb08cb81121a299c3 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 18:00:41 -0700 Subject: [PATCH 125/180] Remove extra declaration in header --- include/sundials/sundials_stepper.h | 4 -- src/sundials/fmod_int32/fsundials_core_mod.c | 20 ---------- .../fmod_int32/fsundials_core_mod.f90 | 38 ------------------- src/sundials/fmod_int64/fsundials_core_mod.c | 20 ---------- .../fmod_int64/fsundials_core_mod.f90 | 38 ------------------- 5 files changed, 120 deletions(-) diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index a88c397ab4..8c528c6bcf 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -128,10 +128,6 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_OneStep(SUNStepper stepper, sunrealtype t0, sunrealtype tout, N_Vector y, sunrealtype* tret); -SUNDIALS_EXPORT -SUNErrCode SUNStepper_TryStep(SUNStepper stepper, sunrealtype t0, - sunrealtype tout, N_Vector y, sunrealtype* tret); - SUNDIALS_EXPORT SUNErrCode SUNStepper_Reset(SUNStepper stepper, sunrealtype tR, N_Vector yR); diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 007f18f375..694603b653 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2928,26 +2928,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingF } -SWIGEXPORT int _wrap_FSUNStepper_TryStep(void *farg1, double const *farg2, double const *farg3, N_Vector farg4, double *farg5) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - sunrealtype arg2 ; - sunrealtype arg3 ; - N_Vector arg4 = (N_Vector) 0 ; - sunrealtype *arg5 = (sunrealtype *) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (sunrealtype)(*farg2); - arg3 = (sunrealtype)(*farg3); - arg4 = (N_Vector)(farg4); - arg5 = (sunrealtype *)(farg5); - result = (SUNErrCode)SUNStepper_TryStep(arg1,arg2,arg3,arg4,arg5); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index d4160f5600..8db2180895 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -562,7 +562,6 @@ module fsundials_core_mod public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_SetForcingFn - public :: FSUNStepper_TryStep public :: FSUNStepper_SetStepDirection public :: FSUNStepper_GetStepDirection @@ -2243,18 +2242,6 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_TryStep(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSUNStepper_TryStep") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -real(C_DOUBLE), intent(in) :: farg3 -type(C_PTR), value :: farg4 -type(C_PTR), value :: farg5 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetStepDirection") & result(fresult) @@ -5345,31 +5332,6 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_TryStep(stepper, t0, tout, y, tret) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: stepper -real(C_DOUBLE), intent(in) :: t0 -real(C_DOUBLE), intent(in) :: tout -type(N_Vector), target, intent(inout) :: y -real(C_DOUBLE), dimension(*), target, intent(inout) :: tret -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 -real(C_DOUBLE) :: farg3 -type(C_PTR) :: farg4 -type(C_PTR) :: farg5 - -farg1 = stepper -farg2 = t0 -farg3 = tout -farg4 = c_loc(y) -farg5 = c_loc(tret(1)) -fresult = swigc_FSUNStepper_TryStep(farg1, farg2, farg3, farg4, farg5) -swig_result = fresult -end function - function FSUNStepper_SetStepDirection(stepper, stepdir) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 461ec4661d..5c8bf3198c 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2928,26 +2928,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingF } -SWIGEXPORT int _wrap_FSUNStepper_TryStep(void *farg1, double const *farg2, double const *farg3, N_Vector farg4, double *farg5) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - sunrealtype arg2 ; - sunrealtype arg3 ; - N_Vector arg4 = (N_Vector) 0 ; - sunrealtype *arg5 = (sunrealtype *) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (sunrealtype)(*farg2); - arg3 = (sunrealtype)(*farg3); - arg4 = (N_Vector)(farg4); - arg5 = (sunrealtype *)(farg5); - result = (SUNErrCode)SUNStepper_TryStep(arg1,arg2,arg3,arg4,arg5); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 8fefb6198b..6fecc07c6b 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -562,7 +562,6 @@ module fsundials_core_mod public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_SetForcingFn - public :: FSUNStepper_TryStep public :: FSUNStepper_SetStepDirection public :: FSUNStepper_GetStepDirection @@ -2243,18 +2242,6 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_TryStep(farg1, farg2, farg3, farg4, farg5) & -bind(C, name="_wrap_FSUNStepper_TryStep") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -real(C_DOUBLE), intent(in) :: farg3 -type(C_PTR), value :: farg4 -type(C_PTR), value :: farg5 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetStepDirection") & result(fresult) @@ -5345,31 +5332,6 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_TryStep(stepper, t0, tout, y, tret) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: stepper -real(C_DOUBLE), intent(in) :: t0 -real(C_DOUBLE), intent(in) :: tout -type(N_Vector), target, intent(inout) :: y -real(C_DOUBLE), dimension(*), target, intent(inout) :: tret -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 -real(C_DOUBLE) :: farg3 -type(C_PTR) :: farg4 -type(C_PTR) :: farg5 - -farg1 = stepper -farg2 = t0 -farg3 = tout -farg4 = c_loc(y) -farg5 = c_loc(tret(1)) -fresult = swigc_FSUNStepper_TryStep(farg1, farg2, farg3, farg4, farg5) -swig_result = fresult -end function - function FSUNStepper_SetStepDirection(stepper, stepdir) & result(swig_result) use, intrinsic :: ISO_C_BINDING From b97068548bf1ecb0f8988be73c641951dd580fd8 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 18:21:37 -0700 Subject: [PATCH 126/180] Remove old ARKStepCreateSUNStepper references --- doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst | 4 ++-- doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst | 2 +- doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst index f24e9623c3..d5d8aa2289 100644 --- a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -71,8 +71,8 @@ ForcingStep initialization functions . . . /* create SUNStepper wrappers for the ARKStep memory blocks */ - flag = ARKStepCreateSUNStepper(partition_mem[0], &stepper[0]); - flag = ARKStepCreateSUNStepper(partition_mem[1], &stepper[1]); + flag = ARKodeCreateSUNStepper(partition_mem[0], &stepper[0]); + flag = ARKodeCreateSUNStepper(partition_mem[1], &stepper[1]); /* create a ForcingStep object */ arkode_mem = ForcingStepCreate(steppers[0], steppers[1], t0, y0, sunctx); diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index 994e08419b..ffccdb8910 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -45,7 +45,7 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. ARKStep. Once the ARKStep object is setup, create a :c:type:`SUNStepper` object with - :c:func:`ARKStepCreateSUNStepper`. + :c:func:`ARKodeCreateSUNStepper`. * If supplying a user-defined inner integrator, create the :c:type:`SUNStepper` object as described in section diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index ea482b8a12..9993066416 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -71,8 +71,8 @@ SplittingStep initialization functions . . . /* create SUNStepper wrappers for the ARKStep memory blocks */ - flag = ARKStepCreateSUNStepper(partition_mem[0], &stepper[0]); - flag = ARKStepCreateSUNStepper(partition_mem[1], &stepper[1]); + flag = ARKodeCreateSUNStepper(partition_mem[0], &stepper[0]); + flag = ARKodeCreateSUNStepper(partition_mem[1], &stepper[1]); /* create a SplittingStep object with two partitions */ arkode_mem = SplittingStepCreate(steppers, 2, t0, y0, sunctx); From 89b8334b376d8074f75eef6fdfd4d3a98a5e15c1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 18:30:40 -0700 Subject: [PATCH 127/180] Remove NV_Ith_S --- examples/arkode/C_serial/ark_analytic_partitioned.c | 6 +++--- test/unit_tests/arkode/C_serial/ark_test_forcingstep.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 3fa2670311..51a532ed5d 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -79,10 +79,10 @@ static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, const UserData* const user_data) { N_Vector sol = N_VClone(y0); - const sunrealtype y0_val = NV_Ith_S(y0, 0); + const sunrealtype y0_val = N_VGetArrayPointer(y0)[0]; const sunrealtype lambda = user_data->lambda; - NV_Ith_S(sol, 0) = lambda * y0_val / - (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); + N_VGetArrayPointer(sol)[0] = + lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); return sol; } diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index 149dcad1a1..11345a3cd0 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -78,7 +78,7 @@ static int test_forward(SUNContext ctx) ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); const sunrealtype exact_solution = SUN_RCONST(2.0); - const sunrealtype numerical_solution = NV_Ith_S(y, 0); + const sunrealtype numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { const sunrealtype err = numerical_solution - exact_solution; From 7cd34e8720423a61b0f7c88edcb61d7ef4be075e Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 2 Oct 2024 19:03:13 -0700 Subject: [PATCH 128/180] Switch to new :param: syntax --- .../SplittingStepCoefficients.rst | 184 +++++++----------- 1 file changed, 73 insertions(+), 111 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index e52984d74e..c45c3a77e4 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -118,13 +118,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. - - **Arguments:** - * ``method`` -- the splitting coefficients identifier. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * A ``NULL`` pointer if *method* was invalid or an allocation error occurred. + :param method: the splitting coefficients identifier. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *method* was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -136,14 +132,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. current set of splitting coefficients and their corresponding name, see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. - - **Arguments:** - * ``method`` -- the splitting coefficients identifier. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * A ``NULL`` pointer if *method* was invalid, *method* was - ``"ARKODE_SPLITTING_NONE"``, or an allocation error occurred. + :param method: the splitting coefficients identifier. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *method* was invalid or an allocation error occurred. .. note:: @@ -159,12 +150,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. their corresponding name, see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Coefficients`. - **Arguments:** - * *method* -- the splitting coefficients identifier. - - **Return value:** - * The name associated with *method*. - * ``NULL`` pointer if *method* was invalid. + :param method: the splitting coefficients identifier. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *method* was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -177,12 +165,10 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} \circ \dots \circ \phi^1_{h} \right) (y_{n-1}). - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *partitions* was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -197,12 +183,10 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`L_h` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` is its adjoint. - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *partitions* was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -215,12 +199,10 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + (1 - p) y_{n-1}. - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *partitions* was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -235,13 +217,11 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`L_h` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` is its adjoint. - - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *partitions* was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -257,13 +237,11 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`L_h` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters :math:`p_1, \dots, p_5` are selected to give third order. - - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` was invalid or an allocation error occurred. + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if *partitions* was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -283,15 +261,12 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is selected to increase the order by two each recursion. - - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - * *order* -- A positive even number for the method order of accuracy. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` or ``order`` was invalid or an allocation - error occurred. + + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param order: A positive even number for the method order of accuracy. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if an argument was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -312,15 +287,12 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is selected to increase the order by two each recursion. - - **Arguments:** - * *partitions* -- The number :math:`P > 1` of partitions in the IVP. - * *order* -- A positive even number for the method order of accuracy. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * ``NULL`` if ``partitions`` or ``order`` was invalid or an allocation - error occurred. + + :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param order: A positive even number for the method order of accuracy. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if an argument was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -329,16 +301,13 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Allocates an empty SplittingStepCoefficients. - **Arguments:** - * *sequential_methods* -- The number :math:`r` of sequential methods - combined to produce the overall operator splitting solution. - * *stages* -- The number :math:`s` of stages. - * *partitions* -- The number :math:`P` of partitions in the IVP. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * A ``NULL`` pointer if *sequential_methods*, *stages* or *partitions* was - invalid or an allocation error occurred. + :param sequential_methods: The number :math:`r` of sequential methods + combined to produce the overall operator splitting solution. + :param stages: The number :math:`s` of stages. + :param partitions: The number :math:`P` of partitions in the IVP. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if an argument was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -347,26 +316,24 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Allocates a SplittingStepCoefficients and fills it with the given values. - **Arguments:** - * *sequential_methods* -- The number :math:`r` of sequential methods - combined to produce the overall operator splitting solution. - * *stages* -- The number :math:`s` of stages. - * *partitions* -- The number :math:`P` of partitions in the IVP. - * *order* -- The method order of accuracy. - * *alpha* -- An array of length ``sequential_methods`` containing the - weight of each sequential method used to produce the overall operator - splitting solution. - * *beta* -- An array of length - ``sequential_methods * (stages+1) * partitions`` containing the time nodes - of the inner integrations in the order - - .. math:: - \beta_{1,0,1}, \dots, \beta_{1,0,P}, \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, \beta_{2,0,1}, \dots, \beta_{r,s,P}. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * A ``NULL`` pointer if an argument was invalid or an allocation error - occurred. + :param sequential_methods: The number :math:`r` of sequential methods + combined to produce the overall operator splitting solution. + :param stages: The number :math:`s` of stages. + :param partitions: The number :math:`P` of partitions in the IVP. + :param order: The method order of accuracy. + :param alpha: An array of length ``sequential_methods`` containing the + weight of each sequential method used to produce the overall operator + splitting solution. + :param beta: An array of length + ``sequential_methods * (stages+1) * partitions`` containing the time nodes + of the inner integrations in the order + + .. math:: + \beta_{1,0,1}, \dots, \beta_{1,0,P}, \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, \beta_{2,0,1}, \dots, \beta_{r,s,P}. + + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if an argument was invalid or an allocation error + occurred. .. versionadded:: x.y.z @@ -375,12 +342,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Creates copy of the given splitting coefficients. - **Arguments:** - * ``coefficients`` -- The splitting coefficients to copy. - - **Return value:** - * A :c:type:`SplittingStepCoefficients` structure if successful. - * A ``NULL`` pointer if an allocation error occurred. + :param coefficients: The splitting coefficients to copy. + :return: A :c:type:`SplittingStepCoefficients` structure if successful or a + ``NULL`` pointer if an allocation error occurred. .. versionadded:: x.y.z @@ -389,8 +353,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Deallocate the splitting coefficients memory. - **Arguments:** - * ``coefficients`` -- The splitting coefficients. + :param coefficients: The splitting coefficients. .. versionadded:: x.y.z @@ -399,9 +362,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Write the splitting coefficients to the provided file pointer. - **Arguments:** - * ``coefficients`` -- The splitting coefficients. - * ``outfile`` -- Pointer to use for printing the splitting coefficients. + :param coefficients: The splitting coefficients. + :param outfile: Pointer to use for printing the splitting coefficients. .. note:: @@ -422,7 +384,7 @@ references for each in the table below. We use the naming convention .. code-block:: text - ___ + ARKODE_SPLITTING____ Each of the splitting coefficients that are packaged with SplittingStep are specified by a unique ID having type: From 0c93424b47ae6224d47279ceb352de8850bcf7f2 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 3 Oct 2024 14:49:07 -0700 Subject: [PATCH 129/180] Finish updates to new doc style --- .../Usage/ForcingStep/User_callable.rst | 45 +++++-------- .../Usage/SplittingStep/User_callable.rst | 65 +++++++------------ 2 files changed, 42 insertions(+), 68 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst index d5d8aa2289..92f8e41fcd 100644 --- a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -38,19 +38,18 @@ ForcingStep initialization functions This function allocates and initializes memory for a problem to be solved using the ForcingStep time-stepping module in ARKODE. - **Arguments:** - * *stepper1* -- a :c:type:`SUNStepper` to integrate partition one. - * *stepper2* -- a :c:type:`SUNStepper` to integrate partition two - including the forcing from partition one. - * *t0* -- the initial value of :math:`t`. - * *y0* -- the initial condition vector :math:`y(t_0)`. - * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) - - **Return value:** - If successful, a pointer to initialized problem memory of type ``void*``, - to be passed to all user-facing ForcingStep routines listed below. If - unsuccessful, a ``NULL`` pointer will be returned, and an error message - will be printed to ``stderr``. + :param stepper1: A :c:type:`SUNStepper` to integrate partition one. + :param stepper2: A :c:type:`SUNStepper` to integrate partition two + including the forcing from partition one. + :param t0: The initial value of :math:`t`. + :param y0: The initial condition vector :math:`y(t_0)`. + :param sunctx: The :c:type:`SUNContext` object (see + :numref:`SUNDIALS.SUNContext`) + + :return: If successful, a pointer to initialized problem memory of type + ``void*``, to be passed to all user-facing ForcingStep routines listed + below. If unsuccessful, a ``NULL`` pointer will be returned, and an error + message will be printed to ``stderr``. **Example usage:** @@ -94,21 +93,13 @@ Optional output functions Returns the number of times the :c:type:`SUNStepper` for the given partition index has been evolved (so far). - **Arguments:** - - * *arkode_mem* -- pointer to the ForcingStep memory block. - - * *partition* -- index of the partition (0 or 1) or a negative number to + :param arkode_mem: pointer to the ForcingStep memory block. + :param partition: index of the partition (0 or 1) or a negative number to indicate the total number across both partitions. + :param evolves: number of :c:type:`SUNStepper` evolves. - * *evolves* -- number of :c:type:`SUNStepper` evolves. - - **Return value:** - - * *ARK_SUCCESS* if successful - - * *ARK_MEM_NULL* if the ForcingStep memory was ``NULL`` - - * *ARK_ILL_INPUT* if *partition* was out of bounds + :retval ARK_SUCCESS: if successful + :retval ARK_MEM_NULL: if the ForcingStep memory was ``NULL`` + :retval ARK_ILL_INPUT: if *partition* was out of bounds .. versionadded:: x.y.z \ No newline at end of file diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 9993066416..440860b1a8 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -38,19 +38,17 @@ SplittingStep initialization functions This function allocates and initializes memory for a problem to be solved using the SplittingStep time-stepping module in ARKODE. - **Arguments:** - * *steppers* -- an array of :c:type:`SUNStepper` with one for each - partition of the IVP. - * *partitions* -- the number :math:`P > 1` of partitions in the IVP. - * *t0* -- the initial value of :math:`t`. - * *y0* -- the initial condition vector :math:`y(t_0)`. - * *sunctx* -- the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) - - **Return value:** - If successful, a pointer to initialized problem memory of type ``void*``, - to be passed to all user-facing SplittingStep routines listed below. If - unsuccessful, a ``NULL`` pointer will be returned, and an error message - will be printed to ``stderr``. + :param steppers: an array of :c:type:`SUNStepper` with one for each + partition of the IVP. + :param partitions: the number :math:`P > 1` of partitions in the IVP. + :param t0: the initial value of :math:`t`. + :param y0: the initial condition vector :math:`y(t_0)`. + :param sunctx: the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) + + :return: If successful, a pointer to initialized problem memory of type + ``void*``, to be passed to all user-facing SplittingStep routines listed + below. If unsuccessful, a ``NULL`` pointer will be returned, and an error + message will be printed to ``stderr``. **Example usage:** @@ -91,19 +89,12 @@ Optional inputs for IVP method selection Specifies a customized set of coefficients for the operator splitting method. - **Arguments:** + :param arkode_mem: pointer to the SplittingStep memory block. + :param coefficients: the splitting coefficients for the method. - * *arkode_mem* -- pointer to the SplittingStep memory block. - - * *coefficients* -- the splitting coefficients for the method. - - **Return value:** - - * *ARK_SUCCESS* if successful - - * *ARK_MEM_NULL* if the SplittingStep memory is ``NULL`` - - * *ARK_ILL_INPUT* if an argument has an illegal value + :retval ARK_SUCCESS: if successful + :retval ARK_MEM_NULL: if the SplittingStep memory is ``NULL`` + :retval ARK_ILL_INPUT: if an argument has an illegal value **Notes:** @@ -129,22 +120,14 @@ Optional output functions Returns the number of times the :c:type:`SUNStepper` for the given partition index has been evolved (so far). - **Arguments:** - - * *arkode_mem* -- pointer to the SplittingStep memory block. - - * *partition* -- index of the partition between 0 and :math:`P - 1` or a - negative number to indicate the total number across all - partitions. - - * *evolves* -- number of :c:type:`SUNStepper` evolves. - - **Return value:** - - * *ARK_SUCCESS* if successful - - * *ARK_MEM_NULL* if the SplittingStep memory was ``NULL`` + :param arkode_mem: pointer to the SplittingStep memory block. + :param partition: index of the partition between 0 and :math:`P - 1` or a + negative number to indicate the total number across all + partitions. + :param evolves: number of :c:type:`SUNStepper` evolves. - * *ARK_ILL_INPUT* if *partition* was out of bounds + :retval ARK_SUCCESS: if successful + :retval ARK_MEM_NULL: if the SplittingStep memory was ``NULL`` + :retval ARK_ILL_INPUT: if *partition* was out of bounds .. versionadded:: x.y.z From 605266ce2628b207772df3808a2ce93ff529a59a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 3 Oct 2024 15:03:33 -0700 Subject: [PATCH 130/180] Switch to note and warning directive --- .../source/Usage/SplittingStep/User_callable.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 440860b1a8..282706030a 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -96,15 +96,15 @@ Optional inputs for IVP method selection :retval ARK_MEM_NULL: if the SplittingStep memory is ``NULL`` :retval ARK_ILL_INPUT: if an argument has an illegal value - **Notes:** + .. note:: - For a description of the :c:type:`SplittingStepCoefficients` type and related - functions for creating splitting coefficients see - :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`. + For a description of the :c:type:`SplittingStepCoefficients` type and related + functions for creating splitting coefficients see + :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`. - **Warning:** + .. warning:: - This should not be used with :c:func:`ARKodeSetOrder`. + This should not be used with :c:func:`ARKodeSetOrder`. .. versionadded:: x.y.z From c78a110702c0b3977d98a074bf5a18b041a0d2f9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 8 Oct 2024 15:21:23 -0700 Subject: [PATCH 131/180] Remove return () syntax --- src/arkode/arkode_forcingstep.c | 38 ++++++++++++------------ src/arkode/arkode_splittingstep.c | 48 +++++++++++++++---------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 35224aca27..7762129d98 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -33,7 +33,7 @@ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, { arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, fname, __FILE__, "Time step module memory is NULL."); - return (ARK_MEM_NULL); + return ARK_MEM_NULL; } *step_mem = (ARKodeForcingStepMem)ark_mem->step_mem; return ARK_SUCCESS; @@ -53,7 +53,7 @@ static int forcingStep_AccessARKODEStepMem(void* const arkode_mem, { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, fname, __FILE__, MSG_ARK_NO_MEM); - return (ARK_MEM_NULL); + return ARK_MEM_NULL; } *ark_mem = (ARKodeMem)arkode_mem; @@ -83,7 +83,7 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } /* assume fixed outer step size */ if (!ark_mem->fixedstep) @@ -130,25 +130,25 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, SUNDIALS_MAYBE_UNUSED const int mode) { ARKodeForcingStepMem step_mem = NULL; - int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return retval; } const SUNStepper s0 = step_mem->stepper[0]; - retval = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1); - if (retval != 0) + SUNErrCode err = s0->ops->fullrhs(s0, t, y, ark_mem->tempv1); + if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); - return (ARK_RHSFUNC_FAIL); + return ARK_RHSFUNC_FAIL; } const SUNStepper s1 = step_mem->stepper[1]; - retval = s1->ops->fullrhs(s1, t, y, f); - if (retval != 0) + err = s1->ops->fullrhs(s1, t, y, f); + if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); - return (ARK_RHSFUNC_FAIL); + return ARK_RHSFUNC_FAIL; } N_VLinearSum(SUN_RCONST(1.0), f, SUN_RCONST(1.0), ark_mem->tempv1, f); @@ -163,7 +163,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ @@ -222,7 +222,7 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfil // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeForcingStepMem step_mem = NULL; const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } switch (fmt) { @@ -243,7 +243,7 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfil default: arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, "Invalid formatting option."); - return (ARK_ILL_INPUT); + return ARK_ILL_INPUT; } return ARK_SUCCESS; @@ -327,7 +327,7 @@ void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, { arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, MSG_ARK_BAD_NVECTOR); - return (NULL); + return NULL; } /* Create ark_mem structure and set default values */ @@ -336,7 +336,7 @@ void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, MSG_ARK_NO_MEM); - return (NULL); + return NULL; } const ARKodeForcingStepMem step_mem = @@ -371,7 +371,7 @@ void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, "Error setting default solver options"); ARKodeFree((void**)&ark_mem); - return (NULL); + return NULL; } /* Initialize main ARKODE infrastructure */ @@ -381,7 +381,7 @@ void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, "Unable to initialize main ARKODE infrastructure"); ARKodeFree((void**)&ark_mem); - return (NULL); + return NULL; } return ark_mem; @@ -393,7 +393,7 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } if (partition >= PARTITIONS) { diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 88ec627232..55f02ca702 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -34,7 +34,7 @@ static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, { arkProcessError(ark_mem, ARK_MEM_NULL, __LINE__, fname, __FILE__, "Time step module memory is NULL."); - return (ARK_MEM_NULL); + return ARK_MEM_NULL; } *step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; return ARK_SUCCESS; @@ -54,7 +54,7 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, fname, __FILE__, MSG_ARK_NO_MEM); - return (ARK_MEM_NULL); + return ARK_MEM_NULL; } *ark_mem = (ARKodeMem)arkode_mem; @@ -131,7 +131,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } /* immediately return if resize or reset */ if (init_type == RESIZE_INIT || init_type == RESET_INIT) @@ -182,26 +182,26 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, SUNDIALS_MAYBE_UNUSED const int mode) { ARKodeSplittingStepMem step_mem = NULL; - int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + if (retval != ARK_SUCCESS) { return retval; } - retval = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f); - if (retval != 0) + SUNErrCode err = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f); + if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); - return (ARK_RHSFUNC_FAIL); + return ARK_RHSFUNC_FAIL; } for (int i = 1; i < step_mem->partitions; i++) { - retval = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, + err = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, ark_mem->tempv1); - if (retval != 0) + if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); - return (ARK_RHSFUNC_FAIL); + return ARK_RHSFUNC_FAIL; } N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); } @@ -281,7 +281,7 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ @@ -320,7 +320,7 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } switch (fmt) { @@ -341,7 +341,7 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, default: arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, "Invalid formatting option."); - return (ARK_ILL_INPUT); + return ARK_ILL_INPUT; } return ARK_SUCCESS; @@ -354,7 +354,7 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp { ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } fprintf(fp, "SplittingStep time step module parameters:\n Method order %i\n\n", step_mem->order); @@ -412,7 +412,7 @@ static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) { ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } /* set user-provided value, or default, depending on argument */ step_mem->order = order <= 0 ? 1 : order; @@ -432,7 +432,7 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } retval = splittingStep_SetOrder(ark_mem, 0); if (retval != ARK_SUCCESS) { return retval; } @@ -487,7 +487,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, { arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, MSG_ARK_BAD_NVECTOR); - return (NULL); + return NULL; } /* Create ark_mem structure and set default values */ @@ -496,7 +496,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, { arkProcessError(NULL, ARK_MEM_NULL, __LINE__, __func__, __FILE__, MSG_ARK_NO_MEM); - return (NULL); + return NULL; } const ARKodeSplittingStepMem step_mem = @@ -551,7 +551,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, "Error setting default solver options"); ARKodeFree((void**)&ark_mem); - return (NULL); + return NULL; } /* Initialize main ARKODE infrastructure */ @@ -561,7 +561,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, arkProcessError(ark_mem, retval, __LINE__, __func__, __FILE__, "Unable to initialize main ARKODE infrastructure"); ARKodeFree((void**)&ark_mem); - return (NULL); + return NULL; } return ark_mem; @@ -577,7 +577,7 @@ int SplittingStep_SetCoefficients(void* const arkode_mem, ARKodeSplittingStepMem step_mem = NULL; const int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } if (coefficients == NULL) { @@ -600,7 +600,7 @@ int SplittingStep_SetCoefficients(void* const arkode_mem, { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, "Failed to copy splitting coefficients"); - return (ARK_MEM_NULL); + return ARK_MEM_NULL; } return ARK_SUCCESS; @@ -613,7 +613,7 @@ int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); - if (retval != ARK_SUCCESS) { return (retval); } + if (retval != ARK_SUCCESS) { return retval; } if (partition >= step_mem->partitions) { From b8af167b1590be26cc417a21471469d038a946dc Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 8 Oct 2024 15:53:35 -0700 Subject: [PATCH 132/180] Simplify splittingStep_FullRHS --- src/arkode/arkode_forcingstep.c | 2 +- src/arkode/arkode_splittingstep.c | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 7762129d98..e4e3a5d5b4 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -391,7 +391,7 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves { ARKodeMem ark_mem = NULL; ARKodeForcingStepMem step_mem = NULL; - int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + const int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return retval; } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 55f02ca702..c10912ee0c 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -185,25 +185,17 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } - SUNErrCode err = step_mem->steppers[0]->ops->fullrhs(step_mem->steppers[0], t, y, f); - if (err != SUN_SUCCESS) + for (int i = 0; i < step_mem->partitions; i++) { - arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, - MSG_ARK_RHSFUNC_FAILED, t); - return ARK_RHSFUNC_FAIL; - } - - for (int i = 1; i < step_mem->partitions; i++) - { - err = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, - ark_mem->tempv1); + const SUNErrCode err = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, + i == 0 ? f : ark_mem->tempv1); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); return ARK_RHSFUNC_FAIL; } - N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); + if (i > 0) { N_VLinearSum(ONE, f, ONE, ark_mem->tempv1, f); } } return ARK_SUCCESS; From 18ba8b22937ec35ed21076633ce1fb218a388548 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 8 Oct 2024 16:07:04 -0700 Subject: [PATCH 133/180] Apply formatter --- src/arkode/arkode_forcingstep.c | 6 +++--- src/arkode/arkode_splittingstep.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index e4e3a5d5b4..b3409e5f83 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -143,7 +143,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, } const SUNStepper s1 = step_mem->stepper[1]; - err = s1->ops->fullrhs(s1, t, y, f); + err = s1->ops->fullrhs(s1, t, y, f); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -391,8 +391,8 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves { ARKodeMem ark_mem = NULL; ARKodeForcingStepMem step_mem = NULL; - const int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, - &step_mem); + const int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, + &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return retval; } if (partition >= PARTITIONS) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index c10912ee0c..894074751e 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -187,8 +187,9 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, for (int i = 0; i < step_mem->partitions; i++) { - const SUNErrCode err = step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, - i == 0 ? f : ark_mem->tempv1); + const SUNErrCode err = + step_mem->steppers[i]->ops->fullrhs(step_mem->steppers[i], t, y, + i == 0 ? f : ark_mem->tempv1); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, From aaf55919dc97d5e164f8bea82fdf996c7ac78227 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 8 Oct 2024 16:12:28 -0700 Subject: [PATCH 134/180] Fix error types in ARKodeGetStepDirection --- src/arkode/arkode_io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index 4b83894617..4fef6f3b15 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1313,7 +1313,7 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) if (stepdir == ZERO) { return ARK_SUCCESS; } retval = ARKodeGetStepDirection(arkode_mem, &h); - if (retval != SUN_SUCCESS) { return retval; } + if (retval != ARK_SUCCESS) { return retval; } // TODO(SBR): use SUNRcopysign once merged from other PR // if (SUNRcopysign(h, stepdir) == h) { @@ -1332,8 +1332,8 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) ark_mem->hin = ark_mem->fixedstep ? -h : ZERO; /* Reset error controller (e.g., error and step size history) */ - retval = SUNAdaptController_Reset(ark_mem->hadapt_mem->hcontroller); - if (retval != SUN_SUCCESS) { return (ARK_CONTROLLER_ERR); } + SUNErrCode err = SUNAdaptController_Reset(ark_mem->hadapt_mem->hcontroller); + if (err != SUN_SUCCESS) { return (ARK_CONTROLLER_ERR); } return ARK_SUCCESS; } From de7334d41f641cf92c5babedf82cb6622f4713d0 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Fri, 11 Oct 2024 20:38:22 -0700 Subject: [PATCH 135/180] Use SUNAbortErrHandlerFn for unit tests --- .../arkode/CXX_serial/ark_test_splittingstep.cpp | 12 +----------- .../arkode/C_serial/ark_test_forcingstep.c | 11 +---------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 97c3263530..084daf91b3 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -383,20 +383,10 @@ static int test_custom_stepper(const sundials::Context& ctx) return 0; } -/* Error handling function which prints the error and exits the program */ -static void err_fn(const int line, const char* const func, - const char* const file, const char* const msg, - const SUNErrCode err_code, void* const, const SUNContext) -{ - std::cerr << "Error at line " << line << " of " << func << " in " << file - << ": " << msg << "\n"; - exit(err_code); -} - int main() { sundials::Context ctx; - SUNContext_PushErrHandler(ctx, err_fn, nullptr); + SUNContext_PushErrHandler(ctx, SUNAbortErrHandlerFn, nullptr); int errors = 0; diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index 11345a3cd0..f4b5bab77c 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -98,15 +98,6 @@ static int test_forward(SUNContext ctx) return 0; } -/* Error handling function which prints the error and exits the program */ -static void err_fn(const int line, const char* const func, const char* const file, - const char* const msg, const SUNErrCode err_code, - void* const err_user_data, const SUNContext ctx) -{ - fprintf(stderr, "Error at line %i of %s in %s: %s\n", line, func, file, msg); - exit(err_code); -} - int main() { SUNContext ctx = NULL; @@ -117,7 +108,7 @@ int main() return 1; } - err = SUNContext_PushErrHandler(ctx, err_fn, NULL); + err = SUNContext_PushErrHandler(ctx, SUNAbortErrHandlerFn, NULL); if (err != SUN_SUCCESS) { fprintf(stderr, "Failed to add error handler\n"); From 76e95408e4718b93080df1b23fba9545cabdb1c9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 10:13:19 -0700 Subject: [PATCH 136/180] Reorder ARKODE modules alphabetically --- doc/arkode/guide/source/Mathematics.rst | 387 +++++++++--------- doc/arkode/guide/source/Usage/General.rst | 4 +- .../guide/source/Usage/User_callable.rst | 2 +- doc/arkode/guide/source/Usage/index.rst | 13 +- 4 files changed, 204 insertions(+), 202 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index d7656b322a..c40b982dc7 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -462,191 +462,6 @@ simplified form admits a more efficient and memory-friendly implementation than the more general form :eq:`ARKODE_IVP_simple_explicit`. -.. _ARKODE.Mathematics.SPRKStep: - -SPRKStep -- Symplectic Partitioned Runge--Kutta methods -======================================================= - -The SPRKStep time-stepping module in ARKODE is designed for problems where the -state vector is partitioned as - -.. math:: - y(t) = - \begin{bmatrix} - p(t) \\ - q(t) - \end{bmatrix} - -and the component partitioned IVP is given by - -.. math:: - \dot{p} &= f_1(t, q), \qquad p(t_0) = p_0 \\ - \dot{q} &= f_2(t, p), \qquad q(t_0) = q_0. - :label: ARKODE_IVP_SPRK - -The right-hand side functions :math:`f_1(t,p)` and :math:`f_2(t,q)` typically -arise from the **separable** Hamiltonian system - -.. math:: - H(t, p, q) = T(t, p) + V(t, q) - -where - -.. math:: - f_1(t, q) \equiv \frac{\partial V(t, q)}{\partial q}, \qquad - f_2(t, p) \equiv \frac{\partial T(t, p)}{\partial p}. - -When *H* is autonomous, then *H* is a conserved quantity. Often this corresponds -to the conservation of energy (for example, in *n*-body problems). For -non-autonomous *H*, the invariants are no longer directly obtainable from the -Hamiltonian :cite:p:`Struckmeier:02`. - -In practice, the ordering of the variables does not matter and is determined by the user. -SPRKStep utilizes Symplectic Partitioned Runge-Kutta (SPRK) methods represented by the pair -of explicit and diagonally implicit Butcher tableaux, - -.. math:: - \begin{array}{c|cccc} - c_1 & 0 & \cdots & 0 & 0 \\ - c_2 & a_1 & 0 & \cdots & \vdots \\ - \vdots & \vdots & \ddots & \ddots & \vdots \\ - c_s & a_1 & \cdots & a_{s-1} & 0 \\ - \hline - & a_1 & \cdots & a_{s-1} & a_s - \end{array} - \qquad \qquad - \begin{array}{c|cccc} - \hat{c}_1 & \hat{a}_1 & \cdots & 0 & 0 \\ - \hat{c}_2 & \hat{a}_1 & \hat{a}_2 & \cdots & \vdots \\ - \vdots & \vdots & \ddots & \ddots & \vdots \\ - \hat{c}_s & \hat{a}_1 & \hat{a}_2 & \cdots & \hat{a}_{s} \\ - \hline - & \hat{a}_1 & \hat{a}_2 & \cdots & \hat{a}_{s} - \end{array}. - -These methods approximately conserve a nearby Hamiltonian for exponentially long -times :cite:p:`HaWa:06`. SPRKStep makes the assumption that the Hamiltonian is -separable, in which case the resulting method is explicit. SPRKStep provides -schemes with order of accuracy and conservation equal to -:math:`q = \{1,2,3,4,5,6,8,10\}`. The references for these these methods and -the default methods used are given in the section :numref:`Butcher.sprk`. - -In the default case, the algorithm for a single time-step is as follows -(for autonomous Hamiltonian systems the times provided to :math:`f_1` and -:math:`f_2` -can be ignored). - -#. Set :math:`P_0 = p_{n-1}, Q_1 = q_{n-1}` - -#. For :math:`i = 1,\ldots,s` do: - - #. :math:`P_i = P_{i-1} + h_n \hat{a}_i f_1(t_{n-1} + \hat{c}_i h_n, Q_i)` - #. :math:`Q_{i+1} = Q_i + h_n a_i f_2(t_{n-1} + c_i h_n, P_i)` - -#. Set :math:`p_n = P_s, q_n = Q_{s+1}` - -.. _ARKODE.Mathematics.SPRKStep.Compensated: - -Optionally, a different algorithm leveraging compensated summation can be used -that is more robust to roundoff error at the expense of 2 extra vector operations -per stage and an additional 5 per time step. It also requires one extra vector to -be stored. However, it is significantly more robust to roundoff error accumulation -:cite:p:`Sof:02`. When compensated summation is enabled, the following incremental -form is used to compute a time step: - -#. Set :math:`\Delta P_0 = 0, \Delta Q_1 = 0` - -#. For :math:`i = 1,\ldots,s` do: - - #. :math:`\Delta P_i = \Delta P_{i-1} + h_n \hat{a}_i f_1(t_{n-1} + \hat{c}_i h_n, q_{n-1} + \Delta Q_i)` - #. :math:`\Delta Q_{i+1} = \Delta Q_i + h_n a_i f_2(t_{n-1} + c_i h_n, p_{n-1} + \Delta P_i)` - -#. Set :math:`\Delta p_n = \Delta P_s, \Delta q_n = \Delta Q_{s+1}` - -#. Using compensated summation, set :math:`p_n = p_{n-1} + \Delta p_n, q_n = q_{n-1} + \Delta q_n` - -Since temporal error based adaptive time-stepping is known to ruin the -conservation property :cite:p:`HaWa:06`, SPRKStep requires that ARKODE be run -using a fixed time-step size. - -.. However, it is possible for a user to provide a -.. problem-specific adaptivity controller such as the one described in :cite:p:`HaSo:05`. -.. The `ark_kepler.c` example demonstrates an implementation of such controller. - - -.. _ARKODE.Mathematics.SplittingStep: - -SplittingStep -- Operator splitting methods -================================================ - -The SplittingStep time-stepping module in ARKODE is designed for IVPs of the -form - -.. math:: - \dot{y} = f_1(t,y) + f_2(t,y) + \dots + f_P(t,y), \qquad y(t_0) = y_0, - -with :math:`P > 1` additive partitions. Operator splitting methods, such as -those implemented in SplittingStep, allow each partition to be integrated -separately, possibly with different numerical integrators or exact solution -procedures. Coupling is only performed though initial conditions which are -passed from the flow of one partition to the next. - -The following algorithmic procedure is used in the Splitting-Step module: - -#. For :math:`i = 1, \dots, r` do: - - #. Set :math:`y_{n, i} = y_{n - 1}`. - - #. For :math:`j = 0, \dots, s` do: - - #. For :math:`k = 1, \dots, P` do: - - #. Let :math:`t_{\text{start}} = t_{n-1} + \beta_{i,j-1,k} h_n` and - :math:`t_{\text{end}} = t_{n-1} + \beta_{i,j,k} h_n`. - - #. Let :math:`v(t_{\text{start}}) = y_{n,i}`. - - #. For :math:`t \in [t_{\text{start}}, t_{\text{end}}]` solve - :math:`\dot{v} = f_{k}(t, v)`. - - #. Set :math:`y_{n, i} = v(t_{\text{end}})`. - -#. Set :math:`y_n = \sum_{i=1}^r \alpha_i y_{n,i}` - -Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number -of sequential methods within the overall operator splitting scheme. The -sequential methods have independent flows which are linearly combined to produce -the next step. The real coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` -determine the particular scheme and properties such as the order of accuracy. - -An alternative representation of the SplittingStep solution is - -.. math:: - y_n = \sum_{i=1}^P \alpha_i \left( \phi^P_{\gamma_{i,1,P} h} \circ - \phi^{P-1}_{\gamma_{i,1,P-1} h} \circ \dots \circ \phi^1_{\gamma_{i,1,1} h} - \circ \phi^P_{\gamma_{i,2,P} h} \circ \dots \circ \phi^P_{\gamma_{i,s,P} h} - \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right), - (y_{n-1}) - -where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and -:math:`\phi^k_{h}` is the flow map for partition :math:`k`: - -.. math:: - \phi^k_{h}(y_{n_1}) = v(t_n), - \quad \begin{cases} - v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f_k(t, v). - \end{cases} - -SplittingStep provides standard operator splitting methods such as Lie-Trotter -and Strang splitting, as well as schemes of arbitrarily high order. -Alternatively, users may construct their own coefficients (see -:numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`). Generally, -methods of order three and higher with real coefficients require backward -integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. -Currently, a fixed time step must be specified for the outer SplittingStep, but -inner integrators are free to use adaptive time steps. - - .. _ARKODE.Mathematics.ForcingStep: ForcingStep -- Forcing method @@ -668,14 +483,15 @@ ForcingStep is given by \dot{v}_2 &= f_1^* + f_2(t, v_2), \\ y_n &= v_2(t_n). -Like a Lie-Trotter method from SplittingStep, the partitions are evolved through -a sequence of inner IVPs which can be solved with an arbitrary integrator or -exact solution procedure. However, the IVP for partition two includes a -"forcing" or "tendency" term :math:`f_1^*` to strengthen the coupling. This -coupling leads to a first order method provided :math:`v_1` and :math:`v_2` are -integrated to at least first order accuracy. Currently, a fixed time step must -be specified for the outer ForcingStep, but inner integrators are free to use -adaptive time steps. +Like a Lie-Trotter method from +:ref:`SplittingStep `, the partitions are +evolved through a sequence of inner IVPs which can be solved with an arbitrary +integrator or exact solution procedure. However, the IVP for partition two +includes a "forcing" or "tendency" term :math:`f_1^*` to strengthen the +coupling. This coupling leads to a first order method provided :math:`v_1` and +:math:`v_2` are integrated to at least first order accuracy. Currently, a fixed +time step must be specified for the outer ForcingStep, but inner integrators are +free to use adaptive time steps. .. _ARKODE.Mathematics.MRIStep: @@ -835,6 +651,191 @@ may supply their own method by defining and attaching a coupling table, see :numref:`ARKODE.Usage.MRIStep.MRIStepCoupling` for more information. +.. _ARKODE.Mathematics.SplittingStep: + +SplittingStep -- Operator splitting methods +================================================ + +The SplittingStep time-stepping module in ARKODE is designed for IVPs of the +form + +.. math:: + \dot{y} = f_1(t,y) + f_2(t,y) + \dots + f_P(t,y), \qquad y(t_0) = y_0, + +with :math:`P > 1` additive partitions. Operator splitting methods, such as +those implemented in SplittingStep, allow each partition to be integrated +separately, possibly with different numerical integrators or exact solution +procedures. Coupling is only performed though initial conditions which are +passed from the flow of one partition to the next. + +The following algorithmic procedure is used in the Splitting-Step module: + +#. For :math:`i = 1, \dots, r` do: + + #. Set :math:`y_{n, i} = y_{n - 1}`. + + #. For :math:`j = 0, \dots, s` do: + + #. For :math:`k = 1, \dots, P` do: + + #. Let :math:`t_{\text{start}} = t_{n-1} + \beta_{i,j-1,k} h_n` and + :math:`t_{\text{end}} = t_{n-1} + \beta_{i,j,k} h_n`. + + #. Let :math:`v(t_{\text{start}}) = y_{n,i}`. + + #. For :math:`t \in [t_{\text{start}}, t_{\text{end}}]` solve + :math:`\dot{v} = f_{k}(t, v)`. + + #. Set :math:`y_{n, i} = v(t_{\text{end}})`. + +#. Set :math:`y_n = \sum_{i=1}^r \alpha_i y_{n,i}` + +Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number +of sequential methods within the overall operator splitting scheme. The +sequential methods have independent flows which are linearly combined to produce +the next step. The real coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` +determine the particular scheme and properties such as the order of accuracy. + +An alternative representation of the SplittingStep solution is + +.. math:: + y_n = \sum_{i=1}^P \alpha_i \left( \phi^P_{\gamma_{i,1,P} h} \circ + \phi^{P-1}_{\gamma_{i,1,P-1} h} \circ \dots \circ \phi^1_{\gamma_{i,1,1} h} + \circ \phi^P_{\gamma_{i,2,P} h} \circ \dots \circ \phi^P_{\gamma_{i,s,P} h} + \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right) + (y_{n-1}) + +where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and +:math:`\phi^k_{h}` is the flow map for partition :math:`k`: + +.. math:: + \phi^k_{h}(y_{n_1}) = v(t_n), + \quad \begin{cases} + v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f_k(t, v). + \end{cases} + +SplittingStep provides standard operator splitting methods such as Lie-Trotter +and Strang splitting, as well as schemes of arbitrarily high order. +Alternatively, users may construct their own coefficients (see +:numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`). Generally, +methods of order three and higher with real coefficients require backward +integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. +Currently, a fixed time step must be specified for the outer SplittingStep, but +inner integrators are free to use adaptive time steps. + + +.. _ARKODE.Mathematics.SPRKStep: + +SPRKStep -- Symplectic Partitioned Runge--Kutta methods +======================================================= + +The SPRKStep time-stepping module in ARKODE is designed for problems where the +state vector is partitioned as + +.. math:: + y(t) = + \begin{bmatrix} + p(t) \\ + q(t) + \end{bmatrix} + +and the component partitioned IVP is given by + +.. math:: + \dot{p} &= f_1(t, q), \qquad p(t_0) = p_0 \\ + \dot{q} &= f_2(t, p), \qquad q(t_0) = q_0. + :label: ARKODE_IVP_SPRK + +The right-hand side functions :math:`f_1(t,p)` and :math:`f_2(t,q)` typically +arise from the **separable** Hamiltonian system + +.. math:: + H(t, p, q) = T(t, p) + V(t, q) + +where + +.. math:: + f_1(t, q) \equiv \frac{\partial V(t, q)}{\partial q}, \qquad + f_2(t, p) \equiv \frac{\partial T(t, p)}{\partial p}. + +When *H* is autonomous, then *H* is a conserved quantity. Often this corresponds +to the conservation of energy (for example, in *n*-body problems). For +non-autonomous *H*, the invariants are no longer directly obtainable from the +Hamiltonian :cite:p:`Struckmeier:02`. + +In practice, the ordering of the variables does not matter and is determined by the user. +SPRKStep utilizes Symplectic Partitioned Runge-Kutta (SPRK) methods represented by the pair +of explicit and diagonally implicit Butcher tableaux, + +.. math:: + \begin{array}{c|cccc} + c_1 & 0 & \cdots & 0 & 0 \\ + c_2 & a_1 & 0 & \cdots & \vdots \\ + \vdots & \vdots & \ddots & \ddots & \vdots \\ + c_s & a_1 & \cdots & a_{s-1} & 0 \\ + \hline + & a_1 & \cdots & a_{s-1} & a_s + \end{array} + \qquad \qquad + \begin{array}{c|cccc} + \hat{c}_1 & \hat{a}_1 & \cdots & 0 & 0 \\ + \hat{c}_2 & \hat{a}_1 & \hat{a}_2 & \cdots & \vdots \\ + \vdots & \vdots & \ddots & \ddots & \vdots \\ + \hat{c}_s & \hat{a}_1 & \hat{a}_2 & \cdots & \hat{a}_{s} \\ + \hline + & \hat{a}_1 & \hat{a}_2 & \cdots & \hat{a}_{s} + \end{array}. + +These methods approximately conserve a nearby Hamiltonian for exponentially long +times :cite:p:`HaWa:06`. SPRKStep makes the assumption that the Hamiltonian is +separable, in which case the resulting method is explicit. SPRKStep provides +schemes with order of accuracy and conservation equal to +:math:`q = \{1,2,3,4,5,6,8,10\}`. The references for these these methods and +the default methods used are given in the section :numref:`Butcher.sprk`. + +In the default case, the algorithm for a single time-step is as follows +(for autonomous Hamiltonian systems the times provided to :math:`f_1` and +:math:`f_2` +can be ignored). + +#. Set :math:`P_0 = p_{n-1}, Q_1 = q_{n-1}` + +#. For :math:`i = 1,\ldots,s` do: + + #. :math:`P_i = P_{i-1} + h_n \hat{a}_i f_1(t_{n-1} + \hat{c}_i h_n, Q_i)` + #. :math:`Q_{i+1} = Q_i + h_n a_i f_2(t_{n-1} + c_i h_n, P_i)` + +#. Set :math:`p_n = P_s, q_n = Q_{s+1}` + +.. _ARKODE.Mathematics.SPRKStep.Compensated: + +Optionally, a different algorithm leveraging compensated summation can be used +that is more robust to roundoff error at the expense of 2 extra vector operations +per stage and an additional 5 per time step. It also requires one extra vector to +be stored. However, it is significantly more robust to roundoff error accumulation +:cite:p:`Sof:02`. When compensated summation is enabled, the following incremental +form is used to compute a time step: + +#. Set :math:`\Delta P_0 = 0, \Delta Q_1 = 0` + +#. For :math:`i = 1,\ldots,s` do: + + #. :math:`\Delta P_i = \Delta P_{i-1} + h_n \hat{a}_i f_1(t_{n-1} + \hat{c}_i h_n, q_{n-1} + \Delta Q_i)` + #. :math:`\Delta Q_{i+1} = \Delta Q_i + h_n a_i f_2(t_{n-1} + c_i h_n, p_{n-1} + \Delta P_i)` + +#. Set :math:`\Delta p_n = \Delta P_s, \Delta q_n = \Delta Q_{s+1}` + +#. Using compensated summation, set :math:`p_n = p_{n-1} + \Delta p_n, q_n = q_{n-1} + \Delta q_n` + +Since temporal error based adaptive time-stepping is known to ruin the +conservation property :cite:p:`HaWa:06`, SPRKStep requires that ARKODE be run +using a fixed time-step size. + +.. However, it is possible for a user to provide a +.. problem-specific adaptivity controller such as the one described in :cite:p:`HaSo:05`. +.. The `ark_kepler.c` example demonstrates an implementation of such controller. + + .. _ARKODE.Mathematics.Error.Norm: Error norms diff --git a/doc/arkode/guide/source/Usage/General.rst b/doc/arkode/guide/source/Usage/General.rst index 6b04ed758a..c3875b10a4 100644 --- a/doc/arkode/guide/source/Usage/General.rst +++ b/doc/arkode/guide/source/Usage/General.rst @@ -54,10 +54,10 @@ to the SUNDIALS core header file. #include // Provides core SUNDIALS types #include // ARKStep provides explicit, implicit, IMEX additive RK methods. #include // ERKStep provides explicit RK methods. - #include // SPRKStep provides symplectic partitioned RK methods. - #include // SplittingStep provides operator splitting methods. #include // ForcingStep provides a forcing method. #include // MRIStep provides multirate RK methods. + #include // SplittingStep provides operator splitting methods. + #include // SPRKStep provides symplectic partitioned RK methods. Each of these define several types and various constants, include function prototypes, and include the shared ``arkode/arkode.h`` and diff --git a/doc/arkode/guide/source/Usage/User_callable.rst b/doc/arkode/guide/source/Usage/User_callable.rst index e33d66c866..b8ce8481ba 100644 --- a/doc/arkode/guide/source/Usage/User_callable.rst +++ b/doc/arkode/guide/source/Usage/User_callable.rst @@ -49,9 +49,9 @@ In the function descriptions below, we identify those that have any of the restr Then in the introduction for each of the stepper-specific documentation sections (:numref:`ARKODE.Usage.ARKStep.UserCallable`, :numref:`ARKODE.Usage.ERKStep.UserCallable`, -:numref:`ARKODE.Usage.SplittingStep.UserCallable`, :numref:`ARKODE.Usage.ForcingStep.UserCallable`, :numref:`ARKODE.Usage.MRIStep.UserCallable`, +:numref:`ARKODE.Usage.SplittingStep.UserCallable`, and :numref:`ARKODE.Usage.SPRKStep.UserCallable`) we clarify the categories of these functions that are supported. diff --git a/doc/arkode/guide/source/Usage/index.rst b/doc/arkode/guide/source/Usage/index.rst index 08d4fb43d3..042fdaf3f5 100644 --- a/doc/arkode/guide/source/Usage/index.rst +++ b/doc/arkode/guide/source/Usage/index.rst @@ -37,10 +37,11 @@ ARKODE's time stepping modules, including "relaxation" methods and preconitioners. Following our discussion of these commonalities, we separately discuss the usage details that that are specific to each of ARKODE's time stepping modules: :ref:`ARKStep `, -:ref:`ERKStep `, :ref:`SPRKStep `, -:ref:`SplittingStep `, -:ref:`ForcingStep `, and -:ref:`MRIStep `. +:ref:`ERKStep `, +:ref:`ForcingStep `, +:ref:`MRIStep `, +:ref:`SplittingStep `, and +:ref:`SPRKStep `. ARKODE also uses various input and output constants; these are defined as needed throughout this chapter, but for convenience the full list is provided @@ -79,7 +80,7 @@ ARKBBDPRE can only be used with NVECTOR_PARALLEL. Preconditioners ARKStep/index.rst ERKStep/index.rst - SPRKStep/index.rst - SplittingStep/index.rst ForcingStep/index.rst MRIStep/index.rst + SplittingStep/index.rst + SPRKStep/index.rst From 2192cec40adcfe98e41e55646b6c2e9080a04abd Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 10:28:14 -0700 Subject: [PATCH 137/180] Document what SUNStepper operations are required --- .../guide/source/Usage/ForcingStep/User_callable.rst | 7 +++++-- .../guide/source/Usage/SplittingStep/User_callable.rst | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst index 92f8e41fcd..82cc8c4d33 100644 --- a/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/ForcingStep/User_callable.rst @@ -38,9 +38,12 @@ ForcingStep initialization functions This function allocates and initializes memory for a problem to be solved using the ForcingStep time-stepping module in ARKODE. - :param stepper1: A :c:type:`SUNStepper` to integrate partition one. + :param stepper1: A :c:type:`SUNStepper` to integrate partition one. All + :c:type:`SUNStepper` operations are required to be implemented except + :c:func:`SUNStepper_SetForcing`. :param stepper2: A :c:type:`SUNStepper` to integrate partition two - including the forcing from partition one. + including the forcing from partition one. All :c:type:`SUNStepper` + operations are required to be implemented. :param t0: The initial value of :math:`t`. :param y0: The initial condition vector :math:`y(t_0)`. :param sunctx: The :c:type:`SUNContext` object (see diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 282706030a..c536c6961b 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -39,7 +39,8 @@ SplittingStep initialization functions using the SplittingStep time-stepping module in ARKODE. :param steppers: an array of :c:type:`SUNStepper` with one for each - partition of the IVP. + partition of the IVP. All :c:type:`SUNStepper` operations are required to + be implemented except :c:func:`SUNStepper_SetForcing`. :param partitions: the number :math:`P > 1` of partitions in the IVP. :param t0: the initial value of :math:`t`. :param y0: the initial condition vector :math:`y(t_0)`. From 2837af2bb93ef7f6f7e2990f22ec2cf8c47f7fd9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 10:30:50 -0700 Subject: [PATCH 138/180] Order ARKODE create functions alphabetically --- doc/arkode/guide/source/Usage/User_callable.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/User_callable.rst b/doc/arkode/guide/source/Usage/User_callable.rst index b8ce8481ba..46b54ecaef 100644 --- a/doc/arkode/guide/source/Usage/User_callable.rst +++ b/doc/arkode/guide/source/Usage/User_callable.rst @@ -62,7 +62,8 @@ ARKODE initialization and deallocation functions ------------------------------------------------------ For functions to create an ARKODE stepper instance see :c:func:`ARKStepCreate`, -:c:func:`ERKStepCreate`, :c:func:`MRIStepCreate`, or :c:func:`SPRKStepCreate`. +:c:func:`ERKStepCreate`, :c:func:`ForcingStepCreate`, :c:func:`MRIStepCreate`, +:c:func:`SplittingStepCreate`, or :c:func:`SPRKStepCreate`. .. c:function:: void ARKodeFree(void** arkode_mem) From 8d6f6f9992afb531c8d09c79887c154325d7bd7e Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 10:46:25 -0700 Subject: [PATCH 139/180] SUNStepper docs on step direction --- .../sunstepper/SUNStepper_Description.rst | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/doc/shared/sunstepper/SUNStepper_Description.rst b/doc/shared/sunstepper/SUNStepper_Description.rst index 52e71601ee..defb0a7cb1 100644 --- a/doc/shared/sunstepper/SUNStepper_Description.rst +++ b/doc/shared/sunstepper/SUNStepper_Description.rst @@ -145,6 +145,28 @@ Stepping Functions :return: A :c:type:`SUNErrCode` indicating success or failure. +.. c:function:: SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) + + This function specifies the direction of integration (forward or backward). + + :param stepper: the stepper object. + :param stepdir: value whose sign determines the direction. A positive value + selects forward integration, a negative value selects backward + integration, and zero leaves the current direction unchanged. + :return: A :c:type:`SUNErrCode` indicating success or failure. + + +.. c:function:: SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) + + This function provides the direction of integration that will be used on the + next internal step. + + :param stepper: the stepper object. + :param stepdir: a positive number if integrating forward, a negative number + if integrating backward, or zero if the direction has not been set. + :return: A :c:type:`SUNErrCode` indicating success or failure. + + .. c:function:: SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) This function sets the data necessary to compute the forcing term @@ -284,6 +306,26 @@ determined by the "consumer" of the :c:type:`SUNStepper`. :return: A :c:type:`SUNErrCode` indicating success or failure. +.. c:function:: SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn) + + This function attaches a :c:type:`SUNStepperSetStepDirectionFn` function to a + :c:type:`SUNStepper` object. + + :param stepper: a stepper object. + :param fn: the :c:type:`SUNStepperSetStepDirectionFn` function to attach. + :return: A :c:type:`SUNErrCode` indicating success or failure. + + +.. c:function:: SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, SUNStepperGetStepDirectionFn fn) + + This function attaches a :c:type:`SUNStepperGetStepDirectionFn` function to a + :c:type:`SUNStepper` object. + + :param stepper: a stepper object. + :param fn: the :c:type:`SUNStepperGetStepDirectionFn` function to attach. + :return: A :c:type:`SUNErrCode` indicating success or failure. + + .. c:function:: SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn) This function attaches a :c:type:`SUNStepperSetForcingFn` function to a @@ -341,6 +383,18 @@ abstract base class. :c:func:`SUNStepper_SetStopTime`. +.. c:type:: SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype stepdir) + + This type represents a function with the signature of + :c:func:`SUNStepper_SetStepDirection`. + + +.. c:type:: SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, sunrealtype* stepdir) + + This type represents a function with the signature of + :c:func:`SUNStepper_GetStepDirection`. + + .. c:type:: SUNErrCode (*SUNStepperSetForcingFn)(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) This type represents a function with the signature of From 3e2e3bf30c32fb0da6df566a04783b61e42658a9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 11:01:47 -0700 Subject: [PATCH 140/180] Order modules in math considerations section overview --- doc/arkode/guide/source/Mathematics.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index c40b982dc7..1e9f3ea5e6 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -60,14 +60,15 @@ of the ARKODE infrastructure, including its usage modes and approaches for interpolated solution output. We then discuss the current suite of time-stepping modules supplied with ARKODE, including the ARKStep module for :ref:`additive Runge--Kutta methods `, -the ERKStep module that is optimized for :ref:`explicit Runge--Kutta -methods `, SplittingStep for :ref:`operator splitting -methods `, ForcingStep for :ref:`a forcing -method `, and the MRIStep module for -:ref:`multirate infinitesimal step (MIS), multirate infinitesimal GARK -(MRI-GARK), and implicit-explicit MRI-GARK (IMEX-MRI-GARK) methods -`. We then discuss the :ref:`adaptive temporal error -controllers ` shared by the time-stepping +the ERKStep module that is optimized for :ref:`explicit Runge--Kutta methods +`, ForcingStep for :ref:`a forcing method +`, MRIStep for :ref:`multirate infinitesimal +step (MIS), multirate infinitesimal GARK (MRI-GARK), and implicit-explicit +MRI-GARK (IMEX-MRI-GARK) methods `, SplittingStep +for :ref:`operator splitting methods `, and +SPRKStep for :ref:`symplectic partitioned Runge--Kutta methods +`. We then discuss the :ref:`adaptive temporal +error controllers ` shared by the time-stepping modules, including discussion of our choice of norms for measuring errors within various components of the solver. From 55e6e24ebfe4f60025fa1db2c76b04a5e33b5e11 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 11:05:19 -0700 Subject: [PATCH 141/180] Remove redundant step_supports_forcing flag --- src/arkode/arkode.c | 1 - src/arkode/arkode_arkstep.c | 1 - src/arkode/arkode_impl.h | 1 - 3 files changed, 3 deletions(-) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 49861cdcf1..b9b8e573ab 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -1443,7 +1443,6 @@ ARKodeMem arkCreate(SUNContext sunctx) ark_mem->step_supports_implicit = SUNFALSE; ark_mem->step_supports_massmatrix = SUNFALSE; ark_mem->step_supports_relaxation = SUNFALSE; - ark_mem->step_supports_forcing = SUNFALSE; /* Initialize root finding variables */ ark_mem->root_mem = NULL; diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 6cc8f4f572..93ac87e227 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -146,7 +146,6 @@ void* ARKStepCreate(ARKRhsFn fe, ARKRhsFn fi, sunrealtype t0, N_Vector y0, ark_mem->step_supports_implicit = SUNTRUE; ark_mem->step_supports_massmatrix = SUNTRUE; ark_mem->step_supports_relaxation = SUNTRUE; - ark_mem->step_supports_forcing = SUNTRUE; ark_mem->step_mem = (void*)step_mem; /* Set default values for optional inputs */ diff --git a/src/arkode/arkode_impl.h b/src/arkode/arkode_impl.h index 9a59a14185..6bcb5d6cbb 100644 --- a/src/arkode/arkode_impl.h +++ b/src/arkode/arkode_impl.h @@ -461,7 +461,6 @@ struct ARKodeMemRec ARKMassMultFn step_mmult; /* Time stepper module -- forcing */ - sunbooleantype step_supports_forcing; ARKTimestepSetForcingFn step_setforcing; /* N_Vector storage */ From 3c9e4b6a18d0406d6223da0139c9ddb7756acfe0 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 19:20:24 -0700 Subject: [PATCH 142/180] Fix whitespace in error output --- .../arkode/CXX_serial/ark_test_splittingstep.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 084daf91b3..c29bf046fd 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -79,7 +79,7 @@ static int test_forward(sundials::Context& ctx, const int partitions) { const auto err = numerical_solution - exact_solution; std::cerr << "Forward solution with " << partitions - << " partitions failed with an error of" << err << "\n"; + << " partitions failed with an error of " << err << "\n"; return 1; } else @@ -309,7 +309,7 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, SUNStepper_SetContent(stepper, static_cast(const_cast(&lambda))); - const auto empty_func = [](auto... args) { return 0; }; + const auto empty_func = [](auto...) { return 0; }; SUNStepper_SetResetFn(stepper, empty_func); SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetStepDirectionFn(stepper, empty_func); @@ -323,7 +323,7 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, SUNStepper_GetContent(s, &content); const auto lam = *static_cast(content); N_VScale(std::exp(lam * (tout - t0)), y, y); - *tret = tout; + // *tret = tout; return 0; }; SUNStepper_SetEvolveFn(stepper, evolve); @@ -366,7 +366,7 @@ static int test_custom_stepper(const sundials::Context& ctx) if (SUNRCompare(exact_solution, numerical_solution)) { const auto err = numerical_solution - exact_solution; - std::cerr << "Custom SUNStepper failed with an error of" << err << "\n"; + std::cerr << "Custom SUNStepper failed with an error of " << err << "\n"; return 1; } else From 5ab56b176ade5d220b9fd8ada468aa33a11f821a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 19:30:06 -0700 Subject: [PATCH 143/180] Remove unnecessary GetStepDirection functionality from SUNStepper --- .../sunstepper/SUNStepper_Description.rst | 27 ------------------- include/sundials/sundials_stepper.h | 10 ------- src/arkode/arkode_sunstepper.c | 23 ---------------- src/sundials/sundials_stepper.c | 19 ------------- src/sundials/sundials_stepper_impl.h | 1 - 5 files changed, 80 deletions(-) diff --git a/doc/shared/sunstepper/SUNStepper_Description.rst b/doc/shared/sunstepper/SUNStepper_Description.rst index defb0a7cb1..273d4b1479 100644 --- a/doc/shared/sunstepper/SUNStepper_Description.rst +++ b/doc/shared/sunstepper/SUNStepper_Description.rst @@ -156,17 +156,6 @@ Stepping Functions :return: A :c:type:`SUNErrCode` indicating success or failure. -.. c:function:: SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) - - This function provides the direction of integration that will be used on the - next internal step. - - :param stepper: the stepper object. - :param stepdir: a positive number if integrating forward, a negative number - if integrating backward, or zero if the direction has not been set. - :return: A :c:type:`SUNErrCode` indicating success or failure. - - .. c:function:: SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) This function sets the data necessary to compute the forcing term @@ -316,16 +305,6 @@ determined by the "consumer" of the :c:type:`SUNStepper`. :return: A :c:type:`SUNErrCode` indicating success or failure. -.. c:function:: SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, SUNStepperGetStepDirectionFn fn) - - This function attaches a :c:type:`SUNStepperGetStepDirectionFn` function to a - :c:type:`SUNStepper` object. - - :param stepper: a stepper object. - :param fn: the :c:type:`SUNStepperGetStepDirectionFn` function to attach. - :return: A :c:type:`SUNErrCode` indicating success or failure. - - .. c:function:: SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn) This function attaches a :c:type:`SUNStepperSetForcingFn` function to a @@ -389,12 +368,6 @@ abstract base class. :c:func:`SUNStepper_SetStepDirection`. -.. c:type:: SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, sunrealtype* stepdir) - - This type represents a function with the signature of - :c:func:`SUNStepper_GetStepDirection`. - - .. c:type:: SUNErrCode (*SUNStepperSetForcingFn)(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) This type represents a function with the signature of diff --git a/include/sundials/sundials_stepper.h b/include/sundials/sundials_stepper.h index 8c528c6bcf..66110bd8f7 100644 --- a/include/sundials/sundials_stepper.h +++ b/include/sundials/sundials_stepper.h @@ -48,9 +48,6 @@ typedef SUNErrCode (*SUNStepperSetStopTimeFn)(SUNStepper stepper, typedef SUNErrCode (*SUNStepperSetStepDirectionFn)(SUNStepper stepper, sunrealtype stepdir); -typedef SUNErrCode (*SUNStepperGetStepDirectionFn)(SUNStepper stepper, - sunrealtype* stepdir); - typedef SUNErrCode (*SUNStepperSetForcingFn)(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, @@ -113,10 +110,6 @@ SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, SUNStepperSetStepDirectionFn fn); -SUNDIALS_EXPORT -SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, - SUNStepperGetStepDirectionFn fn); - SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn); @@ -137,9 +130,6 @@ SUNErrCode SUNStepper_SetStopTime(SUNStepper stepper, sunrealtype tstop); SUNDIALS_EXPORT SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir); -SUNDIALS_EXPORT -SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir); - SUNDIALS_EXPORT SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, diff --git a/src/arkode/arkode_sunstepper.c b/src/arkode/arkode_sunstepper.c index 560615ef5b..f6237499d0 100644 --- a/src/arkode/arkode_sunstepper.c +++ b/src/arkode/arkode_sunstepper.c @@ -122,20 +122,6 @@ static SUNErrCode arkSUNStepperSetStepDirection(SUNStepper stepper, return SUN_SUCCESS; } -static SUNErrCode arkSUNStepperGetStepDirection(SUNStepper stepper, - sunrealtype* stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - /* extract the ARKODE memory struct */ - void* arkode_mem; - SUNCheckCall(SUNStepper_GetContent(stepper, &arkode_mem)); - - stepper->last_flag = ARKodeGetStepDirection(arkode_mem, stepdir); - if (stepper->last_flag != ARK_SUCCESS) { return SUN_ERR_OP_FAIL; } - - return SUN_SUCCESS; -} - static SUNErrCode arkSUNStepperSetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) @@ -188,15 +174,6 @@ int ARKodeCreateSUNStepper(void* arkode_mem, SUNStepper* stepper) err = SUNStepper_SetStepDirectionFn(*stepper, arkSUNStepperSetStepDirection); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - err = SUNStepper_SetGetStepDirectionFn(*stepper, arkSUNStepperGetStepDirection); - if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - - err = SUNStepper_SetStepDirectionFn(*stepper, arkSUNStepperSetStepDirection); - if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - - err = SUNStepper_SetGetStepDirectionFn(*stepper, arkSUNStepperGetStepDirection); - if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - if (ark_mem->step_setforcing != NULL) { err = SUNStepper_SetForcingFn(*stepper, arkSUNStepperSetForcing); diff --git a/src/sundials/sundials_stepper.c b/src/sundials/sundials_stepper.c index e33d311e62..a86a61508c 100644 --- a/src/sundials/sundials_stepper.c +++ b/src/sundials/sundials_stepper.c @@ -31,7 +31,6 @@ SUNErrCode SUNStepper_Create(SUNContext sunctx, SUNStepper* stepper_ptr) stepper->ops->reset = NULL; stepper->ops->setstoptime = NULL; stepper->ops->setstepdirection = NULL; - stepper->ops->getstepdirection = NULL; stepper->ops->setforcing = NULL; *stepper_ptr = stepper; @@ -100,16 +99,6 @@ SUNErrCode SUNStepper_SetStepDirection(SUNStepper stepper, sunrealtype stepdir) return SUN_ERR_NOT_IMPLEMENTED; } -SUNErrCode SUNStepper_GetStepDirection(SUNStepper stepper, sunrealtype* stepdir) -{ - SUNFunctionBegin(stepper->sunctx); - if (stepper->ops->setstepdirection) - { - return stepper->ops->getstepdirection(stepper, stepdir); - } - return SUN_ERR_NOT_IMPLEMENTED; -} - SUNErrCode SUNStepper_SetForcing(SUNStepper stepper, sunrealtype tshift, sunrealtype tscale, N_Vector* forcing, int nforcing) @@ -193,14 +182,6 @@ SUNErrCode SUNStepper_SetStepDirectionFn(SUNStepper stepper, return SUN_SUCCESS; } -SUNErrCode SUNStepper_SetGetStepDirectionFn(SUNStepper stepper, - SUNStepperGetStepDirectionFn fn) -{ - SUNFunctionBegin(stepper->sunctx); - stepper->ops->getstepdirection = fn; - return SUN_SUCCESS; -} - SUNErrCode SUNStepper_SetForcingFn(SUNStepper stepper, SUNStepperSetForcingFn fn) { SUNFunctionBegin(stepper->sunctx); diff --git a/src/sundials/sundials_stepper_impl.h b/src/sundials/sundials_stepper_impl.h index a11d36de7e..e34c06f4e4 100644 --- a/src/sundials/sundials_stepper_impl.h +++ b/src/sundials/sundials_stepper_impl.h @@ -30,7 +30,6 @@ struct SUNStepper_Ops_ SUNStepperResetFn reset; SUNStepperSetStopTimeFn setstoptime; SUNStepperSetStepDirectionFn setstepdirection; - SUNStepperGetStepDirectionFn getstepdirection; SUNStepperSetForcingFn setforcing; }; From 35f6f1d96286a1ffb0f0e47fc98fbb51ec277128 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 22 Oct 2024 19:32:55 -0700 Subject: [PATCH 144/180] Update swig --- src/sundials/fmod_int32/fsundials_core_mod.c | 28 ---------- .../fmod_int32/fsundials_core_mod.f90 | 52 ------------------- src/sundials/fmod_int64/fsundials_core_mod.c | 28 ---------- .../fmod_int64/fsundials_core_mod.f90 | 52 ------------------- 4 files changed, 160 deletions(-) diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 694603b653..f619317022 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2900,20 +2900,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStepDirectionFn(void *farg1, SUNStepperSetSt } -SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGetStepDirectionFn farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperGetStepDirectionFn arg2 = (SUNStepperGetStepDirectionFn) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperGetStepDirectionFn)(farg2); - result = (SUNErrCode)SUNStepper_SetGetStepDirectionFn(arg1,arg2); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2942,18 +2928,4 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *far } -SWIGEXPORT int _wrap_FSUNStepper_GetStepDirection(void *farg1, double *farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - sunrealtype *arg2 = (sunrealtype *) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (sunrealtype *)(farg2); - result = (SUNErrCode)SUNStepper_GetStepDirection(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 8db2180895..608d67499c 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -560,10 +560,8 @@ module fsundials_core_mod public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn - public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_SetForcingFn public :: FSUNStepper_SetStepDirection - public :: FSUNStepper_GetStepDirection ! WRAPPER DECLARATIONS interface @@ -2224,15 +2222,6 @@ function swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetGetStepDirectionFn") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetForcingFn") & result(fresult) @@ -2251,15 +2240,6 @@ function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_GetStepDirection(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_GetStepDirection") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - end interface @@ -5300,22 +5280,6 @@ function FSUNStepper_SetStepDirectionFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_SetGetStepDirectionFn(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_SetGetStepDirectionFn(farg1, farg2) -swig_result = fresult -end function - function FSUNStepper_SetForcingFn(stepper, fn) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5348,21 +5312,5 @@ function FSUNStepper_SetStepDirection(stepper, stepdir) & swig_result = fresult end function -function FSUNStepper_GetStepDirection(stepper, stepdir) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: stepper -real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = stepper -farg2 = c_loc(stepdir(1)) -fresult = swigc_FSUNStepper_GetStepDirection(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 5c8bf3198c..a53ee7da71 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2900,20 +2900,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStepDirectionFn(void *farg1, SUNStepperSetSt } -SWIGEXPORT int _wrap_FSUNStepper_SetGetStepDirectionFn(void *farg1, SUNStepperGetStepDirectionFn farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - SUNStepperGetStepDirectionFn arg2 = (SUNStepperGetStepDirectionFn) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (SUNStepperGetStepDirectionFn)(farg2); - result = (SUNErrCode)SUNStepper_SetGetStepDirectionFn(arg1,arg2); - fresult = (SUNErrCode)(result); - return fresult; -} - - SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingFn farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2942,18 +2928,4 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *far } -SWIGEXPORT int _wrap_FSUNStepper_GetStepDirection(void *farg1, double *farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - sunrealtype *arg2 = (sunrealtype *) 0 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (sunrealtype *)(farg2); - result = (SUNErrCode)SUNStepper_GetStepDirection(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 6fecc07c6b..92e8919e4d 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -560,10 +560,8 @@ module fsundials_core_mod public :: FSUNStepper_SetResetFn public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn - public :: FSUNStepper_SetGetStepDirectionFn public :: FSUNStepper_SetForcingFn public :: FSUNStepper_SetStepDirection - public :: FSUNStepper_GetStepDirection ! WRAPPER DECLARATIONS interface @@ -2224,15 +2222,6 @@ function swigc_FSUNStepper_SetStepDirectionFn(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_SetGetStepDirectionFn(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetGetStepDirectionFn") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & bind(C, name="_wrap_FSUNStepper_SetForcingFn") & result(fresult) @@ -2251,15 +2240,6 @@ function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNStepper_GetStepDirection(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_GetStepDirection") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - end interface @@ -5300,22 +5280,6 @@ function FSUNStepper_SetStepDirectionFn(stepper, fn) & swig_result = fresult end function -function FSUNStepper_SetGetStepDirectionFn(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_SetGetStepDirectionFn(farg1, farg2) -swig_result = fresult -end function - function FSUNStepper_SetForcingFn(stepper, fn) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5348,21 +5312,5 @@ function FSUNStepper_SetStepDirection(stepper, stepdir) & swig_result = fresult end function -function FSUNStepper_GetStepDirection(stepper, stepdir) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: stepper -real(C_DOUBLE), dimension(*), target, intent(inout) :: stepdir -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = stepper -farg2 = c_loc(stepdir(1)) -fresult = swigc_FSUNStepper_GetStepDirection(farg1, farg2) -swig_result = fresult -end function - end module From 121a8e64dd8166339774bd3b921f4d2584e97d90 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 28 Oct 2024 16:08:25 -0700 Subject: [PATCH 145/180] Swig and formatter --- src/arkode/arkode_forcingstep.c | 3 +- src/arkode/arkode_splittingstep.c | 2 +- src/sundials/fmod_int32/fsundials_core_mod.c | 14 +++++ .../fmod_int32/fsundials_core_mod.f90 | 54 +++++++++---------- src/sundials/fmod_int64/fsundials_core_mod.c | 26 ++++----- .../fmod_int64/fsundials_core_mod.f90 | 54 +++++++++---------- 6 files changed, 83 insertions(+), 70 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index dbf074f3b4..3e13394057 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -133,7 +133,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } - SUNErrCode err = SUNStepper_FullRhs(step_mem->stepper[0], t, y, ark_mem->tempv1); + SUNErrCode err = SUNStepper_FullRhs(step_mem->stepper[0], t, y, + ark_mem->tempv1); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 9c2af2d9d7..34c9cc6b1b 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -188,7 +188,7 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, for (int i = 0; i < step_mem->partitions; i++) { const SUNErrCode err = SUNStepper_FullRhs(step_mem->steppers[i], t, y, - i == 0 ? f : ark_mem->tempv1); + i == 0 ? f : ark_mem->tempv1); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 962aae2be5..57c723b757 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -2736,6 +2736,20 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNStepper_SetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_SetForcing(void *farg1, double const *farg2, double const *farg3, void *farg4, int const *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 58d609a2c9..6979dc3bb3 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -549,6 +549,7 @@ module fsundials_core_mod public :: FSUNStepper_FullRhs public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime + public :: FSUNStepper_SetStepDirection public :: FSUNStepper_SetForcing public :: FSUNStepper_SetContent public :: FSUNStepper_GetContent @@ -560,11 +561,7 @@ module fsundials_core_mod public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetForcingFn -<<<<<<< HEAD - public :: FSUNStepper_SetStepDirection -======= public :: FSUNStepper_SetDestroyFn ->>>>>>> feature/sunstepper ! WRAPPER DECLARATIONS interface @@ -2121,6 +2118,15 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_SetForcing(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_SetForcing") & result(fresult) @@ -2223,21 +2229,12 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function -<<<<<<< HEAD -function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetStepDirection") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -======= 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 ->>>>>>> feature/sunstepper integer(C_INT) :: fresult end function @@ -5090,6 +5087,22 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function +function FSUNStepper_SetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = stepper +farg2 = stepdir +fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_SetForcing(stepper, tshift, tscale, forcing, nforcing) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5275,25 +5288,11 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function -<<<<<<< HEAD -function FSUNStepper_SetStepDirection(stepper, stepdir) & -======= function FSUNStepper_SetDestroyFn(stepper, fn) & ->>>>>>> feature/sunstepper result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: stepper -<<<<<<< HEAD -real(C_DOUBLE), intent(in) :: stepdir -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = stepper -farg2 = stepdir -fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) -======= type(C_FUNPTR), intent(in), value :: fn integer(C_INT) :: fresult type(C_PTR) :: farg1 @@ -5302,7 +5301,6 @@ function FSUNStepper_SetDestroyFn(stepper, fn) & farg1 = stepper farg2 = fn fresult = swigc_FSUNStepper_SetDestroyFn(farg1, farg2) ->>>>>>> feature/sunstepper swig_result = fresult end function diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 06f5440f36..f47b6b7a48 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -2736,6 +2736,20 @@ SWIGEXPORT int _wrap_FSUNStepper_SetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { + int fresult ; + SUNStepper arg1 = (SUNStepper) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNStepper)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNStepper_SetStepDirection(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNStepper_SetForcing(void *farg1, double const *farg2, double const *farg3, void *farg4, int const *farg5) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2896,17 +2910,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetForcingFn(void *farg1, SUNStepperSetForcingF } -<<<<<<< HEAD -SWIGEXPORT int _wrap_FSUNStepper_SetStepDirection(void *farg1, double const *farg2) { - int fresult ; - SUNStepper arg1 = (SUNStepper) 0 ; - sunrealtype arg2 ; - SUNErrCode result; - - arg1 = (SUNStepper)(farg1); - arg2 = (sunrealtype)(*farg2); - result = (SUNErrCode)SUNStepper_SetStepDirection(arg1,arg2); -======= SWIGEXPORT int _wrap_FSUNStepper_SetDestroyFn(void *farg1, SUNStepperDestroyFn farg2) { int fresult ; SUNStepper arg1 = (SUNStepper) 0 ; @@ -2916,7 +2919,6 @@ SWIGEXPORT int _wrap_FSUNStepper_SetDestroyFn(void *farg1, SUNStepperDestroyFn f arg1 = (SUNStepper)(farg1); arg2 = (SUNStepperDestroyFn)(farg2); result = (SUNErrCode)SUNStepper_SetDestroyFn(arg1,arg2); ->>>>>>> feature/sunstepper 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 3ddbfb398d..3544460efc 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -549,6 +549,7 @@ module fsundials_core_mod public :: FSUNStepper_FullRhs public :: FSUNStepper_Reset public :: FSUNStepper_SetStopTime + public :: FSUNStepper_SetStepDirection public :: FSUNStepper_SetForcing public :: FSUNStepper_SetContent public :: FSUNStepper_GetContent @@ -560,11 +561,7 @@ module fsundials_core_mod public :: FSUNStepper_SetStopTimeFn public :: FSUNStepper_SetStepDirectionFn public :: FSUNStepper_SetForcingFn -<<<<<<< HEAD - public :: FSUNStepper_SetStepDirection -======= public :: FSUNStepper_SetDestroyFn ->>>>>>> feature/sunstepper ! WRAPPER DECLARATIONS interface @@ -2121,6 +2118,15 @@ function swigc_FSUNStepper_SetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & +bind(C, name="_wrap_FSUNStepper_SetStepDirection") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FSUNStepper_SetForcing(farg1, farg2, farg3, farg4, farg5) & bind(C, name="_wrap_FSUNStepper_SetForcing") & result(fresult) @@ -2223,21 +2229,12 @@ function swigc_FSUNStepper_SetForcingFn(farg1, farg2) & integer(C_INT) :: fresult end function -<<<<<<< HEAD -function swigc_FSUNStepper_SetStepDirection(farg1, farg2) & -bind(C, name="_wrap_FSUNStepper_SetStepDirection") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -======= 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 ->>>>>>> feature/sunstepper integer(C_INT) :: fresult end function @@ -5090,6 +5087,22 @@ function FSUNStepper_SetStopTime(stepper, tstop) & swig_result = fresult end function +function FSUNStepper_SetStepDirection(stepper, stepdir) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: stepper +real(C_DOUBLE), intent(in) :: stepdir +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = stepper +farg2 = stepdir +fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) +swig_result = fresult +end function + function FSUNStepper_SetForcing(stepper, tshift, tscale, forcing, nforcing) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -5275,25 +5288,11 @@ function FSUNStepper_SetForcingFn(stepper, fn) & swig_result = fresult end function -<<<<<<< HEAD -function FSUNStepper_SetStepDirection(stepper, stepdir) & -======= function FSUNStepper_SetDestroyFn(stepper, fn) & ->>>>>>> feature/sunstepper result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: stepper -<<<<<<< HEAD -real(C_DOUBLE), intent(in) :: stepdir -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = stepper -farg2 = stepdir -fresult = swigc_FSUNStepper_SetStepDirection(farg1, farg2) -======= type(C_FUNPTR), intent(in), value :: fn integer(C_INT) :: fresult type(C_PTR) :: farg1 @@ -5302,7 +5301,6 @@ function FSUNStepper_SetDestroyFn(stepper, fn) & farg1 = stepper farg2 = fn fresult = swigc_FSUNStepper_SetDestroyFn(farg1, farg2) ->>>>>>> feature/sunstepper swig_result = fresult end function From 838e681734ccd712038084f7dd8377e2d24cb5e1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 28 Oct 2024 16:46:31 -0700 Subject: [PATCH 146/180] Update custom stepper not to use evolve state as in-out argument --- .../CXX_serial/ark_test_splittingstep.cpp | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index c29bf046fd..2e62944a79 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -302,31 +302,51 @@ static int test_resize(const sundials::Context& ctx) /* Creates a custom SUNStepper for the linear, scalar ODE y' = lambda*y */ static SUNStepper create_exp_stepper(const sundials::Context& ctx, - const sunrealtype& lambda) + const sunrealtype& lam, const N_Vector tmpl) { SUNStepper stepper = nullptr; SUNStepper_Create(ctx, &stepper); - SUNStepper_SetContent(stepper, - static_cast(const_cast(&lambda))); + + struct Content { + const sunrealtype lambda; + sunrealtype t; + const N_Vector v; + + static Content &from_stepper(SUNStepper s) { + void *content = nullptr; + SUNStepper_GetContent(s, &content); + return *static_cast(content); + } + }; + + SUNStepper_SetContent(stepper, new Content{lam, 0, N_VClone(tmpl)}); + SUNStepper_SetResetFn(stepper, [](SUNStepper s, const sunrealtype tR, const N_Vector vR) { + auto &content = Content::from_stepper(s); + content.t = tR; + N_VScale(1, vR, content.v); + return 0; + }); const auto empty_func = [](auto...) { return 0; }; - SUNStepper_SetResetFn(stepper, empty_func); SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); - const auto evolve = [](const SUNStepper s, const sunrealtype t0, - const sunrealtype tout, const N_Vector y, + const auto evolve = [](const SUNStepper s, + const sunrealtype tout, const N_Vector vret, sunrealtype* const tret) { - void* content = nullptr; - SUNStepper_GetContent(s, &content); - const auto lam = *static_cast(content); - N_VScale(std::exp(lam * (tout - t0)), y, y); - // *tret = tout; + const auto &content = Content::from_stepper(s); + N_VScale(std::exp(content.lambda * (tout - content.t)), content.v, vret); + *tret = tout; return 0; }; SUNStepper_SetEvolveFn(stepper, evolve); + + SUNStepper_SetDestroyFn(stepper, [](SUNStepper stepper) { + delete &Content::from_stepper(stepper); + return 0; + }); return stepper; } @@ -348,8 +368,8 @@ static int test_custom_stepper(const sundials::Context& ctx) const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - SUNStepper steppers[] = {create_exp_stepper(ctx, lambda1), - create_exp_stepper(ctx, lambda2)}; + SUNStepper steppers[] = {create_exp_stepper(ctx, lambda1, y), + create_exp_stepper(ctx, lambda2, y)}; auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); From dc433f34c575d5b8261bc2aa4c7d3cf5743e23b4 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 28 Oct 2024 17:24:59 -0700 Subject: [PATCH 147/180] Fix memory leak --- .../CXX_serial/ark_test_splittingstep.cpp | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 2e62944a79..0c4d18c731 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -302,51 +302,63 @@ static int test_resize(const sundials::Context& ctx) /* Creates a custom SUNStepper for the linear, scalar ODE y' = lambda*y */ static SUNStepper create_exp_stepper(const sundials::Context& ctx, - const sunrealtype& lam, const N_Vector tmpl) + const sunrealtype& lam, const N_Vector y) { SUNStepper stepper = nullptr; SUNStepper_Create(ctx, &stepper); - struct Content { + struct Content + { const sunrealtype lambda; - sunrealtype t; + sunrealtype t{}; const N_Vector v; - static Content &from_stepper(SUNStepper s) { - void *content = nullptr; + Content(const sunrealtype l, const N_Vector tmpl) : lambda(l), v(N_VClone(tmpl)) {} + + ~Content() { + N_VDestroy(v); + } + + static Content& from_stepper(SUNStepper s) + { + void* content = nullptr; SUNStepper_GetContent(s, &content); return *static_cast(content); } }; - SUNStepper_SetContent(stepper, new Content{lam, 0, N_VClone(tmpl)}); - SUNStepper_SetResetFn(stepper, [](SUNStepper s, const sunrealtype tR, const N_Vector vR) { - auto &content = Content::from_stepper(s); - content.t = tR; + SUNStepper_SetContent(stepper, new Content(lam, y)); + + const auto reset = [](SUNStepper s, const sunrealtype tR, const N_Vector vR) + { + auto& content = Content::from_stepper(s); + content.t = tR; N_VScale(1, vR, content.v); return 0; - }); + }; + SUNStepper_SetResetFn(stepper, reset); const auto empty_func = [](auto...) { return 0; }; SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); - const auto evolve = [](const SUNStepper s, - const sunrealtype tout, const N_Vector vret, - sunrealtype* const tret) + const auto evolve = [](const SUNStepper s, const sunrealtype tout, + const N_Vector vret, sunrealtype* const tret) { - const auto &content = Content::from_stepper(s); + const auto& content = Content::from_stepper(s); N_VScale(std::exp(content.lambda * (tout - content.t)), content.v, vret); *tret = tout; return 0; }; SUNStepper_SetEvolveFn(stepper, evolve); - SUNStepper_SetDestroyFn(stepper, [](SUNStepper stepper) { - delete &Content::from_stepper(stepper); + const auto destroy = [](SUNStepper s) + { + delete &Content::from_stepper(s); return 0; - }); + }; + SUNStepper_SetDestroyFn(stepper, destroy); return stepper; } From 85e6275a5848ea9433ca0deb383948499a44bbb9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 28 Oct 2024 17:28:51 -0700 Subject: [PATCH 148/180] Apply formatter --- .../arkode/CXX_serial/ark_test_splittingstep.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index 0c4d18c731..c4af724826 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -313,11 +313,11 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, sunrealtype t{}; const N_Vector v; - Content(const sunrealtype l, const N_Vector tmpl) : lambda(l), v(N_VClone(tmpl)) {} + Content(const sunrealtype l, const N_Vector tmpl) + : lambda(l), v(N_VClone(tmpl)) + {} - ~Content() { - N_VDestroy(v); - } + ~Content() { N_VDestroy(v); } static Content& from_stepper(SUNStepper s) { From 63043ee5f0ca65890d04a0a54820eb9ac2b5b577 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Mon, 28 Oct 2024 17:35:24 -0700 Subject: [PATCH 149/180] Add setstepdirection back --- src/sundials/sundials_stepper_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sundials/sundials_stepper_impl.h b/src/sundials/sundials_stepper_impl.h index 4e4834a3e1..5262b5eaa8 100644 --- a/src/sundials/sundials_stepper_impl.h +++ b/src/sundials/sundials_stepper_impl.h @@ -28,6 +28,7 @@ struct SUNStepper_Ops_ SUNStepperFullRhsFn fullrhs; SUNStepperResetFn reset; SUNStepperSetStopTimeFn setstoptime; + SUNStepperSetStepDirectionFn setstepdirection; SUNStepperSetForcingFn setforcing; SUNStepperDestroyFn destroy; }; From 09bd9daaa738da166f93b6e001ac30f0d5864f35 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 29 Oct 2024 17:26:45 -0700 Subject: [PATCH 150/180] Add full RHS mode back --- src/arkode/arkode_forcingstep.c | 4 ++-- src/arkode/arkode_splittingstep.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 3e13394057..2daa0a2016 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -134,7 +134,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, if (retval != ARK_SUCCESS) { return retval; } SUNErrCode err = SUNStepper_FullRhs(step_mem->stepper[0], t, y, - ark_mem->tempv1); + ark_mem->tempv1, SUN_FULLRHS_OTHER); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -142,7 +142,7 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return ARK_RHSFUNC_FAIL; } - err = SUNStepper_FullRhs(step_mem->stepper[1], t, y, f); + err = SUNStepper_FullRhs(step_mem->stepper[1], t, y, f, SUN_FULLRHS_OTHER); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 34c9cc6b1b..38c1e3ae36 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -188,7 +188,8 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, for (int i = 0; i < step_mem->partitions; i++) { const SUNErrCode err = SUNStepper_FullRhs(step_mem->steppers[i], t, y, - i == 0 ? f : ark_mem->tempv1); + i == 0 ? f : ark_mem->tempv1, + SUN_FULLRHS_OTHER); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, From 684a9eec1568e2831e26e7d46a595fa42c99d473 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 5 Nov 2024 10:02:08 -0800 Subject: [PATCH 151/180] Fix error message for NULL stepper --- src/arkode/arkode_splittingstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 38c1e3ae36..15ccf5e970 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -456,7 +456,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, if (steppers[i] == NULL) { arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "steppers[i] = NULL illegal.", i); + "steppers[%d] = NULL illegal.", i); return NULL; } } From 8d1bf5fb949885c0df2b12150a5352b39e823646 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 5 Nov 2024 10:07:09 -0800 Subject: [PATCH 152/180] Rename PARTITIONS to NUM_PARTITIONS --- src/arkode/arkode_forcingstep.c | 10 +++++----- src/arkode/arkode_forcingstep_impl.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 2daa0a2016..7f63e45a90 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -226,14 +226,14 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfil switch (fmt) { case SUN_OUTPUTFORMAT_TABLE: - for (int k = 0; k < PARTITIONS; k++) + for (int k = 0; k < NUM_PARTITIONS; k++) { fprintf(outfile, "Partition %i evolves = %ld\n", k, step_mem->n_stepper_evolves[k]); } break; case SUN_OUTPUTFORMAT_CSV: - for (int k = 0; k < PARTITIONS; k++) + for (int k = 0; k < NUM_PARTITIONS; k++) { fprintf(outfile, "Partition %i evolves,%ld\n", k, step_mem->n_stepper_evolves[k]); @@ -268,7 +268,7 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) if (retval != ARK_SUCCESS) { return; } /* output long integer quantities */ - for (int k = 0; k < PARTITIONS; k++) + for (int k = 0; k < NUM_PARTITIONS; k++) { fprintf(outfile, "ForcingStep: partition %i: n_stepper_evolves = %li\n", k, step_mem->n_stepper_evolves[k]); @@ -394,10 +394,10 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves &ark_mem, &step_mem); if (retval != ARK_SUCCESS) { return retval; } - if (partition >= PARTITIONS) + if (partition >= NUM_PARTITIONS) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "The partition index is %i but there are only 2 partitions", + "The partition index is %i but there are only 2 NUM_partitions", partition); return ARK_ILL_INPUT; } diff --git a/src/arkode/arkode_forcingstep_impl.h b/src/arkode/arkode_forcingstep_impl.h index 77c542b7f4..a7940a9c4c 100644 --- a/src/arkode/arkode_forcingstep_impl.h +++ b/src/arkode/arkode_forcingstep_impl.h @@ -19,12 +19,12 @@ #include -#define PARTITIONS 2 +#define NUM_PARTITIONS 2 typedef struct ARKodeForcingStepMemRec { - SUNStepper stepper[PARTITIONS]; - long int n_stepper_evolves[PARTITIONS]; + SUNStepper stepper[NUM_PARTITIONS]; + long int n_stepper_evolves[NUM_PARTITIONS]; }* ARKodeForcingStepMem; #endif From c509f7a76db2d715776e287831864a2651d28811 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 5 Nov 2024 10:15:07 -0800 Subject: [PATCH 153/180] Add nodes on potential future optimizations --- src/arkode/arkode_forcingstep.c | 3 +++ src/arkode/arkode_splittingstep.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 7f63e45a90..26beccb318 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -142,6 +142,9 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, return ARK_RHSFUNC_FAIL; } + /* TODO(SBR): this *may* be able to use SUN_FULLRHS_END mode in some cases + * but we need to be certain the state of the SUNStepper is consistent with + * the outer forcing method */ err = SUNStepper_FullRhs(step_mem->stepper[1], t, y, f, SUN_FULLRHS_OTHER); if (err != SUN_SUCCESS) { diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 15ccf5e970..3dde7dd873 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -246,6 +246,11 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, #endif const SUNStepper stepper = step_mem->steppers[k]; + /* TODO(SBR): A potential future optimization is removing this reset and + * a call to SUNStepper_SetStopTime later for methods that start a step + * evolving the same partition the last step ended with (essentially a + * FSAL property). Care is needed when a reset occurs, the step direction + * changes, the coefficients change, etc. */ SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } From 34b8e1243c349495210d6689e96c193417815fd5 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 5 Nov 2024 10:17:51 -0800 Subject: [PATCH 154/180] Apply formatter --- src/arkode/arkode_forcingstep.c | 2 +- src/arkode/arkode_splittingstep.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 26beccb318..a694d04a07 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -400,7 +400,7 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves if (partition >= NUM_PARTITIONS) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, - "The partition index is %i but there are only 2 NUM_partitions", + "The partition index is %i but there are only 2 partitions", partition); return ARK_ILL_INPUT; } diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 3dde7dd873..981296917b 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -251,7 +251,7 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, * evolving the same partition the last step ended with (essentially a * FSAL property). Care is needed when a reset occurs, the step direction * changes, the coefficients change, etc. */ - SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); + SUNErrCode err = SUNStepper_Reset(stepper, t_start, y); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStepDirection(stepper, t_end - t_start); From f7978bd2343368b3609ce7f8c7a177a66f9f68d5 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 08:06:50 -0800 Subject: [PATCH 155/180] Fix stage indexing in docs --- doc/arkode/guide/source/Mathematics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 1e9f3ea5e6..d1e8d288fc 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -675,7 +675,7 @@ The following algorithmic procedure is used in the Splitting-Step module: #. Set :math:`y_{n, i} = y_{n - 1}`. - #. For :math:`j = 0, \dots, s` do: + #. For :math:`j = 1, \dots, s` do: #. For :math:`k = 1, \dots, P` do: From 1562d1bda557ac0e530a076a540a179720869d7b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 08:17:39 -0800 Subject: [PATCH 156/180] Fix equation for parallel splitting --- .../source/Usage/SplittingStep/SplittingStepCoefficients.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index c45c3a77e4..1fee47cf41 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -197,7 +197,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. math:: y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + - (1 - p) y_{n-1}. + (1 - P) y_{n-1}. :param partitions: The number :math:`P > 1` of partitions in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a From 593df5ec248ec7f10952e5f41fec9d08bc004209 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 08:24:04 -0800 Subject: [PATCH 157/180] Apply simple doc fixes from code review Co-authored-by: David Gardner --- doc/arkode/guide/source/Mathematics.rst | 4 +- .../source/Usage/SplittingStep/Skeleton.rst | 23 ++-- .../SplittingStepCoefficients.rst | 103 ++++++++++-------- .../Usage/SplittingStep/User_callable.rst | 6 +- 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 1e9f3ea5e6..dbcca406b6 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -694,7 +694,7 @@ The following algorithmic procedure is used in the Splitting-Step module: Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number of sequential methods within the overall operator splitting scheme. The sequential methods have independent flows which are linearly combined to produce -the next step. The real coefficients :math:`\alpha_i` and :math:`\beta_{i,j,k}` +the next step. The real coefficients :math:`\alpha \in \mathbb{R}^{r}` and :math:`\beta \in \mathbb{R}^{r \times s + 1 \times P}` determine the particular scheme and properties such as the order of accuracy. An alternative representation of the SplittingStep solution is @@ -706,7 +706,7 @@ An alternative representation of the SplittingStep solution is \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right) (y_{n-1}) -where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` and +where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` is the scaling factor for the step size, :math:`h`, and :math:`\phi^k_{h}` is the flow map for partition :math:`k`: .. math:: diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index ffccdb8910..be4db315c3 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -37,7 +37,7 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Create a stepper object for each problem partition - * If using ARKStep as an inner integrator, create the ARKStep object with + * If using ARKStep as an partition integrator, create the ARKStep object with :c:func:`ARKStepCreate` and configure the integrator as desired for evolving the partition. See sections :numref:`ARKODE.Usage.Skeleton`, :numref:`ARKODE.Usage.OptionalInputs`, and @@ -47,13 +47,13 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. Once the ARKStep object is setup, create a :c:type:`SUNStepper` object with :c:func:`ARKodeCreateSUNStepper`. - * If supplying a user-defined inner integrator, create the + * If supplying a user-defined partition integrator, create the :c:type:`SUNStepper` object as described in section :numref:`SUNStepper.Implementing`. .. note:: - When using ARKStep as an inner integrator it is the user's responsibility + When using ARKStep as a partition integrator it is the user's responsibility to create and configure the integrator. User-specified options regarding how the integration should be performed (e.g., adaptive vs. fixed time step, explicit/implicit/ImEx partitioning, algebraic solvers, etc.) will @@ -71,12 +71,11 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. integrators may be the same or different depending on what is required by the user code. - Specifying a rootfinding problem for an inner integrator is not supported. - Rootfinding problems should be created and initialized with the outer - integrator. See the steps below and :c:func:`ARKodeRootInit()` for more - details. + Specifying a rootfinding problem for a partitiona integrator is not supported. + Rootfinding problems should be created and initialized with SplittingStep. + See the steps below and :c:func:`ARKodeRootInit()` for more details. -#. Create a SplittingStep object for the outer integration +#. Create a SplittingStep object Create the SplittingStep object by calling :c:func:`SplittingStepCreate`. One of the inputs to :c:func:`SplittingStepCreate` is an array of @@ -85,7 +84,7 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Set the SplittingStep step size Call :c:func:`ARKodeSetFixedStep()` on the SplittingStep object to specify - the outer time step size. + the overall time step size. #. *Set optional inputs* @@ -99,11 +98,11 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Free solver memory - * If ARKStep was used as an inner IVP integrator, call + * If an ARKODE stepper module was used as an partition IVP integrator, call :c:func:`SUNStepper_Destroy` and :c:func:`ARKodeFree` to free the memory - allocated for that inner integrator. + allocated for that integrator. - * If a user-defined inner integrator was supplied, free the integrator + * If a user-defined partition integrator was supplied, free the integrator content and call :c:func:`SUNStepper_Destroy` to free the :c:type:`SUNStepper` object. diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index c45c3a77e4..38cdfbaf63 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -34,31 +34,33 @@ stored in a :c:type:`SplittingStepCoefficients` object which is a pointer to a As described in :numref:`ARKODE.Mathematics.SplittingStep`, an operator splitting method is defined by a vector :math:`\alpha \in \mathbb{R}^{r}` and - a tensor :math:`\beta \in \mathbb{R}^{r \times (s + 1) \times P}`. + a tensor :math:`\beta \in \mathbb{R}^{r \times (s + 1) \times P}` where :math:`r` is + the number of sequential methods, :math:`s` is the number of stages, and :math:`P` + is the number of partitions. .. c:member:: sunrealtype *alpha - An array of length ``[sequential_methods]`` containing the weight of each - sequential method used to produce the overall operator splitting solution + An array containing the weight of each sequential method used to produce the + overall operator splitting solution. The array is of length + ``[sequential_methods]``. .. c:member:: sunrealtype ***beta - A three-dimensional array with dimensions - ``[sequential_methods][stages+1][partitions]`` containing the time nodes - of the inner integrations. + A three-dimensional array containing the time nodes of the inner integrations. + The array has dimensions ``[sequential_methods][stages+1][partitions]``. .. c:member:: int sequential_methods - The number :math:`r` of sequential methods combined to produce the overall + The number of sequential methods, :math:`r`, combined to produce the overall operator splitting solution .. c:member:: int stages - The number :math:`s` of stages + The number of stages, :math:`s` .. c:member:: int partitions - The number :math:`P` of partitions in the IVP + The number of partitions, :math:`P`, in the IVP .. c:member:: int order @@ -99,15 +101,19 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. +--------------------------------------------------------------+-------------------------------------------------------------+ | :c:func:`SplittingStepCoefficients_SuzukiFractal()` | Create an arbitrary order, five-jump composition method | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Alloc()` | Allocate an empty SplittingStepCoefficient | + | :c:func:`SplittingStepCoefficients_Alloc()` | Allocate an empty :c:type:`SplittingStepCoefficients` | + | | object | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Create()` | Create a new SplittingStepCoefficient from coefficients | + | :c:func:`SplittingStepCoefficients_Create()` | Create a new :c:type:`SplittingStepCoefficients` object | + | | from coefficient arrays | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a SplittingStepCoefficients | + | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a :c:type:`SplittingStepCoefficients` | + | | object | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Free()` | Deallocate a SplittingStepCoefficients | + | :c:func:`SplittingStepCoefficients_Free()` | Deallocate a :c:type:`SplittingStepCoefficients` object | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Write()` | Write the SplittingStepCoefficients to an output file | + | :c:func:`SplittingStepCoefficients_Write()` | Write the :c:type:`SplittingStepCoefficients` object to an | + | | output file | +--------------------------------------------------------------+-------------------------------------------------------------+ @@ -120,7 +126,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. :param method: the splitting coefficients identifier. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *method* was invalid or an allocation error occurred. + ``NULL`` pointer if ``method`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -134,7 +140,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. :param method: the splitting coefficients identifier. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *method* was invalid or an allocation error occurred. + ``NULL`` pointer if ``method`` was invalid or an allocation error occurred. .. note:: @@ -152,7 +158,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. :param method: the splitting coefficients identifier. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *method* was invalid or an allocation error occurred. + ``NULL`` pointer if ``method`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -165,9 +171,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} \circ \dots \circ \phi^1_{h} \right) (y_{n-1}). - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *partitions* was invalid or an allocation error + ``NULL`` pointer if ``partitions`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -183,9 +189,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`L_h` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` is its adjoint. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *partitions* was invalid or an allocation error + ``NULL`` pointer if ``partitions`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -199,9 +205,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + (1 - p) y_{n-1}. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *partitions* was invalid or an allocation error + ``NULL`` pointer if ``partitions`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -218,9 +224,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. where :math:`L_h` is the Lie-Trotter splitting and :math:`L^*_h = L^{-1}_{-h}` is its adjoint. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *partitions* was invalid or an allocation error + ``NULL`` pointer if ``partitions`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -238,9 +244,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters :math:`p_1, \dots, p_5` are selected to give third order. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a - ``NULL`` pointer if *partitions* was invalid or an allocation error + ``NULL`` pointer if ``partitions`` was invalid or an allocation error occurred. .. versionadded:: x.y.z @@ -256,13 +262,13 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. T_h^{[2]} &= S_h, \\ T_h^{[i+2]} &= T_{\gamma_1 h}^{[i]} \circ T_{(1 - 2 \gamma_1) h}^{[i]} \circ T_{\gamma_1 h}^{[i]}, \\ - y_n &= T_h^{[order]}(y_{n-1}), + y_n &= T_h^{[\mathrm{order}]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is + where :math:`S` is the Strang splitting and :math:`\gamma_1` is selected to increase the order by two each recursion. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :param order: A positive even number for the method order of accuracy. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error @@ -282,13 +288,13 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Q_h^{[i+2]} &= Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]} \circ Q_{(1 - 4 \gamma_1) h}^i \circ Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]}, \\ - y_n &= Q_h^{[order]}(y_{n-1}), + y_n &= Q_h^{[\mathrm{order}]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting and parameter :math:`\gamma_1` is + where :math:`S` is the Strang splitting and :math:`\gamma_1` is selected to increase the order by two each recursion. - :param partitions: The number :math:`P > 1` of partitions in the IVP. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :param order: A positive even number for the method order of accuracy. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error @@ -299,12 +305,12 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Alloc(int sequential_methods, int stages, int partitions) - Allocates an empty SplittingStepCoefficients. + Allocates an empty :c:type:`SplittingStepCoefficients` object. - :param sequential_methods: The number :math:`r` of sequential methods + :param sequential_methods: The number of sequential methods, :math:`r \geq 1`, combined to produce the overall operator splitting solution. - :param stages: The number :math:`s` of stages. - :param partitions: The number :math:`P` of partitions in the IVP. + :param stages: The number of stages, :math:`s \geq 1`. + :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error occurred. @@ -314,22 +320,31 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Create(int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta) - Allocates a SplittingStepCoefficients and fills it with the given values. + Allocates a :c:type:`SplittingStepCoefficients` object and fills it with the given values. - :param sequential_methods: The number :math:`r` of sequential methods + :param sequential_methods: The number of sequential methods, :math:`r \geq 1` combined to produce the overall operator splitting solution. - :param stages: The number :math:`s` of stages. - :param partitions: The number :math:`P` of partitions in the IVP. + :param stages: The number of stages, :math:`s \geq 1`. + :param partitions: The number of partitions, :math:`P > 1` in the IVP. :param order: The method order of accuracy. :param alpha: An array of length ``sequential_methods`` containing the weight of each sequential method used to produce the overall operator splitting solution. :param beta: An array of length ``sequential_methods * (stages+1) * partitions`` containing the time nodes - of the inner integrations in the order + of the inner integrations in the C order .. math:: - \beta_{1,0,1}, \dots, \beta_{1,0,P}, \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, \beta_{2,0,1}, \dots, \beta_{r,s,P}. + \beta_{1,0,1}, \dots, \beta_{1,0,P}, + \dots, + \beta_{1,s,1}, \dots, \beta_{1,s,P} + \beta_{2,0,1}, \dots, \beta_{2,0,P} + \dots, + \beta_{2,s,1}, \dots, \beta_{2,s,P} + \dots, + \beta_{r,0,1}, \dots, \beta_{r,0,P} + \dots, + \beta_{r,s,1}, \dots, \beta_{r,s,P} :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error @@ -353,7 +368,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Deallocate the splitting coefficients memory. - :param coefficients: The splitting coefficients. + :param coefficients: A pointer to the splitting coefficients. .. versionadded:: x.y.z diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index c536c6961b..f8694ba1bc 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -38,10 +38,10 @@ SplittingStep initialization functions This function allocates and initializes memory for a problem to be solved using the SplittingStep time-stepping module in ARKODE. - :param steppers: an array of :c:type:`SUNStepper` with one for each + :param steppers: an array of :c:type:`SUNStepper` objects with one for each partition of the IVP. All :c:type:`SUNStepper` operations are required to be implemented except :c:func:`SUNStepper_SetForcing`. - :param partitions: the number :math:`P > 1` of partitions in the IVP. + :param partitions: the number of partitions, :math:`P > 1`, in the IVP. :param t0: the initial value of :math:`t`. :param y0: the initial condition vector :math:`y(t_0)`. :param sunctx: the :c:type:`SUNContext` object (see :numref:`SUNDIALS.SUNContext`) @@ -88,7 +88,7 @@ Optional inputs for IVP method selection .. c:function:: int SplittingStep_SetCoefficients(void* arkode_mem, SplittingStepCoefficients coefficients) - Specifies a customized set of coefficients for the operator splitting method. + Specifies a set of coefficients for the operator splitting method. :param arkode_mem: pointer to the SplittingStep memory block. :param coefficients: the splitting coefficients for the method. From 8ab2aa8bb706189fa3e51d242a03397b8ca421f7 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 09:02:09 -0800 Subject: [PATCH 158/180] Apply simple src fixes Co-authored-by: David Gardner --- include/arkode/arkode_forcingstep.h | 2 +- include/arkode/arkode_splittingstep.h | 2 +- src/arkode/arkode_forcingstep.c | 2 +- src/arkode/arkode_io.c | 2 +- src/arkode/arkode_splittingstep.c | 8 ++++---- src/arkode/arkode_splittingstep_coefficients.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/arkode/arkode_forcingstep.h b/include/arkode/arkode_forcingstep.h index 16296b4422..b5fa85e123 100644 --- a/include/arkode/arkode_forcingstep.h +++ b/include/arkode/arkode_forcingstep.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * This is the header file for the ARKODE ForcingStep module. + * This is the header file for the ARKODE ForcingStep module. *--------------------------------------------------------------*/ #ifndef ARKODE_FORCINGINGSTEP_H_ diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index 006225e7d4..cd354a8d07 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End *--------------------------------------------------------------- - * This is the header file for the ARKODE SplittingStep module. + * This is the header file for the ARKODE SplittingStep module. *--------------------------------------------------------------*/ #ifndef ARKODE_SPLITTINGSTEP_H_ diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index a694d04a07..7360013391 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -238,7 +238,7 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfil case SUN_OUTPUTFORMAT_CSV: for (int k = 0; k < NUM_PARTITIONS; k++) { - fprintf(outfile, "Partition %i evolves,%ld\n", k, + fprintf(outfile, ",Partition %i evolves,%ld", k, step_mem->n_stepper_evolves[k]); } break; diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index f82c0eef35..920c39f0d2 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1317,7 +1317,7 @@ int ARKodeSetStepDirection(void* arkode_mem, sunrealtype stepdir) // TODO(SBR): use SUNRcopysign once merged from other PR // if (SUNRcopysign(h, stepdir) == h) { - if (h == ZERO || ((h > 0) == (stepdir > 0))) { return ARK_SUCCESS; } + if (h == ZERO || ((h > ZERO) == (stepdir > ZERO))) { return ARK_SUCCESS; } /* Reverse the sign of h. If adaptive, h will be overwritten anyway by the * initial step estimation since ARKodeReset must be called before this. diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 981296917b..51e4250edf 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -98,7 +98,7 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, } else { - /* Bump the order up to be even but with an error */ + /* Bump the order up to be even but with a warning */ const int new_order = step_mem->order + 1; arkProcessError(ark_mem, ARK_WARNING, __LINE__, __func__, __FILE__, "No splitting method at requested order, using q=%i.", @@ -139,7 +139,7 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) return ARK_SUCCESS; } - /* assume fixed outer step size */ + /* assume fixed step size */ if (!ark_mem->fixedstep) { arkProcessError(ark_mem, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, @@ -260,7 +260,7 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, err = SUNStepper_SetStopTime(stepper, t_end); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } - sunrealtype tret = 0; + sunrealtype tret = ZERO; err = SUNStepper_Evolve(stepper, t_end, y, &tret); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } @@ -332,7 +332,7 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, case SUN_OUTPUTFORMAT_CSV: for (int k = 0; k < step_mem->partitions; k++) { - fprintf(outfile, "Partition %i evolves,%ld\n", k, + fprintf(outfile, ",Partition %i evolves,%ld", k, step_mem->n_stepper_evolves[k]); } break; diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index 7837b8dc64..80260abe0a 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -438,7 +438,7 @@ void SplittingStepCoefficients_Write(const SplittingStepCoefficients coefficient FILE* const outfile) { // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged - if (coefficients == NULL || coefficients->alpha == NULL || + if (outfile == NULL || coefficients == NULL || coefficients->alpha == NULL || coefficients->beta == NULL || coefficients->beta[0] == NULL || coefficients->beta[0][0] == NULL) { From f2a73cd2bd738cf8394124b80279fd00e1823339 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 09:04:40 -0800 Subject: [PATCH 159/180] Apply suggestions for PDE formulation comment Co-authored-by: David Gardner --- .../C_serial/ark_advection_diffusion_reaction_splitting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index d494aebb71..9a9dc663cd 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -15,7 +15,7 @@ * * The following test simulates a simple 1D advection-diffusion- * reaction equation, - * u_t = a*(u^2/2)_x + b*u_xx + c*(u - u^3) + * u_t = (a/2)*(u^2)_x + b*u_xx + c*(u - u^3) * for t in [0, 1], x in [0, 1], with initial conditions * u(0,x) = u_0 * and Dirichlet boundary conditions at x=0 and x=1 From e61e6d223c15008c3809b7edcca6dc82b3a85c01 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 09:08:31 -0800 Subject: [PATCH 160/180] Apply simple fixes for unit tests from code review Co-authored-by: David Gardner --- .../CXX_serial/ark_test_splittingstep.cpp | 28 +++++++++---------- .../arkode/C_serial/ark_test_forcingstep.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index c4af724826..f3d0bf874b 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -39,7 +39,7 @@ static int test_forward(sundials::Context& ctx, const int partitions) constexpr auto tf = SUN_RCONST(1.0); constexpr auto dt = SUN_RCONST(8.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-6); - constexpr auto global_tol = 10 * local_tol; + constexpr auto global_tol = SUN_RCONST(10.0) * local_tol; const auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); @@ -73,7 +73,7 @@ static int test_forward(sundials::Context& ctx, const int partitions) /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); - const auto numerical_solution = NV_Ith_S(y, 0); + const auto numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { @@ -119,7 +119,7 @@ static int test_mixed_directions(const sundials::Context& ctx) constexpr auto t3 = t0; constexpr auto dt = -SUN_RCONST(1.23e-3); constexpr auto local_tol = SUN_RCONST(1.0e-6); - constexpr auto global_tol = 10 * local_tol; + constexpr auto global_tol = SUN_RCONST(10.0) * local_tol; const auto y = N_VNew_Serial(2, ctx); N_VConst(SUN_RCONST(1.0), y); const auto err = N_VClone(y); @@ -128,16 +128,16 @@ static int test_mixed_directions(const sundials::Context& ctx) const ARKRhsFn f1 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) { - NV_Ith_S(zdot, 0) = NV_Ith_S(z, 1) - t; - NV_Ith_S(zdot, 1) = SUN_RCONST(0.0); + N_VGetArrayPointer(zdot)[0] = N_VGetArrayPointer(z)[1] - t; + N_VGetArrayPointer(zdot)[1] = SUN_RCONST(0.0); return 0; }; const ARKRhsFn f2 = [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) { - NV_Ith_S(zdot, 0) = SUN_RCONST(0.0); - NV_Ith_S(zdot, 1) = t - NV_Ith_S(z, 0); + N_VGetArrayPointer(zdot)[0] = SUN_RCONST(0.0); + N_VGetArrayPointer(zdot)[1] = t - N_VGetArrayPointer(z)[0]; return 0; }; @@ -202,7 +202,7 @@ static int test_mixed_directions(const sundials::Context& ctx) /* Integrates the ODE * - * y' = [y^2] - [y*(y - 1)] = -y + * y' = [y^2] - [y*(y + 1)] = -y * * with initial condition y(0) = 1 and partitioning specified by the square * brackets. Powers and products are done componentwise. At t = 0.5, we resize @@ -261,8 +261,8 @@ static int test_resize(const sundials::Context& ctx) /* Resize */ const auto y_new = N_VNew_Serial(2, ctx); - NV_Ith_S(y_new, 0) = SUN_RCONST(1.0); - NV_Ith_S(y_new, 1) = NV_Ith_S(y, 0); + N_VGetArrayPointer(y_new)[0] = SUN_RCONST(1.0); + N_NGetArrayPointer(y_new)[1] = N_VGetArrayPointer(y)[0]; N_VDestroy(y); ARKodeResize(arkode_mem, y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); ARKodeResize(parititon_mem[0], y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); @@ -272,8 +272,8 @@ static int test_resize(const sundials::Context& ctx) ARKodeEvolve(arkode_mem, t2, y_new, &tret, ARK_NORMAL); const auto err = N_VClone(y_new); - NV_Ith_S(err, 0) = std::exp(t1 - t2); - NV_Ith_S(err, 1) = std::exp(t0 - t2); + N_VGetArrayPointer(err)[0] = std::exp(t1 - t2); + N_VGetArrayPointer(err)[1] = std::exp(t0 - t2); N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y_new, err); const auto max_err = N_VMaxNorm(err); @@ -333,7 +333,7 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, { auto& content = Content::from_stepper(s); content.t = tR; - N_VScale(1, vR, content.v); + N_VScale(SUN_RCONST(1.0), vR, content.v); return 0; }; SUNStepper_SetResetFn(stepper, reset); @@ -394,7 +394,7 @@ static int test_custom_stepper(const sundials::Context& ctx) /* Check that the solution matches the exact solution */ const auto exact_solution = std::exp(t0 - tf); - const auto numerical_solution = NV_Ith_S(y, 0); + const auto numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompare(exact_solution, numerical_solution)) { const auto err = numerical_solution - exact_solution; diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index f4b5bab77c..e0f0ce648c 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -56,7 +56,7 @@ static int test_forward(SUNContext ctx) const sunrealtype tf = SUN_RCONST(1.0); const sunrealtype dt = SUN_RCONST(1.0e-4); const sunrealtype local_tol = SUN_RCONST(1.0e-6); - const sunrealtype global_tol = 10 * local_tol; + const sunrealtype global_tol = SUN_RCONST(10.0) * local_tol; const N_Vector y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); From ab6c699f44fb7e9bbb6599390247d97fcea9c922 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 13:23:36 -0800 Subject: [PATCH 161/180] SplittingStepCoefficients_Free to SplittingStepCoefficients_Destroy --- .../SplittingStepCoefficients.rst | 4 +-- .../C_serial/ark_analytic_partitioned.c | 4 +-- include/arkode/arkode_splittingstep.h | 4 +-- src/arkode/arkode_splittingstep.c | 6 ++--- .../arkode_splittingstep_coefficients.c | 27 ++++++++++--------- .../fmod_int32/farkode_splittingstep_mod.c | 9 +++---- .../fmod_int32/farkode_splittingstep_mod.f90 | 19 +++++++------ .../fmod_int64/farkode_splittingstep_mod.c | 9 +++---- .../fmod_int64/farkode_splittingstep_mod.f90 | 19 +++++++------ .../CXX_serial/ark_test_splittingstep.cpp | 18 ++++++------- .../ark_test_splittingstep_coefficients.c | 18 ++++++------- 11 files changed, 67 insertions(+), 70 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index af267e0f09..132f8572dd 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -110,7 +110,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a :c:type:`SplittingStepCoefficients` | | | object | +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Free()` | Deallocate a :c:type:`SplittingStepCoefficients` object | + | :c:func:`SplittingStepCoefficients_Destroy()` | Deallocate a :c:type:`SplittingStepCoefficients` object | +--------------------------------------------------------------+-------------------------------------------------------------+ | :c:func:`SplittingStepCoefficients_Write()` | Write the :c:type:`SplittingStepCoefficients` object to an | | | output file | @@ -364,7 +364,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. versionadded:: x.y.z -.. c:function:: void SplittingStepCoefficients_Free(SplittingStepCoefficients coefficients) +.. c:function:: void SplittingStepCoefficients_Destroy(SplittingStepCoefficients* coefficients) Deallocate the splitting coefficients memory. diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 51a532ed5d..485689d8ac 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -202,7 +202,7 @@ int main(const int argc, char* const argv[]) if (coefficients_name != NULL) { - const SplittingStepCoefficients coefficients = + SplittingStepCoefficients coefficients = SplittingStepCoefficients_LoadCoefficientsByName(coefficients_name); if (check_flag(coefficients, "SplittingStepCoefficients_LoadCoefficientsByName", 0)) @@ -213,7 +213,7 @@ int main(const int argc, char* const argv[]) flag = SplittingStep_SetCoefficients(arkode_mem, coefficients); if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); } } else diff --git a/include/arkode/arkode_splittingstep.h b/include/arkode/arkode_splittingstep.h index cd354a8d07..b916bf7d6a 100644 --- a/include/arkode/arkode_splittingstep.h +++ b/include/arkode/arkode_splittingstep.h @@ -62,8 +62,8 @@ SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Alloc( SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Create( int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta); -SUNDIALS_EXPORT void SplittingStepCoefficients_Free( - SplittingStepCoefficients coefficients); +SUNDIALS_EXPORT void SplittingStepCoefficients_Destroy( + SplittingStepCoefficients* coefficients); SUNDIALS_EXPORT SplittingStepCoefficients SplittingStepCoefficients_Copy(SplittingStepCoefficients coefficients); SUNDIALS_EXPORT void SplittingStepCoefficients_Write( diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index 51e4250edf..a0be1914f4 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -371,7 +371,7 @@ static void splittingStep_Free(const ARKodeMem ark_mem) { free(step_mem->steppers); free(step_mem->n_stepper_evolves); - SplittingStepCoefficients_Free(step_mem->coefficients); + SplittingStepCoefficients_Destroy(&step_mem->coefficients); free(step_mem); } ark_mem->step_mem = NULL; @@ -415,7 +415,7 @@ static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) /* set user-provided value, or default, depending on argument */ step_mem->order = order <= 0 ? 1 : order; - SplittingStepCoefficients_Free(step_mem->coefficients); + SplittingStepCoefficients_Destroy(&step_mem->coefficients); step_mem->coefficients = NULL; return ARK_SUCCESS; @@ -592,7 +592,7 @@ int SplittingStep_SetCoefficients(void* const arkode_mem, return ARK_ILL_INPUT; } - SplittingStepCoefficients_Free(step_mem->coefficients); + SplittingStepCoefficients_Destroy(&step_mem->coefficients); step_mem->coefficients = SplittingStepCoefficients_Copy(coefficients); if (step_mem->coefficients == NULL) { diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index 80260abe0a..afa01ad0b5 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -28,7 +28,7 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( { if (sequential_methods < 1 || stages < 1 || partitions < 1) { return NULL; } - const SplittingStepCoefficients coefficients = + SplittingStepCoefficients coefficients = (SplittingStepCoefficients)malloc(sizeof(*coefficients)); if (coefficients == NULL) { return NULL; } @@ -41,7 +41,7 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( sizeof(*coefficients->alpha)); if (coefficients->alpha == NULL) { - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); return NULL; } @@ -54,7 +54,7 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( (sunrealtype***)malloc(sequential_methods * sizeof(*coefficients->beta)); if (coefficients->beta == NULL) { - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); return NULL; } @@ -63,7 +63,7 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( sequential_methods * (stages + 1) * sizeof(*beta_cols)); if (beta_cols == NULL) { - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); return NULL; } @@ -73,7 +73,7 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( sizeof(*beta_mem)); if (beta_mem == NULL) { - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); return NULL; } @@ -115,20 +115,21 @@ SplittingStepCoefficients SplittingStepCoefficients_Create( /*--------------------------------------------------------------- Routine to free splitting coefficients ---------------------------------------------------------------*/ -void SplittingStepCoefficients_Free(const SplittingStepCoefficients coefficients) +void SplittingStepCoefficients_Destroy(SplittingStepCoefficients* coefficients) { - if (coefficients != NULL) + if (*coefficients != NULL && coefficients != NULL) { - free(coefficients->alpha); - if (coefficients->beta != NULL) + free((*coefficients)->alpha); + if ((*coefficients)->beta != NULL) { - free(coefficients->beta[0][0]); - free(coefficients->beta[0]); - free(coefficients->beta); + free((*coefficients)->beta[0][0]); + free((*coefficients)->beta[0]); + free((*coefficients)->beta); } } - free(coefficients); + free(*coefficients); + *coefficients = NULL; } /*--------------------------------------------------------------- diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.c b/src/arkode/fmod_int32/farkode_splittingstep_mod.c index 413a87802e..792a01a5d6 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.c @@ -523,12 +523,11 @@ SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Create(int const *f } -SWIGEXPORT void _wrap_FSplittingStepCoefficients_Free(SwigClassWrapper const *farg1) { - SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Destroy(void *farg1) { + SplittingStepCoefficients *arg1 = (SplittingStepCoefficients *) 0 ; - SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Free(SplittingStepCoefficients)", return ); - arg1 = (SplittingStepCoefficients)(farg1->cptr); - SplittingStepCoefficients_Free(arg1); + arg1 = (SplittingStepCoefficients *)(farg1); + SplittingStepCoefficients_Destroy(arg1); } diff --git a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 index 13f4e2b7be..00dab7249a 100644 --- a/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_splittingstep_mod.f90 @@ -76,7 +76,7 @@ module farkode_splittingstep_mod ARKODE_SPLITTING_YOSHIDA_8_6_2, ARKODE_MAX_SPLITTING_NUM public :: FSplittingStepCoefficients_Alloc public :: FSplittingStepCoefficients_Create - public :: FSplittingStepCoefficients_Free + public :: FSplittingStepCoefficients_Destroy public :: FSplittingStepCoefficients_Copy public :: FSplittingStepCoefficients_Write public :: FSplittingStepCoefficients_LoadCoefficients @@ -249,11 +249,10 @@ function swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, far type(SwigClassWrapper) :: fresult end function -subroutine swigc_FSplittingStepCoefficients_Free(farg1) & -bind(C, name="_wrap_FSplittingStepCoefficients_Free") +subroutine swigc_FSplittingStepCoefficients_Destroy(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Destroy") use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg1 end subroutine function swigc_FSplittingStepCoefficients_Copy(farg1) & @@ -642,13 +641,13 @@ function FSplittingStepCoefficients_Create(sequential_methods, stages, partition swig_result%swigdata = fresult end function -subroutine FSplittingStepCoefficients_Free(coefficients) +subroutine FSplittingStepCoefficients_Destroy(coefficients) use, intrinsic :: ISO_C_BINDING -class(SplittingStepCoefficientsMem), intent(in) :: coefficients -type(SwigClassWrapper) :: farg1 +type(C_PTR), target, intent(inout) :: coefficients +type(C_PTR) :: farg1 -farg1 = coefficients%swigdata -call swigc_FSplittingStepCoefficients_Free(farg1) +farg1 = c_loc(coefficients) +call swigc_FSplittingStepCoefficients_Destroy(farg1) end subroutine function FSplittingStepCoefficients_Copy(coefficients) & diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.c b/src/arkode/fmod_int64/farkode_splittingstep_mod.c index 413a87802e..792a01a5d6 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.c +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.c @@ -523,12 +523,11 @@ SWIGEXPORT SwigClassWrapper _wrap_FSplittingStepCoefficients_Create(int const *f } -SWIGEXPORT void _wrap_FSplittingStepCoefficients_Free(SwigClassWrapper const *farg1) { - SplittingStepCoefficients arg1 = (SplittingStepCoefficients) 0 ; +SWIGEXPORT void _wrap_FSplittingStepCoefficients_Destroy(void *farg1) { + SplittingStepCoefficients *arg1 = (SplittingStepCoefficients *) 0 ; - SWIG_check_mutable(*farg1, "SplittingStepCoefficients", "SplittingStepCoefficientsMem", "SplittingStepCoefficients_Free(SplittingStepCoefficients)", return ); - arg1 = (SplittingStepCoefficients)(farg1->cptr); - SplittingStepCoefficients_Free(arg1); + arg1 = (SplittingStepCoefficients *)(farg1); + SplittingStepCoefficients_Destroy(arg1); } diff --git a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 index 13f4e2b7be..00dab7249a 100644 --- a/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_splittingstep_mod.f90 @@ -76,7 +76,7 @@ module farkode_splittingstep_mod ARKODE_SPLITTING_YOSHIDA_8_6_2, ARKODE_MAX_SPLITTING_NUM public :: FSplittingStepCoefficients_Alloc public :: FSplittingStepCoefficients_Create - public :: FSplittingStepCoefficients_Free + public :: FSplittingStepCoefficients_Destroy public :: FSplittingStepCoefficients_Copy public :: FSplittingStepCoefficients_Write public :: FSplittingStepCoefficients_LoadCoefficients @@ -249,11 +249,10 @@ function swigc_FSplittingStepCoefficients_Create(farg1, farg2, farg3, farg4, far type(SwigClassWrapper) :: fresult end function -subroutine swigc_FSplittingStepCoefficients_Free(farg1) & -bind(C, name="_wrap_FSplittingStepCoefficients_Free") +subroutine swigc_FSplittingStepCoefficients_Destroy(farg1) & +bind(C, name="_wrap_FSplittingStepCoefficients_Destroy") use, intrinsic :: ISO_C_BINDING -import :: swigclasswrapper -type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg1 end subroutine function swigc_FSplittingStepCoefficients_Copy(farg1) & @@ -642,13 +641,13 @@ function FSplittingStepCoefficients_Create(sequential_methods, stages, partition swig_result%swigdata = fresult end function -subroutine FSplittingStepCoefficients_Free(coefficients) +subroutine FSplittingStepCoefficients_Destroy(coefficients) use, intrinsic :: ISO_C_BINDING -class(SplittingStepCoefficientsMem), intent(in) :: coefficients -type(SwigClassWrapper) :: farg1 +type(C_PTR), target, intent(inout) :: coefficients +type(C_PTR) :: farg1 -farg1 = coefficients%swigdata -call swigc_FSplittingStepCoefficients_Free(farg1) +farg1 = c_loc(coefficients) +call swigc_FSplittingStepCoefficients_Destroy(farg1) end subroutine function FSplittingStepCoefficients_Copy(coefficients) & diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index f3d0bf874b..af2e254860 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -154,10 +154,10 @@ static int test_mixed_directions(const sundials::Context& ctx) ARKodeSetFixedStep(arkode_mem, dt); ARKodeSetInterpolantType(arkode_mem, ARK_INTERP_HERMITE); ARKodeSetMaxNumSteps(arkode_mem, -1); - const auto coefficients = + auto coefficients = SplittingStepCoefficients_LoadCoefficients(ARKODE_SPLITTING_RUTH_3_3_2); SplittingStep_SetCoefficients(arkode_mem, coefficients); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); /* Integrate from 0 to -1 */ auto tret = t0; @@ -251,18 +251,18 @@ static int test_resize(const sundials::Context& ctx) auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); - const auto coefficients = SplittingStepCoefficients_SymmetricParallel(2); + auto coefficients = SplittingStepCoefficients_SymmetricParallel(2); SplittingStep_SetCoefficients(arkode_mem, coefficients); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); /* Integrate from 0 to 0.5 */ auto tret = t0; ARKodeEvolve(arkode_mem, t1, y, &tret, ARK_NORMAL); /* Resize */ - const auto y_new = N_VNew_Serial(2, ctx); + const auto y_new = N_VNew_Serial(2, ctx); N_VGetArrayPointer(y_new)[0] = SUN_RCONST(1.0); - N_NGetArrayPointer(y_new)[1] = N_VGetArrayPointer(y)[0]; + N_VGetArrayPointer(y_new)[1] = N_VGetArrayPointer(y)[0]; N_VDestroy(y); ARKodeResize(arkode_mem, y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); ARKodeResize(parititon_mem[0], y_new, SUN_RCONST(1.0), t1, nullptr, nullptr); @@ -271,7 +271,7 @@ static int test_resize(const sundials::Context& ctx) /* Integrate from 0.5 to 1 */ ARKodeEvolve(arkode_mem, t2, y_new, &tret, ARK_NORMAL); - const auto err = N_VClone(y_new); + const auto err = N_VClone(y_new); N_VGetArrayPointer(err)[0] = std::exp(t1 - t2); N_VGetArrayPointer(err)[1] = std::exp(t0 - t2); N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y_new, err); @@ -385,9 +385,9 @@ static int test_custom_stepper(const sundials::Context& ctx) auto arkode_mem = SplittingStepCreate(steppers, 2, t0, y, ctx); ARKodeSetFixedStep(arkode_mem, dt); - const auto coefficients = SplittingStepCoefficients_SuzukiFractal(2, 6); + auto coefficients = SplittingStepCoefficients_SuzukiFractal(2, 6); SplittingStep_SetCoefficients(arkode_mem, coefficients); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); auto tret = t0; ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c index ba7d863488..751ca96fe2 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c @@ -142,25 +142,25 @@ int main(int argc, char* argv[]) SplittingStepCoefficients_Copy(coefficients); retval += check_coefficients("Lie-Trotter (copy)", coefficients_copy, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - SplittingStepCoefficients_Free(coefficients); - SplittingStepCoefficients_Free(coefficients_copy); + SplittingStepCoefficients_Destroy(&coefficients); + SplittingStepCoefficients_Destroy(&coefficients_copy); coefficients = SplittingStepCoefficients_LoadCoefficients( ARKODE_SPLITTING_LIE_TROTTER_1_1_2); retval += check_coefficients("Lie-Trotter (load by enum)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); coefficients = SplittingStepCoefficients_LoadCoefficientsByName( "ARKODE_SPLITTING_LIE_TROTTER_1_1_2"); retval += check_coefficients("Lie-Trotter (load by name)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); coefficients = SplittingStepCoefficients_LieTrotter(2); retval += check_coefficients("Lie-Trotter (constructor)", coefficients, 1, 1, 2, 1, alpha_lie_trotter, beta_lie_trotter); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); sunrealtype alpha_strang[] = {ONE}; sunrealtype beta_strang[] = {ZERO, ZERO, ZERO, HALF, HALF, ONE, @@ -169,7 +169,7 @@ int main(int argc, char* argv[]) coefficients = SplittingStepCoefficients_Strang(3); retval += check_coefficients("Strang", coefficients, 1, 3, 3, 2, alpha_strang, beta_strang); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); sunrealtype alpha_parallel[] = {ONE, ONE, -ONE}; sunrealtype beta_parallel[] = {ZERO, ZERO, ONE, ZERO, ZERO, ZERO, @@ -178,7 +178,7 @@ int main(int argc, char* argv[]) coefficients = SplittingStepCoefficients_Parallel(2); retval += check_coefficients("Parallel", coefficients, 3, 1, 2, 1, alpha_parallel, beta_parallel); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); sunrealtype alpha_symmetric_parallel[] = {HALF, HALF, -ONE}; sunrealtype beta_symmetric_parallel[] = {ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, @@ -189,7 +189,7 @@ int main(int argc, char* argv[]) coefficients = SplittingStepCoefficients_SymmetricParallel(3); retval += check_coefficients("Symmetric Parallel", coefficients, 2, 3, 3, 2, alpha_symmetric_parallel, beta_symmetric_parallel); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); sunrealtype alpha_suzuki_fractal[] = {ONE}; sunrealtype beta_suzuki_fractal[] = {ZERO, @@ -210,7 +210,7 @@ int main(int argc, char* argv[]) coefficients = SplittingStepCoefficients_SuzukiFractal(2, 4); retval += check_coefficients("Suzuki Fractal", coefficients, 1, 6, 2, 4, alpha_suzuki_fractal, beta_suzuki_fractal); - SplittingStepCoefficients_Free(coefficients); + SplittingStepCoefficients_Destroy(&coefficients); printf("%d test failures\n", retval); From 2b4a8e627a074bed79282b4376f061b3f12be6f9 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 13:45:27 -0800 Subject: [PATCH 162/180] Move initialization of beta to avoid memory leak --- src/arkode/arkode_splittingstep_coefficients.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arkode/arkode_splittingstep_coefficients.c b/src/arkode/arkode_splittingstep_coefficients.c index afa01ad0b5..f0e8a743c5 100644 --- a/src/arkode/arkode_splittingstep_coefficients.c +++ b/src/arkode/arkode_splittingstep_coefficients.c @@ -67,6 +67,11 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( return NULL; } + for (int i = 0; i < sequential_methods; i++) + { + coefficients->beta[i] = &beta_cols[i * (stages + 1)]; + } + /* Contiguous memory to store the beta tensor */ sunrealtype* beta_mem = (sunrealtype*)calloc(sequential_methods * (stages + 1) * partitions, @@ -80,7 +85,6 @@ SplittingStepCoefficients SplittingStepCoefficients_Alloc( /* Set pointers into the beta tensor */ for (int i = 0; i < sequential_methods; i++) { - coefficients->beta[i] = &beta_cols[i * (stages + 1)]; for (int j = 0; j <= stages; j++) { coefficients->beta[i][j] = &beta_mem[(i * (stages + 1) + j) * partitions]; From b9d04ba670d9d0e3322ce34c8069e1a8e738858d Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 14:00:22 -0800 Subject: [PATCH 163/180] Make splittingstep skeleton not particular to ARKStep --- .../source/Usage/SplittingStep/Skeleton.rst | 25 ++++++++----------- .../Usage/SplittingStep/User_callable.rst | 10 ++++---- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index be4db315c3..3c56449892 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -37,15 +37,12 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. #. Create a stepper object for each problem partition - * If using ARKStep as an partition integrator, create the ARKStep object with - :c:func:`ARKStepCreate` and configure the integrator as desired for - evolving the partition. See sections :numref:`ARKODE.Usage.Skeleton`, - :numref:`ARKODE.Usage.OptionalInputs`, and - :numref:`ARKODE.Usage.ARKStep.OptionalInputs` for details on configuring - ARKStep. + * If using an ARKODE stepper module as an partition integrator, create and + configure the stepper as normal following the steps detailed in the section + for the desired stepper. - Once the ARKStep object is setup, create a :c:type:`SUNStepper` object with - :c:func:`ARKodeCreateSUNStepper`. + Once the ARKODE stepper object is setup, create a :c:type:`SUNStepper` + object with :c:func:`ARKodeCreateSUNStepper`. * If supplying a user-defined partition integrator, create the :c:type:`SUNStepper` object as described in section @@ -53,12 +50,12 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. .. note:: - When using ARKStep as a partition integrator it is the user's responsibility - to create and configure the integrator. User-specified options regarding - how the integration should be performed (e.g., adaptive vs. fixed time - step, explicit/implicit/ImEx partitioning, algebraic solvers, etc.) will - be respected during evolution of a partition during SplittingStep - integration. + When using ARKODE for partition integrators, it is the user's + responsibility to create and configure the integrator. User-specified + options regarding how the integration should be performed (e.g., adaptive + vs. fixed time step, explicit/implicit/ImEx partitioning, algebraic + solvers, etc.) will be respected during evolution of a partition during + SplittingStep integration. If a *user_data* pointer needs to be passed to user functions called by an inner integrator then it should be attached here by calling diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index f8694ba1bc..5c0e88eca0 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -58,18 +58,18 @@ SplittingStep initialization functions /* inner ARKODE objects for integrating individual partitions */ void *partition_mem[] = {NULL, NULL}; - /* SUNSteppers to wrap the inner ARKStep objects */ + /* SUNSteppers to wrap the inner ARKODE objects */ SUNStepper steppers[] = {NULL, NULL}; - /* create ARKStep objects, setting right-hand side functions and the + /* create ARKODE objects, setting right-hand side functions and the initial condition */ - partition_mem[0] = ARKStepCreate(fe1, fi1, t0, y0, sunctx); + partition_mem[0] = ERKStepCreate(f1, t0, y0, sunctx); partition_mem[1] = ARKStepCreate(fe2, fi2, t0, y0, sunctx); - /* setup ARKStep */ + /* setup ARKODE objects */ . . . - /* create SUNStepper wrappers for the ARKStep memory blocks */ + /* create SUNStepper wrappers for the ARKODE memory blocks */ flag = ARKodeCreateSUNStepper(partition_mem[0], &stepper[0]); flag = ARKodeCreateSUNStepper(partition_mem[1], &stepper[1]); From 7748696afa92456681582f06598794d6c1fb823a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 14:07:38 -0800 Subject: [PATCH 164/180] Remove inner and outer terms --- .../source/Usage/SplittingStep/Skeleton.rst | 23 ++++++++++--------- .../SplittingStepCoefficients.rst | 4 ++-- .../Usage/SplittingStep/User_callable.rst | 4 ++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst index 3c56449892..7ed6772409 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/Skeleton.rst @@ -58,19 +58,20 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. SplittingStep integration. If a *user_data* pointer needs to be passed to user functions called by - an inner integrator then it should be attached here by calling + a partition integrator then it should be attached here by calling :c:func:`ARKodeSetUserData()`. This *user_data* pointer will only be - passed to user-supplied functions that are attached to an inner + passed to user-supplied functions that are attached to a partition integrator. To supply a *user_data* pointer to user-supplied functions - called by the outer integrator the desired pointer should be attached by - calling :c:func:`ARKodeSetUserData()` after creating the SplittingStep - memory below. The *user_data* pointers attached to the inner and outer - integrators may be the same or different depending on what is required by - the user code. + called by the SplittingStep integrator, the desired pointer should be + attached by calling :c:func:`ARKodeSetUserData()` after creating the + SplittingStep memory below. The *user_data* pointers attached to the + partition and SplittingStep integrators may be the same or different + depending on what is required by the user code. - Specifying a rootfinding problem for a partitiona integrator is not supported. - Rootfinding problems should be created and initialized with SplittingStep. - See the steps below and :c:func:`ARKodeRootInit()` for more details. + Specifying a rootfinding problem for a partition integrator is not + supported. Rootfinding problems should be created and initialized with + SplittingStep. See the steps below and :c:func:`ARKodeRootInit()` for more + details. #. Create a SplittingStep object @@ -104,7 +105,7 @@ skeleton program presented in :numref:`ARKODE.Usage.Skeleton` are *italicized*. object. * Call :c:func:`ARKodeFree` to free the memory allocated for the - SplittingStep outer integration object. + SplittingStep integration object. #. *Free the SUNContext object* diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 132f8572dd..c0cab3c22b 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -46,7 +46,7 @@ stored in a :c:type:`SplittingStepCoefficients` object which is a pointer to a .. c:member:: sunrealtype ***beta - A three-dimensional array containing the time nodes of the inner integrations. + A three-dimensional array containing the time nodes of the partition integrations. The array has dimensions ``[sequential_methods][stages+1][partitions]``. .. c:member:: int sequential_methods @@ -332,7 +332,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. splitting solution. :param beta: An array of length ``sequential_methods * (stages+1) * partitions`` containing the time nodes - of the inner integrations in the C order + of the partition integrations in the C order .. math:: \beta_{1,0,1}, \dots, \beta_{1,0,P}, diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index 5c0e88eca0..d33ab12293 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -55,10 +55,10 @@ SplittingStep initialization functions .. code-block:: C - /* inner ARKODE objects for integrating individual partitions */ + /* ARKODE objects for integrating individual partitions */ void *partition_mem[] = {NULL, NULL}; - /* SUNSteppers to wrap the inner ARKODE objects */ + /* SUNSteppers to wrap the ARKODE objects */ SUNStepper steppers[] = {NULL, NULL}; /* create ARKODE objects, setting right-hand side functions and the From 192cc48f872afcef84bbc3d5b3c2048a486fc32a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Tue, 12 Nov 2024 14:20:41 -0800 Subject: [PATCH 165/180] Remove unnecessary headers --- src/arkode/arkode_forcingstep.c | 1 - src/arkode/arkode_splittingstep.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index 7360013391..f4590cf8cc 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -14,7 +14,6 @@ * This is the implementation file for ARKODE's forcing method *--------------------------------------------------------------*/ -#include #include #include diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index a0be1914f4..e99b9656a4 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -15,7 +15,6 @@ * splitting module *--------------------------------------------------------------*/ -#include #include #include From 4a93d50b366f0ce8a3a56662dfdeee43ae2f0a0a Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 13 Nov 2024 15:34:52 -0800 Subject: [PATCH 166/180] Mention splitting and forcing method in SUNStepper docs --- CHANGELOG.md | 8 ++++---- doc/shared/RecentChanges.rst | 9 ++++++--- doc/shared/sunstepper/SUNStepper_Implementing.rst | 6 ++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81e36b29c7..af9f170cf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,10 @@ Added the `ARKodeSetStepDirection` and `ARKodeGetStepDirection` functions to change and query the direction of integration. Added the `SUNStepper` base class to represent a generic solution procedure for -IVPs. A SUNStepper can be created from an ARKODE memory block with the new -function `ARKodeCreateSUNStepper`. To enable interoperability with -`MRIStepInnerStepper`, the function `MRIStepInnerStepper_CreateFromSUNStepper` -was added. +IVPs. This is used by the SplittingStep and ForcingStep modules of ARKODE. A +SUNStepper can be created from an ARKODE memory block with the new function +`ARKodeCreateSUNStepper`. To enable interoperability with `MRIStepInnerStepper`, +the function `MRIStepInnerStepper_CreateFromSUNStepper` was added. The following DIRK schemes now have coefficients accurate to quad precision: * `ARKODE_BILLINGTON_3_3_2` diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index ac556d3b1e..3c253d97df 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -12,9 +12,12 @@ Added the :c:func:`ARKodeSetStepDirection` and :c:func:`ARKodeGetStepDirection` functions to change and query the direction of integration. Added the :c:type:`SUNStepper` base class to represent a generic solution -procedure for IVPs. A SUNStepper can be created from an ARKODE memory block with -the new function :c:func:`ARKodeCreateSUNStepper`. To enable interoperability -with :c:type:`MRIStepInnerStepper`, the function +procedure for IVPs. This is used by the +:ref:`SplittingStep ` and +:ref:`ForcingStep ` modules of ARKODE. A SUNStepper +can be created from an ARKODE memory block with the new function +:c:func:`ARKodeCreateSUNStepper`. To enable interoperability with +:c:type:`MRIStepInnerStepper`, the function :c:func:`MRIStepInnerStepper_CreateFromSUNStepper` was added. The following DIRK schemes now have coefficients accurate to quad precision: diff --git a/doc/shared/sunstepper/SUNStepper_Implementing.rst b/doc/shared/sunstepper/SUNStepper_Implementing.rst index 1f57de65de..dda9d11ade 100644 --- a/doc/shared/sunstepper/SUNStepper_Implementing.rst +++ b/doc/shared/sunstepper/SUNStepper_Implementing.rst @@ -40,7 +40,8 @@ To create a SUNStepper implementation: recorded with :c:func:`SUNStepper_SetLastFlag`. #. In the user code, before creating the outer memory structure that uses the - :c:type:`SUNStepper`, do the following: + :c:type:`SUNStepper`, e.g., with :c:func:`SplittingStepCreate` or + :c:func:`ForcingStepCreate`, do the following: #. Create a :c:type:`SUNStepper` object with :c:func:`SUNStepper_Create`. @@ -51,4 +52,5 @@ To create a SUNStepper implementation: #. Attach the member function implementations using the functions described in :numref:`SUNStepper.Description.BaseMethods.AttachFunctions`. -#. Attach the :c:type:`SUNStepper` object to the outer memory structure. +#. Attach the :c:type:`SUNStepper` object to the outer memory structure, e.g., + with :c:func:`SplittingStepCreate` or :c:func:`ForcingStepCreate`. From 9ea4ef41aeae9c868987f0c1f263c3a0136194ff Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 13 Nov 2024 16:11:15 -0800 Subject: [PATCH 167/180] Update beta to be 1 indexed for stages --- doc/arkode/guide/source/Mathematics.rst | 28 +++++++++++-------- .../SplittingStepCoefficients.rst | 21 +++++++------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 883d8871c1..cb29e12cde 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -679,8 +679,8 @@ The following algorithmic procedure is used in the Splitting-Step module: #. For :math:`k = 1, \dots, P` do: - #. Let :math:`t_{\text{start}} = t_{n-1} + \beta_{i,j-1,k} h_n` and - :math:`t_{\text{end}} = t_{n-1} + \beta_{i,j,k} h_n`. + #. Let :math:`t_{\text{start}} = t_{n-1} + \beta_{i,j,k} h_n` and + :math:`t_{\text{end}} = t_{n-1} + \beta_{i,j+1,k} h_n`. #. Let :math:`v(t_{\text{start}}) = y_{n,i}`. @@ -694,20 +694,26 @@ The following algorithmic procedure is used in the Splitting-Step module: Here, :math:`s` denotes the number of stages, while :math:`r` denotes the number of sequential methods within the overall operator splitting scheme. The sequential methods have independent flows which are linearly combined to produce -the next step. The real coefficients :math:`\alpha \in \mathbb{R}^{r}` and :math:`\beta \in \mathbb{R}^{r \times s + 1 \times P}` -determine the particular scheme and properties such as the order of accuracy. +the next step. The real coefficients :math:`\alpha \in \mathbb{R}^{r}` and +:math:`\beta \in \mathbb{R}^{r \times (s + 1) \times P}` determine the +particular scheme and properties such as the order of accuracy. An alternative representation of the SplittingStep solution is .. math:: - y_n = \sum_{i=1}^P \alpha_i \left( \phi^P_{\gamma_{i,1,P} h} \circ - \phi^{P-1}_{\gamma_{i,1,P-1} h} \circ \dots \circ \phi^1_{\gamma_{i,1,1} h} - \circ \phi^P_{\gamma_{i,2,P} h} \circ \dots \circ \phi^P_{\gamma_{i,s,P} h} - \circ \dots \circ \phi^1_{\gamma_{i,s,1} h} \right) - (y_{n-1}) + y_n = \sum_{i=1}^P \alpha_i \left( + \phi^P_{\gamma_{i,s,P} h_n} \circ + \phi^{P-1}_{\gamma_{i,s,P-1} h_n} \circ \dots \circ + \phi^{1}_{\gamma_{i,s,1} h_n} \circ + \phi^P_{\gamma_{i,s-1,P} h_n} \circ \dots \circ + \phi^1_{\gamma_{i,s-1,1} h_n} \circ \dots \circ + \phi^P_{\gamma_{i,1,P} h_n} \circ \dots \circ + \phi^1_{\gamma_{i,1,1} h_n} + \right)(y_{n-1}) -where :math:`\gamma_{i,j,k} = \beta_{i,j,k} - \beta_{i,j-1,k}` is the scaling factor for the step size, :math:`h`, and -:math:`\phi^k_{h}` is the flow map for partition :math:`k`: +where :math:`\gamma_{i,j,k} = \beta_{i,j+1,k} - \beta_{i,j,k}` is the scaling +factor for the step size, :math:`h_n`, and :math:`\phi^k_{h}` is the flow map +for partition :math:`k`: .. math:: \phi^k_{h}(y_{n_1}) = v(t_n), diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index c0cab3c22b..8879aebca2 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -320,31 +320,32 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Create(int sequential_methods, int stages, int partitions, int order, sunrealtype* alpha, sunrealtype* beta) - Allocates a :c:type:`SplittingStepCoefficients` object and fills it with the given values. + Allocates a :c:type:`SplittingStepCoefficients` object and fills it with the + given values. :param sequential_methods: The number of sequential methods, :math:`r \geq 1` combined to produce the overall operator splitting solution. :param stages: The number of stages, :math:`s \geq 1`. :param partitions: The number of partitions, :math:`P > 1` in the IVP. :param order: The method order of accuracy. - :param alpha: An array of length ``sequential_methods`` containing the - weight of each sequential method used to produce the overall operator - splitting solution. + :param alpha: An array of length ``sequential_methods`` containing the weight + of each sequential method used to produce the overall operator splitting + solution. :param beta: An array of length ``sequential_methods * (stages+1) * partitions`` containing the time nodes of the partition integrations in the C order .. math:: - \beta_{1,0,1}, \dots, \beta_{1,0,P}, + \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, - \beta_{1,s,1}, \dots, \beta_{1,s,P} - \beta_{2,0,1}, \dots, \beta_{2,0,P} + \beta_{1,s+1,1}, \dots, \beta_{1,s+1,P} + \beta_{2,1,1}, \dots, \beta_{2,1,P} \dots, - \beta_{2,s,1}, \dots, \beta_{2,s,P} + \beta_{2,s+1,1}, \dots, \beta_{2,s+1,P} \dots, - \beta_{r,0,1}, \dots, \beta_{r,0,P} + \beta_{r,1,1}, \dots, \beta_{r,1,P} \dots, - \beta_{r,s,1}, \dots, \beta_{r,s,P} + \beta_{r,s+1,1}, \dots, \beta_{r,s+1,P} :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error From 9848af8537c8a943ffd44b9db7fa81af5445dcc5 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 13 Nov 2024 17:22:09 -0800 Subject: [PATCH 168/180] Add Lie-Trotter and Strang examples to math considerations --- doc/arkode/guide/source/Mathematics.rst | 53 ++++++++- .../SplittingStepCoefficients.rst | 108 ++++++++---------- doc/shared/sundials.bib | 10 ++ 3 files changed, 109 insertions(+), 62 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index cb29e12cde..3549bb92a5 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -484,7 +484,7 @@ ForcingStep is given by \dot{v}_2 &= f_1^* + f_2(t, v_2), \\ y_n &= v_2(t_n). -Like a Lie-Trotter method from +Like a Lie--Trotter method from :ref:`SplittingStep `, the partitions are evolved through a sequence of inner IVPs which can be solved with an arbitrary integrator or exact solution procedure. However, the IVP for partition two @@ -716,13 +716,58 @@ factor for the step size, :math:`h_n`, and :math:`\phi^k_{h}` is the flow map for partition :math:`k`: .. math:: - \phi^k_{h}(y_{n_1}) = v(t_n), + \phi^k_{h}(y_{n-1}) = v(t_n), \quad \begin{cases} v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f_k(t, v). \end{cases} -SplittingStep provides standard operator splitting methods such as Lie-Trotter -and Strang splitting, as well as schemes of arbitrarily high order. +For example, the Lie--Trotter splitting :cite:p:`BCM:24`, given by + +.. math:: + y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} + \circ \dots \circ \phi^1_{h} \right) (y_{n-1}), + :label: ARKODE_Lie-Trotter + +is a first order, one-stage, sequential operator splitting method suitable for +any number of partitions. Its coefficients are + +.. math:: + \alpha_1 &= 1, \\ + \beta_{1,j,k} &= \begin{cases} + 0, & j = 1, \\ + 1, & j = 2, + \end{cases} \qquad + j = 1, 2, \quad + k = 1, \dots, P. + +Higher order operator splitting methods are often constructed by composing the +Lie--Trotter splitting with its adjoint: + +.. math:: + L^*_h = L^{-1}_{-h} + = \phi^1_{h} \circ \phi^{2}_{h} \circ \dots \circ \phi^{P}_{h}. + :label: ARKODE_Lie-Trotter_adjoint + +This is the case for the Strang splitting :cite:p:`Strang:68` + +.. math:: + y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), + :label: ARKODE_Strang + +which has :math:`P` stages and coefficients + +.. math:: + \alpha_1 &= 1, \\ + \beta_{1,j,k} &= \begin{cases} + 0, & j = 1, \\ + 1, & j + k > P + 1, \\ + \frac{1}{2}, & \text{otherwise}, + \end{cases} \qquad + j = 1, \dots, P+1, \quad + k = 1, \dots, P. + +SplittingStep provides standard operator splitting methods such as the +Lie--Trotter and Strang splitting, as well as schemes of arbitrarily high order. Alternatively, users may construct their own coefficients (see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`). Generally, methods of order three and higher with real coefficients require backward diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 8879aebca2..91f46ce31e 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -80,41 +80,41 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. _ARKODE.Usage.SplittingStep.SplittingStepCoefficients.Functions.Table: .. table:: SplittingStepCoefficients functions - +--------------------------------------------------------------+-------------------------------------------------------------+ - | Function name | Description | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_LoadCoefficients()` | Load a pre-defined SplittingStepCoefficients by ID | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_LoadCoefficientsByName()` | Load a pre-defined SplittingStepCoefficients by name | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_IDToName()` | Convert a pre-defined SplittingStepCoefficients to its name | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_LieTrotter()` | Create a Lie-Trotter splitting method | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Strang()` | Create a Strang splitting method | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_SymmetricParallel()` | Create a symmetrization of the Lie-Trotter splitting method | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_ThirdOrderSuzuki()` | Create a third order composition method of Suzuki | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_TripleJump()` | Create an arbitrary order, three-jump composition method | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_SuzukiFractal()` | Create an arbitrary order, five-jump composition method | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Alloc()` | Allocate an empty :c:type:`SplittingStepCoefficients` | - | | object | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Create()` | Create a new :c:type:`SplittingStepCoefficients` object | - | | from coefficient arrays | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a :c:type:`SplittingStepCoefficients` | - | | object | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Destroy()` | Deallocate a :c:type:`SplittingStepCoefficients` object | - +--------------------------------------------------------------+-------------------------------------------------------------+ - | :c:func:`SplittingStepCoefficients_Write()` | Write the :c:type:`SplittingStepCoefficients` object to an | - | | output file | - +--------------------------------------------------------------+-------------------------------------------------------------+ + +--------------------------------------------------------------+--------------------------------------------------------------+ + | Function name | Description | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LoadCoefficients()` | Load a pre-defined SplittingStepCoefficients by ID | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LoadCoefficientsByName()` | Load a pre-defined SplittingStepCoefficients by name | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_IDToName()` | Convert a pre-defined SplittingStepCoefficients to its name | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_LieTrotter()` | Create a Lie--Trotter splitting method | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Strang()` | Create a Strang splitting method | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_SymmetricParallel()` | Create a symmetrization of the Lie--Trotter splitting method | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_ThirdOrderSuzuki()` | Create a third order composition method of Suzuki | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_TripleJump()` | Create an arbitrary order, three-jump composition method | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_SuzukiFractal()` | Create an arbitrary order, five-jump composition method | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Alloc()` | Allocate an empty :c:type:`SplittingStepCoefficients` | + | | object | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Create()` | Create a new :c:type:`SplittingStepCoefficients` object | + | | from coefficient arrays | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Copy()` | Create a copy of a :c:type:`SplittingStepCoefficients` | + | | object | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Destroy()` | Deallocate a :c:type:`SplittingStepCoefficients` object | + +--------------------------------------------------------------+--------------------------------------------------------------+ + | :c:func:`SplittingStepCoefficients_Write()` | Write the :c:type:`SplittingStepCoefficients` object to an | + | | output file | + +--------------------------------------------------------------+--------------------------------------------------------------+ .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_LoadCoefficients(ARKODE_SplittingCoefficientsID method) @@ -165,11 +165,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_LieTrotter(int partitions) - Create the coefficients for the first order Lie-Trotter splitting - - .. math:: - y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} - \circ \dots \circ \phi^1_{h} \right) (y_{n-1}). + Create the coefficients for the first order Lie--Trotter splitting + :eq:`ARKODE_Lie-Trotter`. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -182,12 +179,7 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_Strang(int partitions) Create the coefficients for the second order Strang splitting - - .. math:: - y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), - - where :math:`L_h` is the Lie-Trotter splitting and - :math:`L^*_h = L^{-1}_{-h}` is its adjoint. + :cite:p:`Strang:68` :eq:`ARKODE_Strang`. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -215,14 +207,14 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. c:function:: SplittingStepCoefficients SplittingStepCoefficients_SymmetricParallel(int partitions) - Create the coefficients for the second order, symmetrized Lie-Trotter + Create the coefficients for the second order, symmetrized Lie--Trotter splitting :cite:p:`Strang:63` .. math:: y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), - where :math:`L_h` is the Lie-Trotter splitting and - :math:`L^*_h = L^{-1}_{-h}` is its adjoint. + where :math:`L_h` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` and + :math:`L^*_h` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -240,8 +232,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n = \left( L_{p_1 h} \circ L^*_{p_2 h} \circ L_{p_3 h} \circ L^*_{p_4 h} \circ L_{p_5 h} \right) (y_{n-1}), - where :math:`L_h` is the Lie-Trotter splitting and - :math:`L^*_h = L^{-1}_{-h}` is its adjoint. The parameters + where :math:`L_h` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` and + :math:`L^*_h` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. The parameters :math:`p_1, \dots, p_5` are selected to give third order. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. @@ -265,8 +257,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n &= T_h^{[\mathrm{order}]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting and :math:`\gamma_1` is - selected to increase the order by two each recursion. + where :math:`S` is the Strang splitting :eq:`ARKODE_Strang` and + :math:`\gamma_1` is selected to increase the order by two each recursion. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :param order: A positive even number for the method order of accuracy. @@ -291,8 +283,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. y_n &= Q_h^{[\mathrm{order}]}(y_{n-1}), \end{align*} - where :math:`S` is the Strang splitting and :math:`\gamma_1` is - selected to increase the order by two each recursion. + where :math:`S` is the Strang splitting :eq:`ARKODE_Strang` and + :math:`\gamma_1` is selected to increase the order by two each recursion. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :param order: A positive even number for the method order of accuracy. @@ -430,9 +422,9 @@ with values specified for each method below (e.g., Default Operator Splitting Coefficients ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The default SplittingStep coefficients are Lie-Trotter. If a particular order is -requested with :c:func:`ARKodeSetOrder`, the following are the default for each -order +The default SplittingStep coefficients are Lie--Trotter. If a particular order +is requested with :c:func:`ARKodeSetOrder`, the following are the default for +each order .. table:: Default operator splitting coefficients by order. diff --git a/doc/shared/sundials.bib b/doc/shared/sundials.bib index 7902268178..fb587c18f3 100644 --- a/doc/shared/sundials.bib +++ b/doc/shared/sundials.bib @@ -1721,6 +1721,16 @@ @article{Billington:83 year = {1983} } +@article{BCM:24, + title={Splitting methods for differential equations}, + volume={33}, + DOI={10.1017/S0962492923000077}, + journal={Acta Numerica}, + author={Blanes, Sergio and Casas, Fernando and Murua, Ander}, + year={2024}, + pages={1–161} +} + @article{Bogacki:89, author = {Bogacki, P. and Shampine, L.F.}, journal = {Applied Mathematics Letters}, From 1accd453522f0f76586a7322950210f7a5d0abe1 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Wed, 13 Nov 2024 17:54:31 -0800 Subject: [PATCH 169/180] Remove inner and outer terms from docs --- doc/arkode/guide/source/Mathematics.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 3549bb92a5..f62b769ed7 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -491,8 +491,8 @@ integrator or exact solution procedure. However, the IVP for partition two includes a "forcing" or "tendency" term :math:`f_1^*` to strengthen the coupling. This coupling leads to a first order method provided :math:`v_1` and :math:`v_2` are integrated to at least first order accuracy. Currently, a fixed -time step must be specified for the outer ForcingStep, but inner integrators are -free to use adaptive time steps. +time step must be specified for the overall ForcingStep integrator, but +partition integrators are free to use adaptive time steps. .. _ARKODE.Mathematics.MRIStep: @@ -772,8 +772,8 @@ Alternatively, users may construct their own coefficients (see :numref:`ARKODE.Usage.SplittingStep.SplittingStepCoefficients`). Generally, methods of order three and higher with real coefficients require backward integration, i.e., there exist negative :math:`\gamma_{i,j,k}` coefficients. -Currently, a fixed time step must be specified for the outer SplittingStep, but -inner integrators are free to use adaptive time steps. +Currently, a fixed time step must be specified for the overall SplittingStep +integrator, but partition integrators are free to use adaptive time steps. .. _ARKODE.Mathematics.SPRKStep: From d05b9c29b74b256b3b15a3d3dbbab1cc9df85325 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 10:48:48 -0800 Subject: [PATCH 170/180] Add missing subscripts to time step --- doc/arkode/guide/source/Mathematics.rst | 14 ++--- .../SplittingStepCoefficients.rst | 53 ++++++++++--------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index f62b769ed7..fdcb29bc70 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -712,11 +712,11 @@ An alternative representation of the SplittingStep solution is \right)(y_{n-1}) where :math:`\gamma_{i,j,k} = \beta_{i,j+1,k} - \beta_{i,j,k}` is the scaling -factor for the step size, :math:`h_n`, and :math:`\phi^k_{h}` is the flow map +factor for the step size, :math:`h_n`, and :math:`\phi^k_{h_n}` is the flow map for partition :math:`k`: .. math:: - \phi^k_{h}(y_{n-1}) = v(t_n), + \phi^k_{h_n}(y_{n-1}) = v(t_n), \quad \begin{cases} v(t_{n-1}) = y_{n-1}, \\ \dot{v} = f_k(t, v). \end{cases} @@ -724,8 +724,8 @@ for partition :math:`k`: For example, the Lie--Trotter splitting :cite:p:`BCM:24`, given by .. math:: - y_n = L_h(y_{n-1}) = \left( \phi^P_{h} \circ \phi^{P-1}_{h} - \circ \dots \circ \phi^1_{h} \right) (y_{n-1}), + y_n = L_{h_n}(y_{n-1}) = \left( \phi^P_{h_n} \circ \phi^{P-1}_{h_n} + \circ \dots \circ \phi^1_{h_n} \right) (y_{n-1}), :label: ARKODE_Lie-Trotter is a first order, one-stage, sequential operator splitting method suitable for @@ -744,14 +744,14 @@ Higher order operator splitting methods are often constructed by composing the Lie--Trotter splitting with its adjoint: .. math:: - L^*_h = L^{-1}_{-h} - = \phi^1_{h} \circ \phi^{2}_{h} \circ \dots \circ \phi^{P}_{h}. + L^*_{h_n} = L^{-1}_{-h_n} + = \phi^1_{h_n} \circ \phi^{2}_{h_n} \circ \dots \circ \phi^{P}_{h_n}. :label: ARKODE_Lie-Trotter_adjoint This is the case for the Strang splitting :cite:p:`Strang:68` .. math:: - y_n = S_h(y_{n-1}) = \left( L^*_{h/2} \circ L_{h/2} \right) (y_{n-1}), + y_n = S_{h_n}(y_{n-1}) = \left( L^*_{h_n/2} \circ L_{h_n/2} \right)(y_{n-1}), :label: ARKODE_Strang which has :math:`P` stages and coefficients diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 91f46ce31e..70a7983f25 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -194,8 +194,8 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Create the coefficients for the first order parallel splitting method .. math:: - y_n = \phi^1_h(y_{n-1}) + \phi^2_h(y_{n-1}) + \dots + \phi^P(y_{n-1}) + - (1 - P) y_{n-1}. + y_n = \phi^1_{h_n}(y_{n-1}) + \phi^2_{h_n}(y_{n-1}) + \dots + + \phi^P_{h_n}(y_{n-1}) + (1 - P) y_{n-1}. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -211,10 +211,10 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. splitting :cite:p:`Strang:63` .. math:: - y_n = \frac{1}{2} \left( L_h(y_{n-1}) + L^*_h(y_{n-1}) \right), + y_n = \frac{1}{2} \left( L_{h_n}(y_{n-1}) + L^*_{h_n}(y_{n-1}) \right), - where :math:`L_h` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` and - :math:`L^*_h` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. + where :math:`L_{h_n}` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` + and :math:`L^*_{h_n}` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -229,12 +229,12 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Create the coefficients for a splitting method of Suzuki :cite:p:`Suzuki:92` .. math:: - y_n = \left( L_{p_1 h} \circ L^*_{p_2 h} \circ L_{p_3 h} \circ L^*_{p_4 h} - \circ L_{p_5 h} \right) (y_{n-1}), + y_n = \left( L_{p_1 h_n} \circ L^*_{p_2 h_n} \circ L_{p_3 h_n} + \circ L^*_{p_4 h_n} \circ L_{p_5 h_n} \right) (y_{n-1}), - where :math:`L_h` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` and - :math:`L^*_h` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. The parameters - :math:`p_1, \dots, p_5` are selected to give third order. + where :math:`L_{h_n}` is the Lie--Trotter splitting :eq:`ARKODE_Lie-Trotter` + and :math:`L^*_{h_n}` is its adjoint :eq:`ARKODE_Lie-Trotter_adjoint`. The + parameters :math:`p_1, \dots, p_5` are selected to give third order. :param partitions: The number of partitions, :math:`P > 1`, in the IVP. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a @@ -251,10 +251,10 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. math:: \begin{align*} - T_h^{[2]} &= S_h, \\ - T_h^{[i+2]} &= T_{\gamma_1 h}^{[i]} \circ T_{(1 - 2 \gamma_1) h}^{[i]} - \circ T_{\gamma_1 h}^{[i]}, \\ - y_n &= T_h^{[\mathrm{order}]}(y_{n-1}), + T_{h_n}^{[2]} &= S_{h_n}, \\ + T_{h_n}^{[i+2]} &= T_{\gamma_1 h_n}^{[i]} \circ + T_{(1 - 2 \gamma_1) h_n}^{[i]} \circ T_{\gamma_1 h_n}^{[i]}, \\ + y_n &= T_{h_n}^{[\mathrm{order}]}(y_{n-1}), \end{align*} where :math:`S` is the Strang splitting :eq:`ARKODE_Strang` and @@ -276,11 +276,11 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. .. math:: \begin{align*} - Q_h^{[2]} &= S_h, \\ - Q_h^{[i+2]} &= Q_{\gamma_1 h}^{[i]} \circ Q_{\gamma_1 h}^{[i]} \circ - Q_{(1 - 4 \gamma_1) h}^i \circ Q_{\gamma_1 h}^{[i]} \circ - Q_{\gamma_1 h}^{[i]}, \\ - y_n &= Q_h^{[\mathrm{order}]}(y_{n-1}), + Q_{h_n}^{[2]} &= S_{h_n}, \\ + Q_{h_n}^{[i+2]} &= Q_{\gamma_1 h_n}^{[i]} \circ + Q_{\gamma_1 h_n}^{[i]} \circ Q_{(1 - 4 \gamma_1) h_n}^i \circ + Q_{\gamma_1 h_n}^{[i]} \circ Q_{\gamma_1 h_n}^{[i]}, \\ + y_n &= Q_{h_n}^{[\mathrm{order}]}(y_{n-1}), \end{align*} where :math:`S` is the Strang splitting :eq:`ARKODE_Strang` and @@ -328,16 +328,17 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. of the partition integrations in the C order .. math:: - \beta_{1,1,1}, \dots, \beta_{1,1,P}, + & \beta_{1,1,1}, \dots, \beta_{1,1,P}, \dots, - \beta_{1,s+1,1}, \dots, \beta_{1,s+1,P} - \beta_{2,1,1}, \dots, \beta_{2,1,P} + \beta_{1,s+1,1}, \dots, \beta_{1,s+1,P}, + \dots, \\ + & \beta_{2,1,1}, \dots, \beta_{2,1,P}, \dots, - \beta_{2,s+1,1}, \dots, \beta_{2,s+1,P} + \beta_{2,s+1,1}, \dots, \beta_{2,s+1,P}, + \dots, \\ + & \beta_{r,1,1}, \dots, \beta_{r,1,P}, \dots, - \beta_{r,1,1}, \dots, \beta_{r,1,P} - \dots, - \beta_{r,s+1,1}, \dots, \beta_{r,s+1,P} + \beta_{r,s+1,1}, \dots, \beta_{r,s+1,P}. :return: A :c:type:`SplittingStepCoefficients` structure if successful or a ``NULL`` pointer if an argument was invalid or an allocation error From d148f2ed91153f88aab8e059970013ed8bb70551 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 10:59:42 -0800 Subject: [PATCH 171/180] Fix header level --- doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst index d33ab12293..f3ef50ad75 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/User_callable.rst @@ -84,7 +84,7 @@ SplittingStep initialization functions Optional inputs for IVP method selection -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------------------- .. c:function:: int SplittingStep_SetCoefficients(void* arkode_mem, SplittingStepCoefficients coefficients) From 0bc2b303c660e7a9a2d8c1fd6b62537e3b2290f6 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 11:04:45 -0800 Subject: [PATCH 172/180] Move note for SplittingStepCoefficients_Write into param description --- .../Usage/SplittingStep/SplittingStepCoefficients.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst index 70a7983f25..67ed3dac13 100644 --- a/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst +++ b/doc/arkode/guide/source/Usage/SplittingStep/SplittingStepCoefficients.rst @@ -372,12 +372,9 @@ integer constants are defined ``arkode/arkode_splittingstep.h``. Write the splitting coefficients to the provided file pointer. :param coefficients: The splitting coefficients. - :param outfile: Pointer to use for printing the splitting coefficients. - - .. note:: - - The *outfile* argument can be ``stdout`` or ``stderr``, or it may point to - a specific file created using ``fopen``. + :param outfile: Pointer to use for printing the splitting coefficients. It + can be ``stdout`` or ``stderr``, or it may point to a specific file created + using ``fopen``. .. versionadded:: x.y.z From dab105a928ba084097f212f911359d74dc89e822 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 11:15:49 -0800 Subject: [PATCH 173/180] Forward declare static functions in examples --- ...k_advection_diffusion_reaction_splitting.c | 283 +++++++++--------- .../C_serial/ark_analytic_partitioned.c | 145 ++++----- 2 files changed, 227 insertions(+), 201 deletions(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 9a9dc663cd..2c4eb66a14 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -62,147 +62,20 @@ typedef struct sunrealtype u0; /* initial and boundary values */ } UserData; -/* Check function return value... - opt == 0 means SUNDIALS function allocates memory so check if - returned NULL pointer - opt == 1 means SUNDIALS function returns a flag so check if - flag >= 0 - opt == 2 means function allocates memory so check if returned - NULL pointer -*/ -static int check_flag(void* flagvalue, const char* funcname, int opt) -{ - int* errflag; - - /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ - if (opt == 0 && flagvalue == NULL) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - - /* Check if flag < 0 */ - else if (opt == 1) - { - errflag = (int*)flagvalue; - if (*errflag < 0) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, *errflag); - return 1; - } - } - - /* Check if function returned NULL pointer - no memory allocated */ - else if (opt == 2 && flagvalue == NULL) - { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - - return 0; -} - -/* f routine to compute the advection RHS function. */ +/* User-supplied Functions Called by the Solver */ static int f_advection(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) -{ - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ - if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } - - sunrealtype* Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); - if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - - const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); - const sunrealtype u0_sqr = udata->u0 * udata->u0; - - /* Left boundary */ - Ydot[0] = coeff * (Y[1] * Y[1] - u0_sqr); - /* Interior */ - for (sunindextype i = 1; i < udata->N - 1; i++) - { - Ydot[i] = coeff * (Y[i + 1] * Y[i + 1] - Y[i - 1] * Y[i - 1]); - } - /* Right boundary */ - Ydot[udata->N - 1] = coeff * (u0_sqr - Y[udata->N - 1] * Y[udata->N - 1]); - - return 0; -} - -/* f routine to compute the diffusion RHS function. */ + const N_Vector ydot, void* const user_data); static int f_diffusion(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) -{ - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ - if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } - - sunrealtype* Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); - if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - - const sunrealtype coeff = udata->b / (udata->dx * udata->dx); - - /* Left boundary */ - Ydot[0] = coeff * (udata->u0 - 2 * Y[0] + Y[1]); - /* Interior */ - for (sunindextype i = 1; i < udata->N - 1; i++) - { - Ydot[i] = coeff * (Y[i + 1] - 2 * Y[i] + Y[i - 1]); - } - /* Right boundary */ - Ydot[udata->N - 1] = coeff * - (Y[udata->N - 2] - 2 * Y[udata->N - 1] + udata->u0); - - return 0; -} - -/* Routine to compute the diffusion Jacobian function. */ + const N_Vector ydot, void* const user_data); static int jac_diffusion(const sunrealtype t, const N_Vector y, const N_Vector fy, const SUNMatrix Jac, void* const user_data, const N_Vector tmp1, - const N_Vector tmp2, const N_Vector tmp3) -{ - const UserData* const udata = (UserData*)user_data; - const sunrealtype coeff = udata->b / (udata->dx * udata->dx); - - SM_ELEMENT_B(Jac, 0, 0) = -2 * coeff; - for (int i = 1; i < udata->N; i++) - { - SM_ELEMENT_B(Jac, i - 1, i) = coeff; - SM_ELEMENT_B(Jac, i, i) = -2 * coeff; - SM_ELEMENT_B(Jac, i, i - 1) = coeff; - } - - return 0; -} - -/* f routine to compute the reaction RHS function. */ + const N_Vector tmp2, const N_Vector tmp3); static int f_reaction(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) -{ - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ - if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + const N_Vector ydot, void* const user_data); - sunrealtype* Ydot = NULL; - Ydot = N_VGetArrayPointer(ydot); - if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - - for (sunindextype i = 0; i < udata->N; i++) - { - Ydot[i] = udata->c * Y[i] * (SUN_RCONST(1.0) - Y[i] * Y[i]); - } - - return 0; -} +/* Private function to check function return values */ +static int check_flag(void* flagvalue, const char* funcname, int opt); int main(void) { @@ -349,3 +222,145 @@ int main(void) return 0; } + +/* f routine to compute the advection RHS function. */ +static int f_advection(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) +{ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); + const sunrealtype u0_sqr = udata->u0 * udata->u0; + + /* Left boundary */ + Ydot[0] = coeff * (Y[1] * Y[1] - u0_sqr); + /* Interior */ + for (sunindextype i = 1; i < udata->N - 1; i++) + { + Ydot[i] = coeff * (Y[i + 1] * Y[i + 1] - Y[i - 1] * Y[i - 1]); + } + /* Right boundary */ + Ydot[udata->N - 1] = coeff * (u0_sqr - Y[udata->N - 1] * Y[udata->N - 1]); + + return 0; +} + +/* f routine to compute the diffusion RHS function. */ +static int f_diffusion(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) +{ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + + /* Left boundary */ + Ydot[0] = coeff * (udata->u0 - 2 * Y[0] + Y[1]); + /* Interior */ + for (sunindextype i = 1; i < udata->N - 1; i++) + { + Ydot[i] = coeff * (Y[i + 1] - 2 * Y[i] + Y[i - 1]); + } + /* Right boundary */ + Ydot[udata->N - 1] = coeff * + (Y[udata->N - 2] - 2 * Y[udata->N - 1] + udata->u0); + + return 0; +} + +/* Routine to compute the diffusion Jacobian function. */ +static int jac_diffusion(const sunrealtype t, const N_Vector y, + const N_Vector fy, const SUNMatrix Jac, + void* const user_data, const N_Vector tmp1, + const N_Vector tmp2, const N_Vector tmp3) +{ + const UserData* const udata = (UserData*)user_data; + const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + + SM_ELEMENT_B(Jac, 0, 0) = -2 * coeff; + for (int i = 1; i < udata->N; i++) + { + SM_ELEMENT_B(Jac, i - 1, i) = coeff; + SM_ELEMENT_B(Jac, i, i) = -2 * coeff; + SM_ELEMENT_B(Jac, i, i - 1) = coeff; + } + + return 0; +} + +/* f routine to compute the reaction RHS function. */ +static int f_reaction(const sunrealtype t, const N_Vector y, + const N_Vector ydot, void* const user_data) +{ + const UserData* const udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ + if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } + + sunrealtype* Ydot = NULL; + Ydot = N_VGetArrayPointer(ydot); + if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } + + for (sunindextype i = 0; i < udata->N; i++) + { + Ydot[i] = udata->c * Y[i] * (SUN_RCONST(1.0) - Y[i] * Y[i]); + } + + return 0; +} + +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 485689d8ac..fa6f768406 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -57,77 +57,16 @@ typedef struct sunrealtype lambda; } UserData; -/* RHS for f^1(t, y) = -lambda * y */ +/* User-supplied Functions Called by the Solver */ static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data) -{ - sunrealtype lambda = ((UserData*)user_data)->lambda; - N_VScale(-lambda, y, ydot); - return 0; -} - -/* RHS for f^2(t, y) = y^2 */ + void* const user_data); static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data) -{ - N_VProd(y, y, ydot); - return 0; -} - -/* Compute the exact analytic solution */ + void* const user_data); static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, - const UserData* const user_data) -{ - N_Vector sol = N_VClone(y0); - const sunrealtype y0_val = N_VGetArrayPointer(y0)[0]; - const sunrealtype lambda = user_data->lambda; - N_VGetArrayPointer(sol)[0] = - lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); - return sol; -} - -/* Check function return value... - opt == 0 means SUNDIALS function allocates memory so check if - returned NULL pointer - opt == 1 means SUNDIALS function returns a flag so check if - flag >= 0 - opt == 2 means function allocates memory so check if returned - NULL pointer -*/ -static int check_flag(void* flagvalue, const char* funcname, int opt) -{ - int* errflag; + const UserData* const user_data); - /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ - if (opt == 0 && flagvalue == NULL) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - - /* Check if flag < 0 */ - else if (opt == 1) - { - errflag = (int*)flagvalue; - if (*errflag < 0) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, *errflag); - return 1; - } - } - - /* Check if function returned NULL pointer - no memory allocated */ - else if (opt == 2 && flagvalue == NULL) - { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - - return 0; -} +/* Private function to check function return values */ +static int check_flag(void* flagvalue, const char* funcname, int opt); int main(const int argc, char* const argv[]) { @@ -261,3 +200,75 @@ int main(const int argc, char* const argv[]) return 0; } + +/* RHS for f^1(t, y) = -lambda * y */ +static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, + void* const user_data) +{ + sunrealtype lambda = ((UserData*)user_data)->lambda; + N_VScale(-lambda, y, ydot); + return 0; +} + +/* RHS for f^2(t, y) = y^2 */ +static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, + void* const user_data) +{ + N_VProd(y, y, ydot); + return 0; +} + +/* Compute the exact analytic solution */ +static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, + const UserData* const user_data) +{ + N_Vector sol = N_VClone(y0); + const sunrealtype y0_val = N_VGetArrayPointer(y0)[0]; + const sunrealtype lambda = user_data->lambda; + N_VGetArrayPointer(sol)[0] = + lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); + return sol; +} + +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} From fd75720e8bed5c95e3707c0e538d9b276c061c2b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 11:21:54 -0800 Subject: [PATCH 174/180] Remove const from examples --- ...k_advection_diffusion_reaction_splitting.c | 80 +++++++++---------- .../C_serial/ark_analytic_partitioned.c | 46 +++++------ 2 files changed, 56 insertions(+), 70 deletions(-) diff --git a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c index 2c4eb66a14..b6354fd915 100644 --- a/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c +++ b/examples/arkode/C_serial/ark_advection_diffusion_reaction_splitting.c @@ -63,16 +63,12 @@ typedef struct } UserData; /* User-supplied Functions Called by the Solver */ -static int f_advection(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data); -static int f_diffusion(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data); -static int jac_diffusion(const sunrealtype t, const N_Vector y, - const N_Vector fy, const SUNMatrix Jac, - void* const user_data, const N_Vector tmp1, - const N_Vector tmp2, const N_Vector tmp3); -static int f_reaction(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data); +static int f_advection(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); +static int f_diffusion(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); +static int jac_diffusion(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix Jac, + void* user_data, N_Vector tmp1, N_Vector tmp2, + N_Vector tmp3); +static int f_reaction(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); /* Private function to check function return values */ static int check_flag(void* flagvalue, const char* funcname, int opt); @@ -80,16 +76,16 @@ static int check_flag(void* flagvalue, const char* funcname, int opt); int main(void) { /* Problem parameters */ - const sunrealtype T0 = SUN_RCONST(0.0); - const sunrealtype Tf = SUN_RCONST(1.0); - const sunrealtype DT = SUN_RCONST(0.06); - const sunindextype N = 128; - UserData udata = {.N = N, - .dx = SUN_RCONST(1.0) / (N + 1), - .a = SUN_RCONST(1.0), - .b = SUN_RCONST(0.125), - .c = SUN_RCONST(4.0), - .u0 = SUN_RCONST(0.1)}; + sunrealtype T0 = SUN_RCONST(0.0); + sunrealtype Tf = SUN_RCONST(1.0); + sunrealtype DT = SUN_RCONST(0.06); + sunindextype N = 128; + UserData udata = {.N = N, + .dx = SUN_RCONST(1.0) / (N + 1), + .a = SUN_RCONST(1.0), + .b = SUN_RCONST(0.125), + .c = SUN_RCONST(4.0), + .u0 = SUN_RCONST(0.1)}; printf("\n1D Advection-Diffusion-Reaction PDE test problem:\n"); printf(" N = %li\n", (long int)udata.N); @@ -224,20 +220,19 @@ int main(void) } /* f routine to compute the advection RHS function. */ -static int f_advection(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) +static int f_advection(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + UserData* udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } sunrealtype* Ydot = NULL; Ydot = N_VGetArrayPointer(ydot); if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - const sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); - const sunrealtype u0_sqr = udata->u0 * udata->u0; + sunrealtype coeff = udata->a / (SUN_RCONST(4.0) * udata->dx); + sunrealtype u0_sqr = udata->u0 * udata->u0; /* Left boundary */ Ydot[0] = coeff * (Y[1] * Y[1] - u0_sqr); @@ -253,19 +248,18 @@ static int f_advection(const sunrealtype t, const N_Vector y, } /* f routine to compute the diffusion RHS function. */ -static int f_diffusion(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) +static int f_diffusion(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + UserData* udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } sunrealtype* Ydot = NULL; Ydot = N_VGetArrayPointer(ydot); if (check_flag((void*)Ydot, "N_VGetArrayPointer", 0)) { return 1; } - const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + sunrealtype coeff = udata->b / (udata->dx * udata->dx); /* Left boundary */ Ydot[0] = coeff * (udata->u0 - 2 * Y[0] + Y[1]); @@ -282,13 +276,12 @@ static int f_diffusion(const sunrealtype t, const N_Vector y, } /* Routine to compute the diffusion Jacobian function. */ -static int jac_diffusion(const sunrealtype t, const N_Vector y, - const N_Vector fy, const SUNMatrix Jac, - void* const user_data, const N_Vector tmp1, - const N_Vector tmp2, const N_Vector tmp3) +static int jac_diffusion(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix Jac, + void* user_data, N_Vector tmp1, N_Vector tmp2, + N_Vector tmp3) { - const UserData* const udata = (UserData*)user_data; - const sunrealtype coeff = udata->b / (udata->dx * udata->dx); + UserData* udata = (UserData*)user_data; + sunrealtype coeff = udata->b / (udata->dx * udata->dx); SM_ELEMENT_B(Jac, 0, 0) = -2 * coeff; for (int i = 1; i < udata->N; i++) @@ -302,12 +295,11 @@ static int jac_diffusion(const sunrealtype t, const N_Vector y, } /* f routine to compute the reaction RHS function. */ -static int f_reaction(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) +static int f_reaction(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { - const UserData* const udata = (UserData*)user_data; - sunrealtype* Y = NULL; - Y = N_VGetArrayPointer(y); /* access data arrays */ + UserData* udata = (UserData*)user_data; + sunrealtype* Y = NULL; + Y = N_VGetArrayPointer(y); /* access data arrays */ if (check_flag((void*)Y, "N_VGetArrayPointer", 0)) { return 1; } sunrealtype* Ydot = NULL; diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index fa6f768406..0428bfc20d 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -58,20 +58,17 @@ typedef struct } UserData; /* User-supplied Functions Called by the Solver */ -static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data); -static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data); -static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, - const UserData* const user_data); +static int f_linear(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); +static int f_nonlinear(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); +static N_Vector exact_sol(N_Vector y0, sunrealtype tf, UserData* user_data); /* Private function to check function return values */ static int check_flag(void* flagvalue, const char* funcname, int opt); -int main(const int argc, char* const argv[]) +int main(int argc, char* argv[]) { /* Parse arguments */ - const char* const integrator_name = (argc > 1) ? argv[1] : "splitting"; + char* integrator_name = (argc > 1) ? argv[1] : "splitting"; if (strcmp(integrator_name, "splitting") != 0 && strcmp(integrator_name, "forcing") != 0) { @@ -79,14 +76,14 @@ int main(const int argc, char* const argv[]) integrator_name); return 1; } - const char* const coefficients_name = (argc > 2) ? argv[2] : NULL; + char* coefficients_name = (argc > 2) ? argv[2] : NULL; /* Problem parameters */ - const sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ - const sunrealtype tf = SUN_RCONST(1.0); /* final time */ - const sunrealtype dt = SUN_RCONST(0.01); /* outer time step */ - const sunrealtype dt_linear = dt / 5; /* linear integrator time step */ - const sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ + sunrealtype t0 = SUN_RCONST(0.0); /* initial time */ + sunrealtype tf = SUN_RCONST(1.0); /* final time */ + sunrealtype dt = SUN_RCONST(0.01); /* outer time step */ + sunrealtype dt_linear = dt / 5; /* linear integrator time step */ + sunrealtype dt_nonlinear = dt / 10; /* nonlinear integrator time step */ UserData user_data = {.lambda = SUN_RCONST(2.0)}; @@ -96,11 +93,11 @@ int main(const int argc, char* const argv[]) if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } /* Initialize vector with initial condition */ - const N_Vector y = N_VNew_Serial(1, ctx); + N_Vector y = N_VNew_Serial(1, ctx); if (check_flag(y, "N_VNew_Serial", 0)) { return 1; } N_VConst(SUN_RCONST(1.0), y); - const N_Vector y_exact = exact_sol(y, tf, &user_data); + N_Vector y_exact = exact_sol(y, tf, &user_data); printf("\nAnalytical ODE test problem:\n"); printf(" integrator = %s method\n", integrator_name); @@ -170,7 +167,7 @@ int main(const int argc, char* const argv[]) if (check_flag(&flag, "ARKodeEvolve", 1)) { return 1; } /* Print the numerical error and statistics */ - const N_Vector y_err = N_VClone(y); + N_Vector y_err = N_VClone(y); if (check_flag(y_err, "N_VClone", 0)) { return 1; } N_VLinearSum(SUN_RCONST(1.0), y, -SUN_RCONST(1.0), y_exact, y_err); printf("\nError: %" GSYM "\n", N_VMaxNorm(y_err)); @@ -202,8 +199,7 @@ int main(const int argc, char* const argv[]) } /* RHS for f^1(t, y) = -lambda * y */ -static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data) +static int f_linear(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { sunrealtype lambda = ((UserData*)user_data)->lambda; N_VScale(-lambda, y, ydot); @@ -211,20 +207,18 @@ static int f_linear(const sunrealtype t, const N_Vector y, N_Vector ydot, } /* RHS for f^2(t, y) = y^2 */ -static int f_nonlinear(const sunrealtype t, const N_Vector y, N_Vector ydot, - void* const user_data) +static int f_nonlinear(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { N_VProd(y, y, ydot); return 0; } /* Compute the exact analytic solution */ -static N_Vector exact_sol(const N_Vector y0, const sunrealtype tf, - const UserData* const user_data) +static N_Vector exact_sol(N_Vector y0, sunrealtype tf, UserData* user_data) { - N_Vector sol = N_VClone(y0); - const sunrealtype y0_val = N_VGetArrayPointer(y0)[0]; - const sunrealtype lambda = user_data->lambda; + N_Vector sol = N_VClone(y0); + sunrealtype y0_val = N_VGetArrayPointer(y0)[0]; + sunrealtype lambda = user_data->lambda; N_VGetArrayPointer(sol)[0] = lambda * y0_val / (y0_val - (y0_val - lambda) * SUNRexp(lambda * tf)); return sol; From fea95c9ff72851cd6ed117fd28afbefdb8b70133 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 11:31:13 -0800 Subject: [PATCH 175/180] Clarify step sizes in analytic partitioned example --- examples/arkode/C_serial/ark_analytic_partitioned.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index 0428bfc20d..bd6a3b1e30 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -30,9 +30,10 @@ * coefficients (splitting only): the SplittingStepCoefficients to load * * The linear term lambda*y and nonlinear term y^2 are treated as the two - * partitions. The former is integrated with a time step 5x smaller than the - * outer method, while the later uses a 10x smaller time step. Once solved, the - * program prints the error and statistics. + * partitions. The former is integrated using a time step of 5e-3, while the + * later uses a time step of 1e-3. The overall splitting or forcing integrator + * uses a time step of 1e-2. Once solved, the program prints the error and + * statistics. *----------------------------------------------------------------------------*/ /* Header files */ From bba4facfe8ad1e3bfc35290638cfea0f2aa4ffd3 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 12:02:16 -0800 Subject: [PATCH 176/180] Use ERKStep for ark_analytic_partitioned example --- .../C_serial/ark_analytic_partitioned.c | 6 +- .../ark_analytic_partitioned_forcing.out | 59 ++----------------- .../ark_analytic_partitioned_splitting.out | 14 +---- ..._splitting_ARKODE_SPLITTING_BEST_2_2_2.out | 14 +---- ..._splitting_ARKODE_SPLITTING_RUTH_3_3_2.out | 14 +---- ...litting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out | 16 +---- 6 files changed, 16 insertions(+), 107 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index bd6a3b1e30..c97e174c7b 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -37,7 +37,7 @@ *----------------------------------------------------------------------------*/ /* Header files */ -#include +#include #include #include #include @@ -109,7 +109,7 @@ int main(int argc, char* argv[]) printf(" lambda = %" GSYM "\n", user_data.lambda); /* Create the integrator for the linear partition */ - void* linear_mem = ARKStepCreate(f_linear, NULL, t0, y, ctx); + void* linear_mem = ERKStepCreate(f_linear, t0, y, ctx); if (check_flag(linear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetUserData(linear_mem, &user_data); @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } /* Create the integrator for the nonlinear partition */ - void* nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); + void* nonlinear_mem = ERKStepCreate(f_nonlinear, t0, y, ctx); if (check_flag(nonlinear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetFixedStep(nonlinear_mem, dt_nonlinear); diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out index 345ef5752e..caa2df56b7 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out @@ -1,59 +1,8 @@ +[ERROR][rank 0][/home/roberts115/Documents/Operator_Splitting/sundials/src/arkode/arkode.c:2675][arkHandleFailure] An inner SUNStepper error occurred + +SUNDIALS_ERROR: ARKodeEvolve() failed with flag = -49 + Analytical ODE test problem: integrator = forcing method lambda = 2 - -Error: 0.00185186 - -Splitting Stepper Statistics: -Current time = 1.000000000000001 -Steps = 100 -Step attempts = 100 -Stability limited steps = 0 -Accuracy limited steps = 0 -Error test fails = 0 -NLS step fails = 0 -Inequality constraint fails = 0 -Initial step size = 0.01 -Last step size = 0.01 -Current step size = 0.01 -Partition 0 evolves = 100 -Partition 1 evolves = 100 - -Linear Stepper Statistics: -Current time = 1.000000000000001 -Steps = 500 -Step attempts = 500 -Stability limited steps = 0 -Accuracy limited steps = 0 -Error test fails = 0 -NLS step fails = 0 -Inequality constraint fails = 0 -Initial step size = 0.002 -Last step size = 0.002 -Current step size = 0.002 -Explicit RHS fn evals = 2500 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 - -Nonlinear Stepper Statistics: -Current time = 1.000000000000001 -Steps = 1000 -Step attempts = 1000 -Stability limited steps = 0 -Accuracy limited steps = 0 -Error test fails = 0 -NLS step fails = 0 -Inequality constraint fails = 0 -Initial step size = 0.001 -Last step size = 0.001 -Current step size = 0.001 -Explicit RHS fn evals = 5000 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out index 86b8a99bd9..11d237d1ab 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out @@ -32,12 +32,7 @@ Inequality constraint fails = 0 Initial step size = 0.002 Last step size = 0.002 Current step size = 0.002 -Explicit RHS fn evals = 2500 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 2500 Nonlinear Stepper Statistics: Current time = 1.000000000000001 @@ -51,9 +46,4 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.001 Current step size = 0.001 -Explicit RHS fn evals = 5000 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 5000 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out index 4f93ca0df2..24a5099aca 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out @@ -33,12 +33,7 @@ Inequality constraint fails = 0 Initial step size = 0.002 Last step size = 0.0010710678118655 Current step size = 0.002 -Explicit RHS fn evals = 3000 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 3000 Nonlinear Stepper Statistics: Current time = 1.000000000000001 @@ -52,9 +47,4 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0009289321881345005 Current step size = 0.001 -Explicit RHS fn evals = 5500 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 5500 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out index a5377ee61f..adc93c5c54 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out @@ -33,12 +33,7 @@ Inequality constraint fails = 0 Initial step size = 0.002 Last step size = 0.0006666666666667037 Current step size = 0.002 -Explicit RHS fn evals = 6500 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 6500 Nonlinear Stepper Statistics: Current time = 1.000000000000001 @@ -52,9 +47,4 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0009166666666666759 Current step size = 0.001 -Explicit RHS fn evals = 6000 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 6000 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out index f361147975..bf82cb0fca 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out @@ -4,7 +4,7 @@ Analytical ODE test problem: coefficients = ARKODE_SPLITTING_YOSHIDA_8_6_2 lambda = 2 -Error: 1.4436e-12 +Error: 1.4346e-12 Splitting Stepper Statistics: Current time = 1.000000000000001 @@ -33,12 +33,7 @@ Inequality constraint fails = 0 Initial step size = 0.002 Last step size = 0.001936124638611257 Current step size = 0.002 -Explicit RHS fn evals = 11000 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 11000 Nonlinear Stepper Statistics: Current time = 1.000000000000001 @@ -52,9 +47,4 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0008722492772224025 Current step size = 0.001 -Explicit RHS fn evals = 82500 -Implicit RHS fn evals = 0 -NLS iters = 0 -NLS fails = 0 -NLS iters per step = 0 -LS setups = 0 +RHS fn evals = 82500 From 7f862d327be9a0c73604c51dda94c9de04176325 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 12:12:44 -0800 Subject: [PATCH 177/180] Remove const from tests --- .../CXX_serial/ark_test_splittingstep.cpp | 71 +++++++++---------- .../arkode/C_serial/ark_test_forcingstep.c | 24 +++---- .../ark_test_splittingstep_coefficients.c | 15 ++-- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp index af2e254860..df66f8e770 100644 --- a/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp +++ b/test/unit_tests/arkode/CXX_serial/ark_test_splittingstep.cpp @@ -33,20 +33,19 @@ * ERK method. Using the exact solution y(t) = exp(-t), we confirm the numerical * solution is sufficiently accurate. */ -static int test_forward(sundials::Context& ctx, const int partitions) +static int test_forward(sundials::Context& ctx, int partitions) { constexpr auto t0 = SUN_RCONST(0.0); constexpr auto tf = SUN_RCONST(1.0); constexpr auto dt = SUN_RCONST(8.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-6); constexpr auto global_tol = SUN_RCONST(10.0) * local_tol; - const auto y = N_VNew_Serial(1, ctx); + auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - const ARKRhsFn f = [](const sunrealtype, const N_Vector z, - const N_Vector zdot, void* const user_data) + ARKRhsFn f = [](sunrealtype, N_Vector z, N_Vector zdot, void* user_data) { - const auto lambda = *static_cast(user_data); + auto lambda = *static_cast(user_data); N_VScale(lambda, z, zdot); return 0; }; @@ -72,12 +71,12 @@ static int test_forward(sundials::Context& ctx, const int partitions) ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); /* Check that the solution matches the exact solution */ - const auto exact_solution = std::exp(t0 - tf); - const auto numerical_solution = N_VGetArrayPointer(y)[0]; + auto exact_solution = std::exp(t0 - tf); + auto numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { - const auto err = numerical_solution - exact_solution; + auto err = numerical_solution - exact_solution; std::cerr << "Forward solution with " << partitions << " partitions failed with an error of " << err << "\n"; return 1; @@ -120,21 +119,19 @@ static int test_mixed_directions(const sundials::Context& ctx) constexpr auto dt = -SUN_RCONST(1.23e-3); constexpr auto local_tol = SUN_RCONST(1.0e-6); constexpr auto global_tol = SUN_RCONST(10.0) * local_tol; - const auto y = N_VNew_Serial(2, ctx); + auto y = N_VNew_Serial(2, ctx); N_VConst(SUN_RCONST(1.0), y); - const auto err = N_VClone(y); + auto err = N_VClone(y); N_VConst(SUN_RCONST(1.0), err); - const ARKRhsFn f1 = - [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + ARKRhsFn f1 = [](sunrealtype t, N_Vector z, N_Vector zdot, void* const) { N_VGetArrayPointer(zdot)[0] = N_VGetArrayPointer(z)[1] - t; N_VGetArrayPointer(zdot)[1] = SUN_RCONST(0.0); return 0; }; - const ARKRhsFn f2 = - [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + ARKRhsFn f2 = [](sunrealtype t, N_Vector z, N_Vector zdot, void* const) { N_VGetArrayPointer(zdot)[0] = SUN_RCONST(0.0); N_VGetArrayPointer(zdot)[1] = t - N_VGetArrayPointer(z)[0]; @@ -174,7 +171,7 @@ static int test_mixed_directions(const sundials::Context& ctx) ARKodeEvolve(arkode_mem, t3, y, &tret, ARK_NORMAL); N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y, err); - const auto max_err = N_VMaxNorm(err); + auto max_err = N_VMaxNorm(err); if (max_err > global_tol) { @@ -221,18 +218,16 @@ static int test_resize(const sundials::Context& ctx) constexpr auto dt = SUN_RCONST(8.0e-3); constexpr auto local_tol = SUN_RCONST(1.0e-5); constexpr auto global_tol = local_tol; - const auto y = N_VNew_Serial(1, ctx); + auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); - const ARKRhsFn f1 = - [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + ARKRhsFn f1 = [](sunrealtype t, N_Vector z, N_Vector zdot, void* const) { N_VProd(z, z, zdot); return 0; }; - const ARKRhsFn f2 = - [](const sunrealtype t, const N_Vector z, const N_Vector zdot, void* const) + ARKRhsFn f2 = [](sunrealtype t, N_Vector z, N_Vector zdot, void* const) { N_VConst(-SUN_RCONST(1.0), zdot); N_VLinearSum(SUN_RCONST(1.0), zdot, -SUN_RCONST(1.0), z, zdot); @@ -260,7 +255,7 @@ static int test_resize(const sundials::Context& ctx) ARKodeEvolve(arkode_mem, t1, y, &tret, ARK_NORMAL); /* Resize */ - const auto y_new = N_VNew_Serial(2, ctx); + auto y_new = N_VNew_Serial(2, ctx); N_VGetArrayPointer(y_new)[0] = SUN_RCONST(1.0); N_VGetArrayPointer(y_new)[1] = N_VGetArrayPointer(y)[0]; N_VDestroy(y); @@ -271,11 +266,11 @@ static int test_resize(const sundials::Context& ctx) /* Integrate from 0.5 to 1 */ ARKodeEvolve(arkode_mem, t2, y_new, &tret, ARK_NORMAL); - const auto err = N_VClone(y_new); + auto err = N_VClone(y_new); N_VGetArrayPointer(err)[0] = std::exp(t1 - t2); N_VGetArrayPointer(err)[1] = std::exp(t0 - t2); N_VLinearSum(SUN_RCONST(1.0), err, -SUN_RCONST(1.0), y_new, err); - const auto max_err = N_VMaxNorm(err); + auto max_err = N_VMaxNorm(err); if (max_err > global_tol) { @@ -302,20 +297,18 @@ static int test_resize(const sundials::Context& ctx) /* Creates a custom SUNStepper for the linear, scalar ODE y' = lambda*y */ static SUNStepper create_exp_stepper(const sundials::Context& ctx, - const sunrealtype& lam, const N_Vector y) + const sunrealtype& lam, N_Vector y) { SUNStepper stepper = nullptr; SUNStepper_Create(ctx, &stepper); struct Content { - const sunrealtype lambda; + sunrealtype lambda; sunrealtype t{}; - const N_Vector v; + N_Vector v; - Content(const sunrealtype l, const N_Vector tmpl) - : lambda(l), v(N_VClone(tmpl)) - {} + Content(sunrealtype l, N_Vector tmpl) : lambda(l), v(N_VClone(tmpl)) {} ~Content() { N_VDestroy(v); } @@ -329,7 +322,7 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, SUNStepper_SetContent(stepper, new Content(lam, y)); - const auto reset = [](SUNStepper s, const sunrealtype tR, const N_Vector vR) + auto reset = [](SUNStepper s, sunrealtype tR, N_Vector vR) { auto& content = Content::from_stepper(s); content.t = tR; @@ -338,22 +331,22 @@ static SUNStepper create_exp_stepper(const sundials::Context& ctx, }; SUNStepper_SetResetFn(stepper, reset); - const auto empty_func = [](auto...) { return 0; }; + auto empty_func = [](auto...) { return 0; }; SUNStepper_SetStopTimeFn(stepper, empty_func); SUNStepper_SetStepDirectionFn(stepper, empty_func); SUNStepper_SetFullRhsFn(stepper, empty_func); - const auto evolve = [](const SUNStepper s, const sunrealtype tout, - const N_Vector vret, sunrealtype* const tret) + auto evolve = + [](SUNStepper s, sunrealtype tout, N_Vector vret, sunrealtype* tret) { - const auto& content = Content::from_stepper(s); + auto& content = Content::from_stepper(s); N_VScale(std::exp(content.lambda * (tout - content.t)), content.v, vret); *tret = tout; return 0; }; SUNStepper_SetEvolveFn(stepper, evolve); - const auto destroy = [](SUNStepper s) + auto destroy = [](SUNStepper s) { delete &Content::from_stepper(s); return 0; @@ -377,7 +370,7 @@ static int test_custom_stepper(const sundials::Context& ctx) constexpr auto t0 = SUN_RCONST(0.0); constexpr auto tf = SUN_RCONST(1.0); constexpr auto dt = SUN_RCONST(0.1); - const auto y = N_VNew_Serial(1, ctx); + auto y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); SUNStepper steppers[] = {create_exp_stepper(ctx, lambda1, y), @@ -393,11 +386,11 @@ static int test_custom_stepper(const sundials::Context& ctx) ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); /* Check that the solution matches the exact solution */ - const auto exact_solution = std::exp(t0 - tf); - const auto numerical_solution = N_VGetArrayPointer(y)[0]; + auto exact_solution = std::exp(t0 - tf); + auto numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompare(exact_solution, numerical_solution)) { - const auto err = numerical_solution - exact_solution; + auto err = numerical_solution - exact_solution; std::cerr << "Custom SUNStepper failed with an error of " << err << "\n"; return 1; } diff --git a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c index e0f0ce648c..5cfcd9d5fa 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c +++ b/test/unit_tests/arkode/C_serial/ark_test_forcingstep.c @@ -26,8 +26,7 @@ #endif /* RHS function for f_1(t, y) = t / y */ -static int f_forward_1(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) +static int f_forward_1(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { N_VInv(y, ydot); N_VScale(t, ydot, ydot); @@ -35,8 +34,7 @@ static int f_forward_1(const sunrealtype t, const N_Vector y, } /* RHS function for f_2(t, y) = 1 / y */ -static int f_forward_2(const sunrealtype t, const N_Vector y, - const N_Vector ydot, void* const user_data) +static int f_forward_2(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { N_VInv(y, ydot); return 0; @@ -52,13 +50,13 @@ static int f_forward_2(const sunrealtype t, const N_Vector y, */ static int test_forward(SUNContext ctx) { - const sunrealtype t0 = SUN_RCONST(0.0); - const sunrealtype tf = SUN_RCONST(1.0); - const sunrealtype dt = SUN_RCONST(1.0e-4); - const sunrealtype local_tol = SUN_RCONST(1.0e-6); - const sunrealtype global_tol = SUN_RCONST(10.0) * local_tol; + sunrealtype t0 = SUN_RCONST(0.0); + sunrealtype tf = SUN_RCONST(1.0); + sunrealtype dt = SUN_RCONST(1.0e-4); + sunrealtype local_tol = SUN_RCONST(1.0e-6); + sunrealtype global_tol = SUN_RCONST(10.0) * local_tol; - const N_Vector y = N_VNew_Serial(1, ctx); + N_Vector y = N_VNew_Serial(1, ctx); N_VConst(SUN_RCONST(1.0), y); void* parititon_mem[] = {ARKStepCreate(f_forward_1, NULL, t0, y, ctx), @@ -77,11 +75,11 @@ static int test_forward(SUNContext ctx) sunrealtype tret = t0; ARKodeEvolve(arkode_mem, tf, y, &tret, ARK_NORMAL); - const sunrealtype exact_solution = SUN_RCONST(2.0); - const sunrealtype numerical_solution = N_VGetArrayPointer(y)[0]; + sunrealtype exact_solution = SUN_RCONST(2.0); + sunrealtype numerical_solution = N_VGetArrayPointer(y)[0]; if (SUNRCompareTol(exact_solution, numerical_solution, global_tol)) { - const sunrealtype err = numerical_solution - exact_solution; + sunrealtype err = numerical_solution - exact_solution; fprintf(stderr, "Forward direction solution failed with an error of %" GSYM "\n", err); diff --git a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c index 751ca96fe2..937ea2e9b4 100644 --- a/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c +++ b/test/unit_tests/arkode/C_serial/ark_test_splittingstep_coefficients.c @@ -30,14 +30,13 @@ (SUN_RCONST(4.0) - \ SUNRpowerR(SUN_RCONST(4.0), SUN_RCONST(1.0) / SUN_RCONST(3.0)))) -static int check_coefficients(const char* const name, - const SplittingStepCoefficients coefficients, - const int expected_sequential_methods, - const int expected_stages, - const int expected_partitions, - const int expected_order, - const sunrealtype* const expected_alpha, - const sunrealtype* const expected_beta) +static int check_coefficients(const char* name, + SplittingStepCoefficients coefficients, + int expected_sequential_methods, + int expected_stages, int expected_partitions, + int expected_order, + const sunrealtype* expected_alpha, + const sunrealtype* expected_beta) { printf("Testing %s\n", name); From 85302fdeffe2a1c7491280de7336b5a98bc23203 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 12:14:53 -0800 Subject: [PATCH 178/180] Remove const from forcingstep --- src/arkode/arkode_forcingstep.c | 60 +++++++++++++++------------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/arkode/arkode_forcingstep.c b/src/arkode/arkode_forcingstep.c index f4590cf8cc..8108a20212 100644 --- a/src/arkode/arkode_forcingstep.c +++ b/src/arkode/arkode_forcingstep.c @@ -24,9 +24,8 @@ Shortcut routine to unpack step_mem structure from ark_mem. If missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ -static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, - const char* const fname, - ARKodeForcingStepMem* const step_mem) +static int forcingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, + ARKodeForcingStepMem* step_mem) { if (ark_mem->step_mem == NULL) { @@ -42,10 +41,9 @@ static int forcingStep_AccessStepMem(const ARKodeMem ark_mem, Shortcut routine to unpack ark_mem and step_mem structures from void* pointer. If either is missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ -static int forcingStep_AccessARKODEStepMem(void* const arkode_mem, - const char* const fname, - ARKodeMem* const ark_mem, - ARKodeForcingStepMem* const step_mem) +static int forcingStep_AccessARKODEStepMem(void* arkode_mem, const char* fname, + ARKodeMem* ark_mem, + ARKodeForcingStepMem* step_mem) { /* access ARKodeMem structure */ if (arkode_mem == NULL) @@ -63,7 +61,7 @@ static int forcingStep_AccessARKODEStepMem(void* const arkode_mem, This routine checks if all required vector operations are present. If any of them is missing it returns SUNFALSE. ---------------------------------------------------------------*/ -static sunbooleantype forcingStep_CheckNVector(const N_Vector y) +static sunbooleantype forcingStep_CheckNVector(N_Vector y) { return y->ops->nvlinearsum != NULL; } @@ -78,7 +76,7 @@ static sunbooleantype forcingStep_CheckNVector(const N_Vector y) With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ -static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) +static int forcingStep_Init(ARKodeMem ark_mem, int init_type) { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -124,12 +122,11 @@ static int forcingStep_Init(const ARKodeMem ark_mem, const int init_type) called and will not be able to reuse a function evaluation since their state resets at the next SUNStepper_Evolve call. ----------------------------------------------------------------------------*/ -static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, - const N_Vector y, const N_Vector f, - SUNDIALS_MAYBE_UNUSED const int mode) +static int forcingStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, + N_Vector f, SUNDIALS_MAYBE_UNUSED int mode) { ARKodeForcingStepMem step_mem = NULL; - const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } SUNErrCode err = SUNStepper_FullRhs(step_mem->stepper[0], t, y, @@ -159,8 +156,8 @@ static int forcingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, /*--------------------------------------------------------------- This routine performs a single step of the forcing method. ---------------------------------------------------------------*/ -static int forcingStep_TakeStep(const ARKodeMem ark_mem, - sunrealtype* const dsmPtr, int* const nflagPtr) +static int forcingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, + int* nflagPtr) { ARKodeForcingStepMem step_mem = NULL; int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -169,9 +166,9 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ - const SUNStepper s0 = step_mem->stepper[0]; - const sunrealtype tout = ark_mem->tn + ark_mem->h; - sunrealtype tret = 0; + SUNStepper s0 = step_mem->stepper[0]; + sunrealtype tout = ark_mem->tn + ark_mem->h; + sunrealtype tret = 0; /* Evolve stepper 0 on its own */ SUNErrCode err = SUNStepper_Reset(s0, ark_mem->tn, ark_mem->yn); @@ -188,8 +185,8 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, * MRIStep), but that would be very fragile. If the step direction ever * changes or a resize is performed, the stepper and outer forcing method * could become out of sync. */ - const SUNStepper s1 = step_mem->stepper[1]; - err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); + SUNStepper s1 = step_mem->stepper[1]; + err = SUNStepper_Reset(s1, ark_mem->tn, ark_mem->yn); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } err = SUNStepper_SetStepDirection(s1, ark_mem->h); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } @@ -197,7 +194,7 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } /* Write tendency (ycur - yn)/h into stepper 1 forcing */ - const sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; + sunrealtype hinv = SUN_RCONST(1.0) / ark_mem->h; N_VLinearSum(hinv, ark_mem->ycur, -hinv, ark_mem->yn, ark_mem->tempv1); err = SUNStepper_SetForcing(s1, ZERO, ZERO, &ark_mem->tempv1, 1); if (err != SUN_SUCCESS) { return ARK_SUNSTEPPER_ERR; } @@ -217,12 +214,12 @@ static int forcingStep_TakeStep(const ARKodeMem ark_mem, /*--------------------------------------------------------------- Prints integrator statistics ---------------------------------------------------------------*/ -static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfile, - const SUNOutputFormat fmt) +static int forcingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, + SUNOutputFormat fmt) { // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeForcingStepMem step_mem = NULL; - const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } switch (fmt) @@ -253,7 +250,7 @@ static int forcingStep_PrintAllStats(const ARKodeMem ark_mem, FILE* const outfil /*--------------------------------------------------------------- Frees all ForcingStep memory. ---------------------------------------------------------------*/ -static void forcingStep_Free(const ARKodeMem ark_mem) +static void forcingStep_Free(ARKodeMem ark_mem) { free(ark_mem->step_mem); ark_mem->step_mem = NULL; @@ -263,10 +260,10 @@ static void forcingStep_Free(const ARKodeMem ark_mem) This routine outputs the memory from the ForcingStep structure to a specified file pointer (useful when debugging). ---------------------------------------------------------------*/ -static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) +static void forcingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) { ARKodeForcingStepMem step_mem = NULL; - const int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = forcingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return; } /* output long integer quantities */ @@ -282,7 +279,7 @@ static void forcingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) values. Does not change problem-defining function pointers or user_data pointer. ---------------------------------------------------------------*/ -static int forcingStep_SetDefaults(const ARKodeMem ark_mem) +static int forcingStep_SetDefaults(ARKodeMem ark_mem) { ARKodeSetInterpolantType(ark_mem, ARK_INTERP_LAGRANGE); @@ -340,8 +337,7 @@ void* ForcingStepCreate(SUNStepper stepper1, SUNStepper stepper2, return NULL; } - const ARKodeForcingStepMem step_mem = - (ARKodeForcingStepMem)malloc(sizeof(*step_mem)); + ARKodeForcingStepMem step_mem = (ARKodeForcingStepMem)malloc(sizeof(*step_mem)); if (step_mem == NULL) { arkProcessError(ark_mem, ARK_MEM_FAIL, __LINE__, __func__, __FILE__, @@ -392,8 +388,8 @@ int ForcingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves { ARKodeMem ark_mem = NULL; ARKodeForcingStepMem step_mem = NULL; - const int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, - &ark_mem, &step_mem); + int retval = forcingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); if (retval != ARK_SUCCESS) { return retval; } if (partition >= NUM_PARTITIONS) From f063740bc73383e94011b33bc2cb5ba582c30a26 Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 12:17:17 -0800 Subject: [PATCH 179/180] Remove const from splittingstep --- src/arkode/arkode_splittingstep.c | 103 ++++++++++++++---------------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/src/arkode/arkode_splittingstep.c b/src/arkode/arkode_splittingstep.c index e99b9656a4..d77bb7986f 100644 --- a/src/arkode/arkode_splittingstep.c +++ b/src/arkode/arkode_splittingstep.c @@ -25,9 +25,8 @@ Shortcut routine to unpack step_mem structure from ark_mem. If missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ -static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, - const char* const fname, - ARKodeSplittingStepMem* const step_mem) +static int splittingStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, + ARKodeSplittingStepMem* step_mem) { if (ark_mem->step_mem == NULL) { @@ -43,10 +42,9 @@ static int splittingStep_AccessStepMem(const ARKodeMem ark_mem, Shortcut routine to unpack ark_mem and step_mem structures from void* pointer. If either is missing it returns ARK_MEM_NULL. ---------------------------------------------------------------*/ -static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, - const char* const fname, - ARKodeMem* const ark_mem, - ARKodeSplittingStepMem* const step_mem) +static int splittingStep_AccessARKODEStepMem(void* arkode_mem, const char* fname, + ARKodeMem* ark_mem, + ARKodeSplittingStepMem* step_mem) { /* access ARKodeMem structure */ if (arkode_mem == NULL) @@ -64,7 +62,7 @@ static int splittingStep_AccessARKODEStepMem(void* const arkode_mem, This routine checks if all required vector operations are present. If any of them is missing it returns SUNFALSE. ---------------------------------------------------------------*/ -static sunbooleantype splittingStep_CheckNVector(const N_Vector y) +static sunbooleantype splittingStep_CheckNVector(N_Vector y) { return y->ops->nvlinearsum != NULL && y->ops->nvscale != NULL; } @@ -73,8 +71,8 @@ static sunbooleantype splittingStep_CheckNVector(const N_Vector y) This routine determines the splitting coefficients to use, based on the desired accuracy. ---------------------------------------------------------------*/ -static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, - const ARKodeSplittingStepMem step_mem) +static int splittingStep_SetCoefficients(ARKodeMem ark_mem, + ARKodeSplittingStepMem step_mem) { if (step_mem->coefficients != NULL) { return ARK_SUCCESS; } @@ -98,7 +96,7 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, else { /* Bump the order up to be even but with a warning */ - const int new_order = step_mem->order + 1; + int new_order = step_mem->order + 1; arkProcessError(ark_mem, ARK_WARNING, __LINE__, __func__, __FILE__, "No splitting method at requested order, using q=%i.", new_order); @@ -126,7 +124,7 @@ static int splittingStep_SetCoefficients(const ARKodeMem ark_mem, With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ -static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) +static int splittingStep_Init(ARKodeMem ark_mem, int init_type) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -176,19 +174,18 @@ static int splittingStep_Init(const ARKodeMem ark_mem, const int init_type) called and will not be able to reuse a function evaluation since their state resets at the next SUNStepper_Evolve call. ----------------------------------------------------------------------------*/ -static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, - const N_Vector y, const N_Vector f, - SUNDIALS_MAYBE_UNUSED const int mode) +static int splittingStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, + N_Vector f, SUNDIALS_MAYBE_UNUSED int mode) { ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } for (int i = 0; i < step_mem->partitions; i++) { - const SUNErrCode err = SUNStepper_FullRhs(step_mem->steppers[i], t, y, - i == 0 ? f : ark_mem->tempv1, - SUN_FULLRHS_OTHER); + SUNErrCode err = SUNStepper_FullRhs(step_mem->steppers[i], t, y, + i == 0 ? f : ark_mem->tempv1, + SUN_FULLRHS_OTHER); if (err != SUN_SUCCESS) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, @@ -204,11 +201,11 @@ static int splittingStep_FullRHS(const ARKodeMem ark_mem, const sunrealtype t, /*--------------------------------------------------------------- This routine performs a sequential operator splitting method ---------------------------------------------------------------*/ -static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, - const ARKodeSplittingStepMem step_mem, - const int i, const N_Vector y) +static int splittingStep_SequentialMethod(ARKodeMem ark_mem, + ARKodeSplittingStepMem step_mem, + int i, N_Vector y) { - const SplittingStepCoefficients coefficients = step_mem->coefficients; + SplittingStepCoefficients coefficients = step_mem->coefficients; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, @@ -227,13 +224,13 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, #endif for (int k = 0; k < coefficients->partitions; k++) { - const sunrealtype beta_start = coefficients->beta[i][j][k]; - const sunrealtype beta_end = coefficients->beta[i][j + 1][k]; + sunrealtype beta_start = coefficients->beta[i][j][k]; + sunrealtype beta_end = coefficients->beta[i][j + 1][k]; if (beta_start == beta_end) { continue; } - const sunrealtype t_start = ark_mem->tn + beta_start * ark_mem->h; - const sunrealtype t_end = ark_mem->tn + beta_end * ark_mem->h; + sunrealtype t_start = ark_mem->tn + beta_start * ark_mem->h; + sunrealtype t_end = ark_mem->tn + beta_end * ark_mem->h; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_DEBUG, @@ -244,7 +241,7 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, ark_mem->nst, i, j, k, t_start, t_end); #endif - const SUNStepper stepper = step_mem->steppers[k]; + SUNStepper stepper = step_mem->steppers[k]; /* TODO(SBR): A potential future optimization is removing this reset and * a call to SUNStepper_SetStopTime later for methods that start a step * evolving the same partition the last step ended with (essentially a @@ -273,8 +270,8 @@ static int splittingStep_SequentialMethod(const ARKodeMem ark_mem, /*--------------------------------------------------------------- This routine performs a single step of the splitting method. ---------------------------------------------------------------*/ -static int splittingStep_TakeStep(const ARKodeMem ark_mem, - sunrealtype* const dsmPtr, int* const nflagPtr) +static int splittingStep_TakeStep(ARKodeMem ark_mem, sunrealtype* dsmPtr, + int* nflagPtr) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -283,7 +280,7 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, *nflagPtr = ARK_SUCCESS; /* No algebraic solver */ *dsmPtr = ZERO; /* No error estimate */ - const SplittingStepCoefficients coefficients = step_mem->coefficients; + SplittingStepCoefficients coefficients = step_mem->coefficients; N_VScale(ONE, ark_mem->yn, ark_mem->ycur); retval = splittingStep_SequentialMethod(ark_mem, step_mem, 0, ark_mem->ycur); @@ -310,13 +307,12 @@ static int splittingStep_TakeStep(const ARKodeMem ark_mem, /*--------------------------------------------------------------- Prints integrator statistics ---------------------------------------------------------------*/ -static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, - FILE* const outfile, - const SUNOutputFormat fmt) +static int splittingStep_PrintAllStats(ARKodeMem ark_mem, FILE* outfile, + SUNOutputFormat fmt) { // TODO(SBR): update when https://github.com/LLNL/sundials/pull/517 merged ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } switch (fmt) @@ -347,10 +343,10 @@ static int splittingStep_PrintAllStats(const ARKodeMem ark_mem, /*--------------------------------------------------------------- Outputs all solver parameters to the provided file pointer. ---------------------------------------------------------------*/ -static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp) +static int splittingStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) { ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } fprintf(fp, "SplittingStep time step module parameters:\n Method order %i\n\n", @@ -362,10 +358,9 @@ static int splittingStep_WriteParameters(const ARKodeMem ark_mem, FILE* const fp /*--------------------------------------------------------------- Frees all SplittingStep memory. ---------------------------------------------------------------*/ -static void splittingStep_Free(const ARKodeMem ark_mem) +static void splittingStep_Free(ARKodeMem ark_mem) { - const ARKodeSplittingStepMem step_mem = - (ARKodeSplittingStepMem)ark_mem->step_mem; + ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)ark_mem->step_mem; if (step_mem != NULL) { free(step_mem->steppers); @@ -380,10 +375,10 @@ static void splittingStep_Free(const ARKodeMem ark_mem) This routine outputs the memory from the SplittingStep structure to a specified file pointer (useful when debugging). ---------------------------------------------------------------*/ -static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) +static void splittingStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) { ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return; } /* output integer quantities */ @@ -405,10 +400,10 @@ static void splittingStep_PrintMem(const ARKodeMem ark_mem, FILE* const outfile) /*--------------------------------------------------------------- Specifies the method order ---------------------------------------------------------------*/ -static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) +static int splittingStep_SetOrder(ARKodeMem ark_mem, int order) { ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); + int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } /* set user-provided value, or default, depending on argument */ @@ -425,7 +420,7 @@ static int splittingStep_SetOrder(const ARKodeMem ark_mem, const int order) values. Does not change problem-defining function pointers or user_data pointer. ---------------------------------------------------------------*/ -static int splittingStep_SetDefaults(const ARKodeMem ark_mem) +static int splittingStep_SetDefaults(ARKodeMem ark_mem) { ARKodeSplittingStepMem step_mem = NULL; int retval = splittingStep_AccessStepMem(ark_mem, __func__, &step_mem); @@ -444,9 +439,8 @@ static int splittingStep_SetDefaults(const ARKodeMem ark_mem) /*--------------------------------------------------------------- Creates the SplittingStep integrator ---------------------------------------------------------------*/ -void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, - const sunrealtype t0, const N_Vector y0, - const SUNContext sunctx) +void* SplittingStepCreate(SUNStepper* steppers, int partitions, sunrealtype t0, + N_Vector y0, SUNContext sunctx) { if (steppers == NULL) { @@ -496,7 +490,7 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, return NULL; } - const ARKodeSplittingStepMem step_mem = + ARKodeSplittingStepMem step_mem = (ARKodeSplittingStepMem)malloc(sizeof(*step_mem)); if (step_mem == NULL) { @@ -567,13 +561,13 @@ void* SplittingStepCreate(SUNStepper* const steppers, const int partitions, /*--------------------------------------------------------------- Sets the SplittingStep coefficients. ---------------------------------------------------------------*/ -int SplittingStep_SetCoefficients(void* const arkode_mem, - const SplittingStepCoefficients coefficients) +int SplittingStep_SetCoefficients(void* arkode_mem, + SplittingStepCoefficients coefficients) { ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; - const int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, - &ark_mem, &step_mem); + int retval = splittingStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); if (retval != ARK_SUCCESS) { return retval; } if (coefficients == NULL) @@ -603,8 +597,7 @@ int SplittingStep_SetCoefficients(void* const arkode_mem, return ARK_SUCCESS; } -int SplittingStep_GetNumEvolves(void* const arkode_mem, const int partition, - long int* const evolves) +int SplittingStep_GetNumEvolves(void* arkode_mem, int partition, long int* evolves) { ARKodeMem ark_mem = NULL; ARKodeSplittingStepMem step_mem = NULL; From 544f25a675362bbb2c83bbf322707d9f6aa3283b Mon Sep 17 00:00:00 2001 From: Steven Roberts Date: Thu, 14 Nov 2024 12:23:11 -0800 Subject: [PATCH 180/180] Fix splittingstep failure after switching to ERKStep --- .../C_serial/ark_analytic_partitioned.c | 3 +- .../ark_analytic_partitioned_forcing.out | 54 +++++++++++++++++-- .../ark_analytic_partitioned_splitting.out | 7 ++- ..._splitting_ARKODE_SPLITTING_BEST_2_2_2.out | 7 ++- ..._splitting_ARKODE_SPLITTING_RUTH_3_3_2.out | 7 ++- ...litting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out | 9 +++- 6 files changed, 77 insertions(+), 10 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_partitioned.c b/examples/arkode/C_serial/ark_analytic_partitioned.c index c97e174c7b..2313082146 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned.c +++ b/examples/arkode/C_serial/ark_analytic_partitioned.c @@ -37,6 +37,7 @@ *----------------------------------------------------------------------------*/ /* Header files */ +#include #include #include #include @@ -119,7 +120,7 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodeSetFixedStep", 1)) { return 1; } /* Create the integrator for the nonlinear partition */ - void* nonlinear_mem = ERKStepCreate(f_nonlinear, t0, y, ctx); + void* nonlinear_mem = ARKStepCreate(f_nonlinear, NULL, t0, y, ctx); if (check_flag(nonlinear_mem, "N_VNew_Serial", 0)) { return 1; } flag = ARKodeSetFixedStep(nonlinear_mem, dt_nonlinear); diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out index caa2df56b7..dd81702c9d 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_forcing.out @@ -1,8 +1,54 @@ -[ERROR][rank 0][/home/roberts115/Documents/Operator_Splitting/sundials/src/arkode/arkode.c:2675][arkHandleFailure] An inner SUNStepper error occurred - -SUNDIALS_ERROR: ARKodeEvolve() failed with flag = -49 - Analytical ODE test problem: integrator = forcing method lambda = 2 + +Error: 0.00185186 + +Splitting Stepper Statistics: +Current time = 1.000000000000001 +Steps = 100 +Step attempts = 100 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.01 +Last step size = 0.01 +Current step size = 0.01 +Partition 0 evolves = 100 +Partition 1 evolves = 100 + +Linear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 500 +Step attempts = 500 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.002 +Last step size = 0.002 +Current step size = 0.002 +RHS fn evals = 2500 + +Nonlinear Stepper Statistics: +Current time = 1.000000000000001 +Steps = 1000 +Step attempts = 1000 +Stability limited steps = 0 +Accuracy limited steps = 0 +Error test fails = 0 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 0.001 +Last step size = 0.001 +Current step size = 0.001 +Explicit RHS fn evals = 5000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out index 11d237d1ab..77962e7939 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting.out @@ -46,4 +46,9 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.001 Current step size = 0.001 -RHS fn evals = 5000 +Explicit RHS fn evals = 5000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out index 24a5099aca..47ae2487bf 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_BEST_2_2_2.out @@ -47,4 +47,9 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0009289321881345005 Current step size = 0.001 -RHS fn evals = 5500 +Explicit RHS fn evals = 5500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out index adc93c5c54..9a3aea8caf 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_RUTH_3_3_2.out @@ -47,4 +47,9 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0009166666666666759 Current step size = 0.001 -RHS fn evals = 6000 +Explicit RHS fn evals = 6000 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0 diff --git a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out index bf82cb0fca..4a619c463d 100644 --- a/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out +++ b/examples/arkode/C_serial/ark_analytic_partitioned_splitting_ARKODE_SPLITTING_YOSHIDA_8_6_2.out @@ -4,7 +4,7 @@ Analytical ODE test problem: coefficients = ARKODE_SPLITTING_YOSHIDA_8_6_2 lambda = 2 -Error: 1.4346e-12 +Error: 1.44246e-12 Splitting Stepper Statistics: Current time = 1.000000000000001 @@ -47,4 +47,9 @@ Inequality constraint fails = 0 Initial step size = 0.001 Last step size = 0.0008722492772224025 Current step size = 0.001 -RHS fn evals = 82500 +Explicit RHS fn evals = 82500 +Implicit RHS fn evals = 0 +NLS iters = 0 +NLS fails = 0 +NLS iters per step = 0 +LS setups = 0