From 5d6b64bcc60d382fa23fa13e8ee8743ac2b796a3 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 9 Feb 2022 23:51:40 -0800 Subject: [PATCH 001/111] adding relaxation to ARKStep --- examples/arkode/C_serial/CMakeLists.txt | 1 + .../C_serial/ark_conserved_exp_entropy.c | 421 ++++++++++++++++++ .../C_serial/ark_conserved_exp_entropy.h | 16 + include/arkode/arkode.h | 4 + include/arkode/arkode_arkstep.h | 4 + src/arkode/CMakeLists.txt | 1 + src/arkode/arkode.c | 3 + src/arkode/arkode_arkstep.c | 49 +- src/arkode/arkode_arkstep_io.c | 4 + src/arkode/arkode_impl.h | 4 + src/arkode/arkode_relaxation.c | 125 ++++++ src/arkode/arkode_relaxation_impl.h | 55 +++ 12 files changed, 686 insertions(+), 1 deletion(-) create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy.c create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy.h create mode 100644 src/arkode/arkode_relaxation.c create mode 100644 src/arkode/arkode_relaxation_impl.h diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index bf3d1f5cc3..3e7f0314f9 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,6 +26,7 @@ set(ARKODE_examples "ark_brusselator\;\;develop" "ark_brusselator_fp\;\;develop" "ark_brusselator1D\;\;develop" + "ark_conserved_exp_entropy\;\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" "ark_KrylovDemo_prec\;\;develop" diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c new file mode 100644 index 0000000000..2d9c83fb75 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -0,0 +1,421 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 example problem is adapted from: + * + * H. Ranocha, M. Sayyari, L. Dalcin, M. Parsani, and D.I. Ketcheson, + * "Relaxation Runge-Kutta Methods: Fully-Discrete Explicit Entropy-Stable + * Schemes for the Compressible Euler and Navier-Stokes Equations, SIAM Journal + * on Scientific Computing, 42(2), 2020, https://doi.org/10.1137/19M1263480. + * ----------------------------------------------------------------------------- + * This example evolves system + * + * du/dt = -exp(v) + * dv/dt = exp(u) + * + * for t in the interval [0, 5] with the initial condition + * + * u(0) = 1.0 + * v(0) = 0.5 + * + * The exponential entropy given by + * + * e = exp(u) + exp(v) + * + * e' = [ de/du; de/dv ] = [ exp(u); exp(v) ] + * + * is conserved for the analytical solution + * + * u = log(a * exp^(a * t)) - log(b) + * v = log(e + e^(3/2)) - log(b) + * + * where log is the natural logarithm, a = sqrt(e) + e, and + * b = sqrt(e) + e^(a * t). + * + * ---------------------------------------------------------------------------*/ + +/* Header files */ +#include +#include +#include /* access to ARKStep */ +#include /* access to serial N_Vector */ +#include /* access to dense SUNMatrix */ +#include /* access to dense SUNLinearSolver */ + +/* Precision-dependent output macros */ +#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 + +#define EVAL 2.718281828459045235360287471352662497757247093699959574966 + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +/* ODE RHS function */ +int f(realtype t, N_Vector y, N_Vector ydot, void *user_data); + +/* ODE RHS Jacobian function */ +int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, void *user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); + +/* Entropy function */ +int Ent(N_Vector y, realtype* e, void* user_data); + +/* Entropy Jacobian function */ +int JacEnt(N_Vector y, N_Vector J, void* user_data); + +/* ----------------- * + * Utility functions * + * ----------------- */ + +/* Analytic solution */ +int ans(realtype t, N_Vector y); + +/* Check return flags and pointers */ +int check_flag(int flag, const char* funcname); +int check_ptr(void* ptr, const char* funcname); + +/* ------------ * + * Main Program * + * ------------ */ + +int main(int argc, char *argv[]) +{ + /* Error-checking flag */ + int flag; + + /* Initial and final times */ + realtype t0 = RCONST(0.0); + realtype tf = RCONST(5.0); + + /* Relative and absolute tolerances */ + realtype reltol = RCONST(1.0e-6); + realtype abstol = RCONST(1.0e-10); + + /* SUNDIALS context, vector, matrix, and linear solver objects */ + SUNContext ctx = NULL; + N_Vector y = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; + + /* Pointer to vector data array */ + realtype* ydata; + + /* Initial, current, and change in entropy value */ + realtype ent0, ent, dent; + + /* ARKODE memory structure */ + void* arkode_mem = NULL; + + /* ARKODE statistics */ + long int nst, nst_a, nfe, nfi, nsetups, nje, nfeLS, nni, ncfn, netf; + + /* Number of outputs, output counter, output times, and output file */ + int nout = 10; + int iout; + realtype t, tout, dtout; + FILE* UFID; + + /* Command line options */ + int implicit = 0; /* explicit */ + realtype fixed_h = RCONST(0.0); /* adaptive step */ + + /* ----- * + * Setup * + * ----- */ + + if (argc > 1) implicit = atoi(argv[1]); + if (argc > 2) fixed_h = (realtype) atof(argv[2]); + + printf("\nConserved Exponential Entropy problem:\n"); + printf(" reltol = %.1"ESYM"\n", reltol); + printf(" abstol = %.1"ESYM"\n\n",abstol); + + /* Create the SUNDIALS context object for this simulation */ + flag = SUNContext_Create(NULL, &ctx); + if (check_flag(flag, "SUNContext_Create")) return 1; + + /* Create serial vector and set the initial condition values */ + y = N_VNew_Serial(2, ctx); + if (check_ptr(y, "N_VNew_Serial")) return 1; + + ydata = N_VGetArrayPointer(y); + + ydata[0] = RCONST(1.0); + ydata[1] = RCONST(0.5); + + /* Initial entropy */ + flag = Ent(y, &ent0, NULL); + if (check_flag(flag, "Ent")) return 1; + + /* Initialize the ARKStep */ + if (implicit) + arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); + else + arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; + + /* Specify tolerances */ + flag = ARKStepSStolerances(arkode_mem, reltol, abstol); + if (check_flag(flag, "ARKStepSStolerances")) return 1; + + flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); + if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; + + if (fixed_h > 0.0) + { + /* Set the step size */ + flag = ARKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ARKStepSetFixedStep")) return 1; + } + + if (implicit) + { + /* Create dense matrix and linear solver */ + A = SUNDenseMatrix(2, 2, ctx); + if (check_ptr(A, "SUNDenseMatrix")) return 1; + + LS = SUNLinSol_Dense(y, A, ctx); + if (check_ptr(LS, "SUNLinSol_Dense")) return 1; + + /* Attach the matrix and linear solver */ + flag = ARKStepSetLinearSolver(arkode_mem, LS, A); + if (check_flag(flag, "ARKStepSetLinearSolver")) return 1; + + /* Set Jacobian routine */ + flag = ARKStepSetJacFn(arkode_mem, Jac); + if (check_flag(flag, "ARKStepSetJacFn")) return 1; + } + + /* Open output stream for results, output comment line */ + UFID = fopen("solution.txt", "w"); + fprintf(UFID,"# t u v e\n"); + + /* --------------- * + * Advance in Time * + * --------------- */ + + /* Initial time, time between outputs, output time */ + t = t0; + dtout = tf / nout; + tout = t0 + dtout; + + /* Write initial condition to disk */ + fprintf(UFID," %.16"ESYM" %.16"ESYM" %.16"ESYM"\n", t0, ydata[0], ydata[1]); + + printf(" t u v de\n"); + printf(" ---------------------------------------------------------\n"); + printf(" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM"\n", + t, ydata[0], ydata[1], RCONST(0.0)); + + for (iout = 0; iout < nout; iout++) + { + /* Evolve in time */ + flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_NORMAL); + if (check_flag(flag, "ARKStepEvolve")) break; + + /* Output solution and change in entropy */ + flag = Ent(y, &ent, NULL); + if (check_flag(flag, "Ent")) return 1; + + dent = fabs(ent - ent0); + + printf(" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM"\n", + t, ydata[0], ydata[1], dent); + fprintf(UFID," %.16"ESYM" %.16"ESYM" %.16"ESYM" %.16"ESYM"\n", + t, ydata[0], ydata[1], dent); + + /* Update output time */ + tout += dtout; + tout = (tout > tf) ? tf : tout; + } + + printf(" ---------------------------------------------------------\n"); + fclose(UFID); + + /* ------------ * + * Output Stats * + * ------------ */ + + /* Get final statistics on how the solve progressed */ + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + + flag = ARKStepGetNumStepAttempts(arkode_mem, &nst_a); + check_flag(flag, "ARKStepGetNumStepAttempts"); + + flag = ARKStepGetNumErrTestFails(arkode_mem, &netf); + check_flag(flag, "ARKStepGetNumErrTestFails"); + + flag = ARKStepGetNumRhsEvals(arkode_mem, &nfe, &nfi); + check_flag(flag, "ARKStepGetNumRhsEvals"); + + printf("\nFinal Solver Statistics:\n"); + printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); + printf(" Total number of error test failures = %li\n", netf); + printf(" Total RHS evals: Fe = %li, Fi = %li\n", nfe, nfi); + + if (implicit) + { + flag = ARKStepGetNumNonlinSolvIters(arkode_mem, &nni); + check_flag(flag, "ARKStepGetNumNonlinSolvIters"); + + flag = ARKStepGetNumNonlinSolvConvFails(arkode_mem, &ncfn); + check_flag(flag, "ARKStepGetNumNonlinSolvConvFails"); + + flag = ARKStepGetNumLinSolvSetups(arkode_mem, &nsetups); + check_flag(flag, "ARKStepGetNumLinSolvSetups"); + + flag = ARKStepGetNumJacEvals(arkode_mem, &nje); + check_flag(flag, "ARKStepGetNumJacEvals"); + + flag = ARKStepGetNumLinRhsEvals(arkode_mem, &nfeLS); + check_flag(flag, "ARKStepGetNumLinRhsEvals"); + + printf(" Total number of Newton iterations = %li\n", nni); + printf(" Total number of linear solver convergence failures = %li\n", ncfn); + printf(" Total linear solver setups = %li\n", nsetups); + printf(" Total number of Jacobian evaluations = %li\n", nje); + printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); + } + printf("\n"); + + /* -------- * + * Clean up * + * -------- */ + + /* Free ARKStep integrator and SUNDIALS objects */ + ARKStepFree(&arkode_mem); + SUNLinSolFree(LS); + SUNMatDestroy(A); + N_VDestroy(y); + SUNContext_Free(&ctx); + + return flag; +} + + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + + +/* ODE RHS function f(t,y). */ +int f(realtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + realtype* ydata = N_VGetArrayPointer(y); + realtype* fdata = N_VGetArrayPointer(ydot); + + fdata[0] = -exp(ydata[1]); + fdata[1] = exp(ydata[0]); + + return 0; +} + + +/* ODE RHS Jacobian function J(t,y) = df/dy. */ +int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) +{ + realtype* ydata = N_VGetArrayPointer(y); + realtype* Jdata = SUNDenseMatrix_Data(J); + + /* column 0 */ + Jdata[0] = 0; + Jdata[1] = -exp(ydata[1]); + + /* column 1 */ + Jdata[2] = exp(ydata[0]); + Jdata[3] = 0; + + return 0; +} + + +/* Entropy function e(y) */ +int Ent(N_Vector y, realtype* e, void* user_data) +{ + realtype* ydata = N_VGetArrayPointer(y); + + *e = exp(ydata[0]) + exp(ydata[1]); + + return 0; +} + + +/* Entropy function Jacobian Je(y) = de/dy */ +int JacEnt(N_Vector y, N_Vector J, void* user_data) +{ + realtype* ydata = N_VGetArrayPointer(y); + realtype* jdata = N_VGetArrayPointer(J); + + jdata[0] = exp(ydata[0]); + jdata[1] = exp(ydata[1]); + + return 0; +} + + +/* ----------------- * + * Utility functions * + * ----------------- */ + + +/* Analytic solution */ +int ans(realtype t, N_Vector y) +{ + realtype a, b; + realtype* ydata = N_VGetArrayPointer(y); + + a = sqrt(EVAL) + EVAL; + b = sqrt(EVAL) + pow(EVAL, a * t); + + ydata[0] = log(a * exp(a * t)) - log(b); + ydata[1] = log(EVAL + exp(a * t)) - log(b); + + return 0; +} + + +/* Check return flags */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, flag); + return 1; + } + return 0; +} + + +/* Check return pointers */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + return 0; +} diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.h b/examples/arkode/C_serial/ark_conserved_exp_entropy.h new file mode 100644 index 0000000000..5ff6edeb82 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.h @@ -0,0 +1,16 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 + * ----------------------------------------------------------------------------- + * Header file for conserved exponential entropy example problem. + * ---------------------------------------------------------------------------*/ + diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index fa30036ffb..1277e0a4cc 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -170,6 +170,10 @@ typedef int (*ARKPostProcessFn)(realtype t, N_Vector y, typedef int (*ARKStagePredictFn)(realtype t, N_Vector zpred, void *user_data); +typedef int (*ARKRelaxFn)(N_Vector y, realtype* r, void* user_data); + +typedef int (*ARKRelaxJacFn)(N_Vector y, N_Vector J, void* user_data); + /* -------------------------- * MRIStep Inner Stepper Type * -------------------------- */ diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 22245ce2f5..500cbda617 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -458,6 +458,10 @@ SUNDIALS_EXPORT void ARKStepPrintMem(void* arkode_mem, FILE* outfile); SUNDIALS_EXPORT int ARKStepCreateMRIStepInnerStepper(void *arkode_mem, MRIStepInnerStepper *stepper); + +SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, + ARKRelaxJacFn rjac); + #ifdef __cplusplus } #endif diff --git a/src/arkode/CMakeLists.txt b/src/arkode/CMakeLists.txt index 527fe712c1..63c2b3c531 100644 --- a/src/arkode/CMakeLists.txt +++ b/src/arkode/CMakeLists.txt @@ -36,6 +36,7 @@ set(arkode_SOURCES arkode_mristep_io.c arkode_mristep_nls.c arkode_mristep.c + arkode_relaxation.c arkode_root.c arkode.c ) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index fe0747ad91..b647104dba 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -94,6 +94,9 @@ ARKodeMem arkCreate(SUNContext sunctx) ark_mem->constraintsSet = SUNFALSE; ark_mem->constraints = NULL; + /* Initialize relaxation variables */ + ark_mem->relax_mem = NULL; + /* Initialize diagnostics reporting variables */ ark_mem->report = SUNFALSE; ark_mem->diagfp = NULL; diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 693b1b501e..bce99dedc6 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2478,8 +2478,9 @@ int arkStep_StageSetup(ARKodeMem ark_mem, booleantype implicit) int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) { /* local data */ - int retval, j, nvec; + int retval, i, j, nvec; N_Vector y, yerr; + realtype gam; realtype* cvals; N_Vector* Xvecs; ARKodeARKStepMem step_mem; @@ -2551,6 +2552,52 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) *dsmPtr = N_VWrmsNorm(yerr, ark_mem->ewt); } + /* TODO(DJG): + Should this happen before or after the error estimate? If gamma is "small" + then the error estimate should still hold. Do not relax if the step would + fail the error test. Could relaxation reduce the error enough that the test + would pass? Would it be worthwhile to have an option for when to relax? + If before, this should happen in _ComputeSolutions. + If after, should happen in arkCompleteStep? + operation for a set of dot products? + */ + if (ark_mem->relax_mem) + { + ark_mem->relax_mem->est = ZERO; + for (i = 0; i < step_mem->stages; i++) + { + /* TODO(DJG): Update for implicit compute the stage */ + N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); + for (j = 0; j < i; j++) + { + N_VLinearSum(ONE, ark_mem->tempv1, + step_mem->Be->A[i][j], step_mem->Fe[j], + ark_mem->tempv1); + } + + retval = ark_mem->relax_mem->rjac(ark_mem->tempv1, ark_mem->tempv1, + ark_mem->user_data); + if (retval) return retval; + + ark_mem->relax_mem->est += step_mem->Be->b[i] * + N_VDotProd(ark_mem->tempv2, step_mem->Fe[j]); + } + ark_mem->relax_mem->est *= ark_mem->h; + + + retval = ark_mem->relax_mem->rfn(ark_mem->yn, &(ark_mem->relax_mem->rcur), + ark_mem->user_data); + if (retval) return retval; + + retval = arkRelax(ark_mem, &gam); + if (retval) return retval; + + ark_mem->h *= gam; + + N_VLinearSum(gam, ark_mem->ycur, (ONE - gam), ark_mem->yn, + ark_mem->ycur); + } + return(ARK_SUCCESS); } diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 785a32547f..37fa1b8bcf 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -27,6 +27,10 @@ #include +int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) { + return(arkSetRelaxFn(arkode_mem, rfn, rjac)); +} + /*=============================================================== ARKStep Optional input functions (wrappers for generic ARKode utility routines). All are documented in arkode_io.c. diff --git a/src/arkode/arkode_impl.h b/src/arkode/arkode_impl.h index c4eb48eebc..d29f372f7c 100644 --- a/src/arkode/arkode_impl.h +++ b/src/arkode/arkode_impl.h @@ -22,6 +22,7 @@ #include #include "arkode_adapt_impl.h" #include "arkode_root_impl.h" +#include "arkode_relaxation_impl.h" #include #include #include "sundials_context_impl.h" @@ -394,6 +395,9 @@ typedef struct ARKodeMemRec { /* Rootfinding Data */ ARKodeRootMem root_mem; /* root-finding structure */ + /* Relaxation Data */ + ARKodeRelaxMem relax_mem; /* relaxation structure */ + /* User-supplied step solution post-processing function */ ARKPostProcessFn ProcessStep; void* ps_data; /* pointer to user_data */ diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c new file mode 100644 index 0000000000..a6a9a7516c --- /dev/null +++ b/src/arkode/arkode_relaxation.c @@ -0,0 +1,125 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 relaxation (in time) + * functionality + * ---------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#include "arkode_impl.h" +#include +#include + + +int arkSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) +{ + ARKodeMem ark_mem; + + /* Check inputs */ + if (!arkode_mem) + { + arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", + "arkSetRelaxFn", MSG_ARK_NO_MEM); + return ARK_MEM_NULL; + } + ark_mem = (ARKodeMem) arkode_mem; + + if (!rfn) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkSetRelaxFn", + "The relaxation function is NULL."); + return ARK_ILL_INPUT; + } + + if (!rjac) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkSetRelaxFn", + "The relaxation Jacobian function is NULL."); + return ARK_ILL_INPUT; + } + + /* Allocate the relaxation memory structure */ + if (!(ark_mem->relax_mem)) + { + ark_mem->relax_mem = (ARKodeRelaxMem) malloc(sizeof(*(ark_mem->relax_mem))); + if (!(ark_mem->relax_mem)) return(ARK_MEM_FAIL); + + /* Zero out proj_mem */ + memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); + } + + ark_mem->relax_mem->rfn = rfn; + ark_mem->relax_mem->rjac = rjac; + + return ARK_SUCCESS; +} + +/* this could almost be implemented as a user supplied post processing + if the user had access to the method stages, NOTE this requires the + stage solutions not the stage derivatives (as posed right now) so + currently this requires the Z form of take step */ +/* Residual and Jacobian are stepper dependent? to account for imex vs erk vs dirk */ + +static int arkRelaxResidual(realtype gam, realtype* res, ARKodeMem ark_mem) +{ + int flag; + + /* yn + gam * dir = gam ycur + (1 - gam) yn */ + N_VLinearSum(gam, ark_mem->ycur, (ONE - gam), ark_mem->yn, + ark_mem->tempv1); + + flag = ark_mem->relax_mem->rfn(ark_mem->tempv1, res, ark_mem->user_data); + if (flag) return flag; + + /* res = r(yn + gam * dir) - r(yn) - gam * est */ + *res = *res - ark_mem->relax_mem->rcur - gam * ark_mem->relax_mem->est; + + return ARK_SUCCESS; +} + + +int arkRelax(void* arkode_mem, realtype* gam) +{ + int i, flag; + realtype res; + + ARKodeMem ark_mem; + + /* Check inputs */ + if (!arkode_mem) + { + arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", + "arkSetRelaxFn", MSG_ARK_NO_MEM); + return ARK_MEM_NULL; + } + ark_mem = (ARKodeMem) arkode_mem; + + *gam = ONE; + for (i = 0; i < 100; i++) + { + flag = arkRelaxResidual(*gam, &res, ark_mem); + if (flag) return flag; + + *gam += res; + } + + return 0; +} + +/*=============================================================== + EOF + ===============================================================*/ diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h new file mode 100644 index 0000000000..810f8904c8 --- /dev/null +++ b/src/arkode/arkode_relaxation_impl.h @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 + * ----------------------------------------------------------------------------- + * Implementation header file for ARKODE's relaxation (in time) functionality. + * ---------------------------------------------------------------------------*/ + +#ifndef _ARKODE_RELAX_IMPL_H +#define _ARKODE_RELAX_IMPL_H + +#include +#include + +/* ==================== * + * Relaxation Constants * + * ==================== */ + +#define ARK_RELAX_LRW 5 +#define ARK_RELAX_LIW 12 /* int, ptr, etc */ + +/* ========================= * + * Relaxation Data Structure * + * ========================= */ + +typedef struct ARKodeRelaxMemRec* ARKodeRelaxMem; + +struct ARKodeRelaxMemRec +{ + ARKRelaxFn rfn; + ARKRelaxJacFn rjac; + realtype est; + realtype rcur; +}; + +/* ==================== * + * Relaxation Functions * + * ==================== */ + +int arkSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); + +int arkRelax(void* arkode_mem, realtype* gam); + +/* int arkRelaxFree(ARKodeRelaxMem* relax_mem); */ +/* int arkRelaxPrint(ARKodeRelaMem relax_mem, FILE* outfile); */ + +#endif From 245685bf36a7201eff333d70187140cc248abb72 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 13:26:26 -0800 Subject: [PATCH 002/111] remove unused file --- .../arkode/C_serial/ark_conserved_exp_entropy.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy.h diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.h b/examples/arkode/C_serial/ark_conserved_exp_entropy.h deleted file mode 100644 index 5ff6edeb82..0000000000 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.h +++ /dev/null @@ -1,16 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2022, 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 - * ----------------------------------------------------------------------------- - * Header file for conserved exponential entropy example problem. - * ---------------------------------------------------------------------------*/ - From a1447b16cffb0e1b3eed96c6350e8e5bd9a857f7 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 15:03:21 -0800 Subject: [PATCH 003/111] update comments --- .../arkode/C_serial/ark_conserved_exp_entropy.c | 2 +- src/arkode/arkode_arkstep.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index 2d9c83fb75..4253acf18e 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -15,7 +15,7 @@ * * H. Ranocha, M. Sayyari, L. Dalcin, M. Parsani, and D.I. Ketcheson, * "Relaxation Runge-Kutta Methods: Fully-Discrete Explicit Entropy-Stable - * Schemes for the Compressible Euler and Navier-Stokes Equations, SIAM Journal + * Schemes for the Compressible Euler and Navier-Stokes Equations," SIAM Journal * on Scientific Computing, 42(2), 2020, https://doi.org/10.1137/19M1263480. * ----------------------------------------------------------------------------- * This example evolves system diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index bce99dedc6..ed4caf90df 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2553,20 +2553,22 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) } /* TODO(DJG): - Should this happen before or after the error estimate? If gamma is "small" - then the error estimate should still hold. Do not relax if the step would - fail the error test. Could relaxation reduce the error enough that the test - would pass? Would it be worthwhile to have an option for when to relax? + Should this happen before or after the error estimate? If before, this should happen in _ComputeSolutions. If after, should happen in arkCompleteStep? - operation for a set of dot products? + * If gamma is "small enough" then the error estimate should still hold. + * Do not relax if the step would fail the error test. + * Could relaxation reduce the error enough that the test would pass? + * Would it be worthwhile to have an option for when to relax? + Operation for a set of dot products? + Could gamma cause issues with tstop? */ if (ark_mem->relax_mem) { ark_mem->relax_mem->est = ZERO; for (i = 0; i < step_mem->stages; i++) { - /* TODO(DJG): Update for implicit compute the stage */ + /* TODO(DJG): Update for implicit and IMEX stages */ N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); for (j = 0; j < i; j++) { From a3fe4e9aecb1dde5f086a16df3dc172b8c03ba7d Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 15:05:12 -0800 Subject: [PATCH 004/111] add example input option to enable/disable relaxation --- .../C_serial/ark_conserved_exp_entropy.c | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index 4253acf18e..2ed190af92 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -135,19 +135,38 @@ int main(int argc, char *argv[]) FILE* UFID; /* Command line options */ - int implicit = 0; /* explicit */ - realtype fixed_h = RCONST(0.0); /* adaptive step */ + int implicit = 0; /* explicit */ + int relax = 1; /* enable relaxation */ + realtype fixed_h = RCONST(0.0); /* adaptive steps */ - /* ----- * - * Setup * - * ----- */ + /* -------------------- * + * Output Problem Setup * + * -------------------- */ if (argc > 1) implicit = atoi(argv[1]); - if (argc > 2) fixed_h = (realtype) atof(argv[2]); + if (argc > 2) relax = atoi(argv[2]); + if (argc > 3) fixed_h = (realtype) atof(argv[3]); printf("\nConserved Exponential Entropy problem:\n"); - printf(" reltol = %.1"ESYM"\n", reltol); - printf(" abstol = %.1"ESYM"\n\n",abstol); + if (implicit) + printf(" method = ERK\n"); + else + printf(" method = DIRK\n"); + if (relax) + printf(" relaxation = ON"); + else + printf(" relaxation = OFF"); + if (fixed_h > 0.0) + printf(" fixed h = %.6"ESYM"\n", fixed_h); + if (implicit || fixed_h > 0.0) + { + printf(" reltol = %.1"ESYM"\n", reltol); + printf(" abstol = %.1"ESYM"\n\n",abstol); + } + + /* ------------ * + * Setup ARKODE * + * ------------ */ /* Create the SUNDIALS context object for this simulation */ flag = SUNContext_Create(NULL, &ctx); @@ -177,8 +196,12 @@ int main(int argc, char *argv[]) flag = ARKStepSStolerances(arkode_mem, reltol, abstol); if (check_flag(flag, "ARKStepSStolerances")) return 1; - flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); - if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; + if (relax) + { + /* Enable relaxation methods */ + flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); + if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; + } if (fixed_h > 0.0) { From a928afb6f0fbfcfd1ab9f8387da6c9137ff5a1d0 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 15:07:44 -0800 Subject: [PATCH 005/111] fix bug with temp vector --- src/arkode/arkode_arkstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index ed4caf90df..29a6b6a4f1 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2577,7 +2577,7 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) ark_mem->tempv1); } - retval = ark_mem->relax_mem->rjac(ark_mem->tempv1, ark_mem->tempv1, + retval = ark_mem->relax_mem->rjac(ark_mem->tempv1, ark_mem->tempv2, ark_mem->user_data); if (retval) return retval; From eb238964805c707f6f1ed6b5bf067029d7345b43 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 20:46:54 -0800 Subject: [PATCH 006/111] update output --- .../arkode/C_serial/ark_conserved_exp_entropy.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index 2ed190af92..e8d519066e 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -136,7 +136,7 @@ int main(int argc, char *argv[]) /* Command line options */ int implicit = 0; /* explicit */ - int relax = 1; /* enable relaxation */ + int relax = 0; /* enable relaxation */ realtype fixed_h = RCONST(0.0); /* adaptive steps */ /* -------------------- * @@ -149,20 +149,21 @@ int main(int argc, char *argv[]) printf("\nConserved Exponential Entropy problem:\n"); if (implicit) - printf(" method = ERK\n"); - else printf(" method = DIRK\n"); + else + printf(" method = ERK\n"); if (relax) - printf(" relaxation = ON"); + printf(" relaxation = ON\n"); else - printf(" relaxation = OFF"); + printf(" relaxation = OFF\n"); if (fixed_h > 0.0) printf(" fixed h = %.6"ESYM"\n", fixed_h); if (implicit || fixed_h > 0.0) { printf(" reltol = %.1"ESYM"\n", reltol); - printf(" abstol = %.1"ESYM"\n\n",abstol); + printf(" abstol = %.1"ESYM"\n", abstol); } + printf("\n"); /* ------------ * * Setup ARKODE * From 4cfc0ba99090b42e999fb447bfcfd5525fee4eff Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 21:44:26 -0800 Subject: [PATCH 007/111] add RK4 --- .../C_serial/ark_conserved_exp_entropy.c | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index e8d519066e..dbbe80c4a3 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -111,10 +111,11 @@ int main(int argc, char *argv[]) realtype abstol = RCONST(1.0e-10); /* SUNDIALS context, vector, matrix, and linear solver objects */ - SUNContext ctx = NULL; - N_Vector y = NULL; - SUNMatrix A = NULL; - SUNLinearSolver LS = NULL; + SUNContext ctx = NULL; + N_Vector y = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; + ARKodeButcherTable B = NULL; /* Pointer to vector data array */ realtype* ydata; @@ -228,6 +229,30 @@ int main(int argc, char *argv[]) flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; } + else + { + /* Use RK4 */ + B = ARKodeButcherTable_Alloc(4, SUNFALSE); + + B->A[1][0] = RCONST(0.5); + B->A[2][1] = RCONST(0.5); + B->A[3][2] = RCONST(1.0); + + B->c[1] = RCONST(0.5); + B->c[2] = RCONST(0.5); + B->c[3] = RCONST(1.0); + + B->b[0] = RCONST(1.0) / RCONST(6.0); + B->b[1] = RCONST(1.0) / RCONST(3.0); + B->b[2] = RCONST(1.0) / RCONST(3.0); + B->b[3] = RCONST(1.0) / RCONST(6.0); + + B->q = 4; + B->p = 0; + + flag = ARKStepSetTables(arkode_mem, 4, 0, NULL, B); + if (check_flag(flag, "ARKStepSetTables")) return 1; + } /* Open output stream for results, output comment line */ UFID = fopen("solution.txt", "w"); From 0e7ff63da8afe1d93fc787a8b2cf2cb32a4d2d48 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 21:44:45 -0800 Subject: [PATCH 008/111] print relaxation value --- src/arkode/arkode_relaxation.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index a6a9a7516c..0ad87807ed 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -115,8 +115,12 @@ int arkRelax(void* arkode_mem, realtype* gam) if (flag) return flag; *gam += res; + + if (res < 1.0e-12) break; } + printf("gamma = %g\n", *gam); + return 0; } From 1e3308712ed20098f1ddc4672b64cc2099cc3630 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Feb 2022 21:44:58 -0800 Subject: [PATCH 009/111] fix indexing typo --- src/arkode/arkode_arkstep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 29a6b6a4f1..f8f166120c 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2582,11 +2582,10 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) if (retval) return retval; ark_mem->relax_mem->est += step_mem->Be->b[i] * - N_VDotProd(ark_mem->tempv2, step_mem->Fe[j]); + N_VDotProd(ark_mem->tempv2, step_mem->Fe[i]); } ark_mem->relax_mem->est *= ark_mem->h; - retval = ark_mem->relax_mem->rfn(ark_mem->yn, &(ark_mem->relax_mem->rcur), ark_mem->user_data); if (retval) return retval; From cbae50d99bc53cdb684f21c85153b6f722e07924 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 11 Feb 2022 08:42:43 -0800 Subject: [PATCH 010/111] add more member vars --- src/arkode/arkode_relaxation.c | 4 ++-- src/arkode/arkode_relaxation_impl.h | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 0ad87807ed..c3350b9345 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -109,14 +109,14 @@ int arkRelax(void* arkode_mem, realtype* gam) ark_mem = (ARKodeMem) arkode_mem; *gam = ONE; - for (i = 0; i < 100; i++) + for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { flag = arkRelaxResidual(*gam, &res, ark_mem); if (flag) return flag; *gam += res; - if (res < 1.0e-12) break; + if (res < ark_mem->relax_mem->tol) break; } printf("gamma = %g\n", *gam); diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 810f8904c8..f336c2a205 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -35,10 +35,12 @@ typedef struct ARKodeRelaxMemRec* ARKodeRelaxMem; struct ARKodeRelaxMemRec { - ARKRelaxFn rfn; - ARKRelaxJacFn rjac; + ARKRelaxFn rfn; /* relaxation function */ + ARKRelaxJacFn rjac; /* relaxation Jacobian */ realtype est; - realtype rcur; + realtype rcur; /* current relaxation function value */ + realtype tol; /* nonlinear solve tolerance */ + int max_iters; /* nonlinear solve max iterations */ }; /* ==================== * From c2c8917f89c16f2e6ff33b8549141d6dcab0f1b5 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 10 Mar 2022 14:48:54 -0800 Subject: [PATCH 011/111] get relaxation working for ERK methods --- .../C_serial/ark_conserved_exp_entropy.c | 4 +- src/arkode/arkode_arkstep.c | 76 ++++++++++++++++--- src/arkode/arkode_relaxation.c | 47 ++++++++---- 3 files changed, 98 insertions(+), 29 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index dbbe80c4a3..f7b8794fc7 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -275,10 +275,10 @@ int main(int argc, char *argv[]) printf(" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM"\n", t, ydata[0], ydata[1], RCONST(0.0)); - for (iout = 0; iout < nout; iout++) + for (iout = 0; iout < 1; iout++) { /* Evolve in time */ - flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_NORMAL); + flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; /* Output solution and change in entropy */ diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index f8f166120c..dea4e2a8fa 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2553,46 +2553,100 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) } /* TODO(DJG): - Should this happen before or after the error estimate? - If before, this should happen in _ComputeSolutions. - If after, should happen in arkCompleteStep? - * If gamma is "small enough" then the error estimate should still hold. - * Do not relax if the step would fail the error test. - * Could relaxation reduce the error enough that the test would pass? - * Would it be worthwhile to have an option for when to relax? - Operation for a set of dot products? - Could gamma cause issues with tstop? + 1. Update for implicit and IMEX stages + 2. Should this happen before or after the error estimate? + a. If before, this should happen in _ComputeSolutions. + b. If after, should happen in arkCompleteStep? + c. The relaxation parameter should be small, so applying relaxation + would only cause the error test to pass if it barely failed. This is + possible but seems unlikely. So relax after the error is computed. + d. Since this relaxation is just a factor on h we could try to update + the error estimate afterwards. + e. Could also have a threshold to attempt relaxation and see if the + relaxed error passes. + 3. Computing the change estimate requires s dot products. It could be + helpful to compute these in a single reduction but would require + saving s Jacobian vectors. + 4. Could relaxation cause issues with tstop? + 5. Update to sum loop to use linear combination. + 6. Add failure flags for conservation function on Jacobian. + 7. Add options to set tolerance and max iterations. + 8. How exactly does the relaxation equation need to be solved? + 9. Add other nonlinear solver options, for scalar problems Anderson become + a particular implementation of a secant method (does not require + rjac evaluation which requires communication). + 10. User supplied nonlinear solver? + 11. Make sure the FullRHS is computed at the right solution value and the + stored RHS evaluation is correct. + 12. Better separate ark_mem and relax_mem + 13. Don't use gamma for relaxation value (avoid confusion with I - gamma J) + 14. Option to reuse last relaxation value as initial guess or 1 + 15. With low-storage methods some of these values could be computed along + the way since not all RHS values will be saved. This could add extra + communication costs i.e., can't be combined or are thrown away on a step + failure. + + This feature could almost be implemented as a user supplied post processing + function if the user had access to the stage solutions and derivatives. + + Does the residual and Jacobian formulation using the "direction" and + "estimate" hold across methods? Looks like yes for ERK, DIRK, and IMEX-ARK. + What about MRI? */ if (ark_mem->relax_mem) { + /* Compute change estimate = h * sum_i b_i * rjac(z_i) . f_i */ ark_mem->relax_mem->est = ZERO; + for (i = 0; i < step_mem->stages; i++) { - /* TODO(DJG): Update for implicit and IMEX stages */ + /* z_i = y_n + h * sum_j a_i,j f_j */ N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); for (j = 0; j < i; j++) { N_VLinearSum(ONE, ark_mem->tempv1, - step_mem->Be->A[i][j], step_mem->Fe[j], + ark_mem->h * step_mem->Be->A[i][j], step_mem->Fe[j], ark_mem->tempv1); } + /* rjac(z_i) */ retval = ark_mem->relax_mem->rjac(ark_mem->tempv1, ark_mem->tempv2, ark_mem->user_data); if (retval) return retval; + /* Update estimate */ ark_mem->relax_mem->est += step_mem->Be->b[i] * N_VDotProd(ark_mem->tempv2, step_mem->Fe[i]); } + ark_mem->relax_mem->est *= ark_mem->h; + /* Compute direction = sum_i b_i * f_i */ + N_VConst(ZERO, ark_mem->tempv1); + for (i = 0; i < step_mem->stages; i++) + { + N_VLinearSum(ONE, ark_mem->tempv1, + step_mem->Be->b[i], step_mem->Fe[i], + ark_mem->tempv1); + } + N_VScale(ark_mem->h, ark_mem->tempv1, ark_mem->tempv1); + + /* rfun(y_n) */ retval = ark_mem->relax_mem->rfn(ark_mem->yn, &(ark_mem->relax_mem->rcur), ark_mem->user_data); if (retval) return retval; + /* Set solver tolerance and max iterations */ + ark_mem->relax_mem->tol = RCONST(1.0e-14); + ark_mem->relax_mem->max_iters = 2; + + /* Compute relaxation parameter */ retval = arkRelax(ark_mem, &gam); if (retval) return retval; + printf("relax = %23.16e\n", gam); + + /* Relax step size and solution */ ark_mem->h *= gam; N_VLinearSum(gam, ark_mem->ycur, (ONE - gam), ark_mem->yn, diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index c3350b9345..3af5d7a3a8 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -68,34 +68,48 @@ int arkSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) return ARK_SUCCESS; } -/* this could almost be implemented as a user supplied post processing - if the user had access to the method stages, NOTE this requires the - stage solutions not the stage derivatives (as posed right now) so - currently this requires the Z form of take step */ -/* Residual and Jacobian are stepper dependent? to account for imex vs erk vs dirk */ static int arkRelaxResidual(realtype gam, realtype* res, ARKodeMem ark_mem) { int flag; - /* yn + gam * dir = gam ycur + (1 - gam) yn */ - N_VLinearSum(gam, ark_mem->ycur, (ONE - gam), ark_mem->yn, - ark_mem->tempv1); + /* w = yn + gam * direction */ + N_VLinearSum(ONE, ark_mem->yn, gam, ark_mem->tempv1, ark_mem->tempv2); - flag = ark_mem->relax_mem->rfn(ark_mem->tempv1, res, ark_mem->user_data); + /* rfun(w) */ + flag = ark_mem->relax_mem->rfn(ark_mem->tempv2, res, ark_mem->user_data); if (flag) return flag; - /* res = r(yn + gam * dir) - r(yn) - gam * est */ + /* res = r(w) - r(y_n) - gam * estimate */ *res = *res - ark_mem->relax_mem->rcur - gam * ark_mem->relax_mem->est; return ARK_SUCCESS; } +static int arkRelaxJacobian(realtype gam, realtype* jac, ARKodeMem ark_mem) +{ + int flag; + + /* w = yn + gam * direction */ + N_VLinearSum(ONE, ark_mem->yn, gam, ark_mem->tempv1, ark_mem->tempv2); + + /* rjac(w) */ + flag = ark_mem->relax_mem->rjac(ark_mem->tempv2, ark_mem->tempv3, + ark_mem->user_data); + if (flag) return flag; + + /* jac = rjac(w) . direction - estimate */ + *jac = N_VDotProd(ark_mem->tempv3, ark_mem->tempv1) - ark_mem->relax_mem->est; + + return ARK_SUCCESS; +} + + int arkRelax(void* arkode_mem, realtype* gam) { int i, flag; - realtype res; + realtype res, jac; ARKodeMem ark_mem; @@ -114,14 +128,15 @@ int arkRelax(void* arkode_mem, realtype* gam) flag = arkRelaxResidual(*gam, &res, ark_mem); if (flag) return flag; - *gam += res; + flag = arkRelaxJacobian(*gam, &jac, ark_mem); + if (flag) return flag; - if (res < ark_mem->relax_mem->tol) break; - } + *gam -= res / jac; - printf("gamma = %g\n", *gam); + if (SUNRabs(res) < ark_mem->relax_mem->tol) break; + } - return 0; + return ARK_SUCCESS; } /*=============================================================== From f91de2c5ed5aff5ee8b7bfaf0a05598d6da9eee5 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Sun, 16 Oct 2022 19:57:13 -0700 Subject: [PATCH 012/111] clean up relaxation --- examples/arkode/C_serial/CMakeLists.txt | 2 +- .../C_serial/ark_conserved_exp_entropy.c | 283 ++++---- .../ark_conserved_exp_entropy_0_1_0.1.out | 121 ++++ include/arkode/arkode.h | 17 +- include/arkode/arkode_arkstep.h | 24 +- src/arkode/arkode.c | 17 +- src/arkode/arkode_arkstep.c | 285 +++++--- src/arkode/arkode_arkstep_impl.h | 7 + src/arkode/arkode_arkstep_io.c | 64 +- src/arkode/arkode_impl.h | 18 +- src/arkode/arkode_relaxation.c | 661 ++++++++++++++++-- src/arkode/arkode_relaxation_impl.h | 120 +++- 12 files changed, 1294 insertions(+), 325 deletions(-) create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index be7a6cc031..1a2a4235de 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,7 +26,7 @@ set(ARKODE_examples "ark_brusselator\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator1D\;\;exclude-single" - "ark_conserved_exp_entropy\;\;develop" + "ark_conserved_exp_entropy\;0 1 0.1\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" "ark_KrylovDemo_prec\;\;exclude-single" diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy.c index f7b8794fc7..9b73da073e 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy.c @@ -28,29 +28,30 @@ * u(0) = 1.0 * v(0) = 0.5 * - * The exponential entropy given by + * The system has the analytic solution * - * e = exp(u) + exp(v) - * - * e' = [ de/du; de/dv ] = [ exp(u); exp(v) ] - * - * is conserved for the analytical solution - * - * u = log(a * exp^(a * t)) - log(b) - * v = log(e + e^(3/2)) - log(b) + * u = log(e + e^(3/2)) - log(b) + * v = log(a * e^(a * t)) - log(b) * * where log is the natural logarithm, a = sqrt(e) + e, and * b = sqrt(e) + e^(a * t). * + * The conserved exponential entropy for the system is given by + * ent(u,v) = exp(u) + exp(v) with the Jacobian + * ent'(u,v) = [ de/du de/dv ]^T = [ exp(u) exp(v) ]^T. + * + * The problem is advanced in time with an explicit or implicit relaxed + * Runge-Kutta method to ensure conservation of the entropy. * ---------------------------------------------------------------------------*/ /* Header files */ -#include #include -#include /* access to ARKStep */ -#include /* access to serial N_Vector */ -#include /* access to dense SUNMatrix */ -#include /* access to dense SUNLinearSolver */ +#include + +#include +#include +#include +#include /* Precision-dependent output macros */ #if defined(SUNDIALS_EXTENDED_PRECISION) @@ -63,6 +64,7 @@ #define FSYM "f" #endif +/* Value of the natural number e */ #define EVAL 2.718281828459045235360287471352662497757247093699959574966 /* ----------------------- * @@ -70,24 +72,24 @@ * ----------------------- */ /* ODE RHS function */ -int f(realtype t, N_Vector y, N_Vector ydot, void *user_data); +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); /* ODE RHS Jacobian function */ -int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, void *user_data, +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); /* Entropy function */ -int Ent(N_Vector y, realtype* e, void* user_data); +int Ent(N_Vector* y, sunrealtype* e, void* user_data); /* Entropy Jacobian function */ -int JacEnt(N_Vector y, N_Vector J, void* user_data); +int JacEnt(N_Vector* y, N_Vector* J, void* user_data); /* ----------------- * * Utility functions * * ----------------- */ /* Analytic solution */ -int ans(realtype t, N_Vector y); +int ans(sunrealtype t, N_Vector y); /* Check return flags and pointers */ int check_flag(int flag, const char* funcname); @@ -97,73 +99,78 @@ int check_ptr(void* ptr, const char* funcname); * Main Program * * ------------ */ -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { /* Error-checking flag */ int flag; /* Initial and final times */ - realtype t0 = RCONST(0.0); - realtype tf = RCONST(5.0); + sunrealtype t0 = SUN_RCONST(0.0); + sunrealtype tf = SUN_RCONST(5.0); /* Relative and absolute tolerances */ - realtype reltol = RCONST(1.0e-6); - realtype abstol = RCONST(1.0e-10); + sunrealtype reltol = SUN_RCONST(1.0e-6); + sunrealtype abstol = SUN_RCONST(1.0e-10); /* SUNDIALS context, vector, matrix, and linear solver objects */ - SUNContext ctx = NULL; - N_Vector y = NULL; - SUNMatrix A = NULL; - SUNLinearSolver LS = NULL; - ARKodeButcherTable B = NULL; + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; + ARKodeButcherTable B = NULL; /* Pointer to vector data array */ - realtype* ydata; + sunrealtype* ydata; + sunrealtype* ytdata; /* Initial, current, and change in entropy value */ - realtype ent0, ent, dent; + sunrealtype ent0, ent, ent_err; + + /* Solution errors */ + sunrealtype u_err, v_err; /* ARKODE memory structure */ void* arkode_mem = NULL; /* ARKODE statistics */ - long int nst, nst_a, nfe, nfi, nsetups, nje, nfeLS, nni, ncfn, netf; + long int nst, nst_a, nfe, nfi; + long int nre, nrje, nri, nrf; + long int nsetups, nje, nfeLS, nni, ncfn, netf; /* Number of outputs, output counter, output times, and output file */ - int nout = 10; - int iout; - realtype t, tout, dtout; - FILE* UFID; + int nout = 10; + int iout; + sunrealtype t, tout, dtout; + FILE* UFID; /* Command line options */ - int implicit = 0; /* explicit */ - int relax = 0; /* enable relaxation */ - realtype fixed_h = RCONST(0.0); /* adaptive steps */ + int implicit = 0; /* explicit */ + int relax = 1; /* enable relaxation */ + int steps = 100; /* number of steps */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ /* -------------------- * * Output Problem Setup * * -------------------- */ if (argc > 1) implicit = atoi(argv[1]); - if (argc > 2) relax = atoi(argv[2]); - if (argc > 3) fixed_h = (realtype) atof(argv[3]); + if (argc > 2) relax = atoi(argv[2]); + if (argc > 3) fixed_h = (sunrealtype)atof(argv[3]); + if (argc > 4) steps = atoi(argv[4]); printf("\nConserved Exponential Entropy problem:\n"); - if (implicit) - printf(" method = DIRK\n"); - else - printf(" method = ERK\n"); - if (relax) - printf(" relaxation = ON\n"); - else - printf(" relaxation = OFF\n"); - if (fixed_h > 0.0) - printf(" fixed h = %.6"ESYM"\n", fixed_h); - if (implicit || fixed_h > 0.0) + if (implicit) printf(" method = DIRK\n"); + else printf(" method = ERK\n"); + if (relax) printf(" relaxation = ON\n"); + else printf(" relaxation = OFF\n"); + if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); + if (implicit || !(fixed_h > SUN_RCONST(0.0))) { - printf(" reltol = %.1"ESYM"\n", reltol); - printf(" abstol = %.1"ESYM"\n", abstol); + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); } + printf(" steps = %d\n", steps); printf("\n"); /* ------------ * @@ -179,19 +186,24 @@ int main(int argc, char *argv[]) if (check_ptr(y, "N_VNew_Serial")) return 1; ydata = N_VGetArrayPointer(y); + if (check_ptr(ydata, "N_VGetArrayPointer")) return 1; + + ydata[0] = SUN_RCONST(1.0); + ydata[1] = SUN_RCONST(0.5); - ydata[0] = RCONST(1.0); - ydata[1] = RCONST(0.5); + ytrue = N_VClone(y); + if (check_ptr(ytrue, "N_VClone")) return 1; + + ytdata = N_VGetArrayPointer(ytrue); + if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; /* Initial entropy */ - flag = Ent(y, &ent0, NULL); + flag = Ent(&y, &ent0, NULL); if (check_flag(flag, "Ent")) return 1; /* Initialize the ARKStep */ - if (implicit) - arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); - else - arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + if (implicit) arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); + else arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; /* Specify tolerances */ @@ -201,7 +213,7 @@ int main(int argc, char *argv[]) if (relax) { /* Enable relaxation methods */ - flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); + flag = ARKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; } @@ -229,23 +241,23 @@ int main(int argc, char *argv[]) flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; } - else + else if (fixed_h > 0.0) { /* Use RK4 */ B = ARKodeButcherTable_Alloc(4, SUNFALSE); - B->A[1][0] = RCONST(0.5); - B->A[2][1] = RCONST(0.5); - B->A[3][2] = RCONST(1.0); + B->A[1][0] = SUN_RCONST(0.5); + B->A[2][1] = SUN_RCONST(0.5); + B->A[3][2] = SUN_RCONST(1.0); - B->c[1] = RCONST(0.5); - B->c[2] = RCONST(0.5); - B->c[3] = RCONST(1.0); + B->c[1] = SUN_RCONST(0.5); + B->c[2] = SUN_RCONST(0.5); + B->c[3] = SUN_RCONST(1.0); - B->b[0] = RCONST(1.0) / RCONST(6.0); - B->b[1] = RCONST(1.0) / RCONST(3.0); - B->b[2] = RCONST(1.0) / RCONST(3.0); - B->b[3] = RCONST(1.0) / RCONST(6.0); + B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); + B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); B->q = 4; B->p = 0; @@ -255,8 +267,8 @@ int main(int argc, char *argv[]) } /* Open output stream for results, output comment line */ - UFID = fopen("solution.txt", "w"); - fprintf(UFID,"# t u v e\n"); + UFID = fopen("ark_conserved_exp_entropy.txt", "w"); + fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); /* --------------- * * Advance in Time * @@ -267,37 +279,56 @@ int main(int argc, char *argv[]) dtout = tf / nout; tout = t0 + dtout; - /* Write initial condition to disk */ - fprintf(UFID," %.16"ESYM" %.16"ESYM" %.16"ESYM"\n", t0, ydata[0], ydata[1]); - - printf(" t u v de\n"); - printf(" ---------------------------------------------------------\n"); - printf(" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM"\n", - t, ydata[0], ydata[1], RCONST(0.0)); - - for (iout = 0; iout < 1; iout++) + /* Output the initial condition and entropy */ + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM + " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t0, ydata[0], ydata[1], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0), + SUN_RCONST(0.0)); + + printf(" t u v e " + "delta e\n"); + printf(" " + "---------------------------------------------------------------------" + "---\n"); + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); + + for (iout = 0; iout < steps; iout++) { /* Evolve in time */ flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; - /* Output solution and change in entropy */ - flag = Ent(y, &ent, NULL); + /* Output solution and errors */ + flag = Ent(&y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; - dent = fabs(ent - ent0); + flag = ans(t, ytrue); + if (check_flag(flag, "ans")) return 1; + + ent_err = ent - ent0; + u_err = ydata[0] - ytdata[0]; + v_err = ydata[1] - ytdata[1]; + + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + t, ydata[0], ydata[1], ent, ent_err); - printf(" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM" %14.6"ESYM"\n", - t, ydata[0], ydata[1], dent); - fprintf(UFID," %.16"ESYM" %.16"ESYM" %.16"ESYM" %.16"ESYM"\n", - t, ydata[0], ydata[1], dent); + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM + " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); /* Update output time */ tout += dtout; tout = (tout > tf) ? tf : tout; } - printf(" ---------------------------------------------------------\n"); + printf(" " + "---------------------------------------------------------------------" + "---\n"); fclose(UFID); /* ------------ * @@ -345,6 +376,26 @@ int main(int argc, char *argv[]) printf(" Total number of Jacobian evaluations = %li\n", nje); printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); } + + if (relax) + { + flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); + check_flag(flag, "ARKStepGetNumRelaxFnEvals"); + + flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); + check_flag(flag, "ARKStepGetNumRelaxJacEvals"); + + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nri); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxSolveFails"); + + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation iters = %li\n", nri); + printf(" Total Relaxation fails = %li\n", nrf); + } printf("\n"); /* -------- * @@ -356,36 +407,34 @@ int main(int argc, char *argv[]) SUNLinSolFree(LS); SUNMatDestroy(A); N_VDestroy(y); + N_VDestroy(ytrue); SUNContext_Free(&ctx); return flag; } - /* ----------------------- * * User-supplied functions * * ----------------------- */ - /* ODE RHS function f(t,y). */ -int f(realtype t, N_Vector y, N_Vector ydot, void* user_data) +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { - realtype* ydata = N_VGetArrayPointer(y); - realtype* fdata = N_VGetArrayPointer(ydot); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* fdata = N_VGetArrayPointer(ydot); fdata[0] = -exp(ydata[1]); - fdata[1] = exp(ydata[0]); + fdata[1] = exp(ydata[0]); return 0; } - /* ODE RHS Jacobian function J(t,y) = df/dy. */ -int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) { - realtype* ydata = N_VGetArrayPointer(y); - realtype* Jdata = SUNDenseMatrix_Data(J); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* Jdata = SUNDenseMatrix_Data(J); /* column 0 */ Jdata[0] = 0; @@ -398,23 +447,21 @@ int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, return 0; } - /* Entropy function e(y) */ -int Ent(N_Vector y, realtype* e, void* user_data) +int Ent(N_Vector* y, sunrealtype* e, void* user_data) { - realtype* ydata = N_VGetArrayPointer(y); + sunrealtype* ydata = N_VGetArrayPointer(y[0]); - *e = exp(ydata[0]) + exp(ydata[1]); + e[0] = exp(ydata[0]) + exp(ydata[1]); return 0; } - /* Entropy function Jacobian Je(y) = de/dy */ -int JacEnt(N_Vector y, N_Vector J, void* user_data) +int JacEnt(N_Vector* y, N_Vector* J, void* user_data) { - realtype* ydata = N_VGetArrayPointer(y); - realtype* jdata = N_VGetArrayPointer(J); + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* jdata = N_VGetArrayPointer(J[0]); jdata[0] = exp(ydata[0]); jdata[1] = exp(ydata[1]); @@ -422,28 +469,25 @@ int JacEnt(N_Vector y, N_Vector J, void* user_data) return 0; } - /* ----------------- * * Utility functions * * ----------------- */ - /* Analytic solution */ -int ans(realtype t, N_Vector y) +int ans(sunrealtype t, N_Vector y) { - realtype a, b; - realtype* ydata = N_VGetArrayPointer(y); + sunrealtype a, b; + sunrealtype* ydata = N_VGetArrayPointer(y); a = sqrt(EVAL) + EVAL; - b = sqrt(EVAL) + pow(EVAL, a * t); + b = sqrt(EVAL) + exp(a * t); - ydata[0] = log(a * exp(a * t)) - log(b); - ydata[1] = log(EVAL + exp(a * t)) - log(b); + ydata[0] = log(EVAL + exp(SUN_RCONST(1.5))) - log(b); + ydata[1] = log(a * exp(a * t)) - log(b); return 0; } - /* Check return flags */ int check_flag(int flag, const char* funcname) { @@ -456,7 +500,6 @@ int check_flag(int flag, const char* funcname) return 0; } - /* Check return pointers */ int check_ptr(void* ptr, const char* funcname) { diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out new file mode 100644 index 0000000000..8b554ec945 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out @@ -0,0 +1,121 @@ + +Conserved Exponential Entropy problem: + method = ERK + relaxation = ON + fixed h = 0.1 + steps = 100 + + t u v e delta e + ------------------------------------------------------------------------ + 0.000000e+00 1.000000e+00 5.000000e-01 4.367003e+00 0.000000e+00 + 9.999382e-02 8.121005e-01 7.487561e-01 4.367003e+00 0.000000e+00 + 1.999992e-01 5.769249e-01 9.502857e-01 4.367003e+00 0.000000e+00 + 3.000146e-01 2.959876e-01 1.106101e+00 4.367003e+00 0.000000e+00 + 4.000353e-01 -2.543835e-02 1.221455e+00 4.367003e+00 -8.881784e-16 + 5.000560e-01 -3.799263e-01 1.303752e+00 4.367003e+00 -1.776357e-15 + 6.000730e-01 -7.596828e-01 1.360768e+00 4.367003e+00 -1.776357e-15 + 7.000851e-01 -1.157790e+00 1.399414e+00 4.367003e+00 -8.881784e-16 + 8.000923e-01 -1.568735e+00 1.425201e+00 4.367003e+00 -8.881784e-16 + 9.000955e-01 -1.988427e+00 1.442224e+00 4.367003e+00 -1.776357e-15 + 1.000096e+00 -2.413974e+00 1.453379e+00 4.367003e+00 0.000000e+00 + 1.100094e+00 -2.843391e+00 1.460654e+00 4.367003e+00 -1.776357e-15 + 1.200091e+00 -3.275348e+00 1.465383e+00 4.367003e+00 -1.776357e-15 + 1.300086e+00 -3.708962e+00 1.468450e+00 4.367003e+00 -1.776357e-15 + 1.400081e+00 -4.143654e+00 1.470437e+00 4.367003e+00 -2.664535e-15 + 1.500076e+00 -4.579044e+00 1.471724e+00 4.367003e+00 -2.664535e-15 + 1.600070e+00 -5.014888e+00 1.472556e+00 4.367003e+00 -3.552714e-15 + 1.700064e+00 -5.451025e+00 1.473094e+00 4.367003e+00 -4.440892e-15 + 1.800058e+00 -5.887351e+00 1.473441e+00 4.367003e+00 -5.329071e-15 + 1.900052e+00 -6.323800e+00 1.473666e+00 4.367003e+00 -5.329071e-15 + 2.000046e+00 -6.760328e+00 1.473812e+00 4.367003e+00 -4.440892e-15 + 2.100040e+00 -7.196908e+00 1.473905e+00 4.367003e+00 -3.552714e-15 + 2.200034e+00 -7.633521e+00 1.473966e+00 4.367003e+00 -2.664535e-15 + 2.300028e+00 -8.070155e+00 1.474005e+00 4.367003e+00 -8.881784e-16 + 2.400021e+00 -8.506803e+00 1.474031e+00 4.367003e+00 -1.776357e-15 + 2.500015e+00 -8.943460e+00 1.474047e+00 4.367003e+00 -2.664535e-15 + 2.600009e+00 -9.380122e+00 1.474058e+00 4.367003e+00 -1.776357e-15 + 2.700003e+00 -9.816789e+00 1.474064e+00 4.367003e+00 0.000000e+00 + 2.799997e+00 -1.025346e+01 1.474069e+00 4.367003e+00 8.881784e-16 + 2.899990e+00 -1.069013e+01 1.474072e+00 4.367003e+00 8.881784e-15 + 2.999984e+00 -1.112680e+01 1.474074e+00 4.367003e+00 1.509903e-14 + 3.099978e+00 -1.156347e+01 1.474075e+00 4.367003e+00 1.865175e-14 + 3.199972e+00 -1.200014e+01 1.474076e+00 4.367003e+00 2.131628e-14 + 3.299966e+00 -1.243682e+01 1.474076e+00 4.367003e+00 2.309264e-14 + 3.399959e+00 -1.287349e+01 1.474076e+00 4.367003e+00 2.220446e-14 + 3.499953e+00 -1.331016e+01 1.474077e+00 4.367003e+00 2.309264e-14 + 3.599947e+00 -1.374684e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 3.699941e+00 -1.418351e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 3.799935e+00 -1.462018e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 3.899928e+00 -1.505686e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 3.999922e+00 -1.549353e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 4.099916e+00 -1.593020e+01 1.474077e+00 4.367003e+00 2.398082e-14 + 4.199910e+00 -1.636688e+01 1.474077e+00 4.367003e+00 2.575717e-14 + 4.299904e+00 -1.680355e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 4.399898e+00 -1.724022e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 4.499891e+00 -1.767689e+01 1.474077e+00 4.367003e+00 2.309264e-14 + 4.599885e+00 -1.811357e+01 1.474077e+00 4.367003e+00 2.398082e-14 + 4.699879e+00 -1.855024e+01 1.474077e+00 4.367003e+00 2.398082e-14 + 4.799873e+00 -1.898691e+01 1.474077e+00 4.367003e+00 2.486900e-14 + 4.899866e+00 -1.942359e+01 1.474077e+00 4.367003e+00 2.398082e-14 + 4.999860e+00 -1.986026e+01 1.474077e+00 4.367003e+00 2.309264e-14 + 5.099854e+00 -2.029693e+01 1.474077e+00 4.367003e+00 2.220446e-14 + 5.199854e+00 -2.073363e+01 1.474077e+00 4.367003e+00 3.019807e-14 + 5.299854e+00 -2.117033e+01 1.474077e+00 4.367003e+00 3.463896e-14 + 5.399854e+00 -2.160703e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 5.499854e+00 -2.204373e+01 1.474077e+00 4.367003e+00 4.174439e-14 + 5.599854e+00 -2.248043e+01 1.474077e+00 4.367003e+00 4.352074e-14 + 5.699854e+00 -2.291713e+01 1.474077e+00 4.367003e+00 4.352074e-14 + 5.799854e+00 -2.335383e+01 1.474077e+00 4.367003e+00 4.352074e-14 + 5.899854e+00 -2.379053e+01 1.474077e+00 4.367003e+00 4.352074e-14 + 5.999854e+00 -2.422723e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 6.099854e+00 -2.466394e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 6.199854e+00 -2.510064e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 6.299854e+00 -2.553734e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 6.399854e+00 -2.597404e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 6.499854e+00 -2.641074e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 6.599854e+00 -2.684744e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 6.699854e+00 -2.728414e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 6.799854e+00 -2.772084e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 6.899854e+00 -2.815754e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 6.999854e+00 -2.859424e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 7.099854e+00 -2.903094e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 7.199854e+00 -2.946764e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 7.299854e+00 -2.990434e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 7.399854e+00 -3.034104e+01 1.474077e+00 4.367003e+00 4.529710e-14 + 7.499854e+00 -3.077774e+01 1.474077e+00 4.367003e+00 4.440892e-14 + 7.599854e+00 -3.121444e+01 1.474077e+00 4.367003e+00 4.352074e-14 + 7.699854e+00 -3.165114e+01 1.474077e+00 4.367003e+00 4.263256e-14 + 7.799854e+00 -3.208784e+01 1.474077e+00 4.367003e+00 4.263256e-14 + 7.899854e+00 -3.252454e+01 1.474077e+00 4.367003e+00 4.174439e-14 + 7.999854e+00 -3.296124e+01 1.474077e+00 4.367003e+00 4.174439e-14 + 8.099854e+00 -3.339794e+01 1.474077e+00 4.367003e+00 4.263256e-14 + 8.199854e+00 -3.383464e+01 1.474077e+00 4.367003e+00 4.085621e-14 + 8.299854e+00 -3.427134e+01 1.474077e+00 4.367003e+00 3.996803e-14 + 8.399854e+00 -3.470804e+01 1.474077e+00 4.367003e+00 3.996803e-14 + 8.499854e+00 -3.514474e+01 1.474077e+00 4.367003e+00 3.996803e-14 + 8.599854e+00 -3.558144e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 8.699854e+00 -3.601814e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 8.799854e+00 -3.645484e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 8.899854e+00 -3.689154e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 8.999854e+00 -3.732824e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.099854e+00 -3.776494e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.199854e+00 -3.820164e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.299854e+00 -3.863835e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.399854e+00 -3.907505e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.499854e+00 -3.951175e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.599854e+00 -3.994845e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.699854e+00 -4.038515e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.799854e+00 -4.082185e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.899854e+00 -4.125855e+01 1.474077e+00 4.367003e+00 3.907985e-14 + 9.999854e+00 -4.169525e+01 1.474077e+00 4.367003e+00 3.907985e-14 + ------------------------------------------------------------------------ + +Final Solver Statistics: + Internal solver steps = 100 (attempted = 100) + Total number of error test failures = 0 + Total RHS evals: Fe = 401, Fi = 0 + Total Relaxation Fn evals = 100 + Total Relaxation Jac evals = 400 + Total Relaxation iters = 79 + Total Relaxation fails = 0 + diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index 1277e0a4cc..47207b6cbc 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -132,6 +132,10 @@ extern "C" { #define ARK_CONTEXT_ERR -42 +#define ARK_RELAX_MEM_NULL -43 +#define ARK_RELAX_FUNC_FAIL -44 +#define ARK_RELAX_JAC_FAIL -45 + #define ARK_UNRECOGNIZED_ERROR -99 /* ------------------------------ @@ -170,9 +174,9 @@ typedef int (*ARKPostProcessFn)(realtype t, N_Vector y, typedef int (*ARKStagePredictFn)(realtype t, N_Vector zpred, void *user_data); -typedef int (*ARKRelaxFn)(N_Vector y, realtype* r, void* user_data); +typedef int (*ARKRelaxFn)(N_Vector* y, realtype* r, void* user_data); -typedef int (*ARKRelaxJacFn)(N_Vector y, N_Vector J, void* user_data); +typedef int (*ARKRelaxJacFn)(N_Vector* y, N_Vector* J, void* user_data); /* -------------------------- * MRIStep Inner Stepper Type @@ -180,6 +184,15 @@ typedef int (*ARKRelaxJacFn)(N_Vector y, N_Vector J, void* user_data); typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; +/* -------------------------- + * Relaxation Solver Options + * -------------------------- */ + +typedef enum { + ARK_RELAX_NEWTON, + ARK_RELAX_FIXEDPOINT, +} ARKRelaxationSolver; + #ifdef __cplusplus } #endif diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 11ec2e836a..9ffbac8772 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -465,9 +465,27 @@ SUNDIALS_EXPORT void ARKStepPrintMem(void* arkode_mem, FILE* outfile); SUNDIALS_EXPORT int ARKStepCreateMRIStepInnerStepper(void *arkode_mem, MRIStepInnerStepper *stepper); - -SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, - ARKRelaxJacFn rjac); +/* Relaxation functions */ +SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, + ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, + sunrealtype eta_rf); +SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, + sunrealtype lower); +SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); +SUNDIALS_EXPORT int ARKSteSetRelaxSolver(void* arkode_mem, + ARKRelaxationSolver solver); +SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, + sunrealtype upper); +SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, + long int* r_evals); +SUNDIALS_EXPORT int ARKStepGetNumRelaxJacEvals(void* arkode_mem, + long int* J_evals); +SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveFails(void* arkode_mem, + long int* fails); +SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveIters(void* arkode_mem, + long int* iters); #ifdef __cplusplus } diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 914ea96f8e..0cd8d9e285 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -95,7 +95,8 @@ ARKodeMem arkCreate(SUNContext sunctx) ark_mem->constraints = NULL; /* Initialize relaxation variables */ - ark_mem->relax_mem = NULL; + ark_mem->relax_enabled = SUNFALSE; + ark_mem->relax_mem = NULL; /* Initialize diagnostics reporting variables */ ark_mem->report = SUNFALSE; @@ -853,6 +854,13 @@ int arkEvolve(ARKodeMem ark_mem, realtype tout, N_Vector yout, kflag = arkCheckConvergence(ark_mem, &nflag, &ncf); if (kflag < 0) break; + /* Perform relaxation */ + if (ark_mem->relax_enabled && (kflag == ARK_SUCCESS)) + { + kflag = arkRelax(ark_mem, &dsm, &nflag); + if (kflag < 0) break; + } + /* perform constraint-handling (if selected, and if solver check passed) */ if (ark_mem->constraintsSet && (kflag == ARK_SUCCESS)) { kflag = arkCheckConstraints(ark_mem, &constrfails, &nflag); @@ -1097,6 +1105,13 @@ void arkFree(void **arkode_mem) ark_mem->root_mem = NULL; } + /* free the relaxation module */ + if (ark_mem->relax_mem) + { + (void) arkRelaxDestroy(ark_mem->relax_mem); + ark_mem->relax_mem = NULL; + } + free(*arkode_mem); *arkode_mem = NULL; } diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 93f5f8b619..75bf6bede4 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2498,9 +2498,8 @@ int arkStep_StageSetup(ARKodeMem ark_mem, booleantype implicit) int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) { /* local data */ - int retval, i, j, nvec; + int retval, j, nvec; N_Vector y, yerr; - realtype gam; realtype* cvals; N_Vector* Xvecs; ARKodeARKStepMem step_mem; @@ -2572,107 +2571,6 @@ int arkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) *dsmPtr = N_VWrmsNorm(yerr, ark_mem->ewt); } - /* TODO(DJG): - 1. Update for implicit and IMEX stages - 2. Should this happen before or after the error estimate? - a. If before, this should happen in _ComputeSolutions. - b. If after, should happen in arkCompleteStep? - c. The relaxation parameter should be small, so applying relaxation - would only cause the error test to pass if it barely failed. This is - possible but seems unlikely. So relax after the error is computed. - d. Since this relaxation is just a factor on h we could try to update - the error estimate afterwards. - e. Could also have a threshold to attempt relaxation and see if the - relaxed error passes. - 3. Computing the change estimate requires s dot products. It could be - helpful to compute these in a single reduction but would require - saving s Jacobian vectors. - 4. Could relaxation cause issues with tstop? - 5. Update to sum loop to use linear combination. - 6. Add failure flags for conservation function on Jacobian. - 7. Add options to set tolerance and max iterations. - 8. How exactly does the relaxation equation need to be solved? - 9. Add other nonlinear solver options, for scalar problems Anderson become - a particular implementation of a secant method (does not require - rjac evaluation which requires communication). - 10. User supplied nonlinear solver? - 11. Make sure the FullRHS is computed at the right solution value and the - stored RHS evaluation is correct. - 12. Better separate ark_mem and relax_mem - 13. Don't use gamma for relaxation value (avoid confusion with I - gamma J) - 14. Option to reuse last relaxation value as initial guess or 1 - 15. With low-storage methods some of these values could be computed along - the way since not all RHS values will be saved. This could add extra - communication costs i.e., can't be combined or are thrown away on a step - failure. - - This feature could almost be implemented as a user supplied post processing - function if the user had access to the stage solutions and derivatives. - - Does the residual and Jacobian formulation using the "direction" and - "estimate" hold across methods? Looks like yes for ERK, DIRK, and IMEX-ARK. - What about MRI? - */ - if (ark_mem->relax_mem) - { - /* Compute change estimate = h * sum_i b_i * rjac(z_i) . f_i */ - ark_mem->relax_mem->est = ZERO; - - for (i = 0; i < step_mem->stages; i++) - { - /* z_i = y_n + h * sum_j a_i,j f_j */ - N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); - for (j = 0; j < i; j++) - { - N_VLinearSum(ONE, ark_mem->tempv1, - ark_mem->h * step_mem->Be->A[i][j], step_mem->Fe[j], - ark_mem->tempv1); - } - - /* rjac(z_i) */ - retval = ark_mem->relax_mem->rjac(ark_mem->tempv1, ark_mem->tempv2, - ark_mem->user_data); - if (retval) return retval; - - /* Update estimate */ - ark_mem->relax_mem->est += step_mem->Be->b[i] * - N_VDotProd(ark_mem->tempv2, step_mem->Fe[i]); - } - - ark_mem->relax_mem->est *= ark_mem->h; - - /* Compute direction = sum_i b_i * f_i */ - N_VConst(ZERO, ark_mem->tempv1); - for (i = 0; i < step_mem->stages; i++) - { - N_VLinearSum(ONE, ark_mem->tempv1, - step_mem->Be->b[i], step_mem->Fe[i], - ark_mem->tempv1); - } - N_VScale(ark_mem->h, ark_mem->tempv1, ark_mem->tempv1); - - /* rfun(y_n) */ - retval = ark_mem->relax_mem->rfn(ark_mem->yn, &(ark_mem->relax_mem->rcur), - ark_mem->user_data); - if (retval) return retval; - - /* Set solver tolerance and max iterations */ - ark_mem->relax_mem->tol = RCONST(1.0e-14); - ark_mem->relax_mem->max_iters = 2; - - /* Compute relaxation parameter */ - retval = arkRelax(ark_mem, &gam); - if (retval) return retval; - - printf("relax = %23.16e\n", gam); - - /* Relax step size and solution */ - ark_mem->h *= gam; - - N_VLinearSum(gam, ark_mem->ycur, (ONE - gam), ark_mem->yn, - ark_mem->ycur); - } - return(ARK_SUCCESS); } @@ -3055,6 +2953,187 @@ int arkStep_SetInnerForcing(void* arkode_mem, realtype tshift, realtype tscale, return(0); } +/* ----------------------------------------------------------------------------- + * arkStep_RelaxDeltaY + * + * Computes the RK update to yn for use in relaxation methods + * ---------------------------------------------------------------------------*/ + +int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) +{ + int i, nvec, retval; + realtype* cvals; + N_Vector* Xvecs; + ARKodeARKStepMem step_mem; + + /* Access the stepper memory structure */ + if (!(ark_mem->step_mem)) + { + arkProcessError(ark_mem, ARK_MEM_NULL, "ARKODE::ARKStep", + "arkStep_RelaxDeltaY", MSG_ARKSTEP_NO_MEM); + return ARK_MEM_NULL; + } + step_mem = (ARKodeARKStepMem)(ark_mem->step_mem); + + /* Set arrays for fused vector operation */ + cvals = step_mem->cvals; + Xvecs = step_mem->Xvecs; + + nvec = 0; + for (i = 0; i < step_mem->stages; i++) + { + /* Explicit pieces */ + if (step_mem->explicit) + { + cvals[nvec] = ark_mem->h * step_mem->Be->b[i]; + Xvecs[nvec] = step_mem->Fe[i]; + nvec++; + } + /* Implicit pieces */ + if (step_mem->implicit) + { + cvals[nvec] = ark_mem->h * step_mem->Bi->b[i]; + Xvecs[nvec] = step_mem->Fi[i]; + nvec++; + } + } + + /* Compute time step update (delta_y) */ + retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv1); + if (retval) return ARK_VECTOROP_ERR; + + *delta_y = ark_mem->tempv1; + + return ARK_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + * arkStep_RelaxDeltaE + * + * Computes the change in the relaxation functions for use in relaxation methods + * delta_e = h * sum_i b_i * + * ---------------------------------------------------------------------------*/ + +int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, + ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, + N_Vector* work_space_2, long int* num_relax_jac_evals, + sunrealtype* delta_e_out) +{ + int i, j, nvec, retval; + realtype* cvals; + N_Vector* Xvecs; + ARKodeARKStepMem step_mem; + + /* Access the stepper memory structure */ + if (!(ark_mem->step_mem)) + { + arkProcessError(ark_mem, ARK_MEM_NULL, "ARKODE::ARKStep", + "arkStep_RelaxDeltaE", MSG_ARKSTEP_NO_MEM); + return ARK_MEM_NULL; + } + step_mem = (ARKodeARKStepMem)(ark_mem->step_mem); + + /* Initialize output */ + for (j = 0; j < num_relax_fn; j++) + delta_e_out[j] = ZERO; + + /* Set arrays for fused vector operation */ + cvals = step_mem->cvals; + Xvecs = step_mem->Xvecs; + + for (i = 0; i < step_mem->stages; i++) + { + nvec = 0; + + /* Start with y_n */ + cvals[nvec] = ONE; + Xvecs[nvec] = ark_mem->yn; + nvec++; + + /* Explicit pieces */ + if (step_mem->explicit) + { + for (j = 0; j < i; j++) + { + cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; + Xvecs[nvec] = step_mem->Fe[j]; + nvec++; + } + } + + /* Implicit pieces */ + if (step_mem->implicit) + { + for (j = 0; j <= i; j++) + { + cvals[nvec] = ark_mem->h * step_mem->Bi->A[i][j]; + Xvecs[nvec] = step_mem->Fi[j]; + nvec++; + } + } + + /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ae[i,j] Fi[j] */ + retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv2); + if (retval) return ARK_VECTOROP_ERR; + + /* Duplicate stage to compute entropy Jacobians at z_i */ + for (j = 0; j < num_relax_fn; j++) + N_VScale(ONE, ark_mem->tempv2, work_space_1[j]); + + /* Evaluate the Jacobians at z_i */ + retval = relax_jac_fn(work_space_1, work_space_2, ark_mem->user_data); + (*num_relax_jac_evals)++; + if (retval < 0) return ARK_RELAX_JAC_FAIL; + if (retval > 0) return ARK_RELAX_JAC_RECV; + + /* Update estimates */ + if (step_mem->explicit && step_mem->implicit) + { + N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], + step_mem->Bi->b[i], step_mem->Fi[i], + ark_mem->tempv1); + for (j = 0; j < num_relax_fn; j++) + { + delta_e_out[j] += N_VDotProdLocal(work_space_2[j], ark_mem->tempv1); + } + } + else if (step_mem->explicit) + { + for (j = 0; j < num_relax_fn; j++) + delta_e_out[j] += step_mem->Be->b[i] * N_VDotProdLocal(work_space_2[j], + step_mem->Fe[i]); + } + else if (step_mem->implicit) + { + for (j = 0; j < num_relax_fn; j++) + delta_e_out[j] += step_mem->Bi->b[i] * N_VDotProdLocal(work_space_2[j], + step_mem->Fi[i]); + } + } + + /* Ignore negative return for node-local vectors where this is a non-op */ + N_VDotProdMultiAllReduce(num_relax_fn, ark_mem->tempv1, delta_e_out); + + for (j = 0; j < num_relax_fn; j++) + delta_e_out[j] *= ark_mem->h; + + /* printf("de = %23.16e\n", delta_e_out[0]); */ + + return ARK_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + * arkStep_GetOrder + * + * Returns the method order + * ---------------------------------------------------------------------------*/ + +int arkStep_GetOrder(ARKodeMem ark_mem) +{ + ARKodeARKStepMem step_mem = (ARKodeARKStepMem)(ark_mem->step_mem); + return step_mem->q; +} + /*=============================================================== EOF ===============================================================*/ diff --git a/src/arkode/arkode_arkstep_impl.h b/src/arkode/arkode_arkstep_impl.h index cafa58c266..3b352038ed 100644 --- a/src/arkode/arkode_arkstep_impl.h +++ b/src/arkode/arkode_arkstep_impl.h @@ -229,6 +229,13 @@ int arkStep_MRIStepInnerFullRhs(MRIStepInnerStepper stepper, realtype t, int arkStep_MRIStepInnerReset(MRIStepInnerStepper stepper, realtype tR, N_Vector yR); +/* private functions for relaxation */ +int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y); +int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, + ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, + N_Vector* work_space_2, long int* relax_jac_fn_evals, + sunrealtype* delta_e_out); +int arkStep_GetOrder(ARKodeMem ark_mem); /*=============================================================== Reusable ARKStep Error Messages diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index d84b511e75..0a570a65b1 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -26,11 +26,6 @@ #include #include - -int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) { - return(arkSetRelaxFn(arkode_mem, rfn, rjac)); -} - /*=============================================================== ARKStep Optional input functions (wrappers for generic ARKODE utility routines). All are documented in arkode_io.c. @@ -254,7 +249,66 @@ int ARKStepGetLastMassFlag(void *arkode_mem, long int *flag) { char *ARKStepGetLinReturnFlagName(long int flag) { return(arkLSGetReturnFlagName(flag)); } +/* ----------------------------------------------------------------------------- + * Wrappers for the ARKODE relaxation module + * ---------------------------------------------------------------------------*/ + +int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, + ARKRelaxJacFn rjac) +{ + return arkRelaxCreate(arkode_mem, nrfn, rfn, rjac, arkStep_RelaxDeltaY, + arkStep_RelaxDeltaE, arkStep_GetOrder); +} + +int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +{ + return arkRelaxSetEtaFail(arkode_mem, eta_rf); +} + +int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +{ + return arkRelaxSetLowerBound(arkode_mem, lower); +} + +int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) +{ + return arkRelaxSetMaxIters(arkode_mem, max_iters); +} + +int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +{ + return arkRelaxSetSolver(arkode_mem, solver); +} +int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +{ + return arkRelaxSetTol(arkode_mem, tol); +} + +int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) +{ + return arkRelaxSetUpperBound(arkode_mem, upper); +} + +int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) +{ + return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); +} + +int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) +{ + return arkRelaxGetNumRelaxJacEvals(arkode_mem, J_evals); +} + +int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) +{ + return arkRelaxGetNumSolveFails(arkode_mem, fails); +} + +int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) +{ + return arkRelaxGetNumSolveIters(arkode_mem, iters); +} /*=============================================================== ARKStep optional input functions -- stepper-specific diff --git a/src/arkode/arkode_impl.h b/src/arkode/arkode_impl.h index cba2ac09c6..dc0af9b9c1 100644 --- a/src/arkode/arkode_impl.h +++ b/src/arkode/arkode_impl.h @@ -18,13 +18,16 @@ #define _ARKODE_IMPL_H #include + #include #include -#include "arkode_adapt_impl.h" -#include "arkode_root_impl.h" -#include "arkode_relaxation_impl.h" #include #include + +#include "arkode_types_impl.h" +#include "arkode_adapt_impl.h" +#include "arkode_relaxation_impl.h" +#include "arkode_root_impl.h" #include "sundials_context_impl.h" #include "sundials_logger_impl.h" @@ -271,8 +274,8 @@ typedef struct ARKodeMassMemRec { The type ARKodeMem is type pointer to struct ARKodeMemRec. This structure contains fields to keep track of problem state. ---------------------------------------------------------------*/ -typedef struct ARKodeMemRec { - +struct ARKodeMemRec +{ SUNContext sunctx; realtype uround; /* machine unit roundoff */ @@ -404,7 +407,8 @@ typedef struct ARKodeMemRec { ARKodeRootMem root_mem; /* root-finding structure */ /* Relaxation Data */ - ARKodeRelaxMem relax_mem; /* relaxation structure */ + sunbooleantype relax_enabled; /* is relaxation enabled? */ + ARKodeRelaxMem relax_mem; /* relaxation data structure */ /* User-supplied step solution post-processing function */ ARKPostProcessFn ProcessStep; @@ -424,7 +428,7 @@ typedef struct ARKodeMemRec { force_pass is true and is used by the XBraid interface to determine if a time step passed or failed the time step error test. */ -} *ARKodeMem; +}; diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 3af5d7a3a8..9cafd04fec 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -15,130 +15,669 @@ * functionality * ---------------------------------------------------------------------------*/ +#include #include #include -#include #include #include "arkode_impl.h" -#include -#include +#include "arkode_relaxation_impl.h" +/* ============================================================================= + * Private Functions + * ===========================================================================*/ -int arkSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) +/* Access the ARKODE and relaxation memory structures */ +static int arkRelaxAccessMem(void* arkode_mem, const char* fname, + ARKodeMem* ark_mem, ARKodeRelaxMem* relax_mem) { - ARKodeMem ark_mem; - - /* Check inputs */ if (!arkode_mem) { - arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", - "arkSetRelaxFn", MSG_ARK_NO_MEM); + arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", fname, MSG_ARK_NO_MEM); return ARK_MEM_NULL; } - ark_mem = (ARKodeMem) arkode_mem; + *ark_mem = (ARKodeMem)arkode_mem; - if (!rfn) + if (!((*ark_mem)->relax_mem)) { - arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkSetRelaxFn", - "The relaxation function is NULL."); - return ARK_ILL_INPUT; + arkProcessError(*ark_mem, ARK_RELAX_MEM_NULL, "ARKODE", fname, + MSG_RELAX_MEM_NULL); + return ARK_RELAX_MEM_NULL; } + *relax_mem = (ARKodeRelaxMem)((*ark_mem)->relax_mem); - if (!rjac) + return ARK_SUCCESS; +} + +/* Evaluate the relaxation residual function */ +static int arkRelaxResidual(sunrealtype* relax_vals, N_Vector* y_relax, + sunrealtype* res_vals, ARKodeMem ark_mem) +{ + int i, retval; + int num_relax_fn = ark_mem->relax_mem->num_relax_fn; + long int num_relax_fn_evals = ark_mem->relax_mem->num_relax_fn_evals; + sunrealtype* e_old = ark_mem->relax_mem->e_old; + sunrealtype* delta_e = ark_mem->relax_mem->delta_e; + void* user_data = ark_mem->user_data; + + /* Evaluate entropy functions */ + retval = ark_mem->relax_mem->relax_fn(y_relax, res_vals, user_data); + num_relax_fn_evals++; + if (retval < 0) return ARK_RELAX_FUNC_FAIL; + if (retval > 0) return ARK_RELAX_FUNC_RECV; + + /* Compute relaxation residual */ + for (i = 0; i < num_relax_fn; ++i) + res_vals[i] = res_vals[i] - e_old[i] - relax_vals[i] * delta_e[i]; + + return ARK_SUCCESS; +} + +/* Evaluate the relaxation Jacobian function */ +static int arkRelaxJacobian(sunrealtype* relax_vals, N_Vector* y_relax, + sunrealtype* jac_vals, ARKodeMem ark_mem) +{ + int i, retval; + int num_relax_fn = ark_mem->relax_mem->num_relax_fn; + long int num_relax_jac_fn_evals = ark_mem->relax_mem->num_relax_jac_evals; + N_Vector delta_y = ark_mem->relax_mem->delta_y; + N_Vector* J_vecs = ark_mem->relax_mem->J_vecs; + sunrealtype* delta_e = ark_mem->relax_mem->delta_e; + void* user_data = ark_mem->user_data; + + /* Evaluate Jacobian of entropy functions */ + retval = ark_mem->relax_mem->relax_jac_fn(y_relax, J_vecs, user_data); + num_relax_jac_fn_evals++; + if (retval < 0) return ARK_RELAX_JAC_FAIL; + if (retval > 0) return ARK_RELAX_JAC_RECV; + + /* Compute relaxation residual Jacobian */ + retval = N_VDotProdMulti(num_relax_fn, delta_y, J_vecs, jac_vals); + if (retval) return retval; + + for (i = 0; i < num_relax_fn; ++i) jac_vals[i] -= delta_e[i]; + + return ARK_SUCCESS; +} + +/* Solve the relaxation residual equation using Newton's method */ +static int arkRelaxNewtonSolve(ARKodeMem ark_mem) +{ + int i, retval; + sunrealtype max_res; + ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + + for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { - arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkSetRelaxFn", - "The relaxation Jacobian function is NULL."); + /* y_relax = y_n + r * delta_y */ + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[i], + ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[i]); + + /* Compute the current residual */ + retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, + relax_mem->res_vals, ark_mem); + if (retval) return retval; + + /* Check for convergence of all values */ + max_res = SUNRabs(relax_mem->res_vals[0]); + for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) + max_res = SUNMAX(max_res, relax_mem->res_vals[i]); + + if (max_res < relax_mem->tol) return ARK_SUCCESS; + + /* Update iteration count */ + relax_mem->total_iters++; + + /* Compute Jacobian and update */ + retval = arkRelaxJacobian(relax_mem->relax_vals, relax_mem->y_relax, + relax_mem->jac_vals, ark_mem); + if (retval) return retval; + + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + relax_mem->relax_vals[i] -= relax_mem->res_vals[i] / relax_mem->jac_vals[i]; + } + + return ARK_RELAX_SOLVE_RECV; +} + +/* Solve the relaxation residual equation using Newton's method */ +static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) +{ + int i, retval; + sunrealtype max_res; + ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + + for (i = 0; i < ark_mem->relax_mem->max_iters; i++) + { + /* y_relax = y_n + r * delta_y */ + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[i], + ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[i]); + + /* Compute the current residual */ + retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, + relax_mem->res_vals, ark_mem); + if (retval) return retval; + + /* Check for convergence of all values */ + max_res = SUNRabs(relax_mem->res_vals[0]); + for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) + max_res = SUNMAX(max_res, relax_mem->res_vals[i]); + + if (max_res < relax_mem->tol) return ARK_SUCCESS; + + /* Update iteration count */ + relax_mem->total_iters++; + + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + relax_mem->relax_vals[i] -= relax_mem->res_vals[i]; + } + + return ARK_RELAX_SOLVE_RECV; +} + +/* Compute and apply relaxation parameter */ +int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, + sunrealtype* relax_val_out) +{ + int i, retval; + sunrealtype relax_val_max, relax_val_min; + + /* Get the change in entropy (use y_relax and J_vecs as scratch) */ + retval = relax_mem->delta_e_fn(ark_mem, relax_mem->num_relax_fn, + relax_mem->relax_jac_fn, relax_mem->y_relax, + relax_mem->J_vecs, + &(relax_mem->num_relax_jac_evals), + relax_mem->delta_e); + if (retval) return retval; + + /* Get the change in state */ + retval = relax_mem->delta_y_fn(ark_mem, &(relax_mem->delta_y)); + if (retval) return retval; + + /* Duplicate state to evaluate entropy functions at y_n */ + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + N_VScale(ONE, ark_mem->yn, ark_mem->relax_mem->y_relax[i]); + + retval = relax_mem->relax_fn(ark_mem->relax_mem->y_relax, relax_mem->e_old, + ark_mem->user_data); + relax_mem->num_relax_fn_evals++; + if (retval < 0) return ARK_RELAX_FUNC_FAIL; + if (retval > 0) return ARK_RELAX_FUNC_RECV; + + /* Initial guess for relaxation parameter */ + for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) + relax_mem->relax_vals[i] = ONE; + + switch(relax_mem->solver) + { + case(ARK_RELAX_NEWTON): + retval = arkRelaxNewtonSolve(ark_mem); + break; + case(ARK_RELAX_FIXEDPOINT): + retval = arkRelaxFixedPointSolve(ark_mem); + break; + default: return ARK_ILL_INPUT; + break; } - /* Allocate the relaxation memory structure */ - if (!(ark_mem->relax_mem)) + /* Check for solver failure */ + if (retval) { - ark_mem->relax_mem = (ARKodeRelaxMem) malloc(sizeof(*(ark_mem->relax_mem))); - if (!(ark_mem->relax_mem)) return(ARK_MEM_FAIL); + relax_mem->total_fails++; + return retval; + } - /* Zero out proj_mem */ - memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); + /* Compute max and min relaxation values */ + relax_val_max = relax_mem->relax_vals[0]; + relax_val_min = relax_mem->relax_vals[0]; + for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) + { + relax_val_min = SUNMIN(relax_val_min, relax_mem->relax_vals[i]); + relax_val_max = SUNMAX(relax_val_max, relax_mem->relax_vals[i]); } - ark_mem->relax_mem->rfn = rfn; - ark_mem->relax_mem->rjac = rjac; + /* Check for bad relaxation value */ + if (relax_val_min < relax_mem->lower_bound || + relax_val_max > relax_mem->upper_bound) + return ARK_RELAX_SOLVE_RECV; + + /* Return min relaxation value */ + *relax_val_out = relax_val_min; + + return ARK_SUCCESS; +} + +/* ============================================================================= + * User Functions + * ===========================================================================*/ + +/* ----------------------------------------------------------------------------- + * Set functions + * ---------------------------------------------------------------------------*/ + +int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetEtaFail", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (eta_fail < SUN_RCONST(1.0)) relax_mem->eta_fail = eta_fail; + else relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + + return ARK_SUCCESS; +} + +int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetLowerBound", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (lower < SUN_RCONST(1.0)) relax_mem->lower_bound = lower; + else relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; + + return ARK_SUCCESS; +} + +int arkRelaxSetMaxIters(void* arkode_mem, int max_iters) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetMaxIters", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (max_iters > 0) relax_mem->max_iters = max_iters; + else relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; return ARK_SUCCESS; } +int arkRelaxSetSolver(void* arkode_mem, ARKRelaxationSolver solver) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetSolver", &ark_mem, + &relax_mem); + if (retval) return retval; -static int arkRelaxResidual(realtype gam, realtype* res, ARKodeMem ark_mem) + relax_mem->solver = solver; + + return ARK_SUCCESS; +} + +int arkRelaxSetTol(void* arkode_mem, sunrealtype tol) { - int flag; + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetTol", &ark_mem, &relax_mem); + if (retval) return retval; - /* w = yn + gam * direction */ - N_VLinearSum(ONE, ark_mem->yn, gam, ark_mem->tempv1, ark_mem->tempv2); + if (tol > SUN_RCONST(0.0)) relax_mem->tol = tol; + else relax_mem->tol = ARK_RELAX_DEFAULT_TOL; + + return ARK_SUCCESS; +} + +int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; - /* rfun(w) */ - flag = ark_mem->relax_mem->rfn(ark_mem->tempv2, res, ark_mem->user_data); - if (flag) return flag; + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetUpperBound", &ark_mem, + &relax_mem); + if (retval) return retval; - /* res = r(w) - r(y_n) - gam * estimate */ - *res = *res - ark_mem->relax_mem->rcur - gam * ark_mem->relax_mem->est; + if (upper > SUN_RCONST(1.0)) relax_mem->upper_bound = upper; + else relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; return ARK_SUCCESS; } +/* ----------------------------------------------------------------------------- + * Get functions + * ---------------------------------------------------------------------------*/ -static int arkRelaxJacobian(realtype gam, realtype* jac, ARKodeMem ark_mem) +int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) { - int flag; + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; - /* w = yn + gam * direction */ - N_VLinearSum(ONE, ark_mem->yn, gam, ark_mem->tempv1, ark_mem->tempv2); + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxFnEvals", &ark_mem, + &relax_mem); + if (retval) return retval; - /* rjac(w) */ - flag = ark_mem->relax_mem->rjac(ark_mem->tempv2, ark_mem->tempv3, - ark_mem->user_data); - if (flag) return flag; + *r_evals = relax_mem->num_relax_fn_evals; - /* jac = rjac(w) . direction - estimate */ - *jac = N_VDotProd(ark_mem->tempv3, ark_mem->tempv1) - ark_mem->relax_mem->est; + return ARK_SUCCESS; +} + +int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxJacEvals", &ark_mem, + &relax_mem); + if (retval) return retval; + + *J_evals = relax_mem->num_relax_jac_evals; return ARK_SUCCESS; } +int arkRelaxGetNumSolveFails(void* arkode_mem, long int* fails) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumSolveFails", &ark_mem, + &relax_mem); + if (retval) return retval; -int arkRelax(void* arkode_mem, realtype* gam) + *fails = relax_mem->total_fails; + + return ARK_SUCCESS; +} + +int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters) { - int i, flag; - realtype res, jac; + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumSolveIters", &ark_mem, + &relax_mem); + if (retval) return retval; + *iters = relax_mem->total_iters; + + return ARK_SUCCESS; +} + +/* ============================================================================= + * Driver and Stepper Functions + * ===========================================================================*/ + +/* Constructor called by stepper */ +int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, + ARKRelaxJacFn relax_jac_fn, ARKRelaxDeltaYFn delta_y_fn, + ARKRelaxDeltaEFn delta_e_fn, ARKRelaxGetOrderFn get_order_fn) +{ ARKodeMem ark_mem; /* Check inputs */ if (!arkode_mem) { - arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", - "arkSetRelaxFn", MSG_ARK_NO_MEM); + arkProcessError(NULL, ARK_MEM_NULL, "ARKODE", "arkRelaxCreate", + MSG_ARK_NO_MEM); return ARK_MEM_NULL; } - ark_mem = (ARKodeMem) arkode_mem; + ark_mem = (ARKodeMem)arkode_mem; - *gam = ONE; - for (i = 0; i < ark_mem->relax_mem->max_iters; i++) + /* Check for valid inputs */ + if (num_relax_fn < 0) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", + "The number of relaxation functions must be non-negative"); + return ARK_ILL_INPUT; + } + + if (num_relax_fn == 0 && (relax_fn || relax_jac_fn)) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", + "The number of relaxation functions is 0 but the relaxation" + " or Jacobian function was not NULL."); + return ARK_ILL_INPUT; + } + + if (num_relax_fn > 0 && !relax_fn) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", + "The relaxation function is NULL."); + return ARK_ILL_INPUT; + } + + if (num_relax_fn > 0 && !relax_jac_fn) { - flag = arkRelaxResidual(*gam, &res, ark_mem); - if (flag) return flag; + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", + "The relaxation Jacobian function is NULL."); + return ARK_ILL_INPUT; + } - flag = arkRelaxJacobian(*gam, &jac, ark_mem); - if (flag) return flag; + /* Disable relaxation if user inputs are 0 and NULL */ + if (num_relax_fn == 0 && !relax_fn && !relax_jac_fn) + { + ark_mem->relax_enabled = SUNFALSE; + return ARK_SUCCESS; + } - *gam -= res / jac; + /* Check for stepper supplied inputs */ + if (!delta_y_fn || !delta_e_fn || !get_order_fn) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", + "The Delta y, Delta e, or get order function is NULL."); + return ARK_ILL_INPUT; + } - if (SUNRabs(res) < ark_mem->relax_mem->tol) break; + /* Check if sufficient memory has already been allocated */ + if (ark_mem->relax_mem) + { + if (ark_mem->relax_mem->num_relax_fn_alloc < num_relax_fn) + { + arkRelaxDestroy(arkode_mem); + ark_mem->relax_mem = NULL; + } } + /* Allocate the relaxation memory structure if necessary */ + if (!(ark_mem->relax_mem)) + { + ark_mem->relax_mem = (ARKodeRelaxMem)malloc(sizeof(*(ark_mem->relax_mem))); + if (!(ark_mem->relax_mem)) return ARK_MEM_FAIL; + + /* Zero out relax_mem */ + memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); + + /* Allocate vectors */ + ark_mem->relax_mem->y_relax = N_VCloneVectorArray(num_relax_fn, ark_mem->yn); + if (!(ark_mem->relax_mem->y_relax)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->J_vecs = N_VCloneVectorArray(num_relax_fn, ark_mem->yn); + if (!(ark_mem->relax_mem->J_vecs)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + /* Allocate arrays */ + ark_mem->relax_mem->delta_e = + (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); + if (!(ark_mem->relax_mem->delta_e)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->e_old = + (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); + if (!(ark_mem->relax_mem->e_old)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->res_vals = + (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); + if (!(ark_mem->relax_mem->res_vals)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->jac_vals = + (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); + if (!(ark_mem->relax_mem->jac_vals)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->relax_vals = + (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); + if (!(ark_mem->relax_mem->relax_vals)) + { + arkRelaxDestroy(arkode_mem); + return ARK_MEM_FAIL; + } + + ark_mem->relax_mem->num_relax_fn_alloc = num_relax_fn; + } + + /* Initialize other values */ + ark_mem->relax_mem->relax_fn = relax_fn; + ark_mem->relax_mem->relax_jac_fn = relax_jac_fn; + ark_mem->relax_mem->delta_y_fn = delta_y_fn; + ark_mem->relax_mem->delta_e_fn = delta_e_fn; + ark_mem->relax_mem->get_order_fn = get_order_fn; + ark_mem->relax_mem->num_relax_fn = num_relax_fn; + ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; + ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; + ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; + ark_mem->relax_mem->tol = ARK_RELAX_DEFAULT_TOL; + ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; + + /* Enable relaxation */ + ark_mem->relax_enabled = SUNTRUE; + + return ARK_SUCCESS; +} + +/* Destructor called by driver */ +int arkRelaxDestroy(ARKodeRelaxMem relax_mem) +{ + if (!relax_mem) return ARK_SUCCESS; + + /* Free vectors */ + if (relax_mem->y_relax) + { + N_VDestroyVectorArray(relax_mem->y_relax, relax_mem->num_relax_fn_alloc); + relax_mem->y_relax = NULL; + } + + if (relax_mem->y_relax) + { + N_VDestroyVectorArray(relax_mem->J_vecs, relax_mem->num_relax_fn_alloc); + relax_mem->J_vecs = NULL; + } + + /* Free arrays */ + if (relax_mem->delta_e) + { + free(relax_mem->delta_e); + relax_mem->delta_e = NULL; + } + + if (relax_mem->e_old) + { + free(relax_mem->e_old); + relax_mem->e_old = NULL; + } + + if (relax_mem->res_vals) + { + free(relax_mem->res_vals); + relax_mem->res_vals = NULL; + } + + if (relax_mem->jac_vals) + { + free(relax_mem->jac_vals); + relax_mem->jac_vals = NULL; + } + + if (relax_mem->relax_vals) + { + free(relax_mem->relax_vals); + relax_mem->relax_vals = NULL; + } + + /* Free structure */ + free(relax_mem); + + return ARK_SUCCESS; +} + +/* Compute and apply relaxation, called by driver */ +int arkRelax(ARKodeMem ark_mem, realtype* dsm_inout, int* nflag_out) +{ + int retval; + sunrealtype relax_val; + ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + + /* Get the relaxation memory structure */ + if (!relax_mem) + { + arkProcessError(ark_mem, ARK_RELAX_MEM_NULL, "ARKODE", + "arkRelax", MSG_RELAX_MEM_NULL); + return ARK_RELAX_MEM_NULL; + } + + /* Compute the relaxation parameter */ + retval = arkRelaxSolve(ark_mem, relax_mem, &relax_val); + if (retval < 0) return retval; + if (retval > 0) + { + /* Recoverable failure, cut step size and try again */ + ark_mem->eta = relax_mem->eta_fail; + return TRY_AGAIN; + } + + /* Update step size and error estimate */ + ark_mem->h *= relax_val; + *dsm_inout *= SUNRpowerI(relax_val, relax_mem->get_order_fn(ark_mem)); + + /* Relax solution */ + N_VLinearSum(relax_val, ark_mem->ycur, (ONE - relax_val), ark_mem->yn, + ark_mem->ycur); + +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "relaxation", + "relaxation parameter = %"RSYM", relaxed h = %"RSYM + ", relaxed error = %"RSYM, + relax, ark_mem->h, *dsmPtr); +#endif + return ARK_SUCCESS; } -/*=============================================================== - EOF - ===============================================================*/ +/* ============================================================================= + * EOF + * ===========================================================================*/ diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index f336c2a205..3a6f4c2006 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -18,40 +18,116 @@ #define _ARKODE_RELAX_IMPL_H #include + #include +#include +#include + +#include "arkode_types_impl.h" + +/* ----------------------------------------------------------------------------- + * Relaxation Constants + * ---------------------------------------------------------------------------*/ + +#define ARK_RELAX_DEFAULT_TOL SUN_RCONST(1.0e-14) +#define ARK_RELAX_DEFAULT_MAX_ITERS 100 +#define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.5) +#define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.5) +#define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) + +/* ----------------------------------------------------------------------------- + * Relaxation Private Return Values (see arkode/arkode.h for public values) + * ---------------------------------------------------------------------------*/ + +#define ARK_RELAX_FUNC_RECV 1; +#define ARK_RELAX_JAC_RECV 2; +#define ARK_RELAX_SOLVE_RECV -1; /* <<< should be recoverable */ + +/* ----------------------------------------------------------------------------- + * Stepper Supplied Relaxation Functions + * ---------------------------------------------------------------------------*/ -/* ==================== * - * Relaxation Constants * - * ==================== */ +/* Compute the change in state for the current step y_new = y_old + delta_y */ +typedef int (*ARKRelaxDeltaYFn)(ARKodeMem ark_mem, N_Vector* delta_y); -#define ARK_RELAX_LRW 5 -#define ARK_RELAX_LIW 12 /* int, ptr, etc */ +/* Compute the estimated change in entropy for this step delta_e */ +typedef int (*ARKRelaxDeltaEFn)(ARKodeMem ark_mem, int num_relax_fn, + ARKRelaxJacFn relax_jac_fn, + N_Vector* work_space_1, N_Vector* work_space_2, + long int* evals_out, sunrealtype* delta_e_out); -/* ========================= * - * Relaxation Data Structure * - * ========================= */ +/* Get the method order */ +typedef int (*ARKRelaxGetOrderFn)(ARKodeMem ark_mem); -typedef struct ARKodeRelaxMemRec* ARKodeRelaxMem; +/* ----------------------------------------------------------------------------- + * Relaxation Data Structure + * ---------------------------------------------------------------------------*/ struct ARKodeRelaxMemRec { - ARKRelaxFn rfn; /* relaxation function */ - ARKRelaxJacFn rjac; /* relaxation Jacobian */ - realtype est; - realtype rcur; /* current relaxation function value */ - realtype tol; /* nonlinear solve tolerance */ - int max_iters; /* nonlinear solve max iterations */ + /* user-supplied and stepper supplied functions */ + ARKRelaxFn relax_fn; /* user relaxation function ("entropy") */ + ARKRelaxJacFn relax_jac_fn; /* user relaxation Jacobian */ + ARKRelaxDeltaYFn delta_y_fn; /* get delta y from stepper */ + ARKRelaxDeltaEFn delta_e_fn; /* get delta entropy from stepper */ + ARKRelaxGetOrderFn get_order_fn; /* get the method order */ + + /* stepper computed quantities used in the residual and Jacobian */ + N_Vector delta_y; /* change in solution */ + sunrealtype* delta_e; /* change in entropy */ + + /* relaxation variables */ + int num_relax_fn; /* number of entropy functions */ + int num_relax_fn_alloc; /* allocated workspce size */ + long int num_relax_fn_evals; /* counter for function evals */ + long int num_relax_jac_evals; /* counter for jacobian evals */ + N_Vector* y_relax; /* relaxed state y_n + relax * delta_y */ + N_Vector* J_vecs; /* relaxation Jacobian vectors */ + sunrealtype* e_old; /* entropy at start of step y(t_{n-1}) */ + sunrealtype* res_vals; /* relaxation residual values */ + sunrealtype* jac_vals; /* relaxation Jacobian values */ + sunrealtype* relax_vals; /* relaxation parameter values */ + sunrealtype lower_bound; /* smallest allowed relaxation value */ + sunrealtype upper_bound; /* largest allowed relaxation value */ + sunrealtype eta_fail; /* failed relaxation step size factor */ + + /* nonlinear solver settings */ + ARKRelaxationSolver solver; /* choice of relaxation solver */ + sunrealtype tol; /* nonlinear solve tolerance */ + int max_iters; /* nonlinear solve max iterations */ + long int total_iters; /* total nonlinear iterations */ + long int total_fails; /* number of nonlinear solver fails */ }; -/* ==================== * - * Relaxation Functions * - * ==================== */ +/* ----------------------------------------------------------------------------- + * Relaxation Functions + * ---------------------------------------------------------------------------*/ + +/* Driver and Stepper Functions */ +int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, + ARKRelaxJacFn relax_jac_fn, ARKRelaxDeltaYFn delta_y_fn, + ARKRelaxDeltaEFn delta_e_fn, + ARKRelaxGetOrderFn get_order_fn); +int arkRelaxDestroy(ARKodeRelaxMem relax_mem); +int arkRelax(ARKodeMem ark_mem, sunrealtype* dsm_inout, int* nflag_out); -int arkSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); +/* User Functions */ +int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail); +int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); +int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); +int arkRelaxSetSolver(void* arkode_mem, ARKRelaxationSolver solver); +int arkRelaxSetTol(void* arkode_mem, sunrealtype tol); +int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); -int arkRelax(void* arkode_mem, realtype* gam); +int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); +int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* j_evals); +int arkRelaxGetNumSolveFails(void* arkode_mem, long int* fails); +int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters); + +/* ----------------------------------------------------------------------------- + * Error Messages + * ---------------------------------------------------------------------------*/ -/* int arkRelaxFree(ARKodeRelaxMem* relax_mem); */ -/* int arkRelaxPrint(ARKodeRelaMem relax_mem, FILE* outfile); */ +#define MSG_RELAX_MEM_NULL "Relaxation memory is NULL." #endif From 8d021e57d7afbef1888b1ac97145df1c1994f2a9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 24 Oct 2022 16:14:02 -0700 Subject: [PATCH 013/111] forgot to add new header --- src/arkode/arkode_types_impl.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/arkode/arkode_types_impl.h diff --git a/src/arkode/arkode_types_impl.h b/src/arkode/arkode_types_impl.h new file mode 100644 index 0000000000..ec9cbef30d --- /dev/null +++ b/src/arkode/arkode_types_impl.h @@ -0,0 +1,23 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 + * ----------------------------------------------------------------------------- + * Implementation header file with forward declarations of ARKODE types. + * ---------------------------------------------------------------------------*/ + +#ifndef _ARKODE_TYPES_IMPL_H +#define _ARKODE_TYPES_IMPL_H + +typedef struct ARKodeMemRec* ARKodeMem; +typedef struct ARKodeRelaxMemRec* ARKodeRelaxMem; + +#endif From eff781d718a74b8df602054fd01188b555cf6ea8 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 24 Oct 2022 16:44:40 -0700 Subject: [PATCH 014/111] add plotting script --- examples/utilities/plot_data_time_series.py | 208 ++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100755 examples/utilities/plot_data_time_series.py diff --git a/examples/utilities/plot_data_time_series.py b/examples/utilities/plot_data_time_series.py new file mode 100755 index 0000000000..46c5d1e831 --- /dev/null +++ b/examples/utilities/plot_data_time_series.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +# ----------------------------------------------------------------------------- +# Programmer(s): David J. Gardner @ LLNL +# ----------------------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2002-2022, 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 +# ----------------------------------------------------------------------------- +# Script to plot and compare time series data from multiple files +# +# The input data files must contain an M x (N + 1) matrix of values where the +# first column of each row is the output time and the remaining values are the +# N output quantities. Additionally the data files must contain header comment +# starting with "vars:" that lists the name for each data column i.e., +# +# # vars: time quantity_0 quantity_1 . . . quantity_N-1 +# t_0 q_0,0 q_0,1 q_0,2 . . . q_0,N-1 +# t_1 q_1,0 q_1,1 q_1,2 . . . q_1,N-1 +# . . . . . . +# . . . . . . +# . . . . . . +# t_M-1 q_M-1,0 q_M-1,1 q_M-1,2 . . . q_M-1,N-1 +# +# where t_m is the m-th output time and q_m,n is the n-th quantity at the m-th +# output time. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# main routine +# ----------------------------------------------------------------------------- +def main(): + + import argparse + import matplotlib.pyplot as plt + import numpy as np + import shlex + + parser = argparse.ArgumentParser(description='''Plot data files''') + + parser.add_argument('quantity', type=str, + help='''Quantity to plot''') + + parser.add_argument('datafiles', type=str, nargs='+', + help='''Data files to plot''') + + # Plot display options + + parser.add_argument('--save', action='store_true', + help='''Save figure to file''') + + parser.add_argument('--labels', type=str, nargs='+', + help='''Data file labels for plot legend''') + + parser.add_argument('--title', type=str, + help='''Plot title''') + + parser.add_argument('--xlabel', type=str, + help='''x-axis label''') + + parser.add_argument('--ylabel', type=str, + help='''y-axis label''') + + parser.add_argument('--grid', action='store_true', + help='''Add grid to plot''') + + # Axis scaling + logscale = parser.add_mutually_exclusive_group() + + logscale.add_argument('--logx', action='store_true', + help='''Plot with log scale x-axis''') + + logscale.add_argument('--logy', action='store_true', + help='''Plot with log scale y-axis''') + + logscale.add_argument('--loglog', action='store_true', + help='''Use log scale x and y axes''') + + # Debugging options + + parser.add_argument('--debug', action='store_true', + help='Enable debugging') + + # Parse command line args + args = parser.parse_args() + + # Create figure and axes + fig, ax = plt.subplots() + + for i, datafile in enumerate(args.datafiles): + + quantities = None + with open(datafile) as fn: + # read the file line by line + for line in fn: + # skip empty lines + if not line.strip(): + continue + # exit after reading initial comment lines + if "#" not in line: + break + # split line into a list + text = shlex.split(line) + # extract quantity names + if "vars:" in line: + quantities = text[2:] + continue + + # Check inputs + if quantities is None: + print("ERROR: quantity names not provided") + sys.exit() + + if args.quantity not in quantities: + print("ERROR: quantity not found") + print(f" Possible values: {quantities}") + sys.exit() + + # Get data column index + idx = quantities.index(args.quantity) + + # Load data + data = np.loadtxt(datafile, dtype=np.double) + + if args.debug: + print(np.shape(data)) + print(data) + + # Extract t and q data + tdata = data[:,0] # first column has t values + qdata = data[:,idx] # remaining columns have q values + + # line colors: matplotlib.org/stable/tutorials/colors/colormaps.html + # and colorbrewer2.org) + if len(args.datafiles) < 22: + colors = ["#d62728", "#1f77b4", "#2ca02c", "#9467bd", "#ff7f0e", + "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf", + "#000000", "#ff9896", "#aec7e8", "#98df8a", "#c5b0d5", + "#ffbb78", "#c49c94", "#f7b6d2", "#c7c7c7", "#dbdb8d", + "#9edae5"] + else: + print("ERROR: ncols > ncolors") + sys.exit() + + # Set plot label for legend + if (args.labels): + label=args.labels[i] + else: + label=None + + if args.logx or args.logy or args.loglog: + ax.plot(tdata, np.abs(qdata), label=label, + color=colors[i]) + else: + ax.plot(tdata, qdata, label=label, + color=colors[i]) + + # Change axis scale + if args.logx: + ax.set_xscale("log") + elif args.logy: + ax.set_yscale("log") + elif args.loglog: + ax.set_xscale("log") + ax.set_yscale("log") + + # Add title + if args.title: + plt.title(args.title) + + # Add x-axis label + if args.xlabel: + plt.xlabel(args.xlabel) + else: + plt.xlabel("time") + + # Add y-axis label + if args.ylabel: + plt.ylabel(args.ylabel) + else: + plt.ylabel(args.quantity.replace("_"," ")); + + # Add legend + if args.labels: + ax.legend(bbox_to_anchor=(1, 0.95), loc="upper right") + + # Add grid + if args.grid: + plt.grid() + + # Save plot to file + if args.save: + plt.savefig("fig.pdf") + else: + plt.show() + +# ----------------------------------------------------------------------------- +# run the main routine +# ----------------------------------------------------------------------------- + +if __name__ == '__main__': + import sys + sys.exit(main()) From 611bbae48aea32066c3c932728529d7a8df8ae72 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 24 Oct 2022 17:09:05 -0700 Subject: [PATCH 015/111] add dissipative example --- examples/arkode/C_serial/CMakeLists.txt | 1 + .../C_serial/ark_dissipated_exp_entropy.c | 453 ++++++++++++++++++ 2 files changed, 454 insertions(+) create mode 100644 examples/arkode/C_serial/ark_dissipated_exp_entropy.c diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 1a2a4235de..60983deb4b 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -27,6 +27,7 @@ set(ARKODE_examples "ark_brusselator_fp\;\;exclude-single" "ark_brusselator1D\;\;exclude-single" "ark_conserved_exp_entropy\;0 1 0.1\;develop" + "ark_dissipated_exp_entropy\;0 1 0.1\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" "ark_KrylovDemo_prec\;\;exclude-single" diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c new file mode 100644 index 0000000000..aba356560f --- /dev/null +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -0,0 +1,453 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 example problem is adapted from: + * + * H. Ranocha, M. Sayyari, L. Dalcin, M. Parsani, and D.I. Ketcheson, + * "Relaxation Runge-Kutta Methods: Fully-Discrete Explicit Entropy-Stable + * Schemes for the Compressible Euler and Navier-Stokes Equations," SIAM Journal + * on Scientific Computing, 42(2), 2020, https://doi.org/10.1137/19M1263480. + * ----------------------------------------------------------------------------- + * This example evolves the equation du/dt = -exp(u) for t in the interval + * [0, 5] with the initial condition u(0) = 0.5. The equation has the analytic + * solution u(t) = -log(e^{-0.5} + t) and the dissipated exponential entropy is + * given by ent(u) = exp(u) with Jacobian ent'(u) = de/du = exp(u). + * + * The problem is advanced in time with an explicit or implicit relaxed + * Runge-Kutta method to ensure dissipation of the entropy. + * ---------------------------------------------------------------------------*/ + +/* Header files */ +#include +#include + +#include +#include +#include +#include + +/* Precision-dependent output macros */ +#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 + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +/* ODE RHS function */ +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); + +/* ODE RHS Jacobian function */ +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); + +/* Entropy function */ +int Ent(N_Vector* y, sunrealtype* e, void* user_data); + +/* Entropy Jacobian function */ +int JacEnt(N_Vector* y, N_Vector* J, void* user_data); + +/* ----------------- * + * Utility functions * + * ----------------- */ + +/* Analytic solution */ +int ans(sunrealtype t, N_Vector y); + +/* Check return flags and pointers */ +int check_flag(int flag, const char* funcname); +int check_ptr(void* ptr, const char* funcname); + +/* ------------ * + * Main Program * + * ------------ */ + +int main(int argc, char* argv[]) +{ + /* Error-checking flag */ + int flag; + + /* Initial and final times */ + sunrealtype t0 = SUN_RCONST(0.0); + sunrealtype tf = SUN_RCONST(5.0); + + /* Relative and absolute tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); + sunrealtype abstol = SUN_RCONST(1.0e-10); + + /* SUNDIALS context, vector, matrix, and linear solver objects */ + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; + ARKodeButcherTable B = NULL; + + /* Pointer to vector data array */ + sunrealtype* ydata; + sunrealtype* ytdata; + + /* Initial, current, and change in entropy value */ + sunrealtype ent0, ent, delta_ent; + + /* Solution errors */ + sunrealtype u_err; + + /* ARKODE memory structure */ + void* arkode_mem = NULL; + + /* ARKODE statistics */ + long int nst, nst_a, nfe, nfi, nri, nrf; + long int nsetups, nje, nfeLS, nni, ncfn, netf; + + /* Number of outputs, output counter, output times, and output file */ + int nout = 10; + int iout; + sunrealtype t, tout, dtout; + FILE* UFID; + + /* Command line options */ + int implicit = 0; /* explicit */ + int relax = 0; /* enable relaxation */ + int steps = 100; /* number of steps */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ + + /* -------------------- * + * Output Problem Setup * + * -------------------- */ + + if (argc > 1) implicit = atoi(argv[1]); + if (argc > 2) relax = atoi(argv[2]); + if (argc > 3) fixed_h = (sunrealtype)atof(argv[3]); + if (argc > 4) steps = atoi(argv[4]); + + printf("\nDissipated Exponential Entropy problem:\n"); + if (implicit) printf(" method = DIRK\n"); + else printf(" method = ERK\n"); + if (relax) printf(" relaxation = ON\n"); + else printf(" relaxation = OFF\n"); + if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); + if (implicit || !(fixed_h > SUN_RCONST(0.0))) + { + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); + } + printf(" steps = %d\n", steps); + printf("\n"); + + /* ------------ * + * Setup ARKODE * + * ------------ */ + + /* Create the SUNDIALS context object for this simulation */ + flag = SUNContext_Create(NULL, &ctx); + if (check_flag(flag, "SUNContext_Create")) return 1; + + /* Create serial vector and set the initial condition values */ + y = N_VNew_Serial(2, ctx); + if (check_ptr(y, "N_VNew_Serial")) return 1; + + ydata = N_VGetArrayPointer(y); + if (check_ptr(ydata, "N_VGetArrayPointer")) return 1; + + ydata[0] = SUN_RCONST(1.0); + ydata[1] = SUN_RCONST(0.5); + + ytrue = N_VClone(y); + if (check_ptr(ytrue, "N_VClone")) return 1; + + ytdata = N_VGetArrayPointer(ytrue); + if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; + + /* Initialize the ARKStep */ + if (implicit) arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); + else arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; + + /* Specify tolerances */ + flag = ARKStepSStolerances(arkode_mem, reltol, abstol); + if (check_flag(flag, "ARKStepSStolerances")) return 1; + + if (relax) + { + /* Enable relaxation methods */ + flag = ARKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); + if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; + } + + if (fixed_h > 0.0) + { + /* Set the step size */ + flag = ARKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ARKStepSetFixedStep")) return 1; + } + + if (implicit) + { + /* Create dense matrix and linear solver */ + A = SUNDenseMatrix(2, 2, ctx); + if (check_ptr(A, "SUNDenseMatrix")) return 1; + + LS = SUNLinSol_Dense(y, A, ctx); + if (check_ptr(LS, "SUNLinSol_Dense")) return 1; + + /* Attach the matrix and linear solver */ + flag = ARKStepSetLinearSolver(arkode_mem, LS, A); + if (check_flag(flag, "ARKStepSetLinearSolver")) return 1; + + /* Set Jacobian routine */ + flag = ARKStepSetJacFn(arkode_mem, Jac); + if (check_flag(flag, "ARKStepSetJacFn")) return 1; + } + else if (fixed_h > 0.0) + { + /* Use RK4 */ + B = ARKodeButcherTable_Alloc(4, SUNFALSE); + + B->A[1][0] = SUN_RCONST(0.5); + B->A[2][1] = SUN_RCONST(0.5); + B->A[3][2] = SUN_RCONST(1.0); + + B->c[1] = SUN_RCONST(0.5); + B->c[2] = SUN_RCONST(0.5); + B->c[3] = SUN_RCONST(1.0); + + B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); + B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); + + B->q = 4; + B->p = 0; + + flag = ARKStepSetTables(arkode_mem, 4, 0, NULL, B); + if (check_flag(flag, "ARKStepSetTables")) return 1; + } + + /* Open output stream for results, output comment line */ + UFID = fopen("ark_dissipated_exp_entropy.txt", "w"); + fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); + + /* --------------- * + * Advance in Time * + * --------------- */ + + /* Initial time, time between outputs, output time */ + t = t0; + dtout = tf / nout; + tout = t0 + dtout; + + /* Output the initial condition and entropy */ + flag = Ent(&y, &ent0, NULL); + if (check_flag(flag, "Ent")) return 1; + + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t0, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); + + printf(" t u e delta e\n"); + printf(" " + "---------------------------------------------------------------------" + "---\n"); + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", + t, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); + + for (iout = 0; iout < steps; iout++) + { + /* Evolve in time */ + flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); + if (check_flag(flag, "ARKStepEvolve")) break; + + /* Output solution and errors */ + flag = Ent(&y, &ent, NULL); + if (check_flag(flag, "Ent")) return 1; + + flag = ans(t, ytrue); + if (check_flag(flag, "ans")) return 1; + + delta_ent = ent - ent0; + u_err = ydata[0] - ytdata[0]; + + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.16" ESYM " %14.6" ESYM "\n", + t, ydata[0], ent, u_err, delta_ent); + + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t, ydata[0], ent, u_err, delta_ent); + + /* Update output time */ + tout += dtout; + tout = (tout > tf) ? tf : tout; + } + + printf(" " + "---------------------------------------------------------------------" + "---\n"); + fclose(UFID); + + /* ------------ * + * Output Stats * + * ------------ */ + + /* Get final statistics on how the solve progressed */ + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + + flag = ARKStepGetNumStepAttempts(arkode_mem, &nst_a); + check_flag(flag, "ARKStepGetNumStepAttempts"); + + flag = ARKStepGetNumErrTestFails(arkode_mem, &netf); + check_flag(flag, "ARKStepGetNumErrTestFails"); + + flag = ARKStepGetNumRhsEvals(arkode_mem, &nfe, &nfi); + check_flag(flag, "ARKStepGetNumRhsEvals"); + + printf("\nFinal Solver Statistics:\n"); + printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); + printf(" Total number of error test failures = %li\n", netf); + printf(" Total RHS evals: Fe = %li, Fi = %li\n", nfe, nfi); + + if (implicit) + { + flag = ARKStepGetNumNonlinSolvIters(arkode_mem, &nni); + check_flag(flag, "ARKStepGetNumNonlinSolvIters"); + + flag = ARKStepGetNumNonlinSolvConvFails(arkode_mem, &ncfn); + check_flag(flag, "ARKStepGetNumNonlinSolvConvFails"); + + flag = ARKStepGetNumLinSolvSetups(arkode_mem, &nsetups); + check_flag(flag, "ARKStepGetNumLinSolvSetups"); + + flag = ARKStepGetNumJacEvals(arkode_mem, &nje); + check_flag(flag, "ARKStepGetNumJacEvals"); + + flag = ARKStepGetNumLinRhsEvals(arkode_mem, &nfeLS); + check_flag(flag, "ARKStepGetNumLinRhsEvals"); + + printf(" Total number of Newton iterations = %li\n", nni); + printf(" Total number of linear solver convergence failures = %li\n", ncfn); + printf(" Total linear solver setups = %li\n", nsetups); + printf(" Total number of Jacobian evaluations = %li\n", nje); + printf(" Total RHS evals for setting up the linear system = %li\n", nfeLS); + } + + if (relax) + { + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nri); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxSolveFails"); + + printf(" Total Relaxation iters = %li\n", nri); + printf(" Total Relaxation fails = %li\n", nrf); + } + printf("\n"); + + /* -------- * + * Clean up * + * -------- */ + + /* Free ARKStep integrator and SUNDIALS objects */ + ARKStepFree(&arkode_mem); + SUNLinSolFree(LS); + SUNMatDestroy(A); + N_VDestroy(y); + N_VDestroy(ytrue); + SUNContext_Free(&ctx); + + return flag; +} + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +/* ODE RHS function f(t,y). */ +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* fdata = N_VGetArrayPointer(ydot); + fdata[0] = -exp(ydata[0]); + return 0; +} + +/* ODE RHS Jacobian function J(t,y) = df/dy. */ +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* Jdata = SUNDenseMatrix_Data(J); + Jdata[0] = -exp(ydata[0]); + return 0; +} + +/* Entropy function e(y) */ +int Ent(N_Vector* y, sunrealtype* e, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + e[0] = exp(ydata[0]); + return 0; +} + +/* Entropy function Jacobian Je(y) = de/dy */ +int JacEnt(N_Vector* y, N_Vector* J, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* jdata = N_VGetArrayPointer(J[0]); + jdata[0] = exp(ydata[0]); + return 0; +} + +/* ----------------- * + * Utility functions * + * ----------------- */ + +/* Analytic solution */ +int ans(sunrealtype t, N_Vector y) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + ydata[0] = log(exp(SUN_RCONST(-0.5)) + t); + return 0; +} + +/* Check return flags */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, flag); + return 1; + } + return 0; +} + +/* Check return pointers */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + return 0; +} From 175b52e68105662c167cf182890ce51ff41ce28a Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 24 Oct 2022 18:11:04 -0700 Subject: [PATCH 016/111] ARKStep relaxation function documentation --- .../Usage/ARKStep_c_interface/Relaxation.rst | 201 ++++++++++++++++++ .../Usage/ARKStep_c_interface/index.rst | 1 + src/arkode/arkode_relaxation_impl.h | 6 +- 3 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst new file mode 100644 index 0000000000..58ca345550 --- /dev/null +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -0,0 +1,201 @@ +.. ----------------------------------------------------------------------------- + Programmer(s): David J. Gardner @ LLNL + ----------------------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2022, 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.ARKStep.Relaxation: + +Relaxation Methods +================== + +This section describes user-callable functions for utilizing relaxation methods +with ARKStep. + +Enabling or Disabling Relaxation +-------------------------------- + +.. c:function:: int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac); + + Attaches the user supplied functions for evaluating the relaxation function + (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation + functions (``nrfn``). + + :param arkode_mem: the ARKStep memory structure + :param nrfn: the number of relaxation functions + :param rfn: the user-defined relaxation function + :param rjac: the user-defined Jacobian of the relaxation function + + :retval ARK_SUCCESS: the function existed successfully + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_ILL_INPUT: an invalid input combination was provided see the + output error message for more details + :retval ARK_MEM_FAIL: a memory allocation failed + + .. note:: + + If ``nrfn`` is zero and both ``rfn`` and ``rjac`` are ``NULL`` relaxation + is disabled. + +Optional Input Functions +------------------------ + +This section describes optional input functions used to control the relaxation +method. + +.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); + + Sets the step size reduction factor applied after a failed relaxation solve. + The default value is 0.25. Input values :math:`\geq 1` will result in the + default value being used. + + :param arkode_mem: the ARKStep memory structure + :param eta_rf: the step size reduction factor + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); + + Sets the smallest acceptable value for the relaxation parameter. Values + smaller than the lower bound will result in a relaxation solve failure and + the step will be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is 0.8. Input values + :math:`\geq 1` will result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param lower: the relaxation parameter lower bound + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); + + Sets the maximum number of nonlinear iterations allowed when solving for the + relaxation parameter. If the maximum number of iterations is reached before + meeting the solve tolerance (determined by :c:func:`ARKStepSetRelaxTol`), the + step will be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is 5. Input values + :math:`\leq 0` will result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param max_iters: the maximum number of solver iterations allowed + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver); + + Sets the nonlinear solver method used to compute the relaxation parameter. + The default value is ``ARK_RELAX_NEWTON``. + + :param arkode_mem: the ARKStep memory structure + :param solver: the nonlinear solver to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); + + Sets the nonlinear solver tolerance to use when computing the relaxation + parameter. If the tolerance is not reached within the maximum number of + iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), step will be + repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is 5. Input values + :math:`\leq 0` will result in the default value being used. + + The default value is 1.0e-14. Input values :math:`\leq 0.0` will + result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param tol: the nonlinear solver tolerance to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); + + Sets the largest acceptable value for the relaxation parameter. Values + larger than the upper bound will result in a relaxation solve failure and + the step will be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is 1.2. Input values + :math:`\leq 1` will result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param eta_rf: the relaxation parameter upper bound + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +Optional Output Functions +------------------------- + +This section describes optional output functions used to retrieve information +about the performance of the relaxation method. + +.. c:function:: int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); + + Get the number of times the user's relaxation function was evaluated. + + :param arkode_mem: the ARKStep memory structure + :param r_evals: the number of relaxation function evaluations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); + + Get the number of times the user's relaxation Jacobian was evaluated. + + :param arkode_mem: the ARKStep memory structure + :param J_evals: the number of relaxation Jacobian evaluations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); + + Get the number of times the relaxation parameter nonlinear solver failed. + + :param arkode_mem: the ARKStep memory structure + :param fails: the number of relaxation nonlinear solver failures + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters); + + Get the number of relaxation parameter nonlinear solver iterations. + + :param arkode_mem: the ARKStep memory structure + :param iters: the number of relaxation nonlinear solver iterations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/index.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/index.rst index 512947fa9f..4f1ee42f5e 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/index.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/index.rst @@ -59,5 +59,6 @@ detailed in the following subsections. Skeleton User_callable + Relaxation Preconditioners XBraid diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 3a6f4c2006..edd552da49 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -30,9 +30,9 @@ * ---------------------------------------------------------------------------*/ #define ARK_RELAX_DEFAULT_TOL SUN_RCONST(1.0e-14) -#define ARK_RELAX_DEFAULT_MAX_ITERS 100 -#define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.5) -#define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.5) +#define ARK_RELAX_DEFAULT_MAX_ITERS 5 +#define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) +#define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.2) #define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) /* ----------------------------------------------------------------------------- From 9fab3e4223b186ddae7a86a15677145aeac40f0f Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 19 Dec 2022 15:18:50 -0800 Subject: [PATCH 017/111] fix typos in docs --- doc/arkode/guide/source/Mathematics.rst | 5 +++++ .../source/Usage/ARKStep_c_interface/Relaxation.rst | 13 +++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index fde8bacfb7..669f583697 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2076,3 +2076,8 @@ step attempt, or fails with the minimum step size, then the integration is halte and an error is returned. In this case the user may need to employ other strategies as discussed in :numref:`ARKODE.Usage.ARKStep.Tolerances` and :numref:`ARKODE.Usage.ERKStep.Tolerances` to satisfy the inequality constraints. + +.. _ARKODE.Mathematics.Relaxation: + +Relaxation Methods +================== diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 58ca345550..d43db7b4d1 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -34,7 +34,7 @@ Enabling or Disabling Relaxation :param rfn: the user-defined relaxation function :param rjac: the user-defined Jacobian of the relaxation function - :retval ARK_SUCCESS: the function existed successfully + :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` :retval ARK_ILL_INPUT: an invalid input combination was provided see the output error message for more details @@ -115,13 +115,10 @@ method. Sets the nonlinear solver tolerance to use when computing the relaxation parameter. If the tolerance is not reached within the maximum number of - iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), step will be - repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is 5. Input values - :math:`\leq 0` will result in the default value being used. - - The default value is 1.0e-14. Input values :math:`\leq 0.0` will - result in the default value being used. + iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the step will + be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is 1.0e-14. Input values + :math:`\leq 0.0` will result in the default value being used. :param arkode_mem: the ARKStep memory structure :param tol: the nonlinear solver tolerance to use From 6c96ca9ceae0b09beb5f0766113cdce8f9aced93 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 9 Jan 2023 22:11:35 -0800 Subject: [PATCH 018/111] documentation updates --- CHANGELOG.md | 4 + doc/arkode/guide/source/Introduction.rst | 5 + doc/arkode/guide/source/Mathematics.rst | 37 ++++++++ .../Usage/ARKStep_c_interface/Relaxation.rst | 3 +- .../guide/source/Usage/User_supplied.rst | 48 ++++++++++ doc/shared/sundials.bib | 91 +++++++++++++++++++ 6 files changed, 187 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 554b8c4cac..938d3363f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # SUNDIALS Changelog +## Changes to SUNDIALS in release 6.6.0 + +Added support for relaxation Runge-Kutta methods to ARKStep. + ## Changes to SUNDIALS in release 6.5.0 Added the functions `ARKStepGetJac`, `ARKStepGetJacTime`, diff --git a/doc/arkode/guide/source/Introduction.rst b/doc/arkode/guide/source/Introduction.rst index 58fbd99d13..0755a2e8aa 100644 --- a/doc/arkode/guide/source/Introduction.rst +++ b/doc/arkode/guide/source/Introduction.rst @@ -118,6 +118,11 @@ provided with SUNDIALS, or again may utilize a user-supplied module. Changes from previous versions ============================== +Changes in v5.6.0 +----------------- + +Added support for relaxation Runge-Kutta methods in ARKStep. + Changes in v5.5.0 ----------------- diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 669f583697..f6437ad09d 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2081,3 +2081,40 @@ strategies as discussed in :numref:`ARKODE.Usage.ARKStep.Tolerances` and Relaxation Methods ================== + +For cases where the problem :eq:`ARKODE_IVP` is dissipative or conservative with +respect to a smooth convex function :math:`\xi(y(t))`, it is desirable to ensure +this property is preserved by the numerical method applied to the IVP. That is +:math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative problems and +:math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems. + +To this end, ARKODE supports relaxation methods :cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` +to guarantee the dissipation or preservation of a global function. This is +achieved by solving the auxiliary scalar nonlinear system + +.. math:: + F(r) = \xi(y_n + r d) - \xi(y_n) - r e = 0 + :label: ARKODE_RELAX_NLS + +for the relaxation factor :math:`r` at the end of each time step. The update +direction is :math:`d = h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` +and the estimate of the change in :math:`\xi` is +:math:`e = h_n \sum_{i=1}^{s} \langle \xi'(z_i), b^E_i f^E_i + b^I_i f^I_i \rangle` +where :math:`\xi'` is the Jacobian of :math:`\xi`. The relaxed solution is given +by + +.. math:: + y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} + :label: ARKODE_RELAX_SOL + +Currently, the nonlinear system :eq:`ARKODE_RELAX_NLS` can be solved using a +fixed point or Newton iteration. Should this iteration fail to meet the +residual tolerance in the maximum allowed number of iterations, the step size +will be reduced by the factor :math:`\eta_\text{rf}` (default 0.25). +Additionally, a relaxation value greater than :math:`r_\text{max}` (default 0.8) +or less than :math:`r_\text{min}` (default 1.2) will result in a solver failure +and the step will be repeated with the step size reduced by +:math:`\eta_\text{rf}`. + +For more information on utilizing relaxation Runge-Kutta methos, see +:numref:`ARKODE.Usage.ARKStep.Relaxation`. diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index d43db7b4d1..90c78f68fe 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -18,7 +18,8 @@ Relaxation Methods ================== This section describes user-callable functions for utilizing relaxation methods -with ARKStep. +with ARKStep. For more information on relaxation Runge-Kutta methods see +:numref:`ARKODE.Mathematics.Relaxation`. Enabling or Disabling Relaxation -------------------------------- diff --git a/doc/arkode/guide/source/Usage/User_supplied.rst b/doc/arkode/guide/source/Usage/User_supplied.rst index bd6be82ecc..cca6a1af76 100644 --- a/doc/arkode/guide/source/Usage/User_supplied.rst +++ b/doc/arkode/guide/source/Usage/User_supplied.rst @@ -63,6 +63,9 @@ The user-supplied functions for ARKODE consist of: by the outer integrator to the inner integrator, or state data supplied by the inner integrator to the outer integrator. +* if relaxation is enabled, a function that evaluates the dissipative or + conservative function :math:`\xi(y(t))` and a function to evaluate its + Jacobian :math:`\xi'(y(t))`. .. _ARKODE.Usage.ODERHS: @@ -1114,3 +1117,48 @@ outer integrator for the outer integration. **Notes:** In a heterogeneous computing environment if any data copies between the host and device vector data are necessary, this is where that should occur. + + +.. _ARKODE.Usage.RelaxFn: + +Relaxation function +------------------- + +.. c:type:: int (*ARKRelaxFn)(N_Vector* y, realtype* r, void* user_data) + + When applying relaxation, an :c:func:`ARKRelaxFn` function computes the + dissipative or conservative function :math:`\xi(y)`. + + **Arguments:** + * *y* -- the current value of the dependent variable vector. + * *r* -- the array of :math:`\xi_i(y(t))` values + * *user_data* -- the ``user_data`` pointer that was passed to + :c:func:`ARKStepSetUserData`. + + **Return value:** + An :c:func:`MRIStepPostInnerFn` function should return 0 if successful, a + positive value if a recoverable error occurred, or a negative value if an + unrecoverable error occurred. If a recoverable error occurs, the step size + will be reduced and the step repeated. + +.. _ARKODE.Usage.RelaxJacFn: + +Relaxation Jacobian function +---------------------------- + +.. c:type:: int (*ARKRelaxJacFn)(N_Vector* y, N_Vector* J, void* user_data); + + When applying relaxation, an :c:func:`ARKRelaxJacFn` functions computes the + Jacobians of the :math:`\xi'_i(y)` function :math:`\xi_i(y(t))`. + + **Arguments:** + * *y* -- the current value of the dependent variable vector. + * *J* -- the array Jacobian vectors :math:`\xi'_i(y(t))` + * *user_data* -- the ``user_data`` pointer that was passed to + :c:func:`ARKStepSetUserData`. + + **Return value:** + An :c:func:`MRIStepPostInnerFn` function should return 0 if successful, a + positive value if a recoverable error occurred, or a negative value if an + unrecoverable error occurred. If a recoverable error occurs, the step size + will be reduced and the step repeated. diff --git a/doc/shared/sundials.bib b/doc/shared/sundials.bib index bddcc058a4..56055b8542 100644 --- a/doc/shared/sundials.bib +++ b/doc/shared/sundials.bib @@ -1989,6 +1989,97 @@ @techreport{Zon:63 year = {1963} } +% +% Relaxation Runge-Kutta Methods +% + +% IMEX and Multirate Relaxation Methods +@article{kang2022entropy, + title = {{Entropy--Preserving and Entropy--Stable Relaxation IMEX and Multirate Time--Stepping Methods}}, + author = {Kang, Shinhoo and Constantinescu, Emil M}, + journal = {Journal of Scientific Computing}, + volume = {93}, + number = {1}, + pages = {1--31}, + year = {2022}, + publisher = {Springer}, + doi = {10.1007/s10915-022-01982-w} +} + +@article{ketcheson2019relaxation, + title = {{Relaxation Runge--Kutta methods: Conservation and stability for inner-product norms}}, + author = {Ketcheson, David I}, + journal = {SIAM Journal on Numerical Analysis}, + volume = {57}, + number = {6}, + pages = {2850--2870}, + year = {2019}, + publisher = {SIAM}, + doi = {10.1137/19M1263662} +} + +% Local Relaxation Runge-Kutta +@article{ranocha2020fully, + title = {{Fully discrete explicit locally entropy-stable schemes for the compressible Euler and Navier--Stokes equations}}, + author = {Ranocha, Hendrik and Dalcin, Lisandro and Parsani, Matteo}, + journal = {Computers \& Mathematics with Applications}, + volume = {80}, + number = {5}, + pages = {1343--1359}, + year = {2020}, + publisher = {Elsevier}, + doi = {10.1016/j.camwa.2020.06.016} +} + +% Relaxation in Multistep and General Linear Methods +@article{ranocha2020general, + title = {General relaxation methods for initial-value problems with application to multistep schemes}, + author = {Ranocha, Hendrik and L{\'o}czi, Lajos and Ketcheson, David I}, + journal = {Numerische Mathematik}, + volume = {146}, + number = {4}, + pages = {875--906}, + year = {2020}, + publisher = {Springer}, + doi = {10.1007/s00211-020-01158-4} +} + +% Global Relaxation Runge-Kutta +@article{ranocha2020relaxation, + title = {{Relaxation Runge--Kutta Methods: Fully Discrete Explicit Entropy-Stable Schemes for the Compressible Euler and Navier--Stokes Equations}}, + author = {Ranocha, Hendrik and Sayyari, Mohammed and Dalcin, Lisandro and Parsani, Matteo and Ketcheson, David I}, + journal = {SIAM Journal on Scientific Computing}, + volume = {42}, + number = {2}, + pages = {A612--A638}, + year = {2020}, + publisher = {SIAM}, + doi = {10.1137/19M1263480} +} + +% Relaxation Hamiltontian +@article{ranocha2020hamiltonian, + title = {{Relaxation Runge--Kutta methods for Hamiltonian problems}}, + author = {Ranocha, Hendrik and Ketcheson, David I}, + journal = {Journal of Scientific Computing}, + volume = {84}, + number = {1}, + pages = {1--27}, + year = {2020}, + publisher = {Springer}, + doi = {10.1007/s10915-020-01277-y} +} + +@article{rogowski2022performance, + title = {{Performance analysis of relaxation Runge--Kutta methods}}, + author = {Rogowski, Marcin and Dalcin, Lisandro and Parsani, Matteo and Keyes, David E}, + journal = {The International Journal of High Performance Computing Applications}, + pages = {10943420221085947}, + year = {2022}, + publisher = {SAGE Publications Sage UK: London, England}, + doi = {10.1177/10943420221085947} +} + % % Kokkos % From 001f46e3081f04aa3c422484730f5ff446dcae68 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 13:57:13 -0800 Subject: [PATCH 019/111] doc updates and corrections --- doc/arkode/guide/source/Introduction.rst | 4 +++- doc/arkode/guide/source/Mathematics.rst | 16 +++++++++---- .../Usage/ARKStep_c_interface/Relaxation.rst | 9 +++---- .../guide/source/Usage/User_supplied.rst | 24 +++++++++---------- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/doc/arkode/guide/source/Introduction.rst b/doc/arkode/guide/source/Introduction.rst index 0755a2e8aa..64caa821f7 100644 --- a/doc/arkode/guide/source/Introduction.rst +++ b/doc/arkode/guide/source/Introduction.rst @@ -121,7 +121,9 @@ Changes from previous versions Changes in v5.6.0 ----------------- -Added support for relaxation Runge-Kutta methods in ARKStep. +Added support for relaxation Runge-Kutta methods in ARKStep, see +:numref:`ARKODE.Mathematics.Relaxation` and +:numref:`ARKODE.Usage.ARKStep.Relaxation` for more information. Changes in v5.5.0 ----------------- diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index f6437ad09d..563d4b9d49 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2089,19 +2089,20 @@ this property is preserved by the numerical method applied to the IVP. That is :math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems. To this end, ARKODE supports relaxation methods :cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` -to guarantee the dissipation or preservation of a global function. This is +to guarantee the dissipation or preservation of a global function. Given a +second order method with :math:`b^E_i \geq 0` and :math:`b^I_i \geq 0`, this is achieved by solving the auxiliary scalar nonlinear system .. math:: - F(r) = \xi(y_n + r d) - \xi(y_n) - r e = 0 + F(r) = \xi(y_{n-1} + r d) - \xi(y_{n-1}) - r e = 0 :label: ARKODE_RELAX_NLS for the relaxation factor :math:`r` at the end of each time step. The update direction is :math:`d = h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` and the estimate of the change in :math:`\xi` is :math:`e = h_n \sum_{i=1}^{s} \langle \xi'(z_i), b^E_i f^E_i + b^I_i f^I_i \rangle` -where :math:`\xi'` is the Jacobian of :math:`\xi`. The relaxed solution is given -by +where :math:`\xi'` is the Jacobian of :math:`\xi`. The relaxed solution is then +given by .. math:: y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} @@ -2116,5 +2117,10 @@ or less than :math:`r_\text{min}` (default 1.2) will result in a solver failure and the step will be repeated with the step size reduced by :math:`\eta_\text{rf}`. -For more information on utilizing relaxation Runge-Kutta methos, see +In the case where there are multiple functions :math:`\xi_i(y)` of interest that +do not need to be conserved but may also be dissipated, ARKODE will compute the +relaxation values for each function and select :math:`r = \min_i r_i`. As a +result each :math:`\xi_i(y)` will be dissipated. + +For more information on utilizing relaxation Runge-Kutta methods, see :numref:`ARKODE.Usage.ARKStep.Relaxation`. diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 90c78f68fe..998a6a0984 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -32,8 +32,10 @@ Enabling or Disabling Relaxation :param arkode_mem: the ARKStep memory structure :param nrfn: the number of relaxation functions - :param rfn: the user-defined relaxation function - :param rjac: the user-defined Jacobian of the relaxation function + :param rfn: the user-defined function to compute the relaxation function + :math:`\xi_i(y)` + :param rjac: the user-defined function to compute the relaxation Jacobian + :math:`\xi'_i(y)` :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -43,8 +45,7 @@ Enabling or Disabling Relaxation .. note:: - If ``nrfn`` is zero and both ``rfn`` and ``rjac`` are ``NULL`` relaxation - is disabled. + If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. Optional Input Functions ------------------------ diff --git a/doc/arkode/guide/source/Usage/User_supplied.rst b/doc/arkode/guide/source/Usage/User_supplied.rst index cca6a1af76..90c3129477 100644 --- a/doc/arkode/guide/source/Usage/User_supplied.rst +++ b/doc/arkode/guide/source/Usage/User_supplied.rst @@ -63,9 +63,9 @@ The user-supplied functions for ARKODE consist of: by the outer integrator to the inner integrator, or state data supplied by the inner integrator to the outer integrator. -* if relaxation is enabled, a function that evaluates the dissipative or - conservative function :math:`\xi(y(t))` and a function to evaluate its - Jacobian :math:`\xi'(y(t))`. +* if relaxation is enabled (optional), a function that evaluates the dissipative + or conservative functions :math:`\xi_i(y(t))` (required) and a function to + evaluate the Jacobians :math:`\xi_i'(y(t))` (required). .. _ARKODE.Usage.ODERHS: @@ -1126,18 +1126,18 @@ Relaxation function .. c:type:: int (*ARKRelaxFn)(N_Vector* y, realtype* r, void* user_data) - When applying relaxation, an :c:func:`ARKRelaxFn` function computes the - dissipative or conservative function :math:`\xi(y)`. + When applying relaxation, an :c:func:`ARKRelaxFn` function is required to + compute the dissipative or conservative functions :math:`\xi_i(y)`. **Arguments:** * *y* -- the current value of the dependent variable vector. - * *r* -- the array of :math:`\xi_i(y(t))` values + * *r* -- the array of :math:`\xi_i(y)` values. * *user_data* -- the ``user_data`` pointer that was passed to :c:func:`ARKStepSetUserData`. **Return value:** - An :c:func:`MRIStepPostInnerFn` function should return 0 if successful, a - positive value if a recoverable error occurred, or a negative value if an + An :c:func:`ARKRelaxFn` function should return 0 if successful, a positive + value if a recoverable error occurred, or a negative value if an unrecoverable error occurred. If a recoverable error occurs, the step size will be reduced and the step repeated. @@ -1148,17 +1148,17 @@ Relaxation Jacobian function .. c:type:: int (*ARKRelaxJacFn)(N_Vector* y, N_Vector* J, void* user_data); - When applying relaxation, an :c:func:`ARKRelaxJacFn` functions computes the - Jacobians of the :math:`\xi'_i(y)` function :math:`\xi_i(y(t))`. + When applying relaxation, an :c:func:`ARKRelaxJacFn` function is required to + computes the Jacobians :math:`\xi'_i(y)`. **Arguments:** * *y* -- the current value of the dependent variable vector. - * *J* -- the array Jacobian vectors :math:`\xi'_i(y(t))` + * *J* -- an array Jacobian vectors :math:`\xi'_i(y)`. * *user_data* -- the ``user_data`` pointer that was passed to :c:func:`ARKStepSetUserData`. **Return value:** - An :c:func:`MRIStepPostInnerFn` function should return 0 if successful, a + An :c:func:`ARKRelaxJacFn` function should return 0 if successful, a positive value if a recoverable error occurred, or a negative value if an unrecoverable error occurred. If a recoverable error occurs, the step size will be reduced and the step repeated. From 4644bad938e260e73347ff86599b45dc94d315bb Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 14:37:43 -0800 Subject: [PATCH 020/111] add relax output to PrintAllStats --- src/arkode/arkode_io.c | 11 +++++++++ src/arkode/arkode_relaxation.c | 36 +++++++++++++++++++++++++++++ src/arkode/arkode_relaxation_impl.h | 2 ++ 3 files changed, 49 insertions(+) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index 33603d550f..56a3512375 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1675,6 +1675,7 @@ int arkGetUserData(void *arkode_mem, void** user_data) int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) { + int retval; ARKodeMem ark_mem; ARKodeRootMem ark_root_mem; @@ -1704,6 +1705,11 @@ int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) ark_root_mem = (ARKodeRootMem) ark_mem->root_mem; fprintf(outfile, "Root fn evals = %ld\n", ark_root_mem->nge); } + if (ark_mem->relax_enabled) + { + retval = arkRelaxPrintAllStats(arkode_mem, outfile, fmt); + if (retval != ARK_SUCCESS) return(retval); + } break; case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, "Time,%"RSYM, ark_mem->tcur); @@ -1722,6 +1728,11 @@ int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) ark_root_mem = (ARKodeRootMem) ark_mem->root_mem; fprintf(outfile, ",Roof fn evals,%ld", ark_root_mem->nge); } + if (ark_mem->relax_enabled) + { + retval = arkRelaxPrintAllStats(arkode_mem, outfile, fmt); + if (retval != ARK_SUCCESS) return(retval); + } break; default: arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkPrintAllStats", diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 9cafd04fec..9ad9a6a2c6 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -22,6 +22,7 @@ #include "arkode_impl.h" #include "arkode_relaxation_impl.h" +#include "sundials/sundials_types.h" /* ============================================================================= * Private Functions @@ -416,6 +417,41 @@ int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters) return ARK_SUCCESS; } +int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxPrintAllStats", &ark_mem, + &relax_mem); + if (retval) return retval; + + switch(fmt) + { + case SUN_OUTPUTFORMAT_TABLE: + fprintf(outfile, "Relax fn evals = %ld\n", + relax_mem->num_relax_fn_evals); + fprintf(outfile, "Relax Jac evals = %ld\n", + relax_mem->num_relax_jac_evals); + fprintf(outfile, "Relax NLS iters = %ld\n", + relax_mem->total_iters); + fprintf(outfile, "Relax NLS fails = %ld\n", + relax_mem->total_fails); + case SUN_OUTPUTFORMAT_CSV: + fprintf(outfile, ",Relax fn evals,%ld", relax_mem->num_relax_fn_evals); + fprintf(outfile, ",Relax Jac evals,%ld", relax_mem->num_relax_jac_evals); + fprintf(outfile, ",Relax NLS iters,%ld", relax_mem->total_iters); + fprintf(outfile, ",Relax NLS fails,%ld", relax_mem->total_fails); + default: + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxPrintAllStats", + "Invalid formatting option."); + return ARK_ILL_INPUT; + } + + return ARK_SUCCESS; +} + /* ============================================================================= * Driver and Stepper Functions * ===========================================================================*/ diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index edd552da49..1a2977133b 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -124,6 +124,8 @@ int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* j_evals); int arkRelaxGetNumSolveFails(void* arkode_mem, long int* fails); int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters); +int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt); + /* ----------------------------------------------------------------------------- * Error Messages * ---------------------------------------------------------------------------*/ From eff65e1701f1408326831e9fa97d0fd8196e10d0 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 14:37:53 -0800 Subject: [PATCH 021/111] fix compiler warning --- include/arkode/arkode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index 47207b6cbc..ce2483b177 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -190,7 +190,7 @@ typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; typedef enum { ARK_RELAX_NEWTON, - ARK_RELAX_FIXEDPOINT, + ARK_RELAX_FIXEDPOINT } ARKRelaxationSolver; #ifdef __cplusplus From 8e9431d3269740302fcd6e5d7de44121490cc2cc Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 16:05:38 -0800 Subject: [PATCH 022/111] fix build error with info logging enabled --- src/arkode/arkode_relaxation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 9ad9a6a2c6..20b7eab222 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -708,7 +708,7 @@ int arkRelax(ARKodeMem ark_mem, realtype* dsm_inout, int* nflag_out) "ARKODE::arkStep_TakeStep_Z", "relaxation", "relaxation parameter = %"RSYM", relaxed h = %"RSYM ", relaxed error = %"RSYM, - relax, ark_mem->h, *dsmPtr); + relax_val, ark_mem->h, *dsm_into); #endif return ARK_SUCCESS; From d54b53e8d8e6031fcafe0bd5c619820e2c5b83f1 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 16:11:28 -0800 Subject: [PATCH 023/111] fix typo --- src/arkode/arkode_relaxation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 20b7eab222..6c184df3c6 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -708,7 +708,7 @@ int arkRelax(ARKodeMem ark_mem, realtype* dsm_inout, int* nflag_out) "ARKODE::arkStep_TakeStep_Z", "relaxation", "relaxation parameter = %"RSYM", relaxed h = %"RSYM ", relaxed error = %"RSYM, - relax_val, ark_mem->h, *dsm_into); + relax_val, ark_mem->h, *dsm_inout); #endif return ARK_SUCCESS; From 07fd288b71cf7670b6d6a169915cc362262c7bc1 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 17:29:56 -0800 Subject: [PATCH 024/111] unstash ERKStep updates --- examples/arkode/C_serial/CMakeLists.txt | 3 +- ...ropy.c => ark_conserved_exp_entropy_ark.c} | 2 +- ...ark_conserved_exp_entropy_ark_0_1_0.1.out} | 0 .../C_serial/ark_conserved_exp_entropy_erk.c | 436 ++++++++++++++++++ include/arkode/arkode_arkstep.h | 4 +- include/arkode/arkode_erkstep.h | 21 + src/arkode/arkode_arkstep.c | 18 +- src/arkode/arkode_arkstep_io.c | 2 +- src/arkode/arkode_erkstep.c | 143 ++++++ src/arkode/arkode_erkstep_impl.h | 8 + src/arkode/arkode_erkstep_io.c | 60 +++ 11 files changed, 687 insertions(+), 10 deletions(-) rename examples/arkode/C_serial/{ark_conserved_exp_entropy.c => ark_conserved_exp_entropy_ark.c} (99%) rename examples/arkode/C_serial/{ark_conserved_exp_entropy_0_1_0.1.out => ark_conserved_exp_entropy_ark_0_1_0.1.out} (100%) create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 60983deb4b..c5488d15d5 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,7 +26,8 @@ set(ARKODE_examples "ark_brusselator\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator1D\;\;exclude-single" - "ark_conserved_exp_entropy\;0 1 0.1\;develop" + "ark_conserved_exp_entropy_ark\;0 1 0.1\;develop" + "ark_conserved_exp_entropy_erk\;1 0.1\;develop" "ark_dissipated_exp_entropy\;0 1 0.1\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c similarity index 99% rename from examples/arkode/C_serial/ark_conserved_exp_entropy.c rename to examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 9b73da073e..eba6a2d7fb 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -267,7 +267,7 @@ int main(int argc, char* argv[]) } /* Open output stream for results, output comment line */ - UFID = fopen("ark_conserved_exp_entropy.txt", "w"); + UFID = fopen("ark_conserved_exp_entropy_ark.txt", "w"); fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); /* --------------- * diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out similarity index 100% rename from examples/arkode/C_serial/ark_conserved_exp_entropy_0_1_0.1.out rename to examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c new file mode 100644 index 0000000000..863f9bdf51 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -0,0 +1,436 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 example problem is adapted from: + * + * H. Ranocha, M. Sayyari, L. Dalcin, M. Parsani, and D.I. Ketcheson, + * "Relaxation Runge-Kutta Methods: Fully-Discrete Explicit Entropy-Stable + * Schemes for the Compressible Euler and Navier-Stokes Equations," SIAM Journal + * on Scientific Computing, 42(2), 2020, https://doi.org/10.1137/19M1263480. + * ----------------------------------------------------------------------------- + * This example evolves system + * + * du/dt = -exp(v) + * dv/dt = exp(u) + * + * for t in the interval [0, 5] with the initial condition + * + * u(0) = 1.0 + * v(0) = 0.5 + * + * The system has the analytic solution + * + * u = log(e + e^(3/2)) - log(b) + * v = log(a * e^(a * t)) - log(b) + * + * where log is the natural logarithm, a = sqrt(e) + e, and + * b = sqrt(e) + e^(a * t). + * + * The conserved exponential entropy for the system is given by + * ent(u,v) = exp(u) + exp(v) with the Jacobian + * ent'(u,v) = [ de/du de/dv ]^T = [ exp(u) exp(v) ]^T. + * + * The problem is advanced in time with an explicit relaxed + * Runge-Kutta method to ensure conservation of the entropy. + * ---------------------------------------------------------------------------*/ + +/* Header files */ +#include +#include + +#include +#include + +/* Precision-dependent output macros */ +#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 + +/* Value of the natural number e */ +#define EVAL 2.718281828459045235360287471352662497757247093699959574966 + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +/* ODE RHS function */ +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); + +/* Entropy function */ +int Ent(N_Vector* y, sunrealtype* e, void* user_data); + +/* Entropy Jacobian function */ +int JacEnt(N_Vector* y, N_Vector* J, void* user_data); + +/* ----------------- * + * Utility functions * + * ----------------- */ + +/* Analytic solution */ +int ans(sunrealtype t, N_Vector y); + +/* Check return flags and pointers */ +int check_flag(int flag, const char* funcname); +int check_ptr(void* ptr, const char* funcname); + +/* ------------ * + * Main Program * + * ------------ */ + +int main(int argc, char* argv[]) +{ + /* Error-checking flag */ + int flag; + + /* Initial and final times */ + sunrealtype t0 = SUN_RCONST(0.0); + sunrealtype tf = SUN_RCONST(5.0); + + /* Relative and absolute tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); + sunrealtype abstol = SUN_RCONST(1.0e-10); + + /* SUNDIALS context, vector, matrix, and linear solver objects */ + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; + ARKodeButcherTable B = NULL; + + /* Pointer to vector data array */ + sunrealtype* ydata; + sunrealtype* ytdata; + + /* Initial, current, and change in entropy value */ + sunrealtype ent0, ent, ent_err; + + /* Solution errors */ + sunrealtype u_err, v_err; + + /* ARKODE memory structure */ + void* arkode_mem = NULL; + + /* ARKODE statistics */ + long int nst, nst_a, nfe; + long int nre, nrje, nri, nrf, netf; + + /* Number of outputs, output counter, output times, and output file */ + int nout = 10; + int iout; + sunrealtype t, tout, dtout; + FILE* UFID; + + /* Command line options */ + int relax = 1; /* enable relaxation */ + int steps = 100; /* number of steps */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ + + /* -------------------- * + * Output Problem Setup * + * -------------------- */ + + if (argc > 1) relax = atoi(argv[1]); + if (argc > 2) fixed_h = (sunrealtype)atof(argv[2]); + if (argc > 3) steps = atoi(argv[3]); + + printf("\nConserved Exponential Entropy problem:\n"); + printf(" method = ERK\n"); + if (relax) printf(" relaxation = ON\n"); + else printf(" relaxation = OFF\n"); + if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); + if (!(fixed_h > SUN_RCONST(0.0))) + { + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); + } + printf(" steps = %d\n", steps); + printf("\n"); + + /* ------------ * + * Setup ARKODE * + * ------------ */ + + /* Create the SUNDIALS context object for this simulation */ + flag = SUNContext_Create(NULL, &ctx); + if (check_flag(flag, "SUNContext_Create")) return 1; + + /* Create serial vector and set the initial condition values */ + y = N_VNew_Serial(2, ctx); + if (check_ptr(y, "N_VNew_Serial")) return 1; + + ydata = N_VGetArrayPointer(y); + if (check_ptr(ydata, "N_VGetArrayPointer")) return 1; + + ydata[0] = SUN_RCONST(1.0); + ydata[1] = SUN_RCONST(0.5); + + ytrue = N_VClone(y); + if (check_ptr(ytrue, "N_VClone")) return 1; + + ytdata = N_VGetArrayPointer(ytrue); + if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; + + /* Initial entropy */ + flag = Ent(&y, &ent0, NULL); + if (check_flag(flag, "Ent")) return 1; + + /* Initialize the ERKStep */ + arkode_mem = ERKStepCreate(f, t0, y, ctx); + if (check_ptr(arkode_mem, "ERKStepCreate")) return 1; + + /* Specify tolerances */ + flag = ERKStepSStolerances(arkode_mem, reltol, abstol); + if (check_flag(flag, "ERKStepSStolerances")) return 1; + + if (relax) + { + /* Enable relaxation methods */ + flag = ERKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); + if (check_flag(flag, "ERKStepSetRelaxFn")) return 1; + } + + if (fixed_h > 0.0) + { + /* Set the step size */ + flag = ERKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ERKStepSetFixedStep")) return 1; + + /* Use RK4 */ + B = ARKodeButcherTable_Alloc(4, SUNFALSE); + + B->A[1][0] = SUN_RCONST(0.5); + B->A[2][1] = SUN_RCONST(0.5); + B->A[3][2] = SUN_RCONST(1.0); + + B->c[1] = SUN_RCONST(0.5); + B->c[2] = SUN_RCONST(0.5); + B->c[3] = SUN_RCONST(1.0); + + B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); + B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); + B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); + + B->q = 4; + B->p = 0; + + flag = ERKStepSetTable(arkode_mem, B); + if (check_flag(flag, "ERKStepSetTables")) return 1; + } + + /* Open output stream for results, output comment line */ + UFID = fopen("ark_conserved_exp_entropy_erk.txt", "w"); + fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); + + /* --------------- * + * Advance in Time * + * --------------- */ + + /* Initial time, time between outputs, output time */ + t = t0; + dtout = tf / nout; + tout = t0 + dtout; + + /* Output the initial condition and entropy */ + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM + " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t0, ydata[0], ydata[1], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0), + SUN_RCONST(0.0)); + + printf(" t u v e " + "delta e\n"); + printf(" " + "---------------------------------------------------------------------" + "---\n"); + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); + + for (iout = 0; iout < steps; iout++) + { + /* Evolve in time */ + flag = ERKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); + if (check_flag(flag, "ERKStepEvolve")) break; + + /* Output solution and errors */ + flag = Ent(&y, &ent, NULL); + if (check_flag(flag, "Ent")) return 1; + + flag = ans(t, ytrue); + if (check_flag(flag, "ans")) return 1; + + ent_err = ent - ent0; + u_err = ydata[0] - ytdata[0]; + v_err = ydata[1] - ytdata[1]; + + printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + t, ydata[0], ydata[1], ent, ent_err); + + fprintf(UFID, + "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM + " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", + t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); + + /* Update output time */ + tout += dtout; + tout = (tout > tf) ? tf : tout; + } + + printf(" " + "---------------------------------------------------------------------" + "---\n"); + fclose(UFID); + + /* ------------ * + * Output Stats * + * ------------ */ + + /* Get final statistics on how the solve progressed */ + flag = ERKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ERKStepGetNumSteps"); + + flag = ERKStepGetNumStepAttempts(arkode_mem, &nst_a); + check_flag(flag, "ERKStepGetNumStepAttempts"); + + flag = ERKStepGetNumErrTestFails(arkode_mem, &netf); + check_flag(flag, "ERKStepGetNumErrTestFails"); + + flag = ERKStepGetNumRhsEvals(arkode_mem, &nfe); + check_flag(flag, "ERKStepGetNumRhsEvals"); + + printf("\nFinal Solver Statistics:\n"); + printf(" Internal solver steps = %li (attempted = %li)\n", nst, nst_a); + printf(" Total number of error test failures = %li\n", netf); + printf(" Total RHS evals = %li\n", nfe); + + if (relax) + { + flag = ERKStepGetNumRelaxFnEvals(arkode_mem, &nre); + check_flag(flag, "ERKStepGetNumRelaxFnEvals"); + + flag = ERKStepGetNumRelaxJacEvals(arkode_mem, &nrje); + check_flag(flag, "ERKStepGetNumRelaxJacEvals"); + + flag = ERKStepGetNumRelaxSolveIters(arkode_mem, &nri); + check_flag(flag, "ERKStepGetNumRelaxSolveIters"); + + flag = ERKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + check_flag(flag, "ERKStepGetNumRelaxSolveFails"); + + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation iters = %li\n", nri); + printf(" Total Relaxation fails = %li\n", nrf); + } + printf("\n"); + + /* -------- * + * Clean up * + * -------- */ + + /* Free ERKStep integrator and SUNDIALS objects */ + ERKStepFree(&arkode_mem); + N_VDestroy(y); + N_VDestroy(ytrue); + SUNContext_Free(&ctx); + + return flag; +} + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +/* ODE RHS function f(t,y). */ +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* fdata = N_VGetArrayPointer(ydot); + + fdata[0] = -exp(ydata[1]); + fdata[1] = exp(ydata[0]); + + return 0; +} + +/* Entropy function e(y) */ +int Ent(N_Vector* y, sunrealtype* e, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + + e[0] = exp(ydata[0]) + exp(ydata[1]); + + return 0; +} + +/* Entropy function Jacobian Je(y) = de/dy */ +int JacEnt(N_Vector* y, N_Vector* J, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* jdata = N_VGetArrayPointer(J[0]); + + jdata[0] = exp(ydata[0]); + jdata[1] = exp(ydata[1]); + + return 0; +} + +/* ----------------- * + * Utility functions * + * ----------------- */ + +/* Analytic solution */ +int ans(sunrealtype t, N_Vector y) +{ + sunrealtype a, b; + sunrealtype* ydata = N_VGetArrayPointer(y); + + a = sqrt(EVAL) + EVAL; + b = sqrt(EVAL) + exp(a * t); + + ydata[0] = log(EVAL + exp(SUN_RCONST(1.5))) - log(b); + ydata[1] = log(a * exp(a * t)) - log(b); + + return 0; +} + +/* Check return flags */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, flag); + return 1; + } + return 0; +} + +/* Check return pointers */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + return 0; +} diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 4b5a9c1c8a..9ab04644dc 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -478,8 +478,8 @@ SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); -SUNDIALS_EXPORT int ARKSteSetRelaxSolver(void* arkode_mem, - ARKRelaxationSolver solver); +SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, + ARKRelaxationSolver solver); SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 0fff7c9326..3be24cba09 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -259,6 +259,27 @@ SUNDIALS_EXPORT void ERKStepFree(void **arkode_mem); /* Output the ERKStep memory structure (useful when debugging) */ SUNDIALS_EXPORT void ERKStepPrintMem(void* arkode_mem, FILE* outfile); +/* Relaxation functions */ +SUNDIALS_EXPORT int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, + ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ERKStepSetRelaxEtaFail(void* arkode_mem, + sunrealtype eta_rf); +SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, + sunrealtype lower); +SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); +SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, + ARKRelaxationSolver solver); +SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, + sunrealtype upper); +SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, + long int* r_evals); +SUNDIALS_EXPORT int ERKStepGetNumRelaxJacEvals(void* arkode_mem, + long int* J_evals); +SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveFails(void* arkode_mem, + long int* fails); +SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveIters(void* arkode_mem, + long int* iters); #ifdef __cplusplus } diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 75bf6bede4..cf8beaf6a7 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3035,7 +3035,9 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, /* Initialize output */ for (j = 0; j < num_relax_fn; j++) + { delta_e_out[j] = ZERO; + } /* Set arrays for fused vector operation */ cvals = step_mem->cvals; @@ -3072,19 +3074,21 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, } } - /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ae[i,j] Fi[j] */ + /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv2); if (retval) return ARK_VECTOROP_ERR; /* Duplicate stage to compute entropy Jacobians at z_i */ for (j = 0; j < num_relax_fn; j++) + { N_VScale(ONE, ark_mem->tempv2, work_space_1[j]); + } /* Evaluate the Jacobians at z_i */ retval = relax_jac_fn(work_space_1, work_space_2, ark_mem->user_data); (*num_relax_jac_evals)++; - if (retval < 0) return ARK_RELAX_JAC_FAIL; - if (retval > 0) return ARK_RELAX_JAC_RECV; + if (retval < 0) { return ARK_RELAX_JAC_FAIL; } + if (retval > 0) { return ARK_RELAX_JAC_RECV; } /* Update estimates */ if (step_mem->explicit && step_mem->implicit) @@ -3100,14 +3104,18 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, else if (step_mem->explicit) { for (j = 0; j < num_relax_fn; j++) + { delta_e_out[j] += step_mem->Be->b[i] * N_VDotProdLocal(work_space_2[j], step_mem->Fe[i]); + } } else if (step_mem->implicit) { for (j = 0; j < num_relax_fn; j++) + { delta_e_out[j] += step_mem->Bi->b[i] * N_VDotProdLocal(work_space_2[j], step_mem->Fi[i]); + } } } @@ -3115,9 +3123,9 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, N_VDotProdMultiAllReduce(num_relax_fn, ark_mem->tempv1, delta_e_out); for (j = 0; j < num_relax_fn; j++) + { delta_e_out[j] *= ark_mem->h; - - /* printf("de = %23.16e\n", delta_e_out[0]); */ + } return ARK_SUCCESS; } diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index f8d3269f13..e1dbf7a19e 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -283,7 +283,7 @@ int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) return arkRelaxSetMaxIters(arkode_mem, max_iters); } -int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) { return arkRelaxSetSolver(arkode_mem, solver); } diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index 1980536dca..6d2cf5f2e0 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1133,6 +1133,149 @@ int erkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) return(ARK_SUCCESS); } +/* ----------------------------------------------------------------------------- + * erkStep_RelaxDeltaY + * + * Computes the RK update to yn for use in relaxation methods + * ---------------------------------------------------------------------------*/ + +int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) +{ + int i, nvec, retval; + realtype* cvals; + N_Vector* Xvecs; + ARKodeERKStepMem step_mem; + + /* Access the stepper memory structure */ + if (!(ark_mem->step_mem)) + { + arkProcessError(ark_mem, ARK_MEM_NULL, "ARKODE::ERKStep", + "erkStep_RelaxDeltaY", MSG_ERKSTEP_NO_MEM); + return ARK_MEM_NULL; + } + step_mem = (ARKodeERKStepMem)(ark_mem->step_mem); + + /* Set arrays for fused vector operation */ + cvals = step_mem->cvals; + Xvecs = step_mem->Xvecs; + + nvec = 0; + for (i = 0; i < step_mem->stages; i++) + { + cvals[nvec] = ark_mem->h * step_mem->B->b[i]; + Xvecs[nvec] = step_mem->F[i]; + nvec++; + } + + /* Compute time step update (delta_y) */ + retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv1); + if (retval) return ARK_VECTOROP_ERR; + + *delta_y = ark_mem->tempv1; + + return ARK_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + * erkStep_RelaxDeltaE + * + * Computes the change in the relaxation functions for use in relaxation methods + * delta_e = h * sum_i b_i * + * ---------------------------------------------------------------------------*/ + +int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, + ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, + N_Vector* work_space_2, long int* num_relax_jac_evals, + sunrealtype* delta_e_out) +{ + int i, j, nvec, retval; + realtype* cvals; + N_Vector* Xvecs; + ARKodeERKStepMem step_mem; + + /* Access the stepper memory structure */ + if (!(ark_mem->step_mem)) + { + arkProcessError(ark_mem, ARK_MEM_NULL, "ARKODE::ERKStep", + "erkStep_RelaxDeltaE", MSG_ERKSTEP_NO_MEM); + return ARK_MEM_NULL; + } + step_mem = (ARKodeERKStepMem)(ark_mem->step_mem); + + /* Initialize output */ + for (j = 0; j < num_relax_fn; j++) + { + delta_e_out[j] = ZERO; + } + + /* Set arrays for fused vector operation */ + cvals = step_mem->cvals; + Xvecs = step_mem->Xvecs; + + for (i = 0; i < step_mem->stages; i++) + { + nvec = 0; + + /* Start with y_n */ + cvals[nvec] = ONE; + Xvecs[nvec] = ark_mem->yn; + nvec++; + + /* Explicit pieces */ + for (j = 0; j < i; j++) + { + cvals[nvec] = ark_mem->h * step_mem->B->A[i][j]; + Xvecs[nvec] = step_mem->F[j]; + nvec++; + } + + /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] */ + retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv2); + if (retval) return ARK_VECTOROP_ERR; + + /* Duplicate stage to compute entropy Jacobians at z_i */ + for (j = 0; j < num_relax_fn; j++) + { + N_VScale(ONE, ark_mem->tempv2, work_space_1[j]); + } + + /* Evaluate the Jacobians at z_i */ + retval = relax_jac_fn(work_space_1, work_space_2, ark_mem->user_data); + (*num_relax_jac_evals)++; + if (retval < 0) { return ARK_RELAX_JAC_FAIL; } + if (retval > 0) { return ARK_RELAX_JAC_RECV; } + + /* Update estimates */ + for (j = 0; j < num_relax_fn; j++) + { + delta_e_out[j] += step_mem->B->b[i] * N_VDotProdLocal(work_space_2[j], + step_mem->F[i]); + } + } + + /* Ignore negative return for node-local vectors where this is a non-op */ + N_VDotProdMultiAllReduce(num_relax_fn, ark_mem->tempv1, delta_e_out); + + for (j = 0; j < num_relax_fn; j++) + { + delta_e_out[j] *= ark_mem->h; + } + + return ARK_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + * erkStep_GetOrder + * + * Returns the method order + * ---------------------------------------------------------------------------*/ + +int erkStep_GetOrder(ARKodeMem ark_mem) +{ + ARKodeERKStepMem step_mem = (ARKodeERKStepMem)(ark_mem->step_mem); + return step_mem->q; +} + /*=============================================================== EOF ===============================================================*/ diff --git a/src/arkode/arkode_erkstep_impl.h b/src/arkode/arkode_erkstep_impl.h index 85c709a8f9..bac537a6a6 100644 --- a/src/arkode/arkode_erkstep_impl.h +++ b/src/arkode/arkode_erkstep_impl.h @@ -83,6 +83,14 @@ int erkStep_SetButcherTable(ARKodeMem ark_mem); int erkStep_CheckButcherTable(ARKodeMem ark_mem); int erkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsm); +/* private functions for relaxation */ +int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y); +int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, + ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, + N_Vector* work_space_2, long int* relax_jac_fn_evals, + sunrealtype* delta_e_out); +int erkStep_GetOrder(ARKodeMem ark_mem); + /*=============================================================== Reusable ERKStep Error Messages ===============================================================*/ diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 91793936e4..1ceca8a5c9 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -148,6 +148,66 @@ int ERKStepGetUserData(void *arkode_mem, void** user_data) { char *ERKStepGetReturnFlagName(long int flag) { return(arkGetReturnFlagName(flag)); } +/* ----------------------------------------------------------------------------- + * Wrappers for the ARKODE relaxation module + * ---------------------------------------------------------------------------*/ + +int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, + ARKRelaxJacFn rjac) +{ + return arkRelaxCreate(arkode_mem, nrfn, rfn, rjac, erkStep_RelaxDeltaY, + erkStep_RelaxDeltaE, erkStep_GetOrder); +} + +int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +{ + return arkRelaxSetEtaFail(arkode_mem, eta_rf); +} + +int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +{ + return arkRelaxSetLowerBound(arkode_mem, lower); +} + +int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) +{ + return arkRelaxSetMaxIters(arkode_mem, max_iters); +} + +int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +{ + return arkRelaxSetSolver(arkode_mem, solver); +} + +int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +{ + return arkRelaxSetTol(arkode_mem, tol); +} + +int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) +{ + return arkRelaxSetUpperBound(arkode_mem, upper); +} + +int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) +{ + return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); +} + +int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) +{ + return arkRelaxGetNumRelaxJacEvals(arkode_mem, J_evals); +} + +int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) +{ + return arkRelaxGetNumSolveFails(arkode_mem, fails); +} + +int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) +{ + return arkRelaxGetNumSolveIters(arkode_mem, iters); +} /*=============================================================== ERKStep optional input functions -- stepper-specific From 6aed8b0f9d3d59cd70929fc27714db1380dd6e4b Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 17:33:12 -0800 Subject: [PATCH 025/111] add ERKStep docs --- CHANGELOG.md | 3 +- doc/arkode/guide/source/Introduction.rst | 6 +- doc/arkode/guide/source/Mathematics.rst | 1 + .../Usage/ERKStep_c_interface/Relaxation.rst | 200 ++++++++++++++++++ .../Usage/ERKStep_c_interface/index.rst | 1 + 5 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index 938d3363f8..c207487a1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## Changes to SUNDIALS in release 6.6.0 -Added support for relaxation Runge-Kutta methods to ARKStep. +Added support for relaxation Runge-Kutta methods to ERKStep and ARKStep in +ARKODE. ## Changes to SUNDIALS in release 6.5.0 diff --git a/doc/arkode/guide/source/Introduction.rst b/doc/arkode/guide/source/Introduction.rst index 64caa821f7..4884e41772 100644 --- a/doc/arkode/guide/source/Introduction.rst +++ b/doc/arkode/guide/source/Introduction.rst @@ -121,9 +121,9 @@ Changes from previous versions Changes in v5.6.0 ----------------- -Added support for relaxation Runge-Kutta methods in ARKStep, see -:numref:`ARKODE.Mathematics.Relaxation` and -:numref:`ARKODE.Usage.ARKStep.Relaxation` for more information. +Added support for relaxation Runge-Kutta methods in ERKStep and ARKStep, see +:numref:`ARKODE.Mathematics.Relaxation`, :numref:`ARKODE.Usage.ERKStep.Relaxation`, +and :numref:`ARKODE.Usage.ARKStep.Relaxation` for more information. Changes in v5.5.0 ----------------- diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 563d4b9d49..28adb94432 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2123,4 +2123,5 @@ relaxation values for each function and select :math:`r = \min_i r_i`. As a result each :math:`\xi_i(y)` will be dissipated. For more information on utilizing relaxation Runge-Kutta methods, see +:numref:`ARKODE.Usage.ERKStep.Relaxation` and :numref:`ARKODE.Usage.ARKStep.Relaxation`. diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst new file mode 100644 index 0000000000..874f7f2676 --- /dev/null +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -0,0 +1,200 @@ +.. ----------------------------------------------------------------------------- + Programmer(s): David J. Gardner @ LLNL + ----------------------------------------------------------------------------- + SUNDIALS Copyright Start + Copyright (c) 2002-2022, 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.ERKStep.Relaxation: + +Relaxation Methods +================== + +This section describes user-callable functions for utilizing relaxation methods +with ERKStep. For more information on relaxation Runge-Kutta methods see +:numref:`ARKODE.Mathematics.Relaxation`. + +Enabling or Disabling Relaxation +-------------------------------- + +.. c:function:: int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac); + + Attaches the user supplied functions for evaluating the relaxation function + (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation + functions (``nrfn``). + + :param arkode_mem: the ERKStep memory structure + :param nrfn: the number of relaxation functions + :param rfn: the user-defined function to compute the relaxation function + :math:`\xi_i(y)` + :param rjac: the user-defined function to compute the relaxation Jacobian + :math:`\xi'_i(y)` + + :retval ARK_SUCCESS: the function exited successfully + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_ILL_INPUT: an invalid input combination was provided see the + output error message for more details + :retval ARK_MEM_FAIL: a memory allocation failed + + .. note:: + + If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. + +Optional Input Functions +------------------------ + +This section describes optional input functions used to control the relaxation +method. + +.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); + + Sets the step size reduction factor applied after a failed relaxation solve. + The default value is 0.25. Input values :math:`\geq 1` will result in the + default value being used. + + :param arkode_mem: the ERKStep memory structure + :param eta_rf: the step size reduction factor + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); + + Sets the smallest acceptable value for the relaxation parameter. Values + smaller than the lower bound will result in a relaxation solve failure and + the step will be repeated with a smaller step size (determined by + :c:func:`ERKStepSetRelaxEtaFail`). The default value is 0.8. Input values + :math:`\geq 1` will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param lower: the relaxation parameter lower bound + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); + + Sets the maximum number of nonlinear iterations allowed when solving for the + relaxation parameter. If the maximum number of iterations is reached before + meeting the solve tolerance (determined by :c:func:`ERKStepSetRelaxTol`), the + step will be repeated with a smaller step size (determined by + :c:func:`ERKStepSetRelaxEtaFail`). The default value is 5. Input values + :math:`\leq 0` will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param max_iters: the maximum number of solver iterations allowed + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver); + + Sets the nonlinear solver method used to compute the relaxation parameter. + The default value is ``ARK_RELAX_NEWTON``. + + :param arkode_mem: the ERKStep memory structure + :param solver: the nonlinear solver to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); + + Sets the nonlinear solver tolerance to use when computing the relaxation + parameter. If the tolerance is not reached within the maximum number of + iterations (determined by :c:func:`ERKStepSetRelaxMaxIters`), the step will + be repeated with a smaller step size (determined by + :c:func:`ERKStepSetRelaxEtaFail`). The default value is 1.0e-14. Input values + :math:`\leq 0.0` will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param tol: the nonlinear solver tolerance to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); + + Sets the largest acceptable value for the relaxation parameter. Values + larger than the upper bound will result in a relaxation solve failure and + the step will be repeated with a smaller step size (determined by + :c:func:`ERKStepSetRelaxEtaFail`). The default value is 1.2. Input values + :math:`\leq 1` will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param eta_rf: the relaxation parameter upper bound + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +Optional Output Functions +------------------------- + +This section describes optional output functions used to retrieve information +about the performance of the relaxation method. + +.. c:function:: int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); + + Get the number of times the user's relaxation function was evaluated. + + :param arkode_mem: the ERKStep memory structure + :param r_evals: the number of relaxation function evaluations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); + + Get the number of times the user's relaxation Jacobian was evaluated. + + :param arkode_mem: the ERKStep memory structure + :param J_evals: the number of relaxation Jacobian evaluations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); + + Get the number of times the relaxation parameter nonlinear solver failed. + + :param arkode_mem: the ERKStep memory structure + :param fails: the number of relaxation nonlinear solver failures + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters); + + Get the number of relaxation parameter nonlinear solver iterations. + + :param arkode_mem: the ERKStep memory structure + :param iters: the number of relaxation nonlinear solver iterations + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/index.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/index.rst index f2e40f2b12..2bf289488f 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/index.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/index.rst @@ -42,3 +42,4 @@ detailed in the following sub-sections. Skeleton User_callable + Relaxation From 0844c41d4c017130f0255b426a23897ba10c4850 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 20:45:09 -0800 Subject: [PATCH 026/111] limit max relax failures in a step --- .../Usage/ARKStep_c_interface/Relaxation.rst | 48 ++++++++--- .../Usage/ERKStep_c_interface/Relaxation.rst | 48 ++++++++--- include/arkode/arkode.h | 8 +- include/arkode/arkode_arkstep.h | 3 + include/arkode/arkode_erkstep.h | 5 +- src/arkode/arkode.c | 4 +- src/arkode/arkode_arkstep_io.c | 14 +++- src/arkode/arkode_erkstep_io.c | 14 +++- src/arkode/arkode_relaxation.c | 81 +++++++++++++++---- src/arkode/arkode_relaxation_impl.h | 22 +++-- 10 files changed, 192 insertions(+), 55 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 998a6a0984..e55059fbd0 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -24,7 +24,7 @@ with ARKStep. For more information on relaxation Runge-Kutta methods see Enabling or Disabling Relaxation -------------------------------- -.. c:function:: int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac); +.. c:function:: int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac) Attaches the user supplied functions for evaluating the relaxation function (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation @@ -53,7 +53,7 @@ Optional Input Functions This section describes optional input functions used to control the relaxation method. -.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); +.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) Sets the step size reduction factor applied after a failed relaxation solve. The default value is 0.25. Input values :math:`\geq 1` will result in the @@ -67,7 +67,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); +.. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) Sets the smallest acceptable value for the relaxation parameter. Values smaller than the lower bound will result in a relaxation solve failure and @@ -83,7 +83,21 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); +.. c:function:: int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) + + Sets the maximum number relaxation failures allowed in a single step attempt + before the integration is halted with an error. The default value is 10. + Input values :math:`\leq 0` will result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param max_iters: the maximum number relaxtion failures allowed in a step + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the relaxation parameter. If the maximum number of iterations is reached before @@ -100,7 +114,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver); +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. @@ -113,7 +127,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +.. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) Sets the nonlinear solver tolerance to use when computing the relaxation parameter. If the tolerance is not reached within the maximum number of @@ -130,7 +144,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); +.. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) Sets the largest acceptable value for the relaxation parameter. Values larger than the upper bound will result in a relaxation solve failure and @@ -152,7 +166,7 @@ Optional Output Functions This section describes optional output functions used to retrieve information about the performance of the relaxation method. -.. c:function:: int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); +.. c:function:: int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) Get the number of times the user's relaxation function was evaluated. @@ -164,7 +178,7 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); +.. c:function:: int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) Get the number of times the user's relaxation Jacobian was evaluated. @@ -176,7 +190,19 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); +.. c:function:: int ARKStepGetNumRelaxFails(void* arkode_mem, long int* fails) + + Get the total number of relaxation failures. + + :param arkode_mem: the ARKStep memory structure + :param fails: the total number of relaxation failures + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) Get the number of times the relaxation parameter nonlinear solver failed. @@ -188,7 +214,7 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters); +.. c:function:: int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) Get the number of relaxation parameter nonlinear solver iterations. diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index 874f7f2676..55fd5ec651 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -24,7 +24,7 @@ with ERKStep. For more information on relaxation Runge-Kutta methods see Enabling or Disabling Relaxation -------------------------------- -.. c:function:: int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac); +.. c:function:: int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac) Attaches the user supplied functions for evaluating the relaxation function (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation @@ -53,7 +53,7 @@ Optional Input Functions This section describes optional input functions used to control the relaxation method. -.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); +.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) Sets the step size reduction factor applied after a failed relaxation solve. The default value is 0.25. Input values :math:`\geq 1` will result in the @@ -67,7 +67,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); +.. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) Sets the smallest acceptable value for the relaxation parameter. Values smaller than the lower bound will result in a relaxation solve failure and @@ -83,7 +83,21 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); +.. c:function:: int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) + + Sets the maximum number relaxation failures allowed in a single step attempt + before the integration is halted with an error. The default value is 10. + Input values :math:`\leq 0` will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param max_iters: the maximum number relaxtion failures allowed in a step + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the relaxation parameter. If the maximum number of iterations is reached before @@ -100,7 +114,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver); +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. @@ -113,7 +127,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +.. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) Sets the nonlinear solver tolerance to use when computing the relaxation parameter. If the tolerance is not reached within the maximum number of @@ -130,7 +144,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); +.. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) Sets the largest acceptable value for the relaxation parameter. Values larger than the upper bound will result in a relaxation solve failure and @@ -152,7 +166,7 @@ Optional Output Functions This section describes optional output functions used to retrieve information about the performance of the relaxation method. -.. c:function:: int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); +.. c:function:: int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) Get the number of times the user's relaxation function was evaluated. @@ -164,7 +178,7 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); +.. c:function:: int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) Get the number of times the user's relaxation Jacobian was evaluated. @@ -176,7 +190,19 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); +.. c:function:: int ERKStepGetNumRelaxFails(void* arkode_mem, long int* fails) + + Get the total number of relaxation failures. + + :param arkode_mem: the ERKStep memory structure + :param fails: the total number of relaxation failures + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + +.. c:function:: int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) Get the number of times the relaxation parameter nonlinear solver failed. @@ -188,7 +214,7 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters); +.. c:function:: int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) Get the number of relaxation parameter nonlinear solver iterations. diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index ce2483b177..f333090789 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -132,9 +132,11 @@ extern "C" { #define ARK_CONTEXT_ERR -42 -#define ARK_RELAX_MEM_NULL -43 -#define ARK_RELAX_FUNC_FAIL -44 -#define ARK_RELAX_JAC_FAIL -45 +#define ARK_RELAX_FAIL -43 +#define ARK_RELAX_MEM_NULL -44 +#define ARK_RELAX_FUNC_FAIL -45 +#define ARK_RELAX_JAC_FAIL -46 + #define ARK_UNRECOGNIZED_ERROR -99 diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 9ab04644dc..eb2465bd22 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -477,6 +477,7 @@ SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); +SUNDIALS_EXPORT int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver); @@ -487,6 +488,8 @@ SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); +SUNDIALS_EXPORT int ARKStepGetNumRelaxFails(void* arkode_mem, + long int* relax_fails); SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveIters(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 3be24cba09..5e1e290761 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -266,9 +266,10 @@ SUNDIALS_EXPORT int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower); +SUNDIALS_EXPORT int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, - ARKRelaxationSolver solver); + ARKRelaxationSolver solver); SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); @@ -276,6 +277,8 @@ SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); +SUNDIALS_EXPORT int ERKStepGetNumRelaxFails(void* arkode_mem, + long int* relax_fails); SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveIters(void* arkode_mem, diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 0cd8d9e285..dbc2e8c516 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -646,6 +646,7 @@ int arkEvolve(ARKodeMem ark_mem, realtype tout, N_Vector yout, booleantype inactive_roots; realtype dsm; int nflag, attempts, ncf, nef, constrfails; + int relax_fails; /* Check and process inputs */ @@ -829,6 +830,7 @@ int arkEvolve(ARKodeMem ark_mem, realtype tout, N_Vector yout, /* Looping point for step attempts */ dsm = ZERO; attempts = ncf = nef = constrfails = ark_mem->last_kflag = 0; + relax_fails = 0; nflag = FIRST_CALL; for(;;) { @@ -857,7 +859,7 @@ int arkEvolve(ARKodeMem ark_mem, realtype tout, N_Vector yout, /* Perform relaxation */ if (ark_mem->relax_enabled && (kflag == ARK_SUCCESS)) { - kflag = arkRelax(ark_mem, &dsm, &nflag); + kflag = arkRelax(ark_mem, &relax_fails, &dsm, &nflag); if (kflag < 0) break; } diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index e1dbf7a19e..9179ef192a 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -278,6 +278,11 @@ int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) return arkRelaxSetLowerBound(arkode_mem, lower); } +int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) +{ + arkRelaxSetMaxFails(arkode_mem, max_fails); +} + int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) { return arkRelaxSetMaxIters(arkode_mem, max_iters); @@ -308,14 +313,19 @@ int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) return arkRelaxGetNumRelaxJacEvals(arkode_mem, J_evals); } +int ARKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails) +{ + return arkRelaxGetNumRelaxFails(arkode_mem, relax_fails); +} + int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) { - return arkRelaxGetNumSolveFails(arkode_mem, fails); + return arkRelaxGetNumRelaxSolveFails(arkode_mem, fails); } int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) { - return arkRelaxGetNumSolveIters(arkode_mem, iters); + return arkRelaxGetNumRelaxSolveIters(arkode_mem, iters); } /*=============================================================== diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 1ceca8a5c9..d1eda14c19 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -169,6 +169,11 @@ int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) return arkRelaxSetLowerBound(arkode_mem, lower); } +int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) +{ + arkRelaxSetMaxFails(arkode_mem, max_fails); +} + int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) { return arkRelaxSetMaxIters(arkode_mem, max_iters); @@ -199,14 +204,19 @@ int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) return arkRelaxGetNumRelaxJacEvals(arkode_mem, J_evals); } +int ERKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails) +{ + return arkRelaxGetNumRelaxFails(arkode_mem, relax_fails); +} + int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) { - return arkRelaxGetNumSolveFails(arkode_mem, fails); + return arkRelaxGetNumRelaxSolveFails(arkode_mem, fails); } int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) { - return arkRelaxGetNumSolveIters(arkode_mem, iters); + return arkRelaxGetNumRelaxSolveIters(arkode_mem, iters); } /*=============================================================== diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 6c184df3c6..cdeb10d07c 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -128,7 +128,7 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) if (max_res < relax_mem->tol) return ARK_SUCCESS; /* Update iteration count */ - relax_mem->total_iters++; + relax_mem->nls_iters++; /* Compute Jacobian and update */ retval = arkRelaxJacobian(relax_mem->relax_vals, relax_mem->y_relax, @@ -169,7 +169,7 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) if (max_res < relax_mem->tol) return ARK_SUCCESS; /* Update iteration count */ - relax_mem->total_iters++; + relax_mem->nls_iters++; for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) relax_mem->relax_vals[i] -= relax_mem->res_vals[i]; @@ -227,7 +227,7 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, /* Check for solver failure */ if (retval) { - relax_mem->total_fails++; + relax_mem->nls_fails++; return retval; } @@ -291,6 +291,22 @@ int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower) return ARK_SUCCESS; } +int arkRelaxSetMaxFails(void* arkode_mem, int max_fails) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetMaxFails", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (max_fails > 0) relax_mem->max_fails = max_fails; + else relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; + + return ARK_SUCCESS; +} + int arkRelaxSetMaxIters(void* arkode_mem, int max_iters) { int retval; @@ -387,32 +403,47 @@ int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) return ARK_SUCCESS; } -int arkRelaxGetNumSolveFails(void* arkode_mem, long int* fails) +int arkRelaxGetNumRelaxFails(void* arkode_mem, long int* relax_fails) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumSolveFails", &ark_mem, + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxFails", &ark_mem, &relax_mem); if (retval) return retval; - *fails = relax_mem->total_fails; + *relax_fails = relax_mem->num_fails; return ARK_SUCCESS; } -int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters) +int arkRelaxGetNumRelaxSolveFails(void* arkode_mem, long int* fails) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumSolveIters", &ark_mem, - &relax_mem); + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxSolveFails", + &ark_mem, &relax_mem); + if (retval) return retval; + + *fails = relax_mem->nls_fails; + + return ARK_SUCCESS; +} + +int arkRelaxGetNumRelaxSolveIters(void* arkode_mem, long int* iters) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxSolveIters", + &ark_mem, &relax_mem); if (retval) return retval; - *iters = relax_mem->total_iters; + *iters = relax_mem->nls_iters; return ARK_SUCCESS; } @@ -434,15 +465,18 @@ int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) relax_mem->num_relax_fn_evals); fprintf(outfile, "Relax Jac evals = %ld\n", relax_mem->num_relax_jac_evals); + fprintf(outfile, "Relax fails = %ld\n", + relax_mem->num_fails); fprintf(outfile, "Relax NLS iters = %ld\n", - relax_mem->total_iters); + relax_mem->nls_iters); fprintf(outfile, "Relax NLS fails = %ld\n", - relax_mem->total_fails); + relax_mem->nls_fails); case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, ",Relax fn evals,%ld", relax_mem->num_relax_fn_evals); fprintf(outfile, ",Relax Jac evals,%ld", relax_mem->num_relax_jac_evals); - fprintf(outfile, ",Relax NLS iters,%ld", relax_mem->total_iters); - fprintf(outfile, ",Relax NLS fails,%ld", relax_mem->total_fails); + fprintf(outfile, ",Relax fails,%ld", relax_mem->num_fails); + fprintf(outfile, ",Relax NLS iters,%ld", relax_mem->nls_iters); + fprintf(outfile, ",Relax NLS fails,%ld", relax_mem->nls_fails); default: arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxPrintAllStats", "Invalid formatting option."); @@ -602,6 +636,7 @@ int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, ark_mem->relax_mem->delta_e_fn = delta_e_fn; ark_mem->relax_mem->get_order_fn = get_order_fn; ark_mem->relax_mem->num_relax_fn = num_relax_fn; + ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; @@ -671,7 +706,8 @@ int arkRelaxDestroy(ARKodeRelaxMem relax_mem) } /* Compute and apply relaxation, called by driver */ -int arkRelax(ARKodeMem ark_mem, realtype* dsm_inout, int* nflag_out) +int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, + int* nflag_out) { int retval; sunrealtype relax_val; @@ -690,8 +726,21 @@ int arkRelax(ARKodeMem ark_mem, realtype* dsm_inout, int* nflag_out) if (retval < 0) return retval; if (retval > 0) { - /* Recoverable failure, cut step size and try again */ + /* Update failure counts */ + relax_mem->num_fails++; + (*relax_fails)++; + + /* Check for max fails in a step */ + if (*relax_fails == relax_mem->max_fails) + return ARK_RELAX_FAIL; + + /* Return with an error if |h| == hmin */ + if (SUNRabs(ark_mem->h) <= ark_mem->hmin * ONEPSM) + return ARK_RELAX_FAIL; + + /* Cut step size and try again */ ark_mem->eta = relax_mem->eta_fail; + return TRY_AGAIN; } diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 1a2977133b..e41014e815 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -29,6 +29,7 @@ * Relaxation Constants * ---------------------------------------------------------------------------*/ +#define ARK_RELAX_DEFAULT_MAX_FAILS 10 #define ARK_RELAX_DEFAULT_TOL SUN_RCONST(1.0e-14) #define ARK_RELAX_DEFAULT_MAX_ITERS 5 #define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) @@ -41,7 +42,7 @@ #define ARK_RELAX_FUNC_RECV 1; #define ARK_RELAX_JAC_RECV 2; -#define ARK_RELAX_SOLVE_RECV -1; /* <<< should be recoverable */ +#define ARK_RELAX_SOLVE_RECV 3; /* ----------------------------------------------------------------------------- * Stepper Supplied Relaxation Functions @@ -79,8 +80,10 @@ struct ARKodeRelaxMemRec /* relaxation variables */ int num_relax_fn; /* number of entropy functions */ int num_relax_fn_alloc; /* allocated workspce size */ - long int num_relax_fn_evals; /* counter for function evals */ - long int num_relax_jac_evals; /* counter for jacobian evals */ + int max_fails; /* max allowed relax fails in a step */ + long int num_relax_fn_evals; /* counter for total function evals */ + long int num_relax_jac_evals; /* counter for total jacobian evals */ + long int num_fails; /* counter for total relaxation fails */ N_Vector* y_relax; /* relaxed state y_n + relax * delta_y */ N_Vector* J_vecs; /* relaxation Jacobian vectors */ sunrealtype* e_old; /* entropy at start of step y(t_{n-1}) */ @@ -95,8 +98,8 @@ struct ARKodeRelaxMemRec ARKRelaxationSolver solver; /* choice of relaxation solver */ sunrealtype tol; /* nonlinear solve tolerance */ int max_iters; /* nonlinear solve max iterations */ - long int total_iters; /* total nonlinear iterations */ - long int total_fails; /* number of nonlinear solver fails */ + long int nls_iters; /* total nonlinear iterations */ + long int nls_fails; /* number of nonlinear solver fails */ }; /* ----------------------------------------------------------------------------- @@ -109,11 +112,13 @@ int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, ARKRelaxDeltaEFn delta_e_fn, ARKRelaxGetOrderFn get_order_fn); int arkRelaxDestroy(ARKodeRelaxMem relax_mem); -int arkRelax(ARKodeMem ark_mem, sunrealtype* dsm_inout, int* nflag_out); +int arkRelax(ARKodeMem ark_mem, int* relax_fails, sunrealtype* dsm_inout, + int* nflag_out); /* User Functions */ int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail); int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); +int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); int arkRelaxSetSolver(void* arkode_mem, ARKRelaxationSolver solver); int arkRelaxSetTol(void* arkode_mem, sunrealtype tol); @@ -121,8 +126,9 @@ int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* j_evals); -int arkRelaxGetNumSolveFails(void* arkode_mem, long int* fails); -int arkRelaxGetNumSolveIters(void* arkode_mem, long int* iters); +int arkRelaxGetNumRelaxFails(void* arkode_mem, long int* relax_fails); +int arkRelaxGetNumRelaxSolveFails(void* arkode_mem, long int* fails); +int arkRelaxGetNumRelaxSolveIters(void* arkode_mem, long int* iters); int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt); From 2a4a30267e25d1ef4a65b709580736f1800f00b7 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 20:50:42 -0800 Subject: [PATCH 027/111] add missing returns --- src/arkode/arkode_arkstep_io.c | 2 +- src/arkode/arkode_erkstep_io.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 9179ef192a..75816132c0 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -280,7 +280,7 @@ int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) { - arkRelaxSetMaxFails(arkode_mem, max_fails); + return arkRelaxSetMaxFails(arkode_mem, max_fails); } int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index d1eda14c19..1fa09ee102 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -171,7 +171,7 @@ int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) { - arkRelaxSetMaxFails(arkode_mem, max_fails); + return arkRelaxSetMaxFails(arkode_mem, max_fails); } int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) From ddbe7606fece16bb13a0ea5b4e089dc1d5f00ae4 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 10 Jan 2023 21:42:03 -0800 Subject: [PATCH 028/111] rename ARKRelaxationSolver --- .../guide/source/Usage/ARKStep_c_interface/Relaxation.rst | 2 +- .../guide/source/Usage/ERKStep_c_interface/Relaxation.rst | 2 +- include/arkode/arkode.h | 2 +- include/arkode/arkode_arkstep.h | 2 +- include/arkode/arkode_erkstep.h | 2 +- src/arkode/arkode_arkstep_io.c | 2 +- src/arkode/arkode_erkstep_io.c | 2 +- src/arkode/arkode_relaxation.c | 2 +- src/arkode/arkode_relaxation_impl.h | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index e55059fbd0..f838b8beb3 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -114,7 +114,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index 55fd5ec651..e71c429d88 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -114,7 +114,7 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index f333090789..a2c85b25eb 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -193,7 +193,7 @@ typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; typedef enum { ARK_RELAX_NEWTON, ARK_RELAX_FIXEDPOINT -} ARKRelaxationSolver; +} ARKRelaxSolver; #ifdef __cplusplus } diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index eb2465bd22..05136cad9a 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -480,7 +480,7 @@ SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, SUNDIALS_EXPORT int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, - ARKRelaxationSolver solver); + ARKRelaxSolver solver); SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 5e1e290761..9c1226fe97 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -269,7 +269,7 @@ SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, SUNDIALS_EXPORT int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, - ARKRelaxationSolver solver); + ARKRelaxSolver solver); SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 75816132c0..fd60d3f93c 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -288,7 +288,7 @@ int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) return arkRelaxSetMaxIters(arkode_mem, max_iters); } -int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) { return arkRelaxSetSolver(arkode_mem, solver); } diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 1fa09ee102..074321310b 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -179,7 +179,7 @@ int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) return arkRelaxSetMaxIters(arkode_mem, max_iters); } -int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxationSolver solver) +int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) { return arkRelaxSetSolver(arkode_mem, solver); } diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index cdeb10d07c..e9ce31e9f7 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -323,7 +323,7 @@ int arkRelaxSetMaxIters(void* arkode_mem, int max_iters) return ARK_SUCCESS; } -int arkRelaxSetSolver(void* arkode_mem, ARKRelaxationSolver solver) +int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver) { int retval; ARKodeMem ark_mem; diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index e41014e815..3729ff3e2f 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -95,7 +95,7 @@ struct ARKodeRelaxMemRec sunrealtype eta_fail; /* failed relaxation step size factor */ /* nonlinear solver settings */ - ARKRelaxationSolver solver; /* choice of relaxation solver */ + ARKRelaxSolver solver; /* choice of relaxation solver */ sunrealtype tol; /* nonlinear solve tolerance */ int max_iters; /* nonlinear solve max iterations */ long int nls_iters; /* total nonlinear iterations */ @@ -120,7 +120,7 @@ int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail); int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); -int arkRelaxSetSolver(void* arkode_mem, ARKRelaxationSolver solver); +int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver); int arkRelaxSetTol(void* arkode_mem, sunrealtype tol); int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); From 026c44abfe84dc94b56c5c9aa89e3b9427744d82 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 11 Jan 2023 07:35:13 -0800 Subject: [PATCH 029/111] add versionadded to docs --- .../Usage/ARKStep_c_interface/Relaxation.rst | 27 +++++++++++++++++++ .../Usage/ERKStep_c_interface/Relaxation.rst | 27 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index f838b8beb3..f124147ebe 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -47,6 +47,8 @@ Enabling or Disabling Relaxation If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. + .. versionadded:: 5.6.0 + Optional Input Functions ------------------------ @@ -67,6 +69,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) Sets the smallest acceptable value for the relaxation parameter. Values @@ -83,6 +87,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) Sets the maximum number relaxation failures allowed in a single step attempt @@ -97,6 +103,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the @@ -114,6 +122,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. @@ -127,6 +137,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) Sets the nonlinear solver tolerance to use when computing the relaxation @@ -144,6 +156,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) Sets the largest acceptable value for the relaxation parameter. Values @@ -160,6 +174,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + Optional Output Functions ------------------------- @@ -178,6 +194,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) Get the number of times the user's relaxation Jacobian was evaluated. @@ -190,6 +208,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepGetNumRelaxFails(void* arkode_mem, long int* fails) Get the total number of relaxation failures. @@ -202,6 +222,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) Get the number of times the relaxation parameter nonlinear solver failed. @@ -214,6 +236,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) Get the number of relaxation parameter nonlinear solver iterations. @@ -224,3 +248,6 @@ about the performance of the relaxation method. :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index e71c429d88..f2110820c6 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -47,6 +47,8 @@ Enabling or Disabling Relaxation If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. + .. versionadded:: 5.6.0 + Optional Input Functions ------------------------ @@ -67,6 +69,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) Sets the smallest acceptable value for the relaxation parameter. Values @@ -83,6 +87,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) Sets the maximum number relaxation failures allowed in a single step attempt @@ -97,6 +103,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the @@ -114,6 +122,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. @@ -127,6 +137,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) Sets the nonlinear solver tolerance to use when computing the relaxation @@ -144,6 +156,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) Sets the largest acceptable value for the relaxation parameter. Values @@ -160,6 +174,8 @@ method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + Optional Output Functions ------------------------- @@ -178,6 +194,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals) Get the number of times the user's relaxation Jacobian was evaluated. @@ -190,6 +208,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepGetNumRelaxFails(void* arkode_mem, long int* fails) Get the total number of relaxation failures. @@ -202,6 +222,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) Get the number of times the relaxation parameter nonlinear solver failed. @@ -214,6 +236,8 @@ about the performance of the relaxation method. :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + .. versionadded:: 5.6.0 + .. c:function:: int ERKStepGetNumRelaxSolveIters(void* arkode_mem, long int* iters) Get the number of relaxation parameter nonlinear solver iterations. @@ -224,3 +248,6 @@ about the performance of the relaxation method. :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 From b35db967ebf1ebc7213f1c1cda8a002d294af8c6 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 11 Jan 2023 09:53:27 -0800 Subject: [PATCH 030/111] clean up examples, fix error in Jac --- examples/arkode/C_serial/CMakeLists.txt | 5 +- .../C_serial/ark_conserved_exp_entropy_ark.c | 127 +++++++----------- .../ark_conserved_exp_entropy_ark_0_1_0.1.out | 121 ----------------- .../C_serial/ark_conserved_exp_entropy_erk.c | 91 ++++--------- 4 files changed, 80 insertions(+), 264 deletions(-) delete mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index c5488d15d5..dc53f4a469 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -26,8 +26,9 @@ set(ARKODE_examples "ark_brusselator\;\;develop" "ark_brusselator_fp\;\;exclude-single" "ark_brusselator1D\;\;exclude-single" - "ark_conserved_exp_entropy_ark\;0 1 0.1\;develop" - "ark_conserved_exp_entropy_erk\;1 0.1\;develop" + "ark_conserved_exp_entropy_ark\;1 0\;develop" + "ark_conserved_exp_entropy_ark\;1 1\;develop" + "ark_conserved_exp_entropy_erk\;1\;develop" "ark_dissipated_exp_entropy\;0 1 0.1\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index eba6a2d7fb..c42cbf1302 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -113,12 +113,11 @@ int main(int argc, char* argv[]) sunrealtype abstol = SUN_RCONST(1.0e-10); /* SUNDIALS context, vector, matrix, and linear solver objects */ - SUNContext ctx = NULL; - N_Vector y = NULL; - N_Vector ytrue = NULL; - SUNMatrix A = NULL; - SUNLinearSolver LS = NULL; - ARKodeButcherTable B = NULL; + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; /* Pointer to vector data array */ sunrealtype* ydata; @@ -135,42 +134,43 @@ int main(int argc, char* argv[]) /* ARKODE statistics */ long int nst, nst_a, nfe, nfi; - long int nre, nrje, nri, nrf; + long int nrf, nre, nrje, nrnlsi, nrnlsf; long int nsetups, nje, nfeLS, nni, ncfn, netf; - /* Number of outputs, output counter, output times, and output file */ - int nout = 10; - int iout; - sunrealtype t, tout, dtout; + /* Output time and file */ + sunrealtype t; FILE* UFID; /* Command line options */ - int implicit = 0; /* explicit */ - int relax = 1; /* enable relaxation */ - int steps = 100; /* number of steps */ - sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ + int relax = 1; /* enable relaxation */ + int implicit = 1; /* implicit */ /* -------------------- * * Output Problem Setup * * -------------------- */ - if (argc > 1) implicit = atoi(argv[1]); - if (argc > 2) relax = atoi(argv[2]); - if (argc > 3) fixed_h = (sunrealtype)atof(argv[3]); - if (argc > 4) steps = atoi(argv[4]); + if (argc > 1) relax = atoi(argv[1]); + if (argc > 2) implicit = atoi(argv[2]); printf("\nConserved Exponential Entropy problem:\n"); - if (implicit) printf(" method = DIRK\n"); - else printf(" method = ERK\n"); - if (relax) printf(" relaxation = ON\n"); - else printf(" relaxation = OFF\n"); - if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); - if (implicit || !(fixed_h > SUN_RCONST(0.0))) + if (implicit) + { + printf(" method = DIRK\n"); + } + else + { + printf(" method = ERK\n"); + } + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); + if (relax) + { + printf(" relaxation = ON\n"); + } + else { - printf(" reltol = %.1" ESYM "\n", reltol); - printf(" abstol = %.1" ESYM "\n", abstol); + printf(" relaxation = OFF\n"); } - printf(" steps = %d\n", steps); printf("\n"); /* ------------ * @@ -202,8 +202,14 @@ int main(int argc, char* argv[]) if (check_flag(flag, "Ent")) return 1; /* Initialize the ARKStep */ - if (implicit) arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); - else arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + if (implicit) + { + arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); + } + else + { + arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + } if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; /* Specify tolerances */ @@ -217,13 +223,6 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; } - if (fixed_h > 0.0) - { - /* Set the step size */ - flag = ARKStepSetFixedStep(arkode_mem, fixed_h); - if (check_flag(flag, "ARKStepSetFixedStep")) return 1; - } - if (implicit) { /* Create dense matrix and linear solver */ @@ -241,30 +240,6 @@ int main(int argc, char* argv[]) flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; } - else if (fixed_h > 0.0) - { - /* Use RK4 */ - B = ARKodeButcherTable_Alloc(4, SUNFALSE); - - B->A[1][0] = SUN_RCONST(0.5); - B->A[2][1] = SUN_RCONST(0.5); - B->A[3][2] = SUN_RCONST(1.0); - - B->c[1] = SUN_RCONST(0.5); - B->c[2] = SUN_RCONST(0.5); - B->c[3] = SUN_RCONST(1.0); - - B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - - B->q = 4; - B->p = 0; - - flag = ARKStepSetTables(arkode_mem, 4, 0, NULL, B); - if (check_flag(flag, "ARKStepSetTables")) return 1; - } /* Open output stream for results, output comment line */ UFID = fopen("ark_conserved_exp_entropy_ark.txt", "w"); @@ -274,10 +249,8 @@ int main(int argc, char* argv[]) * Advance in Time * * --------------- */ - /* Initial time, time between outputs, output time */ - t = t0; - dtout = tf / nout; - tout = t0 + dtout; + /* Initial time */ + t = t0; /* Output the initial condition and entropy */ fprintf(UFID, @@ -295,10 +268,10 @@ int main(int argc, char* argv[]) "\n", t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); - for (iout = 0; iout < steps; iout++) + while (t < tf) { /* Evolve in time */ - flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); + flag = ARKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; /* Output solution and errors */ @@ -320,10 +293,6 @@ int main(int argc, char* argv[]) "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); - - /* Update output time */ - tout += dtout; - tout = (tout > tf) ? tf : tout; } printf(" " @@ -379,22 +348,26 @@ int main(int argc, char* argv[]) if (relax) { + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ARKStepGetNumRelaxFnEvals"); flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ARKStepGetNumRelaxJacEvals"); - flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nri); + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); check_flag(flag, "ARKStepGetNumRelaxSolveIters"); - flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ARKStepGetNumRelaxSolveFails"); + printf(" Total Relaxation fails = %li\n", nrf); printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation iters = %li\n", nri); - printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); } printf("\n"); @@ -438,10 +411,10 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, /* column 0 */ Jdata[0] = 0; - Jdata[1] = -exp(ydata[1]); + Jdata[1] = exp(ydata[0]); /* column 1 */ - Jdata[2] = exp(ydata[0]); + Jdata[2] = -exp(ydata[1]); Jdata[3] = 0; return 0; diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out deleted file mode 100644 index 8b554ec945..0000000000 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_0_1_0.1.out +++ /dev/null @@ -1,121 +0,0 @@ - -Conserved Exponential Entropy problem: - method = ERK - relaxation = ON - fixed h = 0.1 - steps = 100 - - t u v e delta e - ------------------------------------------------------------------------ - 0.000000e+00 1.000000e+00 5.000000e-01 4.367003e+00 0.000000e+00 - 9.999382e-02 8.121005e-01 7.487561e-01 4.367003e+00 0.000000e+00 - 1.999992e-01 5.769249e-01 9.502857e-01 4.367003e+00 0.000000e+00 - 3.000146e-01 2.959876e-01 1.106101e+00 4.367003e+00 0.000000e+00 - 4.000353e-01 -2.543835e-02 1.221455e+00 4.367003e+00 -8.881784e-16 - 5.000560e-01 -3.799263e-01 1.303752e+00 4.367003e+00 -1.776357e-15 - 6.000730e-01 -7.596828e-01 1.360768e+00 4.367003e+00 -1.776357e-15 - 7.000851e-01 -1.157790e+00 1.399414e+00 4.367003e+00 -8.881784e-16 - 8.000923e-01 -1.568735e+00 1.425201e+00 4.367003e+00 -8.881784e-16 - 9.000955e-01 -1.988427e+00 1.442224e+00 4.367003e+00 -1.776357e-15 - 1.000096e+00 -2.413974e+00 1.453379e+00 4.367003e+00 0.000000e+00 - 1.100094e+00 -2.843391e+00 1.460654e+00 4.367003e+00 -1.776357e-15 - 1.200091e+00 -3.275348e+00 1.465383e+00 4.367003e+00 -1.776357e-15 - 1.300086e+00 -3.708962e+00 1.468450e+00 4.367003e+00 -1.776357e-15 - 1.400081e+00 -4.143654e+00 1.470437e+00 4.367003e+00 -2.664535e-15 - 1.500076e+00 -4.579044e+00 1.471724e+00 4.367003e+00 -2.664535e-15 - 1.600070e+00 -5.014888e+00 1.472556e+00 4.367003e+00 -3.552714e-15 - 1.700064e+00 -5.451025e+00 1.473094e+00 4.367003e+00 -4.440892e-15 - 1.800058e+00 -5.887351e+00 1.473441e+00 4.367003e+00 -5.329071e-15 - 1.900052e+00 -6.323800e+00 1.473666e+00 4.367003e+00 -5.329071e-15 - 2.000046e+00 -6.760328e+00 1.473812e+00 4.367003e+00 -4.440892e-15 - 2.100040e+00 -7.196908e+00 1.473905e+00 4.367003e+00 -3.552714e-15 - 2.200034e+00 -7.633521e+00 1.473966e+00 4.367003e+00 -2.664535e-15 - 2.300028e+00 -8.070155e+00 1.474005e+00 4.367003e+00 -8.881784e-16 - 2.400021e+00 -8.506803e+00 1.474031e+00 4.367003e+00 -1.776357e-15 - 2.500015e+00 -8.943460e+00 1.474047e+00 4.367003e+00 -2.664535e-15 - 2.600009e+00 -9.380122e+00 1.474058e+00 4.367003e+00 -1.776357e-15 - 2.700003e+00 -9.816789e+00 1.474064e+00 4.367003e+00 0.000000e+00 - 2.799997e+00 -1.025346e+01 1.474069e+00 4.367003e+00 8.881784e-16 - 2.899990e+00 -1.069013e+01 1.474072e+00 4.367003e+00 8.881784e-15 - 2.999984e+00 -1.112680e+01 1.474074e+00 4.367003e+00 1.509903e-14 - 3.099978e+00 -1.156347e+01 1.474075e+00 4.367003e+00 1.865175e-14 - 3.199972e+00 -1.200014e+01 1.474076e+00 4.367003e+00 2.131628e-14 - 3.299966e+00 -1.243682e+01 1.474076e+00 4.367003e+00 2.309264e-14 - 3.399959e+00 -1.287349e+01 1.474076e+00 4.367003e+00 2.220446e-14 - 3.499953e+00 -1.331016e+01 1.474077e+00 4.367003e+00 2.309264e-14 - 3.599947e+00 -1.374684e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 3.699941e+00 -1.418351e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 3.799935e+00 -1.462018e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 3.899928e+00 -1.505686e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 3.999922e+00 -1.549353e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 4.099916e+00 -1.593020e+01 1.474077e+00 4.367003e+00 2.398082e-14 - 4.199910e+00 -1.636688e+01 1.474077e+00 4.367003e+00 2.575717e-14 - 4.299904e+00 -1.680355e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 4.399898e+00 -1.724022e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 4.499891e+00 -1.767689e+01 1.474077e+00 4.367003e+00 2.309264e-14 - 4.599885e+00 -1.811357e+01 1.474077e+00 4.367003e+00 2.398082e-14 - 4.699879e+00 -1.855024e+01 1.474077e+00 4.367003e+00 2.398082e-14 - 4.799873e+00 -1.898691e+01 1.474077e+00 4.367003e+00 2.486900e-14 - 4.899866e+00 -1.942359e+01 1.474077e+00 4.367003e+00 2.398082e-14 - 4.999860e+00 -1.986026e+01 1.474077e+00 4.367003e+00 2.309264e-14 - 5.099854e+00 -2.029693e+01 1.474077e+00 4.367003e+00 2.220446e-14 - 5.199854e+00 -2.073363e+01 1.474077e+00 4.367003e+00 3.019807e-14 - 5.299854e+00 -2.117033e+01 1.474077e+00 4.367003e+00 3.463896e-14 - 5.399854e+00 -2.160703e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 5.499854e+00 -2.204373e+01 1.474077e+00 4.367003e+00 4.174439e-14 - 5.599854e+00 -2.248043e+01 1.474077e+00 4.367003e+00 4.352074e-14 - 5.699854e+00 -2.291713e+01 1.474077e+00 4.367003e+00 4.352074e-14 - 5.799854e+00 -2.335383e+01 1.474077e+00 4.367003e+00 4.352074e-14 - 5.899854e+00 -2.379053e+01 1.474077e+00 4.367003e+00 4.352074e-14 - 5.999854e+00 -2.422723e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 6.099854e+00 -2.466394e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 6.199854e+00 -2.510064e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 6.299854e+00 -2.553734e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 6.399854e+00 -2.597404e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 6.499854e+00 -2.641074e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 6.599854e+00 -2.684744e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 6.699854e+00 -2.728414e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 6.799854e+00 -2.772084e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 6.899854e+00 -2.815754e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 6.999854e+00 -2.859424e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 7.099854e+00 -2.903094e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 7.199854e+00 -2.946764e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 7.299854e+00 -2.990434e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 7.399854e+00 -3.034104e+01 1.474077e+00 4.367003e+00 4.529710e-14 - 7.499854e+00 -3.077774e+01 1.474077e+00 4.367003e+00 4.440892e-14 - 7.599854e+00 -3.121444e+01 1.474077e+00 4.367003e+00 4.352074e-14 - 7.699854e+00 -3.165114e+01 1.474077e+00 4.367003e+00 4.263256e-14 - 7.799854e+00 -3.208784e+01 1.474077e+00 4.367003e+00 4.263256e-14 - 7.899854e+00 -3.252454e+01 1.474077e+00 4.367003e+00 4.174439e-14 - 7.999854e+00 -3.296124e+01 1.474077e+00 4.367003e+00 4.174439e-14 - 8.099854e+00 -3.339794e+01 1.474077e+00 4.367003e+00 4.263256e-14 - 8.199854e+00 -3.383464e+01 1.474077e+00 4.367003e+00 4.085621e-14 - 8.299854e+00 -3.427134e+01 1.474077e+00 4.367003e+00 3.996803e-14 - 8.399854e+00 -3.470804e+01 1.474077e+00 4.367003e+00 3.996803e-14 - 8.499854e+00 -3.514474e+01 1.474077e+00 4.367003e+00 3.996803e-14 - 8.599854e+00 -3.558144e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 8.699854e+00 -3.601814e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 8.799854e+00 -3.645484e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 8.899854e+00 -3.689154e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 8.999854e+00 -3.732824e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.099854e+00 -3.776494e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.199854e+00 -3.820164e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.299854e+00 -3.863835e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.399854e+00 -3.907505e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.499854e+00 -3.951175e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.599854e+00 -3.994845e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.699854e+00 -4.038515e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.799854e+00 -4.082185e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.899854e+00 -4.125855e+01 1.474077e+00 4.367003e+00 3.907985e-14 - 9.999854e+00 -4.169525e+01 1.474077e+00 4.367003e+00 3.907985e-14 - ------------------------------------------------------------------------ - -Final Solver Statistics: - Internal solver steps = 100 (attempted = 100) - Total number of error test failures = 0 - Total RHS evals: Fe = 401, Fi = 0 - Total Relaxation Fn evals = 100 - Total Relaxation Jac evals = 400 - Total Relaxation iters = 79 - Total Relaxation fails = 0 - diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index 863f9bdf51..b0d33a4ffa 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -107,10 +107,9 @@ int main(int argc, char* argv[]) sunrealtype abstol = SUN_RCONST(1.0e-10); /* SUNDIALS context, vector, matrix, and linear solver objects */ - SUNContext ctx = NULL; - N_Vector y = NULL; - N_Vector ytrue = NULL; - ARKodeButcherTable B = NULL; + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; /* Pointer to vector data array */ sunrealtype* ydata; @@ -127,38 +126,33 @@ int main(int argc, char* argv[]) /* ARKODE statistics */ long int nst, nst_a, nfe; - long int nre, nrje, nri, nrf, netf; + long int nrf, nre, nrje, nrnlsi, nrnlsf, netf; - /* Number of outputs, output counter, output times, and output file */ - int nout = 10; - int iout; - sunrealtype t, tout, dtout; + /* Output time and file */ + sunrealtype t; FILE* UFID; /* Command line options */ - int relax = 1; /* enable relaxation */ - int steps = 100; /* number of steps */ - sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ + int relax = 1; /* enable relaxation */ /* -------------------- * * Output Problem Setup * * -------------------- */ if (argc > 1) relax = atoi(argv[1]); - if (argc > 2) fixed_h = (sunrealtype)atof(argv[2]); - if (argc > 3) steps = atoi(argv[3]); printf("\nConserved Exponential Entropy problem:\n"); printf(" method = ERK\n"); - if (relax) printf(" relaxation = ON\n"); - else printf(" relaxation = OFF\n"); - if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); - if (!(fixed_h > SUN_RCONST(0.0))) + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); + if (relax) + { + printf(" relaxation = ON\n"); + } + else { - printf(" reltol = %.1" ESYM "\n", reltol); - printf(" abstol = %.1" ESYM "\n", abstol); + printf(" relaxation = OFF\n"); } - printf(" steps = %d\n", steps); printf("\n"); /* ------------ * @@ -204,35 +198,6 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ERKStepSetRelaxFn")) return 1; } - if (fixed_h > 0.0) - { - /* Set the step size */ - flag = ERKStepSetFixedStep(arkode_mem, fixed_h); - if (check_flag(flag, "ERKStepSetFixedStep")) return 1; - - /* Use RK4 */ - B = ARKodeButcherTable_Alloc(4, SUNFALSE); - - B->A[1][0] = SUN_RCONST(0.5); - B->A[2][1] = SUN_RCONST(0.5); - B->A[3][2] = SUN_RCONST(1.0); - - B->c[1] = SUN_RCONST(0.5); - B->c[2] = SUN_RCONST(0.5); - B->c[3] = SUN_RCONST(1.0); - - B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - - B->q = 4; - B->p = 0; - - flag = ERKStepSetTable(arkode_mem, B); - if (check_flag(flag, "ERKStepSetTables")) return 1; - } - /* Open output stream for results, output comment line */ UFID = fopen("ark_conserved_exp_entropy_erk.txt", "w"); fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); @@ -241,10 +206,8 @@ int main(int argc, char* argv[]) * Advance in Time * * --------------- */ - /* Initial time, time between outputs, output time */ - t = t0; - dtout = tf / nout; - tout = t0 + dtout; + /* Initial time */ + t = t0; /* Output the initial condition and entropy */ fprintf(UFID, @@ -262,10 +225,10 @@ int main(int argc, char* argv[]) "\n", t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); - for (iout = 0; iout < steps; iout++) + while (t < tf) { /* Evolve in time */ - flag = ERKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); + flag = ERKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ERKStepEvolve")) break; /* Output solution and errors */ @@ -287,10 +250,6 @@ int main(int argc, char* argv[]) "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); - - /* Update output time */ - tout += dtout; - tout = (tout > tf) ? tf : tout; } printf(" " @@ -322,22 +281,26 @@ int main(int argc, char* argv[]) if (relax) { + flag = ERKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ERKStepGetNumRelaxFails"); + flag = ERKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ERKStepGetNumRelaxFnEvals"); flag = ERKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ERKStepGetNumRelaxJacEvals"); - flag = ERKStepGetNumRelaxSolveIters(arkode_mem, &nri); + flag = ERKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); check_flag(flag, "ERKStepGetNumRelaxSolveIters"); - flag = ERKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + flag = ERKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ERKStepGetNumRelaxSolveFails"); + printf(" Total Relaxation fails = %li\n", nrf); printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation iters = %li\n", nri); - printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation iters = %li\n", nrnlsi); + printf(" Total Relaxation fails = %li\n", nrnlsf); } printf("\n"); From 6a715f97bd23f440b7ee2a5810af0da0689df55c Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 11 Jan 2023 12:13:22 -0800 Subject: [PATCH 031/111] check for negative b values in Butcher table --- .../C_serial/ark_conserved_exp_entropy_ark.c | 5 +++ src/arkode/arkode_arkstep.c | 33 +++++++++++++++++++ src/arkode/arkode_erkstep.c | 16 +++++++++ 3 files changed, 54 insertions(+) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index c42cbf1302..f416a3a2cc 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -239,6 +239,11 @@ int main(int argc, char* argv[]) /* Set Jacobian routine */ flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; + + /* Select a Butcher table with non-negative b values */ + flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + "ARKODE_ERK_NONE"); + if (check_flag(flag, "ARKStepSetTableName")) return 1; } /* Open output stream for results, output comment line */ diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index cf8beaf6a7..6a164bce28 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2146,6 +2146,39 @@ int arkStep_CheckButcherTables(ARKodeMem ark_mem) } } + /* check if all b values are positive for relaxation */ + if (ark_mem->relax_enabled) + { + okay = SUNTRUE; + if (step_mem->explicit) + { + for (i = 0; i < step_mem->stages; i++) + if (step_mem->Be->b[i] < ZERO) + okay = SUNFALSE; + if (!okay) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", + "arkStep_CheckButcherTables", + "The explicit Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } + } + + if (step_mem->implicit) + { + for (i = 0; i < step_mem->stages; i++) + if (step_mem->Bi->b[i] < ZERO) + okay = SUNFALSE; + if (!okay) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", + "arkStep_CheckButcherTables", + "The implicit Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } + } + } + return(ARK_SUCCESS); } diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index 6d2cf5f2e0..d7891527a4 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1048,6 +1048,22 @@ int erkStep_CheckButcherTable(ARKodeMem ark_mem) return(ARK_INVALID_TABLE); } + /* check if all b values are positive for relaxation */ + if (ark_mem->relax_enabled) + { + okay = SUNTRUE; + for (i = 0; i < step_mem->stages; i++) + if (step_mem->B->b[i] < ZERO) + okay = SUNFALSE; + if (!okay) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ERKStep", + "erkStep_CheckButcherTable", + "The Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } + } + return(ARK_SUCCESS); } From 6579f8c7cbea9aa4c70647738af4467fba5cc5d9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 11 Jan 2023 14:39:01 -0800 Subject: [PATCH 032/111] clean up examples --- examples/arkode/C_serial/CMakeLists.txt | 50 ++--- .../C_serial/ark_conserved_exp_entropy_ark.c | 43 +---- .../C_serial/ark_conserved_exp_entropy_erk.c | 39 +--- .../C_serial/ark_dissipated_exp_entropy.c | 180 +++++++----------- 4 files changed, 101 insertions(+), 211 deletions(-) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index dc53f4a469..563500d259 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -94,14 +94,6 @@ set(ARKODE_extras ark_robertson_stats.csv ) -# Specify libraries to link against -set(ARKODE_LIB sundials_arkode) -set(NVECS_LIB sundials_nvecserial) - -# Set-up linker flags and link libraries -set(SUNDIALS_LIBS ${ARKODE_LIB} ${NVECS_LIB} ${EXE_EXTRA_LINK_LIBS}) - - # Add the build and install targets for each ARKODE example foreach(example_tuple ${ARKODE_examples}) @@ -117,8 +109,16 @@ foreach(example_tuple ${ARKODE_examples}) # folder for IDEs set_target_properties(${example} PROPERTIES FOLDER "Examples") + # directories to include + target_include_directories(${example} + PRIVATE + ${PROJECT_SOURCE_DIR}/examples/utilities) + # libraries to link against - target_link_libraries(${example} ${SUNDIALS_LIBS}) + target_link_libraries(${example} + sundials_arkode + sundials_nvecserial + ${EXE_EXTRA_LINK_LIBS}) endif() # check if example args are provided and set the test name @@ -147,12 +147,6 @@ endforeach(example_tuple ${ARKODE_examples}) # Add the build and install targets for each KLU example (if needed) if(BUILD_SUNLINSOL_KLU) - # Sundials KLU linear solver module - set(SUNLINSOLKLU_LIBS sundials_sunlinsolklu) - - # KLU libraries - list(APPEND SUNLINSOLKLU_LIBS) - foreach(example_tuple ${ARKODE_examples_KLU}) # parse the example tuple @@ -170,8 +164,17 @@ if(BUILD_SUNLINSOL_KLU) ANSWER_FILE ${example}.out EXAMPLE_TYPE ${example_type}) + # directories to include + target_include_directories(${example} + PRIVATE + ${PROJECT_SOURCE_DIR}/examples/utilities) + # libraries to link against - target_link_libraries(${example} ${SUNDIALS_LIBS} ${SUNLINSOLKLU_LIBS}) + target_link_libraries(${example} + sundials_arkode + sundials_nvecserial + sundials_sunlinsolklu + ${EXE_EXTRA_LINK_LIBS}) # install example source and out files if(EXAMPLES_INSTALL) @@ -187,12 +190,6 @@ endif() # Add the build and install targets for each SuperLU_MT example (if needed) if(BUILD_SUNLINSOL_SUPERLUMT) - # Sundials SuperLU_MT linear solver module - set(SUNLINSOLSLUMT_LIBS sundials_sunlinsolsuperlumt) - - # SuperLU_MT libraries - list(APPEND SUNLINSOLSLUMT_LIBS ${SUPERLUMT_LIBRARIES}) - foreach(example_tuple ${ARKODE_examples_SUPERLUMT}) # parse the example tuple @@ -211,7 +208,11 @@ if(BUILD_SUNLINSOL_SUPERLUMT) EXAMPLE_TYPE ${example_type}) # libraries to link against - target_link_libraries(${example} ${SUNDIALS_LIBS} ${SUNLINSOLSLUMT_LIBS}) + target_link_libraries(${example} + sundials_arkode + sundials_nvecserial + sundials_sunlinsolsuperlumt + ${EXE_EXTRA_LINK_LIBS}) # install example source and out files if(EXAMPLES_INSTALL) @@ -235,6 +236,9 @@ if(EXAMPLES_INSTALL) install(FILES ${extrafile} DESTINATION ${EXAMPLES_INSTALL_PATH}/arkode/C_serial) endforeach(extrafile ${ARKODE_extras}) + install(FILES "${PROJECT_SOURCE_DIR}/examples/utilities/example_utilities.h" + DESTINATION ${EXAMPLES_INSTALL_PATH}/arkode/C_serial) + # Prepare substitution variables for Makefile and/or CMakeLists templates set(SOLVER "ARKODE") set(SOLVER_LIB "sundials_arkode") diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index f416a3a2cc..8b44b21487 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -48,22 +48,15 @@ #include #include +/* Common utilities */ +#include + +/* SUNDIALS headers */ #include #include #include #include -/* Precision-dependent output macros */ -#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 - /* Value of the natural number e */ #define EVAL 2.718281828459045235360287471352662497757247093699959574966 @@ -91,10 +84,6 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); -/* Check return flags and pointers */ -int check_flag(int flag, const char* funcname); -int check_ptr(void* ptr, const char* funcname); - /* ------------ * * Main Program * * ------------ */ @@ -465,27 +454,3 @@ int ans(sunrealtype t, N_Vector y) return 0; } - -/* Check return flags */ -int check_flag(int flag, const char* funcname) -{ - if (flag < 0) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, flag); - return 1; - } - return 0; -} - -/* Check return pointers */ -int check_ptr(void* ptr, const char* funcname) -{ - if (!ptr) - { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - return 0; -} diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index b0d33a4ffa..b512e4bf87 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -48,20 +48,13 @@ #include #include +/* Common utilities */ +#include + +/* SUNDIALS headers */ #include #include -/* Precision-dependent output macros */ -#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 - /* Value of the natural number e */ #define EVAL 2.718281828459045235360287471352662497757247093699959574966 @@ -373,27 +366,3 @@ int ans(sunrealtype t, N_Vector y) return 0; } - -/* Check return flags */ -int check_flag(int flag, const char* funcname) -{ - if (flag < 0) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, flag); - return 1; - } - return 0; -} - -/* Check return pointers */ -int check_ptr(void* ptr, const char* funcname) -{ - if (!ptr) - { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - return 0; -} diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index aba356560f..814280488a 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -31,22 +31,15 @@ #include #include +/* Common utilities */ +#include + +/* SUNDIALS headers */ #include #include #include #include -/* Precision-dependent output macros */ -#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 - /* ----------------------- * * User-supplied functions * * ----------------------- */ @@ -71,10 +64,6 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); -/* Check return flags and pointers */ -int check_flag(int flag, const char* funcname); -int check_ptr(void* ptr, const char* funcname); - /* ------------ * * Main Program * * ------------ */ @@ -93,12 +82,11 @@ int main(int argc, char* argv[]) sunrealtype abstol = SUN_RCONST(1.0e-10); /* SUNDIALS context, vector, matrix, and linear solver objects */ - SUNContext ctx = NULL; - N_Vector y = NULL; - N_Vector ytrue = NULL; - SUNMatrix A = NULL; - SUNLinearSolver LS = NULL; - ARKodeButcherTable B = NULL; + SUNContext ctx = NULL; + N_Vector y = NULL; + N_Vector ytrue = NULL; + SUNMatrix A = NULL; + SUNLinearSolver LS = NULL; /* Pointer to vector data array */ sunrealtype* ydata; @@ -114,42 +102,44 @@ int main(int argc, char* argv[]) void* arkode_mem = NULL; /* ARKODE statistics */ - long int nst, nst_a, nfe, nfi, nri, nrf; + long int nst, nst_a, nfe, nfi; + long int nrf, nre, nrje, nrnlsi, nrnlsf; long int nsetups, nje, nfeLS, nni, ncfn, netf; - /* Number of outputs, output counter, output times, and output file */ - int nout = 10; - int iout; - sunrealtype t, tout, dtout; + /* Output time and file */ + sunrealtype t; FILE* UFID; /* Command line options */ - int implicit = 0; /* explicit */ - int relax = 0; /* enable relaxation */ - int steps = 100; /* number of steps */ - sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive steps */ + int relax = 1; /* enable relaxation */ + int implicit = 1; /* implicit */ /* -------------------- * * Output Problem Setup * * -------------------- */ - if (argc > 1) implicit = atoi(argv[1]); - if (argc > 2) relax = atoi(argv[2]); - if (argc > 3) fixed_h = (sunrealtype)atof(argv[3]); - if (argc > 4) steps = atoi(argv[4]); + if (argc > 1) relax = atoi(argv[1]); + if (argc > 2) implicit = atoi(argv[2]); printf("\nDissipated Exponential Entropy problem:\n"); - if (implicit) printf(" method = DIRK\n"); - else printf(" method = ERK\n"); - if (relax) printf(" relaxation = ON\n"); - else printf(" relaxation = OFF\n"); - if (fixed_h > SUN_RCONST(0.0)) printf(" fixed h = %" GSYM "\n", fixed_h); - if (implicit || !(fixed_h > SUN_RCONST(0.0))) + if (implicit) + { + printf(" method = DIRK\n"); + } + else + { + printf(" method = ERK\n"); + } + printf(" reltol = %.1" ESYM "\n", reltol); + printf(" abstol = %.1" ESYM "\n", abstol); + if (relax) + { + printf(" relaxation = ON\n"); + } + else { - printf(" reltol = %.1" ESYM "\n", reltol); - printf(" abstol = %.1" ESYM "\n", abstol); + printf(" relaxation = OFF\n"); } - printf(" steps = %d\n", steps); printf("\n"); /* ------------ * @@ -177,8 +167,14 @@ int main(int argc, char* argv[]) if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; /* Initialize the ARKStep */ - if (implicit) arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); - else arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + if (implicit) + { + arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); + } + else + { + arkode_mem = ARKStepCreate(f, NULL, t0, y, ctx); + } if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; /* Specify tolerances */ @@ -192,13 +188,6 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; } - if (fixed_h > 0.0) - { - /* Set the step size */ - flag = ARKStepSetFixedStep(arkode_mem, fixed_h); - if (check_flag(flag, "ARKStepSetFixedStep")) return 1; - } - if (implicit) { /* Create dense matrix and linear solver */ @@ -215,44 +204,23 @@ int main(int argc, char* argv[]) /* Set Jacobian routine */ flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; - } - else if (fixed_h > 0.0) - { - /* Use RK4 */ - B = ARKodeButcherTable_Alloc(4, SUNFALSE); - B->A[1][0] = SUN_RCONST(0.5); - B->A[2][1] = SUN_RCONST(0.5); - B->A[3][2] = SUN_RCONST(1.0); - - B->c[1] = SUN_RCONST(0.5); - B->c[2] = SUN_RCONST(0.5); - B->c[3] = SUN_RCONST(1.0); - - B->b[0] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - B->b[1] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[2] = SUN_RCONST(1.0) / SUN_RCONST(3.0); - B->b[3] = SUN_RCONST(1.0) / SUN_RCONST(6.0); - - B->q = 4; - B->p = 0; - - flag = ARKStepSetTables(arkode_mem, 4, 0, NULL, B); - if (check_flag(flag, "ARKStepSetTables")) return 1; + /* Select a Butcher table with non-negative b values */ + flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + "ARKODE_ERK_NONE"); + if (check_flag(flag, "ARKStepSetTableName")) return 1; } /* Open output stream for results, output comment line */ UFID = fopen("ark_dissipated_exp_entropy.txt", "w"); - fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); + fprintf(UFID, "# vars: t u entropy u_err delta_entropy\n"); /* --------------- * * Advance in Time * * --------------- */ - /* Initial time, time between outputs, output time */ - t = t0; - dtout = tf / nout; - tout = t0 + dtout; + /* Initial time */ + t = t0; /* Output the initial condition and entropy */ flag = Ent(&y, &ent0, NULL); @@ -269,10 +237,10 @@ int main(int argc, char* argv[]) printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", t, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); - for (iout = 0; iout < steps; iout++) + while (t < tf) { /* Evolve in time */ - flag = ARKStepEvolve(arkode_mem, tout, y, &t, ARK_ONE_STEP); + flag = ARKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; /* Output solution and errors */ @@ -291,10 +259,6 @@ int main(int argc, char* argv[]) fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ent, u_err, delta_ent); - - /* Update output time */ - tout += dtout; - tout = (tout > tf) ? tf : tout; } printf(" " @@ -350,14 +314,26 @@ int main(int argc, char* argv[]) if (relax) { - flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nri); + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + + flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); + check_flag(flag, "ARKStepGetNumRelaxFnEvals"); + + flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); + check_flag(flag, "ARKStepGetNumRelaxJacEvals"); + + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); check_flag(flag, "ARKStepGetNumRelaxSolveIters"); - flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrf); + flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ARKStepGetNumRelaxSolveFails"); - printf(" Total Relaxation iters = %li\n", nri); - printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); } printf("\n"); @@ -427,27 +403,3 @@ int ans(sunrealtype t, N_Vector y) ydata[0] = log(exp(SUN_RCONST(-0.5)) + t); return 0; } - -/* Check return flags */ -int check_flag(int flag, const char* funcname) -{ - if (flag < 0) - { - fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", - funcname, flag); - return 1; - } - return 0; -} - -/* Check return pointers */ -int check_ptr(void* ptr, const char* funcname) -{ - if (!ptr) - { - fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", - funcname); - return 1; - } - return 0; -} From 13b94d42fd767e5ce9c319edd37e474ab1a4d614 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 09:14:05 -0600 Subject: [PATCH 033/111] fix bug in loop index --- src/arkode/arkode_relaxation.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index e9ce31e9f7..8164196213 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -104,16 +104,16 @@ static int arkRelaxJacobian(sunrealtype* relax_vals, N_Vector* y_relax, /* Solve the relaxation residual equation using Newton's method */ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) { - int i, retval; + int i, j, retval; sunrealtype max_res; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* y_relax = y_n + r * delta_y */ - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[i], - ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[i]); + for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[j], + ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[j]); /* Compute the current residual */ retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, @@ -122,8 +122,8 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) /* Check for convergence of all values */ max_res = SUNRabs(relax_mem->res_vals[0]); - for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) - max_res = SUNMAX(max_res, relax_mem->res_vals[i]); + for (j = 1; j < ark_mem->relax_mem->num_relax_fn; ++j) + max_res = SUNMAX(max_res, relax_mem->res_vals[j]); if (max_res < relax_mem->tol) return ARK_SUCCESS; @@ -135,8 +135,8 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) relax_mem->jac_vals, ark_mem); if (retval) return retval; - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - relax_mem->relax_vals[i] -= relax_mem->res_vals[i] / relax_mem->jac_vals[i]; + for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) + relax_mem->relax_vals[j] -= relax_mem->res_vals[j] / relax_mem->jac_vals[j]; } return ARK_RELAX_SOLVE_RECV; @@ -145,16 +145,16 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) /* Solve the relaxation residual equation using Newton's method */ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) { - int i, retval; + int i, j, retval; sunrealtype max_res; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* y_relax = y_n + r * delta_y */ - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[i], - ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[i]); + for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[j], + ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[j]); /* Compute the current residual */ retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, @@ -163,16 +163,16 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) /* Check for convergence of all values */ max_res = SUNRabs(relax_mem->res_vals[0]); - for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) - max_res = SUNMAX(max_res, relax_mem->res_vals[i]); + for (j = 1; j < ark_mem->relax_mem->num_relax_fn; ++j) + max_res = SUNMAX(max_res, relax_mem->res_vals[j]); if (max_res < relax_mem->tol) return ARK_SUCCESS; /* Update iteration count */ relax_mem->nls_iters++; - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - relax_mem->relax_vals[i] -= relax_mem->res_vals[i]; + for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) + relax_mem->relax_vals[j] -= relax_mem->res_vals[j]; } return ARK_RELAX_SOLVE_RECV; From f62f656e6336c0a93805302e6c66136ce4c98eea Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 09:32:19 -0600 Subject: [PATCH 034/111] use precision specific functions --- .../C_serial/ark_conserved_exp_entropy_ark.c | 26 +++++++++---------- .../C_serial/ark_conserved_exp_entropy_erk.c | 26 ++++++++----------- .../C_serial/ark_dissipated_exp_entropy.c | 10 +++---- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 8b44b21487..68f0b3bb83 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -390,8 +390,8 @@ int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) sunrealtype* ydata = N_VGetArrayPointer(y); sunrealtype* fdata = N_VGetArrayPointer(ydot); - fdata[0] = -exp(ydata[1]); - fdata[1] = exp(ydata[0]); + fdata[0] = -EXP(ydata[1]); + fdata[1] = EXP(ydata[0]); return 0; } @@ -404,12 +404,12 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, sunrealtype* Jdata = SUNDenseMatrix_Data(J); /* column 0 */ - Jdata[0] = 0; - Jdata[1] = exp(ydata[0]); + Jdata[0] = SUN_RCONST(0.0); + Jdata[1] = EXP(ydata[0]); /* column 1 */ - Jdata[2] = -exp(ydata[1]); - Jdata[3] = 0; + Jdata[2] = -EXP(ydata[1]); + Jdata[3] = SUN_RCONST(0.0); return 0; } @@ -419,7 +419,7 @@ int Ent(N_Vector* y, sunrealtype* e, void* user_data) { sunrealtype* ydata = N_VGetArrayPointer(y[0]); - e[0] = exp(ydata[0]) + exp(ydata[1]); + e[0] = EXP(ydata[0]) + EXP(ydata[1]); return 0; } @@ -430,8 +430,8 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data) sunrealtype* ydata = N_VGetArrayPointer(y[0]); sunrealtype* jdata = N_VGetArrayPointer(J[0]); - jdata[0] = exp(ydata[0]); - jdata[1] = exp(ydata[1]); + jdata[0] = EXP(ydata[0]); + jdata[1] = EXP(ydata[1]); return 0; } @@ -446,11 +446,11 @@ int ans(sunrealtype t, N_Vector y) sunrealtype a, b; sunrealtype* ydata = N_VGetArrayPointer(y); - a = sqrt(EVAL) + EVAL; - b = sqrt(EVAL) + exp(a * t); + a = SQRT(EVAL) + EVAL; + b = SQRT(EVAL) + EXP(a * t); - ydata[0] = log(EVAL + exp(SUN_RCONST(1.5))) - log(b); - ydata[1] = log(a * exp(a * t)) - log(b); + ydata[0] = LOG(EVAL + EXP(SUN_RCONST(1.5))) - LOG(b); + ydata[1] = LOG(a * EXP(a * t)) - LOG(b); return 0; } diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index b512e4bf87..fc87d496e8 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -78,10 +78,6 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); -/* Check return flags and pointers */ -int check_flag(int flag, const char* funcname); -int check_ptr(void* ptr, const char* funcname); - /* ------------ * * Main Program * * ------------ */ @@ -292,8 +288,8 @@ int main(int argc, char* argv[]) printf(" Total Relaxation fails = %li\n", nrf); printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation iters = %li\n", nrnlsi); - printf(" Total Relaxation fails = %li\n", nrnlsf); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); } printf("\n"); @@ -320,8 +316,8 @@ int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) sunrealtype* ydata = N_VGetArrayPointer(y); sunrealtype* fdata = N_VGetArrayPointer(ydot); - fdata[0] = -exp(ydata[1]); - fdata[1] = exp(ydata[0]); + fdata[0] = -EXP(ydata[1]); + fdata[1] = EXP(ydata[0]); return 0; } @@ -331,7 +327,7 @@ int Ent(N_Vector* y, sunrealtype* e, void* user_data) { sunrealtype* ydata = N_VGetArrayPointer(y[0]); - e[0] = exp(ydata[0]) + exp(ydata[1]); + e[0] = EXP(ydata[0]) + EXP(ydata[1]); return 0; } @@ -342,8 +338,8 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data) sunrealtype* ydata = N_VGetArrayPointer(y[0]); sunrealtype* jdata = N_VGetArrayPointer(J[0]); - jdata[0] = exp(ydata[0]); - jdata[1] = exp(ydata[1]); + jdata[0] = EXP(ydata[0]); + jdata[1] = EXP(ydata[1]); return 0; } @@ -358,11 +354,11 @@ int ans(sunrealtype t, N_Vector y) sunrealtype a, b; sunrealtype* ydata = N_VGetArrayPointer(y); - a = sqrt(EVAL) + EVAL; - b = sqrt(EVAL) + exp(a * t); + a = SQRT(EVAL) + EVAL; + b = SQRT(EVAL) + EXP(a * t); - ydata[0] = log(EVAL + exp(SUN_RCONST(1.5))) - log(b); - ydata[1] = log(a * exp(a * t)) - log(b); + ydata[0] = LOG(EVAL + EXP(SUN_RCONST(1.5))) - LOG(b); + ydata[1] = LOG(a * EXP(a * t)) - LOG(b); return 0; } diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index 814280488a..eb55e4d309 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -361,7 +361,7 @@ int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { sunrealtype* ydata = N_VGetArrayPointer(y); sunrealtype* fdata = N_VGetArrayPointer(ydot); - fdata[0] = -exp(ydata[0]); + fdata[0] = -EXP(ydata[0]); return 0; } @@ -371,7 +371,7 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, { sunrealtype* ydata = N_VGetArrayPointer(y); sunrealtype* Jdata = SUNDenseMatrix_Data(J); - Jdata[0] = -exp(ydata[0]); + Jdata[0] = -EXP(ydata[0]); return 0; } @@ -379,7 +379,7 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, int Ent(N_Vector* y, sunrealtype* e, void* user_data) { sunrealtype* ydata = N_VGetArrayPointer(y[0]); - e[0] = exp(ydata[0]); + e[0] = EXP(ydata[0]); return 0; } @@ -388,7 +388,7 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data) { sunrealtype* ydata = N_VGetArrayPointer(y[0]); sunrealtype* jdata = N_VGetArrayPointer(J[0]); - jdata[0] = exp(ydata[0]); + jdata[0] = EXP(ydata[0]); return 0; } @@ -400,6 +400,6 @@ int JacEnt(N_Vector* y, N_Vector* J, void* user_data) int ans(sunrealtype t, N_Vector y) { sunrealtype* ydata = N_VGetArrayPointer(y); - ydata[0] = log(exp(SUN_RCONST(-0.5)) + t); + ydata[0] = LOG(EXP(SUN_RCONST(-0.5)) + t); return 0; } From 7849e91169568eeab06bbac9306f8201883f5325 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 09:33:25 -0600 Subject: [PATCH 035/111] fix include order dependency --- examples/arkode/CXX_serial/CMakeLists.txt | 6 ++++++ examples/utilities/example_utilities.hpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/examples/arkode/CXX_serial/CMakeLists.txt b/examples/arkode/CXX_serial/CMakeLists.txt index 44ac75d4cf..e5c49d9ad8 100644 --- a/examples/arkode/CXX_serial/CMakeLists.txt +++ b/examples/arkode/CXX_serial/CMakeLists.txt @@ -70,6 +70,11 @@ foreach(example_tuple ${ARKODE_examples}) target_compile_features(${example_target} PRIVATE cxx_std_14) + # directories to include + target_include_directories(${example_target} + PRIVATE + ${PROJECT_SOURCE_DIR}/examples/utilities) + # libraries to link against target_link_libraries(${example_target} sundials_arkode @@ -122,6 +127,7 @@ if(EXAMPLES_INSTALL) README ${ARKODE_extras} ${ARKODE_headers} + "${PROJECT_SOURCE_DIR}/examples/utilities/example_utilities.hpp" TEST_INSTALL CXX_serial ) diff --git a/examples/utilities/example_utilities.hpp b/examples/utilities/example_utilities.hpp index 7d28fc0cfb..91accd71b4 100644 --- a/examples/utilities/example_utilities.hpp +++ b/examples/utilities/example_utilities.hpp @@ -18,6 +18,8 @@ #include #include +#include + // Check function return flag int check_flag(const int flag, const std::string funcname) { From 6f5b6ae59e9c0e5bdbb64301e7391175ce9c6a72 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 09:33:53 -0600 Subject: [PATCH 036/111] add example utilites header for C examples --- examples/utilities/example_utilities.h | 76 ++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 examples/utilities/example_utilities.h diff --git a/examples/utilities/example_utilities.h b/examples/utilities/example_utilities.h new file mode 100644 index 0000000000..9ea9626b27 --- /dev/null +++ b/examples/utilities/example_utilities.h @@ -0,0 +1,76 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 + * ----------------------------------------------------------------------------- + * Utility functions for C++ examples + * ---------------------------------------------------------------------------*/ + +#include + +#include + +/* Check return flags */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "ERROR: %s() returned %d\n", funcname, flag); + return 1; + } + return 0; +} + +/* Check return pointers */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "ERROR: %s() returned NULL\n", funcname); + return 1; + } + return 0; +} + +/* Precision specific math function macros */ +#if defined(SUNDIALS_DOUBLE_PRECISION) +#define EXP(x) (exp((x))) +#define SIN(x) (sin((x))) +#define COS(x) (cos((x))) +#define SQRT(x) (sqrt((x))) +#define ABS(x) (fabs((x))) +#define LOG(x) (log((x))) +#elif defined(SUNDIALS_SINGLE_PRECISION) +#define EXP(x) (expf((x))) +#define SIN(x) (sinf((x))) +#define COS(x) (cosf((x))) +#define SQRT(x) (sqrtf((x))) +#define ABS(x) (fabsf((x))) +#define LOG(x) (logf((x))) +#elif defined(SUNDIALS_EXTENDED_PRECISION) +#define EXP(x) (expl((x))) +#define SIN(x) (sinl((x))) +#define COS(x) (cosl((x))) +#define SQRT(x) (sqrtl((x))) +#define ABS(x) (fabsl((x))) +#define LOG(x) (logl((x))) +#endif + +/* Precision specific output macros */ +#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 From 0f63ab27458f3dcc90d2d4144ab5792f1838daac Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 09:51:18 -0600 Subject: [PATCH 037/111] add fixed step option --- .../C_serial/ark_conserved_exp_entropy_ark.c | 16 ++++++++++++++-- .../C_serial/ark_conserved_exp_entropy_erk.c | 14 +++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 68f0b3bb83..048ec796e4 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -131,8 +131,9 @@ int main(int argc, char* argv[]) FILE* UFID; /* Command line options */ - int relax = 1; /* enable relaxation */ - int implicit = 1; /* implicit */ + int relax = 1; /* enable relaxation */ + int implicit = 1; /* implicit */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive stepping */ /* -------------------- * * Output Problem Setup * @@ -140,6 +141,7 @@ int main(int argc, char* argv[]) if (argc > 1) relax = atoi(argv[1]); if (argc > 2) implicit = atoi(argv[2]); + if (argc > 3) fixed_h = atof(argv[3]); printf("\nConserved Exponential Entropy problem:\n"); if (implicit) @@ -152,6 +154,10 @@ int main(int argc, char* argv[]) } printf(" reltol = %.1" ESYM "\n", reltol); printf(" abstol = %.1" ESYM "\n", abstol); + if (fixed_h > SUN_RCONST(0.0)) + { + printf(" fixed h = %.1" ESYM "\n", fixed_h); + } if (relax) { printf(" relaxation = ON\n"); @@ -235,6 +241,12 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetTableName")) return 1; } + if (fixed_h > SUN_RCONST(0.0)) + { + flag = ARKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ARKStepSetFixedStep")) return 1; + } + /* Open output stream for results, output comment line */ UFID = fopen("ark_conserved_exp_entropy_ark.txt", "w"); fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index fc87d496e8..ba698df652 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -122,18 +122,24 @@ int main(int argc, char* argv[]) FILE* UFID; /* Command line options */ - int relax = 1; /* enable relaxation */ + int relax = 1; /* enable relaxation */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive stepping */ /* -------------------- * * Output Problem Setup * * -------------------- */ if (argc > 1) relax = atoi(argv[1]); + if (argc > 2) fixed_h = atof(argv[2]); printf("\nConserved Exponential Entropy problem:\n"); printf(" method = ERK\n"); printf(" reltol = %.1" ESYM "\n", reltol); printf(" abstol = %.1" ESYM "\n", abstol); + if (fixed_h > SUN_RCONST(0.0)) + { + printf(" fixed h = %.1" ESYM "\n", fixed_h); + } if (relax) { printf(" relaxation = ON\n"); @@ -187,6 +193,12 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ERKStepSetRelaxFn")) return 1; } + if (fixed_h > SUN_RCONST(0.0)) + { + flag = ERKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ERKStepSetFixedStep")) return 1; + } + /* Open output stream for results, output comment line */ UFID = fopen("ark_conserved_exp_entropy_erk.txt", "w"); fprintf(UFID, "# vars: t u v entropy u_err v_err entropy_error\n"); From 9188f2ef499683609e81c4ea8f9a5eb522f47717 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 18 Jan 2023 10:47:20 -0600 Subject: [PATCH 038/111] pendulum example --- examples/arkode/CXX_serial/CMakeLists.txt | 1 + examples/arkode/CXX_serial/ark_pendulum.cpp | 405 ++++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 examples/arkode/CXX_serial/ark_pendulum.cpp diff --git a/examples/arkode/CXX_serial/CMakeLists.txt b/examples/arkode/CXX_serial/CMakeLists.txt index e5c49d9ad8..2b45972d9d 100644 --- a/examples/arkode/CXX_serial/CMakeLists.txt +++ b/examples/arkode/CXX_serial/CMakeLists.txt @@ -34,6 +34,7 @@ set(ARKODE_examples "ark_kpr_Mt.cpp\;2 4 0 -10 0\;develop" "ark_kpr_Mt.cpp\;0 4 0 -10 1 10 1\;develop" "ark_kpr_Mt.cpp\;0 4 0 -10 0 10 1\;develop" + "ark_pendulum.cpp\;\;develop" ) # Header files to install diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp new file mode 100644 index 0000000000..e57ea79578 --- /dev/null +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -0,0 +1,405 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2022, 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 example problem is adapted from: + * + * H. Ranocha, M. Sayyari, L. Dalcin, M. Parsani, and D.I. Ketcheson, + * "Relaxation Runge-Kutta Methods: Fully-Discrete Explicit Entropy-Stable + * Schemes for the Compressible Euler and Navier-Stokes Equations," SIAM Journal + * on Scientific Computing, 42(2), 2020, https://doi.org/10.1137/19M1263480. + * ----------------------------------------------------------------------------- + * This example evolves system y = [u, v]^T + * + * du/dt = -sin(v) + * dv/dt = u + * + * for t in the interval [0, 1000] with the initial condition y0 = [1.5 1.0]^T. + * The conserved energy and its Jacobian for the system are + * + * e(y) = 0.5 u^2 - cos(v) and e'(y) = [u, sin(v)]^T + * + * The problem is advanced in time with an explicit or implicit relaxed + * Runge-Kutta method to ensure conservation of the energy. + * ---------------------------------------------------------------------------*/ + +// Standard headers +#include +#include +#include +#include +#include +#include + +// Common utility functions +#include + +// SUNDIALS headers +#include +#include +#include +#include + +#include "arkode/arkode_butcher.h" +#include "sundials/sundials_types.h" + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +// ODE RHS function +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); + +// ODE RHS Jacobian function +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); + +// Energy function +int Eng(N_Vector* y, sunrealtype* e, void* user_data); + +// Energy Jacobian function +int JacEng(N_Vector* y, N_Vector* J, void* user_data); + +/* ------------ * + * Main Program * + * ------------ */ + +int main(int argc, char* argv[]) +{ + // Create the SUNDIALS context object for this simulation + sundials::Context ctx; + + // Initial and final times + sunrealtype t0 = SUN_RCONST(0.0); + sunrealtype tf = SUN_RCONST(1000.0); + + // Relative and absolute tolerances + sunrealtype reltol = SUN_RCONST(1.0e-6); + sunrealtype abstol = SUN_RCONST(1.0e-10); + + // Command line options + int relax = 1; // enable relaxation + int implicit = 1; // implicit + sunrealtype fixed_h = SUN_RCONST(0.0); // adaptive + + /* -------------------- * + * Output Problem Setup * + * -------------------- */ + + if (argc > 1) relax = atoi(argv[1]); + if (argc > 2) implicit = atoi(argv[2]); + if (argc > 3) fixed_h = atof(argv[3]); + + std::cout << "Nonlinear Pendulum problem:\n"; + if (implicit) { std::cout << " method = DIRK\n"; } + else { std::cout << " method = ERK\n"; } + if (relax) { std::cout << " relaxation = ON\n"; } + else { std::cout << " relaxation = OFF\n"; } + std::cout << " reltol = " << reltol << "\n"; + std::cout << " abstol = " << abstol << "\n"; + if (fixed_h > SUN_RCONST(0.0)) + { + std::cout << " fixed h = " << fixed_h << "\n"; + } + std::cout << std::endl; + + /* ------------ * + * Setup ARKODE * + * ------------ */ + + // Create serial vector and set the initial condition values + N_Vector y = N_VNew_Serial(2, ctx); + if (check_ptr(y, "N_VNew_Serial")) return 1; + + sunrealtype* ydata = N_VGetArrayPointer(y); + if (check_ptr(ydata, "N_VGetArrayPointer")) return 1; + + ydata[0] = SUN_RCONST(1.5); + ydata[1] = SUN_RCONST(1.0); + + // Initial energy + sunrealtype eng0; + int flag = Eng(&y, &eng0, nullptr); + if (check_flag(flag, "Eng")) return 1; + + // Initialize the ARKStep + void* arkode_mem = nullptr; + if (implicit) { arkode_mem = ARKStepCreate(nullptr, f, t0, y, ctx); } + else { arkode_mem = ARKStepCreate(f, nullptr, t0, y, ctx); } + if (check_ptr(arkode_mem, "ARKStepCreate")) return 1; + + // Specify tolerances + flag = ARKStepSStolerances(arkode_mem, reltol, abstol); + if (check_flag(flag, "ARKStepSStolerances")) return 1; + + if (relax) + { + // Enable relaxation methods + flag = ARKStepSetRelaxFn(arkode_mem, 1, Eng, JacEng); + if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; + + flag = ARKStepSetRelaxMaxIters(arkode_mem, 100); + if (check_flag(flag, "ARKStepSetRelaxMaxIters")) return 1; + } + + SUNMatrix A = nullptr; + SUNLinearSolver LS = nullptr; + + if (implicit) + { + // Create dense matrix and linear solver + A = SUNDenseMatrix(2, 2, ctx); + if (check_ptr(A, "SUNDenseMatrix")) return 1; + + LS = SUNLinSol_Dense(y, A, ctx); + if (check_ptr(LS, "SUNLinSol_Dense")) return 1; + + // Attach the matrix and linear solver + flag = ARKStepSetLinearSolver(arkode_mem, LS, A); + if (check_flag(flag, "ARKStepSetLinearSolver")) return 1; + + // Set Jacobian routine + flag = ARKStepSetJacFn(arkode_mem, Jac); + if (check_flag(flag, "ARKStepSetJacFn")) return 1; + + // Select a Butcher table with non-negative b values + // flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + // "ARKODE_ERK_NONE"); + // if (check_flag(flag, "ARKStepSetTableName")) return 1; + } + + if (fixed_h > SUN_RCONST(0.0)) + { + // 3rd-order SDIRK method of Norsett + ARKodeButcherTable B = ARKodeButcherTable_Alloc(2, SUNFALSE); + + B->A[0][0] = std::sqrt(3.0)/6.0 + 0.5; + B->A[1][0] = -std::sqrt(3.0)/3.0; + B->A[1][1] = std::sqrt(3.0)/6.0 + 0.5; + + B->c[0] = 0.5; + B->c[1] = 0.5; + + B->b[0] = std::sqrt(3.0)/6.0 + 0.5; + B->b[1] = 0.5 - std::sqrt(3.0)/6.0; + + B->q = 3; + B->p = 0; + + flag = ARKStepSetTables(arkode_mem, 3, 0, B, nullptr); + if (check_flag(flag, "ARKStepSetTables")) return 1; + + flag = ARKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ARKStepSetFixedStep")) return 1; + } + + /* --------------- * + * Advance in Time * + * --------------- */ + + // Initial time + sunrealtype t = t0; + + // Output the initial condition and energy + std::ofstream outfile("ark_pendulum.txt"); + outfile << "# vars: t u v energy energy_err\n"; + outfile << std::scientific; + outfile << std::setprecision(std::numeric_limits::digits10); + outfile << t << " " << ydata[0] << " " << ydata[1] << " " << eng0 << " " + << SUN_RCONST(0.0) << std::endl; + + std::cout << std::setw(24) << "t" << std::setw(24) << "u" << std::setw(24) + << "v" << std::setw(24) << "e" << std::setw(24) << "e err" + << std::endl; + for (int i = 0; i < 9; i++) std::cout << "--------------"; + + std::cout << std::endl; + std::cout << std::scientific; + std::cout << std::setprecision(std::numeric_limits::digits10); + std::cout << std::setw(24) << t << std::setw(24) << ydata[0] << std::setw(24) + << ydata[1] << std::setw(24) << eng0 << std::setw(24) + << SUN_RCONST(0.0); + std::cout << std::endl; + + while (t < tf) + { + // Evolve in time + flag = ARKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); + if (check_flag(flag, "ARKStepEvolve")) break; + + // Output solution and errors + sunrealtype eng; + flag = Eng(&y, &eng, nullptr); + if (check_flag(flag, "Eng")) return 1; + + sunrealtype eng_chng = eng - eng0; + + outfile << t << " " << ydata[0] << " " << ydata[1] << " " << eng << " " + << eng_chng << std::endl; + + std::cout << std::setw(24) << t << std::setw(24) << ydata[0] + << std::setw(24) << ydata[1] << std::setw(24) << eng + << std::setw(24) << eng_chng << std::endl; + } + + for (int i = 0; i < 9; i++) std::cout << "--------------"; + std::cout << std::endl; + outfile.close(); + + /* ------------ * + * Output Stats * + * ------------ */ + + // ARKODE statistics + long int nst, nst_a, nfe, nfi; + long int nrf, nre, nrje, nrnlsi, nrnlsf; + long int nsetups, nje, nfeLS, nni, ncfn, netf; + + // Get final statistics on how the solve progressed + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + + flag = ARKStepGetNumStepAttempts(arkode_mem, &nst_a); + check_flag(flag, "ARKStepGetNumStepAttempts"); + + flag = ARKStepGetNumErrTestFails(arkode_mem, &netf); + check_flag(flag, "ARKStepGetNumErrTestFails"); + + flag = ARKStepGetNumRhsEvals(arkode_mem, &nfe, &nfi); + check_flag(flag, "ARKStepGetNumRhsEvals"); + + std::cout << std::endl; + std::cout << "Final Solver Statistics:\n"; + std::cout << " Internal solver steps = " << nst << " (attempted = " << nst_a + << ")\n"; + std::cout << " Total number of error test failures = " << netf << "\n"; + std::cout << " Total RHS evals: Fe = " << nfe << ", Fi = " << nfi << "\n"; + + if (implicit) + { + flag = ARKStepGetNumNonlinSolvIters(arkode_mem, &nni); + check_flag(flag, "ARKStepGetNumNonlinSolvIters"); + + flag = ARKStepGetNumNonlinSolvConvFails(arkode_mem, &ncfn); + check_flag(flag, "ARKStepGetNumNonlinSolvConvFails"); + + flag = ARKStepGetNumLinSolvSetups(arkode_mem, &nsetups); + check_flag(flag, "ARKStepGetNumLinSolvSetups"); + + flag = ARKStepGetNumJacEvals(arkode_mem, &nje); + check_flag(flag, "ARKStepGetNumJacEvals"); + + flag = ARKStepGetNumLinRhsEvals(arkode_mem, &nfeLS); + check_flag(flag, "ARKStepGetNumLinRhsEvals"); + + std::cout << " Total number of Newton iterations = " << nni << "\n"; + std::cout << " Total number of linear solver convergence failures = " << ncfn + << "\n"; + std::cout << " Total linear solver setups = " << nsetups << "\n"; + std::cout << " Total number of Jacobian evaluations = " << nje << "\n"; + std::cout << " Total RHS evals for setting up the linear system = " << nfeLS + << "\n"; + } + + if (relax) + { + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + + flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); + check_flag(flag, "ARKStepGetNumRelaxFnEvals"); + + flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); + check_flag(flag, "ARKStepGetNumRelaxJacEvals"); + + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); + check_flag(flag, "ARKStepGetNumRelaxSolveFails"); + + std::cout << " Total Relaxation fails = " << nrf << "\n"; + std::cout << " Total Relaxation Fn evals = " << nre << "\n"; + std::cout << " Total Relaxation Jac evals = " << nrje << "\n"; + std::cout << " Total Relaxation NLS iters = " << nrnlsi << "\n"; + std::cout << " Total Relaxation NLS fails = " << nrnlsf << "\n"; + } + std::cout << "\n"; + + /* -------- * + * Clean up * + * -------- */ + + // Free ARKStep integrator and SUNDIALS objects + ARKStepFree(&arkode_mem); + SUNLinSolFree(LS); + SUNMatDestroy(A); + N_VDestroy(y); + + return flag; +} + +/* ----------------------- * + * User-supplied functions * + * ----------------------- */ + +// ODE RHS function f(t,y). +int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* fdata = N_VGetArrayPointer(ydot); + + fdata[0] = -std::sin(ydata[1]); + fdata[1] = ydata[0]; + + return 0; +} + +// ODE RHS Jacobian function J(t,y) = df/dy. +int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, + N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) +{ + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* Jdata = SUNDenseMatrix_Data(J); + + // column 0 + Jdata[0] = SUN_RCONST(0.0); + Jdata[1] = SUN_RCONST(1.0); + + // column 1 + Jdata[2] = -std::cos(ydata[1]); + Jdata[3] = SUN_RCONST(0.0); + + return 0; +} + +// Energy function e(y) +int Eng(N_Vector* y, sunrealtype* e, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + + e[0] = SUN_RCONST(0.5) * ydata[0] * ydata[0] - std::cos(ydata[1]); + + return 0; +} + +// Energy function Jacobian Je(y) = de/dy +int JacEng(N_Vector* y, N_Vector* J, void* user_data) +{ + sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* jdata = N_VGetArrayPointer(J[0]); + + jdata[0] = ydata[0]; + jdata[1] = std::sin(ydata[1]); + + return 0; +} From 5c838f7adc45797ee1aa58d6edc7342b6335dd38 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 1 Jun 2023 13:49:58 -0700 Subject: [PATCH 039/111] update submodules --- .gitlab/radiuss-spack-configs | 2 +- .gitlab/uberenv | 2 +- test/answers | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/radiuss-spack-configs b/.gitlab/radiuss-spack-configs index 6f22afc1ec..8194d152ac 160000 --- a/.gitlab/radiuss-spack-configs +++ b/.gitlab/radiuss-spack-configs @@ -1 +1 @@ -Subproject commit 6f22afc1ece86c479d2d2a64e14736ef00b632d6 +Subproject commit 8194d152acfdfcc8ad5a27051e9988f1e20e8779 diff --git a/.gitlab/uberenv b/.gitlab/uberenv index 0d00dc8e19..4941c237ee 160000 --- a/.gitlab/uberenv +++ b/.gitlab/uberenv @@ -1 +1 @@ -Subproject commit 0d00dc8e19a889ba07ae433590b87533c4b5b3da +Subproject commit 4941c237eec514d6d68872243efb9f4af8843f4d diff --git a/test/answers b/test/answers index adc6da31cd..72fd01e63e 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit adc6da31cd21bfa6e70d6fb026510008643f8ebb +Subproject commit 72fd01e63edeffe39a800c820ac8aa8447270bf7 From d6fd8770a25ea9d247cd07f1126c6486a33f441c Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 1 Jun 2023 13:54:29 -0700 Subject: [PATCH 040/111] fix submodule updates --- .gitlab/radiuss-spack-configs | 2 +- .gitlab/uberenv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/radiuss-spack-configs b/.gitlab/radiuss-spack-configs index 8194d152ac..6f22afc1ec 160000 --- a/.gitlab/radiuss-spack-configs +++ b/.gitlab/radiuss-spack-configs @@ -1 +1 @@ -Subproject commit 8194d152acfdfcc8ad5a27051e9988f1e20e8779 +Subproject commit 6f22afc1ece86c479d2d2a64e14736ef00b632d6 diff --git a/.gitlab/uberenv b/.gitlab/uberenv index 4941c237ee..0d00dc8e19 160000 --- a/.gitlab/uberenv +++ b/.gitlab/uberenv @@ -1 +1 @@ -Subproject commit 4941c237eec514d6d68872243efb9f4af8843f4d +Subproject commit 0d00dc8e19a889ba07ae433590b87533c4b5b3da From e9431b787d22cbfd7c9557ebbd493ffda1bbbb56 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 1 Jun 2023 14:02:44 -0700 Subject: [PATCH 041/111] add missing breaks --- src/arkode/arkode_relaxation.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 8164196213..8c7c93c81a 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -471,12 +471,14 @@ int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) relax_mem->nls_iters); fprintf(outfile, "Relax NLS fails = %ld\n", relax_mem->nls_fails); + break; case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, ",Relax fn evals,%ld", relax_mem->num_relax_fn_evals); fprintf(outfile, ",Relax Jac evals,%ld", relax_mem->num_relax_jac_evals); fprintf(outfile, ",Relax fails,%ld", relax_mem->num_fails); fprintf(outfile, ",Relax NLS iters,%ld", relax_mem->nls_iters); fprintf(outfile, ",Relax NLS fails,%ld", relax_mem->nls_fails); + break; default: arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxPrintAllStats", "Invalid formatting option."); From 3f5ef4c15042888f08f577f556c374dbe2a18cee Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 1 Jun 2023 14:09:58 -0700 Subject: [PATCH 042/111] fix memory leak --- src/arkode/arkode_relaxation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 8c7c93c81a..1b8870b1db 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -664,7 +664,7 @@ int arkRelaxDestroy(ARKodeRelaxMem relax_mem) relax_mem->y_relax = NULL; } - if (relax_mem->y_relax) + if (relax_mem->J_vecs) { N_VDestroyVectorArray(relax_mem->J_vecs, relax_mem->num_relax_fn_alloc); relax_mem->J_vecs = NULL; From 5591e5f06525fd730ebb10404345136c2cbcc149 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 3 Jul 2023 14:56:50 -0700 Subject: [PATCH 043/111] debugging output --- src/arkode/arkode_relaxation.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 1b8870b1db..0cd541f832 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -108,6 +108,15 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) sunrealtype max_res; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", + "tolerance = %g", relax_mem->tol); + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", + "0: relaxation param = %g", relax_mem->relax_vals[0]); +#endif + for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* y_relax = y_n + r * delta_y */ @@ -120,6 +129,12 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) relax_mem->res_vals, ark_mem); if (retval) return retval; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", + "%d: relaxation resid = %g", i, relax_mem->res_vals[0]); +#endif + /* Check for convergence of all values */ max_res = SUNRabs(relax_mem->res_vals[0]); for (j = 1; j < ark_mem->relax_mem->num_relax_fn; ++j) @@ -135,8 +150,20 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) relax_mem->jac_vals, ark_mem); if (retval) return retval; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", + "%d: relaxation jac = %g", i, relax_mem->jac_vals[0]); +#endif + for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) relax_mem->relax_vals[j] -= relax_mem->res_vals[j] / relax_mem->jac_vals[j]; + +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", + "%d: relaxation param = %g", i+1, relax_mem->relax_vals[0]); +#endif } return ARK_RELAX_SOLVE_RECV; @@ -743,6 +770,12 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, /* Cut step size and try again */ ark_mem->eta = relax_mem->eta_fail; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkStep_TakeStep_Z", "relaxation", + "relaxation failed"); +#endif + return TRY_AGAIN; } From fa41480d4743917b575c805c3f28c6ebf490fe7a Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 3 Jul 2023 16:01:58 -0700 Subject: [PATCH 044/111] simplify interface for single relaxation equation --- examples/arkode/CXX_serial/ark_pendulum.cpp | 22 +- .../C_serial/ark_conserved_exp_entropy_ark.c | 22 +- .../C_serial/ark_conserved_exp_entropy_erk.c | 22 +- .../C_serial/ark_dissipated_exp_entropy.c | 22 +- include/arkode/arkode.h | 4 +- include/arkode/arkode_arkstep.h | 4 +- include/arkode/arkode_erkstep.h | 4 +- src/arkode/arkode_arkstep.c | 68 ++-- src/arkode/arkode_arkstep_impl.h | 8 +- src/arkode/arkode_arkstep_io.c | 5 +- src/arkode/arkode_erkstep.c | 49 +-- src/arkode/arkode_erkstep_impl.h | 8 +- src/arkode/arkode_erkstep_io.c | 5 +- src/arkode/arkode_relaxation.c | 337 +++++------------- src/arkode/arkode_relaxation_impl.h | 25 +- 15 files changed, 196 insertions(+), 409 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index e57ea79578..ddd96cabef 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -64,10 +64,10 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); // Energy function -int Eng(N_Vector* y, sunrealtype* e, void* user_data); +int Eng(N_Vector y, sunrealtype* e, void* user_data); // Energy Jacobian function -int JacEng(N_Vector* y, N_Vector* J, void* user_data); +int JacEng(N_Vector y, N_Vector J, void* user_data); /* ------------ * * Main Program * @@ -128,7 +128,7 @@ int main(int argc, char* argv[]) // Initial energy sunrealtype eng0; - int flag = Eng(&y, &eng0, nullptr); + int flag = Eng(y, &eng0, nullptr); if (check_flag(flag, "Eng")) return 1; // Initialize the ARKStep @@ -144,7 +144,7 @@ int main(int argc, char* argv[]) if (relax) { // Enable relaxation methods - flag = ARKStepSetRelaxFn(arkode_mem, 1, Eng, JacEng); + flag = ARKStepSetRelaxFn(arkode_mem, Eng, JacEng); if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; flag = ARKStepSetRelaxMaxIters(arkode_mem, 100); @@ -238,7 +238,7 @@ int main(int argc, char* argv[]) // Output solution and errors sunrealtype eng; - flag = Eng(&y, &eng, nullptr); + flag = Eng(y, &eng, nullptr); if (check_flag(flag, "Eng")) return 1; sunrealtype eng_chng = eng - eng0; @@ -383,20 +383,20 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, } // Energy function e(y) -int Eng(N_Vector* y, sunrealtype* e, void* user_data) +int Eng(N_Vector y, sunrealtype* e, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); - e[0] = SUN_RCONST(0.5) * ydata[0] * ydata[0] - std::cos(ydata[1]); + *e = SUN_RCONST(0.5) * ydata[0] * ydata[0] - std::cos(ydata[1]); return 0; } // Energy function Jacobian Je(y) = de/dy -int JacEng(N_Vector* y, N_Vector* J, void* user_data) +int JacEng(N_Vector y, N_Vector J, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); - sunrealtype* jdata = N_VGetArrayPointer(J[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* jdata = N_VGetArrayPointer(J); jdata[0] = ydata[0]; jdata[1] = std::sin(ydata[1]); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 048ec796e4..b1c125bfde 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -72,10 +72,10 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); /* Entropy function */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data); +int Ent(N_Vector y, sunrealtype* e, void* user_data); /* Entropy Jacobian function */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data); +int JacEnt(N_Vector y, N_Vector J, void* user_data); /* ----------------- * * Utility functions * @@ -193,7 +193,7 @@ int main(int argc, char* argv[]) if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; /* Initial entropy */ - flag = Ent(&y, &ent0, NULL); + flag = Ent(y, &ent0, NULL); if (check_flag(flag, "Ent")) return 1; /* Initialize the ARKStep */ @@ -214,7 +214,7 @@ int main(int argc, char* argv[]) if (relax) { /* Enable relaxation methods */ - flag = ARKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); + flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; } @@ -281,7 +281,7 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepEvolve")) break; /* Output solution and errors */ - flag = Ent(&y, &ent, NULL); + flag = Ent(y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; flag = ans(t, ytrue); @@ -427,20 +427,20 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, } /* Entropy function e(y) */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data) +int Ent(N_Vector y, sunrealtype* e, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); - e[0] = EXP(ydata[0]) + EXP(ydata[1]); + *e = EXP(ydata[0]) + EXP(ydata[1]); return 0; } /* Entropy function Jacobian Je(y) = de/dy */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data) +int JacEnt(N_Vector y, N_Vector J, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); - sunrealtype* jdata = N_VGetArrayPointer(J[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* jdata = N_VGetArrayPointer(J); jdata[0] = EXP(ydata[0]); jdata[1] = EXP(ydata[1]); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index ba698df652..eb56b7e645 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -66,10 +66,10 @@ int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); /* Entropy function */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data); +int Ent(N_Vector y, sunrealtype* e, void* user_data); /* Entropy Jacobian function */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data); +int JacEnt(N_Vector y, N_Vector J, void* user_data); /* ----------------- * * Utility functions * @@ -175,7 +175,7 @@ int main(int argc, char* argv[]) if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; /* Initial entropy */ - flag = Ent(&y, &ent0, NULL); + flag = Ent(y, &ent0, NULL); if (check_flag(flag, "Ent")) return 1; /* Initialize the ERKStep */ @@ -189,7 +189,7 @@ int main(int argc, char* argv[]) if (relax) { /* Enable relaxation methods */ - flag = ERKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); + flag = ERKStepSetRelaxFn(arkode_mem, Ent, JacEnt); if (check_flag(flag, "ERKStepSetRelaxFn")) return 1; } @@ -233,7 +233,7 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ERKStepEvolve")) break; /* Output solution and errors */ - flag = Ent(&y, &ent, NULL); + flag = Ent(y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; flag = ans(t, ytrue); @@ -335,20 +335,20 @@ int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) } /* Entropy function e(y) */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data) +int Ent(N_Vector y, sunrealtype* e, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); - e[0] = EXP(ydata[0]) + EXP(ydata[1]); + *e = EXP(ydata[0]) + EXP(ydata[1]); return 0; } /* Entropy function Jacobian Je(y) = de/dy */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data) +int JacEnt(N_Vector y, N_Vector J, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); - sunrealtype* jdata = N_VGetArrayPointer(J[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* jdata = N_VGetArrayPointer(J); jdata[0] = EXP(ydata[0]); jdata[1] = EXP(ydata[1]); diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index eb55e4d309..e8fb7182a3 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -52,10 +52,10 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); /* Entropy function */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data); +int Ent(N_Vector y, sunrealtype* e, void* user_data); /* Entropy Jacobian function */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data); +int JacEnt(N_Vector y, N_Vector J, void* user_data); /* ----------------- * * Utility functions * @@ -184,7 +184,7 @@ int main(int argc, char* argv[]) if (relax) { /* Enable relaxation methods */ - flag = ARKStepSetRelaxFn(arkode_mem, 1, Ent, JacEnt); + flag = ARKStepSetRelaxFn(arkode_mem, Ent, JacEnt); if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; } @@ -223,7 +223,7 @@ int main(int argc, char* argv[]) t = t0; /* Output the initial condition and entropy */ - flag = Ent(&y, &ent0, NULL); + flag = Ent(y, &ent0, NULL); if (check_flag(flag, "Ent")) return 1; fprintf(UFID, @@ -244,7 +244,7 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepEvolve")) break; /* Output solution and errors */ - flag = Ent(&y, &ent, NULL); + flag = Ent(y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; flag = ans(t, ytrue); @@ -376,18 +376,18 @@ int Jac(sunrealtype t, N_Vector y, N_Vector fy, SUNMatrix J, void* user_data, } /* Entropy function e(y) */ -int Ent(N_Vector* y, sunrealtype* e, void* user_data) +int Ent(N_Vector y, sunrealtype* e, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); - e[0] = EXP(ydata[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); + *e = EXP(ydata[0]); return 0; } /* Entropy function Jacobian Je(y) = de/dy */ -int JacEnt(N_Vector* y, N_Vector* J, void* user_data) +int JacEnt(N_Vector y, N_Vector J, void* user_data) { - sunrealtype* ydata = N_VGetArrayPointer(y[0]); - sunrealtype* jdata = N_VGetArrayPointer(J[0]); + sunrealtype* ydata = N_VGetArrayPointer(y); + sunrealtype* jdata = N_VGetArrayPointer(J); jdata[0] = EXP(ydata[0]); return 0; } diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index 946f0bce47..21ecd64fcf 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -176,9 +176,9 @@ typedef int (*ARKPostProcessFn)(realtype t, N_Vector y, typedef int (*ARKStagePredictFn)(realtype t, N_Vector zpred, void *user_data); -typedef int (*ARKRelaxFn)(N_Vector* y, realtype* r, void* user_data); +typedef int (*ARKRelaxFn)(N_Vector y, realtype* r, void* user_data); -typedef int (*ARKRelaxJacFn)(N_Vector* y, N_Vector* J, void* user_data); +typedef int (*ARKRelaxJacFn)(N_Vector y, N_Vector J, void* user_data); /* -------------------------- * MRIStep Inner Stepper Type diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 759c6840f3..1f27a4613c 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -474,8 +474,8 @@ SUNDIALS_EXPORT int ARKStepCreateMRIStepInnerStepper(void *arkode_mem, MRIStepInnerStepper *stepper); /* Relaxation functions */ -SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, - ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, + ARKRelaxJacFn rjac); SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 46703c7793..db50a423de 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -261,8 +261,8 @@ SUNDIALS_EXPORT void ERKStepFree(void **arkode_mem); SUNDIALS_EXPORT void ERKStepPrintMem(void* arkode_mem, FILE* outfile); /* Relaxation functions */ -SUNDIALS_EXPORT int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, - ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, + ARKRelaxJacFn rjac); SUNDIALS_EXPORT int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 99a867b61f..10711b93e9 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -22,6 +22,7 @@ #include "arkode_impl.h" #include "arkode_arkstep_impl.h" #include "arkode_interp_impl.h" +#include "sundials/sundials_nvector.h" #include #include @@ -3010,7 +3011,7 @@ int arkStep_SetInnerForcing(void* arkode_mem, realtype tshift, realtype tscale, * Computes the RK update to yn for use in relaxation methods * ---------------------------------------------------------------------------*/ -int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) +int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) { int i, nvec, retval; realtype* cvals; @@ -3050,11 +3051,9 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) } /* Compute time step update (delta_y) */ - retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv1); + retval = N_VLinearCombination(nvec, cvals, Xvecs, delta_y); if (retval) return ARK_VECTOROP_ERR; - *delta_y = ark_mem->tempv1; - return ARK_SUCCESS; } @@ -3062,18 +3061,19 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) * arkStep_RelaxDeltaE * * Computes the change in the relaxation functions for use in relaxation methods - * delta_e = h * sum_i b_i * + * delta_e = h * sum_i b_i * * ---------------------------------------------------------------------------*/ -int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, - ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, - N_Vector* work_space_2, long int* num_relax_jac_evals, +int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, + long int* num_relax_jac_evals, sunrealtype* delta_e_out) { int i, j, nvec, retval; realtype* cvals; N_Vector* Xvecs; ARKodeARKStepMem step_mem; + N_Vector z_stage = ark_mem->tempv1; + N_Vector J_relax = ark_mem->tempv2; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) @@ -3085,10 +3085,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, step_mem = (ARKodeARKStepMem)(ark_mem->step_mem); /* Initialize output */ - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] = ZERO; - } + *delta_e_out = ZERO; /* Set arrays for fused vector operation */ cvals = step_mem->cvals; @@ -3096,14 +3093,13 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, for (i = 0; i < step_mem->stages; i++) { + /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ nvec = 0; - /* Start with y_n */ cvals[nvec] = ONE; Xvecs[nvec] = ark_mem->yn; nvec++; - /* Explicit pieces */ if (step_mem->explicit) { for (j = 0; j < i; j++) @@ -3114,7 +3110,6 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, } } - /* Implicit pieces */ if (step_mem->implicit) { for (j = 0; j <= i; j++) @@ -3125,58 +3120,39 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, } } - /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ - retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv2); + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); if (retval) return ARK_VECTOROP_ERR; - /* Duplicate stage to compute entropy Jacobians at z_i */ - for (j = 0; j < num_relax_fn; j++) - { - N_VScale(ONE, ark_mem->tempv2, work_space_1[j]); - } - - /* Evaluate the Jacobians at z_i */ - retval = relax_jac_fn(work_space_1, work_space_2, ark_mem->user_data); + /* Evaluate the Jacobian at z_i */ + retval = relax_jac_fn(z_stage, ark_mem->tempv2, ark_mem->user_data); (*num_relax_jac_evals)++; if (retval < 0) { return ARK_RELAX_JAC_FAIL; } if (retval > 0) { return ARK_RELAX_JAC_RECV; } - /* Update estimates */ + /* Update estimate of relaxation function change */ if (step_mem->explicit && step_mem->implicit) { N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], step_mem->Bi->b[i], step_mem->Fi[i], - ark_mem->tempv1); - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] += N_VDotProdLocal(work_space_2[j], ark_mem->tempv1); - } + z_stage); + *delta_e_out += N_VDotProdLocal(J_relax, z_stage); } else if (step_mem->explicit) { - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] += step_mem->Be->b[i] * N_VDotProdLocal(work_space_2[j], - step_mem->Fe[i]); - } + *delta_e_out += step_mem->Be->b[i] * N_VDotProdLocal(J_relax, + step_mem->Fe[i]); } else if (step_mem->implicit) { - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] += step_mem->Bi->b[i] * N_VDotProdLocal(work_space_2[j], - step_mem->Fi[i]); - } + *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, + step_mem->Fi[i]); } } /* Ignore negative return for node-local vectors where this is a non-op */ - N_VDotProdMultiAllReduce(num_relax_fn, ark_mem->tempv1, delta_e_out); + N_VDotProdMultiAllReduce(1, ark_mem->tempv2, delta_e_out); - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] *= ark_mem->h; - } + *delta_e_out *= ark_mem->h; return ARK_SUCCESS; } diff --git a/src/arkode/arkode_arkstep_impl.h b/src/arkode/arkode_arkstep_impl.h index 90a52ab23a..9ab9c772b1 100644 --- a/src/arkode/arkode_arkstep_impl.h +++ b/src/arkode/arkode_arkstep_impl.h @@ -230,11 +230,9 @@ int arkStep_MRIStepInnerReset(MRIStepInnerStepper stepper, realtype tR, N_Vector yR); /* private functions for relaxation */ -int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y); -int arkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, - ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, - N_Vector* work_space_2, long int* relax_jac_fn_evals, - sunrealtype* delta_e_out); +int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y); +int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, + long int* relax_jac_fn_evals, sunrealtype* delta_e_out); int arkStep_GetOrder(ARKodeMem ark_mem); /*=============================================================== diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index c012474a14..1fa88cae52 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -263,10 +263,9 @@ char *ARKStepGetLinReturnFlagName(long int flag) { * Wrappers for the ARKODE relaxation module * ---------------------------------------------------------------------------*/ -int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, - ARKRelaxJacFn rjac) +int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) { - return arkRelaxCreate(arkode_mem, nrfn, rfn, rjac, arkStep_RelaxDeltaY, + return arkRelaxCreate(arkode_mem, rfn, rjac, arkStep_RelaxDeltaY, arkStep_RelaxDeltaE, arkStep_GetOrder); } diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index d792610988..c303b6ba25 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1168,7 +1168,7 @@ int erkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsmPtr) * Computes the RK update to yn for use in relaxation methods * ---------------------------------------------------------------------------*/ -int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) +int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) { int i, nvec, retval; realtype* cvals; @@ -1197,11 +1197,9 @@ int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) } /* Compute time step update (delta_y) */ - retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv1); + retval = N_VLinearCombination(nvec, cvals, Xvecs, delta_y); if (retval) return ARK_VECTOROP_ERR; - *delta_y = ark_mem->tempv1; - return ARK_SUCCESS; } @@ -1212,15 +1210,15 @@ int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y) * delta_e = h * sum_i b_i * * ---------------------------------------------------------------------------*/ -int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, - ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, - N_Vector* work_space_2, long int* num_relax_jac_evals, - sunrealtype* delta_e_out) +int erkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, + long int* num_relax_jac_evals, sunrealtype* delta_e_out) { int i, j, nvec, retval; realtype* cvals; N_Vector* Xvecs; ARKodeERKStepMem step_mem; + N_Vector z_stage = ark_mem->tempv1; + N_Vector J_relax = ark_mem->tempv2; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) @@ -1232,10 +1230,7 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, step_mem = (ARKodeERKStepMem)(ark_mem->step_mem); /* Initialize output */ - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] = ZERO; - } + *delta_e_out = ZERO; /* Set arrays for fused vector operation */ cvals = step_mem->cvals; @@ -1243,14 +1238,13 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, for (i = 0; i < step_mem->stages; i++) { + /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ nvec = 0; - /* Start with y_n */ cvals[nvec] = ONE; Xvecs[nvec] = ark_mem->yn; nvec++; - /* Explicit pieces */ for (j = 0; j < i; j++) { cvals[nvec] = ark_mem->h * step_mem->B->A[i][j]; @@ -1258,37 +1252,24 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, nvec++; } - /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] */ - retval = N_VLinearCombination(nvec, cvals, Xvecs, ark_mem->tempv2); + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); if (retval) return ARK_VECTOROP_ERR; - /* Duplicate stage to compute entropy Jacobians at z_i */ - for (j = 0; j < num_relax_fn; j++) - { - N_VScale(ONE, ark_mem->tempv2, work_space_1[j]); - } - - /* Evaluate the Jacobians at z_i */ - retval = relax_jac_fn(work_space_1, work_space_2, ark_mem->user_data); + /* Evaluate the Jacobian at z_i */ + retval = relax_jac_fn(z_stage, J_relax, ark_mem->user_data); (*num_relax_jac_evals)++; if (retval < 0) { return ARK_RELAX_JAC_FAIL; } if (retval > 0) { return ARK_RELAX_JAC_RECV; } /* Update estimates */ - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] += step_mem->B->b[i] * N_VDotProdLocal(work_space_2[j], - step_mem->F[i]); - } + *delta_e_out += step_mem->B->b[i] * N_VDotProdLocal(J_relax, + step_mem->F[i]); } /* Ignore negative return for node-local vectors where this is a non-op */ - N_VDotProdMultiAllReduce(num_relax_fn, ark_mem->tempv1, delta_e_out); + N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); - for (j = 0; j < num_relax_fn; j++) - { - delta_e_out[j] *= ark_mem->h; - } + delta_e_out[j] *= ark_mem->h; return ARK_SUCCESS; } diff --git a/src/arkode/arkode_erkstep_impl.h b/src/arkode/arkode_erkstep_impl.h index d647f4721f..f3684d9d39 100644 --- a/src/arkode/arkode_erkstep_impl.h +++ b/src/arkode/arkode_erkstep_impl.h @@ -84,11 +84,9 @@ int erkStep_CheckButcherTable(ARKodeMem ark_mem); int erkStep_ComputeSolutions(ARKodeMem ark_mem, realtype *dsm); /* private functions for relaxation */ -int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector* delta_y); -int erkStep_RelaxDeltaE(ARKodeMem ark_mem, int num_relax_fn, - ARKRelaxJacFn relax_jac_fn, N_Vector* work_space_1, - N_Vector* work_space_2, long int* relax_jac_fn_evals, - sunrealtype* delta_e_out); +int erkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y); +int erkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, + long int* relax_jac_fn_evals, sunrealtype* delta_e_out); int erkStep_GetOrder(ARKodeMem ark_mem); /*=============================================================== diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 76f58b0d3c..356e3bb27a 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -154,10 +154,9 @@ char *ERKStepGetReturnFlagName(long int flag) { * Wrappers for the ARKODE relaxation module * ---------------------------------------------------------------------------*/ -int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, - ARKRelaxJacFn rjac) +int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) { - return arkRelaxCreate(arkode_mem, nrfn, rfn, rjac, erkStep_RelaxDeltaY, + return arkRelaxCreate(arkode_mem, rfn, rjac, erkStep_RelaxDeltaY, erkStep_RelaxDeltaE, erkStep_GetOrder); } diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 0cd541f832..a78cbfbfc3 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -13,6 +13,11 @@ * ----------------------------------------------------------------------------- * This is the implementation file for ARKODE's relaxation (in time) * functionality + * + * Temporary vectors utilized in the functions below: + * tempv1 - holds delta_y, the update direction vector + * tempv2 - holds y_relax, the relaxed solution vector + * tempv3 - holds J_relax, the Jacobian of the relaxation function * ---------------------------------------------------------------------------*/ #include @@ -50,53 +55,46 @@ static int arkRelaxAccessMem(void* arkode_mem, const char* fname, return ARK_SUCCESS; } -/* Evaluate the relaxation residual function */ -static int arkRelaxResidual(sunrealtype* relax_vals, N_Vector* y_relax, - sunrealtype* res_vals, ARKodeMem ark_mem) +/* Evaluates the relaxation residual function */ +static int arkRelaxResidual(sunrealtype relax_param, N_Vector y_relax, + sunrealtype* relax_res, ARKodeMem ark_mem) { - int i, retval; - int num_relax_fn = ark_mem->relax_mem->num_relax_fn; - long int num_relax_fn_evals = ark_mem->relax_mem->num_relax_fn_evals; - sunrealtype* e_old = ark_mem->relax_mem->e_old; - sunrealtype* delta_e = ark_mem->relax_mem->delta_e; - void* user_data = ark_mem->user_data; - - /* Evaluate entropy functions */ - retval = ark_mem->relax_mem->relax_fn(y_relax, res_vals, user_data); - num_relax_fn_evals++; + int retval; + sunrealtype e_old = ark_mem->relax_mem->e_old; + sunrealtype delta_e = ark_mem->relax_mem->delta_e; + void* user_data = ark_mem->user_data; + + /* Evaluate entropy function */ + retval = ark_mem->relax_mem->relax_fn(y_relax, relax_res, user_data); + ark_mem->relax_mem->num_relax_fn_evals++; if (retval < 0) return ARK_RELAX_FUNC_FAIL; if (retval > 0) return ARK_RELAX_FUNC_RECV; /* Compute relaxation residual */ - for (i = 0; i < num_relax_fn; ++i) - res_vals[i] = res_vals[i] - e_old[i] - relax_vals[i] * delta_e[i]; + *relax_res = *relax_res - e_old - relax_param * delta_e; return ARK_SUCCESS; } -/* Evaluate the relaxation Jacobian function */ -static int arkRelaxJacobian(sunrealtype* relax_vals, N_Vector* y_relax, - sunrealtype* jac_vals, ARKodeMem ark_mem) +/* Evaluates the Jacobian of the relaxation residual function */ +static int arkRelaxResidualJacobian(sunrealtype relax_param, N_Vector y_relax, + sunrealtype* relax_jac, ARKodeMem ark_mem) { - int i, retval; - int num_relax_fn = ark_mem->relax_mem->num_relax_fn; - long int num_relax_jac_fn_evals = ark_mem->relax_mem->num_relax_jac_evals; - N_Vector delta_y = ark_mem->relax_mem->delta_y; - N_Vector* J_vecs = ark_mem->relax_mem->J_vecs; - sunrealtype* delta_e = ark_mem->relax_mem->delta_e; - void* user_data = ark_mem->user_data; + int retval; + N_Vector delta_y = ark_mem->tempv1; + N_Vector J_relax = ark_mem->tempv3; + sunrealtype delta_e = ark_mem->relax_mem->delta_e; + void* user_data = ark_mem->user_data; /* Evaluate Jacobian of entropy functions */ - retval = ark_mem->relax_mem->relax_jac_fn(y_relax, J_vecs, user_data); - num_relax_jac_fn_evals++; + retval = ark_mem->relax_mem->relax_jac_fn(y_relax, J_relax, user_data); + ark_mem->relax_mem->num_relax_jac_evals++; if (retval < 0) return ARK_RELAX_JAC_FAIL; if (retval > 0) return ARK_RELAX_JAC_RECV; /* Compute relaxation residual Jacobian */ - retval = N_VDotProdMulti(num_relax_fn, delta_y, J_vecs, jac_vals); - if (retval) return retval; - - for (i = 0; i < num_relax_fn; ++i) jac_vals[i] -= delta_e[i]; + *relax_jac = N_VDotProd(delta_y, J_relax); + *relax_jac -= delta_e; return ARK_SUCCESS; } @@ -104,9 +102,10 @@ static int arkRelaxJacobian(sunrealtype* relax_vals, N_Vector* y_relax, /* Solve the relaxation residual equation using Newton's method */ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) { - int i, j, retval; - sunrealtype max_res; + int i, retval; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + N_Vector delta_y = ark_mem->tempv1; + N_Vector y_relax = ark_mem->tempv2; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, @@ -114,55 +113,49 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) "tolerance = %g", relax_mem->tol); SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "0: relaxation param = %g", relax_mem->relax_vals[0]); + "0: relaxation param = %g", relax_mem->relax_param); #endif for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* y_relax = y_n + r * delta_y */ - for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[j], - ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[j]); + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_param, delta_y, y_relax); /* Compute the current residual */ - retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, - relax_mem->res_vals, ark_mem); + retval = arkRelaxResidual(relax_mem->relax_param, y_relax, + &(relax_mem->res), ark_mem); if (retval) return retval; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation resid = %g", i, relax_mem->res_vals[0]); + "%d: relaxation resid = %g", i, relax_mem->res); #endif - /* Check for convergence of all values */ - max_res = SUNRabs(relax_mem->res_vals[0]); - for (j = 1; j < ark_mem->relax_mem->num_relax_fn; ++j) - max_res = SUNMAX(max_res, relax_mem->res_vals[j]); - - if (max_res < relax_mem->tol) return ARK_SUCCESS; - - /* Update iteration count */ - relax_mem->nls_iters++; + /* Check for convergence */ + if (SUNRabs(relax_mem->res) < relax_mem->tol) return ARK_SUCCESS; /* Compute Jacobian and update */ - retval = arkRelaxJacobian(relax_mem->relax_vals, relax_mem->y_relax, - relax_mem->jac_vals, ark_mem); + retval = arkRelaxResidualJacobian(relax_mem->relax_param, y_relax, + &(relax_mem->jac), + ark_mem); if (retval) return retval; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation jac = %g", i, relax_mem->jac_vals[0]); + "%d: relaxation jac = %g", i, relax_mem->jac); #endif - for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) - relax_mem->relax_vals[j] -= relax_mem->res_vals[j] / relax_mem->jac_vals[j]; + relax_mem->relax_param -= relax_mem->res / relax_mem->jac; + + /* Update cumulative iteration count */ + relax_mem->nls_iters++; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation param = %g", i+1, relax_mem->relax_vals[0]); + "%d: relaxation param = %g", i+1, relax_mem->relax_param); #endif } @@ -172,34 +165,28 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) /* Solve the relaxation residual equation using Newton's method */ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) { - int i, j, retval; - sunrealtype max_res; + int i, retval; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + N_Vector delta_y = ark_mem->tempv1; + N_Vector y_relax = ark_mem->tempv2; for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* y_relax = y_n + r * delta_y */ - for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_vals[j], - ark_mem->relax_mem->delta_y, ark_mem->relax_mem->y_relax[j]); + N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_param, delta_y, y_relax); /* Compute the current residual */ - retval = arkRelaxResidual(relax_mem->relax_vals, relax_mem->y_relax, - relax_mem->res_vals, ark_mem); + retval = arkRelaxResidual(relax_mem->relax_param, y_relax, + &(relax_mem->res), ark_mem); if (retval) return retval; - /* Check for convergence of all values */ - max_res = SUNRabs(relax_mem->res_vals[0]); - for (j = 1; j < ark_mem->relax_mem->num_relax_fn; ++j) - max_res = SUNMAX(max_res, relax_mem->res_vals[j]); + /* Check for convergence */ + if (relax_mem->res < relax_mem->tol) return ARK_SUCCESS; - if (max_res < relax_mem->tol) return ARK_SUCCESS; + relax_mem->relax_param -= relax_mem->res; /* Update iteration count */ relax_mem->nls_iters++; - - for (j = 0; j < ark_mem->relax_mem->num_relax_fn; ++j) - relax_mem->relax_vals[j] -= relax_mem->res_vals[j]; } return ARK_RELAX_SOLVE_RECV; @@ -209,34 +196,29 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, sunrealtype* relax_val_out) { - int i, retval; - sunrealtype relax_val_max, relax_val_min; + int retval; - /* Get the change in entropy (use y_relax and J_vecs as scratch) */ - retval = relax_mem->delta_e_fn(ark_mem, relax_mem->num_relax_fn, - relax_mem->relax_jac_fn, relax_mem->y_relax, - relax_mem->J_vecs, + /* Get the change in entropy (uses temp vectors 1 and 2) */ + retval = relax_mem->delta_e_fn(ark_mem, + relax_mem->relax_jac_fn, &(relax_mem->num_relax_jac_evals), - relax_mem->delta_e); + &(relax_mem->delta_e)); if (retval) return retval; - /* Get the change in state */ - retval = relax_mem->delta_y_fn(ark_mem, &(relax_mem->delta_y)); + /* Get the change in state (delta_y = tempv1) */ + retval = relax_mem->delta_y_fn(ark_mem, ark_mem->tempv1); if (retval) return retval; - /* Duplicate state to evaluate entropy functions at y_n */ - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - N_VScale(ONE, ark_mem->yn, ark_mem->relax_mem->y_relax[i]); - - retval = relax_mem->relax_fn(ark_mem->relax_mem->y_relax, relax_mem->e_old, + /* Store the current relaxation function value */ + retval = relax_mem->relax_fn(ark_mem->yn, &(relax_mem->e_old), ark_mem->user_data); relax_mem->num_relax_fn_evals++; if (retval < 0) return ARK_RELAX_FUNC_FAIL; if (retval > 0) return ARK_RELAX_FUNC_RECV; /* Initial guess for relaxation parameter */ - for (i = 0; i < ark_mem->relax_mem->num_relax_fn; ++i) - relax_mem->relax_vals[i] = ONE; + /* ADD OPTION TO USE GAMMA FROM LAST STEP */ + relax_mem->relax_param = ONE; switch(relax_mem->solver) { @@ -258,22 +240,13 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, return retval; } - /* Compute max and min relaxation values */ - relax_val_max = relax_mem->relax_vals[0]; - relax_val_min = relax_mem->relax_vals[0]; - for (i = 1; i < ark_mem->relax_mem->num_relax_fn; ++i) - { - relax_val_min = SUNMIN(relax_val_min, relax_mem->relax_vals[i]); - relax_val_max = SUNMAX(relax_val_max, relax_mem->relax_vals[i]); - } - /* Check for bad relaxation value */ - if (relax_val_min < relax_mem->lower_bound || - relax_val_max > relax_mem->upper_bound) + if (ark_mem->relax_mem->relax_param < relax_mem->lower_bound || + ark_mem->relax_mem->relax_param > relax_mem->upper_bound) return ARK_RELAX_SOLVE_RECV; - /* Return min relaxation value */ - *relax_val_out = relax_val_min; + /* Return relaxation value */ + *relax_val_out = ark_mem->relax_mem->relax_param; return ARK_SUCCESS; } @@ -520,7 +493,7 @@ int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) * ===========================================================================*/ /* Constructor called by stepper */ -int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, +int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, ARKRelaxJacFn relax_jac_fn, ARKRelaxDeltaYFn delta_y_fn, ARKRelaxDeltaEFn delta_e_fn, ARKRelaxGetOrderFn get_order_fn) { @@ -535,44 +508,29 @@ int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, } ark_mem = (ARKodeMem)arkode_mem; - /* Check for valid inputs */ - if (num_relax_fn < 0) + /* Disable relaxation if both user inputs are NULL */ + if (!relax_fn && !relax_jac_fn) { - arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", - "The number of relaxation functions must be non-negative"); - return ARK_ILL_INPUT; - } - - if (num_relax_fn == 0 && (relax_fn || relax_jac_fn)) - { - arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", - "The number of relaxation functions is 0 but the relaxation" - " or Jacobian function was not NULL."); - return ARK_ILL_INPUT; + ark_mem->relax_enabled = SUNFALSE; + return ARK_SUCCESS; } - if (num_relax_fn > 0 && !relax_fn) + /* Ensure both the relaxation function and Jacobian are provided */ + if (!relax_fn) { arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", "The relaxation function is NULL."); return ARK_ILL_INPUT; } - if (num_relax_fn > 0 && !relax_jac_fn) + if (!relax_jac_fn) { arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", "The relaxation Jacobian function is NULL."); return ARK_ILL_INPUT; } - /* Disable relaxation if user inputs are 0 and NULL */ - if (num_relax_fn == 0 && !relax_fn && !relax_jac_fn) - { - ark_mem->relax_enabled = SUNFALSE; - return ARK_SUCCESS; - } - - /* Check for stepper supplied inputs */ + /* Ensure stepper supplied inputs are provided */ if (!delta_y_fn || !delta_e_fn || !get_order_fn) { arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxCreate", @@ -580,98 +538,29 @@ int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, return ARK_ILL_INPUT; } - /* Check if sufficient memory has already been allocated */ - if (ark_mem->relax_mem) - { - if (ark_mem->relax_mem->num_relax_fn_alloc < num_relax_fn) - { - arkRelaxDestroy(arkode_mem); - ark_mem->relax_mem = NULL; - } - } - - /* Allocate the relaxation memory structure if necessary */ + /* Allocate and initialize relaxation memory structure */ if (!(ark_mem->relax_mem)) { ark_mem->relax_mem = (ARKodeRelaxMem)malloc(sizeof(*(ark_mem->relax_mem))); if (!(ark_mem->relax_mem)) return ARK_MEM_FAIL; - - /* Zero out relax_mem */ memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); - /* Allocate vectors */ - ark_mem->relax_mem->y_relax = N_VCloneVectorArray(num_relax_fn, ark_mem->yn); - if (!(ark_mem->relax_mem->y_relax)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->J_vecs = N_VCloneVectorArray(num_relax_fn, ark_mem->yn); - if (!(ark_mem->relax_mem->J_vecs)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - /* Allocate arrays */ - ark_mem->relax_mem->delta_e = - (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); - if (!(ark_mem->relax_mem->delta_e)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->e_old = - (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); - if (!(ark_mem->relax_mem->e_old)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->res_vals = - (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); - if (!(ark_mem->relax_mem->res_vals)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->jac_vals = - (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); - if (!(ark_mem->relax_mem->jac_vals)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->relax_vals = - (sunrealtype*)malloc(num_relax_fn * sizeof(sunrealtype)); - if (!(ark_mem->relax_mem->relax_vals)) - { - arkRelaxDestroy(arkode_mem); - return ARK_MEM_FAIL; - } - - ark_mem->relax_mem->num_relax_fn_alloc = num_relax_fn; + /* Initialize other values */ + ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; + ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; + ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; + ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; + ark_mem->relax_mem->tol = ARK_RELAX_DEFAULT_TOL; + ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; } - /* Initialize other values */ + /* Set function pointers */ ark_mem->relax_mem->relax_fn = relax_fn; ark_mem->relax_mem->relax_jac_fn = relax_jac_fn; ark_mem->relax_mem->delta_y_fn = delta_y_fn; ark_mem->relax_mem->delta_e_fn = delta_e_fn; ark_mem->relax_mem->get_order_fn = get_order_fn; - ark_mem->relax_mem->num_relax_fn = num_relax_fn; - ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; - ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; - ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; - ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; - ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; - ark_mem->relax_mem->tol = ARK_RELAX_DEFAULT_TOL; - ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; /* Enable relaxation */ ark_mem->relax_enabled = SUNTRUE; @@ -684,50 +573,6 @@ int arkRelaxDestroy(ARKodeRelaxMem relax_mem) { if (!relax_mem) return ARK_SUCCESS; - /* Free vectors */ - if (relax_mem->y_relax) - { - N_VDestroyVectorArray(relax_mem->y_relax, relax_mem->num_relax_fn_alloc); - relax_mem->y_relax = NULL; - } - - if (relax_mem->J_vecs) - { - N_VDestroyVectorArray(relax_mem->J_vecs, relax_mem->num_relax_fn_alloc); - relax_mem->J_vecs = NULL; - } - - /* Free arrays */ - if (relax_mem->delta_e) - { - free(relax_mem->delta_e); - relax_mem->delta_e = NULL; - } - - if (relax_mem->e_old) - { - free(relax_mem->e_old); - relax_mem->e_old = NULL; - } - - if (relax_mem->res_vals) - { - free(relax_mem->res_vals); - relax_mem->res_vals = NULL; - } - - if (relax_mem->jac_vals) - { - free(relax_mem->jac_vals); - relax_mem->jac_vals = NULL; - } - - if (relax_mem->relax_vals) - { - free(relax_mem->relax_vals); - relax_mem->relax_vals = NULL; - } - /* Free structure */ free(relax_mem); diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 3729ff3e2f..7c8fe21d3c 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -49,12 +49,10 @@ * ---------------------------------------------------------------------------*/ /* Compute the change in state for the current step y_new = y_old + delta_y */ -typedef int (*ARKRelaxDeltaYFn)(ARKodeMem ark_mem, N_Vector* delta_y); +typedef int (*ARKRelaxDeltaYFn)(ARKodeMem ark_mem, N_Vector delta_y); /* Compute the estimated change in entropy for this step delta_e */ -typedef int (*ARKRelaxDeltaEFn)(ARKodeMem ark_mem, int num_relax_fn, - ARKRelaxJacFn relax_jac_fn, - N_Vector* work_space_1, N_Vector* work_space_2, +typedef int (*ARKRelaxDeltaEFn)(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, long int* evals_out, sunrealtype* delta_e_out); /* Get the method order */ @@ -73,23 +71,16 @@ struct ARKodeRelaxMemRec ARKRelaxDeltaEFn delta_e_fn; /* get delta entropy from stepper */ ARKRelaxGetOrderFn get_order_fn; /* get the method order */ - /* stepper computed quantities used in the residual and Jacobian */ - N_Vector delta_y; /* change in solution */ - sunrealtype* delta_e; /* change in entropy */ - /* relaxation variables */ - int num_relax_fn; /* number of entropy functions */ - int num_relax_fn_alloc; /* allocated workspce size */ int max_fails; /* max allowed relax fails in a step */ long int num_relax_fn_evals; /* counter for total function evals */ long int num_relax_jac_evals; /* counter for total jacobian evals */ long int num_fails; /* counter for total relaxation fails */ - N_Vector* y_relax; /* relaxed state y_n + relax * delta_y */ - N_Vector* J_vecs; /* relaxation Jacobian vectors */ - sunrealtype* e_old; /* entropy at start of step y(t_{n-1}) */ - sunrealtype* res_vals; /* relaxation residual values */ - sunrealtype* jac_vals; /* relaxation Jacobian values */ - sunrealtype* relax_vals; /* relaxation parameter values */ + sunrealtype e_old; /* entropy at start of step y(t_{n-1}) */ + sunrealtype delta_e; /* change in entropy */ + sunrealtype res; /* relaxation residual value */ + sunrealtype jac; /* relaxation Jacobian value */ + sunrealtype relax_param; /* relaxation parameter value */ sunrealtype lower_bound; /* smallest allowed relaxation value */ sunrealtype upper_bound; /* largest allowed relaxation value */ sunrealtype eta_fail; /* failed relaxation step size factor */ @@ -107,7 +98,7 @@ struct ARKodeRelaxMemRec * ---------------------------------------------------------------------------*/ /* Driver and Stepper Functions */ -int arkRelaxCreate(void* arkode_mem, int num_relax_fn, ARKRelaxFn relax_fn, +int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, ARKRelaxJacFn relax_jac_fn, ARKRelaxDeltaYFn delta_y_fn, ARKRelaxDeltaEFn delta_e_fn, ARKRelaxGetOrderFn get_order_fn); From 4df0f81d3652213174edb6d523a3728aeb60871a Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Mon, 3 Jul 2023 18:42:25 -0700 Subject: [PATCH 045/111] skeleton of Brent's method --- src/arkode/arkode_relaxation.c | 145 +++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index a78cbfbfc3..f14c501e7f 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -162,6 +162,151 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) return ARK_RELAX_SOLVE_RECV; } +/* Solve the relaxation residual equation using Newton's method */ +static int arkRelaxBrentsSolve(ARKodeMem ark_mem) +{ + int i, j, retval; + sunrealtype prev, f_prev; /* previous solution and function value */ + sunrealtype curr, f_curr; /* current solution and function value */ + sunrealtype brac, f_brac; /* together brac and curr bracket zero */ + sunrealtype mid; /* midpoint between brac and curr */ + ARKodeRelaxMem relax_mem = ark_mem->relax_mem; + N_Vector delta_y = ark_mem->tempv1; + N_Vector y_relax = ark_mem->tempv2; + + /* Compute interval that brackets the root */ + prev = SUN_RCONST(0.9) * relax_mem->relax_param; + curr = SUN_RCONST(1.1) * relax_mem->relax_param; + for (i = 0; i < 10; i++) + { + /* y_relax = y_n + r * delta_y */ + N_VLinearSum(ONE, ark_mem->yn, prev, delta_y, y_relax); + + /* Compute relaxation residual */ + retval = arkRelaxResidual(prev, y_relax, &f_prev, ark_mem); + ark_mem->relax_mem->num_relax_fn_evals++; + if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } + if (retval > 0) { return ARK_RELAX_FUNC_RECV; } + + /* Check if we got lucky */ + if (SUNRabs(f_prev) < relax_mem->tol) + { + relax_mem->res = f_prev; + relax_mem->relax_param = prev; + return ARK_SUCCESS; + } + + if (relax_mem->res < ZERO) break; + + f_curr = f_prev; + curr = prev; + prev *= SUN_RCONST(0.9); + } + if (relax_mem->res > ZERO) { return ARK_RELAX_SOLVE_RECV; } + + for (i = 0; i < 10; i++) + { + /* y_relax = y_n + r * delta_y */ + N_VLinearSum(ONE, ark_mem->yn, curr, delta_y, y_relax); + + /* Compute relaxation residual */ + retval = arkRelaxResidual(curr, y_relax, &f_curr, ark_mem); + ark_mem->relax_mem->num_relax_fn_evals++; + if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } + if (retval > 0) { return ARK_RELAX_FUNC_RECV; } + + /* Check if we got lucky */ + if (SUNRabs(f_curr) < relax_mem->tol) + { + relax_mem->res = f_curr; + relax_mem->relax_param = curr; + return ARK_SUCCESS; + } + + if (relax_mem->res > ZERO) break; + + f_prev = f_curr; + prev = curr; + curr *= SUN_RCONST(1.1); + } + if (relax_mem->res < ZERO) { return ARK_RELAX_SOLVE_RECV; } + + /* Initialize values (prev = lower bound and curr = upper bound) */ + brac = prev; + f_brac = f_prev; + + /* Find root */ + for (i = 0; i < ark_mem->relax_mem->max_iters; i++) + { + /* Ensure brac and curr bracket zero */ + if (signbit(f_prev) != signbit(f_curr)) + { + brac = prev; + f_brac = f_prev; + // spre = scur = xcur - xpre + } + + /* Ensure the current solution better of bracketing values */ + if (SUNRabs(f_brac) < SUNRabs(f_curr)) + { + prev = curr; + curr = brac; + brac = prev; + + f_prev = f_curr; + f_curr = f_brac; + f_brac = f_prev; + } + + /* Compute midpoint */ + mid = SUN_RCONST(0.5) * (c - b); + + if (SUNRabs(mid) < tol1) + { + relax_mem->relax_param = curr; + return ARK_SUCCESS; + } + + + if (SUNRabs(e) > tol1 && SUNRabs(f_perv) > SUNRabs(f_cur)) + { + /* Inverse quadratic interpolation */ + + } + else + { + /* Bisection */ + d = mid; + e = d; + } + + /* Update previous best solution */ + prev = curr; + f_prev = f_curr; + + /* Compute new current solution */ + if (SUNRabs(d) > tol1) + { + curr += d; + } + else + { + curr += copysign(tol1, mid); + } + + /* y_relax = y_n + r * delta_y */ + N_VLinearSum(ONE, ark_mem->yn, curr, delta_y, y_relax); + + /* Compute relaxation residual */ + retval = arkRelaxResidual(curr, y_relax, &f_curr, ark_mem); + ark_mem->relax_mem->num_relax_fn_evals++; + if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } + if (retval > 0) { return ARK_RELAX_FUNC_RECV; } + } + + return ARK_RELAX_SOLVE_RECV; +} + /* Solve the relaxation residual equation using Newton's method */ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) { From 4b65a1098e67ee8fc43ec44ed0d8454b78b630b9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 15:07:28 -0700 Subject: [PATCH 046/111] change tol to res_tol, update default --- include/arkode/arkode_arkstep.h | 3 ++- include/arkode/arkode_erkstep.h | 3 ++- src/arkode/arkode_arkstep_io.c | 4 ++-- src/arkode/arkode_erkstep_io.c | 4 ++-- src/arkode/arkode_relaxation.c | 16 ++++++++-------- src/arkode/arkode_relaxation_impl.h | 16 +++++++++------- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index 1f27a4613c..c30ba72f21 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -484,7 +484,8 @@ SUNDIALS_EXPORT int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver); -SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +SUNDIALS_EXPORT int ARKStepSetRelaxResTol(void* arkode_mem, + sunrealtype res_tol); SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index db50a423de..71e47f2b0b 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -271,7 +271,8 @@ SUNDIALS_EXPORT int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver); -SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol); +SUNDIALS_EXPORT int ERKStepSetRelaxResTol(void* arkode_mem, + sunrealtype res_tol); SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 1fa88cae52..a62b285925 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -294,9 +294,9 @@ int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) return arkRelaxSetSolver(arkode_mem, solver); } -int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) { - return arkRelaxSetTol(arkode_mem, tol); + return arkRelaxSetResTol(arkode_mem, res_tol); } int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 356e3bb27a..c1aeade36b 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -185,9 +185,9 @@ int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) return arkRelaxSetSolver(arkode_mem, solver); } -int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) { - return arkRelaxSetTol(arkode_mem, tol); + return arkRelaxSetResTol(arkode_mem, res_tol); } int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index f14c501e7f..7acead0010 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -110,7 +110,7 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "tolerance = %g", relax_mem->tol); + "tolerance = %g", relax_mem->res_tol); SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", "0: relaxation param = %g", relax_mem->relax_param); @@ -133,7 +133,7 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) #endif /* Check for convergence */ - if (SUNRabs(relax_mem->res) < relax_mem->tol) return ARK_SUCCESS; + if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; /* Compute Jacobian and update */ retval = arkRelaxResidualJacobian(relax_mem->relax_param, y_relax, @@ -326,7 +326,7 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) if (retval) return retval; /* Check for convergence */ - if (relax_mem->res < relax_mem->tol) return ARK_SUCCESS; + if (relax_mem->res < relax_mem->res_tol) return ARK_SUCCESS; relax_mem->relax_param -= relax_mem->res; @@ -483,17 +483,17 @@ int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver) return ARK_SUCCESS; } -int arkRelaxSetTol(void* arkode_mem, sunrealtype tol) +int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetTol", &ark_mem, &relax_mem); + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetResTol", &ark_mem, &relax_mem); if (retval) return retval; - if (tol > SUN_RCONST(0.0)) relax_mem->tol = tol; - else relax_mem->tol = ARK_RELAX_DEFAULT_TOL; + if (res_tol > SUN_RCONST(0.0)) relax_mem->res_tol = res_tol; + else relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; return ARK_SUCCESS; } @@ -696,7 +696,7 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; - ark_mem->relax_mem->tol = ARK_RELAX_DEFAULT_TOL; + ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; } diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 7c8fe21d3c..2649b3ec8b 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -30,7 +30,7 @@ * ---------------------------------------------------------------------------*/ #define ARK_RELAX_DEFAULT_MAX_FAILS 10 -#define ARK_RELAX_DEFAULT_TOL SUN_RCONST(1.0e-14) +#define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) #define ARK_RELAX_DEFAULT_MAX_ITERS 5 #define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) #define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.2) @@ -86,11 +86,13 @@ struct ARKodeRelaxMemRec sunrealtype eta_fail; /* failed relaxation step size factor */ /* nonlinear solver settings */ - ARKRelaxSolver solver; /* choice of relaxation solver */ - sunrealtype tol; /* nonlinear solve tolerance */ - int max_iters; /* nonlinear solve max iterations */ - long int nls_iters; /* total nonlinear iterations */ - long int nls_fails; /* number of nonlinear solver fails */ + ARKRelaxSolver solver; /* choice of relaxation solver */ + sunrealtype res_tol; /* nonlinear residual solve tolerance */ + sunrealtype rel_tol; /* nonlinear iterate relative tolerance */ + sunrealtype abs_tol; /* nonlinear iterate absolute tolerance */ + int max_iters; /* nonlinear solve max iterations */ + long int nls_iters; /* total nonlinear iterations */ + long int nls_fails; /* number of nonlinear solver fails */ }; /* ----------------------------------------------------------------------------- @@ -112,7 +114,7 @@ int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver); -int arkRelaxSetTol(void* arkode_mem, sunrealtype tol); +int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol); int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); From ddb50ec74beb4b804ef1b3dfe719d1fa6af35bca Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:05:57 -0700 Subject: [PATCH 047/111] switch to better DIRK method --- examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index b1c125bfde..d293cfb129 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -236,7 +236,7 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetJacFn")) return 1; /* Select a Butcher table with non-negative b values */ - flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + flag = ARKStepSetTableName(arkode_mem, "ARKODE_ARK2_DIRK_3_1_2", "ARKODE_ERK_NONE"); if (check_flag(flag, "ARKStepSetTableName")) return 1; } From c7557cd1d623a8626e8d279358c8bf3069a23649 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:06:57 -0700 Subject: [PATCH 048/111] add relaxation errors to failure handler --- src/arkode/arkode.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 7813c1f941..6b83939f55 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -2533,6 +2533,23 @@ int arkHandleFailure(ARKodeMem ark_mem, int flag) arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE", "ARKODE", "ARKODE was provided an invalid method table"); break; + case ARK_RELAX_FAIL: + arkProcessError(ark_mem, ARK_RELAX_FAIL, "ARKODE", "ARKODE", + "At t = %Lg the relaxation module failed", + (long double) ark_mem->tcur); + break; + case ARK_RELAX_MEM_NULL: + arkProcessError(ark_mem, ARK_RELAX_MEM_NULL, "ARKODE", "ARKODE", + "The ARKODE relaxation module memory is NULL"); + break; + case ARK_RELAX_FUNC_FAIL: + arkProcessError(ark_mem, ARK_RELAX_FUNC_FAIL, "ARKODE", "ARKODE", + "The relaxation function failed unrecoverably"); + break; + case ARK_RELAX_JAC_FAIL: + arkProcessError(ark_mem, ARK_RELAX_JAC_FAIL, "ARKODE", "ARKODE", + "The relaxation Jacobian failed unrecoverably"); + break; default: /* This return should never happen */ arkProcessError(ark_mem, ARK_UNRECOGNIZED_ERROR, "ARKODE", "ARKODE", From d0065e6653c7146394fe01667d00616ea0930ecf Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:07:59 -0700 Subject: [PATCH 049/111] move different_sign to impl header, add same_sign --- src/arkode/arkode_impl.h | 8 ++++++++ src/arkode/arkode_root.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/arkode/arkode_impl.h b/src/arkode/arkode_impl.h index 8358616d93..d93aaf074f 100644 --- a/src/arkode/arkode_impl.h +++ b/src/arkode/arkode_impl.h @@ -52,6 +52,14 @@ extern "C" { #define ARK_PROFILER ark_mem->sunctx->profiler #define ARK_LOGGER ark_mem->sunctx->logger +/*=============================================================== + MACROS + ===============================================================*/ + +/* TODO(DJG): replace with signbit when C99+ is required */ +#define DIFFERENT_SIGN(a,b) ( ( (a) < 0 && (b) > 0 ) || ( (a) > 0 && (b) < 0 ) ) +#define SAME_SIGN(a,b) ( ( (a) > 0 && (b) > 0 ) || ( (a) < 0 && (b) < 0 ) ) + /*=============================================================== ARKODE Private Constants ===============================================================*/ diff --git a/src/arkode/arkode_root.c b/src/arkode/arkode_root.c index 6acdb578ce..7c0b49df81 100644 --- a/src/arkode/arkode_root.c +++ b/src/arkode/arkode_root.c @@ -526,8 +526,6 @@ int arkRootCheck3(void* arkode_mem) return(RTFOUND); } -#define DIFFERENT_SIGN(a,b) ( ( (a) < 0 && (b) > 0 ) || ( (a) > 0 && (b) < 0 ) ) - /*--------------------------------------------------------------- arkRootfind From 3dc70847a5dd67ebd0402bba3d0d3f3fb582c715 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:11:16 -0700 Subject: [PATCH 050/111] have RelaxResidual functions compute relaxed state --- src/arkode/arkode_relaxation.c | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 7acead0010..3b52cb5622 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -56,19 +56,24 @@ static int arkRelaxAccessMem(void* arkode_mem, const char* fname, } /* Evaluates the relaxation residual function */ -static int arkRelaxResidual(sunrealtype relax_param, N_Vector y_relax, - sunrealtype* relax_res, ARKodeMem ark_mem) +static int arkRelaxResidual(sunrealtype relax_param, sunrealtype* relax_res, + ARKodeMem ark_mem) { int retval; sunrealtype e_old = ark_mem->relax_mem->e_old; sunrealtype delta_e = ark_mem->relax_mem->delta_e; + N_Vector delta_y = ark_mem->tempv1; + N_Vector y_relax = ark_mem->tempv2; void* user_data = ark_mem->user_data; + /* y_relax = y_n + r * delta_y */ + N_VLinearSum(ONE, ark_mem->yn, relax_param, delta_y, y_relax); + /* Evaluate entropy function */ retval = ark_mem->relax_mem->relax_fn(y_relax, relax_res, user_data); ark_mem->relax_mem->num_relax_fn_evals++; - if (retval < 0) return ARK_RELAX_FUNC_FAIL; - if (retval > 0) return ARK_RELAX_FUNC_RECV; + if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } + if (retval > 0) { return ARK_RELAX_FUNC_RECV; } /* Compute relaxation residual */ *relax_res = *relax_res - e_old - relax_param * delta_e; @@ -77,20 +82,24 @@ static int arkRelaxResidual(sunrealtype relax_param, N_Vector y_relax, } /* Evaluates the Jacobian of the relaxation residual function */ -static int arkRelaxResidualJacobian(sunrealtype relax_param, N_Vector y_relax, +static int arkRelaxResidualJacobian(sunrealtype relax_param, sunrealtype* relax_jac, ARKodeMem ark_mem) { int retval; N_Vector delta_y = ark_mem->tempv1; + N_Vector y_relax = ark_mem->tempv2; N_Vector J_relax = ark_mem->tempv3; sunrealtype delta_e = ark_mem->relax_mem->delta_e; void* user_data = ark_mem->user_data; + /* y_relax = y_n + r * delta_y */ + N_VLinearSum(ONE, ark_mem->yn, relax_param, delta_y, y_relax); + /* Evaluate Jacobian of entropy functions */ retval = ark_mem->relax_mem->relax_jac_fn(y_relax, J_relax, user_data); ark_mem->relax_mem->num_relax_jac_evals++; - if (retval < 0) return ARK_RELAX_JAC_FAIL; - if (retval > 0) return ARK_RELAX_JAC_RECV; + if (retval < 0) { return ARK_RELAX_JAC_FAIL; } + if (retval > 0) { return ARK_RELAX_JAC_RECV; } /* Compute relaxation residual Jacobian */ *relax_jac = N_VDotProd(delta_y, J_relax); @@ -104,8 +113,6 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) { int i, retval; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; - N_Vector delta_y = ark_mem->tempv1; - N_Vector y_relax = ark_mem->tempv2; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, @@ -118,12 +125,9 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { - /* y_relax = y_n + r * delta_y */ - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_param, delta_y, y_relax); - /* Compute the current residual */ - retval = arkRelaxResidual(relax_mem->relax_param, y_relax, - &(relax_mem->res), ark_mem); + retval = arkRelaxResidual(relax_mem->relax_param, &(relax_mem->res), + ark_mem); if (retval) return retval; #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO @@ -136,8 +140,7 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; /* Compute Jacobian and update */ - retval = arkRelaxResidualJacobian(relax_mem->relax_param, y_relax, - &(relax_mem->jac), + retval = arkRelaxResidualJacobian(relax_mem->relax_param, &(relax_mem->jac), ark_mem); if (retval) return retval; @@ -312,21 +315,16 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) { int i, retval; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; - N_Vector delta_y = ark_mem->tempv1; - N_Vector y_relax = ark_mem->tempv2; for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { - /* y_relax = y_n + r * delta_y */ - N_VLinearSum(ONE, ark_mem->yn, relax_mem->relax_param, delta_y, y_relax); - /* Compute the current residual */ - retval = arkRelaxResidual(relax_mem->relax_param, y_relax, - &(relax_mem->res), ark_mem); + retval = arkRelaxResidual(relax_mem->relax_param, &(relax_mem->res), + ark_mem); if (retval) return retval; /* Check for convergence */ - if (relax_mem->res < relax_mem->res_tol) return ARK_SUCCESS; + if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; relax_mem->relax_param -= relax_mem->res; From 7849e8ef10678fa2508e004b3454a13f9c2c90e8 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:12:03 -0700 Subject: [PATCH 051/111] debugging output --- src/arkode/arkode_relaxation.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 3b52cb5622..e9d36ccf3c 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -380,6 +380,12 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, if (retval) { relax_mem->nls_fails++; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkRelaxSolve", "failed solve", + "return flag = %d, num fails = %ld", + retval, relax_mem->nls_fails); +#endif return retval; } From c5848a7691182f6321880f077deeca8bdd9ecc7b Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:12:44 -0700 Subject: [PATCH 052/111] unrecoverable error with fixed stepping + relaxation --- src/arkode/arkode_relaxation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index e9d36ccf3c..28e9b83b1f 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -761,6 +761,9 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, if (SUNRabs(ark_mem->h) <= ark_mem->hmin * ONEPSM) return ARK_RELAX_FAIL; + /* Return with error if using fixed step sizes */ + if (ark_mem->fixedstep) return(ARK_RELAX_FAIL); + /* Cut step size and try again */ ark_mem->eta = relax_mem->eta_fail; From 4ee02437749d0276652041865424f346294e94d1 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:14:08 -0700 Subject: [PATCH 053/111] use previous gamma as initial guess --- src/arkode/arkode_relaxation.c | 11 ++++++++--- src/arkode/arkode_relaxation_impl.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 28e9b83b1f..9a76166f66 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -360,8 +360,7 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, if (retval > 0) return ARK_RELAX_FUNC_RECV; /* Initial guess for relaxation parameter */ - /* ADD OPTION TO USE GAMMA FROM LAST STEP */ - relax_mem->relax_param = ONE; + relax_mem->relax_param = relax_mem->relax_param_prev; switch(relax_mem->solver) { @@ -394,6 +393,9 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, ark_mem->relax_mem->relax_param > relax_mem->upper_bound) return ARK_RELAX_SOLVE_RECV; + /* Save parameter for next initial guess */ + relax_mem->relax_param_prev = relax_mem->relax_param; + /* Return relaxation value */ *relax_val_out = ark_mem->relax_mem->relax_param; @@ -694,7 +696,7 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, if (!(ark_mem->relax_mem)) return ARK_MEM_FAIL; memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); - /* Initialize other values */ + /* Set defaults */ ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; @@ -702,6 +704,9 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; + + /* Initialize values */ + ark_mem->relax_mem->relax_param_prev = ONE; } /* Set function pointers */ diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 2649b3ec8b..ce1c0a0a20 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -80,7 +80,8 @@ struct ARKodeRelaxMemRec sunrealtype delta_e; /* change in entropy */ sunrealtype res; /* relaxation residual value */ sunrealtype jac; /* relaxation Jacobian value */ - sunrealtype relax_param; /* relaxation parameter value */ + sunrealtype relax_param; /* current relaxation parameter value */ + sunrealtype relax_param_prev; /* previous relaxation parameter value */ sunrealtype lower_bound; /* smallest allowed relaxation value */ sunrealtype upper_bound; /* largest allowed relaxation value */ sunrealtype eta_fail; /* failed relaxation step size factor */ From 84ecaeb20643cce96f88aa0b94eced45f2863b90 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 4 Jul 2023 23:15:53 -0700 Subject: [PATCH 054/111] add Brent's method --- include/arkode/arkode.h | 1 + src/arkode/arkode_impl.h | 1 + src/arkode/arkode_relaxation.c | 210 ++++++++++++++++++---------- src/arkode/arkode_relaxation_impl.h | 4 +- 4 files changed, 143 insertions(+), 73 deletions(-) diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index 21ecd64fcf..60b5c77a66 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -191,6 +191,7 @@ typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; * -------------------------- */ typedef enum { + ARK_RELAX_BRENT, ARK_RELAX_NEWTON, ARK_RELAX_FIXEDPOINT } ARKRelaxSolver; diff --git a/src/arkode/arkode_impl.h b/src/arkode/arkode_impl.h index d93aaf074f..37a03617a2 100644 --- a/src/arkode/arkode_impl.h +++ b/src/arkode/arkode_impl.h @@ -79,6 +79,7 @@ extern "C" { #define HALF RCONST(0.5) /* real 0.5 */ #define ONE RCONST(1.0) /* real 1.0 */ #define TWO RCONST(2.0) /* real 2.0 */ +#define THREE RCONST(3.0) /* real 3.0 */ #define FOUR RCONST(4.0) /* real 4.0 */ #define FIVE RCONST(5.0) /* real 5.0 */ diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 9a76166f66..8239e31c66 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -166,142 +166,203 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) } /* Solve the relaxation residual equation using Newton's method */ -static int arkRelaxBrentsSolve(ARKodeMem ark_mem) +static int arkRelaxBrentSolve(ARKodeMem ark_mem) { - int i, j, retval; - sunrealtype prev, f_prev; /* previous solution and function value */ - sunrealtype curr, f_curr; /* current solution and function value */ - sunrealtype brac, f_brac; /* together brac and curr bracket zero */ - sunrealtype mid; /* midpoint between brac and curr */ + int i, retval; + sunrealtype xa, fa; /* previous solution and function value */ + sunrealtype xb, fb; /* current solution and function value */ + sunrealtype xc, fc; /* together brac and curr bracket zero */ + sunrealtype xm; /* midpoint between brac and curr */ + sunrealtype old_update; /* previous iteration update */ + sunrealtype new_update; /* new iteration update */ + sunrealtype tol; /* iteration tolerance */ + sunrealtype pt, qt, rt, st; /* temporary values */ + ARKodeRelaxMem relax_mem = ark_mem->relax_mem; - N_Vector delta_y = ark_mem->tempv1; - N_Vector y_relax = ark_mem->tempv2; /* Compute interval that brackets the root */ - prev = SUN_RCONST(0.9) * relax_mem->relax_param; - curr = SUN_RCONST(1.1) * relax_mem->relax_param; + xa = SUN_RCONST(0.9) * relax_mem->relax_param; + xb = SUN_RCONST(1.1) * relax_mem->relax_param; + for (i = 0; i < 10; i++) { - /* y_relax = y_n + r * delta_y */ - N_VLinearSum(ONE, ark_mem->yn, prev, delta_y, y_relax); - /* Compute relaxation residual */ - retval = arkRelaxResidual(prev, y_relax, &f_prev, ark_mem); + retval = arkRelaxResidual(xa, &fa, ark_mem); ark_mem->relax_mem->num_relax_fn_evals++; if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } if (retval > 0) { return ARK_RELAX_FUNC_RECV; } /* Check if we got lucky */ - if (SUNRabs(f_prev) < relax_mem->tol) + if (SUNRabs(fa) < relax_mem->res_tol) { - relax_mem->res = f_prev; - relax_mem->relax_param = prev; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkRelaxBrentSolve", "Lower bound solves", + "relax param = %g, relax residual = %g", + xa, fa); +#endif + relax_mem->res = fa; + relax_mem->relax_param = xa; return ARK_SUCCESS; } - if (relax_mem->res < ZERO) break; + if (fa < ZERO) break; - f_curr = f_prev; - curr = prev; - prev *= SUN_RCONST(0.9); + fb = fa; + xb = xa; + xa *= SUN_RCONST(0.9); } - if (relax_mem->res > ZERO) { return ARK_RELAX_SOLVE_RECV; } + if (fa > ZERO) { return ARK_RELAX_SOLVE_RECV; } for (i = 0; i < 10; i++) { - /* y_relax = y_n + r * delta_y */ - N_VLinearSum(ONE, ark_mem->yn, curr, delta_y, y_relax); - /* Compute relaxation residual */ - retval = arkRelaxResidual(curr, y_relax, &f_curr, ark_mem); + retval = arkRelaxResidual(xb, &fb, ark_mem); ark_mem->relax_mem->num_relax_fn_evals++; if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } if (retval > 0) { return ARK_RELAX_FUNC_RECV; } /* Check if we got lucky */ - if (SUNRabs(f_curr) < relax_mem->tol) + if (SUNRabs(fb) < relax_mem->res_tol) { - relax_mem->res = f_curr; - relax_mem->relax_param = curr; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkRelaxBrentSolve", "Upper bound solves", + "relax param = %g, relax residual = %g", + xb, fb); +#endif + relax_mem->res = fb; + relax_mem->relax_param = xb; return ARK_SUCCESS; } - if (relax_mem->res > ZERO) break; + if (fb > ZERO) break; - f_prev = f_curr; - prev = curr; - curr *= SUN_RCONST(1.1); + fa = fb; + xa = xb; + xb *= SUN_RCONST(1.1); } - if (relax_mem->res < ZERO) { return ARK_RELAX_SOLVE_RECV; } + if (fb < ZERO) { return ARK_RELAX_SOLVE_RECV; } - /* Initialize values (prev = lower bound and curr = upper bound) */ - brac = prev; - f_brac = f_prev; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkRelaxBrentSolve", "Initial interval", + "xa = %g, xb = %g, fa = %g, fb = %g", + xa, xb, fa, fb); +#endif + + /* Initialize values bracketing values to lower bound */ + xc = xa; + fc = fa; /* Find root */ for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { - /* Ensure brac and curr bracket zero */ - if (signbit(f_prev) != signbit(f_curr)) + /* Ensure xc and xb bracket zero */ + if (SAME_SIGN(fc,fb)) { - brac = prev; - f_brac = f_prev; - // spre = scur = xcur - xpre + xc = xa; + fc = fa; + old_update = new_update = xb - xa; } - /* Ensure the current solution better of bracketing values */ - if (SUNRabs(f_brac) < SUNRabs(f_curr)) + /* Ensure xb is closer to zero than xc */ + if (SUNRabs(fb) > SUNRabs(fc)) { - prev = curr; - curr = brac; - brac = prev; + xa = xb; + xb = xc; + xc = xa; - f_prev = f_curr; - f_curr = f_brac; - f_brac = f_prev; + fa = fb; + fb = fc; + fc = fa; } - /* Compute midpoint */ - mid = SUN_RCONST(0.5) * (c - b); + /* Update tolerance */ + tol = relax_mem->rel_tol * SUNRabs(xb) + HALF * relax_mem->abs_tol; + + /* Compute midpoint for bisection */ + xm = SUN_RCONST(0.5) * (xc - xb); - if (SUNRabs(mid) < tol1) + /* Check for convergence */ + if (SUNRabs(xm) < tol || SUNRabs(fb) < relax_mem->res_tol) { - relax_mem->relax_param = curr; +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, + "ARKODE::arkRelaxBrentSolve", "Coverged", + "xm = %g, tol = %g, res tol = %g, relax param = %g, relax residual = %g", + xm, tol, relax_mem->res_tol, xb, fb); +#endif + relax_mem->res = fb; + relax_mem->relax_param = xb; return ARK_SUCCESS; } - - if (SUNRabs(e) > tol1 && SUNRabs(f_perv) > SUNRabs(f_cur)) + /* Compute iteration update */ + if (SUNRabs(old_update) >= tol && SUNRabs(fb) < SUNRabs(fa)) { - /* Inverse quadratic interpolation */ - + /* Converging sufficiently fast, interpolate solution */ + st = fb / fa; + + if (xa == xc) + { + /* Two unique values available, try linear interpolant (secant) */ + pt = TWO * xm * st ; + qt = ONE - st; + } + else + { + /* Three unique values available, try inverse quadratic interpolant */ + qt = fa / fc; + rt = fb / fc; + pt = st * (TWO * xm * qt * (qt - rt) - (xb - xa) * (rt - ONE)); + qt = (qt - ONE) * (rt - ONE) * (st - ONE); + } + + /* Ensure updates produce values within [xc, xb] or [xb, xc] */ + if (pt > ZERO) { qt = -qt; } + else { pt = -pt; } + + /* Check if interpolant is acceptable, otherwise use bisection */ + st = THREE * xm * qt - SUNRabs(tol * qt); + rt = SUNRabs(old_update * qt); + + if (TWO * pt < SUNMIN(st, rt)) + { + old_update = new_update; + new_update = pt / qt; + } + else + { + new_update = xm; + old_update = xm; + } } else { - /* Bisection */ - d = mid; - e = d; + /* Converging too slowly, use bisection */ + new_update = xm; + old_update = xm; } - /* Update previous best solution */ - prev = curr; - f_prev = f_curr; + /* Update solution */ + xa = xb; + fa = fb; - /* Compute new current solution */ - if (SUNRabs(d) > tol1) + /* If update is small, use tolerance in bisection direction */ + if (SUNRabs(new_update) > tol) { - curr += d; + xb += new_update; } else { - curr += copysign(tol1, mid); + /* TODO(DJG): Replace with copysign when C99+ required */ + if (xm > ZERO) { xb += tol; } + else { xb -= tol; } } - /* y_relax = y_n + r * delta_y */ - N_VLinearSum(ONE, ark_mem->yn, curr, delta_y, y_relax); - /* Compute relaxation residual */ - retval = arkRelaxResidual(curr, y_relax, &f_curr, ark_mem); + retval = arkRelaxResidual(xb, &fb, ark_mem); ark_mem->relax_mem->num_relax_fn_evals++; if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } if (retval > 0) { return ARK_RELAX_FUNC_RECV; } @@ -364,6 +425,9 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, switch(relax_mem->solver) { + case(ARK_RELAX_BRENT): + retval = arkRelaxBrentSolve(ark_mem); + break; case(ARK_RELAX_NEWTON): retval = arkRelaxNewtonSolve(ark_mem); break; @@ -703,6 +767,8 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; + ark_mem->relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; + ark_mem->relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; /* Initialize values */ diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index ce1c0a0a20..d8e64cd165 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -31,7 +31,9 @@ #define ARK_RELAX_DEFAULT_MAX_FAILS 10 #define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) -#define ARK_RELAX_DEFAULT_MAX_ITERS 5 +#define ARK_RELAX_DEFAULT_REL_TOL (4 * SUN_UNIT_ROUNDOFF) +#define ARK_RELAX_DEFAULT_ABS_TOL SUN_RCONST(1.0e-14) +#define ARK_RELAX_DEFAULT_MAX_ITERS 10 #define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) #define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.2) #define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) From e060d42509a7c5874f62987873651623eeadf2fb Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 02:06:24 -0700 Subject: [PATCH 055/111] debugging output --- .../C_serial/ark_conserved_exp_entropy_ark.c | 5 ++++- src/arkode/arkode_arkstep.c | 19 +++++++++++++++---- src/arkode/arkode_relaxation.c | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index d293cfb129..e3729621a2 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -95,7 +95,7 @@ int main(int argc, char* argv[]) /* Initial and final times */ sunrealtype t0 = SUN_RCONST(0.0); - sunrealtype tf = SUN_RCONST(5.0); + sunrealtype tf = SUN_RCONST(0.03); /* Relative and absolute tolerances */ sunrealtype reltol = SUN_RCONST(1.0e-6); @@ -280,6 +280,9 @@ int main(int argc, char* argv[]) flag = ARKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; + printf("y_new (returned):\n"); + N_VPrint(y); + /* Output solution and errors */ flag = Ent(y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 10711b93e9..ac83148587 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3102,7 +3102,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, if (step_mem->explicit) { - for (j = 0; j < i; j++) + for (j = 0; j < i; j++) // for IMEX this might need to be <= i { cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; Xvecs[nvec] = step_mem->Fe[j]; @@ -3123,12 +3123,19 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); if (retval) return ARK_VECTOROP_ERR; + printf("z%d:\n", i); + N_VPrint(z_stage); + printf("f(z%d):\n", i); + N_VPrint(step_mem->Fi[i]); + /* Evaluate the Jacobian at z_i */ - retval = relax_jac_fn(z_stage, ark_mem->tempv2, ark_mem->user_data); + retval = relax_jac_fn(z_stage, J_relax, ark_mem->user_data); (*num_relax_jac_evals)++; if (retval < 0) { return ARK_RELAX_JAC_FAIL; } if (retval > 0) { return ARK_RELAX_JAC_RECV; } + sunrealtype dot, tmp; + /* Update estimate of relaxation function change */ if (step_mem->explicit && step_mem->implicit) { @@ -3144,9 +3151,13 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, } else if (step_mem->implicit) { - *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, - step_mem->Fi[i]); + dot = N_VDotProdLocal(J_relax, step_mem->Fi[i]); + tmp = step_mem->Bi->b[i] * dot; + *delta_e_out += tmp; } + printf("dot%d: %.16e\n", i, dot); + printf("b%d: %.16e\n", i, step_mem->Bi->b[i]); + printf("tmp%d: %.16e\n", i, *delta_e_out); } /* Ignore negative return for node-local vectors where this is a non-op */ diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 8239e31c66..ca827b6d91 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -423,6 +423,16 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, /* Initial guess for relaxation parameter */ relax_mem->relax_param = relax_mem->relax_param_prev; + printf("y_n:\n"); + N_VPrint(ark_mem->yn); + printf("direction:\n"); + N_VPrint(ark_mem->tempv1); + printf("eta_old: %.16e\n", relax_mem->e_old); + printf("eta_est: %.16e\n", relax_mem->delta_e); + sunrealtype tmp; + arkRelaxResidual(ONE, &tmp, ark_mem); + printf("r(1): %.16e\n", relax_mem->delta_e); + switch(relax_mem->solver) { case(ARK_RELAX_BRENT): @@ -439,6 +449,8 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, break; } + printf("gam: %.16e\n", relax_mem->relax_param); + /* Check for solver failure */ if (retval) { @@ -855,6 +867,9 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, N_VLinearSum(relax_val, ark_mem->ycur, (ONE - relax_val), ark_mem->yn, ark_mem->ycur); + printf("y_new:\n"); + N_VPrint(ark_mem->ycur); + #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "relaxation", From 259e1c42487367e7987f4f903290eaaf7c0e5092 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 10:50:00 -0700 Subject: [PATCH 056/111] Store stages for relaxation with implicit/IMEX methods Storing the stages (or computing the delta_e estimate along the way) is necesary to avoid inconsistencies between z_i, F(z_i), and J_relax(z_i) that arise from reconstructing stages from stored RHS values like with ERK methods. --- .../C_serial/ark_conserved_exp_entropy_ark.c | 5 +- src/arkode/arkode_arkstep.c | 85 +++++++++++++------ src/arkode/arkode_arkstep_impl.h | 1 + src/arkode/arkode_relaxation.c | 24 +++--- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index e3729621a2..d293cfb129 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -95,7 +95,7 @@ int main(int argc, char* argv[]) /* Initial and final times */ sunrealtype t0 = SUN_RCONST(0.0); - sunrealtype tf = SUN_RCONST(0.03); + sunrealtype tf = SUN_RCONST(5.0); /* Relative and absolute tolerances */ sunrealtype reltol = SUN_RCONST(1.0e-6); @@ -280,9 +280,6 @@ int main(int argc, char* argv[]) flag = ARKStepEvolve(arkode_mem, tf, y, &t, ARK_ONE_STEP); if (check_flag(flag, "ARKStepEvolve")) break; - printf("y_new (returned):\n"); - N_VPrint(y); - /* Output solution and errors */ flag = Ent(y, &ent, NULL); if (check_flag(flag, "Ent")) return 1; diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index ac83148587..b49720f14a 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -692,6 +692,15 @@ void ARKStepFree(void **arkode_mem) ark_mem->liw -= step_mem->stages; } + /* free stage vectors */ + if (step_mem->z != NULL) { + for(j=0; jstages; j++) + arkFreeVec(ark_mem, &step_mem->z[j]); + free(step_mem->z); + step_mem->z = NULL; + ark_mem->liw -= step_mem->stages; + } + /* free the reusable arrays for fused vector interface */ if (step_mem->cvals != NULL) { free(step_mem->cvals); @@ -1163,6 +1172,18 @@ int arkStep_Init(void* arkode_mem, int init_type) ark_mem->liw += step_mem->stages; /* pointers */ } + /* Allocate stage storage for relaxation with implicit/IMEX methods */ + if (ark_mem->relax_enabled && step_mem->implicit) + { + if (step_mem->z == NULL) + step_mem->z = (N_Vector *) calloc(step_mem->stages, sizeof(N_Vector)); + for (j = 0; j < step_mem->stages; j++) { + if (!arkAllocVec(ark_mem, ark_mem->ewt, &(step_mem->z[j]))) + return(ARK_MEM_FAIL); + } + ark_mem->liw += step_mem->stages; /* pointers */ + } + /* Allocate reusable arrays for fused vector operations */ step_mem->nfusedopvecs = 2 * step_mem->stages + 2 + step_mem->nforcing; if (step_mem->cvals == NULL) { @@ -1726,6 +1747,13 @@ int arkStep_TakeStep_Z(void* arkode_mem, realtype *dsmPtr, int *nflagPtr) } /* successful stage solve */ + + /* store stage (if necessary for relaxation) */ + if (ark_mem->relax_enabled && step_mem->implicit) + { + N_VScale(ONE, ark_mem->ycur, step_mem->z[is]); + } + /* store implicit RHS (value in Fi[is] is from preceding nonlinear iteration) */ if (step_mem->implicit) { @@ -3093,41 +3121,31 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, for (i = 0; i < step_mem->stages; i++) { - /* Construct stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ - nvec = 0; + if (step_mem->implicit) + { + /* Use stored stages */ + z_stage = step_mem->z[i]; + } + else + { + /* Reconstruct explicit stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] */ + nvec = 0; - cvals[nvec] = ONE; - Xvecs[nvec] = ark_mem->yn; - nvec++; + cvals[nvec] = ONE; + Xvecs[nvec] = ark_mem->yn; + nvec++; - if (step_mem->explicit) - { - for (j = 0; j < i; j++) // for IMEX this might need to be <= i + for (j = 0; j < i; j++) { cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; Xvecs[nvec] = step_mem->Fe[j]; nvec++; } - } - if (step_mem->implicit) - { - for (j = 0; j <= i; j++) - { - cvals[nvec] = ark_mem->h * step_mem->Bi->A[i][j]; - Xvecs[nvec] = step_mem->Fi[j]; - nvec++; - } + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); + if (retval) return ARK_VECTOROP_ERR; } - retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); - if (retval) return ARK_VECTOROP_ERR; - - printf("z%d:\n", i); - N_VPrint(z_stage); - printf("f(z%d):\n", i); - N_VPrint(step_mem->Fi[i]); - /* Evaluate the Jacobian at z_i */ retval = relax_jac_fn(z_stage, J_relax, ark_mem->user_data); (*num_relax_jac_evals)++; @@ -3155,16 +3173,27 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, tmp = step_mem->Bi->b[i] * dot; *delta_e_out += tmp; } - printf("dot%d: %.16e\n", i, dot); - printf("b%d: %.16e\n", i, step_mem->Bi->b[i]); - printf("tmp%d: %.16e\n", i, *delta_e_out); + /* printf("z%d:\n", i); */ + /* N_VPrint(z_stage); */ + /* printf("f(z%d):\n", i); */ + /* N_VPrint(step_mem->Fi[i]); */ + /* printf("deta:\n"); */ + /* N_VPrint(J_relax); */ + /* printf("dot%d: %.16e\n", i, dot); */ + /* printf("b%d: %.16e\n", i, step_mem->Bi->b[i]); */ + /* printf("b*dot%d: %.16e\n", i, tmp); */ + /* printf("est%d: %.16e\n", i, *delta_e_out); */ } /* Ignore negative return for node-local vectors where this is a non-op */ N_VDotProdMultiAllReduce(1, ark_mem->tempv2, delta_e_out); + /* printf("est_r: %.16e\n", *delta_e_out); */ + *delta_e_out *= ark_mem->h; + /* printf("dt*est: %.16e\n", *delta_e_out); */ + return ARK_SUCCESS; } diff --git a/src/arkode/arkode_arkstep_impl.h b/src/arkode/arkode_arkstep_impl.h index 9ab9c772b1..91ff0e6489 100644 --- a/src/arkode/arkode_arkstep_impl.h +++ b/src/arkode/arkode_arkstep_impl.h @@ -77,6 +77,7 @@ typedef struct ARKodeARKStepMemRec { /* ARK method storage and parameters */ N_Vector *Fe; /* explicit RHS at each stage */ N_Vector *Fi; /* implicit RHS at each stage */ + N_Vector *z; /* stages (for relaxation) */ N_Vector sdata; /* old stage data in residual */ N_Vector zpred; /* predicted stage solution */ N_Vector zcor; /* stage correction */ diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index ca827b6d91..c6a17db9a5 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -423,15 +423,15 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, /* Initial guess for relaxation parameter */ relax_mem->relax_param = relax_mem->relax_param_prev; - printf("y_n:\n"); - N_VPrint(ark_mem->yn); - printf("direction:\n"); - N_VPrint(ark_mem->tempv1); - printf("eta_old: %.16e\n", relax_mem->e_old); - printf("eta_est: %.16e\n", relax_mem->delta_e); - sunrealtype tmp; - arkRelaxResidual(ONE, &tmp, ark_mem); - printf("r(1): %.16e\n", relax_mem->delta_e); + /* printf("y_n:\n"); */ + /* N_VPrint(ark_mem->yn); */ + /* printf("direction:\n"); */ + /* N_VPrint(ark_mem->tempv1); */ + /* printf("eta_old: %.16e\n", relax_mem->e_old); */ + /* printf("eta_est: %.16e\n", relax_mem->delta_e); */ + /* sunrealtype tmp; */ + /* arkRelaxResidual(ONE, &tmp, ark_mem); */ + /* printf("r(1): %.16e\n", relax_mem->delta_e); */ switch(relax_mem->solver) { @@ -449,7 +449,7 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, break; } - printf("gam: %.16e\n", relax_mem->relax_param); + /* printf("gam: %.16e\n", relax_mem->relax_param); */ /* Check for solver failure */ if (retval) @@ -867,8 +867,8 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, N_VLinearSum(relax_val, ark_mem->ycur, (ONE - relax_val), ark_mem->yn, ark_mem->ycur); - printf("y_new:\n"); - N_VPrint(ark_mem->ycur); + /* printf("y_new:\n"); */ + /* N_VPrint(ark_mem->ycur); */ #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, From e0a0995fd5ea9075061d80f73ce777f15c13d5c0 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 11:24:41 -0700 Subject: [PATCH 057/111] add comment about storing stages --- src/arkode/arkode_arkstep.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index b49720f14a..2c618188f2 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3090,6 +3090,12 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) * * Computes the change in the relaxation functions for use in relaxation methods * delta_e = h * sum_i b_i * + * + * With implicit and IMEX methods it is necessary to storing the method stages + * (or computing the delta_e estimate along the way) to avoid inconsistencies + * between z_i, F(z_i), and J_relax(z_i) that arise from reconstructing stages + * from stored RHS values like with ERK methods. As such the take step function + * stores the stages along the way but only when there is an implicit RHS. * ---------------------------------------------------------------------------*/ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, From bfe5613463030573b2621334432dc61aa305bf9f Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 11:29:16 -0700 Subject: [PATCH 058/111] remove some debugging output --- src/arkode/arkode_arkstep.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 2c618188f2..079ba52e90 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3158,8 +3158,6 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, if (retval < 0) { return ARK_RELAX_JAC_FAIL; } if (retval > 0) { return ARK_RELAX_JAC_RECV; } - sunrealtype dot, tmp; - /* Update estimate of relaxation function change */ if (step_mem->explicit && step_mem->implicit) { @@ -3175,31 +3173,16 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, } else if (step_mem->implicit) { - dot = N_VDotProdLocal(J_relax, step_mem->Fi[i]); - tmp = step_mem->Bi->b[i] * dot; - *delta_e_out += tmp; - } - /* printf("z%d:\n", i); */ - /* N_VPrint(z_stage); */ - /* printf("f(z%d):\n", i); */ - /* N_VPrint(step_mem->Fi[i]); */ - /* printf("deta:\n"); */ - /* N_VPrint(J_relax); */ - /* printf("dot%d: %.16e\n", i, dot); */ - /* printf("b%d: %.16e\n", i, step_mem->Bi->b[i]); */ - /* printf("b*dot%d: %.16e\n", i, tmp); */ - /* printf("est%d: %.16e\n", i, *delta_e_out); */ + *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, + step_mem->Fi[i]); + } } /* Ignore negative return for node-local vectors where this is a non-op */ - N_VDotProdMultiAllReduce(1, ark_mem->tempv2, delta_e_out); - - /* printf("est_r: %.16e\n", *delta_e_out); */ + N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); *delta_e_out *= ark_mem->h; - /* printf("dt*est: %.16e\n", *delta_e_out); */ - return ARK_SUCCESS; } From 94235223f548494e0526c41a269b0035c9825474 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 11:29:31 -0700 Subject: [PATCH 059/111] fix delta_e in ERKStep --- src/arkode/arkode_erkstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index c303b6ba25..adbf3ea66b 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1269,7 +1269,7 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, /* Ignore negative return for node-local vectors where this is a non-op */ N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); - delta_e_out[j] *= ark_mem->h; + *delta_e_out *= ark_mem->h; return ARK_SUCCESS; } From 365801dd6d3c41628ed7b154136d5ea5bf6abaa2 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 11:47:55 -0700 Subject: [PATCH 060/111] update table checks --- examples/arkode/CXX_serial/ark_pendulum.cpp | 6 +-- src/arkode/arkode_arkstep.c | 41 +++++++++++++-------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index ddd96cabef..825a1d01b0 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -172,9 +172,9 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetJacFn")) return 1; // Select a Butcher table with non-negative b values - // flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", - // "ARKODE_ERK_NONE"); - // if (check_flag(flag, "ARKStepSetTableName")) return 1; + flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + "ARKODE_ERK_NONE"); + if (check_flag(flag, "ARKStepSetTableName")) return 1; } if (fixed_h > SUN_RCONST(0.0)) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 079ba52e90..246e97f1e0 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -2193,35 +2193,44 @@ int arkStep_CheckButcherTables(ARKodeMem ark_mem) } } - /* check if all b values are positive for relaxation */ + /* Check if the method is compatible with relaxation */ if (ark_mem->relax_enabled) { - okay = SUNTRUE; + if (step_mem->q < 2) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", + "arkStep_CheckButcherTables", + "The Butcher table(s) must be at least second order!"); + return ARK_INVALID_TABLE; + } + if (step_mem->explicit) { + /* Check if all b values are positive */ for (i = 0; i < step_mem->stages; i++) - if (step_mem->Be->b[i] < ZERO) - okay = SUNFALSE; - if (!okay) { - arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", - "arkStep_CheckButcherTables", - "The explicit Butcher table has a negative b value!"); - return ARK_INVALID_TABLE; + if (step_mem->Be->b[i] < ZERO) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", + "arkStep_CheckButcherTables", + "The explicit Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } } } if (step_mem->implicit) { + /* Check if all b values are positive */ for (i = 0; i < step_mem->stages; i++) - if (step_mem->Bi->b[i] < ZERO) - okay = SUNFALSE; - if (!okay) { - arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", - "arkStep_CheckButcherTables", - "The implicit Butcher table has a negative b value!"); - return ARK_INVALID_TABLE; + if (step_mem->Bi->b[i] < ZERO) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ARKStep", + "arkStep_CheckButcherTables", + "The implicit Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } } } } From 8cdcf970212229bc162f88069b914bc0f36a7174 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 14:57:36 -0700 Subject: [PATCH 061/111] revise math docs --- doc/arkode/guide/source/Mathematics.rst | 59 ++++++++++++------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 5b47a95669..aedf67b54c 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2080,46 +2080,45 @@ strategies as discussed in :numref:`ARKODE.Usage.ARKStep.Tolerances` and Relaxation Methods ================== -For cases where the problem :eq:`ARKODE_IVP` is dissipative or conservative with -respect to a smooth convex function :math:`\xi(y(t))`, it is desirable to ensure -this property is preserved by the numerical method applied to the IVP. That is -:math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative problems and -:math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems. +For cases where the problem :eq:`ARKODE_IVP` is conservative or dissipative with +respect to a smooth convex function :math:`\xi(y(t))`, it is desirable to have +the numerical method preserve these properties. That is +:math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems +and :math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative problems. To this end, +ARKODE supports relaxation methods +:cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` to +ensure dissipation or preservation of a global function. -To this end, ARKODE supports relaxation methods :cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` -to guarantee the dissipation or preservation of a global function. Given a -second order method with :math:`b^E_i \geq 0` and :math:`b^I_i \geq 0`, this is -achieved by solving the auxiliary scalar nonlinear system +Relaxation methods compute a new solution .. math:: - F(r) = \xi(y_{n-1} + r d) - \xi(y_{n-1}) - r e = 0 - :label: ARKODE_RELAX_NLS + y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} + :label: ARKODE_RELAX_SOL -for the relaxation factor :math:`r` at the end of each time step. The update -direction is :math:`d = h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` -and the estimate of the change in :math:`\xi` is -:math:`e = h_n \sum_{i=1}^{s} \langle \xi'(z_i), b^E_i f^E_i + b^I_i f^I_i \rangle` -where :math:`\xi'` is the Jacobian of :math:`\xi`. The relaxed solution is then -given by +where :math:`d \equiv h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` is the update +direction and the relaxation factor, :math:`r`, is selected to ensure +conservation or dissipation. Given a second order method with +:math:`b^E_i \geq 0` and :math:`b^I_i \geq 0`, the factor :math:`r` is computed +by solving the auxiliary scalar nonlinear system .. math:: - y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} - :label: ARKODE_RELAX_SOL + F(r) = \xi(y_{n-1} + r d) - \xi(y_{n-1}) - r e = 0 + :label: ARKODE_RELAX_NLS -Currently, the nonlinear system :eq:`ARKODE_RELAX_NLS` can be solved using a -fixed point or Newton iteration. Should this iteration fail to meet the -residual tolerance in the maximum allowed number of iterations, the step size -will be reduced by the factor :math:`\eta_\text{rf}` (default 0.25). -Additionally, a relaxation value greater than :math:`r_\text{max}` (default 0.8) -or less than :math:`r_\text{min}` (default 1.2) will result in a solver failure +at the end of each time step. The estimated change in :math:`\xi` is given by +:math:`e \equiv h_n \sum_{i=1}^{s} \langle \xi'(z_i), b^E_i f^E_i + b^I_i f^I_i \rangle` +where :math:`\xi'` is the Jacobian of :math:`\xi`. + +By default the nonlinear system :eq:`ARKODE_RELAX_NLS` is solved using Newton +iteration. Optionally, a fixed-point iteration of Brent's method can be +utilized. If this iteration fail to meet the specified tolerances in the +maximum allowed number of iterations, the step size is reduced by the factor +:math:`\eta_\text{rf}` (default 0.25) and the step is repeated. Additionally, a +relaxation value greater than :math:`r_\text{max}` (default 0.8) or less than +:math:`r_\text{min}` (default 1.2), will be considered as a failed solve and the and the step will be repeated with the step size reduced by :math:`\eta_\text{rf}`. -In the case where there are multiple functions :math:`\xi_i(y)` of interest that -do not need to be conserved but may also be dissipated, ARKODE will compute the -relaxation values for each function and select :math:`r = \min_i r_i`. As a -result each :math:`\xi_i(y)` will be dissipated. - For more information on utilizing relaxation Runge-Kutta methods, see :numref:`ARKODE.Usage.ERKStep.Relaxation` and :numref:`ARKODE.Usage.ARKStep.Relaxation`. From 40b390379ce7d02be46b864d6805f783c66f5bfd Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 15:31:26 -0700 Subject: [PATCH 062/111] revise usage docs --- .../Usage/ARKStep_c_interface/Relaxation.rst | 58 +++++++++++++------ .../Usage/ERKStep_c_interface/Relaxation.rst | 58 +++++++++++++------ 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index f124147ebe..93074e8499 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -24,18 +24,16 @@ with ARKStep. For more information on relaxation Runge-Kutta methods see Enabling or Disabling Relaxation -------------------------------- -.. c:function:: int ARKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac) +.. c:function:: int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) Attaches the user supplied functions for evaluating the relaxation function - (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation - functions (``nrfn``). + (``rfn``) and its Jacobian (``rjac``). :param arkode_mem: the ARKStep memory structure - :param nrfn: the number of relaxation functions :param rfn: the user-defined function to compute the relaxation function - :math:`\xi_i(y)` + :math:`\xi(y)` :param rjac: the user-defined function to compute the relaxation Jacobian - :math:`\xi'_i(y)` + :math:`\xi'(y)` :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -45,7 +43,7 @@ Enabling or Disabling Relaxation .. note:: - If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. + If both ``rfn = rjac = NULL`` relaxation is disabled. .. versionadded:: 5.6.0 @@ -109,10 +107,11 @@ method. Sets the maximum number of nonlinear iterations allowed when solving for the relaxation parameter. If the maximum number of iterations is reached before - meeting the solve tolerance (determined by :c:func:`ARKStepSetRelaxTol`), the - step will be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is 5. Input values - :math:`\leq 0` will result in the default value being used. + meeting the solve tolerance (determined by :c:func:`ARKStepSetRelaxResTol` + and :c:func:`ARKStepSetRelaxTol`), the step will be repeated with a smaller + step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). The default + value is 10. Input values :math:`\leq 0` will result in the default value + being used. :param arkode_mem: the ARKStep memory structure :param max_iters: the maximum number of solver iterations allowed @@ -130,7 +129,8 @@ method. The default value is ``ARK_RELAX_NEWTON``. :param arkode_mem: the ARKStep memory structure - :param solver: the nonlinear solver to use + :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT``, + ``ARK_RELAX_NEWTON``, or ``ARK_RELAX_FIXEDPOINT`` :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -139,17 +139,41 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +.. c:function:: int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) - Sets the nonlinear solver tolerance to use when computing the relaxation - parameter. If the tolerance is not reached within the maximum number of + Sets the nonlinear solver residual tolerance to use when computing the + relaxation parameter. If the residual or solution tolerance (see + :c:func:`ARKStepSetRelaxMaxIter`) is not reached within the maximum number of iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is 1.0e-14. Input values + :c:func:`ARKStepSetRelaxEtaFail`). The default value is :math:`4 \epsilon` + where :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` will result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param tol: the nonlinear solver tolerance to use + :param tol: the nonlinear solver residual tolerance to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 + +.. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) + + Sets the nonlinear solver relative and absolute tolerance on :math:`r`. If + the residual or solution tolerance is not reached within the maximum + number of iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the + step will be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default relative and absolute + tolerances are :math:`4 \epsilon` and :math:`10^{-14}`, respectively, where + :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` + will result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param tol: the nonlinear solver relative solution tolerance to use + :param tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index f2110820c6..d16a016849 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -24,18 +24,16 @@ with ERKStep. For more information on relaxation Runge-Kutta methods see Enabling or Disabling Relaxation -------------------------------- -.. c:function:: int ERKStepSetRelaxFn(void* arkode_mem, int nrfn, ARKRelaxFn rfn, ARKRelaxJacFn rjac) +.. c:function:: int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) Attaches the user supplied functions for evaluating the relaxation function - (``rfn``) and its Jacobian (``rjac``) and specifies the number of relaxation - functions (``nrfn``). + (``rfn``) and its Jacobian (``rjac``). :param arkode_mem: the ERKStep memory structure - :param nrfn: the number of relaxation functions :param rfn: the user-defined function to compute the relaxation function - :math:`\xi_i(y)` + :math:`\xi(y)` :param rjac: the user-defined function to compute the relaxation Jacobian - :math:`\xi'_i(y)` + :math:`\xi'(y)` :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -45,7 +43,7 @@ Enabling or Disabling Relaxation .. note:: - If ``nrfn = 0`` and both ``rfn = rjac = NULL`` relaxation is disabled. + If both ``rfn = rjac = NULL`` relaxation is disabled. .. versionadded:: 5.6.0 @@ -109,10 +107,11 @@ method. Sets the maximum number of nonlinear iterations allowed when solving for the relaxation parameter. If the maximum number of iterations is reached before - meeting the solve tolerance (determined by :c:func:`ERKStepSetRelaxTol`), the - step will be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default value is 5. Input values - :math:`\leq 0` will result in the default value being used. + meeting the solve tolerance (determined by :c:func:`ERKStepSetRelaxResTol` + and :c:func:`ERKStepSetRelaxTol`), the step will be repeated with a smaller + step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). The default + value is 10. Input values :math:`\leq 0` will result in the default value + being used. :param arkode_mem: the ERKStep memory structure :param max_iters: the maximum number of solver iterations allowed @@ -130,7 +129,8 @@ method. The default value is ``ARK_RELAX_NEWTON``. :param arkode_mem: the ERKStep memory structure - :param solver: the nonlinear solver to use + :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT``, + ``ARK_RELAX_NEWTON``, or ``ARK_RELAX_FIXEDPOINT`` :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -139,17 +139,41 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype tol) +.. c:function:: int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) - Sets the nonlinear solver tolerance to use when computing the relaxation - parameter. If the tolerance is not reached within the maximum number of + Sets the nonlinear solver residual tolerance to use when computing the + relaxation parameter. If the residual or solution tolerance (see + :c:func:`ERKStepSetRelaxMaxIter`) is not reached within the maximum number of iterations (determined by :c:func:`ERKStepSetRelaxMaxIters`), the step will be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default value is 1.0e-14. Input values + :c:func:`ERKStepSetRelaxEtaFail`). The default value is :math:`4 \epsilon` + where :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` will result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param tol: the nonlinear solver tolerance to use + :param tol: the nonlinear solver residual tolerance to use + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 + +.. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) + + Sets the nonlinear solver relative and absolute tolerance on :math:`r`. If + the residual or solution tolerance is not reached within the maximum + number of iterations (determined by :c:func:`ERKStepSetRelaxMaxIters`), the + step will be repeated with a smaller step size (determined by + :c:func:`ERKStepSetRelaxEtaFail`). The default relative and absolute + tolerances are :math:`4 \epsilon` and :math:`10^{-14}`, respectively, where + :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` + will result in the default value being used. + + :param arkode_mem: the ERKStep memory structure + :param tol: the nonlinear solver relative solution tolerance to use + :param tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` From ae99a9377a1ad64abcc58d1680c04a233fff5d70 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 15:37:57 -0700 Subject: [PATCH 063/111] revise user supplied fn doc --- .../guide/source/Usage/User_supplied.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/arkode/guide/source/Usage/User_supplied.rst b/doc/arkode/guide/source/Usage/User_supplied.rst index a0fce06ce9..9a5c83be79 100644 --- a/doc/arkode/guide/source/Usage/User_supplied.rst +++ b/doc/arkode/guide/source/Usage/User_supplied.rst @@ -63,9 +63,9 @@ The user-supplied functions for ARKODE consist of: by the outer integrator to the inner integrator, or state data supplied by the inner integrator to the outer integrator. -* if relaxation is enabled (optional), a function that evaluates the dissipative - or conservative functions :math:`\xi_i(y(t))` (required) and a function to - evaluate the Jacobians :math:`\xi_i'(y(t))` (required). +* if relaxation is enabled (optional), a function that evaluates the + conservative or dissipative function :math:`\xi(y(t))` (required) and a + function to evaluate its Jacobian :math:`\xi'(y(t))` (required). .. _ARKODE.Usage.ODERHS: @@ -1124,14 +1124,14 @@ outer integrator for the outer integration. Relaxation function ------------------- -.. c:type:: int (*ARKRelaxFn)(N_Vector* y, realtype* r, void* user_data) +.. c:type:: int (*ARKRelaxFn)(N_Vector y, realtype* r, void* user_data) When applying relaxation, an :c:func:`ARKRelaxFn` function is required to - compute the dissipative or conservative functions :math:`\xi_i(y)`. + compute the conservative or dissipative function :math:`\xi(y)`. **Arguments:** * *y* -- the current value of the dependent variable vector. - * *r* -- the array of :math:`\xi_i(y)` values. + * *r* -- the value of :math:`\xi(y)`. * *user_data* -- the ``user_data`` pointer that was passed to :c:func:`ARKStepSetUserData`. @@ -1146,14 +1146,15 @@ Relaxation function Relaxation Jacobian function ---------------------------- -.. c:type:: int (*ARKRelaxJacFn)(N_Vector* y, N_Vector* J, void* user_data); +.. c:type:: int (*ARKRelaxJacFn)(N_Vector y, N_Vector J, void* user_data); When applying relaxation, an :c:func:`ARKRelaxJacFn` function is required to - computes the Jacobians :math:`\xi'_i(y)`. + compute the Jacobian :math:`\xi'(y)` of the :c:func:`ARKRelaxFn` + :math:`\xi(y)`. **Arguments:** * *y* -- the current value of the dependent variable vector. - * *J* -- an array Jacobian vectors :math:`\xi'_i(y)`. + * *J* -- the Jacobian vector :math:`\xi'(y)`. * *user_data* -- the ``user_data`` pointer that was passed to :c:func:`ARKStepSetUserData`. From ed0e0399179e87f288f97bf9cca0ff749524d182 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 16:06:43 -0700 Subject: [PATCH 064/111] sync and clean up examples --- examples/arkode/CXX_serial/ark_pendulum.cpp | 3 --- examples/arkode/C_serial/CMakeLists.txt | 8 +++++++- .../C_serial/ark_conserved_exp_entropy_ark.c | 7 +++---- .../C_serial/ark_conserved_exp_entropy_erk.c | 7 +++---- .../C_serial/ark_dissipated_exp_entropy.c | 18 +++++++++++++++--- examples/utilities/example_utilities.h | 2 +- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index 825a1d01b0..0bafc6c059 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -146,9 +146,6 @@ int main(int argc, char* argv[]) // Enable relaxation methods flag = ARKStepSetRelaxFn(arkode_mem, Eng, JacEng); if (check_flag(flag, "ARKStepSetRelaxFn")) return 1; - - flag = ARKStepSetRelaxMaxIters(arkode_mem, 100); - if (check_flag(flag, "ARKStepSetRelaxMaxIters")) return 1; } SUNMatrix A = nullptr; diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 4dc7284151..7f6c865272 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -29,7 +29,8 @@ set(ARKODE_examples "ark_conserved_exp_entropy_ark\;1 0\;develop" "ark_conserved_exp_entropy_ark\;1 1\;develop" "ark_conserved_exp_entropy_erk\;1\;develop" - "ark_dissipated_exp_entropy\;0 1 0.1\;develop" + "ark_dissipated_exp_entropy\;1 0\;develop" + "ark_dissipated_exp_entropy\;1 1\;develop" "ark_heat1D\;\;develop" "ark_heat1D_adapt\;\;develop" "ark_KrylovDemo_prec\;\;exclude-single" @@ -207,6 +208,11 @@ if(BUILD_SUNLINSOL_SUPERLUMT) ANSWER_FILE ${example}.out EXAMPLE_TYPE ${example_type}) + # directories to include + target_include_directories(${example} + PRIVATE + ${PROJECT_SOURCE_DIR}/examples/utilities) + # libraries to link against target_link_libraries(${example} sundials_arkode diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index d293cfb129..145ac0fc60 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -192,10 +192,6 @@ int main(int argc, char* argv[]) ytdata = N_VGetArrayPointer(ytrue); if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; - /* Initial entropy */ - flag = Ent(y, &ent0, NULL); - if (check_flag(flag, "Ent")) return 1; - /* Initialize the ARKStep */ if (implicit) { @@ -259,6 +255,9 @@ int main(int argc, char* argv[]) t = t0; /* Output the initial condition and entropy */ + flag = Ent(y, &ent0, NULL); + if (check_flag(flag, "Ent")) return 1; + fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index eb56b7e645..0ee348328c 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -174,10 +174,6 @@ int main(int argc, char* argv[]) ytdata = N_VGetArrayPointer(ytrue); if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; - /* Initial entropy */ - flag = Ent(y, &ent0, NULL); - if (check_flag(flag, "Ent")) return 1; - /* Initialize the ERKStep */ arkode_mem = ERKStepCreate(f, t0, y, ctx); if (check_ptr(arkode_mem, "ERKStepCreate")) return 1; @@ -211,6 +207,9 @@ int main(int argc, char* argv[]) t = t0; /* Output the initial condition and entropy */ + flag = Ent(y, &ent0, NULL); + if (check_flag(flag, "Ent")) return 1; + fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index e8fb7182a3..2185f2f7c4 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -111,8 +111,9 @@ int main(int argc, char* argv[]) FILE* UFID; /* Command line options */ - int relax = 1; /* enable relaxation */ - int implicit = 1; /* implicit */ + int relax = 1; /* enable relaxation */ + int implicit = 1; /* implicit */ + sunrealtype fixed_h = SUN_RCONST(0.0); /* adaptive stepping */ /* -------------------- * * Output Problem Setup * @@ -120,6 +121,7 @@ int main(int argc, char* argv[]) if (argc > 1) relax = atoi(argv[1]); if (argc > 2) implicit = atoi(argv[2]); + if (argc > 3) fixed_h = atof(argv[3]); printf("\nDissipated Exponential Entropy problem:\n"); if (implicit) @@ -132,6 +134,10 @@ int main(int argc, char* argv[]) } printf(" reltol = %.1" ESYM "\n", reltol); printf(" abstol = %.1" ESYM "\n", abstol); + if (fixed_h > SUN_RCONST(0.0)) + { + printf(" fixed h = %.1" ESYM "\n", fixed_h); + } if (relax) { printf(" relaxation = ON\n"); @@ -206,11 +212,17 @@ int main(int argc, char* argv[]) if (check_flag(flag, "ARKStepSetJacFn")) return 1; /* Select a Butcher table with non-negative b values */ - flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + flag = ARKStepSetTableName(arkode_mem, "ARKODE_ARK2_DIRK_3_1_2", "ARKODE_ERK_NONE"); if (check_flag(flag, "ARKStepSetTableName")) return 1; } + if (fixed_h > SUN_RCONST(0.0)) + { + flag = ARKStepSetFixedStep(arkode_mem, fixed_h); + if (check_flag(flag, "ARKStepSetFixedStep")) return 1; + } + /* Open output stream for results, output comment line */ UFID = fopen("ark_dissipated_exp_entropy.txt", "w"); fprintf(UFID, "# vars: t u entropy u_err delta_entropy\n"); diff --git a/examples/utilities/example_utilities.h b/examples/utilities/example_utilities.h index 9ea9626b27..8651d5f3b4 100644 --- a/examples/utilities/example_utilities.h +++ b/examples/utilities/example_utilities.h @@ -11,7 +11,7 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * Utility functions for C++ examples + * Utility functions for C examples * ---------------------------------------------------------------------------*/ #include From e38231ff98f9674aaf02f366ac37390c6c735bfb Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 16:07:00 -0700 Subject: [PATCH 065/111] correct Norsett method --- examples/arkode/CXX_serial/ark_pendulum.cpp | 56 ++++++++++++--------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index 0bafc6c059..d32b404843 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -168,33 +168,43 @@ int main(int argc, char* argv[]) flag = ARKStepSetJacFn(arkode_mem, Jac); if (check_flag(flag, "ARKStepSetJacFn")) return 1; - // Select a Butcher table with non-negative b values - flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", - "ARKODE_ERK_NONE"); - if (check_flag(flag, "ARKStepSetTableName")) return 1; + if (fixed_h > SUN_RCONST(0.0)) + { + // 3rd-order SDIRK method of Norsett + ARKodeButcherTable B = ARKodeButcherTable_Alloc(2, SUNFALSE); + + const sunrealtype gamma = ((SUN_RCONST(3.0) + std::sqrt(SUN_RCONST(3.0))) + / SUN_RCONST(6.0)); + + B->A[0][0] = gamma; + B->A[1][0] = SUN_RCONST(1.0) - SUN_RCONST(2.0) * gamma; + B->A[1][1] = gamma; + + B->c[0] = gamma; + B->c[1] = SUN_RCONST(1.0) - gamma; + + B->b[0] = SUN_RCONST(0.5); + B->b[1] = SUN_RCONST(0.5); + + B->q = 3; + B->p = 0; + + flag = ARKStepSetTables(arkode_mem, 3, 0, B, nullptr); + if (check_flag(flag, "ARKStepSetTables")) return 1; + + ARKodeButcherTable_Free(B); + } + else + { + // Select a Butcher table with non-negative b values + flag = ARKStepSetTableName(arkode_mem, "ARKODE_SDIRK_2_1_2", + "ARKODE_ERK_NONE"); + if (check_flag(flag, "ARKStepSetTableName")) return 1; + } } if (fixed_h > SUN_RCONST(0.0)) { - // 3rd-order SDIRK method of Norsett - ARKodeButcherTable B = ARKodeButcherTable_Alloc(2, SUNFALSE); - - B->A[0][0] = std::sqrt(3.0)/6.0 + 0.5; - B->A[1][0] = -std::sqrt(3.0)/3.0; - B->A[1][1] = std::sqrt(3.0)/6.0 + 0.5; - - B->c[0] = 0.5; - B->c[1] = 0.5; - - B->b[0] = std::sqrt(3.0)/6.0 + 0.5; - B->b[1] = 0.5 - std::sqrt(3.0)/6.0; - - B->q = 3; - B->p = 0; - - flag = ARKStepSetTables(arkode_mem, 3, 0, B, nullptr); - if (check_flag(flag, "ARKStepSetTables")) return 1; - flag = ARKStepSetFixedStep(arkode_mem, fixed_h); if (check_flag(flag, "ARKStepSetFixedStep")) return 1; } From 0a30a27a193275801cb435c6cf60c4865b015d0f Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 16:18:13 -0700 Subject: [PATCH 066/111] remove new include --- src/arkode/arkode_arkstep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 246e97f1e0..f7e1952f96 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -22,7 +22,6 @@ #include "arkode_impl.h" #include "arkode_arkstep_impl.h" #include "arkode_interp_impl.h" -#include "sundials/sundials_nvector.h" #include #include From c3d0d8138b570dc53f75f43d6d059d4bd55199c7 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 16:18:28 -0700 Subject: [PATCH 067/111] update comment --- src/arkode/arkode_arkstep.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index f7e1952f96..6945e5657e 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3104,6 +3104,10 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) * between z_i, F(z_i), and J_relax(z_i) that arise from reconstructing stages * from stored RHS values like with ERK methods. As such the take step function * stores the stages along the way but only when there is an implicit RHS. + * + * When the low storage structure of methods can be exploited, computing the + * delta_e estimate along the way with explicit methods may be necessary to + * avoid storing additional RHS or stage values. * ---------------------------------------------------------------------------*/ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, From 43e2018bd5ee4a730b4a1bbf659e41659fa2a0a5 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 16:18:51 -0700 Subject: [PATCH 068/111] update ERK method check --- src/arkode/arkode_erkstep.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index adbf3ea66b..87945ecab6 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1064,17 +1064,24 @@ int erkStep_CheckButcherTable(ARKodeMem ark_mem) /* check if all b values are positive for relaxation */ if (ark_mem->relax_enabled) { - okay = SUNTRUE; - for (i = 0; i < step_mem->stages; i++) - if (step_mem->B->b[i] < ZERO) - okay = SUNFALSE; - if (!okay) + if (step_mem->q < 2) { arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ERKStep", - "erkStep_CheckButcherTable", - "The Butcher table has a negative b value!"); + "erkStep_CheckButcherTables", + "The Butcher table must be at least second order!"); return ARK_INVALID_TABLE; } + + for (i = 0; i < step_mem->stages; i++) + { + if (step_mem->B->b[i] < ZERO) + { + arkProcessError(ark_mem, ARK_INVALID_TABLE, "ARKODE::ERKStep", + "erkStep_CheckButcherTable", + "The Butcher table has a negative b value!"); + return ARK_INVALID_TABLE; + } + } } return(ARK_SUCCESS); From bb12a943c9cd1595e7180ba365798d50480edba5 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 17:04:48 -0700 Subject: [PATCH 069/111] update table of constants --- doc/arkode/guide/source/Constants.rst | 24 ++++++++++++++++++++++++ include/arkode/arkode.h | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/arkode/guide/source/Constants.rst b/doc/arkode/guide/source/Constants.rst index 8558965ee4..a0f2d02c1a 100644 --- a/doc/arkode/guide/source/Constants.rst +++ b/doc/arkode/guide/source/Constants.rst @@ -62,6 +62,19 @@ contains the ARKODE output constants. +---------------------------------------------+-----------------------------------------------------------+ | | +---------------------------------------------+-----------------------------------------------------------+ + | **Relaxtion module input constants** | + +---------------------------------------------+-----------------------------------------------------------+ + | :index:`ARK_RELAX_BRENT` | Specifies Brent's method as the relaxation nonlinear | + | | solver. | + +---------------------------------------------+-----------------------------------------------------------+ + | :index:`ARK_RELAX_FIXEDPOINT` | Specifies the fixed-point iteration as the relaxation | + | | nonlinear solver. | + +---------------------------------------------+-----------------------------------------------------------+ + | :index:`ARK_RELAX_NEWTON` | Specifies Newton's method as the relaxation nonlinear | + | | solver. | + +---------------------------------------------+-----------------------------------------------------------+ + | | + +---------------------------------------------+-----------------------------------------------------------+ | **Explicit Butcher table specification** | +---------------------------------------------+-----------------------------------------------------------+ | :index:`ARKODE_HEUN_EULER_2_1_2` | Use the Heun-Euler-2-1-2 ERK method. | @@ -377,6 +390,17 @@ contains the ARKODE output constants. +-------------------------------------+------+------------------------------------------------------------+ | :index:`ARK_INVALID_TABLE` | -41 | An invalid Butcher or MRI table was encountered. | +-------------------------------------+------+------------------------------------------------------------+ + | :index:`ARK_CONTEXT_ERR` | -42 | | + +-------------------------------------+------+------------------------------------------------------------+ + | :index:`ARK_RELAX_FAIL` | -43 | An error occurred in computing the relaxation parameter | + +-------------------------------------+------+------------------------------------------------------------+ + | :index:`ARK_RELAX_MEM_FAIL` | -44 | The relaxation memory structure is ``NULL`` | + +-------------------------------------+------+------------------------------------------------------------+ + | :index:`ARK_RELAX_FUNC_FAIL` | -45 | The relaxation function returned an unrecoverable error | + +-------------------------------------+------+------------------------------------------------------------+ + | :index:`ARK_RELAX_JAC_FAIL` | -46 | The relaxation Jacobian function returned an unrecoverable | + | | | error | + +-------------------------------------+------+------------------------------------------------------------+ | :index:`ARK_UNRECOGNIZED_ERROR` | -99 | An unknown error was encountered. | +-------------------------------------+------+------------------------------------------------------------+ | | diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index 60b5c77a66..f393554ea2 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -192,8 +192,8 @@ typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; typedef enum { ARK_RELAX_BRENT, - ARK_RELAX_NEWTON, - ARK_RELAX_FIXEDPOINT + ARK_RELAX_FIXEDPOINT, + ARK_RELAX_NEWTON } ARKRelaxSolver; #ifdef __cplusplus From 69cbd0083890c7746fb202cee70211aa992296c3 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 17:07:26 -0700 Subject: [PATCH 070/111] remove debugging output --- src/arkode/arkode_relaxation.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index c6a17db9a5..2498590f32 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -417,22 +417,12 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, retval = relax_mem->relax_fn(ark_mem->yn, &(relax_mem->e_old), ark_mem->user_data); relax_mem->num_relax_fn_evals++; - if (retval < 0) return ARK_RELAX_FUNC_FAIL; - if (retval > 0) return ARK_RELAX_FUNC_RECV; + if (retval < 0) { return ARK_RELAX_FUNC_FAIL; } + if (retval > 0) { return ARK_RELAX_FUNC_RECV; } /* Initial guess for relaxation parameter */ relax_mem->relax_param = relax_mem->relax_param_prev; - /* printf("y_n:\n"); */ - /* N_VPrint(ark_mem->yn); */ - /* printf("direction:\n"); */ - /* N_VPrint(ark_mem->tempv1); */ - /* printf("eta_old: %.16e\n", relax_mem->e_old); */ - /* printf("eta_est: %.16e\n", relax_mem->delta_e); */ - /* sunrealtype tmp; */ - /* arkRelaxResidual(ONE, &tmp, ark_mem); */ - /* printf("r(1): %.16e\n", relax_mem->delta_e); */ - switch(relax_mem->solver) { case(ARK_RELAX_BRENT): @@ -449,8 +439,6 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, break; } - /* printf("gam: %.16e\n", relax_mem->relax_param); */ - /* Check for solver failure */ if (retval) { @@ -467,7 +455,9 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, /* Check for bad relaxation value */ if (ark_mem->relax_mem->relax_param < relax_mem->lower_bound || ark_mem->relax_mem->relax_param > relax_mem->upper_bound) + { return ARK_RELAX_SOLVE_RECV; + } /* Save parameter for next initial guess */ relax_mem->relax_param_prev = relax_mem->relax_param; @@ -867,9 +857,6 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, N_VLinearSum(relax_val, ark_mem->ycur, (ONE - relax_val), ark_mem->yn, ark_mem->ycur); - /* printf("y_new:\n"); */ - /* N_VPrint(ark_mem->ycur); */ - #if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, "ARKODE::arkStep_TakeStep_Z", "relaxation", From 229c0d01b9d7a4dec3901cd2625c42a581eafb6c Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 18:00:16 -0700 Subject: [PATCH 071/111] reduce example output --- examples/arkode/CXX_serial/ark_pendulum.cpp | 35 ++++++++++++------- .../C_serial/ark_conserved_exp_entropy_ark.c | 32 ++++++++++------- .../C_serial/ark_conserved_exp_entropy_erk.c | 32 ++++++++++------- .../C_serial/ark_dissipated_exp_entropy.c | 28 +++++++++------ 4 files changed, 77 insertions(+), 50 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index d32b404843..1aee60b398 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -23,7 +23,7 @@ * du/dt = -sin(v) * dv/dt = u * - * for t in the interval [0, 1000] with the initial condition y0 = [1.5 1.0]^T. + * for t in the interval [0, 10] with the initial condition y0 = [1.5 1.0]^T. * The conserved energy and its Jacobian for the system are * * e(y) = 0.5 u^2 - cos(v) and e'(y) = [u, sin(v)]^T @@ -80,7 +80,7 @@ int main(int argc, char* argv[]) // Initial and final times sunrealtype t0 = SUN_RCONST(0.0); - sunrealtype tf = SUN_RCONST(1000.0); + sunrealtype tf = SUN_RCONST(10.0); // Relative and absolute tolerances sunrealtype reltol = SUN_RCONST(1.0e-6); @@ -224,17 +224,17 @@ int main(int argc, char* argv[]) outfile << t << " " << ydata[0] << " " << ydata[1] << " " << eng0 << " " << SUN_RCONST(0.0) << std::endl; - std::cout << std::setw(24) << "t" << std::setw(24) << "u" << std::setw(24) - << "v" << std::setw(24) << "e" << std::setw(24) << "e err" - << std::endl; + std::cout << std::setw(5) << "step" << std::setw(24) << "t" << std::setw(24) + << "u" << std::setw(24) << "v" << std::setw(24) << "e" + << std::setw(24) << "e err" << std::endl; for (int i = 0; i < 9; i++) std::cout << "--------------"; std::cout << std::endl; std::cout << std::scientific; std::cout << std::setprecision(std::numeric_limits::digits10); - std::cout << std::setw(24) << t << std::setw(24) << ydata[0] << std::setw(24) - << ydata[1] << std::setw(24) << eng0 << std::setw(24) - << SUN_RCONST(0.0); + std::cout << std::setw(5) << 0 << std::setw(24) << t << std::setw(24) + << ydata[0] << std::setw(24) << ydata[1] << std::setw(24) << eng0 + << std::setw(24) << SUN_RCONST(0.0); std::cout << std::endl; while (t < tf) @@ -250,13 +250,22 @@ int main(int argc, char* argv[]) sunrealtype eng_chng = eng - eng0; + /* Output to the screen every periodically */ + long int nst; + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + + if (nst % 1000 == 0) + { + std::cout << std::setw(5) << nst << std::setw(24) << t << std::setw(24) + << ydata[0] << std::setw(24) << ydata[1] << std::setw(24) << eng + << std::setw(24) << eng_chng << std::endl; + } + + /* Write all steps to file */ outfile << t << " " << ydata[0] << " " << ydata[1] << " " << eng << " " << eng_chng << std::endl; - - std::cout << std::setw(24) << t << std::setw(24) << ydata[0] - << std::setw(24) << ydata[1] << std::setw(24) << eng - << std::setw(24) << eng_chng << std::endl; - } + } for (int i = 0; i < 9; i++) std::cout << "--------------"; std::cout << std::endl; diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 145ac0fc60..2a94ac3181 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -264,14 +264,13 @@ int main(int argc, char* argv[]) t0, ydata[0], ydata[1], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0), SUN_RCONST(0.0)); - printf(" t u v e " - "delta e\n"); - printf(" " - "---------------------------------------------------------------------" - "---\n"); - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + printf(" step t u v e " + " delta e\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); + printf("%5d %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", - t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); + 0, t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); while (t < tf) { @@ -290,19 +289,26 @@ int main(int argc, char* argv[]) u_err = ydata[0] - ytdata[0]; v_err = ydata[1] - ytdata[1]; - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM - "\n", - t, ydata[0], ydata[1], ent, ent_err); + /* Output to the screen every periodically */ + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + if (nst % 40 == 0) + { + printf("%5ld %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + nst, t, ydata[0], ydata[1], ent, ent_err); + } + + /* Write all steps to file */ fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); } - printf(" " - "---------------------------------------------------------------------" - "---\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); fclose(UFID); /* ------------ * diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index 0ee348328c..9071f7218a 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -216,14 +216,13 @@ int main(int argc, char* argv[]) t0, ydata[0], ydata[1], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0), SUN_RCONST(0.0)); - printf(" t u v e " - "delta e\n"); - printf(" " - "---------------------------------------------------------------------" - "---\n"); - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + printf(" step t u v e " + " delta e\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); + printf("%5d %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", - t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); + 0, t, ydata[0], ydata[1], ent0, SUN_RCONST(0.0)); while (t < tf) { @@ -242,19 +241,26 @@ int main(int argc, char* argv[]) u_err = ydata[0] - ytdata[0]; v_err = ydata[1] - ytdata[1]; - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM - "\n", - t, ydata[0], ydata[1], ent, ent_err); + /* Output to the screen every periodically */ + flag = ERKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ERKStepGetNumSteps"); + if (nst % 40 == 0) + { + printf("%5ld %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM + "\n", + nst, t, ydata[0], ydata[1], ent, ent_err); + } + + /* Write all steps to file */ fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ydata[1], ent, u_err, v_err, ent_err); } - printf(" " - "---------------------------------------------------------------------" - "---\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); fclose(UFID); /* ------------ * diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index 2185f2f7c4..d2733f6049 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -242,12 +242,11 @@ int main(int argc, char* argv[]) "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t0, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); - printf(" t u e delta e\n"); - printf(" " - "---------------------------------------------------------------------" - "---\n"); - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", - t, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); + printf(" step t u e u_err delta e\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); + printf("%5d %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", + 0, t, ydata[0], ent0, SUN_RCONST(0.0), SUN_RCONST(0.0)); while (t < tf) { @@ -265,17 +264,24 @@ int main(int argc, char* argv[]) delta_ent = ent - ent0; u_err = ydata[0] - ytdata[0]; - printf(" %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.16" ESYM " %14.6" ESYM "\n", - t, ydata[0], ent, u_err, delta_ent); + /* Output to the screen every periodically */ + flag = ARKStepGetNumSteps(arkode_mem, &nst); + check_flag(flag, "ARKStepGetNumSteps"); + if (nst % 40 == 0) + { + printf("%5ld %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM " %14.6" ESYM "\n", + nst, t, ydata[0], ent, u_err, delta_ent); + } + + /* Write all steps to file */ fprintf(UFID, "%23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM " %23.16" ESYM "\n", t, ydata[0], ent, u_err, delta_ent); } - printf(" " - "---------------------------------------------------------------------" - "---\n"); + printf(" --------------------------------------------------------------------" + "-----------\n"); fclose(UFID); /* ------------ * From f691c6562c5c22ebeb4f9c3caa4ea49627dc762c Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 18:21:14 -0700 Subject: [PATCH 072/111] return error if relaxation + deduce implicit RHS --- src/arkode/arkode_arkstep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 6945e5657e..5febd833b7 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -1148,6 +1148,14 @@ int arkStep_Init(void* arkode_mem, int init_type) return(ARK_ILL_INPUT); } + /* Relaxation is incompatible with implicit RHS deduction */ + if (ark_mem->relax_enabled && step_mem->implicit && step_mem->deduce_rhs) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE::ARKStep", + "arkStep_Init", "Relaxation cannot be performed when deducing implicit RHS values"); + return ARK_ILL_INPUT; + } + /* Allocate ARK RHS vector memory, update storage requirements */ /* Allocate Fe[0] ... Fe[stages-1] if needed */ if (step_mem->explicit) { From 64dbe25dfdd8a8883580f218209ef8d73fe09b81 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 18:39:51 -0700 Subject: [PATCH 073/111] add example .out files --- examples/arkode/CXX_serial/ark_pendulum.out | 34 +++++++++++ .../ark_conserved_exp_entropy_ark_1_0.out | 24 ++++++++ .../ark_conserved_exp_entropy_ark_1_1.out | 52 +++++++++++++++++ .../ark_conserved_exp_entropy_erk_1.out | 24 ++++++++ .../ark_dissipated_exp_entropy_1_0.out | 25 ++++++++ .../ark_dissipated_exp_entropy_1_1.out | 58 +++++++++++++++++++ 6 files changed, 217 insertions(+) create mode 100644 examples/arkode/CXX_serial/ark_pendulum.out create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out create mode 100644 examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out create mode 100644 examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out create mode 100644 examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out diff --git a/examples/arkode/CXX_serial/ark_pendulum.out b/examples/arkode/CXX_serial/ark_pendulum.out new file mode 100644 index 0000000000..7d88b055f1 --- /dev/null +++ b/examples/arkode/CXX_serial/ark_pendulum.out @@ -0,0 +1,34 @@ +Nonlinear Pendulum problem: + method = DIRK + relaxation = ON + reltol = 1e-06 + abstol = 1e-10 + + step t u v e e err +------------------------------------------------------------------------------------------------------------------------------ + 0 0.000000000000000e+00 1.500000000000000e+00 1.000000000000000e+00 5.846976941318602e-01 0.000000000000000e+00 + 1000 1.226511879534299e+00 3.458488320982976e-01 2.123384535074106e+00 5.846976941318555e-01 -4.773959005888173e-15 + 2000 2.398784336118560e+00 -6.416442371616857e-01 1.959343228667432e+00 5.846976941318377e-01 -2.253752739989068e-14 + 3000 3.618483293504332e+00 -1.718124366999066e+00 4.706406225355917e-01 5.846976941318435e-01 -1.676436767183986e-14 + 4000 4.580865391430372e+00 -1.411700239944070e+00 -1.146421559917496e+00 5.846976941318369e-01 -2.331468351712829e-14 + 5000 5.877850661141863e+00 -2.026377125271683e-01 -2.170219947005763e+00 5.846976941318408e-01 -1.942890293094024e-14 + 6000 7.079795692175875e+00 8.320973704310155e-01 -1.811622127832077e+00 5.846976941318234e-01 -3.685940441755520e-14 + 7000 8.313428698722841e+00 1.777791699609239e+00 -9.412012907795819e-02 5.846976941318288e-01 -3.141931159689193e-14 + 8000 9.289846347799413e+00 1.192220279192671e+00 1.444463648145965e+00 5.846976941318289e-01 -3.130828929442941e-14 +------------------------------------------------------------------------------------------------------------------------------ + +Final Solver Statistics: + Internal solver steps = 8518 (attempted = 8528) + Total number of error test failures = 10 + Total RHS evals: Fe = 0, Fi = 50909 + Total number of Newton iterations = 25332 + Total number of linear solver convergence failures = 5 + Total linear solver setups = 459 + Total number of Jacobian evaluations = 146 + Total RHS evals for setting up the linear system = 0 + Total Relaxation fails = 0 + Total Relaxation Fn evals = 25494 + Total Relaxation Jac evals = 25494 + Total Relaxation NLS iters = 8438 + Total Relaxation NLS fails = 0 + diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out new file mode 100644 index 0000000000..09a30c1559 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out @@ -0,0 +1,24 @@ + +Conserved Exponential Entropy problem: + method = ERK + reltol = 1.0e-06 + abstol = 1.0e-10 + relaxation = ON + + step t u v e delta e + ------------------------------------------------------------------------------- + 0 0.000000e+00 1.000000e+00 5.000000e-01 4.367003e+00 0.000000e+00 + 40 6.911091e-01 -1.121528e+00 1.396547e+00 4.367003e+00 -1.776357e-15 + 80 1.946408e+00 -6.526227e+00 1.473742e+00 4.367003e+00 4.440892e-15 + ------------------------------------------------------------------------------- + +Final Solver Statistics: + Internal solver steps = 99 (attempted = 124) + Total number of error test failures = 0 + Total RHS evals: Fe = 722, Fi = 0 + Total Relaxation fails = 25 + Total Relaxation Fn evals = 622 + Total Relaxation Jac evals = 1019 + Total Relaxation NLS iters = 399 + Total Relaxation NLS fails = 25 + diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out new file mode 100644 index 0000000000..6d4dfcbe07 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out @@ -0,0 +1,52 @@ + +Conserved Exponential Entropy problem: + method = DIRK + reltol = 1.0e-06 + abstol = 1.0e-10 + relaxation = ON + + step t u v e delta e + ------------------------------------------------------------------------------- + 0 0.000000e+00 1.000000e+00 5.000000e-01 4.367003e+00 0.000000e+00 + 40 4.754706e-02 9.164641e-01 6.241023e-01 4.367003e+00 8.881784e-16 + 80 8.098591e-02 8.514226e-01 7.050883e-01 4.367003e+00 0.000000e+00 + 120 1.285350e-01 7.498036e-01 8.111164e-01 4.367003e+00 1.776357e-15 + 160 1.711613e-01 6.495637e-01 8.970255e-01 4.367003e+00 8.881784e-16 + 200 2.117650e-01 5.461535e-01 9.709320e-01 4.367003e+00 5.329071e-15 + 240 2.453290e-01 4.549914e-01 1.026344e+00 4.367003e+00 0.000000e+00 + 280 2.845614e-01 3.421715e-01 1.084852e+00 4.367003e+00 1.776357e-15 + 320 3.187813e-01 2.385199e-01 1.130639e+00 4.367003e+00 1.776357e-15 + 360 3.470183e-01 1.495118e-01 1.164942e+00 4.367003e+00 4.440892e-15 + 400 3.679487e-01 8.161060e-02 1.188444e+00 4.367003e+00 1.776357e-15 + 440 3.849834e-01 2.519301e-02 1.206417e+00 4.367003e+00 7.105427e-15 + 480 3.919101e-01 1.965927e-03 1.213438e+00 4.367003e+00 3.552714e-15 + 520 3.949458e-01 -8.265002e-03 1.216465e+00 4.367003e+00 2.664535e-15 + 560 4.054406e-01 -4.387006e-02 1.226690e+00 4.367003e+00 -1.776357e-15 + 600 4.224627e-01 -1.023806e-01 1.242516e+00 4.367003e+00 0.000000e+00 + 640 4.483804e-01 -1.931947e-01 1.264884e+00 4.367003e+00 -1.776357e-15 + 680 4.858087e-01 -3.277677e-01 1.293760e+00 4.367003e+00 1.776357e-15 + 720 5.292378e-01 -4.885049e-01 1.322678e+00 4.367003e+00 -4.440892e-15 + 760 5.861685e-01 -7.057075e-01 1.354092e+00 4.367003e+00 -6.217249e-15 + 800 6.559300e-01 -9.802131e-01 1.384235e+00 4.367003e+00 -2.664535e-15 + 840 7.351394e-01 -1.300674e+00 1.409682e+00 4.367003e+00 8.881784e-16 + 880 8.653344e-01 -1.841818e+00 1.437100e+00 4.367003e+00 -8.881784e-16 + 920 1.014019e+00 -2.473635e+00 1.454590e+00 4.367003e+00 8.881784e-16 + 960 1.342023e+00 -3.891227e+00 1.469390e+00 4.367003e+00 3.552714e-15 + 1000 2.028294e+00 -6.883726e+00 1.473842e+00 4.367003e+00 5.329071e-15 + ------------------------------------------------------------------------------- + +Final Solver Statistics: + Internal solver steps = 1024 (attempted = 1376) + Total number of error test failures = 86 + Total RHS evals: Fe = 0, Fi = 9934 + Total number of Newton iterations = 5803 + Total number of linear solver convergence failures = 37 + Total linear solver setups = 844 + Total number of Jacobian evaluations = 304 + Total RHS evals for setting up the linear system = 0 + Total Relaxation fails = 266 + Total Relaxation Fn evals = 7023 + Total Relaxation Jac evals = 8651 + Total Relaxation NLS iters = 4523 + Total Relaxation NLS fails = 252 + diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out new file mode 100644 index 0000000000..9ac4f91736 --- /dev/null +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out @@ -0,0 +1,24 @@ + +Conserved Exponential Entropy problem: + method = ERK + reltol = 1.0e-06 + abstol = 1.0e-10 + relaxation = ON + + step t u v e delta e + ------------------------------------------------------------------------------- + 0 0.000000e+00 1.000000e+00 5.000000e-01 4.367003e+00 0.000000e+00 + 40 6.759227e-01 -1.060311e+00 1.391445e+00 4.367003e+00 -1.776357e-15 + 80 1.694830e+00 -5.428257e+00 1.473071e+00 4.367003e+00 -8.881784e-16 + ------------------------------------------------------------------------------- + +Final Solver Statistics: + Internal solver steps = 95 (attempted = 121) + Total number of error test failures = 2 + Total RHS evals = 582 + Total Relaxation fails = 24 + Total Relaxation Fn evals = 608 + Total Relaxation Jac evals = 995 + Total Relaxation NLS iters = 390 + Total Relaxation NLS fails = 24 + diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out new file mode 100644 index 0000000000..6a5121fb97 --- /dev/null +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out @@ -0,0 +1,25 @@ + +Dissipated Exponential Entropy problem: + method = ERK + reltol = 1.0e-06 + abstol = 1.0e-10 + relaxation = ON + + step t u e u_err delta e + ------------------------------------------------------------------------------- + 0 0.000000e+00 1.000000e+00 2.718282e+00 0.000000e+00 0.000000e+00 + 40 5.788604e-01 5.473125e-02 1.056257e+00 -1.153415e-01 -1.662025e+00 + 80 1.549362e+00 -6.508864e-01 5.215832e-01 -1.419091e+00 -2.196699e+00 + 120 5.112347e+00 -1.701137e+00 1.824759e-01 -3.444910e+00 -2.535806e+00 + ------------------------------------------------------------------------------- + +Final Solver Statistics: + Internal solver steps = 120 (attempted = 121) + Total number of error test failures = 1 + Total RHS evals: Fe = 728, Fi = 0 + Total Relaxation fails = 0 + Total Relaxation Fn evals = 478 + Total Relaxation Jac evals = 841 + Total Relaxation NLS iters = 236 + Total Relaxation NLS fails = 0 + diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out new file mode 100644 index 0000000000..16223e4509 --- /dev/null +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out @@ -0,0 +1,58 @@ + +Dissipated Exponential Entropy problem: + method = DIRK + reltol = 1.0e-06 + abstol = 1.0e-10 + relaxation = ON + + step t u e u_err delta e + ------------------------------------------------------------------------------- + 0 0.000000e+00 1.000000e+00 2.718282e+00 0.000000e+00 0.000000e+00 + 40 5.526158e-02 8.600499e-01 2.363279e+00 1.272854e+00 -3.550031e-01 + 80 1.093640e-01 7.397289e-01 2.095367e+00 1.073951e+00 -6.229145e-01 + 120 1.612130e-01 6.365925e-01 1.890030e+00 9.008919e-01 -8.282523e-01 + 160 2.201486e-01 5.309810e-01 1.700600e+00 7.213195e-01 -1.017682e+00 + 200 2.871668e-01 4.230499e-01 1.526610e+00 5.354378e-01 -1.191671e+00 + 240 3.512118e-01 3.297675e-01 1.390645e+00 3.729438e-01 -1.327637e+00 + 280 4.123793e-01 2.481302e-01 1.281627e+00 2.293969e-01 -1.436655e+00 + 320 4.706553e-01 1.760997e-01 1.192557e+00 1.017477e-01 -1.525725e+00 + 360 5.259422e-01 1.122496e-01 1.118792e+00 -1.215402e-02 -1.599490e+00 + 400 5.741445e-01 5.972517e-02 1.061545e+00 -1.063613e-01 -1.656737e+00 + 440 6.089411e-01 2.345290e-02 1.023730e+00 -1.716794e-01 -1.694552e+00 + 480 6.285201e-01 3.607534e-03 1.003614e+00 -2.075045e-01 -1.714668e+00 + 520 6.338452e-01 -1.722590e-03 9.982789e-01 -2.171370e-01 -1.720003e+00 + 560 6.445818e-01 -1.238363e-02 9.876927e-01 -2.364167e-01 -1.730589e+00 + 600 6.650292e-01 -3.237820e-02 9.681404e-01 -2.726226e-01 -1.750141e+00 + 640 6.961721e-01 -6.208318e-02 9.398047e-01 -3.265243e-01 -1.778477e+00 + 680 7.383329e-01 -1.009412e-01 9.039862e-01 -3.972338e-01 -1.814296e+00 + 720 7.935942e-01 -1.496889e-01 8.609758e-01 -4.862503e-01 -1.857306e+00 + 760 8.638045e-01 -2.083816e-01 8.118971e-01 -5.938720e-01 -1.906385e+00 + 800 9.507169e-01 -2.765670e-01 7.583828e-01 -7.194868e-01 -1.959899e+00 + 840 1.056126e+00 -3.534728e-01 7.022451e-01 -8.618895e-01 -2.016037e+00 + 880 1.183115e+00 -4.388956e-01 6.447481e-01 -1.020913e+00 -2.073534e+00 + 920 1.336064e+00 -5.329441e-01 5.868746e-01 -1.196969e+00 -2.131407e+00 + 960 1.525261e+00 -6.382359e-01 5.282234e-01 -1.395199e+00 -2.190058e+00 + 1000 1.757860e+00 -7.541178e-01 4.704255e-01 -1.614638e+00 -2.247856e+00 + 1040 2.039637e+00 -8.785936e-01 4.153667e-01 -1.851706e+00 -2.302915e+00 + 1080 2.390936e+00 -1.014799e+00 3.624754e-01 -2.112566e+00 -2.355806e+00 + 1120 2.828054e+00 -1.161876e+00 3.128987e-01 -2.395772e+00 -2.405383e+00 + 1160 3.358496e+00 -1.315431e+00 2.683586e-01 -2.692944e+00 -2.449923e+00 + 1200 4.027263e+00 -1.480493e+00 2.275254e-01 -3.013869e+00 -2.490756e+00 + 1240 4.854394e+00 -1.652924e+00 1.914892e-01 -3.350542e+00 -2.526793e+00 + ------------------------------------------------------------------------------- + +Final Solver Statistics: + Internal solver steps = 1246 (attempted = 1247) + Total number of error test failures = 1 + Total RHS evals: Fe = 0, Fi = 10714 + Total number of Newton iterations = 6970 + Total number of linear solver convergence failures = 125 + Total linear solver setups = 192 + Total number of Jacobian evaluations = 131 + Total RHS evals for setting up the linear system = 0 + Total Relaxation fails = 0 + Total Relaxation Fn evals = 4138 + Total Relaxation Jac evals = 5385 + Total Relaxation NLS iters = 1644 + Total Relaxation NLS fails = 0 + From 4717f4e5ae6d489cb6c87d78a4cea0907c6685a9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 21:02:22 -0700 Subject: [PATCH 074/111] update output for test machine --- .../ark_dissipated_exp_entropy_1_0.out | 18 ++-- .../ark_dissipated_exp_entropy_1_1.out | 82 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out index 6a5121fb97..b2c3a67e8d 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out @@ -8,18 +8,18 @@ Dissipated Exponential Entropy problem: step t u e u_err delta e ------------------------------------------------------------------------------- 0 0.000000e+00 1.000000e+00 2.718282e+00 0.000000e+00 0.000000e+00 - 40 5.788604e-01 5.473125e-02 1.056257e+00 -1.153415e-01 -1.662025e+00 - 80 1.549362e+00 -6.508864e-01 5.215832e-01 -1.419091e+00 -2.196699e+00 - 120 5.112347e+00 -1.701137e+00 1.824759e-01 -3.444910e+00 -2.535806e+00 + 40 4.675332e-01 1.798296e-01 1.197013e+00 1.083801e-01 -1.521269e+00 + 80 1.147092e+00 -4.153968e-01 6.600783e-01 -9.770808e-01 -2.058204e+00 + 120 3.654055e+00 -1.391763e+00 2.486366e-01 -2.841170e+00 -2.469645e+00 ------------------------------------------------------------------------------- Final Solver Statistics: - Internal solver steps = 120 (attempted = 121) - Total number of error test failures = 1 - Total RHS evals: Fe = 728, Fi = 0 + Internal solver steps = 130 (attempted = 130) + Total number of error test failures = 0 + Total RHS evals: Fe = 783, Fi = 0 Total Relaxation fails = 0 - Total Relaxation Fn evals = 478 - Total Relaxation Jac evals = 841 - Total Relaxation NLS iters = 236 + Total Relaxation Fn evals = 392 + Total Relaxation Jac evals = 782 + Total Relaxation NLS iters = 132 Total Relaxation NLS fails = 0 diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out index 16223e4509..fa719a264d 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out @@ -8,51 +8,51 @@ Dissipated Exponential Entropy problem: step t u e u_err delta e ------------------------------------------------------------------------------- 0 0.000000e+00 1.000000e+00 2.718282e+00 0.000000e+00 0.000000e+00 - 40 5.526158e-02 8.600499e-01 2.363279e+00 1.272854e+00 -3.550031e-01 - 80 1.093640e-01 7.397289e-01 2.095367e+00 1.073951e+00 -6.229145e-01 - 120 1.612130e-01 6.365925e-01 1.890030e+00 9.008919e-01 -8.282523e-01 - 160 2.201486e-01 5.309810e-01 1.700600e+00 7.213195e-01 -1.017682e+00 - 200 2.871668e-01 4.230499e-01 1.526610e+00 5.354378e-01 -1.191671e+00 - 240 3.512118e-01 3.297675e-01 1.390645e+00 3.729438e-01 -1.327637e+00 - 280 4.123793e-01 2.481302e-01 1.281627e+00 2.293969e-01 -1.436655e+00 - 320 4.706553e-01 1.760997e-01 1.192557e+00 1.017477e-01 -1.525725e+00 - 360 5.259422e-01 1.122496e-01 1.118792e+00 -1.215402e-02 -1.599490e+00 - 400 5.741445e-01 5.972517e-02 1.061545e+00 -1.063613e-01 -1.656737e+00 - 440 6.089411e-01 2.345290e-02 1.023730e+00 -1.716794e-01 -1.694552e+00 - 480 6.285201e-01 3.607534e-03 1.003614e+00 -2.075045e-01 -1.714668e+00 - 520 6.338452e-01 -1.722590e-03 9.982789e-01 -2.171370e-01 -1.720003e+00 - 560 6.445818e-01 -1.238363e-02 9.876927e-01 -2.364167e-01 -1.730589e+00 - 600 6.650292e-01 -3.237820e-02 9.681404e-01 -2.726226e-01 -1.750141e+00 - 640 6.961721e-01 -6.208318e-02 9.398047e-01 -3.265243e-01 -1.778477e+00 - 680 7.383329e-01 -1.009412e-01 9.039862e-01 -3.972338e-01 -1.814296e+00 - 720 7.935942e-01 -1.496889e-01 8.609758e-01 -4.862503e-01 -1.857306e+00 - 760 8.638045e-01 -2.083816e-01 8.118971e-01 -5.938720e-01 -1.906385e+00 - 800 9.507169e-01 -2.765670e-01 7.583828e-01 -7.194868e-01 -1.959899e+00 - 840 1.056126e+00 -3.534728e-01 7.022451e-01 -8.618895e-01 -2.016037e+00 - 880 1.183115e+00 -4.388956e-01 6.447481e-01 -1.020913e+00 -2.073534e+00 - 920 1.336064e+00 -5.329441e-01 5.868746e-01 -1.196969e+00 -2.131407e+00 - 960 1.525261e+00 -6.382359e-01 5.282234e-01 -1.395199e+00 -2.190058e+00 - 1000 1.757860e+00 -7.541178e-01 4.704255e-01 -1.614638e+00 -2.247856e+00 - 1040 2.039637e+00 -8.785936e-01 4.153667e-01 -1.851706e+00 -2.302915e+00 - 1080 2.390936e+00 -1.014799e+00 3.624754e-01 -2.112566e+00 -2.355806e+00 - 1120 2.828054e+00 -1.161876e+00 3.128987e-01 -2.395772e+00 -2.405383e+00 - 1160 3.358496e+00 -1.315431e+00 2.683586e-01 -2.692944e+00 -2.449923e+00 - 1200 4.027263e+00 -1.480493e+00 2.275254e-01 -3.013869e+00 -2.490756e+00 - 1240 4.854394e+00 -1.652924e+00 1.914892e-01 -3.350542e+00 -2.526793e+00 + 40 5.532834e-02 8.598921e-01 2.362906e+00 1.272595e+00 -3.553760e-01 + 80 1.097061e-01 7.390122e-01 2.093866e+00 1.072757e+00 -6.244157e-01 + 120 1.621192e-01 6.348810e-01 1.886798e+00 8.980007e-01 -8.314842e-01 + 160 2.128767e-01 5.434247e-01 1.721894e+00 7.425986e-01 -9.963881e-01 + 200 2.816359e-01 4.315291e-01 1.539610e+00 5.501251e-01 -1.178672e+00 + 240 3.484648e-01 3.335947e-01 1.395977e+00 3.796434e-01 -1.322305e+00 + 280 4.133160e-01 2.469303e-01 1.280090e+00 2.272780e-01 -1.438192e+00 + 320 4.764552e-01 1.692067e-01 1.184365e+00 8.948479e-02 -1.533917e+00 + 360 5.342836e-01 1.029604e-01 1.108447e+00 -2.878187e-02 -1.609834e+00 + 400 5.805889e-01 5.290718e-02 1.054332e+00 -1.186227e-01 -1.663950e+00 + 440 6.131438e-01 1.915938e-02 1.019344e+00 -1.794246e-01 -1.698938e+00 + 480 6.301872e-01 1.935497e-03 1.001937e+00 -2.105255e-01 -1.716344e+00 + 520 6.350100e-01 -2.884950e-03 9.971192e-01 -2.192380e-01 -1.721163e+00 + 560 6.468882e-01 -1.465940e-02 9.854475e-01 -2.405343e-01 -1.732834e+00 + 600 6.693569e-01 -3.655950e-02 9.641007e-01 -2.802015e-01 -1.754181e+00 + 640 7.021244e-01 -6.766195e-02 9.345763e-01 -3.366619e-01 -1.783705e+00 + 680 7.450858e-01 -1.070275e-01 8.985009e-01 -4.083288e-01 -1.819781e+00 + 720 8.015384e-01 -1.565058e-01 8.551265e-01 -4.987252e-01 -1.863155e+00 + 760 8.754911e-01 -2.178256e-01 8.042657e-01 -6.112329e-01 -1.914016e+00 + 800 9.627556e-01 -2.856560e-01 7.515211e-01 -7.362769e-01 -1.966761e+00 + 840 1.068726e+00 -3.622828e-01 6.960855e-01 -8.782493e-01 -2.022196e+00 + 880 1.205356e+00 -4.531342e-01 6.356328e-01 -1.047503e+00 -2.082649e+00 + 920 1.360691e+00 -5.472947e-01 5.785127e-01 -1.223917e+00 -2.139769e+00 + 960 1.555080e+00 -6.538651e-01 5.200319e-01 -1.424719e+00 -2.198250e+00 + 1000 1.799105e+00 -7.733362e-01 4.614709e-01 -1.651150e+00 -2.256811e+00 + 1040 2.083363e+00 -8.965948e-01 4.079565e-01 -1.886097e+00 -2.310325e+00 + 1080 2.428941e+00 -1.028483e+00 3.575490e-01 -2.138850e+00 -2.360733e+00 + 1120 2.880022e+00 -1.178008e+00 3.078913e-01 -2.426922e+00 -2.410391e+00 + 1160 3.423853e+00 -1.332822e+00 2.637319e-01 -2.726684e+00 -2.454550e+00 + 1200 4.082008e+00 -1.492878e+00 2.247249e-01 -3.037999e+00 -2.493557e+00 + 1240 4.890808e+00 -1.659881e+00 1.901617e-01 -3.364145e+00 -2.528120e+00 ------------------------------------------------------------------------------- Final Solver Statistics: - Internal solver steps = 1246 (attempted = 1247) - Total number of error test failures = 1 - Total RHS evals: Fe = 0, Fi = 10714 - Total number of Newton iterations = 6970 - Total number of linear solver convergence failures = 125 - Total linear solver setups = 192 - Total number of Jacobian evaluations = 131 + Internal solver steps = 1244 (attempted = 1246) + Total number of error test failures = 2 + Total RHS evals: Fe = 0, Fi = 9633 + Total number of Newton iterations = 5892 + Total number of linear solver convergence failures = 81 + Total linear solver setups = 149 + Total number of Jacobian evaluations = 93 Total RHS evals for setting up the linear system = 0 Total Relaxation fails = 0 - Total Relaxation Fn evals = 4138 - Total Relaxation Jac evals = 5385 - Total Relaxation NLS iters = 1644 + Total Relaxation Fn evals = 3773 + Total Relaxation Jac evals = 5019 + Total Relaxation NLS iters = 1281 Total Relaxation NLS fails = 0 From 6bd135c6d53e9e8e7172d67cdb6649e9b0fcc8e2 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 21:51:06 -0700 Subject: [PATCH 075/111] remove debugging logging output --- src/arkode/arkode_relaxation.c | 58 ---------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 2498590f32..f914ce8c41 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -114,15 +114,6 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) int i, retval; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "tolerance = %g", relax_mem->res_tol); - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "0: relaxation param = %g", relax_mem->relax_param); -#endif - for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { /* Compute the current residual */ @@ -130,12 +121,6 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) ark_mem); if (retval) return retval; -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation resid = %g", i, relax_mem->res); -#endif - /* Check for convergence */ if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; @@ -144,22 +129,10 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) ark_mem); if (retval) return retval; -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation jac = %g", i, relax_mem->jac); -#endif - relax_mem->relax_param -= relax_mem->res / relax_mem->jac; /* Update cumulative iteration count */ relax_mem->nls_iters++; - -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkStep_TakeStep_Z", "NewtonSolve", - "%d: relaxation param = %g", i+1, relax_mem->relax_param); -#endif } return ARK_RELAX_SOLVE_RECV; @@ -195,12 +168,6 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) /* Check if we got lucky */ if (SUNRabs(fa) < relax_mem->res_tol) { -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkRelaxBrentSolve", "Lower bound solves", - "relax param = %g, relax residual = %g", - xa, fa); -#endif relax_mem->res = fa; relax_mem->relax_param = xa; return ARK_SUCCESS; @@ -225,12 +192,6 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) /* Check if we got lucky */ if (SUNRabs(fb) < relax_mem->res_tol) { -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkRelaxBrentSolve", "Upper bound solves", - "relax param = %g, relax residual = %g", - xb, fb); -#endif relax_mem->res = fb; relax_mem->relax_param = xb; return ARK_SUCCESS; @@ -244,13 +205,6 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) } if (fb < ZERO) { return ARK_RELAX_SOLVE_RECV; } -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkRelaxBrentSolve", "Initial interval", - "xa = %g, xb = %g, fa = %g, fb = %g", - xa, xb, fa, fb); -#endif - /* Initialize values bracketing values to lower bound */ xc = xa; fc = fa; @@ -287,12 +241,6 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) /* Check for convergence */ if (SUNRabs(xm) < tol || SUNRabs(fb) < relax_mem->res_tol) { -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkRelaxBrentSolve", "Coverged", - "xm = %g, tol = %g, res tol = %g, relax param = %g, relax residual = %g", - xm, tol, relax_mem->res_tol, xb, fb); -#endif relax_mem->res = fb; relax_mem->relax_param = xb; return ARK_SUCCESS; @@ -443,12 +391,6 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, if (retval) { relax_mem->nls_fails++; -#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO - SUNLogger_QueueMsg(ARK_LOGGER, SUN_LOGLEVEL_INFO, - "ARKODE::arkRelaxSolve", "failed solve", - "return flag = %d, num fails = %ld", - retval, relax_mem->nls_fails); -#endif return retval; } From 4f673a0fba121912984732f3c3b208dc79a53326 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 22:10:03 -0700 Subject: [PATCH 076/111] add step length tol to Newton and tol set function --- .../Usage/ARKStep_c_interface/Relaxation.rst | 6 +-- .../Usage/ERKStep_c_interface/Relaxation.rst | 6 +-- include/arkode/arkode_arkstep.h | 2 + include/arkode/arkode_erkstep.h | 2 + src/arkode/arkode_arkstep_io.c | 6 +++ src/arkode/arkode_erkstep_io.c | 6 +++ src/arkode/arkode_relaxation.c | 39 ++++++++++++++++--- src/arkode/arkode_relaxation_impl.h | 1 + 8 files changed, 57 insertions(+), 11 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 93074e8499..eaf515ec2e 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -151,7 +151,7 @@ method. :math:`\leq 0.0` will result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param tol: the nonlinear solver residual tolerance to use + :param res_tol: the nonlinear solver residual tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -172,8 +172,8 @@ method. will result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param tol: the nonlinear solver relative solution tolerance to use - :param tol: the nonlinear solver absolute solution tolerance to use + :param rel_tol: the nonlinear solver relative solution tolerance to use + :param abs_tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index d16a016849..c0dd5dbfaf 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -151,7 +151,7 @@ method. :math:`\leq 0.0` will result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param tol: the nonlinear solver residual tolerance to use + :param res_tol: the nonlinear solver residual tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -172,8 +172,8 @@ method. will result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param tol: the nonlinear solver relative solution tolerance to use - :param tol: the nonlinear solver absolute solution tolerance to use + :param rel_tol: the nonlinear solver relative solution tolerance to use + :param rel_tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index c30ba72f21..62312a128f 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -486,6 +486,8 @@ SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver); SUNDIALS_EXPORT int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); +SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, + sunrealtype abs_tol); SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 71e47f2b0b..d4a31afa66 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -273,6 +273,8 @@ SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver); SUNDIALS_EXPORT int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); +SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, + sunrealtype abs_tol); SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper); SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index a62b285925..772fc3c0d1 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -299,6 +299,12 @@ int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) return arkRelaxSetResTol(arkode_mem, res_tol); } +int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, + sunrealtype abs_tol) +{ + return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); +} + int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) { return arkRelaxSetUpperBound(arkode_mem, upper); diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index c1aeade36b..4390371f0f 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -190,6 +190,12 @@ int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) return arkRelaxSetResTol(arkode_mem, res_tol); } +int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, + sunrealtype abs_tol) +{ + return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); +} + int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) { return arkRelaxSetUpperBound(arkode_mem, upper); diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index f914ce8c41..fa6c239fbb 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -112,6 +112,7 @@ static int arkRelaxResidualJacobian(sunrealtype relax_param, static int arkRelaxNewtonSolve(ARKodeMem ark_mem) { int i, retval; + sunrealtype tol, delta; ARKodeRelaxMem relax_mem = ark_mem->relax_mem; for (i = 0; i < ark_mem->relax_mem->max_iters; i++) @@ -122,17 +123,25 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) if (retval) return retval; /* Check for convergence */ - if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; + if (SUNRabs(relax_mem->res) < relax_mem->res_tol) { return ARK_SUCCESS; } - /* Compute Jacobian and update */ + /* Compute Jacobian */ retval = arkRelaxResidualJacobian(relax_mem->relax_param, &(relax_mem->jac), ark_mem); if (retval) return retval; - relax_mem->relax_param -= relax_mem->res / relax_mem->jac; + /* Update step length tolerance and solution */ + tol = (relax_mem->rel_tol * SUNRabs(relax_mem->relax_param) + + relax_mem->abs_tol); + + delta = relax_mem->res / relax_mem->jac; + relax_mem->relax_param -= delta; /* Update cumulative iteration count */ relax_mem->nls_iters++; + + /* Check for small update */ + if (SUNRabs(delta) < tol) { return ARK_SUCCESS; } } return ARK_RELAX_SOLVE_RECV; @@ -333,7 +342,7 @@ static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) if (retval) return retval; /* Check for convergence */ - if (SUNRabs(relax_mem->res) < relax_mem->res_tol) return ARK_SUCCESS; + if (SUNRabs(relax_mem->res) < relax_mem->res_tol) { return ARK_SUCCESS; } relax_mem->relax_param -= relax_mem->res; @@ -503,7 +512,8 @@ int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol) ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetResTol", &ark_mem, &relax_mem); + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetResTol", &ark_mem, + &relax_mem); if (retval) return retval; if (res_tol > SUN_RCONST(0.0)) relax_mem->res_tol = res_tol; @@ -512,6 +522,25 @@ int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol) return ARK_SUCCESS; } +int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetTol", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (rel_tol > SUN_RCONST(0.0)) relax_mem->rel_tol = rel_tol; + else relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; + + if (abs_tol > SUN_RCONST(0.0)) relax_mem->abs_tol = abs_tol; + else relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; + + return ARK_SUCCESS; +} + int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper) { int retval; diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index d8e64cd165..de6e248094 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -118,6 +118,7 @@ int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver); int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol); +int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); From ebc6158a36e2190aada0c7e617869287db96a9e9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 22:24:17 -0700 Subject: [PATCH 077/111] regen Fortran interfaces --- src/arkode/fmod/farkode_arkstep_mod.c | 200 +++++++++++++ src/arkode/fmod/farkode_arkstep_mod.f90 | 374 ++++++++++++++++++++++++ src/arkode/fmod/farkode_erkstep_mod.c | 200 +++++++++++++ src/arkode/fmod/farkode_erkstep_mod.f90 | 372 +++++++++++++++++++++++ src/arkode/fmod/farkode_mod.f90 | 23 +- 5 files changed, 1165 insertions(+), 4 deletions(-) diff --git a/src/arkode/fmod/farkode_arkstep_mod.c b/src/arkode/fmod/farkode_arkstep_mod.c index 543f624102..246aa79852 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.c +++ b/src/arkode/fmod/farkode_arkstep_mod.c @@ -2445,4 +2445,204 @@ SWIGEXPORT int _wrap_FARKStepCreateMRIStepInnerStepper(void *farg1, void *farg2) } +SWIGEXPORT int _wrap_FARKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJacFn farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKRelaxFn arg2 = (ARKRelaxFn) 0 ; + ARKRelaxJacFn arg3 = (ARKRelaxJacFn) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (ARKRelaxFn)(farg2); + arg3 = (ARKRelaxJacFn)(farg3); + result = (int)ARKStepSetRelaxFn(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKStepSetRelaxEtaFail(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxLowerBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKStepSetRelaxLowerBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxMaxFails(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ARKStepSetRelaxMaxFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxMaxIters(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ARKStepSetRelaxMaxIters(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxSolver(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKRelaxSolver arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (ARKRelaxSolver)(*farg2); + result = (int)ARKStepSetRelaxSolver(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxResTol(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKStepSetRelaxResTol(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxTol(void *farg1, double const *farg2, double const *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + sunrealtype arg3 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + arg3 = (sunrealtype)(*farg3); + result = (int)ARKStepSetRelaxTol(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepSetRelaxUpperBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKStepSetRelaxUpperBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxFnEvals(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxJacEvals(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepGetNumRelaxFails(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepGetNumRelaxSolveFails(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxSolveFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FARKStepGetNumRelaxSolveIters(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxSolveIters(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + diff --git a/src/arkode/fmod/farkode_arkstep_mod.f90 b/src/arkode/fmod/farkode_arkstep_mod.f90 index 5002a7b1c4..fd3ce6edc9 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.f90 +++ b/src/arkode/fmod/farkode_arkstep_mod.f90 @@ -49,9 +49,11 @@ module farkode_arkstep_mod integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_DIRK_3 = ARKODE_ARK324L2SA_DIRK_4_2_3 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_DIRK_4 = ARKODE_SDIRK_5_3_4 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_DIRK_5 = ARKODE_ARK548L2SA_DIRK_8_4_5 + integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ETABLE_2 = ARKODE_ARK2_ERK_3_1_2 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ETABLE_3 = ARKODE_ARK324L2SA_ERK_4_2_3 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ETABLE_4 = ARKODE_ARK436L2SA_ERK_6_3_4 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ETABLE_5 = ARKODE_ARK548L2SA_ERK_8_4_5 + integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ITABLE_2 = ARKODE_ARK2_DIRK_3_1_2 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ITABLE_3 = ARKODE_ARK324L2SA_DIRK_4_2_3 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ITABLE_4 = ARKODE_ARK436L2SA_DIRK_6_3_4 integer(C_INT), parameter, public :: ARKSTEP_DEFAULT_ARK_ITABLE_5 = ARKODE_ARK548L2SA_DIRK_8_4_5 @@ -210,6 +212,20 @@ module farkode_arkstep_mod public :: FARKStepFree public :: FARKStepPrintMem public :: FARKStepCreateMRIStepInnerStepper + public :: FARKStepSetRelaxFn + public :: FARKStepSetRelaxEtaFail + public :: FARKStepSetRelaxLowerBound + public :: FARKStepSetRelaxMaxFails + public :: FARKStepSetRelaxMaxIters + public :: FARKStepSetRelaxSolver + public :: FARKStepSetRelaxResTol + public :: FARKStepSetRelaxTol + public :: FARKStepSetRelaxUpperBound + public :: FARKStepGetNumRelaxFnEvals + public :: FARKStepGetNumRelaxJacEvals + public :: FARKStepGetNumRelaxFails + public :: FARKStepGetNumRelaxSolveFails + public :: FARKStepGetNumRelaxSolveIters ! WRAPPER DECLARATIONS interface @@ -1628,6 +1644,134 @@ function swigc_FARKStepCreateMRIStepInnerStepper(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKStepSetRelaxFn(farg1, farg2, farg3) & +bind(C, name="_wrap_FARKStepSetRelaxFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxEtaFail") & +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_FARKStepSetRelaxLowerBound(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxLowerBound") & +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_FARKStepSetRelaxMaxFails(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxMaxFails") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FARKStepSetRelaxMaxIters(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxMaxIters") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FARKStepSetRelaxSolver(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxSolver") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FARKStepSetRelaxResTol(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxResTol") & +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_FARKStepSetRelaxTol(farg1, farg2, farg3) & +bind(C, name="_wrap_FARKStepSetRelaxTol") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FARKStepSetRelaxUpperBound(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxUpperBound") & +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_FARKStepGetNumRelaxFnEvals(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxFnEvals") & +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_FARKStepGetNumRelaxJacEvals(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxJacEvals") & +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_FARKStepGetNumRelaxFails(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxFails") & +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_FARKStepGetNumRelaxSolveFails(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxSolveFails") & +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_FARKStepGetNumRelaxSolveIters(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxSolveIters") & +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 @@ -4234,5 +4378,235 @@ function FARKStepCreateMRIStepInnerStepper(arkode_mem, stepper) & swig_result = fresult end function +function FARKStepSetRelaxFn(arkode_mem, rfn, rjac) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(C_FUNPTR), intent(in), value :: rfn +type(C_FUNPTR), intent(in), value :: rjac +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_FUNPTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = arkode_mem +farg2 = rfn +farg3 = rjac +fresult = swigc_FARKStepSetRelaxFn(farg1, farg2, farg3) +swig_result = fresult +end function + +function FARKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: eta_rf +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = eta_rf +fresult = swigc_FARKStepSetRelaxEtaFail(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxLowerBound(arkode_mem, lower) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: lower +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = lower +fresult = swigc_FARKStepSetRelaxLowerBound(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxMaxFails(arkode_mem, max_fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: max_fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = max_fails +fresult = swigc_FARKStepSetRelaxMaxFails(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxMaxIters(arkode_mem, max_iters) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: max_iters +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = max_iters +fresult = swigc_FARKStepSetRelaxMaxIters(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxSolver(arkode_mem, solver) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(ARKRelaxSolver), intent(in) :: solver +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = solver +fresult = swigc_FARKStepSetRelaxSolver(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxResTol(arkode_mem, res_tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: res_tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = res_tol +fresult = swigc_FARKStepSetRelaxResTol(farg1, farg2) +swig_result = fresult +end function + +function FARKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: rel_tol +real(C_DOUBLE), intent(in) :: abs_tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 +real(C_DOUBLE) :: farg3 + +farg1 = arkode_mem +farg2 = rel_tol +farg3 = abs_tol +fresult = swigc_FARKStepSetRelaxTol(farg1, farg2, farg3) +swig_result = fresult +end function + +function FARKStepSetRelaxUpperBound(arkode_mem, upper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: upper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = upper +fresult = swigc_FARKStepSetRelaxUpperBound(farg1, farg2) +swig_result = fresult +end function + +function FARKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: r_evals +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(r_evals(1)) +fresult = swigc_FARKStepGetNumRelaxFnEvals(farg1, farg2) +swig_result = fresult +end function + +function FARKStepGetNumRelaxJacEvals(arkode_mem, j_evals) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: j_evals +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(j_evals(1)) +fresult = swigc_FARKStepGetNumRelaxJacEvals(farg1, farg2) +swig_result = fresult +end function + +function FARKStepGetNumRelaxFails(arkode_mem, relax_fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: relax_fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(relax_fails(1)) +fresult = swigc_FARKStepGetNumRelaxFails(farg1, farg2) +swig_result = fresult +end function + +function FARKStepGetNumRelaxSolveFails(arkode_mem, fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(fails(1)) +fresult = swigc_FARKStepGetNumRelaxSolveFails(farg1, farg2) +swig_result = fresult +end function + +function FARKStepGetNumRelaxSolveIters(arkode_mem, iters) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: iters +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(iters(1)) +fresult = swigc_FARKStepGetNumRelaxSolveIters(farg1, farg2) +swig_result = fresult +end function + end module diff --git a/src/arkode/fmod/farkode_erkstep_mod.c b/src/arkode/fmod/farkode_erkstep_mod.c index d990659fb9..a60eb9d62c 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.c +++ b/src/arkode/fmod/farkode_erkstep_mod.c @@ -1348,4 +1348,204 @@ SWIGEXPORT void _wrap_FERKStepPrintMem(void *farg1, void *farg2) { } +SWIGEXPORT int _wrap_FERKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJacFn farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKRelaxFn arg2 = (ARKRelaxFn) 0 ; + ARKRelaxJacFn arg3 = (ARKRelaxJacFn) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (ARKRelaxFn)(farg2); + arg3 = (ARKRelaxJacFn)(farg3); + result = (int)ERKStepSetRelaxFn(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ERKStepSetRelaxEtaFail(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxLowerBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ERKStepSetRelaxLowerBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxMaxFails(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ERKStepSetRelaxMaxFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxMaxIters(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ERKStepSetRelaxMaxIters(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxSolver(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + ARKRelaxSolver arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (ARKRelaxSolver)(*farg2); + result = (int)ERKStepSetRelaxSolver(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxResTol(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ERKStepSetRelaxResTol(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxTol(void *farg1, double const *farg2, double const *farg3) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + sunrealtype arg3 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + arg3 = (sunrealtype)(*farg3); + result = (int)ERKStepSetRelaxTol(arg1,arg2,arg3); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepSetRelaxUpperBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ERKStepSetRelaxUpperBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxFnEvals(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxJacEvals(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepGetNumRelaxFails(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepGetNumRelaxSolveFails(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxSolveFails(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FERKStepGetNumRelaxSolveIters(void *farg1, long *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + long *arg2 = (long *) 0 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxSolveIters(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + diff --git a/src/arkode/fmod/farkode_erkstep_mod.f90 b/src/arkode/fmod/farkode_erkstep_mod.f90 index 7e2b05ae23..579b64e302 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.f90 +++ b/src/arkode/fmod/farkode_erkstep_mod.f90 @@ -125,6 +125,20 @@ module farkode_erkstep_mod public :: FERKStepGetStepStats public :: FERKStepFree public :: FERKStepPrintMem + public :: FERKStepSetRelaxFn + public :: FERKStepSetRelaxEtaFail + public :: FERKStepSetRelaxLowerBound + public :: FERKStepSetRelaxMaxFails + public :: FERKStepSetRelaxMaxIters + public :: FERKStepSetRelaxSolver + public :: FERKStepSetRelaxResTol + public :: FERKStepSetRelaxTol + public :: FERKStepSetRelaxUpperBound + public :: FERKStepGetNumRelaxFnEvals + public :: FERKStepGetNumRelaxJacEvals + public :: FERKStepGetNumRelaxFails + public :: FERKStepGetNumRelaxSolveFails + public :: FERKStepGetNumRelaxSolveIters ! WRAPPER DECLARATIONS interface @@ -844,6 +858,134 @@ subroutine swigc_FERKStepPrintMem(farg1, farg2) & type(C_PTR), value :: farg2 end subroutine +function swigc_FERKStepSetRelaxFn(farg1, farg2, farg3) & +bind(C, name="_wrap_FERKStepSetRelaxFn") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_FUNPTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxEtaFail") & +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_FERKStepSetRelaxLowerBound(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxLowerBound") & +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_FERKStepSetRelaxMaxFails(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxMaxFails") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FERKStepSetRelaxMaxIters(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxMaxIters") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FERKStepSetRelaxSolver(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxSolver") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + +function swigc_FERKStepSetRelaxResTol(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxResTol") & +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_FERKStepSetRelaxTol(farg1, farg2, farg3) & +bind(C, name="_wrap_FERKStepSetRelaxTol") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +real(C_DOUBLE), intent(in) :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FERKStepSetRelaxUpperBound(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxUpperBound") & +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_FERKStepGetNumRelaxFnEvals(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxFnEvals") & +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_FERKStepGetNumRelaxJacEvals(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxJacEvals") & +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_FERKStepGetNumRelaxFails(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxFails") & +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_FERKStepGetNumRelaxSolveFails(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxSolveFails") & +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_FERKStepGetNumRelaxSolveIters(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxSolveIters") & +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 @@ -2178,5 +2320,235 @@ subroutine FERKStepPrintMem(arkode_mem, outfile) call swigc_FERKStepPrintMem(farg1, farg2) end subroutine +function FERKStepSetRelaxFn(arkode_mem, rfn, rjac) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +type(C_FUNPTR), intent(in), value :: rfn +type(C_FUNPTR), intent(in), value :: rjac +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_FUNPTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = arkode_mem +farg2 = rfn +farg3 = rjac +fresult = swigc_FERKStepSetRelaxFn(farg1, farg2, farg3) +swig_result = fresult +end function + +function FERKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: eta_rf +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = eta_rf +fresult = swigc_FERKStepSetRelaxEtaFail(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxLowerBound(arkode_mem, lower) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: lower +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = lower +fresult = swigc_FERKStepSetRelaxLowerBound(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxMaxFails(arkode_mem, max_fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: max_fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = max_fails +fresult = swigc_FERKStepSetRelaxMaxFails(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxMaxIters(arkode_mem, max_iters) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: max_iters +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = max_iters +fresult = swigc_FERKStepSetRelaxMaxIters(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxSolver(arkode_mem, solver) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(ARKRelaxSolver), intent(in) :: solver +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = solver +fresult = swigc_FERKStepSetRelaxSolver(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxResTol(arkode_mem, res_tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: res_tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = res_tol +fresult = swigc_FERKStepSetRelaxResTol(farg1, farg2) +swig_result = fresult +end function + +function FERKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: rel_tol +real(C_DOUBLE), intent(in) :: abs_tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 +real(C_DOUBLE) :: farg3 + +farg1 = arkode_mem +farg2 = rel_tol +farg3 = abs_tol +fresult = swigc_FERKStepSetRelaxTol(farg1, farg2, farg3) +swig_result = fresult +end function + +function FERKStepSetRelaxUpperBound(arkode_mem, upper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: upper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = upper +fresult = swigc_FERKStepSetRelaxUpperBound(farg1, farg2) +swig_result = fresult +end function + +function FERKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: r_evals +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(r_evals(1)) +fresult = swigc_FERKStepGetNumRelaxFnEvals(farg1, farg2) +swig_result = fresult +end function + +function FERKStepGetNumRelaxJacEvals(arkode_mem, j_evals) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: j_evals +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(j_evals(1)) +fresult = swigc_FERKStepGetNumRelaxJacEvals(farg1, farg2) +swig_result = fresult +end function + +function FERKStepGetNumRelaxFails(arkode_mem, relax_fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: relax_fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(relax_fails(1)) +fresult = swigc_FERKStepGetNumRelaxFails(farg1, farg2) +swig_result = fresult +end function + +function FERKStepGetNumRelaxSolveFails(arkode_mem, fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(fails(1)) +fresult = swigc_FERKStepGetNumRelaxSolveFails(farg1, farg2) +swig_result = fresult +end function + +function FERKStepGetNumRelaxSolveIters(arkode_mem, iters) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: iters +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(iters(1)) +fresult = swigc_FERKStepGetNumRelaxSolveIters(farg1, farg2) +swig_result = fresult +end function + end module diff --git a/src/arkode/fmod/farkode_mod.f90 b/src/arkode/fmod/farkode_mod.f90 index dd41dfce77..f4eb249a3a 100644 --- a/src/arkode/fmod/farkode_mod.f90 +++ b/src/arkode/fmod/farkode_mod.f90 @@ -100,7 +100,19 @@ module farkode_mod integer(C_INT), parameter, public :: ARK_INTERP_FAIL = -40_C_INT integer(C_INT), parameter, public :: ARK_INVALID_TABLE = -41_C_INT integer(C_INT), parameter, public :: ARK_CONTEXT_ERR = -42_C_INT + integer(C_INT), parameter, public :: ARK_RELAX_FAIL = -43_C_INT + integer(C_INT), parameter, public :: ARK_RELAX_MEM_NULL = -44_C_INT + integer(C_INT), parameter, public :: ARK_RELAX_FUNC_FAIL = -45_C_INT + integer(C_INT), parameter, public :: ARK_RELAX_JAC_FAIL = -46_C_INT integer(C_INT), parameter, public :: ARK_UNRECOGNIZED_ERROR = -99_C_INT + ! typedef enum ARKRelaxSolver + enum, bind(c) + enumerator :: ARK_RELAX_BRENT + enumerator :: ARK_RELAX_FIXEDPOINT + enumerator :: ARK_RELAX_NEWTON + end enum + integer, parameter, public :: ARKRelaxSolver = kind(ARK_RELAX_BRENT) + public :: ARK_RELAX_BRENT, ARK_RELAX_FIXEDPOINT, ARK_RELAX_NEWTON public :: FARKBandPrecInit public :: FARKBandPrecGetWorkSpace public :: FARKBandPrecGetNumRhsEvals @@ -192,7 +204,8 @@ module farkode_mod enumerator :: ARKODE_ESDIRK437L2SA_7_3_4 enumerator :: ARKODE_ESDIRK547L2SA_7_4_5 enumerator :: ARKODE_ESDIRK547L2SA2_7_4_5 - enumerator :: ARKODE_MAX_DIRK_NUM = ARKODE_ESDIRK547L2SA2_7_4_5 + enumerator :: ARKODE_ARK2_DIRK_3_1_2 + enumerator :: ARKODE_MAX_DIRK_NUM = ARKODE_ARK2_DIRK_3_1_2 end enum integer, parameter, public :: ARKODE_DIRKTableID = kind(ARKODE_DIRK_NONE) public :: ARKODE_DIRK_NONE, ARKODE_MIN_DIRK_NUM, ARKODE_SDIRK_2_1_2, ARKODE_BILLINGTON_3_3_2, ARKODE_TRBDF2_3_3_2, & @@ -200,7 +213,8 @@ module farkode_mod ARKODE_KVAERNO_5_3_4, ARKODE_ARK436L2SA_DIRK_6_3_4, ARKODE_KVAERNO_7_4_5, ARKODE_ARK548L2SA_DIRK_8_4_5, & ARKODE_ARK437L2SA_DIRK_7_3_4, ARKODE_ARK548L2SAb_DIRK_8_4_5, ARKODE_ESDIRK324L2SA_4_2_3, ARKODE_ESDIRK325L2SA_5_2_3, & ARKODE_ESDIRK32I5L2SA_5_2_3, ARKODE_ESDIRK436L2SA_6_3_4, ARKODE_ESDIRK43I6L2SA_6_3_4, ARKODE_QESDIRK436L2SA_6_3_4, & - ARKODE_ESDIRK437L2SA_7_3_4, ARKODE_ESDIRK547L2SA_7_4_5, ARKODE_ESDIRK547L2SA2_7_4_5, ARKODE_MAX_DIRK_NUM + ARKODE_ESDIRK437L2SA_7_3_4, ARKODE_ESDIRK547L2SA_7_4_5, ARKODE_ESDIRK547L2SA2_7_4_5, ARKODE_ARK2_DIRK_3_1_2, & + ARKODE_MAX_DIRK_NUM public :: FARKodeButcherTable_LoadDIRK type, bind(C) :: SwigArrayWrapper type(C_PTR), public :: data = C_NULL_PTR @@ -243,14 +257,15 @@ module farkode_mod enumerator :: ARKODE_KNOTH_WOLKE_3_3 enumerator :: ARKODE_ARK437L2SA_ERK_7_3_4 enumerator :: ARKODE_ARK548L2SAb_ERK_8_4_5 - enumerator :: ARKODE_MAX_ERK_NUM = ARKODE_ARK548L2SAb_ERK_8_4_5 + enumerator :: ARKODE_ARK2_ERK_3_1_2 + enumerator :: ARKODE_MAX_ERK_NUM = ARKODE_ARK2_ERK_3_1_2 end enum integer, parameter, public :: ARKODE_ERKTableID = kind(ARKODE_ERK_NONE) public :: ARKODE_ERK_NONE, ARKODE_MIN_ERK_NUM, ARKODE_HEUN_EULER_2_1_2, ARKODE_BOGACKI_SHAMPINE_4_2_3, & ARKODE_ARK324L2SA_ERK_4_2_3, ARKODE_ZONNEVELD_5_3_4, ARKODE_ARK436L2SA_ERK_6_3_4, ARKODE_SAYFY_ABURUB_6_3_4, & ARKODE_CASH_KARP_6_4_5, ARKODE_FEHLBERG_6_4_5, ARKODE_DORMAND_PRINCE_7_4_5, ARKODE_ARK548L2SA_ERK_8_4_5, & ARKODE_VERNER_8_5_6, ARKODE_FEHLBERG_13_7_8, ARKODE_KNOTH_WOLKE_3_3, ARKODE_ARK437L2SA_ERK_7_3_4, & - ARKODE_ARK548L2SAb_ERK_8_4_5, ARKODE_MAX_ERK_NUM + ARKODE_ARK548L2SAb_ERK_8_4_5, ARKODE_ARK2_ERK_3_1_2, ARKODE_MAX_ERK_NUM public :: FARKodeButcherTable_LoadERK public :: FARKodeButcherTable_LoadERKByName integer(C_INT), parameter, public :: ARKLS_SUCCESS = 0_C_INT From bf78e13a8e061a5bb143000b5faac5b2243ac324 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 5 Jul 2023 22:30:41 -0700 Subject: [PATCH 078/111] update tarscript --- scripts/arkode | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/arkode b/scripts/arkode index f87b467d4a..d6ab949254 100755 --- a/scripts/arkode +++ b/scripts/arkode @@ -83,8 +83,11 @@ $tar $tarfile $distrobase/src/arkode/arkode_mristep.c $tar $tarfile $distrobase/src/arkode/arkode_mristep_impl.h $tar $tarfile $distrobase/src/arkode/arkode_mristep_io.c $tar $tarfile $distrobase/src/arkode/arkode_mristep_nls.c +$tar $tarfile $distrobase/src/arkode/arkode_relaxation.c +$tar $tarfile $distrobase/src/arkode/arkode_relaxation_impl.h $tar $tarfile $distrobase/src/arkode/arkode_root.c $tar $tarfile $distrobase/src/arkode/arkode_root_impl.h +$tar $tarfile $distrobase/src/arkode/arkode_types_impl.h $tar $tarfile $distrobase/src/arkode/xbraid/CMakeLists.txt $tar $tarfile $distrobase/src/arkode/xbraid/arkode_xbraid.c @@ -184,6 +187,14 @@ $tar $tarfile $distrobase/examples/arkode/C_serial/ark_brusselator_mri.c $tar $tarfile $distrobase/examples/arkode/C_serial/ark_brusselator_mri.out $tar $tarfile $distrobase/examples/arkode/C_serial/ark_brusselator_1D_mri.c $tar $tarfile $distrobase/examples/arkode/C_serial/ark_brusselator_1D_mri.out +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out +$tar $tarfile $distrobase/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out $tar $tarfile $distrobase/examples/arkode/C_serial/ark_heat1D.c $tar $tarfile $distrobase/examples/arkode/C_serial/ark_heat1D.out $tar $tarfile $distrobase/examples/arkode/C_serial/ark_heat1D_adapt.c @@ -284,6 +295,8 @@ $tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_kpr_Mt_2_-5_0_-10.out $tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_kpr_Mt_2_8_0_-10.out $tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_kpr_Mt_0_4_0_-10_0_10_1.out $tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_kpr_Mt_0_4_0_-10_1_10_1.out +$tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_pendulum.cpp +$tar $tarfile $distrobase/examples/arkode/CXX_serial/ark_pendulum.out $tar $tarfile $distrobase/examples/arkode/CXX_serial/plot_heat2D.py $tar $tarfile $distrobase/examples/arkode/CXX_serial/plot_sol.py From 27c91405109b4b9fdfa24f59626aba5193c83f86 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 6 Jul 2023 06:58:02 -0700 Subject: [PATCH 079/111] fix doc typo --- .../guide/source/Usage/ARKStep_c_interface/Relaxation.rst | 2 +- .../guide/source/Usage/ERKStep_c_interface/Relaxation.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index eaf515ec2e..b4af665f0f 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -123,7 +123,7 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) +.. c:function:: int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index c0dd5dbfaf..d981262a43 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -123,7 +123,7 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ARKSteSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) +.. c:function:: int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. The default value is ``ARK_RELAX_NEWTON``. From d5f22bd8878a434c701e669e0c7848f6355d6e21 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 6 Jul 2023 08:03:12 -0700 Subject: [PATCH 080/111] add missing file to tarscript --- scripts/shared | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/shared b/scripts/shared index b9a7da6458..c3212344ae 100755 --- a/scripts/shared +++ b/scripts/shared @@ -579,6 +579,7 @@ echo " --- Add examples utilities to $tarfile" $tar $tarfile $distrobase/examples/utilities/custom_memory_helper_gpu.h $tar $tarfile $distrobase/examples/utilities/custom_memory_helper_sycl.h +$tar $tarfile $distrobase/examples/utilities/example_utilities.h $tar $tarfile $distrobase/examples/utilities/example_utilities.hpp $tar $tarfile $distrobase/examples/utilities/test_utilities.f90 $tar $tarfile $distrobase/examples/utilities/plot_data_2d.py From 01ea48415641899b9904928e1294fdd5dc7fbc83 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 6 Jul 2023 09:54:05 -0700 Subject: [PATCH 081/111] include current director in install tests --- examples/templates/cmakelists_serial_C_ex.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/templates/cmakelists_serial_C_ex.in b/examples/templates/cmakelists_serial_C_ex.in index 804cda9968..33c620e643 100644 --- a/examples/templates/cmakelists_serial_C_ex.in +++ b/examples/templates/cmakelists_serial_C_ex.in @@ -83,6 +83,9 @@ set(SUNDIALS_LIBRARIES ${SUNDIALS_MANYVEC_LIB} ${SUNDIALS_EXTRA_LIBS}) +# Include the current directory +include_directories(.) + # ------------------------------------------------------------------------------ # Set the names of the examples to be built and their dependencies From 0baf4e8271b12521be51630e500480ca5c1c9166 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 6 Jul 2023 09:55:20 -0700 Subject: [PATCH 082/111] update answers commit --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 96d6e170c1..7819cc606f 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 96d6e170c15f997d1e9062d4e6478e618d3f30ca +Subproject commit 7819cc606fddf71268731910f6fa0720ae3df84b From 75037f76b765c16ae4cac8f2592ba65644bdaa78 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 11 Jul 2023 18:52:20 -0700 Subject: [PATCH 083/111] switch to multiple of h for accpetable relax parameter range, fix input checks --- include/arkode/arkode_arkstep.h | 8 +-- include/arkode/arkode_erkstep.h | 8 +-- src/arkode/arkode_arkstep_io.c | 18 +++--- src/arkode/arkode_erkstep_io.c | 18 +++--- src/arkode/arkode_relaxation.c | 96 ++++++++++++++--------------- src/arkode/arkode_relaxation_impl.h | 23 ++++--- 6 files changed, 85 insertions(+), 86 deletions(-) diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index eaf344eb2c..a144ebe905 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -478,10 +478,10 @@ SUNDIALS_EXPORT int ARKStepCreateMRIStepInnerStepper(void *arkode_mem, /* Relaxation functions */ SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ARKStepSetRelaxBoundFactor(void* arkode_mem, + sunrealtype bound_factor); SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); -SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, - sunrealtype lower); SUNDIALS_EXPORT int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, @@ -490,14 +490,14 @@ SUNDIALS_EXPORT int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); -SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, - sunrealtype upper); SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ARKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); SUNDIALS_EXPORT int ARKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails); +SUNDIALS_EXPORT int ARKStepGetNumRelaxBoundFails(void* arkode_mem, + long int* fails); SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); SUNDIALS_EXPORT int ARKStepGetNumRelaxSolveIters(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index c7b55032a6..7cf11406dc 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -265,10 +265,10 @@ SUNDIALS_EXPORT void ERKStepPrintMem(void* arkode_mem, FILE* outfile); /* Relaxation functions */ SUNDIALS_EXPORT int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); +SUNDIALS_EXPORT int ERKStepSetRelaxBoundFactor(void* arkode_mem, + sunrealtype bound_factor); SUNDIALS_EXPORT int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); -SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, - sunrealtype lower); SUNDIALS_EXPORT int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, @@ -277,14 +277,14 @@ SUNDIALS_EXPORT int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); -SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, - sunrealtype upper); SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ERKStepGetNumRelaxJacEvals(void* arkode_mem, long int* J_evals); SUNDIALS_EXPORT int ERKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails); +SUNDIALS_EXPORT int ERKStepGetNumRelaxBoundFails(void* arkode_mem, + long int* fails); SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails); SUNDIALS_EXPORT int ERKStepGetNumRelaxSolveIters(void* arkode_mem, diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 8435eea98b..2391e7ba26 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -272,14 +272,14 @@ int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) arkStep_RelaxDeltaE, arkStep_GetOrder); } -int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +int ARKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) { - return arkRelaxSetEtaFail(arkode_mem, eta_rf); + return arkRelaxSetBoundFactor(arkode_mem, bound_factor); } -int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) { - return arkRelaxSetLowerBound(arkode_mem, lower); + return arkRelaxSetEtaFail(arkode_mem, eta_rf); } int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) @@ -308,11 +308,6 @@ int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); } -int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) -{ - return arkRelaxSetUpperBound(arkode_mem, upper); -} - int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) { return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); @@ -328,6 +323,11 @@ int ARKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails) return arkRelaxGetNumRelaxFails(arkode_mem, relax_fails); } +int ARKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) +{ + return arkRelaxGetNumRelaxBoundFails(arkode_mem, fails); +} + int ARKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) { return arkRelaxGetNumRelaxSolveFails(arkode_mem, fails); diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index f95fd4b190..2aee8caf9b 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -163,14 +163,14 @@ int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) erkStep_RelaxDeltaE, erkStep_GetOrder); } -int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +int ERKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) { - return arkRelaxSetEtaFail(arkode_mem, eta_rf); + return arkRelaxSetBoundFactor(arkode_mem, bound_factor); } -int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) { - return arkRelaxSetLowerBound(arkode_mem, lower); + return arkRelaxSetEtaFail(arkode_mem, eta_rf); } int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) @@ -199,11 +199,6 @@ int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); } -int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) -{ - return arkRelaxSetUpperBound(arkode_mem, upper); -} - int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) { return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); @@ -219,6 +214,11 @@ int ERKStepGetNumRelaxFails(void* arkode_mem, long int* relax_fails) return arkRelaxGetNumRelaxFails(arkode_mem, relax_fails); } +int ERKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) +{ + return arkRelaxGetNumRelaxBoundFails(arkode_mem, fails); +} + int ERKStepGetNumRelaxSolveFails(void* arkode_mem, long int* fails) { return arkRelaxGetNumRelaxSolveFails(arkode_mem, fails); diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index fa6c239fbb..e0d3f21aaf 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -404,9 +404,10 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, } /* Check for bad relaxation value */ - if (ark_mem->relax_mem->relax_param < relax_mem->lower_bound || - ark_mem->relax_mem->relax_param > relax_mem->upper_bound) + if (SUNRabs(relax_mem->relax_param - ONE) > + relax_mem->bound_factor * SUNRabs(ark_mem->h)) { + relax_mem->bound_fails++; return ARK_RELAX_SOLVE_RECV; } @@ -427,34 +428,34 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, * Set functions * ---------------------------------------------------------------------------*/ -int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail) +int arkRelaxSetBoundFactor(void* arkode_mem, sunrealtype bound_factor) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetEtaFail", &ark_mem, + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetBoundFactor", &ark_mem, &relax_mem); if (retval) return retval; - if (eta_fail < SUN_RCONST(1.0)) relax_mem->eta_fail = eta_fail; - else relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + if (bound_factor > ZERO) { relax_mem->bound_factor = bound_factor; } + else { relax_mem->bound_factor = ARK_RELAX_DEFAULT_BOUND_FACTOR; } return ARK_SUCCESS; } -int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower) +int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetLowerBound", &ark_mem, + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetEtaFail", &ark_mem, &relax_mem); if (retval) return retval; - if (lower < SUN_RCONST(1.0)) relax_mem->lower_bound = lower; - else relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; + if (eta_fail > ZERO && eta_fail < ONE) { relax_mem->eta_fail = eta_fail; } + else { relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; } return ARK_SUCCESS; } @@ -469,8 +470,8 @@ int arkRelaxSetMaxFails(void* arkode_mem, int max_fails) &relax_mem); if (retval) return retval; - if (max_fails > 0) relax_mem->max_fails = max_fails; - else relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; + if (max_fails > 0) { relax_mem->max_fails = max_fails; } + else { relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; } return ARK_SUCCESS; } @@ -485,8 +486,8 @@ int arkRelaxSetMaxIters(void* arkode_mem, int max_iters) &relax_mem); if (retval) return retval; - if (max_iters > 0) relax_mem->max_iters = max_iters; - else relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; + if (max_iters > 0) { relax_mem->max_iters = max_iters; } + else { relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; } return ARK_SUCCESS; } @@ -516,8 +517,8 @@ int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol) &relax_mem); if (retval) return retval; - if (res_tol > SUN_RCONST(0.0)) relax_mem->res_tol = res_tol; - else relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; + if (res_tol > ZERO) { relax_mem->res_tol = res_tol; } + else { relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; } return ARK_SUCCESS; } @@ -532,27 +533,11 @@ int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) &relax_mem); if (retval) return retval; - if (rel_tol > SUN_RCONST(0.0)) relax_mem->rel_tol = rel_tol; - else relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; - - if (abs_tol > SUN_RCONST(0.0)) relax_mem->abs_tol = abs_tol; - else relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; - - return ARK_SUCCESS; -} - -int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper) -{ - int retval; - ARKodeMem ark_mem; - ARKodeRelaxMem relax_mem; - - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetUpperBound", &ark_mem, - &relax_mem); - if (retval) return retval; + if (rel_tol > ZERO) { relax_mem->rel_tol = rel_tol; } + else { relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; } - if (upper > SUN_RCONST(1.0)) relax_mem->upper_bound = upper; - else relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; + if (abs_tol > ZERO) { relax_mem->abs_tol = abs_tol; } + else { relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; } return ARK_SUCCESS; } @@ -621,6 +606,21 @@ int arkRelaxGetNumRelaxSolveFails(void* arkode_mem, long int* fails) return ARK_SUCCESS; } +int arkRelaxGetNumRelaxBoundFails(void* arkode_mem, long int* fails) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxGetNumRelaxBoundFails", + &ark_mem, &relax_mem); + if (retval) return retval; + + *fails = relax_mem->bound_fails; + + return ARK_SUCCESS; +} + int arkRelaxGetNumRelaxSolveIters(void* arkode_mem, long int* iters) { int retval; @@ -734,15 +734,14 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); /* Set defaults */ - ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; - ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; - ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; - ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; - ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; - ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; - ark_mem->relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; - ark_mem->relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; - ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; + ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; + ark_mem->relax_mem->bound_factor = ARK_RELAX_DEFAULT_BOUND_FACTOR; + ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; + ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; + ark_mem->relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; + ark_mem->relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; + ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; /* Initialize values */ ark_mem->relax_mem->relax_param_prev = ONE; @@ -798,15 +797,16 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, realtype* dsm_inout, (*relax_fails)++; /* Check for max fails in a step */ - if (*relax_fails == relax_mem->max_fails) - return ARK_RELAX_FAIL; + if (*relax_fails == relax_mem->max_fails) { return ARK_RELAX_FAIL; } /* Return with an error if |h| == hmin */ if (SUNRabs(ark_mem->h) <= ark_mem->hmin * ONEPSM) + { return ARK_RELAX_FAIL; + } /* Return with error if using fixed step sizes */ - if (ark_mem->fixedstep) return(ARK_RELAX_FAIL); + if (ark_mem->fixedstep) { return(ARK_RELAX_FAIL); } /* Cut step size and try again */ ark_mem->eta = relax_mem->eta_fail; diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index de6e248094..3dd97ade7b 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -29,14 +29,13 @@ * Relaxation Constants * ---------------------------------------------------------------------------*/ -#define ARK_RELAX_DEFAULT_MAX_FAILS 10 -#define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) -#define ARK_RELAX_DEFAULT_REL_TOL (4 * SUN_UNIT_ROUNDOFF) -#define ARK_RELAX_DEFAULT_ABS_TOL SUN_RCONST(1.0e-14) -#define ARK_RELAX_DEFAULT_MAX_ITERS 10 -#define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) -#define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.2) -#define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) +#define ARK_RELAX_DEFAULT_MAX_FAILS 10 +#define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) +#define ARK_RELAX_DEFAULT_REL_TOL (4 * SUN_UNIT_ROUNDOFF) +#define ARK_RELAX_DEFAULT_ABS_TOL SUN_RCONST(1.0e-14) +#define ARK_RELAX_DEFAULT_MAX_ITERS 10 +#define ARK_RELAX_DEFAULT_BOUND_FACTOR SUN_RCONST(0.5) +#define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) /* ----------------------------------------------------------------------------- * Relaxation Private Return Values (see arkode/arkode.h for public values) @@ -84,8 +83,7 @@ struct ARKodeRelaxMemRec sunrealtype jac; /* relaxation Jacobian value */ sunrealtype relax_param; /* current relaxation parameter value */ sunrealtype relax_param_prev; /* previous relaxation parameter value */ - sunrealtype lower_bound; /* smallest allowed relaxation value */ - sunrealtype upper_bound; /* largest allowed relaxation value */ + sunrealtype bound_factor; /* relax param acceptance threshold */ sunrealtype eta_fail; /* failed relaxation step size factor */ /* nonlinear solver settings */ @@ -96,6 +94,7 @@ struct ARKodeRelaxMemRec int max_iters; /* nonlinear solve max iterations */ long int nls_iters; /* total nonlinear iterations */ long int nls_fails; /* number of nonlinear solver fails */ + long int bound_fails; /* number of relax param bound fails */ }; /* ----------------------------------------------------------------------------- @@ -112,18 +111,18 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, sunrealtype* dsm_inout, int* nflag_out); /* User Functions */ +int arkRelaxSetBoundFactor(void* arkode_mem, sunrealtype bound_factor); int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail); -int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver); int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol); int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); -int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* j_evals); int arkRelaxGetNumRelaxFails(void* arkode_mem, long int* relax_fails); +int arkRelaxGetNumRelaxBoundFails(void* arkode_mem, long int* fails); int arkRelaxGetNumRelaxSolveFails(void* arkode_mem, long int* fails); int arkRelaxGetNumRelaxSolveIters(void* arkode_mem, long int* iters); From df07f7efeb4860222cafc8f8fa9eaf80a497d05b Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 11 Jul 2023 20:52:06 -0700 Subject: [PATCH 084/111] remove fixed-point option --- include/arkode/arkode.h | 1 - src/arkode/arkode_relaxation.c | 37 ++++++++-------------------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/include/arkode/arkode.h b/include/arkode/arkode.h index f393554ea2..3b12589182 100644 --- a/include/arkode/arkode.h +++ b/include/arkode/arkode.h @@ -192,7 +192,6 @@ typedef _SUNDIALS_STRUCT_ _MRIStepInnerStepper *MRIStepInnerStepper; typedef enum { ARK_RELAX_BRENT, - ARK_RELAX_FIXEDPOINT, ARK_RELAX_NEWTON } ARKRelaxSolver; diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index e0d3f21aaf..1e43162df5 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -245,7 +245,7 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) tol = relax_mem->rel_tol * SUNRabs(xb) + HALF * relax_mem->abs_tol; /* Compute midpoint for bisection */ - xm = SUN_RCONST(0.5) * (xc - xb); + xm = HALF * (xc - xb); /* Check for convergence */ if (SUNRabs(xm) < tol || SUNRabs(fb) < relax_mem->res_tol) @@ -328,31 +328,6 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) return ARK_RELAX_SOLVE_RECV; } -/* Solve the relaxation residual equation using Newton's method */ -static int arkRelaxFixedPointSolve(ARKodeMem ark_mem) -{ - int i, retval; - ARKodeRelaxMem relax_mem = ark_mem->relax_mem; - - for (i = 0; i < ark_mem->relax_mem->max_iters; i++) - { - /* Compute the current residual */ - retval = arkRelaxResidual(relax_mem->relax_param, &(relax_mem->res), - ark_mem); - if (retval) return retval; - - /* Check for convergence */ - if (SUNRabs(relax_mem->res) < relax_mem->res_tol) { return ARK_SUCCESS; } - - relax_mem->relax_param -= relax_mem->res; - - /* Update iteration count */ - relax_mem->nls_iters++; - } - - return ARK_RELAX_SOLVE_RECV; -} - /* Compute and apply relaxation parameter */ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, sunrealtype* relax_val_out) @@ -388,9 +363,6 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, case(ARK_RELAX_NEWTON): retval = arkRelaxNewtonSolve(ark_mem); break; - case(ARK_RELAX_FIXEDPOINT): - retval = arkRelaxFixedPointSolve(ark_mem); - break; default: return ARK_ILL_INPUT; break; @@ -502,6 +474,13 @@ int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver) &relax_mem); if (retval) return retval; + if (solver != ARK_RELAX_BRENT && solver != ARK_RELAX_NEWTON) + { + arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkRelaxSetSolver", + "An invalid relaxation solver option was provided."); + return ARK_ILL_INPUT; + } + relax_mem->solver = solver; return ARK_SUCCESS; From 08797584744dba665e9434fa732f102f4dfb357b Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Tue, 11 Jul 2023 20:52:59 -0700 Subject: [PATCH 085/111] doc updates --- doc/arkode/guide/source/Constants.rst | 5 +- doc/arkode/guide/source/Mathematics.rst | 52 +++--- .../Usage/ARKStep_c_interface/Relaxation.rst | 167 +++++++++++------- .../Usage/ERKStep_c_interface/Relaxation.rst | 166 ++++++++++------- 4 files changed, 236 insertions(+), 154 deletions(-) diff --git a/doc/arkode/guide/source/Constants.rst b/doc/arkode/guide/source/Constants.rst index a0f2d02c1a..fd4e8f6777 100644 --- a/doc/arkode/guide/source/Constants.rst +++ b/doc/arkode/guide/source/Constants.rst @@ -67,9 +67,6 @@ contains the ARKODE output constants. | :index:`ARK_RELAX_BRENT` | Specifies Brent's method as the relaxation nonlinear | | | solver. | +---------------------------------------------+-----------------------------------------------------------+ - | :index:`ARK_RELAX_FIXEDPOINT` | Specifies the fixed-point iteration as the relaxation | - | | nonlinear solver. | - +---------------------------------------------+-----------------------------------------------------------+ | :index:`ARK_RELAX_NEWTON` | Specifies Newton's method as the relaxation nonlinear | | | solver. | +---------------------------------------------+-----------------------------------------------------------+ @@ -390,7 +387,7 @@ contains the ARKODE output constants. +-------------------------------------+------+------------------------------------------------------------+ | :index:`ARK_INVALID_TABLE` | -41 | An invalid Butcher or MRI table was encountered. | +-------------------------------------+------+------------------------------------------------------------+ - | :index:`ARK_CONTEXT_ERR` | -42 | | + | :index:`ARK_CONTEXT_ERR` | -42 | An error occurred with the SUNDIALS context object | +-------------------------------------+------+------------------------------------------------------------+ | :index:`ARK_RELAX_FAIL` | -43 | An error occurred in computing the relaxation parameter | +-------------------------------------+------+------------------------------------------------------------+ diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index aedf67b54c..eee142f4b6 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2081,25 +2081,27 @@ Relaxation Methods ================== For cases where the problem :eq:`ARKODE_IVP` is conservative or dissipative with -respect to a smooth convex function :math:`\xi(y(t))`, it is desirable to have +respect to a smooth *convex* function :math:`\xi(y(t))`, it is desirable to have the numerical method preserve these properties. That is :math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems and :math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative problems. To this end, ARKODE supports relaxation methods -:cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` to -ensure dissipation or preservation of a global function. +:cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` +applied to ERK, DIRK, or ARK methods to ensure dissipation or preservation of a +global function. -Relaxation methods compute a new solution +The relaxed solution is given by .. math:: y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} :label: ARKODE_RELAX_SOL -where :math:`d \equiv h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` is the update -direction and the relaxation factor, :math:`r`, is selected to ensure -conservation or dissipation. Given a second order method with -:math:`b^E_i \geq 0` and :math:`b^I_i \geq 0`, the factor :math:`r` is computed -by solving the auxiliary scalar nonlinear system +where :math:`d \equiv h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` is the +update direction and the relaxation factor, :math:`r`, is selected to ensure +conservation or dissipation. Given an ERK, DIRK, or ARK method of at least +second order with non-negative solution weights (i.e., :math:`b_i \geq 0` for +ERKStep or :math:`b^E_i \geq 0` and :math:`b^I_i \geq 0` for ARKStep), the +factor :math:`r` is computed by solving the auxiliary scalar nonlinear system .. math:: F(r) = \xi(y_{n-1} + r d) - \xi(y_{n-1}) - r e = 0 @@ -2109,16 +2111,26 @@ at the end of each time step. The estimated change in :math:`\xi` is given by :math:`e \equiv h_n \sum_{i=1}^{s} \langle \xi'(z_i), b^E_i f^E_i + b^I_i f^I_i \rangle` where :math:`\xi'` is the Jacobian of :math:`\xi`. -By default the nonlinear system :eq:`ARKODE_RELAX_NLS` is solved using Newton -iteration. Optionally, a fixed-point iteration of Brent's method can be -utilized. If this iteration fail to meet the specified tolerances in the -maximum allowed number of iterations, the step size is reduced by the factor -:math:`\eta_\text{rf}` (default 0.25) and the step is repeated. Additionally, a -relaxation value greater than :math:`r_\text{max}` (default 0.8) or less than -:math:`r_\text{min}` (default 1.2), will be considered as a failed solve and the -and the step will be repeated with the step size reduced by -:math:`\eta_\text{rf}`. - -For more information on utilizing relaxation Runge-Kutta methods, see +Two iterative methods are provided for solving :eq:`ARKODE_RELAX_NLS`, Newton's +method and Brent's method. When using Newton's method (the default), the +iteration is halted either when the residual tolerance is met, +:math:`F(r^{(k)}) < \epsilon_{\mathrm{relax\_res}}`, or when the difference +between successive iterates satisfies the relative and absolute tolerances, +:math:`|\delta_r^{(k)}| = |r^{(k)} - r^{(k-1)}| < \epsilon_{\mathrm{relax\_rtol}} |r^{(k-1)}| + \epsilon_{\mathrm{relax\_atol}}`. +Brent's method applies the same residual tolerance check and the additionally +halts when the bisection update satisfies the relative and absolute tolerances, +:math:`|0.5 (r_c - r^{k})| < \epsilon_{\mathrm{relax\_rtol}} |r^{(k)}| + 0.5 \epsilon_{\mathrm{relax\_atol}}` +where :math:`r_c` and :math:`r^{(k)}` bound the root. + +If the nonlinear fails to meet the specified tolerances within the maximum +allowed number of iterations, the step size is reduced by the factor +:math:`\eta_\mathrm{rf}` (default 0.25) and the step is repeated. The root of +:eq:`ARKODE_RELAX_NLS` is :math:`1 + \mathcal{O}(h_n^{q - 1})` for a method +of order :math:`q` :cite:p:`ranocha2020relaxation`. As such, if +:math:`|r - 1| > \mathcal{B} |h_n|` (default :math:`\mathcal{B} = 0.5`, the +computed :math:`r` value is considered invalid and the step will be repeated +with the step size reduced by :math:`\eta_\mathrm{rf}`. + +For more information on utilizing relaxation Runge--Kutta methods, see :numref:`ARKODE.Usage.ERKStep.Relaxation` and :numref:`ARKODE.Usage.ARKStep.Relaxation`. diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index b4af665f0f..708460ea3c 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -17,7 +17,7 @@ Relaxation Methods ================== -This section describes user-callable functions for utilizing relaxation methods +This section describes user-callable functions for applying relaxation methods with ARKStep. For more information on relaxation Runge-Kutta methods see :numref:`ARKODE.Mathematics.Relaxation`. @@ -29,6 +29,16 @@ Enabling or Disabling Relaxation Attaches the user supplied functions for evaluating the relaxation function (``rfn``) and its Jacobian (``rjac``). + Both ``rfn`` and ``rjac`` are required and an error will be returned if only + one of the functions is ``NULL``. If both ``rfn`` and ``rjac`` are ``NULL``, + relaxation is disabled. + + When combined with fixed time step sizes, ARKStep will attempt each step + using the specified step size. If the step is successful, relaxation will be + applied, effectively modifying the step size for the current step. If the + step fails or applying relaxation fails, :c:func:`ARKStepEvolve` will + return with an error. + :param arkode_mem: the ARKStep memory structure :param rfn: the user-defined function to compute the relaxation function :math:`\xi(y)` @@ -37,30 +47,39 @@ Enabling or Disabling Relaxation :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` - :retval ARK_ILL_INPUT: an invalid input combination was provided see the - output error message for more details + :retval ARK_ILL_INPUT: an invalid input combination was provided (see the + output error message for more details) :retval ARK_MEM_FAIL: a memory allocation failed - .. note:: + .. warning:: - If both ``rfn = rjac = NULL`` relaxation is disabled. + Applying relaxation requires using a method of at least second order with + :math:`b^E_i \geq 0` and :math:`b^I_i \geq 0`. If these conditions are not + satisfied, :c:func:`ARKStepEvolve` will return with an error during + initialization. .. versionadded:: 5.6.0 Optional Input Functions ------------------------ -This section describes optional input functions used to control the relaxation -method. +This section describes optional input functions used to control applying +relaxation. -.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +.. c:function:: int ARKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) - Sets the step size reduction factor applied after a failed relaxation solve. - The default value is 0.25. Input values :math:`\geq 1` will result in the + Sets the factor :math:`\mathcal{B}` used in determining an acceptable value + of the relaxation parameter, :math:`r`. + + If :math:`|r - 1| > \mathcal{B} h_n`, the value of :math:`r` is considered + unacceptable and the step will be repeated with a smaller step size + (determined by :c:func:`ARKStepSetRelaxEtaFail`). + + The default value is 0.5. Input values :math:`\leq 0` will result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param eta_rf: the step size reduction factor + :param bound_factor: the factor used to accept the relaxation parameter value :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -69,16 +88,15 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) + + Sets the step size reduction factor after a failed relaxation application. - Sets the smallest acceptable value for the relaxation parameter. Values - smaller than the lower bound will result in a relaxation solve failure and - the step will be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is 0.8. Input values - :math:`\geq 1` will result in the default value being used. + The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param lower: the relaxation parameter lower bound + :param eta_rf: the step size reduction factor :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -89,12 +107,15 @@ method. .. c:function:: int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) - Sets the maximum number relaxation failures allowed in a single step attempt - before the integration is halted with an error. The default value is 10. - Input values :math:`\leq 0` will result in the default value being used. + Sets the maximum number of times applying relaxation can fail within a step + attempt before the integration is halted with an error. + + The default value is 10. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ARKStep memory structure - :param max_iters: the maximum number relaxtion failures allowed in a step + :param max_fails: the maximum number of failed relaxation applications + allowed in a step :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -106,12 +127,15 @@ method. .. c:function:: int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the - relaxation parameter. If the maximum number of iterations is reached before - meeting the solve tolerance (determined by :c:func:`ARKStepSetRelaxResTol` - and :c:func:`ARKStepSetRelaxTol`), the step will be repeated with a smaller - step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). The default - value is 10. Input values :math:`\leq 0` will result in the default value - being used. + relaxation parameter. + + If the maximum number of iterations is reached before meeting the solve + tolerance (determined by :c:func:`ARKStepSetRelaxResTol` and + :c:func:`ARKStepSetRelaxTol`), the step will be repeated with a smaller + step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). + + The default value is 10. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ARKStep memory structure :param max_iters: the maximum number of solver iterations allowed @@ -126,29 +150,34 @@ method. .. c:function:: int ARKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. + The default value is ``ARK_RELAX_NEWTON``. :param arkode_mem: the ARKStep memory structure - :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT``, - ``ARK_RELAX_NEWTON``, or ``ARK_RELAX_FIXEDPOINT`` + :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT`` or + ``ARK_RELAX_NEWTON`` :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + :retval ARK_ILL_INPUT: an invalid solver option was provided .. versionadded:: 5.6.0 .. c:function:: int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) - Sets the nonlinear solver residual tolerance to use when computing the - relaxation parameter. If the residual or solution tolerance (see - :c:func:`ARKStepSetRelaxMaxIter`) is not reached within the maximum number of - iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the step will - be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is :math:`4 \epsilon` - where :math:`\epsilon` is floating-point precision. Input values - :math:`\leq 0.0` will result in the default value being used. + Sets the nonlinear solver residual tolerance to use when solving + :eq:`ARKODE_RELAX_NLS`. + + If the residual or solution tolerance (see :c:func:`ARKStepSetRelaxMaxIter`) + is not reached within the maximum number of iterations (determined by + :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a smaller + step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). + + The default value is :math:`4 \epsilon` where :math:`\epsilon` is + floating-point precision. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ARKStep memory structure :param res_tol: the nonlinear solver residual tolerance to use @@ -162,36 +191,23 @@ method. .. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) - Sets the nonlinear solver relative and absolute tolerance on :math:`r`. If - the residual or solution tolerance is not reached within the maximum - number of iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the - step will be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default relative and absolute - tolerances are :math:`4 \epsilon` and :math:`10^{-14}`, respectively, where - :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` - will result in the default value being used. - - :param arkode_mem: the ARKStep memory structure - :param rel_tol: the nonlinear solver relative solution tolerance to use - :param abs_tol: the nonlinear solver absolute solution tolerance to use - - :retval ARK_SUCCESS: the value was successfully set - :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` - :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was - ``NULL`` + Sets the nonlinear solver relative and absolute tolerance on changes in + :math:`r` when solving :eq:`ARKODE_RELAX_NLS`. - .. versionadded:: 5.6.0 -.. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) + If the residual (see :c:func:`ARKStepSetRelaxResTol`) or solution tolerance + is not reached within the maximum number of iterations (determined by + :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a smaller + step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). - Sets the largest acceptable value for the relaxation parameter. Values - larger than the upper bound will result in a relaxation solve failure and - the step will be repeated with a smaller step size (determined by - :c:func:`ARKStepSetRelaxEtaFail`). The default value is 1.2. Input values - :math:`\leq 1` will result in the default value being used. + The default relative and absolute tolerances are :math:`4 \epsilon` and + :math:`10^{-14}`, respectively, where :math:`\epsilon` is floating-point + precision. Input values :math:`\leq 0` will result in the default value being + used. :param arkode_mem: the ARKStep memory structure - :param eta_rf: the relaxation parameter upper bound + :param rel_tol: the nonlinear solver relative solution tolerance to use + :param abs_tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -200,6 +216,7 @@ method. .. versionadded:: 5.6.0 + Optional Output Functions ------------------------- @@ -236,10 +253,30 @@ about the performance of the relaxation method. .. c:function:: int ARKStepGetNumRelaxFails(void* arkode_mem, long int* fails) - Get the total number of relaxation failures. + Get the total number of times applying relaxation failed. + + The counter includes the sum of the number of nonlinear solver failure + (see :c:func:`ARKStepGetNumRelaxSolveFails`) and the number of failures due + an unacceptable relaxation value (see :c:func:`ARKStepSetRelaxBoundFactor`). + + :param arkode_mem: the ARKStep memory structure + :param fails: the total number of failed relaxation attempts + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 + + +.. c:function:: int ARKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) + + Get the number of times the relaxation parameter as deemed unacceptable. :param arkode_mem: the ARKStep memory structure - :param fails: the total number of relaxation failures + :param fails: the number of failures due to an unacceptable relaxation + parameter value :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index d981262a43..1a5c7da5b4 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -17,7 +17,7 @@ Relaxation Methods ================== -This section describes user-callable functions for utilizing relaxation methods +This section describes user-callable functions for applying relaxation methods with ERKStep. For more information on relaxation Runge-Kutta methods see :numref:`ARKODE.Mathematics.Relaxation`. @@ -29,6 +29,16 @@ Enabling or Disabling Relaxation Attaches the user supplied functions for evaluating the relaxation function (``rfn``) and its Jacobian (``rjac``). + Both ``rfn`` and ``rjac`` are required and an error will be returned if only + one of the functions is ``NULL``. If both ``rfn`` and ``rjac`` are ``NULL``, + relaxation is disabled. + + When combined with fixed time step sizes, ERKStep will attempt each step + using the specified step size. If the step is successful, relaxation will be + applied, effectively modifying the step size for the current step. If the + step fails or applying relaxation fails, :c:func:`ERKStepEvolve` will + return with an error. + :param arkode_mem: the ERKStep memory structure :param rfn: the user-defined function to compute the relaxation function :math:`\xi(y)` @@ -37,30 +47,38 @@ Enabling or Disabling Relaxation :retval ARK_SUCCESS: the function exited successfully :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` - :retval ARK_ILL_INPUT: an invalid input combination was provided see the - output error message for more details + :retval ARK_ILL_INPUT: an invalid input combination was provided (see the + output error message for more details) :retval ARK_MEM_FAIL: a memory allocation failed - .. note:: + .. warning:: - If both ``rfn = rjac = NULL`` relaxation is disabled. + Applying relaxation requires using a method of at least second order with + :math:`b_i \geq 0`. If these conditions are not satisfied, + :c:func:`ERKStepEvolve` will return with an error during initialization. .. versionadded:: 5.6.0 Optional Input Functions ------------------------ -This section describes optional input functions used to control the relaxation -method. +This section describes optional input functions used to control applying +relaxation. -.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +.. c:function:: int ERKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) - Sets the step size reduction factor applied after a failed relaxation solve. - The default value is 0.25. Input values :math:`\geq 1` will result in the + Sets the factor :math:`\mathcal{B}` used in determining an acceptable value + of the relaxation parameter, :math:`r`. + + If :math:`|r - 1| > \mathcal{B} h_n`, the value of :math:`r` is considered + unacceptable and the step will be repeated with a smaller step size + (determined by :c:func:`ERKStepSetRelaxEtaFail`). + + The default value is 0.5. Input values :math:`\leq 0` will result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param eta_rf: the step size reduction factor + :param bound_factor: the factor used to accept the relaxation parameter value :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -69,16 +87,15 @@ method. .. versionadded:: 5.6.0 -.. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) +.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) + + Sets the step size reduction factor after a failed relaxation application. - Sets the smallest acceptable value for the relaxation parameter. Values - smaller than the lower bound will result in a relaxation solve failure and - the step will be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default value is 0.8. Input values - :math:`\geq 1` will result in the default value being used. + The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param lower: the relaxation parameter lower bound + :param eta_rf: the step size reduction factor :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -89,12 +106,15 @@ method. .. c:function:: int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) - Sets the maximum number relaxation failures allowed in a single step attempt - before the integration is halted with an error. The default value is 10. - Input values :math:`\leq 0` will result in the default value being used. + Sets the maximum number of times applying relaxation can fail within a step + attempt before the integration is halted with an error. + + The default value is 10. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ERKStep memory structure - :param max_iters: the maximum number relaxtion failures allowed in a step + :param max_fails: the maximum number of failed relaxation applications + allowed in a step :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -106,12 +126,15 @@ method. .. c:function:: int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters) Sets the maximum number of nonlinear iterations allowed when solving for the - relaxation parameter. If the maximum number of iterations is reached before - meeting the solve tolerance (determined by :c:func:`ERKStepSetRelaxResTol` - and :c:func:`ERKStepSetRelaxTol`), the step will be repeated with a smaller - step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). The default - value is 10. Input values :math:`\leq 0` will result in the default value - being used. + relaxation parameter. + + If the maximum number of iterations is reached before meeting the solve + tolerance (determined by :c:func:`ERKStepSetRelaxResTol` and + :c:func:`ERKStepSetRelaxTol`), the step will be repeated with a smaller + step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). + + The default value is 10. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ERKStep memory structure :param max_iters: the maximum number of solver iterations allowed @@ -126,29 +149,34 @@ method. .. c:function:: int ERKStepSetRelaxSolver(void* arkode_mem, ARKRelaxSolver solver) Sets the nonlinear solver method used to compute the relaxation parameter. + The default value is ``ARK_RELAX_NEWTON``. :param arkode_mem: the ERKStep memory structure - :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT``, - ``ARK_RELAX_NEWTON``, or ``ARK_RELAX_FIXEDPOINT`` + :param solver: the nonlinear solver to use: ``ARK_RELAX_BRENT`` or + ``ARK_RELAX_NEWTON`` :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was ``NULL`` + :retval ARK_ILL_INPUT: an invalid solver option was provided .. versionadded:: 5.6.0 .. c:function:: int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol) - Sets the nonlinear solver residual tolerance to use when computing the - relaxation parameter. If the residual or solution tolerance (see - :c:func:`ERKStepSetRelaxMaxIter`) is not reached within the maximum number of - iterations (determined by :c:func:`ERKStepSetRelaxMaxIters`), the step will - be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default value is :math:`4 \epsilon` - where :math:`\epsilon` is floating-point precision. Input values - :math:`\leq 0.0` will result in the default value being used. + Sets the nonlinear solver residual tolerance to use when solving + :eq:`ARKODE_RELAX_NLS`. + + If the residual or solution tolerance (see :c:func:`ERKStepSetRelaxMaxIter`) + is not reached within the maximum number of iterations (determined by + :c:func:`ERKStepSetRelaxMaxIters`), the step will be repeated with a smaller + step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). + + The default value is :math:`4 \epsilon` where :math:`\epsilon` is + floating-point precision. Input values :math:`\leq 0` will result in the + default value being used. :param arkode_mem: the ERKStep memory structure :param res_tol: the nonlinear solver residual tolerance to use @@ -162,36 +190,23 @@ method. .. c:function:: int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) - Sets the nonlinear solver relative and absolute tolerance on :math:`r`. If - the residual or solution tolerance is not reached within the maximum - number of iterations (determined by :c:func:`ERKStepSetRelaxMaxIters`), the - step will be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default relative and absolute - tolerances are :math:`4 \epsilon` and :math:`10^{-14}`, respectively, where - :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0.0` - will result in the default value being used. - - :param arkode_mem: the ERKStep memory structure - :param rel_tol: the nonlinear solver relative solution tolerance to use - :param rel_tol: the nonlinear solver absolute solution tolerance to use - - :retval ARK_SUCCESS: the value was successfully set - :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` - :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was - ``NULL`` + Sets the nonlinear solver relative and absolute tolerance on changes in + :math:`r` when solving :eq:`ARKODE_RELAX_NLS`. - .. versionadded:: 5.6.0 -.. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) + If the residual (see :c:func:`ERKStepSetRelaxResTol`) or solution tolerance + is not reached within the maximum number of iterations (determined by + :c:func:`ERKStepSetRelaxMaxIters`), the step will be repeated with a smaller + step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). - Sets the largest acceptable value for the relaxation parameter. Values - larger than the upper bound will result in a relaxation solve failure and - the step will be repeated with a smaller step size (determined by - :c:func:`ERKStepSetRelaxEtaFail`). The default value is 1.2. Input values - :math:`\leq 1` will result in the default value being used. + The default relative and absolute tolerances are :math:`4 \epsilon` and + :math:`10^{-14}`, respectively, where :math:`\epsilon` is floating-point + precision. Input values :math:`\leq 0` will result in the default value being + used. :param arkode_mem: the ERKStep memory structure - :param eta_rf: the relaxation parameter upper bound + :param rel_tol: the nonlinear solver relative solution tolerance to use + :param abs_tol: the nonlinear solver absolute solution tolerance to use :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -200,6 +215,7 @@ method. .. versionadded:: 5.6.0 + Optional Output Functions ------------------------- @@ -236,10 +252,30 @@ about the performance of the relaxation method. .. c:function:: int ERKStepGetNumRelaxFails(void* arkode_mem, long int* fails) - Get the total number of relaxation failures. + Get the total number of times applying relaxation failed. + + The counter includes the sum of the number of nonlinear solver failure + (see :c:func:`ERKStepGetNumRelaxSolveFails`) and the number of failures due + an unacceptable relaxation value (see :c:func:`ERKStepSetRelaxBoundFactor`). + + :param arkode_mem: the ERKStep memory structure + :param fails: the total number of failed relaxation attempts + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` + + .. versionadded:: 5.6.0 + + +.. c:function:: int ERKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) + + Get the number of times the relaxation parameter as deemed unacceptable. :param arkode_mem: the ERKStep memory structure - :param fails: the total number of relaxation failures + :param fails: the number of failures due to an unacceptable relaxation + parameter value :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` From 6f12a96e2cfb43a26c08fc08b7260dbb89ef2333 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 06:48:46 -0700 Subject: [PATCH 086/111] regenerate f2003 --- src/arkode/fmod/farkode_arkstep_mod.c | 42 ++++++---- src/arkode/fmod/farkode_arkstep_mod.f90 | 104 +++++++++++++++--------- src/arkode/fmod/farkode_erkstep_mod.c | 42 ++++++---- src/arkode/fmod/farkode_erkstep_mod.f90 | 104 +++++++++++++++--------- src/arkode/fmod/farkode_mod.f90 | 3 +- src/arkode/fmod/farkode_mristep_mod.c | 14 ++++ src/arkode/fmod/farkode_mristep_mod.f90 | 26 ++++++ src/cvode/fmod/fcvode_mod.c | 14 ++++ src/cvode/fmod/fcvode_mod.f90 | 26 ++++++ src/cvodes/fmod/fcvodes_mod.c | 14 ++++ src/cvodes/fmod/fcvodes_mod.f90 | 26 ++++++ 11 files changed, 307 insertions(+), 108 deletions(-) diff --git a/src/arkode/fmod/farkode_arkstep_mod.c b/src/arkode/fmod/farkode_arkstep_mod.c index 246aa79852..fc68746a42 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.c +++ b/src/arkode/fmod/farkode_arkstep_mod.c @@ -1089,6 +1089,20 @@ SWIGEXPORT int _wrap_FARKStepSetMaxStep(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FARKStepSetInterpolateStopTime(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ARKStepSetInterpolateStopTime(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKStepSetStopTime(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; @@ -2461,7 +2475,7 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJ } -SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FARKStepSetRelaxBoundFactor(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -2469,13 +2483,13 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ARKStepSetRelaxEtaFail(arg1,arg2); + result = (int)ARKStepSetRelaxBoundFactor(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FARKStepSetRelaxLowerBound(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -2483,7 +2497,7 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxLowerBound(void *farg1, double const *farg2 arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ARKStepSetRelaxLowerBound(arg1,arg2); + result = (int)ARKStepSetRelaxEtaFail(arg1,arg2); fresult = (int)(result); return fresult; } @@ -2561,21 +2575,21 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxTol(void *farg1, double const *farg2, doubl } -SWIGEXPORT int _wrap_FARKStepSetRelaxUpperBound(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FARKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; - sunrealtype arg2 ; + long *arg2 = (long *) 0 ; int result; arg1 = (void *)(farg1); - arg2 = (sunrealtype)(*farg2); - result = (int)ARKStepSetRelaxUpperBound(arg1,arg2); + arg2 = (long *)(farg2); + result = (int)ARKStepGetNumRelaxFnEvals(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FARKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FARKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -2583,13 +2597,13 @@ SWIGEXPORT int _wrap_FARKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ARKStepGetNumRelaxFnEvals(arg1,arg2); + result = (int)ARKStepGetNumRelaxJacEvals(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FARKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FARKStepGetNumRelaxFails(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -2597,13 +2611,13 @@ SWIGEXPORT int _wrap_FARKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ARKStepGetNumRelaxJacEvals(arg1,arg2); + result = (int)ARKStepGetNumRelaxFails(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FARKStepGetNumRelaxFails(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FARKStepGetNumRelaxBoundFails(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -2611,7 +2625,7 @@ SWIGEXPORT int _wrap_FARKStepGetNumRelaxFails(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ARKStepGetNumRelaxFails(arg1,arg2); + result = (int)ARKStepGetNumRelaxBoundFails(arg1,arg2); fresult = (int)(result); return fresult; } diff --git a/src/arkode/fmod/farkode_arkstep_mod.f90 b/src/arkode/fmod/farkode_arkstep_mod.f90 index fd3ce6edc9..67be97b821 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.f90 +++ b/src/arkode/fmod/farkode_arkstep_mod.f90 @@ -119,6 +119,7 @@ module farkode_arkstep_mod public :: FARKStepSetInitStep public :: FARKStepSetMinStep public :: FARKStepSetMaxStep + public :: FARKStepSetInterpolateStopTime public :: FARKStepSetStopTime public :: FARKStepClearStopTime public :: FARKStepSetFixedStep @@ -213,17 +214,17 @@ module farkode_arkstep_mod public :: FARKStepPrintMem public :: FARKStepCreateMRIStepInnerStepper public :: FARKStepSetRelaxFn + public :: FARKStepSetRelaxBoundFactor public :: FARKStepSetRelaxEtaFail - public :: FARKStepSetRelaxLowerBound public :: FARKStepSetRelaxMaxFails public :: FARKStepSetRelaxMaxIters public :: FARKStepSetRelaxSolver public :: FARKStepSetRelaxResTol public :: FARKStepSetRelaxTol - public :: FARKStepSetRelaxUpperBound public :: FARKStepGetNumRelaxFnEvals public :: FARKStepGetNumRelaxJacEvals public :: FARKStepGetNumRelaxFails + public :: FARKStepGetNumRelaxBoundFails public :: FARKStepGetNumRelaxSolveFails public :: FARKStepGetNumRelaxSolveIters @@ -774,6 +775,15 @@ function swigc_FARKStepSetMaxStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKStepSetInterpolateStopTime(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetInterpolateStopTime") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FARKStepSetStopTime(farg1, farg2) & bind(C, name="_wrap_FARKStepSetStopTime") & result(fresult) @@ -1654,8 +1664,8 @@ function swigc_FARKStepSetRelaxFn(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & -bind(C, name="_wrap_FARKStepSetRelaxEtaFail") & +function swigc_FARKStepSetRelaxBoundFactor(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxBoundFactor") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1663,8 +1673,8 @@ function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FARKStepSetRelaxLowerBound(farg1, farg2) & -bind(C, name="_wrap_FARKStepSetRelaxLowerBound") & +function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxEtaFail") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1718,15 +1728,6 @@ function swigc_FARKStepSetRelaxTol(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FARKStepSetRelaxUpperBound(farg1, farg2) & -bind(C, name="_wrap_FARKStepSetRelaxUpperBound") & -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_FARKStepGetNumRelaxFnEvals(farg1, farg2) & bind(C, name="_wrap_FARKStepGetNumRelaxFnEvals") & result(fresult) @@ -1754,6 +1755,15 @@ function swigc_FARKStepGetNumRelaxFails(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FARKStepGetNumRelaxBoundFails(farg1, farg2) & +bind(C, name="_wrap_FARKStepGetNumRelaxBoundFails") & +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_FARKStepGetNumRelaxSolveFails(farg1, farg2) & bind(C, name="_wrap_FARKStepGetNumRelaxSolveFails") & result(fresult) @@ -2791,6 +2801,22 @@ function FARKStepSetMaxStep(arkode_mem, hmax) & swig_result = fresult end function +function FARKStepSetInterpolateStopTime(arkode_mem, interp) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: interp +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = interp +fresult = swigc_FARKStepSetInterpolateStopTime(farg1, farg2) +swig_result = fresult +end function + function FARKStepSetStopTime(arkode_mem, tstop) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -4397,35 +4423,35 @@ function FARKStepSetRelaxFn(arkode_mem, rfn, rjac) & swig_result = fresult end function -function FARKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +function FARKStepSetRelaxBoundFactor(arkode_mem, bound_factor) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: eta_rf +real(C_DOUBLE), intent(in) :: bound_factor integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = eta_rf -fresult = swigc_FARKStepSetRelaxEtaFail(farg1, farg2) +farg2 = bound_factor +fresult = swigc_FARKStepSetRelaxBoundFactor(farg1, farg2) swig_result = fresult end function -function FARKStepSetRelaxLowerBound(arkode_mem, lower) & +function FARKStepSetRelaxEtaFail(arkode_mem, eta_rf) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: lower +real(C_DOUBLE), intent(in) :: eta_rf integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = lower -fresult = swigc_FARKStepSetRelaxLowerBound(farg1, farg2) +farg2 = eta_rf +fresult = swigc_FARKStepSetRelaxEtaFail(farg1, farg2) swig_result = fresult end function @@ -4512,22 +4538,6 @@ function FARKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & swig_result = fresult end function -function FARKStepSetRelaxUpperBound(arkode_mem, upper) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: upper -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = arkode_mem -farg2 = upper -fresult = swigc_FARKStepSetRelaxUpperBound(farg1, farg2) -swig_result = fresult -end function - function FARKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -4576,6 +4586,22 @@ function FARKStepGetNumRelaxFails(arkode_mem, relax_fails) & swig_result = fresult end function +function FARKStepGetNumRelaxBoundFails(arkode_mem, fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(fails(1)) +fresult = swigc_FARKStepGetNumRelaxBoundFails(farg1, farg2) +swig_result = fresult +end function + function FARKStepGetNumRelaxSolveFails(arkode_mem, fails) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod/farkode_erkstep_mod.c b/src/arkode/fmod/farkode_erkstep_mod.c index a60eb9d62c..76687fb692 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.c +++ b/src/arkode/fmod/farkode_erkstep_mod.c @@ -757,6 +757,20 @@ SWIGEXPORT int _wrap_FERKStepSetMaxStep(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FERKStepSetInterpolateStopTime(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)ERKStepSetInterpolateStopTime(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FERKStepSetStopTime(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; @@ -1364,7 +1378,7 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJ } -SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FERKStepSetRelaxBoundFactor(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -1372,13 +1386,13 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ERKStepSetRelaxEtaFail(arg1,arg2); + result = (int)ERKStepSetRelaxBoundFactor(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FERKStepSetRelaxLowerBound(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -1386,7 +1400,7 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxLowerBound(void *farg1, double const *farg2 arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ERKStepSetRelaxLowerBound(arg1,arg2); + result = (int)ERKStepSetRelaxEtaFail(arg1,arg2); fresult = (int)(result); return fresult; } @@ -1464,21 +1478,21 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxTol(void *farg1, double const *farg2, doubl } -SWIGEXPORT int _wrap_FERKStepSetRelaxUpperBound(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FERKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; - sunrealtype arg2 ; + long *arg2 = (long *) 0 ; int result; arg1 = (void *)(farg1); - arg2 = (sunrealtype)(*farg2); - result = (int)ERKStepSetRelaxUpperBound(arg1,arg2); + arg2 = (long *)(farg2); + result = (int)ERKStepGetNumRelaxFnEvals(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FERKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FERKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -1486,13 +1500,13 @@ SWIGEXPORT int _wrap_FERKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ERKStepGetNumRelaxFnEvals(arg1,arg2); + result = (int)ERKStepGetNumRelaxJacEvals(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FERKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FERKStepGetNumRelaxFails(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -1500,13 +1514,13 @@ SWIGEXPORT int _wrap_FERKStepGetNumRelaxJacEvals(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ERKStepGetNumRelaxJacEvals(arg1,arg2); + result = (int)ERKStepGetNumRelaxFails(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FERKStepGetNumRelaxFails(void *farg1, long *farg2) { +SWIGEXPORT int _wrap_FERKStepGetNumRelaxBoundFails(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; long *arg2 = (long *) 0 ; @@ -1514,7 +1528,7 @@ SWIGEXPORT int _wrap_FERKStepGetNumRelaxFails(void *farg1, long *farg2) { arg1 = (void *)(farg1); arg2 = (long *)(farg2); - result = (int)ERKStepGetNumRelaxFails(arg1,arg2); + result = (int)ERKStepGetNumRelaxBoundFails(arg1,arg2); fresult = (int)(result); return fresult; } diff --git a/src/arkode/fmod/farkode_erkstep_mod.f90 b/src/arkode/fmod/farkode_erkstep_mod.f90 index 579b64e302..fd8fef7ab8 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.f90 +++ b/src/arkode/fmod/farkode_erkstep_mod.f90 @@ -84,6 +84,7 @@ module farkode_erkstep_mod public :: FERKStepSetInitStep public :: FERKStepSetMinStep public :: FERKStepSetMaxStep + public :: FERKStepSetInterpolateStopTime public :: FERKStepSetStopTime public :: FERKStepClearStopTime public :: FERKStepSetFixedStep @@ -126,17 +127,17 @@ module farkode_erkstep_mod public :: FERKStepFree public :: FERKStepPrintMem public :: FERKStepSetRelaxFn + public :: FERKStepSetRelaxBoundFactor public :: FERKStepSetRelaxEtaFail - public :: FERKStepSetRelaxLowerBound public :: FERKStepSetRelaxMaxFails public :: FERKStepSetRelaxMaxIters public :: FERKStepSetRelaxSolver public :: FERKStepSetRelaxResTol public :: FERKStepSetRelaxTol - public :: FERKStepSetRelaxUpperBound public :: FERKStepGetNumRelaxFnEvals public :: FERKStepGetNumRelaxJacEvals public :: FERKStepGetNumRelaxFails + public :: FERKStepGetNumRelaxBoundFails public :: FERKStepGetNumRelaxSolveFails public :: FERKStepGetNumRelaxSolveIters @@ -475,6 +476,15 @@ function swigc_FERKStepSetMaxStep(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FERKStepSetInterpolateStopTime(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetInterpolateStopTime") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FERKStepSetStopTime(farg1, farg2) & bind(C, name="_wrap_FERKStepSetStopTime") & result(fresult) @@ -868,8 +878,8 @@ function swigc_FERKStepSetRelaxFn(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & -bind(C, name="_wrap_FERKStepSetRelaxEtaFail") & +function swigc_FERKStepSetRelaxBoundFactor(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxBoundFactor") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -877,8 +887,8 @@ function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FERKStepSetRelaxLowerBound(farg1, farg2) & -bind(C, name="_wrap_FERKStepSetRelaxLowerBound") & +function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxEtaFail") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -932,15 +942,6 @@ function swigc_FERKStepSetRelaxTol(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FERKStepSetRelaxUpperBound(farg1, farg2) & -bind(C, name="_wrap_FERKStepSetRelaxUpperBound") & -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_FERKStepGetNumRelaxFnEvals(farg1, farg2) & bind(C, name="_wrap_FERKStepGetNumRelaxFnEvals") & result(fresult) @@ -968,6 +969,15 @@ function swigc_FERKStepGetNumRelaxFails(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FERKStepGetNumRelaxBoundFails(farg1, farg2) & +bind(C, name="_wrap_FERKStepGetNumRelaxBoundFails") & +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_FERKStepGetNumRelaxSolveFails(farg1, farg2) & bind(C, name="_wrap_FERKStepGetNumRelaxSolveFails") & result(fresult) @@ -1621,6 +1631,22 @@ function FERKStepSetMaxStep(arkode_mem, hmax) & swig_result = fresult end function +function FERKStepSetInterpolateStopTime(arkode_mem, interp) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: interp +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = interp +fresult = swigc_FERKStepSetInterpolateStopTime(farg1, farg2) +swig_result = fresult +end function + function FERKStepSetStopTime(arkode_mem, tstop) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -2339,35 +2365,35 @@ function FERKStepSetRelaxFn(arkode_mem, rfn, rjac) & swig_result = fresult end function -function FERKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +function FERKStepSetRelaxBoundFactor(arkode_mem, bound_factor) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: eta_rf +real(C_DOUBLE), intent(in) :: bound_factor integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = eta_rf -fresult = swigc_FERKStepSetRelaxEtaFail(farg1, farg2) +farg2 = bound_factor +fresult = swigc_FERKStepSetRelaxBoundFactor(farg1, farg2) swig_result = fresult end function -function FERKStepSetRelaxLowerBound(arkode_mem, lower) & +function FERKStepSetRelaxEtaFail(arkode_mem, eta_rf) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: lower +real(C_DOUBLE), intent(in) :: eta_rf integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = lower -fresult = swigc_FERKStepSetRelaxLowerBound(farg1, farg2) +farg2 = eta_rf +fresult = swigc_FERKStepSetRelaxEtaFail(farg1, farg2) swig_result = fresult end function @@ -2454,22 +2480,6 @@ function FERKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & swig_result = fresult end function -function FERKStepSetRelaxUpperBound(arkode_mem, upper) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: upper -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = arkode_mem -farg2 = upper -fresult = swigc_FERKStepSetRelaxUpperBound(farg1, farg2) -swig_result = fresult -end function - function FERKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -2518,6 +2528,22 @@ function FERKStepGetNumRelaxFails(arkode_mem, relax_fails) & swig_result = fresult end function +function FERKStepGetNumRelaxBoundFails(arkode_mem, fails) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_LONG), dimension(*), target, intent(inout) :: fails +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = arkode_mem +farg2 = c_loc(fails(1)) +fresult = swigc_FERKStepGetNumRelaxBoundFails(farg1, farg2) +swig_result = fresult +end function + function FERKStepGetNumRelaxSolveFails(arkode_mem, fails) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod/farkode_mod.f90 b/src/arkode/fmod/farkode_mod.f90 index f4eb249a3a..b0f26eda24 100644 --- a/src/arkode/fmod/farkode_mod.f90 +++ b/src/arkode/fmod/farkode_mod.f90 @@ -108,11 +108,10 @@ module farkode_mod ! typedef enum ARKRelaxSolver enum, bind(c) enumerator :: ARK_RELAX_BRENT - enumerator :: ARK_RELAX_FIXEDPOINT enumerator :: ARK_RELAX_NEWTON end enum integer, parameter, public :: ARKRelaxSolver = kind(ARK_RELAX_BRENT) - public :: ARK_RELAX_BRENT, ARK_RELAX_FIXEDPOINT, ARK_RELAX_NEWTON + public :: ARK_RELAX_BRENT, ARK_RELAX_NEWTON public :: FARKBandPrecInit public :: FARKBandPrecGetWorkSpace public :: FARKBandPrecGetNumRhsEvals diff --git a/src/arkode/fmod/farkode_mristep_mod.c b/src/arkode/fmod/farkode_mristep_mod.c index fcd9d093b5..8ba7ad5296 100644 --- a/src/arkode/fmod/farkode_mristep_mod.c +++ b/src/arkode/fmod/farkode_mristep_mod.c @@ -1061,6 +1061,20 @@ SWIGEXPORT int _wrap_FMRIStepSetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FMRIStepSetInterpolateStopTime(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)MRIStepSetInterpolateStopTime(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FMRIStepClearStopTime(void *farg1) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod/farkode_mristep_mod.f90 b/src/arkode/fmod/farkode_mristep_mod.f90 index 2c0b32a367..b80ca727f8 100644 --- a/src/arkode/fmod/farkode_mristep_mod.f90 +++ b/src/arkode/fmod/farkode_mristep_mod.f90 @@ -160,6 +160,7 @@ module farkode_mristep_mod public :: FMRIStepSetNonlinConvCoef public :: FMRIStepSetMaxHnilWarns public :: FMRIStepSetStopTime + public :: FMRIStepSetInterpolateStopTime public :: FMRIStepClearStopTime public :: FMRIStepSetFixedStep public :: FMRIStepSetRootDirection @@ -734,6 +735,15 @@ function swigc_FMRIStepSetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FMRIStepSetInterpolateStopTime(farg1, farg2) & +bind(C, name="_wrap_FMRIStepSetInterpolateStopTime") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FMRIStepClearStopTime(farg1) & bind(C, name="_wrap_FMRIStepClearStopTime") & result(fresult) @@ -2313,6 +2323,22 @@ function FMRIStepSetStopTime(arkode_mem, tstop) & swig_result = fresult end function +function FMRIStepSetInterpolateStopTime(arkode_mem, interp) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: interp +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = interp +fresult = swigc_FMRIStepSetInterpolateStopTime(farg1, farg2) +swig_result = fresult +end function + function FMRIStepClearStopTime(arkode_mem) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/cvode/fmod/fcvode_mod.c b/src/cvode/fmod/fcvode_mod.c index db7e75ce06..5b63d2b605 100644 --- a/src/cvode/fmod/fcvode_mod.c +++ b/src/cvode/fmod/fcvode_mod.c @@ -628,6 +628,20 @@ SWIGEXPORT int _wrap_FCVodeSetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FCVodeSetInterpolateStopTime(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)CVodeSetInterpolateStopTime(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FCVodeClearStopTime(void *farg1) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/cvode/fmod/fcvode_mod.f90 b/src/cvode/fmod/fcvode_mod.f90 index d107e94c9a..738f334a3f 100644 --- a/src/cvode/fmod/fcvode_mod.f90 +++ b/src/cvode/fmod/fcvode_mod.f90 @@ -103,6 +103,7 @@ module fcvode_mod public :: FCVodeSetNonlinearSolver public :: FCVodeSetStabLimDet public :: FCVodeSetStopTime + public :: FCVodeSetInterpolateStopTime public :: FCVodeClearStopTime public :: FCVodeSetUseIntegratorFusedKernels public :: FCVodeSetUserData @@ -471,6 +472,15 @@ function swigc_FCVodeSetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FCVodeSetInterpolateStopTime(farg1, farg2) & +bind(C, name="_wrap_FCVodeSetInterpolateStopTime") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FCVodeClearStopTime(farg1) & bind(C, name="_wrap_FCVodeClearStopTime") & result(fresult) @@ -1823,6 +1833,22 @@ function FCVodeSetStopTime(cvode_mem, tstop) & swig_result = fresult end function +function FCVodeSetInterpolateStopTime(cvode_mem, interp) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: cvode_mem +integer(C_INT), intent(in) :: interp +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = cvode_mem +farg2 = interp +fresult = swigc_FCVodeSetInterpolateStopTime(farg1, farg2) +swig_result = fresult +end function + function FCVodeClearStopTime(cvode_mem) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/cvodes/fmod/fcvodes_mod.c b/src/cvodes/fmod/fcvodes_mod.c index 1fa4e6bd9f..7c5b85e0af 100644 --- a/src/cvodes/fmod/fcvodes_mod.c +++ b/src/cvodes/fmod/fcvodes_mod.c @@ -702,6 +702,20 @@ SWIGEXPORT int _wrap_FCVodeSetStopTime(void *farg1, double const *farg2) { } +SWIGEXPORT int _wrap_FCVodeSetInterpolateStopTime(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)CVodeSetInterpolateStopTime(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FCVodeClearStopTime(void *farg1) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/cvodes/fmod/fcvodes_mod.f90 b/src/cvodes/fmod/fcvodes_mod.f90 index 39d8868e2f..505ed54f8a 100644 --- a/src/cvodes/fmod/fcvodes_mod.f90 +++ b/src/cvodes/fmod/fcvodes_mod.f90 @@ -133,6 +133,7 @@ module fcvodes_mod public :: FCVodeSetNonlinearSolver public :: FCVodeSetStabLimDet public :: FCVodeSetStopTime + public :: FCVodeSetInterpolateStopTime public :: FCVodeClearStopTime public :: FCVodeSetUserData public :: FCVodeSetEtaFixedStepBounds @@ -645,6 +646,15 @@ function swigc_FCVodeSetStopTime(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FCVodeSetInterpolateStopTime(farg1, farg2) & +bind(C, name="_wrap_FCVodeSetInterpolateStopTime") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +integer(C_INT), intent(in) :: farg2 +integer(C_INT) :: fresult +end function + function swigc_FCVodeClearStopTime(farg1) & bind(C, name="_wrap_FCVodeClearStopTime") & result(fresult) @@ -3229,6 +3239,22 @@ function FCVodeSetStopTime(cvode_mem, tstop) & swig_result = fresult end function +function FCVodeSetInterpolateStopTime(cvode_mem, interp) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: cvode_mem +integer(C_INT), intent(in) :: interp +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = cvode_mem +farg2 = interp +fresult = swigc_FCVodeSetInterpolateStopTime(farg1, farg2) +swig_result = fresult +end function + function FCVodeClearStopTime(cvode_mem) & result(swig_result) use, intrinsic :: ISO_C_BINDING From 79f3ea5aedb413ff2c103ec6d0fdaa7d617bc998 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 14:40:36 -0700 Subject: [PATCH 087/111] revert change to bound factor --- include/arkode/arkode_arkstep.h | 6 ++- include/arkode/arkode_erkstep.h | 6 ++- src/arkode/arkode_arkstep_io.c | 13 ++++-- src/arkode/arkode_erkstep_io.c | 13 ++++-- src/arkode/arkode_relaxation.c | 53 ++++++++++++++++--------- src/arkode/arkode_relaxation_impl.h | 21 +++++----- src/arkode/fmod/farkode_arkstep_mod.c | 22 ++++++++-- src/arkode/fmod/farkode_arkstep_mod.f90 | 52 ++++++++++++++++++------ src/arkode/fmod/farkode_erkstep_mod.c | 22 ++++++++-- src/arkode/fmod/farkode_erkstep_mod.f90 | 52 ++++++++++++++++++------ 10 files changed, 187 insertions(+), 73 deletions(-) diff --git a/include/arkode/arkode_arkstep.h b/include/arkode/arkode_arkstep.h index a144ebe905..a4951bb888 100644 --- a/include/arkode/arkode_arkstep.h +++ b/include/arkode/arkode_arkstep.h @@ -478,10 +478,10 @@ SUNDIALS_EXPORT int ARKStepCreateMRIStepInnerStepper(void *arkode_mem, /* Relaxation functions */ SUNDIALS_EXPORT int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); -SUNDIALS_EXPORT int ARKStepSetRelaxBoundFactor(void* arkode_mem, - sunrealtype bound_factor); SUNDIALS_EXPORT int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); +SUNDIALS_EXPORT int ARKStepSetRelaxLowerBound(void* arkode_mem, + sunrealtype lower); SUNDIALS_EXPORT int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ARKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ARKStepSetRelaxSolver(void* arkode_mem, @@ -490,6 +490,8 @@ SUNDIALS_EXPORT int ARKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); SUNDIALS_EXPORT int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); +SUNDIALS_EXPORT int ARKStepSetRelaxUpperBound(void* arkode_mem, + sunrealtype upper); SUNDIALS_EXPORT int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ARKStepGetNumRelaxJacEvals(void* arkode_mem, diff --git a/include/arkode/arkode_erkstep.h b/include/arkode/arkode_erkstep.h index 7cf11406dc..9f5b56f072 100644 --- a/include/arkode/arkode_erkstep.h +++ b/include/arkode/arkode_erkstep.h @@ -265,10 +265,10 @@ SUNDIALS_EXPORT void ERKStepPrintMem(void* arkode_mem, FILE* outfile); /* Relaxation functions */ SUNDIALS_EXPORT int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac); -SUNDIALS_EXPORT int ERKStepSetRelaxBoundFactor(void* arkode_mem, - sunrealtype bound_factor); SUNDIALS_EXPORT int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf); +SUNDIALS_EXPORT int ERKStepSetRelaxLowerBound(void* arkode_mem, + sunrealtype lower); SUNDIALS_EXPORT int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails); SUNDIALS_EXPORT int ERKStepSetRelaxMaxIters(void* arkode_mem, int max_iters); SUNDIALS_EXPORT int ERKStepSetRelaxSolver(void* arkode_mem, @@ -277,6 +277,8 @@ SUNDIALS_EXPORT int ERKStepSetRelaxResTol(void* arkode_mem, sunrealtype res_tol); SUNDIALS_EXPORT int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); +SUNDIALS_EXPORT int ERKStepSetRelaxUpperBound(void* arkode_mem, + sunrealtype upper); SUNDIALS_EXPORT int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); SUNDIALS_EXPORT int ERKStepGetNumRelaxJacEvals(void* arkode_mem, diff --git a/src/arkode/arkode_arkstep_io.c b/src/arkode/arkode_arkstep_io.c index 2391e7ba26..50f9182a75 100644 --- a/src/arkode/arkode_arkstep_io.c +++ b/src/arkode/arkode_arkstep_io.c @@ -272,14 +272,14 @@ int ARKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) arkStep_RelaxDeltaE, arkStep_GetOrder); } -int ARKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) +int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) { - return arkRelaxSetBoundFactor(arkode_mem, bound_factor); + return arkRelaxSetEtaFail(arkode_mem, eta_rf); } -int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) { - return arkRelaxSetEtaFail(arkode_mem, eta_rf); + return arkRelaxSetLowerBound(arkode_mem, lower); } int ARKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) @@ -308,6 +308,11 @@ int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); } +int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) +{ + return arkRelaxSetUpperBound(arkode_mem, upper); +} + int ARKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) { return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); diff --git a/src/arkode/arkode_erkstep_io.c b/src/arkode/arkode_erkstep_io.c index 2aee8caf9b..34bb7d46c2 100644 --- a/src/arkode/arkode_erkstep_io.c +++ b/src/arkode/arkode_erkstep_io.c @@ -163,14 +163,14 @@ int ERKStepSetRelaxFn(void* arkode_mem, ARKRelaxFn rfn, ARKRelaxJacFn rjac) erkStep_RelaxDeltaE, erkStep_GetOrder); } -int ERKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) +int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) { - return arkRelaxSetBoundFactor(arkode_mem, bound_factor); + return arkRelaxSetEtaFail(arkode_mem, eta_rf); } -int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) { - return arkRelaxSetEtaFail(arkode_mem, eta_rf); + return arkRelaxSetLowerBound(arkode_mem, lower); } int ERKStepSetRelaxMaxFails(void* arkode_mem, int max_fails) @@ -199,6 +199,11 @@ int ERKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, return arkRelaxSetTol(arkode_mem, rel_tol, abs_tol); } +int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) +{ + return arkRelaxSetUpperBound(arkode_mem, upper); +} + int ERKStepGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals) { return arkRelaxGetNumRelaxFnEvals(arkode_mem, r_evals); diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 1e43162df5..f8f5f65006 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -376,8 +376,8 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, } /* Check for bad relaxation value */ - if (SUNRabs(relax_mem->relax_param - ONE) > - relax_mem->bound_factor * SUNRabs(ark_mem->h)) + if (ark_mem->relax_mem->relax_param < relax_mem->lower_bound || + ark_mem->relax_mem->relax_param > relax_mem->upper_bound) { relax_mem->bound_fails++; return ARK_RELAX_SOLVE_RECV; @@ -400,34 +400,34 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, * Set functions * ---------------------------------------------------------------------------*/ -int arkRelaxSetBoundFactor(void* arkode_mem, sunrealtype bound_factor) +int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetBoundFactor", &ark_mem, + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetEtaFail", &ark_mem, &relax_mem); if (retval) return retval; - if (bound_factor > ZERO) { relax_mem->bound_factor = bound_factor; } - else { relax_mem->bound_factor = ARK_RELAX_DEFAULT_BOUND_FACTOR; } + if (eta_fail > ZERO && eta_fail < ONE) { relax_mem->eta_fail = eta_fail; } + else { relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; } return ARK_SUCCESS; } -int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail) +int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower) { int retval; ARKodeMem ark_mem; ARKodeRelaxMem relax_mem; - retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetEtaFail", &ark_mem, + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetLowerBound", &ark_mem, &relax_mem); if (retval) return retval; - if (eta_fail > ZERO && eta_fail < ONE) { relax_mem->eta_fail = eta_fail; } - else { relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; } + if (lower > ZERO && lower < ONE) { relax_mem->lower_bound = lower; } + else { relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; } return ARK_SUCCESS; } @@ -521,6 +521,22 @@ int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) return ARK_SUCCESS; } +int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper) +{ + int retval; + ARKodeMem ark_mem; + ARKodeRelaxMem relax_mem; + + retval = arkRelaxAccessMem(arkode_mem, "arkRelaxSetUpperBound", &ark_mem, + &relax_mem); + if (retval) return retval; + + if (upper > ONE) { relax_mem->upper_bound = upper; } + else { relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; } + + return ARK_SUCCESS; +} + /* ----------------------------------------------------------------------------- * Get functions * ---------------------------------------------------------------------------*/ @@ -713,14 +729,15 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, memset(ark_mem->relax_mem, 0, sizeof(struct ARKodeRelaxMemRec)); /* Set defaults */ - ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; - ark_mem->relax_mem->bound_factor = ARK_RELAX_DEFAULT_BOUND_FACTOR; - ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; - ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; - ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; - ark_mem->relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; - ark_mem->relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; - ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; + ark_mem->relax_mem->max_fails = ARK_RELAX_DEFAULT_MAX_FAILS; + ark_mem->relax_mem->lower_bound = ARK_RELAX_DEFAULT_LOWER_BOUND; + ark_mem->relax_mem->upper_bound = ARK_RELAX_DEFAULT_UPPER_BOUND; + ark_mem->relax_mem->eta_fail = ARK_RELAX_DEFAULT_ETA_FAIL; + ark_mem->relax_mem->solver = ARK_RELAX_NEWTON; + ark_mem->relax_mem->res_tol = ARK_RELAX_DEFAULT_RES_TOL; + ark_mem->relax_mem->rel_tol = ARK_RELAX_DEFAULT_REL_TOL; + ark_mem->relax_mem->abs_tol = ARK_RELAX_DEFAULT_ABS_TOL; + ark_mem->relax_mem->max_iters = ARK_RELAX_DEFAULT_MAX_ITERS; /* Initialize values */ ark_mem->relax_mem->relax_param_prev = ONE; diff --git a/src/arkode/arkode_relaxation_impl.h b/src/arkode/arkode_relaxation_impl.h index 3dd97ade7b..9a6e5b4c38 100644 --- a/src/arkode/arkode_relaxation_impl.h +++ b/src/arkode/arkode_relaxation_impl.h @@ -29,13 +29,14 @@ * Relaxation Constants * ---------------------------------------------------------------------------*/ -#define ARK_RELAX_DEFAULT_MAX_FAILS 10 -#define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) -#define ARK_RELAX_DEFAULT_REL_TOL (4 * SUN_UNIT_ROUNDOFF) -#define ARK_RELAX_DEFAULT_ABS_TOL SUN_RCONST(1.0e-14) -#define ARK_RELAX_DEFAULT_MAX_ITERS 10 -#define ARK_RELAX_DEFAULT_BOUND_FACTOR SUN_RCONST(0.5) -#define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) +#define ARK_RELAX_DEFAULT_MAX_FAILS 10 +#define ARK_RELAX_DEFAULT_RES_TOL (4 * SUN_UNIT_ROUNDOFF) +#define ARK_RELAX_DEFAULT_REL_TOL (4 * SUN_UNIT_ROUNDOFF) +#define ARK_RELAX_DEFAULT_ABS_TOL SUN_RCONST(1.0e-14) +#define ARK_RELAX_DEFAULT_MAX_ITERS 10 +#define ARK_RELAX_DEFAULT_LOWER_BOUND SUN_RCONST(0.8) +#define ARK_RELAX_DEFAULT_UPPER_BOUND SUN_RCONST(1.2) +#define ARK_RELAX_DEFAULT_ETA_FAIL SUN_RCONST(0.25) /* ----------------------------------------------------------------------------- * Relaxation Private Return Values (see arkode/arkode.h for public values) @@ -83,7 +84,8 @@ struct ARKodeRelaxMemRec sunrealtype jac; /* relaxation Jacobian value */ sunrealtype relax_param; /* current relaxation parameter value */ sunrealtype relax_param_prev; /* previous relaxation parameter value */ - sunrealtype bound_factor; /* relax param acceptance threshold */ + sunrealtype lower_bound; /* smallest allowed relaxation value */ + sunrealtype upper_bound; /* largest allowed relaxation value */ sunrealtype eta_fail; /* failed relaxation step size factor */ /* nonlinear solver settings */ @@ -111,13 +113,14 @@ int arkRelax(ARKodeMem ark_mem, int* relax_fails, sunrealtype* dsm_inout, int* nflag_out); /* User Functions */ -int arkRelaxSetBoundFactor(void* arkode_mem, sunrealtype bound_factor); int arkRelaxSetEtaFail(void* arkode_mem, sunrealtype eta_fail); +int arkRelaxSetLowerBound(void* arkode_mem, sunrealtype lower); int arkRelaxSetMaxFails(void* arkode_mem, int max_fails); int arkRelaxSetMaxIters(void* arkode_mem, int max_iters); int arkRelaxSetSolver(void* arkode_mem, ARKRelaxSolver solver); int arkRelaxSetResTol(void* arkode_mem, sunrealtype res_tol); int arkRelaxSetTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol); +int arkRelaxSetUpperBound(void* arkode_mem, sunrealtype upper); int arkRelaxGetNumRelaxFnEvals(void* arkode_mem, long int* r_evals); int arkRelaxGetNumRelaxJacEvals(void* arkode_mem, long int* j_evals); diff --git a/src/arkode/fmod/farkode_arkstep_mod.c b/src/arkode/fmod/farkode_arkstep_mod.c index fc68746a42..2ae77231a3 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.c +++ b/src/arkode/fmod/farkode_arkstep_mod.c @@ -2475,7 +2475,7 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJ } -SWIGEXPORT int _wrap_FARKStepSetRelaxBoundFactor(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -2483,13 +2483,13 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxBoundFactor(void *farg1, double const *farg arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ARKStepSetRelaxBoundFactor(arg1,arg2); + result = (int)ARKStepSetRelaxEtaFail(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FARKStepSetRelaxLowerBound(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -2497,7 +2497,7 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxEtaFail(void *farg1, double const *farg2) { arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ARKStepSetRelaxEtaFail(arg1,arg2); + result = (int)ARKStepSetRelaxLowerBound(arg1,arg2); fresult = (int)(result); return fresult; } @@ -2575,6 +2575,20 @@ SWIGEXPORT int _wrap_FARKStepSetRelaxTol(void *farg1, double const *farg2, doubl } +SWIGEXPORT int _wrap_FARKStepSetRelaxUpperBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ARKStepSetRelaxUpperBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FARKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod/farkode_arkstep_mod.f90 b/src/arkode/fmod/farkode_arkstep_mod.f90 index 67be97b821..c52006c929 100644 --- a/src/arkode/fmod/farkode_arkstep_mod.f90 +++ b/src/arkode/fmod/farkode_arkstep_mod.f90 @@ -214,13 +214,14 @@ module farkode_arkstep_mod public :: FARKStepPrintMem public :: FARKStepCreateMRIStepInnerStepper public :: FARKStepSetRelaxFn - public :: FARKStepSetRelaxBoundFactor public :: FARKStepSetRelaxEtaFail + public :: FARKStepSetRelaxLowerBound public :: FARKStepSetRelaxMaxFails public :: FARKStepSetRelaxMaxIters public :: FARKStepSetRelaxSolver public :: FARKStepSetRelaxResTol public :: FARKStepSetRelaxTol + public :: FARKStepSetRelaxUpperBound public :: FARKStepGetNumRelaxFnEvals public :: FARKStepGetNumRelaxJacEvals public :: FARKStepGetNumRelaxFails @@ -1664,8 +1665,8 @@ function swigc_FARKStepSetRelaxFn(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FARKStepSetRelaxBoundFactor(farg1, farg2) & -bind(C, name="_wrap_FARKStepSetRelaxBoundFactor") & +function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxEtaFail") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1673,8 +1674,8 @@ function swigc_FARKStepSetRelaxBoundFactor(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FARKStepSetRelaxEtaFail(farg1, farg2) & -bind(C, name="_wrap_FARKStepSetRelaxEtaFail") & +function swigc_FARKStepSetRelaxLowerBound(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxLowerBound") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1728,6 +1729,15 @@ function swigc_FARKStepSetRelaxTol(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FARKStepSetRelaxUpperBound(farg1, farg2) & +bind(C, name="_wrap_FARKStepSetRelaxUpperBound") & +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_FARKStepGetNumRelaxFnEvals(farg1, farg2) & bind(C, name="_wrap_FARKStepGetNumRelaxFnEvals") & result(fresult) @@ -4423,35 +4433,35 @@ function FARKStepSetRelaxFn(arkode_mem, rfn, rjac) & swig_result = fresult end function -function FARKStepSetRelaxBoundFactor(arkode_mem, bound_factor) & +function FARKStepSetRelaxEtaFail(arkode_mem, eta_rf) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: bound_factor +real(C_DOUBLE), intent(in) :: eta_rf integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = bound_factor -fresult = swigc_FARKStepSetRelaxBoundFactor(farg1, farg2) +farg2 = eta_rf +fresult = swigc_FARKStepSetRelaxEtaFail(farg1, farg2) swig_result = fresult end function -function FARKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +function FARKStepSetRelaxLowerBound(arkode_mem, lower) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: eta_rf +real(C_DOUBLE), intent(in) :: lower integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = eta_rf -fresult = swigc_FARKStepSetRelaxEtaFail(farg1, farg2) +farg2 = lower +fresult = swigc_FARKStepSetRelaxLowerBound(farg1, farg2) swig_result = fresult end function @@ -4538,6 +4548,22 @@ function FARKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & swig_result = fresult end function +function FARKStepSetRelaxUpperBound(arkode_mem, upper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: upper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = upper +fresult = swigc_FARKStepSetRelaxUpperBound(farg1, farg2) +swig_result = fresult +end function + function FARKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod/farkode_erkstep_mod.c b/src/arkode/fmod/farkode_erkstep_mod.c index 76687fb692..46836ba780 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.c +++ b/src/arkode/fmod/farkode_erkstep_mod.c @@ -1378,7 +1378,7 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxFn(void *farg1, ARKRelaxFn farg2, ARKRelaxJ } -SWIGEXPORT int _wrap_FERKStepSetRelaxBoundFactor(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -1386,13 +1386,13 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxBoundFactor(void *farg1, double const *farg arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ERKStepSetRelaxBoundFactor(arg1,arg2); + result = (int)ERKStepSetRelaxEtaFail(arg1,arg2); fresult = (int)(result); return fresult; } -SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { +SWIGEXPORT int _wrap_FERKStepSetRelaxLowerBound(void *farg1, double const *farg2) { int fresult ; void *arg1 = (void *) 0 ; sunrealtype arg2 ; @@ -1400,7 +1400,7 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxEtaFail(void *farg1, double const *farg2) { arg1 = (void *)(farg1); arg2 = (sunrealtype)(*farg2); - result = (int)ERKStepSetRelaxEtaFail(arg1,arg2); + result = (int)ERKStepSetRelaxLowerBound(arg1,arg2); fresult = (int)(result); return fresult; } @@ -1478,6 +1478,20 @@ SWIGEXPORT int _wrap_FERKStepSetRelaxTol(void *farg1, double const *farg2, doubl } +SWIGEXPORT int _wrap_FERKStepSetRelaxUpperBound(void *farg1, double const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + sunrealtype arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (int)ERKStepSetRelaxUpperBound(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FERKStepGetNumRelaxFnEvals(void *farg1, long *farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod/farkode_erkstep_mod.f90 b/src/arkode/fmod/farkode_erkstep_mod.f90 index fd8fef7ab8..3857ac1a7d 100644 --- a/src/arkode/fmod/farkode_erkstep_mod.f90 +++ b/src/arkode/fmod/farkode_erkstep_mod.f90 @@ -127,13 +127,14 @@ module farkode_erkstep_mod public :: FERKStepFree public :: FERKStepPrintMem public :: FERKStepSetRelaxFn - public :: FERKStepSetRelaxBoundFactor public :: FERKStepSetRelaxEtaFail + public :: FERKStepSetRelaxLowerBound public :: FERKStepSetRelaxMaxFails public :: FERKStepSetRelaxMaxIters public :: FERKStepSetRelaxSolver public :: FERKStepSetRelaxResTol public :: FERKStepSetRelaxTol + public :: FERKStepSetRelaxUpperBound public :: FERKStepGetNumRelaxFnEvals public :: FERKStepGetNumRelaxJacEvals public :: FERKStepGetNumRelaxFails @@ -878,8 +879,8 @@ function swigc_FERKStepSetRelaxFn(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FERKStepSetRelaxBoundFactor(farg1, farg2) & -bind(C, name="_wrap_FERKStepSetRelaxBoundFactor") & +function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxEtaFail") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -887,8 +888,8 @@ function swigc_FERKStepSetRelaxBoundFactor(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FERKStepSetRelaxEtaFail(farg1, farg2) & -bind(C, name="_wrap_FERKStepSetRelaxEtaFail") & +function swigc_FERKStepSetRelaxLowerBound(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxLowerBound") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -942,6 +943,15 @@ function swigc_FERKStepSetRelaxTol(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FERKStepSetRelaxUpperBound(farg1, farg2) & +bind(C, name="_wrap_FERKStepSetRelaxUpperBound") & +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_FERKStepGetNumRelaxFnEvals(farg1, farg2) & bind(C, name="_wrap_FERKStepGetNumRelaxFnEvals") & result(fresult) @@ -2365,35 +2375,35 @@ function FERKStepSetRelaxFn(arkode_mem, rfn, rjac) & swig_result = fresult end function -function FERKStepSetRelaxBoundFactor(arkode_mem, bound_factor) & +function FERKStepSetRelaxEtaFail(arkode_mem, eta_rf) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: bound_factor +real(C_DOUBLE), intent(in) :: eta_rf integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = bound_factor -fresult = swigc_FERKStepSetRelaxBoundFactor(farg1, farg2) +farg2 = eta_rf +fresult = swigc_FERKStepSetRelaxEtaFail(farg1, farg2) swig_result = fresult end function -function FERKStepSetRelaxEtaFail(arkode_mem, eta_rf) & +function FERKStepSetRelaxLowerBound(arkode_mem, lower) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -real(C_DOUBLE), intent(in) :: eta_rf +real(C_DOUBLE), intent(in) :: lower integer(C_INT) :: fresult type(C_PTR) :: farg1 real(C_DOUBLE) :: farg2 farg1 = arkode_mem -farg2 = eta_rf -fresult = swigc_FERKStepSetRelaxEtaFail(farg1, farg2) +farg2 = lower +fresult = swigc_FERKStepSetRelaxLowerBound(farg1, farg2) swig_result = fresult end function @@ -2480,6 +2490,22 @@ function FERKStepSetRelaxTol(arkode_mem, rel_tol, abs_tol) & swig_result = fresult end function +function FERKStepSetRelaxUpperBound(arkode_mem, upper) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +real(C_DOUBLE), intent(in) :: upper +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = arkode_mem +farg2 = upper +fresult = swigc_FERKStepSetRelaxUpperBound(farg1, farg2) +swig_result = fresult +end function + function FERKStepGetNumRelaxFnEvals(arkode_mem, r_evals) & result(swig_result) use, intrinsic :: ISO_C_BINDING From 2755dc030b49643f4202aaadde1f4e48e3f350b7 Mon Sep 17 00:00:00 2001 From: David Gardner Date: Wed, 12 Jul 2023 17:44:33 -0700 Subject: [PATCH 088/111] Apply suggestions from code review Co-authored-by: Daniel R. Reynolds --- .../source/Usage/ARKStep_c_interface/Relaxation.rst | 2 +- examples/arkode/CXX_serial/ark_pendulum.cpp | 4 ++-- .../arkode/C_serial/ark_conserved_exp_entropy_ark.c | 6 +++--- .../arkode/C_serial/ark_conserved_exp_entropy_erk.c | 2 +- examples/arkode/C_serial/ark_dissipated_exp_entropy.c | 2 +- src/arkode/arkode_arkstep.c | 10 +++++----- src/arkode/arkode_relaxation.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 708460ea3c..5692398cb3 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -18,7 +18,7 @@ Relaxation Methods ================== This section describes user-callable functions for applying relaxation methods -with ARKStep. For more information on relaxation Runge-Kutta methods see +with ARKStep. For more information on relaxation Runge--Kutta methods see :numref:`ARKODE.Mathematics.Relaxation`. Enabling or Disabling Relaxation diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index 1aee60b398..ec3efa1688 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -131,7 +131,7 @@ int main(int argc, char* argv[]) int flag = Eng(y, &eng0, nullptr); if (check_flag(flag, "Eng")) return 1; - // Initialize the ARKStep + // Initialize ARKStep void* arkode_mem = nullptr; if (implicit) { arkode_mem = ARKStepCreate(nullptr, f, t0, y, ctx); } else { arkode_mem = ARKStepCreate(f, nullptr, t0, y, ctx); } @@ -250,7 +250,7 @@ int main(int argc, char* argv[]) sunrealtype eng_chng = eng - eng0; - /* Output to the screen every periodically */ + /* Output to the screen periodically */ long int nst; flag = ARKStepGetNumSteps(arkode_mem, &nst); check_flag(flag, "ARKStepGetNumSteps"); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 2a94ac3181..f2b5f8516b 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -41,7 +41,7 @@ * ent'(u,v) = [ de/du de/dv ]^T = [ exp(u) exp(v) ]^T. * * The problem is advanced in time with an explicit or implicit relaxed - * Runge-Kutta method to ensure conservation of the entropy. + * Runge-Kutta method from ARKStep to ensure conservation of the entropy. * ---------------------------------------------------------------------------*/ /* Header files */ @@ -192,7 +192,7 @@ int main(int argc, char* argv[]) ytdata = N_VGetArrayPointer(ytrue); if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; - /* Initialize the ARKStep */ + /* Initialize ARKStep */ if (implicit) { arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); @@ -289,7 +289,7 @@ int main(int argc, char* argv[]) u_err = ydata[0] - ytdata[0]; v_err = ydata[1] - ytdata[1]; - /* Output to the screen every periodically */ + /* Output to the screen periodically */ flag = ARKStepGetNumSteps(arkode_mem, &nst); check_flag(flag, "ARKStepGetNumSteps"); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index 9071f7218a..509bbce8de 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -41,7 +41,7 @@ * ent'(u,v) = [ de/du de/dv ]^T = [ exp(u) exp(v) ]^T. * * The problem is advanced in time with an explicit relaxed - * Runge-Kutta method to ensure conservation of the entropy. + * Runge-Kutta method from ERKStep to ensure conservation of the entropy. * ---------------------------------------------------------------------------*/ /* Header files */ diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index d2733f6049..06f7b22d8a 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -172,7 +172,7 @@ int main(int argc, char* argv[]) ytdata = N_VGetArrayPointer(ytrue); if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; - /* Initialize the ARKStep */ + /* Initialize ARKStep */ if (implicit) { arkode_mem = ARKStepCreate(NULL, f, t0, y, ctx); diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 5febd833b7..49b839e2d9 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3107,15 +3107,15 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) * Computes the change in the relaxation functions for use in relaxation methods * delta_e = h * sum_i b_i * * - * With implicit and IMEX methods it is necessary to storing the method stages - * (or computing the delta_e estimate along the way) to avoid inconsistencies + * With implicit and IMEX methods it is necessary to store the method stages + * (or compute the delta_e estimate along the way) to avoid inconsistencies * between z_i, F(z_i), and J_relax(z_i) that arise from reconstructing stages * from stored RHS values like with ERK methods. As such the take step function * stores the stages along the way but only when there is an implicit RHS. * - * When the low storage structure of methods can be exploited, computing the - * delta_e estimate along the way with explicit methods may be necessary to - * avoid storing additional RHS or stage values. + * Future: when ARKStep can exploit the structure of low storage methods, it may + * be necessary to compute the delta_e estimate along the way with explicit + * methods to avoid storing additional RHS or stage values. * ---------------------------------------------------------------------------*/ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index f8f5f65006..ea8af1f340 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -147,7 +147,7 @@ static int arkRelaxNewtonSolve(ARKodeMem ark_mem) return ARK_RELAX_SOLVE_RECV; } -/* Solve the relaxation residual equation using Newton's method */ +/* Solve the relaxation residual equation using Brent's method */ static int arkRelaxBrentSolve(ARKodeMem ark_mem) { int i, retval; From 601555bd147337672e1d67067566db97e3cdb880 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 16:02:10 -0700 Subject: [PATCH 089/111] doc updates --- doc/arkode/guide/source/Mathematics.rst | 21 +++-- .../Usage/ARKStep_c_interface/Relaxation.rst | 88 ++++++++++++------- .../Usage/ERKStep_c_interface/Relaxation.rst | 68 +++++++++----- 3 files changed, 114 insertions(+), 63 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index eee142f4b6..8a1de3ca60 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2117,19 +2117,22 @@ iteration is halted either when the residual tolerance is met, :math:`F(r^{(k)}) < \epsilon_{\mathrm{relax\_res}}`, or when the difference between successive iterates satisfies the relative and absolute tolerances, :math:`|\delta_r^{(k)}| = |r^{(k)} - r^{(k-1)}| < \epsilon_{\mathrm{relax\_rtol}} |r^{(k-1)}| + \epsilon_{\mathrm{relax\_atol}}`. -Brent's method applies the same residual tolerance check and the additionally -halts when the bisection update satisfies the relative and absolute tolerances, +Brent's method applies the same residual tolerance check and additionally halts +when the bisection update satisfies the relative and absolute tolerances, :math:`|0.5 (r_c - r^{k})| < \epsilon_{\mathrm{relax\_rtol}} |r^{(k)}| + 0.5 \epsilon_{\mathrm{relax\_atol}}` where :math:`r_c` and :math:`r^{(k)}` bound the root. -If the nonlinear fails to meet the specified tolerances within the maximum +If the nonlinear solve fails to meet the specified tolerances within the maximum allowed number of iterations, the step size is reduced by the factor -:math:`\eta_\mathrm{rf}` (default 0.25) and the step is repeated. The root of -:eq:`ARKODE_RELAX_NLS` is :math:`1 + \mathcal{O}(h_n^{q - 1})` for a method -of order :math:`q` :cite:p:`ranocha2020relaxation`. As such, if -:math:`|r - 1| > \mathcal{B} |h_n|` (default :math:`\mathcal{B} = 0.5`, the -computed :math:`r` value is considered invalid and the step will be repeated -with the step size reduced by :math:`\eta_\mathrm{rf}`. +:math:`\eta_\mathrm{rf}` (default 0.25) and the step is repeated. Additionally, +the solution of :eq:`ARKODE_RELAX_NLS` should be +:math:`r = 1 + \mathcal{O}(h_n^{q - 1})` for a method of order :math:`q` +:cite:p:`ranocha2020relaxation`. As such, limits are imposed on the range of +relaxation values allowed (i.e., limiting the maximum change in step size due to +relaxation). A relaxation value greater than :math:`r_\text{max}` (default 1.2) +or less than :math:`r_\text{min}` (default 0.8), is considered as a failed +relaxation application and the step will is repeated with the step size reduced +by :math:`\eta_\text{rf}`. For more information on utilizing relaxation Runge--Kutta methods, see :numref:`ARKODE.Usage.ERKStep.Relaxation` and diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 5692398cb3..7aca7d7a85 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -33,11 +33,9 @@ Enabling or Disabling Relaxation one of the functions is ``NULL``. If both ``rfn`` and ``rjac`` are ``NULL``, relaxation is disabled. - When combined with fixed time step sizes, ARKStep will attempt each step - using the specified step size. If the step is successful, relaxation will be - applied, effectively modifying the step size for the current step. If the - step fails or applying relaxation fails, :c:func:`ARKStepEvolve` will - return with an error. + With DIRK and IMEX-ARK methods, applying relaxation requires allocating + :math:`s` additional state vectors (where :math:`s` is the number of stages + in the method). :param arkode_mem: the ARKStep memory structure :param rfn: the user-defined function to compute the relaxation function @@ -58,6 +56,14 @@ Enabling or Disabling Relaxation satisfied, :c:func:`ARKStepEvolve` will return with an error during initialization. + .. note:: + + When combined with fixed time step sizes, ARKStep will attempt each step + using the specified step size. If the step is successful, relaxation will + be applied, effectively modifying the step size for the current step. If + the step fails or applying relaxation fails, :c:func:`ARKStepEvolve` will + return with an error. + .. versionadded:: 5.6.0 Optional Input Functions @@ -66,20 +72,37 @@ Optional Input Functions This section describes optional input functions used to control applying relaxation. -.. c:function:: int ARKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) +.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) + + Sets the step size reduction factor applied after a failed relaxation + application. + + The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. + + :param arkode_mem: the ARKStep memory structure + :param eta_rf: the step size reduction factor + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` - Sets the factor :math:`\mathcal{B}` used in determining an acceptable value - of the relaxation parameter, :math:`r`. + .. versionadded:: 5.6.0 - If :math:`|r - 1| > \mathcal{B} h_n`, the value of :math:`r` is considered - unacceptable and the step will be repeated with a smaller step size +.. c:function:: int ARKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) + + Sets the smallest acceptable value for the relaxation parameter. + + Values smaller than the lower bound will result in a failed relaxation + application and the step will be repeated with a smaller step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). - The default value is 0.5. Input values :math:`\leq 0` will result in the - default value being used. + The default value is 0.8. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. :param arkode_mem: the ARKStep memory structure - :param bound_factor: the factor used to accept the relaxation parameter value + :param lower: the relaxation parameter lower bound :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -88,15 +111,19 @@ relaxation. .. versionadded:: 5.6.0 -.. c:function:: int ARKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +.. c:function:: int ARKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) - Sets the step size reduction factor after a failed relaxation application. + Sets the largest acceptable value for the relaxation parameter. - The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will - result in the default value being used. + Values larger than the upper bound will result in a failed relaxation + application and the step will be repeated with a smaller step size + (determined by :c:func:`ARKStepSetRelaxEtaFail`). + + The default value is 1.2. Input values :math:`\leq 1` will result in the + default value being used. :param arkode_mem: the ARKStep memory structure - :param eta_rf: the step size reduction factor + :param upper: the relaxation parameter upper bound :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -170,10 +197,11 @@ relaxation. Sets the nonlinear solver residual tolerance to use when solving :eq:`ARKODE_RELAX_NLS`. - If the residual or solution tolerance (see :c:func:`ARKStepSetRelaxMaxIter`) - is not reached within the maximum number of iterations (determined by - :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a smaller - step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). + If the residual or iteration update tolerance (see + :c:func:`ARKStepSetRelaxMaxIter`) is not reached within the maximum number of + iterations (determined by :c:func:`ARKStepSetRelaxMaxIters`), the step will + be repeated with a smaller step size (determined by + :c:func:`ARKStepSetRelaxEtaFail`). The default value is :math:`4 \epsilon` where :math:`\epsilon` is floating-point precision. Input values :math:`\leq 0` will result in the @@ -192,13 +220,12 @@ relaxation. .. c:function:: int ARKStepSetRelaxTol(void* arkode_mem, sunrealtype rel_tol, sunrealtype abs_tol) Sets the nonlinear solver relative and absolute tolerance on changes in - :math:`r` when solving :eq:`ARKODE_RELAX_NLS`. + :math:`r` iterates when solving :eq:`ARKODE_RELAX_NLS`. - - If the residual (see :c:func:`ARKStepSetRelaxResTol`) or solution tolerance - is not reached within the maximum number of iterations (determined by - :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a smaller - step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). + If the residual (see :c:func:`ARKStepSetRelaxResTol`) or iterate update + tolerance is not reached within the maximum number of iterations (determined + by :c:func:`ARKStepSetRelaxMaxIters`), the step will be repeated with a + smaller step size (determined by :c:func:`ARKStepSetRelaxEtaFail`). The default relative and absolute tolerances are :math:`4 \epsilon` and :math:`10^{-14}`, respectively, where :math:`\epsilon` is floating-point @@ -216,7 +243,6 @@ relaxation. .. versionadded:: 5.6.0 - Optional Output Functions ------------------------- @@ -255,7 +281,7 @@ about the performance of the relaxation method. Get the total number of times applying relaxation failed. - The counter includes the sum of the number of nonlinear solver failure + The counter includes the sum of the number of nonlinear solver failures (see :c:func:`ARKStepGetNumRelaxSolveFails`) and the number of failures due an unacceptable relaxation value (see :c:func:`ARKStepSetRelaxBoundFactor`). @@ -272,7 +298,7 @@ about the performance of the relaxation method. .. c:function:: int ARKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) - Get the number of times the relaxation parameter as deemed unacceptable. + Get the number of times the relaxation parameter was deemed unacceptable. :param arkode_mem: the ARKStep memory structure :param fails: the number of failures due to an unacceptable relaxation diff --git a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst index 1a5c7da5b4..ab45d7f54c 100644 --- a/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ERKStep_c_interface/Relaxation.rst @@ -18,7 +18,7 @@ Relaxation Methods ================== This section describes user-callable functions for applying relaxation methods -with ERKStep. For more information on relaxation Runge-Kutta methods see +with ERKStep. For more information on relaxation Runge--Kutta methods see :numref:`ARKODE.Mathematics.Relaxation`. Enabling or Disabling Relaxation @@ -33,12 +33,6 @@ Enabling or Disabling Relaxation one of the functions is ``NULL``. If both ``rfn`` and ``rjac`` are ``NULL``, relaxation is disabled. - When combined with fixed time step sizes, ERKStep will attempt each step - using the specified step size. If the step is successful, relaxation will be - applied, effectively modifying the step size for the current step. If the - step fails or applying relaxation fails, :c:func:`ERKStepEvolve` will - return with an error. - :param arkode_mem: the ERKStep memory structure :param rfn: the user-defined function to compute the relaxation function :math:`\xi(y)` @@ -57,6 +51,14 @@ Enabling or Disabling Relaxation :math:`b_i \geq 0`. If these conditions are not satisfied, :c:func:`ERKStepEvolve` will return with an error during initialization. + .. note:: + + When combined with fixed time step sizes, ERKStep will attempt each step + using the specified step size. If the step is successful, relaxation will + be applied, effectively modifying the step size for the current step. If + the step fails or applying relaxation fails, :c:func:`ERKStepEvolve` will + return with an error. + .. versionadded:: 5.6.0 Optional Input Functions @@ -65,20 +67,37 @@ Optional Input Functions This section describes optional input functions used to control applying relaxation. -.. c:function:: int ERKStepSetRelaxBoundFactor(void* arkode_mem, sunrealtype bound_factor) +.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) + + Sets the step size reduction factor applied after a failed relaxation + application. + + The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. - Sets the factor :math:`\mathcal{B}` used in determining an acceptable value - of the relaxation parameter, :math:`r`. + :param arkode_mem: the ERKStep memory structure + :param eta_rf: the step size reduction factor + + :retval ARK_SUCCESS: the value was successfully set + :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` + :retval ARK_RELAX_MEM_NULL: the internal relaxation memory structure was + ``NULL`` - If :math:`|r - 1| > \mathcal{B} h_n`, the value of :math:`r` is considered - unacceptable and the step will be repeated with a smaller step size + .. versionadded:: 5.6.0 + +.. c:function:: int ERKStepSetRelaxLowerBound(void* arkode_mem, sunrealtype lower) + + Sets the smallest acceptable value for the relaxation parameter. + + Values smaller than the lower bound will result in a failed relaxation + application and the step will be repeated with a smaller step size (determined by :c:func:`ERKStepSetRelaxEtaFail`). - The default value is 0.5. Input values :math:`\leq 0` will result in the - default value being used. + The default value is 0.8. Input values :math:`\leq 0` or :math:`\geq 1` will + result in the default value being used. :param arkode_mem: the ERKStep memory structure - :param bound_factor: the factor used to accept the relaxation parameter value + :param lower: the relaxation parameter lower bound :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -87,15 +106,19 @@ relaxation. .. versionadded:: 5.6.0 -.. c:function:: int ERKStepSetRelaxEtaFail(void* arkode_mem, sunrealtype eta_rf) +.. c:function:: int ERKStepSetRelaxUpperBound(void* arkode_mem, sunrealtype upper) - Sets the step size reduction factor after a failed relaxation application. + Sets the largest acceptable value for the relaxation parameter. - The default value is 0.25. Input values :math:`\leq 0` or :math:`\geq 1` will - result in the default value being used. + Values larger than the upper bound will result in a failed relaxation + application and the step will be repeated with a smaller step size + (determined by :c:func:`ERKStepSetRelaxEtaFail`). + + The default value is 1.2. Input values :math:`\leq 1` will result in the + default value being used. :param arkode_mem: the ERKStep memory structure - :param eta_rf: the step size reduction factor + :param upper: the relaxation parameter upper bound :retval ARK_SUCCESS: the value was successfully set :retval ARK_MEM_NULL: ``arkode_mem`` was ``NULL`` @@ -215,7 +238,6 @@ relaxation. .. versionadded:: 5.6.0 - Optional Output Functions ------------------------- @@ -254,7 +276,7 @@ about the performance of the relaxation method. Get the total number of times applying relaxation failed. - The counter includes the sum of the number of nonlinear solver failure + The counter includes the sum of the number of nonlinear solver failures (see :c:func:`ERKStepGetNumRelaxSolveFails`) and the number of failures due an unacceptable relaxation value (see :c:func:`ERKStepSetRelaxBoundFactor`). @@ -271,7 +293,7 @@ about the performance of the relaxation method. .. c:function:: int ERKStepGetNumRelaxBoundFails(void* arkode_mem, long int* fails) - Get the number of times the relaxation parameter as deemed unacceptable. + Get the number of times the relaxation parameter was deemed unacceptable. :param arkode_mem: the ERKStep memory structure :param fails: the number of failures due to an unacceptable relaxation From da0e87204af7f1012f3607dcb5a0c1288805bc98 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 17:46:18 -0700 Subject: [PATCH 090/111] fix typos in comments --- examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c | 4 ++-- examples/arkode/C_serial/ark_dissipated_exp_entropy.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index 509bbce8de..f233f1d376 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -174,7 +174,7 @@ int main(int argc, char* argv[]) ytdata = N_VGetArrayPointer(ytrue); if (check_ptr(ytdata, "N_VGetArrayPointer")) return 1; - /* Initialize the ERKStep */ + /* Initialize ERKStep */ arkode_mem = ERKStepCreate(f, t0, y, ctx); if (check_ptr(arkode_mem, "ERKStepCreate")) return 1; @@ -241,7 +241,7 @@ int main(int argc, char* argv[]) u_err = ydata[0] - ytdata[0]; v_err = ydata[1] - ytdata[1]; - /* Output to the screen every periodically */ + /* Output to the screen periodically */ flag = ERKStepGetNumSteps(arkode_mem, &nst); check_flag(flag, "ERKStepGetNumSteps"); diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index 06f7b22d8a..c5eb5d0409 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -264,7 +264,7 @@ int main(int argc, char* argv[]) delta_ent = ent - ent0; u_err = ydata[0] - ytdata[0]; - /* Output to the screen every periodically */ + /* Output to the screen periodically */ flag = ARKStepGetNumSteps(arkode_mem, &nst); check_flag(flag, "ARKStepGetNumSteps"); From 7aee4dd760edb5ffb840e2086c8827ba0771e1ff Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 20:40:39 -0700 Subject: [PATCH 091/111] fix compiler warnings (GCC 12) --- examples/arkode/CXX_serial/ark_heat2D.cpp | 16 ++++++---------- src/arkode/arkode_relaxation.c | 5 ++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_heat2D.cpp b/examples/arkode/CXX_serial/ark_heat2D.cpp index 4cdf148542..3a78042a25 100644 --- a/examples/arkode/CXX_serial/ark_heat2D.cpp +++ b/examples/arkode/CXX_serial/ark_heat2D.cpp @@ -1061,11 +1061,14 @@ static int OpenOutput(UserData *udata) // Write output static int WriteOutput(realtype t, N_Vector u, UserData *udata) { - int flag; - realtype max; + int flag; if (udata->output > 0) { + // Compute rms norm of the state + realtype urms = sqrt(N_VDotProd(u, u) / udata->nx / udata->ny); + + // Output current status if (udata->forcing) { // Compute the error @@ -1073,15 +1076,8 @@ static int WriteOutput(realtype t, N_Vector u, UserData *udata) if (check_flag(&flag, "SolutionError", 1)) return 1; // Compute max error - max = N_VMaxNorm(udata->e); - } + realtype max = N_VMaxNorm(udata->e); - // Compute rms norm of the state - realtype urms = sqrt(N_VDotProd(u, u) / udata->nx / udata->ny); - - // Output current status - if (udata->forcing) - { cout << setw(22) << t << setw(25) << urms << setw(25) << max << endl; } else diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index ea8af1f340..bf9e94c807 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -214,10 +214,13 @@ static int arkRelaxBrentSolve(ARKodeMem ark_mem) } if (fb < ZERO) { return ARK_RELAX_SOLVE_RECV; } - /* Initialize values bracketing values to lower bound */ + /* Initialize values bracketing values to lower bound and updates */ xc = xa; fc = fa; + old_update = ZERO; + new_update = ZERO; + /* Find root */ for (i = 0; i < ark_mem->relax_mem->max_iters; i++) { From 81aeada386400a4b92284d7e5914513f5292e9c4 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 20:41:18 -0700 Subject: [PATCH 092/111] add warnings to shared utility headers --- examples/utilities/example_utilities.h | 13 ++++++---- examples/utilities/example_utilities.hpp | 30 +++++++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/examples/utilities/example_utilities.h b/examples/utilities/example_utilities.h index 8651d5f3b4..9184cc19c4 100644 --- a/examples/utilities/example_utilities.h +++ b/examples/utilities/example_utilities.h @@ -11,14 +11,15 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * Utility functions for C examples + * This header file should *NOT* be included in user codes and exists *ONLY* to + * reduce duplicate utility functions and macros across example programs. * ---------------------------------------------------------------------------*/ #include #include -/* Check return flags */ +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ int check_flag(int flag, const char* funcname) { if (flag < 0) @@ -29,7 +30,7 @@ int check_flag(int flag, const char* funcname) return 0; } -/* Check return pointers */ +/* Check if a function returned a NULL pointer */ int check_ptr(void* ptr, const char* funcname) { if (!ptr) @@ -40,7 +41,9 @@ int check_ptr(void* ptr, const char* funcname) return 0; } -/* Precision specific math function macros */ +/* Convince macros for calling common precision-specific math functions -- When + type-generic math macros are available (see tgmath.h) defining and using such + macros is unnecessary. */ #if defined(SUNDIALS_DOUBLE_PRECISION) #define EXP(x) (exp((x))) #define SIN(x) (sin((x))) @@ -64,7 +67,7 @@ int check_ptr(void* ptr, const char* funcname) #define LOG(x) (logl((x))) #endif -/* Precision specific output macros */ +/* Convince macros for using precision-specific format specifiers */ #if defined(SUNDIALS_EXTENDED_PRECISION) #define GSYM "Lg" #define ESYM "Le" diff --git a/examples/utilities/example_utilities.hpp b/examples/utilities/example_utilities.hpp index f83425bfa2..2dcc7b5364 100644 --- a/examples/utilities/example_utilities.hpp +++ b/examples/utilities/example_utilities.hpp @@ -11,16 +11,15 @@ * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------------------- - * Utility functions for C++ examples + * This header file should *NOT* be included in user codes and exists *ONLY* to + * reduce duplicate utility functions across example programs. * ---------------------------------------------------------------------------*/ #include #include #include -#include - -// Check function return flag +// Check for an unrecoverable (negative) return value from a SUNDIALS function int check_flag(const int flag, const std::string funcname) { if (!flag) return 0; @@ -37,17 +36,30 @@ int check_ptr(const void* ptr, const std::string funcname) return 1; } -inline void find_arg(std::vector& args, const std::string key, sunrealtype& dest) +// Functions for parsing vectors of command line inputs +inline void find_arg(std::vector& args, const std::string key, float& dest) { auto it = std::find(args.begin(), args.end(), key); if (it != args.end()) { -#if defined(SUNDIALS_SINGLE_PRECISION) dest = stof(*(it + 1)); -#elif defined(SUNDIALS_DOUBLE_PRECISION) + args.erase(it, it + 2); + } +} + +inline void find_arg(std::vector& args, const std::string key, double& dest) +{ + auto it = std::find(args.begin(), args.end(), key); + if (it != args.end()) { dest = stod(*(it + 1)); -#elif defined(SUNDIALS_EXTENDED_PRECISION) + args.erase(it, it + 2); + } +} + +inline void find_arg(std::vector& args, const std::string key, long double& dest) +{ + auto it = std::find(args.begin(), args.end(), key); + if (it != args.end()) { dest = stold(*(it + 1)); -#endif args.erase(it, it + 2); } } From aeea4279adace9c54d1b229520a6bf3f3b08c526 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 20:54:48 -0700 Subject: [PATCH 093/111] update lrw and liw --- src/arkode/arkode.c | 2 +- src/arkode/arkode_relaxation.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index e61fc14c5d..6c3f7219a1 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -104,7 +104,7 @@ ARKodeMem arkCreate(SUNContext sunctx) /* Initialize lrw and liw */ ark_mem->lrw = 18; - ark_mem->liw = 39; /* fcn/data ptr, int, long int, sunindextype, booleantype */ + ark_mem->liw = 41; /* fcn/data ptr, int, long int, sunindextype, booleantype */ /* No mallocs have been done yet */ ark_mem->VabstolMallocDone = SUNFALSE; diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index bf9e94c807..308fa36db0 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -744,6 +744,10 @@ int arkRelaxCreate(void* arkode_mem, ARKRelaxFn relax_fn, /* Initialize values */ ark_mem->relax_mem->relax_param_prev = ONE; + + /* Update workspace sizes */ + ark_mem->lrw += 12; + ark_mem->liw += 14; } /* Set function pointers */ From 8cb706b3866a5fce7d8b45b320a2fbf30fd7dcb6 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 20:59:50 -0700 Subject: [PATCH 094/111] update comment on relaxation actions --- src/arkode/arkode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arkode/arkode.c b/src/arkode/arkode.c index 6c3f7219a1..e89a153375 100644 --- a/src/arkode/arkode.c +++ b/src/arkode/arkode.c @@ -856,7 +856,11 @@ int arkEvolve(ARKodeMem ark_mem, realtype tout, N_Vector yout, kflag = arkCheckConvergence(ark_mem, &nflag, &ncf); if (kflag < 0) break; - /* Perform relaxation */ + /* Perform relaxation: + - computes relaxation parameter + - on success, updates ycur, h, and dsm + - on recoverable failure, updates eta and signals to retry step + - on fatal error, returns negative error flag */ if (ark_mem->relax_enabled && (kflag == ARK_SUCCESS)) { kflag = arkRelax(ark_mem, &relax_fails, &dsm, &nflag); From 28aeb863d07f5977e410628a4761c0ac97dfdef3 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 21:07:14 -0700 Subject: [PATCH 095/111] check if N_VDotProdMultiAllReduce is provided --- src/arkode/arkode_arkstep.c | 56 +++++++++++++++++++++++++++---------- src/arkode/arkode_erkstep.c | 19 ++++++++++--- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 49b839e2d9..0cc2821211 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3179,27 +3179,53 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, if (retval > 0) { return ARK_RELAX_JAC_RECV; } /* Update estimate of relaxation function change */ - if (step_mem->explicit && step_mem->implicit) + if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) { - N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], - step_mem->Bi->b[i], step_mem->Fi[i], - z_stage); - *delta_e_out += N_VDotProdLocal(J_relax, z_stage); - } - else if (step_mem->explicit) - { - *delta_e_out += step_mem->Be->b[i] * N_VDotProdLocal(J_relax, - step_mem->Fe[i]); + if (step_mem->explicit && step_mem->implicit) + { + N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], + step_mem->Bi->b[i], step_mem->Fi[i], + z_stage); + *delta_e_out += N_VDotProdLocal(J_relax, z_stage); + } + else if (step_mem->explicit) + { + *delta_e_out += step_mem->Be->b[i] * N_VDotProdLocal(J_relax, + step_mem->Fe[i]); + } + else if (step_mem->implicit) + { + *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, + step_mem->Fi[i]); + } } - else if (step_mem->implicit) + else { - *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, - step_mem->Fi[i]); + if (step_mem->explicit && step_mem->implicit) + { + N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], + step_mem->Bi->b[i], step_mem->Fi[i], + z_stage); + *delta_e_out += N_VDotProd(J_relax, z_stage); + } + else if (step_mem->explicit) + { + *delta_e_out += step_mem->Be->b[i] * N_VDotProd(J_relax, + step_mem->Fe[i]); + } + else if (step_mem->implicit) + { + *delta_e_out += step_mem->Bi->b[i] * N_VDotProd(J_relax, + step_mem->Fi[i]); + } } } - /* Ignore negative return for node-local vectors where this is a non-op */ - N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); + if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) + { + retval = N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); + if (retval) { return ARK_VECTOROP_ERR; } + } *delta_e_out *= ark_mem->h; diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index 87945ecab6..709df774e4 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1269,12 +1269,23 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, if (retval > 0) { return ARK_RELAX_JAC_RECV; } /* Update estimates */ - *delta_e_out += step_mem->B->b[i] * N_VDotProdLocal(J_relax, - step_mem->F[i]); + if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) + { + *delta_e_out += step_mem->B->b[i] * N_VDotProdLocal(J_relax, + step_mem->F[i]); + } + else + { + *delta_e_out += step_mem->B->b[i] * N_VDotProd(J_relax, + step_mem->F[i]); + } } - /* Ignore negative return for node-local vectors where this is a non-op */ - N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); + if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) + { + retval = N_VDotProdMultiAllReduce(1, J_relax, delta_e_out); + if (retval) { return ARK_VECTOROP_ERR; } + } *delta_e_out *= ark_mem->h; From 84894ccfd7990808789522cd208285e8e8dbd628 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 21:10:57 -0700 Subject: [PATCH 096/111] simplify PrintAllStats --- src/arkode/arkode_io.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/arkode/arkode_io.c b/src/arkode/arkode_io.c index 22f080ea48..e60b76bf98 100644 --- a/src/arkode/arkode_io.c +++ b/src/arkode/arkode_io.c @@ -1747,11 +1747,6 @@ int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) ark_root_mem = (ARKodeRootMem) ark_mem->root_mem; fprintf(outfile, "Root fn evals = %ld\n", ark_root_mem->nge); } - if (ark_mem->relax_enabled) - { - retval = arkRelaxPrintAllStats(arkode_mem, outfile, fmt); - if (retval != ARK_SUCCESS) return(retval); - } break; case SUN_OUTPUTFORMAT_CSV: fprintf(outfile, "Time,%"RSYM, ark_mem->tcur); @@ -1770,11 +1765,6 @@ int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) ark_root_mem = (ARKodeRootMem) ark_mem->root_mem; fprintf(outfile, ",Roof fn evals,%ld", ark_root_mem->nge); } - if (ark_mem->relax_enabled) - { - retval = arkRelaxPrintAllStats(arkode_mem, outfile, fmt); - if (retval != ARK_SUCCESS) return(retval); - } break; default: arkProcessError(ark_mem, ARK_ILL_INPUT, "ARKODE", "arkPrintAllStats", @@ -1782,6 +1772,13 @@ int arkPrintAllStats(void *arkode_mem, FILE *outfile, SUNOutputFormat fmt) return(ARK_ILL_INPUT); } + /* Print relaxation stats */ + if (ark_mem->relax_enabled) + { + retval = arkRelaxPrintAllStats(arkode_mem, outfile, fmt); + if (retval != ARK_SUCCESS) return(retval); + } + return(ARK_SUCCESS); } From 0614414869200d221ded67130050de0eceddf5cc Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 21:11:14 -0700 Subject: [PATCH 097/111] add bound fails to PrintAllStats --- src/arkode/arkode_relaxation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 308fa36db0..2814c0630e 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -653,6 +653,8 @@ int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) relax_mem->num_relax_jac_evals); fprintf(outfile, "Relax fails = %ld\n", relax_mem->num_fails); + fprintf(outfile, "Relax bound fails = %ld\n", + relax_mem->bound_fails); fprintf(outfile, "Relax NLS iters = %ld\n", relax_mem->nls_iters); fprintf(outfile, "Relax NLS fails = %ld\n", @@ -662,6 +664,7 @@ int arkRelaxPrintAllStats(void* arkode_mem, FILE* outfile, SUNOutputFormat fmt) fprintf(outfile, ",Relax fn evals,%ld", relax_mem->num_relax_fn_evals); fprintf(outfile, ",Relax Jac evals,%ld", relax_mem->num_relax_jac_evals); fprintf(outfile, ",Relax fails,%ld", relax_mem->num_fails); + fprintf(outfile, ",Relax bound fails,%ld", relax_mem->bound_fails); fprintf(outfile, ",Relax NLS iters,%ld", relax_mem->nls_iters); fprintf(outfile, ",Relax NLS fails,%ld", relax_mem->nls_fails); break; From 059061037d09b2fd896502c4a6f3bb97ecbaa286 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 21:29:18 -0700 Subject: [PATCH 098/111] adjust temporary vector usage --- src/arkode/arkode_arkstep.c | 4 ++-- src/arkode/arkode_erkstep.c | 4 ++-- src/arkode/arkode_relaxation.c | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 0cc2821211..237f8502be 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3126,8 +3126,8 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, realtype* cvals; N_Vector* Xvecs; ARKodeARKStepMem step_mem; - N_Vector z_stage = ark_mem->tempv1; - N_Vector J_relax = ark_mem->tempv2; + N_Vector z_stage = ark_mem->tempv2; + N_Vector J_relax = ark_mem->tempv3; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) diff --git a/src/arkode/arkode_erkstep.c b/src/arkode/arkode_erkstep.c index 709df774e4..f21aa2602b 100644 --- a/src/arkode/arkode_erkstep.c +++ b/src/arkode/arkode_erkstep.c @@ -1224,8 +1224,8 @@ int erkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, realtype* cvals; N_Vector* Xvecs; ARKodeERKStepMem step_mem; - N_Vector z_stage = ark_mem->tempv1; - N_Vector J_relax = ark_mem->tempv2; + N_Vector z_stage = ark_mem->tempv2; + N_Vector J_relax = ark_mem->tempv3; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) diff --git a/src/arkode/arkode_relaxation.c b/src/arkode/arkode_relaxation.c index 2814c0630e..cc9fb5d0b8 100644 --- a/src/arkode/arkode_relaxation.c +++ b/src/arkode/arkode_relaxation.c @@ -15,9 +15,9 @@ * functionality * * Temporary vectors utilized in the functions below: - * tempv1 - holds delta_y, the update direction vector - * tempv2 - holds y_relax, the relaxed solution vector - * tempv3 - holds J_relax, the Jacobian of the relaxation function + * tempv2 - holds delta_y, the update direction vector + * tempv3 - holds y_relax, the relaxed solution vector + * tempv4 - holds J_relax, the Jacobian of the relaxation function * ---------------------------------------------------------------------------*/ #include @@ -62,8 +62,8 @@ static int arkRelaxResidual(sunrealtype relax_param, sunrealtype* relax_res, int retval; sunrealtype e_old = ark_mem->relax_mem->e_old; sunrealtype delta_e = ark_mem->relax_mem->delta_e; - N_Vector delta_y = ark_mem->tempv1; - N_Vector y_relax = ark_mem->tempv2; + N_Vector delta_y = ark_mem->tempv2; + N_Vector y_relax = ark_mem->tempv3; void* user_data = ark_mem->user_data; /* y_relax = y_n + r * delta_y */ @@ -86,9 +86,9 @@ static int arkRelaxResidualJacobian(sunrealtype relax_param, sunrealtype* relax_jac, ARKodeMem ark_mem) { int retval; - N_Vector delta_y = ark_mem->tempv1; - N_Vector y_relax = ark_mem->tempv2; - N_Vector J_relax = ark_mem->tempv3; + N_Vector delta_y = ark_mem->tempv2; + N_Vector y_relax = ark_mem->tempv3; + N_Vector J_relax = ark_mem->tempv4; sunrealtype delta_e = ark_mem->relax_mem->delta_e; void* user_data = ark_mem->user_data; @@ -337,15 +337,15 @@ int arkRelaxSolve(ARKodeMem ark_mem, ARKodeRelaxMem relax_mem, { int retval; - /* Get the change in entropy (uses temp vectors 1 and 2) */ + /* Get the change in entropy (uses temp vectors 2 and 3) */ retval = relax_mem->delta_e_fn(ark_mem, relax_mem->relax_jac_fn, &(relax_mem->num_relax_jac_evals), &(relax_mem->delta_e)); if (retval) return retval; - /* Get the change in state (delta_y = tempv1) */ - retval = relax_mem->delta_y_fn(ark_mem, ark_mem->tempv1); + /* Get the change in state (delta_y = tempv2) */ + retval = relax_mem->delta_y_fn(ark_mem, ark_mem->tempv2); if (retval) return retval; /* Store the current relaxation function value */ From 08214bd982c100c0866c7219efc7b125035cfdba Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 22:47:57 -0700 Subject: [PATCH 099/111] update workspace size in output files --- examples/arkode/C_parallel/ark_diurnal_kry_bbd_p.out | 4 ++-- examples/arkode/C_parallel/ark_diurnal_kry_p.out | 2 +- examples/arkode/C_parhyp/ark_diurnal_kry_ph.out | 2 +- examples/arkode/C_serial/ark_KrylovDemo_prec.out | 8 ++++---- examples/arkode/C_serial/ark_KrylovDemo_prec_1.out | 8 ++++---- examples/arkode/C_serial/ark_KrylovDemo_prec_2.out | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/arkode/C_parallel/ark_diurnal_kry_bbd_p.out b/examples/arkode/C_parallel/ark_diurnal_kry_bbd_p.out index d3e94e7725..5d53186f79 100644 --- a/examples/arkode/C_parallel/ark_diurnal_kry_bbd_p.out +++ b/examples/arkode/C_parallel/ark_diurnal_kry_bbd_p.out @@ -58,7 +58,7 @@ At top right: c1, c2 = -4.190e-08 4.163e+11 Final Statistics: -lenrw = 3901 leniw = 265 +lenrw = 3901 leniw = 267 lenrwls = 2455 leniwls = 126 nst = 7252 nfe = 0 nfe = 76109 nfels = 82856 @@ -127,7 +127,7 @@ At top right: c1, c2 = -6.607e-08 4.163e+11 Final Statistics: -lenrw = 3901 leniw = 270 +lenrw = 3901 leniw = 272 lenrwls = 2455 leniwls = 126 nst = 7364 nfe = 0 nfe = 77457 nfels = 101131 diff --git a/examples/arkode/C_parallel/ark_diurnal_kry_p.out b/examples/arkode/C_parallel/ark_diurnal_kry_p.out index a3b8276583..97f07c3221 100644 --- a/examples/arkode/C_parallel/ark_diurnal_kry_p.out +++ b/examples/arkode/C_parallel/ark_diurnal_kry_p.out @@ -52,7 +52,7 @@ At top right: c1, c2 = 1.567e-26 4.163e+11 Final Statistics: -lenrw = 3301 leniw = 241 +lenrw = 3301 leniw = 243 lenrwls = 2455 leniwls = 126 nst = 7103 nfe = 0 nfi = 74602 nfels = 87206 diff --git a/examples/arkode/C_parhyp/ark_diurnal_kry_ph.out b/examples/arkode/C_parhyp/ark_diurnal_kry_ph.out index d88203c2b1..411f0a09fc 100644 --- a/examples/arkode/C_parhyp/ark_diurnal_kry_ph.out +++ b/examples/arkode/C_parhyp/ark_diurnal_kry_ph.out @@ -52,7 +52,7 @@ At top right: c1, c2 = -4.442e-20 4.163e+11 Final Statistics: -lenrw = 3301 leniw = 241 +lenrw = 3301 leniw = 243 lenrwls = 2455 leniwls = 126 nst = 7237 nfe = 0 nfi = 75881 nfels = 88695 diff --git a/examples/arkode/C_serial/ark_KrylovDemo_prec.out b/examples/arkode/C_serial/ark_KrylovDemo_prec.out index e6390da296..3a63a46785 100644 --- a/examples/arkode/C_serial/ark_KrylovDemo_prec.out +++ b/examples/arkode/C_serial/ark_KrylovDemo_prec.out @@ -419,7 +419,7 @@ Species 6 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 129 + ARKStep integer workspace length = 131 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 266 @@ -488,7 +488,7 @@ t = 1.00e+01 nst = 251 nfe = 0 nfi = 4101 nni = 2746 hu = 7.09e-02 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 134 + ARKStep integer workspace length = 136 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 251 @@ -557,7 +557,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5722 nni = 3907 hu = 1.35e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 139 + ARKStep integer workspace length = 141 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 @@ -626,7 +626,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5728 nni = 3912 hu = 1.31e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 144 + ARKStep integer workspace length = 146 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 diff --git a/examples/arkode/C_serial/ark_KrylovDemo_prec_1.out b/examples/arkode/C_serial/ark_KrylovDemo_prec_1.out index e6390da296..58b34e703d 100644 --- a/examples/arkode/C_serial/ark_KrylovDemo_prec_1.out +++ b/examples/arkode/C_serial/ark_KrylovDemo_prec_1.out @@ -419,7 +419,7 @@ Species 6 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 129 + ARKStep integer workspace length = 131 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 266 @@ -488,7 +488,7 @@ t = 1.00e+01 nst = 251 nfe = 0 nfi = 4101 nni = 2746 hu = 7.09e-02 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 134 + ARKStep integer workspace length = 136 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 251 @@ -557,7 +557,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5722 nni = 3907 hu = 1.35e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 139 + ARKStep integer workspace length = 141 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 @@ -626,7 +626,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5728 nni = 3912 hu = 1.31e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 144 + ARKStep integer workspace length = 146 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 diff --git a/examples/arkode/C_serial/ark_KrylovDemo_prec_2.out b/examples/arkode/C_serial/ark_KrylovDemo_prec_2.out index e6390da296..1af6fb8046 100644 --- a/examples/arkode/C_serial/ark_KrylovDemo_prec_2.out +++ b/examples/arkode/C_serial/ark_KrylovDemo_prec_2.out @@ -419,7 +419,7 @@ Species 6 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 129 + ARKStep integer workspace length = 131 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 266 @@ -488,7 +488,7 @@ t = 1.00e+01 nst = 251 nfe = 0 nfi = 4101 nni = 2746 hu = 7.09e-02 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 134 + ARKStep integer workspace length = 136 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 251 @@ -557,7 +557,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5722 nni = 3907 hu = 1.35e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 139 + ARKStep integer workspace length = 141 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 @@ -626,7 +626,7 @@ t = 1.00e+01 nst = 359 nfe = 0 nfi = 5728 nni = 3912 hu = 1.31e-01 Final statistics for this run: ARKStep real workspace length = 3557 - ARKStep integer workspace length = 144 + ARKStep integer workspace length = 146 ARKLS real workspace length = 2647 ARKLS integer workspace length = 42 Number of steps = 359 From 103c48994682be6e14fc36216248ce253a62af23 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Wed, 12 Jul 2023 23:58:07 -0700 Subject: [PATCH 100/111] support fixed mass matrix --- doc/arkode/guide/source/Mathematics.rst | 14 +-- src/arkode/arkode_arkstep.c | 123 ++++++++++++++++-------- 2 files changed, 91 insertions(+), 46 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index 8a1de3ca60..a85271eabd 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2096,12 +2096,14 @@ The relaxed solution is given by y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} :label: ARKODE_RELAX_SOL -where :math:`d \equiv h_n \sum_{i=1}^{s}(b^E_i f^E_i + b^I_i f^I_i)` is the -update direction and the relaxation factor, :math:`r`, is selected to ensure -conservation or dissipation. Given an ERK, DIRK, or ARK method of at least -second order with non-negative solution weights (i.e., :math:`b_i \geq 0` for -ERKStep or :math:`b^E_i \geq 0` and :math:`b^I_i \geq 0` for ARKStep), the -factor :math:`r` is computed by solving the auxiliary scalar nonlinear system +where :math:`d` is the update to :math:`y_n` (i.e., +:math:`h_n \sum_{i=1}^{s}(b^E_i \hat{f}^E_i + b^I_i \hat{f}^I_i)` for ARKStep +and :math:`h_n \sum_{i=1}^{s} b_i f_i` for ERKStep) and :math:`r` is the +relaxation factor selected to ensure conservation or dissipation. Given an ERK, +DIRK, or ARK method of at least second order with non-negative solution weights +(i.e., :math:`b_i \geq 0` for ERKStep or :math:`b^E_i \geq 0` and +:math:`b^I_i \geq 0` for ARKStep), the factor :math:`r` is computed by solving +the auxiliary scalar nonlinear system .. math:: F(r) = \xi(y_{n-1} + r d) - \xi(y_{n-1}) - r e = 0 diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 237f8502be..2a31cfed55 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3098,6 +3098,13 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) retval = N_VLinearCombination(nvec, cvals, Xvecs, delta_y); if (retval) return ARK_VECTOROP_ERR; + if (step_mem->mass_type == MASS_FIXED) + { + /* Solve to compute update M^{-1} h * sum_j Ae[i,j] Fe[j] + Ai[i,j] Fi[j] */ + retval = step_mem->msolve((void *) ark_mem, delta_y, step_mem->nlscoef); + if (retval) { return ARK_MASSSOLVE_FAIL; } + } + return ARK_SUCCESS; } @@ -3114,7 +3121,7 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) * stores the stages along the way but only when there is an implicit RHS. * * Future: when ARKStep can exploit the structure of low storage methods, it may - * be necessary to compute the delta_e estimate along the way with explicit + * be necessary to compute the delta_e estimate along the way with explicit * methods to avoid storing additional RHS or stage values. * ---------------------------------------------------------------------------*/ @@ -3128,6 +3135,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, ARKodeARKStepMem step_mem; N_Vector z_stage = ark_mem->tempv2; N_Vector J_relax = ark_mem->tempv3; + N_Vector rhs_tmp = NULL; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) @@ -3154,22 +3162,49 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, } else { - /* Reconstruct explicit stages z[i] = y_n + h * sum_j Ae[i,j] Fe[j] */ - nvec = 0; + /* Reconstruct explicit stages */ + if (step_mem->mass_type == MASS_FIXED) + { + /* Fixed mass matrix: z[i] = y_n + M^{-1} h * sum_j Ae[i,j] Fe[j] */ + nvec = 0; - cvals[nvec] = ONE; - Xvecs[nvec] = ark_mem->yn; - nvec++; + for (j = 0; j < i; j++) + { + cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; + Xvecs[nvec] = step_mem->Fe[j]; + nvec++; + } + + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); + if (retval) return ARK_VECTOROP_ERR; + + /* Solve to compute update M^{-1} h * sum_j Ae[i,j] Fe[j] */ + retval = step_mem->msolve((void *) ark_mem, z_stage, step_mem->nlscoef); + if (retval) { return ARK_MASSSOLVE_FAIL; } - for (j = 0; j < i; j++) + /* Compute z[i] = y_n + update */ + N_VLinearSum(ONE, ark_mem->yn, ONE, z_stage, z_stage); + } + else { - cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; - Xvecs[nvec] = step_mem->Fe[j]; + /* Identity matrix: z[i] = y_n + h * sum_j Ae[i,j] Fe[j] or time + dependent matrix: z[i] = y_n + h * sum_j Ae[i,j] M(t)^{-1} Fe[j] */ + nvec = 0; + + cvals[nvec] = ONE; + Xvecs[nvec] = ark_mem->yn; nvec++; - } - retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); - if (retval) return ARK_VECTOROP_ERR; + for (j = 0; j < i; j++) + { + cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; + Xvecs[nvec] = step_mem->Fe[j]; + nvec++; + } + + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); + if (retval) return ARK_VECTOROP_ERR; + } } /* Evaluate the Jacobian at z_i */ @@ -3178,47 +3213,55 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, if (retval < 0) { return ARK_RELAX_JAC_FAIL; } if (retval > 0) { return ARK_RELAX_JAC_RECV; } - /* Update estimate of relaxation function change */ - if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) + /* Reset temporary RHS alias */ + rhs_tmp = z_stage; + + /* Compute delta_e = h * sum_i b_i * */ + if (step_mem->explicit && step_mem->implicit) { - if (step_mem->explicit && step_mem->implicit) - { - N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], - step_mem->Bi->b[i], step_mem->Fi[i], - z_stage); - *delta_e_out += N_VDotProdLocal(J_relax, z_stage); - } - else if (step_mem->explicit) + N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], + step_mem->Bi->b[i], step_mem->Fi[i], + rhs_tmp); + } + else if (step_mem->explicit) + { + if (step_mem->mass_type == MASS_FIXED) { - *delta_e_out += step_mem->Be->b[i] * N_VDotProdLocal(J_relax, - step_mem->Fe[i]); + N_VScale(ONE, step_mem->Fe[i], rhs_tmp); } - else if (step_mem->implicit) + else { - *delta_e_out += step_mem->Bi->b[i] * N_VDotProdLocal(J_relax, - step_mem->Fi[i]); + rhs_tmp = step_mem->Fe[i]; } } else { - if (step_mem->explicit && step_mem->implicit) - { - N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], - step_mem->Bi->b[i], step_mem->Fi[i], - z_stage); - *delta_e_out += N_VDotProd(J_relax, z_stage); - } - else if (step_mem->explicit) + if (step_mem->mass_type == MASS_FIXED) { - *delta_e_out += step_mem->Be->b[i] * N_VDotProd(J_relax, - step_mem->Fe[i]); + N_VScale(ONE, step_mem->Fi[i], rhs_tmp); } - else if (step_mem->implicit) + else { - *delta_e_out += step_mem->Bi->b[i] * N_VDotProd(J_relax, - step_mem->Fi[i]); + rhs_tmp = step_mem->Fi[i]; } } + + if (step_mem->mass_type == MASS_FIXED) + { + retval = step_mem->msolve((void *) ark_mem, rhs_tmp, + step_mem->nlscoef); + if (retval) { return ARK_MASSSOLVE_FAIL; } + } + + /* Update estimate of relaxation function change */ + if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) + { + *delta_e_out += N_VDotProdLocal(J_relax, rhs_tmp); + } + else + { + *delta_e_out += N_VDotProd(J_relax, rhs_tmp); + } } if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) From f44dd154be0b6972d4b037f883ab7fc624e3d14b Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 20:14:24 -0700 Subject: [PATCH 101/111] save stages with fixed M to reduce mass solves --- .../Usage/ARKStep_c_interface/Relaxation.rst | 6 +- src/arkode/arkode_arkstep.c | 62 ++++++------------- 2 files changed, 23 insertions(+), 45 deletions(-) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 7aca7d7a85..3a7ab57b6b 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -33,9 +33,9 @@ Enabling or Disabling Relaxation one of the functions is ``NULL``. If both ``rfn`` and ``rjac`` are ``NULL``, relaxation is disabled. - With DIRK and IMEX-ARK methods, applying relaxation requires allocating - :math:`s` additional state vectors (where :math:`s` is the number of stages - in the method). + With DIRK and IMEX-ARK methods or when a fixed mass matrix is present, + applying relaxation requires allocating :math:`s` additional state vectors + (where :math:`s` is the number of stages in the method). :param arkode_mem: the ARKStep memory structure :param rfn: the user-defined function to compute the relaxation function diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index 2a31cfed55..a8e808fea1 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -1179,8 +1179,10 @@ int arkStep_Init(void* arkode_mem, int init_type) ark_mem->liw += step_mem->stages; /* pointers */ } - /* Allocate stage storage for relaxation with implicit/IMEX methods */ - if (ark_mem->relax_enabled && step_mem->implicit) + /* Allocate stage storage for relaxation with implicit/IMEX methods or if a + fixed mass matrix is present (since we store f(t,y) not M^{-1} f(t,y)) */ + if (ark_mem->relax_enabled && (step_mem->implicit || + step_mem->mass_type == MASS_FIXED)) { if (step_mem->z == NULL) step_mem->z = (N_Vector *) calloc(step_mem->stages, sizeof(N_Vector)); @@ -1756,7 +1758,8 @@ int arkStep_TakeStep_Z(void* arkode_mem, realtype *dsmPtr, int *nflagPtr) /* successful stage solve */ /* store stage (if necessary for relaxation) */ - if (ark_mem->relax_enabled && step_mem->implicit) + if (ark_mem->relax_enabled && (step_mem->implicit || + step_mem->mass_type == MASS_FIXED)) { N_VScale(ONE, ark_mem->ycur, step_mem->z[is]); } @@ -3118,7 +3121,9 @@ int arkStep_RelaxDeltaY(ARKodeMem ark_mem, N_Vector delta_y) * (or compute the delta_e estimate along the way) to avoid inconsistencies * between z_i, F(z_i), and J_relax(z_i) that arise from reconstructing stages * from stored RHS values like with ERK methods. As such the take step function - * stores the stages along the way but only when there is an implicit RHS. + * stores the stages along the way but only when there is an implicit RHS. When + * a fixed mass matrix is present the stages are also stored to avoid additional + * mass matrix solves in reconstructing the stages for an ERK method. * * Future: when ARKStep can exploit the structure of low storage methods, it may * be necessary to compute the delta_e estimate along the way with explicit @@ -3155,7 +3160,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, for (i = 0; i < step_mem->stages; i++) { - if (step_mem->implicit) + if (step_mem->implicit || step_mem->mass_type == MASS_FIXED) { /* Use stored stages */ z_stage = step_mem->z[i]; @@ -3163,48 +3168,21 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, else { /* Reconstruct explicit stages */ - if (step_mem->mass_type == MASS_FIXED) - { - /* Fixed mass matrix: z[i] = y_n + M^{-1} h * sum_j Ae[i,j] Fe[j] */ - nvec = 0; - - for (j = 0; j < i; j++) - { - cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; - Xvecs[nvec] = step_mem->Fe[j]; - nvec++; - } - - retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); - if (retval) return ARK_VECTOROP_ERR; + nvec = 0; - /* Solve to compute update M^{-1} h * sum_j Ae[i,j] Fe[j] */ - retval = step_mem->msolve((void *) ark_mem, z_stage, step_mem->nlscoef); - if (retval) { return ARK_MASSSOLVE_FAIL; } + cvals[nvec] = ONE; + Xvecs[nvec] = ark_mem->yn; + nvec++; - /* Compute z[i] = y_n + update */ - N_VLinearSum(ONE, ark_mem->yn, ONE, z_stage, z_stage); - } - else + for (j = 0; j < i; j++) { - /* Identity matrix: z[i] = y_n + h * sum_j Ae[i,j] Fe[j] or time - dependent matrix: z[i] = y_n + h * sum_j Ae[i,j] M(t)^{-1} Fe[j] */ - nvec = 0; - - cvals[nvec] = ONE; - Xvecs[nvec] = ark_mem->yn; + cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; + Xvecs[nvec] = step_mem->Fe[j]; nvec++; - - for (j = 0; j < i; j++) - { - cvals[nvec] = ark_mem->h * step_mem->Be->A[i][j]; - Xvecs[nvec] = step_mem->Fe[j]; - nvec++; - } - - retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); - if (retval) return ARK_VECTOROP_ERR; } + + retval = N_VLinearCombination(nvec, cvals, Xvecs, z_stage); + if (retval) return ARK_VECTOROP_ERR; } /* Evaluate the Jacobian at z_i */ From 2e59e75e8039b142d485abe2d04c27f4d32de511 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 20:16:18 -0700 Subject: [PATCH 102/111] add back missing b[i] after add M support --- src/arkode/arkode_arkstep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/arkode/arkode_arkstep.c b/src/arkode/arkode_arkstep.c index a8e808fea1..e1245168e0 100644 --- a/src/arkode/arkode_arkstep.c +++ b/src/arkode/arkode_arkstep.c @@ -3135,12 +3135,13 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, sunrealtype* delta_e_out) { int i, j, nvec, retval; - realtype* cvals; + sunrealtype* cvals; N_Vector* Xvecs; ARKodeARKStepMem step_mem; N_Vector z_stage = ark_mem->tempv2; N_Vector J_relax = ark_mem->tempv3; N_Vector rhs_tmp = NULL; + sunrealtype bi = ONE; /* Access the stepper memory structure */ if (!(ark_mem->step_mem)) @@ -3200,6 +3201,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, N_VLinearSum(step_mem->Be->b[i], step_mem->Fe[i], step_mem->Bi->b[i], step_mem->Fi[i], rhs_tmp); + bi = ONE; } else if (step_mem->explicit) { @@ -3211,6 +3213,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, { rhs_tmp = step_mem->Fe[i]; } + bi = step_mem->Be->b[i]; } else { @@ -3222,6 +3225,7 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, { rhs_tmp = step_mem->Fi[i]; } + bi = step_mem->Bi->b[i]; } if (step_mem->mass_type == MASS_FIXED) @@ -3234,11 +3238,11 @@ int arkStep_RelaxDeltaE(ARKodeMem ark_mem, ARKRelaxJacFn relax_jac_fn, /* Update estimate of relaxation function change */ if (J_relax->ops->nvdotprodlocal && J_relax->ops->nvdotprodmultiallreduce) { - *delta_e_out += N_VDotProdLocal(J_relax, rhs_tmp); + *delta_e_out += bi * N_VDotProdLocal(J_relax, rhs_tmp); } else { - *delta_e_out += N_VDotProd(J_relax, rhs_tmp); + *delta_e_out += bi * N_VDotProd(J_relax, rhs_tmp); } } From f502c00731e69e3c76ee0730641685ec8e85fc23 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 20:45:36 -0700 Subject: [PATCH 103/111] remove example utilities --- .../C_serial/ark_conserved_exp_entropy_ark.c | 57 ++++++++++++- .../C_serial/ark_conserved_exp_entropy_erk.c | 57 ++++++++++++- .../C_serial/ark_dissipated_exp_entropy.c | 57 ++++++++++++- examples/utilities/example_utilities.h | 79 ------------------- scripts/shared | 1 - 5 files changed, 162 insertions(+), 89 deletions(-) delete mode 100644 examples/utilities/example_utilities.h diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index f2b5f8516b..82a8e07df2 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -48,9 +48,6 @@ #include #include -/* Common utilities */ -#include - /* SUNDIALS headers */ #include #include @@ -60,6 +57,32 @@ /* Value of the natural number e */ #define EVAL 2.718281828459045235360287471352662497757247093699959574966 +/* Convince macros for calling precision-specific math functions */ +#if defined(SUNDIALS_DOUBLE_PRECISION) +#define EXP(x) (exp((x))) +#define SQRT(x) (sqrt((x))) +#define LOG(x) (log((x))) +#elif defined(SUNDIALS_SINGLE_PRECISION) +#define EXP(x) (expf((x))) +#define SQRT(x) (sqrtf((x))) +#define LOG(x) (logf((x))) +#elif defined(SUNDIALS_EXTENDED_PRECISION) +#define EXP(x) (expl((x))) +#define SQRT(x) (sqrtl((x))) +#define LOG(x) (logl((x))) +#endif + +/* Convince macros for using precision-specific format specifiers */ +#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 + /* ----------------------- * * User-supplied functions * * ----------------------- */ @@ -84,6 +107,12 @@ int JacEnt(N_Vector y, N_Vector J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname); + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname); + /* ------------ * * Main Program * * ------------ */ @@ -471,3 +500,25 @@ int ans(sunrealtype t, N_Vector y) return 0; } + +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "ERROR: %s() returned %d\n", funcname, flag); + return 1; + } + return 0; +} + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "ERROR: %s() returned NULL\n", funcname); + return 1; + } + return 0; +} diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index f233f1d376..b315fd550a 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -48,9 +48,6 @@ #include #include -/* Common utilities */ -#include - /* SUNDIALS headers */ #include #include @@ -58,6 +55,32 @@ /* Value of the natural number e */ #define EVAL 2.718281828459045235360287471352662497757247093699959574966 +/* Convince macros for calling precision-specific math functions */ +#if defined(SUNDIALS_DOUBLE_PRECISION) +#define EXP(x) (exp((x))) +#define SQRT(x) (sqrt((x))) +#define LOG(x) (log((x))) +#elif defined(SUNDIALS_SINGLE_PRECISION) +#define EXP(x) (expf((x))) +#define SQRT(x) (sqrtf((x))) +#define LOG(x) (logf((x))) +#elif defined(SUNDIALS_EXTENDED_PRECISION) +#define EXP(x) (expl((x))) +#define SQRT(x) (sqrtl((x))) +#define LOG(x) (logl((x))) +#endif + +/* Convince macros for using precision-specific format specifiers */ +#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 + /* ----------------------- * * User-supplied functions * * ----------------------- */ @@ -78,6 +101,12 @@ int JacEnt(N_Vector y, N_Vector J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname); + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname); + /* ------------ * * Main Program * * ------------ */ @@ -379,3 +408,25 @@ int ans(sunrealtype t, N_Vector y) return 0; } + +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "ERROR: %s() returned %d\n", funcname, flag); + return 1; + } + return 0; +} + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "ERROR: %s() returned NULL\n", funcname); + return 1; + } + return 0; +} diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index c5eb5d0409..e8aac55c79 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -31,15 +31,38 @@ #include #include -/* Common utilities */ -#include - /* SUNDIALS headers */ #include #include #include #include +/* Convince macros for calling precision-specific math functions */ +#if defined(SUNDIALS_DOUBLE_PRECISION) +#define EXP(x) (exp((x))) +#define SQRT(x) (sqrt((x))) +#define LOG(x) (log((x))) +#elif defined(SUNDIALS_SINGLE_PRECISION) +#define EXP(x) (expf((x))) +#define SQRT(x) (sqrtf((x))) +#define LOG(x) (logf((x))) +#elif defined(SUNDIALS_EXTENDED_PRECISION) +#define EXP(x) (expl((x))) +#define SQRT(x) (sqrtl((x))) +#define LOG(x) (logl((x))) +#endif + +/* Convince macros for using precision-specific format specifiers */ +#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 + /* ----------------------- * * User-supplied functions * * ----------------------- */ @@ -64,6 +87,12 @@ int JacEnt(N_Vector y, N_Vector J, void* user_data); /* Analytic solution */ int ans(sunrealtype t, N_Vector y); +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname); + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname); + /* ------------ * * Main Program * * ------------ */ @@ -421,3 +450,25 @@ int ans(sunrealtype t, N_Vector y) ydata[0] = LOG(EXP(SUN_RCONST(-0.5)) + t); return 0; } + +/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ +int check_flag(int flag, const char* funcname) +{ + if (flag < 0) + { + fprintf(stderr, "ERROR: %s() returned %d\n", funcname, flag); + return 1; + } + return 0; +} + +/* Check if a function returned a NULL pointer */ +int check_ptr(void* ptr, const char* funcname) +{ + if (!ptr) + { + fprintf(stderr, "ERROR: %s() returned NULL\n", funcname); + return 1; + } + return 0; +} diff --git a/examples/utilities/example_utilities.h b/examples/utilities/example_utilities.h deleted file mode 100644 index 9184cc19c4..0000000000 --- a/examples/utilities/example_utilities.h +++ /dev/null @@ -1,79 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * ----------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2022, 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 file should *NOT* be included in user codes and exists *ONLY* to - * reduce duplicate utility functions and macros across example programs. - * ---------------------------------------------------------------------------*/ - -#include - -#include - -/* Check for an unrecoverable (negative) return flag from a SUNDIALS function */ -int check_flag(int flag, const char* funcname) -{ - if (flag < 0) - { - fprintf(stderr, "ERROR: %s() returned %d\n", funcname, flag); - return 1; - } - return 0; -} - -/* Check if a function returned a NULL pointer */ -int check_ptr(void* ptr, const char* funcname) -{ - if (!ptr) - { - fprintf(stderr, "ERROR: %s() returned NULL\n", funcname); - return 1; - } - return 0; -} - -/* Convince macros for calling common precision-specific math functions -- When - type-generic math macros are available (see tgmath.h) defining and using such - macros is unnecessary. */ -#if defined(SUNDIALS_DOUBLE_PRECISION) -#define EXP(x) (exp((x))) -#define SIN(x) (sin((x))) -#define COS(x) (cos((x))) -#define SQRT(x) (sqrt((x))) -#define ABS(x) (fabs((x))) -#define LOG(x) (log((x))) -#elif defined(SUNDIALS_SINGLE_PRECISION) -#define EXP(x) (expf((x))) -#define SIN(x) (sinf((x))) -#define COS(x) (cosf((x))) -#define SQRT(x) (sqrtf((x))) -#define ABS(x) (fabsf((x))) -#define LOG(x) (logf((x))) -#elif defined(SUNDIALS_EXTENDED_PRECISION) -#define EXP(x) (expl((x))) -#define SIN(x) (sinl((x))) -#define COS(x) (cosl((x))) -#define SQRT(x) (sqrtl((x))) -#define ABS(x) (fabsl((x))) -#define LOG(x) (logl((x))) -#endif - -/* Convince macros for using precision-specific format specifiers */ -#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 diff --git a/scripts/shared b/scripts/shared index c3212344ae..b9a7da6458 100755 --- a/scripts/shared +++ b/scripts/shared @@ -579,7 +579,6 @@ echo " --- Add examples utilities to $tarfile" $tar $tarfile $distrobase/examples/utilities/custom_memory_helper_gpu.h $tar $tarfile $distrobase/examples/utilities/custom_memory_helper_sycl.h -$tar $tarfile $distrobase/examples/utilities/example_utilities.h $tar $tarfile $distrobase/examples/utilities/example_utilities.hpp $tar $tarfile $distrobase/examples/utilities/test_utilities.f90 $tar $tarfile $distrobase/examples/utilities/plot_data_2d.py From 94b113368438c393aa87fab956c5c65c4560d064 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 20:51:18 -0700 Subject: [PATCH 104/111] add note about mass matrix support --- .../guide/source/Usage/ARKStep_c_interface/Relaxation.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst index 3a7ab57b6b..6d2027265d 100644 --- a/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst +++ b/doc/arkode/guide/source/Usage/ARKStep_c_interface/Relaxation.rst @@ -21,6 +21,12 @@ This section describes user-callable functions for applying relaxation methods with ARKStep. For more information on relaxation Runge--Kutta methods see :numref:`ARKODE.Mathematics.Relaxation`. +.. note:: + + Relaxation support as not been evaluated with non-identity mass matrices. + While this usage mode is supported, feedback from users who explore this + combination would be appreciated. + Enabling or Disabling Relaxation -------------------------------- From c0d72017d05808b6e7684d7f44c97cd1c4dcab2e Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 21:40:26 -0700 Subject: [PATCH 105/111] point users to references for examples --- doc/arkode/guide/source/Mathematics.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/arkode/guide/source/Mathematics.rst b/doc/arkode/guide/source/Mathematics.rst index a85271eabd..fbe18f3e40 100644 --- a/doc/arkode/guide/source/Mathematics.rst +++ b/doc/arkode/guide/source/Mathematics.rst @@ -2080,17 +2080,17 @@ strategies as discussed in :numref:`ARKODE.Usage.ARKStep.Tolerances` and Relaxation Methods ================== -For cases where the problem :eq:`ARKODE_IVP` is conservative or dissipative with +When the solution of :eq:`ARKODE_IVP` is conservative or dissipative with respect to a smooth *convex* function :math:`\xi(y(t))`, it is desirable to have the numerical method preserve these properties. That is -:math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative problems -and :math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative problems. To this end, -ARKODE supports relaxation methods -:cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation` -applied to ERK, DIRK, or ARK methods to ensure dissipation or preservation of a -global function. - -The relaxed solution is given by +:math:`\xi(y_n) = \xi(y_{n-1}) = \ldots = \xi(y_{0})` for conservative systems +and :math:`\xi(y_n) \leq \xi(y_{n-1})` for dissipative systems. For examples +of such problems, see the references below and the citations there in. + +For such problems, ARKODE supports relaxation methods +:cite:p:`ketcheson2019relaxation, kang2022entropy, ranocha2020relaxation, ranocha2020hamiltonian` +applied to ERK, DIRK, or ARK methods to ensure dissipation or preservation of +the global function. The relaxed solution is given by .. math:: y_r = y_{n-1} + r d = r y_n + (1 - r) y_{n - 1} From 194ac3deb344cf82851d587a5ce7156f095b96aa Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 21:41:46 -0700 Subject: [PATCH 106/111] remove example_utilties.h from CMake files --- examples/arkode/CXX_serial/CMakeLists.txt | 6 ------ examples/arkode/C_serial/CMakeLists.txt | 18 ------------------ 2 files changed, 24 deletions(-) diff --git a/examples/arkode/CXX_serial/CMakeLists.txt b/examples/arkode/CXX_serial/CMakeLists.txt index bded241a5f..41f210c212 100644 --- a/examples/arkode/CXX_serial/CMakeLists.txt +++ b/examples/arkode/CXX_serial/CMakeLists.txt @@ -71,11 +71,6 @@ foreach(example_tuple ${ARKODE_examples}) target_compile_features(${example_target} PRIVATE cxx_std_14) - # directories to include - target_include_directories(${example_target} - PRIVATE - ${PROJECT_SOURCE_DIR}/examples/utilities) - # libraries to link against target_link_libraries(${example_target} sundials_arkode @@ -128,7 +123,6 @@ if(EXAMPLES_INSTALL) README ${ARKODE_extras} ${ARKODE_headers} - "${PROJECT_SOURCE_DIR}/examples/utilities/example_utilities.hpp" TEST_INSTALL CXX_serial ) diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 7f6c865272..a9ea064c0c 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -110,11 +110,6 @@ foreach(example_tuple ${ARKODE_examples}) # folder for IDEs set_target_properties(${example} PROPERTIES FOLDER "Examples") - # directories to include - target_include_directories(${example} - PRIVATE - ${PROJECT_SOURCE_DIR}/examples/utilities) - # libraries to link against target_link_libraries(${example} sundials_arkode @@ -165,11 +160,6 @@ if(BUILD_SUNLINSOL_KLU) ANSWER_FILE ${example}.out EXAMPLE_TYPE ${example_type}) - # directories to include - target_include_directories(${example} - PRIVATE - ${PROJECT_SOURCE_DIR}/examples/utilities) - # libraries to link against target_link_libraries(${example} sundials_arkode @@ -208,11 +198,6 @@ if(BUILD_SUNLINSOL_SUPERLUMT) ANSWER_FILE ${example}.out EXAMPLE_TYPE ${example_type}) - # directories to include - target_include_directories(${example} - PRIVATE - ${PROJECT_SOURCE_DIR}/examples/utilities) - # libraries to link against target_link_libraries(${example} sundials_arkode @@ -242,9 +227,6 @@ if(EXAMPLES_INSTALL) install(FILES ${extrafile} DESTINATION ${EXAMPLES_INSTALL_PATH}/arkode/C_serial) endforeach(extrafile ${ARKODE_extras}) - install(FILES "${PROJECT_SOURCE_DIR}/examples/utilities/example_utilities.h" - DESTINATION ${EXAMPLES_INSTALL_PATH}/arkode/C_serial) - # Prepare substitution variables for Makefile and/or CMakeLists templates set(SOLVER "ARKODE") set(SOLVER_LIB "sundials_arkode") From 6eb07bf6a763194a754c47f6efc9f3b7a71a0792 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Thu, 13 Jul 2023 22:04:32 -0700 Subject: [PATCH 107/111] add back CXX example utils in CMake --- examples/arkode/CXX_serial/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/arkode/CXX_serial/CMakeLists.txt b/examples/arkode/CXX_serial/CMakeLists.txt index 41f210c212..bded241a5f 100644 --- a/examples/arkode/CXX_serial/CMakeLists.txt +++ b/examples/arkode/CXX_serial/CMakeLists.txt @@ -71,6 +71,11 @@ foreach(example_tuple ${ARKODE_examples}) target_compile_features(${example_target} PRIVATE cxx_std_14) + # directories to include + target_include_directories(${example_target} + PRIVATE + ${PROJECT_SOURCE_DIR}/examples/utilities) + # libraries to link against target_link_libraries(${example_target} sundials_arkode @@ -123,6 +128,7 @@ if(EXAMPLES_INSTALL) README ${ARKODE_extras} ${ARKODE_headers} + "${PROJECT_SOURCE_DIR}/examples/utilities/example_utilities.hpp" TEST_INSTALL CXX_serial ) From b66adfa16469f92459cc69f24db46aaeb01f96b9 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 14 Jul 2023 09:29:41 -0700 Subject: [PATCH 108/111] update example outputs --- examples/arkode/CXX_serial/ark_pendulum.cpp | 58 +++++++++++-------- .../C_serial/ark_conserved_exp_entropy_ark.c | 26 +++++---- .../C_serial/ark_conserved_exp_entropy_erk.c | 26 +++++---- .../C_serial/ark_dissipated_exp_entropy.c | 26 +++++---- 4 files changed, 80 insertions(+), 56 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.cpp b/examples/arkode/CXX_serial/ark_pendulum.cpp index ec3efa1688..d56ee752b8 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.cpp +++ b/examples/arkode/CXX_serial/ark_pendulum.cpp @@ -217,6 +217,9 @@ int main(int argc, char* argv[]) sunrealtype t = t0; // Output the initial condition and energy + int swidth = 8; + int rwidth = std::numeric_limits::digits10 + 8; + std::ofstream outfile("ark_pendulum.txt"); outfile << "# vars: t u v energy energy_err\n"; outfile << std::scientific; @@ -224,17 +227,19 @@ int main(int argc, char* argv[]) outfile << t << " " << ydata[0] << " " << ydata[1] << " " << eng0 << " " << SUN_RCONST(0.0) << std::endl; - std::cout << std::setw(5) << "step" << std::setw(24) << "t" << std::setw(24) - << "u" << std::setw(24) << "v" << std::setw(24) << "e" - << std::setw(24) << "e err" << std::endl; - for (int i = 0; i < 9; i++) std::cout << "--------------"; + std::cout << std::setw(swidth) << "step" << std::setw(rwidth) << "t" + << std::setw(rwidth) << "u" << std::setw(rwidth) << "v" + << std::setw(rwidth) << "e" << std::setw(rwidth) << "e err" + << std::endl; + for (int i = 0; i < swidth + 5 * rwidth; i++) std::cout << "-"; std::cout << std::endl; std::cout << std::scientific; std::cout << std::setprecision(std::numeric_limits::digits10); - std::cout << std::setw(5) << 0 << std::setw(24) << t << std::setw(24) - << ydata[0] << std::setw(24) << ydata[1] << std::setw(24) << eng0 - << std::setw(24) << SUN_RCONST(0.0); + std::cout << std::setw(swidth) << 0 << std::setw(rwidth) << t + << std::setw(rwidth) << ydata[0] << std::setw(rwidth) << ydata[1] + << std::setw(rwidth) << eng0 << std::setw(rwidth) + << SUN_RCONST(0.0); std::cout << std::endl; while (t < tf) @@ -257,9 +262,10 @@ int main(int argc, char* argv[]) if (nst % 1000 == 0) { - std::cout << std::setw(5) << nst << std::setw(24) << t << std::setw(24) - << ydata[0] << std::setw(24) << ydata[1] << std::setw(24) << eng - << std::setw(24) << eng_chng << std::endl; + std::cout << std::setw(swidth) << nst << std::setw(rwidth) << t + << std::setw(rwidth) << ydata[0] << std::setw(rwidth) + << ydata[1] << std::setw(rwidth) << eng << std::setw(rwidth) + << eng_chng << std::endl; } /* Write all steps to file */ @@ -267,7 +273,7 @@ int main(int argc, char* argv[]) << eng_chng << std::endl; } - for (int i = 0; i < 9; i++) std::cout << "--------------"; + for (int i = 0; i < swidth + 5 * rwidth; i++) std::cout << "-"; std::cout << std::endl; outfile.close(); @@ -276,9 +282,7 @@ int main(int argc, char* argv[]) * ------------ */ // ARKODE statistics - long int nst, nst_a, nfe, nfi; - long int nrf, nre, nrje, nrnlsi, nrnlsf; - long int nsetups, nje, nfeLS, nni, ncfn, netf; + long int nst, nst_a, netf, nfe, nfi; // Get final statistics on how the solve progressed flag = ARKStepGetNumSteps(arkode_mem, &nst); @@ -302,6 +306,8 @@ int main(int argc, char* argv[]) if (implicit) { + long int nsetups, nje, nfeLS, nni, ncfn; + flag = ARKStepGetNumNonlinSolvIters(arkode_mem, &nni); check_flag(flag, "ARKStepGetNumNonlinSolvIters"); @@ -328,8 +334,7 @@ int main(int argc, char* argv[]) if (relax) { - flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); - check_flag(flag, "ARKStepGetNumRelaxFails"); + long int nre, nrje, nrf, nrbf, nrnlsi, nrnlsf; flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ARKStepGetNumRelaxFnEvals"); @@ -337,17 +342,24 @@ int main(int argc, char* argv[]) flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ARKStepGetNumRelaxJacEvals"); - flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); - check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + + flag = ARKStepGetNumRelaxBoundFails(arkode_mem, &nrbf); + check_flag(flag, "ARKStepGetNumRelaxBoundFails"); flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ARKStepGetNumRelaxSolveFails"); - std::cout << " Total Relaxation fails = " << nrf << "\n"; - std::cout << " Total Relaxation Fn evals = " << nre << "\n"; - std::cout << " Total Relaxation Jac evals = " << nrje << "\n"; - std::cout << " Total Relaxation NLS iters = " << nrnlsi << "\n"; - std::cout << " Total Relaxation NLS fails = " << nrnlsf << "\n"; + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + std::cout << " Total Relaxation Fn evals = " << nre << "\n"; + std::cout << " Total Relaxation Jac evals = " << nrje << "\n"; + std::cout << " Total Relaxation fails = " << nrf << "\n"; + std::cout << " Total Relaxation bound fails = " << nrbf << "\n"; + std::cout << " Total Relaxation NLS fails = " << nrnlsf << "\n"; + std::cout << " Total Relaxation NLS iters = " << nrnlsi << "\n"; } std::cout << "\n"; diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 82a8e07df2..03e716b13e 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -152,7 +152,7 @@ int main(int argc, char* argv[]) /* ARKODE statistics */ long int nst, nst_a, nfe, nfi; - long int nrf, nre, nrje, nrnlsi, nrnlsf; + long int nrf, nrbf, nre, nrje, nrnlsi, nrnlsf; long int nsetups, nje, nfeLS, nni, ncfn, netf; /* Output time and file */ @@ -388,26 +388,30 @@ int main(int argc, char* argv[]) if (relax) { - flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); - check_flag(flag, "ARKStepGetNumRelaxFails"); - flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ARKStepGetNumRelaxFnEvals"); flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ARKStepGetNumRelaxJacEvals"); - flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); - check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + + flag = ARKStepGetNumRelaxBoundFails(arkode_mem, &nrbf); + check_flag(flag, "ARKStepGetNumRelaxBoundFails"); flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ARKStepGetNumRelaxSolveFails"); - printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation Fn evals = %li\n", nre); - printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation NLS iters = %li\n", nrnlsi); - printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } printf("\n"); diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index b315fd550a..07b74ab1e7 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -144,7 +144,7 @@ int main(int argc, char* argv[]) /* ARKODE statistics */ long int nst, nst_a, nfe; - long int nrf, nre, nrje, nrnlsi, nrnlsf, netf; + long int nrf, nrbf, nre, nrje, nrnlsi, nrnlsf, netf; /* Output time and file */ sunrealtype t; @@ -316,26 +316,30 @@ int main(int argc, char* argv[]) if (relax) { - flag = ERKStepGetNumRelaxFails(arkode_mem, &nrf); - check_flag(flag, "ERKStepGetNumRelaxFails"); - flag = ERKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ERKStepGetNumRelaxFnEvals"); flag = ERKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ERKStepGetNumRelaxJacEvals"); - flag = ERKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); - check_flag(flag, "ERKStepGetNumRelaxSolveIters"); + flag = ERKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ERKStepGetNumRelaxFails"); + + flag = ERKStepGetNumRelaxBoundFails(arkode_mem, &nrbf); + check_flag(flag, "ERKStepGetNumRelaxBoundFails"); flag = ERKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ERKStepGetNumRelaxSolveFails"); - printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation Fn evals = %li\n", nre); - printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation NLS iters = %li\n", nrnlsi); - printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + flag = ERKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); + check_flag(flag, "ERKStepGetNumRelaxSolveIters"); + + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } printf("\n"); diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index e8aac55c79..e51c6392c4 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -132,7 +132,7 @@ int main(int argc, char* argv[]) /* ARKODE statistics */ long int nst, nst_a, nfe, nfi; - long int nrf, nre, nrje, nrnlsi, nrnlsf; + long int nrf, nrbf, nre, nrje, nrnlsi, nrnlsf; long int nsetups, nje, nfeLS, nni, ncfn, netf; /* Output time and file */ @@ -361,26 +361,30 @@ int main(int argc, char* argv[]) if (relax) { - flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); - check_flag(flag, "ARKStepGetNumRelaxFails"); - flag = ARKStepGetNumRelaxFnEvals(arkode_mem, &nre); check_flag(flag, "ARKStepGetNumRelaxFnEvals"); flag = ARKStepGetNumRelaxJacEvals(arkode_mem, &nrje); check_flag(flag, "ARKStepGetNumRelaxJacEvals"); - flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); - check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + flag = ARKStepGetNumRelaxFails(arkode_mem, &nrf); + check_flag(flag, "ARKStepGetNumRelaxFails"); + + flag = ARKStepGetNumRelaxBoundFails(arkode_mem, &nrbf); + check_flag(flag, "ARKStepGetNumRelaxBoundFails"); flag = ARKStepGetNumRelaxSolveFails(arkode_mem, &nrnlsf); check_flag(flag, "ARKStepGetNumRelaxSolveFails"); - printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation Fn evals = %li\n", nre); - printf(" Total Relaxation Jac evals = %li\n", nrje); - printf(" Total Relaxation NLS iters = %li\n", nrnlsi); - printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + flag = ARKStepGetNumRelaxSolveIters(arkode_mem, &nrnlsi); + check_flag(flag, "ARKStepGetNumRelaxSolveIters"); + + printf(" Total Relaxation Fn evals = %li\n", nre); + printf(" Total Relaxation Jac evals = %li\n", nrje); + printf(" Total Relaxation fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation NLS fails = %li\n", nrnlsf); + printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } printf("\n"); From 4c86a0dda30926ec9d873311666c46c10103129f Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 14 Jul 2023 10:08:24 -0700 Subject: [PATCH 109/111] udpate answers submodule commit --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 7819cc606f..9e00b28270 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 7819cc606fddf71268731910f6fa0720ae3df84b +Subproject commit 9e00b2827014a2f2839297b2aa9df799f4d1c391 From 5322b3a114662755362fe993ba1f0177dbb5af49 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 14 Jul 2023 12:15:28 -0700 Subject: [PATCH 110/111] update .out file for Jenkins --- examples/arkode/CXX_serial/ark_pendulum.out | 35 ++++++++++--------- .../ark_conserved_exp_entropy_ark_1_0.out | 11 +++--- .../ark_conserved_exp_entropy_ark_1_1.out | 11 +++--- .../ark_conserved_exp_entropy_erk_1.out | 11 +++--- .../ark_dissipated_exp_entropy_1_0.out | 11 +++--- .../ark_dissipated_exp_entropy_1_1.out | 11 +++--- 6 files changed, 48 insertions(+), 42 deletions(-) diff --git a/examples/arkode/CXX_serial/ark_pendulum.out b/examples/arkode/CXX_serial/ark_pendulum.out index 7d88b055f1..dca1a58ccb 100644 --- a/examples/arkode/CXX_serial/ark_pendulum.out +++ b/examples/arkode/CXX_serial/ark_pendulum.out @@ -4,18 +4,18 @@ Nonlinear Pendulum problem: reltol = 1e-06 abstol = 1e-10 - step t u v e e err ------------------------------------------------------------------------------------------------------------------------------- - 0 0.000000000000000e+00 1.500000000000000e+00 1.000000000000000e+00 5.846976941318602e-01 0.000000000000000e+00 - 1000 1.226511879534299e+00 3.458488320982976e-01 2.123384535074106e+00 5.846976941318555e-01 -4.773959005888173e-15 - 2000 2.398784336118560e+00 -6.416442371616857e-01 1.959343228667432e+00 5.846976941318377e-01 -2.253752739989068e-14 - 3000 3.618483293504332e+00 -1.718124366999066e+00 4.706406225355917e-01 5.846976941318435e-01 -1.676436767183986e-14 - 4000 4.580865391430372e+00 -1.411700239944070e+00 -1.146421559917496e+00 5.846976941318369e-01 -2.331468351712829e-14 - 5000 5.877850661141863e+00 -2.026377125271683e-01 -2.170219947005763e+00 5.846976941318408e-01 -1.942890293094024e-14 - 6000 7.079795692175875e+00 8.320973704310155e-01 -1.811622127832077e+00 5.846976941318234e-01 -3.685940441755520e-14 - 7000 8.313428698722841e+00 1.777791699609239e+00 -9.412012907795819e-02 5.846976941318288e-01 -3.141931159689193e-14 - 8000 9.289846347799413e+00 1.192220279192671e+00 1.444463648145965e+00 5.846976941318289e-01 -3.130828929442941e-14 ------------------------------------------------------------------------------------------------------------------------------- + step t u v e e err +--------------------------------------------------------------------------------------------------------------------------- + 0 0.000000000000000e+00 1.500000000000000e+00 1.000000000000000e+00 5.846976941318602e-01 0.000000000000000e+00 + 1000 1.226511879534299e+00 3.458488320982976e-01 2.123384535074106e+00 5.846976941318555e-01 -4.773959005888173e-15 + 2000 2.398784336118560e+00 -6.416442371616857e-01 1.959343228667432e+00 5.846976941318377e-01 -2.253752739989068e-14 + 3000 3.618483293504332e+00 -1.718124366999066e+00 4.706406225355917e-01 5.846976941318435e-01 -1.676436767183986e-14 + 4000 4.580865391430372e+00 -1.411700239944070e+00 -1.146421559917496e+00 5.846976941318369e-01 -2.331468351712829e-14 + 5000 5.877850661141863e+00 -2.026377125271683e-01 -2.170219947005763e+00 5.846976941318408e-01 -1.942890293094024e-14 + 6000 7.079795692175875e+00 8.320973704310155e-01 -1.811622127832077e+00 5.846976941318234e-01 -3.685940441755520e-14 + 7000 8.313428698722841e+00 1.777791699609239e+00 -9.412012907795819e-02 5.846976941318288e-01 -3.141931159689193e-14 + 8000 9.289846347799413e+00 1.192220279192671e+00 1.444463648145965e+00 5.846976941318289e-01 -3.130828929442941e-14 +--------------------------------------------------------------------------------------------------------------------------- Final Solver Statistics: Internal solver steps = 8518 (attempted = 8528) @@ -26,9 +26,10 @@ Final Solver Statistics: Total linear solver setups = 459 Total number of Jacobian evaluations = 146 Total RHS evals for setting up the linear system = 0 - Total Relaxation fails = 0 - Total Relaxation Fn evals = 25494 - Total Relaxation Jac evals = 25494 - Total Relaxation NLS iters = 8438 - Total Relaxation NLS fails = 0 + Total Relaxation Fn evals = 25494 + Total Relaxation Jac evals = 25494 + Total Relaxation fails = 0 + Total Relaxation bound fails = 0 + Total Relaxation NLS fails = 0 + Total Relaxation NLS iters = 8438 diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out index 09a30c1559..0a364b9742 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out @@ -16,9 +16,10 @@ Final Solver Statistics: Internal solver steps = 99 (attempted = 124) Total number of error test failures = 0 Total RHS evals: Fe = 722, Fi = 0 - Total Relaxation fails = 25 - Total Relaxation Fn evals = 622 - Total Relaxation Jac evals = 1019 - Total Relaxation NLS iters = 399 - Total Relaxation NLS fails = 25 + Total Relaxation Fn evals = 622 + Total Relaxation Jac evals = 1019 + Total Relaxation fails = 25 + Total Relaxation bound fails = 25 + Total Relaxation NLS fails = 25 + Total Relaxation NLS iters = 399 diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out index 6d4dfcbe07..e1809f0bfc 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out @@ -44,9 +44,10 @@ Final Solver Statistics: Total linear solver setups = 844 Total number of Jacobian evaluations = 304 Total RHS evals for setting up the linear system = 0 - Total Relaxation fails = 266 - Total Relaxation Fn evals = 7023 - Total Relaxation Jac evals = 8651 - Total Relaxation NLS iters = 4523 - Total Relaxation NLS fails = 252 + Total Relaxation Fn evals = 7023 + Total Relaxation Jac evals = 8651 + Total Relaxation fails = 266 + Total Relaxation bound fails = 266 + Total Relaxation NLS fails = 252 + Total Relaxation NLS iters = 4523 diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out index 9ac4f91736..cf02ceaca1 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out @@ -16,9 +16,10 @@ Final Solver Statistics: Internal solver steps = 95 (attempted = 121) Total number of error test failures = 2 Total RHS evals = 582 - Total Relaxation fails = 24 - Total Relaxation Fn evals = 608 - Total Relaxation Jac evals = 995 - Total Relaxation NLS iters = 390 - Total Relaxation NLS fails = 24 + Total Relaxation Fn evals = 608 + Total Relaxation Jac evals = 995 + Total Relaxation fails = 24 + Total Relaxation bound fails = 24 + Total Relaxation NLS fails = 24 + Total Relaxation NLS iters = 390 diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out index b2c3a67e8d..90df8380be 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_0.out @@ -17,9 +17,10 @@ Final Solver Statistics: Internal solver steps = 130 (attempted = 130) Total number of error test failures = 0 Total RHS evals: Fe = 783, Fi = 0 - Total Relaxation fails = 0 - Total Relaxation Fn evals = 392 - Total Relaxation Jac evals = 782 - Total Relaxation NLS iters = 132 - Total Relaxation NLS fails = 0 + Total Relaxation Fn evals = 392 + Total Relaxation Jac evals = 782 + Total Relaxation fails = 0 + Total Relaxation bound fails = 0 + Total Relaxation NLS fails = 0 + Total Relaxation NLS iters = 132 diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out index fa719a264d..49be4a5967 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy_1_1.out @@ -50,9 +50,10 @@ Final Solver Statistics: Total linear solver setups = 149 Total number of Jacobian evaluations = 93 Total RHS evals for setting up the linear system = 0 - Total Relaxation fails = 0 - Total Relaxation Fn evals = 3773 - Total Relaxation Jac evals = 5019 - Total Relaxation NLS iters = 1281 - Total Relaxation NLS fails = 0 + Total Relaxation Fn evals = 3773 + Total Relaxation Jac evals = 5019 + Total Relaxation fails = 0 + Total Relaxation bound fails = 0 + Total Relaxation NLS fails = 0 + Total Relaxation NLS iters = 1281 From bc4b20900fee3df62f4cc61fc6e07b7422994b73 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 14 Jul 2023 12:34:01 -0700 Subject: [PATCH 111/111] fix typo in output --- examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c | 2 +- examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out | 2 +- examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out | 2 +- examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c | 2 +- examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out | 2 +- examples/arkode/C_serial/ark_dissipated_exp_entropy.c | 2 +- test/answers | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c index 03e716b13e..9064c56987 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark.c @@ -409,7 +409,7 @@ int main(int argc, char* argv[]) printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrbf); printf(" Total Relaxation NLS fails = %li\n", nrnlsf); printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out index 0a364b9742..05f6b3f4ce 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_0.out @@ -19,7 +19,7 @@ Final Solver Statistics: Total Relaxation Fn evals = 622 Total Relaxation Jac evals = 1019 Total Relaxation fails = 25 - Total Relaxation bound fails = 25 + Total Relaxation bound fails = 0 Total Relaxation NLS fails = 25 Total Relaxation NLS iters = 399 diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out index e1809f0bfc..77742dc2bd 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_ark_1_1.out @@ -47,7 +47,7 @@ Final Solver Statistics: Total Relaxation Fn evals = 7023 Total Relaxation Jac evals = 8651 Total Relaxation fails = 266 - Total Relaxation bound fails = 266 + Total Relaxation bound fails = 14 Total Relaxation NLS fails = 252 Total Relaxation NLS iters = 4523 diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c index 07b74ab1e7..a13add2ac3 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk.c @@ -337,7 +337,7 @@ int main(int argc, char* argv[]) printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrbf); printf(" Total Relaxation NLS fails = %li\n", nrnlsf); printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } diff --git a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out index cf02ceaca1..9e1649f48e 100644 --- a/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out +++ b/examples/arkode/C_serial/ark_conserved_exp_entropy_erk_1.out @@ -19,7 +19,7 @@ Final Solver Statistics: Total Relaxation Fn evals = 608 Total Relaxation Jac evals = 995 Total Relaxation fails = 24 - Total Relaxation bound fails = 24 + Total Relaxation bound fails = 0 Total Relaxation NLS fails = 24 Total Relaxation NLS iters = 390 diff --git a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c index e51c6392c4..76da27a0c1 100644 --- a/examples/arkode/C_serial/ark_dissipated_exp_entropy.c +++ b/examples/arkode/C_serial/ark_dissipated_exp_entropy.c @@ -382,7 +382,7 @@ int main(int argc, char* argv[]) printf(" Total Relaxation Fn evals = %li\n", nre); printf(" Total Relaxation Jac evals = %li\n", nrje); printf(" Total Relaxation fails = %li\n", nrf); - printf(" Total Relaxation bound fails = %li\n", nrf); + printf(" Total Relaxation bound fails = %li\n", nrbf); printf(" Total Relaxation NLS fails = %li\n", nrnlsf); printf(" Total Relaxation NLS iters = %li\n", nrnlsi); } diff --git a/test/answers b/test/answers index 9e00b28270..97011ebcf0 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 9e00b2827014a2f2839297b2aa9df799f4d1c391 +Subproject commit 97011ebcf0322a6372bbff86acf7a95c5546169c