From 290b9b83a19031073aa7486e5c1b4bfa187e1065 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 15 Dec 2025 13:43:11 -0600 Subject: [PATCH 01/76] power updates --- include/sundials/sundials_domeigestimator.h | 4 + include/sundomeigest/sundomeigest_power.h | 7 +- src/sundials/sundials_domeigestimator.c | 10 + src/sundomeigest/power/sundomeigest_power.c | 146 ++++++++- .../sundomeigest/Power/CMakeLists.txt | 6 +- .../Power/test_sundomeigest_power_complex.c | 299 ++++++++++++++++++ .../sundomeigest/test_sundomeigest.c | 31 ++ .../sundomeigest/test_sundomeigest.h | 1 + 8 files changed, 496 insertions(+), 8 deletions(-) create mode 100644 test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index cd3cb3f7db..f4dfbd29ee 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -52,6 +52,7 @@ struct SUNDomEigEstimator_Ops_ SUNErrCode (*setnumpreprocessiters)(SUNDomEigEstimator, int); SUNErrCode (*setreltol)(SUNDomEigEstimator, sunrealtype); SUNErrCode (*setinitialguess)(SUNDomEigEstimator, N_Vector); + SUNErrCode (*setcomplex)(SUNDomEigEstimator); SUNErrCode (*initialize)(SUNDomEigEstimator); SUNErrCode (*estimate)(SUNDomEigEstimator, sunrealtype*, sunrealtype*); SUNErrCode (*getres)(SUNDomEigEstimator, sunrealtype*); @@ -105,6 +106,9 @@ SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol) SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 62171ac318..049f215f25 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -41,7 +41,7 @@ struct SUNDomEigEstimatorContent_Power_ SUNATimesFn ATimes; /* User provided ATimes function */ void* ATdata; /* ATimes function data*/ - N_Vector V, q; /* workspace vectors */ + N_Vector V, q, q_prev; /* workspace vectors */ int num_warmups; /* Number of preprocessing iterations */ long int max_iters; /* Maximum number of power iterations */ @@ -51,6 +51,8 @@ struct SUNDomEigEstimatorContent_Power_ sunrealtype rel_tol; /* Convergence criteria for the power iteration */ sunrealtype res; /* Residual from the last Estimate call */ + + sunbooleantype complex; /* Flag for complex eigenvalue request */ }; typedef struct SUNDomEigEstimatorContent_Power_* SUNDomEigEstimatorContent_Power; @@ -84,6 +86,9 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE); diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 3e26d25a4a..b2b462c469 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -257,6 +257,16 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q return (ier); } +SUNErrCode SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE) +{ + SUNErrCode ier; + SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); + if (DEE->ops->setcomplex) { ier = DEE->ops->setcomplex(DEE); } + else { ier = SUN_SUCCESS; } + SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); + return (ier); +} + SUNErrCode SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE) { SUNErrCode ier; diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 0202ab955b..a8bbce889d 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -51,6 +51,19 @@ * ----------------------------------------------------------------- */ +/* +* -------------------------------------------------------------------------- +* private functions +* -------------------------------------------------------------------------- +*/ + +SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, + sunrealtype lambdaR, + N_Vector v_prev, + N_Vector v, + sunrealtype* lambdaR_out, + sunrealtype* lambdaI_out); + /* ---------------------------------------------------------------------------- * Function to create a new PI estimator */ @@ -93,6 +106,7 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Power; + DEE->ops->setcomplex = SUNDomEigEstimator_SetComplex_Power; DEE->ops->initialize = SUNDomEigEstimator_Initialize_Power; DEE->ops->estimate = SUNDomEigEstimator_Estimate_Power; DEE->ops->getres = SUNDomEigEstimator_GetRes_Power; @@ -114,6 +128,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, content->ATdata = NULL; content->V = NULL; content->q = NULL; + content->q_prev = NULL; + content->complex = SUNFALSE; content->max_iters = max_iters; content->num_warmups = DEE_NUM_OF_WARMUPS_PI_DEFAULT; content->rel_tol = rel_tol; @@ -156,6 +172,22 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } +SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + + /* set the complex flag */ + PI_CONTENT(DEE)->complex = SUNTRUE; + + /* allocate q_prev vector */ + PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); + + return SUN_SUCCESS; +} + SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE) { SUNFunctionBegin(DEE->sunctx); @@ -275,6 +307,10 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); SUNAssert((PI_CONTENT(DEE)->max_iters >= 0), SUN_ERR_ARG_CORRUPT); + if(PI_CONTENT(DEE)->complex == SUNTRUE) + { + SUNAssert(PI_CONTENT(DEE)->q_prev, SUN_ERR_ARG_CORRUPT); + } sunrealtype newlambdaR = ZERO; sunrealtype oldlambdaR = ZERO; @@ -302,6 +338,12 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, for (int k = 0; k < PI_CONTENT(DEE)->max_iters; k++) { + if(PI_CONTENT(DEE)->complex == SUNTRUE) //TODO: instead we can Scale after convergence and reiterate once more + { + N_VScale(ONE, PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q_prev); + SUNCheckLastErr(); + } + retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->num_ATimes++; @@ -312,10 +354,6 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, PI_CONTENT(DEE)->q); //Rayleigh quotient SUNCheckLastErr(); - PI_CONTENT(DEE)->res = SUNRabs(newlambdaR - oldlambdaR) / SUNRabs(newlambdaR); - - if (PI_CONTENT(DEE)->res < PI_CONTENT(DEE)->rel_tol) { break; } - normq = N_VDotProd(PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->q); SUNCheckLastErr(); @@ -323,11 +361,27 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, N_VScale(ONE / normq, PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->V); SUNCheckLastErr(); + PI_CONTENT(DEE)->res = SUNRabs(newlambdaR - oldlambdaR) / SUNRabs(newlambdaR); + + if (PI_CONTENT(DEE)->res < PI_CONTENT(DEE)->rel_tol) { break; } + oldlambdaR = newlambdaR; } - *lambdaI = ZERO; - *lambdaR = newlambdaR; + if(PI_CONTENT(DEE)->complex == SUNTRUE) + { + retval = sundomeigestimator_complex_dom_eigs_from_PI(DEE, newlambdaR, + PI_CONTENT(DEE)->q_prev, + PI_CONTENT(DEE)->V, + lambdaR, lambdaI); + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + } + else + { + *lambdaR = newlambdaR; + *lambdaI = ZERO; + } return SUN_SUCCESS; } @@ -401,6 +455,86 @@ SUNErrCode SUNDomEigEstimator_Write_Power(SUNDomEigEstimator DEE, FILE* outfile) return SUN_SUCCESS; } +SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, + sunrealtype lambdaR, + N_Vector v_prev, + N_Vector v, + sunrealtype* lambdaR_out, + sunrealtype* lambdaI_out) +{ + SUNFunctionBegin(DEE->sunctx); + + int retval; + sunrealtype cos_qs, det_G_inv, h11, h12,h21, h22, p11, p12, p21, p22; + sunrealtype proj_cond_inv = SUN_RCONST(1e-2); + cos_qs = N_VDotProd(v_prev, v); + SUNCheckLastErr(); + + printf("cos_qs: " SUN_FORMAT_G "\n", cos_qs); + + if(fabs(fabs(cos_qs) - ONE) < proj_cond_inv) + { + printf("Warning: Projection matrix is ill-conditioned. Returning " + "dominant eigenvalue as real part only.\n"); + /* Dominant eigenvalue is real */ + *lambdaR_out = lambdaR; + *lambdaI_out = ZERO; + //TODO: store eigenvector as well for a get routine + return SUN_SUCCESS; + } + else + { + det_G_inv = ONE/(ONE - cos_qs * cos_qs); + + /* Solve for G = [v_prev v]' * [v_prev v] and compute + projected matrix P = G^{-1} * [v_prev v]' * A * [v_prev v] */ + + retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, + v_prev, PI_CONTENT(DEE)->q); + PI_CONTENT(DEE)->num_ATimes++; + PI_CONTENT(DEE)->num_iters++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + h11 = N_VDotProd(v_prev, PI_CONTENT(DEE)->q); + h21 = N_VDotProd(v, PI_CONTENT(DEE)->q); + + retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, + v, PI_CONTENT(DEE)->q); + PI_CONTENT(DEE)->num_ATimes++; + PI_CONTENT(DEE)->num_iters++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + h12 = N_VDotProd(v_prev, PI_CONTENT(DEE)->q); + h22 = N_VDotProd(v, PI_CONTENT(DEE)->q); + + p11 = det_G_inv * (h11 - cos_qs * h21); + p12 = det_G_inv * (h12 - cos_qs * h22); + p21 = det_G_inv * (h21 - cos_qs * h11); + p22 = det_G_inv * (h22 - cos_qs * h12); + + /* Compute eigenvalues of P */ + sunrealtype traceP = p11 + p22; + sunrealtype detP = p11 * p22 - p12 * p21; + sunrealtype discrim = traceP * traceP - SUN_RCONST(4.0) * detP; + if(discrim >= ZERO) + { + /* Dominant eigenvalue is real */ + *lambdaR_out = (traceP + SUNRsqrt(discrim)) / SUN_RCONST(2.0); + *lambdaI_out = ZERO; + } + else + { + /* Dominant eigenvalue is complex */ + *lambdaR_out = traceP / SUN_RCONST(2.0); + *lambdaI_out = SUNRsqrt(-discrim) / SUN_RCONST(2.0); + } + //TODO: store eigenvector as well for a get routine + //find eigenvector of P and map back to original space by [v_prev v] * eigenvector_P + } + + return SUN_SUCCESS; +} + SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) { SUNFunctionBegin((*DEEptr)->sunctx); diff --git a/test/unit_tests/sundomeigest/Power/CMakeLists.txt b/test/unit_tests/sundomeigest/Power/CMakeLists.txt index 5f19a92990..ebc0f76a40 100644 --- a/test/unit_tests/sundomeigest/Power/CMakeLists.txt +++ b/test/unit_tests/sundomeigest/Power/CMakeLists.txt @@ -25,7 +25,11 @@ set(sundomeigest_power_examples "test_sundomeigest_power\;100 100 0 0\;" "test_sundomeigest_power\;1000 100 0 0\;" "test_sundomeigest_power\;10000 100 0 0\;" - "test_sundomeigest_power\;100000 100 0 0\;") + "test_sundomeigest_power\;100000 100 0 0\;" + "test_sundomeigest_power_complex\;100 100 0 0\;" + "test_sundomeigest_power_complex\;1000 100 0 0\;" + "test_sundomeigest_power_complex\;10000 100 100 0\;" + "test_sundomeigest_power_complex\;100000 100 100 0\;") # Dependencies for dominant eigenvalue examples set(sundomeigest_power_dependencies test_sundomeigest) diff --git a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c new file mode 100644 index 0000000000..b24d0bd484 --- /dev/null +++ b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c @@ -0,0 +1,299 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Mustafa Aggul @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * These test functions check some components of Power Iteration + * module implementation. + * ----------------------------------------------------------------- + */ + +#include +#include +#include "../test_sundomeigest.h" + +/* constants */ +#define ZERO SUN_RCONST(0.0) + +#define factor SUN_RCONST(-10.0) +#define realpart SUN_RCONST(-30000.0) +#define imagpart SUN_RCONST(+40000.0) + +/* user data structure */ +typedef struct +{ + sunindextype N; /* problem size */ + N_Vector diag; /* matrix diagonal */ + + /* nondiagonal entries of the matrix that lead to the complex conjugate eigenvalues */ + sunrealtype real_part; + sunrealtype imag_part; +} UserData; + +/* private functions */ +/* matrix-vector product */ +int ATimes(void* ProbData, N_Vector v, N_Vector z); +/* checks function return values */ +int check_flag(void* flagvalue, const char* funcname, int opt); + +/* ---------------------------------------------------------------------- + * DomEig Module Testing Routine + * --------------------------------------------------------------------*/ +int main(int argc, char* argv[]) +{ + int fails = 0; /* counter for test failures */ + int passfail = 0; /* overall pass/fail flag */ + SUNDomEigEstimator DEE = NULL; /* domeig estimator object */ + UserData ProbData; /* problem data structure */ + int num_warmups; /* number of preprocessing iters */ + long int max_iters; /* max power iteration */ + long int num_iters; /* cur. number of iterations */ + long int num_ATimes; /* number of ATimes calls */ + int print_timing; /* timing output flag */ + sunrealtype res; /* current residual */ + sunrealtype lambdaR, lambdaI; /* computed domeig parts */ + sunrealtype tlambdaR, tlambdaI; /* true domeig parts */ + SUNContext sunctx; + sunrealtype rel_tol = SUN_RCONST(1.0e-2); /* relative tol for pass/fail */ + sunrealtype rel_error; + N_Vector q; /* random initial eigenvector */ + + if (SUNContext_Create(SUN_COMM_NULL, &sunctx)) + { + printf("ERROR: SUNContext_Create failed\n"); + return (-1); + } + + /* check inputs: local problem size, max iters, num preprocessing, timing flag */ + if (argc < 5) + { + printf("ERROR: FOUR (4) Inputs required:\n"); + printf(" Problem size should be >= 2\n"); + printf(" Maximum number of power iterations should be > 0\n"); + printf(" Number of preprocessing iters should be >= 0\n"); + printf(" Include timers for calculation (0=off, 1=on)\n"); + return 1; + } + ProbData.N = (sunindextype)atol(argv[1]); + if (ProbData.N <= 0) + { + printf("ERROR: Problem size must be a positive integer\n"); + return 1; + } + max_iters = atoi(argv[2]); + if (max_iters <= 0) + { + printf( + "ERROR: Maximum number of power iterations must be a positive integer\n"); + return 1; + } + num_warmups = atoi(argv[3]); + if (num_warmups < 0) + { + printf("ERROR: Number of preprocessing must be a nonnegative integer\n"); + return 1; + } + print_timing = atoi(argv[4]); + SetTiming(print_timing); + + printf("\nDomEig module test:\n"); + printf(" Problem size = %ld\n", (long int)ProbData.N); + printf(" Number of power iterations = %ld\n", (long int)max_iters); + printf(" Number of preprocessing iters = %i\n", num_warmups); + printf(" Timing output flag = %i\n\n", print_timing); + + /* Create vectors */ + ProbData.diag = N_VNew_Serial(ProbData.N, sunctx); + if (check_flag(ProbData.diag, "N_VNew_Serial", 0)) { return 1; } + + q = N_VClone(ProbData.diag); + if (check_flag(q, "N_VClone", 0)) { return 1; } + + sunrealtype* qd = N_VGetArrayPointer(q); + for (int i = 0; i < ProbData.N; i++) + { + qd[i] = (sunrealtype)rand() / (sunrealtype)RAND_MAX; + } + + /* Fill matrix diagonal and problem data */ + // real diag is [3 4 5 ... N 0 0]*factor + // 2x2 block matrix attached to the last two diagonals is + // [ realpart imagpart; + // [-imagpart realpart] + // This setup allows two types of dominant eigenvalues (real and complex) + // based on the "factor" and the problem dimension N. + sunrealtype* v = N_VGetArrayPointer(ProbData.diag); + for (int i = 0; i < ProbData.N - 2; i++) { v[i] = factor * (i + 3); } + + // Set the problem data corresponding to 2x2 block matrix + ProbData.real_part = realpart; + ProbData.imag_part = imagpart; + + /* Create Power Iteration Dominant Eigvalue Estimator (DEE)*/ + DEE = SUNDomEigEstimator_Power(q, max_iters, rel_tol, sunctx); + if (check_flag(DEE, "SUNDomEigEstimator_Power", 0)) { return 1; } + + fails += Test_SUNDomEigEstimator_SetATimes(DEE, &ProbData, ATimes, 0); + fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, max_iters, 0); + fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); + fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); + fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); + fails += Test_SUNDomEigEstimator_SetComplex(DEE, 0); + fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); + fails += Test_SUNDomEigEstimator_Estimate(DEE, &lambdaR, &lambdaI, 0); + fails += Test_SUNDomEigEstimator_GetRes(DEE, &res, 0); + if (res < SUN_SMALL_REAL) + { + printf(" >>> FAILED test -- SUNDomEigEstimator_GetRes return value\n"); + fails++; + } + fails += Test_SUNDomEigEstimator_GetNumIters(DEE, &num_iters, 0); + if (num_iters <= 0) + { + printf( + " >>> FAILED test -- SUNDomEigEstimator_GetNumIters return value\n"); + fails++; + } + fails += Test_SUNDomEigEstimator_GetNumATimesCalls(DEE, &num_ATimes, 0); + fails += Test_SUNDomEigEstimator_Write(DEE, 0); + + if (fails) + { + printf("FAIL: SUNDomEigEstimator_Power module failed %i initialization " + "tests\n\n", + fails); + return 1; + } + else + { + printf("SUCCESS: SUNDomEigEstimator_Power module passed all initialization " + "tests\n\n"); + } + + /* First check if the computed eigenvalue has a nonzero magnitute */ + sunrealtype norm_of_dom_eig = SUNRsqrt(lambdaR * lambdaR + lambdaI * lambdaI); + if (norm_of_dom_eig < SUN_SMALL_REAL) + { + printf("FAIL: Dominant Eigenvalue Test Failed\n\n"); + return 1; + } + + /* Identify the tlambdaR and tlambdaI based on given parameters*/ + if (SUNRsqrt(realpart * realpart + imagpart * imagpart) > -factor * ProbData.N) + { + /* Dominant eigenvalue corresponds to the 2x2 block matrix */ + tlambdaR = realpart; + tlambdaI = imagpart; + } + else + { + /* Dominant eigenvalue corresponds to the maximum real value at the diagonal */ + tlambdaR = factor * ProbData.N; + tlambdaI = ZERO; + } + + printf("\ncomputed dominant eigenvalue = " SUN_FORMAT_G " + " SUN_FORMAT_G + " i\n", + lambdaR, lambdaI); + printf(" true dominant eigenvalue = " SUN_FORMAT_G " + " SUN_FORMAT_G + " i\n", + tlambdaR, tlambdaI); + + /* Compare the estimated dom_eig with the tlambdaR and tlambdaI*/ + rel_error = SUNRsqrt((lambdaR - tlambdaR) * (lambdaR - tlambdaR) + + (lambdaI - tlambdaI) * (lambdaI - tlambdaI)); + + rel_error /= norm_of_dom_eig; + + if (rel_error < rel_tol) + { + printf("\n\nPASS: relative error = " SUN_FORMAT_G " \n\n", rel_error); + } + else + { + printf("\n\nFAIL: relative error = " SUN_FORMAT_G " \n\n", rel_error); + passfail += 1; + } + + /* Free solver and vectors */ + N_VDestroy(ProbData.diag); + SUNContext_Free(&sunctx); + N_VDestroy(q); + SUNDomEigEstimator_Destroy(&DEE); + + return (passfail); +} + +/* ---------------------------------------------------------------------- + * Private helper functions + * --------------------------------------------------------------------*/ + +/* matrix-vector product */ +int ATimes(void* Data, N_Vector v_vec, N_Vector z_vec) +{ + /* local variables */ + sunrealtype *v, *z, *diag, real_part, imag_part; + sunindextype i, N; + UserData* ProbData; + + /* access user data structure and vector data */ + ProbData = (UserData*)Data; + v = N_VGetArrayPointer(v_vec); + if (check_flag(v, "N_VGetArrayPointer", 0)) { return 1; } + z = N_VGetArrayPointer(z_vec); + if (check_flag(z, "N_VGetArrayPointer", 0)) { return 1; } + N = ProbData->N; + real_part = ProbData->real_part; + imag_part = ProbData->imag_part; + diag = N_VGetArrayPointer(ProbData->diag); + if (check_flag(diag, "N_VGetArrayPointer", 0)) { return 1; } + + /* perform product on the diagonal part of the matrix */ + for (i = 0; i < N - 2; i++) { z[i] = diag[i] * v[i]; } + + /* perform product at the non-diagonal last two rows */ + z[N - 2] = v[N - 2] * real_part + v[N - 1] * imag_part; + z[N - 1] = v[N - 1] * real_part - v[N - 2] * imag_part; + /* return with success */ + return 0; +} + +/* Check function return value based on "opt" input: + 0: function allocates memory so check for NULL pointer + 1: function returns a flag so check for flag != 0 */ +int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nERROR: %s() failed - returned NULL pointer\n\n", funcname); + return 1; + } + + /* Check if flag != 0 */ + if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag != 0) + { + fprintf(stderr, "\nERROR: %s() failed with flag = %d\n\n", funcname, + *errflag); + return 1; + } + } + + return 0; +} diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.c b/test/unit_tests/sundomeigest/test_sundomeigest.c index a878711eff..f8f34313e4 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.c +++ b/test/unit_tests/sundomeigest/test_sundomeigest.c @@ -201,6 +201,37 @@ int Test_SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q, return (0); } +/* ---------------------------------------------------------------------- + * SUNDomEigEstimator_SetComplex Test + * --------------------------------------------------------------------*/ +int Test_SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE, int myid) +{ + int failure; + double start_time, stop_time; + + /* try calling SUNDomEigEstimator_SetComplex routine: should pass/fail based on expected input */ + start_time = get_time(); + failure = SUNDomEigEstimator_SetComplex(DEE); + stop_time = get_time(); + + if (failure) + { + printf(">>> FAILED test -- SUNDomEigEstimator_SetComplex check, Proc %d \n", + myid); + PRINT_TIME(" SUNDomEigEstimator_SetComplex Time: %22.15e \n \n", + stop_time - start_time); + return (1); + } + else if (myid == 0) + { + printf(" PASSED test -- SUNDomEigEstimator_SetComplex \n"); + PRINT_TIME(" SUNDomEigEstimator_SetComplex Time: %22.15e \n \n", + stop_time - start_time); + } + + return (0); +} + /* ---------------------------------------------------------------------- * SUNDomEigEstimator_Initialize Test * --------------------------------------------------------------------*/ diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.h b/test/unit_tests/sundomeigest/test_sundomeigest.h index db5bd7b303..df29f5cd64 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.h +++ b/test/unit_tests/sundomeigest/test_sundomeigest.h @@ -41,6 +41,7 @@ int Test_SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol, int myid); int Test_SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q, int myid); +int Test_SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE, int myid); int Test_SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE, int myid); int Test_SUNDomEigEstimator_Estimate(SUNDomEigEstimator DEE, sunrealtype* lambdaR, sunrealtype* lambdaI, int myid); From ee6479efabd8a3c65514015d8234c151b45ab9ec Mon Sep 17 00:00:00 2001 From: maggul Date: Sat, 3 Jan 2026 21:46:54 -0600 Subject: [PATCH 02/76] preprocess up to a reltol --- include/sundials/sundials_domeigestimator.h | 5 ++ include/sundomeigest/sundomeigest_arnoldi.h | 6 ++ include/sundomeigest/sundomeigest_power.h | 6 ++ src/sundials/sundials_domeigestimator.c | 14 ++++ .../arnoldi/sundomeigest_arnoldi.c | 53 +++++++++++++++ src/sundomeigest/power/sundomeigest_power.c | 65 +++++++++++++++++-- .../Arnoldi/test_sundomeigest_arnoldi.c | 1 + .../Power/test_sundomeigest_power.c | 1 + .../Power/test_sundomeigest_power_complex.c | 3 +- .../sundomeigest/test_sundomeigest.c | 37 +++++++++++ .../sundomeigest/test_sundomeigest.h | 2 + 11 files changed, 185 insertions(+), 8 deletions(-) diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index f4dfbd29ee..caee89d1f0 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -50,6 +50,7 @@ struct SUNDomEigEstimator_Ops_ const char* file_name, int argc, char* argv[]); SUNErrCode (*setmaxiters)(SUNDomEigEstimator, long int); SUNErrCode (*setnumpreprocessiters)(SUNDomEigEstimator, int); + SUNErrCode (*settolpreprocessiters)(SUNDomEigEstimator, sunrealtype); SUNErrCode (*setreltol)(SUNDomEigEstimator, sunrealtype); SUNErrCode (*setinitialguess)(SUNDomEigEstimator, N_Vector); SUNErrCode (*setcomplex)(SUNDomEigEstimator); @@ -100,6 +101,10 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_iters); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, + sunrealtype tol); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol); diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 6ea7538018..a7780dd167 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -48,6 +48,8 @@ struct SUNDomEigEstimatorContent_Arnoldi_ int kry_dim; /* Krylov subspace dimension */ int num_warmups; /* Number of preprocessing iterations */ long int num_iters; /* Number of iterations in last Estimate call */ + sunbooleantype warmup_to_tol; /* Type of warmup iterations */ + sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ long int num_ATimes; /* Number of ATimes calls */ @@ -79,6 +81,10 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, int num_iters); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, + sunrealtype tol); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess_Arnoldi(SUNDomEigEstimator DEE, N_Vector q); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 049f215f25..ae3b5c54d4 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -46,6 +46,8 @@ struct SUNDomEigEstimatorContent_Power_ int num_warmups; /* Number of preprocessing iterations */ long int max_iters; /* Maximum number of power iterations */ long int num_iters; /* Number of iterations in last Estimate call */ + sunbooleantype warmup_to_tol; /* Type of warmup iterations */ + sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ long int num_ATimes; /* Number of ATimes calls */ @@ -78,6 +80,10 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Power(SUNDomEigEstimator DEE, int num_iters); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Power(SUNDomEigEstimator DEE, + sunrealtype tol); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRelTol_Power(SUNDomEigEstimator DEE, sunrealtype tol); diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index b2b462c469..33e74ee08f 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -236,6 +236,20 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, return (ier); } +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, + sunrealtype tol) +{ + SUNErrCode ier; + SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); + if (DEE->ops->settolpreprocessiters) + { + ier = DEE->ops->settolpreprocessiters(DEE, tol); + } + else { ier = SUN_SUCCESS; } + SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); + return (ier); +} + SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype rel_tol) { diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index b57a1e9ced..669beed6fc 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -42,6 +42,7 @@ /* Default estimator parameters */ #define DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT 100 +#define DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT SUN_RCONST(1.0e-2) /* Default Arnoldi Iteration parameters */ #define DEE_KRYLOV_DIM_DEFAULT 3 @@ -104,6 +105,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; + DEE->ops->settolpreprocessiters = + SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Arnoldi; DEE->ops->initialize = SUNDomEigEstimator_Initialize_Arnoldi; DEE->ops->estimate = SUNDomEigEstimator_Estimate_Arnoldi; @@ -129,6 +132,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, content->num_warmups = DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT; content->num_iters = 0; content->num_ATimes = 0; + content->warmup_to_tol = SUNFALSE; + content->tol_preprocess = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; content->LAPACK_A = NULL; content->LAPACK_wr = NULL; content->LAPACK_wi = NULL; @@ -282,6 +287,33 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator D /* set the number of warmups */ Arnoldi_CONTENT(DEE)->num_warmups = num_iters; + + /* set the type of warmup iterations */ + Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; + return SUN_SUCCESS; +} + +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, + sunrealtype tol) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + + /* set the tolerance for preprocessing iterations */ + if(tol <= SUN_RCONST(0.0)) + { + tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; + } + else + { + Arnoldi_CONTENT(DEE)->tol_preprocess = tol; + } + + /* set the type of warmup iterations */ + Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; + return SUN_SUCCESS; } @@ -327,6 +359,10 @@ SUNErrCode SUNDomEigEstimator_Estimate_Arnoldi(SUNDomEigEstimator DEE, Arnoldi_CONTENT(DEE)->num_ATimes = 0; Arnoldi_CONTENT(DEE)->num_iters = 0; + sunrealtype res; + sunrealtype newnormlambda = ZERO; + sunrealtype oldnormlambda = ZERO; + /* Set the initial q = A^{num_warmups}q/||A^{num_warmups}q|| */ for (int i = 0; i < Arnoldi_CONTENT(DEE)->num_warmups; i++) { @@ -337,12 +373,29 @@ SUNErrCode SUNDomEigEstimator_Estimate_Arnoldi(SUNDomEigEstimator DEE, Arnoldi_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + if (Arnoldi_CONTENT(DEE)->warmup_to_tol) + { + newnormlambda = N_VDotProd(Arnoldi_CONTENT(DEE)->V[0], + Arnoldi_CONTENT(DEE)->q); //Rayleigh quotient + SUNCheckLastErr(); + } + normq = N_VDotProd(Arnoldi_CONTENT(DEE)->q, Arnoldi_CONTENT(DEE)->q); SUNCheckLastErr(); normq = SUNRsqrt(normq); N_VScale(ONE / normq, Arnoldi_CONTENT(DEE)->q, Arnoldi_CONTENT(DEE)->V[0]); SUNCheckLastErr(); + + if (Arnoldi_CONTENT(DEE)->warmup_to_tol) + { + res = SUNRabs(newnormlambda - oldnormlambda) / SUNRabs(newnormlambda); + oldnormlambda = newnormlambda; + if(res < Arnoldi_CONTENT(DEE)->tol_preprocess) + { + break; + } + } } for (int i = 0; i < n; i++) diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index a8bbce889d..e0bf0e8417 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -32,6 +32,7 @@ /* Default estimator parameters */ #define DEE_NUM_OF_WARMUPS_PI_DEFAULT 100 +#define DEE_TOL_OF_WARMUPS_PI_DEFAULT SUN_RCONST(1.0e-2) /* Default Power Iteration parameters */ #define DEE_TOL_DEFAULT SUN_RCONST(0.005) @@ -104,6 +105,7 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; + DEE->ops->settolpreprocessiters = SUNDomEigEstimator_SetTolPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Power; DEE->ops->setcomplex = SUNDomEigEstimator_SetComplex_Power; @@ -136,6 +138,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, content->res = ZERO; content->num_iters = 0; content->num_ATimes = 0; + content->warmup_to_tol = SUNFALSE; + content->tol_preprocess = DEE_TOL_OF_WARMUPS_PI_DEFAULT; /* Allocate content */ content->q = N_VClone(q); @@ -178,12 +182,14 @@ SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE) SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); /* set the complex flag */ PI_CONTENT(DEE)->complex = SUNTRUE; /* allocate q_prev vector */ PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); + SUNCheckLastErrNull(); return SUN_SUCCESS; } @@ -237,6 +243,33 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Power(SUNDomEigEstimator DEE /* set the number of warmups */ PI_CONTENT(DEE)->num_warmups = num_iters; + + /* set the type of warmup iterations */ + PI_CONTENT(DEE)->warmup_to_tol = SUNFALSE; + return SUN_SUCCESS; +} + +SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Power(SUNDomEigEstimator DEE, + sunrealtype tol) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + + /* set the tolerance for preprocessing iterations */ + if(tol <= SUN_RCONST(0.0)) + { + tol = DEE_TOL_OF_WARMUPS_PI_DEFAULT; + } + else + { + PI_CONTENT(DEE)->tol_preprocess = tol; + } + + /* set the type of warmup iterations */ + PI_CONTENT(DEE)->warmup_to_tol = SUNTRUE; + return SUN_SUCCESS; } @@ -307,38 +340,56 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); SUNAssert((PI_CONTENT(DEE)->max_iters >= 0), SUN_ERR_ARG_CORRUPT); - if(PI_CONTENT(DEE)->complex == SUNTRUE) + if(PI_CONTENT(DEE)->complex) { SUNAssert(PI_CONTENT(DEE)->q_prev, SUN_ERR_ARG_CORRUPT); } - sunrealtype newlambdaR = ZERO; - sunrealtype oldlambdaR = ZERO; - int retval; sunrealtype normq; PI_CONTENT(DEE)->num_ATimes = 0; PI_CONTENT(DEE)->num_iters = 0; + sunrealtype res; + sunrealtype newlambdaR = ZERO; + sunrealtype oldlambdaR = ZERO; + /* Set the initial q = A^{num_warmups}q/||A^{num_warmups}q|| */ for (int i = 0; i < PI_CONTENT(DEE)->num_warmups; i++) { retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, - PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q); + PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->num_ATimes++; PI_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + if(PI_CONTENT(DEE)->warmup_to_tol) + { + newlambdaR = N_VDotProd(PI_CONTENT(DEE)->V, + PI_CONTENT(DEE)->q); //Rayleigh quotient + SUNCheckLastErr(); + } + normq = N_VDotProd(PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->q); SUNCheckLastErr(); normq = SUNRsqrt(normq); N_VScale(ONE / normq, PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->V); SUNCheckLastErr(); + + if(PI_CONTENT(DEE)->warmup_to_tol) + { + res = SUNRabs(newlambdaR - oldlambdaR) / SUNRabs(newlambdaR); + oldlambdaR = newlambdaR; + if(res < PI_CONTENT(DEE)->tol_preprocess) + { + break; + } + } } for (int k = 0; k < PI_CONTENT(DEE)->max_iters; k++) { - if(PI_CONTENT(DEE)->complex == SUNTRUE) //TODO: instead we can Scale after convergence and reiterate once more + if(PI_CONTENT(DEE)->complex) //TODO: instead we can Scale after convergence and reiterate once more { N_VScale(ONE, PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q_prev); SUNCheckLastErr(); @@ -368,7 +419,7 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, oldlambdaR = newlambdaR; } - if(PI_CONTENT(DEE)->complex == SUNTRUE) + if(PI_CONTENT(DEE)->complex) { retval = sundomeigestimator_complex_dom_eigs_from_PI(DEE, newlambdaR, PI_CONTENT(DEE)->q_prev, diff --git a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c index f101845125..88cd282bfe 100644 --- a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c +++ b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c @@ -149,6 +149,7 @@ int main(int argc, char* argv[]) // It should return with SUN_SUCCESS fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, kry_dim, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); + fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); diff --git a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c index 513bdc4cdf..84ebcf5912 100644 --- a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c +++ b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c @@ -146,6 +146,7 @@ int main(int argc, char* argv[]) fails += Test_SUNDomEigEstimator_SetATimes(DEE, &ProbData, ATimes, 0); fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, max_iters, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); + fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); diff --git a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c index b24d0bd484..ad948f72a8 100644 --- a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c +++ b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c @@ -147,6 +147,7 @@ int main(int argc, char* argv[]) fails += Test_SUNDomEigEstimator_SetATimes(DEE, &ProbData, ATimes, 0); fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, max_iters, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); + fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); fails += Test_SUNDomEigEstimator_SetComplex(DEE, 0); @@ -216,7 +217,7 @@ int main(int argc, char* argv[]) rel_error /= norm_of_dom_eig; - if (rel_error < rel_tol) + if (rel_error < SUN_RCONST(10.0) * rel_tol) { printf("\n\nPASS: relative error = " SUN_FORMAT_G " \n\n", rel_error); } diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.c b/test/unit_tests/sundomeigest/test_sundomeigest.c index f8f34313e4..9c72cfd42e 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.c +++ b/test/unit_tests/sundomeigest/test_sundomeigest.c @@ -136,6 +136,43 @@ int Test_SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, return (0); } +/* ---------------------------------------------------------------------- + * SUNDomEigEstimator_SetTolPreprocessIters Test + * --------------------------------------------------------------------*/ +int Test_SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, + sunrealtype tol_warmups, + int myid) +{ + int failure; + double start_time, stop_time; + + /* try calling SUNDomEigEstimator_SetTolPreprocessIters routine: should pass/fail based on expected input */ + start_time = get_time(); + failure = SUNDomEigEstimator_SetTolPreprocessIters(DEE, tol_warmups); + stop_time = get_time(); + + if (failure) + { + printf(">>> FAILED test -- SUNDomEigEstimator_SetTolPreprocessIters check, " + "Proc " + "%d \n", + myid); + PRINT_TIME(" SUNDomEigEstimator_SetTolPreprocessIters Time: %22.15e \n " + "\n", + stop_time - start_time); + return (1); + } + else if (myid == 0) + { + printf(" PASSED test -- SUNDomEigEstimator_SetTolPreprocessIters \n"); + PRINT_TIME(" SUNDomEigEstimator_SetTolPreprocessIters Time: %22.15e \n " + "\n", + stop_time - start_time); + } + + return (0); +} + /* ---------------------------------------------------------------------- * SUNDomEigEstimator_SetRelTol Test * --------------------------------------------------------------------*/ diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.h b/test/unit_tests/sundomeigest/test_sundomeigest.h index df29f5cd64..76523eeffc 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.h +++ b/test/unit_tests/sundomeigest/test_sundomeigest.h @@ -37,6 +37,8 @@ int Test_SUNDomEigEstimator_SetMaxIters(SUNDomEigEstimator DEE, long int max_iters, int myid); int Test_SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_warmups, int myid); +int Test_SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, + sunrealtype tol_warmups, int myid); int Test_SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol, int myid); int Test_SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q, From 2a9c2a6ec7557cca7a9e7cb0a9d9cc8a08bc3f9c Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 9 Feb 2026 13:24:57 -0600 Subject: [PATCH 03/76] LSRKStep updates for complex eig support --- include/arkode/arkode_lsrkstep.h | 3 + src/arkode/arkode_lsrkstep.c | 417 +++++++++++++++++++- src/arkode/arkode_lsrkstep_impl.h | 34 ++ src/arkode/arkode_lsrkstep_io.c | 38 ++ src/sundomeigest/power/sundomeigest_power.c | 2 +- 5 files changed, 486 insertions(+), 8 deletions(-) diff --git a/include/arkode/arkode_lsrkstep.h b/include/arkode/arkode_lsrkstep.h index ac7c3d745d..e9c61a4678 100644 --- a/include/arkode/arkode_lsrkstep.h +++ b/include/arkode/arkode_lsrkstep.h @@ -93,6 +93,9 @@ SUNDIALS_EXPORT int LSRKStepSetMaxNumStages(void* arkode_mem, SUNDIALS_EXPORT int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety); +SUNDIALS_EXPORT int LSRKStepSetUseEllipseForStability(void* arkode_mem, + sunbooleantype use_ellipse); + SUNDIALS_EXPORT int LSRKStepSetNumDomEigEstInitPreprocessIters(void* arkode_mem, int num_iters); diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index ec09b323d7..461d21d59f 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -206,6 +206,7 @@ void* lsrkStep_Create_Commons(ARKRhsFn rhs, sunrealtype t0, N_Vector y0, /* Initialize flags */ step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; + step_mem->use_ellipse = SUNTRUE; step_mem->is_SSP = SUNFALSE; step_mem->init_warmup = SUNTRUE; @@ -309,6 +310,7 @@ int lsrkStep_ReInit_Commons(void* arkode_mem, ARKRhsFn rhs, sunrealtype t0, step_mem->num_dee_iters = 0; step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; + step_mem->use_ellipse = SUNTRUE; step_mem->init_warmup = SUNTRUE; return ARK_SUCCESS; @@ -540,8 +542,9 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype hmax, w0, w1, temp1, temp2, arg, bjm1, bjm2, mus, thjm1, thjm2, zjm1, zjm2, dzjm1, dzjm2, d2zjm1, d2zjm2, zj, dzj, d2zj, bj, ajm1, mu, nu, thj; - const sunrealtype onep54 = SUN_RCONST(1.54), c13 = SUN_RCONST(13.0), - p8 = SUN_RCONST(0.8), p4 = SUN_RCONST(0.4); + sunrealtype stability_norm; + + const sunrealtype p8 = SUN_RCONST(0.8), p4 = SUN_RCONST(0.4); ARKodeLSRKStepMem step_mem; /* initialize algebraic solver convergence flag to success, @@ -556,6 +559,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; + const sunrealtype coefz = THREE/TWO / (ONE - TWO/SUN_RCONST(15.0) * step_mem->rkc_damping); + /* Compute dominant eigenvalue and update stats */ if (step_mem->dom_eig_update) { @@ -563,10 +568,17 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (retval != ARK_SUCCESS) { return retval; } } - sunrealtype ss = - SUNRceil(SUNRsqrt(onep54 * SUNRabs(ark_mem->h) * step_mem->spectral_radius)); + /* Compute number of stages based on current step size and + dominant eigenvalue using Eq. (2.7) in Verwer et al. (2004) */ + sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; + sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); + /* Check if number of stages exceeds maximum allowed. + If so, and if adaptive stepping is enabled, reduce step size + and return ARK_RETRY_STEP. If fixed step size, return + ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -577,8 +589,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (!ark_mem->fixedstep) { - hmax = ark_mem->hadapt_mem->safety * SUNSQR(step_mem->stage_max_limit) / - (onep54 * step_mem->spectral_radius); + hmax = ark_mem->hadapt_mem->safety * (ONE - SUNSQR(step_mem->stage_max_limit)) / + (coefz * step_mem->lambdaR); ark_mem->eta = hmax / ark_mem->h; *nflagPtr = ARK_RETRY_STEP; ark_mem->hadapt_mem->nst_exp++; @@ -595,6 +607,51 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; + /* For the linear stability with the test equation, y' = lambda*y, + the stability function of RKC methods is given by the Chebyshev + polynomial of the first kind, T_s(z), where s is the number of + stages and z is related to the eigenvalue and step size. For the + method to be stable, the stability norm |T_s(z)| must be less + than or equal to 1. To check stability norm with the requested + number of stages and z, we evaluate the exact stability function + or an inscribed ellipse approximation of the stability region at + the point z and check if its absolute value is greater than 1. + If the stability norm is greater than one, for adaptive stepping, + we reduce step size and return ARK_RETRY_STEP. For fixed step size, + we increase number of stages until stability norm is acceptable or + stage_max_limit is reached. */ + retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + + if (stability_norm > ONE - SUN_SMALL_REAL) + { + if (!ark_mem->fixedstep) + { + ark_mem->eta = ark_mem->hadapt_mem->safety / stability_norm; + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else + { + while (stability_norm > ONE - SUN_SMALL_REAL && step_mem->req_stages < step_mem->stage_max_limit) + { + step_mem->req_stages += 1; + retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, + &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + } + if (stability_norm > ONE - SUN_SMALL_REAL || step_mem->req_stages >= step_mem->stage_max_limit) + { + arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, + __FILE__, + "Unable to achieve stable results: Either reduce the " + "step size or increase the stage_max_limit"); + return ARK_MAX_STAGE_LIMIT_FAIL; + } + } + } + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -629,7 +686,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Track the number of successful steps to determine if the previous step failed. */ step_mem->step_nst = ark_mem->nst + 1; - w0 = (ONE + TWO / (c13 * SUNSQR((sunrealtype)(step_mem->req_stages)))); + w0 = (ONE + step_mem->rkc_damping / SUNSQR((sunrealtype)(step_mem->req_stages))); temp1 = SUNSQR(w0) - ONE; temp2 = SUNRsqrt(temp1); @@ -852,6 +909,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) int retval; sunrealtype hmax, w1, bjm1, bjm2, mus, bj, ajm1, cjm1, temj, cj, mu, nu; const sunrealtype p8 = SUN_RCONST(0.8), p4 = SUN_RCONST(0.4); + sunrealtype stability_norm; ARKodeLSRKStepMem step_mem; /* initialize algebraic solver convergence flag to success, @@ -873,6 +931,10 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (retval != ARK_SUCCESS) { return retval; } } + /* Compute number of stages based on current step size and + dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ + sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; sunrealtype ss = SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * SUNRabs(ark_mem->h) * step_mem->spectral_radius) - @@ -881,6 +943,10 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) ss = SUNMAX(ss, SUN_RCONST(2.0)); + /* Check if number of stages exceeds maximum allowed. + If so, and if adaptive stepping is enabled, reduce step size + and return ARK_RETRY_STEP. If fixed step size, return + ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -911,6 +977,51 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; + /* For the linear stability with the test equation, y' = lambda*y, + the stability function of RKL methods is given by the Legendre + polynomial of the first kind, P_s(z), where s is the number of + stages and z is related to the eigenvalue and step size. For the + method to be stable, the stability norm |P_s(z)| must be less + than or equal to 1. To check stability norm with the requested + number of stages and z, we evaluate the exact stability function + or an inscribed ellipse approximation of the stability region at + the point z and check if its absolute value is greater than 1. + If the stability norm is greater than one, for adaptive stepping, + we reduce step size and return ARK_RETRY_STEP. For fixed step size, + we increase number of stages until stability norm is acceptable or + stage_max_limit is reached. */ + retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + + if (stability_norm > ONE - SUN_SMALL_REAL) + { + if (!ark_mem->fixedstep) + { + ark_mem->eta = ark_mem->hadapt_mem->safety / stability_norm; + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else + { + while (stability_norm > ONE - SUN_SMALL_REAL && step_mem->req_stages < step_mem->stage_max_limit) + { + step_mem->req_stages += 1; + retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, + &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + } + if (stability_norm > ONE - SUN_SMALL_REAL || step_mem->req_stages >= step_mem->stage_max_limit) + { + arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, + __FILE__, + "Unable to achieve stable results: Either reduce the " + "step size or increase the stage_max_limit"); + return ARK_MAX_STAGE_LIMIT_FAIL; + } + } + } + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -2159,12 +2270,18 @@ void lsrkStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) step_mem->spectral_radius_min); fprintf(outfile, "LSRKStep: dom_eig_safety = " SUN_FORMAT_G "\n", step_mem->dom_eig_safety); + fprintf(outfile, "LSRKStep: rkc_damping = " SUN_FORMAT_G "\n", + step_mem->rkc_damping); /* output sunbooleantype quantities */ fprintf(outfile, "LSRKStep: dom_eig_update = %d\n", step_mem->dom_eig_update); fprintf(outfile, "LSRKStep: dom_eig_is_current = %d\n", step_mem->dom_eig_is_current); + fprintf(outfile, "LSRKStep: init_warmup = %d\n", + step_mem->init_warmup); + fprintf(outfile, "LSRKStep: use_ellipse = %d\n", + step_mem->use_ellipse); if (step_mem->DEE != NULL) { @@ -2372,6 +2489,292 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) return retval; } +/*--------------------------------------------------------------- + lsrkStep_RKC_CheckStabilityNorm: + + This routine computes the stability norm for RKC methods. This computation is based on the stability + region of the RKC method, which is determined by the stability function of the method. The stability + function of the RKC method is a rational function of the Chebyshev polynomial of degree s, where s is + the number of stages. The stability region is then determined by the values of z = h*lambda for which + the stability function has magnitude less than or equal to 1. In particular, if use_ellipse is SUNTRUE, + we use a heuristic that approximates the stability region by an ellipse with corners at (0,0), + (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), where re_stab_min and im_stab_min are determined + by the damping parameter and the number of stages as described in the comments. If use_ellipse is SUNFALSE, + we compute the stability norm directly from the stability function using the Chebyshev polynomial. + The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. + ---------------------------------------------------------------*/ +int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, + ARKodeLSRKStepMem step_mem, + sunrealtype* stability_norm) +{ + sunrealtype ss = step_mem->req_stages; + sunrealtype w0, w1, wr, wi, th, sh, ch, b_s, a_s, Ts, Ts_p, Ts_pp, a, b, xc, yc; + sunrealtype re_stab_min, im_stab_min; + sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; + + if (step_mem->use_ellipse) + { + /* The stability region of the RKC method with damping is contained in the ellipse + with corners at (0,0), (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), + where re_stab_min and im_stab_min are the real and imaginary parts of the leftmost point + of the inscribed ellipse. The value of re_stab_min is determined by the damping parameter + and the number of stages by reverting the formula for finding the required number of + stages for a given spectral radius times step size. im_stab_min is then determined by + herustically by deviding re_stab_min by the aspect ratio of the ellipse, which is + approximateted as 3.65*ss, where ss is the number of stages. In particular, if ss=2, + the aspect ratio is estimated to be 0.6*ss. This heuristic is based on the observation + that imaginary extend of the stability region grows linearly with the number of stages. + The factors of 3.65 and 0.6 are determined empirically by plotting the stability region for + different number of stages and the default damping parameter. It is subject to change if the + default damping parameter is changed. */ + re_stab_min = TWO/THREE * (ONE - SUNSQR(ss)) * + (ONE - TWO/SUN_RCONST(15.0) * step_mem->rkc_damping); + im_stab_min = -re_stab_min / (ss == 2 ? SUN_RCONST(0.6) * ss : SUN_RCONST(3.65) * ss); + + xc = re_stab_min / TWO; + yc = ZERO; + a = SUNRabs(re_stab_min) / TWO; + b = SUNRabs(im_stab_min); + + *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); + } + else + { + w0 = ONE + step_mem->rkc_damping / (ss * ss); + th = SUNRacosh(w0); + sh = SUNRsinh(th); + ch = SUNRcosh(th); + + Ts = SUNRcosh(ss * th); + Ts_p = ss * SUNRsinh(ss * th) / sh; + Ts_pp = (ss * ss * SUNRcosh(ss * th) / (sh * sh)) - ss * ch * SUNRsinh(ss * th) / + (sh * sh * sh); + + b_s = Ts_pp / (Ts_p * Ts_p); + a_s = ONE - b_s * Ts; + w1 = Ts_p / Ts_pp; + + wr = w0 + w1 * zR; + wi = w1 * zI; + + sunrealtype TsR, TsI, Ps_ZR, Ps_ZI; + int retval = lsrkStep_cheb_T_complex(ss, wr, wi, &TsR, &TsI); + if (retval != ARK_SUCCESS) { return retval; } + + Ps_ZR = a_s + b_s * TsR; + Ps_ZI = b_s * TsI; + + *stability_norm = SUNRsqrt(SUNSQR(Ps_ZR) + SUNSQR(Ps_ZI)); + } + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + lsrkStep_RKL_CheckStabilityNorm: + + This routine computes the stability norm for RKL methods. This computation is based on the stability + region of the RKL method, which is determined by the stability function of the method. The stability + function of the RKL method is a rational function of the Legendre polynomial of degree s, where s is + the number of stages. The stability region is then determined by the values of z = h*lambda for which + the stability function has magnitude less than or equal to 1. In particular, if use_ellipse is SUNTRUE, + we use a heuristic that approximates the stability region by an ellipse with corners at (0,0), + (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), where re_stab_min and im_stab_min are determined + by the number of stages as described in the comments. If use_ellipse is SUNFALSE, + we compute the stability norm directly from the stability function using the Legendre polynomial. + The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. + ---------------------------------------------------------------*/ +int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, + ARKodeLSRKStepMem step_mem, + sunrealtype* stability_norm) +{ + sunrealtype ss = step_mem->req_stages; + sunrealtype w1, wr, wi, a_s, b_s, a, b, xc, yc; + sunrealtype re_stab_min, im_stab_min; + sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; + + if (step_mem->use_ellipse) + { + /* The stability region of the RKL method is contained in the ellipse + with corners at (0,0), (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), + where re_stab_min and im_stab_min are the real and imaginary parts of the leftmost point + of the inscribed ellipse. The value of re_stab_min is determined by the number of stages + by reverting the formula for finding the required number of stages for a given spectral + radius times step size. im_stab_min is then determined by herustically by deviding + re_stab_min by the aspect ratio of the ellipse, which is approximated as + imag_extend_factor*ss, where ss is the number of stages and the factor imag_extend_factor + is determined empirically by plotting the stability region for different number of stages. + This factor is as follows: */ + + /*s = 2 -> 0.6 + s = 3 -> 1.5 + s = 4 -> 1.33 + s = 5 -> 1.33 + s = 6 to 20 -> 1.27 + s >= 20 and odd -> 1.2 + s >= 20 and even -> 1.06 */ + const sunrealtype imag_extend_factor[7] = { + 0.6, /* s = 2 */ + 1.5, /* s = 3 */ + 1.33, /* s = 4 */ + 1.33, /* s = 5 */ + 1.27, /* s = 6 to 20 */ + 1.2, /* s >= 20 and odd */ + 1.06 /* s >= 20 and even */ + }; + re_stab_min = -((TWO*ss + ONE)*(TWO*ss + ONE)- SUN_RCONST(9.0)) / SUN_RCONST(8.0); + if (ss < 7) + { + im_stab_min = -re_stab_min / (imag_extend_factor[(int)ss-2] * ss); + } + else { + if (ss <= 20) + { + im_stab_min = -re_stab_min / (imag_extend_factor[4] * ss); + } + else + { + im_stab_min = -re_stab_min / (imag_extend_factor[6 - (int)ss % 2] * ss); + } + } + // TODO:get opinon on whether we want to use the heuristic with different factors for different number of stages or + // to use a single global factor for all number of stages. The heuristic with different factors for different number + // of stages is more accurate, especially for small number of stages, but it is also more complicated. + // Instead we can use a single global factor of 1.5 for all number of stages as follows: + // im_stab_min = -re_stab_min / (SUN_RCONST(1.5) * ss); + + xc = re_stab_min / TWO; + yc = ZERO; + a = SUNRabs(re_stab_min) / TWO; + b = SUNRabs(im_stab_min); + + *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); + } + else + { + b_s = (ss*ss + ss - TWO) / (TWO * ss * (ss + ONE)); + a_s = ONE - b_s; + w1 = FOUR / (ss * ss + ss - TWO); // Eq.(15) in Meyer et al. (2014) + wr = ONE + w1 * zR; + wi = w1 * zI; + + sunrealtype PsR, PsI, Ps_ZR, Ps_ZI; + int retval = lsrkStep_legendre_P_complex(ss, wr, wi, &PsR, &PsI); + if (retval != ARK_SUCCESS) { return retval; } + + Ps_ZR = a_s + b_s * PsR; + Ps_ZI = b_s * PsI; + + *stability_norm = SUNRsqrt(SUNSQR(Ps_ZR) + SUNSQR(Ps_ZI)); + } + + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + lsrkStep_cheb_T_complex: + + This routine computes the Chebyshev polynomial of the first kind + T_s(z) for complex argument z = zR + i*zI using the + recurrence relation: + T_0(z) = 1 + T_1(z) = z + T_{k+1}(z) = 2*z*T_k(z) - T_{k-1}(z), k = 1,...,s-1 + ---------------------------------------------------------------*/ +int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, + sunrealtype* TsR, sunrealtype* TsI) +{ + if (s < 0) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "s cannot be negative"); + return ARK_ILL_INPUT; + } + else if (s == 0) + { + *TsR = ONE; + *TsI = ZERO; + return ARK_SUCCESS; + } + else if (s == 1) + { + *TsR = zR; + *TsI = zI; + return ARK_SUCCESS; + } + else + { + sunrealtype Tkm1R = ONE, Tkm1I = ZERO; // T_0(z) + sunrealtype TkR = zR, TkI = zI; // T_1(z) + sunrealtype Tkp1R, Tkp1I; + for (int k = 1; k < s; k++) + { + Tkp1R = SUN_RCONST(2.0) * (zR * TkR - zI * TkI) - Tkm1R; + Tkp1I = SUN_RCONST(2.0) * (zR * TkI + zI * TkR) - Tkm1I; + Tkm1R = TkR; + Tkm1I = TkI; + TkR = Tkp1R; + TkI = Tkp1I; + } + *TsR = TkR; + *TsI = TkI; + } + return ARK_SUCCESS; +} + +/*--------------------------------------------------------------- + lsrkStep_legendre_P_complex: + + This routine computes the Legendre polynomial P_s(z) for complex + argument z = zR + i*zI using the recurrence relation: + P_0(z) = 1 + P_1(z) = z + P_{k+1}(z) = ((2*k+1)*z*P_k(z) - k*P_{k-1}(z))/(k+1), k = 1,...,s-1 + ---------------------------------------------------------------*/ + +int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, + sunrealtype* PsR, sunrealtype* PsI) +{ + if (s < 0) + { + arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__, + "s cannot be negative"); + return ARK_ILL_INPUT; + } + else if (s == 0) + { + *PsR = ONE; + *PsI = ZERO; + return ARK_SUCCESS; + } + else if (s == 1) + { + *PsR = zR; + *PsI = zI; + return ARK_SUCCESS; + } + else + { + sunrealtype Pkm1R = ONE, Pkm1I = ZERO; // P_0(z) + sunrealtype PkR = zR, PkI = zI; // P_1(z) + sunrealtype Pkp1R, Pkp1I; + for (int k = 1; k < s; k++) + { + Pkp1R = ((TWO * k + ONE) * (zR * PkR - zI * PkI) - k * Pkm1R) / (k + ONE); + Pkp1I = ((TWO * k + ONE) * (zR * PkI + zI * PkR) - k * Pkm1I) / (k + ONE); + Pkm1R = PkR; + Pkm1I = PkI; + PkR = Pkp1R; + PkI = Pkp1I; + } + *PsR = PkR; + *PsI = PkI; + } + return ARK_SUCCESS; +} + /*--------------------------------------------------------------- lsrkStep_DQJtimes: diff --git a/src/arkode/arkode_lsrkstep_impl.h b/src/arkode/arkode_lsrkstep_impl.h index 97675f600f..6f22d5df3b 100644 --- a/src/arkode/arkode_lsrkstep_impl.h +++ b/src/arkode/arkode_lsrkstep_impl.h @@ -32,6 +32,7 @@ extern "C" { #define STAGE_MAX_LIMIT_DEFAULT 200 #define DOM_EIG_SAFETY_DEFAULT SUN_RCONST(1.01) +#define RKC_DAMPING_DEFAULT SUN_RCONST(2.0)/SUN_RCONST(13.0) #define DOM_EIG_FREQ_DEFAULT 25 #define DOM_EIG_NUM_WARMUPS_DEFAULT 0 #define DOM_EIG_NUM_INIT_WARMUPS_DEFAULT -1 /* use DEE's default value */ @@ -119,6 +120,29 @@ extern "C" { #endif #endif +/* + * ----------------------------------------------------------------- + * Function : SUNRacosh + * ----------------------------------------------------------------- + * Usage : sunrealtype acosh_x; + * acosh_x = SUNRacosh(x); + * ----------------------------------------------------------------- + * SUNRacosh(x) returns acosh(x) (the hyperbolic arcosine of x). + * ----------------------------------------------------------------- + */ +#ifndef SUNRacosh +#if defined(SUNDIALS_DOUBLE_PRECISION) +#define SUNRacosh(x) (acosh((x))) +#elif defined(SUNDIALS_SINGLE_PRECISION) +#define SUNRacosh(x) (acoshf((x))) +#elif defined(SUNDIALS_EXTENDED_PRECISION) +#define SUNRacosh(x) (acoshl((x))) +#else +#error \ + "SUNDIALS precision not defined, report to github.com/LLNL/sundials/issues" +#endif +#endif + /*=============================================================== LSRK time step module data structure ===============================================================*/ @@ -160,6 +184,7 @@ typedef struct ARKodeLSRKStepMemRec sunrealtype spectral_radius_max; /* max spectral radius*/ sunrealtype spectral_radius_min; /* min spectral radius*/ sunrealtype dom_eig_safety; /* some safety factor for the user provided dom_eig*/ + sunrealtype rkc_damping; /* damping parameter for RKC methods*/ long int dom_eig_freq; /* indicates dom_eig update after dom_eig_freq successful steps*/ int num_init_warmups; /* number of warm-ups in the first DEE estimates */ int num_warmups; /* number of warm-ups in succeeding DEE estimates */ @@ -170,6 +195,7 @@ typedef struct ARKodeLSRKStepMemRec sunbooleantype dom_eig_update; /* flag indicating new dom_eig is needed */ sunbooleantype const_Jac; /* flag indicating Jacobian is constant */ sunbooleantype dom_eig_is_current; /* SUNTRUE if dom_eig has been evaluated at tn */ + sunbooleantype use_ellipse; /* flag indicating whether to use ellipse or exact stability region for stability checks */ sunbooleantype is_SSP; /* flag indicating SSP method*/ sunbooleantype init_warmup; /* flag indicating initial warm-up*/ @@ -218,6 +244,14 @@ int lsrkStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, void lsrkStep_DomEigUpdateLogic(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype dsm); int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem); +int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, + sunrealtype* stability_norm); +int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, + sunrealtype* stability_norm); +int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, + sunrealtype* TsR, sunrealtype* TsI); +int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, + sunrealtype* PsR, sunrealtype* PsI); int lsrkStep_DQJtimes(void* arkode_mem, N_Vector v, N_Vector Jv); /*=============================================================== diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index d5bd5fb3ce..14032d0f2c 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -316,6 +316,41 @@ int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety) return ARK_SUCCESS; } +/*--------------------------------------------------------------- + LSRKStepSetUseEllipseForStability sets whether to use the ellipse or the exact stability region for + stability checks. The stability region check for RKC and RKL methods is performed with the dominant + eigenvalue and the current step size to ensure stability. While this is sufficient for a stability + region of disk, the stability region of RKC and RKL methods is not a disk but rather a more complicated + region that can be approximated by an inscribed ellipse. By default, the ellipse is used for stability + checks, which is a conservative approximation of the stability region that possibly reduces the step + sizes to ensure stability. Setting use_ellipse to SUNFALSE allows the use of the exact stability region, + which can potentially allow for larger step sizes but possibly cause stability failures for the second + dominant eigenvalue since it might be outside of the stability region even if the dominant eigenvalue + is inside the stability region. Using ellipse for stability checks can be beneficial when two dominant + eigenvalues are close to the stability boundary. Nevertheless, unless the full spectrum is used for + stability checks, there is always a risk of stability failures one way or another. Thus, the user should + have the option to choose between the ellipse or the exact stability region for stability checks based + on their problem characteristics and their preference for a more conservative or more aggressive approach + to stability. This input is only used for RKC and RKL methods. + ---------------------------------------------------------------*/ +int LSRKStepSetUseEllipseForStability(void* arkode_mem, sunbooleantype use_ellipse) +{ + ARKodeMem ark_mem; + ARKodeLSRKStepMem step_mem; + int retval; + + /* access ARKodeMem and ARKodeLSRKStepMem structures */ + retval = lsrkStep_AccessARKODEStepMem(arkode_mem, __func__, &ark_mem, + &step_mem); + if (retval != ARK_SUCCESS) { return retval; } + + step_mem->dom_eig_update = SUNTRUE; + step_mem->dom_eig_is_current = SUNFALSE; + step_mem->use_ellipse = use_ellipse; + + return ARK_SUCCESS; +} + /*--------------------------------------------------------------- LSRKStepSetNumDomEigEstInitPreprocessIters sets the number of the preprocessing iterations before the very first estimate call. @@ -760,6 +795,7 @@ int lsrkStep_SetDefaults(ARKodeMem ark_mem) /* Spectral info */ step_mem->dom_eig_safety = DOM_EIG_SAFETY_DEFAULT; step_mem->dom_eig_freq = DOM_EIG_FREQ_DEFAULT; + step_mem->rkc_damping = RKC_DAMPING_DEFAULT; step_mem->const_Jac = SUNFALSE; step_mem->num_init_warmups = DOM_EIG_NUM_INIT_WARMUPS_DEFAULT; step_mem->num_warmups = DOM_EIG_NUM_WARMUPS_DEFAULT; @@ -874,6 +910,8 @@ int lsrkStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) step_mem->spectral_radius); fprintf(fp, " Safety factor for the dom eig = " SUN_FORMAT_G "\n", step_mem->dom_eig_safety); + fprintf(fp, " Damping factor for RKC = " SUN_FORMAT_G "\n", + step_mem->rkc_damping); fprintf(fp, " Max num of successful steps before new dom eig update = %li\n", step_mem->dom_eig_freq); fprintf(fp, " Number of first preprocessing warmups = %i\n", diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index e0bf0e8417..b77c0a998f 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -189,7 +189,7 @@ SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE) /* allocate q_prev vector */ PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); - SUNCheckLastErrNull(); + SUNCheckLastErr(); return SUN_SUCCESS; } From 90123d03ddcfb9e3628803843f2ed64f1d7b01e9 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 9 Feb 2026 14:49:36 -0600 Subject: [PATCH 04/76] revision --- include/sundials/sundials_domeigestimator.h | 9 -- include/sundomeigest/sundomeigest_power.h | 7 +- src/sundials/sundials_domeigestimator.c | 24 ----- .../arnoldi/sundomeigest_arnoldi.c | 6 +- src/sundomeigest/power/sundomeigest_power.c | 101 ++++++------------ .../Arnoldi/test_sundomeigest_arnoldi.c | 1 - .../Power/test_sundomeigest_power.c | 1 - .../Power/test_sundomeigest_power_complex.c | 2 - .../sundomeigest/test_sundomeigest.c | 68 ------------ .../sundomeigest/test_sundomeigest.h | 3 - 10 files changed, 33 insertions(+), 189 deletions(-) diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index caee89d1f0..cd3cb3f7db 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -50,10 +50,8 @@ struct SUNDomEigEstimator_Ops_ const char* file_name, int argc, char* argv[]); SUNErrCode (*setmaxiters)(SUNDomEigEstimator, long int); SUNErrCode (*setnumpreprocessiters)(SUNDomEigEstimator, int); - SUNErrCode (*settolpreprocessiters)(SUNDomEigEstimator, sunrealtype); SUNErrCode (*setreltol)(SUNDomEigEstimator, sunrealtype); SUNErrCode (*setinitialguess)(SUNDomEigEstimator, N_Vector); - SUNErrCode (*setcomplex)(SUNDomEigEstimator); SUNErrCode (*initialize)(SUNDomEigEstimator); SUNErrCode (*estimate)(SUNDomEigEstimator, sunrealtype*, sunrealtype*); SUNErrCode (*getres)(SUNDomEigEstimator, sunrealtype*); @@ -101,19 +99,12 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_iters); -SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, - sunrealtype tol); - SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q); -SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE); - SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index ae3b5c54d4..eba8c98467 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -47,7 +47,6 @@ struct SUNDomEigEstimatorContent_Power_ long int max_iters; /* Maximum number of power iterations */ long int num_iters; /* Number of iterations in last Estimate call */ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ - sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ long int num_ATimes; /* Number of ATimes calls */ @@ -80,10 +79,6 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Power(SUNDomEigEstimator DEE, int num_iters); -SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Power(SUNDomEigEstimator DEE, - sunrealtype tol); - SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRelTol_Power(SUNDomEigEstimator DEE, sunrealtype tol); @@ -93,7 +88,7 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE); +SUNErrCode SUNDomEigEstimator_SetReal_Power(SUNDomEigEstimator DEE); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE); diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 33e74ee08f..3e26d25a4a 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -236,20 +236,6 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, return (ier); } -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, - sunrealtype tol) -{ - SUNErrCode ier; - SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); - if (DEE->ops->settolpreprocessiters) - { - ier = DEE->ops->settolpreprocessiters(DEE, tol); - } - else { ier = SUN_SUCCESS; } - SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); - return (ier); -} - SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype rel_tol) { @@ -271,16 +257,6 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q return (ier); } -SUNErrCode SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE) -{ - SUNErrCode ier; - SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); - if (DEE->ops->setcomplex) { ier = DEE->ops->setcomplex(DEE); } - else { ier = SUN_SUCCESS; } - SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); - return (ier); -} - SUNErrCode SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE) { SUNErrCode ier; diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 669beed6fc..c58c6936bf 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -105,8 +105,6 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; - DEE->ops->settolpreprocessiters = - SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Arnoldi; DEE->ops->initialize = SUNDomEigEstimator_Initialize_Arnoldi; DEE->ops->estimate = SUNDomEigEstimator_Estimate_Arnoldi; @@ -389,9 +387,9 @@ SUNErrCode SUNDomEigEstimator_Estimate_Arnoldi(SUNDomEigEstimator DEE, if (Arnoldi_CONTENT(DEE)->warmup_to_tol) { - res = SUNRabs(newnormlambda - oldnormlambda) / SUNRabs(newnormlambda); + res = SUNRabs(newnormlambda - oldnormlambda); oldnormlambda = newnormlambda; - if(res < Arnoldi_CONTENT(DEE)->tol_preprocess) + if(res <= Arnoldi_CONTENT(DEE)->tol_preprocess * SUNRabs(newnormlambda)) { break; } diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index b77c0a998f..507f0b8b1f 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -32,7 +32,6 @@ /* Default estimator parameters */ #define DEE_NUM_OF_WARMUPS_PI_DEFAULT 100 -#define DEE_TOL_OF_WARMUPS_PI_DEFAULT SUN_RCONST(1.0e-2) /* Default Power Iteration parameters */ #define DEE_TOL_DEFAULT SUN_RCONST(0.005) @@ -105,10 +104,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; - DEE->ops->settolpreprocessiters = SUNDomEigEstimator_SetTolPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Power; - DEE->ops->setcomplex = SUNDomEigEstimator_SetComplex_Power; DEE->ops->initialize = SUNDomEigEstimator_Initialize_Power; DEE->ops->estimate = SUNDomEigEstimator_Estimate_Power; DEE->ops->getres = SUNDomEigEstimator_GetRes_Power; @@ -131,15 +128,13 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, content->V = NULL; content->q = NULL; content->q_prev = NULL; - content->complex = SUNFALSE; + content->complex = SUNTRUE; content->max_iters = max_iters; content->num_warmups = DEE_NUM_OF_WARMUPS_PI_DEFAULT; content->rel_tol = rel_tol; content->res = ZERO; content->num_iters = 0; content->num_ATimes = 0; - content->warmup_to_tol = SUNFALSE; - content->tol_preprocess = DEE_TOL_OF_WARMUPS_PI_DEFAULT; /* Allocate content */ content->q = N_VClone(q); @@ -176,20 +171,24 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetComplex_Power(SUNDomEigEstimator DEE) +SUNErrCode SUNDomEigEstimator_SetReal_Power(SUNDomEigEstimator DEE) { SUNFunctionBegin(DEE->sunctx); SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); - /* set the complex flag */ - PI_CONTENT(DEE)->complex = SUNTRUE; - - /* allocate q_prev vector */ - PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); - SUNCheckLastErr(); + /* set the complex flag to false */ + PI_CONTENT(DEE)->complex = SUNFALSE; + + /* q_prev is allocated in SUNDomEigEstimator_Initialize_Power, which is expected to be + called after this routine. If the user calls this routine after initialization, we need + to free q_prev here. */ + if (PI_CONTENT(DEE)->q_prev) + { + N_VDestroy(PI_CONTENT(DEE)->q_prev); + PI_CONTENT(DEE)->q_prev = NULL; + } return SUN_SUCCESS; } @@ -218,6 +217,11 @@ SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE) SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); + if(PI_CONTENT(DEE)->complex) + { + SUNAssert(PI_CONTENT(DEE)->q_prev == NULL, SUN_ERR_ARG_CORRUPT); + } + /* Initialize the vector V */ sunrealtype normq = N_VDotProd(PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->q); SUNCheckLastErr(); @@ -243,33 +247,6 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Power(SUNDomEigEstimator DEE /* set the number of warmups */ PI_CONTENT(DEE)->num_warmups = num_iters; - - /* set the type of warmup iterations */ - PI_CONTENT(DEE)->warmup_to_tol = SUNFALSE; - return SUN_SUCCESS; -} - -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Power(SUNDomEigEstimator DEE, - sunrealtype tol) -{ - SUNFunctionBegin(DEE->sunctx); - - SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); - SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - - /* set the tolerance for preprocessing iterations */ - if(tol <= SUN_RCONST(0.0)) - { - tol = DEE_TOL_OF_WARMUPS_PI_DEFAULT; - } - else - { - PI_CONTENT(DEE)->tol_preprocess = tol; - } - - /* set the type of warmup iterations */ - PI_CONTENT(DEE)->warmup_to_tol = SUNTRUE; - return SUN_SUCCESS; } @@ -342,16 +319,18 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNAssert((PI_CONTENT(DEE)->max_iters >= 0), SUN_ERR_ARG_CORRUPT); if(PI_CONTENT(DEE)->complex) { - SUNAssert(PI_CONTENT(DEE)->q_prev, SUN_ERR_ARG_CORRUPT); + /* allocate q_prev vector */ + PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); + SUNCheckLastErr(); } + sunrealtype newlambdaR = ZERO; + sunrealtype oldlambdaR = ZERO; + int retval; sunrealtype normq; PI_CONTENT(DEE)->num_ATimes = 0; PI_CONTENT(DEE)->num_iters = 0; - sunrealtype res; - sunrealtype newlambdaR = ZERO; - sunrealtype oldlambdaR = ZERO; /* Set the initial q = A^{num_warmups}q/||A^{num_warmups}q|| */ for (int i = 0; i < PI_CONTENT(DEE)->num_warmups; i++) @@ -362,34 +341,17 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, PI_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } - if(PI_CONTENT(DEE)->warmup_to_tol) - { - newlambdaR = N_VDotProd(PI_CONTENT(DEE)->V, - PI_CONTENT(DEE)->q); //Rayleigh quotient - SUNCheckLastErr(); - } - normq = N_VDotProd(PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->q); SUNCheckLastErr(); normq = SUNRsqrt(normq); N_VScale(ONE / normq, PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->V); SUNCheckLastErr(); - - if(PI_CONTENT(DEE)->warmup_to_tol) - { - res = SUNRabs(newlambdaR - oldlambdaR) / SUNRabs(newlambdaR); - oldlambdaR = newlambdaR; - if(res < PI_CONTENT(DEE)->tol_preprocess) - { - break; - } - } } for (int k = 0; k < PI_CONTENT(DEE)->max_iters; k++) { - if(PI_CONTENT(DEE)->complex) //TODO: instead we can Scale after convergence and reiterate once more + if(PI_CONTENT(DEE)->complex) { N_VScale(ONE, PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q_prev); SUNCheckLastErr(); @@ -412,9 +374,11 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, N_VScale(ONE / normq, PI_CONTENT(DEE)->q, PI_CONTENT(DEE)->V); SUNCheckLastErr(); - PI_CONTENT(DEE)->res = SUNRabs(newlambdaR - oldlambdaR) / SUNRabs(newlambdaR); - - if (PI_CONTENT(DEE)->res < PI_CONTENT(DEE)->rel_tol) { break; } + PI_CONTENT(DEE)->res = SUNRabs(newlambdaR - oldlambdaR); + if (PI_CONTENT(DEE)->res <= PI_CONTENT(DEE)->rel_tol * SUNRabs(newlambdaR)) + { + break; + } oldlambdaR = newlambdaR; } @@ -521,8 +485,6 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); - printf("cos_qs: " SUN_FORMAT_G "\n", cos_qs); - if(fabs(fabs(cos_qs) - ONE) < proj_cond_inv) { printf("Warning: Projection matrix is ill-conditioned. Returning " @@ -530,7 +492,6 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, /* Dominant eigenvalue is real */ *lambdaR_out = lambdaR; *lambdaI_out = ZERO; - //TODO: store eigenvector as well for a get routine return SUN_SUCCESS; } else @@ -579,8 +540,6 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, *lambdaR_out = traceP / SUN_RCONST(2.0); *lambdaI_out = SUNRsqrt(-discrim) / SUN_RCONST(2.0); } - //TODO: store eigenvector as well for a get routine - //find eigenvector of P and map back to original space by [v_prev v] * eigenvector_P } return SUN_SUCCESS; diff --git a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c index 88cd282bfe..f101845125 100644 --- a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c +++ b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c @@ -149,7 +149,6 @@ int main(int argc, char* argv[]) // It should return with SUN_SUCCESS fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, kry_dim, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); - fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); diff --git a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c index 84ebcf5912..513bdc4cdf 100644 --- a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c +++ b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power.c @@ -146,7 +146,6 @@ int main(int argc, char* argv[]) fails += Test_SUNDomEigEstimator_SetATimes(DEE, &ProbData, ATimes, 0); fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, max_iters, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); - fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); diff --git a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c index ad948f72a8..c0eab6ed86 100644 --- a/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c +++ b/test/unit_tests/sundomeigest/Power/test_sundomeigest_power_complex.c @@ -147,10 +147,8 @@ int main(int argc, char* argv[]) fails += Test_SUNDomEigEstimator_SetATimes(DEE, &ProbData, ATimes, 0); fails += Test_SUNDomEigEstimator_SetMaxIters(DEE, max_iters, 0); fails += Test_SUNDomEigEstimator_SetNumPreprocessIters(DEE, num_warmups, 0); - fails += Test_SUNDomEigEstimator_SetTolPreprocessIters(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetRelTol(DEE, rel_tol, 0); fails += Test_SUNDomEigEstimator_SetInitialGuess(DEE, q, 0); - fails += Test_SUNDomEigEstimator_SetComplex(DEE, 0); fails += Test_SUNDomEigEstimator_Initialize(DEE, 0); fails += Test_SUNDomEigEstimator_Estimate(DEE, &lambdaR, &lambdaI, 0); fails += Test_SUNDomEigEstimator_GetRes(DEE, &res, 0); diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.c b/test/unit_tests/sundomeigest/test_sundomeigest.c index 9c72cfd42e..a878711eff 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.c +++ b/test/unit_tests/sundomeigest/test_sundomeigest.c @@ -136,43 +136,6 @@ int Test_SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, return (0); } -/* ---------------------------------------------------------------------- - * SUNDomEigEstimator_SetTolPreprocessIters Test - * --------------------------------------------------------------------*/ -int Test_SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, - sunrealtype tol_warmups, - int myid) -{ - int failure; - double start_time, stop_time; - - /* try calling SUNDomEigEstimator_SetTolPreprocessIters routine: should pass/fail based on expected input */ - start_time = get_time(); - failure = SUNDomEigEstimator_SetTolPreprocessIters(DEE, tol_warmups); - stop_time = get_time(); - - if (failure) - { - printf(">>> FAILED test -- SUNDomEigEstimator_SetTolPreprocessIters check, " - "Proc " - "%d \n", - myid); - PRINT_TIME(" SUNDomEigEstimator_SetTolPreprocessIters Time: %22.15e \n " - "\n", - stop_time - start_time); - return (1); - } - else if (myid == 0) - { - printf(" PASSED test -- SUNDomEigEstimator_SetTolPreprocessIters \n"); - PRINT_TIME(" SUNDomEigEstimator_SetTolPreprocessIters Time: %22.15e \n " - "\n", - stop_time - start_time); - } - - return (0); -} - /* ---------------------------------------------------------------------- * SUNDomEigEstimator_SetRelTol Test * --------------------------------------------------------------------*/ @@ -238,37 +201,6 @@ int Test_SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q, return (0); } -/* ---------------------------------------------------------------------- - * SUNDomEigEstimator_SetComplex Test - * --------------------------------------------------------------------*/ -int Test_SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE, int myid) -{ - int failure; - double start_time, stop_time; - - /* try calling SUNDomEigEstimator_SetComplex routine: should pass/fail based on expected input */ - start_time = get_time(); - failure = SUNDomEigEstimator_SetComplex(DEE); - stop_time = get_time(); - - if (failure) - { - printf(">>> FAILED test -- SUNDomEigEstimator_SetComplex check, Proc %d \n", - myid); - PRINT_TIME(" SUNDomEigEstimator_SetComplex Time: %22.15e \n \n", - stop_time - start_time); - return (1); - } - else if (myid == 0) - { - printf(" PASSED test -- SUNDomEigEstimator_SetComplex \n"); - PRINT_TIME(" SUNDomEigEstimator_SetComplex Time: %22.15e \n \n", - stop_time - start_time); - } - - return (0); -} - /* ---------------------------------------------------------------------- * SUNDomEigEstimator_Initialize Test * --------------------------------------------------------------------*/ diff --git a/test/unit_tests/sundomeigest/test_sundomeigest.h b/test/unit_tests/sundomeigest/test_sundomeigest.h index 76523eeffc..db5bd7b303 100644 --- a/test/unit_tests/sundomeigest/test_sundomeigest.h +++ b/test/unit_tests/sundomeigest/test_sundomeigest.h @@ -37,13 +37,10 @@ int Test_SUNDomEigEstimator_SetMaxIters(SUNDomEigEstimator DEE, long int max_iters, int myid); int Test_SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_warmups, int myid); -int Test_SUNDomEigEstimator_SetTolPreprocessIters(SUNDomEigEstimator DEE, - sunrealtype tol_warmups, int myid); int Test_SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype tol, int myid); int Test_SUNDomEigEstimator_SetInitialGuess(SUNDomEigEstimator DEE, N_Vector q, int myid); -int Test_SUNDomEigEstimator_SetComplex(SUNDomEigEstimator DEE, int myid); int Test_SUNDomEigEstimator_Initialize(SUNDomEigEstimator DEE, int myid); int Test_SUNDomEigEstimator_Estimate(SUNDomEigEstimator DEE, sunrealtype* lambdaR, sunrealtype* lambdaI, int myid); From e23ef542424705fd23af7f4920d71bfeb426be40 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 9 Feb 2026 22:11:55 -0600 Subject: [PATCH 05/76] swig and formatting --- include/arkode/arkode_lsrkstep.h | 2 +- include/sundomeigest/sundomeigest_arnoldi.h | 8 +- include/sundomeigest/sundomeigest_power.h | 6 +- src/arkode/arkode_lsrkstep.c | 81 +++++++------ src/arkode/arkode_lsrkstep_impl.h | 8 +- src/arkode/arkode_lsrkstep_io.c | 4 +- src/arkode/fmod_int32/farkode_lsrkstep_mod.c | 14 +++ .../fmod_int32/farkode_lsrkstep_mod.f90 | 26 ++++ src/arkode/fmod_int64/farkode_lsrkstep_mod.c | 14 +++ .../fmod_int64/farkode_lsrkstep_mod.f90 | 26 ++++ .../fmod_int32/fsundomeigest_arnoldi_mod.c | 62 ++++++++++ .../fmod_int32/fsundomeigest_arnoldi_mod.f90 | 114 ++++++++++++++++++ .../fmod_int64/fsundomeigest_arnoldi_mod.c | 62 ++++++++++ .../fmod_int64/fsundomeigest_arnoldi_mod.f90 | 114 ++++++++++++++++++ .../arnoldi/sundomeigest_arnoldi.c | 50 ++++---- src/sundomeigest/power/sundomeigest_power.c | 65 +++++----- 16 files changed, 541 insertions(+), 115 deletions(-) diff --git a/include/arkode/arkode_lsrkstep.h b/include/arkode/arkode_lsrkstep.h index 49b56a4555..078bcc2468 100644 --- a/include/arkode/arkode_lsrkstep.h +++ b/include/arkode/arkode_lsrkstep.h @@ -93,7 +93,7 @@ SUNDIALS_EXPORT int LSRKStepSetMaxNumStages(void* arkode_mem, SUNDIALS_EXPORT int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety); -SUNDIALS_EXPORT int LSRKStepSetUseEllipseForStability(void* arkode_mem, +SUNDIALS_EXPORT int LSRKStepSetUseEllipseForStability(void* arkode_mem, sunbooleantype use_ellipse); SUNDIALS_EXPORT int LSRKStepSetNumDomEigEstInitPreprocessIters(void* arkode_mem, diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 9dc3a6ad4f..5a273242f6 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -45,11 +45,11 @@ struct SUNDomEigEstimatorContent_Arnoldi_ N_Vector* V; N_Vector q; - int kry_dim; /* Krylov subspace dimension */ - int num_warmups; /* Number of preprocessing iterations */ - long int num_iters; /* Number of iterations in last Estimate call */ + int kry_dim; /* Krylov subspace dimension */ + int num_warmups; /* Number of preprocessing iterations */ + long int num_iters; /* Number of iterations in last Estimate call */ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ - sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ + sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ long int num_ATimes; /* Number of ATimes calls */ diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index eab9685bcb..803884ba71 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -43,9 +43,9 @@ struct SUNDomEigEstimatorContent_Power_ N_Vector V, q, q_prev; /* workspace vectors */ - int num_warmups; /* Number of preprocessing iterations */ - long int max_iters; /* Maximum number of power iterations */ - long int num_iters; /* Number of iterations in last Estimate call */ + int num_warmups; /* Number of preprocessing iterations */ + long int max_iters; /* Maximum number of power iterations */ + long int num_iters; /* Number of iterations in last Estimate call */ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ long int num_ATimes; /* Number of ATimes calls */ diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 7533588901..90379a9878 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -559,7 +559,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; - const sunrealtype coefz = THREE/TWO / (ONE - TWO/SUN_RCONST(15.0) * step_mem->rkc_damping); + const sunrealtype coefz = + THREE / TWO / (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); /* Compute dominant eigenvalue and update stats */ if (step_mem->dom_eig_update) @@ -573,7 +574,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); - ss = SUNMAX(ss, SUN_RCONST(2.0)); + ss = SUNMAX(ss, SUN_RCONST(2.0)); /* Check if number of stages exceeds maximum allowed. If so, and if adaptive stepping is enabled, reduce step size @@ -589,7 +590,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (!ark_mem->fixedstep) { - hmax = ark_mem->hadapt_mem->safety * (ONE - SUNSQR(step_mem->stage_max_limit)) / + hmax = ark_mem->hadapt_mem->safety * + (ONE - SUNSQR(step_mem->stage_max_limit)) / (coefz * step_mem->lambdaR); ark_mem->eta = hmax / ark_mem->h; *nflagPtr = ARK_RETRY_STEP; @@ -634,14 +636,16 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } else { - while (stability_norm > ONE - SUN_SMALL_REAL && step_mem->req_stages < step_mem->stage_max_limit) + while (stability_norm > ONE - SUN_SMALL_REAL && + step_mem->req_stages < step_mem->stage_max_limit) { step_mem->req_stages += 1; retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_SMALL_REAL || step_mem->req_stages >= step_mem->stage_max_limit) + if (stability_norm > ONE - SUN_SMALL_REAL || + step_mem->req_stages >= step_mem->stage_max_limit) { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, __FILE__, @@ -652,7 +656,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } - step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", "spectral radius = " SUN_FORMAT_G @@ -1004,14 +1008,16 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } else { - while (stability_norm > ONE - SUN_SMALL_REAL && step_mem->req_stages < step_mem->stage_max_limit) + while (stability_norm > ONE - SUN_SMALL_REAL && + step_mem->req_stages < step_mem->stage_max_limit) { step_mem->req_stages += 1; retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_SMALL_REAL || step_mem->req_stages >= step_mem->stage_max_limit) + if (stability_norm > ONE - SUN_SMALL_REAL || + step_mem->req_stages >= step_mem->stage_max_limit) { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, __FILE__, @@ -1022,7 +1028,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } - step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", "spectral radius = " SUN_FORMAT_G @@ -2503,8 +2509,7 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) we compute the stability norm directly from the stability function using the Chebyshev polynomial. The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. ---------------------------------------------------------------*/ -int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, - ARKodeLSRKStepMem step_mem, +int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) { sunrealtype ss = step_mem->req_stages; @@ -2521,21 +2526,22 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, of the inscribed ellipse. The value of re_stab_min is determined by the damping parameter and the number of stages by reverting the formula for finding the required number of stages for a given spectral radius times step size. im_stab_min is then determined by - herustically by deviding re_stab_min by the aspect ratio of the ellipse, which is + herustically by dividing re_stab_min by the aspect ratio of the ellipse, which is approximateted as 3.65*ss, where ss is the number of stages. In particular, if ss=2, the aspect ratio is estimated to be 0.6*ss. This heuristic is based on the observation that imaginary extend of the stability region grows linearly with the number of stages. The factors of 3.65 and 0.6 are determined empirically by plotting the stability region for different number of stages and the default damping parameter. It is subject to change if the default damping parameter is changed. */ - re_stab_min = TWO/THREE * (ONE - SUNSQR(ss)) * - (ONE - TWO/SUN_RCONST(15.0) * step_mem->rkc_damping); - im_stab_min = -re_stab_min / (ss == 2 ? SUN_RCONST(0.6) * ss : SUN_RCONST(3.65) * ss); + re_stab_min = TWO / THREE * (ONE - SUNSQR(ss)) * + (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); + im_stab_min = -re_stab_min / + (ss == 2 ? SUN_RCONST(0.6) * ss : SUN_RCONST(3.65) * ss); xc = re_stab_min / TWO; yc = ZERO; - a = SUNRabs(re_stab_min) / TWO; - b = SUNRabs(im_stab_min); + a = SUNRabs(re_stab_min) / TWO; + b = SUNRabs(im_stab_min); *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); } @@ -2546,10 +2552,10 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, sh = SUNRsinh(th); ch = SUNRcosh(th); - Ts = SUNRcosh(ss * th); - Ts_p = ss * SUNRsinh(ss * th) / sh; - Ts_pp = (ss * ss * SUNRcosh(ss * th) / (sh * sh)) - ss * ch * SUNRsinh(ss * th) / - (sh * sh * sh); + Ts = SUNRcosh(ss * th); + Ts_p = ss * SUNRsinh(ss * th) / sh; + Ts_pp = (ss * ss * SUNRcosh(ss * th) / (sh * sh)) - + ss * ch * SUNRsinh(ss * th) / (sh * sh * sh); b_s = Ts_pp / (Ts_p * Ts_p); a_s = ONE - b_s * Ts; @@ -2585,8 +2591,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, we compute the stability norm directly from the stability function using the Legendre polynomial. The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. ---------------------------------------------------------------*/ -int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, - ARKodeLSRKStepMem step_mem, +int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) { sunrealtype ss = step_mem->req_stages; @@ -2602,13 +2607,13 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, where re_stab_min and im_stab_min are the real and imaginary parts of the leftmost point of the inscribed ellipse. The value of re_stab_min is determined by the number of stages by reverting the formula for finding the required number of stages for a given spectral - radius times step size. im_stab_min is then determined by herustically by deviding + radius times step size. im_stab_min is then determined by herustically by dividing re_stab_min by the aspect ratio of the ellipse, which is approximated as imag_extend_factor*ss, where ss is the number of stages and the factor imag_extend_factor is determined empirically by plotting the stability region for different number of stages. This factor is as follows: */ - /*s = 2 -> 0.6 + /*s = 2 -> 0.6 s = 3 -> 1.5 s = 4 -> 1.33 s = 5 -> 1.33 @@ -2624,12 +2629,14 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, 1.2, /* s >= 20 and odd */ 1.06 /* s >= 20 and even */ }; - re_stab_min = -((TWO*ss + ONE)*(TWO*ss + ONE)- SUN_RCONST(9.0)) / SUN_RCONST(8.0); + re_stab_min = -((TWO * ss + ONE) * (TWO * ss + ONE) - SUN_RCONST(9.0)) / + SUN_RCONST(8.0); if (ss < 7) { - im_stab_min = -re_stab_min / (imag_extend_factor[(int)ss-2] * ss); + im_stab_min = -re_stab_min / (imag_extend_factor[(int)ss - 2] * ss); } - else { + else + { if (ss <= 20) { im_stab_min = -re_stab_min / (imag_extend_factor[4] * ss); @@ -2640,23 +2647,23 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, } } // TODO:get opinon on whether we want to use the heuristic with different factors for different number of stages or - // to use a single global factor for all number of stages. The heuristic with different factors for different number + // to use a single global factor for all number of stages. The heuristic with different factors for different number // of stages is more accurate, especially for small number of stages, but it is also more complicated. // Instead we can use a single global factor of 1.5 for all number of stages as follows: // im_stab_min = -re_stab_min / (SUN_RCONST(1.5) * ss); xc = re_stab_min / TWO; yc = ZERO; - a = SUNRabs(re_stab_min) / TWO; - b = SUNRabs(im_stab_min); + a = SUNRabs(re_stab_min) / TWO; + b = SUNRabs(im_stab_min); *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); } else { - b_s = (ss*ss + ss - TWO) / (TWO * ss * (ss + ONE)); + b_s = (ss * ss + ss - TWO) / (TWO * ss * (ss + ONE)); a_s = ONE - b_s; - w1 = FOUR / (ss * ss + ss - TWO); // Eq.(15) in Meyer et al. (2014) + w1 = FOUR / (ss * ss + ss - TWO); // Eq.(15) in Meyer et al. (2014) wr = ONE + w1 * zR; wi = w1 * zI; @@ -2684,7 +2691,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, T_{k+1}(z) = 2*z*T_k(z) - T_{k-1}(z), k = 1,...,s-1 ---------------------------------------------------------------*/ int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, - sunrealtype* TsR, sunrealtype* TsI) + sunrealtype* TsR, sunrealtype* TsI) { if (s < 0) { @@ -2707,7 +2714,7 @@ int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, else { sunrealtype Tkm1R = ONE, Tkm1I = ZERO; // T_0(z) - sunrealtype TkR = zR, TkI = zI; // T_1(z) + sunrealtype TkR = zR, TkI = zI; // T_1(z) sunrealtype Tkp1R, Tkp1I; for (int k = 1; k < s; k++) { @@ -2735,7 +2742,7 @@ int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, ---------------------------------------------------------------*/ int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, - sunrealtype* PsR, sunrealtype* PsI) + sunrealtype* PsR, sunrealtype* PsI) { if (s < 0) { @@ -2758,7 +2765,7 @@ int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, else { sunrealtype Pkm1R = ONE, Pkm1I = ZERO; // P_0(z) - sunrealtype PkR = zR, PkI = zI; // P_1(z) + sunrealtype PkR = zR, PkI = zI; // P_1(z) sunrealtype Pkp1R, Pkp1I; for (int k = 1; k < s; k++) { diff --git a/src/arkode/arkode_lsrkstep_impl.h b/src/arkode/arkode_lsrkstep_impl.h index 9c10eb8e76..83636d38e7 100644 --- a/src/arkode/arkode_lsrkstep_impl.h +++ b/src/arkode/arkode_lsrkstep_impl.h @@ -32,7 +32,7 @@ extern "C" { #define STAGE_MAX_LIMIT_DEFAULT 200 #define DOM_EIG_SAFETY_DEFAULT SUN_RCONST(1.01) -#define RKC_DAMPING_DEFAULT SUN_RCONST(2.0)/SUN_RCONST(13.0) +#define RKC_DAMPING_DEFAULT SUN_RCONST(2.0) / SUN_RCONST(13.0) #define DOM_EIG_FREQ_DEFAULT 25 #define DOM_EIG_NUM_WARMUPS_DEFAULT 0 #define DOM_EIG_NUM_INIT_WARMUPS_DEFAULT -1 /* use DEE's default value */ @@ -196,8 +196,8 @@ typedef struct ARKodeLSRKStepMemRec sunbooleantype const_Jac; /* flag indicating Jacobian is constant */ sunbooleantype dom_eig_is_current; /* SUNTRUE if dom_eig has been evaluated at tn */ sunbooleantype use_ellipse; /* flag indicating whether to use ellipse or exact stability region for stability checks */ - sunbooleantype is_SSP; /* flag indicating SSP method*/ - sunbooleantype init_warmup; /* flag indicating initial warm-up*/ + sunbooleantype is_SSP; /* flag indicating SSP method*/ + sunbooleantype init_warmup; /* flag indicating initial warm-up*/ /* Reusable fused vector operation arrays */ sunrealtype* cvals; @@ -251,7 +251,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, sunrealtype* TsR, sunrealtype* TsI); int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, - sunrealtype* PsR, sunrealtype* PsI); + sunrealtype* PsR, sunrealtype* PsI); int lsrkStep_DQJtimes(void* arkode_mem, N_Vector v, N_Vector Jv); /*=============================================================== diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index 868efb01ef..bfa15751b4 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -344,9 +344,9 @@ int LSRKStepSetUseEllipseForStability(void* arkode_mem, sunbooleantype use_ellip &step_mem); if (retval != ARK_SUCCESS) { return retval; } - step_mem->dom_eig_update = SUNTRUE; + step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; - step_mem->use_ellipse = use_ellipse; + step_mem->use_ellipse = use_ellipse; return ARK_SUCCESS; } diff --git a/src/arkode/fmod_int32/farkode_lsrkstep_mod.c b/src/arkode/fmod_int32/farkode_lsrkstep_mod.c index d310719af8..6b83da3c65 100644 --- a/src/arkode/fmod_int32/farkode_lsrkstep_mod.c +++ b/src/arkode/fmod_int32/farkode_lsrkstep_mod.c @@ -431,6 +431,20 @@ SWIGEXPORT int _wrap_FLSRKStepSetDomEigSafetyFactor(void *farg1, double const *f } +SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)LSRKStepSetUseEllipseForStability(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FLSRKStepSetNumDomEigEstInitPreprocessIters(void *farg1, int const *farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 b/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 index d943d4904c..51bc46718a 100644 --- a/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 @@ -56,6 +56,7 @@ module farkode_lsrkstep_mod public :: FLSRKStepSetDomEigFrequency public :: FLSRKStepSetMaxNumStages public :: FLSRKStepSetDomEigSafetyFactor + public :: FLSRKStepSetUseEllipseForStability public :: FLSRKStepSetNumDomEigEstInitPreprocessIters public :: FLSRKStepSetNumDomEigEstPreprocessIters public :: FLSRKStepSetNumSSPStages @@ -193,6 +194,15 @@ function swigc_FLSRKStepSetDomEigSafetyFactor(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) & +bind(C, name="_wrap_FLSRKStepSetUseEllipseForStability") & +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_FLSRKStepSetNumDomEigEstInitPreprocessIters(farg1, farg2) & bind(C, name="_wrap_FLSRKStepSetNumDomEigEstInitPreprocessIters") & result(fresult) @@ -513,6 +523,22 @@ function FLSRKStepSetDomEigSafetyFactor(arkode_mem, dom_eig_safety) & swig_result = fresult end function +function FLSRKStepSetUseEllipseForStability(arkode_mem, use_ellipse) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: use_ellipse +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = use_ellipse +fresult = swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) +swig_result = fresult +end function + function FLSRKStepSetNumDomEigEstInitPreprocessIters(arkode_mem, num_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/arkode/fmod_int64/farkode_lsrkstep_mod.c b/src/arkode/fmod_int64/farkode_lsrkstep_mod.c index d310719af8..6b83da3c65 100644 --- a/src/arkode/fmod_int64/farkode_lsrkstep_mod.c +++ b/src/arkode/fmod_int64/farkode_lsrkstep_mod.c @@ -431,6 +431,20 @@ SWIGEXPORT int _wrap_FLSRKStepSetDomEigSafetyFactor(void *farg1, double const *f } +SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const *farg2) { + int fresult ; + void *arg1 = (void *) 0 ; + int arg2 ; + int result; + + arg1 = (void *)(farg1); + arg2 = (int)(*farg2); + result = (int)LSRKStepSetUseEllipseForStability(arg1,arg2); + fresult = (int)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FLSRKStepSetNumDomEigEstInitPreprocessIters(void *farg1, int const *farg2) { int fresult ; void *arg1 = (void *) 0 ; diff --git a/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 b/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 index d943d4904c..51bc46718a 100644 --- a/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 @@ -56,6 +56,7 @@ module farkode_lsrkstep_mod public :: FLSRKStepSetDomEigFrequency public :: FLSRKStepSetMaxNumStages public :: FLSRKStepSetDomEigSafetyFactor + public :: FLSRKStepSetUseEllipseForStability public :: FLSRKStepSetNumDomEigEstInitPreprocessIters public :: FLSRKStepSetNumDomEigEstPreprocessIters public :: FLSRKStepSetNumSSPStages @@ -193,6 +194,15 @@ function swigc_FLSRKStepSetDomEigSafetyFactor(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) & +bind(C, name="_wrap_FLSRKStepSetUseEllipseForStability") & +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_FLSRKStepSetNumDomEigEstInitPreprocessIters(farg1, farg2) & bind(C, name="_wrap_FLSRKStepSetNumDomEigEstInitPreprocessIters") & result(fresult) @@ -513,6 +523,22 @@ function FLSRKStepSetDomEigSafetyFactor(arkode_mem, dom_eig_safety) & swig_result = fresult end function +function FLSRKStepSetUseEllipseForStability(arkode_mem, use_ellipse) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(C_PTR) :: arkode_mem +integer(C_INT), intent(in) :: use_ellipse +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +integer(C_INT) :: farg2 + +farg1 = arkode_mem +farg2 = use_ellipse +fresult = swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) +swig_result = fresult +end function + function FLSRKStepSetNumDomEigEstInitPreprocessIters(arkode_mem, num_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index 3c0799fc5a..cd530e4a96 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -468,6 +468,54 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(SwigClass } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::warmup_to_tol", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->warmup_to_tol = arg2; +} + + +SWIGEXPORT int _wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::warmup_to_tol", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (int) ((arg1)->warmup_to_tol); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(SwigClassWrapper const *farg1, double const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::tol_preprocess", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (sunrealtype)(*farg2); + if (arg1) (arg1)->tol_preprocess = arg2; +} + + +SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(SwigClassWrapper const *farg1) { + double fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::tol_preprocess", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (sunrealtype) ((arg1)->tol_preprocess); + fresult = (sunrealtype)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(SwigClassWrapper const *farg1, long const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; long arg2 ; @@ -737,6 +785,20 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEig } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetInitialGuess_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index 787459fa26..72b4d805df 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -54,6 +54,10 @@ module fsundomeigest_arnoldi_mod procedure :: get_num_warmups => swigf_SUNDomEigEstimatorContent_Arnoldi__num_warmups_get procedure :: set_num_iters => swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_set procedure :: get_num_iters => swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_get + procedure :: set_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set + procedure :: get_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get + procedure :: set_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set + procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get procedure :: set_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set @@ -80,6 +84,7 @@ module fsundomeigest_arnoldi_mod public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi + public :: FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi public :: FSUNDomEigEstimator_Initialize_Arnoldi public :: FSUNDomEigEstimator_Estimate_Arnoldi @@ -209,6 +214,40 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(farg1) & integer(C_LONG) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set") use, intrinsic :: ISO_C_BINDING @@ -397,6 +436,15 @@ function swigc_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi") & +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_FSUNDomEigEstimator_SetInitialGuess_Arnoldi(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetInitialGuess_Arnoldi") & result(fresult) @@ -639,6 +687,56 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(self, warmup_to_tol) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_INT), intent(in) :: warmup_to_tol +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = warmup_to_tol +call swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(self, tol_preprocess) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE), intent(in) :: tol_preprocess +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = self%swigdata +farg2 = tol_preprocess +call swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +real(C_DOUBLE) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(self, num_atimes) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -930,6 +1028,22 @@ function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & swig_result = fresult end function +function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = c_loc(dee) +farg2 = tol +fresult = swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetInitialGuess_Arnoldi(dee, q) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index 6a49443ec8..e7a3195a9e 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -468,6 +468,54 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(SwigClass } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(SwigClassWrapper const *farg1, int const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + int arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::warmup_to_tol", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (int)(*farg2); + if (arg1) (arg1)->warmup_to_tol = arg2; +} + + +SWIGEXPORT int _wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(SwigClassWrapper const *farg1) { + int fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + int result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::warmup_to_tol", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (int) ((arg1)->warmup_to_tol); + fresult = (int)(result); + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(SwigClassWrapper const *farg1, double const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::tol_preprocess", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (sunrealtype)(*farg2); + if (arg1) (arg1)->tol_preprocess = arg2; +} + + +SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(SwigClassWrapper const *farg1) { + double fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::tol_preprocess", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (sunrealtype) ((arg1)->tol_preprocess); + fresult = (sunrealtype)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(SwigClassWrapper const *farg1, long const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; long arg2 ; @@ -737,6 +785,20 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEig } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + sunrealtype arg2 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (sunrealtype)(*farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetInitialGuess_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index 21ed6d482c..f51786e2ee 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -54,6 +54,10 @@ module fsundomeigest_arnoldi_mod procedure :: get_num_warmups => swigf_SUNDomEigEstimatorContent_Arnoldi__num_warmups_get procedure :: set_num_iters => swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_set procedure :: get_num_iters => swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_get + procedure :: set_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set + procedure :: get_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get + procedure :: set_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set + procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get procedure :: set_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set @@ -80,6 +84,7 @@ module fsundomeigest_arnoldi_mod public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi + public :: FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi public :: FSUNDomEigEstimator_Initialize_Arnoldi public :: FSUNDomEigEstimator_Estimate_Arnoldi @@ -209,6 +214,40 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(farg1) & integer(C_LONG) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set") use, intrinsic :: ISO_C_BINDING @@ -397,6 +436,15 @@ function swigc_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi") & +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_FSUNDomEigEstimator_SetInitialGuess_Arnoldi(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetInitialGuess_Arnoldi") & result(fresult) @@ -639,6 +687,56 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__num_iters_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(self, warmup_to_tol) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_INT), intent(in) :: warmup_to_tol +type(SwigClassWrapper) :: farg1 +integer(C_INT) :: farg2 + +farg1 = self%swigdata +farg2 = warmup_to_tol +call swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_INT) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(self, tol_preprocess) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE), intent(in) :: tol_preprocess +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = self%swigdata +farg2 = tol_preprocess +call swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +real(C_DOUBLE) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(self, num_atimes) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -930,6 +1028,22 @@ function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & swig_result = fresult end function +function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: tol +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = c_loc(dee) +farg2 = tol +fresult = swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetInitialGuess_Arnoldi(dee, q) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index ca50b98df6..1e5cb3af1f 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -122,23 +122,23 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, DEE->content = content; /* Fill content */ - content->ATimes = NULL; - content->ATdata = NULL; - content->V = NULL; - content->q = NULL; - content->kry_dim = kry_dim; - content->num_warmups = DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT; - content->num_iters = 0; - content->num_ATimes = 0; - content->warmup_to_tol = SUNFALSE; + content->ATimes = NULL; + content->ATdata = NULL; + content->V = NULL; + content->q = NULL; + content->kry_dim = kry_dim; + content->num_warmups = DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT; + content->num_iters = 0; + content->num_ATimes = 0; + content->warmup_to_tol = SUNFALSE; content->tol_preprocess = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; - content->LAPACK_A = NULL; - content->LAPACK_wr = NULL; - content->LAPACK_wi = NULL; - content->LAPACK_work = NULL; - content->LAPACK_lwork = 0; - content->LAPACK_arr = NULL; - content->Hes = NULL; + content->LAPACK_A = NULL; + content->LAPACK_wr = NULL; + content->LAPACK_wi = NULL; + content->LAPACK_work = NULL; + content->LAPACK_lwork = 0; + content->LAPACK_arr = NULL; + content->Hes = NULL; /* Allocate content */ content->q = N_VClone(q); @@ -287,7 +287,7 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator D Arnoldi_CONTENT(DEE)->num_warmups = num_iters; /* set the type of warmup iterations */ - Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; + Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; return SUN_SUCCESS; } @@ -300,14 +300,8 @@ SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator D SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); /* set the tolerance for preprocessing iterations */ - if(tol <= SUN_RCONST(0.0)) - { - tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; - } - else - { - Arnoldi_CONTENT(DEE)->tol_preprocess = tol; - } + if (tol <= SUN_RCONST(0.0)) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } + else { Arnoldi_CONTENT(DEE)->tol_preprocess = tol; } /* set the type of warmup iterations */ Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; @@ -384,12 +378,12 @@ SUNErrCode SUNDomEigEstimator_Estimate_Arnoldi(SUNDomEigEstimator DEE, normq = SUNRsqrt(normq); N_VScale(ONE / normq, Arnoldi_CONTENT(DEE)->q, Arnoldi_CONTENT(DEE)->V[0]); SUNCheckLastErr(); - + if (Arnoldi_CONTENT(DEE)->warmup_to_tol) { - res = SUNRabs(newnormlambda - oldnormlambda); + res = SUNRabs(newnormlambda - oldnormlambda); oldnormlambda = newnormlambda; - if(res <= Arnoldi_CONTENT(DEE)->tol_preprocess * SUNRabs(newnormlambda)) + if (res <= Arnoldi_CONTENT(DEE)->tol_preprocess * SUNRabs(newnormlambda)) { break; } diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 07a0a13c98..deb7157087 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -57,12 +57,9 @@ * -------------------------------------------------------------------------- */ -SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, - sunrealtype lambdaR, - N_Vector v_prev, - N_Vector v, - sunrealtype* lambdaR_out, - sunrealtype* lambdaI_out); +SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( + SUNDomEigEstimator DEE, sunrealtype lambdaR, N_Vector v_prev, N_Vector v, + sunrealtype* lambdaR_out, sunrealtype* lambdaI_out); /* ---------------------------------------------------------------------------- * Function to create a new PI estimator @@ -217,7 +214,7 @@ SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE) SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); - if(PI_CONTENT(DEE)->complex) + if (PI_CONTENT(DEE)->complex) { SUNAssert(PI_CONTENT(DEE)->q_prev == NULL, SUN_ERR_ARG_CORRUPT); } @@ -317,7 +314,7 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); SUNAssert((PI_CONTENT(DEE)->max_iters >= 0), SUN_ERR_ARG_CORRUPT); - if(PI_CONTENT(DEE)->complex) + if (PI_CONTENT(DEE)->complex) { /* allocate q_prev vector */ PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); @@ -336,7 +333,7 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, for (int i = 0; i < PI_CONTENT(DEE)->num_warmups; i++) { retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, - PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q); + PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->num_ATimes++; PI_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } @@ -351,7 +348,7 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, for (int k = 0; k < PI_CONTENT(DEE)->max_iters; k++) { - if(PI_CONTENT(DEE)->complex) + if (PI_CONTENT(DEE)->complex) { N_VScale(ONE, PI_CONTENT(DEE)->V, PI_CONTENT(DEE)->q_prev); SUNCheckLastErr(); @@ -375,22 +372,21 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNCheckLastErr(); PI_CONTENT(DEE)->res = SUNRabs(newlambdaR - oldlambdaR); - if (PI_CONTENT(DEE)->res <= PI_CONTENT(DEE)->rel_tol * SUNRabs(newlambdaR)) + if (PI_CONTENT(DEE)->res <= PI_CONTENT(DEE)->rel_tol * SUNRabs(newlambdaR)) { - break; + break; } oldlambdaR = newlambdaR; } - if(PI_CONTENT(DEE)->complex) + if (PI_CONTENT(DEE)->complex) { retval = sundomeigestimator_complex_dom_eigs_from_PI(DEE, newlambdaR, - PI_CONTENT(DEE)->q_prev, - PI_CONTENT(DEE)->V, - lambdaR, lambdaI); + PI_CONTENT(DEE)->q_prev, + PI_CONTENT(DEE)->V, + lambdaR, lambdaI); if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } - } else { @@ -470,22 +466,19 @@ SUNErrCode SUNDomEigEstimator_Write_Power(SUNDomEigEstimator DEE, FILE* outfile) return SUN_SUCCESS; } -SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, - sunrealtype lambdaR, - N_Vector v_prev, - N_Vector v, - sunrealtype* lambdaR_out, - sunrealtype* lambdaI_out) +SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( + SUNDomEigEstimator DEE, sunrealtype lambdaR, N_Vector v_prev, N_Vector v, + sunrealtype* lambdaR_out, sunrealtype* lambdaI_out) { SUNFunctionBegin(DEE->sunctx); - + int retval; - sunrealtype cos_qs, det_G_inv, h11, h12,h21, h22, p11, p12, p21, p22; + sunrealtype cos_qs, det_G_inv, h11, h12, h21, h22, p11, p12, p21, p22; sunrealtype proj_cond_inv = SUN_RCONST(1e-2); - cos_qs = N_VDotProd(v_prev, v); + cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); - if(fabs(fabs(cos_qs) - ONE) < proj_cond_inv) + if (fabs(fabs(cos_qs) - ONE) < proj_cond_inv) { printf("Warning: Projection matrix is ill-conditioned. Returning " "dominant eigenvalue as real part only.\n"); @@ -496,13 +489,13 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, } else { - det_G_inv = ONE/(ONE - cos_qs * cos_qs); + det_G_inv = ONE / (ONE - cos_qs * cos_qs); /* Solve for G = [v_prev v]' * [v_prev v] and compute projected matrix P = G^{-1} * [v_prev v]' * A * [v_prev v] */ - retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, - v_prev, PI_CONTENT(DEE)->q); + retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, v_prev, + PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->num_ATimes++; PI_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } @@ -510,8 +503,8 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, h11 = N_VDotProd(v_prev, PI_CONTENT(DEE)->q); h21 = N_VDotProd(v, PI_CONTENT(DEE)->q); - retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, - v, PI_CONTENT(DEE)->q); + retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, v, + PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->num_ATimes++; PI_CONTENT(DEE)->num_iters++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } @@ -525,10 +518,10 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI(SUNDomEigEstimator DEE, p22 = det_G_inv * (h22 - cos_qs * h12); /* Compute eigenvalues of P */ - sunrealtype traceP = p11 + p22; - sunrealtype detP = p11 * p22 - p12 * p21; - sunrealtype discrim = traceP * traceP - SUN_RCONST(4.0) * detP; - if(discrim >= ZERO) + sunrealtype traceP = p11 + p22; + sunrealtype detP = p11 * p22 - p12 * p21; + sunrealtype discrim = traceP * traceP - SUN_RCONST(4.0) * detP; + if (discrim >= ZERO) { /* Dominant eigenvalue is real */ *lambdaR_out = (traceP + SUNRsqrt(discrim)) / SUN_RCONST(2.0); From 2c2d8e61a9b55ced9efecfbefb39e99f13a97e22 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 10:33:13 -0600 Subject: [PATCH 06/76] deactivate the py interface check temporarily --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6238ad61a..ebf16cfd9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,8 @@ jobs: # Check for changes to trigger python interface checks # Updates in include or bindings/sundials4py directories if git diff --name-only "$BASE" "$HEAD" | grep -qE '^(include/|bindings/sundials4py/)'; then - echo "python=true" >> "$GITHUB_OUTPUT" + #echo "python=true" >> "$GITHUB_OUTPUT" + echo "python=false" >> "$GITHUB_OUTPUT" else echo "python=false" >> "$GITHUB_OUTPUT" fi From f93ab677b07f7bc7d402e8e4db0b029d4da9e946 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 10:45:59 -0600 Subject: [PATCH 07/76] removed unused zI --- src/arkode/arkode_lsrkstep.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 90379a9878..077c36961e 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -572,7 +572,6 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Compute number of stages based on current step size and dominant eigenvalue using Eq. (2.7) in Verwer et al. (2004) */ sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); @@ -938,7 +937,6 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Compute number of stages based on current step size and dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; sunrealtype ss = SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * SUNRabs(ark_mem->h) * step_mem->spectral_radius) - From 59f3f1c3c059d7d135f92149472fba2cdc466e9f Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 11:08:49 -0600 Subject: [PATCH 08/76] fixed ci issues --- src/arkode/arkode_lsrkstep.c | 5 +---- src/sundomeigest/arnoldi/sundomeigest_arnoldi.c | 3 ++- src/sundomeigest/power/sundomeigest_power.c | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 077c36961e..9a5d35a67c 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -938,10 +938,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; sunrealtype ss = - SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * SUNRabs(ark_mem->h) * - step_mem->spectral_radius) - - ONE) / - TWO); + SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zR) - ONE) / TWO); ss = SUNMAX(ss, SUN_RCONST(2.0)); diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 1e5cb3af1f..ce4e75cac9 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -38,7 +38,8 @@ #error Incompatible sunrealtype for LAPACK; disable LAPACK and rebuild #endif -#define ONE SUN_RCONST(1.0) +#define ZERO SUN_RCONST(0.0) +#define ONE SUN_RCONST(1.0) /* Default estimator parameters */ #define DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT 100 diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index deb7157087..056148494d 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -478,7 +478,7 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); - if (fabs(fabs(cos_qs) - ONE) < proj_cond_inv) + if (SUNRabs(SUNRabs(cos_qs) - ONE) < proj_cond_inv) { printf("Warning: Projection matrix is ill-conditioned. Returning " "dominant eigenvalue as real part only.\n"); From 5fc27eb582e5586a625b91ff8a3682212c5112a5 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 21:12:11 -0600 Subject: [PATCH 09/76] zR to zRabs fix and output files --- .../arkode/C_serial/ark_analytic_lsrk.out | 16 +-- .../C_serial/ark_analytic_lsrk_domeigest.c | 4 + .../C_serial/ark_analytic_lsrk_domeigest.out | 28 ++-- ...iters_1_sundomeigestimator.max_iters_1.out | 24 ++-- .../C_serial/ark_analytic_lsrk_varjac.out | 24 ++-- examples/arkode/C_serial/ark_heat1D_adapt.out | 125 +++++++++--------- src/arkode/arkode_lsrkstep.c | 6 +- test/answers | 2 +- 8 files changed, 114 insertions(+), 115 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_lsrk.out b/examples/arkode/C_serial/ark_analytic_lsrk.out index d8f00ed4ad..2441d6b625 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk.out +++ b/examples/arkode/C_serial/ark_analytic_lsrk.out @@ -19,22 +19,22 @@ Analytical ODE test problem: --------------------- Final Statistics: -Current time = 10.0040469322476 -Steps = 1120 -Step attempts = 1124 +Current time = 10.0013387372969 +Steps = 1122 +Step attempts = 1125 Stability limited steps = 232 -Accuracy limited steps = 1124 -Error test fails = 4 +Accuracy limited steps = 1125 +Error test fails = 3 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 1.93010111094261e-10 Last step size = 0.01791 -Current step size = 0.0370361796227445 -RHS fn evals = 141974 +Current step size = 0.0393007765090647 +RHS fn evals = 141846 Number of dom_eig updates = 1 Max. num. of stages used = 199 Max. num. of stages allowed = 200 Max. spectral radius = 1010000 Min. spectral radius = 1010000 -ACCURACY at the final time = 1.52101e-13 +ACCURACY at the final time = 1.04139e-13 \ No newline at end of file diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c index 5c35c8802a..2d1d3ba15a 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c @@ -237,6 +237,10 @@ int main(int argc, char* argv[]) flag = ARKodeSetOptions(arkode_mem, NULL, NULL, argc, argv); if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } + /* Set real type dominant eigenvalue */ + flag = SUNDomEigEstimator_SetReal_Power(DEE); + if (check_flag(&flag, "SUNDomEigEstimator_SetReal_Power", 1)) { return 1; } + /* Open output stream for results, output comment line */ UFID = fopen("solution.txt", "w"); fprintf(UFID, "# t u\n"); diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.out b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.out index 6518d38b4b..7bdb6371a6 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.out +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.out @@ -23,24 +23,24 @@ The stiffness of the problem is directly proportional to --------------------- Final Statistics: -Current time = 10.0225297852833 -Steps = 1228 -Step attempts = 1293 -Stability limited steps = 100 -Accuracy limited steps = 1293 -Error test fails = 65 +Current time = 10.0071779045287 +Steps = 1223 +Step attempts = 1280 +Stability limited steps = 53 +Accuracy limited steps = 1280 +Error test fails = 57 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 1.93010111094261e-10 -Last step size = 0.0231428574002256 -Current step size = 0.0355362892083706 -RHS fn evals = 134017 -Number of dom_eig updates = 85 -Number of fe calls for DEE = 304 -Number of iterations for DEE = 180 +Last step size = 0.0232720439260913 +Current step size = 0.026140590649044 +RHS fn evals = 132154 +Number of dom_eig updates = 81 +Number of fe calls for DEE = 278 +Number of iterations for DEE = 172 Max. num. of stages used = 199 Max. num. of stages allowed = 200 -Max. spectral radius = 1010100.99886782 +Max. spectral radius = 1010100.56057129 Min. spectral radius = 1009899.00000001 -ACCURACY at the final time = 2.41362e-13 \ No newline at end of file +ACCURACY at the final time = 5.97078e-13 \ No newline at end of file diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest_arkid.dom_eig_est_init_preprocess_iters_1_sundomeigestimator.max_iters_1.out b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest_arkid.dom_eig_est_init_preprocess_iters_1_sundomeigestimator.max_iters_1.out index c0fa551a34..17f974ce3a 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest_arkid.dom_eig_est_init_preprocess_iters_1_sundomeigestimator.max_iters_1.out +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest_arkid.dom_eig_est_init_preprocess_iters_1_sundomeigestimator.max_iters_1.out @@ -23,24 +23,24 @@ The stiffness of the problem is directly proportional to --------------------- Final Statistics: -Current time = 10.0078124292941 -Steps = 1220 -Step attempts = 1279 -Stability limited steps = 109 -Accuracy limited steps = 1279 -Error test fails = 59 +Current time = 10.0012842870746 +Steps = 1225 +Step attempts = 1282 +Stability limited steps = 44 +Accuracy limited steps = 1282 +Error test fails = 57 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 1.93010111094261e-10 -Last step size = 0.0231428888979688 -Current step size = 0.0371525856132128 -RHS fn evals = 132879 +Last step size = 0.0232720481291628 +Current step size = 0.0257097908695329 +RHS fn evals = 132323 Number of dom_eig updates = 81 -Number of fe calls for DEE = 147 +Number of fe calls for DEE = 144 Number of iterations for DEE = 91 Max. num. of stages used = 199 Max. num. of stages allowed = 200 -Max. spectral radius = 1010099.62410851 +Max. spectral radius = 1010100.37814108 Min. spectral radius = 1009899 -ACCURACY at the final time = 1.98952e-13 +ACCURACY at the final time = 7.18314e-13 diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_varjac.out b/examples/arkode/C_serial/ark_analytic_lsrk_varjac.out index 5deb40defe..06ef355cc0 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_varjac.out +++ b/examples/arkode/C_serial/ark_analytic_lsrk_varjac.out @@ -23,22 +23,22 @@ The stiffness of the problem is directly proportional to --------------------- Final Statistics: -Current time = 10.0176850761672 -Steps = 1218 -Step attempts = 1274 -Stability limited steps = 102 -Accuracy limited steps = 1274 -Error test fails = 56 +Current time = 10.0024706965917 +Steps = 1225 +Step attempts = 1283 +Stability limited steps = 47 +Accuracy limited steps = 1283 +Error test fails = 58 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 1.93010111094261e-10 -Last step size = 0.0231428715572232 -Current step size = 0.035071188930862 -RHS fn evals = 133006 -Number of dom_eig updates = 80 +Last step size = 0.0232720622166514 +Current step size = 0.0258318595494996 +RHS fn evals = 132509 +Number of dom_eig updates = 81 Max. num. of stages used = 199 Max. num. of stages allowed = 200 -Max. spectral radius = 1010100.38096708 +Max. spectral radius = 1010099.76668785 Min. spectral radius = 1009899 -ACCURACY at the final time = 2.42473e-13 +ACCURACY at the final time = 6.7879e-13 \ No newline at end of file diff --git a/examples/arkode/C_serial/ark_heat1D_adapt.out b/examples/arkode/C_serial/ark_heat1D_adapt.out index 486aa1afa7..e6038fc3be 100644 --- a/examples/arkode/C_serial/ark_heat1D_adapt.out +++ b/examples/arkode/C_serial/ark_heat1D_adapt.out @@ -1,4 +1,4 @@ - + 1D adaptive Heat PDE test problem: diffusion coefficient: k = 0.5 initial N = 21 @@ -9,70 +9,65 @@ 2 3.629021901461023e-08 7.258043802922046e-07 2.979456598576975e-08 21 5 7 3 7.258043802922046e-07 1.451608760584409e-05 6.255954438851742e-07 21 5 10 4 1.451608760584409e-05 2.903217521168818e-04 1.252930976498461e-05 21 5 15 - 5 2.903217521168818e-04 6.126068069781881e-04 2.459838644186664e-04 21 5 25 - 6 6.126068069781881e-04 9.290787020628410e-04 7.144322430967174e-04 21 5 32 - 7 9.290787020628410e-04 1.489561505368265e-03 1.379420423280650e-03 21 5 35 - 8 1.489561505368265e-03 2.325159614097476e-03 2.469259985973879e-03 23 5 52 - 9 2.325159614097476e-03 3.361999740397126e-03 4.371341102713489e-03 25 5 57 - 10 3.361999740397126e-03 6.201055294512660e-03 6.521135930410600e-03 25 5 54 - 11 6.201055294512660e-03 1.418650069539316e-02 9.936752057635645e-03 25 5 67 - 12 1.418650069539316e-02 2.333213441554981e-02 1.585365842114015e-02 31 5 105 - 13 2.333213441554981e-02 4.406570962017380e-02 2.310185354591536e-02 35 5 105 - 14 2.008720875364794e-02 2.008720875364794e-02 2.619890527929925e-02 39 10 210 - 15 7.612495042470456e-03 7.612495042470456e-03 2.610193126039753e-02 45 10 210 - 16 7.612495042470456e-03 1.454749389509495e-02 2.599543134042868e-02 49 5 105 - 17 1.035124260735241e-02 9.623584088096175e-03 2.668739865066598e-02 51 10 210 - 18 9.623584088096175e-03 1.808588536649627e-02 2.742440379794423e-02 51 5 105 - 19 7.662423372185243e-03 7.662423372185243e-03 2.902877933846531e-02 55 10 210 - 20 7.662423372185243e-03 7.128779196128293e-03 2.917474275029238e-02 57 5 105 - 21 7.128779196128293e-03 2.053445907774081e-02 2.954312382254983e-02 57 5 105 - 22 4.876204398547680e-03 4.876204398547680e-03 2.934121710997109e-02 59 15 315 - 23 4.876204398547680e-03 2.752514919310949e-02 2.907913475120046e-02 61 5 105 - 24 2.752514919310949e-02 4.377833231260805e-02 2.996863244315595e-02 61 5 105 - 25 5.860520609965611e-03 5.860520609965611e-03 3.011300327651581e-02 61 15 315 - 26 5.860520609965611e-03 2.122600293991792e-02 3.024518321533060e-02 61 5 105 - 27 2.122600293991792e-02 3.112837153750105e-02 3.064025813334170e-02 61 5 105 - 28 1.870342143878760e-02 1.870342143878760e-02 3.090712832903318e-02 61 10 210 - 29 1.305397332951553e-02 1.305397332951553e-02 3.105660078721369e-02 61 10 210 - 30 1.305397332951553e-02 3.913625221524024e-02 3.118619476221617e-02 61 5 105 - 31 8.923092432433761e-03 8.923092432433761e-03 3.126466431767916e-02 61 15 315 - 32 8.923092432433761e-03 5.453693279556655e-02 3.133618094903397e-02 61 5 105 - 33 5.453693279556655e-02 4.954496883018829e-02 3.168843516690587e-02 61 5 105 - 34 3.014010839536864e-02 3.014010839536864e-02 3.181338185246980e-02 61 10 210 - 35 3.014010839536864e-02 3.678555807281301e-02 3.191794712426370e-02 61 5 105 - 36 3.678555807281301e-02 3.476686530276936e-02 3.202902948330123e-02 61 5 105 - 37 3.476686530276936e-02 3.960510158166916e-02 3.210723616069101e-02 61 5 105 - 38 9.901275395417290e-03 9.901275395417290e-03 3.212754808688930e-02 61 10 210 - 39 9.901275395417290e-03 1.608611002309788e-02 3.214647303730912e-02 61 5 105 - 40 1.608611002309788e-02 1.737382001042755e-02 3.217640642946924e-02 61 5 105 - 41 5.780028939058430e-03 5.780028939058430e-03 3.218639994967080e-02 61 10 210 - 42 5.780028939058430e-03 1.978316801800984e-02 3.219614944911910e-02 61 5 105 - 43 1.978316801800984e-02 7.923920461515500e-02 3.222753929792427e-02 61 5 105 - 44 3.859752706881468e-02 3.744468647560687e-02 3.227866560109782e-02 61 10 210 - 45 9.361171618901718e-03 9.361171618901718e-03 3.229006833024283e-02 61 8 168 - 46 9.361171618901718e-03 3.048633995504502e-02 3.230111259528021e-02 61 5 105 - 47 7.621584988761255e-03 7.621584988761255e-03 3.230976204749648e-02 61 6 126 - 48 7.621584988761255e-03 2.404168804167736e-02 3.231811860211665e-02 61 5 105 - 49 6.010422010419341e-03 6.010422010419341e-03 3.232449785857627e-02 61 9 189 - 50 6.010422010419341e-03 6.453871784197467e-02 3.233069573088176e-02 61 5 88 - 51 1.613467946049367e-02 1.613467946049367e-02 3.234646577367104e-02 61 8 168 - 52 1.613467946049367e-02 7.983978031506800e-02 3.236106367911412e-02 61 5 105 - 53 1.995994507876700e-02 1.995994507876700e-02 3.237758969538931e-02 61 6 126 - 54 1.995994507876700e-02 5.327643670096720e-02 3.239264495548737e-02 61 5 105 - 55 5.327643670096720e-02 5.221342060569773e-02 3.242388384426916e-02 61 5 105 - 56 5.221342060569773e-02 6.119509641455161e-02 3.245144550640932e-02 61 5 105 - 57 6.119509641455161e-02 6.902801155300395e-02 3.247260935342249e-02 61 5 105 - 58 1.698526306192734e-02 1.698526306192734e-02 3.247810457245497e-02 61 15 315 - 59 1.698526306192734e-02 5.325036736883956e-02 3.248298741424058e-02 61 5 105 - 60 5.325036736883956e-02 6.413589159708979e-02 3.249622373085292e-02 61 5 105 - 61 1.603397289927245e-02 1.603397289927245e-02 3.249947624067350e-02 61 10 210 - 62 1.603397289927245e-02 4.028511063251124e-02 3.250248665714761e-02 61 5 105 - 63 1.007127765812781e-02 1.007127765812781e-02 3.250425876038111e-02 61 6 126 - 64 1.007127765812781e-02 2.014255531625573e-02 3.250595095364737e-02 61 5 100 - 65 2.014255531625573e-02 2.014255531625573e-02 3.250909359584335e-02 61 5 105 + 5 2.903217521168818e-04 6.126068069778898e-04 2.459838644186664e-04 21 5 25 + 6 6.126068069778898e-04 9.290787020628659e-04 7.144322430964959e-04 21 5 32 + 7 9.290787020628659e-04 1.489561505368306e-03 1.379420423280460e-03 21 5 35 + 8 1.489561505368306e-03 2.325159614097548e-03 2.469259985973726e-03 23 5 52 + 9 2.325159614097548e-03 3.361999740396916e-03 4.371341102713385e-03 25 5 57 + 10 3.361999740396916e-03 6.201055294512209e-03 6.521135930410380e-03 25 5 54 + 11 6.201055294512209e-03 1.418650069539443e-02 9.936752057635235e-03 25 5 67 + 12 1.418650069539443e-02 2.333213441555008e-02 1.585365842114031e-02 31 5 105 + 13 2.333213441555008e-02 4.406570962019823e-02 2.310185354591553e-02 35 5 105 + 14 2.008717179820959e-02 2.008717179820959e-02 2.619889986889061e-02 39 10 210 + 15 8.346522811620464e-03 7.516706023047939e-03 2.618935131509393e-02 45 10 210 + 16 7.516706023047939e-03 1.495982035074134e-02 2.605945023323194e-02 49 5 105 + 17 1.111835094428806e-02 1.043206929750673e-02 2.680310543767818e-02 51 10 210 + 18 1.043206929750673e-02 1.509912815975813e-02 2.757588323574690e-02 51 5 105 + 19 2.230665125977254e-03 2.230665125977254e-03 2.882948365478040e-02 55 15 315 + 20 2.230665125977254e-03 1.531517453472657e-02 2.897539770462856e-02 55 5 103 + 21 1.531517453472657e-02 1.649126444481822e-02 2.983825560863861e-02 55 5 105 + 22 9.196187820414967e-03 9.196187820414967e-03 2.946262498296182e-02 60 10 210 + 23 9.196187820414967e-03 3.036135590208354e-02 2.934957847587715e-02 62 5 105 + 24 3.036135590208354e-02 2.824109528142596e-02 3.019083663918624e-02 62 5 105 + 25 5.767357365903751e-03 5.767357365903751e-03 3.031100857768801e-02 62 15 315 + 26 5.767357365903751e-03 3.181338676737989e-02 3.042185345764588e-02 62 5 105 + 27 3.181338676737989e-02 4.544743555056333e-02 3.089848026181038e-02 62 5 105 + 28 1.136185888764083e-02 1.136185888764083e-02 3.102713583604160e-02 62 6 126 + 29 1.136185888764083e-02 1.101971236076085e-02 3.111573737276951e-02 62 5 105 + 30 1.101971236076085e-02 2.032915619754837e-02 3.121556348208696e-02 62 5 105 + 31 1.810888029400946e-02 1.810888029400946e-02 3.135670708815374e-02 62 10 210 + 32 1.810888029400946e-02 2.234029750896407e-02 3.148115671516088e-02 62 5 105 + 33 2.234029750896407e-02 2.889109188475510e-02 3.160878025037404e-02 62 5 105 + 34 2.889109188475510e-02 3.120042409187010e-02 3.173412977265944e-02 62 5 105 + 35 7.800106022967526e-03 7.800106022967526e-03 3.176464043664869e-02 62 8 168 + 36 7.800106022967526e-03 3.170037066227539e-02 3.179375653346459e-02 62 5 105 + 37 3.170037066227539e-02 3.787213092748833e-02 3.189887295603718e-02 62 5 105 + 38 2.837355332913126e-02 2.837355332913126e-02 3.197801883167253e-02 62 10 210 + 39 2.837355332913126e-02 3.278446668151765e-02 3.204779178298942e-02 62 5 105 + 40 3.278446668151765e-02 3.020564177204807e-02 3.211240653324073e-02 62 5 105 + 41 7.551410443012017e-03 7.551410443012017e-03 3.212626059266561e-02 62 8 168 + 42 7.551410443012017e-03 9.178102815962437e-03 3.213890913006593e-02 62 5 105 + 43 9.178102815962437e-03 1.649464282378404e-02 3.215471668066559e-02 62 5 105 + 44 1.649464282378404e-02 2.602185028814931e-02 3.218133771973418e-02 62 5 105 + 45 1.713665707473882e-02 1.713665707473882e-02 3.220690702186930e-02 62 10 210 + 46 1.713665707473882e-02 3.530352717263601e-02 3.223040887486339e-02 62 5 105 + 47 8.825881793159003e-03 8.825881793159003e-03 3.224177338005089e-02 62 8 168 + 48 8.825881793159003e-03 2.586353802027211e-02 3.225265894426493e-02 62 5 105 + 49 2.586353802027211e-02 3.291894174702289e-02 3.228169996973265e-02 62 5 105 + 50 3.291894174702289e-02 4.048834834381512e-02 3.231625687442660e-02 62 5 105 + 51 4.048834834381512e-02 6.688543998612889e-02 3.235083603511235e-02 62 5 105 + 52 6.688543998612889e-02 6.955316324211452e-02 3.239371035449163e-02 62 5 105 + 53 6.955316324211452e-02 6.790707004153698e-02 3.243064328586971e-02 62 5 105 + 54 1.697676751038425e-02 1.697676751038425e-02 3.243617411633083e-02 62 9 189 + 55 1.697676751038425e-02 3.162563349768197e-02 3.244133298132829e-02 62 5 105 + 56 3.162563349768197e-02 4.821561406413451e-02 3.245001080654254e-02 62 5 105 + 57 4.821561406413451e-02 7.764755023495810e-02 3.246092238823795e-02 62 5 105 + 58 1.941188755873953e-02 1.941188755873953e-02 3.246445882359153e-02 62 6 126 + 59 1.941188755873953e-02 3.882377511747900e-02 3.246778727298686e-02 62 5 105 + 60 3.882377511747900e-02 3.882377511747900e-02 3.247351310624037e-02 62 5 105 ---------------------------------------------------------------------------------------- Final solver statistics: - Total number of time steps = 65 - Total nonlinear iterations = 433 - Total linear iterations = 8275 + Total number of time steps = 60 + Total nonlinear iterations = 370 + Total linear iterations = 6972 diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 9a5d35a67c..0372906b52 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -936,9 +936,9 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Compute number of stages based on current step size and dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ - sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype ss = - SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zR) - ONE) / TWO); + sunrealtype zRabs = SUNRabs(ark_mem->h * step_mem->lambdaR); + sunrealtype ss = + SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zRabs) - ONE) / TWO); ss = SUNMAX(ss, SUN_RCONST(2.0)); diff --git a/test/answers b/test/answers index 124abc1828..318a7c1ec2 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 124abc18285097fc64f0709c1f0a083f6d015ab7 +Subproject commit 318a7c1ec25231993236c5079762d04a1737eb7b From 585e714af2f801a50632cdfcc61a27450b9192f6 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 21:19:28 -0600 Subject: [PATCH 10/76] format check --- src/arkode/arkode_lsrkstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 0372906b52..1cdb3a19e2 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -937,7 +937,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Compute number of stages based on current step size and dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ sunrealtype zRabs = SUNRabs(ark_mem->h * step_mem->lambdaR); - sunrealtype ss = + sunrealtype ss = SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zRabs) - ONE) / TWO); ss = SUNMAX(ss, SUN_RCONST(2.0)); From 88998340ab5287b966a2449e0884f7d7f63a1969 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 22:18:36 -0600 Subject: [PATCH 11/76] q_prev destroy --- src/sundomeigest/power/sundomeigest_power.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 056148494d..e703a4797f 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -554,6 +554,11 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) N_VDestroy(PI_CONTENT(DEE)->q); PI_CONTENT(DEE)->q = NULL; } + if (PI_CONTENT(DEE)->q_prev) + { + N_VDestroy(PI_CONTENT(DEE)->q_prev); + PI_CONTENT(DEE)->q_prev = NULL; + } if (PI_CONTENT(DEE)->V) { N_VDestroy(PI_CONTENT(DEE)->V); From ccb80c8d40fff25214162de8571fa516c51c448d Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 12 Feb 2026 23:41:43 -0600 Subject: [PATCH 12/76] updated answers with the correct CI test results --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 318a7c1ec2..7999b4bf02 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 318a7c1ec25231993236c5079762d04a1737eb7b +Subproject commit 7999b4bf0222b22dc75289123b7f14c36b27bbd9 From da13267bdf75a1ab3f9ded380a5ff0bc7aa67575 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 3 Mar 2026 00:37:17 -0600 Subject: [PATCH 13/76] revision --- .../source/Usage/LSRKStep/User_callable.rst | 37 ++++++ doc/shared/figs/arkode/STS2_region_s10.PNG | Bin 0 -> 199934 bytes doc/shared/sundomeigest/SUNDomEigEst_API.rst | 20 +++ .../SUNDomEigEst_Introduction.rst | 51 +++++++- .../sundomeigest/SUNDomEigEst_Power.rst | 23 ++++ .../C_serial/ark_analytic_lsrk_domeigest.c | 4 +- include/arkode/arkode_lsrkstep.h | 4 +- include/sundomeigest/sundomeigest_arnoldi.h | 4 +- include/sundomeigest/sundomeigest_power.h | 2 +- src/arkode/arkode_lsrkstep.c | 115 ++++++------------ src/arkode/arkode_lsrkstep_io.c | 21 +--- .../arnoldi/sundomeigest_arnoldi.c | 5 +- src/sundomeigest/power/sundomeigest_power.c | 14 +-- 13 files changed, 181 insertions(+), 119 deletions(-) create mode 100644 doc/shared/figs/arkode/STS2_region_s10.PNG diff --git a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst index 1e37c08b1d..48332204cc 100644 --- a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst @@ -315,6 +315,43 @@ Allowable Method Families This routine will be called by :c:func:`ARKodeSetOptions` when using the key "arkid.dom_eig_safety_factor". +.. c:function:: int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, sunbooleantype analytic_stab_region); + + Specifies whether to use the analytic stability region for determining the number of stages in STS methods. + + **Arguments:** + * *arkode_mem* -- pointer to the LSRKStep memory block. + * *analytic_stab_region* -- Use the analytic stability region if ``SUNTRUE``; use the inscribed ellipse stability region if ``SUNFALSE``. + + **Return value:** + * *ARK_SUCCESS* if successful + * *ARK_MEM_NULL* if ``arkode_mem`` was ``NULL``. + + .. note:: + + If :c:func:`LSRKStepSetUseAnalyticStabRegion` is not called, then the default + ``analytic_stab_region`` is set to ``SUNFALSE``. This routine will be called by + :c:func:`ARKodeSetOptions` when using the key "arkid.use_analytic_stab_region". + + :c:func:`LSRKStepSetUseAnalyticStabRegion` sets whether to use the ellipse or the exact stability region for + stability checks. The stability region check for RKC and RKL methods is performed with the dominant + eigenvalue and the current step size to ensure stability. While this is sufficient for a stability + region of disk, the stability region of RKC and RKL methods is not a disk but rather a more complicated + region that can be approximated by an inscribed ellipse. By default, the ellipse is used for stability + checks, which is a conservative approximation of the stability region that possibly reduces the step + sizes to ensure stability. Setting use_analytic_stab_region to SUNTRUE allows the use of the exact + stability region, which can potentially allow for larger step sizes but possibly cause stability failures + for the second dominant eigenvalue since it might be outside of the stability region even if the dominant + eigenvalue is inside the stability region. Using ellipse for stability checks can be beneficial when two + dominant eigenvalues are close to the stability boundary. Nevertheless, unless the full spectrum is used + for stability checks, there is always a risk of stability failures one way or another. Thus, users + have the option to choose their preference for a more conservative or more aggressive + approach to stability. This input is only used for RKC and RKL methods. + + .. figure:: ../../../../../arkode/guide/source/figs/arkode/STS2_region_s10.png + :alt: Stability region of RKL method with 10 stages + :align: center + :width: 50% .. c:function:: int LSRKStepSetNumDomEigEstInitPreprocessIters(void* arkode_mem, int num_iters); diff --git a/doc/shared/figs/arkode/STS2_region_s10.PNG b/doc/shared/figs/arkode/STS2_region_s10.PNG new file mode 100644 index 0000000000000000000000000000000000000000..47115cacbf222005547c6379786145998be45ce2 GIT binary patch literal 199934 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 literal 0 HcmV?d00001 diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index fb9cfb030f..feba340834 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -259,6 +259,26 @@ instead of supplying a dummy routine. .. note:: + The relative tolerance is used as a stopping criterion for the Power Iteration method. Specifically, + it defines the acceptable relative change between successive dominant eigenvalue estimates. + + When used in combination with Arnoldi Iteration, this routine sets the stopping criterion for + the preprocessing Power Iteration phase. In this workflow, Power Iteration is first applied to + perform an initial convergence check for the dominant eigenvalue estimate. The convergence + criterion is based on the change in magnitude between successive estimates and is defined as + + .. math:: + + \left|\,|\lambda_{k}| - |\lambda_{k-1}|\,\right| + \le \texttt{rel_tol} \cdot |\lambda_{k}|. + + The implementation performs this inexpensive preprocessing check using only the magnitude of + the eigenvalue estimates. Arnoldi Iteration is executed only after this convergence criterion is + satisfied. This approach ensures that Arnoldi is performed only once, rather than repeatedly + running Arnoldi and checking convergence based on its complex-valued results. By relying on + the cheaper magnitude-based preprocessing step, the routine avoids multiple Arnoldi runs that would + yield only marginal improvements in accuracy while incurring significantly higher computational cost. + This routine will be called by :c:func:`SUNDomEigEstimator_SetOptions` when using the key "Did.rel_tol". diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Introduction.rst b/doc/shared/sundomeigest/SUNDomEigEst_Introduction.rst index 8db9db05dc..b5f9fd31a3 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Introduction.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Introduction.rst @@ -38,15 +38,54 @@ Moreover, advanced users can provide a customized :c:type:`SUNDomEigEstimator` implementation to any SUNDIALS package, particularly in cases where they provide their own :c:type:`N_Vector`. -While Krylov-based estimators preset the number of Krylov subspace -dimensions, resulting in a tolerance-free estimation, SUNDIALS requires -that iterative estimators stop when the residual meets a prescribed -tolerance, :math:`\tau`, +The default Power iteration implementation estimates complex-valued dominant +eigenvalues. After the iteration phase, a postprocessing step is performed +using the two most recent iterate vectors (approximations of the dominant +eigenvector). These vectors are used to construct a 2×2 projection of the +original matrix. + +If the two iterates are (numerically) linearly dependent, this indicates +convergence to a one-dimensional invariant subspace, consistent with a +real-valued dominant eigenvalue. In this case, the dominant eigenvalue +estimate is taken as the Rayleigh quotient of the final iterate. + +If the iterates are not linearly dependent, they span a two-dimensional +subspace. A 2×2 projection of the original matrix onto this subspace is +constructed, and the eigenvalues of this projected matrix are used as the +dominant eigenvalue estimates. This allows the method to capture complex +conjugate dominant eigenvalue pairs. + +Convergence is determined using a magnitude-based relative tolerance +criterion. Given successive eigenvalue estimates :math:`\lambda_k` and +:math:`\lambda_{k-1}`, convergence is achieved when .. math:: - :name: pi_rel_tol + :name: pi_rel_tol + + \frac{\left||\lambda_k| - |\lambda_{k-1}|\right|}{\left|\lambda_k \right|} < \tau. + +where :math:`\tau` is a prescribed tolerance. + +An option is also provided to estimate only a real-valued dominant +eigenvalue. In this mode, the 2×2 projection step is skipped and the +Rayleigh quotient of the final iterate is returned directly. + +Krylov-based estimators use a fixed number of Krylov subspace dimensions in +order to guarantee a bounded memory footprint, which is essential for +large-scale problems. Unlike the Power iteration, these implementations do +not perform tolerance-based convergence checks at every Arnoldi step since +repeating an Arnoldi iteration due to failed convergence would be +computationally expensive. + +Instead, the magnitude-based convergence criterion defined in +:ref:`relative tolerance ` is used as a preliminary screening +mechanism before invoking the Krylov-based estimator. While this approach +is slightly less robust than explicitly monitoring both the real and +imaginary components of the eigenvalue residual during Arnoldi iteration, +it significantly reduces computational cost. This trade-off is particularly +advantageous for large-scale problems, where each Arnoldi cycle may be +expensive. - \frac{\left|\lambda_k - \lambda_{k-1}\right|}{\left|\lambda_k \right|} < \tau. For users interested in providing their own :c:func:`SUNDomEigEstimator`, the following section presents the :c:type:`SUNDomEigEstimator` class and its implementation diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index af79b90622..56d36552fb 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -109,6 +109,27 @@ routines: :c:func:`SUNDomEigEstimator_SetInitialGuess`. +.. c:function:: SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); + + This routine sets the ``real`` flag in the Power iteration dominant eigenvalue estimator object. + + :param DEE: the dominant eigenvalue estimator object. + :param real: the value to set the ``real`` flag to. + + :returns: If successful, ``SUN_SUCCESS`` otherwise an appropriate error code. + + .. note:: + + If ``real`` is ``SUNTRUE``, then the convergence criterion is based on the relative change + in the magnitude of successive eigenvalue estimates. If ``real`` is ``SUNFALSE``, then a + postprocessing step is performed to compute the complex-valued dominant eigenvalue estimate, + and the convergence criterion is based on the relative change in the magnitude of successive + eigenvalue estimates. :c:func:`SUNDomEigEstimator_SetRelTol` can be used to set + the relative tolerance for this convergence criterion. + + The default value is ``SUNFALSE``. + + .. _SUNDomEigEst.Power.Description: SUNDomEigEstimator_Power Description @@ -195,6 +216,8 @@ eigenvalue estimator operations listed in :numref:`SUNDomEigEst.API`: * ``SUNDomEigEstimator_SetRelTol_Power`` +* ``SUNDomEigEstimator_SetDEEisReal_Power`` + * ``SUNDomEigEstimator_Initialize_Power`` * ``SUNDomEigEstimator_Estimate_Power`` diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c index 2d1d3ba15a..6a288e7e5a 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c @@ -238,8 +238,8 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } /* Set real type dominant eigenvalue */ - flag = SUNDomEigEstimator_SetReal_Power(DEE); - if (check_flag(&flag, "SUNDomEigEstimator_SetReal_Power", 1)) { return 1; } + flag = SUNDomEigEstimator_SetDEEisReal_Power(DEE, SUNTRUE); + if (check_flag(&flag, "SUNDomEigEstimator_SetDEEisReal_Power", 1)) { return 1; } /* Open output stream for results, output comment line */ UFID = fopen("solution.txt", "w"); diff --git a/include/arkode/arkode_lsrkstep.h b/include/arkode/arkode_lsrkstep.h index 078bcc2468..3961403fa8 100644 --- a/include/arkode/arkode_lsrkstep.h +++ b/include/arkode/arkode_lsrkstep.h @@ -93,8 +93,8 @@ SUNDIALS_EXPORT int LSRKStepSetMaxNumStages(void* arkode_mem, SUNDIALS_EXPORT int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety); -SUNDIALS_EXPORT int LSRKStepSetUseEllipseForStability(void* arkode_mem, - sunbooleantype use_ellipse); +SUNDIALS_EXPORT int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, + sunbooleantype analytic_stab_region); SUNDIALS_EXPORT int LSRKStepSetNumDomEigEstInitPreprocessIters(void* arkode_mem, int num_iters); diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 5a273242f6..328a1d7a1b 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -82,8 +82,8 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator D int num_iters); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, - sunrealtype tol); +SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, + sunrealtype tol); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess_Arnoldi(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 803884ba71..b6f6626cc0 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -88,7 +88,7 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetReal_Power(SUNDomEigEstimator DEE); +SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE); diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 1cdb3a19e2..5058becfb0 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -608,19 +608,11 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - /* For the linear stability with the test equation, y' = lambda*y, - the stability function of RKC methods is given by the Chebyshev - polynomial of the first kind, T_s(z), where s is the number of - stages and z is related to the eigenvalue and step size. For the - method to be stable, the stability norm |T_s(z)| must be less - than or equal to 1. To check stability norm with the requested - number of stages and z, we evaluate the exact stability function - or an inscribed ellipse approximation of the stability region at - the point z and check if its absolute value is greater than 1. - If the stability norm is greater than one, for adaptive stepping, - we reduce step size and return ARK_RETRY_STEP. For fixed step size, - we increase number of stages until stability norm is acceptable or - stage_max_limit is reached. */ + /* To check stability, we evaluate the analytic stability function or an inscribed + ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. + For fixed step size, we increase number of stages until stability norm is acceptable + or stage_max_limit is reached. */ retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -976,19 +968,11 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - /* For the linear stability with the test equation, y' = lambda*y, - the stability function of RKL methods is given by the Legendre - polynomial of the first kind, P_s(z), where s is the number of - stages and z is related to the eigenvalue and step size. For the - method to be stable, the stability norm |P_s(z)| must be less - than or equal to 1. To check stability norm with the requested - number of stages and z, we evaluate the exact stability function - or an inscribed ellipse approximation of the stability region at - the point z and check if its absolute value is greater than 1. - If the stability norm is greater than one, for adaptive stepping, - we reduce step size and return ARK_RETRY_STEP. For fixed step size, - we increase number of stages until stability norm is acceptable or - stage_max_limit is reached. */ + /* To check stability, we evaluate the analytic stability function or an inscribed + ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. + For fixed step size, we increase number of stages until stability norm is acceptable + or stage_max_limit is reached. */ retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -2493,16 +2477,10 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) /*--------------------------------------------------------------- lsrkStep_RKC_CheckStabilityNorm: - This routine computes the stability norm for RKC methods. This computation is based on the stability - region of the RKC method, which is determined by the stability function of the method. The stability - function of the RKC method is a rational function of the Chebyshev polynomial of degree s, where s is - the number of stages. The stability region is then determined by the values of z = h*lambda for which - the stability function has magnitude less than or equal to 1. In particular, if use_ellipse is SUNTRUE, - we use a heuristic that approximates the stability region by an ellipse with corners at (0,0), - (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), where re_stab_min and im_stab_min are determined - by the damping parameter and the number of stages as described in the comments. If use_ellipse is SUNFALSE, - we compute the stability norm directly from the stability function using the Chebyshev polynomial. - The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. + This routine computes the stability norm for RKC methods. + If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. + If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using + the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2515,19 +2493,14 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me if (step_mem->use_ellipse) { - /* The stability region of the RKC method with damping is contained in the ellipse - with corners at (0,0), (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), - where re_stab_min and im_stab_min are the real and imaginary parts of the leftmost point - of the inscribed ellipse. The value of re_stab_min is determined by the damping parameter - and the number of stages by reverting the formula for finding the required number of - stages for a given spectral radius times step size. im_stab_min is then determined by - herustically by dividing re_stab_min by the aspect ratio of the ellipse, which is - approximateted as 3.65*ss, where ss is the number of stages. In particular, if ss=2, - the aspect ratio is estimated to be 0.6*ss. This heuristic is based on the observation - that imaginary extend of the stability region grows linearly with the number of stages. - The factors of 3.65 and 0.6 are determined empirically by plotting the stability region for - different number of stages and the default damping parameter. It is subject to change if the - default damping parameter is changed. */ + /* The stability region of the damped RKC method is approximated by an ellipse with + vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,±im_stab_min). These vertices + depend on the damping parameter. Also, im_stab_min is estimated heuristically from + the ellipse aspect ratio, taken as approximately 3.65s, where s is the number of stages + (for s=2, the ratio is approximated as 0.6s). This heuristic reflects the observed + near-linear growth of the imaginary extent with the number of stages. The numerical + factors (3.65 and 0.6) were obtained empirically from stability-region plots using + the default damping parameter and may change if the damping is modified. */ re_stab_min = TWO / THREE * (ONE - SUNSQR(ss)) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); im_stab_min = -re_stab_min / @@ -2575,16 +2548,10 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me /*--------------------------------------------------------------- lsrkStep_RKL_CheckStabilityNorm: - This routine computes the stability norm for RKL methods. This computation is based on the stability - region of the RKL method, which is determined by the stability function of the method. The stability - function of the RKL method is a rational function of the Legendre polynomial of degree s, where s is - the number of stages. The stability region is then determined by the values of z = h*lambda for which - the stability function has magnitude less than or equal to 1. In particular, if use_ellipse is SUNTRUE, - we use a heuristic that approximates the stability region by an ellipse with corners at (0,0), - (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), where re_stab_min and im_stab_min are determined - by the number of stages as described in the comments. If use_ellipse is SUNFALSE, - we compute the stability norm directly from the stability function using the Legendre polynomial. - The stability norm is then computed as the magnitude of the stability function evaluated at z = h*lambda. + This routine computes the stability norm for RKL methods. + If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. + If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using + the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2597,18 +2564,8 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me if (step_mem->use_ellipse) { - /* The stability region of the RKL method is contained in the ellipse - with corners at (0,0), (re_stab_min, 0) and (re_stab_min/2, +/- im_stab_min), - where re_stab_min and im_stab_min are the real and imaginary parts of the leftmost point - of the inscribed ellipse. The value of re_stab_min is determined by the number of stages - by reverting the formula for finding the required number of stages for a given spectral - radius times step size. im_stab_min is then determined by herustically by dividing - re_stab_min by the aspect ratio of the ellipse, which is approximated as - imag_extend_factor*ss, where ss is the number of stages and the factor imag_extend_factor - is determined empirically by plotting the stability region for different number of stages. - This factor is as follows: */ - - /*s = 2 -> 0.6 + /* The inscibed ellipse parameters are estimated heuristically based on s values as follows: + s = 2 -> 0.6 s = 3 -> 1.5 s = 4 -> 1.33 s = 5 -> 1.33 @@ -2616,13 +2573,13 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me s >= 20 and odd -> 1.2 s >= 20 and even -> 1.06 */ const sunrealtype imag_extend_factor[7] = { - 0.6, /* s = 2 */ - 1.5, /* s = 3 */ - 1.33, /* s = 4 */ - 1.33, /* s = 5 */ - 1.27, /* s = 6 to 20 */ - 1.2, /* s >= 20 and odd */ - 1.06 /* s >= 20 and even */ + SUN_RCONST(0.6), /* s = 2 */ + SUN_RCONST(1.5), /* s = 3 */ + SUN_RCONST(1.33), /* s = 4 */ + SUN_RCONST(1.33), /* s = 5 */ + SUN_RCONST(1.27), /* s = 6 to 20 */ + SUN_RCONST(1.2), /* s >= 20 and odd */ + SUN_RCONST(1.06) /* s >= 20 and even */ }; re_stab_min = -((TWO * ss + ONE) * (TWO * ss + ONE) - SUN_RCONST(9.0)) / SUN_RCONST(8.0); @@ -2641,7 +2598,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me im_stab_min = -re_stab_min / (imag_extend_factor[6 - (int)ss % 2] * ss); } } - // TODO:get opinon on whether we want to use the heuristic with different factors for different number of stages or + // TODO: get opinon on whether we want to use the heuristic with different factors for different number of stages or // to use a single global factor for all number of stages. The heuristic with different factors for different number // of stages is more accurate, especially for small number of stages, but it is also more complicated. // Instead we can use a single global factor of 1.5 for all number of stages as follows: diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index bfa15751b4..3b5b526b7b 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -317,23 +317,10 @@ int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety) } /*--------------------------------------------------------------- - LSRKStepSetUseEllipseForStability sets whether to use the ellipse or the exact stability region for - stability checks. The stability region check for RKC and RKL methods is performed with the dominant - eigenvalue and the current step size to ensure stability. While this is sufficient for a stability - region of disk, the stability region of RKC and RKL methods is not a disk but rather a more complicated - region that can be approximated by an inscribed ellipse. By default, the ellipse is used for stability - checks, which is a conservative approximation of the stability region that possibly reduces the step - sizes to ensure stability. Setting use_ellipse to SUNFALSE allows the use of the exact stability region, - which can potentially allow for larger step sizes but possibly cause stability failures for the second - dominant eigenvalue since it might be outside of the stability region even if the dominant eigenvalue - is inside the stability region. Using ellipse for stability checks can be beneficial when two dominant - eigenvalues are close to the stability boundary. Nevertheless, unless the full spectrum is used for - stability checks, there is always a risk of stability failures one way or another. Thus, the user should - have the option to choose between the ellipse or the exact stability region for stability checks based - on their problem characteristics and their preference for a more conservative or more aggressive approach - to stability. This input is only used for RKC and RKL methods. + LSRKStepSetUseAnalyticStabRegion sets whether to use the ellipse or the exact + stability region for stability checks. ---------------------------------------------------------------*/ -int LSRKStepSetUseEllipseForStability(void* arkode_mem, sunbooleantype use_ellipse) +int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, sunbooleantype use_analytic_stab_region) { ARKodeMem ark_mem; ARKodeLSRKStepMem step_mem; @@ -346,7 +333,7 @@ int LSRKStepSetUseEllipseForStability(void* arkode_mem, sunbooleantype use_ellip step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; - step_mem->use_ellipse = use_ellipse; + step_mem->use_ellipse = !use_analytic_stab_region; return ARK_SUCCESS; } diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index ce4e75cac9..f200b84e4c 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -106,6 +106,7 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; + DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Arnoldi; DEE->ops->setinitialguess = SUNDomEigEstimator_SetInitialGuess_Arnoldi; DEE->ops->initialize = SUNDomEigEstimator_Initialize_Arnoldi; DEE->ops->estimate = SUNDomEigEstimator_Estimate_Arnoldi; @@ -292,8 +293,8 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator D return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, - sunrealtype tol) +SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, + sunrealtype tol) { SUNFunctionBegin(DEE->sunctx); diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index e703a4797f..d6bc84e4bd 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -168,20 +168,20 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetReal_Power(SUNDomEigEstimator DEE) +SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) { SUNFunctionBegin(DEE->sunctx); SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - /* set the complex flag to false */ - PI_CONTENT(DEE)->complex = SUNFALSE; + /* set the complex flag to the opposite of the real flag */ + PI_CONTENT(DEE)->complex = !real; /* q_prev is allocated in SUNDomEigEstimator_Initialize_Power, which is expected to be called after this routine. If the user calls this routine after initialization, we need to free q_prev here. */ - if (PI_CONTENT(DEE)->q_prev) + if (!(PI_CONTENT(DEE)->complex) && PI_CONTENT(DEE)->q_prev) { N_VDestroy(PI_CONTENT(DEE)->q_prev); PI_CONTENT(DEE)->q_prev = NULL; @@ -314,7 +314,7 @@ SUNErrCode SUNDomEigEstimator_Estimate_Power(SUNDomEigEstimator DEE, SUNAssert(PI_CONTENT(DEE)->V, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->q, SUN_ERR_ARG_CORRUPT); SUNAssert((PI_CONTENT(DEE)->max_iters >= 0), SUN_ERR_ARG_CORRUPT); - if (PI_CONTENT(DEE)->complex) + if (PI_CONTENT(DEE)->complex && (PI_CONTENT(DEE)->q_prev == NULL)) { /* allocate q_prev vector */ PI_CONTENT(DEE)->q_prev = N_VClone(PI_CONTENT(DEE)->q); @@ -474,14 +474,12 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( int retval; sunrealtype cos_qs, det_G_inv, h11, h12, h21, h22, p11, p12, p21, p22; - sunrealtype proj_cond_inv = SUN_RCONST(1e-2); + sunrealtype proj_cond_inv = SUN_RCONST(1e-10); cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); if (SUNRabs(SUNRabs(cos_qs) - ONE) < proj_cond_inv) { - printf("Warning: Projection matrix is ill-conditioned. Returning " - "dominant eigenvalue as real part only.\n"); /* Dominant eigenvalue is real */ *lambdaR_out = lambdaR; *lambdaI_out = ZERO; From 77a99ec33c1d72efc06447449552727a7b3fea03 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 5 Mar 2026 01:07:25 -0600 Subject: [PATCH 14/76] docs and stand alone module -- need a bug fix --- .../sundomeigest/SUNDomEigEst_Power.rst | 4 +- examples/arkode/C_serial/CMakeLists.txt | 2 + .../C_serial/ark_brusselator_lsrk_domeigest.c | 384 ++++++++++++++++ .../ark_brusselator_lsrk_domeigest.out | 41 ++ .../ark_brusselator_lsrk_externaldomeigest.c | 434 ++++++++++++++++++ ...ark_brusselator_lsrk_externaldomeigest.out | 39 ++ include/sundials/sundials_domeigestimator.h | 11 + include/sundomeigest/sundomeigest_arnoldi.h | 14 +- include/sundomeigest/sundomeigest_power.h | 14 +- src/sundials/sundials_domeigestimator.c | 23 + .../arnoldi/sundomeigest_arnoldi.c | 123 +++++ src/sundomeigest/power/sundomeigest_power.c | 124 ++++- test/answers | 2 +- 13 files changed, 1210 insertions(+), 5 deletions(-) create mode 100644 examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c create mode 100644 examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.out create mode 100644 examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c create mode 100644 examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index 56d36552fb..5ef3df5697 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -111,7 +111,9 @@ routines: .. c:function:: SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); - This routine sets the ``real`` flag in the Power iteration dominant eigenvalue estimator object. + This routine informs the Power iteration that the dominant eigenvalue is + real-valued, so that the complex projection described in Section + :numref:`SUNDomEigEst.Introduction` can be omitted. :param DEE: the dominant eigenvalue estimator object. :param real: the value to set the ``real`` flag to. diff --git a/examples/arkode/C_serial/CMakeLists.txt b/examples/arkode/C_serial/CMakeLists.txt index 3416b105a0..95533b7932 100644 --- a/examples/arkode/C_serial/CMakeLists.txt +++ b/examples/arkode/C_serial/CMakeLists.txt @@ -42,6 +42,8 @@ set(ARKODE_examples "ark_analytic_ssprk.c\;\;develop" "ark_brusselator_1D_mri.c\;\;develop" "ark_brusselator_fp.c\;\;exclude-single" + "ark_brusselator_lsrk_domeigest.c\;\;develop" + "ark_brusselator_lsrk_externaldomeigest.c\;\;develop" "ark_brusselator_mri.c\;\;develop" "ark_brusselator.c\;\;develop" "ark_brusselator1D_imexmri.c\;0 0.001\;exclude-single" diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c new file mode 100644 index 0000000000..2a33231e03 --- /dev/null +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c @@ -0,0 +1,384 @@ +/*----------------------------------------------------------------- + * Programmer(s): Mustafa Aggul @ SMU + * Based on + * ark_analytic_lsrk_domeigest.c by Mustafa Aggul @ SMU and + * ark_brusselator.c by Daniel R. Reynolds @ UMBC + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025-2026, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * Example problem: + * + * The following test simulates a brusselator problem from chemical + * kinetics. This is an ODE system with 3 components, Y = [u,v,w], + * satisfying the equations, + * du/dt = a - (w+1)*u + v*u^2 + * dv/dt = w*u - v*u^2 + * dw/dt = (b-w)/ep - w*u + * for t in the interval [0.0, 10.0], with initial conditions + * Y0 = [u0,v0,w0]. + * + * We have 3 different testing scenarios: + * + * Test 1: u0=3.9, v0=1.1, w0=2.8, a=1.2, b=2.5, ep=1.0e-5 + * Here, all three components exhibit a rapid transient change + * during the first 0.2 time units, followed by a slow and + * smooth evolution. + * + * Test 2: u0=1.2, v0=3.1, w0=3, a=1, b=3.5, ep=5.0e-6 + * Here, w experiences a fast initial transient, jumping 0.5 + * within a few steps. All values proceed smoothly until + * around t=6.5, when both u and v undergo a sharp transition, + * with u increaseing from around 0.5 to 5 and v decreasing + * from around 6 to 1 in less than 0.5 time units. After this + * transition, both u and v continue to evolve somewhat + * rapidly for another 1.4 time units, and finish off smoothly. + * + * Test 3: u0=3, v0=3, w0=3.5, a=0.5, b=3, ep=5.0e-4 + * Here, all components undergo very rapid initial transients + * during the first 0.3 time units, and all then proceed very + * smoothly for the remainder of the simulation. + * + * This file is hard-coded to use test 2. + * + * This program solves the problem with the LSRK method using internal + * SUNDIALS dominant eigenvalue estimation (DEE) module. + * + * 100 outputs are printed at equal intervals, and run statistics + * are printed at the end. + *-----------------------------------------------------------------*/ + +/* Header files */ +#include /* prototypes for LSRKStep fcts., consts */ +#include +#include /* serial N_Vector types, fcts., macros */ +#include +#include /* def. of SUNRsqrt, etc. */ +#include /* definition of type sunrealtype */ +#include /* access to Power Iteration module */ + +#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 Called by the Solver */ +static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); + +/* Private function to check function return values */ +static int check_flag(void* flagvalue, const char* funcname, int opt); + +/* Main Program */ +int main(int argc, char* argv[]) +{ + /* general problem parameters */ + sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ + sunrealtype Tf = SUN_RCONST(10.0); /* final time */ + sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ + sunindextype NEQ = 3; /* number of dependent vars. */ + int Nt = (int)ceil(Tf / dTout); /* number of output times */ + int test = 2; /* test problem to run */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-10); + sunrealtype a, b, ep, u0, v0, w0; + + /* general problem variables */ + int flag; /* reusable error-checking flag */ + N_Vector y = NULL; /* empty vector for storing solution */ + void* arkode_mem = NULL; /* empty ARKode memory structure */ + sunrealtype rdata[3]; + FILE* UFID; + sunrealtype t, tout; + int iout; + + /* Dominant Eigenvalue Estimator (DEE) pointers and variables */ + SUNDomEigEstimator DEE = NULL; /* domeig estimator object */ + sunindextype max_iters = 100; /* max number of power iterations (PI)*/ + sunindextype numwarmup = 10; /* number of preprocessing warmups */ + sunrealtype rel_tol = SUN_RCONST(5.0e-3); /* relative error for PI*/ + N_Vector q = NULL; /* random initial eigenvector */ + + /* Create the SUNDIALS context object for this simulation */ + SUNContext ctx; + flag = SUNContext_Create(SUN_COMM_NULL, &ctx); + if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } + + /* set up the test problem according to the desired test */ + if (test == 1) + { + u0 = SUN_RCONST(3.9); + v0 = SUN_RCONST(1.1); + w0 = SUN_RCONST(2.8); + a = SUN_RCONST(1.2); + b = SUN_RCONST(2.5); + ep = SUN_RCONST(1.0e-5); + } + else if (test == 3) + { + u0 = SUN_RCONST(3.0); + v0 = SUN_RCONST(3.0); + w0 = SUN_RCONST(3.5); + a = SUN_RCONST(0.5); + b = SUN_RCONST(3.0); + ep = SUN_RCONST(5.0e-4); + } + else + { + u0 = SUN_RCONST(1.2); + v0 = SUN_RCONST(3.1); + w0 = SUN_RCONST(3.0); + a = SUN_RCONST(1.0); + b = SUN_RCONST(3.5); + ep = SUN_RCONST(5.0e-6); + } + + /* Initial problem output */ + printf("\nBrusselator ODE test problem:\n"); + printf(" initial conditions: u0 = %" GSYM ", v0 = %" GSYM + ", w0 = %" GSYM "\n", + u0, v0, w0); + printf(" problem parameters: a = %" GSYM ", b = %" GSYM ", ep = %" GSYM + "\n", + a, b, ep); + printf(" reltol = %.1" ESYM ", abstol = %.1" ESYM "\n\n", reltol, abstol); + + /* Initialize data structures */ + rdata[0] = a; /* set user data */ + rdata[1] = b; + rdata[2] = ep; + y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ + if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } + NV_Ith_S(y, 0) = u0; /* Set initial conditions */ + NV_Ith_S(y, 1) = v0; + NV_Ith_S(y, 2) = w0; + + /* Call LSRKStepCreateSTS to initialize the ARK timestepper module and + specify the right-hand side function in y'=f(t,y), the initial time + T0, and the initial dependent variable vector y. */ + arkode_mem = LSRKStepCreateSTS(f, T0, y, ctx); + if (check_flag((void*)arkode_mem, "LSRKStepCreateSTS", 0)) { return 1; } + + /* Set routines */ + flag = ARKodeSetUserData(arkode_mem, + (void*)rdata); /* Pass rdata to user functions */ + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + flag = ARKodeSStolerances(arkode_mem, reltol, abstol); /* Specify tolerances */ + if (check_flag(&flag, "ARKodeSStolerances", 1)) { return 1; } + + flag = ARKodeSetInterpolantType(arkode_mem, + ARK_INTERP_LAGRANGE); /* Specify stiff interpolant */ + if (check_flag(&flag, "ARKodeSetInterpolantType", 1)) { return 1; } + + /* Set the initial random eigenvector for the DEE */ + q = N_VClone(y); + if (check_flag(q, "N_VClone", 0)) { return 1; } + + sunrealtype* qd = N_VGetArrayPointer(q); + for (int i = 0; i < NEQ; i++) + { + qd[i] = (sunrealtype)rand() / (sunrealtype)RAND_MAX; + } + + /* Create power iteration dominant eigenvalue estimator (DEE) */ + DEE = SUNDomEigEstimator_Power(q, max_iters, rel_tol, ctx); + if (check_flag(DEE, "SUNDomEigEstimator_Power", 0)) { return 1; } + + /* After the DEE creation, random q vector is no longer needed. + It is used only to initialize the DEE */ + N_VDestroy(q); + + /* Attach the DEE to the LSRKStep module. + There is no need to set Atimes or initialize since these are all + performed after attaching the DEE by LSRKStep. */ + flag = LSRKStepSetDomEigEstimator(arkode_mem, DEE); + if (check_flag(&flag, "LSRKStepSetDomEigEstimator", 1)) { return 1; } + + /* Set the number of preprocessing warmups. The warmup + is used to compute a "better" initial eigenvector and so an initial + eigenvalue. The warmup is performed only once by the LSRKStep module + internally unless LSRKStepSetNumDomEigEstPreprocessIters is called to set + a new number of succeeding warmups that would be executed before + every dominant eigenvalue estimate calls */ + flag = LSRKStepSetNumDomEigEstInitPreprocessIters(arkode_mem, numwarmup); + if (check_flag(&flag, "LSRKStepSetNumDomEigEstInitPreprocessIters", 1)) + { + return 1; + } + + /* Specify after how many successful steps dom_eig is recomputed */ + flag = LSRKStepSetDomEigFrequency(arkode_mem, 0); + if (check_flag(&flag, "LSRKStepSetDomEigFrequency", 1)) { return 1; } + + /* Specify max number of stages allowed */ + flag = LSRKStepSetMaxNumStages(arkode_mem, 200); + if (check_flag(&flag, "LSRKStepSetMaxNumStages", 1)) { return 1; } + + /* Specify max number of steps allowed */ + flag = ARKodeSetMaxNumSteps(arkode_mem, 2000); + if (check_flag(&flag, "ARKodeSetMaxNumSteps", 1)) { return 1; } + + /* Specify safety factor for user provided dom_eig */ + flag = LSRKStepSetDomEigSafetyFactor(arkode_mem, SUN_RCONST(1.01)); + if (check_flag(&flag, "LSRKStepSetDomEigSafetyFactor", 1)) { return 1; } + + /* Specify the number of preprocessing warmups before each estimate call + succeeding the very first estimate call. */ + flag = LSRKStepSetNumDomEigEstPreprocessIters(arkode_mem, 0); + if (check_flag(&flag, "LSRKStepSetNumDomEigEstPreprocessIters", 1)) + { + return 1; + } + + /* Specify the Runge--Kutta--Chebyshev LSRK method by name */ + flag = LSRKStepSetSTSMethodByName(arkode_mem, "ARKODE_LSRK_RKL_2"); + if (check_flag(&flag, "LSRKStepSetSTSMethodByName", 1)) { return 1; } + + /* Override any current settings with command-line options */ + flag = SUNDomEigEstimator_SetOptions(DEE, NULL, NULL, argc, argv); + if (check_flag(&flag, "SUNDomEigEstimator_SetOptions", 1)) { return 1; } + + /* Override any current settings with command-line options */ + flag = ARKodeSetOptions(arkode_mem, NULL, NULL, argc, argv); + if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } + + /* Open output stream for results, output comment line */ + UFID = fopen("solution.txt", "w"); + fprintf(UFID, "# t u v w\n"); + + /* output initial condition to disk */ + fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", T0, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + + /* Main time-stepping loop: calls ARKodeEvolve to perform the integration, then + prints results. Stops when the final time has been reached */ + t = T0; + tout = T0 + dTout; + printf(" t u v w\n"); + printf(" -------------------------------------------\n"); + printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM "\n", t, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + + for (iout = 0; iout < Nt; iout++) + { + flag = ARKodeEvolve(arkode_mem, tout, y, &t, ARK_NORMAL); /* call integrator */ + if (check_flag(&flag, "ARKodeEvolve", 1)) { break; } + printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM + "\n", /* access/print solution */ + t, NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", t, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + if (flag >= 0) + { /* successful solve: update time */ + tout += dTout; + tout = (tout > Tf) ? Tf : tout; + } + else + { /* unsuccessful solve: break */ + fprintf(stderr, "Solver failure, stopping integration\n"); + break; + } + } + printf(" -------------------------------------------\n"); + fclose(UFID); + + /* Print final statistics */ + printf("\nFinal Statistics:\n"); + flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + /* Clean up and return with successful completion */ + N_VDestroy(y); /* Free y vector */ + ARKodeFree(&arkode_mem); /* Free integrator memory */ + SUNDomEigEstimator_Destroy(&DEE); /* Free DEE object */ + SUNContext_Free(&ctx); /* Free context */ + + return flag; +} + +/*------------------------------- + * Functions called by the solver + *-------------------------------*/ + +/* f routine to compute the ODE RHS function f(t,y). */ +static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + sunrealtype* rdata = (sunrealtype*)user_data; /* cast user_data to sunrealtype */ + sunrealtype a = rdata[0]; /* access data entries */ + sunrealtype b = rdata[1]; + sunrealtype ep = rdata[2]; + sunrealtype u = NV_Ith_S(y, 0); /* access solution values */ + sunrealtype v = NV_Ith_S(y, 1); + sunrealtype w = NV_Ith_S(y, 2); + + /* fill in the RHS function */ + NV_Ith_S(ydot, 0) = a - (w + 1.0) * u + v * u * u; + NV_Ith_S(ydot, 1) = w * u - v * u * u; + NV_Ith_S(ydot, 2) = (b - w) / ep - w * u; + + return 0; /* Return with success */ +} + +/*------------------------------- + * Private helper functions + *-------------------------------*/ + +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} + +/*---- end of file ----*/ diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.out b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.out new file mode 100644 index 0000000000..83cb9efb40 --- /dev/null +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.out @@ -0,0 +1,41 @@ + +Brusselator ODE test problem: + initial conditions: u0 = 1.2, v0 = 3.1, w0 = 3 + problem parameters: a = 1, b = 3.5, ep = 5e-06 + reltol = 1.0e-06, abstol = 1.0e-10 + + t u v w + ------------------------------------------- + 0.000000 1.200000 3.100000 3.000000 + 1.000000 1.103852 3.013128 3.499981 + 2.000000 0.687945 3.521426 3.499988 + 3.000000 0.409445 4.277957 3.499993 + 4.000000 0.367889 4.942066 3.499994 + 5.000000 0.413862 5.510684 3.499993 + 6.000000 0.589251 5.855724 3.499990 + 7.000000 4.756506 0.735406 3.499917 + 8.000000 1.813465 1.575773 3.499968 + 9.000000 0.527922 2.807379 3.499991 + 10.000000 0.305608 3.657399 3.499995 + ------------------------------------------- + +Final Statistics: +Current time = 10.0124653670818 +Steps = 752 +Step attempts = 762 +Stability limited steps = 0 +Accuracy limited steps = 762 +Error test fails = 10 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 1.13978962117636e-08 +Last step size = 0.020921379243018 +Current step size = 0.0212806907861296 +RHS fn evals = 47265 +Number of dom_eig updates = 1 +Number of fe calls for DEE = 12 +Number of iterations for DEE = 12 +Max. num. of stages used = 195 +Max. num. of stages allowed = 200 +Max. spectral radius = 202001.212020988 +Min. spectral radius = 202001.212020988 \ No newline at end of file diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c new file mode 100644 index 0000000000..f102c025e3 --- /dev/null +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -0,0 +1,434 @@ +/*----------------------------------------------------------------- + * Programmer(s): Mustafa Aggul @ SMU + * Based on + * ark_analytic_lsrk_domeigest.c by Mustafa Aggul @ SMU and + * ark_brusselator.c by Daniel R. Reynolds @ UMBC + *--------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2025-2026, Lawrence Livermore National Security, + * University of Maryland Baltimore County, and the SUNDIALS contributors. + * Copyright (c) 2013-2025, Lawrence Livermore National Security + * and Southern Methodist University. + * Copyright (c) 2002-2013, Lawrence Livermore National Security. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + *--------------------------------------------------------------- + * Example problem: + * + * The following test simulates a brusselator problem from chemical + * kinetics. This is an ODE system with 3 components, Y = [u,v,w], + * satisfying the equations, + * du/dt = a - (w+1)*u + v*u^2 + * dv/dt = w*u - v*u^2 + * dw/dt = (b-w)/ep - w*u + * for t in the interval [0.0, 10.0], with initial conditions + * Y0 = [u0,v0,w0]. + * + * We have 3 different testing scenarios: + * + * Test 1: u0=3.9, v0=1.1, w0=2.8, a=1.2, b=2.5, ep=1.0e-5 + * Here, all three components exhibit a rapid transient change + * during the first 0.2 time units, followed by a slow and + * smooth evolution. + * + * Test 2: u0=1.2, v0=3.1, w0=3, a=1, b=3.5, ep=5.0e-6 + * Here, w experiences a fast initial transient, jumping 0.5 + * within a few steps. All values proceed smoothly until + * around t=6.5, when both u and v undergo a sharp transition, + * with u increaseing from around 0.5 to 5 and v decreasing + * from around 6 to 1 in less than 0.5 time units. After this + * transition, both u and v continue to evolve somewhat + * rapidly for another 1.4 time units, and finish off smoothly. + * + * Test 3: u0=3, v0=3, w0=3.5, a=0.5, b=3, ep=5.0e-4 + * Here, all components undergo very rapid initial transients + * during the first 0.3 time units, and all then proceed very + * smoothly for the remainder of the simulation. + * + * This file is hard-coded to use test 2. + * + * This program solves the problem with the LSRK method using internal + * SUNDIALS dominant eigenvalue estimation (DEE) module. + * + * 100 outputs are printed at equal intervals, and run statistics + * are printed at the end. + *-----------------------------------------------------------------*/ + +/* Header files */ +#include /* prototypes for LSRKStep fcts., consts */ +#include +#include /* serial N_Vector types, fcts., macros */ +#include +#include /* def. of SUNRsqrt, etc. */ +#include /* definition of type sunrealtype */ +#include /* access to Power Iteration module */ + +#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 Called by the Solver */ +static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); + +/* steady f at a given time for dominant eigenvalue estimation */ +static int fstead(N_Vector y, N_Vector ydot, void* user_data); + +/* User-supplied Dominated Eigenvalue Called by the Solver */ +static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, + sunrealtype* lambdaI, void* user_data, N_Vector temp1, + N_Vector temp2, N_Vector temp3); + +/* Private function to check function return values */ +static int check_flag(void* flagvalue, const char* funcname, int opt); + +/* user data structure */ +typedef struct +{ + SUNContext ctx; + sunrealtype rdata[3]; + sunrealtype curent_time; + SUNDomEigEstimator DEE; + sunrealtype rel_tol; + sunindextype max_iters; + sunindextype numwarmup; +} UserData; + +/* Main Program */ +int main(int argc, char* argv[]) +{ + /* general problem parameters */ + sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ + sunrealtype Tf = SUN_RCONST(10.0); /* final time */ + sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ + sunindextype NEQ = 3; /* number of dependent vars. */ + int Nt = (int)ceil(Tf / dTout); /* number of output times */ + int test = 2; /* test problem to run */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-10); + sunrealtype a, b, ep, u0, v0, w0; + + /* general problem variables */ + int flag; /* reusable error-checking flag */ + N_Vector y = NULL; /* empty vector for storing solution */ + void* arkode_mem = NULL; /* empty ARKode memory structure */ + UserData ProbData; /* problem data structure */ + FILE* UFID; + sunrealtype t, tout; + int iout; + + /* Create the SUNDIALS context object for this simulation */ + SUNContext ctx; + flag = SUNContext_Create(SUN_COMM_NULL, &ctx); + if (check_flag(&flag, "SUNContext_Create", 1)) { return 1; } + + /* set up the test problem according to the desired test */ + if (test == 1) + { + u0 = SUN_RCONST(3.9); + v0 = SUN_RCONST(1.1); + w0 = SUN_RCONST(2.8); + a = SUN_RCONST(1.2); + b = SUN_RCONST(2.5); + ep = SUN_RCONST(1.0e-5); + } + else if (test == 3) + { + u0 = SUN_RCONST(3.0); + v0 = SUN_RCONST(3.0); + w0 = SUN_RCONST(3.5); + a = SUN_RCONST(0.5); + b = SUN_RCONST(3.0); + ep = SUN_RCONST(5.0e-4); + } + else + { + u0 = SUN_RCONST(1.2); + v0 = SUN_RCONST(3.1); + w0 = SUN_RCONST(3.0); + a = SUN_RCONST(1.0); + b = SUN_RCONST(3.5); + ep = SUN_RCONST(5.0e-6); + } + + /* Initial problem output */ + printf("\nBrusselator ODE test problem:\n"); + printf(" initial conditions: u0 = %" GSYM ", v0 = %" GSYM + ", w0 = %" GSYM "\n", + u0, v0, w0); + printf(" problem parameters: a = %" GSYM ", b = %" GSYM ", ep = %" GSYM + "\n", + a, b, ep); + printf(" reltol = %.1" ESYM ", abstol = %.1" ESYM "\n\n", reltol, abstol); + + /* Initialize data structures */ + ProbData.ctx = ctx; + ProbData.rdata[0] = a; /* set user data */ + ProbData.rdata[1] = b; + ProbData.rdata[2] = ep; + ProbData.DEE = NULL; + ProbData.rel_tol = SUN_RCONST(5.0e-3); + ProbData.max_iters = 100; + ProbData.numwarmup = 10; + ProbData.curent_time = T0; + y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ + if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } + NV_Ith_S(y, 0) = u0; /* Set initial conditions */ + NV_Ith_S(y, 1) = v0; + NV_Ith_S(y, 2) = w0; + + /* Call LSRKStepCreateSTS to initialize the ARK timestepper module and + specify the right-hand side function in y'=f(t,y), the initial time + T0, and the initial dependent variable vector y. */ + arkode_mem = LSRKStepCreateSTS(f, T0, y, ctx); + if (check_flag((void*)arkode_mem, "LSRKStepCreateSTS", 0)) { return 1; } + + /* Set routines */ + flag = ARKodeSetUserData(arkode_mem, + (void*)&ProbData); /* Pass rdata to user functions */ + if (check_flag(&flag, "ARKodeSetUserData", 1)) { return 1; } + + flag = ARKodeSStolerances(arkode_mem, reltol, abstol); /* Specify tolerances */ + if (check_flag(&flag, "ARKodeSStolerances", 1)) { return 1; } + + flag = ARKodeSetInterpolantType(arkode_mem, + ARK_INTERP_LAGRANGE); /* Specify stiff interpolant */ + if (check_flag(&flag, "ARKodeSetInterpolantType", 1)) { return 1; } + + /* Specify user provided spectral radius */ + flag = LSRKStepSetDomEigFn(arkode_mem, dom_eig); + if (check_flag(&flag, "LSRKStepSetDomEigFn", 1)) { return 1; } + + /* Specify after how many successful steps dom_eig is recomputed */ + flag = LSRKStepSetDomEigFrequency(arkode_mem, 0); + if (check_flag(&flag, "LSRKStepSetDomEigFrequency", 1)) { return 1; } + + /* Specify max number of stages allowed */ + flag = LSRKStepSetMaxNumStages(arkode_mem, 200); + if (check_flag(&flag, "LSRKStepSetMaxNumStages", 1)) { return 1; } + + /* Specify max number of steps allowed */ + flag = ARKodeSetMaxNumSteps(arkode_mem, 2000); + if (check_flag(&flag, "ARKodeSetMaxNumSteps", 1)) { return 1; } + + /* Specify safety factor for user provided dom_eig */ + flag = LSRKStepSetDomEigSafetyFactor(arkode_mem, SUN_RCONST(1.01)); + if (check_flag(&flag, "LSRKStepSetDomEigSafetyFactor", 1)) { return 1; } + + /* Specify the number of preprocessing warmups before each estimate call + succeeding the very first estimate call. */ + flag = LSRKStepSetNumDomEigEstPreprocessIters(arkode_mem, 0); + if (check_flag(&flag, "LSRKStepSetNumDomEigEstPreprocessIters", 1)) + { + return 1; + } + + /* Specify the Runge--Kutta--Chebyshev LSRK method by name */ + flag = LSRKStepSetSTSMethodByName(arkode_mem, "ARKODE_LSRK_RKL_2"); + if (check_flag(&flag, "LSRKStepSetSTSMethodByName", 1)) { return 1; } + + /* Override any current settings with command-line options */ + flag = ARKodeSetOptions(arkode_mem, NULL, NULL, argc, argv); + if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } + + /* Open output stream for results, output comment line */ + UFID = fopen("solution.txt", "w"); + fprintf(UFID, "# t u v w\n"); + + /* output initial condition to disk */ + fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", T0, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + + /* Main time-stepping loop: calls ARKodeEvolve to perform the integration, then + prints results. Stops when the final time has been reached */ + t = T0; + tout = T0 + dTout; + printf(" t u v w\n"); + printf(" -------------------------------------------\n"); + printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM "\n", t, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + + for (iout = 0; iout < Nt; iout++) + { + flag = ARKodeEvolve(arkode_mem, tout, y, &t, ARK_NORMAL); /* call integrator */ + if (check_flag(&flag, "ARKodeEvolve", 1)) { break; } + printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM + "\n", /* access/print solution */ + t, NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", t, + NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); + if (flag >= 0) + { /* successful solve: update time */ + tout += dTout; + tout = (tout > Tf) ? Tf : tout; + } + else + { /* unsuccessful solve: break */ + fprintf(stderr, "Solver failure, stopping integration\n"); + break; + } + } + printf(" -------------------------------------------\n"); + fclose(UFID); + + /* Print final statistics */ + printf("\nFinal Statistics:\n"); + flag = ARKodePrintAllStats(arkode_mem, stdout, SUN_OUTPUTFORMAT_TABLE); + if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } + + /* Clean up and return with successful completion */ + N_VDestroy(y); /* Free y vector */ + ARKodeFree(&arkode_mem); /* Free integrator memory */ + SUNDomEigEstimator_Destroy(&ProbData.DEE); /* Free DEE object */ + SUNContext_Free(&ctx); /* Free context */ + + return flag; +} + +/*------------------------------- + * Functions called by the solver + *-------------------------------*/ + +/* f routine to compute the ODE RHS function f(t,y). */ +static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) +{ + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + sunrealtype* rdata = data->rdata; /* access rdata from UserData */ + sunrealtype a = rdata[0]; /* access data entries */ + sunrealtype b = rdata[1]; + sunrealtype ep = rdata[2]; + sunrealtype u = NV_Ith_S(y, 0); /* access solution values */ + sunrealtype v = NV_Ith_S(y, 1); + sunrealtype w = NV_Ith_S(y, 2); + + /* fill in the RHS function */ + NV_Ith_S(ydot, 0) = a - (w + 1.0) * u + v * u * u; + NV_Ith_S(ydot, 1) = w * u - v * u * u; + NV_Ith_S(ydot, 2) = (b - w) / ep - w * u; + + return 0; /* Return with success */ +} + +/* steady f at a given time for dominant eigenvalue estimation */ +static int fstead(N_Vector y, N_Vector ydot, void* user_data) +{ + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + sunrealtype t = data->curent_time; /* access current time from UserData */ + + f(t, y, ydot, user_data); + + return 0; /* Return with success */ +} + + + + +/* dom_eig routine to estimate the dominated eigenvalue */ +static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, + sunrealtype* lambdaI, void* user_data, N_Vector temp1, + N_Vector temp2, N_Vector temp3) +{ + int flag; + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + data->curent_time = t; /* update current time in UserData */ + + SUNContext ctx = data->ctx; /* access context from UserData */ + SUNDomEigEstimator DEE = data->DEE; /* access DEE from UserData */ + + if (DEE == NULL) + { + /* Create random initial vector for power iteration */ + sunrealtype* qd = N_VGetArrayPointer(temp1); + sunindextype NEQ = N_VGetLength(temp1); + for (int i = 0; i < NEQ; i++) + { + qd[i] = (sunrealtype)rand() / (sunrealtype)RAND_MAX; + } + + /* Create power iteration dominant eigenvalue estimator (DEE) */ + DEE = SUNDomEigEstimator_Power(temp1, data->max_iters, data->rel_tol, ctx); + if (check_flag(DEE, "SUNDomEigEstimator_Power", 0)) { return 1; } + + /* Set the ODE right-hand side function at t for the Jacobian-vector products */ + flag = SUNDomEigEstimator_SetRHS(DEE, user_data, fstead); + if (check_flag(&flag, "SUNDomEigEstimator_SetRHS", 1)) { return 1; } + + /* Set the linearization vector for the Jacobian-vector products */ + flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) { return 1; } + + flag = SUNDomEigEstimator_SetNumPreprocessIters(DEE, data->numwarmup); + if (check_flag(&flag, "SUNDomEigEstimator_SetNumPreprocessIters", 1)) { return 1; } + + flag = SUNDomEigEstimator_Initialize(DEE); + if (check_flag(&flag, "SUNDomEigEstimator_Initialize", 1)) { return 1; } + } + + /* Update the linearization vector for the Jacobian-vector products */ + flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) { return 1; } + + /* Estimate the dominant eigenvalue with power iteration */ + flag = SUNDomEigEstimator_Estimate(DEE, lambdaR, lambdaI); + if (check_flag(&flag, "SUNDomEigEstimator_Estimate", 1)) { return 1; } + + return 0; /* return with success */ +} + +/*------------------------------- + * Private helper functions + *-------------------------------*/ + +/* Check function return value... + opt == 0 means SUNDIALS function allocates memory so check if + returned NULL pointer + opt == 1 means SUNDIALS function returns a flag so check if + flag >= 0 + opt == 2 means function allocates memory so check if returned + NULL pointer +*/ +static int check_flag(void* flagvalue, const char* funcname, int opt) +{ + int* errflag; + + /* Check if SUNDIALS function returned NULL pointer - no memory allocated */ + if (opt == 0 && flagvalue == NULL) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + /* Check if flag < 0 */ + else if (opt == 1) + { + errflag = (int*)flagvalue; + if (*errflag < 0) + { + fprintf(stderr, "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n", + funcname, *errflag); + return 1; + } + } + + /* Check if function returned NULL pointer - no memory allocated */ + else if (opt == 2 && flagvalue == NULL) + { + fprintf(stderr, "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n", + funcname); + return 1; + } + + return 0; +} + +/*---- end of file ----*/ diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out new file mode 100644 index 0000000000..b0578c5eb3 --- /dev/null +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out @@ -0,0 +1,39 @@ + +Brusselator ODE test problem: + initial conditions: u0 = 1.2, v0 = 3.1, w0 = 3 + problem parameters: a = 1, b = 3.5, ep = 5e-06 + reltol = 1.0e-06, abstol = 1.0e-10 + + t u v w + ------------------------------------------- + 0.000000 1.200000 3.100000 3.000000 + 1.000000 1.103852 3.013146 3.499981 + 2.000000 0.687969 3.521408 3.499988 + 3.000000 0.409454 4.277927 3.499993 + 4.000000 0.367888 4.942040 3.499994 + 5.000000 0.413859 5.510654 3.499993 + 6.000000 0.589236 5.855711 3.499990 + 7.000000 4.756658 0.735408 3.499917 + 8.000000 1.813541 1.575726 3.499968 + 9.000000 0.527942 2.807335 3.499991 + 10.000000 0.305609 3.657368 3.499995 + ------------------------------------------- + +Final Statistics: +Current time = 10.0012625740025 +Steps = 821 +Step attempts = 825 +Stability limited steps = 248 +Accuracy limited steps = 825 +Error test fails = 4 +NLS step fails = 0 +Inequality constraint fails = 0 +Initial step size = 1.13978962117636e-08 +Last step size = 0.020737468701875 +Current step size = 0.0210884918677079 +RHS fn evals = 100668 +Number of dom_eig updates = 1 +Max. num. of stages used = 199 +Max. num. of stages allowed = 200 +Max. spectral radius = 808004.848070097 +Min. spectral radius = 808004.848070097 \ No newline at end of file diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index 0723678d21..bd1762791f 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -32,6 +32,9 @@ extern "C" { #endif +typedef int (*DEERhsFn)(N_Vector y, N_Vector ydot, void* user_data); +#define MAX_DQITERS 3 + /* ----------------------------------------------------------------- * Generic definition of SUNDomEigEstimator (DEE) * ----------------------------------------------------------------- */ @@ -46,6 +49,8 @@ typedef _SUNDIALS_STRUCT_ SUNDomEigEstimator_* SUNDomEigEstimator; struct SUNDomEigEstimator_Ops_ { SUNErrCode (*setatimes)(SUNDomEigEstimator, void*, SUNATimesFn); + SUNErrCode (*setrhs)(SUNDomEigEstimator, void*, DEERhsFn); + SUNErrCode (*setrhslinearizationvector)(SUNDomEigEstimator, N_Vector); SUNErrCode (*setoptions)(SUNDomEigEstimator DEE, const char* Did, const char* file_name, int argc, char* argv[]); SUNErrCode (*setmaxiters)(SUNDomEigEstimator, long int); @@ -86,6 +91,12 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); + +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, N_Vector v); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetOptions(SUNDomEigEstimator DEE, const char* Did, const char* file_name, diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 328a1d7a1b..b5d3fa4944 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -43,7 +43,7 @@ struct SUNDomEigEstimatorContent_Arnoldi_ /* Krylov subspace vectors */ N_Vector* V; - N_Vector q; + N_Vector q, rhs_linV, Fv, work; int kry_dim; /* Krylov subspace dimension */ int num_warmups; /* Number of preprocessing iterations */ @@ -53,6 +53,10 @@ struct SUNDomEigEstimatorContent_Arnoldi_ long int num_ATimes; /* Number of ATimes calls */ + DEERhsFn rhsfn; /* User provided RHS function */ + void* rhs_data; /* RHS function data */ + long int nfevals; /* Number of RHS evaluations */ + sunrealtype* LAPACK_A; /* The vector which holds rows of the Hessenberg matrix in the given order */ sunrealtype* LAPACK_wr; /* Real parts of eigenvalues */ sunrealtype* LAPACK_wi; /* Imaginary parts of eigenvalues */ @@ -77,6 +81,14 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, + void* rhs_data, DEERhsFn RHSfn); + +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator DEE, + N_Vector v); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, int num_iters); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index b6f6626cc0..8b51797f0f 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -41,7 +41,7 @@ struct SUNDomEigEstimatorContent_Power_ SUNATimesFn ATimes; /* User provided ATimes function */ void* ATdata; /* ATimes function data*/ - N_Vector V, q, q_prev; /* workspace vectors */ + N_Vector V, q, q_prev, rhs_linV, Fv, work; /* workspace vectors */ int num_warmups; /* Number of preprocessing iterations */ long int max_iters; /* Maximum number of power iterations */ @@ -53,6 +53,10 @@ struct SUNDomEigEstimatorContent_Power_ sunrealtype rel_tol; /* Convergence criteria for the power iteration */ sunrealtype res; /* Residual from the last Estimate call */ + DEERhsFn rhsfn; /* User provided RHS function */ + void* rhs_data; /* RHS function data */ + long int nfevals; /* Number of RHS evaluations */ + sunbooleantype complex; /* Flag for complex eigenvalue request */ }; @@ -71,6 +75,10 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, void* rhs_data, + DEERhsFn RHSfn); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetMaxIters_Power(SUNDomEigEstimator DEE, long int max_iters); @@ -87,6 +95,10 @@ SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); +SUNDIALS_EXPORT +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, + N_Vector v); + SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 2349c6da2b..76841bf8bf 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -193,6 +193,29 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, return (ier); } +SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) +{ + SUNErrCode ier; + SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); + if (DEE->ops->setrhs) { ier = DEE->ops->setrhs(DEE, rhs_data, RHSfn); } + else { ier = SUN_SUCCESS; } + SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); + return (ier); +} + +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, N_Vector v) +{ + SUNErrCode ier; + SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); + if (DEE->ops->setrhslinearizationvector) + { + ier = DEE->ops->setrhslinearizationvector(DEE, v); + } + else { ier = SUN_SUCCESS; } + SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); + return (ier); +} + SUNErrCode SUNDomEigEstimator_SetOptions(SUNDomEigEstimator DEE, const char* Did, const char* file_name, int argc, char* argv[]) diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index f200b84e4c..4c729bd1b0 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -64,6 +64,8 @@ int sundomeigest_Compare(const void* a, const void* b); +SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv); + /* * ----------------------------------------------------------------- * exported functions @@ -104,6 +106,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; + DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Arnoldi; + DEE->ops->setrhslinearizationvector = + SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Arnoldi; @@ -128,12 +133,18 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, content->ATdata = NULL; content->V = NULL; content->q = NULL; + content->rhs_linV = NULL; + content->Fv = NULL; + content->work = NULL; content->kry_dim = kry_dim; content->num_warmups = DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT; content->num_iters = 0; content->num_ATimes = 0; content->warmup_to_tol = SUNFALSE; content->tol_preprocess = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; + content->rhsfn = NULL; + content->rhs_data = NULL; + content->nfevals = 0; content->LAPACK_A = NULL; content->LAPACK_wr = NULL; content->LAPACK_wi = NULL; @@ -176,6 +187,45 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, return SUN_SUCCESS; } +SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, + void* rhs_data, DEERhsFn RHSfn) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + + /* set function pointers to integrator-supplied RHS routine + and data, and return with success */ + Arnoldi_CONTENT(DEE)->rhsfn = RHSfn; + Arnoldi_CONTENT(DEE)->rhs_data = rhs_data; + + DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); + SUNCheckLastErr(); + + return SUN_SUCCESS; +} + +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator DEE, N_Vector v) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(v, SUN_ERR_ARG_CORRUPT); + + if (Arnoldi_CONTENT(DEE)->rhs_linV == NULL) + { + Arnoldi_CONTENT(DEE)->rhs_linV = N_VClone(v); + SUNCheckLastErr(); + } + + N_VScale(ONE, v, Arnoldi_CONTENT(DEE)->rhs_linV); + SUNCheckLastErr(); + + return SUN_SUCCESS; +} + SUNErrCode SUNDomEigEstimator_Initialize_Arnoldi(SUNDomEigEstimator DEE) { SUNFunctionBegin(DEE->sunctx); @@ -535,6 +585,11 @@ SUNErrCode SUNDomEigEstimator_Destroy_Arnoldi(SUNDomEigEstimator* DEEptr) N_VDestroy(Arnoldi_CONTENT(DEE)->q); Arnoldi_CONTENT(DEE)->q = NULL; } + if (Arnoldi_CONTENT(DEE)->rhs_linV) + { + N_VDestroy(Arnoldi_CONTENT(DEE)->rhs_linV); + Arnoldi_CONTENT(DEE)->rhs_linV = NULL; + } if (Arnoldi_CONTENT(DEE)->V) { N_VDestroyVectorArray(Arnoldi_CONTENT(DEE)->V, @@ -608,3 +663,71 @@ int sundomeigest_Compare(const void* a, const void* b) sunrealtype mag_b = SUNRsqrt(cplx_b[0] * cplx_b[0] + cplx_b[1] * cplx_b[1]); return (mag_b > mag_a) - (mag_b < mag_a); // Descending order } + +/*--------------------------------------------------------------- + dee_DQJtimes: + + This routine generates a difference quotient approximation to + the Jacobian-vector product f_y(t,y) * v. The approximation is + Jv = [f(y + v*sig) - f(y)]/sig, where sig = 1 / ||v||_WRMS, + i.e. the WRMS norm of v*sig is 1. + ---------------------------------------------------------------*/ +SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) +{ + SUNDomEigEstimator DEE = (SUNDomEigEstimator)voidstarDEE; + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(v, SUN_ERR_ARG_CORRUPT); + SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE)->rhs_linV, SUN_ERR_ARG_CORRUPT); + // TODO: Add assertion as needed + + if (Arnoldi_CONTENT(DEE)->work == NULL) + { + Arnoldi_CONTENT(DEE)->work = N_VClone(v); + SUNCheckLastErr(); + } + if (Arnoldi_CONTENT(DEE)->Fv == NULL) + { + Arnoldi_CONTENT(DEE)->Fv = N_VClone(v); + SUNCheckLastErr(); + } + + sunrealtype sig, siginv; + int iter, retval; + + N_Vector y = Arnoldi_CONTENT(DEE)->rhs_linV; + N_Vector work = Arnoldi_CONTENT(DEE)->work; + N_Vector Fv = Arnoldi_CONTENT(DEE)->Fv; + + retval = Arnoldi_CONTENT(DEE)->rhsfn(y, Arnoldi_CONTENT(DEE)->Fv, Arnoldi_CONTENT(DEE)->rhs_data); + Arnoldi_CONTENT(DEE)->nfevals++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + /* Initialize perturbation to 1/||v|| */ + // sunrealtype sig = ONE / N_VWrmsNorm(v, ark_mem->ewt); + sunrealtype sig = ONE / N_VWrmsNorm(v, v); + + for (iter = 0; iter < MAX_DQITERS; iter++) + { + /* Set work = y + sig*v */ + N_VLinearSum(sig, v, ONE, y, work); + + /* Set Jv = f(tn, y+sig*v) */ + retval = Arnoldi_CONTENT(DEE)->rhsfn(work, Jv, Arnoldi_CONTENT(DEE)->rhs_data); + Arnoldi_CONTENT(DEE)->nfevals++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + /* If f failed recoverably, shrink sig and retry */ + sig *= SUN_RCONST(0.25); + } + + /* Replace Jv by (Jv - fn)/sig */ + siginv = ONE / sig; + N_VLinearSum(siginv, Jv, -siginv, Fv, Jv); + + return SUN_SUCCESS; +} \ No newline at end of file diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index d6bc84e4bd..8c7ec7a487 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -61,6 +61,8 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( SUNDomEigEstimator DEE, sunrealtype lambdaR, N_Vector v_prev, N_Vector v, sunrealtype* lambdaR_out, sunrealtype* lambdaI_out); +SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv); + /* ---------------------------------------------------------------------------- * Function to create a new PI estimator */ @@ -99,6 +101,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; + DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Power; + DEE->ops->setrhslinearizationvector = + SUNDomEigEstimator_SetRHSLinearizationVector_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; @@ -125,11 +130,17 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, content->V = NULL; content->q = NULL; content->q_prev = NULL; + content->rhs_linV = NULL; + content->Fv = NULL; + content->work = NULL; content->complex = SUNTRUE; content->max_iters = max_iters; content->num_warmups = DEE_NUM_OF_WARMUPS_PI_DEFAULT; content->rel_tol = rel_tol; content->res = ZERO; + content->rhsfn = NULL; + content->rhs_data = NULL; + content->nfevals = 0; content->num_iters = 0; content->num_ATimes = 0; @@ -168,6 +179,46 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } +SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, + void* rhs_data, DEERhsFn RHSfn) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(RHSfn, SUN_ERR_ARG_CORRUPT); + + /* set function pointers to integrator-supplied RHS routine + and data, and return with success */ + PI_CONTENT(DEE)->rhsfn = RHSfn; + PI_CONTENT(DEE)->rhs_data = rhs_data; + + DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); + SUNCheckLastErr(); + + return SUN_SUCCESS; +} + +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, N_Vector v) +{ + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(v, SUN_ERR_ARG_CORRUPT); + + if (PI_CONTENT(DEE)->rhs_linV == NULL) + { + PI_CONTENT(DEE)->rhs_linV = N_VClone(v); + SUNCheckLastErr(); + } + + N_VScale(ONE, v, PI_CONTENT(DEE)->rhs_linV); + SUNCheckLastErr(); + + return SUN_SUCCESS; +} + SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) { SUNFunctionBegin(DEE->sunctx); @@ -562,7 +613,11 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) N_VDestroy(PI_CONTENT(DEE)->V); PI_CONTENT(DEE)->V = NULL; } - + if (PI_CONTENT(DEE)->rhs_linV) + { + N_VDestroy(PI_CONTENT(DEE)->rhs_linV); + PI_CONTENT(DEE)->rhs_linV = NULL; + } free(DEE->content); DEE->content = NULL; } @@ -575,3 +630,70 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) *DEEptr = NULL; return SUN_SUCCESS; } + +/*--------------------------------------------------------------- + dee_DQJtimes: + + This routine generates a difference quotient approximation to + the Jacobian-vector product f_y(t,y) * v. The approximation is + Jv = [f(y + v*sig) - f(y)]/sig, where sig = 1 / ||v||_WRMS, + i.e. the WRMS norm of v*sig is 1. + ---------------------------------------------------------------*/ +SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) +{ + SUNDomEigEstimator DEE = (SUNDomEigEstimator)voidstarDEE; + SUNFunctionBegin(DEE->sunctx); + + SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); + SUNAssert(v, SUN_ERR_ARG_CORRUPT); + SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE)->rhs_linV, SUN_ERR_ARG_CORRUPT); + + if (PI_CONTENT(DEE)->work == NULL) + { + PI_CONTENT(DEE)->work = N_VClone(v); + SUNCheckLastErr(); + } + if (PI_CONTENT(DEE)->Fv == NULL) + { + PI_CONTENT(DEE)->Fv = N_VClone(v); + SUNCheckLastErr(); + } + + sunrealtype sig, siginv; + int iter, retval; + + N_Vector y = PI_CONTENT(DEE)->rhs_linV; + N_Vector work = PI_CONTENT(DEE)->work; + N_Vector Fv = PI_CONTENT(DEE)->Fv; + + retval = PI_CONTENT(DEE)->rhsfn(y, PI_CONTENT(DEE)->Fv, PI_CONTENT(DEE)->rhs_data); + PI_CONTENT(DEE)->nfevals++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + /* Initialize perturbation to 1/||v|| */ + // sunrealtype sig = ONE / N_VWrmsNorm(v, ark_mem->ewt); + sig = ONE / N_VWrmsNorm(v, v); + + for (iter = 0; iter < MAX_DQITERS; iter++) + { + /* Set work = y + sig*v */ + N_VLinearSum(sig, v, ONE, y, work); + + /* Set Jv = f(tn, y+sig*v) */ + retval = PI_CONTENT(DEE)->rhsfn(work, Jv, PI_CONTENT(DEE)->rhs_data); + PI_CONTENT(DEE)->nfevals++; + if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + + /* If f failed recoverably, shrink sig and retry */ + sig *= SUN_RCONST(0.25); + } + + /* Replace Jv by (Jv - fn)/sig */ + siginv = ONE / sig; + N_VLinearSum(siginv, Jv, -siginv, Fv, Jv); + + return SUN_SUCCESS; +} \ No newline at end of file diff --git a/test/answers b/test/answers index 7999b4bf02..5ec2272ec7 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 7999b4bf0222b22dc75289123b7f14c36b27bbd9 +Subproject commit 5ec2272ec73e150f72c049a86ed7a8a4fc478277 From 1ca8905e41de84226b6e09f930e06d90ed2fc6cd Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 5 Mar 2026 23:39:28 -0600 Subject: [PATCH 15/76] bug fix --- ...ark_brusselator_lsrk_externaldomeigest.out | 44 +++++++++---------- src/sundomeigest/power/sundomeigest_power.c | 3 +- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out index b0578c5eb3..2966c64060 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out @@ -7,33 +7,33 @@ Brusselator ODE test problem: t u v w ------------------------------------------- 0.000000 1.200000 3.100000 3.000000 - 1.000000 1.103852 3.013146 3.499981 - 2.000000 0.687969 3.521408 3.499988 - 3.000000 0.409454 4.277927 3.499993 - 4.000000 0.367888 4.942040 3.499994 - 5.000000 0.413859 5.510654 3.499993 - 6.000000 0.589236 5.855711 3.499990 - 7.000000 4.756658 0.735408 3.499917 - 8.000000 1.813541 1.575726 3.499968 - 9.000000 0.527942 2.807335 3.499991 - 10.000000 0.305609 3.657368 3.499995 + 1.000000 1.103852 3.013128 3.499981 + 2.000000 0.687945 3.521426 3.499988 + 3.000000 0.409445 4.277957 3.499993 + 4.000000 0.367889 4.942066 3.499994 + 5.000000 0.413862 5.510684 3.499993 + 6.000000 0.589251 5.855724 3.499990 + 7.000000 4.756506 0.735406 3.499917 + 8.000000 1.813465 1.575773 3.499968 + 9.000000 0.527922 2.807379 3.499991 + 10.000000 0.305608 3.657399 3.499995 ------------------------------------------- Final Statistics: -Current time = 10.0012625740025 -Steps = 821 -Step attempts = 825 -Stability limited steps = 248 -Accuracy limited steps = 825 -Error test fails = 4 +Current time = 10.0124653670818 +Steps = 752 +Step attempts = 762 +Stability limited steps = 0 +Accuracy limited steps = 762 +Error test fails = 10 NLS step fails = 0 Inequality constraint fails = 0 Initial step size = 1.13978962117636e-08 -Last step size = 0.020737468701875 -Current step size = 0.0210884918677079 -RHS fn evals = 100668 +Last step size = 0.020921379243018 +Current step size = 0.0212806907861296 +RHS fn evals = 47265 Number of dom_eig updates = 1 -Max. num. of stages used = 199 +Max. num. of stages used = 195 Max. num. of stages allowed = 200 -Max. spectral radius = 808004.848070097 -Min. spectral radius = 808004.848070097 \ No newline at end of file +Max. spectral radius = 202001.212007683 +Min. spectral radius = 202001.212007683 \ No newline at end of file diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 8c7ec7a487..18052c1f2a 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -685,7 +685,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) /* Set Jv = f(tn, y+sig*v) */ retval = PI_CONTENT(DEE)->rhsfn(work, Jv, PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; - if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } + if (retval == 0) { break; } + if (retval < 0) { return (-1); } /* If f failed recoverably, shrink sig and retry */ sig *= SUN_RCONST(0.25); From c707ddfb274628c33e112e0591655770aca5bf51 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 6 Mar 2026 20:32:37 -0600 Subject: [PATCH 16/76] revert the workflow change --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebf16cfd9b..b6238ad61a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,8 +96,7 @@ jobs: # Check for changes to trigger python interface checks # Updates in include or bindings/sundials4py directories if git diff --name-only "$BASE" "$HEAD" | grep -qE '^(include/|bindings/sundials4py/)'; then - #echo "python=true" >> "$GITHUB_OUTPUT" - echo "python=false" >> "$GITHUB_OUTPUT" + echo "python=true" >> "$GITHUB_OUTPUT" else echo "python=false" >> "$GITHUB_OUTPUT" fi From 5b6412620645e72be52fe4ac62922afbe5a50806 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 6 Mar 2026 20:44:23 -0600 Subject: [PATCH 17/76] ci trigger step-1 --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 5ec2272ec7..d543e9bb80 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 5ec2272ec73e150f72c049a86ed7a8a4fc478277 +Subproject commit d543e9bb801d354358f46354f533b5bafedcf7be From d60f793bf5dc7fba7939efb524f4b0d01942ab9d Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 6 Mar 2026 20:46:48 -0600 Subject: [PATCH 18/76] ci trigger step-2 --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index d543e9bb80..5ec2272ec7 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit d543e9bb801d354358f46354f533b5bafedcf7be +Subproject commit 5ec2272ec73e150f72c049a86ed7a8a4fc478277 From 1fb0192d26759c7ffb95c98070a8666b7b9d1c30 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 6 Mar 2026 21:07:50 -0600 Subject: [PATCH 19/76] formatting --- .../C_serial/ark_analytic_lsrk_domeigest.c | 5 +- .../C_serial/ark_brusselator_lsrk_domeigest.c | 14 ++-- .../ark_brusselator_lsrk_externaldomeigest.c | 76 ++++++++++--------- include/arkode/arkode_lsrkstep.h | 4 +- include/sundials/sundials_domeigestimator.h | 6 +- include/sundomeigest/sundomeigest_arnoldi.h | 12 +-- include/sundomeigest/sundomeigest_power.h | 15 ++-- src/arkode/arkode_lsrkstep_io.c | 3 +- src/sundials/sundials_domeigestimator.c | 6 +- .../arnoldi/sundomeigest_arnoldi.c | 13 ++-- src/sundomeigest/power/sundomeigest_power.c | 19 +++-- 11 files changed, 97 insertions(+), 76 deletions(-) diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c index 6a288e7e5a..a35c397d1e 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c @@ -239,7 +239,10 @@ int main(int argc, char* argv[]) /* Set real type dominant eigenvalue */ flag = SUNDomEigEstimator_SetDEEisReal_Power(DEE, SUNTRUE); - if (check_flag(&flag, "SUNDomEigEstimator_SetDEEisReal_Power", 1)) { return 1; } + if (check_flag(&flag, "SUNDomEigEstimator_SetDEEisReal_Power", 1)) + { + return 1; + } /* Open output stream for results, output comment line */ UFID = fopen("solution.txt", "w"); diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c index 2a33231e03..c656a48b53 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c @@ -93,14 +93,14 @@ int main(int argc, char* argv[]) sunindextype NEQ = 3; /* number of dependent vars. */ int Nt = (int)ceil(Tf / dTout); /* number of output times */ int test = 2; /* test problem to run */ - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); sunrealtype a, b, ep, u0, v0, w0; /* general problem variables */ - int flag; /* reusable error-checking flag */ - N_Vector y = NULL; /* empty vector for storing solution */ - void* arkode_mem = NULL; /* empty ARKode memory structure */ + int flag; /* reusable error-checking flag */ + N_Vector y = NULL; /* empty vector for storing solution */ + void* arkode_mem = NULL; /* empty ARKode memory structure */ sunrealtype rdata[3]; FILE* UFID; sunrealtype t, tout; @@ -303,10 +303,10 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } /* Clean up and return with successful completion */ - N_VDestroy(y); /* Free y vector */ - ARKodeFree(&arkode_mem); /* Free integrator memory */ + N_VDestroy(y); /* Free y vector */ + ARKodeFree(&arkode_mem); /* Free integrator memory */ SUNDomEigEstimator_Destroy(&DEE); /* Free DEE object */ - SUNContext_Free(&ctx); /* Free context */ + SUNContext_Free(&ctx); /* Free context */ return flag; } diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index f102c025e3..43e8240569 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -113,15 +113,15 @@ int main(int argc, char* argv[]) sunindextype NEQ = 3; /* number of dependent vars. */ int Nt = (int)ceil(Tf / dTout); /* number of output times */ int test = 2; /* test problem to run */ - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); sunrealtype a, b, ep, u0, v0, w0; /* general problem variables */ - int flag; /* reusable error-checking flag */ - N_Vector y = NULL; /* empty vector for storing solution */ - void* arkode_mem = NULL; /* empty ARKode memory structure */ - UserData ProbData; /* problem data structure */ + int flag; /* reusable error-checking flag */ + N_Vector y = NULL; /* empty vector for storing solution */ + void* arkode_mem = NULL; /* empty ARKode memory structure */ + UserData ProbData; /* problem data structure */ FILE* UFID; sunrealtype t, tout; int iout; @@ -171,16 +171,16 @@ int main(int argc, char* argv[]) printf(" reltol = %.1" ESYM ", abstol = %.1" ESYM "\n\n", reltol, abstol); /* Initialize data structures */ - ProbData.ctx = ctx; - ProbData.rdata[0] = a; /* set user data */ - ProbData.rdata[1] = b; - ProbData.rdata[2] = ep; - ProbData.DEE = NULL; - ProbData.rel_tol = SUN_RCONST(5.0e-3); - ProbData.max_iters = 100; - ProbData.numwarmup = 10; + ProbData.ctx = ctx; + ProbData.rdata[0] = a; /* set user data */ + ProbData.rdata[1] = b; + ProbData.rdata[2] = ep; + ProbData.DEE = NULL; + ProbData.rel_tol = SUN_RCONST(5.0e-3); + ProbData.max_iters = 100; + ProbData.numwarmup = 10; ProbData.curent_time = T0; - y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ + y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } NV_Ith_S(y, 0) = u0; /* Set initial conditions */ NV_Ith_S(y, 1) = v0; @@ -286,10 +286,10 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodePrintAllStats", 1)) { return 1; } /* Clean up and return with successful completion */ - N_VDestroy(y); /* Free y vector */ - ARKodeFree(&arkode_mem); /* Free integrator memory */ + N_VDestroy(y); /* Free y vector */ + ARKodeFree(&arkode_mem); /* Free integrator memory */ SUNDomEigEstimator_Destroy(&ProbData.DEE); /* Free DEE object */ - SUNContext_Free(&ctx); /* Free context */ + SUNContext_Free(&ctx); /* Free context */ return flag; } @@ -301,14 +301,14 @@ int main(int argc, char* argv[]) /* f routine to compute the ODE RHS function f(t,y). */ static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) { - UserData* data = (UserData*)user_data; /* cast user_data to UserData */ - sunrealtype* rdata = data->rdata; /* access rdata from UserData */ - sunrealtype a = rdata[0]; /* access data entries */ - sunrealtype b = rdata[1]; - sunrealtype ep = rdata[2]; - sunrealtype u = NV_Ith_S(y, 0); /* access solution values */ - sunrealtype v = NV_Ith_S(y, 1); - sunrealtype w = NV_Ith_S(y, 2); + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + sunrealtype* rdata = data->rdata; /* access rdata from UserData */ + sunrealtype a = rdata[0]; /* access data entries */ + sunrealtype b = rdata[1]; + sunrealtype ep = rdata[2]; + sunrealtype u = NV_Ith_S(y, 0); /* access solution values */ + sunrealtype v = NV_Ith_S(y, 1); + sunrealtype w = NV_Ith_S(y, 2); /* fill in the RHS function */ NV_Ith_S(ydot, 0) = a - (w + 1.0) * u + v * u * u; @@ -322,32 +322,29 @@ static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) static int fstead(N_Vector y, N_Vector ydot, void* user_data) { UserData* data = (UserData*)user_data; /* cast user_data to UserData */ - sunrealtype t = data->curent_time; /* access current time from UserData */ + sunrealtype t = data->curent_time; /* access current time from UserData */ f(t, y, ydot, user_data); return 0; /* Return with success */ } - - - /* dom_eig routine to estimate the dominated eigenvalue */ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, sunrealtype* lambdaI, void* user_data, N_Vector temp1, N_Vector temp2, N_Vector temp3) { int flag; - UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ data->curent_time = t; /* update current time in UserData */ - SUNContext ctx = data->ctx; /* access context from UserData */ + SUNContext ctx = data->ctx; /* access context from UserData */ SUNDomEigEstimator DEE = data->DEE; /* access DEE from UserData */ if (DEE == NULL) { /* Create random initial vector for power iteration */ - sunrealtype* qd = N_VGetArrayPointer(temp1); + sunrealtype* qd = N_VGetArrayPointer(temp1); sunindextype NEQ = N_VGetLength(temp1); for (int i = 0; i < NEQ; i++) { @@ -364,10 +361,16 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, /* Set the linearization vector for the Jacobian-vector products */ flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) { return 1; } + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) + { + return 1; + } flag = SUNDomEigEstimator_SetNumPreprocessIters(DEE, data->numwarmup); - if (check_flag(&flag, "SUNDomEigEstimator_SetNumPreprocessIters", 1)) { return 1; } + if (check_flag(&flag, "SUNDomEigEstimator_SetNumPreprocessIters", 1)) + { + return 1; + } flag = SUNDomEigEstimator_Initialize(DEE); if (check_flag(&flag, "SUNDomEigEstimator_Initialize", 1)) { return 1; } @@ -375,7 +378,10 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, /* Update the linearization vector for the Jacobian-vector products */ flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) { return 1; } + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) + { + return 1; + } /* Estimate the dominant eigenvalue with power iteration */ flag = SUNDomEigEstimator_Estimate(DEE, lambdaR, lambdaI); diff --git a/include/arkode/arkode_lsrkstep.h b/include/arkode/arkode_lsrkstep.h index 3961403fa8..09412bdceb 100644 --- a/include/arkode/arkode_lsrkstep.h +++ b/include/arkode/arkode_lsrkstep.h @@ -93,8 +93,8 @@ SUNDIALS_EXPORT int LSRKStepSetMaxNumStages(void* arkode_mem, SUNDIALS_EXPORT int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety); -SUNDIALS_EXPORT int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, - sunbooleantype analytic_stab_region); +SUNDIALS_EXPORT int LSRKStepSetUseAnalyticStabRegion( + void* arkode_mem, sunbooleantype analytic_stab_region); SUNDIALS_EXPORT int LSRKStepSetNumDomEigEstInitPreprocessIters(void* arkode_mem, int num_iters); diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index bd1762791f..bdff126743 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -92,10 +92,12 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); +SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, + DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, + N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetOptions(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index b5d3fa4944..c76454528b 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -53,9 +53,9 @@ struct SUNDomEigEstimatorContent_Arnoldi_ long int num_ATimes; /* Number of ATimes calls */ - DEERhsFn rhsfn; /* User provided RHS function */ - void* rhs_data; /* RHS function data */ - long int nfevals; /* Number of RHS evaluations */ + DEERhsFn rhsfn; /* User provided RHS function */ + void* rhs_data; /* RHS function data */ + long int nfevals; /* Number of RHS evaluations */ sunrealtype* LAPACK_A; /* The vector which holds rows of the Hessenberg matrix in the given order */ sunrealtype* LAPACK_wr; /* Real parts of eigenvalues */ @@ -83,11 +83,11 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn); + void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator DEE, - N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi( + SUNDomEigEstimator DEE, N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 8b51797f0f..db973e4fff 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -53,9 +53,9 @@ struct SUNDomEigEstimatorContent_Power_ sunrealtype rel_tol; /* Convergence criteria for the power iteration */ sunrealtype res; /* Residual from the last Estimate call */ - DEERhsFn rhsfn; /* User provided RHS function */ - void* rhs_data; /* RHS function data */ - long int nfevals; /* Number of RHS evaluations */ + DEERhsFn rhsfn; /* User provided RHS function */ + void* rhs_data; /* RHS function data */ + long int nfevals; /* Number of RHS evaluations */ sunbooleantype complex; /* Flag for complex eigenvalue request */ }; @@ -76,8 +76,8 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, void* rhs_data, - DEERhsFn RHSfn); +SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, + void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetMaxIters_Power(SUNDomEigEstimator DEE, @@ -96,11 +96,12 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, N_Vector v); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); +SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, + sunbooleantype real); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE); diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index 3b5b526b7b..cdaf3d2cae 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -320,7 +320,8 @@ int LSRKStepSetDomEigSafetyFactor(void* arkode_mem, sunrealtype dom_eig_safety) LSRKStepSetUseAnalyticStabRegion sets whether to use the ellipse or the exact stability region for stability checks. ---------------------------------------------------------------*/ -int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, sunbooleantype use_analytic_stab_region) +int LSRKStepSetUseAnalyticStabRegion(void* arkode_mem, + sunbooleantype use_analytic_stab_region) { ARKodeMem ark_mem; ARKodeLSRKStepMem step_mem; diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 76841bf8bf..a5bbdd75c1 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -193,7 +193,8 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, return (ier); } -SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) +SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, + DEERhsFn RHSfn) { SUNErrCode ier; SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); @@ -203,7 +204,8 @@ SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEE return (ier); } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, + N_Vector v) { SUNErrCode ier; SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 4c729bd1b0..6951c0bdd7 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -188,7 +188,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, } SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn) + void* rhs_data, DEERhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); @@ -197,7 +197,7 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, /* set function pointers to integrator-supplied RHS routine and data, and return with success */ - Arnoldi_CONTENT(DEE)->rhsfn = RHSfn; + Arnoldi_CONTENT(DEE)->rhsfn = RHSfn; Arnoldi_CONTENT(DEE)->rhs_data = rhs_data; DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); @@ -206,7 +206,8 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator DEE, N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi( + SUNDomEigEstimator DEE, N_Vector v) { SUNFunctionBegin(DEE->sunctx); @@ -703,7 +704,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_Vector work = Arnoldi_CONTENT(DEE)->work; N_Vector Fv = Arnoldi_CONTENT(DEE)->Fv; - retval = Arnoldi_CONTENT(DEE)->rhsfn(y, Arnoldi_CONTENT(DEE)->Fv, Arnoldi_CONTENT(DEE)->rhs_data); + retval = Arnoldi_CONTENT(DEE)->rhsfn(y, Arnoldi_CONTENT(DEE)->Fv, + Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } @@ -717,7 +719,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(sig, v, ONE, y, work); /* Set Jv = f(tn, y+sig*v) */ - retval = Arnoldi_CONTENT(DEE)->rhsfn(work, Jv, Arnoldi_CONTENT(DEE)->rhs_data); + retval = Arnoldi_CONTENT(DEE)->rhsfn(work, Jv, + Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 18052c1f2a..b3030333e0 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -100,8 +100,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, SUNCheckLastErrNull(); /* Attach operations */ - DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; - DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Power; + DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; + DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Power; DEE->ops->setrhslinearizationvector = SUNDomEigEstimator_SetRHSLinearizationVector_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; @@ -179,7 +179,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); @@ -190,16 +190,17 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, /* set function pointers to integrator-supplied RHS routine and data, and return with success */ - PI_CONTENT(DEE)->rhsfn = RHSfn; + PI_CONTENT(DEE)->rhsfn = RHSfn; PI_CONTENT(DEE)->rhs_data = rhs_data; - + DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); SUNCheckLastErr(); return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, + N_Vector v) { SUNFunctionBegin(DEE->sunctx); @@ -219,7 +220,8 @@ SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) +SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, + sunbooleantype real) { SUNFunctionBegin(DEE->sunctx); @@ -669,7 +671,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_Vector work = PI_CONTENT(DEE)->work; N_Vector Fv = PI_CONTENT(DEE)->Fv; - retval = PI_CONTENT(DEE)->rhsfn(y, PI_CONTENT(DEE)->Fv, PI_CONTENT(DEE)->rhs_data); + retval = PI_CONTENT(DEE)->rhsfn(y, PI_CONTENT(DEE)->Fv, + PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } From d088d11f2996314a9d1cac1a551aca2dacf94f2f Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 6 Mar 2026 21:20:00 -0600 Subject: [PATCH 20/76] swig and litgen --- .../arkode/arkode_lsrkstep_generated.hpp | 3 + .../sundials_domeigestimator_generated.hpp | 6 + .../sundomeigest_power_generated.hpp | 10 + src/arkode/fmod_int32/farkode_lsrkstep_mod.c | 4 +- .../fmod_int32/farkode_lsrkstep_mod.f90 | 14 +- src/arkode/fmod_int64/farkode_lsrkstep_mod.c | 4 +- .../fmod_int64/farkode_lsrkstep_mod.f90 | 14 +- src/sundials/fmod_int32/fsundials_core_mod.c | 30 ++ .../fmod_int32/fsundials_core_mod.f90 | 59 ++++ src/sundials/fmod_int64/fsundials_core_mod.c | 30 ++ .../fmod_int64/fsundials_core_mod.f90 | 59 ++++ .../fmod_int32/fsundomeigest_arnoldi_mod.c | 178 +++++++++- .../fmod_int32/fsundomeigest_arnoldi_mod.f90 | 330 +++++++++++++++++- .../fmod_int64/fsundomeigest_arnoldi_mod.c | 178 +++++++++- .../fmod_int64/fsundomeigest_arnoldi_mod.f90 | 330 +++++++++++++++++- 15 files changed, 1217 insertions(+), 32 deletions(-) diff --git a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp index 252f93ff92..cae989c9fe 100644 --- a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp @@ -42,6 +42,9 @@ m.def("LSRKStepSetMaxNumStages", LSRKStepSetMaxNumStages, nb::arg("arkode_mem"), m.def("LSRKStepSetDomEigSafetyFactor", LSRKStepSetDomEigSafetyFactor, nb::arg("arkode_mem"), nb::arg("dom_eig_safety")); +m.def("LSRKStepSetUseAnalyticStabRegion", LSRKStepSetUseAnalyticStabRegion, + nb::arg("arkode_mem"), nb::arg("analytic_stab_region")); + m.def("LSRKStepSetNumDomEigEstInitPreprocessIters", LSRKStepSetNumDomEigEstInitPreprocessIters, nb::arg("arkode_mem"), nb::arg("num_iters")); diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index c39c1575db..5df6787084 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -16,6 +16,12 @@ auto pyClassSUNDomEigEstimator_ = .def(nb::init<>()) // implicit default constructor ; +m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), + nb::arg("rhs_data"), nb::arg("RHSfn")); + +m.def("SUNDomEigEstimator_SetRHSLinearizationVector", + SUNDomEigEstimator_SetRHSLinearizationVector, nb::arg("DEE"), nb::arg("v")); + m.def("SUNDomEigEstimator_SetMaxIters", SUNDomEigEstimator_SetMaxIters, nb::arg("DEE"), nb::arg("max_iters")); diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 996531f676..5721225c69 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -32,6 +32,16 @@ m.def( }, nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); + +m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, + nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); + +m.def("SUNDomEigEstimator_SetRHSLinearizationVector_Power", + SUNDomEigEstimator_SetRHSLinearizationVector_Power, nb::arg("DEE"), + nb::arg("v")); + +m.def("SUNDomEigEstimator_SetDEEisReal_Power", + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus // // #endif diff --git a/src/arkode/fmod_int32/farkode_lsrkstep_mod.c b/src/arkode/fmod_int32/farkode_lsrkstep_mod.c index 6b83da3c65..95b9a8f923 100644 --- a/src/arkode/fmod_int32/farkode_lsrkstep_mod.c +++ b/src/arkode/fmod_int32/farkode_lsrkstep_mod.c @@ -431,7 +431,7 @@ SWIGEXPORT int _wrap_FLSRKStepSetDomEigSafetyFactor(void *farg1, double const *f } -SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const *farg2) { +SWIGEXPORT int _wrap_FLSRKStepSetUseAnalyticStabRegion(void *farg1, int const *farg2) { int fresult ; void *arg1 = (void *) 0 ; int arg2 ; @@ -439,7 +439,7 @@ SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const * arg1 = (void *)(farg1); arg2 = (int)(*farg2); - result = (int)LSRKStepSetUseEllipseForStability(arg1,arg2); + result = (int)LSRKStepSetUseAnalyticStabRegion(arg1,arg2); fresult = (int)(result); return fresult; } diff --git a/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 b/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 index 51bc46718a..ec7392a5ac 100644 --- a/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 +++ b/src/arkode/fmod_int32/farkode_lsrkstep_mod.f90 @@ -56,7 +56,7 @@ module farkode_lsrkstep_mod public :: FLSRKStepSetDomEigFrequency public :: FLSRKStepSetMaxNumStages public :: FLSRKStepSetDomEigSafetyFactor - public :: FLSRKStepSetUseEllipseForStability + public :: FLSRKStepSetUseAnalyticStabRegion public :: FLSRKStepSetNumDomEigEstInitPreprocessIters public :: FLSRKStepSetNumDomEigEstPreprocessIters public :: FLSRKStepSetNumSSPStages @@ -194,8 +194,8 @@ function swigc_FLSRKStepSetDomEigSafetyFactor(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) & -bind(C, name="_wrap_FLSRKStepSetUseEllipseForStability") & +function swigc_FLSRKStepSetUseAnalyticStabRegion(farg1, farg2) & +bind(C, name="_wrap_FLSRKStepSetUseAnalyticStabRegion") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -523,19 +523,19 @@ function FLSRKStepSetDomEigSafetyFactor(arkode_mem, dom_eig_safety) & swig_result = fresult end function -function FLSRKStepSetUseEllipseForStability(arkode_mem, use_ellipse) & +function FLSRKStepSetUseAnalyticStabRegion(arkode_mem, analytic_stab_region) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -integer(C_INT), intent(in) :: use_ellipse +integer(C_INT), intent(in) :: analytic_stab_region integer(C_INT) :: fresult type(C_PTR) :: farg1 integer(C_INT) :: farg2 farg1 = arkode_mem -farg2 = use_ellipse -fresult = swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) +farg2 = analytic_stab_region +fresult = swigc_FLSRKStepSetUseAnalyticStabRegion(farg1, farg2) swig_result = fresult end function diff --git a/src/arkode/fmod_int64/farkode_lsrkstep_mod.c b/src/arkode/fmod_int64/farkode_lsrkstep_mod.c index 6b83da3c65..95b9a8f923 100644 --- a/src/arkode/fmod_int64/farkode_lsrkstep_mod.c +++ b/src/arkode/fmod_int64/farkode_lsrkstep_mod.c @@ -431,7 +431,7 @@ SWIGEXPORT int _wrap_FLSRKStepSetDomEigSafetyFactor(void *farg1, double const *f } -SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const *farg2) { +SWIGEXPORT int _wrap_FLSRKStepSetUseAnalyticStabRegion(void *farg1, int const *farg2) { int fresult ; void *arg1 = (void *) 0 ; int arg2 ; @@ -439,7 +439,7 @@ SWIGEXPORT int _wrap_FLSRKStepSetUseEllipseForStability(void *farg1, int const * arg1 = (void *)(farg1); arg2 = (int)(*farg2); - result = (int)LSRKStepSetUseEllipseForStability(arg1,arg2); + result = (int)LSRKStepSetUseAnalyticStabRegion(arg1,arg2); fresult = (int)(result); return fresult; } diff --git a/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 b/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 index 51bc46718a..ec7392a5ac 100644 --- a/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 +++ b/src/arkode/fmod_int64/farkode_lsrkstep_mod.f90 @@ -56,7 +56,7 @@ module farkode_lsrkstep_mod public :: FLSRKStepSetDomEigFrequency public :: FLSRKStepSetMaxNumStages public :: FLSRKStepSetDomEigSafetyFactor - public :: FLSRKStepSetUseEllipseForStability + public :: FLSRKStepSetUseAnalyticStabRegion public :: FLSRKStepSetNumDomEigEstInitPreprocessIters public :: FLSRKStepSetNumDomEigEstPreprocessIters public :: FLSRKStepSetNumSSPStages @@ -194,8 +194,8 @@ function swigc_FLSRKStepSetDomEigSafetyFactor(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) & -bind(C, name="_wrap_FLSRKStepSetUseEllipseForStability") & +function swigc_FLSRKStepSetUseAnalyticStabRegion(farg1, farg2) & +bind(C, name="_wrap_FLSRKStepSetUseAnalyticStabRegion") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -523,19 +523,19 @@ function FLSRKStepSetDomEigSafetyFactor(arkode_mem, dom_eig_safety) & swig_result = fresult end function -function FLSRKStepSetUseEllipseForStability(arkode_mem, use_ellipse) & +function FLSRKStepSetUseAnalyticStabRegion(arkode_mem, analytic_stab_region) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(C_PTR) :: arkode_mem -integer(C_INT), intent(in) :: use_ellipse +integer(C_INT), intent(in) :: analytic_stab_region integer(C_INT) :: fresult type(C_PTR) :: farg1 integer(C_INT) :: farg2 farg1 = arkode_mem -farg2 = use_ellipse -fresult = swigc_FLSRKStepSetUseEllipseForStability(farg1, farg2) +farg2 = analytic_stab_region +fresult = swigc_FLSRKStepSetUseAnalyticStabRegion(farg1, farg2) swig_result = fresult end function diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 4f3fb2ec1a..4087e2d50d 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -3800,6 +3800,36 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + void *arg2 = (void *) 0 ; + DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (void *)(farg2); + arg3 = (DEERhsFn)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHS(arg1,arg2,arg3); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator farg1, N_Vector farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (N_Vector)(farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetMaxIters(SUNDomEigEstimator farg1, long const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 152bd0b5d0..7e585242ad 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -683,9 +683,12 @@ module fsundials_core_mod public :: FSUNAdjointStepper_GetNumRecompute public :: FSUNAdjointStepper_PrintAllStats public :: FSUNAdjointStepper_Destroy + integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT ! struct struct SUNDomEigEstimator_Ops_ type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes + type(C_FUNPTR), public :: setrhs + type(C_FUNPTR), public :: setrhslinearizationvector type(C_FUNPTR), public :: setoptions type(C_FUNPTR), public :: setmaxiters type(C_FUNPTR), public :: setnumpreprocessiters @@ -709,6 +712,8 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_NewEmpty public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes + public :: FSUNDomEigEstimator_SetRHS + public :: FSUNDomEigEstimator_SetRHSLinearizationVector public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2935,6 +2940,25 @@ function swigc_FSUNDomEigEstimator_SetATimes(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector") & +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_FSUNDomEigEstimator_SetMaxIters(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetMaxIters") & result(fresult) @@ -7125,6 +7149,41 @@ function FSUNDomEigEstimator_SetATimes(dee, a_data, atimes) & swig_result = fresult end function +function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(C_PTR) :: rhs_data +type(C_FUNPTR), intent(in), value :: rhsfn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = c_loc(dee) +farg2 = rhs_data +farg3 = rhsfn +fresult = swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) +swig_result = fresult +end function + +function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(N_Vector), target, intent(inout) :: v +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = c_loc(dee) +farg2 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetMaxIters(dee, max_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 0a21360f9b..c2f7cac137 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -3800,6 +3800,36 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + void *arg2 = (void *) 0 ; + DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (void *)(farg2); + arg3 = (DEERhsFn)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHS(arg1,arg2,arg3); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator farg1, N_Vector farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (N_Vector)(farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetMaxIters(SUNDomEigEstimator farg1, long const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 593e9cb190..334be73d43 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -683,9 +683,12 @@ module fsundials_core_mod public :: FSUNAdjointStepper_GetNumRecompute public :: FSUNAdjointStepper_PrintAllStats public :: FSUNAdjointStepper_Destroy + integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT ! struct struct SUNDomEigEstimator_Ops_ type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes + type(C_FUNPTR), public :: setrhs + type(C_FUNPTR), public :: setrhslinearizationvector type(C_FUNPTR), public :: setoptions type(C_FUNPTR), public :: setmaxiters type(C_FUNPTR), public :: setnumpreprocessiters @@ -709,6 +712,8 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_NewEmpty public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes + public :: FSUNDomEigEstimator_SetRHS + public :: FSUNDomEigEstimator_SetRHSLinearizationVector public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2935,6 +2940,25 @@ function swigc_FSUNDomEigEstimator_SetATimes(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector") & +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_FSUNDomEigEstimator_SetMaxIters(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetMaxIters") & result(fresult) @@ -7125,6 +7149,41 @@ function FSUNDomEigEstimator_SetATimes(dee, a_data, atimes) & swig_result = fresult end function +function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(C_PTR) :: rhs_data +type(C_FUNPTR), intent(in), value :: rhsfn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = c_loc(dee) +farg2 = rhs_data +farg3 = rhsfn +fresult = swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) +swig_result = fresult +end function + +function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(N_Vector), target, intent(inout) :: v +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = c_loc(dee) +farg2 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetMaxIters(dee, max_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index cd530e4a96..0fae4ded0a 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -396,6 +396,78 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__q_get(SwigClassWrap } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->rhs_linV = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->rhs_linV); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->Fv = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->Fv); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__work_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::work", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->work = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__work_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::work", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->work); + fresult = result; + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(SwigClassWrapper const *farg1, int const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; int arg2 ; @@ -540,6 +612,78 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(SwigClas } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, DEERhsFn farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + DEERhsFn arg2 = (DEERhsFn) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (DEERhsFn)(farg2); + if (arg1) (arg1)->rhsfn = arg2; +} + + +SWIGEXPORT DEERhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { + DEERhsFn fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + DEERhsFn result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (DEERhsFn) ((arg1)->rhsfn); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(SwigClassWrapper const *farg1, void *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + void *arg2 = (void *) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_data", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (void *)(farg2); + if (arg1) (arg1)->rhs_data = arg2; +} + + +SWIGEXPORT void * _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(SwigClassWrapper const *farg1) { + void * fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + void *result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_data", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (void *) ((arg1)->rhs_data); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(SwigClassWrapper const *farg1, long const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + long arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::nfevals", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (long)(*farg2); + if (arg1) (arg1)->nfevals = arg2; +} + + +SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(SwigClassWrapper const *farg1) { + long fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + long result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::nfevals", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (long) ((arg1)->nfevals); + fresult = (long)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(SwigClassWrapper const *farg1, double *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; sunrealtype *arg2 = (sunrealtype *) 0 ; @@ -771,6 +915,36 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + void *arg2 = (void *) 0 ; + DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (void *)(farg2); + arg3 = (DEERhsFn)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHS_Arnoldi(arg1,arg2,arg3); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (N_Vector)(farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, int const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; @@ -785,7 +959,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEig } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -793,7 +967,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEig arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRelTol_Arnoldi(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index 72b4d805df..29a7ed4b56 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -48,6 +48,12 @@ module fsundomeigest_arnoldi_mod procedure :: get_V => swigf_SUNDomEigEstimatorContent_Arnoldi__V_get procedure :: set_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_set procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get + procedure :: set_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set + procedure :: get_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get + procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set + procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get + procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set + procedure :: get_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_get procedure :: set_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set procedure :: get_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_get procedure :: set_num_warmups => swigf_SUNDomEigEstimatorContent_Arnoldi__num_warmups_set @@ -60,6 +66,12 @@ module fsundomeigest_arnoldi_mod procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get + procedure :: set_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set + procedure :: get_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get + procedure :: set_rhs_data => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set + procedure :: get_rhs_data => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get + procedure :: set_nfevals => swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_set + procedure :: get_nfevals => swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_get procedure :: set_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set procedure :: get_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_get procedure :: set_LAPACK_wr => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_wr_set @@ -83,8 +95,10 @@ module fsundomeigest_arnoldi_mod end interface public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi + public :: FSUNDomEigEstimator_SetRHS_Arnoldi + public :: FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi - public :: FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi + public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi public :: FSUNDomEigEstimator_Initialize_Arnoldi public :: FSUNDomEigEstimator_Estimate_Arnoldi @@ -163,6 +177,57 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__q_get(farg1) & type(C_PTR) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__work_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__work_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__work_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__work_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set") use, intrinsic :: ISO_C_BINDING @@ -265,6 +330,57 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(farg1) & integer(C_LONG) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_LONG), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_LONG) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set") use, intrinsic :: ISO_C_BINDING @@ -427,6 +543,25 @@ function swigc_FSUNDomEigEstimator_SetATimes_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS_Arnoldi") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi") & +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_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi") & result(fresult) @@ -436,8 +571,8 @@ function swigc_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRelTol_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRelTol_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -612,6 +747,81 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(self, rhs_linv) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: rhs_linv +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(rhs_linv) +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set(self, fv) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: fv +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(fv) +call swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__work_set(self, work) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: work +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(work) +call swigc_SUNDomEigEstimatorContent_Arnoldi__work_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__work_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__work_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(self, kry_dim) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -762,6 +972,81 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(self, rhsfn) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_FUNPTR), intent(in), value :: rhsfn +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR) :: farg2 + +farg1 = self%swigdata +farg2 = rhsfn +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_FUNPTR) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_FUNPTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(self, rhs_data) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: rhs_data +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = rhs_data +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(self, nfevals) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_LONG), intent(in) :: nfevals +type(SwigClassWrapper) :: farg1 +integer(C_LONG) :: farg2 + +farg1 = self%swigdata +farg2 = nfevals +call swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_LONG) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_LONG) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(self, lapack_a) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -1012,6 +1297,41 @@ function FSUNDomEigEstimator_SetATimes_Arnoldi(dee, a_data, atimes) & swig_result = fresult end function +function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(C_PTR) :: rhs_data +type(C_FUNPTR), intent(in), value :: rhsfn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = c_loc(dee) +farg2 = rhs_data +farg3 = rhsfn +fresult = swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) +swig_result = fresult +end function + +function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(N_Vector), target, intent(inout) :: v +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = c_loc(dee) +farg2 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -1028,7 +1348,7 @@ function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & swig_result = fresult end function -function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & +function FSUNDomEigEstimator_SetRelTol_Arnoldi(dee, tol) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1040,7 +1360,7 @@ function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & farg1 = c_loc(dee) farg2 = tol -fresult = swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRelTol_Arnoldi(farg1, farg2) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index e7a3195a9e..58223556f3 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -396,6 +396,78 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__q_get(SwigClassWrap } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->rhs_linV = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->rhs_linV); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->Fv = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->Fv); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__work_set(SwigClassWrapper const *farg1, N_Vector farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::work", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (N_Vector)(farg2); + if (arg1) (arg1)->work = arg2; +} + + +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__work_get(SwigClassWrapper const *farg1) { + N_Vector fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + N_Vector result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::work", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (N_Vector) ((arg1)->work); + fresult = result; + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(SwigClassWrapper const *farg1, int const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; int arg2 ; @@ -540,6 +612,78 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(SwigClas } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, DEERhsFn farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + DEERhsFn arg2 = (DEERhsFn) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (DEERhsFn)(farg2); + if (arg1) (arg1)->rhsfn = arg2; +} + + +SWIGEXPORT DEERhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { + DEERhsFn fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + DEERhsFn result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (DEERhsFn) ((arg1)->rhsfn); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(SwigClassWrapper const *farg1, void *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + void *arg2 = (void *) 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_data", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (void *)(farg2); + if (arg1) (arg1)->rhs_data = arg2; +} + + +SWIGEXPORT void * _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(SwigClassWrapper const *farg1) { + void * fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + void *result = 0 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_data", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (void *) ((arg1)->rhs_data); + fresult = result; + return fresult; +} + + +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(SwigClassWrapper const *farg1, long const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + long arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::nfevals", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (long)(*farg2); + if (arg1) (arg1)->nfevals = arg2; +} + + +SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(SwigClassWrapper const *farg1) { + long fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + long result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::nfevals", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (long) ((arg1)->nfevals); + fresult = (long)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(SwigClassWrapper const *farg1, double *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; sunrealtype *arg2 = (sunrealtype *) 0 ; @@ -771,6 +915,36 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + void *arg2 = (void *) 0 ; + DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (void *)(farg2); + arg3 = (DEERhsFn)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHS_Arnoldi(arg1,arg2,arg3); + fresult = (SUNErrCode)(result); + return fresult; +} + + +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { + int fresult ; + SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; + N_Vector arg2 = (N_Vector) 0 ; + SUNErrCode result; + + arg1 = (SUNDomEigEstimator)(farg1); + arg2 = (N_Vector)(farg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(arg1,arg2); + fresult = (SUNErrCode)(result); + return fresult; +} + + SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, int const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; @@ -785,7 +959,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEig } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator farg1, double const *farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -793,7 +967,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(SUNDomEig arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRelTol_Arnoldi(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index f51786e2ee..109ccdeb03 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -48,6 +48,12 @@ module fsundomeigest_arnoldi_mod procedure :: get_V => swigf_SUNDomEigEstimatorContent_Arnoldi__V_get procedure :: set_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_set procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get + procedure :: set_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set + procedure :: get_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get + procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set + procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get + procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set + procedure :: get_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_get procedure :: set_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set procedure :: get_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_get procedure :: set_num_warmups => swigf_SUNDomEigEstimatorContent_Arnoldi__num_warmups_set @@ -60,6 +66,12 @@ module fsundomeigest_arnoldi_mod procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get + procedure :: set_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set + procedure :: get_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get + procedure :: set_rhs_data => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set + procedure :: get_rhs_data => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get + procedure :: set_nfevals => swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_set + procedure :: get_nfevals => swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_get procedure :: set_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set procedure :: get_LAPACK_A => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_get procedure :: set_LAPACK_wr => swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_wr_set @@ -83,8 +95,10 @@ module fsundomeigest_arnoldi_mod end interface public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi + public :: FSUNDomEigEstimator_SetRHS_Arnoldi + public :: FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi - public :: FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi + public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi public :: FSUNDomEigEstimator_Initialize_Arnoldi public :: FSUNDomEigEstimator_Estimate_Arnoldi @@ -163,6 +177,57 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__q_get(farg1) & type(C_PTR) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__work_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__work_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__work_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__work_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set") use, intrinsic :: ISO_C_BINDING @@ -265,6 +330,57 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(farg1) & integer(C_LONG) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR), value :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: fresult +end function + +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_LONG), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__nfevals_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +integer(C_LONG) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set") use, intrinsic :: ISO_C_BINDING @@ -427,6 +543,25 @@ function swigc_FSUNDomEigEstimator_SetATimes_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function +function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS_Arnoldi") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +type(C_PTR), value :: farg1 +type(C_PTR), value :: farg2 +type(C_FUNPTR), value :: farg3 +integer(C_INT) :: fresult +end function + +function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi") & +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_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & bind(C, name="_wrap_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi") & result(fresult) @@ -436,8 +571,8 @@ function swigc_FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(farg1, farg2) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRelTol_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRelTol_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -612,6 +747,81 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(self, rhs_linv) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: rhs_linv +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(rhs_linv) +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set(self, fv) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: fv +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(fv) +call swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__work_set(self, work) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(N_Vector), target, intent(inout) :: work +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = c_loc(work) +call swigc_SUNDomEigEstimatorContent_Arnoldi__work_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__work_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(N_Vector), pointer :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__work_get(farg1) +call c_f_pointer(fresult, swig_result) +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set(self, kry_dim) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -762,6 +972,81 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(self, rhsfn) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_FUNPTR), intent(in), value :: rhsfn +type(SwigClassWrapper) :: farg1 +type(C_FUNPTR) :: farg2 + +farg1 = self%swigdata +farg2 = rhsfn +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_FUNPTR) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_FUNPTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(self, rhs_data) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: rhs_data +type(SwigClassWrapper) :: farg1 +type(C_PTR) :: farg2 + +farg1 = self%swigdata +farg2 = rhs_data +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +type(C_PTR) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +type(C_PTR) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_data_get(farg1) +swig_result = fresult +end function + +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(self, nfevals) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_LONG), intent(in) :: nfevals +type(SwigClassWrapper) :: farg1 +integer(C_LONG) :: farg2 + +farg1 = self%swigdata +farg2 = nfevals +call swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_LONG) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +integer(C_LONG) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__nfevals_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__LAPACK_A_set(self, lapack_a) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -1012,6 +1297,41 @@ function FSUNDomEigEstimator_SetATimes_Arnoldi(dee, a_data, atimes) & swig_result = fresult end function +function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(C_PTR) :: rhs_data +type(C_FUNPTR), intent(in), value :: rhsfn +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 +type(C_FUNPTR) :: farg3 + +farg1 = c_loc(dee) +farg2 = rhs_data +farg3 = rhsfn +fresult = swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) +swig_result = fresult +end function + +function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +integer(C_INT) :: swig_result +type(SUNDomEigEstimator), target, intent(inout) :: dee +type(N_Vector), target, intent(inout) :: v +integer(C_INT) :: fresult +type(C_PTR) :: farg1 +type(C_PTR) :: farg2 + +farg1 = c_loc(dee) +farg2 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) +swig_result = fresult +end function + function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & result(swig_result) use, intrinsic :: ISO_C_BINDING @@ -1028,7 +1348,7 @@ function FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(dee, num_iters) & swig_result = fresult end function -function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & +function FSUNDomEigEstimator_SetRelTol_Arnoldi(dee, tol) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1040,7 +1360,7 @@ function FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(dee, tol) & farg1 = c_loc(dee) farg2 = tol -fresult = swigc_FSUNDomEigEstimator_SetTolPreprocessIters_Arnoldi(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRelTol_Arnoldi(farg1, farg2) swig_result = fresult end function From 91913db7187f40327aff353e386a32ed0b5d4975 Mon Sep 17 00:00:00 2001 From: maggul Date: Sat, 14 Mar 2026 17:52:10 -0500 Subject: [PATCH 21/76] revision --- .../sundials_domeigestimator_generated.hpp | 4 +- .../sundomeigest_power_generated.hpp | 4 +- .../ark_brusselator_lsrk_externaldomeigest.c | 29 +---- examples/arkode/C_serial/ark_heat1D_adapt.out | 117 +++++++++--------- include/sundials/sundials_domeigestimator.h | 9 +- include/sundomeigest/sundomeigest_arnoldi.h | 8 +- include/sundomeigest/sundomeigest_power.h | 8 +- src/sundials/fmod_int32/fsundials_core_mod.c | 4 +- .../fmod_int32/fsundials_core_mod.f90 | 12 +- src/sundials/fmod_int64/fsundials_core_mod.c | 4 +- .../fmod_int64/fsundials_core_mod.f90 | 12 +- src/sundials/sundials_domeigestimator.c | 8 +- .../fmod_int32/fsundomeigest_arnoldi_mod.c | 16 +-- .../fmod_int32/fsundomeigest_arnoldi_mod.f90 | 34 ++--- .../fmod_int64/fsundomeigest_arnoldi_mod.c | 16 +-- .../fmod_int64/fsundomeigest_arnoldi_mod.f90 | 34 ++--- .../arnoldi/sundomeigest_arnoldi.c | 61 +++++---- src/sundomeigest/power/sundomeigest_power.c | 61 +++++---- .../Arnoldi/test_sundomeigest_arnoldi.c | 2 +- 19 files changed, 228 insertions(+), 215 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index 5df6787084..d95fef74f5 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -19,8 +19,8 @@ auto pyClassSUNDomEigEstimator_ = m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); -m.def("SUNDomEigEstimator_SetRHSLinearizationVector", - SUNDomEigEstimator_SetRHSLinearizationVector, nb::arg("DEE"), nb::arg("v")); +m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", + SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("v")); m.def("SUNDomEigEstimator_SetMaxIters", SUNDomEigEstimator_SetMaxIters, nb::arg("DEE"), nb::arg("max_iters")); diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 5721225c69..e78db1afc4 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -36,8 +36,8 @@ m.def( m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); -m.def("SUNDomEigEstimator_SetRHSLinearizationVector_Power", - SUNDomEigEstimator_SetRHSLinearizationVector_Power, nb::arg("DEE"), +m.def("SUNDomEigEstimator_SetRHSLinearizationPoint_Power", + SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), nb::arg("v")); m.def("SUNDomEigEstimator_SetDEEisReal_Power", diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 43e8240569..54a187a6f4 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -80,9 +80,6 @@ /* User-supplied Functions Called by the Solver */ static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); -/* steady f at a given time for dominant eigenvalue estimation */ -static int fstead(N_Vector y, N_Vector ydot, void* user_data); - /* User-supplied Dominated Eigenvalue Called by the Solver */ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, sunrealtype* lambdaI, void* user_data, N_Vector temp1, @@ -96,7 +93,6 @@ typedef struct { SUNContext ctx; sunrealtype rdata[3]; - sunrealtype curent_time; SUNDomEigEstimator DEE; sunrealtype rel_tol; sunindextype max_iters; @@ -179,7 +175,6 @@ int main(int argc, char* argv[]) ProbData.rel_tol = SUN_RCONST(5.0e-3); ProbData.max_iters = 100; ProbData.numwarmup = 10; - ProbData.curent_time = T0; y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } NV_Ith_S(y, 0) = u0; /* Set initial conditions */ @@ -318,17 +313,6 @@ static int f(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data) return 0; /* Return with success */ } -/* steady f at a given time for dominant eigenvalue estimation */ -static int fstead(N_Vector y, N_Vector ydot, void* user_data) -{ - UserData* data = (UserData*)user_data; /* cast user_data to UserData */ - sunrealtype t = data->curent_time; /* access current time from UserData */ - - f(t, y, ydot, user_data); - - return 0; /* Return with success */ -} - /* dom_eig routine to estimate the dominated eigenvalue */ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, sunrealtype* lambdaI, void* user_data, N_Vector temp1, @@ -336,7 +320,6 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, { int flag; UserData* data = (UserData*)user_data; /* cast user_data to UserData */ - data->curent_time = t; /* update current time in UserData */ SUNContext ctx = data->ctx; /* access context from UserData */ SUNDomEigEstimator DEE = data->DEE; /* access DEE from UserData */ @@ -356,12 +339,12 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, if (check_flag(DEE, "SUNDomEigEstimator_Power", 0)) { return 1; } /* Set the ODE right-hand side function at t for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHS(DEE, user_data, fstead); + flag = SUNDomEigEstimator_SetRHS(DEE, user_data, f); if (check_flag(&flag, "SUNDomEigEstimator_SetRHS", 1)) { return 1; } /* Set the linearization vector for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) + flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); // set the time t as well + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) { return 1; } @@ -376,9 +359,9 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, if (check_flag(&flag, "SUNDomEigEstimator_Initialize", 1)) { return 1; } } - /* Update the linearization vector for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationVector(DEE, y); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationVector", 1)) + /* Update the linearization vector and time for the Jacobian-vector products */ + flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); + if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) { return 1; } diff --git a/examples/arkode/C_serial/ark_heat1D_adapt.out b/examples/arkode/C_serial/ark_heat1D_adapt.out index e6038fc3be..22318e1d33 100644 --- a/examples/arkode/C_serial/ark_heat1D_adapt.out +++ b/examples/arkode/C_serial/ark_heat1D_adapt.out @@ -9,62 +9,67 @@ 2 3.629021901461023e-08 7.258043802922046e-07 2.979456598576975e-08 21 5 7 3 7.258043802922046e-07 1.451608760584409e-05 6.255954438851742e-07 21 5 10 4 1.451608760584409e-05 2.903217521168818e-04 1.252930976498461e-05 21 5 15 - 5 2.903217521168818e-04 6.126068069778898e-04 2.459838644186664e-04 21 5 25 - 6 6.126068069778898e-04 9.290787020628659e-04 7.144322430964959e-04 21 5 32 - 7 9.290787020628659e-04 1.489561505368306e-03 1.379420423280460e-03 21 5 35 - 8 1.489561505368306e-03 2.325159614097548e-03 2.469259985973726e-03 23 5 52 - 9 2.325159614097548e-03 3.361999740396916e-03 4.371341102713385e-03 25 5 57 - 10 3.361999740396916e-03 6.201055294512209e-03 6.521135930410380e-03 25 5 54 - 11 6.201055294512209e-03 1.418650069539443e-02 9.936752057635235e-03 25 5 67 - 12 1.418650069539443e-02 2.333213441555008e-02 1.585365842114031e-02 31 5 105 - 13 2.333213441555008e-02 4.406570962019823e-02 2.310185354591553e-02 35 5 105 - 14 2.008717179820959e-02 2.008717179820959e-02 2.619889986889061e-02 39 10 210 - 15 8.346522811620464e-03 7.516706023047939e-03 2.618935131509393e-02 45 10 210 - 16 7.516706023047939e-03 1.495982035074134e-02 2.605945023323194e-02 49 5 105 - 17 1.111835094428806e-02 1.043206929750673e-02 2.680310543767818e-02 51 10 210 - 18 1.043206929750673e-02 1.509912815975813e-02 2.757588323574690e-02 51 5 105 - 19 2.230665125977254e-03 2.230665125977254e-03 2.882948365478040e-02 55 15 315 - 20 2.230665125977254e-03 1.531517453472657e-02 2.897539770462856e-02 55 5 103 - 21 1.531517453472657e-02 1.649126444481822e-02 2.983825560863861e-02 55 5 105 - 22 9.196187820414967e-03 9.196187820414967e-03 2.946262498296182e-02 60 10 210 - 23 9.196187820414967e-03 3.036135590208354e-02 2.934957847587715e-02 62 5 105 - 24 3.036135590208354e-02 2.824109528142596e-02 3.019083663918624e-02 62 5 105 - 25 5.767357365903751e-03 5.767357365903751e-03 3.031100857768801e-02 62 15 315 - 26 5.767357365903751e-03 3.181338676737989e-02 3.042185345764588e-02 62 5 105 - 27 3.181338676737989e-02 4.544743555056333e-02 3.089848026181038e-02 62 5 105 - 28 1.136185888764083e-02 1.136185888764083e-02 3.102713583604160e-02 62 6 126 - 29 1.136185888764083e-02 1.101971236076085e-02 3.111573737276951e-02 62 5 105 - 30 1.101971236076085e-02 2.032915619754837e-02 3.121556348208696e-02 62 5 105 - 31 1.810888029400946e-02 1.810888029400946e-02 3.135670708815374e-02 62 10 210 - 32 1.810888029400946e-02 2.234029750896407e-02 3.148115671516088e-02 62 5 105 - 33 2.234029750896407e-02 2.889109188475510e-02 3.160878025037404e-02 62 5 105 - 34 2.889109188475510e-02 3.120042409187010e-02 3.173412977265944e-02 62 5 105 - 35 7.800106022967526e-03 7.800106022967526e-03 3.176464043664869e-02 62 8 168 - 36 7.800106022967526e-03 3.170037066227539e-02 3.179375653346459e-02 62 5 105 - 37 3.170037066227539e-02 3.787213092748833e-02 3.189887295603718e-02 62 5 105 - 38 2.837355332913126e-02 2.837355332913126e-02 3.197801883167253e-02 62 10 210 - 39 2.837355332913126e-02 3.278446668151765e-02 3.204779178298942e-02 62 5 105 - 40 3.278446668151765e-02 3.020564177204807e-02 3.211240653324073e-02 62 5 105 - 41 7.551410443012017e-03 7.551410443012017e-03 3.212626059266561e-02 62 8 168 - 42 7.551410443012017e-03 9.178102815962437e-03 3.213890913006593e-02 62 5 105 - 43 9.178102815962437e-03 1.649464282378404e-02 3.215471668066559e-02 62 5 105 - 44 1.649464282378404e-02 2.602185028814931e-02 3.218133771973418e-02 62 5 105 - 45 1.713665707473882e-02 1.713665707473882e-02 3.220690702186930e-02 62 10 210 - 46 1.713665707473882e-02 3.530352717263601e-02 3.223040887486339e-02 62 5 105 - 47 8.825881793159003e-03 8.825881793159003e-03 3.224177338005089e-02 62 8 168 - 48 8.825881793159003e-03 2.586353802027211e-02 3.225265894426493e-02 62 5 105 - 49 2.586353802027211e-02 3.291894174702289e-02 3.228169996973265e-02 62 5 105 - 50 3.291894174702289e-02 4.048834834381512e-02 3.231625687442660e-02 62 5 105 - 51 4.048834834381512e-02 6.688543998612889e-02 3.235083603511235e-02 62 5 105 - 52 6.688543998612889e-02 6.955316324211452e-02 3.239371035449163e-02 62 5 105 - 53 6.955316324211452e-02 6.790707004153698e-02 3.243064328586971e-02 62 5 105 - 54 1.697676751038425e-02 1.697676751038425e-02 3.243617411633083e-02 62 9 189 - 55 1.697676751038425e-02 3.162563349768197e-02 3.244133298132829e-02 62 5 105 - 56 3.162563349768197e-02 4.821561406413451e-02 3.245001080654254e-02 62 5 105 - 57 4.821561406413451e-02 7.764755023495810e-02 3.246092238823795e-02 62 5 105 - 58 1.941188755873953e-02 1.941188755873953e-02 3.246445882359153e-02 62 6 126 - 59 1.941188755873953e-02 3.882377511747900e-02 3.246778727298686e-02 62 5 105 - 60 3.882377511747900e-02 3.882377511747900e-02 3.247351310624037e-02 62 5 105 + 5 2.903217521168818e-04 6.126068069781881e-04 2.459838644186664e-04 21 5 25 + 6 6.126068069781881e-04 9.290787020628410e-04 7.144322430967174e-04 21 5 32 + 7 9.290787020628410e-04 1.489561505368265e-03 1.379420423280650e-03 21 5 35 + 8 1.489561505368265e-03 2.325159614097476e-03 2.469259985973879e-03 23 5 52 + 9 2.325159614097476e-03 3.361999740397126e-03 4.371341102713489e-03 25 5 57 + 10 3.361999740397126e-03 6.201055294512660e-03 6.521135930410600e-03 25 5 54 + 11 6.201055294512660e-03 1.418650069539316e-02 9.936752057635645e-03 25 5 67 + 12 1.418650069539316e-02 2.333213441554981e-02 1.585365842114015e-02 31 5 105 + 13 2.333213441554981e-02 4.406570962017380e-02 2.310185354591536e-02 35 5 105 + 14 2.008720875364794e-02 2.008720875364794e-02 2.619890527929925e-02 39 10 210 + 15 7.612495042470456e-03 7.612495042470456e-03 2.610193126039753e-02 45 10 210 + 16 7.612495042470456e-03 1.454749389509495e-02 2.599543134042868e-02 49 5 105 + 17 1.035124260735241e-02 9.623584088096175e-03 2.668739865066598e-02 51 10 210 + 18 9.623584088096175e-03 1.808588536649627e-02 2.742440379794423e-02 51 5 105 + 19 7.662423372185243e-03 7.662423372185243e-03 2.902877933846531e-02 55 10 210 + 20 7.662423372185243e-03 7.128779196128293e-03 2.917474275029238e-02 57 5 105 + 21 7.128779196128293e-03 2.053445907774081e-02 2.954312382254983e-02 57 5 105 + 22 4.876204398547680e-03 4.876204398547680e-03 2.934121710997109e-02 59 15 315 + 23 4.876204398547680e-03 2.752514919310949e-02 2.907913475120046e-02 61 5 105 + 24 2.752514919310949e-02 4.377833231260805e-02 2.996863244315595e-02 61 5 105 + 25 5.860520609965611e-03 5.860520609965611e-03 3.011300327651581e-02 61 15 315 + 26 5.860520609965611e-03 2.122600293991792e-02 3.024518321533060e-02 61 5 105 + 27 2.122600293991792e-02 3.112837153750105e-02 3.064025813334170e-02 61 5 105 + 28 1.870342143878760e-02 1.870342143878760e-02 3.090712832903318e-02 61 10 210 + 29 1.305397332951553e-02 1.305397332951553e-02 3.105660078721369e-02 61 10 210 + 30 1.305397332951553e-02 3.913625221524024e-02 3.118619476221617e-02 61 5 105 + 31 8.923092432433761e-03 8.923092432433761e-03 3.126466431767916e-02 61 15 315 + 32 8.923092432433761e-03 5.453693279556655e-02 3.133618094903397e-02 61 5 105 + 33 5.453693279556655e-02 4.954496883018829e-02 3.168843516690587e-02 61 5 105 + 34 3.014010839536864e-02 3.014010839536864e-02 3.181338185246980e-02 61 10 210 + 35 3.014010839536864e-02 3.678555807281301e-02 3.191794712426370e-02 61 5 105 + 36 3.678555807281301e-02 3.476686530276936e-02 3.202902948330123e-02 61 5 105 + 37 3.476686530276936e-02 3.960510158166916e-02 3.210723616069101e-02 61 5 105 + 38 9.901275395417290e-03 9.901275395417290e-03 3.212754808688930e-02 61 10 210 + 39 9.901275395417290e-03 1.608611002309788e-02 3.214647303730912e-02 61 5 105 + 40 1.608611002309788e-02 1.737382001042755e-02 3.217640642946924e-02 61 5 105 + 41 5.780028939058430e-03 5.780028939058430e-03 3.218639994967080e-02 61 10 210 + 42 5.780028939058430e-03 1.978316801800984e-02 3.219614944911910e-02 61 5 105 + 43 1.978316801800984e-02 7.923920461515500e-02 3.222753929792427e-02 61 5 105 + 44 3.859752706881468e-02 3.744468647560687e-02 3.227866560109782e-02 61 10 210 + 45 9.361171618901718e-03 9.361171618901718e-03 3.229006833024283e-02 61 8 168 + 46 9.361171618901718e-03 3.048633995504502e-02 3.230111259528021e-02 61 5 105 + 47 7.621584988761255e-03 7.621584988761255e-03 3.230976204749648e-02 61 6 126 + 48 7.621584988761255e-03 2.404168804167736e-02 3.231811860211665e-02 61 5 105 + 49 6.010422010419341e-03 6.010422010419341e-03 3.232449785857627e-02 61 9 189 + 50 6.010422010419341e-03 6.453871784197467e-02 3.233069573088176e-02 61 5 88 + 51 1.613467946049367e-02 1.613467946049367e-02 3.234646577367104e-02 61 8 168 + 52 1.613467946049367e-02 7.983978031506800e-02 3.236106367911412e-02 61 5 105 + 53 1.995994507876700e-02 1.995994507876700e-02 3.237758969538931e-02 61 6 126 + 54 1.995994507876700e-02 5.327643670096720e-02 3.239264495548737e-02 61 5 105 + 55 5.327643670096720e-02 5.221342060569773e-02 3.242388384426916e-02 61 5 105 + 56 5.221342060569773e-02 6.119509641455161e-02 3.245144550640932e-02 61 5 105 + 57 6.119509641455161e-02 6.902801155300395e-02 3.247260935342249e-02 61 5 105 + 58 1.698526306192734e-02 1.698526306192734e-02 3.247810457245497e-02 61 15 315 + 59 1.698526306192734e-02 5.325036736883956e-02 3.248298741424058e-02 61 5 105 + 60 5.325036736883956e-02 6.413589159708979e-02 3.249622373085292e-02 61 5 105 + 61 1.603397289927245e-02 1.603397289927245e-02 3.249947624067350e-02 61 10 210 + 62 1.603397289927245e-02 4.028511063251124e-02 3.250248665714761e-02 61 5 105 + 63 1.007127765812781e-02 1.007127765812781e-02 3.250425876038111e-02 61 6 126 + 64 1.007127765812781e-02 2.014255531625573e-02 3.250595095364737e-02 61 5 100 + 65 2.014255531625573e-02 2.014255531625573e-02 3.250909359584335e-02 61 5 105 ---------------------------------------------------------------------------------------- Final solver statistics: Total number of time steps = 60 diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index bdff126743..b44eac9e04 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -32,7 +32,7 @@ extern "C" { #endif -typedef int (*DEERhsFn)(N_Vector y, N_Vector ydot, void* user_data); +typedef int (*DEERhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); #define MAX_DQITERS 3 /* ----------------------------------------------------------------- @@ -50,7 +50,8 @@ struct SUNDomEigEstimator_Ops_ { SUNErrCode (*setatimes)(SUNDomEigEstimator, void*, SUNATimesFn); SUNErrCode (*setrhs)(SUNDomEigEstimator, void*, DEERhsFn); - SUNErrCode (*setrhslinearizationvector)(SUNDomEigEstimator, N_Vector); + SUNErrCode (*setrhslinearizationpoint)(SUNDomEigEstimator, sunrealtype, + N_Vector); SUNErrCode (*setoptions)(SUNDomEigEstimator DEE, const char* Did, const char* file_name, int argc, char* argv[]); SUNErrCode (*setmaxiters)(SUNDomEigEstimator, long int); @@ -96,8 +97,8 @@ SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, - N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator DEE, + sunrealtype t, N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetOptions(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index c76454528b..30c99818f3 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -43,7 +43,7 @@ struct SUNDomEigEstimatorContent_Arnoldi_ /* Krylov subspace vectors */ N_Vector* V; - N_Vector q, rhs_linV, Fv, work; + N_Vector q, rhs_linY, Fy, work; int kry_dim; /* Krylov subspace dimension */ int num_warmups; /* Number of preprocessing iterations */ @@ -51,6 +51,8 @@ struct SUNDomEigEstimatorContent_Arnoldi_ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ + sunrealtype rhs_linT; /* Linearization time for the RHS function */ + long int num_ATimes; /* Number of ATimes calls */ DEERhsFn rhsfn; /* User provided RHS function */ @@ -86,8 +88,8 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi( - SUNDomEigEstimator DEE, N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi( + SUNDomEigEstimator DEE, sunrealtype t, N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index db973e4fff..f8ee398f59 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -41,13 +41,15 @@ struct SUNDomEigEstimatorContent_Power_ SUNATimesFn ATimes; /* User provided ATimes function */ void* ATdata; /* ATimes function data*/ - N_Vector V, q, q_prev, rhs_linV, Fv, work; /* workspace vectors */ + N_Vector V, q, q_prev, rhs_linY, Fy, work; /* workspace vectors */ int num_warmups; /* Number of preprocessing iterations */ long int max_iters; /* Maximum number of power iterations */ long int num_iters; /* Number of iterations in last Estimate call */ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ + sunrealtype rhs_linT; /* Linearization time for the RHS function */ + long int num_ATimes; /* Number of ATimes calls */ sunrealtype rel_tol; /* Convergence criteria for the power iteration */ @@ -96,8 +98,8 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, - N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power(SUNDomEigEstimator DEE, + sunrealtype t, N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 4087e2d50d..85c8acfe22 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -3816,7 +3816,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; N_Vector arg2 = (N_Vector) 0 ; @@ -3824,7 +3824,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEsti arg1 = (SUNDomEigEstimator)(farg1); arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 7e585242ad..83522b0344 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -688,7 +688,7 @@ module fsundials_core_mod type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes type(C_FUNPTR), public :: setrhs - type(C_FUNPTR), public :: setrhslinearizationvector + type(C_FUNPTR), public :: setrhslinearizationpoint type(C_FUNPTR), public :: setoptions type(C_FUNPTR), public :: setmaxiters type(C_FUNPTR), public :: setnumpreprocessiters @@ -713,7 +713,7 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes public :: FSUNDomEigEstimator_SetRHS - public :: FSUNDomEigEstimator_SetRHSLinearizationVector + public :: FSUNDomEigEstimator_SetRHSLinearizationPoint public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2950,8 +2950,8 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector") & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -7168,7 +7168,7 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7180,7 +7180,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & farg1 = c_loc(dee) farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) swig_result = fresult end function diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index c2f7cac137..8121d51752 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -3816,7 +3816,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; N_Vector arg2 = (N_Vector) 0 ; @@ -3824,7 +3824,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEsti arg1 = (SUNDomEigEstimator)(farg1); arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 334be73d43..c6feeacd5c 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -688,7 +688,7 @@ module fsundials_core_mod type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes type(C_FUNPTR), public :: setrhs - type(C_FUNPTR), public :: setrhslinearizationvector + type(C_FUNPTR), public :: setrhslinearizationpoint type(C_FUNPTR), public :: setoptions type(C_FUNPTR), public :: setmaxiters type(C_FUNPTR), public :: setnumpreprocessiters @@ -713,7 +713,7 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes public :: FSUNDomEigEstimator_SetRHS - public :: FSUNDomEigEstimator_SetRHSLinearizationVector + public :: FSUNDomEigEstimator_SetRHSLinearizationPoint public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2950,8 +2950,8 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector") & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -7168,7 +7168,7 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7180,7 +7180,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationVector(dee, v) & farg1 = c_loc(dee) farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) swig_result = fresult end function diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index a50a94f794..4db11c3916 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -204,14 +204,14 @@ SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, return (ier); } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector(SUNDomEigEstimator DEE, - N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator DEE, + sunrealtype t, N_Vector v) { SUNErrCode ier; SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); - if (DEE->ops->setrhslinearizationvector) + if (DEE->ops->setrhslinearizationpoint) { - ier = DEE->ops->setrhslinearizationvector(DEE, v); + ier = DEE->ops->setrhslinearizationpoint(DEE, t, v); } else { ier = SUN_SUCCESS; } SUNDIALS_MARK_FUNCTION_END(getSUNProfiler(DEE)); diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index 0fae4ded0a..e382f8ec61 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -396,25 +396,25 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__q_get(SwigClassWrap } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(SwigClassWrapper const *farg1, N_Vector farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(SwigClassWrapper const *farg1, N_Vector farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector arg2 = (N_Vector) 0 ; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return ); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linY", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); arg2 = (N_Vector)(farg2); - if (arg1) (arg1)->rhs_linV = arg2; + if (arg1) (arg1)->rhs_linY = arg2; } -SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(SwigClassWrapper const *farg1) { +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(SwigClassWrapper const *farg1) { N_Vector fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector result; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return 0); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linY", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (N_Vector) ((arg1)->rhs_linV); + result = (N_Vector) ((arg1)->rhs_linY); fresult = result; return fresult; } @@ -931,7 +931,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; N_Vector arg2 = (N_Vector) 0 ; @@ -939,7 +939,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDo arg1 = (SUNDomEigEstimator)(farg1); arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index 29a7ed4b56..4613bce2cb 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -48,8 +48,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_V => swigf_SUNDomEigEstimatorContent_Arnoldi__V_get procedure :: set_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_set procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get - procedure :: set_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set - procedure :: get_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get + procedure :: set_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set + procedure :: get_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set @@ -96,7 +96,7 @@ module fsundomeigest_arnoldi_mod public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi public :: FSUNDomEigEstimator_SetRHS_Arnoldi - public :: FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi + public :: FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi @@ -177,16 +177,16 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__q_get(farg1) & type(C_PTR) :: fresult end function -subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set") +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set") use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 type(C_PTR), value :: farg2 end subroutine -function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get") & +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper @@ -553,8 +553,8 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -747,19 +747,19 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(self, rhs_linv) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_linY) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: rhs_linv +type(N_Vector), target, intent(inout) :: rhs_linY type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(rhs_linv) -call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) +farg2 = c_loc(rhs_linY) +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) end subroutine -function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(N_Vector), pointer :: swig_result @@ -768,7 +768,7 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & type(SwigClassWrapper) :: farg1 farg1 = self%swigdata -fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) call c_f_pointer(fresult, swig_result) end function @@ -1316,7 +1316,7 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1328,7 +1328,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & farg1 = c_loc(dee) farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index 58223556f3..f682d42eba 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -396,25 +396,25 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__q_get(SwigClassWrap } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(SwigClassWrapper const *farg1, N_Vector farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(SwigClassWrapper const *farg1, N_Vector farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector arg2 = (N_Vector) 0 ; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return ); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linY", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); arg2 = (N_Vector)(farg2); - if (arg1) (arg1)->rhs_linV = arg2; + if (arg1) (arg1)->rhs_linY = arg2; } -SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(SwigClassWrapper const *farg1) { +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(SwigClassWrapper const *farg1) { N_Vector fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector result; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linV", return 0); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linY", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (N_Vector) ((arg1)->rhs_linV); + result = (N_Vector) ((arg1)->rhs_linY); fresult = result; return fresult; } @@ -931,7 +931,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; N_Vector arg2 = (N_Vector) 0 ; @@ -939,7 +939,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(SUNDo arg1 = (SUNDomEigEstimator)(farg1); arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(arg1,arg2); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index 109ccdeb03..9b085fb6aa 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -48,8 +48,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_V => swigf_SUNDomEigEstimatorContent_Arnoldi__V_get procedure :: set_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_set procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get - procedure :: set_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set - procedure :: get_rhs_linV => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get + procedure :: set_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set + procedure :: get_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set @@ -96,7 +96,7 @@ module fsundomeigest_arnoldi_mod public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi public :: FSUNDomEigEstimator_SetRHS_Arnoldi - public :: FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi + public :: FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi @@ -177,16 +177,16 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__q_get(farg1) & type(C_PTR) :: fresult end function -subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set") +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set") use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 type(C_PTR), value :: farg2 end subroutine -function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get") & +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper @@ -553,8 +553,8 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -747,19 +747,19 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(self, rhs_linv) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_linY) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: rhs_linv +type(N_Vector), target, intent(inout) :: rhs_linY type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(rhs_linv) -call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_set(farg1, farg2) +farg2 = c_loc(rhs_linY) +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) end subroutine -function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(N_Vector), pointer :: swig_result @@ -768,7 +768,7 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(self) & type(SwigClassWrapper) :: farg1 farg1 = self%swigdata -fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linV_get(farg1) +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) call c_f_pointer(fresult, swig_result) end function @@ -1316,7 +1316,7 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1328,7 +1328,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(dee, v) & farg1 = c_loc(dee) farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi(farg1, farg2) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 6951c0bdd7..fe5ee72c49 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -107,8 +107,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Arnoldi; - DEE->ops->setrhslinearizationvector = - SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi; + DEE->ops->setrhslinearizationpoint = + SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Arnoldi; @@ -133,8 +133,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, content->ATdata = NULL; content->V = NULL; content->q = NULL; - content->rhs_linV = NULL; - content->Fv = NULL; + content->rhs_linY = NULL; + content->rhs_linT = ZERO; + content->Fy = NULL; content->work = NULL; content->kry_dim = kry_dim; content->num_warmups = DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT; @@ -206,22 +207,24 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Arnoldi( - SUNDomEigEstimator DEE, N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi( + SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) { SUNFunctionBegin(DEE->sunctx); SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - SUNAssert(v, SUN_ERR_ARG_CORRUPT); + SUNAssert(y, SUN_ERR_ARG_CORRUPT); - if (Arnoldi_CONTENT(DEE)->rhs_linV == NULL) + if (Arnoldi_CONTENT(DEE)->rhs_linY == NULL) { - Arnoldi_CONTENT(DEE)->rhs_linV = N_VClone(v); + Arnoldi_CONTENT(DEE)->rhs_linY = N_VClone(y); SUNCheckLastErr(); } - N_VScale(ONE, v, Arnoldi_CONTENT(DEE)->rhs_linV); + Arnoldi_CONTENT(DEE)->rhs_linT = t; + + N_VScale(ONE, y, Arnoldi_CONTENT(DEE)->rhs_linY); SUNCheckLastErr(); return SUN_SUCCESS; @@ -353,8 +356,9 @@ SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); /* set the tolerance for preprocessing iterations */ - if (tol <= SUN_RCONST(0.0)) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } - else { Arnoldi_CONTENT(DEE)->tol_preprocess = tol; } + if (tol < SUN_SMALL_REAL) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } + + Arnoldi_CONTENT(DEE)->tol_preprocess = tol; /* set the type of warmup iterations */ Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; @@ -586,10 +590,10 @@ SUNErrCode SUNDomEigEstimator_Destroy_Arnoldi(SUNDomEigEstimator* DEEptr) N_VDestroy(Arnoldi_CONTENT(DEE)->q); Arnoldi_CONTENT(DEE)->q = NULL; } - if (Arnoldi_CONTENT(DEE)->rhs_linV) + if (Arnoldi_CONTENT(DEE)->rhs_linY) { - N_VDestroy(Arnoldi_CONTENT(DEE)->rhs_linV); - Arnoldi_CONTENT(DEE)->rhs_linV = NULL; + N_VDestroy(Arnoldi_CONTENT(DEE)->rhs_linY); + Arnoldi_CONTENT(DEE)->rhs_linY = NULL; } if (Arnoldi_CONTENT(DEE)->V) { @@ -683,7 +687,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(v, SUN_ERR_ARG_CORRUPT); SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); - SUNAssert(Arnoldi_CONTENT(DEE)->rhs_linV, SUN_ERR_ARG_CORRUPT); + SUNAssert(Arnoldi_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); // TODO: Add assertion as needed if (Arnoldi_CONTENT(DEE)->work == NULL) @@ -691,27 +695,32 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) Arnoldi_CONTENT(DEE)->work = N_VClone(v); SUNCheckLastErr(); } - if (Arnoldi_CONTENT(DEE)->Fv == NULL) + if (Arnoldi_CONTENT(DEE)->Fy == NULL) { - Arnoldi_CONTENT(DEE)->Fv = N_VClone(v); + Arnoldi_CONTENT(DEE)->Fy = N_VClone(v); SUNCheckLastErr(); } sunrealtype sig, siginv; int iter, retval; - N_Vector y = Arnoldi_CONTENT(DEE)->rhs_linV; + N_Vector y = Arnoldi_CONTENT(DEE)->rhs_linY; N_Vector work = Arnoldi_CONTENT(DEE)->work; - N_Vector Fv = Arnoldi_CONTENT(DEE)->Fv; + N_Vector Fy = Arnoldi_CONTENT(DEE)->Fy; - retval = Arnoldi_CONTENT(DEE)->rhsfn(y, Arnoldi_CONTENT(DEE)->Fv, + retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, y, + Fy, Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } - /* Initialize perturbation to 1/||v|| */ - // sunrealtype sig = ONE / N_VWrmsNorm(v, ark_mem->ewt); - sunrealtype sig = ONE / N_VWrmsNorm(v, v); + /* Initialize perturbation */ + sunrealtype ydotv = N_VDotProd(y, v); + sunrealtype vdotv = N_VDotProd(v, v); + sunrealtype sq1norm = N_VL1Norm(v); + sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; + sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); + sig = sign * sqrteps * SUNMAX(SUNRabs(ydotv), sq1norm) / vdotv; for (iter = 0; iter < MAX_DQITERS; iter++) { @@ -719,7 +728,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(sig, v, ONE, y, work); /* Set Jv = f(tn, y+sig*v) */ - retval = Arnoldi_CONTENT(DEE)->rhsfn(work, Jv, + retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, work, Jv, Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } @@ -730,7 +739,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) /* Replace Jv by (Jv - fn)/sig */ siginv = ONE / sig; - N_VLinearSum(siginv, Jv, -siginv, Fv, Jv); + N_VLinearSum(siginv, Jv, -siginv, Fy, Jv); return SUN_SUCCESS; } \ No newline at end of file diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index b3030333e0..132e6637ef 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -102,8 +102,8 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Power; - DEE->ops->setrhslinearizationvector = - SUNDomEigEstimator_SetRHSLinearizationVector_Power; + DEE->ops->setrhslinearizationpoint = + SUNDomEigEstimator_SetRHSLinearizationPoint_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; @@ -130,8 +130,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, content->V = NULL; content->q = NULL; content->q_prev = NULL; - content->rhs_linV = NULL; - content->Fv = NULL; + content->rhs_linY = NULL; + content->rhs_linT = ZERO; + content->Fy = NULL; content->work = NULL; content->complex = SUNTRUE; content->max_iters = max_iters; @@ -199,22 +200,24 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationVector_Power(SUNDomEigEstimator DEE, - N_Vector v) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power(SUNDomEigEstimator DEE, + sunrealtype t, N_Vector y) { SUNFunctionBegin(DEE->sunctx); SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - SUNAssert(v, SUN_ERR_ARG_CORRUPT); + SUNAssert(y, SUN_ERR_ARG_CORRUPT); - if (PI_CONTENT(DEE)->rhs_linV == NULL) + if (PI_CONTENT(DEE)->rhs_linY == NULL) { - PI_CONTENT(DEE)->rhs_linV = N_VClone(v); + PI_CONTENT(DEE)->rhs_linY = N_VClone(y); SUNCheckLastErr(); } - N_VScale(ONE, v, PI_CONTENT(DEE)->rhs_linV); + PI_CONTENT(DEE)->rhs_linT = t; + + N_VScale(ONE, y, PI_CONTENT(DEE)->rhs_linY); SUNCheckLastErr(); return SUN_SUCCESS; @@ -527,7 +530,9 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( int retval; sunrealtype cos_qs, det_G_inv, h11, h12, h21, h22, p11, p12, p21, p22; - sunrealtype proj_cond_inv = SUN_RCONST(1e-10); + /* The threshold for identifying real or complex DEE is experimentally + determined based on the relative tolerance PI_CONTENT(DEE)->rel_tol */ + sunrealtype proj_cond_inv = PI_CONTENT(DEE)->rel_tol; cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); @@ -615,10 +620,10 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) N_VDestroy(PI_CONTENT(DEE)->V); PI_CONTENT(DEE)->V = NULL; } - if (PI_CONTENT(DEE)->rhs_linV) + if (PI_CONTENT(DEE)->rhs_linY) { - N_VDestroy(PI_CONTENT(DEE)->rhs_linV); - PI_CONTENT(DEE)->rhs_linV = NULL; + N_VDestroy(PI_CONTENT(DEE)->rhs_linY); + PI_CONTENT(DEE)->rhs_linY = NULL; } free(DEE->content); DEE->content = NULL; @@ -651,34 +656,39 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(v, SUN_ERR_ARG_CORRUPT); SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); - SUNAssert(PI_CONTENT(DEE)->rhs_linV, SUN_ERR_ARG_CORRUPT); + SUNAssert(PI_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); if (PI_CONTENT(DEE)->work == NULL) { PI_CONTENT(DEE)->work = N_VClone(v); SUNCheckLastErr(); } - if (PI_CONTENT(DEE)->Fv == NULL) + if (PI_CONTENT(DEE)->Fy == NULL) { - PI_CONTENT(DEE)->Fv = N_VClone(v); + PI_CONTENT(DEE)->Fy = N_VClone(v); SUNCheckLastErr(); } sunrealtype sig, siginv; int iter, retval; - N_Vector y = PI_CONTENT(DEE)->rhs_linV; + N_Vector y = PI_CONTENT(DEE)->rhs_linY; N_Vector work = PI_CONTENT(DEE)->work; - N_Vector Fv = PI_CONTENT(DEE)->Fv; + N_Vector Fy = PI_CONTENT(DEE)->Fy; - retval = PI_CONTENT(DEE)->rhsfn(y, PI_CONTENT(DEE)->Fv, + retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, y, + Fy, PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } - /* Initialize perturbation to 1/||v|| */ - // sunrealtype sig = ONE / N_VWrmsNorm(v, ark_mem->ewt); - sig = ONE / N_VWrmsNorm(v, v); + /* Initialize perturbation */ + sunrealtype ydotv = N_VDotProd(y, v); + sunrealtype vdotv = N_VDotProd(v, v); + sunrealtype sq1norm = N_VL1Norm(v); + sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; + sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); + sig = sign * sqrteps * SUNMAX(SUNRabs(ydotv), sq1norm) / vdotv; for (iter = 0; iter < MAX_DQITERS; iter++) { @@ -686,7 +696,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(sig, v, ONE, y, work); /* Set Jv = f(tn, y+sig*v) */ - retval = PI_CONTENT(DEE)->rhsfn(work, Jv, PI_CONTENT(DEE)->rhs_data); + retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, work, Jv, + PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; if (retval == 0) { break; } if (retval < 0) { return (-1); } @@ -697,7 +708,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) /* Replace Jv by (Jv - fn)/sig */ siginv = ONE / sig; - N_VLinearSum(siginv, Jv, -siginv, Fv, Jv); + N_VLinearSum(siginv, Jv, -siginv, Fy, Jv); return SUN_SUCCESS; } \ No newline at end of file diff --git a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c index 4631632648..3cbb48dbdb 100644 --- a/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c +++ b/test/unit_tests/sundomeigest/Arnoldi/test_sundomeigest_arnoldi.c @@ -220,7 +220,7 @@ int main(int argc, char* argv[]) rel_error /= norm_of_dom_eig; - if (rel_error < rel_tol) + if (rel_error < SUN_RCONST(10.0) * rel_tol) { printf("\n\nPASS: relative error = " SUN_FORMAT_G " \n\n", rel_error); } From 1035e710a5ae16e33bf649f6ef3745b5b03c80e9 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 16 Mar 2026 01:31:05 -0500 Subject: [PATCH 22/76] removed warmup --- .../sundomeigest/SUNDomEigEst_Arnoldi.rst | 28 ++++++- .../sundomeigest/SUNDomEigEst_Power.rst | 25 +++++- .../C_serial/ark_brusselator_lsrk_domeigest.c | 26 +----- .../ark_brusselator_lsrk_externaldomeigest.c | 84 +++++-------------- include/sundomeigest/sundomeigest_arnoldi.h | 3 +- include/sundomeigest/sundomeigest_power.h | 4 +- 6 files changed, 73 insertions(+), 97 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst index c12869c44c..5cee1216ea 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst @@ -116,15 +116,24 @@ The SUNDomEigEstimator_Arnoldi module defines the *content* field of a void* ATdata; N_Vector* V; N_Vector q; + N_Vector rhs_linY; + N_Vector Fy; + N_Vector work; int kry_dim; int num_warmups; long int num_iters; + sunbooleantype warmup_to_tol; + sunrealtype tol_preprocess; + sunrealtype rhs_linT; long int num_ATimes; + DEERhsFn rhsfn; + void* rhs_data; + long int nfevals; sunrealtype* LAPACK_A; sunrealtype* LAPACK_wr; sunrealtype* LAPACK_wi; sunrealtype* LAPACK_work; - snuindextype LAPACK_lwork; + sunindextype LAPACK_lwork; sunrealtype** LAPACK_arr; sunrealtype** Hes; }; @@ -137,7 +146,7 @@ information: * ``ATData`` - pointer to structure for ``ATimes``, -* ``V, q`` - vectors used for workspace by the Arnoldi algorithm. +* ``V, q, Fy, work`` - vectors used for workspace. * ``kry_dim`` - dimension of Krylov subspaces (default is 3), @@ -146,6 +155,21 @@ information: * ``num_iters`` - number of iterations (preprocessing and estimation) in the last :c:func:`SUNDomEigEstimator_Estimate` call, +* ``warmup_to_tol`` - type of warmup iterations (default is ``SUNFALSE``) + +* ``tol_preprocess`` - tolerance for preprocessing iterations (default is 0.005; + only used if ``warmup_to_tol`` is ``SUNTRUE``), + +* ``rhs_linY`` - state vector for linearization point, + +* ``rhs_linT`` - time value for linearization point (default is 0.0), + +* ``rhsfn`` - user provided RHS function, + +* ``rhs_data`` - pointer to the data structure for ``rhsfn``, + +* ``nfevals`` - number of RHS evaluations, + * ``num_ATimes`` - number of calls to the ``ATimes`` function, * ``LAPACK_A, LAPACK_wr, LAPACK_wi, LAPACK_work`` - ``sunrealtype`` used for workspace by LAPACK, diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index 5ef3df5697..8d632e7c6b 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -109,7 +109,7 @@ routines: :c:func:`SUNDomEigEstimator_SetInitialGuess`. -.. c:function:: SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); +.. c:function:: SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) This routine informs the Power iteration that the dominant eigenvalue is real-valued, so that the complex projection described in Section @@ -148,12 +148,21 @@ The SUNDomEigEstimator_Power module defines the *content* field of a void* ATdata; N_Vector* V; N_Vector q; + N_Vector q_prev; + N_Vector rhs_linY; + N_Vector Fy; + N_Vector work; int num_warmups; long int max_iters; long int num_iters; long int num_ATimes; + sunrealtype rhs_linT; sunrealtype rel_tol; sunrealtype res; + DEERhsFn rhsfn; + void* rhs_data; + long int nfevals; + sunbooleantype complex; }; @@ -164,7 +173,7 @@ information: * ``ATData`` - pointer to structure for ``ATimes``, -* ``V, q`` - ``N_Vector`` used for workspace by the PI algorithm. +* ``V, q, q_prev, Fy, work`` - ``N_Vector`` used for workspace. * ``num_warmups`` - number of preprocessing iterations (default is 100), @@ -175,11 +184,23 @@ information: * ``num_ATimes`` - number of calls to the ``ATimes`` function, +* ``rhs_linY`` - state vector for linearization point, + +* ``rhs_linT`` - time value for linearization point (default is 0.0), + * ``rel_tol`` - relative tolerance for the convergence criteria (default is 0.005), * ``res`` - the residual from the last :c:func:`SUNDomEigEstimator_Estimate` call. +* ``rhsfn`` - user provided RHS function, + +* ``rhs_data`` - pointer to the data structure for ``rhsfn``, + +* ``nfevals`` - number of RHS evaluations, + +* ``complex`` - flag indicating whether the dominant eigenvalue is + complex-valued (default is ``SUNTRUE``). This estimator is constructed to perform the following operations: diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c index c656a48b53..65c108d041 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c @@ -102,7 +102,6 @@ int main(int argc, char* argv[]) N_Vector y = NULL; /* empty vector for storing solution */ void* arkode_mem = NULL; /* empty ARKode memory structure */ sunrealtype rdata[3]; - FILE* UFID; sunrealtype t, tout; int iout; @@ -204,8 +203,8 @@ int main(int argc, char* argv[]) N_VDestroy(q); /* Attach the DEE to the LSRKStep module. - There is no need to set Atimes or initialize since these are all - performed after attaching the DEE by LSRKStep. */ + There is no need to set Atimes or initialize since LSRKStep provides + a default Atimes, and initialized the DEE, after it is attached. */ flag = LSRKStepSetDomEigEstimator(arkode_mem, DEE); if (check_flag(&flag, "LSRKStepSetDomEigEstimator", 1)) { return 1; } @@ -214,7 +213,7 @@ int main(int argc, char* argv[]) eigenvalue. The warmup is performed only once by the LSRKStep module internally unless LSRKStepSetNumDomEigEstPreprocessIters is called to set a new number of succeeding warmups that would be executed before - every dominant eigenvalue estimate calls */ + every dominant eigenvalue estimation call */ flag = LSRKStepSetNumDomEigEstInitPreprocessIters(arkode_mem, numwarmup); if (check_flag(&flag, "LSRKStepSetNumDomEigEstInitPreprocessIters", 1)) { @@ -237,14 +236,6 @@ int main(int argc, char* argv[]) flag = LSRKStepSetDomEigSafetyFactor(arkode_mem, SUN_RCONST(1.01)); if (check_flag(&flag, "LSRKStepSetDomEigSafetyFactor", 1)) { return 1; } - /* Specify the number of preprocessing warmups before each estimate call - succeeding the very first estimate call. */ - flag = LSRKStepSetNumDomEigEstPreprocessIters(arkode_mem, 0); - if (check_flag(&flag, "LSRKStepSetNumDomEigEstPreprocessIters", 1)) - { - return 1; - } - /* Specify the Runge--Kutta--Chebyshev LSRK method by name */ flag = LSRKStepSetSTSMethodByName(arkode_mem, "ARKODE_LSRK_RKL_2"); if (check_flag(&flag, "LSRKStepSetSTSMethodByName", 1)) { return 1; } @@ -257,14 +248,6 @@ int main(int argc, char* argv[]) flag = ARKodeSetOptions(arkode_mem, NULL, NULL, argc, argv); if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } - /* Open output stream for results, output comment line */ - UFID = fopen("solution.txt", "w"); - fprintf(UFID, "# t u v w\n"); - - /* output initial condition to disk */ - fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", T0, - NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); - /* Main time-stepping loop: calls ARKodeEvolve to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; @@ -281,8 +264,6 @@ int main(int argc, char* argv[]) printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM "\n", /* access/print solution */ t, NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); - fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", t, - NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); if (flag >= 0) { /* successful solve: update time */ tout += dTout; @@ -295,7 +276,6 @@ int main(int argc, char* argv[]) } } printf(" -------------------------------------------\n"); - fclose(UFID); /* Print final statistics */ printf("\nFinal Statistics:\n"); diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 54a187a6f4..1686301281 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -19,43 +19,23 @@ *--------------------------------------------------------------- * Example problem: * - * The following test simulates a brusselator problem from chemical - * kinetics. This is an ODE system with 3 components, Y = [u,v,w], - * satisfying the equations, - * du/dt = a - (w+1)*u + v*u^2 - * dv/dt = w*u - v*u^2 - * dw/dt = (b-w)/ep - w*u - * for t in the interval [0.0, 10.0], with initial conditions - * Y0 = [u0,v0,w0]. - * - * We have 3 different testing scenarios: - * - * Test 1: u0=3.9, v0=1.1, w0=2.8, a=1.2, b=2.5, ep=1.0e-5 - * Here, all three components exhibit a rapid transient change - * during the first 0.2 time units, followed by a slow and - * smooth evolution. - * - * Test 2: u0=1.2, v0=3.1, w0=3, a=1, b=3.5, ep=5.0e-6 - * Here, w experiences a fast initial transient, jumping 0.5 - * within a few steps. All values proceed smoothly until - * around t=6.5, when both u and v undergo a sharp transition, - * with u increaseing from around 0.5 to 5 and v decreasing - * from around 6 to 1 in less than 0.5 time units. After this - * transition, both u and v continue to evolve somewhat - * rapidly for another 1.4 time units, and finish off smoothly. - * - * Test 3: u0=3, v0=3, w0=3.5, a=0.5, b=3, ep=5.0e-4 - * Here, all components undergo very rapid initial transients - * during the first 0.3 time units, and all then proceed very - * smoothly for the remainder of the simulation. - * - * This file is hard-coded to use test 2. - * - * This program solves the problem with the LSRK method using internal - * SUNDIALS dominant eigenvalue estimation (DEE) module. - * - * 100 outputs are printed at equal intervals, and run statistics - * are printed at the end. + * The following test simulates the same problem as + * ark_brusselator_lsrk_domeigest.c. + * + * The only difference with that example is that this one + * attaches a "user provided" dominant eigenvalue estimate, + * and where that estimate is provided by a user-constructed + * SUNDomEigEstimator object (see the dom_eig function below). + * + * While this example and ark_brusselator_lsrk_domeigest.c should provide + * the same results, the purpose of this example is to show + * users how they may manually construct SUNDomEigEstimator + * objects to query the dominant eigenvalues of a desired + * function. In particular, we note that there is no + * requirement for the SUNDomEigEstimator to be used purely + * for super-time-stepping methods in LSRKStep, so users + * interested in other purposes may focus on the contents + * of the dom_eig function below as a template. *-----------------------------------------------------------------*/ /* Header files */ @@ -96,7 +76,6 @@ typedef struct SUNDomEigEstimator DEE; sunrealtype rel_tol; sunindextype max_iters; - sunindextype numwarmup; } UserData; /* Main Program */ @@ -118,7 +97,6 @@ int main(int argc, char* argv[]) N_Vector y = NULL; /* empty vector for storing solution */ void* arkode_mem = NULL; /* empty ARKode memory structure */ UserData ProbData; /* problem data structure */ - FILE* UFID; sunrealtype t, tout; int iout; @@ -174,7 +152,6 @@ int main(int argc, char* argv[]) ProbData.DEE = NULL; ProbData.rel_tol = SUN_RCONST(5.0e-3); ProbData.max_iters = 100; - ProbData.numwarmup = 10; y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } NV_Ith_S(y, 0) = u0; /* Set initial conditions */ @@ -219,14 +196,6 @@ int main(int argc, char* argv[]) flag = LSRKStepSetDomEigSafetyFactor(arkode_mem, SUN_RCONST(1.01)); if (check_flag(&flag, "LSRKStepSetDomEigSafetyFactor", 1)) { return 1; } - /* Specify the number of preprocessing warmups before each estimate call - succeeding the very first estimate call. */ - flag = LSRKStepSetNumDomEigEstPreprocessIters(arkode_mem, 0); - if (check_flag(&flag, "LSRKStepSetNumDomEigEstPreprocessIters", 1)) - { - return 1; - } - /* Specify the Runge--Kutta--Chebyshev LSRK method by name */ flag = LSRKStepSetSTSMethodByName(arkode_mem, "ARKODE_LSRK_RKL_2"); if (check_flag(&flag, "LSRKStepSetSTSMethodByName", 1)) { return 1; } @@ -235,14 +204,6 @@ int main(int argc, char* argv[]) flag = ARKodeSetOptions(arkode_mem, NULL, NULL, argc, argv); if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } - /* Open output stream for results, output comment line */ - UFID = fopen("solution.txt", "w"); - fprintf(UFID, "# t u v w\n"); - - /* output initial condition to disk */ - fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", T0, - NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); - /* Main time-stepping loop: calls ARKodeEvolve to perform the integration, then prints results. Stops when the final time has been reached */ t = T0; @@ -259,8 +220,6 @@ int main(int argc, char* argv[]) printf(" %10.6" FSYM " %10.6" FSYM " %10.6" FSYM " %10.6" FSYM "\n", /* access/print solution */ t, NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); - fprintf(UFID, " %.16" ESYM " %.16" ESYM " %.16" ESYM " %.16" ESYM "\n", t, - NV_Ith_S(y, 0), NV_Ith_S(y, 1), NV_Ith_S(y, 2)); if (flag >= 0) { /* successful solve: update time */ tout += dTout; @@ -273,7 +232,6 @@ int main(int argc, char* argv[]) } } printf(" -------------------------------------------\n"); - fclose(UFID); /* Print final statistics */ printf("\nFinal Statistics:\n"); @@ -324,6 +282,8 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, SUNContext ctx = data->ctx; /* access context from UserData */ SUNDomEigEstimator DEE = data->DEE; /* access DEE from UserData */ + /* DEE is initialized to NULL, so on the first dom_eig call we need + to create and initialize this object */ if (DEE == NULL) { /* Create random initial vector for power iteration */ @@ -349,12 +309,6 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, return 1; } - flag = SUNDomEigEstimator_SetNumPreprocessIters(DEE, data->numwarmup); - if (check_flag(&flag, "SUNDomEigEstimator_SetNumPreprocessIters", 1)) - { - return 1; - } - flag = SUNDomEigEstimator_Initialize(DEE); if (check_flag(&flag, "SUNDomEigEstimator_Initialize", 1)) { return 1; } } diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 30c99818f3..8e08ffa3ab 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -50,8 +50,7 @@ struct SUNDomEigEstimatorContent_Arnoldi_ long int num_iters; /* Number of iterations in last Estimate call */ sunbooleantype warmup_to_tol; /* Type of warmup iterations */ sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ - - sunrealtype rhs_linT; /* Linearization time for the RHS function */ + sunrealtype rhs_linT; /* Time value for linearization point */ long int num_ATimes; /* Number of ATimes calls */ diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index f8ee398f59..bc4156c7c0 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -46,9 +46,7 @@ struct SUNDomEigEstimatorContent_Power_ int num_warmups; /* Number of preprocessing iterations */ long int max_iters; /* Maximum number of power iterations */ long int num_iters; /* Number of iterations in last Estimate call */ - sunbooleantype warmup_to_tol; /* Type of warmup iterations */ - - sunrealtype rhs_linT; /* Linearization time for the RHS function */ + sunrealtype rhs_linT; /* Time value for linearization point */ long int num_ATimes; /* Number of ATimes calls */ From a9ca56fdc0fd7c2c9edefe884d58e651573404dc Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 16 Mar 2026 01:40:37 -0500 Subject: [PATCH 23/76] formatting --- .../ark_brusselator_lsrk_externaldomeigest.c | 21 ++++++++++--------- include/sundials/sundials_domeigestimator.h | 7 ++++--- include/sundomeigest/sundomeigest_power.h | 12 +++++------ src/sundials/sundials_domeigestimator.c | 2 +- .../arnoldi/sundomeigest_arnoldi.c | 13 ++++++------ src/sundomeigest/power/sundomeigest_power.c | 15 +++++++------ 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 1686301281..8e6a872160 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -145,13 +145,13 @@ int main(int argc, char* argv[]) printf(" reltol = %.1" ESYM ", abstol = %.1" ESYM "\n\n", reltol, abstol); /* Initialize data structures */ - ProbData.ctx = ctx; - ProbData.rdata[0] = a; /* set user data */ - ProbData.rdata[1] = b; - ProbData.rdata[2] = ep; - ProbData.DEE = NULL; - ProbData.rel_tol = SUN_RCONST(5.0e-3); - ProbData.max_iters = 100; + ProbData.ctx = ctx; + ProbData.rdata[0] = a; /* set user data */ + ProbData.rdata[1] = b; + ProbData.rdata[2] = ep; + ProbData.DEE = NULL; + ProbData.rel_tol = SUN_RCONST(5.0e-3); + ProbData.max_iters = 100; y = N_VNew_Serial(NEQ, ctx); /* Create serial vector for solution */ if (check_flag((void*)y, "N_VNew_Serial", 0)) { return 1; } NV_Ith_S(y, 0) = u0; /* Set initial conditions */ @@ -277,7 +277,7 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, N_Vector temp2, N_Vector temp3) { int flag; - UserData* data = (UserData*)user_data; /* cast user_data to UserData */ + UserData* data = (UserData*)user_data; /* cast user_data to UserData */ SUNContext ctx = data->ctx; /* access context from UserData */ SUNDomEigEstimator DEE = data->DEE; /* access DEE from UserData */ @@ -303,7 +303,8 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, if (check_flag(&flag, "SUNDomEigEstimator_SetRHS", 1)) { return 1; } /* Set the linearization vector for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); // set the time t as well + flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, + y); // set the time t as well if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) { return 1; @@ -314,7 +315,7 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, } /* Update the linearization vector and time for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); + flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) { return 1; diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index b44eac9e04..de39321ca0 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -32,7 +32,8 @@ extern "C" { #endif -typedef int (*DEERhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); +typedef int (*DEERhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, + void* user_data); #define MAX_DQITERS 3 /* ----------------------------------------------------------------- @@ -50,8 +51,8 @@ struct SUNDomEigEstimator_Ops_ { SUNErrCode (*setatimes)(SUNDomEigEstimator, void*, SUNATimesFn); SUNErrCode (*setrhs)(SUNDomEigEstimator, void*, DEERhsFn); - SUNErrCode (*setrhslinearizationpoint)(SUNDomEigEstimator, sunrealtype, - N_Vector); + SUNErrCode (*setrhslinearizationpoint)(SUNDomEigEstimator, sunrealtype, + N_Vector); SUNErrCode (*setoptions)(SUNDomEigEstimator DEE, const char* Did, const char* file_name, int argc, char* argv[]); SUNErrCode (*setmaxiters)(SUNDomEigEstimator, long int); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index bc4156c7c0..facf402045 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -43,10 +43,10 @@ struct SUNDomEigEstimatorContent_Power_ N_Vector V, q, q_prev, rhs_linY, Fy, work; /* workspace vectors */ - int num_warmups; /* Number of preprocessing iterations */ - long int max_iters; /* Maximum number of power iterations */ - long int num_iters; /* Number of iterations in last Estimate call */ - sunrealtype rhs_linT; /* Time value for linearization point */ + int num_warmups; /* Number of preprocessing iterations */ + long int max_iters; /* Maximum number of power iterations */ + long int num_iters; /* Number of iterations in last Estimate call */ + sunrealtype rhs_linT; /* Time value for linearization point */ long int num_ATimes; /* Number of ATimes calls */ @@ -96,8 +96,8 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power(SUNDomEigEstimator DEE, - sunrealtype t, N_Vector v); +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power( + SUNDomEigEstimator DEE, sunrealtype t, N_Vector v); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 4db11c3916..f38c293333 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -205,7 +205,7 @@ SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, } SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator DEE, - sunrealtype t, N_Vector v) + sunrealtype t, N_Vector v) { SUNErrCode ier; SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index fe5ee72c49..1db40f396d 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -708,17 +708,16 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_Vector work = Arnoldi_CONTENT(DEE)->work; N_Vector Fy = Arnoldi_CONTENT(DEE)->Fy; - retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, y, - Fy, + retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, y, Fy, Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } /* Initialize perturbation */ - sunrealtype ydotv = N_VDotProd(y, v); - sunrealtype vdotv = N_VDotProd(v, v); + sunrealtype ydotv = N_VDotProd(y, v); + sunrealtype vdotv = N_VDotProd(v, v); sunrealtype sq1norm = N_VL1Norm(v); - sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; + sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); sig = sign * sqrteps * SUNMAX(SUNRabs(ydotv), sq1norm) / vdotv; @@ -728,8 +727,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(sig, v, ONE, y, work); /* Set Jv = f(tn, y+sig*v) */ - retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, work, Jv, - Arnoldi_CONTENT(DEE)->rhs_data); + retval = Arnoldi_CONTENT(DEE)->rhsfn(Arnoldi_CONTENT(DEE)->rhs_linT, work, + Jv, Arnoldi_CONTENT(DEE)->rhs_data); Arnoldi_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 132e6637ef..d94ce8a0e6 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -200,8 +200,8 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power(SUNDomEigEstimator DEE, - sunrealtype t, N_Vector y) +SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power( + SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) { SUNFunctionBegin(DEE->sunctx); @@ -676,17 +676,16 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_Vector work = PI_CONTENT(DEE)->work; N_Vector Fy = PI_CONTENT(DEE)->Fy; - retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, y, - Fy, + retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, y, Fy, PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } /* Initialize perturbation */ - sunrealtype ydotv = N_VDotProd(y, v); - sunrealtype vdotv = N_VDotProd(v, v); + sunrealtype ydotv = N_VDotProd(y, v); + sunrealtype vdotv = N_VDotProd(v, v); sunrealtype sq1norm = N_VL1Norm(v); - sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; + sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); sig = sign * sqrteps * SUNMAX(SUNRabs(ydotv), sq1norm) / vdotv; @@ -696,7 +695,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(sig, v, ONE, y, work); /* Set Jv = f(tn, y+sig*v) */ - retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, work, Jv, + retval = PI_CONTENT(DEE)->rhsfn(PI_CONTENT(DEE)->rhs_linT, work, Jv, PI_CONTENT(DEE)->rhs_data); PI_CONTENT(DEE)->nfevals++; if (retval == 0) { break; } From 71bceec96fba52bf972015ab743a91e6d1645569 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 16 Mar 2026 19:30:28 -0500 Subject: [PATCH 24/76] swig --- .../sundials_domeigestimator_generated.hpp | 3 +- .../sundomeigest_power_generated.hpp | 2 +- src/sundials/fmod_int32/fsundials_core_mod.c | 10 ++- .../fmod_int32/fsundials_core_mod.f90 | 16 ++-- src/sundials/fmod_int64/fsundials_core_mod.c | 10 ++- .../fmod_int64/fsundials_core_mod.f90 | 16 ++-- .../fmod_int32/fsundomeigest_arnoldi_mod.c | 46 +++++++--- .../fmod_int32/fsundomeigest_arnoldi_mod.f90 | 90 ++++++++++++++----- .../fmod_int64/fsundomeigest_arnoldi_mod.c | 46 +++++++--- .../fmod_int64/fsundomeigest_arnoldi_mod.f90 | 90 ++++++++++++++----- 10 files changed, 245 insertions(+), 84 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index d95fef74f5..cba6138b31 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -20,7 +20,8 @@ m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", - SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("v")); + SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("t"), + nb::arg("v")); m.def("SUNDomEigEstimator_SetMaxIters", SUNDomEigEstimator_SetMaxIters, nb::arg("DEE"), nb::arg("max_iters")); diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index e78db1afc4..629b893670 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -38,7 +38,7 @@ m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, m.def("SUNDomEigEstimator_SetRHSLinearizationPoint_Power", SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), - nb::arg("v")); + nb::arg("t"), nb::arg("v")); m.def("SUNDomEigEstimator_SetDEEisReal_Power", SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index 85c8acfe22..f8845fa1af 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -3816,15 +3816,17 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; - N_Vector arg2 = (N_Vector) 0 ; + sunrealtype arg2 ; + N_Vector arg3 = (N_Vector) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); - arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2); + arg2 = (sunrealtype)(*farg2); + arg3 = (N_Vector)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index 83522b0344..e88cf2f64a 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -2950,12 +2950,13 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) & bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 +real(C_DOUBLE), intent(in) :: farg2 +type(C_PTR), value :: farg3 integer(C_INT) :: fresult end function @@ -7168,19 +7169,22 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: t type(N_Vector), target, intent(inout) :: v integer(C_INT) :: fresult type(C_PTR) :: farg1 -type(C_PTR) :: farg2 +real(C_DOUBLE) :: farg2 +type(C_PTR) :: farg3 farg1 = c_loc(dee) -farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) +farg2 = t +farg3 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 8121d51752..9188255af7 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -3816,15 +3816,17 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; - N_Vector arg2 = (N_Vector) 0 ; + sunrealtype arg2 ; + N_Vector arg3 = (N_Vector) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); - arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2); + arg2 = (sunrealtype)(*farg2); + arg3 = (N_Vector)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index c6feeacd5c..37ec0768d0 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -2950,12 +2950,13 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) & bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 +real(C_DOUBLE), intent(in) :: farg2 +type(C_PTR), value :: farg3 integer(C_INT) :: fresult end function @@ -7168,19 +7169,22 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: t type(N_Vector), target, intent(inout) :: v integer(C_INT) :: fresult type(C_PTR) :: farg1 -type(C_PTR) :: farg2 +real(C_DOUBLE) :: farg2 +type(C_PTR) :: farg3 farg1 = c_loc(dee) -farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2) +farg2 = t +farg3 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index e382f8ec61..6928cfcdaa 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -420,25 +420,25 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(SwigCl } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set(SwigClassWrapper const *farg1, N_Vector farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_set(SwigClassWrapper const *farg1, N_Vector farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector arg2 = (N_Vector) 0 ; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return ); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fy", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); arg2 = (N_Vector)(farg2); - if (arg1) (arg1)->Fv = arg2; + if (arg1) (arg1)->Fy = arg2; } -SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get(SwigClassWrapper const *farg1) { +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_get(SwigClassWrapper const *farg1) { N_Vector fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector result; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return 0); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fy", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (N_Vector) ((arg1)->Fv); + result = (N_Vector) ((arg1)->Fy); fresult = result; return fresult; } @@ -588,6 +588,30 @@ SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(Sw } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(SwigClassWrapper const *farg1, double const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linT", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (sunrealtype)(*farg2); + if (arg1) (arg1)->rhs_linT = arg2; +} + + +SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(SwigClassWrapper const *farg1) { + double fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linT", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (sunrealtype) ((arg1)->rhs_linT); + fresult = (sunrealtype)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(SwigClassWrapper const *farg1, long const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; long arg2 ; @@ -931,15 +955,17 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; - N_Vector arg2 = (N_Vector) 0 ; + sunrealtype arg2 ; + N_Vector arg3 = (N_Vector) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); - arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2); + arg2 = (sunrealtype)(*farg2); + arg3 = (N_Vector)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index 4613bce2cb..b1e9b7321d 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -50,8 +50,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get procedure :: set_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set procedure :: get_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get - procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set - procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get + procedure :: set_Fy => swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_set + procedure :: get_Fy => swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_get procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set procedure :: get_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_get procedure :: set_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set @@ -64,6 +64,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get procedure :: set_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get + procedure :: set_rhs_linT => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set + procedure :: get_rhs_linT => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get procedure :: set_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set @@ -194,16 +196,16 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) & type(C_PTR) :: fresult end function -subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set") +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_set") use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 type(C_PTR), value :: farg2 end subroutine -function swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get") & +function swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper @@ -313,6 +315,23 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) & real(C_DOUBLE) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set") use, intrinsic :: ISO_C_BINDING @@ -553,12 +572,13 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) & bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 +real(C_DOUBLE), intent(in) :: farg2 +type(C_PTR), value :: farg3 integer(C_INT) :: fresult end function @@ -747,15 +767,15 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_linY) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_liny) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: rhs_linY +type(N_Vector), target, intent(inout) :: rhs_liny type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(rhs_linY) +farg2 = c_loc(rhs_liny) call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) end subroutine @@ -772,19 +792,19 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set(self, fv) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_set(self, fy) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: fv +type(N_Vector), target, intent(inout) :: fy type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(fv) -call swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) +farg2 = c_loc(fy) +call swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_set(farg1, farg2) end subroutine -function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & +function swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(N_Vector), pointer :: swig_result @@ -793,7 +813,7 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & type(SwigClassWrapper) :: farg1 farg1 = self%swigdata -fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_get(farg1) call c_f_pointer(fresult, swig_result) end function @@ -947,6 +967,31 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(self, rhs_lint) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE), intent(in) :: rhs_lint +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = self%swigdata +farg2 = rhs_lint +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +real(C_DOUBLE) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(self, num_atimes) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -1316,19 +1361,22 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: t type(N_Vector), target, intent(inout) :: v integer(C_INT) :: fresult type(C_PTR) :: farg1 -type(C_PTR) :: farg2 +real(C_DOUBLE) :: farg2 +type(C_PTR) :: farg3 farg1 = c_loc(dee) -farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) +farg2 = t +farg3 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index f682d42eba..549c4f04f6 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -420,25 +420,25 @@ SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(SwigCl } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set(SwigClassWrapper const *farg1, N_Vector farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_set(SwigClassWrapper const *farg1, N_Vector farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector arg2 = (N_Vector) 0 ; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return ); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fy", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); arg2 = (N_Vector)(farg2); - if (arg1) (arg1)->Fv = arg2; + if (arg1) (arg1)->Fy = arg2; } -SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get(SwigClassWrapper const *farg1) { +SWIGEXPORT N_Vector _wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_get(SwigClassWrapper const *farg1) { N_Vector fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; N_Vector result; - SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fv", return 0); + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::Fy", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (N_Vector) ((arg1)->Fv); + result = (N_Vector) ((arg1)->Fy); fresult = result; return fresult; } @@ -588,6 +588,30 @@ SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(Sw } +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(SwigClassWrapper const *farg1, double const *farg2) { + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype arg2 ; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linT", return ); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + arg2 = (sunrealtype)(*farg2); + if (arg1) (arg1)->rhs_linT = arg2; +} + + +SWIGEXPORT double _wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(SwigClassWrapper const *farg1) { + double fresult ; + struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; + sunrealtype result; + + SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhs_linT", return 0); + arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); + result = (sunrealtype) ((arg1)->rhs_linT); + fresult = (sunrealtype)(result); + return fresult; +} + + SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(SwigClassWrapper const *farg1, long const *farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; long arg2 ; @@ -931,15 +955,17 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, N_Vector farg2) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; - N_Vector arg2 = (N_Vector) 0 ; + sunrealtype arg2 ; + N_Vector arg3 = (N_Vector) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); - arg2 = (N_Vector)(farg2); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2); + arg2 = (sunrealtype)(*farg2); + arg3 = (N_Vector)(farg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index 9b085fb6aa..980b7f0d5f 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -50,8 +50,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_q => swigf_SUNDomEigEstimatorContent_Arnoldi__q_get procedure :: set_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set procedure :: get_rhs_linY => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get - procedure :: set_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set - procedure :: get_Fv => swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get + procedure :: set_Fy => swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_set + procedure :: get_Fy => swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_get procedure :: set_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_set procedure :: get_work => swigf_SUNDomEigEstimatorContent_Arnoldi__work_get procedure :: set_kry_dim => swigf_SUNDomEigEstimatorContent_Arnoldi__kry_dim_set @@ -64,6 +64,8 @@ module fsundomeigest_arnoldi_mod procedure :: get_warmup_to_tol => swigf_SUNDomEigEstimatorContent_Arnoldi__warmup_to_tol_get procedure :: set_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_set procedure :: get_tol_preprocess => swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get + procedure :: set_rhs_linT => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set + procedure :: get_rhs_linT => swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get procedure :: set_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set procedure :: get_num_ATimes => swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get procedure :: set_rhsfn => swigf_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set @@ -194,16 +196,16 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(farg1) & type(C_PTR) :: fresult end function -subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_set") +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_set") use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper type(SwigClassWrapper) :: farg1 type(C_PTR), value :: farg2 end subroutine -function swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) & -bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fv_get") & +function swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__Fy_get") & result(fresult) use, intrinsic :: ISO_C_BINDING import :: swigclasswrapper @@ -313,6 +315,23 @@ function swigc_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(farg1) & real(C_DOUBLE) :: fresult end function +subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(farg1, farg2) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set") +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE), intent(in) :: farg2 +end subroutine + +function swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(farg1) & +bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get") & +result(fresult) +use, intrinsic :: ISO_C_BINDING +import :: swigclasswrapper +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: fresult +end function + subroutine swigc_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(farg1, farg2) & bind(C, name="_wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set") use, intrinsic :: ISO_C_BINDING @@ -553,12 +572,13 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) & +function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) & bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 +real(C_DOUBLE), intent(in) :: farg2 +type(C_PTR), value :: farg3 integer(C_INT) :: fresult end function @@ -747,15 +767,15 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__q_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_linY) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(self, rhs_liny) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: rhs_linY +type(N_Vector), target, intent(inout) :: rhs_liny type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(rhs_linY) +farg2 = c_loc(rhs_liny) call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_set(farg1, farg2) end subroutine @@ -772,19 +792,19 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linY_get(self) & call c_f_pointer(fresult, swig_result) end function -subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_set(self, fv) +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_set(self, fy) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self -type(N_Vector), target, intent(inout) :: fv +type(N_Vector), target, intent(inout) :: fy type(SwigClassWrapper) :: farg1 type(C_PTR) :: farg2 farg1 = self%swigdata -farg2 = c_loc(fv) -call swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_set(farg1, farg2) +farg2 = c_loc(fy) +call swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_set(farg1, farg2) end subroutine -function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & +function swigf_SUNDomEigEstimatorContent_Arnoldi__Fy_get(self) & result(swig_result) use, intrinsic :: ISO_C_BINDING type(N_Vector), pointer :: swig_result @@ -793,7 +813,7 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__Fv_get(self) & type(SwigClassWrapper) :: farg1 farg1 = self%swigdata -fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fv_get(farg1) +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__Fy_get(farg1) call c_f_pointer(fresult, swig_result) end function @@ -947,6 +967,31 @@ function swigf_SUNDomEigEstimatorContent_Arnoldi__tol_preprocess_get(self) & swig_result = fresult end function +subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(self, rhs_lint) +use, intrinsic :: ISO_C_BINDING +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE), intent(in) :: rhs_lint +type(SwigClassWrapper) :: farg1 +real(C_DOUBLE) :: farg2 + +farg1 = self%swigdata +farg2 = rhs_lint +call swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_set(farg1, farg2) +end subroutine + +function swigf_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(self) & +result(swig_result) +use, intrinsic :: ISO_C_BINDING +real(C_DOUBLE) :: swig_result +class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self +real(C_DOUBLE) :: fresult +type(SwigClassWrapper) :: farg1 + +farg1 = self%swigdata +fresult = swigc_SUNDomEigEstimatorContent_Arnoldi__rhs_linT_get(farg1) +swig_result = fresult +end function + subroutine swigf_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_set(self, num_atimes) use, intrinsic :: ISO_C_BINDING class(SUNDomEigEstimatorContent_Arnoldi_), intent(in) :: self @@ -1316,19 +1361,22 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, v) & +function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result type(SUNDomEigEstimator), target, intent(inout) :: dee +real(C_DOUBLE), intent(in) :: t type(N_Vector), target, intent(inout) :: v integer(C_INT) :: fresult type(C_PTR) :: farg1 -type(C_PTR) :: farg2 +real(C_DOUBLE) :: farg2 +type(C_PTR) :: farg3 farg1 = c_loc(dee) -farg2 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2) +farg2 = t +farg3 = c_loc(v) +fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function From e9b5eeffbae86b83e6f85f06beb651b1c696a3c1 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 16 Mar 2026 22:52:32 -0500 Subject: [PATCH 25/76] added new examples to the answers repo --- .../C_serial/ark_brusselator_lsrk_externaldomeigest.out | 4 ++-- src/sundomeigest/power/sundomeigest_power.c | 2 +- test/answers | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out index 2966c64060..ccc4759935 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.out @@ -35,5 +35,5 @@ RHS fn evals = 47265 Number of dom_eig updates = 1 Max. num. of stages used = 195 Max. num. of stages allowed = 200 -Max. spectral radius = 202001.212007683 -Min. spectral radius = 202001.212007683 \ No newline at end of file +Max. spectral radius = 202001.210790713 +Min. spectral radius = 202001.210790713 \ No newline at end of file diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index d94ce8a0e6..1607f1e5d0 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -710,4 +710,4 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) N_VLinearSum(siginv, Jv, -siginv, Fy, Jv); return SUN_SUCCESS; -} \ No newline at end of file +} diff --git a/test/answers b/test/answers index 5ec2272ec7..92abe38290 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 5ec2272ec73e150f72c049a86ed7a8a4fc478277 +Subproject commit 92abe3829002e024ba872fdf73209550b34d4ed3 From 6503453d2b7ce5b757c34a095546f49922ae02f5 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 17 Mar 2026 09:18:41 -0500 Subject: [PATCH 26/76] treshold for real eig and output files updates --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 30 +++++++++++++++++-- .../C_serial/ark_brusselator_lsrk_domeigest.c | 11 ++++++- .../ark_brusselator_lsrk_externaldomeigest.c | 11 ++++++- src/sundomeigest/power/sundomeigest_power.c | 28 ++++++++++++----- test/answers | 2 +- 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index feba340834..5520db5481 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -259,8 +259,34 @@ instead of supplying a dummy routine. .. note:: - The relative tolerance is used as a stopping criterion for the Power Iteration method. Specifically, - it defines the acceptable relative change between successive dominant eigenvalue estimates. + The relative tolerance is used as a stopping criterion for the Power Iteration method. Specifically, + it defines the acceptable relative change between successive dominant eigenvalue estimates. It also + serves as a threshold for determining whether the dominant eigenvalue is real or complex. + + A threshold, with :math:`\varepsilon` representing the machine precision, + + .. math:: + \texttt{gram_det_tol} = 10 \cdot \max\left(\varepsilon,\; \texttt{rel_tol}\right) + + is used to assess the numerical rank of the 2×2 Gram matrix formed by the current and previous + iterates in the Power Iteration method. If the determinant of this Gram matrix is less than or equal to + this threshold, the iterates are considered nearly linearly dependent, and the dominant eigenvalue is + treated as real. + + To ensure that the Power Iteration method captures small imaginary parts of the dominant eigenvalue, + the relative tolerance should not be chosen too large. In practice, the smallest reliably detectable + imaginary part is proportional to the chosen relative tolerance, i.e., + + .. math:: + |\beta| \gtrsim \mathcal{O}(\texttt{rel_tol}). + + Therefore, to resolve an expected imaginary part of magnitude :math:`|\beta|`, it is recommended to choose + + .. math:: + \texttt{rel_tol} \ll |\beta|. + + Choosing a smaller relative tolerance improves the ability to detect weakly complex eigenvalues, + but may increase computational cost. When used in combination with Arnoldi Iteration, this routine sets the stopping criterion for the preprocessing Power Iteration phase. In this workflow, Power Iteration is first applied to diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c index 65c108d041..228fde123a 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c @@ -93,9 +93,18 @@ int main(int argc, char* argv[]) sunindextype NEQ = 3; /* number of dependent vars. */ int Nt = (int)ceil(Tf / dTout); /* number of output times */ int test = 2; /* test problem to run */ + sunrealtype a, b, ep, u0, v0, w0; + +#if defined(SUNDIALS_DOUBLE_PRECISION) sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); - sunrealtype a, b, ep, u0, v0, w0; +#elif defined(SUNDIALS_SINGLE_PRECISION) + sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-8); +#elif defined(SUNDIALS_EXTENDED_PRECISION) + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-10); +#endif /* general problem variables */ int flag; /* reusable error-checking flag */ diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 8e6a872160..5f996906cb 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -88,9 +88,18 @@ int main(int argc, char* argv[]) sunindextype NEQ = 3; /* number of dependent vars. */ int Nt = (int)ceil(Tf / dTout); /* number of output times */ int test = 2; /* test problem to run */ + sunrealtype a, b, ep, u0, v0, w0; + +#if defined(SUNDIALS_DOUBLE_PRECISION) sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); - sunrealtype a, b, ep, u0, v0, w0; +#elif defined(SUNDIALS_SINGLE_PRECISION) + sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-8); +#elif defined(SUNDIALS_EXTENDED_PRECISION) + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype abstol = SUN_RCONST(1.0e-10); +#endif /* general problem variables */ int flag; /* reusable error-checking flag */ diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 1607f1e5d0..999b20dc24 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -529,14 +529,24 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( SUNFunctionBegin(DEE->sunctx); int retval; - sunrealtype cos_qs, det_G_inv, h11, h12, h21, h22, p11, p12, p21, p22; + sunrealtype cos_qs, gram_det, det_G_inv, h11, h12, h21, h22, p11, p12, p21, p22; /* The threshold for identifying real or complex DEE is experimentally determined based on the relative tolerance PI_CONTENT(DEE)->rel_tol */ - sunrealtype proj_cond_inv = PI_CONTENT(DEE)->rel_tol; - cos_qs = N_VDotProd(v_prev, v); + sunrealtype gram_det_tol = SUNMAX(SUN_RCONST(10.0) * SUN_UNIT_ROUNDOFF, + SUN_RCONST(10.0) * PI_CONTENT(DEE)->rel_tol); + cos_qs = N_VDotProd(v_prev, v); SUNCheckLastErr(); - if (SUNRabs(SUNRabs(cos_qs) - ONE) < proj_cond_inv) + /* Safety against roundoff in dot product */ + if (cos_qs > ONE) { cos_qs = ONE; } + if (cos_qs < -ONE) { cos_qs = -ONE; } + + /* Use Gram determinant as the near-dependence measure: + G = [ [1, cos_qs], [cos_qs, 1] ], det(G) = 1 - cos_qs^2 + This assumes v_prev and v are normalized. */ + gram_det = ONE - cos_qs * cos_qs; + + if (gram_det <= gram_det_tol) { /* Dominant eigenvalue is real */ *lambdaR_out = lambdaR; @@ -545,10 +555,10 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( } else { - det_G_inv = ONE / (ONE - cos_qs * cos_qs); + det_G_inv = ONE / gram_det; - /* Solve for G = [v_prev v]' * [v_prev v] and compute - projected matrix P = G^{-1} * [v_prev v]' * A * [v_prev v] */ + /* Solve for G = [v_prev v]' * [v_prev v] and compute + projected matrix P = G^{-1} * [v_prev v]' * A * [v_prev v] */ retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, v_prev, PI_CONTENT(DEE)->q); @@ -557,7 +567,9 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } h11 = N_VDotProd(v_prev, PI_CONTENT(DEE)->q); + SUNCheckLastErr(); h21 = N_VDotProd(v, PI_CONTENT(DEE)->q); + SUNCheckLastErr(); retval = PI_CONTENT(DEE)->ATimes(PI_CONTENT(DEE)->ATdata, v, PI_CONTENT(DEE)->q); @@ -566,7 +578,9 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( if (retval != 0) { return SUN_ERR_USER_FCN_FAIL; } h12 = N_VDotProd(v_prev, PI_CONTENT(DEE)->q); + SUNCheckLastErr(); h22 = N_VDotProd(v, PI_CONTENT(DEE)->q); + SUNCheckLastErr(); p11 = det_G_inv * (h11 - cos_qs * h21); p12 = det_G_inv * (h12 - cos_qs * h22); diff --git a/test/answers b/test/answers index 92abe38290..e4069e0df0 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 92abe3829002e024ba872fdf73209550b34d4ed3 +Subproject commit e4069e0df0e9bfacd7e761937f53a730ef0267a7 From f866c62cd7b11127b2e023219815cae5006db589 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 17 Mar 2026 09:38:56 -0500 Subject: [PATCH 27/76] formatting --- .../C_serial/ark_brusselator_lsrk_domeigest.c | 18 +++++++++--------- .../ark_brusselator_lsrk_externaldomeigest.c | 18 +++++++++--------- src/sundomeigest/power/sundomeigest_power.c | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c index 228fde123a..26ab2d1ae0 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_domeigest.c @@ -87,22 +87,22 @@ static int check_flag(void* flagvalue, const char* funcname, int opt); int main(int argc, char* argv[]) { /* general problem parameters */ - sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ - sunrealtype Tf = SUN_RCONST(10.0); /* final time */ - sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ - sunindextype NEQ = 3; /* number of dependent vars. */ - int Nt = (int)ceil(Tf / dTout); /* number of output times */ - int test = 2; /* test problem to run */ + sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ + sunrealtype Tf = SUN_RCONST(10.0); /* final time */ + sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ + sunindextype NEQ = 3; /* number of dependent vars. */ + int Nt = (int)ceil(Tf / dTout); /* number of output times */ + int test = 2; /* test problem to run */ sunrealtype a, b, ep, u0, v0, w0; #if defined(SUNDIALS_DOUBLE_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); #elif defined(SUNDIALS_SINGLE_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-8); #elif defined(SUNDIALS_EXTENDED_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); #endif diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 5f996906cb..f5b57aca7d 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -82,22 +82,22 @@ typedef struct int main(int argc, char* argv[]) { /* general problem parameters */ - sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ - sunrealtype Tf = SUN_RCONST(10.0); /* final time */ - sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ - sunindextype NEQ = 3; /* number of dependent vars. */ - int Nt = (int)ceil(Tf / dTout); /* number of output times */ - int test = 2; /* test problem to run */ + sunrealtype T0 = SUN_RCONST(0.0); /* initial time */ + sunrealtype Tf = SUN_RCONST(10.0); /* final time */ + sunrealtype dTout = SUN_RCONST(1.0); /* time between outputs */ + sunindextype NEQ = 3; /* number of dependent vars. */ + int Nt = (int)ceil(Tf / dTout); /* number of output times */ + int test = 2; /* test problem to run */ sunrealtype a, b, ep, u0, v0, w0; #if defined(SUNDIALS_DOUBLE_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); #elif defined(SUNDIALS_SINGLE_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-4); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-8); #elif defined(SUNDIALS_EXTENDED_PRECISION) - sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ + sunrealtype reltol = SUN_RCONST(1.0e-6); /* tolerances */ sunrealtype abstol = SUN_RCONST(1.0e-10); #endif diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 999b20dc24..e64746b554 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -538,7 +538,7 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( SUNCheckLastErr(); /* Safety against roundoff in dot product */ - if (cos_qs > ONE) { cos_qs = ONE; } + if (cos_qs > ONE) { cos_qs = ONE; } if (cos_qs < -ONE) { cos_qs = -ONE; } /* Use Gram determinant as the near-dependence measure: From 278876e724eb71e6ee7f4c89ada53df89a3a9853 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 17 Mar 2026 10:49:07 -0500 Subject: [PATCH 28/76] memory leak --- .../arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c | 1 + test/answers | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index f5b57aca7d..963841c097 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -306,6 +306,7 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, /* Create power iteration dominant eigenvalue estimator (DEE) */ DEE = SUNDomEigEstimator_Power(temp1, data->max_iters, data->rel_tol, ctx); if (check_flag(DEE, "SUNDomEigEstimator_Power", 0)) { return 1; } + data->DEE = DEE; /* Set the ODE right-hand side function at t for the Jacobian-vector products */ flag = SUNDomEigEstimator_SetRHS(DEE, user_data, f); diff --git a/test/answers b/test/answers index e4069e0df0..e4491f134f 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit e4069e0df0e9bfacd7e761937f53a730ef0267a7 +Subproject commit e4491f134f7ecc6cff414fc254ed97eb6bcc2929 From 65dbe440e1cd58767d042e6a6f6cf339e8601cbd Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 17 Mar 2026 14:51:24 -0500 Subject: [PATCH 29/76] Missing N_VDestroys --- src/sundomeigest/power/sundomeigest_power.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index e64746b554..511b1e4253 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -639,6 +639,16 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) N_VDestroy(PI_CONTENT(DEE)->rhs_linY); PI_CONTENT(DEE)->rhs_linY = NULL; } + if (PI_CONTENT(DEE)->Fy) + { + N_VDestroy(PI_CONTENT(DEE)->Fy); + PI_CONTENT(DEE)->Fy = NULL; + } + if (PI_CONTENT(DEE)->work) + { + N_VDestroy(PI_CONTENT(DEE)->work); + PI_CONTENT(DEE)->work = NULL; + } free(DEE->content); DEE->content = NULL; } From bb7da69733a38eed69bf61a6707f2f32d8303753 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 17 Mar 2026 19:33:25 -0500 Subject: [PATCH 30/76] update the answers repo --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index e4491f134f..8cf043ca14 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit e4491f134f7ecc6cff414fc254ed97eb6bcc2929 +Subproject commit 8cf043ca14922548a22d3d0ce19737ef9e68f38a From 2a8a5c9dfb28d86c438b48b654cacdee778b8291 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 19 Mar 2026 09:39:55 -0500 Subject: [PATCH 31/76] bindings fix --- .../arkode/arkode_arkstep_generated.hpp | 114 +- .../arkode/arkode_erkstep_generated.hpp | 103 +- .../arkode/arkode_forcingstep_generated.hpp | 41 +- .../sundials4py/arkode/arkode_generated.hpp | 2994 +++++++---------- .../arkode/arkode_lsrkstep_generated.hpp | 197 +- .../arkode/arkode_mristep_generated.hpp | 390 +-- .../arkode/arkode_splittingstep_generated.hpp | 488 ++- .../arkode/arkode_sprkstep_generated.hpp | 48 +- .../sundomeigest_power_generated.hpp | 63 +- 9 files changed, 1911 insertions(+), 2527 deletions(-) diff --git a/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp index cd2a1a4775..c914e5f159 100644 --- a/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp @@ -1,85 +1,67 @@ // #ifndef _ARKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ARKStepSetExplicit", ARKStepSetExplicit, nb::arg("arkode_mem")); +m.def("ARKStepSetExplicit", + ARKStepSetExplicit, nb::arg("arkode_mem")); -m.def("ARKStepSetImplicit", ARKStepSetImplicit, nb::arg("arkode_mem")); +m.def("ARKStepSetImplicit", + ARKStepSetImplicit, nb::arg("arkode_mem")); -m.def("ARKStepSetImEx", ARKStepSetImEx, nb::arg("arkode_mem")); +m.def("ARKStepSetImEx", + ARKStepSetImEx, nb::arg("arkode_mem")); -m.def("ARKStepSetTables", ARKStepSetTables, nb::arg("arkode_mem"), nb::arg("q"), - nb::arg("p"), nb::arg("Bi"), nb::arg("Be")); +m.def("ARKStepSetTables", + ARKStepSetTables, nb::arg("arkode_mem"), nb::arg("q"), nb::arg("p"), nb::arg("Bi"), nb::arg("Be")); -m.def("ARKStepSetTableNum", ARKStepSetTableNum, nb::arg("arkode_mem"), - nb::arg("itable"), nb::arg("etable")); +m.def("ARKStepSetTableNum", + ARKStepSetTableNum, nb::arg("arkode_mem"), nb::arg("itable"), nb::arg("etable")); -m.def("ARKStepSetTableName", ARKStepSetTableName, nb::arg("arkode_mem"), - nb::arg("itable"), nb::arg("etable")); +m.def("ARKStepSetTableName", + ARKStepSetTableName, nb::arg("arkode_mem"), nb::arg("itable"), nb::arg("etable")); -m.def( - "ARKStepGetCurrentButcherTables", - [](void* arkode_mem) -> std::tuple - { - auto ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKStepGetCurrentButcherTables", + [](void * arkode_mem) -> std::tuple { - ARKodeButcherTable Bi_adapt_modifiable; - ARKodeButcherTable Be_adapt_modifiable; + auto ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + ARKodeButcherTable Bi_adapt_modifiable; + ARKodeButcherTable Be_adapt_modifiable; - int r = ARKStepGetCurrentButcherTables(arkode_mem, &Bi_adapt_modifiable, - &Be_adapt_modifiable); - return std::make_tuple(r, Bi_adapt_modifiable, Be_adapt_modifiable); - }; + int r = ARKStepGetCurrentButcherTables(arkode_mem, &Bi_adapt_modifiable, &Be_adapt_modifiable); + return std::make_tuple(r, Bi_adapt_modifiable, Be_adapt_modifiable); + }; - return ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); + return ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); -m.def( - "ARKStepGetTimestepperStats", - [](void* arkode_mem) -> std::tuple - { - auto ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) - -> std::tuple +m.def("ARKStepGetTimestepperStats", + [](void * arkode_mem) -> std::tuple { - long expsteps_adapt_modifiable; - long accsteps_adapt_modifiable; - long step_attempts_adapt_modifiable; - long nfe_evals_adapt_modifiable; - long nfi_evals_adapt_modifiable; - long nlinsetups_adapt_modifiable; - long netfails_adapt_modifiable; + auto ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long expsteps_adapt_modifiable; + long accsteps_adapt_modifiable; + long step_attempts_adapt_modifiable; + long nfe_evals_adapt_modifiable; + long nfi_evals_adapt_modifiable; + long nlinsetups_adapt_modifiable; + long netfails_adapt_modifiable; - int r = ARKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, - &accsteps_adapt_modifiable, - &step_attempts_adapt_modifiable, - &nfe_evals_adapt_modifiable, - &nfi_evals_adapt_modifiable, - &nlinsetups_adapt_modifiable, - &netfails_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable, - accsteps_adapt_modifiable, - step_attempts_adapt_modifiable, - nfe_evals_adapt_modifiable, - nfi_evals_adapt_modifiable, - nlinsetups_adapt_modifiable, - netfails_adapt_modifiable); - }; + int r = ARKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, &accsteps_adapt_modifiable, &step_attempts_adapt_modifiable, &nfe_evals_adapt_modifiable, &nfi_evals_adapt_modifiable, &nlinsetups_adapt_modifiable, &netfails_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable, accsteps_adapt_modifiable, step_attempts_adapt_modifiable, nfe_evals_adapt_modifiable, nfi_evals_adapt_modifiable, nlinsetups_adapt_modifiable, netfails_adapt_modifiable); + }; - return ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); + return ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp index 019ac44004..e1ead7144f 100644 --- a/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp @@ -1,68 +1,57 @@ // #ifndef _ERKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ERKStepSetTable", ERKStepSetTable, nb::arg("arkode_mem"), nb::arg("B")); +m.def("ERKStepSetTable", + ERKStepSetTable, nb::arg("arkode_mem"), nb::arg("B")); -m.def("ERKStepSetTableNum", ERKStepSetTableNum, nb::arg("arkode_mem"), - nb::arg("etable")); +m.def("ERKStepSetTableNum", + ERKStepSetTableNum, nb::arg("arkode_mem"), nb::arg("etable")); -m.def("ERKStepSetTableName", ERKStepSetTableName, nb::arg("arkode_mem"), - nb::arg("etable")); +m.def("ERKStepSetTableName", + ERKStepSetTableName, nb::arg("arkode_mem"), nb::arg("etable")); -m.def( - "ERKStepGetCurrentButcherTable", - [](void* arkode_mem) -> std::tuple - { - auto ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ERKStepGetCurrentButcherTable", + [](void * arkode_mem) -> std::tuple { - ARKodeButcherTable B_adapt_modifiable; - - int r = ERKStepGetCurrentButcherTable(arkode_mem, &B_adapt_modifiable); - return std::make_tuple(r, B_adapt_modifiable); - }; - - return ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def( - "ERKStepGetTimestepperStats", - [](void* arkode_mem) -> std::tuple - { - auto ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + ARKodeButcherTable B_adapt_modifiable; + + int r = ERKStepGetCurrentButcherTable(arkode_mem, &B_adapt_modifiable); + return std::make_tuple(r, B_adapt_modifiable); + }; + + return ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("ERKStepGetTimestepperStats", + [](void * arkode_mem) -> std::tuple { - long expsteps_adapt_modifiable; - long accsteps_adapt_modifiable; - long step_attempts_adapt_modifiable; - long nfevals_adapt_modifiable; - long netfails_adapt_modifiable; - - int r = ERKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, - &accsteps_adapt_modifiable, - &step_attempts_adapt_modifiable, - &nfevals_adapt_modifiable, - &netfails_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable, - accsteps_adapt_modifiable, - step_attempts_adapt_modifiable, - nfevals_adapt_modifiable, netfails_adapt_modifiable); - }; - - return ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), "Grouped optional output functions"); + auto ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long expsteps_adapt_modifiable; + long accsteps_adapt_modifiable; + long step_attempts_adapt_modifiable; + long nfevals_adapt_modifiable; + long netfails_adapt_modifiable; + + int r = ERKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, &accsteps_adapt_modifiable, &step_attempts_adapt_modifiable, &nfevals_adapt_modifiable, &netfails_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable, accsteps_adapt_modifiable, step_attempts_adapt_modifiable, nfevals_adapt_modifiable, netfails_adapt_modifiable); + }; + + return ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + "Grouped optional output functions"); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp b/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp index ca5d33a7c3..ad7d27b2ea 100644 --- a/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp @@ -1,33 +1,28 @@ // #ifndef ARKODE_FORCINGINGSTEP_H_ -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ForcingStepReInit", ForcingStepReInit, nb::arg("arkode_mem"), - nb::arg("stepper1"), nb::arg("stepper2"), nb::arg("t0"), nb::arg("y0")); +m.def("ForcingStepReInit", + ForcingStepReInit, nb::arg("arkode_mem"), nb::arg("stepper1"), nb::arg("stepper2"), nb::arg("t0"), nb::arg("y0")); -m.def( - "ForcingStepGetNumEvolves", - [](void* arkode_mem, int partition) -> std::tuple - { - auto ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return = - [](void* arkode_mem, int partition) -> std::tuple +m.def("ForcingStepGetNumEvolves", + [](void * arkode_mem, int partition) -> std::tuple { - long evolves_adapt_modifiable; + auto ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition) -> std::tuple + { + long evolves_adapt_modifiable; - int r = ForcingStepGetNumEvolves(arkode_mem, partition, - &evolves_adapt_modifiable); - return std::make_tuple(r, evolves_adapt_modifiable); - }; + int r = ForcingStepGetNumEvolves(arkode_mem, partition, &evolves_adapt_modifiable); + return std::make_tuple(r, evolves_adapt_modifiable); + }; - return ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, - partition); - }, - nb::arg("arkode_mem"), nb::arg("partition")); + return ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, partition); + }, nb::arg("arkode_mem"), nb::arg("partition")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_generated.hpp b/bindings/sundials4py/arkode/arkode_generated.hpp index e5e6bba6c3..321c4f855d 100644 --- a/bindings/sundials4py/arkode/arkode_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_generated.hpp @@ -1,1922 +1,1508 @@ // #ifndef _ARKODE_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// -m.attr("ARK_NORMAL") = 1; -m.attr("ARK_ONE_STEP") = 2; -m.attr("ARK_ADAPT_CUSTOM") = -1; -m.attr("ARK_ADAPT_PID") = 0; -m.attr("ARK_ADAPT_PI") = 1; -m.attr("ARK_ADAPT_I") = 2; -m.attr("ARK_ADAPT_EXP_GUS") = 3; -m.attr("ARK_ADAPT_IMP_GUS") = 4; -m.attr("ARK_ADAPT_IMEX_GUS") = 5; -m.attr("ARK_FULLRHS_START") = 0; -m.attr("ARK_FULLRHS_END") = 1; -m.attr("ARK_FULLRHS_OTHER") = 2; -m.attr("ARK_INTERP_MAX_DEGREE") = 5; -m.attr("ARK_INTERP_NONE") = -1; -m.attr("ARK_INTERP_HERMITE") = 0; -m.attr("ARK_INTERP_LAGRANGE") = 1; -m.attr("ARK_SUCCESS") = 0; -m.attr("ARK_TSTOP_RETURN") = 1; -m.attr("ARK_ROOT_RETURN") = 2; -m.attr("ARK_WARNING") = 99; -m.attr("ARK_TOO_MUCH_WORK") = -1; -m.attr("ARK_TOO_MUCH_ACC") = -2; -m.attr("ARK_ERR_FAILURE") = -3; -m.attr("ARK_CONV_FAILURE") = -4; -m.attr("ARK_LINIT_FAIL") = -5; -m.attr("ARK_LSETUP_FAIL") = -6; -m.attr("ARK_LSOLVE_FAIL") = -7; -m.attr("ARK_RHSFUNC_FAIL") = -8; -m.attr("ARK_FIRST_RHSFUNC_ERR") = -9; -m.attr("ARK_REPTD_RHSFUNC_ERR") = -10; -m.attr("ARK_UNREC_RHSFUNC_ERR") = -11; -m.attr("ARK_RTFUNC_FAIL") = -12; -m.attr("ARK_LFREE_FAIL") = -13; -m.attr("ARK_MASSINIT_FAIL") = -14; -m.attr("ARK_MASSSETUP_FAIL") = -15; -m.attr("ARK_MASSSOLVE_FAIL") = -16; -m.attr("ARK_MASSFREE_FAIL") = -17; -m.attr("ARK_MASSMULT_FAIL") = -18; -m.attr("ARK_CONSTR_FAIL") = -19; -m.attr("ARK_MEM_FAIL") = -20; -m.attr("ARK_MEM_NULL") = -21; -m.attr("ARK_ILL_INPUT") = -22; -m.attr("ARK_NO_MALLOC") = -23; -m.attr("ARK_BAD_K") = -24; -m.attr("ARK_BAD_T") = -25; -m.attr("ARK_BAD_DKY") = -26; -m.attr("ARK_TOO_CLOSE") = -27; -m.attr("ARK_VECTOROP_ERR") = -28; -m.attr("ARK_NLS_INIT_FAIL") = -29; -m.attr("ARK_NLS_SETUP_FAIL") = -30; -m.attr("ARK_NLS_SETUP_RECVR") = -31; -m.attr("ARK_NLS_OP_ERR") = -32; -m.attr("ARK_INNERSTEP_ATTACH_ERR") = -33; -m.attr("ARK_INNERSTEP_FAIL") = -34; -m.attr("ARK_OUTERTOINNER_FAIL") = -35; -m.attr("ARK_INNERTOOUTER_FAIL") = -36; -m.attr("ARK_POSTPROCESS_FAIL") = -37; -m.attr("ARK_POSTPROCESS_STEP_FAIL") = -37; +// +m.attr("ARK_NORMAL") = 1; +m.attr("ARK_ONE_STEP") = 2; +m.attr("ARK_ADAPT_CUSTOM") = -1; +m.attr("ARK_ADAPT_PID") = 0; +m.attr("ARK_ADAPT_PI") = 1; +m.attr("ARK_ADAPT_I") = 2; +m.attr("ARK_ADAPT_EXP_GUS") = 3; +m.attr("ARK_ADAPT_IMP_GUS") = 4; +m.attr("ARK_ADAPT_IMEX_GUS") = 5; +m.attr("ARK_FULLRHS_START") = 0; +m.attr("ARK_FULLRHS_END") = 1; +m.attr("ARK_FULLRHS_OTHER") = 2; +m.attr("ARK_INTERP_MAX_DEGREE") = 5; +m.attr("ARK_INTERP_NONE") = -1; +m.attr("ARK_INTERP_HERMITE") = 0; +m.attr("ARK_INTERP_LAGRANGE") = 1; +m.attr("ARK_SUCCESS") = 0; +m.attr("ARK_TSTOP_RETURN") = 1; +m.attr("ARK_ROOT_RETURN") = 2; +m.attr("ARK_WARNING") = 99; +m.attr("ARK_TOO_MUCH_WORK") = -1; +m.attr("ARK_TOO_MUCH_ACC") = -2; +m.attr("ARK_ERR_FAILURE") = -3; +m.attr("ARK_CONV_FAILURE") = -4; +m.attr("ARK_LINIT_FAIL") = -5; +m.attr("ARK_LSETUP_FAIL") = -6; +m.attr("ARK_LSOLVE_FAIL") = -7; +m.attr("ARK_RHSFUNC_FAIL") = -8; +m.attr("ARK_FIRST_RHSFUNC_ERR") = -9; +m.attr("ARK_REPTD_RHSFUNC_ERR") = -10; +m.attr("ARK_UNREC_RHSFUNC_ERR") = -11; +m.attr("ARK_RTFUNC_FAIL") = -12; +m.attr("ARK_LFREE_FAIL") = -13; +m.attr("ARK_MASSINIT_FAIL") = -14; +m.attr("ARK_MASSSETUP_FAIL") = -15; +m.attr("ARK_MASSSOLVE_FAIL") = -16; +m.attr("ARK_MASSFREE_FAIL") = -17; +m.attr("ARK_MASSMULT_FAIL") = -18; +m.attr("ARK_CONSTR_FAIL") = -19; +m.attr("ARK_MEM_FAIL") = -20; +m.attr("ARK_MEM_NULL") = -21; +m.attr("ARK_ILL_INPUT") = -22; +m.attr("ARK_NO_MALLOC") = -23; +m.attr("ARK_BAD_K") = -24; +m.attr("ARK_BAD_T") = -25; +m.attr("ARK_BAD_DKY") = -26; +m.attr("ARK_TOO_CLOSE") = -27; +m.attr("ARK_VECTOROP_ERR") = -28; +m.attr("ARK_NLS_INIT_FAIL") = -29; +m.attr("ARK_NLS_SETUP_FAIL") = -30; +m.attr("ARK_NLS_SETUP_RECVR") = -31; +m.attr("ARK_NLS_OP_ERR") = -32; +m.attr("ARK_INNERSTEP_ATTACH_ERR") = -33; +m.attr("ARK_INNERSTEP_FAIL") = -34; +m.attr("ARK_OUTERTOINNER_FAIL") = -35; +m.attr("ARK_INNERTOOUTER_FAIL") = -36; +m.attr("ARK_POSTPROCESS_FAIL") = -37; +m.attr("ARK_POSTPROCESS_STEP_FAIL") = -37; m.attr("ARK_POSTPROCESS_STAGE_FAIL") = -38; -m.attr("ARK_USER_PREDICT_FAIL") = -39; -m.attr("ARK_INTERP_FAIL") = -40; -m.attr("ARK_INVALID_TABLE") = -41; -m.attr("ARK_CONTEXT_ERR") = -42; -m.attr("ARK_RELAX_FAIL") = -43; -m.attr("ARK_RELAX_MEM_NULL") = -44; -m.attr("ARK_RELAX_FUNC_FAIL") = -45; -m.attr("ARK_RELAX_JAC_FAIL") = -46; -m.attr("ARK_CONTROLLER_ERR") = -47; -m.attr("ARK_STEPPER_UNSUPPORTED") = -48; -m.attr("ARK_DOMEIG_FAIL") = -49; -m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -50; -m.attr("ARK_SUNSTEPPER_ERR") = -51; -m.attr("ARK_STEP_DIRECTION_ERR") = -52; -m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -53; -m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -54; -m.attr("ARK_SUNADJSTEPPER_ERR") = -55; -m.attr("ARK_DEE_FAIL") = -56; -m.attr("ARK_UNRECOGNIZED_ERROR") = -99; - -auto pyEnumARKRelaxSolver = nb::enum_(m, "ARKRelaxSolver", - nb::is_arithmetic(), "") - .value("ARK_RELAX_BRENT", ARK_RELAX_BRENT, "") - .value("ARK_RELAX_NEWTON", ARK_RELAX_NEWTON, "") - .export_values(); +m.attr("ARK_USER_PREDICT_FAIL") = -39; +m.attr("ARK_INTERP_FAIL") = -40; +m.attr("ARK_INVALID_TABLE") = -41; +m.attr("ARK_CONTEXT_ERR") = -42; +m.attr("ARK_RELAX_FAIL") = -43; +m.attr("ARK_RELAX_MEM_NULL") = -44; +m.attr("ARK_RELAX_FUNC_FAIL") = -45; +m.attr("ARK_RELAX_JAC_FAIL") = -46; +m.attr("ARK_CONTROLLER_ERR") = -47; +m.attr("ARK_STEPPER_UNSUPPORTED") = -48; +m.attr("ARK_DOMEIG_FAIL") = -49; +m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -50; +m.attr("ARK_SUNSTEPPER_ERR") = -51; +m.attr("ARK_STEP_DIRECTION_ERR") = -52; +m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -53; +m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -54; +m.attr("ARK_SUNADJSTEPPER_ERR") = -55; +m.attr("ARK_DEE_FAIL") = -56; +m.attr("ARK_UNRECOGNIZED_ERROR") = -99; + + +auto pyEnumARKRelaxSolver = + nb::enum_(m, "ARKRelaxSolver", nb::is_arithmetic(), "") + .value("ARK_RELAX_BRENT", ARK_RELAX_BRENT, "") + .value("ARK_RELAX_NEWTON", ARK_RELAX_NEWTON, "") + .export_values(); // #ifndef SWIG -// +// // #endif -// +// + auto pyEnumARKAccumError = - nb::enum_(m, "ARKAccumError", nb::is_arithmetic(), "") - .value("ARK_ACCUMERROR_NONE", ARK_ACCUMERROR_NONE, "") - .value("ARK_ACCUMERROR_MAX", ARK_ACCUMERROR_MAX, "") - .value("ARK_ACCUMERROR_SUM", ARK_ACCUMERROR_SUM, "") - .value("ARK_ACCUMERROR_AVG", ARK_ACCUMERROR_AVG, "") + nb::enum_(m, "ARKAccumError", nb::is_arithmetic(), "") + .value("ARK_ACCUMERROR_NONE", ARK_ACCUMERROR_NONE, "") + .value("ARK_ACCUMERROR_MAX", ARK_ACCUMERROR_MAX, "") + .value("ARK_ACCUMERROR_SUM", ARK_ACCUMERROR_SUM, "") + .value("ARK_ACCUMERROR_AVG", ARK_ACCUMERROR_AVG, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def("ARKodeReset", ARKodeReset, nb::arg("arkode_mem"), nb::arg("tR"), - nb::arg("yR")); - -m.def( - "ARKodeCreateMRIStepInnerStepper", - [](void* arkode_mem) - -> std::tuple>> - { - auto ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - MRIStepInnerStepper stepper_adapt_modifiable; - - int r = ARKodeCreateMRIStepInnerStepper(arkode_mem, - &stepper_adapt_modifiable); - return std::make_tuple(r, stepper_adapt_modifiable); - }; - auto ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr = - [&ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return]( - void* arkode_mem) - -> std::tuple>> +// + +m.def("ARKodeReset", + ARKodeReset, nb::arg("arkode_mem"), nb::arg("tR"), nb::arg("yR")); + +m.def("ARKodeCreateMRIStepInnerStepper", + [](void * arkode_mem) -> std::tuple>> { - auto lambda_result = - ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return( - arkode_mem); - - return std::make_tuple(std::get<0>(lambda_result), - our_make_shared, - MRIStepInnerStepperDeleter>( - std::get<1>(lambda_result))); - }; - - return ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr( - arkode_mem); - }, - nb::arg("arkode_mem"), "Utility to wrap ARKODE as an MRIStepInnerStepper", - nb::rv_policy::reference); - -m.def("ARKodeSStolerances", ARKodeSStolerances, nb::arg("arkode_mem"), - nb::arg("reltol"), nb::arg("abstol")); - -m.def("ARKodeSVtolerances", ARKodeSVtolerances, nb::arg("arkode_mem"), - nb::arg("reltol"), nb::arg("abstol")); - -m.def("ARKodeResStolerance", ARKodeResStolerance, nb::arg("arkode_mem"), - nb::arg("rabstol")); - -m.def("ARKodeResVtolerance", ARKodeResVtolerance, nb::arg("arkode_mem"), - nb::arg("rabstol")); - -m.def( - "ARKodeSetRootDirection", - [](void* arkode_mem, std::vector rootdir_1d) -> int - { - auto ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector = - [](void* arkode_mem, std::vector rootdir_1d) -> int + auto ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + MRIStepInnerStepper stepper_adapt_modifiable; + + int r = ARKodeCreateMRIStepInnerStepper(arkode_mem, &stepper_adapt_modifiable); + return std::make_tuple(r, stepper_adapt_modifiable); + }; + auto ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr = [&ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return](void * arkode_mem) -> std::tuple>> + { + auto lambda_result = ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return(arkode_mem); + + return std::make_tuple(std::get<0>(lambda_result), our_make_shared, MRIStepInnerStepperDeleter>(std::get<1>(lambda_result))); + return lambda_result; + }; + + return ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr(arkode_mem); + }, + nb::arg("arkode_mem"), + "Utility to wrap ARKODE as an MRIStepInnerStepper", + nb::rv_policy::reference); + +m.def("ARKodeSStolerances", + ARKodeSStolerances, nb::arg("arkode_mem"), nb::arg("reltol"), nb::arg("abstol")); + +m.def("ARKodeSVtolerances", + ARKodeSVtolerances, nb::arg("arkode_mem"), nb::arg("reltol"), nb::arg("abstol")); + +m.def("ARKodeResStolerance", + ARKodeResStolerance, nb::arg("arkode_mem"), nb::arg("rabstol")); + +m.def("ARKodeResVtolerance", + ARKodeResVtolerance, nb::arg("arkode_mem"), nb::arg("rabstol")); + +m.def("ARKodeSetRootDirection", + [](void * arkode_mem, std::vector rootdir_1d) -> int { - int* rootdir_1d_ptr = rootdir_1d.empty() ? nullptr : rootdir_1d.data(); + auto ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector = [](void * arkode_mem, std::vector rootdir_1d) -> int + { + int* rootdir_1d_ptr = rootdir_1d.empty() ? nullptr : rootdir_1d.data(); - auto lambda_result = ARKodeSetRootDirection(arkode_mem, rootdir_1d_ptr); - return lambda_result; - }; + auto lambda_result = ARKodeSetRootDirection(arkode_mem, rootdir_1d_ptr); + return lambda_result; + }; - return ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector(arkode_mem, - rootdir_1d); - }, - nb::arg("arkode_mem"), nb::arg("rootdir_1d")); + return ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector(arkode_mem, rootdir_1d); + }, nb::arg("arkode_mem"), nb::arg("rootdir_1d")); -m.def("ARKodeSetNoInactiveRootWarn", ARKodeSetNoInactiveRootWarn, - nb::arg("arkode_mem")); +m.def("ARKodeSetNoInactiveRootWarn", + ARKodeSetNoInactiveRootWarn, nb::arg("arkode_mem")); -m.def("ARKodeSetDefaults", ARKodeSetDefaults, nb::arg("arkode_mem")); +m.def("ARKodeSetDefaults", + ARKodeSetDefaults, nb::arg("arkode_mem")); -m.def("ARKodeSetOrder", ARKodeSetOrder, nb::arg("arkode_mem"), nb::arg("maxord")); +m.def("ARKodeSetOrder", + ARKodeSetOrder, nb::arg("arkode_mem"), nb::arg("maxord")); -m.def("ARKodeSetInterpolantType", ARKodeSetInterpolantType, - nb::arg("arkode_mem"), nb::arg("itype")); +m.def("ARKodeSetInterpolantType", + ARKodeSetInterpolantType, nb::arg("arkode_mem"), nb::arg("itype")); -m.def("ARKodeSetInterpolantDegree", ARKodeSetInterpolantDegree, - nb::arg("arkode_mem"), nb::arg("degree")); +m.def("ARKodeSetInterpolantDegree", + ARKodeSetInterpolantDegree, nb::arg("arkode_mem"), nb::arg("degree")); -m.def("ARKodeSetMaxNumSteps", ARKodeSetMaxNumSteps, nb::arg("arkode_mem"), - nb::arg("mxsteps")); +m.def("ARKodeSetMaxNumSteps", + ARKodeSetMaxNumSteps, nb::arg("arkode_mem"), nb::arg("mxsteps")); -m.def("ARKodeSetInterpolateStopTime", ARKodeSetInterpolateStopTime, - nb::arg("arkode_mem"), nb::arg("interp")); +m.def("ARKodeSetInterpolateStopTime", + ARKodeSetInterpolateStopTime, nb::arg("arkode_mem"), nb::arg("interp")); -m.def("ARKodeSetStopTime", ARKodeSetStopTime, nb::arg("arkode_mem"), - nb::arg("tstop")); +m.def("ARKodeSetStopTime", + ARKodeSetStopTime, nb::arg("arkode_mem"), nb::arg("tstop")); -m.def("ARKodeClearStopTime", ARKodeClearStopTime, nb::arg("arkode_mem")); +m.def("ARKodeClearStopTime", + ARKodeClearStopTime, nb::arg("arkode_mem")); -m.def("ARKodeSetFixedStep", ARKodeSetFixedStep, nb::arg("arkode_mem"), - nb::arg("hfixed")); +m.def("ARKodeSetFixedStep", + ARKodeSetFixedStep, nb::arg("arkode_mem"), nb::arg("hfixed")); -m.def("ARKodeSetStepDirection", ARKodeSetStepDirection, nb::arg("arkode_mem"), - nb::arg("stepdir")); +m.def("ARKodeSetStepDirection", + ARKodeSetStepDirection, nb::arg("arkode_mem"), nb::arg("stepdir")); -m.def("ARKodeSetNonlinearSolver", ARKodeSetNonlinearSolver, - nb::arg("arkode_mem"), nb::arg("NLS")); +m.def("ARKodeSetNonlinearSolver", + ARKodeSetNonlinearSolver, nb::arg("arkode_mem"), nb::arg("NLS")); -m.def("ARKodeSetLinear", ARKodeSetLinear, nb::arg("arkode_mem"), - nb::arg("timedepend")); +m.def("ARKodeSetLinear", + ARKodeSetLinear, nb::arg("arkode_mem"), nb::arg("timedepend")); -m.def("ARKodeSetNonlinear", ARKodeSetNonlinear, nb::arg("arkode_mem")); +m.def("ARKodeSetNonlinear", + ARKodeSetNonlinear, nb::arg("arkode_mem")); -m.def("ARKodeSetAutonomous", ARKodeSetAutonomous, nb::arg("arkode_mem"), - nb::arg("autonomous")); +m.def("ARKodeSetAutonomous", + ARKodeSetAutonomous, nb::arg("arkode_mem"), nb::arg("autonomous")); -m.def("ARKodeSetDeduceImplicitRhs", ARKodeSetDeduceImplicitRhs, - nb::arg("arkode_mem"), nb::arg("deduce")); +m.def("ARKodeSetDeduceImplicitRhs", + ARKodeSetDeduceImplicitRhs, nb::arg("arkode_mem"), nb::arg("deduce")); -m.def("ARKodeSetNonlinCRDown", ARKodeSetNonlinCRDown, nb::arg("arkode_mem"), - nb::arg("crdown")); +m.def("ARKodeSetNonlinCRDown", + ARKodeSetNonlinCRDown, nb::arg("arkode_mem"), nb::arg("crdown")); -m.def("ARKodeSetNonlinRDiv", ARKodeSetNonlinRDiv, nb::arg("arkode_mem"), - nb::arg("rdiv")); +m.def("ARKodeSetNonlinRDiv", + ARKodeSetNonlinRDiv, nb::arg("arkode_mem"), nb::arg("rdiv")); -m.def("ARKodeSetDeltaGammaMax", ARKodeSetDeltaGammaMax, nb::arg("arkode_mem"), - nb::arg("dgmax")); +m.def("ARKodeSetDeltaGammaMax", + ARKodeSetDeltaGammaMax, nb::arg("arkode_mem"), nb::arg("dgmax")); -m.def("ARKodeSetLSetupFrequency", ARKodeSetLSetupFrequency, - nb::arg("arkode_mem"), nb::arg("msbp")); +m.def("ARKodeSetLSetupFrequency", + ARKodeSetLSetupFrequency, nb::arg("arkode_mem"), nb::arg("msbp")); -m.def("ARKodeSetPredictorMethod", ARKodeSetPredictorMethod, - nb::arg("arkode_mem"), nb::arg("method")); +m.def("ARKodeSetPredictorMethod", + ARKodeSetPredictorMethod, nb::arg("arkode_mem"), nb::arg("method")); -m.def("ARKodeSetMaxNonlinIters", ARKodeSetMaxNonlinIters, nb::arg("arkode_mem"), - nb::arg("maxcor")); +m.def("ARKodeSetMaxNonlinIters", + ARKodeSetMaxNonlinIters, nb::arg("arkode_mem"), nb::arg("maxcor")); -m.def("ARKodeSetMaxConvFails", ARKodeSetMaxConvFails, nb::arg("arkode_mem"), - nb::arg("maxncf")); +m.def("ARKodeSetMaxConvFails", + ARKodeSetMaxConvFails, nb::arg("arkode_mem"), nb::arg("maxncf")); -m.def("ARKodeSetNonlinConvCoef", ARKodeSetNonlinConvCoef, nb::arg("arkode_mem"), - nb::arg("nlscoef")); +m.def("ARKodeSetNonlinConvCoef", + ARKodeSetNonlinConvCoef, nb::arg("arkode_mem"), nb::arg("nlscoef")); -m.def("ARKodeSetAdaptController", ARKodeSetAdaptController, - nb::arg("arkode_mem"), nb::arg("C")); +m.def("ARKodeSetAdaptController", + ARKodeSetAdaptController, nb::arg("arkode_mem"), nb::arg("C")); -m.def("ARKodeSetAdaptControllerByName", ARKodeSetAdaptControllerByName, - nb::arg("arkode_mem"), nb::arg("cname")); +m.def("ARKodeSetAdaptControllerByName", + ARKodeSetAdaptControllerByName, nb::arg("arkode_mem"), nb::arg("cname")); -m.def("ARKodeSetAdaptivityAdjustment", ARKodeSetAdaptivityAdjustment, - nb::arg("arkode_mem"), nb::arg("adjust")); +m.def("ARKodeSetAdaptivityAdjustment", + ARKodeSetAdaptivityAdjustment, nb::arg("arkode_mem"), nb::arg("adjust")); -m.def("ARKodeSetCFLFraction", ARKodeSetCFLFraction, nb::arg("arkode_mem"), - nb::arg("cfl_frac")); +m.def("ARKodeSetCFLFraction", + ARKodeSetCFLFraction, nb::arg("arkode_mem"), nb::arg("cfl_frac")); -m.def("ARKodeSetErrorBias", ARKodeSetErrorBias, nb::arg("arkode_mem"), - nb::arg("bias")); +m.def("ARKodeSetErrorBias", + ARKodeSetErrorBias, nb::arg("arkode_mem"), nb::arg("bias")); -m.def("ARKodeSetSafetyFactor", ARKodeSetSafetyFactor, nb::arg("arkode_mem"), - nb::arg("safety")); +m.def("ARKodeSetSafetyFactor", + ARKodeSetSafetyFactor, nb::arg("arkode_mem"), nb::arg("safety")); -m.def("ARKodeSetMaxGrowth", ARKodeSetMaxGrowth, nb::arg("arkode_mem"), - nb::arg("mx_growth")); +m.def("ARKodeSetMaxGrowth", + ARKodeSetMaxGrowth, nb::arg("arkode_mem"), nb::arg("mx_growth")); -m.def("ARKodeSetMinReduction", ARKodeSetMinReduction, nb::arg("arkode_mem"), - nb::arg("eta_min")); +m.def("ARKodeSetMinReduction", + ARKodeSetMinReduction, nb::arg("arkode_mem"), nb::arg("eta_min")); -m.def("ARKodeSetFixedStepBounds", ARKodeSetFixedStepBounds, - nb::arg("arkode_mem"), nb::arg("lb"), nb::arg("ub")); +m.def("ARKodeSetFixedStepBounds", + ARKodeSetFixedStepBounds, nb::arg("arkode_mem"), nb::arg("lb"), nb::arg("ub")); -m.def("ARKodeSetMaxFirstGrowth", ARKodeSetMaxFirstGrowth, nb::arg("arkode_mem"), - nb::arg("etamx1")); +m.def("ARKodeSetMaxFirstGrowth", + ARKodeSetMaxFirstGrowth, nb::arg("arkode_mem"), nb::arg("etamx1")); -m.def("ARKodeSetMaxEFailGrowth", ARKodeSetMaxEFailGrowth, nb::arg("arkode_mem"), - nb::arg("etamxf")); +m.def("ARKodeSetMaxEFailGrowth", + ARKodeSetMaxEFailGrowth, nb::arg("arkode_mem"), nb::arg("etamxf")); -m.def("ARKodeSetSmallNumEFails", ARKodeSetSmallNumEFails, nb::arg("arkode_mem"), - nb::arg("small_nef")); +m.def("ARKodeSetSmallNumEFails", + ARKodeSetSmallNumEFails, nb::arg("arkode_mem"), nb::arg("small_nef")); -m.def("ARKodeSetMaxCFailGrowth", ARKodeSetMaxCFailGrowth, nb::arg("arkode_mem"), - nb::arg("etacf")); +m.def("ARKodeSetMaxCFailGrowth", + ARKodeSetMaxCFailGrowth, nb::arg("arkode_mem"), nb::arg("etacf")); -m.def("ARKodeSetMaxErrTestFails", ARKodeSetMaxErrTestFails, - nb::arg("arkode_mem"), nb::arg("maxnef")); +m.def("ARKodeSetMaxErrTestFails", + ARKodeSetMaxErrTestFails, nb::arg("arkode_mem"), nb::arg("maxnef")); -m.def("ARKodeSetConstraints", ARKodeSetConstraints, nb::arg("arkode_mem"), - nb::arg("constraints")); +m.def("ARKodeSetConstraints", + ARKodeSetConstraints, nb::arg("arkode_mem"), nb::arg("constraints")); -m.def("ARKodeSetMaxHnilWarns", ARKodeSetMaxHnilWarns, nb::arg("arkode_mem"), - nb::arg("mxhnil")); +m.def("ARKodeSetMaxHnilWarns", + ARKodeSetMaxHnilWarns, nb::arg("arkode_mem"), nb::arg("mxhnil")); -m.def("ARKodeSetInitStep", ARKodeSetInitStep, nb::arg("arkode_mem"), - nb::arg("hin")); +m.def("ARKodeSetInitStep", + ARKodeSetInitStep, nb::arg("arkode_mem"), nb::arg("hin")); -m.def("ARKodeSetMinStep", ARKodeSetMinStep, nb::arg("arkode_mem"), - nb::arg("hmin")); +m.def("ARKodeSetMinStep", + ARKodeSetMinStep, nb::arg("arkode_mem"), nb::arg("hmin")); -m.def("ARKodeSetMaxStep", ARKodeSetMaxStep, nb::arg("arkode_mem"), - nb::arg("hmax")); +m.def("ARKodeSetMaxStep", + ARKodeSetMaxStep, nb::arg("arkode_mem"), nb::arg("hmax")); -m.def("ARKodeSetMaxNumConstrFails", ARKodeSetMaxNumConstrFails, - nb::arg("arkode_mem"), nb::arg("maxfails")); +m.def("ARKodeSetMaxNumConstrFails", + ARKodeSetMaxNumConstrFails, nb::arg("arkode_mem"), nb::arg("maxfails")); -m.def("ARKodeSetAdjointCheckpointScheme", ARKodeSetAdjointCheckpointScheme, - nb::arg("arkode_mem"), nb::arg("checkpoint_scheme")); +m.def("ARKodeSetAdjointCheckpointScheme", + ARKodeSetAdjointCheckpointScheme, nb::arg("arkode_mem"), nb::arg("checkpoint_scheme")); -m.def("ARKodeSetAdjointCheckpointIndex", ARKodeSetAdjointCheckpointIndex, - nb::arg("arkode_mem"), nb::arg("step_index")); +m.def("ARKodeSetAdjointCheckpointIndex", + ARKodeSetAdjointCheckpointIndex, nb::arg("arkode_mem"), nb::arg("step_index")); -m.def("ARKodeSetUseCompensatedSums", ARKodeSetUseCompensatedSums, - nb::arg("arkode_mem"), nb::arg("onoff")); +m.def("ARKodeSetUseCompensatedSums", + ARKodeSetUseCompensatedSums, nb::arg("arkode_mem"), nb::arg("onoff")); -m.def("ARKodeSetAccumulatedErrorType", ARKodeSetAccumulatedErrorType, - nb::arg("arkode_mem"), nb::arg("accum_type")); +m.def("ARKodeSetAccumulatedErrorType", + ARKodeSetAccumulatedErrorType, nb::arg("arkode_mem"), nb::arg("accum_type")); -m.def("ARKodeResetAccumulatedError", ARKodeResetAccumulatedError, - nb::arg("arkode_mem")); +m.def("ARKodeResetAccumulatedError", + ARKodeResetAccumulatedError, nb::arg("arkode_mem")); -m.def( - "ARKodeEvolve", - [](void* arkode_mem, sunrealtype tout, N_Vector yout, - int itask) -> std::tuple - { - auto ARKodeEvolve_adapt_modifiable_immutable_to_return = - [](void* arkode_mem, sunrealtype tout, N_Vector yout, - int itask) -> std::tuple - { - sunrealtype tret_adapt_modifiable; - - int r = ARKodeEvolve(arkode_mem, tout, yout, &tret_adapt_modifiable, itask); - return std::make_tuple(r, tret_adapt_modifiable); - }; - - return ARKodeEvolve_adapt_modifiable_immutable_to_return(arkode_mem, tout, - yout, itask); - }, - nb::arg("arkode_mem"), nb::arg("tout"), nb::arg("yout"), nb::arg("itask"), - "Integrate the ODE over an interval in t"); - -m.def("ARKodeGetDky", ARKodeGetDky, nb::arg("arkode_mem"), nb::arg("t"), - nb::arg("k"), nb::arg("dky"), - "Computes the kth derivative of the y function at time t"); - -m.def("ARKodeComputeState", ARKodeComputeState, nb::arg("arkode_mem"), - nb::arg("zcor"), nb::arg("z"), - "Utility function to update/compute y based on zcor"); - -m.def( - "ARKodeGetNumRhsEvals", - [](void* arkode_mem, int partition_index) -> std::tuple - { - auto ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem, int partition_index) -> std::tuple - { - long num_rhs_evals_adapt_modifiable; - - int r = ARKodeGetNumRhsEvals(arkode_mem, partition_index, - &num_rhs_evals_adapt_modifiable); - return std::make_tuple(r, num_rhs_evals_adapt_modifiable); - }; - - return ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem, - partition_index); - }, - nb::arg("arkode_mem"), nb::arg("partition_index")); - -m.def( - "ARKodeGetNumStepAttempts", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long step_attempts_adapt_modifiable; - - int r = ARKodeGetNumStepAttempts(arkode_mem, - &step_attempts_adapt_modifiable); - return std::make_tuple(r, step_attempts_adapt_modifiable); - }; - - return ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumSteps", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumSteps_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long nsteps_adapt_modifiable; - - int r = ARKodeGetNumSteps(arkode_mem, &nsteps_adapt_modifiable); - return std::make_tuple(r, nsteps_adapt_modifiable); - }; - - return ARKodeGetNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetLastStep", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetLastStep_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKodeEvolve", + ARKodeEvolve, + nb::arg("arkode_mem"), nb::arg("tout"), nb::arg("yout"), nb::arg("tret"), nb::arg("itask"), + "Integrate the ODE over an interval in t"); + +m.def("ARKodeGetDky", + ARKodeGetDky, + nb::arg("arkode_mem"), nb::arg("t"), nb::arg("k"), nb::arg("dky"), + "Computes the kth derivative of the y function at time t"); + +m.def("ARKodeComputeState", + ARKodeComputeState, + nb::arg("arkode_mem"), nb::arg("zcor"), nb::arg("z"), + "Utility function to update/compute y based on zcor"); + +m.def("ARKodeGetNumRhsEvals", + [](void * arkode_mem, int partition_index) -> std::tuple { - sunrealtype hlast_adapt_modifiable; - - int r = ARKodeGetLastStep(arkode_mem, &hlast_adapt_modifiable); - return std::make_tuple(r, hlast_adapt_modifiable); - }; - - return ARKodeGetLastStep_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetCurrentStep", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetCurrentStep_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition_index) -> std::tuple + { + long num_rhs_evals_adapt_modifiable; + + int r = ARKodeGetNumRhsEvals(arkode_mem, partition_index, &num_rhs_evals_adapt_modifiable); + return std::make_tuple(r, num_rhs_evals_adapt_modifiable); + }; + + return ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem, partition_index); + }, nb::arg("arkode_mem"), nb::arg("partition_index")); + +m.def("ARKodeGetNumStepAttempts", + [](void * arkode_mem) -> std::tuple { - sunrealtype hcur_adapt_modifiable; - - int r = ARKodeGetCurrentStep(arkode_mem, &hcur_adapt_modifiable); - return std::make_tuple(r, hcur_adapt_modifiable); - }; - - return ARKodeGetCurrentStep_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetStepDirection", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetStepDirection_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long step_attempts_adapt_modifiable; + + int r = ARKodeGetNumStepAttempts(arkode_mem, &step_attempts_adapt_modifiable); + return std::make_tuple(r, step_attempts_adapt_modifiable); + }; + + return ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumSteps", + [](void * arkode_mem) -> std::tuple { - sunrealtype stepdir_adapt_modifiable; + auto ARKodeGetNumSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nsteps_adapt_modifiable; - int r = ARKodeGetStepDirection(arkode_mem, &stepdir_adapt_modifiable); - return std::make_tuple(r, stepdir_adapt_modifiable); - }; + int r = ARKodeGetNumSteps(arkode_mem, &nsteps_adapt_modifiable); + return std::make_tuple(r, nsteps_adapt_modifiable); + }; - return ARKodeGetStepDirection_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); + return ARKodeGetNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); -m.def("ARKodeGetErrWeights", ARKodeGetErrWeights, nb::arg("arkode_mem"), - nb::arg("eweight")); +m.def("ARKodeGetLastStep", + ARKodeGetLastStep, nb::arg("arkode_mem"), nb::arg("hlast")); -m.def( - "ARKodeGetNumGEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKodeGetCurrentStep", + ARKodeGetCurrentStep, nb::arg("arkode_mem"), nb::arg("hcur")); + +m.def("ARKodeGetStepDirection", + ARKodeGetStepDirection, nb::arg("arkode_mem"), nb::arg("stepdir")); + +m.def("ARKodeGetErrWeights", + ARKodeGetErrWeights, nb::arg("arkode_mem"), nb::arg("eweight")); + +m.def("ARKodeGetNumGEvals", + [](void * arkode_mem) -> std::tuple { - long ngevals_adapt_modifiable; - - int r = ARKodeGetNumGEvals(arkode_mem, &ngevals_adapt_modifiable); - return std::make_tuple(r, ngevals_adapt_modifiable); - }; - - return ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetRootInfo", - [](void* arkode_mem, std::vector rootsfound_1d) -> int - { - auto ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector = - [](void* arkode_mem, std::vector rootsfound_1d) -> int + auto ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long ngevals_adapt_modifiable; + + int r = ARKodeGetNumGEvals(arkode_mem, &ngevals_adapt_modifiable); + return std::make_tuple(r, ngevals_adapt_modifiable); + }; + + return ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetRootInfo", + [](void * arkode_mem, std::vector rootsfound_1d) -> int { - int* rootsfound_1d_ptr = rootsfound_1d.empty() ? nullptr - : rootsfound_1d.data(); + auto ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector = [](void * arkode_mem, std::vector rootsfound_1d) -> int + { + int* rootsfound_1d_ptr = rootsfound_1d.empty() ? nullptr : rootsfound_1d.data(); - auto lambda_result = ARKodeGetRootInfo(arkode_mem, rootsfound_1d_ptr); - return lambda_result; - }; + auto lambda_result = ARKodeGetRootInfo(arkode_mem, rootsfound_1d_ptr); + return lambda_result; + }; - return ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector(arkode_mem, - rootsfound_1d); - }, - nb::arg("arkode_mem"), nb::arg("rootsfound_1d")); + return ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector(arkode_mem, rootsfound_1d); + }, nb::arg("arkode_mem"), nb::arg("rootsfound_1d")); -m.def("ARKodePrintAllStats", ARKodePrintAllStats, nb::arg("arkode_mem"), - nb::arg("outfile"), nb::arg("fmt")); +m.def("ARKodePrintAllStats", + ARKodePrintAllStats, nb::arg("arkode_mem"), nb::arg("outfile"), nb::arg("fmt")); -m.def("ARKodeGetReturnFlagName", ARKodeGetReturnFlagName, nb::arg("flag")); +m.def("ARKodeGetReturnFlagName", + ARKodeGetReturnFlagName, nb::arg("flag")); -m.def("ARKodeWriteParameters", ARKodeWriteParameters, nb::arg("arkode_mem"), - nb::arg("fp")); +m.def("ARKodeWriteParameters", + ARKodeWriteParameters, nb::arg("arkode_mem"), nb::arg("fp")); -m.def( - "ARKodeGetNumExpSteps", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long expsteps_adapt_modifiable; - - int r = ARKodeGetNumExpSteps(arkode_mem, &expsteps_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable); - }; - - return ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumAccSteps", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKodeGetNumExpSteps", + [](void * arkode_mem) -> std::tuple { - long accsteps_adapt_modifiable; - - int r = ARKodeGetNumAccSteps(arkode_mem, &accsteps_adapt_modifiable); - return std::make_tuple(r, accsteps_adapt_modifiable); - }; - - return ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumErrTestFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long netfails_adapt_modifiable; - - int r = ARKodeGetNumErrTestFails(arkode_mem, &netfails_adapt_modifiable); - return std::make_tuple(r, netfails_adapt_modifiable); - }; - - return ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def("ARKodeGetEstLocalErrors", ARKodeGetEstLocalErrors, nb::arg("arkode_mem"), - nb::arg("ele")); - -m.def( - "ARKodeGetActualInitStep", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetActualInitStep_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - sunrealtype hinused_adapt_modifiable; - - int r = ARKodeGetActualInitStep(arkode_mem, &hinused_adapt_modifiable); - return std::make_tuple(r, hinused_adapt_modifiable); - }; - - return ARKodeGetActualInitStep_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetTolScaleFactor", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetTolScaleFactor_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - sunrealtype tolsfac_adapt_modifiable; - - int r = ARKodeGetTolScaleFactor(arkode_mem, &tolsfac_adapt_modifiable); - return std::make_tuple(r, tolsfac_adapt_modifiable); - }; - - return ARKodeGetTolScaleFactor_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumConstrFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long nconstrfails_adapt_modifiable; - - int r = ARKodeGetNumConstrFails(arkode_mem, &nconstrfails_adapt_modifiable); - return std::make_tuple(r, nconstrfails_adapt_modifiable); - }; - - return ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetStepStats", - [](void* arkode_mem) - -> std::tuple - { - auto ARKodeGetStepStats_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) - -> std::tuple - { - long nsteps_adapt_modifiable; - sunrealtype hinused_adapt_modifiable; - sunrealtype hlast_adapt_modifiable; - sunrealtype hcur_adapt_modifiable; - sunrealtype tcur_adapt_modifiable; - - int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, - &hinused_adapt_modifiable, - &hlast_adapt_modifiable, - &hcur_adapt_modifiable, &tcur_adapt_modifiable); - return std::make_tuple(r, nsteps_adapt_modifiable, - hinused_adapt_modifiable, hlast_adapt_modifiable, - hcur_adapt_modifiable, tcur_adapt_modifiable); - }; - - return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetAccumulatedError", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetAccumulatedError_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long expsteps_adapt_modifiable; + + int r = ARKodeGetNumExpSteps(arkode_mem, &expsteps_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable); + }; + + return ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumAccSteps", + [](void * arkode_mem) -> std::tuple { - sunrealtype accum_error_adapt_modifiable; - - int r = ARKodeGetAccumulatedError(arkode_mem, - &accum_error_adapt_modifiable); - return std::make_tuple(r, accum_error_adapt_modifiable); - }; - - return ARKodeGetAccumulatedError_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumLinSolvSetups", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long accsteps_adapt_modifiable; + + int r = ARKodeGetNumAccSteps(arkode_mem, &accsteps_adapt_modifiable); + return std::make_tuple(r, accsteps_adapt_modifiable); + }; + + return ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumErrTestFails", + [](void * arkode_mem) -> std::tuple { - long nlinsetups_adapt_modifiable; - - int r = ARKodeGetNumLinSolvSetups(arkode_mem, &nlinsetups_adapt_modifiable); - return std::make_tuple(r, nlinsetups_adapt_modifiable); - }; - - return ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetCurrentTime", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetCurrentTime_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long netfails_adapt_modifiable; + + int r = ARKodeGetNumErrTestFails(arkode_mem, &netfails_adapt_modifiable); + return std::make_tuple(r, netfails_adapt_modifiable); + }; + + return ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetEstLocalErrors", + ARKodeGetEstLocalErrors, nb::arg("arkode_mem"), nb::arg("ele")); + +m.def("ARKodeGetActualInitStep", + ARKodeGetActualInitStep, nb::arg("arkode_mem"), nb::arg("hinused")); + +m.def("ARKodeGetTolScaleFactor", + ARKodeGetTolScaleFactor, nb::arg("arkode_mem"), nb::arg("tolsfac")); + +m.def("ARKodeGetNumConstrFails", + [](void * arkode_mem) -> std::tuple { - sunrealtype tcur_adapt_modifiable; - - int r = ARKodeGetCurrentTime(arkode_mem, &tcur_adapt_modifiable); - return std::make_tuple(r, tcur_adapt_modifiable); - }; - - return ARKodeGetCurrentTime_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetCurrentState", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetCurrentState_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nconstrfails_adapt_modifiable; + + int r = ARKodeGetNumConstrFails(arkode_mem, &nconstrfails_adapt_modifiable); + return std::make_tuple(r, nconstrfails_adapt_modifiable); + }; + + return ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetStepStats", + [](void * arkode_mem, sunrealtype * hinused, sunrealtype * hlast, sunrealtype * hcur, sunrealtype * tcur) -> std::tuple { - N_Vector state_adapt_modifiable; - - int r = ARKodeGetCurrentState(arkode_mem, &state_adapt_modifiable); - return std::make_tuple(r, state_adapt_modifiable); - }; - - return ARKodeGetCurrentState_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); - -m.def( - "ARKodeGetCurrentGamma", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetCurrentGamma_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetStepStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem, sunrealtype * hinused, sunrealtype * hlast, sunrealtype * hcur, sunrealtype * tcur) -> std::tuple + { + long nsteps_adapt_modifiable; + + int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, hinused, hlast, hcur, tcur); + return std::make_tuple(r, nsteps_adapt_modifiable); + }; + + return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem, hinused, hlast, hcur, tcur); + }, nb::arg("arkode_mem"), nb::arg("hinused"), nb::arg("hlast"), nb::arg("hcur"), nb::arg("tcur")); + +m.def("ARKodeGetAccumulatedError", + ARKodeGetAccumulatedError, nb::arg("arkode_mem"), nb::arg("accum_error")); + +m.def("ARKodeGetNumLinSolvSetups", + [](void * arkode_mem) -> std::tuple { - sunrealtype gamma_adapt_modifiable; - - int r = ARKodeGetCurrentGamma(arkode_mem, &gamma_adapt_modifiable); - return std::make_tuple(r, gamma_adapt_modifiable); - }; - - return ARKodeGetCurrentGamma_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumNonlinSolvIters", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nlinsetups_adapt_modifiable; + + int r = ARKodeGetNumLinSolvSetups(arkode_mem, &nlinsetups_adapt_modifiable); + return std::make_tuple(r, nlinsetups_adapt_modifiable); + }; + + return ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetCurrentTime", + ARKodeGetCurrentTime, nb::arg("arkode_mem"), nb::arg("tcur")); + +m.def("ARKodeGetCurrentState", + [](void * arkode_mem) -> std::tuple { - long nniters_adapt_modifiable; - - int r = ARKodeGetNumNonlinSolvIters(arkode_mem, &nniters_adapt_modifiable); - return std::make_tuple(r, nniters_adapt_modifiable); - }; - - return ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumNonlinSolvConvFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetCurrentState_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + N_Vector state_adapt_modifiable; + + int r = ARKodeGetCurrentState(arkode_mem, &state_adapt_modifiable); + return std::make_tuple(r, state_adapt_modifiable); + }; + + return ARKodeGetCurrentState_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + "nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("ARKodeGetCurrentGamma", + ARKodeGetCurrentGamma, nb::arg("arkode_mem"), nb::arg("gamma")); + +m.def("ARKodeGetNumNonlinSolvIters", + [](void * arkode_mem) -> std::tuple { - long nnfails_adapt_modifiable; - - int r = ARKodeGetNumNonlinSolvConvFails(arkode_mem, - &nnfails_adapt_modifiable); - return std::make_tuple(r, nnfails_adapt_modifiable); - }; - - return ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNonlinSolvStats", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nniters_adapt_modifiable; + + int r = ARKodeGetNumNonlinSolvIters(arkode_mem, &nniters_adapt_modifiable); + return std::make_tuple(r, nniters_adapt_modifiable); + }; + + return ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumNonlinSolvConvFails", + [](void * arkode_mem) -> std::tuple { - long nniters_adapt_modifiable; - long nnfails_adapt_modifiable; - - int r = ARKodeGetNonlinSolvStats(arkode_mem, &nniters_adapt_modifiable, - &nnfails_adapt_modifiable); - return std::make_tuple(r, nniters_adapt_modifiable, - nnfails_adapt_modifiable); - }; - - return ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumStepSolveFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nnfails_adapt_modifiable; + + int r = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &nnfails_adapt_modifiable); + return std::make_tuple(r, nnfails_adapt_modifiable); + }; + + return ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNonlinSolvStats", + [](void * arkode_mem) -> std::tuple { - long nncfails_adapt_modifiable; - - int r = ARKodeGetNumStepSolveFails(arkode_mem, &nncfails_adapt_modifiable); - return std::make_tuple(r, nncfails_adapt_modifiable); - }; - - return ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetJac", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetJac_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nniters_adapt_modifiable; + long nnfails_adapt_modifiable; + + int r = ARKodeGetNonlinSolvStats(arkode_mem, &nniters_adapt_modifiable, &nnfails_adapt_modifiable); + return std::make_tuple(r, nniters_adapt_modifiable, nnfails_adapt_modifiable); + }; + + return ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumStepSolveFails", + [](void * arkode_mem) -> std::tuple { - SUNMatrix J_adapt_modifiable; - - int r = ARKodeGetJac(arkode_mem, &J_adapt_modifiable); - return std::make_tuple(r, J_adapt_modifiable); - }; - - return ARKodeGetJac_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); - -m.def( - "ARKodeGetJacTime", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetJacTime_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nncfails_adapt_modifiable; + + int r = ARKodeGetNumStepSolveFails(arkode_mem, &nncfails_adapt_modifiable); + return std::make_tuple(r, nncfails_adapt_modifiable); + }; + + return ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetJac", + [](void * arkode_mem) -> std::tuple { - sunrealtype t_J_adapt_modifiable; - - int r = ARKodeGetJacTime(arkode_mem, &t_J_adapt_modifiable); - return std::make_tuple(r, t_J_adapt_modifiable); - }; - - return ARKodeGetJacTime_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetJacNumSteps", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetJac_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + SUNMatrix J_adapt_modifiable; + + int r = ARKodeGetJac(arkode_mem, &J_adapt_modifiable); + return std::make_tuple(r, J_adapt_modifiable); + }; + + return ARKodeGetJac_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + "nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("ARKodeGetJacTime", + ARKodeGetJacTime, nb::arg("arkode_mem"), nb::arg("t_J")); + +m.def("ARKodeGetJacNumSteps", + [](void * arkode_mem) -> std::tuple { - long nst_J_adapt_modifiable; - - int r = ARKodeGetJacNumSteps(arkode_mem, &nst_J_adapt_modifiable); - return std::make_tuple(r, nst_J_adapt_modifiable); - }; - - return ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumJacEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nst_J_adapt_modifiable; + + int r = ARKodeGetJacNumSteps(arkode_mem, &nst_J_adapt_modifiable); + return std::make_tuple(r, nst_J_adapt_modifiable); + }; + + return ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumJacEvals", + [](void * arkode_mem) -> std::tuple { - long njevals_adapt_modifiable; - - int r = ARKodeGetNumJacEvals(arkode_mem, &njevals_adapt_modifiable); - return std::make_tuple(r, njevals_adapt_modifiable); - }; - - return ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumPrecEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long njevals_adapt_modifiable; + + int r = ARKodeGetNumJacEvals(arkode_mem, &njevals_adapt_modifiable); + return std::make_tuple(r, njevals_adapt_modifiable); + }; + + return ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumPrecEvals", + [](void * arkode_mem) -> std::tuple { - long npevals_adapt_modifiable; - - int r = ARKodeGetNumPrecEvals(arkode_mem, &npevals_adapt_modifiable); - return std::make_tuple(r, npevals_adapt_modifiable); - }; - - return ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumPrecSolves", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long npevals_adapt_modifiable; + + int r = ARKodeGetNumPrecEvals(arkode_mem, &npevals_adapt_modifiable); + return std::make_tuple(r, npevals_adapt_modifiable); + }; + + return ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumPrecSolves", + [](void * arkode_mem) -> std::tuple { - long npsolves_adapt_modifiable; - - int r = ARKodeGetNumPrecSolves(arkode_mem, &npsolves_adapt_modifiable); - return std::make_tuple(r, npsolves_adapt_modifiable); - }; - - return ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumLinIters", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long npsolves_adapt_modifiable; + + int r = ARKodeGetNumPrecSolves(arkode_mem, &npsolves_adapt_modifiable); + return std::make_tuple(r, npsolves_adapt_modifiable); + }; + + return ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumLinIters", + [](void * arkode_mem) -> std::tuple { - long nliters_adapt_modifiable; - - int r = ARKodeGetNumLinIters(arkode_mem, &nliters_adapt_modifiable); - return std::make_tuple(r, nliters_adapt_modifiable); - }; - - return ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumLinConvFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nliters_adapt_modifiable; + + int r = ARKodeGetNumLinIters(arkode_mem, &nliters_adapt_modifiable); + return std::make_tuple(r, nliters_adapt_modifiable); + }; + + return ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumLinConvFails", + [](void * arkode_mem) -> std::tuple { - long nlcfails_adapt_modifiable; - - int r = ARKodeGetNumLinConvFails(arkode_mem, &nlcfails_adapt_modifiable); - return std::make_tuple(r, nlcfails_adapt_modifiable); - }; - - return ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumJTSetupEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nlcfails_adapt_modifiable; + + int r = ARKodeGetNumLinConvFails(arkode_mem, &nlcfails_adapt_modifiable); + return std::make_tuple(r, nlcfails_adapt_modifiable); + }; + + return ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumJTSetupEvals", + [](void * arkode_mem) -> std::tuple { - long njtsetups_adapt_modifiable; - - int r = ARKodeGetNumJTSetupEvals(arkode_mem, &njtsetups_adapt_modifiable); - return std::make_tuple(r, njtsetups_adapt_modifiable); - }; - - return ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumJtimesEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long njtsetups_adapt_modifiable; + + int r = ARKodeGetNumJTSetupEvals(arkode_mem, &njtsetups_adapt_modifiable); + return std::make_tuple(r, njtsetups_adapt_modifiable); + }; + + return ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumJtimesEvals", + [](void * arkode_mem) -> std::tuple { - long njvevals_adapt_modifiable; - - int r = ARKodeGetNumJtimesEvals(arkode_mem, &njvevals_adapt_modifiable); - return std::make_tuple(r, njvevals_adapt_modifiable); - }; - - return ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumLinRhsEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long njvevals_adapt_modifiable; + + int r = ARKodeGetNumJtimesEvals(arkode_mem, &njvevals_adapt_modifiable); + return std::make_tuple(r, njvevals_adapt_modifiable); + }; + + return ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumLinRhsEvals", + [](void * arkode_mem) -> std::tuple { - long nfevalsLS_adapt_modifiable; - - int r = ARKodeGetNumLinRhsEvals(arkode_mem, &nfevalsLS_adapt_modifiable); - return std::make_tuple(r, nfevalsLS_adapt_modifiable); - }; - - return ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetLastLinFlag", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nfevalsLS_adapt_modifiable; + + int r = ARKodeGetNumLinRhsEvals(arkode_mem, &nfevalsLS_adapt_modifiable); + return std::make_tuple(r, nfevalsLS_adapt_modifiable); + }; + + return ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetLastLinFlag", + [](void * arkode_mem) -> std::tuple { - long flag_adapt_modifiable; + auto ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long flag_adapt_modifiable; - int r = ARKodeGetLastLinFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; + int r = ARKodeGetLastLinFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; - return ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); + return ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); -m.def("ARKodeGetLinReturnFlagName", ARKodeGetLinReturnFlagName, nb::arg("flag")); +m.def("ARKodeGetLinReturnFlagName", + ARKodeGetLinReturnFlagName, nb::arg("flag")); -m.def( - "ARKodeGetCurrentMassMatrix", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKodeGetCurrentMassMatrix", + [](void * arkode_mem) -> std::tuple { - SUNMatrix M_adapt_modifiable; - - int r = ARKodeGetCurrentMassMatrix(arkode_mem, &M_adapt_modifiable); - return std::make_tuple(r, M_adapt_modifiable); - }; - - return ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), " Optional output functions (non-identity mass matrices)\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def("ARKodeGetResWeights", ARKodeGetResWeights, nb::arg("arkode_mem"), - nb::arg("rweight")); - -m.def( - "ARKodeGetNumMassSetups", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + SUNMatrix M_adapt_modifiable; + + int r = ARKodeGetCurrentMassMatrix(arkode_mem, &M_adapt_modifiable); + return std::make_tuple(r, M_adapt_modifiable); + }; + + return ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions (non-identity mass matrices)\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("ARKodeGetResWeights", + ARKodeGetResWeights, nb::arg("arkode_mem"), nb::arg("rweight")); + +m.def("ARKodeGetNumMassSetups", + [](void * arkode_mem) -> std::tuple { - long nmsetups_adapt_modifiable; - - int r = ARKodeGetNumMassSetups(arkode_mem, &nmsetups_adapt_modifiable); - return std::make_tuple(r, nmsetups_adapt_modifiable); - }; - - return ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassMultSetups", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmsetups_adapt_modifiable; + + int r = ARKodeGetNumMassSetups(arkode_mem, &nmsetups_adapt_modifiable); + return std::make_tuple(r, nmsetups_adapt_modifiable); + }; + + return ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassMultSetups", + [](void * arkode_mem) -> std::tuple { - long nmvsetups_adapt_modifiable; - - int r = ARKodeGetNumMassMultSetups(arkode_mem, &nmvsetups_adapt_modifiable); - return std::make_tuple(r, nmvsetups_adapt_modifiable); - }; - - return ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassMult", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmvsetups_adapt_modifiable; + + int r = ARKodeGetNumMassMultSetups(arkode_mem, &nmvsetups_adapt_modifiable); + return std::make_tuple(r, nmvsetups_adapt_modifiable); + }; + + return ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassMult", + [](void * arkode_mem) -> std::tuple { - long nmvevals_adapt_modifiable; - - int r = ARKodeGetNumMassMult(arkode_mem, &nmvevals_adapt_modifiable); - return std::make_tuple(r, nmvevals_adapt_modifiable); - }; - - return ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassSolves", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmvevals_adapt_modifiable; + + int r = ARKodeGetNumMassMult(arkode_mem, &nmvevals_adapt_modifiable); + return std::make_tuple(r, nmvevals_adapt_modifiable); + }; + + return ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassSolves", + [](void * arkode_mem) -> std::tuple { - long nmsolves_adapt_modifiable; - - int r = ARKodeGetNumMassSolves(arkode_mem, &nmsolves_adapt_modifiable); - return std::make_tuple(r, nmsolves_adapt_modifiable); - }; - - return ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassPrecEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmsolves_adapt_modifiable; + + int r = ARKodeGetNumMassSolves(arkode_mem, &nmsolves_adapt_modifiable); + return std::make_tuple(r, nmsolves_adapt_modifiable); + }; + + return ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassPrecEvals", + [](void * arkode_mem) -> std::tuple { - long nmpevals_adapt_modifiable; - - int r = ARKodeGetNumMassPrecEvals(arkode_mem, &nmpevals_adapt_modifiable); - return std::make_tuple(r, nmpevals_adapt_modifiable); - }; - - return ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassPrecSolves", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmpevals_adapt_modifiable; + + int r = ARKodeGetNumMassPrecEvals(arkode_mem, &nmpevals_adapt_modifiable); + return std::make_tuple(r, nmpevals_adapt_modifiable); + }; + + return ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassPrecSolves", + [](void * arkode_mem) -> std::tuple { - long nmpsolves_adapt_modifiable; - - int r = ARKodeGetNumMassPrecSolves(arkode_mem, &nmpsolves_adapt_modifiable); - return std::make_tuple(r, nmpsolves_adapt_modifiable); - }; - - return ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassIters", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmpsolves_adapt_modifiable; + + int r = ARKodeGetNumMassPrecSolves(arkode_mem, &nmpsolves_adapt_modifiable); + return std::make_tuple(r, nmpsolves_adapt_modifiable); + }; + + return ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassIters", + [](void * arkode_mem) -> std::tuple { - long nmiters_adapt_modifiable; - - int r = ARKodeGetNumMassIters(arkode_mem, &nmiters_adapt_modifiable); - return std::make_tuple(r, nmiters_adapt_modifiable); - }; - - return ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMassConvFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmiters_adapt_modifiable; + + int r = ARKodeGetNumMassIters(arkode_mem, &nmiters_adapt_modifiable); + return std::make_tuple(r, nmiters_adapt_modifiable); + }; + + return ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMassConvFails", + [](void * arkode_mem) -> std::tuple { - long nmcfails_adapt_modifiable; - - int r = ARKodeGetNumMassConvFails(arkode_mem, &nmcfails_adapt_modifiable); - return std::make_tuple(r, nmcfails_adapt_modifiable); - }; - - return ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumMTSetups", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmcfails_adapt_modifiable; + + int r = ARKodeGetNumMassConvFails(arkode_mem, &nmcfails_adapt_modifiable); + return std::make_tuple(r, nmcfails_adapt_modifiable); + }; + + return ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumMTSetups", + [](void * arkode_mem) -> std::tuple { - long nmtsetups_adapt_modifiable; - - int r = ARKodeGetNumMTSetups(arkode_mem, &nmtsetups_adapt_modifiable); - return std::make_tuple(r, nmtsetups_adapt_modifiable); - }; - - return ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetLastMassFlag", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nmtsetups_adapt_modifiable; + + int r = ARKodeGetNumMTSetups(arkode_mem, &nmtsetups_adapt_modifiable); + return std::make_tuple(r, nmtsetups_adapt_modifiable); + }; + + return ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetLastMassFlag", + [](void * arkode_mem) -> std::tuple { - long flag_adapt_modifiable; + auto ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long flag_adapt_modifiable; - int r = ARKodeGetLastMassFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; + int r = ARKodeGetLastMassFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; - return ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); + return ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); -m.def("ARKodePrintMem", ARKodePrintMem, nb::arg("arkode_mem"), nb::arg("outfile"), - "Output the ARKODE memory structure (useful when debugging)"); +m.def("ARKodePrintMem", + ARKodePrintMem, + nb::arg("arkode_mem"), nb::arg("outfile"), + "Output the ARKODE memory structure (useful when debugging)"); -m.def("ARKodeSetRelaxEtaFail", ARKodeSetRelaxEtaFail, nb::arg("arkode_mem"), - nb::arg("eta_rf")); +m.def("ARKodeSetRelaxEtaFail", + ARKodeSetRelaxEtaFail, nb::arg("arkode_mem"), nb::arg("eta_rf")); -m.def("ARKodeSetRelaxLowerBound", ARKodeSetRelaxLowerBound, - nb::arg("arkode_mem"), nb::arg("lower")); +m.def("ARKodeSetRelaxLowerBound", + ARKodeSetRelaxLowerBound, nb::arg("arkode_mem"), nb::arg("lower")); -m.def("ARKodeSetRelaxMaxFails", ARKodeSetRelaxMaxFails, nb::arg("arkode_mem"), - nb::arg("max_fails")); +m.def("ARKodeSetRelaxMaxFails", + ARKodeSetRelaxMaxFails, nb::arg("arkode_mem"), nb::arg("max_fails")); -m.def("ARKodeSetRelaxMaxIters", ARKodeSetRelaxMaxIters, nb::arg("arkode_mem"), - nb::arg("max_iters")); +m.def("ARKodeSetRelaxMaxIters", + ARKodeSetRelaxMaxIters, nb::arg("arkode_mem"), nb::arg("max_iters")); -m.def("ARKodeSetRelaxSolver", ARKodeSetRelaxSolver, nb::arg("arkode_mem"), - nb::arg("solver")); +m.def("ARKodeSetRelaxSolver", + ARKodeSetRelaxSolver, nb::arg("arkode_mem"), nb::arg("solver")); -m.def("ARKodeSetRelaxResTol", ARKodeSetRelaxResTol, nb::arg("arkode_mem"), - nb::arg("res_tol")); +m.def("ARKodeSetRelaxResTol", + ARKodeSetRelaxResTol, nb::arg("arkode_mem"), nb::arg("res_tol")); -m.def("ARKodeSetRelaxTol", ARKodeSetRelaxTol, nb::arg("arkode_mem"), - nb::arg("rel_tol"), nb::arg("abs_tol")); +m.def("ARKodeSetRelaxTol", + ARKodeSetRelaxTol, nb::arg("arkode_mem"), nb::arg("rel_tol"), nb::arg("abs_tol")); -m.def("ARKodeSetRelaxUpperBound", ARKodeSetRelaxUpperBound, - nb::arg("arkode_mem"), nb::arg("upper")); +m.def("ARKodeSetRelaxUpperBound", + ARKodeSetRelaxUpperBound, nb::arg("arkode_mem"), nb::arg("upper")); -m.def( - "ARKodeGetNumRelaxFnEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple - { - long r_evals_adapt_modifiable; - - int r = ARKodeGetNumRelaxFnEvals(arkode_mem, &r_evals_adapt_modifiable); - return std::make_tuple(r, r_evals_adapt_modifiable); - }; - - return ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumRelaxJacEvals", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("ARKodeGetNumRelaxFnEvals", + [](void * arkode_mem) -> std::tuple { - long J_evals_adapt_modifiable; - - int r = ARKodeGetNumRelaxJacEvals(arkode_mem, &J_evals_adapt_modifiable); - return std::make_tuple(r, J_evals_adapt_modifiable); - }; - - return ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumRelaxFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long r_evals_adapt_modifiable; + + int r = ARKodeGetNumRelaxFnEvals(arkode_mem, &r_evals_adapt_modifiable); + return std::make_tuple(r, r_evals_adapt_modifiable); + }; + + return ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumRelaxJacEvals", + [](void * arkode_mem) -> std::tuple { - long relax_fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxFails(arkode_mem, &relax_fails_adapt_modifiable); - return std::make_tuple(r, relax_fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumRelaxBoundFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long J_evals_adapt_modifiable; + + int r = ARKodeGetNumRelaxJacEvals(arkode_mem, &J_evals_adapt_modifiable); + return std::make_tuple(r, J_evals_adapt_modifiable); + }; + + return ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumRelaxFails", + [](void * arkode_mem) -> std::tuple { - long fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxBoundFails(arkode_mem, &fails_adapt_modifiable); - return std::make_tuple(r, fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumRelaxSolveFails", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long relax_fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxFails(arkode_mem, &relax_fails_adapt_modifiable); + return std::make_tuple(r, relax_fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumRelaxBoundFails", + [](void * arkode_mem) -> std::tuple { - long fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxSolveFails(arkode_mem, &fails_adapt_modifiable); - return std::make_tuple(r, fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeGetNumRelaxSolveIters", - [](void* arkode_mem) -> std::tuple - { - auto ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxBoundFails(arkode_mem, &fails_adapt_modifiable); + return std::make_tuple(r, fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumRelaxSolveFails", + [](void * arkode_mem) -> std::tuple { - long iters_adapt_modifiable; - - int r = ARKodeGetNumRelaxSolveIters(arkode_mem, &iters_adapt_modifiable); - return std::make_tuple(r, iters_adapt_modifiable); - }; - - return ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "ARKodeCreateSUNStepper", - [](void* arkode_mem) - -> std::tuple>> - { - auto ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxSolveFails(arkode_mem, &fails_adapt_modifiable); + return std::make_tuple(r, fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeGetNumRelaxSolveIters", + [](void * arkode_mem) -> std::tuple { - SUNStepper stepper_adapt_modifiable; - - int r = ARKodeCreateSUNStepper(arkode_mem, &stepper_adapt_modifiable); - return std::make_tuple(r, stepper_adapt_modifiable); - }; - auto ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr = - [&ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return]( - void* arkode_mem) - -> std::tuple>> + auto ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long iters_adapt_modifiable; + + int r = ARKodeGetNumRelaxSolveIters(arkode_mem, &iters_adapt_modifiable); + return std::make_tuple(r, iters_adapt_modifiable); + }; + + return ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("ARKodeCreateSUNStepper", + [](void * arkode_mem) -> std::tuple>> { - auto lambda_result = - ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return(arkode_mem); - - return std::make_tuple(std::get<0>(lambda_result), - our_make_shared, - SUNStepperDeleter>( - std::get<1>(lambda_result))); - }; - - return ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr(arkode_mem); - }, - nb::arg("arkode_mem"), "SUNStepper functions", nb::rv_policy::reference); + auto ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + SUNStepper stepper_adapt_modifiable; + + int r = ARKodeCreateSUNStepper(arkode_mem, &stepper_adapt_modifiable); + return std::make_tuple(r, stepper_adapt_modifiable); + }; + auto ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr = [&ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return](void * arkode_mem) -> std::tuple>> + { + auto lambda_result = ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return(arkode_mem); + + return std::make_tuple(std::get<0>(lambda_result), our_make_shared, SUNStepperDeleter>(std::get<1>(lambda_result))); + return lambda_result; + }; + + return ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr(arkode_mem); + }, + nb::arg("arkode_mem"), + "SUNStepper functions", + nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKLS_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// -m.attr("ARKLS_SUCCESS") = 0; -m.attr("ARKLS_MEM_NULL") = -1; -m.attr("ARKLS_LMEM_NULL") = -2; -m.attr("ARKLS_ILL_INPUT") = -3; -m.attr("ARKLS_MEM_FAIL") = -4; -m.attr("ARKLS_PMEM_NULL") = -5; -m.attr("ARKLS_MASSMEM_NULL") = -6; -m.attr("ARKLS_JACFUNC_UNRECVR") = -7; -m.attr("ARKLS_JACFUNC_RECVR") = -8; +// +m.attr("ARKLS_SUCCESS") = 0; +m.attr("ARKLS_MEM_NULL") = -1; +m.attr("ARKLS_LMEM_NULL") = -2; +m.attr("ARKLS_ILL_INPUT") = -3; +m.attr("ARKLS_MEM_FAIL") = -4; +m.attr("ARKLS_PMEM_NULL") = -5; +m.attr("ARKLS_MASSMEM_NULL") = -6; +m.attr("ARKLS_JACFUNC_UNRECVR") = -7; +m.attr("ARKLS_JACFUNC_RECVR") = -8; m.attr("ARKLS_MASSFUNC_UNRECVR") = -9; -m.attr("ARKLS_MASSFUNC_RECVR") = -10; -m.attr("ARKLS_SUNMAT_FAIL") = -11; -m.attr("ARKLS_SUNLS_FAIL") = -12; - -m.def( - "ARKodeSetLinearSolver", - [](void* arkode_mem, SUNLinearSolver LS, - std::optional A = std::nullopt) -> int - { - auto ARKodeSetLinearSolver_adapt_optional_arg_with_default_null = - [](void* arkode_mem, SUNLinearSolver LS, - std::optional A = std::nullopt) -> int +m.attr("ARKLS_MASSFUNC_RECVR") = -10; +m.attr("ARKLS_SUNMAT_FAIL") = -11; +m.attr("ARKLS_SUNLS_FAIL") = -12; + +m.def("ARKodeSetLinearSolver", + [](void * arkode_mem, SUNLinearSolver LS, std::optional A = std::nullopt) -> int { - SUNMatrix A_adapt_default_null = nullptr; - if (A.has_value()) A_adapt_default_null = A.value(); + auto ARKodeSetLinearSolver_adapt_optional_arg_with_default_null = [](void * arkode_mem, SUNLinearSolver LS, std::optional A = std::nullopt) -> int + { + SUNMatrix A_adapt_default_null = nullptr; + if (A.has_value()) + A_adapt_default_null = A.value(); - auto lambda_result = ARKodeSetLinearSolver(arkode_mem, LS, - A_adapt_default_null); - return lambda_result; - }; + auto lambda_result = ARKodeSetLinearSolver(arkode_mem, LS, A_adapt_default_null); + return lambda_result; + }; - return ARKodeSetLinearSolver_adapt_optional_arg_with_default_null(arkode_mem, - LS, A); - }, - nb::arg("arkode_mem"), nb::arg("LS"), nb::arg("A").none() = nb::none()); + return ARKodeSetLinearSolver_adapt_optional_arg_with_default_null(arkode_mem, LS, A); + }, nb::arg("arkode_mem"), nb::arg("LS"), nb::arg("A").none() = nb::none()); -m.def("ARKodeSetJacEvalFrequency", ARKodeSetJacEvalFrequency, - nb::arg("arkode_mem"), nb::arg("msbj")); +m.def("ARKodeSetJacEvalFrequency", + ARKodeSetJacEvalFrequency, nb::arg("arkode_mem"), nb::arg("msbj")); -m.def("ARKodeSetLinearSolutionScaling", ARKodeSetLinearSolutionScaling, - nb::arg("arkode_mem"), nb::arg("onoff")); +m.def("ARKodeSetLinearSolutionScaling", + ARKodeSetLinearSolutionScaling, nb::arg("arkode_mem"), nb::arg("onoff")); -m.def("ARKodeSetEpsLin", ARKodeSetEpsLin, nb::arg("arkode_mem"), - nb::arg("eplifac")); +m.def("ARKodeSetEpsLin", + ARKodeSetEpsLin, nb::arg("arkode_mem"), nb::arg("eplifac")); -m.def("ARKodeSetMassEpsLin", ARKodeSetMassEpsLin, nb::arg("arkode_mem"), - nb::arg("eplifac")); +m.def("ARKodeSetMassEpsLin", + ARKodeSetMassEpsLin, nb::arg("arkode_mem"), nb::arg("eplifac")); -m.def("ARKodeSetLSNormFactor", ARKodeSetLSNormFactor, nb::arg("arkode_mem"), - nb::arg("nrmfac")); +m.def("ARKodeSetLSNormFactor", + ARKodeSetLSNormFactor, nb::arg("arkode_mem"), nb::arg("nrmfac")); -m.def("ARKodeSetMassLSNormFactor", ARKodeSetMassLSNormFactor, - nb::arg("arkode_mem"), nb::arg("nrmfac")); +m.def("ARKodeSetMassLSNormFactor", + ARKodeSetMassLSNormFactor, nb::arg("arkode_mem"), nb::arg("nrmfac")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_BUTCHER_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyClassARKodeButcherTableMem = - nb::class_(m, "ARKodeButcherTableMem", "") + nb::class_ + (m, "ARKodeButcherTableMem", "") .def(nb::init<>()) // implicit default constructor - ; - -m.def( - "ARKodeButcherTable_Create", - [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, - sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) - -> std::shared_ptr> - { - auto ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector = - [](int s, int q, int p, sundials4py::Array1d c_1d, - sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, - sundials4py::Array1d d_1d) -> ARKodeButcherTable - { - sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); - sunrealtype* A_1d_ptr = A_1d.size() == 0 ? nullptr : A_1d.data(); - sunrealtype* b_1d_ptr = b_1d.size() == 0 ? nullptr : b_1d.data(); - sunrealtype* d_1d_ptr = d_1d.size() == 0 ? nullptr : d_1d.data(); - - auto lambda_result = ARKodeButcherTable_Create(s, q, p, c_1d_ptr, A_1d_ptr, - b_1d_ptr, d_1d_ptr); - return lambda_result; - }; - auto ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr = - [&ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, - int p, - sundials4py::Array1d c_1d, - sundials4py::Array1d A_1d, - sundials4py::Array1d b_1d, - sundials4py::Array1d d_1d) - -> std::shared_ptr> + ; + + +m.def("ARKodeButcherTable_Create", + [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> std::shared_ptr> { - auto lambda_result = - ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector(s, q, p, c_1d, - A_1d, b_1d, d_1d); - - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; - - return ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr(s, q, p, - c_1d, A_1d, - b_1d, d_1d); - }, - nb::arg("s"), nb::arg("q"), nb::arg("p"), nb::arg("c_1d"), nb::arg("A_1d"), - nb::arg("b_1d"), nb::arg("d_1d")); - -m.def( - "ARKodeButcherTable_Copy", - [](ARKodeButcherTable B) - -> std::shared_ptr> - { - auto ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr = - [](ARKodeButcherTable B) - -> std::shared_ptr> + auto ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector = [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> ARKodeButcherTable + { + sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); + sunrealtype* A_1d_ptr = A_1d.size() == 0 ? nullptr : A_1d.data(); + sunrealtype* b_1d_ptr = b_1d.size() == 0 ? nullptr : b_1d.data(); + sunrealtype* d_1d_ptr = d_1d.size() == 0 ? nullptr : d_1d.data(); + + auto lambda_result = ARKodeButcherTable_Create(s, q, p, c_1d_ptr, A_1d_ptr, b_1d_ptr, d_1d_ptr); + return lambda_result; + }; + auto ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr = [&ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector(s, q, p, c_1d, A_1d, b_1d, d_1d); + + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr(s, q, p, c_1d, A_1d, b_1d, d_1d); + }, nb::arg("s"), nb::arg("q"), nb::arg("p"), nb::arg("c_1d"), nb::arg("A_1d"), nb::arg("b_1d"), nb::arg("d_1d")); + +m.def("ARKodeButcherTable_Copy", + [](ARKodeButcherTable B) -> std::shared_ptr> { - auto lambda_result = ARKodeButcherTable_Copy(B); + auto ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr = [](ARKodeButcherTable B) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_Copy(B); - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr(B); - }, - nb::arg("B")); + return ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr(B); + }, nb::arg("B")); -m.def("ARKodeButcherTable_Write", ARKodeButcherTable_Write, nb::arg("B"), - nb::arg("outfile")); +m.def("ARKodeButcherTable_Write", + ARKodeButcherTable_Write, nb::arg("B"), nb::arg("outfile")); m.def("ARKodeButcherTable_IsStifflyAccurate", - ARKodeButcherTable_IsStifflyAccurate, nb::arg("B")); - -m.def( - "ARKodeButcherTable_CheckOrder", - [](ARKodeButcherTable B, FILE* outfile) -> std::tuple - { - auto ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return = - [](ARKodeButcherTable B, FILE* outfile) -> std::tuple + ARKodeButcherTable_IsStifflyAccurate, nb::arg("B")); + +m.def("ARKodeButcherTable_CheckOrder", + [](ARKodeButcherTable B, FILE * outfile) -> std::tuple { - int q_adapt_modifiable; - int p_adapt_modifiable; - - int r = ARKodeButcherTable_CheckOrder(B, &q_adapt_modifiable, - &p_adapt_modifiable, outfile); - return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); - }; - - return ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return(B, - outfile); - }, - nb::arg("B"), nb::arg("outfile")); - -m.def( - "ARKodeButcherTable_CheckARKOrder", - [](ARKodeButcherTable B1, ARKodeButcherTable B2, - FILE* outfile) -> std::tuple - { - auto ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return = - [](ARKodeButcherTable B1, ARKodeButcherTable B2, - FILE* outfile) -> std::tuple + auto ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return = [](ARKodeButcherTable B, FILE * outfile) -> std::tuple + { + int q_adapt_modifiable; + int p_adapt_modifiable; + + int r = ARKodeButcherTable_CheckOrder(B, &q_adapt_modifiable, &p_adapt_modifiable, outfile); + return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); + }; + + return ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return(B, outfile); + }, nb::arg("B"), nb::arg("outfile")); + +m.def("ARKodeButcherTable_CheckARKOrder", + [](ARKodeButcherTable B1, ARKodeButcherTable B2, FILE * outfile) -> std::tuple { - int q_adapt_modifiable; - int p_adapt_modifiable; - - int r = ARKodeButcherTable_CheckARKOrder(B1, B2, &q_adapt_modifiable, - &p_adapt_modifiable, outfile); - return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); - }; - - return ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return(B1, - B2, - outfile); - }, - nb::arg("B1"), nb::arg("B2"), nb::arg("outfile")); + auto ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return = [](ARKodeButcherTable B1, ARKodeButcherTable B2, FILE * outfile) -> std::tuple + { + int q_adapt_modifiable; + int p_adapt_modifiable; + + int r = ARKodeButcherTable_CheckARKOrder(B1, B2, &q_adapt_modifiable, &p_adapt_modifiable, outfile); + return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); + }; + + return ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return(B1, B2, outfile); + }, nb::arg("B1"), nb::arg("B2"), nb::arg("outfile")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_ERK_TABLES_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyEnumARKODE_ERKTableID = - nb::enum_(m, "ARKODE_ERKTableID", nb::is_arithmetic(), "") - .value("ARKODE_ERK_NONE", ARKODE_ERK_NONE, "ensure enum is signed int") - .value("ARKODE_HEUN_EULER_2_1_2", ARKODE_HEUN_EULER_2_1_2, "") - .value("ARKODE_MIN_ERK_NUM", ARKODE_MIN_ERK_NUM, "") - .value("ARKODE_BOGACKI_SHAMPINE_4_2_3", ARKODE_BOGACKI_SHAMPINE_4_2_3, "") - .value("ARKODE_ARK324L2SA_ERK_4_2_3", ARKODE_ARK324L2SA_ERK_4_2_3, "") - .value("ARKODE_ZONNEVELD_5_3_4", ARKODE_ZONNEVELD_5_3_4, "") - .value("ARKODE_ARK436L2SA_ERK_6_3_4", ARKODE_ARK436L2SA_ERK_6_3_4, "") - .value("ARKODE_SAYFY_ABURUB_6_3_4", ARKODE_SAYFY_ABURUB_6_3_4, "") - .value("ARKODE_CASH_KARP_6_4_5", ARKODE_CASH_KARP_6_4_5, "") - .value("ARKODE_FEHLBERG_6_4_5", ARKODE_FEHLBERG_6_4_5, "") - .value("ARKODE_DORMAND_PRINCE_7_4_5", ARKODE_DORMAND_PRINCE_7_4_5, "") - .value("ARKODE_ARK548L2SA_ERK_8_4_5", ARKODE_ARK548L2SA_ERK_8_4_5, "") - .value("ARKODE_VERNER_8_5_6", ARKODE_VERNER_8_5_6, "") - .value("ARKODE_FEHLBERG_13_7_8", ARKODE_FEHLBERG_13_7_8, "") - .value("ARKODE_KNOTH_WOLKE_3_3", ARKODE_KNOTH_WOLKE_3_3, "") - .value("ARKODE_ARK437L2SA_ERK_7_3_4", ARKODE_ARK437L2SA_ERK_7_3_4, "") - .value("ARKODE_ARK548L2SAb_ERK_8_4_5", ARKODE_ARK548L2SAb_ERK_8_4_5, "") - .value("ARKODE_ARK2_ERK_3_1_2", ARKODE_ARK2_ERK_3_1_2, "") - .value("ARKODE_SOFRONIOU_SPALETTA_5_3_4", ARKODE_SOFRONIOU_SPALETTA_5_3_4, "") - .value("ARKODE_SHU_OSHER_3_2_3", ARKODE_SHU_OSHER_3_2_3, "") - .value("ARKODE_VERNER_9_5_6", ARKODE_VERNER_9_5_6, "") - .value("ARKODE_VERNER_10_6_7", ARKODE_VERNER_10_6_7, "") - .value("ARKODE_VERNER_13_7_8", ARKODE_VERNER_13_7_8, "") - .value("ARKODE_VERNER_16_8_9", ARKODE_VERNER_16_8_9, "") - .value("ARKODE_FORWARD_EULER_1_1", ARKODE_FORWARD_EULER_1_1, "") - .value("ARKODE_RALSTON_EULER_2_1_2", ARKODE_RALSTON_EULER_2_1_2, "") - .value("ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2", - ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2, "") - .value("ARKODE_RALSTON_3_1_2", ARKODE_RALSTON_3_1_2, "") - .value("ARKODE_TSITOURAS_7_4_5", ARKODE_TSITOURAS_7_4_5, "") - .value("ARKODE_MAX_ERK_NUM", ARKODE_MAX_ERK_NUM, "") + nb::enum_(m, "ARKODE_ERKTableID", nb::is_arithmetic(), "") + .value("ARKODE_ERK_NONE", ARKODE_ERK_NONE, "ensure enum is signed int") + .value("ARKODE_HEUN_EULER_2_1_2", ARKODE_HEUN_EULER_2_1_2, "") + .value("ARKODE_MIN_ERK_NUM", ARKODE_MIN_ERK_NUM, "") + .value("ARKODE_BOGACKI_SHAMPINE_4_2_3", ARKODE_BOGACKI_SHAMPINE_4_2_3, "") + .value("ARKODE_ARK324L2SA_ERK_4_2_3", ARKODE_ARK324L2SA_ERK_4_2_3, "") + .value("ARKODE_ZONNEVELD_5_3_4", ARKODE_ZONNEVELD_5_3_4, "") + .value("ARKODE_ARK436L2SA_ERK_6_3_4", ARKODE_ARK436L2SA_ERK_6_3_4, "") + .value("ARKODE_SAYFY_ABURUB_6_3_4", ARKODE_SAYFY_ABURUB_6_3_4, "") + .value("ARKODE_CASH_KARP_6_4_5", ARKODE_CASH_KARP_6_4_5, "") + .value("ARKODE_FEHLBERG_6_4_5", ARKODE_FEHLBERG_6_4_5, "") + .value("ARKODE_DORMAND_PRINCE_7_4_5", ARKODE_DORMAND_PRINCE_7_4_5, "") + .value("ARKODE_ARK548L2SA_ERK_8_4_5", ARKODE_ARK548L2SA_ERK_8_4_5, "") + .value("ARKODE_VERNER_8_5_6", ARKODE_VERNER_8_5_6, "") + .value("ARKODE_FEHLBERG_13_7_8", ARKODE_FEHLBERG_13_7_8, "") + .value("ARKODE_KNOTH_WOLKE_3_3", ARKODE_KNOTH_WOLKE_3_3, "") + .value("ARKODE_ARK437L2SA_ERK_7_3_4", ARKODE_ARK437L2SA_ERK_7_3_4, "") + .value("ARKODE_ARK548L2SAb_ERK_8_4_5", ARKODE_ARK548L2SAb_ERK_8_4_5, "") + .value("ARKODE_ARK2_ERK_3_1_2", ARKODE_ARK2_ERK_3_1_2, "") + .value("ARKODE_SOFRONIOU_SPALETTA_5_3_4", ARKODE_SOFRONIOU_SPALETTA_5_3_4, "") + .value("ARKODE_SHU_OSHER_3_2_3", ARKODE_SHU_OSHER_3_2_3, "") + .value("ARKODE_VERNER_9_5_6", ARKODE_VERNER_9_5_6, "") + .value("ARKODE_VERNER_10_6_7", ARKODE_VERNER_10_6_7, "") + .value("ARKODE_VERNER_13_7_8", ARKODE_VERNER_13_7_8, "") + .value("ARKODE_VERNER_16_8_9", ARKODE_VERNER_16_8_9, "") + .value("ARKODE_FORWARD_EULER_1_1", ARKODE_FORWARD_EULER_1_1, "") + .value("ARKODE_RALSTON_EULER_2_1_2", ARKODE_RALSTON_EULER_2_1_2, "") + .value("ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2", ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2, "") + .value("ARKODE_RALSTON_3_1_2", ARKODE_RALSTON_3_1_2, "") + .value("ARKODE_TSITOURAS_7_4_5", ARKODE_TSITOURAS_7_4_5, "") + .value("ARKODE_MAX_ERK_NUM", ARKODE_MAX_ERK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def( - "ARKodeButcherTable_LoadERK", - [](ARKODE_ERKTableID emethod) - -> std::shared_ptr> - { - auto ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr = - [](ARKODE_ERKTableID emethod) - -> std::shared_ptr> +// + +m.def("ARKodeButcherTable_LoadERK", + [](ARKODE_ERKTableID emethod) -> std::shared_ptr> { - auto lambda_result = ARKodeButcherTable_LoadERK(emethod); - - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; - - return ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr(emethod); - }, - nb::arg("emethod"), "Accessor routine to load built-in ERK table"); - -m.def( - "ARKodeButcherTable_LoadERKByName", - [](const char* emethod) - -> std::shared_ptr> - { - auto ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr = - [](const char* emethod) - -> std::shared_ptr> + auto ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr = [](ARKODE_ERKTableID emethod) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_LoadERK(emethod); + + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr(emethod); + }, + nb::arg("emethod"), + "Accessor routine to load built-in ERK table"); + +m.def("ARKodeButcherTable_LoadERKByName", + [](const char * emethod) -> std::shared_ptr> { - auto lambda_result = ARKodeButcherTable_LoadERKByName(emethod); + auto ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr = [](const char * emethod) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_LoadERKByName(emethod); - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr( - emethod); - }, - nb::arg("emethod")); + return ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr(emethod); + }, nb::arg("emethod")); -m.def("ARKodeButcherTable_ERKIDToName", ARKodeButcherTable_ERKIDToName, - nb::arg("emethod")); +m.def("ARKodeButcherTable_ERKIDToName", + ARKodeButcherTable_ERKIDToName, nb::arg("emethod")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_DIRK_TABLES_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyEnumARKODE_DIRKTableID = - nb::enum_(m, "ARKODE_DIRKTableID", nb::is_arithmetic(), "") - .value("ARKODE_DIRK_NONE", ARKODE_DIRK_NONE, "ensure enum is signed int") - .value("ARKODE_SDIRK_2_1_2", ARKODE_SDIRK_2_1_2, "") - .value("ARKODE_MIN_DIRK_NUM", ARKODE_MIN_DIRK_NUM, "") - .value("ARKODE_BILLINGTON_3_3_2", ARKODE_BILLINGTON_3_3_2, "") - .value("ARKODE_TRBDF2_3_3_2", ARKODE_TRBDF2_3_3_2, "") - .value("ARKODE_KVAERNO_4_2_3", ARKODE_KVAERNO_4_2_3, "") - .value("ARKODE_ARK324L2SA_DIRK_4_2_3", ARKODE_ARK324L2SA_DIRK_4_2_3, "") - .value("ARKODE_CASH_5_2_4", ARKODE_CASH_5_2_4, "") - .value("ARKODE_CASH_5_3_4", ARKODE_CASH_5_3_4, "") - .value("ARKODE_SDIRK_5_3_4", ARKODE_SDIRK_5_3_4, "") - .value("ARKODE_KVAERNO_5_3_4", ARKODE_KVAERNO_5_3_4, "") - .value("ARKODE_ARK436L2SA_DIRK_6_3_4", ARKODE_ARK436L2SA_DIRK_6_3_4, "") - .value("ARKODE_KVAERNO_7_4_5", ARKODE_KVAERNO_7_4_5, "") - .value("ARKODE_ARK548L2SA_DIRK_8_4_5", ARKODE_ARK548L2SA_DIRK_8_4_5, "") - .value("ARKODE_ARK437L2SA_DIRK_7_3_4", ARKODE_ARK437L2SA_DIRK_7_3_4, "") - .value("ARKODE_ARK548L2SAb_DIRK_8_4_5", ARKODE_ARK548L2SAb_DIRK_8_4_5, "") - .value("ARKODE_ESDIRK324L2SA_4_2_3", ARKODE_ESDIRK324L2SA_4_2_3, "") - .value("ARKODE_ESDIRK325L2SA_5_2_3", ARKODE_ESDIRK325L2SA_5_2_3, "") - .value("ARKODE_ESDIRK32I5L2SA_5_2_3", ARKODE_ESDIRK32I5L2SA_5_2_3, "") - .value("ARKODE_ESDIRK436L2SA_6_3_4", ARKODE_ESDIRK436L2SA_6_3_4, "") - .value("ARKODE_ESDIRK43I6L2SA_6_3_4", ARKODE_ESDIRK43I6L2SA_6_3_4, "") - .value("ARKODE_QESDIRK436L2SA_6_3_4", ARKODE_QESDIRK436L2SA_6_3_4, "") - .value("ARKODE_ESDIRK437L2SA_7_3_4", ARKODE_ESDIRK437L2SA_7_3_4, "") - .value("ARKODE_ESDIRK547L2SA_7_4_5", ARKODE_ESDIRK547L2SA_7_4_5, "") - .value("ARKODE_ESDIRK547L2SA2_7_4_5", ARKODE_ESDIRK547L2SA2_7_4_5, "") - .value("ARKODE_ARK2_DIRK_3_1_2", ARKODE_ARK2_DIRK_3_1_2, "") - .value("ARKODE_BACKWARD_EULER_1_1", ARKODE_BACKWARD_EULER_1_1, "") - .value("ARKODE_IMPLICIT_MIDPOINT_1_2", ARKODE_IMPLICIT_MIDPOINT_1_2, "") - .value("ARKODE_IMPLICIT_TRAPEZOIDAL_2_2", ARKODE_IMPLICIT_TRAPEZOIDAL_2_2, "") - .value("ARKODE_MAX_DIRK_NUM", ARKODE_MAX_DIRK_NUM, "") + nb::enum_(m, "ARKODE_DIRKTableID", nb::is_arithmetic(), "") + .value("ARKODE_DIRK_NONE", ARKODE_DIRK_NONE, "ensure enum is signed int") + .value("ARKODE_SDIRK_2_1_2", ARKODE_SDIRK_2_1_2, "") + .value("ARKODE_MIN_DIRK_NUM", ARKODE_MIN_DIRK_NUM, "") + .value("ARKODE_BILLINGTON_3_3_2", ARKODE_BILLINGTON_3_3_2, "") + .value("ARKODE_TRBDF2_3_3_2", ARKODE_TRBDF2_3_3_2, "") + .value("ARKODE_KVAERNO_4_2_3", ARKODE_KVAERNO_4_2_3, "") + .value("ARKODE_ARK324L2SA_DIRK_4_2_3", ARKODE_ARK324L2SA_DIRK_4_2_3, "") + .value("ARKODE_CASH_5_2_4", ARKODE_CASH_5_2_4, "") + .value("ARKODE_CASH_5_3_4", ARKODE_CASH_5_3_4, "") + .value("ARKODE_SDIRK_5_3_4", ARKODE_SDIRK_5_3_4, "") + .value("ARKODE_KVAERNO_5_3_4", ARKODE_KVAERNO_5_3_4, "") + .value("ARKODE_ARK436L2SA_DIRK_6_3_4", ARKODE_ARK436L2SA_DIRK_6_3_4, "") + .value("ARKODE_KVAERNO_7_4_5", ARKODE_KVAERNO_7_4_5, "") + .value("ARKODE_ARK548L2SA_DIRK_8_4_5", ARKODE_ARK548L2SA_DIRK_8_4_5, "") + .value("ARKODE_ARK437L2SA_DIRK_7_3_4", ARKODE_ARK437L2SA_DIRK_7_3_4, "") + .value("ARKODE_ARK548L2SAb_DIRK_8_4_5", ARKODE_ARK548L2SAb_DIRK_8_4_5, "") + .value("ARKODE_ESDIRK324L2SA_4_2_3", ARKODE_ESDIRK324L2SA_4_2_3, "") + .value("ARKODE_ESDIRK325L2SA_5_2_3", ARKODE_ESDIRK325L2SA_5_2_3, "") + .value("ARKODE_ESDIRK32I5L2SA_5_2_3", ARKODE_ESDIRK32I5L2SA_5_2_3, "") + .value("ARKODE_ESDIRK436L2SA_6_3_4", ARKODE_ESDIRK436L2SA_6_3_4, "") + .value("ARKODE_ESDIRK43I6L2SA_6_3_4", ARKODE_ESDIRK43I6L2SA_6_3_4, "") + .value("ARKODE_QESDIRK436L2SA_6_3_4", ARKODE_QESDIRK436L2SA_6_3_4, "") + .value("ARKODE_ESDIRK437L2SA_7_3_4", ARKODE_ESDIRK437L2SA_7_3_4, "") + .value("ARKODE_ESDIRK547L2SA_7_4_5", ARKODE_ESDIRK547L2SA_7_4_5, "") + .value("ARKODE_ESDIRK547L2SA2_7_4_5", ARKODE_ESDIRK547L2SA2_7_4_5, "") + .value("ARKODE_ARK2_DIRK_3_1_2", ARKODE_ARK2_DIRK_3_1_2, "") + .value("ARKODE_BACKWARD_EULER_1_1", ARKODE_BACKWARD_EULER_1_1, "") + .value("ARKODE_IMPLICIT_MIDPOINT_1_2", ARKODE_IMPLICIT_MIDPOINT_1_2, "") + .value("ARKODE_IMPLICIT_TRAPEZOIDAL_2_2", ARKODE_IMPLICIT_TRAPEZOIDAL_2_2, "") + .value("ARKODE_MAX_DIRK_NUM", ARKODE_MAX_DIRK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def( - "ARKodeButcherTable_LoadDIRK", - [](ARKODE_DIRKTableID imethod) - -> std::shared_ptr> - { - auto ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr = - [](ARKODE_DIRKTableID imethod) - -> std::shared_ptr> +// + +m.def("ARKodeButcherTable_LoadDIRK", + [](ARKODE_DIRKTableID imethod) -> std::shared_ptr> { - auto lambda_result = ARKodeButcherTable_LoadDIRK(imethod); - - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; - - return ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr(imethod); - }, - nb::arg("imethod"), "Accessor routine to load built-in DIRK table"); - -m.def( - "ARKodeButcherTable_LoadDIRKByName", - [](const char* imethod) - -> std::shared_ptr> - { - auto ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr = - [](const char* imethod) - -> std::shared_ptr> + auto ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr = [](ARKODE_DIRKTableID imethod) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_LoadDIRK(imethod); + + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr(imethod); + }, + nb::arg("imethod"), + "Accessor routine to load built-in DIRK table"); + +m.def("ARKodeButcherTable_LoadDIRKByName", + [](const char * imethod) -> std::shared_ptr> { - auto lambda_result = ARKodeButcherTable_LoadDIRKByName(imethod); + auto ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr = [](const char * imethod) -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_LoadDIRKByName(imethod); - return our_make_shared, - ARKodeButcherTableDeleter>(lambda_result); - }; + return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr( - imethod); - }, - nb::arg("imethod"), "Accessor routine to load built-in DIRK table"); + return ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr(imethod); + }, + nb::arg("imethod"), + "Accessor routine to load built-in DIRK table"); -m.def("ARKodeButcherTable_DIRKIDToName", ARKodeButcherTable_DIRKIDToName, - nb::arg("imethod")); +m.def("ARKodeButcherTable_DIRKIDToName", + ARKodeButcherTable_DIRKIDToName, nb::arg("imethod")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_SPRKTABLE_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyEnumARKODE_SPRKMethodID = - nb::enum_(m, "ARKODE_SPRKMethodID", nb::is_arithmetic(), "") - .value("ARKODE_SPRK_NONE", ARKODE_SPRK_NONE, "ensure enum is signed int") - .value("ARKODE_SPRK_EULER_1_1", ARKODE_SPRK_EULER_1_1, "") - .value("ARKODE_MIN_SPRK_NUM", ARKODE_MIN_SPRK_NUM, "") - .value("ARKODE_SPRK_LEAPFROG_2_2", ARKODE_SPRK_LEAPFROG_2_2, "") - .value("ARKODE_SPRK_PSEUDO_LEAPFROG_2_2", ARKODE_SPRK_PSEUDO_LEAPFROG_2_2, "") - .value("ARKODE_SPRK_RUTH_3_3", ARKODE_SPRK_RUTH_3_3, "") - .value("ARKODE_SPRK_MCLACHLAN_2_2", ARKODE_SPRK_MCLACHLAN_2_2, "") - .value("ARKODE_SPRK_MCLACHLAN_3_3", ARKODE_SPRK_MCLACHLAN_3_3, "") - .value("ARKODE_SPRK_CANDY_ROZMUS_4_4", ARKODE_SPRK_CANDY_ROZMUS_4_4, "") - .value("ARKODE_SPRK_MCLACHLAN_4_4", ARKODE_SPRK_MCLACHLAN_4_4, "") - .value("ARKODE_SPRK_MCLACHLAN_5_6", ARKODE_SPRK_MCLACHLAN_5_6, "") - .value("ARKODE_SPRK_YOSHIDA_6_8", ARKODE_SPRK_YOSHIDA_6_8, "") - .value("ARKODE_SPRK_SUZUKI_UMENO_8_16", ARKODE_SPRK_SUZUKI_UMENO_8_16, "") - .value("ARKODE_SPRK_SOFRONIOU_10_36", ARKODE_SPRK_SOFRONIOU_10_36, "") - .value("ARKODE_MAX_SPRK_NUM", ARKODE_MAX_SPRK_NUM, "") + nb::enum_(m, "ARKODE_SPRKMethodID", nb::is_arithmetic(), "") + .value("ARKODE_SPRK_NONE", ARKODE_SPRK_NONE, "ensure enum is signed int") + .value("ARKODE_SPRK_EULER_1_1", ARKODE_SPRK_EULER_1_1, "") + .value("ARKODE_MIN_SPRK_NUM", ARKODE_MIN_SPRK_NUM, "") + .value("ARKODE_SPRK_LEAPFROG_2_2", ARKODE_SPRK_LEAPFROG_2_2, "") + .value("ARKODE_SPRK_PSEUDO_LEAPFROG_2_2", ARKODE_SPRK_PSEUDO_LEAPFROG_2_2, "") + .value("ARKODE_SPRK_RUTH_3_3", ARKODE_SPRK_RUTH_3_3, "") + .value("ARKODE_SPRK_MCLACHLAN_2_2", ARKODE_SPRK_MCLACHLAN_2_2, "") + .value("ARKODE_SPRK_MCLACHLAN_3_3", ARKODE_SPRK_MCLACHLAN_3_3, "") + .value("ARKODE_SPRK_CANDY_ROZMUS_4_4", ARKODE_SPRK_CANDY_ROZMUS_4_4, "") + .value("ARKODE_SPRK_MCLACHLAN_4_4", ARKODE_SPRK_MCLACHLAN_4_4, "") + .value("ARKODE_SPRK_MCLACHLAN_5_6", ARKODE_SPRK_MCLACHLAN_5_6, "") + .value("ARKODE_SPRK_YOSHIDA_6_8", ARKODE_SPRK_YOSHIDA_6_8, "") + .value("ARKODE_SPRK_SUZUKI_UMENO_8_16", ARKODE_SPRK_SUZUKI_UMENO_8_16, "") + .value("ARKODE_SPRK_SOFRONIOU_10_36", ARKODE_SPRK_SOFRONIOU_10_36, "") + .value("ARKODE_MAX_SPRK_NUM", ARKODE_MAX_SPRK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// +// + auto pyClassARKodeSPRKTableMem = - nb::class_(m, "ARKodeSPRKTableMem", "") + nb::class_ + (m, "ARKodeSPRKTableMem", "") .def(nb::init<>()) // implicit default constructor - ; - -m.def( - "ARKodeSPRKTable_Create", - [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) - -> std::shared_ptr> - { - auto ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector = - [](int s, int q, sundials4py::Array1d a_1d, - sundials4py::Array1d ahat_1d) -> ARKodeSPRKTable - { - sunrealtype* a_1d_ptr = a_1d.size() == 0 ? nullptr : a_1d.data(); - sunrealtype* ahat_1d_ptr = ahat_1d.size() == 0 ? nullptr : ahat_1d.data(); - - auto lambda_result = ARKodeSPRKTable_Create(s, q, a_1d_ptr, ahat_1d_ptr); - return lambda_result; - }; - auto ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr = - [&ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, - sundials4py::Array1d a_1d, - sundials4py::Array1d ahat_1d) - -> std::shared_ptr> - { - auto lambda_result = - ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector(s, q, a_1d, ahat_1d); - - return our_make_shared, - ARKodeSPRKTableDeleter>(lambda_result); - }; - - return ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr(s, q, a_1d, - ahat_1d); - }, - nb::arg("s"), nb::arg("q"), nb::arg("a_1d"), nb::arg("ahat_1d")); - -m.def( - "ARKodeSPRKTable_Load", - [](ARKODE_SPRKMethodID id) - -> std::shared_ptr> - { - auto ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr = - [](ARKODE_SPRKMethodID id) - -> std::shared_ptr> + ; + + +m.def("ARKodeSPRKTable_Create", + [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> std::shared_ptr> { - auto lambda_result = ARKodeSPRKTable_Load(id); - - return our_make_shared, - ARKodeSPRKTableDeleter>(lambda_result); - }; - - return ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr(id); - }, - nb::arg("id")); - -m.def( - "ARKodeSPRKTable_LoadByName", - [](const char* method) -> std::shared_ptr> - { - auto ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr = - [](const char* method) - -> std::shared_ptr> + auto ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector = [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> ARKodeSPRKTable + { + sunrealtype* a_1d_ptr = a_1d.size() == 0 ? nullptr : a_1d.data(); + sunrealtype* ahat_1d_ptr = ahat_1d.size() == 0 ? nullptr : ahat_1d.data(); + + auto lambda_result = ARKodeSPRKTable_Create(s, q, a_1d_ptr, ahat_1d_ptr); + return lambda_result; + }; + auto ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr = [&ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> std::shared_ptr> + { + auto lambda_result = ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector(s, q, a_1d, ahat_1d); + + return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr(s, q, a_1d, ahat_1d); + }, nb::arg("s"), nb::arg("q"), nb::arg("a_1d"), nb::arg("ahat_1d")); + +m.def("ARKodeSPRKTable_Load", + [](ARKODE_SPRKMethodID id) -> std::shared_ptr> { - auto lambda_result = ARKodeSPRKTable_LoadByName(method); - - return our_make_shared, - ARKodeSPRKTableDeleter>(lambda_result); - }; - - return ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr(method); - }, - nb::arg("method")); - -m.def( - "ARKodeSPRKTable_Copy", - [](ARKodeSPRKTable that_sprk_storage) - -> std::shared_ptr> - { - auto ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr = - [](ARKodeSPRKTable that_sprk_storage) - -> std::shared_ptr> + auto ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr = [](ARKODE_SPRKMethodID id) -> std::shared_ptr> + { + auto lambda_result = ARKodeSPRKTable_Load(id); + + return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr(id); + }, nb::arg("id")); + +m.def("ARKodeSPRKTable_LoadByName", + [](const char * method) -> std::shared_ptr> { - auto lambda_result = ARKodeSPRKTable_Copy(that_sprk_storage); - - return our_make_shared, - ARKodeSPRKTableDeleter>(lambda_result); - }; - - return ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr(that_sprk_storage); - }, - nb::arg("that_sprk_storage")); - -m.def("ARKodeSPRKTable_Write", ARKodeSPRKTable_Write, nb::arg("sprk_table"), - nb::arg("outfile")); - -m.def( - "ARKodeSPRKTable_ToButcher", - [](ARKodeSPRKTable sprk_storage) - -> std::tuple>, - std::shared_ptr>> - { - auto ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return = - [](ARKodeSPRKTable sprk_storage) - -> std::tuple + auto ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr = [](const char * method) -> std::shared_ptr> + { + auto lambda_result = ARKodeSPRKTable_LoadByName(method); + + return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr(method); + }, nb::arg("method")); + +m.def("ARKodeSPRKTable_Copy", + [](ARKodeSPRKTable that_sprk_storage) -> std::shared_ptr> { - ARKodeButcherTable a_ptr_adapt_modifiable; - ARKodeButcherTable b_ptr_adapt_modifiable; - - int r = ARKodeSPRKTable_ToButcher(sprk_storage, &a_ptr_adapt_modifiable, - &b_ptr_adapt_modifiable); - return std::make_tuple(r, a_ptr_adapt_modifiable, b_ptr_adapt_modifiable); - }; - auto ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr = - [&ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return]( - ARKodeSPRKTable sprk_storage) - -> std::tuple>, - std::shared_ptr>> + auto ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr = [](ARKodeSPRKTable that_sprk_storage) -> std::shared_ptr> + { + auto lambda_result = ARKodeSPRKTable_Copy(that_sprk_storage); + + return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr(that_sprk_storage); + }, nb::arg("that_sprk_storage")); + +m.def("ARKodeSPRKTable_Write", + ARKodeSPRKTable_Write, nb::arg("sprk_table"), nb::arg("outfile")); + +m.def("ARKodeSPRKTable_ToButcher", + [](ARKodeSPRKTable sprk_storage) -> std::tuple>, std::shared_ptr>> { - auto lambda_result = - ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return( - sprk_storage); - - return std::make_tuple(std::get<0>(lambda_result), - our_make_shared, - ARKodeButcherTableDeleter>( - std::get<1>(lambda_result)), - our_make_shared, - ARKodeButcherTableDeleter>( - std::get<2>(lambda_result))); - }; - - return ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr(sprk_storage); - }, - nb::arg("sprk_storage"), nb::rv_policy::reference); + auto ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return = [](ARKodeSPRKTable sprk_storage) -> std::tuple + { + ARKodeButcherTable a_ptr_adapt_modifiable; + ARKodeButcherTable b_ptr_adapt_modifiable; + + int r = ARKodeSPRKTable_ToButcher(sprk_storage, &a_ptr_adapt_modifiable, &b_ptr_adapt_modifiable); + return std::make_tuple(r, a_ptr_adapt_modifiable, b_ptr_adapt_modifiable); + }; + auto ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr = [&ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return](ARKodeSPRKTable sprk_storage) -> std::tuple>, std::shared_ptr>> + { + auto lambda_result = ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return(sprk_storage); + + return std::make_tuple(std::get<0>(lambda_result), our_make_shared, ARKodeButcherTableDeleter>(std::get<1>(lambda_result)), our_make_shared, ARKodeButcherTableDeleter>(std::get<2>(lambda_result))); + return lambda_result; + }; + + return ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr(sprk_storage); + }, + nb::arg("sprk_storage"), + nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp index cae989c9fe..0818166a83 100644 --- a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp @@ -1,138 +1,117 @@ // #ifndef _LSRKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyEnumARKODE_LSRKMethodType = - nb::enum_(m, "ARKODE_LSRKMethodType", - nb::is_arithmetic(), "") - .value("ARKODE_LSRK_RKC_2", ARKODE_LSRK_RKC_2, "") - .value("ARKODE_LSRK_RKL_2", ARKODE_LSRK_RKL_2, "") - .value("ARKODE_LSRK_SSP_S_2", ARKODE_LSRK_SSP_S_2, "") - .value("ARKODE_LSRK_SSP_S_3", ARKODE_LSRK_SSP_S_3, "") - .value("ARKODE_LSRK_SSP_10_4", ARKODE_LSRK_SSP_10_4, "") + nb::enum_(m, "ARKODE_LSRKMethodType", nb::is_arithmetic(), "") + .value("ARKODE_LSRK_RKC_2", ARKODE_LSRK_RKC_2, "") + .value("ARKODE_LSRK_RKL_2", ARKODE_LSRK_RKL_2, "") + .value("ARKODE_LSRK_SSP_S_2", ARKODE_LSRK_SSP_S_2, "") + .value("ARKODE_LSRK_SSP_S_3", ARKODE_LSRK_SSP_S_3, "") + .value("ARKODE_LSRK_SSP_10_4", ARKODE_LSRK_SSP_10_4, "") .export_values(); // #ifndef SWIG -// +// // #endif -// +// -m.def("LSRKStepSetSTSMethod", LSRKStepSetSTSMethod, nb::arg("arkode_mem"), - nb::arg("method")); +m.def("LSRKStepSetSTSMethod", + LSRKStepSetSTSMethod, nb::arg("arkode_mem"), nb::arg("method")); -m.def("LSRKStepSetSSPMethod", LSRKStepSetSSPMethod, nb::arg("arkode_mem"), - nb::arg("method")); +m.def("LSRKStepSetSSPMethod", + LSRKStepSetSSPMethod, nb::arg("arkode_mem"), nb::arg("method")); -m.def("LSRKStepSetSTSMethodByName", LSRKStepSetSTSMethodByName, - nb::arg("arkode_mem"), nb::arg("emethod")); +m.def("LSRKStepSetSTSMethodByName", + LSRKStepSetSTSMethodByName, nb::arg("arkode_mem"), nb::arg("emethod")); -m.def("LSRKStepSetSSPMethodByName", LSRKStepSetSSPMethodByName, - nb::arg("arkode_mem"), nb::arg("emethod")); +m.def("LSRKStepSetSSPMethodByName", + LSRKStepSetSSPMethodByName, nb::arg("arkode_mem"), nb::arg("emethod")); -m.def("LSRKStepSetDomEigEstimator", LSRKStepSetDomEigEstimator, - nb::arg("arkode_mem"), nb::arg("DEE")); +m.def("LSRKStepSetDomEigEstimator", + LSRKStepSetDomEigEstimator, nb::arg("arkode_mem"), nb::arg("DEE")); -m.def("LSRKStepSetDomEigFrequency", LSRKStepSetDomEigFrequency, - nb::arg("arkode_mem"), nb::arg("nsteps")); +m.def("LSRKStepSetDomEigFrequency", + LSRKStepSetDomEigFrequency, nb::arg("arkode_mem"), nb::arg("nsteps")); -m.def("LSRKStepSetMaxNumStages", LSRKStepSetMaxNumStages, nb::arg("arkode_mem"), - nb::arg("stage_max_limit")); +m.def("LSRKStepSetMaxNumStages", + LSRKStepSetMaxNumStages, nb::arg("arkode_mem"), nb::arg("stage_max_limit")); -m.def("LSRKStepSetDomEigSafetyFactor", LSRKStepSetDomEigSafetyFactor, - nb::arg("arkode_mem"), nb::arg("dom_eig_safety")); +m.def("LSRKStepSetDomEigSafetyFactor", + LSRKStepSetDomEigSafetyFactor, nb::arg("arkode_mem"), nb::arg("dom_eig_safety")); -m.def("LSRKStepSetUseAnalyticStabRegion", LSRKStepSetUseAnalyticStabRegion, - nb::arg("arkode_mem"), nb::arg("analytic_stab_region")); +m.def("LSRKStepSetUseAnalyticStabRegion", + LSRKStepSetUseAnalyticStabRegion, nb::arg("arkode_mem"), nb::arg("analytic_stab_region")); m.def("LSRKStepSetNumDomEigEstInitPreprocessIters", - LSRKStepSetNumDomEigEstInitPreprocessIters, nb::arg("arkode_mem"), - nb::arg("num_iters")); + LSRKStepSetNumDomEigEstInitPreprocessIters, nb::arg("arkode_mem"), nb::arg("num_iters")); m.def("LSRKStepSetNumDomEigEstPreprocessIters", - LSRKStepSetNumDomEigEstPreprocessIters, nb::arg("arkode_mem"), - nb::arg("num_iters")); - -m.def("LSRKStepSetNumSSPStages", LSRKStepSetNumSSPStages, nb::arg("arkode_mem"), - nb::arg("num_of_stages")); - -m.def( - "LSRKStepGetNumDomEigUpdates", - [](void* arkode_mem) -> std::tuple - { - auto LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + LSRKStepSetNumDomEigEstPreprocessIters, nb::arg("arkode_mem"), nb::arg("num_iters")); + +m.def("LSRKStepSetNumSSPStages", + LSRKStepSetNumSSPStages, nb::arg("arkode_mem"), nb::arg("num_of_stages")); + +m.def("LSRKStepGetNumDomEigUpdates", + [](void * arkode_mem) -> std::tuple { - long dom_eig_num_evals_adapt_modifiable; - - int r = LSRKStepGetNumDomEigUpdates(arkode_mem, - &dom_eig_num_evals_adapt_modifiable); - return std::make_tuple(r, dom_eig_num_evals_adapt_modifiable); - }; - - return LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "LSRKStepGetMaxNumStages", - [](void* arkode_mem) -> std::tuple - { - auto LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long dom_eig_num_evals_adapt_modifiable; + + int r = LSRKStepGetNumDomEigUpdates(arkode_mem, &dom_eig_num_evals_adapt_modifiable); + return std::make_tuple(r, dom_eig_num_evals_adapt_modifiable); + }; + + return LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("LSRKStepGetMaxNumStages", + [](void * arkode_mem) -> std::tuple { - int stage_max_adapt_modifiable; - - int r = LSRKStepGetMaxNumStages(arkode_mem, &stage_max_adapt_modifiable); - return std::make_tuple(r, stage_max_adapt_modifiable); - }; - - return LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "LSRKStepGetNumDomEigEstRhsEvals", - [](void* arkode_mem) -> std::tuple - { - auto LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + int stage_max_adapt_modifiable; + + int r = LSRKStepGetMaxNumStages(arkode_mem, &stage_max_adapt_modifiable); + return std::make_tuple(r, stage_max_adapt_modifiable); + }; + + return LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("LSRKStepGetNumDomEigEstRhsEvals", + [](void * arkode_mem) -> std::tuple { - long nfeDQ_adapt_modifiable; - - int r = LSRKStepGetNumDomEigEstRhsEvals(arkode_mem, - &nfeDQ_adapt_modifiable); - return std::make_tuple(r, nfeDQ_adapt_modifiable); - }; - - return LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "LSRKStepGetNumDomEigEstIters", - [](void* arkode_mem) -> std::tuple - { - auto LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long nfeDQ_adapt_modifiable; + + int r = LSRKStepGetNumDomEigEstRhsEvals(arkode_mem, &nfeDQ_adapt_modifiable); + return std::make_tuple(r, nfeDQ_adapt_modifiable); + }; + + return LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("LSRKStepGetNumDomEigEstIters", + [](void * arkode_mem) -> std::tuple { - long num_iters_adapt_modifiable; + auto LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long num_iters_adapt_modifiable; - int r = LSRKStepGetNumDomEigEstIters(arkode_mem, - &num_iters_adapt_modifiable); - return std::make_tuple(r, num_iters_adapt_modifiable); - }; + int r = LSRKStepGetNumDomEigEstIters(arkode_mem, &num_iters_adapt_modifiable); + return std::make_tuple(r, num_iters_adapt_modifiable); + }; - return LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); + return LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp index e1cb6800ed..1572fa3c41 100644 --- a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp @@ -1,250 +1,208 @@ // #ifndef _MRISTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyEnumMRISTEP_METHOD_TYPE = - nb::enum_(m, "MRISTEP_METHOD_TYPE", nb::is_arithmetic(), "") - .value("MRISTEP_EXPLICIT", MRISTEP_EXPLICIT, "") - .value("MRISTEP_IMPLICIT", MRISTEP_IMPLICIT, "") - .value("MRISTEP_IMEX", MRISTEP_IMEX, "") - .value("MRISTEP_MERK", MRISTEP_MERK, "") - .value("MRISTEP_SR", MRISTEP_SR, "") + nb::enum_(m, "MRISTEP_METHOD_TYPE", nb::is_arithmetic(), "") + .value("MRISTEP_EXPLICIT", MRISTEP_EXPLICIT, "") + .value("MRISTEP_IMPLICIT", MRISTEP_IMPLICIT, "") + .value("MRISTEP_IMEX", MRISTEP_IMEX, "") + .value("MRISTEP_MERK", MRISTEP_MERK, "") + .value("MRISTEP_SR", MRISTEP_SR, "") .export_values(); // #ifndef SWIG -// +// // #endif -// +// + auto pyEnumARKODE_MRITableID = - nb::enum_(m, "ARKODE_MRITableID", nb::is_arithmetic(), - "MRI coupling table IDs") - .value("ARKODE_MRI_NONE", ARKODE_MRI_NONE, "ensure enum is signed int") - .value("ARKODE_MIS_KW3", ARKODE_MIS_KW3, "") - .value("ARKODE_MIN_MRI_NUM", ARKODE_MIN_MRI_NUM, "") - .value("ARKODE_MRI_GARK_ERK33a", ARKODE_MRI_GARK_ERK33a, "") - .value("ARKODE_MRI_GARK_ERK45a", ARKODE_MRI_GARK_ERK45a, "") - .value("ARKODE_MRI_GARK_IRK21a", ARKODE_MRI_GARK_IRK21a, "") - .value("ARKODE_MRI_GARK_ESDIRK34a", ARKODE_MRI_GARK_ESDIRK34a, "") - .value("ARKODE_MRI_GARK_ESDIRK46a", ARKODE_MRI_GARK_ESDIRK46a, "") - .value("ARKODE_IMEX_MRI_GARK3a", ARKODE_IMEX_MRI_GARK3a, "") - .value("ARKODE_IMEX_MRI_GARK3b", ARKODE_IMEX_MRI_GARK3b, "") - .value("ARKODE_IMEX_MRI_GARK4", ARKODE_IMEX_MRI_GARK4, "") - .value("ARKODE_MRI_GARK_FORWARD_EULER", ARKODE_MRI_GARK_FORWARD_EULER, "") - .value("ARKODE_MRI_GARK_RALSTON2", ARKODE_MRI_GARK_RALSTON2, "") - .value("ARKODE_MRI_GARK_ERK22a", ARKODE_MRI_GARK_ERK22a, "") - .value("ARKODE_MRI_GARK_ERK22b", ARKODE_MRI_GARK_ERK22b, "") - .value("ARKODE_MRI_GARK_RALSTON3", ARKODE_MRI_GARK_RALSTON3, "") - .value("ARKODE_MRI_GARK_BACKWARD_EULER", ARKODE_MRI_GARK_BACKWARD_EULER, "") - .value("ARKODE_MRI_GARK_IMPLICIT_MIDPOINT", - ARKODE_MRI_GARK_IMPLICIT_MIDPOINT, "") - .value("ARKODE_IMEX_MRI_GARK_EULER", ARKODE_IMEX_MRI_GARK_EULER, "") - .value("ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL", ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL, - "") - .value("ARKODE_IMEX_MRI_GARK_MIDPOINT", ARKODE_IMEX_MRI_GARK_MIDPOINT, "") - .value("ARKODE_MERK21", ARKODE_MERK21, "") - .value("ARKODE_MERK32", ARKODE_MERK32, "") - .value("ARKODE_MERK43", ARKODE_MERK43, "") - .value("ARKODE_MERK54", ARKODE_MERK54, "") - .value("ARKODE_IMEX_MRI_SR21", ARKODE_IMEX_MRI_SR21, "") - .value("ARKODE_IMEX_MRI_SR32", ARKODE_IMEX_MRI_SR32, "") - .value("ARKODE_IMEX_MRI_SR43", ARKODE_IMEX_MRI_SR43, "") - .value("ARKODE_MAX_MRI_NUM", ARKODE_MAX_MRI_NUM, "") + nb::enum_(m, "ARKODE_MRITableID", nb::is_arithmetic(), "MRI coupling table IDs") + .value("ARKODE_MRI_NONE", ARKODE_MRI_NONE, "ensure enum is signed int") + .value("ARKODE_MIS_KW3", ARKODE_MIS_KW3, "") + .value("ARKODE_MIN_MRI_NUM", ARKODE_MIN_MRI_NUM, "") + .value("ARKODE_MRI_GARK_ERK33a", ARKODE_MRI_GARK_ERK33a, "") + .value("ARKODE_MRI_GARK_ERK45a", ARKODE_MRI_GARK_ERK45a, "") + .value("ARKODE_MRI_GARK_IRK21a", ARKODE_MRI_GARK_IRK21a, "") + .value("ARKODE_MRI_GARK_ESDIRK34a", ARKODE_MRI_GARK_ESDIRK34a, "") + .value("ARKODE_MRI_GARK_ESDIRK46a", ARKODE_MRI_GARK_ESDIRK46a, "") + .value("ARKODE_IMEX_MRI_GARK3a", ARKODE_IMEX_MRI_GARK3a, "") + .value("ARKODE_IMEX_MRI_GARK3b", ARKODE_IMEX_MRI_GARK3b, "") + .value("ARKODE_IMEX_MRI_GARK4", ARKODE_IMEX_MRI_GARK4, "") + .value("ARKODE_MRI_GARK_FORWARD_EULER", ARKODE_MRI_GARK_FORWARD_EULER, "") + .value("ARKODE_MRI_GARK_RALSTON2", ARKODE_MRI_GARK_RALSTON2, "") + .value("ARKODE_MRI_GARK_ERK22a", ARKODE_MRI_GARK_ERK22a, "") + .value("ARKODE_MRI_GARK_ERK22b", ARKODE_MRI_GARK_ERK22b, "") + .value("ARKODE_MRI_GARK_RALSTON3", ARKODE_MRI_GARK_RALSTON3, "") + .value("ARKODE_MRI_GARK_BACKWARD_EULER", ARKODE_MRI_GARK_BACKWARD_EULER, "") + .value("ARKODE_MRI_GARK_IMPLICIT_MIDPOINT", ARKODE_MRI_GARK_IMPLICIT_MIDPOINT, "") + .value("ARKODE_IMEX_MRI_GARK_EULER", ARKODE_IMEX_MRI_GARK_EULER, "") + .value("ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL", ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL, "") + .value("ARKODE_IMEX_MRI_GARK_MIDPOINT", ARKODE_IMEX_MRI_GARK_MIDPOINT, "") + .value("ARKODE_MERK21", ARKODE_MERK21, "") + .value("ARKODE_MERK32", ARKODE_MERK32, "") + .value("ARKODE_MERK43", ARKODE_MERK43, "") + .value("ARKODE_MERK54", ARKODE_MERK54, "") + .value("ARKODE_IMEX_MRI_SR21", ARKODE_IMEX_MRI_SR21, "") + .value("ARKODE_IMEX_MRI_SR32", ARKODE_IMEX_MRI_SR32, "") + .value("ARKODE_IMEX_MRI_SR43", ARKODE_IMEX_MRI_SR43, "") + .value("ARKODE_MAX_MRI_NUM", ARKODE_MAX_MRI_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// +// + auto pyClassMRIStepCouplingMem = - nb::class_(m, "MRIStepCouplingMem", "") + nb::class_ + (m, "MRIStepCouplingMem", "") .def(nb::init<>()) // implicit default constructor - ; - -m.def( - "MRIStepCoupling_LoadTable", - [](ARKODE_MRITableID method) - -> std::shared_ptr> - { - auto MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr = - [](ARKODE_MRITableID method) - -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_LoadTable(method); - - return our_make_shared, - MRIStepCouplingDeleter>(lambda_result); - }; - - return MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr(method); - }, - nb::arg("method"), "Accessor routine to load built-in MRI table"); - -m.def( - "MRIStepCoupling_LoadTableByName", - [](const char* method) -> std::shared_ptr> - { - auto MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr = - [](const char* method) - -> std::shared_ptr> + ; + + +m.def("MRIStepCoupling_LoadTable", + [](ARKODE_MRITableID method) -> std::shared_ptr> { - auto lambda_result = MRIStepCoupling_LoadTableByName(method); - - return our_make_shared, - MRIStepCouplingDeleter>(lambda_result); - }; - - return MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr(method); - }, - nb::arg("method"), "Accessor routine to load built-in MRI table from string"); - -m.def( - "MRIStepCoupling_Create", - [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, - sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) - -> std::shared_ptr> - { - auto MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector = - [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, - sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> MRIStepCoupling + auto MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr = [](ARKODE_MRITableID method) -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_LoadTable(method); + + return our_make_shared, MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr(method); + }, + nb::arg("method"), + "Accessor routine to load built-in MRI table"); + +m.def("MRIStepCoupling_LoadTableByName", + [](const char * method) -> std::shared_ptr> { - sunrealtype* W_1d_ptr = W_1d.size() == 0 ? nullptr : W_1d.data(); - sunrealtype* G_1d_ptr = G_1d.size() == 0 ? nullptr : G_1d.data(); - sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); - - auto lambda_result = MRIStepCoupling_Create(nmat, stages, q, p, W_1d_ptr, - G_1d_ptr, c_1d_ptr); - return lambda_result; - }; - auto MRIStepCoupling_Create_adapt_return_type_to_shared_ptr = - [&MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector](int nmat, int stages, - int q, int p, - sundials4py::Array1d W_1d, - sundials4py::Array1d G_1d, - sundials4py::Array1d c_1d) - -> std::shared_ptr> + auto MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr = [](const char * method) -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_LoadTableByName(method); + + return our_make_shared, MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr(method); + }, + nb::arg("method"), + "Accessor routine to load built-in MRI table from string"); + +m.def("MRIStepCoupling_Create", + [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> std::shared_ptr> { - auto lambda_result = - MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector(nmat, stages, q, p, - W_1d, G_1d, c_1d); - - return our_make_shared, - MRIStepCouplingDeleter>(lambda_result); - }; - - return MRIStepCoupling_Create_adapt_return_type_to_shared_ptr(nmat, stages, - q, p, W_1d, - G_1d, c_1d); - }, - nb::arg("nmat"), nb::arg("stages"), nb::arg("q"), nb::arg("p"), - nb::arg("W_1d"), nb::arg("G_1d"), nb::arg("c_1d")); - -m.def( - "MRIStepCoupling_MIStoMRI", - [](ARKodeButcherTable B, int q, - int p) -> std::shared_ptr> - { - auto MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr = - [](ARKodeButcherTable B, int q, - int p) -> std::shared_ptr> + auto MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector = [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> MRIStepCoupling + { + sunrealtype* W_1d_ptr = W_1d.size() == 0 ? nullptr : W_1d.data(); + sunrealtype* G_1d_ptr = G_1d.size() == 0 ? nullptr : G_1d.data(); + sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); + + auto lambda_result = MRIStepCoupling_Create(nmat, stages, q, p, W_1d_ptr, G_1d_ptr, c_1d_ptr); + return lambda_result; + }; + auto MRIStepCoupling_Create_adapt_return_type_to_shared_ptr = [&MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector(nmat, stages, q, p, W_1d, G_1d, c_1d); + + return our_make_shared, MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_Create_adapt_return_type_to_shared_ptr(nmat, stages, q, p, W_1d, G_1d, c_1d); + }, nb::arg("nmat"), nb::arg("stages"), nb::arg("q"), nb::arg("p"), nb::arg("W_1d"), nb::arg("G_1d"), nb::arg("c_1d")); + +m.def("MRIStepCoupling_MIStoMRI", + [](ARKodeButcherTable B, int q, int p) -> std::shared_ptr> { - auto lambda_result = MRIStepCoupling_MIStoMRI(B, q, p); - - return our_make_shared, - MRIStepCouplingDeleter>(lambda_result); - }; - - return MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr(B, q, p); - }, - nb::arg("B"), nb::arg("q"), nb::arg("p")); - -m.def( - "MRIStepCoupling_Copy", - [](MRIStepCoupling MRIC) -> std::shared_ptr> - { - auto MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr = - [](MRIStepCoupling MRIC) - -> std::shared_ptr> + auto MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr = [](ARKodeButcherTable B, int q, int p) -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_MIStoMRI(B, q, p); + + return our_make_shared, MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr(B, q, p); + }, nb::arg("B"), nb::arg("q"), nb::arg("p")); + +m.def("MRIStepCoupling_Copy", + [](MRIStepCoupling MRIC) -> std::shared_ptr> { - auto lambda_result = MRIStepCoupling_Copy(MRIC); + auto MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr = [](MRIStepCoupling MRIC) -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_Copy(MRIC); - return our_make_shared, - MRIStepCouplingDeleter>(lambda_result); - }; + return our_make_shared, MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; - return MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr(MRIC); - }, - nb::arg("MRIC")); + return MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr(MRIC); + }, nb::arg("MRIC")); -m.def("MRIStepCoupling_Write", MRIStepCoupling_Write, nb::arg("MRIC"), - nb::arg("outfile")); +m.def("MRIStepCoupling_Write", + MRIStepCoupling_Write, nb::arg("MRIC"), nb::arg("outfile")); -m.def("MRIStepSetCoupling", MRIStepSetCoupling, nb::arg("arkode_mem"), - nb::arg("MRIC")); +m.def("MRIStepSetCoupling", + MRIStepSetCoupling, nb::arg("arkode_mem"), nb::arg("MRIC")); -m.def( - "MRIStepGetCurrentCoupling", - [](void* arkode_mem) -> std::tuple - { - auto MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("MRIStepGetCurrentCoupling", + [](void * arkode_mem) -> std::tuple { - MRIStepCoupling MRIC_adapt_modifiable; - - int r = MRIStepGetCurrentCoupling(arkode_mem, &MRIC_adapt_modifiable); - return std::make_tuple(r, MRIC_adapt_modifiable); - }; - - return MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def( - "MRIStepGetLastInnerStepFlag", - [](void* arkode_mem) -> std::tuple - { - auto MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + MRIStepCoupling MRIC_adapt_modifiable; + + int r = MRIStepGetCurrentCoupling(arkode_mem, &MRIC_adapt_modifiable); + return std::make_tuple(r, MRIC_adapt_modifiable); + }; + + return MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("MRIStepGetLastInnerStepFlag", + [](void * arkode_mem) -> std::tuple { - int flag_adapt_modifiable; - - int r = MRIStepGetLastInnerStepFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; - - return MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); - -m.def( - "MRIStepGetNumInnerStepperFails", - [](void* arkode_mem) -> std::tuple - { - auto MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple + auto MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + int flag_adapt_modifiable; + + int r = MRIStepGetLastInnerStepFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; + + return MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); + +m.def("MRIStepGetNumInnerStepperFails", + [](void * arkode_mem) -> std::tuple { - long inner_fails_adapt_modifiable; + auto MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + long inner_fails_adapt_modifiable; - int r = MRIStepGetNumInnerStepperFails(arkode_mem, - &inner_fails_adapt_modifiable); - return std::make_tuple(r, inner_fails_adapt_modifiable); - }; + int r = MRIStepGetNumInnerStepperFails(arkode_mem, &inner_fails_adapt_modifiable); + return std::make_tuple(r, inner_fails_adapt_modifiable); + }; - return MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem")); + return MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, nb::arg("arkode_mem")); -m.def("MRIStepInnerStepper_AddForcing", MRIStepInnerStepper_AddForcing, - nb::arg("stepper"), nb::arg("t"), nb::arg("f")); +m.def("MRIStepInnerStepper_AddForcing", + MRIStepInnerStepper_AddForcing, nb::arg("stepper"), nb::arg("t"), nb::arg("f")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp index 1aaf0677b6..b00416c49f 100644 --- a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp @@ -1,320 +1,222 @@ // #ifndef ARKODE_SPLITTINGSTEP_H_ -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyClassSplittingStepCoefficientsMem = - nb::class_(m, "SplittingStepCoefficientsMem", "") + nb::class_ + (m, "SplittingStepCoefficientsMem", "") .def(nb::init<>()) // implicit default constructor - ; + ; + auto pyEnumARKODE_SplittingCoefficientsID = - nb::enum_(m, "ARKODE_SplittingCoefficientsID", - nb::is_arithmetic(), "") - .value("ARKODE_SPLITTING_NONE", ARKODE_SPLITTING_NONE, - "ensure enum is signed int") - .value("ARKODE_SPLITTING_LIE_TROTTER_1_1_2", - ARKODE_SPLITTING_LIE_TROTTER_1_1_2, "") - .value("ARKODE_MIN_SPLITTING_NUM", ARKODE_MIN_SPLITTING_NUM, "") - .value("ARKODE_SPLITTING_STRANG_2_2_2", ARKODE_SPLITTING_STRANG_2_2_2, "") - .value("ARKODE_SPLITTING_BEST_2_2_2", ARKODE_SPLITTING_BEST_2_2_2, "") - .value("ARKODE_SPLITTING_SUZUKI_3_3_2", ARKODE_SPLITTING_SUZUKI_3_3_2, "") - .value("ARKODE_SPLITTING_RUTH_3_3_2", ARKODE_SPLITTING_RUTH_3_3_2, "") - .value("ARKODE_SPLITTING_YOSHIDA_4_4_2", ARKODE_SPLITTING_YOSHIDA_4_4_2, "") - .value("ARKODE_SPLITTING_YOSHIDA_8_6_2", ARKODE_SPLITTING_YOSHIDA_8_6_2, "") - .value("ARKODE_MAX_SPLITTING_NUM", ARKODE_MAX_SPLITTING_NUM, "") + nb::enum_(m, "ARKODE_SplittingCoefficientsID", nb::is_arithmetic(), "") + .value("ARKODE_SPLITTING_NONE", ARKODE_SPLITTING_NONE, "ensure enum is signed int") + .value("ARKODE_SPLITTING_LIE_TROTTER_1_1_2", ARKODE_SPLITTING_LIE_TROTTER_1_1_2, "") + .value("ARKODE_MIN_SPLITTING_NUM", ARKODE_MIN_SPLITTING_NUM, "") + .value("ARKODE_SPLITTING_STRANG_2_2_2", ARKODE_SPLITTING_STRANG_2_2_2, "") + .value("ARKODE_SPLITTING_BEST_2_2_2", ARKODE_SPLITTING_BEST_2_2_2, "") + .value("ARKODE_SPLITTING_SUZUKI_3_3_2", ARKODE_SPLITTING_SUZUKI_3_3_2, "") + .value("ARKODE_SPLITTING_RUTH_3_3_2", ARKODE_SPLITTING_RUTH_3_3_2, "") + .value("ARKODE_SPLITTING_YOSHIDA_4_4_2", ARKODE_SPLITTING_YOSHIDA_4_4_2, "") + .value("ARKODE_SPLITTING_YOSHIDA_8_6_2", ARKODE_SPLITTING_YOSHIDA_8_6_2, "") + .value("ARKODE_MAX_SPLITTING_NUM", ARKODE_MAX_SPLITTING_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def( - "SplittingStepCoefficients_Create", - [](int sequential_methods, int stages, int partitions, int order, - sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector = - [](int sequential_methods, int stages, int partitions, int order, - sundials4py::Array1d alpha_1d, - sundials4py::Array1d beta_1d) -> SplittingStepCoefficients - { - sunrealtype* alpha_1d_ptr = alpha_1d.size() == 0 ? nullptr - : alpha_1d.data(); - sunrealtype* beta_1d_ptr = beta_1d.size() == 0 ? nullptr : beta_1d.data(); - - auto lambda_result = - SplittingStepCoefficients_Create(sequential_methods, stages, partitions, - order, alpha_1d_ptr, beta_1d_ptr); - return lambda_result; - }; - auto SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr = - [&SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector](int sequential_methods, - int stages, - int partitions, - int order, - sundials4py::Array1d - alpha_1d, - sundials4py::Array1d - beta_1d) - -> std::shared_ptr> +// + +m.def("SplittingStepCoefficients_Create", + [](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> std::shared_ptr> { - auto lambda_result = - SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector(sequential_methods, - stages, - partitions, - order, - alpha_1d, - beta_1d); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr(sequential_methods, - stages, - partitions, - order, - alpha_1d, - beta_1d); - }, - nb::arg("sequential_methods"), nb::arg("stages"), nb::arg("partitions"), - nb::arg("order"), nb::arg("alpha_1d"), nb::arg("beta_1d")); - -m.def( - "SplittingStepCoefficients_Copy", - [](SplittingStepCoefficients coefficients) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr = - [](SplittingStepCoefficients coefficients) - -> std::shared_ptr> + auto SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector = [](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> SplittingStepCoefficients + { + sunrealtype* alpha_1d_ptr = alpha_1d.size() == 0 ? nullptr : alpha_1d.data(); + sunrealtype* beta_1d_ptr = beta_1d.size() == 0 ? nullptr : beta_1d.data(); + + auto lambda_result = SplittingStepCoefficients_Create(sequential_methods, stages, partitions, order, alpha_1d_ptr, beta_1d_ptr); + return lambda_result; + }; + auto SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr = [&SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector(sequential_methods, stages, partitions, order, alpha_1d, beta_1d); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr(sequential_methods, stages, partitions, order, alpha_1d, beta_1d); + }, nb::arg("sequential_methods"), nb::arg("stages"), nb::arg("partitions"), nb::arg("order"), nb::arg("alpha_1d"), nb::arg("beta_1d")); + +m.def("SplittingStepCoefficients_Copy", + [](SplittingStepCoefficients coefficients) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_Copy(coefficients); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr( - coefficients); - }, - nb::arg("coefficients")); - -m.def("SplittingStepCoefficients_Write", SplittingStepCoefficients_Write, - nb::arg("coefficients"), nb::arg("outfile")); - -m.def( - "SplittingStepCoefficients_LoadCoefficients", - [](ARKODE_SplittingCoefficientsID id) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr = - [](ARKODE_SplittingCoefficientsID id) - -> std::shared_ptr> + auto SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr = [](SplittingStepCoefficients coefficients) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_Copy(coefficients); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr(coefficients); + }, nb::arg("coefficients")); + +m.def("SplittingStepCoefficients_Write", + SplittingStepCoefficients_Write, nb::arg("coefficients"), nb::arg("outfile")); + +m.def("SplittingStepCoefficients_LoadCoefficients", + [](ARKODE_SplittingCoefficientsID id) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_LoadCoefficients(id); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr( - id); - }, - nb::arg("id")); - -m.def( - "SplittingStepCoefficients_LoadCoefficientsByName", - [](const char* name) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr = - [](const char* name) - -> std::shared_ptr> + auto SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr = [](ARKODE_SplittingCoefficientsID id) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_LoadCoefficients(id); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr(id); + }, nb::arg("id")); + +m.def("SplittingStepCoefficients_LoadCoefficientsByName", + [](const char * name) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_LoadCoefficientsByName(name); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr( - name); - }, - nb::arg("name")); - -m.def("SplittingStepCoefficients_IDToName", SplittingStepCoefficients_IDToName, - nb::arg("id")); - -m.def( - "SplittingStepCoefficients_LieTrotter", - [](int partitions) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr = - [](int partitions) - -> std::shared_ptr> + auto SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr = [](const char * name) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_LoadCoefficientsByName(name); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr(name); + }, nb::arg("name")); + +m.def("SplittingStepCoefficients_IDToName", + SplittingStepCoefficients_IDToName, nb::arg("id")); + +m.def("SplittingStepCoefficients_LieTrotter", + [](int partitions) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_LieTrotter(partitions); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr( - partitions); - }, - nb::arg("partitions")); - -m.def( - "SplittingStepCoefficients_Strang", - [](int partitions) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr = - [](int partitions) - -> std::shared_ptr> + auto SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_LieTrotter(partitions); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr(partitions); + }, nb::arg("partitions")); + +m.def("SplittingStepCoefficients_Strang", + [](int partitions) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_Strang(partitions); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr( - partitions); - }, - nb::arg("partitions")); - -m.def( - "SplittingStepCoefficients_Parallel", - [](int partitions) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr = - [](int partitions) - -> std::shared_ptr> + auto SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_Strang(partitions); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr(partitions); + }, nb::arg("partitions")); + +m.def("SplittingStepCoefficients_Parallel", + [](int partitions) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_Parallel(partitions); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr( - partitions); - }, - nb::arg("partitions")); - -m.def( - "SplittingStepCoefficients_SymmetricParallel", - [](int partitions) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr = - [](int partitions) - -> std::shared_ptr> + auto SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_Parallel(partitions); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr(partitions); + }, nb::arg("partitions")); + +m.def("SplittingStepCoefficients_SymmetricParallel", + [](int partitions) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_SymmetricParallel(partitions); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr( - partitions); - }, - nb::arg("partitions")); - -m.def( - "SplittingStepCoefficients_ThirdOrderSuzuki", - [](int partitions) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr = - [](int partitions) - -> std::shared_ptr> + auto SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_SymmetricParallel(partitions); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr(partitions); + }, nb::arg("partitions")); + +m.def("SplittingStepCoefficients_ThirdOrderSuzuki", + [](int partitions) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr( - partitions); - }, - nb::arg("partitions")); - -m.def( - "SplittingStepCoefficients_TripleJump", - [](int partitions, int order) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr = - [](int partitions, int order) - -> std::shared_ptr> + auto SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr(partitions); + }, nb::arg("partitions")); + +m.def("SplittingStepCoefficients_TripleJump", + [](int partitions, int order) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_TripleJump(partitions, - order); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr(partitions, - order); - }, - nb::arg("partitions"), nb::arg("order")); - -m.def( - "SplittingStepCoefficients_SuzukiFractal", - [](int partitions, int order) - -> std::shared_ptr> - { - auto SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr = - [](int partitions, int order) - -> std::shared_ptr> + auto SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr = [](int partitions, int order) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_TripleJump(partitions, order); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr(partitions, order); + }, nb::arg("partitions"), nb::arg("order")); + +m.def("SplittingStepCoefficients_SuzukiFractal", + [](int partitions, int order) -> std::shared_ptr> { - auto lambda_result = SplittingStepCoefficients_SuzukiFractal(partitions, - order); - - return our_make_shared, - SplittingStepCoefficientsDeleter>(lambda_result); - }; - - return SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr(partitions, - order); - }, - nb::arg("partitions"), nb::arg("order")); - -m.def("SplittingStepSetCoefficients", SplittingStepSetCoefficients, - nb::arg("arkode_mem"), nb::arg("coefficients")); - -m.def( - "SplittingStepGetNumEvolves", - [](void* arkode_mem, int partition) -> std::tuple - { - auto SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return = - [](void* arkode_mem, int partition) -> std::tuple + auto SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr = [](int partitions, int order) -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_SuzukiFractal(partitions, order); + + return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr(partitions, order); + }, nb::arg("partitions"), nb::arg("order")); + +m.def("SplittingStepSetCoefficients", + SplittingStepSetCoefficients, nb::arg("arkode_mem"), nb::arg("coefficients")); + +m.def("SplittingStepGetNumEvolves", + [](void * arkode_mem, int partition) -> std::tuple { - long evolves_adapt_modifiable; + auto SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition) -> std::tuple + { + long evolves_adapt_modifiable; - int r = SplittingStepGetNumEvolves(arkode_mem, partition, - &evolves_adapt_modifiable); - return std::make_tuple(r, evolves_adapt_modifiable); - }; + int r = SplittingStepGetNumEvolves(arkode_mem, partition, &evolves_adapt_modifiable); + return std::make_tuple(r, evolves_adapt_modifiable); + }; - return SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, - partition); - }, - nb::arg("arkode_mem"), nb::arg("partition")); + return SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, partition); + }, nb::arg("arkode_mem"), nb::arg("partition")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp index 1d92ba3019..42e3129fb9 100644 --- a/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp @@ -1,36 +1,34 @@ // #ifndef _ARKODE_SPRKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("SPRKStepSetMethod", SPRKStepSetMethod, nb::arg("arkode_mem"), - nb::arg("sprk_storage")); +m.def("SPRKStepSetMethod", + SPRKStepSetMethod, nb::arg("arkode_mem"), nb::arg("sprk_storage")); -m.def("SPRKStepSetMethodName", SPRKStepSetMethodName, nb::arg("arkode_mem"), - nb::arg("method")); +m.def("SPRKStepSetMethodName", + SPRKStepSetMethodName, nb::arg("arkode_mem"), nb::arg("method")); -m.def( - "SPRKStepGetCurrentMethod", - [](void* arkode_mem) -> std::tuple - { - auto SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return = - [](void* arkode_mem) -> std::tuple +m.def("SPRKStepGetCurrentMethod", + [](void * arkode_mem) -> std::tuple { - ARKodeSPRKTable sprk_storage_adapt_modifiable; + auto SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple + { + ARKodeSPRKTable sprk_storage_adapt_modifiable; - int r = SPRKStepGetCurrentMethod(arkode_mem, - &sprk_storage_adapt_modifiable); - return std::make_tuple(r, sprk_storage_adapt_modifiable); - }; + int r = SPRKStepGetCurrentMethod(arkode_mem, &sprk_storage_adapt_modifiable); + return std::make_tuple(r, sprk_storage_adapt_modifiable); + }; - return SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return( - arkode_mem); - }, - nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); + return SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), + "nb::rv_policy::reference", + nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 629b893670..6ce3082888 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -1,50 +1,45 @@ // #ifndef _SUNDOMEIGEST_POWER_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// + auto pyClassSUNDomEigEstimatorContent_Power_ = - nb::class_(m, "SUNDomEigEstimatorContent_Power_", - "") + nb::class_ + (m, "SUNDomEigEstimatorContent_Power_", "") .def(nb::init<>()) // implicit default constructor - ; - -m.def( - "SUNDomEigEstimator_Power", - [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) - -> std::shared_ptr> - { - auto SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr = - [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) - -> std::shared_ptr> + ; + + +m.def("SUNDomEigEstimator_Power", + [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) -> std::shared_ptr> { - auto lambda_result = SUNDomEigEstimator_Power(q, max_iters, rel_tol, - sunctx); + auto SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr = [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) -> std::shared_ptr> + { + auto lambda_result = SUNDomEigEstimator_Power(q, max_iters, rel_tol, sunctx); - return our_make_shared, - SUNDomEigEstimatorDeleter>(lambda_result); - }; + return our_make_shared, SUNDomEigEstimatorDeleter>(lambda_result); + return lambda_result; + }; - return SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr(q, max_iters, - rel_tol, - sunctx); - }, - nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), - "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); + return SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr(q, max_iters, rel_tol, sunctx); + }, + nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), + "nb::keep_alive<0, 4>()", + nb::keep_alive<0, 4>()); -m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, - nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); +m.def("SUNDomEigEstimator_SetRHS_Power", + SUNDomEigEstimator_SetRHS_Power, nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); m.def("SUNDomEigEstimator_SetRHSLinearizationPoint_Power", - SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), - nb::arg("t"), nb::arg("v")); + SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), nb::arg("t"), nb::arg("v")); m.def("SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// From 111648553d9f19aab7036c56d4baddbb698a9873 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 19 Mar 2026 09:47:59 -0500 Subject: [PATCH 32/76] formatting --- .../arkode/arkode_arkstep_generated.hpp | 114 +- .../arkode/arkode_erkstep_generated.hpp | 103 +- .../arkode/arkode_forcingstep_generated.hpp | 41 +- .../sundials4py/arkode/arkode_generated.hpp | 2815 +++++++++-------- .../arkode/arkode_lsrkstep_generated.hpp | 197 +- .../arkode/arkode_mristep_generated.hpp | 395 ++- .../arkode/arkode_splittingstep_generated.hpp | 499 +-- .../arkode/arkode_sprkstep_generated.hpp | 48 +- .../sundomeigest_power_generated.hpp | 64 +- 9 files changed, 2385 insertions(+), 1891 deletions(-) diff --git a/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp index c914e5f159..cd2a1a4775 100644 --- a/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_arkstep_generated.hpp @@ -1,67 +1,85 @@ // #ifndef _ARKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ARKStepSetExplicit", - ARKStepSetExplicit, nb::arg("arkode_mem")); +m.def("ARKStepSetExplicit", ARKStepSetExplicit, nb::arg("arkode_mem")); -m.def("ARKStepSetImplicit", - ARKStepSetImplicit, nb::arg("arkode_mem")); +m.def("ARKStepSetImplicit", ARKStepSetImplicit, nb::arg("arkode_mem")); -m.def("ARKStepSetImEx", - ARKStepSetImEx, nb::arg("arkode_mem")); +m.def("ARKStepSetImEx", ARKStepSetImEx, nb::arg("arkode_mem")); -m.def("ARKStepSetTables", - ARKStepSetTables, nb::arg("arkode_mem"), nb::arg("q"), nb::arg("p"), nb::arg("Bi"), nb::arg("Be")); +m.def("ARKStepSetTables", ARKStepSetTables, nb::arg("arkode_mem"), nb::arg("q"), + nb::arg("p"), nb::arg("Bi"), nb::arg("Be")); -m.def("ARKStepSetTableNum", - ARKStepSetTableNum, nb::arg("arkode_mem"), nb::arg("itable"), nb::arg("etable")); +m.def("ARKStepSetTableNum", ARKStepSetTableNum, nb::arg("arkode_mem"), + nb::arg("itable"), nb::arg("etable")); -m.def("ARKStepSetTableName", - ARKStepSetTableName, nb::arg("arkode_mem"), nb::arg("itable"), nb::arg("etable")); +m.def("ARKStepSetTableName", ARKStepSetTableName, nb::arg("arkode_mem"), + nb::arg("itable"), nb::arg("etable")); -m.def("ARKStepGetCurrentButcherTables", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKStepGetCurrentButcherTables", + [](void* arkode_mem) -> std::tuple + { + auto ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - ARKodeButcherTable Bi_adapt_modifiable; - ARKodeButcherTable Be_adapt_modifiable; + ARKodeButcherTable Bi_adapt_modifiable; + ARKodeButcherTable Be_adapt_modifiable; - int r = ARKStepGetCurrentButcherTables(arkode_mem, &Bi_adapt_modifiable, &Be_adapt_modifiable); - return std::make_tuple(r, Bi_adapt_modifiable, Be_adapt_modifiable); - }; + int r = ARKStepGetCurrentButcherTables(arkode_mem, &Bi_adapt_modifiable, + &Be_adapt_modifiable); + return std::make_tuple(r, Bi_adapt_modifiable, Be_adapt_modifiable); + }; - return ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); + return ARKStepGetCurrentButcherTables_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); -m.def("ARKStepGetTimestepperStats", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKStepGetTimestepperStats", + [](void* arkode_mem) -> std::tuple + { + auto ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) + -> std::tuple { - auto ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long expsteps_adapt_modifiable; - long accsteps_adapt_modifiable; - long step_attempts_adapt_modifiable; - long nfe_evals_adapt_modifiable; - long nfi_evals_adapt_modifiable; - long nlinsetups_adapt_modifiable; - long netfails_adapt_modifiable; + long expsteps_adapt_modifiable; + long accsteps_adapt_modifiable; + long step_attempts_adapt_modifiable; + long nfe_evals_adapt_modifiable; + long nfi_evals_adapt_modifiable; + long nlinsetups_adapt_modifiable; + long netfails_adapt_modifiable; - int r = ARKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, &accsteps_adapt_modifiable, &step_attempts_adapt_modifiable, &nfe_evals_adapt_modifiable, &nfi_evals_adapt_modifiable, &nlinsetups_adapt_modifiable, &netfails_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable, accsteps_adapt_modifiable, step_attempts_adapt_modifiable, nfe_evals_adapt_modifiable, nfi_evals_adapt_modifiable, nlinsetups_adapt_modifiable, netfails_adapt_modifiable); - }; + int r = ARKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, + &accsteps_adapt_modifiable, + &step_attempts_adapt_modifiable, + &nfe_evals_adapt_modifiable, + &nfi_evals_adapt_modifiable, + &nlinsetups_adapt_modifiable, + &netfails_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable, + accsteps_adapt_modifiable, + step_attempts_adapt_modifiable, + nfe_evals_adapt_modifiable, + nfi_evals_adapt_modifiable, + nlinsetups_adapt_modifiable, + netfails_adapt_modifiable); + }; - return ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return ARKStepGetTimestepperStats_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp index e1ead7144f..019ac44004 100644 --- a/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_erkstep_generated.hpp @@ -1,57 +1,68 @@ // #ifndef _ERKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ERKStepSetTable", - ERKStepSetTable, nb::arg("arkode_mem"), nb::arg("B")); +m.def("ERKStepSetTable", ERKStepSetTable, nb::arg("arkode_mem"), nb::arg("B")); -m.def("ERKStepSetTableNum", - ERKStepSetTableNum, nb::arg("arkode_mem"), nb::arg("etable")); +m.def("ERKStepSetTableNum", ERKStepSetTableNum, nb::arg("arkode_mem"), + nb::arg("etable")); -m.def("ERKStepSetTableName", - ERKStepSetTableName, nb::arg("arkode_mem"), nb::arg("etable")); +m.def("ERKStepSetTableName", ERKStepSetTableName, nb::arg("arkode_mem"), + nb::arg("etable")); -m.def("ERKStepGetCurrentButcherTable", - [](void * arkode_mem) -> std::tuple +m.def( + "ERKStepGetCurrentButcherTable", + [](void* arkode_mem) -> std::tuple + { + auto ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - ARKodeButcherTable B_adapt_modifiable; - - int r = ERKStepGetCurrentButcherTable(arkode_mem, &B_adapt_modifiable); - return std::make_tuple(r, B_adapt_modifiable); - }; - - return ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def("ERKStepGetTimestepperStats", - [](void * arkode_mem) -> std::tuple + ARKodeButcherTable B_adapt_modifiable; + + int r = ERKStepGetCurrentButcherTable(arkode_mem, &B_adapt_modifiable); + return std::make_tuple(r, B_adapt_modifiable); + }; + + return ERKStepGetCurrentButcherTable_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def( + "ERKStepGetTimestepperStats", + [](void* arkode_mem) -> std::tuple + { + auto ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long expsteps_adapt_modifiable; - long accsteps_adapt_modifiable; - long step_attempts_adapt_modifiable; - long nfevals_adapt_modifiable; - long netfails_adapt_modifiable; - - int r = ERKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, &accsteps_adapt_modifiable, &step_attempts_adapt_modifiable, &nfevals_adapt_modifiable, &netfails_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable, accsteps_adapt_modifiable, step_attempts_adapt_modifiable, nfevals_adapt_modifiable, netfails_adapt_modifiable); - }; - - return ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - "Grouped optional output functions"); + long expsteps_adapt_modifiable; + long accsteps_adapt_modifiable; + long step_attempts_adapt_modifiable; + long nfevals_adapt_modifiable; + long netfails_adapt_modifiable; + + int r = ERKStepGetTimestepperStats(arkode_mem, &expsteps_adapt_modifiable, + &accsteps_adapt_modifiable, + &step_attempts_adapt_modifiable, + &nfevals_adapt_modifiable, + &netfails_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable, + accsteps_adapt_modifiable, + step_attempts_adapt_modifiable, + nfevals_adapt_modifiable, netfails_adapt_modifiable); + }; + + return ERKStepGetTimestepperStats_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), "Grouped optional output functions"); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp b/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp index ad7d27b2ea..ca5d33a7c3 100644 --- a/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_forcingstep_generated.hpp @@ -1,28 +1,33 @@ // #ifndef ARKODE_FORCINGINGSTEP_H_ -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("ForcingStepReInit", - ForcingStepReInit, nb::arg("arkode_mem"), nb::arg("stepper1"), nb::arg("stepper2"), nb::arg("t0"), nb::arg("y0")); +m.def("ForcingStepReInit", ForcingStepReInit, nb::arg("arkode_mem"), + nb::arg("stepper1"), nb::arg("stepper2"), nb::arg("t0"), nb::arg("y0")); -m.def("ForcingStepGetNumEvolves", - [](void * arkode_mem, int partition) -> std::tuple +m.def( + "ForcingStepGetNumEvolves", + [](void* arkode_mem, int partition) -> std::tuple + { + auto ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return = + [](void* arkode_mem, int partition) -> std::tuple { - auto ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition) -> std::tuple - { - long evolves_adapt_modifiable; + long evolves_adapt_modifiable; - int r = ForcingStepGetNumEvolves(arkode_mem, partition, &evolves_adapt_modifiable); - return std::make_tuple(r, evolves_adapt_modifiable); - }; + int r = ForcingStepGetNumEvolves(arkode_mem, partition, + &evolves_adapt_modifiable); + return std::make_tuple(r, evolves_adapt_modifiable); + }; - return ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, partition); - }, nb::arg("arkode_mem"), nb::arg("partition")); + return ForcingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, + partition); + }, + nb::arg("arkode_mem"), nb::arg("partition")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_generated.hpp b/bindings/sundials4py/arkode/arkode_generated.hpp index 321c4f855d..7295bbee06 100644 --- a/bindings/sundials4py/arkode/arkode_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_generated.hpp @@ -1,1508 +1,1783 @@ // #ifndef _ARKODE_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// -m.attr("ARK_NORMAL") = 1; -m.attr("ARK_ONE_STEP") = 2; -m.attr("ARK_ADAPT_CUSTOM") = -1; -m.attr("ARK_ADAPT_PID") = 0; -m.attr("ARK_ADAPT_PI") = 1; -m.attr("ARK_ADAPT_I") = 2; -m.attr("ARK_ADAPT_EXP_GUS") = 3; -m.attr("ARK_ADAPT_IMP_GUS") = 4; -m.attr("ARK_ADAPT_IMEX_GUS") = 5; -m.attr("ARK_FULLRHS_START") = 0; -m.attr("ARK_FULLRHS_END") = 1; -m.attr("ARK_FULLRHS_OTHER") = 2; -m.attr("ARK_INTERP_MAX_DEGREE") = 5; -m.attr("ARK_INTERP_NONE") = -1; -m.attr("ARK_INTERP_HERMITE") = 0; -m.attr("ARK_INTERP_LAGRANGE") = 1; -m.attr("ARK_SUCCESS") = 0; -m.attr("ARK_TSTOP_RETURN") = 1; -m.attr("ARK_ROOT_RETURN") = 2; -m.attr("ARK_WARNING") = 99; -m.attr("ARK_TOO_MUCH_WORK") = -1; -m.attr("ARK_TOO_MUCH_ACC") = -2; -m.attr("ARK_ERR_FAILURE") = -3; -m.attr("ARK_CONV_FAILURE") = -4; -m.attr("ARK_LINIT_FAIL") = -5; -m.attr("ARK_LSETUP_FAIL") = -6; -m.attr("ARK_LSOLVE_FAIL") = -7; -m.attr("ARK_RHSFUNC_FAIL") = -8; -m.attr("ARK_FIRST_RHSFUNC_ERR") = -9; -m.attr("ARK_REPTD_RHSFUNC_ERR") = -10; -m.attr("ARK_UNREC_RHSFUNC_ERR") = -11; -m.attr("ARK_RTFUNC_FAIL") = -12; -m.attr("ARK_LFREE_FAIL") = -13; -m.attr("ARK_MASSINIT_FAIL") = -14; -m.attr("ARK_MASSSETUP_FAIL") = -15; -m.attr("ARK_MASSSOLVE_FAIL") = -16; -m.attr("ARK_MASSFREE_FAIL") = -17; -m.attr("ARK_MASSMULT_FAIL") = -18; -m.attr("ARK_CONSTR_FAIL") = -19; -m.attr("ARK_MEM_FAIL") = -20; -m.attr("ARK_MEM_NULL") = -21; -m.attr("ARK_ILL_INPUT") = -22; -m.attr("ARK_NO_MALLOC") = -23; -m.attr("ARK_BAD_K") = -24; -m.attr("ARK_BAD_T") = -25; -m.attr("ARK_BAD_DKY") = -26; -m.attr("ARK_TOO_CLOSE") = -27; -m.attr("ARK_VECTOROP_ERR") = -28; -m.attr("ARK_NLS_INIT_FAIL") = -29; -m.attr("ARK_NLS_SETUP_FAIL") = -30; -m.attr("ARK_NLS_SETUP_RECVR") = -31; -m.attr("ARK_NLS_OP_ERR") = -32; -m.attr("ARK_INNERSTEP_ATTACH_ERR") = -33; -m.attr("ARK_INNERSTEP_FAIL") = -34; -m.attr("ARK_OUTERTOINNER_FAIL") = -35; -m.attr("ARK_INNERTOOUTER_FAIL") = -36; -m.attr("ARK_POSTPROCESS_FAIL") = -37; -m.attr("ARK_POSTPROCESS_STEP_FAIL") = -37; +// +m.attr("ARK_NORMAL") = 1; +m.attr("ARK_ONE_STEP") = 2; +m.attr("ARK_ADAPT_CUSTOM") = -1; +m.attr("ARK_ADAPT_PID") = 0; +m.attr("ARK_ADAPT_PI") = 1; +m.attr("ARK_ADAPT_I") = 2; +m.attr("ARK_ADAPT_EXP_GUS") = 3; +m.attr("ARK_ADAPT_IMP_GUS") = 4; +m.attr("ARK_ADAPT_IMEX_GUS") = 5; +m.attr("ARK_FULLRHS_START") = 0; +m.attr("ARK_FULLRHS_END") = 1; +m.attr("ARK_FULLRHS_OTHER") = 2; +m.attr("ARK_INTERP_MAX_DEGREE") = 5; +m.attr("ARK_INTERP_NONE") = -1; +m.attr("ARK_INTERP_HERMITE") = 0; +m.attr("ARK_INTERP_LAGRANGE") = 1; +m.attr("ARK_SUCCESS") = 0; +m.attr("ARK_TSTOP_RETURN") = 1; +m.attr("ARK_ROOT_RETURN") = 2; +m.attr("ARK_WARNING") = 99; +m.attr("ARK_TOO_MUCH_WORK") = -1; +m.attr("ARK_TOO_MUCH_ACC") = -2; +m.attr("ARK_ERR_FAILURE") = -3; +m.attr("ARK_CONV_FAILURE") = -4; +m.attr("ARK_LINIT_FAIL") = -5; +m.attr("ARK_LSETUP_FAIL") = -6; +m.attr("ARK_LSOLVE_FAIL") = -7; +m.attr("ARK_RHSFUNC_FAIL") = -8; +m.attr("ARK_FIRST_RHSFUNC_ERR") = -9; +m.attr("ARK_REPTD_RHSFUNC_ERR") = -10; +m.attr("ARK_UNREC_RHSFUNC_ERR") = -11; +m.attr("ARK_RTFUNC_FAIL") = -12; +m.attr("ARK_LFREE_FAIL") = -13; +m.attr("ARK_MASSINIT_FAIL") = -14; +m.attr("ARK_MASSSETUP_FAIL") = -15; +m.attr("ARK_MASSSOLVE_FAIL") = -16; +m.attr("ARK_MASSFREE_FAIL") = -17; +m.attr("ARK_MASSMULT_FAIL") = -18; +m.attr("ARK_CONSTR_FAIL") = -19; +m.attr("ARK_MEM_FAIL") = -20; +m.attr("ARK_MEM_NULL") = -21; +m.attr("ARK_ILL_INPUT") = -22; +m.attr("ARK_NO_MALLOC") = -23; +m.attr("ARK_BAD_K") = -24; +m.attr("ARK_BAD_T") = -25; +m.attr("ARK_BAD_DKY") = -26; +m.attr("ARK_TOO_CLOSE") = -27; +m.attr("ARK_VECTOROP_ERR") = -28; +m.attr("ARK_NLS_INIT_FAIL") = -29; +m.attr("ARK_NLS_SETUP_FAIL") = -30; +m.attr("ARK_NLS_SETUP_RECVR") = -31; +m.attr("ARK_NLS_OP_ERR") = -32; +m.attr("ARK_INNERSTEP_ATTACH_ERR") = -33; +m.attr("ARK_INNERSTEP_FAIL") = -34; +m.attr("ARK_OUTERTOINNER_FAIL") = -35; +m.attr("ARK_INNERTOOUTER_FAIL") = -36; +m.attr("ARK_POSTPROCESS_FAIL") = -37; +m.attr("ARK_POSTPROCESS_STEP_FAIL") = -37; m.attr("ARK_POSTPROCESS_STAGE_FAIL") = -38; -m.attr("ARK_USER_PREDICT_FAIL") = -39; -m.attr("ARK_INTERP_FAIL") = -40; -m.attr("ARK_INVALID_TABLE") = -41; -m.attr("ARK_CONTEXT_ERR") = -42; -m.attr("ARK_RELAX_FAIL") = -43; -m.attr("ARK_RELAX_MEM_NULL") = -44; -m.attr("ARK_RELAX_FUNC_FAIL") = -45; -m.attr("ARK_RELAX_JAC_FAIL") = -46; -m.attr("ARK_CONTROLLER_ERR") = -47; -m.attr("ARK_STEPPER_UNSUPPORTED") = -48; -m.attr("ARK_DOMEIG_FAIL") = -49; -m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -50; -m.attr("ARK_SUNSTEPPER_ERR") = -51; -m.attr("ARK_STEP_DIRECTION_ERR") = -52; -m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -53; -m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -54; -m.attr("ARK_SUNADJSTEPPER_ERR") = -55; -m.attr("ARK_DEE_FAIL") = -56; -m.attr("ARK_UNRECOGNIZED_ERROR") = -99; - - -auto pyEnumARKRelaxSolver = - nb::enum_(m, "ARKRelaxSolver", nb::is_arithmetic(), "") - .value("ARK_RELAX_BRENT", ARK_RELAX_BRENT, "") - .value("ARK_RELAX_NEWTON", ARK_RELAX_NEWTON, "") - .export_values(); +m.attr("ARK_USER_PREDICT_FAIL") = -39; +m.attr("ARK_INTERP_FAIL") = -40; +m.attr("ARK_INVALID_TABLE") = -41; +m.attr("ARK_CONTEXT_ERR") = -42; +m.attr("ARK_RELAX_FAIL") = -43; +m.attr("ARK_RELAX_MEM_NULL") = -44; +m.attr("ARK_RELAX_FUNC_FAIL") = -45; +m.attr("ARK_RELAX_JAC_FAIL") = -46; +m.attr("ARK_CONTROLLER_ERR") = -47; +m.attr("ARK_STEPPER_UNSUPPORTED") = -48; +m.attr("ARK_DOMEIG_FAIL") = -49; +m.attr("ARK_MAX_STAGE_LIMIT_FAIL") = -50; +m.attr("ARK_SUNSTEPPER_ERR") = -51; +m.attr("ARK_STEP_DIRECTION_ERR") = -52; +m.attr("ARK_ADJ_CHECKPOINT_FAIL") = -53; +m.attr("ARK_ADJ_RECOMPUTE_FAIL") = -54; +m.attr("ARK_SUNADJSTEPPER_ERR") = -55; +m.attr("ARK_DEE_FAIL") = -56; +m.attr("ARK_UNRECOGNIZED_ERROR") = -99; + +auto pyEnumARKRelaxSolver = nb::enum_(m, "ARKRelaxSolver", + nb::is_arithmetic(), "") + .value("ARK_RELAX_BRENT", ARK_RELAX_BRENT, "") + .value("ARK_RELAX_NEWTON", ARK_RELAX_NEWTON, "") + .export_values(); // #ifndef SWIG -// +// // #endif -// - +// auto pyEnumARKAccumError = - nb::enum_(m, "ARKAccumError", nb::is_arithmetic(), "") - .value("ARK_ACCUMERROR_NONE", ARK_ACCUMERROR_NONE, "") - .value("ARK_ACCUMERROR_MAX", ARK_ACCUMERROR_MAX, "") - .value("ARK_ACCUMERROR_SUM", ARK_ACCUMERROR_SUM, "") - .value("ARK_ACCUMERROR_AVG", ARK_ACCUMERROR_AVG, "") + nb::enum_(m, "ARKAccumError", nb::is_arithmetic(), "") + .value("ARK_ACCUMERROR_NONE", ARK_ACCUMERROR_NONE, "") + .value("ARK_ACCUMERROR_MAX", ARK_ACCUMERROR_MAX, "") + .value("ARK_ACCUMERROR_SUM", ARK_ACCUMERROR_SUM, "") + .value("ARK_ACCUMERROR_AVG", ARK_ACCUMERROR_AVG, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def("ARKodeReset", - ARKodeReset, nb::arg("arkode_mem"), nb::arg("tR"), nb::arg("yR")); - -m.def("ARKodeCreateMRIStepInnerStepper", - [](void * arkode_mem) -> std::tuple>> +// + +m.def("ARKodeReset", ARKodeReset, nb::arg("arkode_mem"), nb::arg("tR"), + nb::arg("yR")); + +m.def( + "ARKodeCreateMRIStepInnerStepper", + [](void* arkode_mem) + -> std::tuple>> + { + auto ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - MRIStepInnerStepper stepper_adapt_modifiable; - - int r = ARKodeCreateMRIStepInnerStepper(arkode_mem, &stepper_adapt_modifiable); - return std::make_tuple(r, stepper_adapt_modifiable); - }; - auto ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr = [&ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return](void * arkode_mem) -> std::tuple>> - { - auto lambda_result = ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return(arkode_mem); - - return std::make_tuple(std::get<0>(lambda_result), our_make_shared, MRIStepInnerStepperDeleter>(std::get<1>(lambda_result))); - return lambda_result; - }; - - return ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr(arkode_mem); - }, - nb::arg("arkode_mem"), - "Utility to wrap ARKODE as an MRIStepInnerStepper", - nb::rv_policy::reference); - -m.def("ARKodeSStolerances", - ARKodeSStolerances, nb::arg("arkode_mem"), nb::arg("reltol"), nb::arg("abstol")); - -m.def("ARKodeSVtolerances", - ARKodeSVtolerances, nb::arg("arkode_mem"), nb::arg("reltol"), nb::arg("abstol")); - -m.def("ARKodeResStolerance", - ARKodeResStolerance, nb::arg("arkode_mem"), nb::arg("rabstol")); - -m.def("ARKodeResVtolerance", - ARKodeResVtolerance, nb::arg("arkode_mem"), nb::arg("rabstol")); - -m.def("ARKodeSetRootDirection", - [](void * arkode_mem, std::vector rootdir_1d) -> int + MRIStepInnerStepper stepper_adapt_modifiable; + + int r = ARKodeCreateMRIStepInnerStepper(arkode_mem, + &stepper_adapt_modifiable); + return std::make_tuple(r, stepper_adapt_modifiable); + }; + auto ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr = + [&ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return]( + void* arkode_mem) + -> std::tuple>> + { + auto lambda_result = + ARKodeCreateMRIStepInnerStepper_adapt_modifiable_immutable_to_return( + arkode_mem); + + return std::make_tuple(std::get<0>(lambda_result), + our_make_shared, + MRIStepInnerStepperDeleter>( + std::get<1>(lambda_result))); + return lambda_result; + }; + + return ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr( + arkode_mem); + }, + nb::arg("arkode_mem"), "Utility to wrap ARKODE as an MRIStepInnerStepper", + nb::rv_policy::reference); + +m.def("ARKodeSStolerances", ARKodeSStolerances, nb::arg("arkode_mem"), + nb::arg("reltol"), nb::arg("abstol")); + +m.def("ARKodeSVtolerances", ARKodeSVtolerances, nb::arg("arkode_mem"), + nb::arg("reltol"), nb::arg("abstol")); + +m.def("ARKodeResStolerance", ARKodeResStolerance, nb::arg("arkode_mem"), + nb::arg("rabstol")); + +m.def("ARKodeResVtolerance", ARKodeResVtolerance, nb::arg("arkode_mem"), + nb::arg("rabstol")); + +m.def( + "ARKodeSetRootDirection", + [](void* arkode_mem, std::vector rootdir_1d) -> int + { + auto ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector = + [](void* arkode_mem, std::vector rootdir_1d) -> int { - auto ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector = [](void * arkode_mem, std::vector rootdir_1d) -> int - { - int* rootdir_1d_ptr = rootdir_1d.empty() ? nullptr : rootdir_1d.data(); + int* rootdir_1d_ptr = rootdir_1d.empty() ? nullptr : rootdir_1d.data(); - auto lambda_result = ARKodeSetRootDirection(arkode_mem, rootdir_1d_ptr); - return lambda_result; - }; + auto lambda_result = ARKodeSetRootDirection(arkode_mem, rootdir_1d_ptr); + return lambda_result; + }; - return ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector(arkode_mem, rootdir_1d); - }, nb::arg("arkode_mem"), nb::arg("rootdir_1d")); + return ARKodeSetRootDirection_adapt_arr_ptr_to_std_vector(arkode_mem, + rootdir_1d); + }, + nb::arg("arkode_mem"), nb::arg("rootdir_1d")); -m.def("ARKodeSetNoInactiveRootWarn", - ARKodeSetNoInactiveRootWarn, nb::arg("arkode_mem")); +m.def("ARKodeSetNoInactiveRootWarn", ARKodeSetNoInactiveRootWarn, + nb::arg("arkode_mem")); -m.def("ARKodeSetDefaults", - ARKodeSetDefaults, nb::arg("arkode_mem")); +m.def("ARKodeSetDefaults", ARKodeSetDefaults, nb::arg("arkode_mem")); -m.def("ARKodeSetOrder", - ARKodeSetOrder, nb::arg("arkode_mem"), nb::arg("maxord")); +m.def("ARKodeSetOrder", ARKodeSetOrder, nb::arg("arkode_mem"), nb::arg("maxord")); -m.def("ARKodeSetInterpolantType", - ARKodeSetInterpolantType, nb::arg("arkode_mem"), nb::arg("itype")); +m.def("ARKodeSetInterpolantType", ARKodeSetInterpolantType, + nb::arg("arkode_mem"), nb::arg("itype")); -m.def("ARKodeSetInterpolantDegree", - ARKodeSetInterpolantDegree, nb::arg("arkode_mem"), nb::arg("degree")); +m.def("ARKodeSetInterpolantDegree", ARKodeSetInterpolantDegree, + nb::arg("arkode_mem"), nb::arg("degree")); -m.def("ARKodeSetMaxNumSteps", - ARKodeSetMaxNumSteps, nb::arg("arkode_mem"), nb::arg("mxsteps")); +m.def("ARKodeSetMaxNumSteps", ARKodeSetMaxNumSteps, nb::arg("arkode_mem"), + nb::arg("mxsteps")); -m.def("ARKodeSetInterpolateStopTime", - ARKodeSetInterpolateStopTime, nb::arg("arkode_mem"), nb::arg("interp")); +m.def("ARKodeSetInterpolateStopTime", ARKodeSetInterpolateStopTime, + nb::arg("arkode_mem"), nb::arg("interp")); -m.def("ARKodeSetStopTime", - ARKodeSetStopTime, nb::arg("arkode_mem"), nb::arg("tstop")); +m.def("ARKodeSetStopTime", ARKodeSetStopTime, nb::arg("arkode_mem"), + nb::arg("tstop")); -m.def("ARKodeClearStopTime", - ARKodeClearStopTime, nb::arg("arkode_mem")); +m.def("ARKodeClearStopTime", ARKodeClearStopTime, nb::arg("arkode_mem")); -m.def("ARKodeSetFixedStep", - ARKodeSetFixedStep, nb::arg("arkode_mem"), nb::arg("hfixed")); +m.def("ARKodeSetFixedStep", ARKodeSetFixedStep, nb::arg("arkode_mem"), + nb::arg("hfixed")); -m.def("ARKodeSetStepDirection", - ARKodeSetStepDirection, nb::arg("arkode_mem"), nb::arg("stepdir")); +m.def("ARKodeSetStepDirection", ARKodeSetStepDirection, nb::arg("arkode_mem"), + nb::arg("stepdir")); -m.def("ARKodeSetNonlinearSolver", - ARKodeSetNonlinearSolver, nb::arg("arkode_mem"), nb::arg("NLS")); +m.def("ARKodeSetNonlinearSolver", ARKodeSetNonlinearSolver, + nb::arg("arkode_mem"), nb::arg("NLS")); -m.def("ARKodeSetLinear", - ARKodeSetLinear, nb::arg("arkode_mem"), nb::arg("timedepend")); +m.def("ARKodeSetLinear", ARKodeSetLinear, nb::arg("arkode_mem"), + nb::arg("timedepend")); -m.def("ARKodeSetNonlinear", - ARKodeSetNonlinear, nb::arg("arkode_mem")); +m.def("ARKodeSetNonlinear", ARKodeSetNonlinear, nb::arg("arkode_mem")); -m.def("ARKodeSetAutonomous", - ARKodeSetAutonomous, nb::arg("arkode_mem"), nb::arg("autonomous")); +m.def("ARKodeSetAutonomous", ARKodeSetAutonomous, nb::arg("arkode_mem"), + nb::arg("autonomous")); -m.def("ARKodeSetDeduceImplicitRhs", - ARKodeSetDeduceImplicitRhs, nb::arg("arkode_mem"), nb::arg("deduce")); +m.def("ARKodeSetDeduceImplicitRhs", ARKodeSetDeduceImplicitRhs, + nb::arg("arkode_mem"), nb::arg("deduce")); -m.def("ARKodeSetNonlinCRDown", - ARKodeSetNonlinCRDown, nb::arg("arkode_mem"), nb::arg("crdown")); +m.def("ARKodeSetNonlinCRDown", ARKodeSetNonlinCRDown, nb::arg("arkode_mem"), + nb::arg("crdown")); -m.def("ARKodeSetNonlinRDiv", - ARKodeSetNonlinRDiv, nb::arg("arkode_mem"), nb::arg("rdiv")); +m.def("ARKodeSetNonlinRDiv", ARKodeSetNonlinRDiv, nb::arg("arkode_mem"), + nb::arg("rdiv")); -m.def("ARKodeSetDeltaGammaMax", - ARKodeSetDeltaGammaMax, nb::arg("arkode_mem"), nb::arg("dgmax")); +m.def("ARKodeSetDeltaGammaMax", ARKodeSetDeltaGammaMax, nb::arg("arkode_mem"), + nb::arg("dgmax")); -m.def("ARKodeSetLSetupFrequency", - ARKodeSetLSetupFrequency, nb::arg("arkode_mem"), nb::arg("msbp")); +m.def("ARKodeSetLSetupFrequency", ARKodeSetLSetupFrequency, + nb::arg("arkode_mem"), nb::arg("msbp")); -m.def("ARKodeSetPredictorMethod", - ARKodeSetPredictorMethod, nb::arg("arkode_mem"), nb::arg("method")); +m.def("ARKodeSetPredictorMethod", ARKodeSetPredictorMethod, + nb::arg("arkode_mem"), nb::arg("method")); -m.def("ARKodeSetMaxNonlinIters", - ARKodeSetMaxNonlinIters, nb::arg("arkode_mem"), nb::arg("maxcor")); +m.def("ARKodeSetMaxNonlinIters", ARKodeSetMaxNonlinIters, nb::arg("arkode_mem"), + nb::arg("maxcor")); -m.def("ARKodeSetMaxConvFails", - ARKodeSetMaxConvFails, nb::arg("arkode_mem"), nb::arg("maxncf")); +m.def("ARKodeSetMaxConvFails", ARKodeSetMaxConvFails, nb::arg("arkode_mem"), + nb::arg("maxncf")); -m.def("ARKodeSetNonlinConvCoef", - ARKodeSetNonlinConvCoef, nb::arg("arkode_mem"), nb::arg("nlscoef")); +m.def("ARKodeSetNonlinConvCoef", ARKodeSetNonlinConvCoef, nb::arg("arkode_mem"), + nb::arg("nlscoef")); -m.def("ARKodeSetAdaptController", - ARKodeSetAdaptController, nb::arg("arkode_mem"), nb::arg("C")); +m.def("ARKodeSetAdaptController", ARKodeSetAdaptController, + nb::arg("arkode_mem"), nb::arg("C")); -m.def("ARKodeSetAdaptControllerByName", - ARKodeSetAdaptControllerByName, nb::arg("arkode_mem"), nb::arg("cname")); +m.def("ARKodeSetAdaptControllerByName", ARKodeSetAdaptControllerByName, + nb::arg("arkode_mem"), nb::arg("cname")); -m.def("ARKodeSetAdaptivityAdjustment", - ARKodeSetAdaptivityAdjustment, nb::arg("arkode_mem"), nb::arg("adjust")); +m.def("ARKodeSetAdaptivityAdjustment", ARKodeSetAdaptivityAdjustment, + nb::arg("arkode_mem"), nb::arg("adjust")); -m.def("ARKodeSetCFLFraction", - ARKodeSetCFLFraction, nb::arg("arkode_mem"), nb::arg("cfl_frac")); +m.def("ARKodeSetCFLFraction", ARKodeSetCFLFraction, nb::arg("arkode_mem"), + nb::arg("cfl_frac")); -m.def("ARKodeSetErrorBias", - ARKodeSetErrorBias, nb::arg("arkode_mem"), nb::arg("bias")); +m.def("ARKodeSetErrorBias", ARKodeSetErrorBias, nb::arg("arkode_mem"), + nb::arg("bias")); -m.def("ARKodeSetSafetyFactor", - ARKodeSetSafetyFactor, nb::arg("arkode_mem"), nb::arg("safety")); +m.def("ARKodeSetSafetyFactor", ARKodeSetSafetyFactor, nb::arg("arkode_mem"), + nb::arg("safety")); -m.def("ARKodeSetMaxGrowth", - ARKodeSetMaxGrowth, nb::arg("arkode_mem"), nb::arg("mx_growth")); +m.def("ARKodeSetMaxGrowth", ARKodeSetMaxGrowth, nb::arg("arkode_mem"), + nb::arg("mx_growth")); -m.def("ARKodeSetMinReduction", - ARKodeSetMinReduction, nb::arg("arkode_mem"), nb::arg("eta_min")); +m.def("ARKodeSetMinReduction", ARKodeSetMinReduction, nb::arg("arkode_mem"), + nb::arg("eta_min")); -m.def("ARKodeSetFixedStepBounds", - ARKodeSetFixedStepBounds, nb::arg("arkode_mem"), nb::arg("lb"), nb::arg("ub")); +m.def("ARKodeSetFixedStepBounds", ARKodeSetFixedStepBounds, + nb::arg("arkode_mem"), nb::arg("lb"), nb::arg("ub")); -m.def("ARKodeSetMaxFirstGrowth", - ARKodeSetMaxFirstGrowth, nb::arg("arkode_mem"), nb::arg("etamx1")); +m.def("ARKodeSetMaxFirstGrowth", ARKodeSetMaxFirstGrowth, nb::arg("arkode_mem"), + nb::arg("etamx1")); -m.def("ARKodeSetMaxEFailGrowth", - ARKodeSetMaxEFailGrowth, nb::arg("arkode_mem"), nb::arg("etamxf")); +m.def("ARKodeSetMaxEFailGrowth", ARKodeSetMaxEFailGrowth, nb::arg("arkode_mem"), + nb::arg("etamxf")); -m.def("ARKodeSetSmallNumEFails", - ARKodeSetSmallNumEFails, nb::arg("arkode_mem"), nb::arg("small_nef")); +m.def("ARKodeSetSmallNumEFails", ARKodeSetSmallNumEFails, nb::arg("arkode_mem"), + nb::arg("small_nef")); -m.def("ARKodeSetMaxCFailGrowth", - ARKodeSetMaxCFailGrowth, nb::arg("arkode_mem"), nb::arg("etacf")); +m.def("ARKodeSetMaxCFailGrowth", ARKodeSetMaxCFailGrowth, nb::arg("arkode_mem"), + nb::arg("etacf")); -m.def("ARKodeSetMaxErrTestFails", - ARKodeSetMaxErrTestFails, nb::arg("arkode_mem"), nb::arg("maxnef")); +m.def("ARKodeSetMaxErrTestFails", ARKodeSetMaxErrTestFails, + nb::arg("arkode_mem"), nb::arg("maxnef")); -m.def("ARKodeSetConstraints", - ARKodeSetConstraints, nb::arg("arkode_mem"), nb::arg("constraints")); +m.def("ARKodeSetConstraints", ARKodeSetConstraints, nb::arg("arkode_mem"), + nb::arg("constraints")); -m.def("ARKodeSetMaxHnilWarns", - ARKodeSetMaxHnilWarns, nb::arg("arkode_mem"), nb::arg("mxhnil")); +m.def("ARKodeSetMaxHnilWarns", ARKodeSetMaxHnilWarns, nb::arg("arkode_mem"), + nb::arg("mxhnil")); -m.def("ARKodeSetInitStep", - ARKodeSetInitStep, nb::arg("arkode_mem"), nb::arg("hin")); +m.def("ARKodeSetInitStep", ARKodeSetInitStep, nb::arg("arkode_mem"), + nb::arg("hin")); -m.def("ARKodeSetMinStep", - ARKodeSetMinStep, nb::arg("arkode_mem"), nb::arg("hmin")); +m.def("ARKodeSetMinStep", ARKodeSetMinStep, nb::arg("arkode_mem"), + nb::arg("hmin")); -m.def("ARKodeSetMaxStep", - ARKodeSetMaxStep, nb::arg("arkode_mem"), nb::arg("hmax")); +m.def("ARKodeSetMaxStep", ARKodeSetMaxStep, nb::arg("arkode_mem"), + nb::arg("hmax")); -m.def("ARKodeSetMaxNumConstrFails", - ARKodeSetMaxNumConstrFails, nb::arg("arkode_mem"), nb::arg("maxfails")); +m.def("ARKodeSetMaxNumConstrFails", ARKodeSetMaxNumConstrFails, + nb::arg("arkode_mem"), nb::arg("maxfails")); -m.def("ARKodeSetAdjointCheckpointScheme", - ARKodeSetAdjointCheckpointScheme, nb::arg("arkode_mem"), nb::arg("checkpoint_scheme")); +m.def("ARKodeSetAdjointCheckpointScheme", ARKodeSetAdjointCheckpointScheme, + nb::arg("arkode_mem"), nb::arg("checkpoint_scheme")); -m.def("ARKodeSetAdjointCheckpointIndex", - ARKodeSetAdjointCheckpointIndex, nb::arg("arkode_mem"), nb::arg("step_index")); +m.def("ARKodeSetAdjointCheckpointIndex", ARKodeSetAdjointCheckpointIndex, + nb::arg("arkode_mem"), nb::arg("step_index")); -m.def("ARKodeSetUseCompensatedSums", - ARKodeSetUseCompensatedSums, nb::arg("arkode_mem"), nb::arg("onoff")); +m.def("ARKodeSetUseCompensatedSums", ARKodeSetUseCompensatedSums, + nb::arg("arkode_mem"), nb::arg("onoff")); -m.def("ARKodeSetAccumulatedErrorType", - ARKodeSetAccumulatedErrorType, nb::arg("arkode_mem"), nb::arg("accum_type")); +m.def("ARKodeSetAccumulatedErrorType", ARKodeSetAccumulatedErrorType, + nb::arg("arkode_mem"), nb::arg("accum_type")); -m.def("ARKodeResetAccumulatedError", - ARKodeResetAccumulatedError, nb::arg("arkode_mem")); +m.def("ARKodeResetAccumulatedError", ARKodeResetAccumulatedError, + nb::arg("arkode_mem")); -m.def("ARKodeEvolve", - ARKodeEvolve, - nb::arg("arkode_mem"), nb::arg("tout"), nb::arg("yout"), nb::arg("tret"), nb::arg("itask"), - "Integrate the ODE over an interval in t"); +m.def("ARKodeEvolve", ARKodeEvolve, nb::arg("arkode_mem"), nb::arg("tout"), + nb::arg("yout"), nb::arg("tret"), nb::arg("itask"), + "Integrate the ODE over an interval in t"); -m.def("ARKodeGetDky", - ARKodeGetDky, - nb::arg("arkode_mem"), nb::arg("t"), nb::arg("k"), nb::arg("dky"), - "Computes the kth derivative of the y function at time t"); +m.def("ARKodeGetDky", ARKodeGetDky, nb::arg("arkode_mem"), nb::arg("t"), + nb::arg("k"), nb::arg("dky"), + "Computes the kth derivative of the y function at time t"); -m.def("ARKodeComputeState", - ARKodeComputeState, - nb::arg("arkode_mem"), nb::arg("zcor"), nb::arg("z"), - "Utility function to update/compute y based on zcor"); +m.def("ARKodeComputeState", ARKodeComputeState, nb::arg("arkode_mem"), + nb::arg("zcor"), nb::arg("z"), + "Utility function to update/compute y based on zcor"); -m.def("ARKodeGetNumRhsEvals", - [](void * arkode_mem, int partition_index) -> std::tuple +m.def( + "ARKodeGetNumRhsEvals", + [](void* arkode_mem, int partition_index) -> std::tuple + { + auto ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem, int partition_index) -> std::tuple { - auto ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition_index) -> std::tuple - { - long num_rhs_evals_adapt_modifiable; - - int r = ARKodeGetNumRhsEvals(arkode_mem, partition_index, &num_rhs_evals_adapt_modifiable); - return std::make_tuple(r, num_rhs_evals_adapt_modifiable); - }; - - return ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem, partition_index); - }, nb::arg("arkode_mem"), nb::arg("partition_index")); - -m.def("ARKodeGetNumStepAttempts", - [](void * arkode_mem) -> std::tuple + long num_rhs_evals_adapt_modifiable; + + int r = ARKodeGetNumRhsEvals(arkode_mem, partition_index, + &num_rhs_evals_adapt_modifiable); + return std::make_tuple(r, num_rhs_evals_adapt_modifiable); + }; + + return ARKodeGetNumRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem, + partition_index); + }, + nb::arg("arkode_mem"), nb::arg("partition_index")); + +m.def( + "ARKodeGetNumStepAttempts", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long step_attempts_adapt_modifiable; - - int r = ARKodeGetNumStepAttempts(arkode_mem, &step_attempts_adapt_modifiable); - return std::make_tuple(r, step_attempts_adapt_modifiable); - }; - - return ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumSteps", - [](void * arkode_mem) -> std::tuple + long step_attempts_adapt_modifiable; + + int r = ARKodeGetNumStepAttempts(arkode_mem, + &step_attempts_adapt_modifiable); + return std::make_tuple(r, step_attempts_adapt_modifiable); + }; + + return ARKodeGetNumStepAttempts_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumSteps", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumSteps_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nsteps_adapt_modifiable; + long nsteps_adapt_modifiable; - int r = ARKodeGetNumSteps(arkode_mem, &nsteps_adapt_modifiable); - return std::make_tuple(r, nsteps_adapt_modifiable); - }; + int r = ARKodeGetNumSteps(arkode_mem, &nsteps_adapt_modifiable); + return std::make_tuple(r, nsteps_adapt_modifiable); + }; - return ARKodeGetNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return ARKodeGetNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); -m.def("ARKodeGetLastStep", - ARKodeGetLastStep, nb::arg("arkode_mem"), nb::arg("hlast")); +m.def("ARKodeGetLastStep", ARKodeGetLastStep, nb::arg("arkode_mem"), + nb::arg("hlast")); -m.def("ARKodeGetCurrentStep", - ARKodeGetCurrentStep, nb::arg("arkode_mem"), nb::arg("hcur")); +m.def("ARKodeGetCurrentStep", ARKodeGetCurrentStep, nb::arg("arkode_mem"), + nb::arg("hcur")); -m.def("ARKodeGetStepDirection", - ARKodeGetStepDirection, nb::arg("arkode_mem"), nb::arg("stepdir")); +m.def("ARKodeGetStepDirection", ARKodeGetStepDirection, nb::arg("arkode_mem"), + nb::arg("stepdir")); -m.def("ARKodeGetErrWeights", - ARKodeGetErrWeights, nb::arg("arkode_mem"), nb::arg("eweight")); +m.def("ARKodeGetErrWeights", ARKodeGetErrWeights, nb::arg("arkode_mem"), + nb::arg("eweight")); -m.def("ARKodeGetNumGEvals", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetNumGEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long ngevals_adapt_modifiable; - - int r = ARKodeGetNumGEvals(arkode_mem, &ngevals_adapt_modifiable); - return std::make_tuple(r, ngevals_adapt_modifiable); - }; - - return ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetRootInfo", - [](void * arkode_mem, std::vector rootsfound_1d) -> int + long ngevals_adapt_modifiable; + + int r = ARKodeGetNumGEvals(arkode_mem, &ngevals_adapt_modifiable); + return std::make_tuple(r, ngevals_adapt_modifiable); + }; + + return ARKodeGetNumGEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetRootInfo", + [](void* arkode_mem, std::vector rootsfound_1d) -> int + { + auto ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector = + [](void* arkode_mem, std::vector rootsfound_1d) -> int { - auto ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector = [](void * arkode_mem, std::vector rootsfound_1d) -> int - { - int* rootsfound_1d_ptr = rootsfound_1d.empty() ? nullptr : rootsfound_1d.data(); + int* rootsfound_1d_ptr = rootsfound_1d.empty() ? nullptr + : rootsfound_1d.data(); - auto lambda_result = ARKodeGetRootInfo(arkode_mem, rootsfound_1d_ptr); - return lambda_result; - }; + auto lambda_result = ARKodeGetRootInfo(arkode_mem, rootsfound_1d_ptr); + return lambda_result; + }; - return ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector(arkode_mem, rootsfound_1d); - }, nb::arg("arkode_mem"), nb::arg("rootsfound_1d")); + return ARKodeGetRootInfo_adapt_arr_ptr_to_std_vector(arkode_mem, + rootsfound_1d); + }, + nb::arg("arkode_mem"), nb::arg("rootsfound_1d")); -m.def("ARKodePrintAllStats", - ARKodePrintAllStats, nb::arg("arkode_mem"), nb::arg("outfile"), nb::arg("fmt")); +m.def("ARKodePrintAllStats", ARKodePrintAllStats, nb::arg("arkode_mem"), + nb::arg("outfile"), nb::arg("fmt")); -m.def("ARKodeGetReturnFlagName", - ARKodeGetReturnFlagName, nb::arg("flag")); +m.def("ARKodeGetReturnFlagName", ARKodeGetReturnFlagName, nb::arg("flag")); -m.def("ARKodeWriteParameters", - ARKodeWriteParameters, nb::arg("arkode_mem"), nb::arg("fp")); +m.def("ARKodeWriteParameters", ARKodeWriteParameters, nb::arg("arkode_mem"), + nb::arg("fp")); -m.def("ARKodeGetNumExpSteps", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetNumExpSteps", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long expsteps_adapt_modifiable; - - int r = ARKodeGetNumExpSteps(arkode_mem, &expsteps_adapt_modifiable); - return std::make_tuple(r, expsteps_adapt_modifiable); - }; - - return ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumAccSteps", - [](void * arkode_mem) -> std::tuple + long expsteps_adapt_modifiable; + + int r = ARKodeGetNumExpSteps(arkode_mem, &expsteps_adapt_modifiable); + return std::make_tuple(r, expsteps_adapt_modifiable); + }; + + return ARKodeGetNumExpSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumAccSteps", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long accsteps_adapt_modifiable; - - int r = ARKodeGetNumAccSteps(arkode_mem, &accsteps_adapt_modifiable); - return std::make_tuple(r, accsteps_adapt_modifiable); - }; - - return ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumErrTestFails", - [](void * arkode_mem) -> std::tuple + long accsteps_adapt_modifiable; + + int r = ARKodeGetNumAccSteps(arkode_mem, &accsteps_adapt_modifiable); + return std::make_tuple(r, accsteps_adapt_modifiable); + }; + + return ARKodeGetNumAccSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumErrTestFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long netfails_adapt_modifiable; + long netfails_adapt_modifiable; - int r = ARKodeGetNumErrTestFails(arkode_mem, &netfails_adapt_modifiable); - return std::make_tuple(r, netfails_adapt_modifiable); - }; + int r = ARKodeGetNumErrTestFails(arkode_mem, &netfails_adapt_modifiable); + return std::make_tuple(r, netfails_adapt_modifiable); + }; - return ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return ARKodeGetNumErrTestFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); -m.def("ARKodeGetEstLocalErrors", - ARKodeGetEstLocalErrors, nb::arg("arkode_mem"), nb::arg("ele")); +m.def("ARKodeGetEstLocalErrors", ARKodeGetEstLocalErrors, nb::arg("arkode_mem"), + nb::arg("ele")); -m.def("ARKodeGetActualInitStep", - ARKodeGetActualInitStep, nb::arg("arkode_mem"), nb::arg("hinused")); +m.def("ARKodeGetActualInitStep", ARKodeGetActualInitStep, nb::arg("arkode_mem"), + nb::arg("hinused")); -m.def("ARKodeGetTolScaleFactor", - ARKodeGetTolScaleFactor, nb::arg("arkode_mem"), nb::arg("tolsfac")); +m.def("ARKodeGetTolScaleFactor", ARKodeGetTolScaleFactor, nb::arg("arkode_mem"), + nb::arg("tolsfac")); -m.def("ARKodeGetNumConstrFails", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetNumConstrFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nconstrfails_adapt_modifiable; - - int r = ARKodeGetNumConstrFails(arkode_mem, &nconstrfails_adapt_modifiable); - return std::make_tuple(r, nconstrfails_adapt_modifiable); - }; - - return ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetStepStats", - [](void * arkode_mem, sunrealtype * hinused, sunrealtype * hlast, sunrealtype * hcur, sunrealtype * tcur) -> std::tuple + long nconstrfails_adapt_modifiable; + + int r = ARKodeGetNumConstrFails(arkode_mem, &nconstrfails_adapt_modifiable); + return std::make_tuple(r, nconstrfails_adapt_modifiable); + }; + + return ARKodeGetNumConstrFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetStepStats", + [](void* arkode_mem, sunrealtype* hinused, sunrealtype* hlast, + sunrealtype* hcur, sunrealtype* tcur) -> std::tuple + { + auto ARKodeGetStepStats_adapt_modifiable_immutable_to_return = + [](void* arkode_mem, sunrealtype* hinused, sunrealtype* hlast, + sunrealtype* hcur, sunrealtype* tcur) -> std::tuple { - auto ARKodeGetStepStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem, sunrealtype * hinused, sunrealtype * hlast, sunrealtype * hcur, sunrealtype * tcur) -> std::tuple - { - long nsteps_adapt_modifiable; - - int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, hinused, hlast, hcur, tcur); - return std::make_tuple(r, nsteps_adapt_modifiable); - }; - - return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem, hinused, hlast, hcur, tcur); - }, nb::arg("arkode_mem"), nb::arg("hinused"), nb::arg("hlast"), nb::arg("hcur"), nb::arg("tcur")); - -m.def("ARKodeGetAccumulatedError", - ARKodeGetAccumulatedError, nb::arg("arkode_mem"), nb::arg("accum_error")); - -m.def("ARKodeGetNumLinSolvSetups", - [](void * arkode_mem) -> std::tuple + long nsteps_adapt_modifiable; + + int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, hinused, + hlast, hcur, tcur); + return std::make_tuple(r, nsteps_adapt_modifiable); + }; + + return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem, + hinused, hlast, + hcur, tcur); + }, + nb::arg("arkode_mem"), nb::arg("hinused"), nb::arg("hlast"), nb::arg("hcur"), + nb::arg("tcur")); + +m.def("ARKodeGetAccumulatedError", ARKodeGetAccumulatedError, + nb::arg("arkode_mem"), nb::arg("accum_error")); + +m.def( + "ARKodeGetNumLinSolvSetups", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nlinsetups_adapt_modifiable; - - int r = ARKodeGetNumLinSolvSetups(arkode_mem, &nlinsetups_adapt_modifiable); - return std::make_tuple(r, nlinsetups_adapt_modifiable); - }; - - return ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetCurrentTime", - ARKodeGetCurrentTime, nb::arg("arkode_mem"), nb::arg("tcur")); - -m.def("ARKodeGetCurrentState", - [](void * arkode_mem) -> std::tuple + long nlinsetups_adapt_modifiable; + + int r = ARKodeGetNumLinSolvSetups(arkode_mem, &nlinsetups_adapt_modifiable); + return std::make_tuple(r, nlinsetups_adapt_modifiable); + }; + + return ARKodeGetNumLinSolvSetups_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def("ARKodeGetCurrentTime", ARKodeGetCurrentTime, nb::arg("arkode_mem"), + nb::arg("tcur")); + +m.def( + "ARKodeGetCurrentState", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetCurrentState_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetCurrentState_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - N_Vector state_adapt_modifiable; + N_Vector state_adapt_modifiable; - int r = ARKodeGetCurrentState(arkode_mem, &state_adapt_modifiable); - return std::make_tuple(r, state_adapt_modifiable); - }; + int r = ARKodeGetCurrentState(arkode_mem, &state_adapt_modifiable); + return std::make_tuple(r, state_adapt_modifiable); + }; - return ARKodeGetCurrentState_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - "nb::rv_policy::reference", - nb::rv_policy::reference); + return ARKodeGetCurrentState_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); -m.def("ARKodeGetCurrentGamma", - ARKodeGetCurrentGamma, nb::arg("arkode_mem"), nb::arg("gamma")); +m.def("ARKodeGetCurrentGamma", ARKodeGetCurrentGamma, nb::arg("arkode_mem"), + nb::arg("gamma")); -m.def("ARKodeGetNumNonlinSolvIters", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetNumNonlinSolvIters", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nniters_adapt_modifiable; - - int r = ARKodeGetNumNonlinSolvIters(arkode_mem, &nniters_adapt_modifiable); - return std::make_tuple(r, nniters_adapt_modifiable); - }; - - return ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumNonlinSolvConvFails", - [](void * arkode_mem) -> std::tuple + long nniters_adapt_modifiable; + + int r = ARKodeGetNumNonlinSolvIters(arkode_mem, &nniters_adapt_modifiable); + return std::make_tuple(r, nniters_adapt_modifiable); + }; + + return ARKodeGetNumNonlinSolvIters_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumNonlinSolvConvFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nnfails_adapt_modifiable; - - int r = ARKodeGetNumNonlinSolvConvFails(arkode_mem, &nnfails_adapt_modifiable); - return std::make_tuple(r, nnfails_adapt_modifiable); - }; - - return ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNonlinSolvStats", - [](void * arkode_mem) -> std::tuple + long nnfails_adapt_modifiable; + + int r = ARKodeGetNumNonlinSolvConvFails(arkode_mem, + &nnfails_adapt_modifiable); + return std::make_tuple(r, nnfails_adapt_modifiable); + }; + + return ARKodeGetNumNonlinSolvConvFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNonlinSolvStats", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nniters_adapt_modifiable; - long nnfails_adapt_modifiable; - - int r = ARKodeGetNonlinSolvStats(arkode_mem, &nniters_adapt_modifiable, &nnfails_adapt_modifiable); - return std::make_tuple(r, nniters_adapt_modifiable, nnfails_adapt_modifiable); - }; - - return ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumStepSolveFails", - [](void * arkode_mem) -> std::tuple + long nniters_adapt_modifiable; + long nnfails_adapt_modifiable; + + int r = ARKodeGetNonlinSolvStats(arkode_mem, &nniters_adapt_modifiable, + &nnfails_adapt_modifiable); + return std::make_tuple(r, nniters_adapt_modifiable, + nnfails_adapt_modifiable); + }; + + return ARKodeGetNonlinSolvStats_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumStepSolveFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nncfails_adapt_modifiable; - - int r = ARKodeGetNumStepSolveFails(arkode_mem, &nncfails_adapt_modifiable); - return std::make_tuple(r, nncfails_adapt_modifiable); - }; - - return ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetJac", - [](void * arkode_mem) -> std::tuple + long nncfails_adapt_modifiable; + + int r = ARKodeGetNumStepSolveFails(arkode_mem, &nncfails_adapt_modifiable); + return std::make_tuple(r, nncfails_adapt_modifiable); + }; + + return ARKodeGetNumStepSolveFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetJac", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetJac_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetJac_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - SUNMatrix J_adapt_modifiable; + SUNMatrix J_adapt_modifiable; - int r = ARKodeGetJac(arkode_mem, &J_adapt_modifiable); - return std::make_tuple(r, J_adapt_modifiable); - }; + int r = ARKodeGetJac(arkode_mem, &J_adapt_modifiable); + return std::make_tuple(r, J_adapt_modifiable); + }; - return ARKodeGetJac_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - "nb::rv_policy::reference", - nb::rv_policy::reference); + return ARKodeGetJac_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); -m.def("ARKodeGetJacTime", - ARKodeGetJacTime, nb::arg("arkode_mem"), nb::arg("t_J")); +m.def("ARKodeGetJacTime", ARKodeGetJacTime, nb::arg("arkode_mem"), + nb::arg("t_J")); -m.def("ARKodeGetJacNumSteps", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetJacNumSteps", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nst_J_adapt_modifiable; - - int r = ARKodeGetJacNumSteps(arkode_mem, &nst_J_adapt_modifiable); - return std::make_tuple(r, nst_J_adapt_modifiable); - }; - - return ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumJacEvals", - [](void * arkode_mem) -> std::tuple + long nst_J_adapt_modifiable; + + int r = ARKodeGetJacNumSteps(arkode_mem, &nst_J_adapt_modifiable); + return std::make_tuple(r, nst_J_adapt_modifiable); + }; + + return ARKodeGetJacNumSteps_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumJacEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long njevals_adapt_modifiable; - - int r = ARKodeGetNumJacEvals(arkode_mem, &njevals_adapt_modifiable); - return std::make_tuple(r, njevals_adapt_modifiable); - }; - - return ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumPrecEvals", - [](void * arkode_mem) -> std::tuple + long njevals_adapt_modifiable; + + int r = ARKodeGetNumJacEvals(arkode_mem, &njevals_adapt_modifiable); + return std::make_tuple(r, njevals_adapt_modifiable); + }; + + return ARKodeGetNumJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumPrecEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long npevals_adapt_modifiable; - - int r = ARKodeGetNumPrecEvals(arkode_mem, &npevals_adapt_modifiable); - return std::make_tuple(r, npevals_adapt_modifiable); - }; - - return ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumPrecSolves", - [](void * arkode_mem) -> std::tuple + long npevals_adapt_modifiable; + + int r = ARKodeGetNumPrecEvals(arkode_mem, &npevals_adapt_modifiable); + return std::make_tuple(r, npevals_adapt_modifiable); + }; + + return ARKodeGetNumPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumPrecSolves", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long npsolves_adapt_modifiable; - - int r = ARKodeGetNumPrecSolves(arkode_mem, &npsolves_adapt_modifiable); - return std::make_tuple(r, npsolves_adapt_modifiable); - }; - - return ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumLinIters", - [](void * arkode_mem) -> std::tuple + long npsolves_adapt_modifiable; + + int r = ARKodeGetNumPrecSolves(arkode_mem, &npsolves_adapt_modifiable); + return std::make_tuple(r, npsolves_adapt_modifiable); + }; + + return ARKodeGetNumPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumLinIters", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nliters_adapt_modifiable; - - int r = ARKodeGetNumLinIters(arkode_mem, &nliters_adapt_modifiable); - return std::make_tuple(r, nliters_adapt_modifiable); - }; - - return ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumLinConvFails", - [](void * arkode_mem) -> std::tuple + long nliters_adapt_modifiable; + + int r = ARKodeGetNumLinIters(arkode_mem, &nliters_adapt_modifiable); + return std::make_tuple(r, nliters_adapt_modifiable); + }; + + return ARKodeGetNumLinIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumLinConvFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nlcfails_adapt_modifiable; - - int r = ARKodeGetNumLinConvFails(arkode_mem, &nlcfails_adapt_modifiable); - return std::make_tuple(r, nlcfails_adapt_modifiable); - }; - - return ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumJTSetupEvals", - [](void * arkode_mem) -> std::tuple + long nlcfails_adapt_modifiable; + + int r = ARKodeGetNumLinConvFails(arkode_mem, &nlcfails_adapt_modifiable); + return std::make_tuple(r, nlcfails_adapt_modifiable); + }; + + return ARKodeGetNumLinConvFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumJTSetupEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long njtsetups_adapt_modifiable; - - int r = ARKodeGetNumJTSetupEvals(arkode_mem, &njtsetups_adapt_modifiable); - return std::make_tuple(r, njtsetups_adapt_modifiable); - }; - - return ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumJtimesEvals", - [](void * arkode_mem) -> std::tuple + long njtsetups_adapt_modifiable; + + int r = ARKodeGetNumJTSetupEvals(arkode_mem, &njtsetups_adapt_modifiable); + return std::make_tuple(r, njtsetups_adapt_modifiable); + }; + + return ARKodeGetNumJTSetupEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumJtimesEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long njvevals_adapt_modifiable; - - int r = ARKodeGetNumJtimesEvals(arkode_mem, &njvevals_adapt_modifiable); - return std::make_tuple(r, njvevals_adapt_modifiable); - }; - - return ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumLinRhsEvals", - [](void * arkode_mem) -> std::tuple + long njvevals_adapt_modifiable; + + int r = ARKodeGetNumJtimesEvals(arkode_mem, &njvevals_adapt_modifiable); + return std::make_tuple(r, njvevals_adapt_modifiable); + }; + + return ARKodeGetNumJtimesEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumLinRhsEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nfevalsLS_adapt_modifiable; - - int r = ARKodeGetNumLinRhsEvals(arkode_mem, &nfevalsLS_adapt_modifiable); - return std::make_tuple(r, nfevalsLS_adapt_modifiable); - }; - - return ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetLastLinFlag", - [](void * arkode_mem) -> std::tuple + long nfevalsLS_adapt_modifiable; + + int r = ARKodeGetNumLinRhsEvals(arkode_mem, &nfevalsLS_adapt_modifiable); + return std::make_tuple(r, nfevalsLS_adapt_modifiable); + }; + + return ARKodeGetNumLinRhsEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetLastLinFlag", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long flag_adapt_modifiable; + long flag_adapt_modifiable; - int r = ARKodeGetLastLinFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; + int r = ARKodeGetLastLinFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; - return ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return ARKodeGetLastLinFlag_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); -m.def("ARKodeGetLinReturnFlagName", - ARKodeGetLinReturnFlagName, nb::arg("flag")); +m.def("ARKodeGetLinReturnFlagName", ARKodeGetLinReturnFlagName, nb::arg("flag")); -m.def("ARKodeGetCurrentMassMatrix", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetCurrentMassMatrix", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - SUNMatrix M_adapt_modifiable; - - int r = ARKodeGetCurrentMassMatrix(arkode_mem, &M_adapt_modifiable); - return std::make_tuple(r, M_adapt_modifiable); - }; - - return ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions (non-identity mass matrices)\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def("ARKodeGetResWeights", - ARKodeGetResWeights, nb::arg("arkode_mem"), nb::arg("rweight")); - -m.def("ARKodeGetNumMassSetups", - [](void * arkode_mem) -> std::tuple + SUNMatrix M_adapt_modifiable; + + int r = ARKodeGetCurrentMassMatrix(arkode_mem, &M_adapt_modifiable); + return std::make_tuple(r, M_adapt_modifiable); + }; + + return ARKodeGetCurrentMassMatrix_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), " Optional output functions (non-identity mass matrices)\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def("ARKodeGetResWeights", ARKodeGetResWeights, nb::arg("arkode_mem"), + nb::arg("rweight")); + +m.def( + "ARKodeGetNumMassSetups", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmsetups_adapt_modifiable; - - int r = ARKodeGetNumMassSetups(arkode_mem, &nmsetups_adapt_modifiable); - return std::make_tuple(r, nmsetups_adapt_modifiable); - }; - - return ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassMultSetups", - [](void * arkode_mem) -> std::tuple + long nmsetups_adapt_modifiable; + + int r = ARKodeGetNumMassSetups(arkode_mem, &nmsetups_adapt_modifiable); + return std::make_tuple(r, nmsetups_adapt_modifiable); + }; + + return ARKodeGetNumMassSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassMultSetups", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmvsetups_adapt_modifiable; - - int r = ARKodeGetNumMassMultSetups(arkode_mem, &nmvsetups_adapt_modifiable); - return std::make_tuple(r, nmvsetups_adapt_modifiable); - }; - - return ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassMult", - [](void * arkode_mem) -> std::tuple + long nmvsetups_adapt_modifiable; + + int r = ARKodeGetNumMassMultSetups(arkode_mem, &nmvsetups_adapt_modifiable); + return std::make_tuple(r, nmvsetups_adapt_modifiable); + }; + + return ARKodeGetNumMassMultSetups_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassMult", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmvevals_adapt_modifiable; - - int r = ARKodeGetNumMassMult(arkode_mem, &nmvevals_adapt_modifiable); - return std::make_tuple(r, nmvevals_adapt_modifiable); - }; - - return ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassSolves", - [](void * arkode_mem) -> std::tuple + long nmvevals_adapt_modifiable; + + int r = ARKodeGetNumMassMult(arkode_mem, &nmvevals_adapt_modifiable); + return std::make_tuple(r, nmvevals_adapt_modifiable); + }; + + return ARKodeGetNumMassMult_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassSolves", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmsolves_adapt_modifiable; - - int r = ARKodeGetNumMassSolves(arkode_mem, &nmsolves_adapt_modifiable); - return std::make_tuple(r, nmsolves_adapt_modifiable); - }; - - return ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassPrecEvals", - [](void * arkode_mem) -> std::tuple + long nmsolves_adapt_modifiable; + + int r = ARKodeGetNumMassSolves(arkode_mem, &nmsolves_adapt_modifiable); + return std::make_tuple(r, nmsolves_adapt_modifiable); + }; + + return ARKodeGetNumMassSolves_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassPrecEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmpevals_adapt_modifiable; - - int r = ARKodeGetNumMassPrecEvals(arkode_mem, &nmpevals_adapt_modifiable); - return std::make_tuple(r, nmpevals_adapt_modifiable); - }; - - return ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassPrecSolves", - [](void * arkode_mem) -> std::tuple + long nmpevals_adapt_modifiable; + + int r = ARKodeGetNumMassPrecEvals(arkode_mem, &nmpevals_adapt_modifiable); + return std::make_tuple(r, nmpevals_adapt_modifiable); + }; + + return ARKodeGetNumMassPrecEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassPrecSolves", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmpsolves_adapt_modifiable; - - int r = ARKodeGetNumMassPrecSolves(arkode_mem, &nmpsolves_adapt_modifiable); - return std::make_tuple(r, nmpsolves_adapt_modifiable); - }; - - return ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassIters", - [](void * arkode_mem) -> std::tuple + long nmpsolves_adapt_modifiable; + + int r = ARKodeGetNumMassPrecSolves(arkode_mem, &nmpsolves_adapt_modifiable); + return std::make_tuple(r, nmpsolves_adapt_modifiable); + }; + + return ARKodeGetNumMassPrecSolves_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassIters", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmiters_adapt_modifiable; - - int r = ARKodeGetNumMassIters(arkode_mem, &nmiters_adapt_modifiable); - return std::make_tuple(r, nmiters_adapt_modifiable); - }; - - return ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMassConvFails", - [](void * arkode_mem) -> std::tuple + long nmiters_adapt_modifiable; + + int r = ARKodeGetNumMassIters(arkode_mem, &nmiters_adapt_modifiable); + return std::make_tuple(r, nmiters_adapt_modifiable); + }; + + return ARKodeGetNumMassIters_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMassConvFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmcfails_adapt_modifiable; - - int r = ARKodeGetNumMassConvFails(arkode_mem, &nmcfails_adapt_modifiable); - return std::make_tuple(r, nmcfails_adapt_modifiable); - }; - - return ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumMTSetups", - [](void * arkode_mem) -> std::tuple + long nmcfails_adapt_modifiable; + + int r = ARKodeGetNumMassConvFails(arkode_mem, &nmcfails_adapt_modifiable); + return std::make_tuple(r, nmcfails_adapt_modifiable); + }; + + return ARKodeGetNumMassConvFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumMTSetups", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nmtsetups_adapt_modifiable; - - int r = ARKodeGetNumMTSetups(arkode_mem, &nmtsetups_adapt_modifiable); - return std::make_tuple(r, nmtsetups_adapt_modifiable); - }; - - return ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetLastMassFlag", - [](void * arkode_mem) -> std::tuple + long nmtsetups_adapt_modifiable; + + int r = ARKodeGetNumMTSetups(arkode_mem, &nmtsetups_adapt_modifiable); + return std::make_tuple(r, nmtsetups_adapt_modifiable); + }; + + return ARKodeGetNumMTSetups_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetLastMassFlag", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long flag_adapt_modifiable; + long flag_adapt_modifiable; - int r = ARKodeGetLastMassFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; + int r = ARKodeGetLastMassFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; - return ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return ARKodeGetLastMassFlag_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); -m.def("ARKodePrintMem", - ARKodePrintMem, - nb::arg("arkode_mem"), nb::arg("outfile"), - "Output the ARKODE memory structure (useful when debugging)"); +m.def("ARKodePrintMem", ARKodePrintMem, nb::arg("arkode_mem"), nb::arg("outfile"), + "Output the ARKODE memory structure (useful when debugging)"); -m.def("ARKodeSetRelaxEtaFail", - ARKodeSetRelaxEtaFail, nb::arg("arkode_mem"), nb::arg("eta_rf")); +m.def("ARKodeSetRelaxEtaFail", ARKodeSetRelaxEtaFail, nb::arg("arkode_mem"), + nb::arg("eta_rf")); -m.def("ARKodeSetRelaxLowerBound", - ARKodeSetRelaxLowerBound, nb::arg("arkode_mem"), nb::arg("lower")); +m.def("ARKodeSetRelaxLowerBound", ARKodeSetRelaxLowerBound, + nb::arg("arkode_mem"), nb::arg("lower")); -m.def("ARKodeSetRelaxMaxFails", - ARKodeSetRelaxMaxFails, nb::arg("arkode_mem"), nb::arg("max_fails")); +m.def("ARKodeSetRelaxMaxFails", ARKodeSetRelaxMaxFails, nb::arg("arkode_mem"), + nb::arg("max_fails")); -m.def("ARKodeSetRelaxMaxIters", - ARKodeSetRelaxMaxIters, nb::arg("arkode_mem"), nb::arg("max_iters")); +m.def("ARKodeSetRelaxMaxIters", ARKodeSetRelaxMaxIters, nb::arg("arkode_mem"), + nb::arg("max_iters")); -m.def("ARKodeSetRelaxSolver", - ARKodeSetRelaxSolver, nb::arg("arkode_mem"), nb::arg("solver")); +m.def("ARKodeSetRelaxSolver", ARKodeSetRelaxSolver, nb::arg("arkode_mem"), + nb::arg("solver")); -m.def("ARKodeSetRelaxResTol", - ARKodeSetRelaxResTol, nb::arg("arkode_mem"), nb::arg("res_tol")); +m.def("ARKodeSetRelaxResTol", ARKodeSetRelaxResTol, nb::arg("arkode_mem"), + nb::arg("res_tol")); -m.def("ARKodeSetRelaxTol", - ARKodeSetRelaxTol, nb::arg("arkode_mem"), nb::arg("rel_tol"), nb::arg("abs_tol")); +m.def("ARKodeSetRelaxTol", ARKodeSetRelaxTol, nb::arg("arkode_mem"), + nb::arg("rel_tol"), nb::arg("abs_tol")); -m.def("ARKodeSetRelaxUpperBound", - ARKodeSetRelaxUpperBound, nb::arg("arkode_mem"), nb::arg("upper")); +m.def("ARKodeSetRelaxUpperBound", ARKodeSetRelaxUpperBound, + nb::arg("arkode_mem"), nb::arg("upper")); -m.def("ARKodeGetNumRelaxFnEvals", - [](void * arkode_mem) -> std::tuple +m.def( + "ARKodeGetNumRelaxFnEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long r_evals_adapt_modifiable; - - int r = ARKodeGetNumRelaxFnEvals(arkode_mem, &r_evals_adapt_modifiable); - return std::make_tuple(r, r_evals_adapt_modifiable); - }; - - return ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumRelaxJacEvals", - [](void * arkode_mem) -> std::tuple + long r_evals_adapt_modifiable; + + int r = ARKodeGetNumRelaxFnEvals(arkode_mem, &r_evals_adapt_modifiable); + return std::make_tuple(r, r_evals_adapt_modifiable); + }; + + return ARKodeGetNumRelaxFnEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumRelaxJacEvals", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long J_evals_adapt_modifiable; - - int r = ARKodeGetNumRelaxJacEvals(arkode_mem, &J_evals_adapt_modifiable); - return std::make_tuple(r, J_evals_adapt_modifiable); - }; - - return ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumRelaxFails", - [](void * arkode_mem) -> std::tuple + long J_evals_adapt_modifiable; + + int r = ARKodeGetNumRelaxJacEvals(arkode_mem, &J_evals_adapt_modifiable); + return std::make_tuple(r, J_evals_adapt_modifiable); + }; + + return ARKodeGetNumRelaxJacEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumRelaxFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long relax_fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxFails(arkode_mem, &relax_fails_adapt_modifiable); - return std::make_tuple(r, relax_fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumRelaxBoundFails", - [](void * arkode_mem) -> std::tuple + long relax_fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxFails(arkode_mem, &relax_fails_adapt_modifiable); + return std::make_tuple(r, relax_fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxFails_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumRelaxBoundFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxBoundFails(arkode_mem, &fails_adapt_modifiable); - return std::make_tuple(r, fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumRelaxSolveFails", - [](void * arkode_mem) -> std::tuple + long fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxBoundFails(arkode_mem, &fails_adapt_modifiable); + return std::make_tuple(r, fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxBoundFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumRelaxSolveFails", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long fails_adapt_modifiable; - - int r = ARKodeGetNumRelaxSolveFails(arkode_mem, &fails_adapt_modifiable); - return std::make_tuple(r, fails_adapt_modifiable); - }; - - return ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeGetNumRelaxSolveIters", - [](void * arkode_mem) -> std::tuple + long fails_adapt_modifiable; + + int r = ARKodeGetNumRelaxSolveFails(arkode_mem, &fails_adapt_modifiable); + return std::make_tuple(r, fails_adapt_modifiable); + }; + + return ARKodeGetNumRelaxSolveFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetNumRelaxSolveIters", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long iters_adapt_modifiable; - - int r = ARKodeGetNumRelaxSolveIters(arkode_mem, &iters_adapt_modifiable); - return std::make_tuple(r, iters_adapt_modifiable); - }; - - return ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("ARKodeCreateSUNStepper", - [](void * arkode_mem) -> std::tuple>> + long iters_adapt_modifiable; + + int r = ARKodeGetNumRelaxSolveIters(arkode_mem, &iters_adapt_modifiable); + return std::make_tuple(r, iters_adapt_modifiable); + }; + + return ARKodeGetNumRelaxSolveIters_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeCreateSUNStepper", + [](void* arkode_mem) + -> std::tuple>> + { + auto ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - SUNStepper stepper_adapt_modifiable; - - int r = ARKodeCreateSUNStepper(arkode_mem, &stepper_adapt_modifiable); - return std::make_tuple(r, stepper_adapt_modifiable); - }; - auto ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr = [&ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return](void * arkode_mem) -> std::tuple>> - { - auto lambda_result = ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return(arkode_mem); - - return std::make_tuple(std::get<0>(lambda_result), our_make_shared, SUNStepperDeleter>(std::get<1>(lambda_result))); - return lambda_result; - }; - - return ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr(arkode_mem); - }, - nb::arg("arkode_mem"), - "SUNStepper functions", - nb::rv_policy::reference); + SUNStepper stepper_adapt_modifiable; + + int r = ARKodeCreateSUNStepper(arkode_mem, &stepper_adapt_modifiable); + return std::make_tuple(r, stepper_adapt_modifiable); + }; + auto ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr = + [&ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return]( + void* arkode_mem) + -> std::tuple>> + { + auto lambda_result = + ARKodeCreateSUNStepper_adapt_modifiable_immutable_to_return(arkode_mem); + + return std::make_tuple(std::get<0>(lambda_result), + our_make_shared, + SUNStepperDeleter>( + std::get<1>(lambda_result))); + return lambda_result; + }; + + return ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr(arkode_mem); + }, + nb::arg("arkode_mem"), "SUNStepper functions", nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKLS_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// -m.attr("ARKLS_SUCCESS") = 0; -m.attr("ARKLS_MEM_NULL") = -1; -m.attr("ARKLS_LMEM_NULL") = -2; -m.attr("ARKLS_ILL_INPUT") = -3; -m.attr("ARKLS_MEM_FAIL") = -4; -m.attr("ARKLS_PMEM_NULL") = -5; -m.attr("ARKLS_MASSMEM_NULL") = -6; -m.attr("ARKLS_JACFUNC_UNRECVR") = -7; -m.attr("ARKLS_JACFUNC_RECVR") = -8; +// +m.attr("ARKLS_SUCCESS") = 0; +m.attr("ARKLS_MEM_NULL") = -1; +m.attr("ARKLS_LMEM_NULL") = -2; +m.attr("ARKLS_ILL_INPUT") = -3; +m.attr("ARKLS_MEM_FAIL") = -4; +m.attr("ARKLS_PMEM_NULL") = -5; +m.attr("ARKLS_MASSMEM_NULL") = -6; +m.attr("ARKLS_JACFUNC_UNRECVR") = -7; +m.attr("ARKLS_JACFUNC_RECVR") = -8; m.attr("ARKLS_MASSFUNC_UNRECVR") = -9; -m.attr("ARKLS_MASSFUNC_RECVR") = -10; -m.attr("ARKLS_SUNMAT_FAIL") = -11; -m.attr("ARKLS_SUNLS_FAIL") = -12; - -m.def("ARKodeSetLinearSolver", - [](void * arkode_mem, SUNLinearSolver LS, std::optional A = std::nullopt) -> int +m.attr("ARKLS_MASSFUNC_RECVR") = -10; +m.attr("ARKLS_SUNMAT_FAIL") = -11; +m.attr("ARKLS_SUNLS_FAIL") = -12; + +m.def( + "ARKodeSetLinearSolver", + [](void* arkode_mem, SUNLinearSolver LS, + std::optional A = std::nullopt) -> int + { + auto ARKodeSetLinearSolver_adapt_optional_arg_with_default_null = + [](void* arkode_mem, SUNLinearSolver LS, + std::optional A = std::nullopt) -> int { - auto ARKodeSetLinearSolver_adapt_optional_arg_with_default_null = [](void * arkode_mem, SUNLinearSolver LS, std::optional A = std::nullopt) -> int - { - SUNMatrix A_adapt_default_null = nullptr; - if (A.has_value()) - A_adapt_default_null = A.value(); + SUNMatrix A_adapt_default_null = nullptr; + if (A.has_value()) A_adapt_default_null = A.value(); - auto lambda_result = ARKodeSetLinearSolver(arkode_mem, LS, A_adapt_default_null); - return lambda_result; - }; + auto lambda_result = ARKodeSetLinearSolver(arkode_mem, LS, + A_adapt_default_null); + return lambda_result; + }; - return ARKodeSetLinearSolver_adapt_optional_arg_with_default_null(arkode_mem, LS, A); - }, nb::arg("arkode_mem"), nb::arg("LS"), nb::arg("A").none() = nb::none()); + return ARKodeSetLinearSolver_adapt_optional_arg_with_default_null(arkode_mem, + LS, A); + }, + nb::arg("arkode_mem"), nb::arg("LS"), nb::arg("A").none() = nb::none()); -m.def("ARKodeSetJacEvalFrequency", - ARKodeSetJacEvalFrequency, nb::arg("arkode_mem"), nb::arg("msbj")); +m.def("ARKodeSetJacEvalFrequency", ARKodeSetJacEvalFrequency, + nb::arg("arkode_mem"), nb::arg("msbj")); -m.def("ARKodeSetLinearSolutionScaling", - ARKodeSetLinearSolutionScaling, nb::arg("arkode_mem"), nb::arg("onoff")); +m.def("ARKodeSetLinearSolutionScaling", ARKodeSetLinearSolutionScaling, + nb::arg("arkode_mem"), nb::arg("onoff")); -m.def("ARKodeSetEpsLin", - ARKodeSetEpsLin, nb::arg("arkode_mem"), nb::arg("eplifac")); +m.def("ARKodeSetEpsLin", ARKodeSetEpsLin, nb::arg("arkode_mem"), + nb::arg("eplifac")); -m.def("ARKodeSetMassEpsLin", - ARKodeSetMassEpsLin, nb::arg("arkode_mem"), nb::arg("eplifac")); +m.def("ARKodeSetMassEpsLin", ARKodeSetMassEpsLin, nb::arg("arkode_mem"), + nb::arg("eplifac")); -m.def("ARKodeSetLSNormFactor", - ARKodeSetLSNormFactor, nb::arg("arkode_mem"), nb::arg("nrmfac")); +m.def("ARKodeSetLSNormFactor", ARKodeSetLSNormFactor, nb::arg("arkode_mem"), + nb::arg("nrmfac")); -m.def("ARKodeSetMassLSNormFactor", - ARKodeSetMassLSNormFactor, nb::arg("arkode_mem"), nb::arg("nrmfac")); +m.def("ARKodeSetMassLSNormFactor", ARKodeSetMassLSNormFactor, + nb::arg("arkode_mem"), nb::arg("nrmfac")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_BUTCHER_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyClassARKodeButcherTableMem = - nb::class_ - (m, "ARKodeButcherTableMem", "") + nb::class_(m, "ARKodeButcherTableMem", "") .def(nb::init<>()) // implicit default constructor - ; - - -m.def("ARKodeButcherTable_Create", - [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> std::shared_ptr> + ; + +m.def( + "ARKodeButcherTable_Create", + [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, + sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) + -> std::shared_ptr> + { + auto ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector = + [](int s, int q, int p, sundials4py::Array1d c_1d, + sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, + sundials4py::Array1d d_1d) -> ARKodeButcherTable { - auto ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector = [](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> ARKodeButcherTable - { - sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); - sunrealtype* A_1d_ptr = A_1d.size() == 0 ? nullptr : A_1d.data(); - sunrealtype* b_1d_ptr = b_1d.size() == 0 ? nullptr : b_1d.data(); - sunrealtype* d_1d_ptr = d_1d.size() == 0 ? nullptr : d_1d.data(); - - auto lambda_result = ARKodeButcherTable_Create(s, q, p, c_1d_ptr, A_1d_ptr, b_1d_ptr, d_1d_ptr); - return lambda_result; - }; - auto ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr = [&ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, int p, sundials4py::Array1d c_1d, sundials4py::Array1d A_1d, sundials4py::Array1d b_1d, sundials4py::Array1d d_1d) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector(s, q, p, c_1d, A_1d, b_1d, d_1d); - - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr(s, q, p, c_1d, A_1d, b_1d, d_1d); - }, nb::arg("s"), nb::arg("q"), nb::arg("p"), nb::arg("c_1d"), nb::arg("A_1d"), nb::arg("b_1d"), nb::arg("d_1d")); - -m.def("ARKodeButcherTable_Copy", - [](ARKodeButcherTable B) -> std::shared_ptr> + sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); + sunrealtype* A_1d_ptr = A_1d.size() == 0 ? nullptr : A_1d.data(); + sunrealtype* b_1d_ptr = b_1d.size() == 0 ? nullptr : b_1d.data(); + sunrealtype* d_1d_ptr = d_1d.size() == 0 ? nullptr : d_1d.data(); + + auto lambda_result = ARKodeButcherTable_Create(s, q, p, c_1d_ptr, A_1d_ptr, + b_1d_ptr, d_1d_ptr); + return lambda_result; + }; + auto ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr = + [&ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, + int p, + sundials4py::Array1d c_1d, + sundials4py::Array1d A_1d, + sundials4py::Array1d b_1d, + sundials4py::Array1d d_1d) + -> std::shared_ptr> { - auto ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr = [](ARKodeButcherTable B) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_Copy(B); + auto lambda_result = + ARKodeButcherTable_Create_adapt_arr_ptr_to_std_vector(s, q, p, c_1d, + A_1d, b_1d, d_1d); + + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr(s, q, p, + c_1d, A_1d, + b_1d, d_1d); + }, + nb::arg("s"), nb::arg("q"), nb::arg("p"), nb::arg("c_1d"), nb::arg("A_1d"), + nb::arg("b_1d"), nb::arg("d_1d")); + +m.def( + "ARKodeButcherTable_Copy", + [](ARKodeButcherTable B) + -> std::shared_ptr> + { + auto ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr = + [](ARKodeButcherTable B) + -> std::shared_ptr> + { + auto lambda_result = ARKodeButcherTable_Copy(B); - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr(B); - }, nb::arg("B")); + return ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr(B); + }, + nb::arg("B")); -m.def("ARKodeButcherTable_Write", - ARKodeButcherTable_Write, nb::arg("B"), nb::arg("outfile")); +m.def("ARKodeButcherTable_Write", ARKodeButcherTable_Write, nb::arg("B"), + nb::arg("outfile")); m.def("ARKodeButcherTable_IsStifflyAccurate", - ARKodeButcherTable_IsStifflyAccurate, nb::arg("B")); - -m.def("ARKodeButcherTable_CheckOrder", - [](ARKodeButcherTable B, FILE * outfile) -> std::tuple + ARKodeButcherTable_IsStifflyAccurate, nb::arg("B")); + +m.def( + "ARKodeButcherTable_CheckOrder", + [](ARKodeButcherTable B, FILE* outfile) -> std::tuple + { + auto ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return = + [](ARKodeButcherTable B, FILE* outfile) -> std::tuple { - auto ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return = [](ARKodeButcherTable B, FILE * outfile) -> std::tuple - { - int q_adapt_modifiable; - int p_adapt_modifiable; - - int r = ARKodeButcherTable_CheckOrder(B, &q_adapt_modifiable, &p_adapt_modifiable, outfile); - return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); - }; - - return ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return(B, outfile); - }, nb::arg("B"), nb::arg("outfile")); - -m.def("ARKodeButcherTable_CheckARKOrder", - [](ARKodeButcherTable B1, ARKodeButcherTable B2, FILE * outfile) -> std::tuple + int q_adapt_modifiable; + int p_adapt_modifiable; + + int r = ARKodeButcherTable_CheckOrder(B, &q_adapt_modifiable, + &p_adapt_modifiable, outfile); + return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); + }; + + return ARKodeButcherTable_CheckOrder_adapt_modifiable_immutable_to_return(B, + outfile); + }, + nb::arg("B"), nb::arg("outfile")); + +m.def( + "ARKodeButcherTable_CheckARKOrder", + [](ARKodeButcherTable B1, ARKodeButcherTable B2, + FILE* outfile) -> std::tuple + { + auto ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return = + [](ARKodeButcherTable B1, ARKodeButcherTable B2, + FILE* outfile) -> std::tuple { - auto ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return = [](ARKodeButcherTable B1, ARKodeButcherTable B2, FILE * outfile) -> std::tuple - { - int q_adapt_modifiable; - int p_adapt_modifiable; - - int r = ARKodeButcherTable_CheckARKOrder(B1, B2, &q_adapt_modifiable, &p_adapt_modifiable, outfile); - return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); - }; - - return ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return(B1, B2, outfile); - }, nb::arg("B1"), nb::arg("B2"), nb::arg("outfile")); + int q_adapt_modifiable; + int p_adapt_modifiable; + + int r = ARKodeButcherTable_CheckARKOrder(B1, B2, &q_adapt_modifiable, + &p_adapt_modifiable, outfile); + return std::make_tuple(r, q_adapt_modifiable, p_adapt_modifiable); + }; + + return ARKodeButcherTable_CheckARKOrder_adapt_modifiable_immutable_to_return(B1, + B2, + outfile); + }, + nb::arg("B1"), nb::arg("B2"), nb::arg("outfile")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_ERK_TABLES_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyEnumARKODE_ERKTableID = - nb::enum_(m, "ARKODE_ERKTableID", nb::is_arithmetic(), "") - .value("ARKODE_ERK_NONE", ARKODE_ERK_NONE, "ensure enum is signed int") - .value("ARKODE_HEUN_EULER_2_1_2", ARKODE_HEUN_EULER_2_1_2, "") - .value("ARKODE_MIN_ERK_NUM", ARKODE_MIN_ERK_NUM, "") - .value("ARKODE_BOGACKI_SHAMPINE_4_2_3", ARKODE_BOGACKI_SHAMPINE_4_2_3, "") - .value("ARKODE_ARK324L2SA_ERK_4_2_3", ARKODE_ARK324L2SA_ERK_4_2_3, "") - .value("ARKODE_ZONNEVELD_5_3_4", ARKODE_ZONNEVELD_5_3_4, "") - .value("ARKODE_ARK436L2SA_ERK_6_3_4", ARKODE_ARK436L2SA_ERK_6_3_4, "") - .value("ARKODE_SAYFY_ABURUB_6_3_4", ARKODE_SAYFY_ABURUB_6_3_4, "") - .value("ARKODE_CASH_KARP_6_4_5", ARKODE_CASH_KARP_6_4_5, "") - .value("ARKODE_FEHLBERG_6_4_5", ARKODE_FEHLBERG_6_4_5, "") - .value("ARKODE_DORMAND_PRINCE_7_4_5", ARKODE_DORMAND_PRINCE_7_4_5, "") - .value("ARKODE_ARK548L2SA_ERK_8_4_5", ARKODE_ARK548L2SA_ERK_8_4_5, "") - .value("ARKODE_VERNER_8_5_6", ARKODE_VERNER_8_5_6, "") - .value("ARKODE_FEHLBERG_13_7_8", ARKODE_FEHLBERG_13_7_8, "") - .value("ARKODE_KNOTH_WOLKE_3_3", ARKODE_KNOTH_WOLKE_3_3, "") - .value("ARKODE_ARK437L2SA_ERK_7_3_4", ARKODE_ARK437L2SA_ERK_7_3_4, "") - .value("ARKODE_ARK548L2SAb_ERK_8_4_5", ARKODE_ARK548L2SAb_ERK_8_4_5, "") - .value("ARKODE_ARK2_ERK_3_1_2", ARKODE_ARK2_ERK_3_1_2, "") - .value("ARKODE_SOFRONIOU_SPALETTA_5_3_4", ARKODE_SOFRONIOU_SPALETTA_5_3_4, "") - .value("ARKODE_SHU_OSHER_3_2_3", ARKODE_SHU_OSHER_3_2_3, "") - .value("ARKODE_VERNER_9_5_6", ARKODE_VERNER_9_5_6, "") - .value("ARKODE_VERNER_10_6_7", ARKODE_VERNER_10_6_7, "") - .value("ARKODE_VERNER_13_7_8", ARKODE_VERNER_13_7_8, "") - .value("ARKODE_VERNER_16_8_9", ARKODE_VERNER_16_8_9, "") - .value("ARKODE_FORWARD_EULER_1_1", ARKODE_FORWARD_EULER_1_1, "") - .value("ARKODE_RALSTON_EULER_2_1_2", ARKODE_RALSTON_EULER_2_1_2, "") - .value("ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2", ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2, "") - .value("ARKODE_RALSTON_3_1_2", ARKODE_RALSTON_3_1_2, "") - .value("ARKODE_TSITOURAS_7_4_5", ARKODE_TSITOURAS_7_4_5, "") - .value("ARKODE_MAX_ERK_NUM", ARKODE_MAX_ERK_NUM, "") + nb::enum_(m, "ARKODE_ERKTableID", nb::is_arithmetic(), "") + .value("ARKODE_ERK_NONE", ARKODE_ERK_NONE, "ensure enum is signed int") + .value("ARKODE_HEUN_EULER_2_1_2", ARKODE_HEUN_EULER_2_1_2, "") + .value("ARKODE_MIN_ERK_NUM", ARKODE_MIN_ERK_NUM, "") + .value("ARKODE_BOGACKI_SHAMPINE_4_2_3", ARKODE_BOGACKI_SHAMPINE_4_2_3, "") + .value("ARKODE_ARK324L2SA_ERK_4_2_3", ARKODE_ARK324L2SA_ERK_4_2_3, "") + .value("ARKODE_ZONNEVELD_5_3_4", ARKODE_ZONNEVELD_5_3_4, "") + .value("ARKODE_ARK436L2SA_ERK_6_3_4", ARKODE_ARK436L2SA_ERK_6_3_4, "") + .value("ARKODE_SAYFY_ABURUB_6_3_4", ARKODE_SAYFY_ABURUB_6_3_4, "") + .value("ARKODE_CASH_KARP_6_4_5", ARKODE_CASH_KARP_6_4_5, "") + .value("ARKODE_FEHLBERG_6_4_5", ARKODE_FEHLBERG_6_4_5, "") + .value("ARKODE_DORMAND_PRINCE_7_4_5", ARKODE_DORMAND_PRINCE_7_4_5, "") + .value("ARKODE_ARK548L2SA_ERK_8_4_5", ARKODE_ARK548L2SA_ERK_8_4_5, "") + .value("ARKODE_VERNER_8_5_6", ARKODE_VERNER_8_5_6, "") + .value("ARKODE_FEHLBERG_13_7_8", ARKODE_FEHLBERG_13_7_8, "") + .value("ARKODE_KNOTH_WOLKE_3_3", ARKODE_KNOTH_WOLKE_3_3, "") + .value("ARKODE_ARK437L2SA_ERK_7_3_4", ARKODE_ARK437L2SA_ERK_7_3_4, "") + .value("ARKODE_ARK548L2SAb_ERK_8_4_5", ARKODE_ARK548L2SAb_ERK_8_4_5, "") + .value("ARKODE_ARK2_ERK_3_1_2", ARKODE_ARK2_ERK_3_1_2, "") + .value("ARKODE_SOFRONIOU_SPALETTA_5_3_4", ARKODE_SOFRONIOU_SPALETTA_5_3_4, "") + .value("ARKODE_SHU_OSHER_3_2_3", ARKODE_SHU_OSHER_3_2_3, "") + .value("ARKODE_VERNER_9_5_6", ARKODE_VERNER_9_5_6, "") + .value("ARKODE_VERNER_10_6_7", ARKODE_VERNER_10_6_7, "") + .value("ARKODE_VERNER_13_7_8", ARKODE_VERNER_13_7_8, "") + .value("ARKODE_VERNER_16_8_9", ARKODE_VERNER_16_8_9, "") + .value("ARKODE_FORWARD_EULER_1_1", ARKODE_FORWARD_EULER_1_1, "") + .value("ARKODE_RALSTON_EULER_2_1_2", ARKODE_RALSTON_EULER_2_1_2, "") + .value("ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2", + ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2, "") + .value("ARKODE_RALSTON_3_1_2", ARKODE_RALSTON_3_1_2, "") + .value("ARKODE_TSITOURAS_7_4_5", ARKODE_TSITOURAS_7_4_5, "") + .value("ARKODE_MAX_ERK_NUM", ARKODE_MAX_ERK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def("ARKodeButcherTable_LoadERK", - [](ARKODE_ERKTableID emethod) -> std::shared_ptr> +// + +m.def( + "ARKodeButcherTable_LoadERK", + [](ARKODE_ERKTableID emethod) + -> std::shared_ptr> + { + auto ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr = + [](ARKODE_ERKTableID emethod) + -> std::shared_ptr> { - auto ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr = [](ARKODE_ERKTableID emethod) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_LoadERK(emethod); - - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr(emethod); - }, - nb::arg("emethod"), - "Accessor routine to load built-in ERK table"); - -m.def("ARKodeButcherTable_LoadERKByName", - [](const char * emethod) -> std::shared_ptr> + auto lambda_result = ARKodeButcherTable_LoadERK(emethod); + + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr(emethod); + }, + nb::arg("emethod"), "Accessor routine to load built-in ERK table"); + +m.def( + "ARKodeButcherTable_LoadERKByName", + [](const char* emethod) + -> std::shared_ptr> + { + auto ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr = + [](const char* emethod) + -> std::shared_ptr> { - auto ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr = [](const char * emethod) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_LoadERKByName(emethod); + auto lambda_result = ARKodeButcherTable_LoadERKByName(emethod); - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr(emethod); - }, nb::arg("emethod")); + return ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr( + emethod); + }, + nb::arg("emethod")); -m.def("ARKodeButcherTable_ERKIDToName", - ARKodeButcherTable_ERKIDToName, nb::arg("emethod")); +m.def("ARKodeButcherTable_ERKIDToName", ARKodeButcherTable_ERKIDToName, + nb::arg("emethod")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_DIRK_TABLES_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyEnumARKODE_DIRKTableID = - nb::enum_(m, "ARKODE_DIRKTableID", nb::is_arithmetic(), "") - .value("ARKODE_DIRK_NONE", ARKODE_DIRK_NONE, "ensure enum is signed int") - .value("ARKODE_SDIRK_2_1_2", ARKODE_SDIRK_2_1_2, "") - .value("ARKODE_MIN_DIRK_NUM", ARKODE_MIN_DIRK_NUM, "") - .value("ARKODE_BILLINGTON_3_3_2", ARKODE_BILLINGTON_3_3_2, "") - .value("ARKODE_TRBDF2_3_3_2", ARKODE_TRBDF2_3_3_2, "") - .value("ARKODE_KVAERNO_4_2_3", ARKODE_KVAERNO_4_2_3, "") - .value("ARKODE_ARK324L2SA_DIRK_4_2_3", ARKODE_ARK324L2SA_DIRK_4_2_3, "") - .value("ARKODE_CASH_5_2_4", ARKODE_CASH_5_2_4, "") - .value("ARKODE_CASH_5_3_4", ARKODE_CASH_5_3_4, "") - .value("ARKODE_SDIRK_5_3_4", ARKODE_SDIRK_5_3_4, "") - .value("ARKODE_KVAERNO_5_3_4", ARKODE_KVAERNO_5_3_4, "") - .value("ARKODE_ARK436L2SA_DIRK_6_3_4", ARKODE_ARK436L2SA_DIRK_6_3_4, "") - .value("ARKODE_KVAERNO_7_4_5", ARKODE_KVAERNO_7_4_5, "") - .value("ARKODE_ARK548L2SA_DIRK_8_4_5", ARKODE_ARK548L2SA_DIRK_8_4_5, "") - .value("ARKODE_ARK437L2SA_DIRK_7_3_4", ARKODE_ARK437L2SA_DIRK_7_3_4, "") - .value("ARKODE_ARK548L2SAb_DIRK_8_4_5", ARKODE_ARK548L2SAb_DIRK_8_4_5, "") - .value("ARKODE_ESDIRK324L2SA_4_2_3", ARKODE_ESDIRK324L2SA_4_2_3, "") - .value("ARKODE_ESDIRK325L2SA_5_2_3", ARKODE_ESDIRK325L2SA_5_2_3, "") - .value("ARKODE_ESDIRK32I5L2SA_5_2_3", ARKODE_ESDIRK32I5L2SA_5_2_3, "") - .value("ARKODE_ESDIRK436L2SA_6_3_4", ARKODE_ESDIRK436L2SA_6_3_4, "") - .value("ARKODE_ESDIRK43I6L2SA_6_3_4", ARKODE_ESDIRK43I6L2SA_6_3_4, "") - .value("ARKODE_QESDIRK436L2SA_6_3_4", ARKODE_QESDIRK436L2SA_6_3_4, "") - .value("ARKODE_ESDIRK437L2SA_7_3_4", ARKODE_ESDIRK437L2SA_7_3_4, "") - .value("ARKODE_ESDIRK547L2SA_7_4_5", ARKODE_ESDIRK547L2SA_7_4_5, "") - .value("ARKODE_ESDIRK547L2SA2_7_4_5", ARKODE_ESDIRK547L2SA2_7_4_5, "") - .value("ARKODE_ARK2_DIRK_3_1_2", ARKODE_ARK2_DIRK_3_1_2, "") - .value("ARKODE_BACKWARD_EULER_1_1", ARKODE_BACKWARD_EULER_1_1, "") - .value("ARKODE_IMPLICIT_MIDPOINT_1_2", ARKODE_IMPLICIT_MIDPOINT_1_2, "") - .value("ARKODE_IMPLICIT_TRAPEZOIDAL_2_2", ARKODE_IMPLICIT_TRAPEZOIDAL_2_2, "") - .value("ARKODE_MAX_DIRK_NUM", ARKODE_MAX_DIRK_NUM, "") + nb::enum_(m, "ARKODE_DIRKTableID", nb::is_arithmetic(), "") + .value("ARKODE_DIRK_NONE", ARKODE_DIRK_NONE, "ensure enum is signed int") + .value("ARKODE_SDIRK_2_1_2", ARKODE_SDIRK_2_1_2, "") + .value("ARKODE_MIN_DIRK_NUM", ARKODE_MIN_DIRK_NUM, "") + .value("ARKODE_BILLINGTON_3_3_2", ARKODE_BILLINGTON_3_3_2, "") + .value("ARKODE_TRBDF2_3_3_2", ARKODE_TRBDF2_3_3_2, "") + .value("ARKODE_KVAERNO_4_2_3", ARKODE_KVAERNO_4_2_3, "") + .value("ARKODE_ARK324L2SA_DIRK_4_2_3", ARKODE_ARK324L2SA_DIRK_4_2_3, "") + .value("ARKODE_CASH_5_2_4", ARKODE_CASH_5_2_4, "") + .value("ARKODE_CASH_5_3_4", ARKODE_CASH_5_3_4, "") + .value("ARKODE_SDIRK_5_3_4", ARKODE_SDIRK_5_3_4, "") + .value("ARKODE_KVAERNO_5_3_4", ARKODE_KVAERNO_5_3_4, "") + .value("ARKODE_ARK436L2SA_DIRK_6_3_4", ARKODE_ARK436L2SA_DIRK_6_3_4, "") + .value("ARKODE_KVAERNO_7_4_5", ARKODE_KVAERNO_7_4_5, "") + .value("ARKODE_ARK548L2SA_DIRK_8_4_5", ARKODE_ARK548L2SA_DIRK_8_4_5, "") + .value("ARKODE_ARK437L2SA_DIRK_7_3_4", ARKODE_ARK437L2SA_DIRK_7_3_4, "") + .value("ARKODE_ARK548L2SAb_DIRK_8_4_5", ARKODE_ARK548L2SAb_DIRK_8_4_5, "") + .value("ARKODE_ESDIRK324L2SA_4_2_3", ARKODE_ESDIRK324L2SA_4_2_3, "") + .value("ARKODE_ESDIRK325L2SA_5_2_3", ARKODE_ESDIRK325L2SA_5_2_3, "") + .value("ARKODE_ESDIRK32I5L2SA_5_2_3", ARKODE_ESDIRK32I5L2SA_5_2_3, "") + .value("ARKODE_ESDIRK436L2SA_6_3_4", ARKODE_ESDIRK436L2SA_6_3_4, "") + .value("ARKODE_ESDIRK43I6L2SA_6_3_4", ARKODE_ESDIRK43I6L2SA_6_3_4, "") + .value("ARKODE_QESDIRK436L2SA_6_3_4", ARKODE_QESDIRK436L2SA_6_3_4, "") + .value("ARKODE_ESDIRK437L2SA_7_3_4", ARKODE_ESDIRK437L2SA_7_3_4, "") + .value("ARKODE_ESDIRK547L2SA_7_4_5", ARKODE_ESDIRK547L2SA_7_4_5, "") + .value("ARKODE_ESDIRK547L2SA2_7_4_5", ARKODE_ESDIRK547L2SA2_7_4_5, "") + .value("ARKODE_ARK2_DIRK_3_1_2", ARKODE_ARK2_DIRK_3_1_2, "") + .value("ARKODE_BACKWARD_EULER_1_1", ARKODE_BACKWARD_EULER_1_1, "") + .value("ARKODE_IMPLICIT_MIDPOINT_1_2", ARKODE_IMPLICIT_MIDPOINT_1_2, "") + .value("ARKODE_IMPLICIT_TRAPEZOIDAL_2_2", ARKODE_IMPLICIT_TRAPEZOIDAL_2_2, "") + .value("ARKODE_MAX_DIRK_NUM", ARKODE_MAX_DIRK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def("ARKodeButcherTable_LoadDIRK", - [](ARKODE_DIRKTableID imethod) -> std::shared_ptr> +// + +m.def( + "ARKodeButcherTable_LoadDIRK", + [](ARKODE_DIRKTableID imethod) + -> std::shared_ptr> + { + auto ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr = + [](ARKODE_DIRKTableID imethod) + -> std::shared_ptr> { - auto ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr = [](ARKODE_DIRKTableID imethod) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_LoadDIRK(imethod); - - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr(imethod); - }, - nb::arg("imethod"), - "Accessor routine to load built-in DIRK table"); - -m.def("ARKodeButcherTable_LoadDIRKByName", - [](const char * imethod) -> std::shared_ptr> + auto lambda_result = ARKodeButcherTable_LoadDIRK(imethod); + + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr(imethod); + }, + nb::arg("imethod"), "Accessor routine to load built-in DIRK table"); + +m.def( + "ARKodeButcherTable_LoadDIRKByName", + [](const char* imethod) + -> std::shared_ptr> + { + auto ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr = + [](const char* imethod) + -> std::shared_ptr> { - auto ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr = [](const char * imethod) -> std::shared_ptr> - { - auto lambda_result = ARKodeButcherTable_LoadDIRKByName(imethod); + auto lambda_result = ARKodeButcherTable_LoadDIRKByName(imethod); - return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; - }; + return our_make_shared, + ARKodeButcherTableDeleter>(lambda_result); + return lambda_result; + }; - return ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr(imethod); - }, - nb::arg("imethod"), - "Accessor routine to load built-in DIRK table"); + return ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr( + imethod); + }, + nb::arg("imethod"), "Accessor routine to load built-in DIRK table"); -m.def("ARKodeButcherTable_DIRKIDToName", - ARKodeButcherTable_DIRKIDToName, nb::arg("imethod")); +m.def("ARKodeButcherTable_DIRKIDToName", ARKodeButcherTable_DIRKIDToName, + nb::arg("imethod")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// // #ifndef _ARKODE_SPRKTABLE_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyEnumARKODE_SPRKMethodID = - nb::enum_(m, "ARKODE_SPRKMethodID", nb::is_arithmetic(), "") - .value("ARKODE_SPRK_NONE", ARKODE_SPRK_NONE, "ensure enum is signed int") - .value("ARKODE_SPRK_EULER_1_1", ARKODE_SPRK_EULER_1_1, "") - .value("ARKODE_MIN_SPRK_NUM", ARKODE_MIN_SPRK_NUM, "") - .value("ARKODE_SPRK_LEAPFROG_2_2", ARKODE_SPRK_LEAPFROG_2_2, "") - .value("ARKODE_SPRK_PSEUDO_LEAPFROG_2_2", ARKODE_SPRK_PSEUDO_LEAPFROG_2_2, "") - .value("ARKODE_SPRK_RUTH_3_3", ARKODE_SPRK_RUTH_3_3, "") - .value("ARKODE_SPRK_MCLACHLAN_2_2", ARKODE_SPRK_MCLACHLAN_2_2, "") - .value("ARKODE_SPRK_MCLACHLAN_3_3", ARKODE_SPRK_MCLACHLAN_3_3, "") - .value("ARKODE_SPRK_CANDY_ROZMUS_4_4", ARKODE_SPRK_CANDY_ROZMUS_4_4, "") - .value("ARKODE_SPRK_MCLACHLAN_4_4", ARKODE_SPRK_MCLACHLAN_4_4, "") - .value("ARKODE_SPRK_MCLACHLAN_5_6", ARKODE_SPRK_MCLACHLAN_5_6, "") - .value("ARKODE_SPRK_YOSHIDA_6_8", ARKODE_SPRK_YOSHIDA_6_8, "") - .value("ARKODE_SPRK_SUZUKI_UMENO_8_16", ARKODE_SPRK_SUZUKI_UMENO_8_16, "") - .value("ARKODE_SPRK_SOFRONIOU_10_36", ARKODE_SPRK_SOFRONIOU_10_36, "") - .value("ARKODE_MAX_SPRK_NUM", ARKODE_MAX_SPRK_NUM, "") + nb::enum_(m, "ARKODE_SPRKMethodID", nb::is_arithmetic(), "") + .value("ARKODE_SPRK_NONE", ARKODE_SPRK_NONE, "ensure enum is signed int") + .value("ARKODE_SPRK_EULER_1_1", ARKODE_SPRK_EULER_1_1, "") + .value("ARKODE_MIN_SPRK_NUM", ARKODE_MIN_SPRK_NUM, "") + .value("ARKODE_SPRK_LEAPFROG_2_2", ARKODE_SPRK_LEAPFROG_2_2, "") + .value("ARKODE_SPRK_PSEUDO_LEAPFROG_2_2", ARKODE_SPRK_PSEUDO_LEAPFROG_2_2, "") + .value("ARKODE_SPRK_RUTH_3_3", ARKODE_SPRK_RUTH_3_3, "") + .value("ARKODE_SPRK_MCLACHLAN_2_2", ARKODE_SPRK_MCLACHLAN_2_2, "") + .value("ARKODE_SPRK_MCLACHLAN_3_3", ARKODE_SPRK_MCLACHLAN_3_3, "") + .value("ARKODE_SPRK_CANDY_ROZMUS_4_4", ARKODE_SPRK_CANDY_ROZMUS_4_4, "") + .value("ARKODE_SPRK_MCLACHLAN_4_4", ARKODE_SPRK_MCLACHLAN_4_4, "") + .value("ARKODE_SPRK_MCLACHLAN_5_6", ARKODE_SPRK_MCLACHLAN_5_6, "") + .value("ARKODE_SPRK_YOSHIDA_6_8", ARKODE_SPRK_YOSHIDA_6_8, "") + .value("ARKODE_SPRK_SUZUKI_UMENO_8_16", ARKODE_SPRK_SUZUKI_UMENO_8_16, "") + .value("ARKODE_SPRK_SOFRONIOU_10_36", ARKODE_SPRK_SOFRONIOU_10_36, "") + .value("ARKODE_MAX_SPRK_NUM", ARKODE_MAX_SPRK_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - +// auto pyClassARKodeSPRKTableMem = - nb::class_ - (m, "ARKodeSPRKTableMem", "") + nb::class_(m, "ARKodeSPRKTableMem", "") .def(nb::init<>()) // implicit default constructor - ; - - -m.def("ARKodeSPRKTable_Create", - [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> std::shared_ptr> + ; + +m.def( + "ARKodeSPRKTable_Create", + [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) + -> std::shared_ptr> + { + auto ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector = + [](int s, int q, sundials4py::Array1d a_1d, + sundials4py::Array1d ahat_1d) -> ARKodeSPRKTable { - auto ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector = [](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> ARKodeSPRKTable - { - sunrealtype* a_1d_ptr = a_1d.size() == 0 ? nullptr : a_1d.data(); - sunrealtype* ahat_1d_ptr = ahat_1d.size() == 0 ? nullptr : ahat_1d.data(); - - auto lambda_result = ARKodeSPRKTable_Create(s, q, a_1d_ptr, ahat_1d_ptr); - return lambda_result; - }; - auto ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr = [&ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, sundials4py::Array1d a_1d, sundials4py::Array1d ahat_1d) -> std::shared_ptr> - { - auto lambda_result = ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector(s, q, a_1d, ahat_1d); - - return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr(s, q, a_1d, ahat_1d); - }, nb::arg("s"), nb::arg("q"), nb::arg("a_1d"), nb::arg("ahat_1d")); - -m.def("ARKodeSPRKTable_Load", - [](ARKODE_SPRKMethodID id) -> std::shared_ptr> + sunrealtype* a_1d_ptr = a_1d.size() == 0 ? nullptr : a_1d.data(); + sunrealtype* ahat_1d_ptr = ahat_1d.size() == 0 ? nullptr : ahat_1d.data(); + + auto lambda_result = ARKodeSPRKTable_Create(s, q, a_1d_ptr, ahat_1d_ptr); + return lambda_result; + }; + auto ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr = + [&ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector](int s, int q, + sundials4py::Array1d a_1d, + sundials4py::Array1d ahat_1d) + -> std::shared_ptr> { - auto ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr = [](ARKODE_SPRKMethodID id) -> std::shared_ptr> - { - auto lambda_result = ARKodeSPRKTable_Load(id); - - return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr(id); - }, nb::arg("id")); - -m.def("ARKodeSPRKTable_LoadByName", - [](const char * method) -> std::shared_ptr> + auto lambda_result = + ARKodeSPRKTable_Create_adapt_arr_ptr_to_std_vector(s, q, a_1d, ahat_1d); + + return our_make_shared, + ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr(s, q, a_1d, + ahat_1d); + }, + nb::arg("s"), nb::arg("q"), nb::arg("a_1d"), nb::arg("ahat_1d")); + +m.def( + "ARKodeSPRKTable_Load", + [](ARKODE_SPRKMethodID id) + -> std::shared_ptr> + { + auto ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr = + [](ARKODE_SPRKMethodID id) + -> std::shared_ptr> { - auto ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr = [](const char * method) -> std::shared_ptr> - { - auto lambda_result = ARKodeSPRKTable_LoadByName(method); - - return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr(method); - }, nb::arg("method")); - -m.def("ARKodeSPRKTable_Copy", - [](ARKodeSPRKTable that_sprk_storage) -> std::shared_ptr> + auto lambda_result = ARKodeSPRKTable_Load(id); + + return our_make_shared, + ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr(id); + }, + nb::arg("id")); + +m.def( + "ARKodeSPRKTable_LoadByName", + [](const char* method) -> std::shared_ptr> + { + auto ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr = + [](const char* method) + -> std::shared_ptr> { - auto ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr = [](ARKodeSPRKTable that_sprk_storage) -> std::shared_ptr> - { - auto lambda_result = ARKodeSPRKTable_Copy(that_sprk_storage); - - return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; - }; - - return ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr(that_sprk_storage); - }, nb::arg("that_sprk_storage")); - -m.def("ARKodeSPRKTable_Write", - ARKodeSPRKTable_Write, nb::arg("sprk_table"), nb::arg("outfile")); - -m.def("ARKodeSPRKTable_ToButcher", - [](ARKodeSPRKTable sprk_storage) -> std::tuple>, std::shared_ptr>> + auto lambda_result = ARKodeSPRKTable_LoadByName(method); + + return our_make_shared, + ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr(method); + }, + nb::arg("method")); + +m.def( + "ARKodeSPRKTable_Copy", + [](ARKodeSPRKTable that_sprk_storage) + -> std::shared_ptr> + { + auto ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr = + [](ARKodeSPRKTable that_sprk_storage) + -> std::shared_ptr> { - auto ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return = [](ARKodeSPRKTable sprk_storage) -> std::tuple - { - ARKodeButcherTable a_ptr_adapt_modifiable; - ARKodeButcherTable b_ptr_adapt_modifiable; - - int r = ARKodeSPRKTable_ToButcher(sprk_storage, &a_ptr_adapt_modifiable, &b_ptr_adapt_modifiable); - return std::make_tuple(r, a_ptr_adapt_modifiable, b_ptr_adapt_modifiable); - }; - auto ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr = [&ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return](ARKodeSPRKTable sprk_storage) -> std::tuple>, std::shared_ptr>> - { - auto lambda_result = ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return(sprk_storage); - - return std::make_tuple(std::get<0>(lambda_result), our_make_shared, ARKodeButcherTableDeleter>(std::get<1>(lambda_result)), our_make_shared, ARKodeButcherTableDeleter>(std::get<2>(lambda_result))); - return lambda_result; - }; - - return ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr(sprk_storage); - }, - nb::arg("sprk_storage"), - nb::rv_policy::reference); + auto lambda_result = ARKodeSPRKTable_Copy(that_sprk_storage); + + return our_make_shared, + ARKodeSPRKTableDeleter>(lambda_result); + return lambda_result; + }; + + return ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr(that_sprk_storage); + }, + nb::arg("that_sprk_storage")); + +m.def("ARKodeSPRKTable_Write", ARKodeSPRKTable_Write, nb::arg("sprk_table"), + nb::arg("outfile")); + +m.def( + "ARKodeSPRKTable_ToButcher", + [](ARKodeSPRKTable sprk_storage) + -> std::tuple>, + std::shared_ptr>> + { + auto ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return = + [](ARKodeSPRKTable sprk_storage) + -> std::tuple + { + ARKodeButcherTable a_ptr_adapt_modifiable; + ARKodeButcherTable b_ptr_adapt_modifiable; + + int r = ARKodeSPRKTable_ToButcher(sprk_storage, &a_ptr_adapt_modifiable, + &b_ptr_adapt_modifiable); + return std::make_tuple(r, a_ptr_adapt_modifiable, b_ptr_adapt_modifiable); + }; + auto ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr = + [&ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return]( + ARKodeSPRKTable sprk_storage) + -> std::tuple>, + std::shared_ptr>> + { + auto lambda_result = + ARKodeSPRKTable_ToButcher_adapt_modifiable_immutable_to_return( + sprk_storage); + + return std::make_tuple(std::get<0>(lambda_result), + our_make_shared, + ARKodeButcherTableDeleter>( + std::get<1>(lambda_result)), + our_make_shared, + ARKodeButcherTableDeleter>( + std::get<2>(lambda_result))); + return lambda_result; + }; + + return ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr(sprk_storage); + }, + nb::arg("sprk_storage"), nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp index 0818166a83..cae989c9fe 100644 --- a/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_lsrkstep_generated.hpp @@ -1,117 +1,138 @@ // #ifndef _LSRKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyEnumARKODE_LSRKMethodType = - nb::enum_(m, "ARKODE_LSRKMethodType", nb::is_arithmetic(), "") - .value("ARKODE_LSRK_RKC_2", ARKODE_LSRK_RKC_2, "") - .value("ARKODE_LSRK_RKL_2", ARKODE_LSRK_RKL_2, "") - .value("ARKODE_LSRK_SSP_S_2", ARKODE_LSRK_SSP_S_2, "") - .value("ARKODE_LSRK_SSP_S_3", ARKODE_LSRK_SSP_S_3, "") - .value("ARKODE_LSRK_SSP_10_4", ARKODE_LSRK_SSP_10_4, "") + nb::enum_(m, "ARKODE_LSRKMethodType", + nb::is_arithmetic(), "") + .value("ARKODE_LSRK_RKC_2", ARKODE_LSRK_RKC_2, "") + .value("ARKODE_LSRK_RKL_2", ARKODE_LSRK_RKL_2, "") + .value("ARKODE_LSRK_SSP_S_2", ARKODE_LSRK_SSP_S_2, "") + .value("ARKODE_LSRK_SSP_S_3", ARKODE_LSRK_SSP_S_3, "") + .value("ARKODE_LSRK_SSP_10_4", ARKODE_LSRK_SSP_10_4, "") .export_values(); // #ifndef SWIG -// +// // #endif -// +// -m.def("LSRKStepSetSTSMethod", - LSRKStepSetSTSMethod, nb::arg("arkode_mem"), nb::arg("method")); +m.def("LSRKStepSetSTSMethod", LSRKStepSetSTSMethod, nb::arg("arkode_mem"), + nb::arg("method")); -m.def("LSRKStepSetSSPMethod", - LSRKStepSetSSPMethod, nb::arg("arkode_mem"), nb::arg("method")); +m.def("LSRKStepSetSSPMethod", LSRKStepSetSSPMethod, nb::arg("arkode_mem"), + nb::arg("method")); -m.def("LSRKStepSetSTSMethodByName", - LSRKStepSetSTSMethodByName, nb::arg("arkode_mem"), nb::arg("emethod")); +m.def("LSRKStepSetSTSMethodByName", LSRKStepSetSTSMethodByName, + nb::arg("arkode_mem"), nb::arg("emethod")); -m.def("LSRKStepSetSSPMethodByName", - LSRKStepSetSSPMethodByName, nb::arg("arkode_mem"), nb::arg("emethod")); +m.def("LSRKStepSetSSPMethodByName", LSRKStepSetSSPMethodByName, + nb::arg("arkode_mem"), nb::arg("emethod")); -m.def("LSRKStepSetDomEigEstimator", - LSRKStepSetDomEigEstimator, nb::arg("arkode_mem"), nb::arg("DEE")); +m.def("LSRKStepSetDomEigEstimator", LSRKStepSetDomEigEstimator, + nb::arg("arkode_mem"), nb::arg("DEE")); -m.def("LSRKStepSetDomEigFrequency", - LSRKStepSetDomEigFrequency, nb::arg("arkode_mem"), nb::arg("nsteps")); +m.def("LSRKStepSetDomEigFrequency", LSRKStepSetDomEigFrequency, + nb::arg("arkode_mem"), nb::arg("nsteps")); -m.def("LSRKStepSetMaxNumStages", - LSRKStepSetMaxNumStages, nb::arg("arkode_mem"), nb::arg("stage_max_limit")); +m.def("LSRKStepSetMaxNumStages", LSRKStepSetMaxNumStages, nb::arg("arkode_mem"), + nb::arg("stage_max_limit")); -m.def("LSRKStepSetDomEigSafetyFactor", - LSRKStepSetDomEigSafetyFactor, nb::arg("arkode_mem"), nb::arg("dom_eig_safety")); +m.def("LSRKStepSetDomEigSafetyFactor", LSRKStepSetDomEigSafetyFactor, + nb::arg("arkode_mem"), nb::arg("dom_eig_safety")); -m.def("LSRKStepSetUseAnalyticStabRegion", - LSRKStepSetUseAnalyticStabRegion, nb::arg("arkode_mem"), nb::arg("analytic_stab_region")); +m.def("LSRKStepSetUseAnalyticStabRegion", LSRKStepSetUseAnalyticStabRegion, + nb::arg("arkode_mem"), nb::arg("analytic_stab_region")); m.def("LSRKStepSetNumDomEigEstInitPreprocessIters", - LSRKStepSetNumDomEigEstInitPreprocessIters, nb::arg("arkode_mem"), nb::arg("num_iters")); + LSRKStepSetNumDomEigEstInitPreprocessIters, nb::arg("arkode_mem"), + nb::arg("num_iters")); m.def("LSRKStepSetNumDomEigEstPreprocessIters", - LSRKStepSetNumDomEigEstPreprocessIters, nb::arg("arkode_mem"), nb::arg("num_iters")); - -m.def("LSRKStepSetNumSSPStages", - LSRKStepSetNumSSPStages, nb::arg("arkode_mem"), nb::arg("num_of_stages")); - -m.def("LSRKStepGetNumDomEigUpdates", - [](void * arkode_mem) -> std::tuple + LSRKStepSetNumDomEigEstPreprocessIters, nb::arg("arkode_mem"), + nb::arg("num_iters")); + +m.def("LSRKStepSetNumSSPStages", LSRKStepSetNumSSPStages, nb::arg("arkode_mem"), + nb::arg("num_of_stages")); + +m.def( + "LSRKStepGetNumDomEigUpdates", + [](void* arkode_mem) -> std::tuple + { + auto LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long dom_eig_num_evals_adapt_modifiable; - - int r = LSRKStepGetNumDomEigUpdates(arkode_mem, &dom_eig_num_evals_adapt_modifiable); - return std::make_tuple(r, dom_eig_num_evals_adapt_modifiable); - }; - - return LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("LSRKStepGetMaxNumStages", - [](void * arkode_mem) -> std::tuple + long dom_eig_num_evals_adapt_modifiable; + + int r = LSRKStepGetNumDomEigUpdates(arkode_mem, + &dom_eig_num_evals_adapt_modifiable); + return std::make_tuple(r, dom_eig_num_evals_adapt_modifiable); + }; + + return LSRKStepGetNumDomEigUpdates_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "LSRKStepGetMaxNumStages", + [](void* arkode_mem) -> std::tuple + { + auto LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - int stage_max_adapt_modifiable; - - int r = LSRKStepGetMaxNumStages(arkode_mem, &stage_max_adapt_modifiable); - return std::make_tuple(r, stage_max_adapt_modifiable); - }; - - return LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("LSRKStepGetNumDomEigEstRhsEvals", - [](void * arkode_mem) -> std::tuple + int stage_max_adapt_modifiable; + + int r = LSRKStepGetMaxNumStages(arkode_mem, &stage_max_adapt_modifiable); + return std::make_tuple(r, stage_max_adapt_modifiable); + }; + + return LSRKStepGetMaxNumStages_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "LSRKStepGetNumDomEigEstRhsEvals", + [](void* arkode_mem) -> std::tuple + { + auto LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long nfeDQ_adapt_modifiable; - - int r = LSRKStepGetNumDomEigEstRhsEvals(arkode_mem, &nfeDQ_adapt_modifiable); - return std::make_tuple(r, nfeDQ_adapt_modifiable); - }; - - return LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("LSRKStepGetNumDomEigEstIters", - [](void * arkode_mem) -> std::tuple + long nfeDQ_adapt_modifiable; + + int r = LSRKStepGetNumDomEigEstRhsEvals(arkode_mem, + &nfeDQ_adapt_modifiable); + return std::make_tuple(r, nfeDQ_adapt_modifiable); + }; + + return LSRKStepGetNumDomEigEstRhsEvals_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "LSRKStepGetNumDomEigEstIters", + [](void* arkode_mem) -> std::tuple + { + auto LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long num_iters_adapt_modifiable; + long num_iters_adapt_modifiable; - int r = LSRKStepGetNumDomEigEstIters(arkode_mem, &num_iters_adapt_modifiable); - return std::make_tuple(r, num_iters_adapt_modifiable); - }; + int r = LSRKStepGetNumDomEigEstIters(arkode_mem, + &num_iters_adapt_modifiable); + return std::make_tuple(r, num_iters_adapt_modifiable); + }; - return LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return LSRKStepGetNumDomEigEstIters_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp index 1572fa3c41..193832192d 100644 --- a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp @@ -1,208 +1,255 @@ // #ifndef _MRISTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyEnumMRISTEP_METHOD_TYPE = - nb::enum_(m, "MRISTEP_METHOD_TYPE", nb::is_arithmetic(), "") - .value("MRISTEP_EXPLICIT", MRISTEP_EXPLICIT, "") - .value("MRISTEP_IMPLICIT", MRISTEP_IMPLICIT, "") - .value("MRISTEP_IMEX", MRISTEP_IMEX, "") - .value("MRISTEP_MERK", MRISTEP_MERK, "") - .value("MRISTEP_SR", MRISTEP_SR, "") + nb::enum_(m, "MRISTEP_METHOD_TYPE", nb::is_arithmetic(), "") + .value("MRISTEP_EXPLICIT", MRISTEP_EXPLICIT, "") + .value("MRISTEP_IMPLICIT", MRISTEP_IMPLICIT, "") + .value("MRISTEP_IMEX", MRISTEP_IMEX, "") + .value("MRISTEP_MERK", MRISTEP_MERK, "") + .value("MRISTEP_SR", MRISTEP_SR, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - +// auto pyEnumARKODE_MRITableID = - nb::enum_(m, "ARKODE_MRITableID", nb::is_arithmetic(), "MRI coupling table IDs") - .value("ARKODE_MRI_NONE", ARKODE_MRI_NONE, "ensure enum is signed int") - .value("ARKODE_MIS_KW3", ARKODE_MIS_KW3, "") - .value("ARKODE_MIN_MRI_NUM", ARKODE_MIN_MRI_NUM, "") - .value("ARKODE_MRI_GARK_ERK33a", ARKODE_MRI_GARK_ERK33a, "") - .value("ARKODE_MRI_GARK_ERK45a", ARKODE_MRI_GARK_ERK45a, "") - .value("ARKODE_MRI_GARK_IRK21a", ARKODE_MRI_GARK_IRK21a, "") - .value("ARKODE_MRI_GARK_ESDIRK34a", ARKODE_MRI_GARK_ESDIRK34a, "") - .value("ARKODE_MRI_GARK_ESDIRK46a", ARKODE_MRI_GARK_ESDIRK46a, "") - .value("ARKODE_IMEX_MRI_GARK3a", ARKODE_IMEX_MRI_GARK3a, "") - .value("ARKODE_IMEX_MRI_GARK3b", ARKODE_IMEX_MRI_GARK3b, "") - .value("ARKODE_IMEX_MRI_GARK4", ARKODE_IMEX_MRI_GARK4, "") - .value("ARKODE_MRI_GARK_FORWARD_EULER", ARKODE_MRI_GARK_FORWARD_EULER, "") - .value("ARKODE_MRI_GARK_RALSTON2", ARKODE_MRI_GARK_RALSTON2, "") - .value("ARKODE_MRI_GARK_ERK22a", ARKODE_MRI_GARK_ERK22a, "") - .value("ARKODE_MRI_GARK_ERK22b", ARKODE_MRI_GARK_ERK22b, "") - .value("ARKODE_MRI_GARK_RALSTON3", ARKODE_MRI_GARK_RALSTON3, "") - .value("ARKODE_MRI_GARK_BACKWARD_EULER", ARKODE_MRI_GARK_BACKWARD_EULER, "") - .value("ARKODE_MRI_GARK_IMPLICIT_MIDPOINT", ARKODE_MRI_GARK_IMPLICIT_MIDPOINT, "") - .value("ARKODE_IMEX_MRI_GARK_EULER", ARKODE_IMEX_MRI_GARK_EULER, "") - .value("ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL", ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL, "") - .value("ARKODE_IMEX_MRI_GARK_MIDPOINT", ARKODE_IMEX_MRI_GARK_MIDPOINT, "") - .value("ARKODE_MERK21", ARKODE_MERK21, "") - .value("ARKODE_MERK32", ARKODE_MERK32, "") - .value("ARKODE_MERK43", ARKODE_MERK43, "") - .value("ARKODE_MERK54", ARKODE_MERK54, "") - .value("ARKODE_IMEX_MRI_SR21", ARKODE_IMEX_MRI_SR21, "") - .value("ARKODE_IMEX_MRI_SR32", ARKODE_IMEX_MRI_SR32, "") - .value("ARKODE_IMEX_MRI_SR43", ARKODE_IMEX_MRI_SR43, "") - .value("ARKODE_MAX_MRI_NUM", ARKODE_MAX_MRI_NUM, "") + nb::enum_(m, "ARKODE_MRITableID", nb::is_arithmetic(), + "MRI coupling table IDs") + .value("ARKODE_MRI_NONE", ARKODE_MRI_NONE, "ensure enum is signed int") + .value("ARKODE_MIS_KW3", ARKODE_MIS_KW3, "") + .value("ARKODE_MIN_MRI_NUM", ARKODE_MIN_MRI_NUM, "") + .value("ARKODE_MRI_GARK_ERK33a", ARKODE_MRI_GARK_ERK33a, "") + .value("ARKODE_MRI_GARK_ERK45a", ARKODE_MRI_GARK_ERK45a, "") + .value("ARKODE_MRI_GARK_IRK21a", ARKODE_MRI_GARK_IRK21a, "") + .value("ARKODE_MRI_GARK_ESDIRK34a", ARKODE_MRI_GARK_ESDIRK34a, "") + .value("ARKODE_MRI_GARK_ESDIRK46a", ARKODE_MRI_GARK_ESDIRK46a, "") + .value("ARKODE_IMEX_MRI_GARK3a", ARKODE_IMEX_MRI_GARK3a, "") + .value("ARKODE_IMEX_MRI_GARK3b", ARKODE_IMEX_MRI_GARK3b, "") + .value("ARKODE_IMEX_MRI_GARK4", ARKODE_IMEX_MRI_GARK4, "") + .value("ARKODE_MRI_GARK_FORWARD_EULER", ARKODE_MRI_GARK_FORWARD_EULER, "") + .value("ARKODE_MRI_GARK_RALSTON2", ARKODE_MRI_GARK_RALSTON2, "") + .value("ARKODE_MRI_GARK_ERK22a", ARKODE_MRI_GARK_ERK22a, "") + .value("ARKODE_MRI_GARK_ERK22b", ARKODE_MRI_GARK_ERK22b, "") + .value("ARKODE_MRI_GARK_RALSTON3", ARKODE_MRI_GARK_RALSTON3, "") + .value("ARKODE_MRI_GARK_BACKWARD_EULER", ARKODE_MRI_GARK_BACKWARD_EULER, "") + .value("ARKODE_MRI_GARK_IMPLICIT_MIDPOINT", + ARKODE_MRI_GARK_IMPLICIT_MIDPOINT, "") + .value("ARKODE_IMEX_MRI_GARK_EULER", ARKODE_IMEX_MRI_GARK_EULER, "") + .value("ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL", ARKODE_IMEX_MRI_GARK_TRAPEZOIDAL, + "") + .value("ARKODE_IMEX_MRI_GARK_MIDPOINT", ARKODE_IMEX_MRI_GARK_MIDPOINT, "") + .value("ARKODE_MERK21", ARKODE_MERK21, "") + .value("ARKODE_MERK32", ARKODE_MERK32, "") + .value("ARKODE_MERK43", ARKODE_MERK43, "") + .value("ARKODE_MERK54", ARKODE_MERK54, "") + .value("ARKODE_IMEX_MRI_SR21", ARKODE_IMEX_MRI_SR21, "") + .value("ARKODE_IMEX_MRI_SR32", ARKODE_IMEX_MRI_SR32, "") + .value("ARKODE_IMEX_MRI_SR43", ARKODE_IMEX_MRI_SR43, "") + .value("ARKODE_MAX_MRI_NUM", ARKODE_MAX_MRI_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - +// auto pyClassMRIStepCouplingMem = - nb::class_ - (m, "MRIStepCouplingMem", "") + nb::class_(m, "MRIStepCouplingMem", "") .def(nb::init<>()) // implicit default constructor - ; - - -m.def("MRIStepCoupling_LoadTable", - [](ARKODE_MRITableID method) -> std::shared_ptr> + ; + +m.def( + "MRIStepCoupling_LoadTable", + [](ARKODE_MRITableID method) + -> std::shared_ptr> + { + auto MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr = + [](ARKODE_MRITableID method) + -> std::shared_ptr> { - auto MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr = [](ARKODE_MRITableID method) -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_LoadTable(method); - - return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; - }; - - return MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr(method); - }, - nb::arg("method"), - "Accessor routine to load built-in MRI table"); - -m.def("MRIStepCoupling_LoadTableByName", - [](const char * method) -> std::shared_ptr> + auto lambda_result = MRIStepCoupling_LoadTable(method); + + return our_make_shared, + MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr(method); + }, + nb::arg("method"), "Accessor routine to load built-in MRI table"); + +m.def( + "MRIStepCoupling_LoadTableByName", + [](const char* method) -> std::shared_ptr> + { + auto MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr = + [](const char* method) + -> std::shared_ptr> { - auto MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr = [](const char * method) -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_LoadTableByName(method); - - return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; - }; - - return MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr(method); - }, - nb::arg("method"), - "Accessor routine to load built-in MRI table from string"); - -m.def("MRIStepCoupling_Create", - [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> std::shared_ptr> + auto lambda_result = MRIStepCoupling_LoadTableByName(method); + + return our_make_shared, + MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr(method); + }, + nb::arg("method"), "Accessor routine to load built-in MRI table from string"); + +m.def( + "MRIStepCoupling_Create", + [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, + sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) + -> std::shared_ptr> + { + auto MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector = + [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, + sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> MRIStepCoupling { - auto MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector = [](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> MRIStepCoupling - { - sunrealtype* W_1d_ptr = W_1d.size() == 0 ? nullptr : W_1d.data(); - sunrealtype* G_1d_ptr = G_1d.size() == 0 ? nullptr : G_1d.data(); - sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); - - auto lambda_result = MRIStepCoupling_Create(nmat, stages, q, p, W_1d_ptr, G_1d_ptr, c_1d_ptr); - return lambda_result; - }; - auto MRIStepCoupling_Create_adapt_return_type_to_shared_ptr = [&MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector](int nmat, int stages, int q, int p, sundials4py::Array1d W_1d, sundials4py::Array1d G_1d, sundials4py::Array1d c_1d) -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector(nmat, stages, q, p, W_1d, G_1d, c_1d); - - return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; - }; - - return MRIStepCoupling_Create_adapt_return_type_to_shared_ptr(nmat, stages, q, p, W_1d, G_1d, c_1d); - }, nb::arg("nmat"), nb::arg("stages"), nb::arg("q"), nb::arg("p"), nb::arg("W_1d"), nb::arg("G_1d"), nb::arg("c_1d")); - -m.def("MRIStepCoupling_MIStoMRI", - [](ARKodeButcherTable B, int q, int p) -> std::shared_ptr> + sunrealtype* W_1d_ptr = W_1d.size() == 0 ? nullptr : W_1d.data(); + sunrealtype* G_1d_ptr = G_1d.size() == 0 ? nullptr : G_1d.data(); + sunrealtype* c_1d_ptr = c_1d.size() == 0 ? nullptr : c_1d.data(); + + auto lambda_result = MRIStepCoupling_Create(nmat, stages, q, p, W_1d_ptr, + G_1d_ptr, c_1d_ptr); + return lambda_result; + }; + auto MRIStepCoupling_Create_adapt_return_type_to_shared_ptr = + [&MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector](int nmat, int stages, + int q, int p, + sundials4py::Array1d W_1d, + sundials4py::Array1d G_1d, + sundials4py::Array1d c_1d) + -> std::shared_ptr> { - auto MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr = [](ARKodeButcherTable B, int q, int p) -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_MIStoMRI(B, q, p); - - return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; - }; - - return MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr(B, q, p); - }, nb::arg("B"), nb::arg("q"), nb::arg("p")); - -m.def("MRIStepCoupling_Copy", - [](MRIStepCoupling MRIC) -> std::shared_ptr> + auto lambda_result = + MRIStepCoupling_Create_adapt_arr_ptr_to_std_vector(nmat, stages, q, p, + W_1d, G_1d, c_1d); + + return our_make_shared, + MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_Create_adapt_return_type_to_shared_ptr(nmat, stages, + q, p, W_1d, + G_1d, c_1d); + }, + nb::arg("nmat"), nb::arg("stages"), nb::arg("q"), nb::arg("p"), + nb::arg("W_1d"), nb::arg("G_1d"), nb::arg("c_1d")); + +m.def( + "MRIStepCoupling_MIStoMRI", + [](ARKodeButcherTable B, int q, + int p) -> std::shared_ptr> + { + auto MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr = + [](ARKodeButcherTable B, int q, + int p) -> std::shared_ptr> { - auto MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr = [](MRIStepCoupling MRIC) -> std::shared_ptr> - { - auto lambda_result = MRIStepCoupling_Copy(MRIC); + auto lambda_result = MRIStepCoupling_MIStoMRI(B, q, p); + + return our_make_shared, + MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; + + return MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr(B, q, p); + }, + nb::arg("B"), nb::arg("q"), nb::arg("p")); + +m.def( + "MRIStepCoupling_Copy", + [](MRIStepCoupling MRIC) -> std::shared_ptr> + { + auto MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr = + [](MRIStepCoupling MRIC) + -> std::shared_ptr> + { + auto lambda_result = MRIStepCoupling_Copy(MRIC); - return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; - }; + return our_make_shared, + MRIStepCouplingDeleter>(lambda_result); + return lambda_result; + }; - return MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr(MRIC); - }, nb::arg("MRIC")); + return MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr(MRIC); + }, + nb::arg("MRIC")); -m.def("MRIStepCoupling_Write", - MRIStepCoupling_Write, nb::arg("MRIC"), nb::arg("outfile")); +m.def("MRIStepCoupling_Write", MRIStepCoupling_Write, nb::arg("MRIC"), + nb::arg("outfile")); -m.def("MRIStepSetCoupling", - MRIStepSetCoupling, nb::arg("arkode_mem"), nb::arg("MRIC")); +m.def("MRIStepSetCoupling", MRIStepSetCoupling, nb::arg("arkode_mem"), + nb::arg("MRIC")); -m.def("MRIStepGetCurrentCoupling", - [](void * arkode_mem) -> std::tuple +m.def( + "MRIStepGetCurrentCoupling", + [](void* arkode_mem) -> std::tuple + { + auto MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - MRIStepCoupling MRIC_adapt_modifiable; - - int r = MRIStepGetCurrentCoupling(arkode_mem, &MRIC_adapt_modifiable); - return std::make_tuple(r, MRIC_adapt_modifiable); - }; - - return MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - " Optional output functions\n\n nb::rv_policy::reference", - nb::rv_policy::reference); - -m.def("MRIStepGetLastInnerStepFlag", - [](void * arkode_mem) -> std::tuple + MRIStepCoupling MRIC_adapt_modifiable; + + int r = MRIStepGetCurrentCoupling(arkode_mem, &MRIC_adapt_modifiable); + return std::make_tuple(r, MRIC_adapt_modifiable); + }; + + return MRIStepGetCurrentCoupling_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), + " Optional output functions\n\n nb::rv_policy::reference", + nb::rv_policy::reference); + +m.def( + "MRIStepGetLastInnerStepFlag", + [](void* arkode_mem) -> std::tuple + { + auto MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - int flag_adapt_modifiable; - - int r = MRIStepGetLastInnerStepFlag(arkode_mem, &flag_adapt_modifiable); - return std::make_tuple(r, flag_adapt_modifiable); - }; - - return MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); - -m.def("MRIStepGetNumInnerStepperFails", - [](void * arkode_mem) -> std::tuple + int flag_adapt_modifiable; + + int r = MRIStepGetLastInnerStepFlag(arkode_mem, &flag_adapt_modifiable); + return std::make_tuple(r, flag_adapt_modifiable); + }; + + return MRIStepGetLastInnerStepFlag_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "MRIStepGetNumInnerStepperFails", + [](void* arkode_mem) -> std::tuple + { + auto MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - long inner_fails_adapt_modifiable; + long inner_fails_adapt_modifiable; - int r = MRIStepGetNumInnerStepperFails(arkode_mem, &inner_fails_adapt_modifiable); - return std::make_tuple(r, inner_fails_adapt_modifiable); - }; + int r = MRIStepGetNumInnerStepperFails(arkode_mem, + &inner_fails_adapt_modifiable); + return std::make_tuple(r, inner_fails_adapt_modifiable); + }; - return MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return(arkode_mem); - }, nb::arg("arkode_mem")); + return MRIStepGetNumInnerStepperFails_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); -m.def("MRIStepInnerStepper_AddForcing", - MRIStepInnerStepper_AddForcing, nb::arg("stepper"), nb::arg("t"), nb::arg("f")); +m.def("MRIStepInnerStepper_AddForcing", MRIStepInnerStepper_AddForcing, + nb::arg("stepper"), nb::arg("t"), nb::arg("f")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp index b00416c49f..2ec392aa67 100644 --- a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp @@ -1,222 +1,331 @@ // #ifndef ARKODE_SPLITTINGSTEP_H_ -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyClassSplittingStepCoefficientsMem = - nb::class_ - (m, "SplittingStepCoefficientsMem", "") + nb::class_(m, "SplittingStepCoefficientsMem", "") .def(nb::init<>()) // implicit default constructor - ; - + ; auto pyEnumARKODE_SplittingCoefficientsID = - nb::enum_(m, "ARKODE_SplittingCoefficientsID", nb::is_arithmetic(), "") - .value("ARKODE_SPLITTING_NONE", ARKODE_SPLITTING_NONE, "ensure enum is signed int") - .value("ARKODE_SPLITTING_LIE_TROTTER_1_1_2", ARKODE_SPLITTING_LIE_TROTTER_1_1_2, "") - .value("ARKODE_MIN_SPLITTING_NUM", ARKODE_MIN_SPLITTING_NUM, "") - .value("ARKODE_SPLITTING_STRANG_2_2_2", ARKODE_SPLITTING_STRANG_2_2_2, "") - .value("ARKODE_SPLITTING_BEST_2_2_2", ARKODE_SPLITTING_BEST_2_2_2, "") - .value("ARKODE_SPLITTING_SUZUKI_3_3_2", ARKODE_SPLITTING_SUZUKI_3_3_2, "") - .value("ARKODE_SPLITTING_RUTH_3_3_2", ARKODE_SPLITTING_RUTH_3_3_2, "") - .value("ARKODE_SPLITTING_YOSHIDA_4_4_2", ARKODE_SPLITTING_YOSHIDA_4_4_2, "") - .value("ARKODE_SPLITTING_YOSHIDA_8_6_2", ARKODE_SPLITTING_YOSHIDA_8_6_2, "") - .value("ARKODE_MAX_SPLITTING_NUM", ARKODE_MAX_SPLITTING_NUM, "") + nb::enum_(m, "ARKODE_SplittingCoefficientsID", + nb::is_arithmetic(), "") + .value("ARKODE_SPLITTING_NONE", ARKODE_SPLITTING_NONE, + "ensure enum is signed int") + .value("ARKODE_SPLITTING_LIE_TROTTER_1_1_2", + ARKODE_SPLITTING_LIE_TROTTER_1_1_2, "") + .value("ARKODE_MIN_SPLITTING_NUM", ARKODE_MIN_SPLITTING_NUM, "") + .value("ARKODE_SPLITTING_STRANG_2_2_2", ARKODE_SPLITTING_STRANG_2_2_2, "") + .value("ARKODE_SPLITTING_BEST_2_2_2", ARKODE_SPLITTING_BEST_2_2_2, "") + .value("ARKODE_SPLITTING_SUZUKI_3_3_2", ARKODE_SPLITTING_SUZUKI_3_3_2, "") + .value("ARKODE_SPLITTING_RUTH_3_3_2", ARKODE_SPLITTING_RUTH_3_3_2, "") + .value("ARKODE_SPLITTING_YOSHIDA_4_4_2", ARKODE_SPLITTING_YOSHIDA_4_4_2, "") + .value("ARKODE_SPLITTING_YOSHIDA_8_6_2", ARKODE_SPLITTING_YOSHIDA_8_6_2, "") + .value("ARKODE_MAX_SPLITTING_NUM", ARKODE_MAX_SPLITTING_NUM, "") .export_values(); // #ifndef SWIG -// +// // #endif -// - -m.def("SplittingStepCoefficients_Create", - [](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> std::shared_ptr> +// + +m.def( + "SplittingStepCoefficients_Create", + [](int sequential_methods, int stages, int partitions, int order, + sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector = + [](int sequential_methods, int stages, int partitions, int order, + sundials4py::Array1d alpha_1d, + sundials4py::Array1d beta_1d) -> SplittingStepCoefficients { - auto SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector = [](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> SplittingStepCoefficients - { - sunrealtype* alpha_1d_ptr = alpha_1d.size() == 0 ? nullptr : alpha_1d.data(); - sunrealtype* beta_1d_ptr = beta_1d.size() == 0 ? nullptr : beta_1d.data(); - - auto lambda_result = SplittingStepCoefficients_Create(sequential_methods, stages, partitions, order, alpha_1d_ptr, beta_1d_ptr); - return lambda_result; - }; - auto SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr = [&SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector](int sequential_methods, int stages, int partitions, int order, sundials4py::Array1d alpha_1d, sundials4py::Array1d beta_1d) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector(sequential_methods, stages, partitions, order, alpha_1d, beta_1d); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr(sequential_methods, stages, partitions, order, alpha_1d, beta_1d); - }, nb::arg("sequential_methods"), nb::arg("stages"), nb::arg("partitions"), nb::arg("order"), nb::arg("alpha_1d"), nb::arg("beta_1d")); - -m.def("SplittingStepCoefficients_Copy", - [](SplittingStepCoefficients coefficients) -> std::shared_ptr> + sunrealtype* alpha_1d_ptr = alpha_1d.size() == 0 ? nullptr + : alpha_1d.data(); + sunrealtype* beta_1d_ptr = beta_1d.size() == 0 ? nullptr : beta_1d.data(); + + auto lambda_result = + SplittingStepCoefficients_Create(sequential_methods, stages, partitions, + order, alpha_1d_ptr, beta_1d_ptr); + return lambda_result; + }; + auto SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr = + [&SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector](int sequential_methods, + int stages, + int partitions, + int order, + sundials4py::Array1d + alpha_1d, + sundials4py::Array1d + beta_1d) + -> std::shared_ptr> { - auto SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr = [](SplittingStepCoefficients coefficients) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_Copy(coefficients); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr(coefficients); - }, nb::arg("coefficients")); - -m.def("SplittingStepCoefficients_Write", - SplittingStepCoefficients_Write, nb::arg("coefficients"), nb::arg("outfile")); - -m.def("SplittingStepCoefficients_LoadCoefficients", - [](ARKODE_SplittingCoefficientsID id) -> std::shared_ptr> + auto lambda_result = + SplittingStepCoefficients_Create_adapt_arr_ptr_to_std_vector(sequential_methods, + stages, + partitions, + order, + alpha_1d, + beta_1d); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr(sequential_methods, + stages, + partitions, + order, + alpha_1d, + beta_1d); + }, + nb::arg("sequential_methods"), nb::arg("stages"), nb::arg("partitions"), + nb::arg("order"), nb::arg("alpha_1d"), nb::arg("beta_1d")); + +m.def( + "SplittingStepCoefficients_Copy", + [](SplittingStepCoefficients coefficients) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr = + [](SplittingStepCoefficients coefficients) + -> std::shared_ptr> { - auto SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr = [](ARKODE_SplittingCoefficientsID id) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_LoadCoefficients(id); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr(id); - }, nb::arg("id")); - -m.def("SplittingStepCoefficients_LoadCoefficientsByName", - [](const char * name) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_Copy(coefficients); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr( + coefficients); + }, + nb::arg("coefficients")); + +m.def("SplittingStepCoefficients_Write", SplittingStepCoefficients_Write, + nb::arg("coefficients"), nb::arg("outfile")); + +m.def( + "SplittingStepCoefficients_LoadCoefficients", + [](ARKODE_SplittingCoefficientsID id) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr = + [](ARKODE_SplittingCoefficientsID id) + -> std::shared_ptr> { - auto SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr = [](const char * name) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_LoadCoefficientsByName(name); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr(name); - }, nb::arg("name")); - -m.def("SplittingStepCoefficients_IDToName", - SplittingStepCoefficients_IDToName, nb::arg("id")); - -m.def("SplittingStepCoefficients_LieTrotter", - [](int partitions) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_LoadCoefficients(id); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr( + id); + }, + nb::arg("id")); + +m.def( + "SplittingStepCoefficients_LoadCoefficientsByName", + [](const char* name) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr = + [](const char* name) + -> std::shared_ptr> { - auto SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_LieTrotter(partitions); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr(partitions); - }, nb::arg("partitions")); - -m.def("SplittingStepCoefficients_Strang", - [](int partitions) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_LoadCoefficientsByName(name); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr( + name); + }, + nb::arg("name")); + +m.def("SplittingStepCoefficients_IDToName", SplittingStepCoefficients_IDToName, + nb::arg("id")); + +m.def( + "SplittingStepCoefficients_LieTrotter", + [](int partitions) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr = + [](int partitions) + -> std::shared_ptr> { - auto SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_Strang(partitions); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr(partitions); - }, nb::arg("partitions")); - -m.def("SplittingStepCoefficients_Parallel", - [](int partitions) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_LieTrotter(partitions); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr( + partitions); + }, + nb::arg("partitions")); + +m.def( + "SplittingStepCoefficients_Strang", + [](int partitions) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr = + [](int partitions) + -> std::shared_ptr> { - auto SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_Parallel(partitions); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr(partitions); - }, nb::arg("partitions")); - -m.def("SplittingStepCoefficients_SymmetricParallel", - [](int partitions) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_Strang(partitions); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr( + partitions); + }, + nb::arg("partitions")); + +m.def( + "SplittingStepCoefficients_Parallel", + [](int partitions) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr = + [](int partitions) + -> std::shared_ptr> { - auto SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_SymmetricParallel(partitions); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr(partitions); - }, nb::arg("partitions")); - -m.def("SplittingStepCoefficients_ThirdOrderSuzuki", - [](int partitions) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_Parallel(partitions); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr( + partitions); + }, + nb::arg("partitions")); + +m.def( + "SplittingStepCoefficients_SymmetricParallel", + [](int partitions) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr = + [](int partitions) + -> std::shared_ptr> { - auto SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr = [](int partitions) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr(partitions); - }, nb::arg("partitions")); - -m.def("SplittingStepCoefficients_TripleJump", - [](int partitions, int order) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_SymmetricParallel(partitions); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr( + partitions); + }, + nb::arg("partitions")); + +m.def( + "SplittingStepCoefficients_ThirdOrderSuzuki", + [](int partitions) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr = + [](int partitions) + -> std::shared_ptr> { - auto SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr = [](int partitions, int order) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_TripleJump(partitions, order); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr(partitions, order); - }, nb::arg("partitions"), nb::arg("order")); - -m.def("SplittingStepCoefficients_SuzukiFractal", - [](int partitions, int order) -> std::shared_ptr> + auto lambda_result = SplittingStepCoefficients_ThirdOrderSuzuki(partitions); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr( + partitions); + }, + nb::arg("partitions")); + +m.def( + "SplittingStepCoefficients_TripleJump", + [](int partitions, int order) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr = + [](int partitions, int order) + -> std::shared_ptr> { - auto SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr = [](int partitions, int order) -> std::shared_ptr> - { - auto lambda_result = SplittingStepCoefficients_SuzukiFractal(partitions, order); - - return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; - }; - - return SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr(partitions, order); - }, nb::arg("partitions"), nb::arg("order")); - -m.def("SplittingStepSetCoefficients", - SplittingStepSetCoefficients, nb::arg("arkode_mem"), nb::arg("coefficients")); - -m.def("SplittingStepGetNumEvolves", - [](void * arkode_mem, int partition) -> std::tuple + auto lambda_result = SplittingStepCoefficients_TripleJump(partitions, + order); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr(partitions, + order); + }, + nb::arg("partitions"), nb::arg("order")); + +m.def( + "SplittingStepCoefficients_SuzukiFractal", + [](int partitions, int order) + -> std::shared_ptr> + { + auto SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr = + [](int partitions, int order) + -> std::shared_ptr> + { + auto lambda_result = SplittingStepCoefficients_SuzukiFractal(partitions, + order); + + return our_make_shared, + SplittingStepCoefficientsDeleter>(lambda_result); + return lambda_result; + }; + + return SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr(partitions, + order); + }, + nb::arg("partitions"), nb::arg("order")); + +m.def("SplittingStepSetCoefficients", SplittingStepSetCoefficients, + nb::arg("arkode_mem"), nb::arg("coefficients")); + +m.def( + "SplittingStepGetNumEvolves", + [](void* arkode_mem, int partition) -> std::tuple + { + auto SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return = + [](void* arkode_mem, int partition) -> std::tuple { - auto SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return = [](void * arkode_mem, int partition) -> std::tuple - { - long evolves_adapt_modifiable; + long evolves_adapt_modifiable; - int r = SplittingStepGetNumEvolves(arkode_mem, partition, &evolves_adapt_modifiable); - return std::make_tuple(r, evolves_adapt_modifiable); - }; + int r = SplittingStepGetNumEvolves(arkode_mem, partition, + &evolves_adapt_modifiable); + return std::make_tuple(r, evolves_adapt_modifiable); + }; - return SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, partition); - }, nb::arg("arkode_mem"), nb::arg("partition")); + return SplittingStepGetNumEvolves_adapt_modifiable_immutable_to_return(arkode_mem, + partition); + }, + nb::arg("arkode_mem"), nb::arg("partition")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp b/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp index 42e3129fb9..1d92ba3019 100644 --- a/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_sprkstep_generated.hpp @@ -1,34 +1,36 @@ // #ifndef _ARKODE_SPRKSTEP_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// +// -m.def("SPRKStepSetMethod", - SPRKStepSetMethod, nb::arg("arkode_mem"), nb::arg("sprk_storage")); +m.def("SPRKStepSetMethod", SPRKStepSetMethod, nb::arg("arkode_mem"), + nb::arg("sprk_storage")); -m.def("SPRKStepSetMethodName", - SPRKStepSetMethodName, nb::arg("arkode_mem"), nb::arg("method")); +m.def("SPRKStepSetMethodName", SPRKStepSetMethodName, nb::arg("arkode_mem"), + nb::arg("method")); -m.def("SPRKStepGetCurrentMethod", - [](void * arkode_mem) -> std::tuple +m.def( + "SPRKStepGetCurrentMethod", + [](void* arkode_mem) -> std::tuple + { + auto SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple { - auto SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return = [](void * arkode_mem) -> std::tuple - { - ARKodeSPRKTable sprk_storage_adapt_modifiable; + ARKodeSPRKTable sprk_storage_adapt_modifiable; - int r = SPRKStepGetCurrentMethod(arkode_mem, &sprk_storage_adapt_modifiable); - return std::make_tuple(r, sprk_storage_adapt_modifiable); - }; + int r = SPRKStepGetCurrentMethod(arkode_mem, + &sprk_storage_adapt_modifiable); + return std::make_tuple(r, sprk_storage_adapt_modifiable); + }; - return SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return(arkode_mem); - }, - nb::arg("arkode_mem"), - "nb::rv_policy::reference", - nb::rv_policy::reference); + return SPRKStepGetCurrentMethod_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 6ce3082888..3f0d8950cf 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -1,45 +1,51 @@ // #ifndef _SUNDOMEIGEST_POWER_H -// -// #ifdef __cplusplus +// +// #ifdef __cplusplus // #endif -// - +// auto pyClassSUNDomEigEstimatorContent_Power_ = - nb::class_ - (m, "SUNDomEigEstimatorContent_Power_", "") + nb::class_(m, "SUNDomEigEstimatorContent_Power_", + "") .def(nb::init<>()) // implicit default constructor - ; - - -m.def("SUNDomEigEstimator_Power", - [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) -> std::shared_ptr> + ; + +m.def( + "SUNDomEigEstimator_Power", + [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) + -> std::shared_ptr> + { + auto SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr = + [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) + -> std::shared_ptr> { - auto SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr = [](N_Vector q, long max_iters, sunrealtype rel_tol, SUNContext sunctx) -> std::shared_ptr> - { - auto lambda_result = SUNDomEigEstimator_Power(q, max_iters, rel_tol, sunctx); + auto lambda_result = SUNDomEigEstimator_Power(q, max_iters, rel_tol, + sunctx); - return our_make_shared, SUNDomEigEstimatorDeleter>(lambda_result); - return lambda_result; - }; + return our_make_shared, + SUNDomEigEstimatorDeleter>(lambda_result); + return lambda_result; + }; - return SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr(q, max_iters, rel_tol, sunctx); - }, - nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), - "nb::keep_alive<0, 4>()", - nb::keep_alive<0, 4>()); + return SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr(q, max_iters, + rel_tol, + sunctx); + }, + nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), + "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); -m.def("SUNDomEigEstimator_SetRHS_Power", - SUNDomEigEstimator_SetRHS_Power, nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); +m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, + nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); m.def("SUNDomEigEstimator_SetRHSLinearizationPoint_Power", - SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), nb::arg("t"), nb::arg("v")); + SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), + nb::arg("t"), nb::arg("v")); m.def("SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus -// +// // #endif -// +// // #endif -// +// From c270e82041f2586761855a238077ca1f523d3442 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 19 Mar 2026 10:10:10 -0500 Subject: [PATCH 33/76] bindings update from CI --- .../sundials4py/arkode/arkode_generated.hpp | 231 ++++++++++++++---- .../arkode/arkode_mristep_generated.hpp | 5 - .../arkode/arkode_splittingstep_generated.hpp | 11 - .../sundomeigest_power_generated.hpp | 1 - 4 files changed, 185 insertions(+), 63 deletions(-) diff --git a/bindings/sundials4py/arkode/arkode_generated.hpp b/bindings/sundials4py/arkode/arkode_generated.hpp index 7295bbee06..e5e6bba6c3 100644 --- a/bindings/sundials4py/arkode/arkode_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_generated.hpp @@ -134,7 +134,6 @@ m.def( our_make_shared, MRIStepInnerStepperDeleter>( std::get<1>(lambda_result))); - return lambda_result; }; return ARKodeCreateMRIStepInnerStepper_adapt_return_type_to_shared_ptr( @@ -316,9 +315,26 @@ m.def("ARKodeSetAccumulatedErrorType", ARKodeSetAccumulatedErrorType, m.def("ARKodeResetAccumulatedError", ARKodeResetAccumulatedError, nb::arg("arkode_mem")); -m.def("ARKodeEvolve", ARKodeEvolve, nb::arg("arkode_mem"), nb::arg("tout"), - nb::arg("yout"), nb::arg("tret"), nb::arg("itask"), - "Integrate the ODE over an interval in t"); +m.def( + "ARKodeEvolve", + [](void* arkode_mem, sunrealtype tout, N_Vector yout, + int itask) -> std::tuple + { + auto ARKodeEvolve_adapt_modifiable_immutable_to_return = + [](void* arkode_mem, sunrealtype tout, N_Vector yout, + int itask) -> std::tuple + { + sunrealtype tret_adapt_modifiable; + + int r = ARKodeEvolve(arkode_mem, tout, yout, &tret_adapt_modifiable, itask); + return std::make_tuple(r, tret_adapt_modifiable); + }; + + return ARKodeEvolve_adapt_modifiable_immutable_to_return(arkode_mem, tout, + yout, itask); + }, + nb::arg("arkode_mem"), nb::arg("tout"), nb::arg("yout"), nb::arg("itask"), + "Integrate the ODE over an interval in t"); m.def("ARKodeGetDky", ARKodeGetDky, nb::arg("arkode_mem"), nb::arg("t"), nb::arg("k"), nb::arg("dky"), @@ -383,14 +399,56 @@ m.def( }, nb::arg("arkode_mem")); -m.def("ARKodeGetLastStep", ARKodeGetLastStep, nb::arg("arkode_mem"), - nb::arg("hlast")); +m.def( + "ARKodeGetLastStep", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetLastStep_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype hlast_adapt_modifiable; -m.def("ARKodeGetCurrentStep", ARKodeGetCurrentStep, nb::arg("arkode_mem"), - nb::arg("hcur")); + int r = ARKodeGetLastStep(arkode_mem, &hlast_adapt_modifiable); + return std::make_tuple(r, hlast_adapt_modifiable); + }; -m.def("ARKodeGetStepDirection", ARKodeGetStepDirection, nb::arg("arkode_mem"), - nb::arg("stepdir")); + return ARKodeGetLastStep_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetCurrentStep", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetCurrentStep_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype hcur_adapt_modifiable; + + int r = ARKodeGetCurrentStep(arkode_mem, &hcur_adapt_modifiable); + return std::make_tuple(r, hcur_adapt_modifiable); + }; + + return ARKodeGetCurrentStep_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetStepDirection", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetStepDirection_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype stepdir_adapt_modifiable; + + int r = ARKodeGetStepDirection(arkode_mem, &stepdir_adapt_modifiable); + return std::make_tuple(r, stepdir_adapt_modifiable); + }; + + return ARKodeGetStepDirection_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); m.def("ARKodeGetErrWeights", ARKodeGetErrWeights, nb::arg("arkode_mem"), nb::arg("eweight")); @@ -494,11 +552,41 @@ m.def( m.def("ARKodeGetEstLocalErrors", ARKodeGetEstLocalErrors, nb::arg("arkode_mem"), nb::arg("ele")); -m.def("ARKodeGetActualInitStep", ARKodeGetActualInitStep, nb::arg("arkode_mem"), - nb::arg("hinused")); +m.def( + "ARKodeGetActualInitStep", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetActualInitStep_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype hinused_adapt_modifiable; -m.def("ARKodeGetTolScaleFactor", ARKodeGetTolScaleFactor, nb::arg("arkode_mem"), - nb::arg("tolsfac")); + int r = ARKodeGetActualInitStep(arkode_mem, &hinused_adapt_modifiable); + return std::make_tuple(r, hinused_adapt_modifiable); + }; + + return ARKodeGetActualInitStep_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); + +m.def( + "ARKodeGetTolScaleFactor", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetTolScaleFactor_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype tolsfac_adapt_modifiable; + + int r = ARKodeGetTolScaleFactor(arkode_mem, &tolsfac_adapt_modifiable); + return std::make_tuple(r, tolsfac_adapt_modifiable); + }; + + return ARKodeGetTolScaleFactor_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); m.def( "ARKodeGetNumConstrFails", @@ -520,29 +608,50 @@ m.def( m.def( "ARKodeGetStepStats", - [](void* arkode_mem, sunrealtype* hinused, sunrealtype* hlast, - sunrealtype* hcur, sunrealtype* tcur) -> std::tuple + [](void* arkode_mem) + -> std::tuple { auto ARKodeGetStepStats_adapt_modifiable_immutable_to_return = - [](void* arkode_mem, sunrealtype* hinused, sunrealtype* hlast, - sunrealtype* hcur, sunrealtype* tcur) -> std::tuple + [](void* arkode_mem) + -> std::tuple { long nsteps_adapt_modifiable; + sunrealtype hinused_adapt_modifiable; + sunrealtype hlast_adapt_modifiable; + sunrealtype hcur_adapt_modifiable; + sunrealtype tcur_adapt_modifiable; - int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, hinused, - hlast, hcur, tcur); - return std::make_tuple(r, nsteps_adapt_modifiable); + int r = ARKodeGetStepStats(arkode_mem, &nsteps_adapt_modifiable, + &hinused_adapt_modifiable, + &hlast_adapt_modifiable, + &hcur_adapt_modifiable, &tcur_adapt_modifiable); + return std::make_tuple(r, nsteps_adapt_modifiable, + hinused_adapt_modifiable, hlast_adapt_modifiable, + hcur_adapt_modifiable, tcur_adapt_modifiable); }; - return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem, - hinused, hlast, - hcur, tcur); + return ARKodeGetStepStats_adapt_modifiable_immutable_to_return(arkode_mem); }, - nb::arg("arkode_mem"), nb::arg("hinused"), nb::arg("hlast"), nb::arg("hcur"), - nb::arg("tcur")); + nb::arg("arkode_mem")); -m.def("ARKodeGetAccumulatedError", ARKodeGetAccumulatedError, - nb::arg("arkode_mem"), nb::arg("accum_error")); +m.def( + "ARKodeGetAccumulatedError", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetAccumulatedError_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype accum_error_adapt_modifiable; + + int r = ARKodeGetAccumulatedError(arkode_mem, + &accum_error_adapt_modifiable); + return std::make_tuple(r, accum_error_adapt_modifiable); + }; + + return ARKodeGetAccumulatedError_adapt_modifiable_immutable_to_return( + arkode_mem); + }, + nb::arg("arkode_mem")); m.def( "ARKodeGetNumLinSolvSetups", @@ -562,8 +671,22 @@ m.def( }, nb::arg("arkode_mem")); -m.def("ARKodeGetCurrentTime", ARKodeGetCurrentTime, nb::arg("arkode_mem"), - nb::arg("tcur")); +m.def( + "ARKodeGetCurrentTime", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetCurrentTime_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype tcur_adapt_modifiable; + + int r = ARKodeGetCurrentTime(arkode_mem, &tcur_adapt_modifiable); + return std::make_tuple(r, tcur_adapt_modifiable); + }; + + return ARKodeGetCurrentTime_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); m.def( "ARKodeGetCurrentState", @@ -582,8 +705,22 @@ m.def( }, nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); -m.def("ARKodeGetCurrentGamma", ARKodeGetCurrentGamma, nb::arg("arkode_mem"), - nb::arg("gamma")); +m.def( + "ARKodeGetCurrentGamma", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetCurrentGamma_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype gamma_adapt_modifiable; + + int r = ARKodeGetCurrentGamma(arkode_mem, &gamma_adapt_modifiable); + return std::make_tuple(r, gamma_adapt_modifiable); + }; + + return ARKodeGetCurrentGamma_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); m.def( "ARKodeGetNumNonlinSolvIters", @@ -678,8 +815,22 @@ m.def( }, nb::arg("arkode_mem"), "nb::rv_policy::reference", nb::rv_policy::reference); -m.def("ARKodeGetJacTime", ARKodeGetJacTime, nb::arg("arkode_mem"), - nb::arg("t_J")); +m.def( + "ARKodeGetJacTime", + [](void* arkode_mem) -> std::tuple + { + auto ARKodeGetJacTime_adapt_modifiable_immutable_to_return = + [](void* arkode_mem) -> std::tuple + { + sunrealtype t_J_adapt_modifiable; + + int r = ARKodeGetJacTime(arkode_mem, &t_J_adapt_modifiable); + return std::make_tuple(r, t_J_adapt_modifiable); + }; + + return ARKodeGetJacTime_adapt_modifiable_immutable_to_return(arkode_mem); + }, + nb::arg("arkode_mem")); m.def( "ARKodeGetJacNumSteps", @@ -1212,7 +1363,6 @@ m.def( our_make_shared, SUNStepperDeleter>( std::get<1>(lambda_result))); - return lambda_result; }; return ARKodeCreateSUNStepper_adapt_return_type_to_shared_ptr(arkode_mem); @@ -1334,7 +1484,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_Create_adapt_return_type_to_shared_ptr(s, q, p, @@ -1357,7 +1506,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_Copy_adapt_return_type_to_shared_ptr(B); @@ -1476,7 +1624,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_LoadERK_adapt_return_type_to_shared_ptr(emethod); @@ -1496,7 +1643,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_LoadERKByName_adapt_return_type_to_shared_ptr( @@ -1569,7 +1715,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_LoadDIRK_adapt_return_type_to_shared_ptr(imethod); @@ -1589,7 +1734,6 @@ m.def( return our_make_shared, ARKodeButcherTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeButcherTable_LoadDIRKByName_adapt_return_type_to_shared_ptr( @@ -1665,7 +1809,6 @@ m.def( return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeSPRKTable_Create_adapt_return_type_to_shared_ptr(s, q, a_1d, @@ -1686,7 +1829,6 @@ m.def( return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeSPRKTable_Load_adapt_return_type_to_shared_ptr(id); @@ -1705,7 +1847,6 @@ m.def( return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeSPRKTable_LoadByName_adapt_return_type_to_shared_ptr(method); @@ -1725,7 +1866,6 @@ m.def( return our_make_shared, ARKodeSPRKTableDeleter>(lambda_result); - return lambda_result; }; return ARKodeSPRKTable_Copy_adapt_return_type_to_shared_ptr(that_sprk_storage); @@ -1769,7 +1909,6 @@ m.def( our_make_shared, ARKodeButcherTableDeleter>( std::get<2>(lambda_result))); - return lambda_result; }; return ARKodeSPRKTable_ToButcher_adapt_return_type_to_shared_ptr(sprk_storage); diff --git a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp index 193832192d..e1cb6800ed 100644 --- a/bindings/sundials4py/arkode/arkode_mristep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_mristep_generated.hpp @@ -75,7 +75,6 @@ m.def( return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; }; return MRIStepCoupling_LoadTable_adapt_return_type_to_shared_ptr(method); @@ -94,7 +93,6 @@ m.def( return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; }; return MRIStepCoupling_LoadTableByName_adapt_return_type_to_shared_ptr(method); @@ -133,7 +131,6 @@ m.def( return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; }; return MRIStepCoupling_Create_adapt_return_type_to_shared_ptr(nmat, stages, @@ -156,7 +153,6 @@ m.def( return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; }; return MRIStepCoupling_MIStoMRI_adapt_return_type_to_shared_ptr(B, q, p); @@ -175,7 +171,6 @@ m.def( return our_make_shared, MRIStepCouplingDeleter>(lambda_result); - return lambda_result; }; return MRIStepCoupling_Copy_adapt_return_type_to_shared_ptr(MRIC); diff --git a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp index 2ec392aa67..1aaf0677b6 100644 --- a/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp +++ b/bindings/sundials4py/arkode/arkode_splittingstep_generated.hpp @@ -71,7 +71,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_Create_adapt_return_type_to_shared_ptr(sequential_methods, @@ -97,7 +96,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_Copy_adapt_return_type_to_shared_ptr( @@ -121,7 +119,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_LoadCoefficients_adapt_return_type_to_shared_ptr( @@ -142,7 +139,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_LoadCoefficientsByName_adapt_return_type_to_shared_ptr( @@ -166,7 +162,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_LieTrotter_adapt_return_type_to_shared_ptr( @@ -187,7 +182,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_Strang_adapt_return_type_to_shared_ptr( @@ -208,7 +202,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_Parallel_adapt_return_type_to_shared_ptr( @@ -229,7 +222,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_SymmetricParallel_adapt_return_type_to_shared_ptr( @@ -250,7 +242,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_ThirdOrderSuzuki_adapt_return_type_to_shared_ptr( @@ -272,7 +263,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_TripleJump_adapt_return_type_to_shared_ptr(partitions, @@ -294,7 +284,6 @@ m.def( return our_make_shared, SplittingStepCoefficientsDeleter>(lambda_result); - return lambda_result; }; return SplittingStepCoefficients_SuzukiFractal_adapt_return_type_to_shared_ptr(partitions, diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 3f0d8950cf..629b893670 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -24,7 +24,6 @@ m.def( return our_make_shared, SUNDomEigEstimatorDeleter>(lambda_result); - return lambda_result; }; return SUNDomEigEstimator_Power_adapt_return_type_to_shared_ptr(q, max_iters, From d35d56b8b9f064895917cc34c6589c3395530814 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 19 Mar 2026 10:44:46 -0500 Subject: [PATCH 34/76] warmup_to_tol disable --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 5 +++++ .../arnoldi/sundomeigest_arnoldi.c | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 5520db5481..c4ad605eb7 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -305,6 +305,11 @@ instead of supplying a dummy routine. the cheaper magnitude-based preprocessing step, the routine avoids multiple Arnoldi runs that would yield only marginal improvements in accuracy while incurring significantly higher computational cost. + When this routine is used in combination with Power Iteration and ``rel_tol`` is less than or equal + to zero, a default value of ``rel_tol`` = 0.005 is applied. In the case of Arnoldi Iteration, this + routine sets ``rel_tol`` = 0.005 for the preprocessing Power Iteration phase when ``rel_tol`` is zero, + and disables preprocessing based on tolerance. + This routine will be called by :c:func:`SUNDomEigEstimator_SetOptions` when using the key "Did.rel_tol". diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 1db40f396d..55264280d2 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -43,7 +43,7 @@ /* Default estimator parameters */ #define DEE_NUM_OF_WARMUPS_ARNOLDI_DEFAULT 100 -#define DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT SUN_RCONST(1.0e-2) +#define DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT SUN_RCONST(0.005) /* Default Arnoldi Iteration parameters */ #define DEE_KRYLOV_DIM_DEFAULT 3 @@ -342,8 +342,6 @@ SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi(SUNDomEigEstimator D /* set the number of warmups */ Arnoldi_CONTENT(DEE)->num_warmups = num_iters; - /* set the type of warmup iterations */ - Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; return SUN_SUCCESS; } @@ -356,9 +354,19 @@ SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, SUNAssert(Arnoldi_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); /* set the tolerance for preprocessing iterations */ - if (tol < SUN_SMALL_REAL) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } - - Arnoldi_CONTENT(DEE)->tol_preprocess = tol; + if (tol < ZERO) + { + Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; + return SUN_SUCCESS; + } + else if (tol == ZERO) + { + tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; + } + else + { + Arnoldi_CONTENT(DEE)->tol_preprocess = tol; + } /* set the type of warmup iterations */ Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; From 50e7f9281516eb2c3eb951b38a7cfeb7f47dc0e9 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 19 Mar 2026 10:57:40 -0500 Subject: [PATCH 35/76] formatting --- src/sundomeigest/arnoldi/sundomeigest_arnoldi.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 55264280d2..950460e1ab 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -359,14 +359,8 @@ SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; return SUN_SUCCESS; } - else if (tol == ZERO) - { - tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; - } - else - { - Arnoldi_CONTENT(DEE)->tol_preprocess = tol; - } + else if (tol == ZERO) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } + else { Arnoldi_CONTENT(DEE)->tol_preprocess = tol; } /* set the type of warmup iterations */ Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; From 97397b9b902ad2fbba3203ee23dc986917d29029 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 09:56:38 -0500 Subject: [PATCH 36/76] bindings update --- bindings/sundials4py/sundomeigest/generate.yaml | 3 +++ .../sundomeigest/sundomeigest_power_generated.hpp | 10 ---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/bindings/sundials4py/sundomeigest/generate.yaml b/bindings/sundials4py/sundomeigest/generate.yaml index e82948a83a..0df6e5d3b2 100644 --- a/bindings/sundials4py/sundomeigest/generate.yaml +++ b/bindings/sundials4py/sundomeigest/generate.yaml @@ -26,11 +26,14 @@ modules: fn_exclude_by_name__regex: # Don't interface the implementation specific overrides of the generic routines - "^SUNDomEigEstimator_SetATimes_.*" + - "^SUNDomEigEstimator_SetRHS_.*" - "^SUNDomEigEstimator_SetOptions_.*" - "^SUNDomEigEstimator_SetMaxIters_.*" - "^SUNDomEigEstimator_SetNumPreprocessIters_.*" - "^SUNDomEigEstimator_SetRelTol_.*" - "^SUNDomEigEstimator_SetInitialGuess_.*" + - "^SUNDomEigEstimator_SetRHSLinearizationPoint_.*" + - "^SUNDomEigEstimator_SetDEEisReal_.*" - "^SUNDomEigEstimator_Initialize_.*" - "^SUNDomEigEstimator_Estimate_.*" - "^SUNDomEigEstimator_GetRes_.*" diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 629b893670..996531f676 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -32,16 +32,6 @@ m.def( }, nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); - -m.def("SUNDomEigEstimator_SetRHS_Power", SUNDomEigEstimator_SetRHS_Power, - nb::arg("DEE"), nb::arg("rhs_data"), nb::arg("RHSfn")); - -m.def("SUNDomEigEstimator_SetRHSLinearizationPoint_Power", - SUNDomEigEstimator_SetRHSLinearizationPoint_Power, nb::arg("DEE"), - nb::arg("t"), nb::arg("v")); - -m.def("SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus // // #endif From a276b73f85def64a58538830a24794d7a2cedce4 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 10:18:45 -0500 Subject: [PATCH 37/76] binding updates --- .../sundials/sundials_domeigestimator.cpp | 20 ++++++++++++++++++- .../sundials_domeigestimator_generated.hpp | 3 --- .../sundials_domeigestimator_usersupplied.hpp | 9 +++++++++ .../sundials4py/sundomeigest/generate.yaml | 1 - .../sundomeigest_power_generated.hpp | 5 +++++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp index 3e77254954..5c6de28683 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp @@ -85,7 +85,25 @@ void bind_sundomeigestimator(nb::module_& m) nb::arg("DEE"), nb::arg("ATimes").none()); } -} // namespace sundials4py +m.def( + "SUNDomEigEstimator_SetRHS", + [](SUNDomEigEstimator DEE, + std::function> RHSfn) -> SUNErrCode + { + if (!DEE->python) { DEE->python = new SUNDomEigEstimatorFunctionTable; } + + auto fntable = static_cast(DEE->python); + + fntable->deerhs = nb::cast(RHSfn); + + if (RHSfn) + { + return SUNDomEigEstimator_SetRHS(DEE, fntable, + sundomeigestimator_setrhs_wrapper); + } + else { return SUNDomEigEstimator_SetRHS(DEE, fntable, nullptr); } + }, + nb::arg("DEE"), nb::arg("RHSfn").none()); extern "C" void SUNDomEigEstimatorFunctionTable_Destroy(void* ptr) { diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index cba6138b31..82be028a91 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -16,9 +16,6 @@ auto pyClassSUNDomEigEstimator_ = .def(nb::init<>()) // implicit default constructor ; -m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), - nb::arg("rhs_data"), nb::arg("RHSfn")); - m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("t"), nb::arg("v")); diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp index d21b3f2c4c..5c1a2be02a 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp @@ -33,6 +33,7 @@ using namespace sundials::experimental; struct SUNDomEigEstimatorFunctionTable { nb::object atimes; + nb::object deerhs; }; template @@ -43,4 +44,12 @@ SUNErrCode sundomeigestimator_atimes_wrapper(Args... args) 3>(&SUNDomEigEstimatorFunctionTable::atimes, std::forward(args)...); } +template +SUNErrCode sundomeigestimator_setrhs_wrapper(Args... args) +{ + return sundials4py::user_supplied_fn_caller< + std::remove_pointer_t, SUNDomEigEstimatorFunctionTable, + 3>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); +} + #endif \ No newline at end of file diff --git a/bindings/sundials4py/sundomeigest/generate.yaml b/bindings/sundials4py/sundomeigest/generate.yaml index 0df6e5d3b2..29cd516e39 100644 --- a/bindings/sundials4py/sundomeigest/generate.yaml +++ b/bindings/sundials4py/sundomeigest/generate.yaml @@ -33,7 +33,6 @@ modules: - "^SUNDomEigEstimator_SetRelTol_.*" - "^SUNDomEigEstimator_SetInitialGuess_.*" - "^SUNDomEigEstimator_SetRHSLinearizationPoint_.*" - - "^SUNDomEigEstimator_SetDEEisReal_.*" - "^SUNDomEigEstimator_Initialize_.*" - "^SUNDomEigEstimator_Estimate_.*" - "^SUNDomEigEstimator_GetRes_.*" diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 996531f676..ae767b4385 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -32,6 +32,11 @@ m.def( }, nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); + +m.def( + "SUNDomEigEstimator_SetDEEisReal_Power", + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("DEEisReal")); + // #ifdef __cplusplus // // #endif From 2783a4f7bc03a5345999310d0151c5c00814f09a Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 10:28:48 -0500 Subject: [PATCH 38/76] formatting --- bindings/sundials4py/sundials/sundials_domeigestimator.cpp | 2 +- .../sundomeigest/sundomeigest_power_generated.hpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp index 5c6de28683..45f2862f8c 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp @@ -99,7 +99,7 @@ m.def( if (RHSfn) { return SUNDomEigEstimator_SetRHS(DEE, fntable, - sundomeigestimator_setrhs_wrapper); + sundomeigestimator_setrhs_wrapper); } else { return SUNDomEigEstimator_SetRHS(DEE, fntable, nullptr); } }, diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index ae767b4385..8b8257d104 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -33,9 +33,9 @@ m.def( nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); -m.def( - "SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("DEEisReal")); +m.def("SUNDomEigEstimator_SetDEEisReal_Power", + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), + nb::arg("DEEisReal")); // #ifdef __cplusplus // From c3c94b515d13cc42754eea8a0dc7777f7e9968b5 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 10:47:26 -0500 Subject: [PATCH 39/76] litgen --- .../sundials/sundials_domeigestimator_generated.hpp | 3 +++ .../sundials4py/sundomeigest/sundomeigest_power_generated.hpp | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index 82be028a91..cba6138b31 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -16,6 +16,9 @@ auto pyClassSUNDomEigEstimator_ = .def(nb::init<>()) // implicit default constructor ; +m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), + nb::arg("rhs_data"), nb::arg("RHSfn")); + m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("t"), nb::arg("v")); diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index 8b8257d104..c1c3fe0a72 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -34,9 +34,7 @@ m.def( "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); m.def("SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), - nb::arg("DEEisReal")); - + SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus // // #endif From 3817d6803ce9b04299a5654892bb3124d9b6c195 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 10:58:24 -0500 Subject: [PATCH 40/76] removed autogenerated SUNDomEigEstimator_SetRHS --- bindings/sundials4py/sundials/generate.yaml | 1 + .../sundials/sundials_domeigestimator_generated.hpp | 3 --- bindings/sundials4py/test/test_sundomeigest.py | 6 ++++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bindings/sundials4py/sundials/generate.yaml b/bindings/sundials4py/sundials/generate.yaml index ec10551c5a..cf0ebb8e9f 100644 --- a/bindings/sundials4py/sundials/generate.yaml +++ b/bindings/sundials4py/sundials/generate.yaml @@ -63,6 +63,7 @@ modules: - ../../include/sundials/sundials_domeigestimator.h fn_exclude_by_name__regex: - "SUNDomEigEstimator_SetATimes" # nanobind cannot bind to functions which take a function pointer, so we do something custom + - "SUNDomEigEstimator_SetRHS" # nanobind cannot bind to functions which take a function pointer, so we do something custom sundials_errors: path: sundials/sundials_errors_generated.hpp headers: diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index cba6138b31..82be028a91 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -16,9 +16,6 @@ auto pyClassSUNDomEigEstimator_ = .def(nb::init<>()) // implicit default constructor ; -m.def("SUNDomEigEstimator_SetRHS", SUNDomEigEstimator_SetRHS, nb::arg("DEE"), - nb::arg("rhs_data"), nb::arg("RHSfn")); - m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("t"), nb::arg("v")); diff --git a/bindings/sundials4py/test/test_sundomeigest.py b/bindings/sundials4py/test/test_sundomeigest.py index 74a7dc3963..35a2307692 100644 --- a/bindings/sundials4py/test/test_sundomeigest.py +++ b/bindings/sundials4py/test/test_sundomeigest.py @@ -34,6 +34,12 @@ def atimes(_, v, z): SUNDomEigEstimator_SetATimes(e, atimes) + def deerhs(_, v, z): + # dummy rhs for smoke testing + return 0 + + SUNDomEigEstimator_SetRHS(e, deerhs) + return e, nvec else: raise ValueError("Unknown estimator type") From cbebb0fcc4f2ad02b9762447d286ec7cd118f137 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 11:23:57 -0500 Subject: [PATCH 41/76] litgen --- .../sundials/sundials_domeigestimator_generated.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp index 82be028a91..c39c1575db 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_generated.hpp @@ -16,10 +16,6 @@ auto pyClassSUNDomEigEstimator_ = .def(nb::init<>()) // implicit default constructor ; -m.def("SUNDomEigEstimator_SetRHSLinearizationPoint", - SUNDomEigEstimator_SetRHSLinearizationPoint, nb::arg("DEE"), nb::arg("t"), - nb::arg("v")); - m.def("SUNDomEigEstimator_SetMaxIters", SUNDomEigEstimator_SetMaxIters, nb::arg("DEE"), nb::arg("max_iters")); From 3051d1b66620d7df1aa4d6b22f7a304e5a44ad24 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 24 Mar 2026 19:51:28 -0500 Subject: [PATCH 42/76] bindings fix --- .../sundials/sundials_domeigestimator.cpp | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp index 45f2862f8c..2d2f5a6b0e 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp @@ -83,27 +83,29 @@ void bind_sundomeigestimator(nb::module_& m) else { return SUNDomEigEstimator_SetATimes(dee, fntable, nullptr); } }, nb::arg("DEE"), nb::arg("ATimes").none()); -} -m.def( - "SUNDomEigEstimator_SetRHS", - [](SUNDomEigEstimator DEE, - std::function> RHSfn) -> SUNErrCode - { - if (!DEE->python) { DEE->python = new SUNDomEigEstimatorFunctionTable; } + m.def( + "SUNDomEigEstimator_SetRHS", + [](SUNDomEigEstimator DEE, + std::function> RHSfn) -> SUNErrCode + { + if (!DEE->python) { DEE->python = new SUNDomEigEstimatorFunctionTable; } - auto fntable = static_cast(DEE->python); + auto fntable = static_cast(DEE->python); - fntable->deerhs = nb::cast(RHSfn); + fntable->deerhs = nb::cast(RHSfn); - if (RHSfn) - { - return SUNDomEigEstimator_SetRHS(DEE, fntable, - sundomeigestimator_setrhs_wrapper); - } - else { return SUNDomEigEstimator_SetRHS(DEE, fntable, nullptr); } - }, - nb::arg("DEE"), nb::arg("RHSfn").none()); + if (RHSfn) + { + return SUNDomEigEstimator_SetRHS(DEE, fntable, + sundomeigestimator_setrhs_wrapper); + } + else { return SUNDomEigEstimator_SetRHS(DEE, fntable, nullptr); } + }, + nb::arg("DEE"), nb::arg("RHSfn").none()); +} + +} // namespace sundials4py extern "C" void SUNDomEigEstimatorFunctionTable_Destroy(void* ptr) { From 1aa8721a63e3e099078b88eaf85503d232074d55 Mon Sep 17 00:00:00 2001 From: maggul Date: Wed, 25 Mar 2026 08:21:05 -0500 Subject: [PATCH 43/76] revert changes in the test --- bindings/sundials4py/test/test_sundomeigest.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bindings/sundials4py/test/test_sundomeigest.py b/bindings/sundials4py/test/test_sundomeigest.py index 35a2307692..74a7dc3963 100644 --- a/bindings/sundials4py/test/test_sundomeigest.py +++ b/bindings/sundials4py/test/test_sundomeigest.py @@ -34,12 +34,6 @@ def atimes(_, v, z): SUNDomEigEstimator_SetATimes(e, atimes) - def deerhs(_, v, z): - # dummy rhs for smoke testing - return 0 - - SUNDomEigEstimator_SetRHS(e, deerhs) - return e, nvec else: raise ValueError("Unknown estimator type") From 19fc84ac63928d8a52fe47f89c7256b02529b771 Mon Sep 17 00:00:00 2001 From: maggul Date: Wed, 25 Mar 2026 08:44:33 -0500 Subject: [PATCH 44/76] update answers --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 8cf043ca14..ba4e28e3c5 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 8cf043ca14922548a22d3d0ce19737ef9e68f38a +Subproject commit ba4e28e3c53b7883eea1f67ca1f3fc50deef5435 From 615fdcde6a0fac9242a822c235fc603bedc0eefa Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 26 Mar 2026 13:04:27 -0500 Subject: [PATCH 45/76] CI fixes and missing function --- .../source/Usage/LSRKStep/User_callable.rst | 2 +- ...TS2_region_s10.PNG => STS2_region_s10.png} | Bin doc/shared/sundomeigest/SUNDomEigEst_API.rst | 40 ++++++++++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) rename doc/shared/figs/arkode/{STS2_region_s10.PNG => STS2_region_s10.png} (100%) diff --git a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst index 48332204cc..c61663cdf1 100644 --- a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst @@ -348,7 +348,7 @@ Allowable Method Families have the option to choose their preference for a more conservative or more aggressive approach to stability. This input is only used for RKC and RKL methods. - .. figure:: ../../../../../arkode/guide/source/figs/arkode/STS2_region_s10.png + .. figure:: ../../../../../shared/figs/arkode/STS2_region_s10.png :alt: Stability region of RKL method with 10 stages :align: center :width: 50% diff --git a/doc/shared/figs/arkode/STS2_region_s10.PNG b/doc/shared/figs/arkode/STS2_region_s10.png similarity index 100% rename from doc/shared/figs/arkode/STS2_region_s10.PNG rename to doc/shared/figs/arkode/STS2_region_s10.png diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index c4ad605eb7..ea1e30cbc1 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -209,6 +209,27 @@ instead of supplying a dummy routine. A :c:type:`SUNErrCode`. +.. c:function:: SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, SUNRHSFn RHSfn) + + This *optional* function provides a :c:type:`SUNRHSFn` function for performing + evaluations of the right-hand side function, as well as a ``void*`` pointer to a data structure + used by this routine, to the dominant eigenvalue estimator. This function allows the estimator to + perform a discrete Jacobian-vector product using quotient approximations of the Jacobian and estimate + dominant eigenvalues of the Jacobian without requiring the user to provide a matrix-vector product + function. This can be useful when the user does not have access to the Jacobian or its matrix-vector + product, but can evaluate the right-hand side function. + + **Arguments:** + + * *DEE* -- a SUNDomEigEstimator object. + * *rhs_data* -- pointer to structure for ``RHSfn``. + * *RHSfn* -- function pointer to perform right-hand side evaluations. + + **Return value:** + + A :c:type:`SUNErrCode`. + + .. c:function:: SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_iters) This *optional* routine sets the number of preprocessing matrix-vector @@ -244,6 +265,7 @@ instead of supplying a dummy routine. This routine will be called by :c:func:`SUNDomEigEstimator_SetOptions` when using the key "Did.num_preprocess_iters". + .. c:function:: SUNErrCode SUNDomEigEstimator_SetRelTol(SUNDomEigEstimator DEE, sunrealtype rel_tol) This *optional* routine sets the estimator's :ref:`relative tolerance `. @@ -442,13 +464,23 @@ dominant eigenvalue estimator. *All routines are optional.* Functions provided by SUNDIALS packages --------------------------------------------- -To interface with SUNDomEigEst modules, the SUNDIALS packages supply a -:c:type:`SUNATimesFn` function for evaluating the matrix-vector product. This -package-provided routine translates between the user-supplied ODE or DAE systems -and the generic dominant eigenvalue estimator API. The function types for these +To interface with SUNDomEigEst modules, the SUNDIALS packages supply +:c:type:`SUNATimesFn` and :c:type:`SUNRHSFn` functions for evaluating the matrix-vector +product. This package-provided routine translates between the user-supplied ODE or DAE +systems and the generic dominant eigenvalue estimator API. The function types for these routines are defined in the header file ``sundials/sundials_iterative.h``. +.. c:type:: int (*SUNRHSFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* rhs_data) + + Used to compute the right-hand side of an ODE or DAE system. This function is used + when the dominant eigenvalue estimator is configured to perform a discrete + Jacobian-vector product using quotient approximations of the Jacobian. The parameter + *rhs_data* is a pointer to any information about RHS which the function needs in order + to do its job. The time parameter :math:`t` and the vector :math:`y` should be left + unchanged. + + .. _SUNDomEigEst.Generic: The generic SUNDomEigEstimator module From 21b47af0a522d8f8c7decb3367db6c93fd9706e3 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 27 Mar 2026 15:14:18 -0700 Subject: [PATCH 46/76] remove non-ascii characters --- src/arkode/arkode_lsrkstep.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index e7ebcc415e..85349db72a 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -1266,7 +1266,7 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn ​is computed at the beginning + /* The method is not FSAL. Therefore, fn is computed at the beginning of the step unless a renewed step or ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1451,7 +1451,7 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn ​is computed at the beginning + /* The method is not FSAL. Therefore, fn is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1736,7 +1736,7 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn ​is computed at the beginning + /* The method is not FSAL. Therefore, fn is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1941,7 +1941,7 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn ​is computed at the beginning + /* The method is not FSAL. Therefore, fn is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -2494,7 +2494,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me if (step_mem->use_ellipse) { /* The stability region of the damped RKC method is approximated by an ellipse with - vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,±im_stab_min). These vertices + vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,+/-im_stab_min). These vertices depend on the damping parameter. Also, im_stab_min is estimated heuristically from the ellipse aspect ratio, taken as approximately 3.65s, where s is the number of stages (for s=2, the ratio is approximated as 0.6s). This heuristic reflects the observed From 29314ea3e468cfb69dde62744c73c70c0ad1eef8 Mon Sep 17 00:00:00 2001 From: "David J. Gardner" Date: Fri, 27 Mar 2026 15:23:35 -0700 Subject: [PATCH 47/76] wrap long lines, delete trailing whitespace --- src/arkode/arkode_lsrkstep.c | 80 +++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 85349db72a..03def5a797 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -575,10 +575,9 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); - /* Check if number of stages exceeds maximum allowed. - If so, and if adaptive stepping is enabled, reduce step size - and return ARK_RETRY_STEP. If fixed step size, return - ARK_MAX_STAGE_LIMIT_FAIL error. */ + /* Check if number of stages exceeds maximum allowed. If so, and if adaptive + stepping is enabled, reduce step size and return ARK_RETRY_STEP. If fixed + step size, return ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -608,11 +607,12 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an inscribed - ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. - For fixed step size, we increase number of stages until stability norm is acceptable - or stage_max_limit is reached. */ + + /* To check stability, we evaluate the analytic stability function or an + inscribed ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. For + fixed step size, we increase number of stages until stability norm is + acceptable or stage_max_limit is reached. */ retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -934,10 +934,9 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) ss = SUNMAX(ss, SUN_RCONST(2.0)); - /* Check if number of stages exceeds maximum allowed. - If so, and if adaptive stepping is enabled, reduce step size - and return ARK_RETRY_STEP. If fixed step size, return - ARK_MAX_STAGE_LIMIT_FAIL error. */ + /* Check if number of stages exceeds maximum allowed. If so, and if adaptive + stepping is enabled, reduce step size and return ARK_RETRY_STEP. If fixed + step size, return ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -968,11 +967,12 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an inscribed - ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. - For fixed step size, we increase number of stages until stability norm is acceptable - or stage_max_limit is reached. */ + + /* To check stability, we evaluate the analytic stability function or an + inscribed ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. For + fixed step size, we increase number of stages until stability norm is + acceptable or stage_max_limit is reached. */ retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -2477,10 +2477,10 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) /*--------------------------------------------------------------- lsrkStep_RKC_CheckStabilityNorm: - This routine computes the stability norm for RKC methods. - If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. - If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using - the Chebyshev polynomial. + This routine computes the stability norm for RKC methods. If use_ellipse is + SUNTRUE, we use a heuristic that approximates the stability region by an + ellipse. If use_ellipse is SUNFALSE, we compute the stability norm directly + from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2493,14 +2493,16 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me if (step_mem->use_ellipse) { - /* The stability region of the damped RKC method is approximated by an ellipse with - vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,+/-im_stab_min). These vertices - depend on the damping parameter. Also, im_stab_min is estimated heuristically from - the ellipse aspect ratio, taken as approximately 3.65s, where s is the number of stages - (for s=2, the ratio is approximated as 0.6s). This heuristic reflects the observed - near-linear growth of the imaginary extent with the number of stages. The numerical - factors (3.65 and 0.6) were obtained empirically from stability-region plots using - the default damping parameter and may change if the damping is modified. */ + /* The stability region of the damped RKC method is approximated by an + ellipse with vertices at (0,0), (re_stab_min,0), and + (re_stab_min/2,+/-im_stab_min). These vertices depend on the damping + parameter. Also, im_stab_min is estimated heuristically from the ellipse + aspect ratio, taken as approximately 3.65s, where s is the number of + stages (for s=2, the ratio is approximated as 0.6s). This heuristic + reflects the observed near-linear growth of the imaginary extent with the + number of stages. The numerical factors (3.65 and 0.6) were obtained + empirically from stability-region plots using the default damping + parameter and may change if the damping is modified. */ re_stab_min = TWO / THREE * (ONE - SUNSQR(ss)) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); im_stab_min = -re_stab_min / @@ -2548,10 +2550,10 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me /*--------------------------------------------------------------- lsrkStep_RKL_CheckStabilityNorm: - This routine computes the stability norm for RKL methods. - If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. - If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using - the Chebyshev polynomial. + This routine computes the stability norm for RKL methods. If use_ellipse is + SUNTRUE, we use a heuristic that approximates the stability region by an + ellipse. If use_ellipse is SUNFALSE, we compute the stability norm directly + from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2598,10 +2600,12 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me im_stab_min = -re_stab_min / (imag_extend_factor[6 - (int)ss % 2] * ss); } } - // TODO: get opinon on whether we want to use the heuristic with different factors for different number of stages or - // to use a single global factor for all number of stages. The heuristic with different factors for different number - // of stages is more accurate, especially for small number of stages, but it is also more complicated. - // Instead we can use a single global factor of 1.5 for all number of stages as follows: + // TODO: get opinon on whether we want to use the heuristic with different + // factors for different number of stages or to use a single global factor + // for all number of stages. The heuristic with different factors for + // different number of stages is more accurate, especially for small number + // of stages, but it is also more complicated. Instead we can use a single + // global factor of 1.5 for all number of stages as follows: // im_stab_min = -re_stab_min / (SUN_RCONST(1.5) * ss); xc = re_stab_min / TWO; From f8c87e75db46b730661fd0e25cfd742f4a229b6c Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 30 Mar 2026 15:02:53 -0500 Subject: [PATCH 48/76] revision I --- bindings/sundials4py/sundials/generate.yaml | 2 +- .../sundials/sundials_domeigestimator.cpp | 6 +- .../sundials4py/sundomeigest/generate.yaml | 4 +- .../sundomeigest_power_generated.hpp | 4 +- .../source/Usage/LSRKStep/User_callable.rst | 4 + doc/shared/Changelog.rst | 13 +++ doc/shared/RecentChanges.rst | 4 + doc/shared/sundomeigest/SUNDomEigEst_API.rst | 2 +- .../sundomeigest/SUNDomEigEst_Power.rst | 4 +- .../C_serial/ark_analytic_lsrk_domeigest.c | 4 +- .../ark_brusselator_lsrk_externaldomeigest.c | 12 +- include/sundials/sundials_domeigestimator.h | 5 +- include/sundomeigest/sundomeigest_arnoldi.h | 6 +- include/sundomeigest/sundomeigest_power.h | 8 +- src/arkode/arkode_lsrkstep.c | 107 ++++++++---------- src/arkode/arkode_lsrkstep_impl.h | 4 +- src/arkode/arkode_lsrkstep_io.c | 1 + src/sundials/fmod_int32/fsundials_core_mod.c | 8 +- .../fmod_int32/fsundials_core_mod.f90 | 20 ++-- src/sundials/fmod_int64/fsundials_core_mod.c | 8 +- .../fmod_int64/fsundials_core_mod.f90 | 20 ++-- src/sundials/sundials_domeigestimator.c | 4 +- .../fmod_int32/fsundomeigest_arnoldi_mod.c | 8 +- .../fmod_int32/fsundomeigest_arnoldi_mod.f90 | 20 ++-- .../fmod_int64/fsundomeigest_arnoldi_mod.c | 8 +- .../fmod_int64/fsundomeigest_arnoldi_mod.f90 | 20 ++-- .../arnoldi/sundomeigest_arnoldi.c | 8 +- src/sundomeigest/power/sundomeigest_power.c | 10 +- 28 files changed, 169 insertions(+), 155 deletions(-) diff --git a/bindings/sundials4py/sundials/generate.yaml b/bindings/sundials4py/sundials/generate.yaml index cf0ebb8e9f..facf4b39ee 100644 --- a/bindings/sundials4py/sundials/generate.yaml +++ b/bindings/sundials4py/sundials/generate.yaml @@ -63,7 +63,7 @@ modules: - ../../include/sundials/sundials_domeigestimator.h fn_exclude_by_name__regex: - "SUNDomEigEstimator_SetATimes" # nanobind cannot bind to functions which take a function pointer, so we do something custom - - "SUNDomEigEstimator_SetRHS" # nanobind cannot bind to functions which take a function pointer, so we do something custom + - "SUNDomEigEstimator_SetRhs" # nanobind cannot bind to functions which take a function pointer, so we do something custom sundials_errors: path: sundials/sundials_errors_generated.hpp headers: diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp index 2d2f5a6b0e..410e3b1dfa 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp @@ -85,7 +85,7 @@ void bind_sundomeigestimator(nb::module_& m) nb::arg("DEE"), nb::arg("ATimes").none()); m.def( - "SUNDomEigEstimator_SetRHS", + "SUNDomEigEstimator_SetRhs", [](SUNDomEigEstimator DEE, std::function> RHSfn) -> SUNErrCode { @@ -97,10 +97,10 @@ void bind_sundomeigestimator(nb::module_& m) if (RHSfn) { - return SUNDomEigEstimator_SetRHS(DEE, fntable, + return SUNDomEigEstimator_SetRhs(DEE, fntable, sundomeigestimator_setrhs_wrapper); } - else { return SUNDomEigEstimator_SetRHS(DEE, fntable, nullptr); } + else { return SUNDomEigEstimator_SetRhs(DEE, fntable, nullptr); } }, nb::arg("DEE"), nb::arg("RHSfn").none()); } diff --git a/bindings/sundials4py/sundomeigest/generate.yaml b/bindings/sundials4py/sundomeigest/generate.yaml index 29cd516e39..98d6675357 100644 --- a/bindings/sundials4py/sundomeigest/generate.yaml +++ b/bindings/sundials4py/sundomeigest/generate.yaml @@ -26,13 +26,13 @@ modules: fn_exclude_by_name__regex: # Don't interface the implementation specific overrides of the generic routines - "^SUNDomEigEstimator_SetATimes_.*" - - "^SUNDomEigEstimator_SetRHS_.*" + - "^SUNDomEigEstimator_SetRhs_.*" - "^SUNDomEigEstimator_SetOptions_.*" - "^SUNDomEigEstimator_SetMaxIters_.*" - "^SUNDomEigEstimator_SetNumPreprocessIters_.*" - "^SUNDomEigEstimator_SetRelTol_.*" - "^SUNDomEigEstimator_SetInitialGuess_.*" - - "^SUNDomEigEstimator_SetRHSLinearizationPoint_.*" + - "^SUNDomEigEstimator_SetRhsLinearizationPoint_.*" - "^SUNDomEigEstimator_Initialize_.*" - "^SUNDomEigEstimator_Estimate_.*" - "^SUNDomEigEstimator_GetRes_.*" diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index c1c3fe0a72..e5e1dc4267 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -33,8 +33,8 @@ m.def( nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); -m.def("SUNDomEigEstimator_SetDEEisReal_Power", - SUNDomEigEstimator_SetDEEisReal_Power, nb::arg("DEE"), nb::arg("real")); +m.def("SUNDomEigEstimator_SetIsReal_Power", + SUNDomEigEstimator_SetIsReal_Power, nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus // // #endif diff --git a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst index c61663cdf1..70b259df0f 100644 --- a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst @@ -348,6 +348,10 @@ Allowable Method Families have the option to choose their preference for a more conservative or more aggressive approach to stability. This input is only used for RKC and RKL methods. + If :c:func:`LSRKStepSetUseAnalyticStabRegion` is called during integration, the change will take effect + at the next step attempt. Both analytic and ellipse stability regions of RKC and RKL methods with 10 stages + are shown in the figure below. + .. figure:: ../../../../../shared/figs/arkode/STS2_region_s10.png :alt: Stability region of RKL method with 10 stages :align: center diff --git a/doc/shared/Changelog.rst b/doc/shared/Changelog.rst index 45ec4c30ef..df7748528a 100644 --- a/doc/shared/Changelog.rst +++ b/doc/shared/Changelog.rst @@ -29,6 +29,19 @@ Changelog Changes to SUNDIALS in release X.Y.Z ==================================== +.. SED_REPLACEMENT_KEY + +.. _Changelog.7.7.0: + +Changes to SUNDIALS in release 7.7.0 +==================================== + +**Bug Fixes** + +Fixed a minor bug where the number of required stages for STS methods +in the LSRKStep module was incorrectly computed using the spectral +radius instead of the real part of the Jacobian eigenvalues. + .. include:: RecentChanges_link.rst .. _Changelog.7.6.0: diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index c621eb1f94..f5990b445f 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -18,6 +18,10 @@ table. Fixed a bug where passing an empty string to ``SUNLogger_Set{Error,Warning,Info,Debug}Filename`` did not disable the corresponding logging stream `Issue #844 `__. +Fixed a minor bug where the number of required stages for STS methods +in the LSRKStep module was incorrectly computed using the spectral +radius instead of the real part of the Jacobian eigenvalues. + **Deprecation Notices** The ``CVodeSetMonitorFn`` and ``CVodeSetMonitorFrequency`` functions have been deprecated and will be diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index ea1e30cbc1..5da18fd5ed 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -209,7 +209,7 @@ instead of supplying a dummy routine. A :c:type:`SUNErrCode`. -.. c:function:: SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, SUNRHSFn RHSfn) +.. c:function:: SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, SUNRHSFn RHSfn) This *optional* function provides a :c:type:`SUNRHSFn` function for performing evaluations of the right-hand side function, as well as a ``void*`` pointer to a data structure diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index 8d632e7c6b..41b386f7ee 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -109,7 +109,7 @@ routines: :c:func:`SUNDomEigEstimator_SetInitialGuess`. -.. c:function:: SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) +.. c:function:: SUNErrCode SUNDomEigEstimator_SetIsReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) This routine informs the Power iteration that the dominant eigenvalue is real-valued, so that the complex projection described in Section @@ -239,7 +239,7 @@ eigenvalue estimator operations listed in :numref:`SUNDomEigEst.API`: * ``SUNDomEigEstimator_SetRelTol_Power`` -* ``SUNDomEigEstimator_SetDEEisReal_Power`` +* ``SUNDomEigEstimator_SetIsReal_Power`` * ``SUNDomEigEstimator_Initialize_Power`` diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c index a35c397d1e..3ed19609fd 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c @@ -238,8 +238,8 @@ int main(int argc, char* argv[]) if (check_flag(&flag, "ARKodeSetOptions", 1)) { return 1; } /* Set real type dominant eigenvalue */ - flag = SUNDomEigEstimator_SetDEEisReal_Power(DEE, SUNTRUE); - if (check_flag(&flag, "SUNDomEigEstimator_SetDEEisReal_Power", 1)) + flag = SUNDomEigEstimator_SetIsReal_Power(DEE, SUNTRUE); + if (check_flag(&flag, "SUNDomEigEstimator_SetIsReal_Power", 1)) { return 1; } diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 963841c097..40613ea9dd 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -309,13 +309,13 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, data->DEE = DEE; /* Set the ODE right-hand side function at t for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHS(DEE, user_data, f); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHS", 1)) { return 1; } + flag = SUNDomEigEstimator_SetRhs(DEE, user_data, f); + if (check_flag(&flag, "SUNDomEigEstimator_SetRhs", 1)) { return 1; } /* Set the linearization vector for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, + flag = SUNDomEigEstimator_SetRhsLinearizationPoint(DEE, t, y); // set the time t as well - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) + if (check_flag(&flag, "SUNDomEigEstimator_SetRhsLinearizationPoint", 1)) { return 1; } @@ -325,8 +325,8 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, } /* Update the linearization vector and time for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRHSLinearizationPoint(DEE, t, y); - if (check_flag(&flag, "SUNDomEigEstimator_SetRHSLinearizationPoint", 1)) + flag = SUNDomEigEstimator_SetRhsLinearizationPoint(DEE, t, y); + if (check_flag(&flag, "SUNDomEigEstimator_SetRhsLinearizationPoint", 1)) { return 1; } diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index de39321ca0..6791c1b5bb 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -34,7 +34,6 @@ extern "C" { typedef int (*DEERhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); -#define MAX_DQITERS 3 /* ----------------------------------------------------------------- * Generic definition of SUNDomEigEstimator (DEE) @@ -94,11 +93,11 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, +SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator DEE, sunrealtype t, N_Vector v); SUNDIALS_EXPORT diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 8e08ffa3ab..6d1fd81b9d 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -32,6 +32,8 @@ extern "C" { #endif +#define MAX_DQITERS 3 + /* ----------------------------------------------------- * Arnoldi Iteration Implementation of SUNDomEigEstimator * ----------------------------------------------------- */ @@ -83,11 +85,11 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi( +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi( SUNDomEigEstimator DEE, sunrealtype t, N_Vector v); SUNDIALS_EXPORT diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index facf402045..0be3f4af35 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -32,6 +32,8 @@ extern "C" { #endif +#define MAX_DQITERS 3 + /* ----------------------------------------------------- * Power Iteration Implementation of SUNDomEigEstimator * ----------------------------------------------------- */ @@ -76,7 +78,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, void* A_data, SUNATimesFn ATimes); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhs_Power(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn); SUNDIALS_EXPORT @@ -96,11 +98,11 @@ SUNErrCode SUNDomEigEstimator_SetInitialGuess_Power(SUNDomEigEstimator DEE, N_Vector q); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power( +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Power( SUNDomEigEstimator DEE, sunrealtype t, N_Vector v); SUNDIALS_EXPORT -SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetIsReal_Power(SUNDomEigEstimator DEE, sunbooleantype real); SUNDIALS_EXPORT diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 03def5a797..5553ee1a7f 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -206,7 +206,6 @@ void* lsrkStep_Create_Commons(ARKRhsFn rhs, sunrealtype t0, N_Vector y0, /* Initialize flags */ step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; - step_mem->use_ellipse = SUNTRUE; step_mem->is_SSP = SUNFALSE; step_mem->init_warmup = SUNTRUE; @@ -310,7 +309,6 @@ int lsrkStep_ReInit_Commons(void* arkode_mem, ARKRhsFn rhs, sunrealtype t0, step_mem->num_dee_iters = 0; step_mem->dom_eig_update = SUNTRUE; step_mem->dom_eig_is_current = SUNFALSE; - step_mem->use_ellipse = SUNTRUE; step_mem->init_warmup = SUNTRUE; return ARK_SUCCESS; @@ -575,9 +573,10 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); - /* Check if number of stages exceeds maximum allowed. If so, and if adaptive - stepping is enabled, reduce step size and return ARK_RETRY_STEP. If fixed - step size, return ARK_MAX_STAGE_LIMIT_FAIL error. */ + /* Check if number of stages exceeds maximum allowed. + If so, and if adaptive stepping is enabled, reduce step size + and return ARK_RETRY_STEP. If fixed step size, return + ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -607,16 +606,15 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - - /* To check stability, we evaluate the analytic stability function or an - inscribed ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. For - fixed step size, we increase number of stages until stability norm is - acceptable or stage_max_limit is reached. */ + /* To check stability, we evaluate the analytic stability function or an inscribed + ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. + For fixed step size, we increase number of stages until stability norm is acceptable + or stage_max_limit is reached. */ retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } - if (stability_norm > ONE - SUN_SMALL_REAL) + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { if (!ark_mem->fixedstep) { @@ -627,7 +625,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } else { - while (stability_norm > ONE - SUN_SMALL_REAL && + while (stability_norm > ONE - SUN_UNIT_ROUNDOFF && step_mem->req_stages < step_mem->stage_max_limit) { step_mem->req_stages += 1; @@ -635,7 +633,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_SMALL_REAL || + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF || step_mem->req_stages >= step_mem->stage_max_limit) { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, @@ -934,9 +932,10 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) ss = SUNMAX(ss, SUN_RCONST(2.0)); - /* Check if number of stages exceeds maximum allowed. If so, and if adaptive - stepping is enabled, reduce step size and return ARK_RETRY_STEP. If fixed - step size, return ARK_MAX_STAGE_LIMIT_FAIL error. */ + /* Check if number of stages exceeds maximum allowed. + If so, and if adaptive stepping is enabled, reduce step size + and return ARK_RETRY_STEP. If fixed step size, return + ARK_MAX_STAGE_LIMIT_FAIL error. */ if (ss >= step_mem->stage_max_limit) { SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -950,7 +949,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) hmax = ark_mem->hadapt_mem->safety * (SUNSQR(step_mem->stage_max_limit) + step_mem->stage_max_limit - TWO) / - (TWO * step_mem->spectral_radius); + (-TWO * step_mem->lambdaR); ark_mem->eta = hmax / ark_mem->h; *nflagPtr = ARK_RETRY_STEP; ark_mem->hadapt_mem->nst_exp++; @@ -967,16 +966,15 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } step_mem->req_stages = (int)ss; - - /* To check stability, we evaluate the analytic stability function or an - inscribed ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. For - fixed step size, we increase number of stages until stability norm is - acceptable or stage_max_limit is reached. */ + /* To check stability, we evaluate the analytic stability function or an inscribed + ellipse approximation. If the stability norm is greater than one, + for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. + For fixed step size, we increase number of stages until stability norm is acceptable + or stage_max_limit is reached. */ retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } - if (stability_norm > ONE - SUN_SMALL_REAL) + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { if (!ark_mem->fixedstep) { @@ -987,7 +985,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } else { - while (stability_norm > ONE - SUN_SMALL_REAL && + while (stability_norm > ONE - SUN_UNIT_ROUNDOFF && step_mem->req_stages < step_mem->stage_max_limit) { step_mem->req_stages += 1; @@ -995,7 +993,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_SMALL_REAL || + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF || step_mem->req_stages >= step_mem->stage_max_limit) { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, @@ -1266,7 +1264,7 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn is computed at the beginning + /* The method is not FSAL. Therefore, fn ​is computed at the beginning of the step unless a renewed step or ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1451,7 +1449,7 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn is computed at the beginning + /* The method is not FSAL. Therefore, fn ​is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1736,7 +1734,7 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn is computed at the beginning + /* The method is not FSAL. Therefore, fn ​is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -1941,7 +1939,7 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* The method is not FSAL. Therefore, fn is computed at the beginning + /* The method is not FSAL. Therefore, fn ​is computed at the beginning of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { @@ -2477,10 +2475,10 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) /*--------------------------------------------------------------- lsrkStep_RKC_CheckStabilityNorm: - This routine computes the stability norm for RKC methods. If use_ellipse is - SUNTRUE, we use a heuristic that approximates the stability region by an - ellipse. If use_ellipse is SUNFALSE, we compute the stability norm directly - from the stability function using the Chebyshev polynomial. + This routine computes the stability norm for RKC methods. + If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. + If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using + the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2493,16 +2491,14 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me if (step_mem->use_ellipse) { - /* The stability region of the damped RKC method is approximated by an - ellipse with vertices at (0,0), (re_stab_min,0), and - (re_stab_min/2,+/-im_stab_min). These vertices depend on the damping - parameter. Also, im_stab_min is estimated heuristically from the ellipse - aspect ratio, taken as approximately 3.65s, where s is the number of - stages (for s=2, the ratio is approximated as 0.6s). This heuristic - reflects the observed near-linear growth of the imaginary extent with the - number of stages. The numerical factors (3.65 and 0.6) were obtained - empirically from stability-region plots using the default damping - parameter and may change if the damping is modified. */ + /* The stability region of the damped RKC method is approximated by an ellipse with + vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,+/-im_stab_min). These vertices + depend on the damping parameter. Also, im_stab_min is estimated heuristically from + the ellipse aspect ratio, taken as approximately 3.65s, where s is the number of stages + (for s=2, the ratio is approximated as 0.6s). This heuristic reflects the observed + near-linear growth of the imaginary extent with the number of stages. The numerical + factors (3.65 and 0.6) were obtained empirically from stability-region plots using + the default damping parameter and may change if the damping is modified. */ re_stab_min = TWO / THREE * (ONE - SUNSQR(ss)) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); im_stab_min = -re_stab_min / @@ -2550,10 +2546,10 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me /*--------------------------------------------------------------- lsrkStep_RKL_CheckStabilityNorm: - This routine computes the stability norm for RKL methods. If use_ellipse is - SUNTRUE, we use a heuristic that approximates the stability region by an - ellipse. If use_ellipse is SUNFALSE, we compute the stability norm directly - from the stability function using the Chebyshev polynomial. + This routine computes the stability norm for RKL methods. + If use_ellipse is SUNTRUE, we use a heuristic that approximates the stability region by an ellipse. + If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using + the Chebyshev polynomial. ---------------------------------------------------------------*/ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm) @@ -2600,13 +2596,6 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me im_stab_min = -re_stab_min / (imag_extend_factor[6 - (int)ss % 2] * ss); } } - // TODO: get opinon on whether we want to use the heuristic with different - // factors for different number of stages or to use a single global factor - // for all number of stages. The heuristic with different factors for - // different number of stages is more accurate, especially for small number - // of stages, but it is also more complicated. Instead we can use a single - // global factor of 1.5 for all number of stages as follows: - // im_stab_min = -re_stab_min / (SUN_RCONST(1.5) * ss); xc = re_stab_min / TWO; yc = ZERO; @@ -2624,7 +2613,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype PsR, PsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_legendre_P_complex(ss, wr, wi, &PsR, &PsI); + int retval = lsrkStep_legendre_P_complex(step_mem->req_stages, wr, wi, &PsR, &PsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * PsR; @@ -2646,7 +2635,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me T_1(z) = z T_{k+1}(z) = 2*z*T_k(z) - T_{k-1}(z), k = 1,...,s-1 ---------------------------------------------------------------*/ -int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, +int lsrkStep_cheb_T_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* TsR, sunrealtype* TsI) { if (s < 0) @@ -2697,7 +2686,7 @@ int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, P_{k+1}(z) = ((2*k+1)*z*P_k(z) - k*P_{k-1}(z))/(k+1), k = 1,...,s-1 ---------------------------------------------------------------*/ -int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, +int lsrkStep_legendre_P_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* PsR, sunrealtype* PsI) { if (s < 0) diff --git a/src/arkode/arkode_lsrkstep_impl.h b/src/arkode/arkode_lsrkstep_impl.h index 83636d38e7..29afc67ff1 100644 --- a/src/arkode/arkode_lsrkstep_impl.h +++ b/src/arkode/arkode_lsrkstep_impl.h @@ -248,9 +248,9 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me sunrealtype* stability_norm); int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype* stability_norm); -int lsrkStep_cheb_T_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, +int lsrkStep_cheb_T_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* TsR, sunrealtype* TsI); -int lsrkStep_legendre_P_complex(sunrealtype s, sunrealtype zR, sunrealtype zI, +int lsrkStep_legendre_P_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* PsR, sunrealtype* PsI); int lsrkStep_DQJtimes(void* arkode_mem, N_Vector v, N_Vector Jv); diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index cdaf3d2cae..2bc03dfa80 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -787,6 +787,7 @@ int lsrkStep_SetDefaults(ARKodeMem ark_mem) step_mem->const_Jac = SUNFALSE; step_mem->num_init_warmups = DOM_EIG_NUM_INIT_WARMUPS_DEFAULT; step_mem->num_warmups = DOM_EIG_NUM_WARMUPS_DEFAULT; + step_mem->use_ellipse = SUNTRUE; /* Load the default SUNAdaptController */ retval = arkReplaceAdaptController(ark_mem, NULL, SUNTRUE); diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index f8845fa1af..91a0ef8531 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -3800,7 +3800,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; @@ -3810,13 +3810,13 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); arg3 = (DEERhsFn)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHS(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhs(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -3826,7 +3826,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstim arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); arg3 = (N_Vector)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhsLinearizationPoint(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index e88cf2f64a..db23ebb4f8 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -712,8 +712,8 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_NewEmpty public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes - public :: FSUNDomEigEstimator_SetRHS - public :: FSUNDomEigEstimator_SetRHSLinearizationPoint + public :: FSUNDomEigEstimator_SetRhs + public :: FSUNDomEigEstimator_SetRhsLinearizationPoint public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2940,8 +2940,8 @@ function swigc_FSUNDomEigEstimator_SetATimes(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS") & +function swigc_FSUNDomEigEstimator_SetRhs(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhs") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -2950,8 +2950,8 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & +function swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -7150,7 +7150,7 @@ function FSUNDomEigEstimator_SetATimes(dee, a_data, atimes) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & +function FSUNDomEigEstimator_SetRhs(dee, rhs_data, rhsfn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7165,11 +7165,11 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & farg1 = c_loc(dee) farg2 = rhs_data farg3 = rhsfn -fresult = swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhs(farg1, farg2, farg3) swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & +function FSUNDomEigEstimator_SetRhsLinearizationPoint(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7184,7 +7184,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & farg1 = c_loc(dee) farg2 = t farg3 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index 9188255af7..8246fdb86a 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -3800,7 +3800,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; @@ -3810,13 +3810,13 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS(SUNDomEigEstimator farg1, void * arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); arg3 = (DEERhsFn)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHS(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhs(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -3826,7 +3826,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstim arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); arg3 = (N_Vector)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhsLinearizationPoint(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 37ec0768d0..94c1c24625 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -712,8 +712,8 @@ module fsundials_core_mod public :: FSUNDomEigEstimator_NewEmpty public :: FSUNDomEigEstimator_FreeEmpty public :: FSUNDomEigEstimator_SetATimes - public :: FSUNDomEigEstimator_SetRHS - public :: FSUNDomEigEstimator_SetRHSLinearizationPoint + public :: FSUNDomEigEstimator_SetRhs + public :: FSUNDomEigEstimator_SetRhsLinearizationPoint public :: FSUNDomEigEstimator_SetMaxIters public :: FSUNDomEigEstimator_SetNumPreprocessIters public :: FSUNDomEigEstimator_SetRelTol @@ -2940,8 +2940,8 @@ function swigc_FSUNDomEigEstimator_SetATimes(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS") & +function swigc_FSUNDomEigEstimator_SetRhs(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhs") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -2950,8 +2950,8 @@ function swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint") & +function swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -7150,7 +7150,7 @@ function FSUNDomEigEstimator_SetATimes(dee, a_data, atimes) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & +function FSUNDomEigEstimator_SetRhs(dee, rhs_data, rhsfn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7165,11 +7165,11 @@ function FSUNDomEigEstimator_SetRHS(dee, rhs_data, rhsfn) & farg1 = c_loc(dee) farg2 = rhs_data farg3 = rhsfn -fresult = swigc_FSUNDomEigEstimator_SetRHS(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhs(farg1, farg2, farg3) swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & +function FSUNDomEigEstimator_SetRhsLinearizationPoint(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -7184,7 +7184,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationPoint(dee, t, v) & farg1 = c_loc(dee) farg2 = t farg3 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index f38c293333..7a78b9b1bd 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -193,7 +193,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, return (ier); } -SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, +SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) { SUNErrCode ier; @@ -204,7 +204,7 @@ SUNErrCode SUNDomEigEstimator_SetRHS(SUNDomEigEstimator DEE, void* rhs_data, return (ier); } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator DEE, sunrealtype t, N_Vector v) { SUNErrCode ier; diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index 6928cfcdaa..ba7ba33934 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -939,7 +939,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; @@ -949,13 +949,13 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); arg3 = (DEERhsFn)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHS_Arnoldi(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhs_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -965,7 +965,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDom arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); arg3 = (N_Vector)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index b1e9b7321d..94a25a806d 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -97,8 +97,8 @@ module fsundomeigest_arnoldi_mod end interface public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi - public :: FSUNDomEigEstimator_SetRHS_Arnoldi - public :: FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi + public :: FSUNDomEigEstimator_SetRhs_Arnoldi + public :: FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi @@ -562,8 +562,8 @@ function swigc_FSUNDomEigEstimator_SetATimes_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRhs_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhs_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -572,8 +572,8 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1342,7 +1342,7 @@ function FSUNDomEigEstimator_SetATimes_Arnoldi(dee, a_data, atimes) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & +function FSUNDomEigEstimator_SetRhs_Arnoldi(dee, rhs_data, rhsfn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1357,11 +1357,11 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & farg1 = c_loc(dee) farg2 = rhs_data farg3 = rhsfn -fresult = swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhs_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & +function FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1376,7 +1376,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & farg1 = c_loc(dee) farg2 = t farg3 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index 549c4f04f6..6f6e219471 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -939,7 +939,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; @@ -949,13 +949,13 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator farg1 arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); arg3 = (DEERhsFn)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHS_Arnoldi(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhs_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(SUNDomEigEstimator farg1, double const *farg2, N_Vector farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; sunrealtype arg2 ; @@ -965,7 +965,7 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(SUNDom arg1 = (SUNDomEigEstimator)(farg1); arg2 = (sunrealtype)(*farg2); arg3 = (N_Vector)(farg3); - result = (SUNErrCode)SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(arg1,arg2,arg3); + result = (SUNErrCode)SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; } diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index 980b7f0d5f..0fefce6391 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -97,8 +97,8 @@ module fsundomeigest_arnoldi_mod end interface public :: FSUNDomEigEstimator_Arnoldi public :: FSUNDomEigEstimator_SetATimes_Arnoldi - public :: FSUNDomEigEstimator_SetRHS_Arnoldi - public :: FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi + public :: FSUNDomEigEstimator_SetRhs_Arnoldi + public :: FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi public :: FSUNDomEigEstimator_SetNumPreprocessIters_Arnoldi public :: FSUNDomEigEstimator_SetRelTol_Arnoldi public :: FSUNDomEigEstimator_SetInitialGuess_Arnoldi @@ -562,8 +562,8 @@ function swigc_FSUNDomEigEstimator_SetATimes_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHS_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRhs_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhs_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -572,8 +572,8 @@ function swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) & integer(C_INT) :: fresult end function -function swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi") & +function swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(farg1, farg2, farg3) & +bind(C, name="_wrap_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi") & result(fresult) use, intrinsic :: ISO_C_BINDING type(C_PTR), value :: farg1 @@ -1342,7 +1342,7 @@ function FSUNDomEigEstimator_SetATimes_Arnoldi(dee, a_data, atimes) & swig_result = fresult end function -function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & +function FSUNDomEigEstimator_SetRhs_Arnoldi(dee, rhs_data, rhsfn) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1357,11 +1357,11 @@ function FSUNDomEigEstimator_SetRHS_Arnoldi(dee, rhs_data, rhsfn) & farg1 = c_loc(dee) farg2 = rhs_data farg3 = rhsfn -fresult = swigc_FSUNDomEigEstimator_SetRHS_Arnoldi(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhs_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function -function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & +function FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(dee, t, v) & result(swig_result) use, intrinsic :: ISO_C_BINDING integer(C_INT) :: swig_result @@ -1376,7 +1376,7 @@ function FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(dee, t, v) & farg1 = c_loc(dee) farg2 = t farg3 = c_loc(v) -fresult = swigc_FSUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi(farg1, farg2, farg3) +fresult = swigc_FSUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi(farg1, farg2, farg3) swig_result = fresult end function diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 950460e1ab..62e18e4f1d 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -106,9 +106,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Arnoldi(N_Vector q, int kry_dim, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Arnoldi; - DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Arnoldi; + DEE->ops->setrhs = SUNDomEigEstimator_SetRhs_Arnoldi; DEE->ops->setrhslinearizationpoint = - SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi; + SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Arnoldi; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Arnoldi; @@ -188,7 +188,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); @@ -207,7 +207,7 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Arnoldi(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Arnoldi( +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi( SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) { SUNFunctionBegin(DEE->sunctx); diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 511b1e4253..2705434a7d 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -101,9 +101,9 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, /* Attach operations */ DEE->ops->setatimes = SUNDomEigEstimator_SetATimes_Power; - DEE->ops->setrhs = SUNDomEigEstimator_SetRHS_Power; + DEE->ops->setrhs = SUNDomEigEstimator_SetRhs_Power; DEE->ops->setrhslinearizationpoint = - SUNDomEigEstimator_SetRHSLinearizationPoint_Power; + SUNDomEigEstimator_SetRhsLinearizationPoint_Power; DEE->ops->setmaxiters = SUNDomEigEstimator_SetMaxIters_Power; DEE->ops->setnumpreprocessiters = SUNDomEigEstimator_SetNumPreprocessIters_Power; DEE->ops->setreltol = SUNDomEigEstimator_SetRelTol_Power; @@ -180,7 +180,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetRhs_Power(SUNDomEigEstimator DEE, void* rhs_data, DEERhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); @@ -200,7 +200,7 @@ SUNErrCode SUNDomEigEstimator_SetRHS_Power(SUNDomEigEstimator DEE, return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power( +SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Power( SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) { SUNFunctionBegin(DEE->sunctx); @@ -223,7 +223,7 @@ SUNErrCode SUNDomEigEstimator_SetRHSLinearizationPoint_Power( return SUN_SUCCESS; } -SUNErrCode SUNDomEigEstimator_SetDEEisReal_Power(SUNDomEigEstimator DEE, +SUNErrCode SUNDomEigEstimator_SetIsReal_Power(SUNDomEigEstimator DEE, sunbooleantype real) { SUNFunctionBegin(DEE->sunctx); From 2fdf3c94dd08552fccb72af4f64a649f242bd456 Mon Sep 17 00:00:00 2001 From: maggul Date: Mon, 30 Mar 2026 23:57:08 -0500 Subject: [PATCH 49/76] formatting --- .../sundomeigest/sundomeigest_power_generated.hpp | 4 ++-- examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c | 5 +---- include/sundomeigest/sundomeigest_power.h | 2 +- src/arkode/arkode_lsrkstep.c | 3 ++- src/sundomeigest/power/sundomeigest_power.c | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp index e5e1dc4267..27b613dd62 100644 --- a/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp +++ b/bindings/sundials4py/sundomeigest/sundomeigest_power_generated.hpp @@ -33,8 +33,8 @@ m.def( nb::arg("q"), nb::arg("max_iters"), nb::arg("rel_tol"), nb::arg("sunctx"), "nb::keep_alive<0, 4>()", nb::keep_alive<0, 4>()); -m.def("SUNDomEigEstimator_SetIsReal_Power", - SUNDomEigEstimator_SetIsReal_Power, nb::arg("DEE"), nb::arg("real")); +m.def("SUNDomEigEstimator_SetIsReal_Power", SUNDomEigEstimator_SetIsReal_Power, + nb::arg("DEE"), nb::arg("real")); // #ifdef __cplusplus // // #endif diff --git a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c index 3ed19609fd..6327634e11 100644 --- a/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c +++ b/examples/arkode/C_serial/ark_analytic_lsrk_domeigest.c @@ -239,10 +239,7 @@ int main(int argc, char* argv[]) /* Set real type dominant eigenvalue */ flag = SUNDomEigEstimator_SetIsReal_Power(DEE, SUNTRUE); - if (check_flag(&flag, "SUNDomEigEstimator_SetIsReal_Power", 1)) - { - return 1; - } + if (check_flag(&flag, "SUNDomEigEstimator_SetIsReal_Power", 1)) { return 1; } /* Open output stream for results, output comment line */ UFID = fopen("solution.txt", "w"); diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 0be3f4af35..4386142d48 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -103,7 +103,7 @@ SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Power( SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetIsReal_Power(SUNDomEigEstimator DEE, - sunbooleantype real); + sunbooleantype real); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE); diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 5553ee1a7f..4b76f81190 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -2613,7 +2613,8 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype PsR, PsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_legendre_P_complex(step_mem->req_stages, wr, wi, &PsR, &PsI); + int retval = lsrkStep_legendre_P_complex(step_mem->req_stages, wr, wi, &PsR, + &PsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * PsR; diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 2705434a7d..9a439b272b 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -224,7 +224,7 @@ SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Power( } SUNErrCode SUNDomEigEstimator_SetIsReal_Power(SUNDomEigEstimator DEE, - sunbooleantype real) + sunbooleantype real) { SUNFunctionBegin(DEE->sunctx); From b03da4fa7002f58100dec8ae1d43d73606ba2b10 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 31 Mar 2026 00:05:33 -0500 Subject: [PATCH 50/76] swig --- src/sundials/fmod_int32/fsundials_core_mod.f90 | 1 - src/sundials/fmod_int64/fsundials_core_mod.f90 | 1 - .../arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 | 1 + .../arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 | 1 + 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sundials/fmod_int32/fsundials_core_mod.f90 b/src/sundials/fmod_int32/fsundials_core_mod.f90 index db23ebb4f8..97e60c7469 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int32/fsundials_core_mod.f90 @@ -683,7 +683,6 @@ module fsundials_core_mod public :: FSUNAdjointStepper_GetNumRecompute public :: FSUNAdjointStepper_PrintAllStats public :: FSUNAdjointStepper_Destroy - integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT ! struct struct SUNDomEigEstimator_Ops_ type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes diff --git a/src/sundials/fmod_int64/fsundials_core_mod.f90 b/src/sundials/fmod_int64/fsundials_core_mod.f90 index 94c1c24625..e7d8ba4e79 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.f90 +++ b/src/sundials/fmod_int64/fsundials_core_mod.f90 @@ -683,7 +683,6 @@ module fsundials_core_mod public :: FSUNAdjointStepper_GetNumRecompute public :: FSUNAdjointStepper_PrintAllStats public :: FSUNAdjointStepper_Destroy - integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT ! struct struct SUNDomEigEstimator_Ops_ type, bind(C), public :: SUNDomEigEstimator_Ops type(C_FUNPTR), public :: setatimes diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 index 94a25a806d..18adbe9fd2 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.f90 @@ -28,6 +28,7 @@ module fsundomeigest_arnoldi_mod private ! DECLARATION CONSTRUCTS + integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT integer, parameter :: swig_cmem_own_bit = 0 integer, parameter :: swig_cmem_rvalue_bit = 1 diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 index 0fefce6391..9ac8f69d94 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.f90 @@ -28,6 +28,7 @@ module fsundomeigest_arnoldi_mod private ! DECLARATION CONSTRUCTS + integer(C_INT), parameter, public :: MAX_DQITERS = 3_C_INT integer, parameter :: swig_cmem_own_bit = 0 integer, parameter :: swig_cmem_rvalue_bit = 1 From 7b5055502221d9ca8489f3785908cb10be76ca32 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 31 Mar 2026 00:19:29 -0500 Subject: [PATCH 51/76] double to int --- src/arkode/arkode_lsrkstep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 4b76f81190..d1bfcd68ba 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -2531,7 +2531,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype TsR, TsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_cheb_T_complex(ss, wr, wi, &TsR, &TsI); + int retval = lsrkStep_cheb_T_complex(step_mem->req_stages, wr, wi, &TsR, &TsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * TsR; From f798b0ba8b8e6ad7c05ba6c346ea514674118647 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 31 Mar 2026 00:26:08 -0500 Subject: [PATCH 52/76] formatting --- src/arkode/arkode_lsrkstep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index d1bfcd68ba..e032c5ef1c 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -2531,7 +2531,8 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype TsR, TsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_cheb_T_complex(step_mem->req_stages, wr, wi, &TsR, &TsI); + int retval = lsrkStep_cheb_T_complex(step_mem->req_stages, wr, wi, &TsR, + &TsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * TsR; From b26fb9d23519301ab77060cd4251829bb0003cbe Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 31 Mar 2026 08:11:07 -0500 Subject: [PATCH 53/76] update answers --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index ba4e28e3c5..f31cc77e1c 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit ba4e28e3c53b7883eea1f67ca1f3fc50deef5435 +Subproject commit f31cc77e1c3c44b23b021f914e0a4341a206cd39 From 159df676a5535494a04661f151b6549d2490597c Mon Sep 17 00:00:00 2001 From: maggul Date: Wed, 1 Apr 2026 13:26:07 -0500 Subject: [PATCH 54/76] revision II --- .../sundials/sundials_domeigestimator.cpp | 2 +- .../sundials_domeigestimator_usersupplied.hpp | 2 +- .../sundomeigest/SUNDomEigEst_Arnoldi.rst | 2 +- .../sundomeigest/SUNDomEigEst_Power.rst | 2 +- include/sundials/sundials_domeigestimator.h | 6 +- include/sundomeigest/sundomeigest_arnoldi.h | 4 +- include/sundomeigest/sundomeigest_power.h | 4 +- src/arkode/arkode_lsrkstep.c | 151 +++++++++++------- src/arkode/arkode_lsrkstep_impl.h | 6 +- src/sundials/fmod_int32/fsundials_core_mod.c | 6 +- src/sundials/fmod_int64/fsundials_core_mod.c | 6 +- src/sundials/sundials_domeigestimator.c | 2 +- .../fmod_int32/fsundomeigest_arnoldi_mod.c | 20 +-- .../fmod_int64/fsundomeigest_arnoldi_mod.c | 20 +-- .../arnoldi/sundomeigest_arnoldi.c | 2 +- src/sundomeigest/power/sundomeigest_power.c | 2 +- 16 files changed, 140 insertions(+), 97 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp index 410e3b1dfa..ee0ac40326 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator.cpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator.cpp @@ -87,7 +87,7 @@ void bind_sundomeigestimator(nb::module_& m) m.def( "SUNDomEigEstimator_SetRhs", [](SUNDomEigEstimator DEE, - std::function> RHSfn) -> SUNErrCode + std::function> RHSfn) -> SUNErrCode { if (!DEE->python) { DEE->python = new SUNDomEigEstimatorFunctionTable; } diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp index 5c1a2be02a..f37a23aa72 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp @@ -48,7 +48,7 @@ template SUNErrCode sundomeigestimator_setrhs_wrapper(Args... args) { return sundials4py::user_supplied_fn_caller< - std::remove_pointer_t, SUNDomEigEstimatorFunctionTable, + std::remove_pointer_t, SUNDomEigEstimatorFunctionTable, 3>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); } diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst index 5cee1216ea..29dcde5400 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst @@ -126,7 +126,7 @@ The SUNDomEigEstimator_Arnoldi module defines the *content* field of a sunrealtype tol_preprocess; sunrealtype rhs_linT; long int num_ATimes; - DEERhsFn rhsfn; + SUNRhsFn rhsfn; void* rhs_data; long int nfevals; sunrealtype* LAPACK_A; diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index 41b386f7ee..c075c5f99f 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -159,7 +159,7 @@ The SUNDomEigEstimator_Power module defines the *content* field of a sunrealtype rhs_linT; sunrealtype rel_tol; sunrealtype res; - DEERhsFn rhsfn; + SUNRhsFn rhsfn; void* rhs_data; long int nfevals; sunbooleantype complex; diff --git a/include/sundials/sundials_domeigestimator.h b/include/sundials/sundials_domeigestimator.h index 6791c1b5bb..fd27517e35 100644 --- a/include/sundials/sundials_domeigestimator.h +++ b/include/sundials/sundials_domeigestimator.h @@ -32,7 +32,7 @@ extern "C" { #endif -typedef int (*DEERhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, +typedef int (*SUNRhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* user_data); /* ----------------------------------------------------------------- @@ -49,7 +49,7 @@ typedef _SUNDIALS_STRUCT_ SUNDomEigEstimator_* SUNDomEigEstimator; struct SUNDomEigEstimator_Ops_ { SUNErrCode (*setatimes)(SUNDomEigEstimator, void*, SUNATimesFn); - SUNErrCode (*setrhs)(SUNDomEigEstimator, void*, DEERhsFn); + SUNErrCode (*setrhs)(SUNDomEigEstimator, void*, SUNRhsFn); SUNErrCode (*setrhslinearizationpoint)(SUNDomEigEstimator, sunrealtype, N_Vector); SUNErrCode (*setoptions)(SUNDomEigEstimator DEE, const char* Did, @@ -94,7 +94,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, - DEERhsFn RHSfn); + SUNRhsFn RHSfn); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator DEE, diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 6d1fd81b9d..27e6d30147 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -56,7 +56,7 @@ struct SUNDomEigEstimatorContent_Arnoldi_ long int num_ATimes; /* Number of ATimes calls */ - DEERhsFn rhsfn; /* User provided RHS function */ + SUNRhsFn rhsfn; /* User provided RHS function */ void* rhs_data; /* RHS function data */ long int nfevals; /* Number of RHS evaluations */ @@ -86,7 +86,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn); + void* rhs_data, SUNRhsFn RHSfn); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint_Arnoldi( diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index 4386142d48..b8319c56b7 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -55,7 +55,7 @@ struct SUNDomEigEstimatorContent_Power_ sunrealtype rel_tol; /* Convergence criteria for the power iteration */ sunrealtype res; /* Residual from the last Estimate call */ - DEERhsFn rhsfn; /* User provided RHS function */ + SUNRhsFn rhsfn; /* User provided RHS function */ void* rhs_data; /* RHS function data */ long int nfevals; /* Number of RHS evaluations */ @@ -79,7 +79,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetRhs_Power(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn); + void* rhs_data, SUNRhsFn RHSfn); SUNDIALS_EXPORT SUNErrCode SUNDomEigEstimator_SetMaxIters_Power(SUNDomEigEstimator DEE, diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index e032c5ef1c..19a4134277 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -605,36 +605,55 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } - step_mem->req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an inscribed - ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. - For fixed step size, we increase number of stages until stability norm is acceptable - or stage_max_limit is reached. */ - retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); + int req_stages = (int)ss; + + /* To check stability, we evaluate the analytic stability function or an + inscribed ellipse approximation. If the stability norm is greater than + one, first check whether the method is stable at stage_max_limit. If so, + increase the number of stages until stability is obtained. Otherwise, + keep the existing fixed-step error and adaptive-step eta update logic. */ + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, + &stability_norm); if (retval != ARK_SUCCESS) { return retval; } if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - if (!ark_mem->fixedstep) + sunrealtype initial_stability_norm = stability_norm; + sunbooleantype max_stage_is_stable = SUNFALSE; + + if (req_stages < step_mem->stage_max_limit) { - ark_mem->eta = ark_mem->hadapt_mem->safety / stability_norm; - *nflagPtr = ARK_RETRY_STEP; - ark_mem->hadapt_mem->nst_exp++; - return ARK_RETRY_STEP; + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, + step_mem->stage_max_limit, + ark_mem->h, &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + + max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); + stability_norm = initial_stability_norm; } - else + + if (max_stage_is_stable) { - while (stability_norm > ONE - SUN_UNIT_ROUNDOFF && - step_mem->req_stages < step_mem->stage_max_limit) + while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && + (req_stages < step_mem->stage_max_limit)) { - step_mem->req_stages += 1; - retval = lsrkStep_RKC_CheckStabilityNorm(ark_mem, step_mem, - &stability_norm); + req_stages += 1; + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF || - step_mem->req_stages >= step_mem->stage_max_limit) + } + + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) + { + if (!ark_mem->fixedstep) + { + ark_mem->eta = ark_mem->hadapt_mem->safety / initial_stability_norm; + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, __FILE__, @@ -645,6 +664,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } + step_mem->req_stages = req_stages; + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -965,36 +986,56 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } - step_mem->req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an inscribed - ellipse approximation. If the stability norm is greater than one, - for adaptive stepping, we reduce step size and return ARK_RETRY_STEP. - For fixed step size, we increase number of stages until stability norm is acceptable - or stage_max_limit is reached. */ - retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, &stability_norm); + int req_stages = (int)ss; + + /* To check stability, we evaluate the analytic stability function or an + inscribed ellipse approximation. If the stability norm is greater than + one, first check whether the method is stable at stage_max_limit. If so, + increase the number of stages until stability is obtained. Otherwise, + keep the existing fixed-step error and adaptive-step eta update logic. */ + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, + &stability_norm); if (retval != ARK_SUCCESS) { return retval; } if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - if (!ark_mem->fixedstep) + sunrealtype initial_stability_norm = stability_norm; + sunbooleantype max_stage_is_stable = SUNFALSE; + + if (req_stages < step_mem->stage_max_limit) { - ark_mem->eta = ark_mem->hadapt_mem->safety / stability_norm; - *nflagPtr = ARK_RETRY_STEP; - ark_mem->hadapt_mem->nst_exp++; - return ARK_RETRY_STEP; + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, + step_mem->stage_max_limit, + ark_mem->h, + &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + + max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); + stability_norm = initial_stability_norm; } - else + + if (max_stage_is_stable) { - while (stability_norm > ONE - SUN_UNIT_ROUNDOFF && - step_mem->req_stages < step_mem->stage_max_limit) + while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && + (req_stages < step_mem->stage_max_limit)) { - step_mem->req_stages += 1; - retval = lsrkStep_RKL_CheckStabilityNorm(ark_mem, step_mem, - &stability_norm); + req_stages += 1; + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF || - step_mem->req_stages >= step_mem->stage_max_limit) + } + + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) + { + if (!ark_mem->fixedstep) + { + ark_mem->eta = ark_mem->hadapt_mem->safety / initial_stability_norm; + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else { arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, __FILE__, @@ -1005,6 +1046,8 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } + step_mem->req_stages = req_stages; + step_mem->stage_max = SUNMAX(step_mem->req_stages, step_mem->stage_max); SUNLogInfo(ARK_LOGGER, "compute-num-stages", @@ -2434,7 +2477,7 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) return ARK_DOMEIG_FAIL; } - if (step_mem->lambdaR * ark_mem->h > ZERO) + if (step_mem->lambdaR * ark_mem->h > SUNRsqrt(SUN_UNIT_ROUNDOFF)) { arkProcessError(NULL, ARK_DOMEIG_FAIL, __LINE__, __func__, __FILE__, "lambdaR*h must be nonpositive"); @@ -2480,14 +2523,14 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ -int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, - sunrealtype* stability_norm) +int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, + sunrealtype h, sunrealtype* stability_norm) { - sunrealtype ss = step_mem->req_stages; + sunrealtype ss = (sunrealtype)num_stages; sunrealtype w0, w1, wr, wi, th, sh, ch, b_s, a_s, Ts, Ts_p, Ts_pp, a, b, xc, yc; sunrealtype re_stab_min, im_stab_min; - sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; + sunrealtype zR = SUNRabs(h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(h) * step_mem->lambdaI; if (step_mem->use_ellipse) { @@ -2531,8 +2574,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype TsR, TsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_cheb_T_complex(step_mem->req_stages, wr, wi, &TsR, - &TsI); + int retval = lsrkStep_cheb_T_complex(num_stages, wr, wi, &TsR, &TsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * TsR; @@ -2552,14 +2594,14 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ -int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, - sunrealtype* stability_norm) +int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, + sunrealtype h, sunrealtype* stability_norm) { - sunrealtype ss = step_mem->req_stages; + sunrealtype ss = (sunrealtype)num_stages; sunrealtype w1, wr, wi, a_s, b_s, a, b, xc, yc; sunrealtype re_stab_min, im_stab_min; - sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype zI = SUNRabs(ark_mem->h) * step_mem->lambdaI; + sunrealtype zR = SUNRabs(h) * step_mem->lambdaR; + sunrealtype zI = SUNRabs(h) * step_mem->lambdaI; if (step_mem->use_ellipse) { @@ -2614,8 +2656,7 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_me wi = w1 * zI; sunrealtype PsR, PsI, Ps_ZR, Ps_ZI; - int retval = lsrkStep_legendre_P_complex(step_mem->req_stages, wr, wi, &PsR, - &PsI); + int retval = lsrkStep_legendre_P_complex(num_stages, wr, wi, &PsR, &PsI); if (retval != ARK_SUCCESS) { return retval; } Ps_ZR = a_s + b_s * PsR; diff --git a/src/arkode/arkode_lsrkstep_impl.h b/src/arkode/arkode_lsrkstep_impl.h index 29afc67ff1..aaa7bb9e1c 100644 --- a/src/arkode/arkode_lsrkstep_impl.h +++ b/src/arkode/arkode_lsrkstep_impl.h @@ -244,9 +244,11 @@ int lsrkStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, void lsrkStep_DomEigUpdateLogic(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype dsm); int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem); -int lsrkStep_RKC_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, +int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, + int num_stages, sunrealtype h, sunrealtype* stability_norm); -int lsrkStep_RKL_CheckStabilityNorm(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, +int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, + int num_stages, sunrealtype h, sunrealtype* stability_norm); int lsrkStep_cheb_T_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* TsR, sunrealtype* TsI); diff --git a/src/sundials/fmod_int32/fsundials_core_mod.c b/src/sundials/fmod_int32/fsundials_core_mod.c index dd2ca2a602..c690e87f87 100644 --- a/src/sundials/fmod_int32/fsundials_core_mod.c +++ b/src/sundials/fmod_int32/fsundials_core_mod.c @@ -3856,16 +3856,16 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, SUNRhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; - DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNRhsFn arg3 = (SUNRhsFn) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); - arg3 = (DEERhsFn)(farg3); + arg3 = (SUNRhsFn)(farg3); result = (SUNErrCode)SUNDomEigEstimator_SetRhs(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; diff --git a/src/sundials/fmod_int64/fsundials_core_mod.c b/src/sundials/fmod_int64/fsundials_core_mod.c index ac03d92d4b..da329cd45e 100644 --- a/src/sundials/fmod_int64/fsundials_core_mod.c +++ b/src/sundials/fmod_int64/fsundials_core_mod.c @@ -3856,16 +3856,16 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes(SUNDomEigEstimator farg1, voi } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs(SUNDomEigEstimator farg1, void *farg2, SUNRhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; - DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNRhsFn arg3 = (SUNRhsFn) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); - arg3 = (DEERhsFn)(farg3); + arg3 = (SUNRhsFn)(farg3); result = (SUNErrCode)SUNDomEigEstimator_SetRhs(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; diff --git a/src/sundials/sundials_domeigestimator.c b/src/sundials/sundials_domeigestimator.c index 7a78b9b1bd..aba7b5b66a 100644 --- a/src/sundials/sundials_domeigestimator.c +++ b/src/sundials/sundials_domeigestimator.c @@ -194,7 +194,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes(SUNDomEigEstimator DEE, void* A_data, } SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, - DEERhsFn RHSfn) + SUNRhsFn RHSfn) { SUNErrCode ier; SUNDIALS_MARK_FUNCTION_BEGIN(getSUNProfiler(DEE)); diff --git a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c index ba7ba33934..295c851da4 100644 --- a/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int32/fsundomeigest_arnoldi_mod.c @@ -636,25 +636,25 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(SwigClas } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, DEERhsFn farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, SUNRhsFn farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; - DEERhsFn arg2 = (DEERhsFn) 0 ; + SUNRhsFn arg2 = (SUNRhsFn) 0 ; SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - arg2 = (DEERhsFn)(farg2); + arg2 = (SUNRhsFn)(farg2); if (arg1) (arg1)->rhsfn = arg2; } -SWIGEXPORT DEERhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { - DEERhsFn fresult ; +SWIGEXPORT SUNRhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { + SUNRhsFn fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; - DEERhsFn result; + SUNRhsFn result; SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (DEERhsFn) ((arg1)->rhsfn); + result = (SUNRhsFn) ((arg1)->rhsfn); fresult = result; return fresult; } @@ -939,16 +939,16 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, SUNRhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; - DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNRhsFn arg3 = (SUNRhsFn) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); - arg3 = (DEERhsFn)(farg3); + arg3 = (SUNRhsFn)(farg3); result = (SUNErrCode)SUNDomEigEstimator_SetRhs_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; diff --git a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c index 6f6e219471..98bddb6137 100644 --- a/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c +++ b/src/sundomeigest/arnoldi/fmod_int64/fsundomeigest_arnoldi_mod.c @@ -636,25 +636,25 @@ SWIGEXPORT long _wrap_SUNDomEigEstimatorContent_Arnoldi__num_ATimes_get(SwigClas } -SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, DEERhsFn farg2) { +SWIGEXPORT void _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_set(SwigClassWrapper const *farg1, SUNRhsFn farg2) { struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; - DEERhsFn arg2 = (DEERhsFn) 0 ; + SUNRhsFn arg2 = (SUNRhsFn) 0 ; SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return ); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - arg2 = (DEERhsFn)(farg2); + arg2 = (SUNRhsFn)(farg2); if (arg1) (arg1)->rhsfn = arg2; } -SWIGEXPORT DEERhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { - DEERhsFn fresult ; +SWIGEXPORT SUNRhsFn _wrap_SUNDomEigEstimatorContent_Arnoldi__rhsfn_get(SwigClassWrapper const *farg1) { + SUNRhsFn fresult ; struct SUNDomEigEstimatorContent_Arnoldi_ *arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *) 0 ; - DEERhsFn result; + SUNRhsFn result; SWIG_check_mutable_nonnull(*farg1, "struct SUNDomEigEstimatorContent_Arnoldi_ *", "SUNDomEigEstimatorContent_Arnoldi_", "SUNDomEigEstimatorContent_Arnoldi_::rhsfn", return 0); arg1 = (struct SUNDomEigEstimatorContent_Arnoldi_ *)(farg1->cptr); - result = (DEERhsFn) ((arg1)->rhsfn); + result = (SUNRhsFn) ((arg1)->rhsfn); fresult = result; return fresult; } @@ -939,16 +939,16 @@ SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator fa } -SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, DEERhsFn farg3) { +SWIGEXPORT int _wrap_FSUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator farg1, void *farg2, SUNRhsFn farg3) { int fresult ; SUNDomEigEstimator arg1 = (SUNDomEigEstimator) 0 ; void *arg2 = (void *) 0 ; - DEERhsFn arg3 = (DEERhsFn) 0 ; + SUNRhsFn arg3 = (SUNRhsFn) 0 ; SUNErrCode result; arg1 = (SUNDomEigEstimator)(farg1); arg2 = (void *)(farg2); - arg3 = (DEERhsFn)(farg3); + arg3 = (SUNRhsFn)(farg3); result = (SUNErrCode)SUNDomEigEstimator_SetRhs_Arnoldi(arg1,arg2,arg3); fresult = (SUNErrCode)(result); return fresult; diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 62e18e4f1d..003e826644 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -189,7 +189,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Arnoldi(SUNDomEigEstimator DEE, } SUNErrCode SUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn) + void* rhs_data, SUNRhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 9a439b272b..98e67132e3 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -181,7 +181,7 @@ SUNErrCode SUNDomEigEstimator_SetATimes_Power(SUNDomEigEstimator DEE, } SUNErrCode SUNDomEigEstimator_SetRhs_Power(SUNDomEigEstimator DEE, - void* rhs_data, DEERhsFn RHSfn) + void* rhs_data, SUNRhsFn RHSfn) { SUNFunctionBegin(DEE->sunctx); From 14cfec9eab8c187f859e9f00ef55b792e6e8b010 Mon Sep 17 00:00:00 2001 From: maggul Date: Wed, 1 Apr 2026 14:37:47 -0500 Subject: [PATCH 55/76] formatting --- src/arkode/arkode_lsrkstep.c | 13 ++++++------- src/arkode/arkode_lsrkstep_impl.h | 10 ++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 19a4134277..94ac4d9cc0 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -612,7 +612,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) one, first check whether the method is stable at stage_max_limit. If so, increase the number of stages until stability is obtained. Otherwise, keep the existing fixed-step error and adaptive-step eta update logic. */ - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -623,7 +623,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (req_stages < step_mem->stage_max_limit) { - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, step_mem->stage_max_limit, ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } @@ -638,7 +638,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) (req_stages < step_mem->stage_max_limit)) { req_stages += 1; - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } @@ -1006,8 +1006,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) { retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, step_mem->stage_max_limit, - ark_mem->h, - &stability_norm); + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); @@ -2523,7 +2522,7 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ -int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, +int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, sunrealtype h, sunrealtype* stability_norm) { sunrealtype ss = (sunrealtype)num_stages; @@ -2594,7 +2593,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, If use_ellipse is SUNFALSE, we compute the stability norm directly from the stability function using the Chebyshev polynomial. ---------------------------------------------------------------*/ -int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, +int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, sunrealtype h, sunrealtype* stability_norm) { sunrealtype ss = (sunrealtype)num_stages; diff --git a/src/arkode/arkode_lsrkstep_impl.h b/src/arkode/arkode_lsrkstep_impl.h index aaa7bb9e1c..5e4398eb18 100644 --- a/src/arkode/arkode_lsrkstep_impl.h +++ b/src/arkode/arkode_lsrkstep_impl.h @@ -244,12 +244,10 @@ int lsrkStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, void lsrkStep_DomEigUpdateLogic(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, sunrealtype dsm); int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem); -int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, - int num_stages, sunrealtype h, - sunrealtype* stability_norm); -int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, - int num_stages, sunrealtype h, - sunrealtype* stability_norm); +int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, + sunrealtype h, sunrealtype* stability_norm); +int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, + sunrealtype h, sunrealtype* stability_norm); int lsrkStep_cheb_T_complex(int s, sunrealtype zR, sunrealtype zI, sunrealtype* TsR, sunrealtype* TsI); int lsrkStep_legendre_P_complex(int s, sunrealtype zR, sunrealtype zI, From 3fcc198b55e1d232ad1bf1a462046ec36ffa7db6 Mon Sep 17 00:00:00 2001 From: maggul Date: Wed, 1 Apr 2026 21:49:05 -0500 Subject: [PATCH 56/76] update output files --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index f31cc77e1c..cc74e2913e 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit f31cc77e1c3c44b23b021f914e0a4341a206cd39 +Subproject commit cc74e2913e28396e858a43c6f02a126f4beadbea From 8ee74b63e288ecea6d1660978f7a4c42740cd624 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 2 Apr 2026 12:56:42 -0500 Subject: [PATCH 57/76] pdf build CI issue --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 5da18fd5ed..bc199a633f 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -288,7 +288,7 @@ instead of supplying a dummy routine. A threshold, with :math:`\varepsilon` representing the machine precision, .. math:: - \texttt{gram_det_tol} = 10 \cdot \max\left(\varepsilon,\; \texttt{rel_tol}\right) + \mathtt{gram\_det\_tol} = 10 \cdot \max\left(\varepsilon,\; \mathtt{rel\_tol}\right) is used to assess the numerical rank of the 2×2 Gram matrix formed by the current and previous iterates in the Power Iteration method. If the determinant of this Gram matrix is less than or equal to @@ -300,12 +300,12 @@ instead of supplying a dummy routine. imaginary part is proportional to the chosen relative tolerance, i.e., .. math:: - |\beta| \gtrsim \mathcal{O}(\texttt{rel_tol}). + |\beta| \gtrsim \mathcal{O}(\mathtt{rel\_tol}). Therefore, to resolve an expected imaginary part of magnitude :math:`|\beta|`, it is recommended to choose .. math:: - \texttt{rel_tol} \ll |\beta|. + \mathtt{rel\_tol} \ll |\beta|. Choosing a smaller relative tolerance improves the ability to detect weakly complex eigenvalues, but may increase computational cost. @@ -318,7 +318,7 @@ instead of supplying a dummy routine. .. math:: \left|\,|\lambda_{k}| - |\lambda_{k-1}|\,\right| - \le \texttt{rel_tol} \cdot |\lambda_{k}|. + \le \mathtt{rel\_tol} \cdot |\lambda_{k}|. The implementation performs this inexpensive preprocessing check using only the magnitude of the eigenvalue estimates. Arnoldi Iteration is executed only after this convergence criterion is From 60b515423133662063ad9e37eaac8eb9f128e0a8 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 2 Apr 2026 15:35:37 -0500 Subject: [PATCH 58/76] updated answers --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index cc74e2913e..a880d9965e 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit cc74e2913e28396e858a43c6f02a126f4beadbea +Subproject commit a880d9965e788784bd8c05136eb0fa3aa90e9010 From f95f93c5202e2a8f9d2499a6d419dbca1e9e8aa2 Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 2 Apr 2026 17:27:13 -0500 Subject: [PATCH 59/76] updated answers --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index a880d9965e..36972d868d 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit a880d9965e788784bd8c05136eb0fa3aa90e9010 +Subproject commit 36972d868dbe5ae5f7bc51a5cac24906e2317c34 From 37cef76a4f98e73fdc103e830c3a65da35d3f53b Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 2 Apr 2026 22:10:23 -0500 Subject: [PATCH 60/76] dummy change to triger CI --- doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst index 70b259df0f..036c8fbfa8 100644 --- a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst @@ -350,7 +350,7 @@ Allowable Method Families If :c:func:`LSRKStepSetUseAnalyticStabRegion` is called during integration, the change will take effect at the next step attempt. Both analytic and ellipse stability regions of RKC and RKL methods with 10 stages - are shown in the figure below. + are shown in the figure below. .. figure:: ../../../../../shared/figs/arkode/STS2_region_s10.png :alt: Stability region of RKL method with 10 stages From 30949aa058a57bbddcd412038bfcc89ad61b312a Mon Sep 17 00:00:00 2001 From: maggul Date: Thu, 2 Apr 2026 23:25:56 -0500 Subject: [PATCH 61/76] fixing the head issue --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 36972d868d..0aca41148f 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 36972d868dbe5ae5f7bc51a5cac24906e2317c34 +Subproject commit 0aca41148f5117a6c4ef313f3284105a36c67c26 From f6f5b2a3fcd3d2ebbce08d78b527aec5d49781d8 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 3 Apr 2026 01:31:26 -0500 Subject: [PATCH 62/76] update answers --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 0aca41148f..9e436de4ed 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 0aca41148f5117a6c4ef313f3284105a36c67c26 +Subproject commit 9e436de4ed16aa5de84362ab2f71b0233729fe01 From 8415ff0fcffbe2cf098ff4029b2af50938faa644 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 3 Apr 2026 08:40:30 -0500 Subject: [PATCH 63/76] updated the extended results --- test/answers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/answers b/test/answers index 9e436de4ed..5ef70bd970 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 9e436de4ed16aa5de84362ab2f71b0233729fe01 +Subproject commit 5ef70bd970e088a1337256b5ab258713479164fe From 5cc672b5785ce2b4cf37cf5a6fae7bef91722047 Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 3 Apr 2026 14:38:49 -0500 Subject: [PATCH 64/76] copilot suggestions --- .../sundials/sundials_domeigestimator_usersupplied.hpp | 2 +- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 4 ++-- include/sundomeigest/sundomeigest_arnoldi.h | 2 ++ include/sundomeigest/sundomeigest_power.h | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp index f37a23aa72..0013b204a3 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp @@ -49,7 +49,7 @@ SUNErrCode sundomeigestimator_setrhs_wrapper(Args... args) { return sundials4py::user_supplied_fn_caller< std::remove_pointer_t, SUNDomEigEstimatorFunctionTable, - 3>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); + 4>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); } #endif \ No newline at end of file diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index bc199a633f..559af07c00 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -209,9 +209,9 @@ instead of supplying a dummy routine. A :c:type:`SUNErrCode`. -.. c:function:: SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, SUNRHSFn RHSfn) +.. c:function:: SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, SUNRhsFn RHSfn) - This *optional* function provides a :c:type:`SUNRHSFn` function for performing + This *optional* function provides a :c:type:`SUNRhsFn` function for performing evaluations of the right-hand side function, as well as a ``void*`` pointer to a data structure used by this routine, to the dominant eigenvalue estimator. This function allows the estimator to perform a discrete Jacobian-vector product using quotient approximations of the Jacobian and estimate diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 27e6d30147..9e93c6d7ac 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -32,7 +32,9 @@ extern "C" { #endif +#ifndef MAX_DQITERS #define MAX_DQITERS 3 +#endif /* ----------------------------------------------------- * Arnoldi Iteration Implementation of SUNDomEigEstimator diff --git a/include/sundomeigest/sundomeigest_power.h b/include/sundomeigest/sundomeigest_power.h index b8319c56b7..421f05166a 100644 --- a/include/sundomeigest/sundomeigest_power.h +++ b/include/sundomeigest/sundomeigest_power.h @@ -32,7 +32,9 @@ extern "C" { #endif +#ifndef MAX_DQITERS #define MAX_DQITERS 3 +#endif /* ----------------------------------------------------- * Power Iteration Implementation of SUNDomEigEstimator From 7fb704150da1654ae82fa3e223763deb3bc92cfc Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 3 Apr 2026 16:32:43 -0500 Subject: [PATCH 65/76] revision --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 27 ++++++++++++++++--- .../arnoldi/sundomeigest_arnoldi.c | 26 +++++++++++++++--- src/sundomeigest/power/sundomeigest_power.c | 25 ++++++++++++----- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 559af07c00..94e0ae02a3 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -230,6 +230,23 @@ instead of supplying a dummy routine. A :c:type:`SUNErrCode`. +.. c:function:: SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) + + This *optional* function sets the linearization point for the right-hand side function when using + :c:func:`SUNDomEigEstimator_SetRhs`. This allows the estimator to perform a discrete Jacobian-vector product using + quotient approximations of the Jacobian at a specified linearization point. + + **Arguments:** + + * *DEE* -- a SUNDomEigEstimator object. + * *t* -- the time at which the linearization point is specified. + * *y* -- the linearization point for the right-hand side function. + + **Return value:** + + A :c:type:`SUNErrCode`. + + .. c:function:: SUNErrCode SUNDomEigEstimator_SetNumPreprocessIters(SUNDomEigEstimator DEE, int num_iters) This *optional* routine sets the number of preprocessing matrix-vector @@ -327,10 +344,12 @@ instead of supplying a dummy routine. the cheaper magnitude-based preprocessing step, the routine avoids multiple Arnoldi runs that would yield only marginal improvements in accuracy while incurring significantly higher computational cost. - When this routine is used in combination with Power Iteration and ``rel_tol`` is less than or equal - to zero, a default value of ``rel_tol`` = 0.005 is applied. In the case of Arnoldi Iteration, this - routine sets ``rel_tol`` = 0.005 for the preprocessing Power Iteration phase when ``rel_tol`` is zero, - and disables preprocessing based on tolerance. + When this routine is used in combination with Power Iteration, for ``rel_tol <= 0`` or + ``rel_tol >= (1 - \varepsilon)``, a default value of ``rel_tol = 0.005`` is applied. + + In the case of Arnoldi Iteration, this routine sets ``rel_tol = 0.005`` for the preprocessing + Power Iteration phase for ``rel_tol = 0`` or ``rel_tol >= (1 - \varepsilon)``, and disables + preprocessing when ``rel_tol < 0``. This routine will be called by :c:func:`SUNDomEigEstimator_SetOptions` when using the key "Did.rel_tol". diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 003e826644..63f8c07043 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -359,8 +359,11 @@ SUNErrCode SUNDomEigEstimator_SetRelTol_Arnoldi(SUNDomEigEstimator DEE, Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNFALSE; return SUN_SUCCESS; } - else if (tol == ZERO) { tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; } - else { Arnoldi_CONTENT(DEE)->tol_preprocess = tol; } + else if (tol == ZERO || tol > ONE - SUN_UNIT_ROUNDOFF) + { + tol = DEE_TOL_OF_WARMUPS_ARNOLDI_DEFAULT; + } + Arnoldi_CONTENT(DEE)->tol_preprocess = tol; /* set the type of warmup iterations */ Arnoldi_CONTENT(DEE)->warmup_to_tol = SUNTRUE; @@ -597,6 +600,16 @@ SUNErrCode SUNDomEigEstimator_Destroy_Arnoldi(SUNDomEigEstimator* DEEptr) N_VDestroy(Arnoldi_CONTENT(DEE)->rhs_linY); Arnoldi_CONTENT(DEE)->rhs_linY = NULL; } + if (Arnoldi_CONTENT(DEE)->Fy) + { + N_VDestroy(Arnoldi_CONTENT(DEE)->Fy); + Arnoldi_CONTENT(DEE)->Fy = NULL; + } + if (Arnoldi_CONTENT(DEE)->work) + { + N_VDestroy(Arnoldi_CONTENT(DEE)->work); + Arnoldi_CONTENT(DEE)->work = NULL; + } if (Arnoldi_CONTENT(DEE)->V) { N_VDestroyVectorArray(Arnoldi_CONTENT(DEE)->V, @@ -690,7 +703,14 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); - // TODO: Add assertion as needed + + sunrealtype vdotv = N_VDotProd(v, v); + if (vdotv <= SUN_SMALL_REAL) + { + N_VScale(ZERO, v, Jv); + SUNCheckLastErr(); + return SUN_SUCCESS; + } if (Arnoldi_CONTENT(DEE)->work == NULL) { diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 98e67132e3..d7617dc7bf 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -91,8 +91,11 @@ SUNDomEigEstimator SUNDomEigEstimator_Power(N_Vector q, long int max_iters, /* check for max_iters values; if illegal use defaults */ if (max_iters <= 0) { max_iters = DEE_MAX_ITER_DEFAULT; } - /* Check if rel_tol > 0 */ - if (rel_tol < SUN_SMALL_REAL) { rel_tol = DEE_TOL_DEFAULT; } + /* Check if rel_tol > 0 and < 1 */ + if (rel_tol < SUN_SMALL_REAL || rel_tol > ONE - SUN_UNIT_ROUNDOFF) + { + rel_tol = DEE_TOL_DEFAULT; + } /* Create dominant eigenvalue estimator */ DEE = NULL; @@ -253,7 +256,7 @@ SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE) SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - if (PI_CONTENT(DEE)->rel_tol < SUN_SMALL_REAL) + if (PI_CONTENT(DEE)->rel_tol < SUN_SMALL_REAL || PI_CONTENT(DEE)->rel_tol > ONE - SUN_UNIT_ROUNDOFF) { PI_CONTENT(DEE)->rel_tol = DEE_TOL_DEFAULT; } @@ -311,8 +314,11 @@ SUNErrCode SUNDomEigEstimator_SetRelTol_Power(SUNDomEigEstimator DEE, SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - /* Check if rel_tol > 0 */ - if (rel_tol < SUN_SMALL_REAL) { rel_tol = DEE_TOL_DEFAULT; } + /* Check if rel_tol > 0 and < 1 */ + if (rel_tol < SUN_SMALL_REAL || rel_tol > ONE - SUN_UNIT_ROUNDOFF) + { + rel_tol = DEE_TOL_DEFAULT; + } /* set the tolerance */ PI_CONTENT(DEE)->rel_tol = rel_tol; @@ -682,6 +688,14 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(PI_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); + sunrealtype vdotv = N_VDotProd(v, v); + if (vdotv <= SUN_SMALL_REAL) + { + N_VScale(ZERO, v, Jv); + SUNCheckLastErr(); + return SUN_SUCCESS; + } + if (PI_CONTENT(DEE)->work == NULL) { PI_CONTENT(DEE)->work = N_VClone(v); @@ -707,7 +721,6 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) /* Initialize perturbation */ sunrealtype ydotv = N_VDotProd(y, v); - sunrealtype vdotv = N_VDotProd(v, v); sunrealtype sq1norm = N_VL1Norm(v); sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); From be87b7464cd7efde47c6a04c0f14c64019b617c7 Mon Sep 17 00:00:00 2001 From: maggul Date: Sun, 5 Apr 2026 15:32:41 -0500 Subject: [PATCH 66/76] merge with develop manually --- doc/shared/RecentChanges.rst | 71 +++ src/arkode/arkode_lsrkstep.c | 1158 +++++++++++++++++++++++----------- test/answers | 2 +- 3 files changed, 867 insertions(+), 364 deletions(-) diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 1df8b0d186..f51469122b 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -10,6 +10,45 @@ Updated the Kokkos N_Vector to support Kokkos 5.x versions. Added ``SUNLogger_Set{Error,Warning,Info,Debug}File`` functions to allow setting logger output streams with a ``FILE*``. +ARKODE now allows users to supply functions that will be called before each +internal time step attempt (:c:func:`ARKodeSetPreStepFn`), after each successful +time step (:c:func:`ARKodeSetPostStepFn`), before right-hand side routines are +called on an updated state (:c:func:`ARKodeSetPreRhsFn`), and/or once each +internal step/stage is computed (:c:func:`ARKodeSetPostprocessStepFn`/ +:c:func:`ARKodeSetPostprocessStageFn`). These are considered **advanced** +functions, as they should treat the state vector as read-only, otherwise all +theoretical guarantees of solution accuracy and stability will be lost. +As a result of these new functions, the values of multiple ARKODE return +codes (e.g., ``ARK_INTERP_FAIL``) have been updated; users who key off of the +named constants will not be affected, but users who rely on the values +themselves should update their codes accordingly. + +Note to users utilizing the previously undocumented +:c:func:`ARKodeSetPostprocessStepFn` function, the supplied function is now +called on the newly computed state vector for all step attempts not just +successful steps. To obtain the previous behavior of only calling a function on +successful steps, switch to using :c:func:`ARKodeSetPostStepFn`. + +Removed extraneous copy of output vector when using ARKODE in ``ARK_ONE_STEP`` mode. + +The default number of stages for the SSP Runge-Kutta methods :c:enumerator:`ARKODE_LSRK_SSP_S_2` +and :c:enumerator:`ARKODE_LSRK_SSP_S_3` in LSRKStep were changed from 10 and 9, respectively, to +their minimum allowable values of 2 and 4. Users may revert to the previous values by calling +:c:func:`LSRKStepSetNumSSPStages`. + +Added the optional function :c:func:`ARKodeInit` to ARKODE to enable +data allocation before the first call to :c:func:`ARKodeEvolve` +(but after all other optional input routines have been called), to support +users who measure memory usage before beginning a simulation. + +Added the function :c:func:`ARKodeGetStageIndex` that returns the index of the +stage currently being processed, and the total number of stages in the method, for +users who wish to compute auxiliary quantities in their IVP right-hand side functions +during some stages and not others (e.g., in all but the first or last stage). + +Added the functions :c:func:`ARKodeGetLastTime` and :c:func:`ARKodeGetLastState` to +return the last successful time and state achieved by ARKODE, respectively. + **Bug Fixes** Fixed a CMake bug where the SuperLU_MT interface would not be built and @@ -25,6 +64,38 @@ Fixed a minor bug where the number of required stages for STS methods in the LSRKStep module was incorrectly computed using the spectral radius instead of the real part of the Jacobian eigenvalues. +Fixed a bug in logging output from ARKODE, where for some time stepping modules, +the current "time" output in the logger was incorrect. + +Fixed a bug in the ARKODE discrete adjoint checkpointing where an incorrect +state would be stored on the first step if the output vector passed to +:c:func:`ARKodeEvolve` did not contain the initial condition on the first call. + +Fixed a bug in MRIStep when using a custom inner integrator that relies on the +input state being the initial condition for the fast integration rather than +retaining the result from the last inner integration or most recent reset call +and the output vector passed to :c:func:`ARKodeEvolve` does not contain the +initial condition on the first call or the last returned solution on subsequent +calls. + +Removed an extraneous copy of the output vector in each step with SplittingStep. + +Added a missing call to :c:func:`SUNNonlinSolSetup` in MRIStep when using an +IMEX-MRI-SR method. + +Fixed a potential bug in LSRKStep's :c:enumerator:`ARKODE_LSRK_SSP_S_3` method, where a real +number was used instead of an integer, potentially resulting in a rounding error. + +Fixed a bug in LSRKStep where an incorrect state vector could be passed to a +user-supplied dominant eigenvalue function on the first step unless the output +vector passed to :c:func:`ARKodeEvolve` contained the initial condition and when +an eigenvalue estimate is requested on the first step in a subsequent call to +:c:func:`ARKodeEvolve` unless the output vector passed contained the most recently +returned solution. + +Fixed a bug in MRIStep for estimating the first "slow" time step in an adaptive +multirate calculation. + **Deprecation Notices** The ``CVodeSetMonitorFn`` and ``CVodeSetMonitorFrequency`` functions have been deprecated and will be diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 94ac4d9cc0..6ab305fce8 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -180,6 +180,7 @@ void* lsrkStep_Create_Commons(ARKRhsFn rhs, sunrealtype t0, N_Vector y0, ark_mem->step_setdefaults = lsrkStep_SetDefaults; ark_mem->step_getnumrhsevals = lsrkStep_GetNumRhsEvals; ark_mem->step_getestlocalerrors = lsrkStep_GetEstLocalErrors; + ark_mem->step_getstageindex = lsrkStep_GetStageIndex; ark_mem->step_mem = (void*)step_mem; ark_mem->step_supports_adaptive = SUNTRUE; @@ -327,8 +328,7 @@ int lsrkStep_ReInit_Commons(void* arkode_mem, ARKRhsFn rhs, sunrealtype t0, With other initialization types, this routine does nothing. ---------------------------------------------------------------*/ -int lsrkStep_Init(ARKodeMem ark_mem, SUNDIALS_MAYBE_UNUSED sunrealtype tout, - int init_type) +int lsrkStep_Init(ARKodeMem ark_mem, int init_type) { ARKodeLSRKStepMem step_mem; int retval; @@ -451,6 +451,12 @@ int lsrkStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, N_Vector f, /* compute the RHS */ if (!ark_mem->fn_is_current) { + /* call the user-supplied pre-rhs function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(t, y, ark_mem->user_data); + if (retval != 0) { return (ARK_PRERHSFN_FAIL); } + } retval = step_mem->fe(t, y, f, ark_mem->user_data); step_mem->nfe++; if (retval != 0) @@ -470,15 +476,21 @@ int lsrkStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, N_Vector f, ark_mem->fn_is_current is changed by ARKODE. */ if (step_mem->is_SSP) { + /* call the user-supplied pre-rhs function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(t, y, ark_mem->user_data); + if (retval != 0) { return (ARK_PRERHSFN_FAIL); } + } retval = step_mem->fe(t, y, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; - ark_mem->fn_is_current = SUNTRUE; if (retval != 0) { arkProcessError(ark_mem, ARK_RHSFUNC_FAIL, __LINE__, __func__, __FILE__, MSG_ARK_RHSFUNC_FAILED, t); return ARK_RHSFUNC_FAIL; } + ark_mem->fn_is_current = SUNTRUE; } N_VScale(ONE, ark_mem->fn, f); @@ -486,6 +498,13 @@ int lsrkStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, N_Vector f, case ARK_FULLRHS_OTHER: + /* call the user-supplied pre-rhs function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(t, y, ark_mem->user_data); + if (retval != 0) { return (ARK_PRERHSFN_FAIL); } + } + /* call f */ retval = step_mem->fe(t, y, f, ark_mem->user_data); step_mem->nfe++; @@ -518,6 +537,9 @@ int lsrkStep_FullRHS(ARKodeMem ark_mem, sunrealtype t, N_Vector y, N_Vector f, weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is generally used in ARKODE to gauge the convergence of any algebraic solvers. However, since the STS step routines do not involve an algebraic solve, this variable @@ -556,10 +578,16 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; + N_Vector tmp1 = ark_mem->tempv1; + N_Vector tmp2 = ark_mem->tempv2; const sunrealtype coefz = THREE / TWO / (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); + /* Initialize the current stage index */ + step_mem->istage = 0; + step_mem->req_stages = step_mem->stage_max_limit; + /* Compute dominant eigenvalue and update stats */ if (step_mem->dom_eig_update) { @@ -677,10 +705,23 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* Compute RHS function, if necessary. */ + /* Compute RHS function for the start of the step, if necessary. */ if ((!ark_mem->fn_is_current && ark_mem->initsetup) || (step_mem->step_nst != ark_mem->nst)) { + /* call the user-supplied pre-rhs function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + /* call fe */ retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; @@ -700,8 +741,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Track the number of successful steps to determine if the previous step failed. */ step_mem->step_nst = ark_mem->nst + 1; - w0 = (ONE + step_mem->rkc_damping / SUNSQR((sunrealtype)(step_mem->req_stages))); - + /* Initialize constants */ + w0 = (ONE + step_mem->rkc_damping / SUNSQR((sunrealtype)(step_mem->req_stages))); temp1 = SUNSQR(w0) - ONE; temp2 = SUNRsqrt(temp1); arg = step_mem->req_stages * SUNRlog(w0 + temp2); @@ -711,22 +752,20 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) bjm1 = ONE / SUNSQR(TWO * w0); bjm2 = bjm1; + mus = w1 * bjm1; - /* Evaluate the first stage */ - N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); - - mus = w1 * bjm1; - - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + ark_mem->h * mus); - - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * mus, ark_mem->fn, ark_mem->tempv2); + /* Begin stage 1 (store in tmp2) and initialize embedding */ + ark_mem->tcur = ark_mem->tn + ark_mem->h * mus; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * mus, ark_mem->fn, tmp2); + N_VScale(ONE, ark_mem->yn, tmp1); /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tn + ark_mem->h * mus, - ark_mem->tempv2, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, tmp2, ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -735,6 +774,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) } } + /* Initialize constants for stage loop */ thjm2 = ZERO; thjm1 = mus; zjm1 = w0; @@ -747,18 +787,21 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Evaluate stages j = 2,...,step_mem->req_stages */ for (int j = 2; j <= step_mem->req_stages; j++) { - zj = TWO * w0 * zjm1 - zjm2; - dzj = TWO * w0 * dzjm1 - dzjm2 + TWO * zjm1; - d2zj = TWO * w0 * d2zjm1 - d2zjm2 + FOUR * dzjm1; - bj = d2zj / SUNSQR(dzj); - ajm1 = ONE - zjm1 * bjm1; - mu = TWO * w0 * bj / bjm1; - nu = -bj / bjm2; - mus = mu * w1 / w0; - - /* Use the ycur array for temporary storage here */ - retval = step_mem->fe(ark_mem->tcur + ark_mem->h * thjm1, ark_mem->tempv2, - ark_mem->ycur, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in ycur) */ + + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, tmp2, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, tmp2, ark_mem->ycur, ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->ycur, @@ -771,25 +814,31 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - /* compute new stage time factor */ - thj = mu * thjm1 + nu * thjm2 + mus * (ONE - ajm1); - + /* Begin stage j (store in ycur) */ + zj = TWO * w0 * zjm1 - zjm2; + dzj = TWO * w0 * dzjm1 - dzjm2 + TWO * zjm1; + d2zj = TWO * w0 * d2zjm1 - d2zjm2 + FOUR * dzjm1; + bj = d2zj / SUNSQR(dzj); + ajm1 = ONE - zjm1 * bjm1; + mu = TWO * w0 * bj / bjm1; + nu = -bj / bjm2; + mus = mu * w1 / w0; + thj = mu * thjm1 + nu * thjm2 + mus * (ONE - ajm1); + ark_mem->tcur = ark_mem->tn + ark_mem->h * thj; + step_mem->istage = j; SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + ark_mem->h * thj); - + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); cvals[0] = mus * ark_mem->h; Xvecs[0] = ark_mem->ycur; cvals[1] = nu; - Xvecs[1] = ark_mem->tempv1; + Xvecs[1] = tmp1; cvals[2] = ONE - mu - nu; Xvecs[2] = ark_mem->yn; cvals[3] = mu; - Xvecs[3] = ark_mem->tempv2; + Xvecs[3] = tmp2; cvals[4] = -mus * ajm1 * ark_mem->h; Xvecs[4] = ark_mem->fn; - - retval = N_VLinearCombination(5, cvals, Xvecs, ark_mem->ycur); + retval = N_VLinearCombination(5, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -797,11 +846,11 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_VECTOROP_ERR; } - /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL && j < step_mem->req_stages) + /* apply user-supplied stage or step postprocessing function (if supplied) */ + if (j < step_mem->req_stages && ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ark_mem->h * thj, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -809,17 +858,29 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_POSTPROCESS_STAGE_FAIL; } } + else if (j == step_mem->req_stages && ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } /* Shift the data for the next stage */ if (j < step_mem->req_stages) { - /* To avoid two data copies we swap ARKODE's tempv1 and tempv2 pointers*/ - N_Vector temp = ark_mem->tempv1; - ark_mem->tempv1 = ark_mem->tempv2; - ark_mem->tempv2 = temp; + /* Swap tempv1 and tempv2 pointers to handle two-previous-stage logic */ + N_Vector temp = tmp1; + tmp1 = tmp2; + tmp2 = temp; - N_VScale(ONE, ark_mem->ycur, ark_mem->tempv2); + N_VScale(ONE, ark_mem->ycur, tmp2); + /* Update coefficients to handle the two-previous stage logic */ thjm2 = thjm1; thjm1 = thj; bjm2 = bjm1; @@ -837,20 +898,35 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); SUNLogInfo(ARK_LOGGER, "begin-compute-embedding", ""); - /* Compute yerr (if step adaptivity enabled) */ - if (!ark_mem->fixedstep) + /* final stage processing */ + ark_mem->tcur = ark_mem->tn + ark_mem->h; + + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) { - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv2, ark_mem->user_data); - step_mem->nfe++; + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-compute-embedding", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } - SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); - SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", - "status = failed rhs eval, retval = %i", retval); + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv2, + ark_mem->user_data); + step_mem->nfe++; - if (retval < 0) { return ARK_RHSFUNC_FAIL; } - if (retval > 0) { return RHSFUNC_RECVR; } + SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); + SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", + "status = failed rhs eval, retval = %i", retval); + + if (retval < 0) { return ARK_RHSFUNC_FAIL; } + if (retval > 0) { return RHSFUNC_RECVR; } + /* Compute yerr (if step adaptivity enabled) */ + if (!ark_mem->fixedstep) + { /* Estimate the local error and compute its weighted RMS norm */ cvals[0] = p8; Xvecs[0] = ark_mem->yn; @@ -869,23 +945,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_VECTOROP_ERR; } *dsmPtr = N_VWrmsNorm(ark_mem->tempv1, ark_mem->ewt); - lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr); - } - else - { - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv2, ark_mem->user_data); - step_mem->nfe++; - - SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); - SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", - "status = failed rhs eval, retval = %i", retval); - - if (retval < 0) { return ARK_RHSFUNC_FAIL; } - if (retval > 0) { return RHSFUNC_RECVR; } - - lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr); } + lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr, ark_mem->tempv2); SUNLogInfo(ARK_LOGGER, "end-compute-embedding", "status = success"); @@ -902,6 +963,9 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is generally used in ARKODE to gauge the convergence of any algebraic solvers. However, since the STS step routines do not involve an algebraic solve, this variable @@ -921,7 +985,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) { int retval; - sunrealtype hmax, w1, bjm1, bjm2, mus, bj, ajm1, cjm1, temj, cj, mu, nu; + sunrealtype hmax, w1, bjm1, bjm2, mus, bj, ajm1, temj, cj, mu, nu; const sunrealtype p8 = SUN_RCONST(0.8), p4 = SUN_RCONST(0.4); sunrealtype stability_norm; ARKodeLSRKStepMem step_mem; @@ -937,6 +1001,12 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; + N_Vector tmp1 = ark_mem->tempv1; + N_Vector tmp2 = ark_mem->tempv2; + + /* Initialize the current stage index */ + step_mem->istage = 0; + step_mem->req_stages = step_mem->stage_max_limit; /* Compute dominant eigenvalue and update stats */ if (step_mem->dom_eig_update) @@ -1058,10 +1128,21 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); - /* Compute RHS function, if necessary. */ + /* Compute RHS function for the start of the step, if necessary. */ if ((!ark_mem->fn_is_current && ark_mem->initsetup) || (step_mem->step_nst != ark_mem->nst)) { + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; @@ -1081,27 +1162,24 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Track the number of successful steps to determine if the previous step failed. */ step_mem->step_nst = ark_mem->nst + 1; - w1 = FOUR / ((step_mem->req_stages + TWO) * (step_mem->req_stages - ONE)); - + /* Initialize constants */ + w1 = FOUR / ((step_mem->req_stages + TWO) * (step_mem->req_stages - ONE)); bjm2 = ONE / THREE; bjm1 = bjm2; - - /* Evaluate the first stage */ - N_VScale(ONE, ark_mem->yn, ark_mem->tempv1); - mus = w1 * bjm1; - cjm1 = mus; - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + ark_mem->h * mus); - - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * mus, ark_mem->fn, ark_mem->tempv2); + /* Begin stage 1 (store in tmp2) and initialize embedding */ + ark_mem->tcur = ark_mem->tn + ark_mem->h * mus; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * mus, ark_mem->fn, tmp2); + N_VScale(ONE, ark_mem->yn, tmp1); /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tn + ark_mem->h * mus, - ark_mem->tempv2, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, tmp2, ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1113,17 +1191,21 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Evaluate stages j = 2,...,step_mem->req_stages */ for (int j = 2; j <= step_mem->req_stages; j++) { - temj = (j + TWO) * (j - ONE); - bj = temj / (TWO * j * (j + ONE)); - ajm1 = ONE - bjm1; - mu = (TWO * j - ONE) / j * (bj / bjm1); - nu = -(j - ONE) / j * (bj / bjm2); - mus = w1 * mu; - cj = temj * w1 / FOUR; - - /* Use the ycur array for temporary storage here */ - retval = step_mem->fe(ark_mem->tcur + ark_mem->h * cjm1, ark_mem->tempv2, - ark_mem->ycur, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in ycur) */ + + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, tmp2, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, tmp2, ark_mem->ycur, ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->ycur, @@ -1135,22 +1217,30 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + ark_mem->h * cj); + /* Begin stage j (store in ycur) */ + temj = (j + TWO) * (j - ONE); + bj = temj / (TWO * j * (j + ONE)); + ajm1 = ONE - bjm1; + mu = (TWO * j - ONE) / j * (bj / bjm1); + nu = -(j - ONE) / j * (bj / bjm2); + mus = w1 * mu; + cj = temj * w1 / FOUR; + ark_mem->tcur = ark_mem->tn + ark_mem->h * cj; + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); cvals[0] = mus * ark_mem->h; Xvecs[0] = ark_mem->ycur; cvals[1] = nu; - Xvecs[1] = ark_mem->tempv1; + Xvecs[1] = tmp1; cvals[2] = ONE - mu - nu; Xvecs[2] = ark_mem->yn; cvals[3] = mu; - Xvecs[3] = ark_mem->tempv2; + Xvecs[3] = tmp2; cvals[4] = -mus * ajm1 * ark_mem->h; Xvecs[4] = ark_mem->fn; - - retval = N_VLinearCombination(5, cvals, Xvecs, ark_mem->ycur); + retval = N_VLinearCombination(5, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1158,11 +1248,11 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_VECTOROP_ERR; } - /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL && j < step_mem->req_stages) + /* apply user-supplied stage or step postprocessing function (if supplied) */ + if (j < step_mem->req_stages && ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ark_mem->h * cj, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1170,18 +1260,28 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_POSTPROCESS_STAGE_FAIL; } } + else if (j == step_mem->req_stages && ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tcur + ark_mem->h * cj, + ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } /* Shift the data for the next stage */ if (j < step_mem->req_stages) { /* To avoid two data copies we swap ARKODE's tempv1 and tempv2 pointers*/ - N_Vector temp = ark_mem->tempv1; - ark_mem->tempv1 = ark_mem->tempv2; - ark_mem->tempv2 = temp; + N_Vector temp = tmp1; + tmp1 = tmp2; + tmp2 = temp; - N_VScale(ONE, ark_mem->ycur, ark_mem->tempv2); + N_VScale(ONE, ark_mem->ycur, tmp2); - cjm1 = cj; bjm2 = bjm1; bjm1 = bj; } @@ -1189,22 +1289,36 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); + + /* final stage processing */ SUNLogInfo(ARK_LOGGER, "begin-compute-embedding", ""); + ark_mem->tcur = ark_mem->tn + ark_mem->h; - /* Compute yerr (if step adaptivity enabled) */ - if (!ark_mem->fixedstep) + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) { - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv2, ark_mem->user_data); - step_mem->nfe++; + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-compute-embedding", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv2, + ark_mem->user_data); + step_mem->nfe++; - SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); - SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", - "status = failed rhs eval, retval = %i", retval); + SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); + SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", + "status = failed rhs eval, retval = %i", retval); - if (retval < 0) { return ARK_RHSFUNC_FAIL; } - if (retval > 0) { return RHSFUNC_RECVR; } + if (retval < 0) { return ARK_RHSFUNC_FAIL; } + if (retval > 0) { return RHSFUNC_RECVR; } + /* Compute yerr (if step adaptivity enabled) */ + if (!ark_mem->fixedstep) + { /* Estimate the local error and compute its weighted RMS norm */ cvals[0] = p8; Xvecs[0] = ark_mem->yn; @@ -1214,8 +1328,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) Xvecs[2] = ark_mem->fn; cvals[3] = p4 * ark_mem->h; Xvecs[3] = ark_mem->tempv2; - - retval = N_VLinearCombination(4, cvals, Xvecs, ark_mem->tempv1); + retval = N_VLinearCombination(4, cvals, Xvecs, ark_mem->tempv1); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-compute-embedding", @@ -1223,22 +1336,11 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) return ARK_VECTOROP_ERR; } *dsmPtr = N_VWrmsNorm(ark_mem->tempv1, ark_mem->ewt); - lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr); + lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr, ark_mem->tempv2); } else { - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv2, ark_mem->user_data); - step_mem->nfe++; - - SUNLogExtraDebugVec(ARK_LOGGER, "solution RHS", ark_mem->tempv2, "F_n(:) ="); - SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-compute-embedding", - "status = failed rhs eval, retval = %i", retval); - - if (retval < 0) { return ARK_RHSFUNC_FAIL; } - if (retval > 0) { return RHSFUNC_RECVR; } - - lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr); + lsrkStep_DomEigUpdateLogic(ark_mem, step_mem, *dsmPtr, ark_mem->tempv2); } SUNLogInfo(ARK_LOGGER, "end-compute-embedding", "status = success"); @@ -1256,6 +1358,9 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is used to gauge convergence of any algebraic solvers within the step. As this routine involves no algebraic solve, it is set to 0 (success). @@ -1283,39 +1388,58 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; - sunrealtype rs = (sunrealtype)step_mem->req_stages; - sunrealtype sm1inv = ONE / (rs - ONE); - sunrealtype bt1, bt2, bt3; + /* Initialize the current stage index */ + step_mem->istage = 0; + + /* Initialize method coefficients */ + const sunrealtype rs = (sunrealtype)step_mem->req_stages; + const sunrealtype sm1inv = ONE / (rs - ONE); + const sunrealtype hsm1inv = ark_mem->h * sm1inv; + const sunrealtype rsinv = ONE / rs; + const sunrealtype hrsinv = ark_mem->h * rsinv; + sunrealtype hbt1, hbt2, hbt3; /* Embedding coefficients differ when req_stages == 2 */ if (step_mem->req_stages == 2) { - bt1 = SUN_RCONST( - 0.694021459207626); // due to https://doi.org/10.1016/j.cam.2022.114325 pg 5 - bt2 = ZERO; - bt3 = ONE - bt1; + // from https://doi.org/10.1016/j.cam.2022.114325 pg 5 + hbt1 = ark_mem->h * SUN_RCONST(0.694021459207626); + hbt2 = ZERO; + hbt3 = ark_mem->h - hbt1; } else { - bt1 = (rs + ONE) / (rs * rs); - bt2 = ONE / rs; - bt3 = (rs - ONE) / (rs * rs); + hbt1 = hrsinv * (ONE + rsinv); + hbt2 = hrsinv; + hbt3 = hrsinv * (ONE - rsinv); } + /* Begin stage 0 */ SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); /* The method is not FSAL. Therefore, fn ​is computed at the beginning - of the step unless a renewed step or ARKODE updated fn. */ + of the step unless the previous step failed or ARKODE updated fn. */ if (!ark_mem->fn_is_current) { + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; if (retval != ARK_SUCCESS) { - SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = failed rhs eval, retval = %i", retval); return (ARK_RHSFUNC_FAIL); @@ -1325,21 +1449,23 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + ark_mem->h * sm1inv); - N_VLinearSum(ONE, ark_mem->yn, sm1inv * ark_mem->h, ark_mem->fn, ark_mem->ycur); + /* Begin stage 1 and accumulate embedding into tempv1 */ + ark_mem->tcur = ark_mem->tn + hsm1inv; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, hsm1inv, ark_mem->fn, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->yn, bt1 * ark_mem->h, ark_mem->fn, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->yn, hbt1, ark_mem->fn, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tn + sm1inv * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1351,9 +1477,23 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr /* Evaluate stages j = 2,...,step_mem->req_stages - 1 */ for (int j = 2; j < step_mem->req_stages; j++) { - retval = - step_mem->fe(ark_mem->tcur + ((sunrealtype)j - ONE) * sm1inv * ark_mem->h, - ark_mem->ycur, ark_mem->tempv2, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in tempv2) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv2, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv2, @@ -1365,35 +1505,45 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + ark_mem->h * j * sm1inv); - N_VLinearSum(ONE, ark_mem->ycur, sm1inv * ark_mem->h, ark_mem->tempv2, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + step_mem->istage = j; + ark_mem->tcur = ark_mem->tn + j * hsm1inv; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hsm1inv, ark_mem->tempv2, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, bt2 * ark_mem->h, ark_mem->tempv2, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hbt2, ark_mem->tempv2, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + j * sm1inv * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", - "status = failed vector op, retval = %i", retval); + "status = failed postprocess stage, retval = %i", retval); return ARK_POSTPROCESS_STAGE_FAIL; } } } - /* Evaluate the last stage for j = step_mem->req_stages */ - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv2, ark_mem->user_data); + /* Complete the next-to-last stage by evaluating the RHS and storing it in tempv2 */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv2, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv2, @@ -1405,17 +1555,19 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - step_mem->req_stages, ark_mem->tn + ark_mem->h); + /* Compute the step solution */ + ark_mem->tcur = ark_mem->tn + ark_mem->h; + step_mem->istage = step_mem->req_stages; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, + step_mem->req_stages, ark_mem->tcur); cvals[0] = ONE / (sm1inv * rs); Xvecs[0] = ark_mem->ycur; - cvals[1] = ONE / rs; + cvals[1] = rsinv; Xvecs[1] = ark_mem->yn; - cvals[2] = ark_mem->h / rs; + cvals[2] = hrsinv; Xvecs[2] = ark_mem->tempv2; - - retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); + retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1423,17 +1575,28 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr return ARK_VECTOROP_ERR; } + /* apply user-supplied step postprocessing function (if supplied) */ + if (ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } + SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); /* Compute yerr (if step adaptivity enabled) */ if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, bt3 * ark_mem->h, ark_mem->tempv2, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hbt3, ark_mem->tempv2, ark_mem->tempv1); SUNLogExtraDebugVec(ARK_LOGGER, "embedded solution", ark_mem->tempv1, "y_embedded(:) ="); - N_VLinearSum(ONE, ark_mem->ycur, -ONE, ark_mem->tempv1, ark_mem->tempv1); *dsmPtr = N_VWrmsNorm(ark_mem->tempv1, ark_mem->ewt); } @@ -1455,6 +1618,9 @@ int lsrkStep_TakeStepSSPs2(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is used to gauge convergence of any algebraic solvers within the step. As this routine involves no algebraic solve, it is set to 0 (success). @@ -1482,11 +1648,17 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; - sunrealtype rs = (sunrealtype)step_mem->req_stages; - sunrealtype rn = SUNRsqrt(rs); - sunrealtype rat = ONE / (rs - rn); - int in = (int)SUNRround(rn); + /* Initialize the current stage index */ + step_mem->istage = 0; + /* Initialize method coefficients */ + const sunrealtype rs = (sunrealtype)step_mem->req_stages; + const sunrealtype rn = SUNRsqrt(rs); + const sunrealtype hrat = ark_mem->h / (rs - rn); + const sunrealtype hrsinv = ark_mem->h / rs; + const int in = (int)SUNRround(rn); + + /* Begin stage 0 */ SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); @@ -1495,6 +1667,18 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; @@ -1510,20 +1694,23 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + rat * ark_mem->h); - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * rat, ark_mem->fn, ark_mem->ycur); + /* Begin stage 1 and accumulate embedding into tempv1 */ + ark_mem->tcur = ark_mem->tn + hrat; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, hrat, ark_mem->fn, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h / rs, ark_mem->fn, ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->yn, hrsinv, ark_mem->fn, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tn + ark_mem->h * rat, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1532,12 +1719,26 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } - /* Evaluate stages j = 2,...,step_mem->req_stages */ + /* Evaluate first stage group */ for (int j = 2; j <= ((in - 1) * (in - 2) / 2); j++) { - retval = - step_mem->fe(ark_mem->tcur + ((sunrealtype)j - ONE) * rat * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in tempv3) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, @@ -1549,23 +1750,24 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + j * rat * ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, ark_mem->h * rat, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + ark_mem->tcur = ark_mem->tn + j * hrat; + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hrat, ark_mem->tempv3, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + j * rat * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1575,13 +1777,29 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } + /* Copy ycur into tempv2 before looping over second stage group */ N_VScale(ONE, ark_mem->ycur, ark_mem->tempv2); + /* Evaluate second stage group */ for (int j = ((in - 1) * (in - 2) / 2 + 1); j <= (in * (in + 1) / 2 - 1); j++) { - retval = - step_mem->fe(ark_mem->tcur + ((sunrealtype)j - ONE) * rat * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in tempv3) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, @@ -1593,23 +1811,24 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + j * rat * ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, ark_mem->h * rat, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + ark_mem->tcur = ark_mem->tn + j * hrat; + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hrat, ark_mem->tempv3, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + j * rat * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1619,9 +1838,20 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } - retval = step_mem->fe(ark_mem->tcur + - rat * (rn * (rn + ONE) / TWO - ONE) * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, @@ -1633,45 +1863,63 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, (in * (in + 1) / 2), - ark_mem->tn + (in * (in - 1) / 2) * rat * ark_mem->h); + /* Begin the next stage before final stage group */ + ark_mem->tcur = ark_mem->tn + (in * (in - 1) / 2) * hrat; + step_mem->istage = in * (in + 1) / 2; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, + (in * (in + 1) / 2), ark_mem->tcur); cvals[0] = (rn - ONE) / (TWO * rn - ONE); Xvecs[0] = ark_mem->ycur; cvals[1] = rn / (TWO * rn - ONE); Xvecs[1] = ark_mem->tempv2; - cvals[2] = (rn - ONE) * rat * ark_mem->h / (TWO * rn - ONE); + cvals[2] = (rn - ONE) * hrat / (TWO * rn - ONE); Xvecs[2] = ark_mem->tempv3; - - retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); + retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = failed vector op, retval = %i", retval); return ARK_VECTOROP_ERR; } - if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + - rat * (rn * (rn - ONE) / TWO) * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); - if (retval != 0) { return ARK_POSTPROCESS_STAGE_FAIL; } + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess stage, retval = %i", retval); + return ARK_POSTPROCESS_STAGE_FAIL; + } } + /* Evaluate final stage group */ for (int j = (in * (in + 1) / 2 + 1); j <= step_mem->req_stages; j++) { - retval = step_mem->fe(ark_mem->tcur + - ((sunrealtype)j - rn - ONE) * rat * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in tempv3) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, @@ -1683,24 +1931,24 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + ((sunrealtype)j - rn) * rat * ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, ark_mem->h * rat, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + ark_mem->tcur = ark_mem->tn + (j - in) * hrat; + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hrat, ark_mem->tempv3, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } - /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL && j < step_mem->req_stages) + /* apply user-supplied stage or step postprocessing function (if supplied) */ + if (j < step_mem->req_stages && ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + - ((sunrealtype)j - rn) * rat * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1708,13 +1956,24 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr return ARK_POSTPROCESS_STAGE_FAIL; } } + else if (j == step_mem->req_stages && ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tn + ark_mem->h, + ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); - SUNLogInfo(ARK_LOGGER, "begin-compute-embedding", ""); /* Compute yerr (if step adaptivity enabled) */ + SUNLogInfo(ARK_LOGGER, "begin-compute-embedding", ""); if (!ark_mem->fixedstep) { SUNLogExtraDebugVec(ARK_LOGGER, "embedded solution", ark_mem->tempv1, @@ -1722,7 +1981,6 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr N_VLinearSum(ONE, ark_mem->ycur, -ONE, ark_mem->tempv1, ark_mem->tempv1); *dsmPtr = N_VWrmsNorm(ark_mem->tempv1, ark_mem->ewt); } - SUNLogInfo(ARK_LOGGER, "end-compute-embedding", "status = success"); return ARK_SUCCESS; @@ -1742,6 +2000,9 @@ int lsrkStep_TakeStepSSPs3(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is used to gauge convergence of any algebraic solvers within the step. As this routine involves no algebraic solve, it is set to 0 (success). @@ -1769,9 +2030,15 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; - sunrealtype rs = SUN_RCONST(4.0); - sunrealtype p5 = SUN_RCONST(0.5); + /* Initialize the current stage index */ + step_mem->istage = 0; + + /* Initialize method coefficients */ + const sunrealtype rs = SUN_RCONST(4.0); + const sunrealtype hp5 = ark_mem->h * SUN_RCONST(0.5); + const sunrealtype hrsinv = ark_mem->h / rs; + /* Begin stage 0 */ SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); @@ -1780,10 +2047,21 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; - ark_mem->fn_is_current = SUNTRUE; if (retval != ARK_SUCCESS) { SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); @@ -1791,24 +2069,28 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr "status = failed rhs eval, retval = %i", retval); return (ARK_RHSFUNC_FAIL); } + ark_mem->fn_is_current = SUNTRUE; } SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + p5 * ark_mem->h); - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h * p5, ark_mem->fn, ark_mem->ycur); + /* Begin stage 1 and accumulate embedding into tempv1 */ + ark_mem->tcur = ark_mem->tn + hp5; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, hp5, ark_mem->fn, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->yn, ark_mem->h / rs, ark_mem->fn, ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->yn, hrsinv, ark_mem->fn, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tn + ark_mem->h * p5, ark_mem->ycur, - ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1817,8 +2099,21 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } - retval = step_mem->fe(ark_mem->tcur + ark_mem->h * p5, ark_mem->ycur, - ark_mem->tempv3, ark_mem->user_data); + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + /* Evaluate stage RHS */ + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_1(:) ="); @@ -1829,22 +2124,23 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, 2, ark_mem->tn + ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, ark_mem->h * p5, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage 2 */ + ark_mem->tcur = ark_mem->tn + ark_mem->h; + step_mem->istage = 2; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 2, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hp5, ark_mem->tempv3, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1853,8 +2149,22 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv3, ark_mem->user_data); + /* Evaluate stage RHS */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_2(:) ="); @@ -1865,35 +2175,35 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 3, ark_mem->tn + p5 * ark_mem->h); + /* Begin stage 3 */ + ark_mem->tcur = ark_mem->tn + hp5; + step_mem->istage = 3; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 3, ark_mem->tcur); cvals[0] = ONE / THREE; Xvecs[0] = ark_mem->ycur; cvals[1] = TWO / THREE; Xvecs[1] = ark_mem->yn; cvals[2] = ONE / SIX * ark_mem->h; Xvecs[2] = ark_mem->tempv3; - - retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); + retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = failed vector op, retval = %i", retval); return ARK_VECTOROP_ERR; } - if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ark_mem->h * p5, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -1902,8 +2212,22 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr } } - retval = step_mem->fe(ark_mem->tcur + ark_mem->h * p5, ark_mem->ycur, - ark_mem->tempv3, ark_mem->user_data); + /* Evaluate stage RHS */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_3(:) ="); @@ -1914,11 +2238,26 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - step_mem->req_stages, ark_mem->tn + ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, ark_mem->h * p5, ark_mem->tempv3, - ark_mem->ycur); + /* Compute the time step solution and embedding */ + ark_mem->tcur = ark_mem->tn + ark_mem->h; + step_mem->istage = 4; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 4, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hp5, ark_mem->tempv3, ark_mem->ycur); + + /* apply user-supplied step postprocessing function (if supplied) */ + if (ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); @@ -1926,8 +2265,7 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr /* Compute yerr (if step adaptivity enabled) */ if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, ark_mem->h / rs, ark_mem->tempv3, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->tempv1, hrsinv, ark_mem->tempv3, ark_mem->tempv1); SUNLogExtraDebugVec(ARK_LOGGER, "embedded solution", ark_mem->tempv1, "y_embedded(:) ="); @@ -1948,6 +2286,9 @@ int lsrkStep_TakeStepSSP43(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr weighted local error if an embedding is present; otherwise it should be 0. + The variables (ark_mem->tcur, ark_mem->ycur) should + contain the current time and solution at the end of this time step. + The input/output variable nflagPtr is used to gauge convergence of any algebraic solvers within the step. As this routine involves no algebraic solve, it is set to 0 (success). @@ -1968,8 +2309,6 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt *nflagPtr = ARK_SUCCESS; *dsmPtr = ZERO; - const sunrealtype onesixth = ONE / SIX, onefifth = ONE / FIVE; - /* access ARKodeLSRKStepMem structure */ retval = lsrkStep_AccessStepMem(ark_mem, __func__, &step_mem); if (retval != ARK_SUCCESS) { return retval; } @@ -1977,6 +2316,14 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt sunrealtype* cvals = step_mem->cvals; N_Vector* Xvecs = step_mem->Xvecs; + /* Initialize the current stage index */ + step_mem->istage = 0; + + /* Initialize method coefficients */ + const sunrealtype hsixth = ark_mem->h / SIX; + const sunrealtype hfifth = ark_mem->h / FIVE; + + /* Begin stage 0 */ SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, 0, ark_mem->tcur); SUNLogExtraDebugVec(ARK_LOGGER, "stage", ark_mem->yn, "z_0(:) ="); @@ -1985,6 +2332,18 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt of the step unless ARKODE updated fn. */ if (!ark_mem->fn_is_current) { + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tn, ark_mem->yn, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, ark_mem->user_data); step_mem->nfe++; @@ -2000,28 +2359,32 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->fn, "F_0(:) ="); SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 1, ark_mem->tn + onesixth * ark_mem->h); + /* Copy yn into tempv2 for use in later stages */ N_VScale(ONE, ark_mem->yn, ark_mem->tempv2); - N_VLinearSum(ONE, ark_mem->yn, onesixth * ark_mem->h, ark_mem->fn, - ark_mem->ycur); + /* Begin stage 1 and accumulate embedding into tempv1 */ + ark_mem->tcur = ark_mem->tn + hsixth; + step_mem->istage = 1; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 1, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->yn, hsixth, ark_mem->fn, ark_mem->ycur); if (!ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->yn, onefifth * ark_mem->h, ark_mem->fn, - ark_mem->tempv1); + N_VLinearSum(ONE, ark_mem->yn, hfifth, ark_mem->fn, ark_mem->tempv1); } - /* Evaluate stages j = 2,...,step_mem->req_stages */ + /* Evaluate stages j = 2,...,5 */ for (int j = 2; j <= 5; j++) { + /* Complete the previous stage (postprocesses the stage, evaluate the RHS, and + store it in tempv3) */ + /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ((sunrealtype)j - ONE) * - onesixth * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -2030,9 +2393,21 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt } } - retval = step_mem->fe(ark_mem->tcur + - ((sunrealtype)j - ONE) * onesixth * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, @@ -2044,12 +2419,14 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j, - ark_mem->tn + j * onesixth * ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, onesixth * ark_mem->h, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + if (j == 5) { ark_mem->tcur = ark_mem->tn + 2 * hsixth; } + else { ark_mem->tcur = ark_mem->tn + j * hsixth; } + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hsixth, ark_mem->tempv3, ark_mem->ycur); if (j == 4 && !ark_mem->fixedstep) { N_VLinearSum(ONE, ark_mem->tempv1, SUN_RCONST(0.3) * ark_mem->h, @@ -2057,10 +2434,10 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt } } - SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", "stage = %i, tcur = " SUN_FORMAT_G, - 6, ark_mem->tn + TWO * onesixth * ark_mem->h); + /* no need to call RHS preprocessing here, since the stage does not require + a RHS function evaluation */ + /* Finish stage 5 by preparing for the final stage group */ N_VLinearSum(SUN_RCONST(1.0) / SUN_RCONST(25.0), ark_mem->tempv2, SUN_RCONST(9.0) / SUN_RCONST(25.0), ark_mem->ycur, ark_mem->tempv2); @@ -2068,10 +2445,10 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt ark_mem->ycur, ark_mem->ycur); /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + TWO * onesixth * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -2080,14 +2457,30 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt } } + /* Evaluate stages j = 6,...,9 */ for (int j = 6; j <= 9; j++) { - retval = step_mem->fe(ark_mem->tcur + - ((sunrealtype)j - FOUR) * onesixth * ark_mem->h, - ark_mem->ycur, ark_mem->tempv3, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store in tempv3) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; - SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_%i(:) =", j); + SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, + "F_%i(:) =", j - 1); SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-stages-list", "status = failed rhs eval, retval = %i", retval); @@ -2095,16 +2488,17 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt if (retval > 0) { return RHSFUNC_RECVR; } SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); - SUNLogInfo(ARK_LOGGER, "begin-stages-list", - "stage = %i, tcur = " SUN_FORMAT_G, j + 1, - ark_mem->tn + (j - 3) * onesixth * ark_mem->h); - N_VLinearSum(ONE, ark_mem->ycur, onesixth * ark_mem->h, ark_mem->tempv3, - ark_mem->ycur); + /* Begin stage j (update the state and embedding) */ + ark_mem->tcur = ark_mem->tn + (j - 3) * hsixth; + step_mem->istage = j; + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, j, ark_mem->tcur); + N_VLinearSum(ONE, ark_mem->ycur, hsixth, ark_mem->tempv3, ark_mem->ycur); if (j == 7 && !ark_mem->fixedstep) { - N_VLinearSum(ONE, ark_mem->tempv1, onefifth * ark_mem->h, ark_mem->tempv3, + N_VLinearSum(ONE, ark_mem->tempv1, hfifth, ark_mem->tempv3, ark_mem->tempv1); } if (j == 9 && !ark_mem->fixedstep) @@ -2114,11 +2508,10 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt } /* apply user-supplied stage postprocessing function (if supplied) */ - if (ark_mem->ProcessStage != NULL) + if (ark_mem->PostProcessStageFn) { - retval = ark_mem->ProcessStage(ark_mem->tcur + ((sunrealtype)j - THREE) * - onesixth * ark_mem->h, - ark_mem->ycur, ark_mem->user_data); + retval = ark_mem->PostProcessStageFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -2128,25 +2521,44 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt } } - retval = step_mem->fe(ark_mem->tcur + ark_mem->h, ark_mem->ycur, - ark_mem->tempv3, ark_mem->user_data); + /* Complete the previous stage (evaluate the RHS and store it in tempv3) */ + + /* apply user-supplied stage preprocessing function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(ark_mem->tcur, ark_mem->ycur, ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed preprocess rhs, retval = %i", retval); + return ARK_PRERHSFN_FAIL; + } + } + + retval = step_mem->fe(ark_mem->tcur, ark_mem->ycur, ark_mem->tempv3, + ark_mem->user_data); step_mem->nfe++; - SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_10(:) =", 9); + SUNLogExtraDebugVec(ARK_LOGGER, "stage RHS", ark_mem->tempv3, "F_9(:) ="); SUNLogInfoIf(retval != 0, ARK_LOGGER, "end-stages-list", "status = failed rhs eval, retval = %i", retval); if (retval < 0) { return ARK_RHSFUNC_FAIL; } if (retval > 0) { return RHSFUNC_RECVR; } - cvals[0] = SUN_RCONST(0.6); - Xvecs[0] = ark_mem->ycur; - cvals[1] = ONE; - Xvecs[1] = ark_mem->tempv2; - cvals[2] = SUN_RCONST(0.1) * ark_mem->h; - Xvecs[2] = ark_mem->tempv3; - - retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); + SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); + SUNLogInfo(ARK_LOGGER, "begin-stages-list", + "stage = %i, tcur = " SUN_FORMAT_G, 10, ark_mem->tcur); + + /* Compute the final time step solution */ + step_mem->istage = 10; + cvals[0] = SUN_RCONST(0.6); + Xvecs[0] = ark_mem->ycur; + cvals[1] = ONE; + Xvecs[1] = ark_mem->tempv2; + cvals[2] = SUN_RCONST(0.1) * ark_mem->h; + Xvecs[2] = ark_mem->tempv3; + retval = N_VLinearCombination(3, cvals, Xvecs, ark_mem->ycur); if (retval != 0) { SUNLogInfo(ARK_LOGGER, "end-stages-list", @@ -2154,6 +2566,19 @@ int lsrkStep_TakeStepSSP104(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPt return ARK_VECTOROP_ERR; } + /* apply user-supplied step postprocessing function (if supplied) */ + if (ark_mem->PostProcessStepFn) + { + retval = ark_mem->PostProcessStepFn(ark_mem->tcur, ark_mem->ycur, + ark_mem->user_data); + if (retval != 0) + { + SUNLogInfo(ARK_LOGGER, "end-stages-list", + "status = failed postprocess step, retval = %i", retval); + return ARK_POSTPROCESS_STEP_FAIL; + } + } + SUNLogInfo(ARK_LOGGER, "end-stages-list", "status = success"); SUNLogExtraDebugVec(ARK_LOGGER, "updated solution", ark_mem->ycur, "ycur(:) ="); @@ -2245,18 +2670,16 @@ void lsrkStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) fprintf(outfile, "LSRKStep: q = %i\n", step_mem->q); fprintf(outfile, "LSRKStep: p = %i\n", step_mem->p); + fprintf(outfile, "LSRKStep: istage = %i\n", step_mem->istage); + fprintf(outfile, "LSRKStep: req_stages = %i\n", step_mem->req_stages); if (step_mem->is_SSP) { - fprintf(outfile, "LSRKStep: req_stages = %i\n", - step_mem->req_stages); fprintf(outfile, "LSRKStep: nfe = %li\n", step_mem->nfe); } else if (!step_mem->is_SSP) { /* output integer quantities */ - fprintf(outfile, "LSRKStep: req_stages = %i\n", - step_mem->req_stages); fprintf(outfile, "LSRKStep: dom_eig_nst = %li\n", step_mem->dom_eig_nst); fprintf(outfile, "LSRKStep: stage_max = %i\n", @@ -2303,8 +2726,6 @@ void lsrkStep_PrintMem(ARKodeMem ark_mem, FILE* outfile) step_mem->dom_eig_update); fprintf(outfile, "LSRKStep: dom_eig_is_current = %d\n", step_mem->dom_eig_is_current); - fprintf(outfile, "LSRKStep: init_warmup = %d\n", - step_mem->init_warmup); fprintf(outfile, "LSRKStep: use_ellipse = %d\n", step_mem->use_ellipse); @@ -2388,11 +2809,11 @@ int lsrkStep_AccessStepMem(ARKodeMem ark_mem, const char* fname, ---------------------------------------------------------------*/ void lsrkStep_DomEigUpdateLogic(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem, - sunrealtype dsm) + sunrealtype dsm, N_Vector fnew) { if (dsm <= ONE) { - N_VScale(ONE, ark_mem->tempv2, ark_mem->fn); + N_VScale(ONE, fnew, ark_mem->fn); ark_mem->fn_is_current = SUNTRUE; step_mem->dom_eig_is_current = (step_mem->const_Jac == SUNTRUE); @@ -2456,7 +2877,7 @@ int lsrkStep_ComputeNewDomEig(ARKodeMem ark_mem, ARKodeLSRKStepMem step_mem) } else if (step_mem->dom_eig_fn != NULL) { - retval = step_mem->dom_eig_fn(ark_mem->tn, ark_mem->ycur, ark_mem->fn, + retval = step_mem->dom_eig_fn(ark_mem->tn, ark_mem->yn, ark_mem->fn, &step_mem->lambdaR, &step_mem->lambdaI, ark_mem->user_data, ark_mem->tempv1, ark_mem->tempv2, ark_mem->tempv3); @@ -2798,8 +3219,14 @@ int lsrkStep_DQJtimes(void* arkode_mem, N_Vector v, N_Vector Jv) if ((!ark_mem->fn_is_current && ark_mem->initsetup) || (step_mem->step_nst != ark_mem->nst)) { - retval = step_mem->fe(ark_mem->tn, ark_mem->yn, ark_mem->fn, - ark_mem->user_data); + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(t, y, ark_mem->user_data); + if (retval != 0) { return ARK_PRERHSFN_FAIL; } + } + + retval = step_mem->fe(t, y, ark_mem->fn, ark_mem->user_data); step_mem->nfeDQ++; if (retval != ARK_SUCCESS) { @@ -2820,8 +3247,13 @@ int lsrkStep_DQJtimes(void* arkode_mem, N_Vector v, N_Vector Jv) /* Set work = y + sig*v */ N_VLinearSum(sig, v, ONE, y, work); + /* call the user-supplied pre-RHS function (if supplied) */ + if (ark_mem->PreRhsFn) + { + retval = ark_mem->PreRhsFn(t, work, ark_mem->user_data); + if (retval != 0) { return ARK_PRERHSFN_FAIL; } + } /* Set Jv = f(tn, y+sig*v) */ - //TODO:Needs to be update when LSRK Supports IMEX retval = step_mem->fe(t, work, Jv, ark_mem->user_data); step_mem->nfeDQ++; if (retval == 0) { break; } diff --git a/test/answers b/test/answers index 5ef70bd970..1de5f12bd0 160000 --- a/test/answers +++ b/test/answers @@ -1 +1 @@ -Subproject commit 5ef70bd970e088a1337256b5ab258713479164fe +Subproject commit 1de5f12bd0444d044cbe30d308af0ec348e45f41 From b5b4778310da9734db81efff999539f65ae072c6 Mon Sep 17 00:00:00 2001 From: maggul Date: Sun, 5 Apr 2026 15:54:35 -0500 Subject: [PATCH 67/76] removed redefinition --- doc/shared/RecentChanges.rst | 32 ------------------- .../arnoldi/sundomeigest_arnoldi.c | 1 - 2 files changed, 33 deletions(-) diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 1d0b290080..f51469122b 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -60,38 +60,6 @@ table. Fixed a bug where passing an empty string to ``SUNLogger_Set{Error,Warning,Info,Debug}Filename`` did not disable the corresponding logging stream `Issue #844 `__. -Fixed a bug in logging output from ARKODE, where for some time stepping modules, -the current "time" output in the logger was incorrect. - -Fixed a bug in the ARKODE discrete adjoint checkpointing where an incorrect -state would be stored on the first step if the output vector passed to -:c:func:`ARKodeEvolve` did not contain the initial condition on the first call. - -Fixed a bug in MRIStep when using a custom inner integrator that relies on the -input state being the initial condition for the fast integration rather than -retaining the result from the last inner integration or most recent reset call -and the output vector passed to :c:func:`ARKodeEvolve` does not contain the -initial condition on the first call or the last returned solution on subsequent -calls. - -Removed an extraneous copy of the output vector in each step with SplittingStep. - -Added a missing call to :c:func:`SUNNonlinSolSetup` in MRIStep when using an -IMEX-MRI-SR method. - -Fixed a potential bug in LSRKStep's :c:enumerator:`ARKODE_LSRK_SSP_S_3` method, where a real -number was used instead of an integer, potentially resulting in a rounding error. - -Fixed a bug in LSRKStep where an incorrect state vector could be passed to a -user-supplied dominant eigenvalue function on the first step unless the output -vector passed to :c:func:`ARKodeEvolve` contained the initial condition and when -an eigenvalue estimate is requested on the first step in a subsequent call to -:c:func:`ARKodeEvolve` unless the output vector passed contained the most recently -returned solution. - -Fixed a bug in MRIStep for estimating the first "slow" time step in an adaptive -multirate calculation. - Fixed a minor bug where the number of required stages for STS methods in the LSRKStep module was incorrectly computed using the spectral radius instead of the real part of the Jacobian eigenvalues. diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 63f8c07043..c6e2bff907 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -737,7 +737,6 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) /* Initialize perturbation */ sunrealtype ydotv = N_VDotProd(y, v); - sunrealtype vdotv = N_VDotProd(v, v); sunrealtype sq1norm = N_VL1Norm(v); sunrealtype sign = (ydotv >= ZERO) ? ONE : -ONE; sunrealtype sqrteps = SUNRsqrt(SUN_UNIT_ROUNDOFF); From 47e1c5403319cb8a32b5fae003d301471f521bf7 Mon Sep 17 00:00:00 2001 From: maggul Date: Sun, 5 Apr 2026 16:18:34 -0500 Subject: [PATCH 68/76] formatting --- src/arkode/arkode_lsrkstep.c | 2 +- src/sundomeigest/arnoldi/sundomeigest_arnoldi.c | 4 ++-- src/sundomeigest/power/sundomeigest_power.c | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index 0a8394590b..d1381dfd8f 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -742,7 +742,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) step_mem->step_nst = ark_mem->nst + 1; /* Initialize constants */ - w0 = (ONE + step_mem->rkc_damping / SUNSQR((sunrealtype)(step_mem->req_stages))); + w0 = (ONE + step_mem->rkc_damping / SUNSQR((sunrealtype)(step_mem->req_stages))); temp1 = SUNSQR(w0) - ONE; temp2 = SUNRsqrt(temp1); arg = step_mem->req_stages * SUNRlog(w0 + temp2); diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index c6e2bff907..2212864643 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -703,8 +703,8 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(Jv, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); SUNAssert(Arnoldi_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); - - sunrealtype vdotv = N_VDotProd(v, v); + + sunrealtype vdotv = N_VDotProd(v, v); if (vdotv <= SUN_SMALL_REAL) { N_VScale(ZERO, v, Jv); diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index d7617dc7bf..577b822203 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -256,7 +256,8 @@ SUNErrCode SUNDomEigEstimator_Initialize_Power(SUNDomEigEstimator DEE) SUNAssert(DEE, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE), SUN_ERR_ARG_CORRUPT); - if (PI_CONTENT(DEE)->rel_tol < SUN_SMALL_REAL || PI_CONTENT(DEE)->rel_tol > ONE - SUN_UNIT_ROUNDOFF) + if (PI_CONTENT(DEE)->rel_tol < SUN_SMALL_REAL || + PI_CONTENT(DEE)->rel_tol > ONE - SUN_UNIT_ROUNDOFF) { PI_CONTENT(DEE)->rel_tol = DEE_TOL_DEFAULT; } @@ -688,7 +689,7 @@ SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) SUNAssert(PI_CONTENT(DEE)->rhsfn, SUN_ERR_ARG_CORRUPT); SUNAssert(PI_CONTENT(DEE)->rhs_linY, SUN_ERR_ARG_CORRUPT); - sunrealtype vdotv = N_VDotProd(v, v); + sunrealtype vdotv = N_VDotProd(v, v); if (vdotv <= SUN_SMALL_REAL) { N_VScale(ZERO, v, Jv); From 998e379b474f778792ef744ad3852c7ddda32e68 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 7 Apr 2026 11:57:00 -0500 Subject: [PATCH 69/76] binding update --- .../sundials/sundials_domeigestimator_usersupplied.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp index 0013b204a3..4939125dee 100644 --- a/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp +++ b/bindings/sundials4py/sundials/sundials_domeigestimator_usersupplied.hpp @@ -49,7 +49,7 @@ SUNErrCode sundomeigestimator_setrhs_wrapper(Args... args) { return sundials4py::user_supplied_fn_caller< std::remove_pointer_t, SUNDomEigEstimatorFunctionTable, - 4>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); + 1>(&SUNDomEigEstimatorFunctionTable::deerhs, std::forward(args)...); } #endif \ No newline at end of file From c8c30be24f1b40e6f1105c8a8adc54a80390aad7 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 7 Apr 2026 14:29:25 -0500 Subject: [PATCH 70/76] removed double reference --- doc/shared/Changelog.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/shared/Changelog.rst b/doc/shared/Changelog.rst index 232c1e2bd1..a394ef4b1e 100644 --- a/doc/shared/Changelog.rst +++ b/doc/shared/Changelog.rst @@ -24,23 +24,22 @@ Changelog .. SED_REPLACEMENT_KEY -.. _Changelog.7.7.0: +.. _Changelog.X.Y.Z: -Changes to SUNDIALS in release 7.7.0 +Changes to SUNDIALS in release X.Y.Z ==================================== -.. SED_REPLACEMENT_KEY +**Bug Fixes** + +Fixed a minor bug where the number of required stages for STS methods +in the LSRKStep module was incorrectly computed using the spectral +radius instead of the real part of the Jacobian eigenvalues. .. _Changelog.7.7.0: Changes to SUNDIALS in release 7.7.0 ==================================== -**Bug Fixes** - -Fixed a minor bug where the number of required stages for STS methods -in the LSRKStep module was incorrectly computed using the spectral -radius instead of the real part of the Jacobian eigenvalues. .. include:: RecentChanges_link.rst From 5cc11ce642ee353fe250dcc371f4803c2637ee13 Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 7 Apr 2026 15:22:44 -0500 Subject: [PATCH 71/76] merged with develop --- doc/shared/Changelog.rst | 1 + doc/shared/RecentChanges.rst | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/doc/shared/Changelog.rst b/doc/shared/Changelog.rst index 03d983280d..177b3357fa 100644 --- a/doc/shared/Changelog.rst +++ b/doc/shared/Changelog.rst @@ -34,6 +34,7 @@ Changes to SUNDIALS in release X.Y.Z Fixed a minor bug where the number of required stages for STS methods in the LSRKStep module was incorrectly computed using the spectral radius instead of the real part of the Jacobian eigenvalues. + .. include:: RecentChanges_link.rst .. _Changelog.7.7.0: diff --git a/doc/shared/RecentChanges.rst b/doc/shared/RecentChanges.rst index 22e47b0213..137c809a7f 100644 --- a/doc/shared/RecentChanges.rst +++ b/doc/shared/RecentChanges.rst @@ -7,4 +7,8 @@ **Bug Fixes** +Fixed a minor bug where the number of required stages for STS methods +in the LSRKStep module was incorrectly computed using the spectral +radius instead of the real part of the Jacobian eigenvalues. + **Deprecation Notices** From 6402e8a95025e4c5223ee1fbb2f7a00f72e91fed Mon Sep 17 00:00:00 2001 From: maggul Date: Tue, 7 Apr 2026 21:01:23 -0500 Subject: [PATCH 72/76] CI doc error fix --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 94e0ae02a3..b99a3c5610 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -484,13 +484,13 @@ Functions provided by SUNDIALS packages --------------------------------------------- To interface with SUNDomEigEst modules, the SUNDIALS packages supply -:c:type:`SUNATimesFn` and :c:type:`SUNRHSFn` functions for evaluating the matrix-vector +:c:type:`SUNATimesFn` and :c:type:`SUNRhsFn` functions for evaluating the matrix-vector product. This package-provided routine translates between the user-supplied ODE or DAE systems and the generic dominant eigenvalue estimator API. The function types for these routines are defined in the header file ``sundials/sundials_iterative.h``. -.. c:type:: int (*SUNRHSFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* rhs_data) +.. c:type:: int (*SUNRhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* rhs_data) Used to compute the right-hand side of an ODE or DAE system. This function is used when the dominant eigenvalue estimator is configured to perform a discrete From 762980430635223d2f8f0f6f2268b0e6e529caaf Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 10 Apr 2026 13:01:50 -0500 Subject: [PATCH 73/76] revision --- .../source/Usage/LSRKStep/User_callable.rst | 28 +- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 89 +++-- .../sundomeigest/SUNDomEigEst_Arnoldi.rst | 4 +- .../sundomeigest/SUNDomEigEst_Power.rst | 17 +- .../ark_brusselator_lsrk_externaldomeigest.c | 3 +- include/sundomeigest/sundomeigest_arnoldi.h | 2 +- src/arkode/arkode_lsrkstep.c | 325 ++++++++++-------- src/arkode/arkode_lsrkstep_io.c | 2 + .../arnoldi/sundomeigest_arnoldi.c | 8 +- src/sundomeigest/power/sundomeigest_power.c | 8 +- 10 files changed, 263 insertions(+), 223 deletions(-) diff --git a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst index a84cab3e67..141651f44d 100644 --- a/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst +++ b/doc/arkode/guide/source/Usage/LSRKStep/User_callable.rst @@ -329,24 +329,24 @@ Allowable Method Families .. note:: + This input is only used for RKC and RKL methods. + If :c:func:`LSRKStepSetUseAnalyticStabRegion` is not called, then the default ``analytic_stab_region`` is set to ``SUNFALSE``. This routine will be called by :c:func:`ARKodeSetOptions` when using the key "arkid.use_analytic_stab_region". - :c:func:`LSRKStepSetUseAnalyticStabRegion` sets whether to use the ellipse or the exact stability region for - stability checks. The stability region check for RKC and RKL methods is performed with the dominant - eigenvalue and the current step size to ensure stability. While this is sufficient for a stability - region of disk, the stability region of RKC and RKL methods is not a disk but rather a more complicated - region that can be approximated by an inscribed ellipse. By default, the ellipse is used for stability - checks, which is a conservative approximation of the stability region that possibly reduces the step - sizes to ensure stability. Setting use_analytic_stab_region to SUNTRUE allows the use of the exact - stability region, which can potentially allow for larger step sizes but possibly cause stability failures - for the second dominant eigenvalue since it might be outside of the stability region even if the dominant - eigenvalue is inside the stability region. Using ellipse for stability checks can be beneficial when two - dominant eigenvalues are close to the stability boundary. Nevertheless, unless the full spectrum is used - for stability checks, there is always a risk of stability failures one way or another. Thus, users - have the option to choose their preference for a more conservative or more aggressive - approach to stability. This input is only used for RKC and RKL methods. + :c:func:`LSRKStepSetUseAnalyticStabRegion` sets whether to use the exact stability region or an + ellipse that is fully inscribed in the stability region for determining stability in RKC and RKL + methods. Whichever region is selected, LSRKStep will ensure that the complex number + :math:`z=h\lambda`, where :math:`h` is the current time step size and :math:`\lambda` is the + estimated dominant eigenvalue, is in this region. Since the ellipse is smaller than the analytical + stability region it provides a more conservative estimate, which may be appropriate for problems + wherein sub-dominant eigenvalues may also limit stability of the method. Thus, the ellipse may + result in a smaller time step size, more internal stages, or both, when compared to using the + analytical stability region. We note that in either case, since LSRKStep does not examine the + full eigenvalue spectrum, there is always some risk of instability. For applications where + this is a concern, we recommend calling :c:func:`LSRKStepSetDomEigSafetyFactor` with a `dom_eig_safety` + value significantly larger than 1. If :c:func:`LSRKStepSetUseAnalyticStabRegion` is called during integration, the change will take effect at the next step attempt. Both analytic and ellipse stability regions of RKC and RKL methods with 10 stages diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index b99a3c5610..709d80024f 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -211,19 +211,22 @@ instead of supplying a dummy routine. .. c:function:: SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, SUNRhsFn RHSfn) - This *optional* function provides a :c:type:`SUNRhsFn` function for performing - evaluations of the right-hand side function, as well as a ``void*`` pointer to a data structure - used by this routine, to the dominant eigenvalue estimator. This function allows the estimator to - perform a discrete Jacobian-vector product using quotient approximations of the Jacobian and estimate - dominant eigenvalues of the Jacobian without requiring the user to provide a matrix-vector product - function. This can be useful when the user does not have access to the Jacobian or its matrix-vector - product, but can evaluate the right-hand side function. + For applications that do not provide a :c:type:`SUNAtimesFn` function to :c:func:`SUNDomEigEstimator_SetATimes`, + the action of this matrix-vector product may be approximated internally. If the matrix corresponds with + the Jacobian of a vector-valued function, :math:`A = \frac{\partial f_{RHS}}{\partial y}(t,y)`, then the + function :math:`f_{RHS}` may optionally be input via this routine, and the Jacobian-vector products will + be approximated as + + .. math:: + Av \approx \frac{1}{\sigma}\left[ f_{RHS}(t,y+\sigma v) - f_{RHS}(t,y)\right] + + The linearization point :math:`(t,y)` should be separately supplied by calling :c:func:`SUNDomEigEstimator_SetRhsLinearizationPoint`. **Arguments:** * *DEE* -- a SUNDomEigEstimator object. * *rhs_data* -- pointer to structure for ``RHSfn``. - * *RHSfn* -- function pointer to perform right-hand side evaluations. + * *RHSfn* -- function pointer to perform right-hand side evaluations. This is typically the same as the problem-defining function supplied to CVODE or ARKODE. **Return value:** @@ -233,8 +236,7 @@ instead of supplying a dummy routine. .. c:function:: SUNErrCode SUNDomEigEstimator_SetRhsLinearizationPoint(SUNDomEigEstimator DEE, sunrealtype t, N_Vector y) This *optional* function sets the linearization point for the right-hand side function when using - :c:func:`SUNDomEigEstimator_SetRhs`. This allows the estimator to perform a discrete Jacobian-vector product using - quotient approximations of the Jacobian at a specified linearization point. + :c:func:`SUNDomEigEstimator_SetRhs`. **Arguments:** @@ -302,18 +304,29 @@ instead of supplying a dummy routine. it defines the acceptable relative change between successive dominant eigenvalue estimates. It also serves as a threshold for determining whether the dominant eigenvalue is real or complex. - A threshold, with :math:`\varepsilon` representing the machine precision, + When used to check convergence, we declare the iteration converged when the change in magnitude between successive estimates satisfies .. math:: - \mathtt{gram\_det\_tol} = 10 \cdot \max\left(\varepsilon,\; \mathtt{rel\_tol}\right) - is used to assess the numerical rank of the 2×2 Gram matrix formed by the current and previous - iterates in the Power Iteration method. If the determinant of this Gram matrix is less than or equal to - this threshold, the iterates are considered nearly linearly dependent, and the dominant eigenvalue is - treated as real. + \left|\,|\lambda_{k}| - |\lambda_{k-1}|\,\right| + \le \mathtt{rel\_tol} \cdot |\lambda_{k}|. + + When used to assess preprocessing iterations for the Arnoldi method, once the above test is satisfied, + the Arnoldi iteration commences, ensuring that Arnoldi is performed only once, as opposed to restarting + Arnoldi repeatedly. + + When ``rel_tol`` is used as a threshold to assess whether the Power Iteration dominant eigenvalue is + real versus complex, we define + + .. math:: + \mathtt{gram\_det\_tol} = 10 \cdot \max\left(\varepsilon,\; \mathtt{rel\_tol}\right) - To ensure that the Power Iteration method captures small imaginary parts of the dominant eigenvalue, - the relative tolerance should not be chosen too large. In practice, the smallest reliably detectable + where :math:`\varepsilon` represents the machine precision. The ``gram_det_tol`` value is used to + assess the numerical rank of the 2×2 Gram matrix formed by the two most recent iterates + in the Power Iteration method -- if the determinant of this Gram matrix is less than or equal to + ``gram_det_tol``, the iterates are considered linearly dependent, and the dominant eigenvalue is + treated as real. For this use case, to ensure that small imaginary parts of the dominant eigenvalue are + not ignored, ``rel_tol`` should not be chosen too large. In practice, the smallest reliably detectable imaginary part is proportional to the chosen relative tolerance, i.e., .. math:: @@ -327,29 +340,10 @@ instead of supplying a dummy routine. Choosing a smaller relative tolerance improves the ability to detect weakly complex eigenvalues, but may increase computational cost. - When used in combination with Arnoldi Iteration, this routine sets the stopping criterion for - the preprocessing Power Iteration phase. In this workflow, Power Iteration is first applied to - perform an initial convergence check for the dominant eigenvalue estimate. The convergence - criterion is based on the change in magnitude between successive estimates and is defined as - - .. math:: - - \left|\,|\lambda_{k}| - |\lambda_{k-1}|\,\right| - \le \mathtt{rel\_tol} \cdot |\lambda_{k}|. - - The implementation performs this inexpensive preprocessing check using only the magnitude of - the eigenvalue estimates. Arnoldi Iteration is executed only after this convergence criterion is - satisfied. This approach ensures that Arnoldi is performed only once, rather than repeatedly - running Arnoldi and checking convergence based on its complex-valued results. By relying on - the cheaper magnitude-based preprocessing step, the routine avoids multiple Arnoldi runs that would - yield only marginal improvements in accuracy while incurring significantly higher computational cost. - - When this routine is used in combination with Power Iteration, for ``rel_tol <= 0`` or - ``rel_tol >= (1 - \varepsilon)``, a default value of ``rel_tol = 0.005`` is applied. - - In the case of Arnoldi Iteration, this routine sets ``rel_tol = 0.005`` for the preprocessing - Power Iteration phase for ``rel_tol = 0`` or ``rel_tol >= (1 - \varepsilon)``, and disables - preprocessing when ``rel_tol < 0``. + Acceptable inputs to this routine include :math:`0 < \mathtt{rel\_tol} < 1 - \varepsilon`. For Power + Iteration, values outside this range result in the default value of ``rel_tol = 0.005``. For + Arnoldi, ``rel_tol < 0`` disables preprocessing, while + :math:`\mathtt{rel\_tol} \ge 1-\varepsilon` result in the default value of ``rel_tol = 0.005``. This routine will be called by :c:func:`SUNDomEigEstimator_SetOptions` when using the key "Did.rel_tol". @@ -480,19 +474,20 @@ dominant eigenvalue estimator. *All routines are optional.* .. _SUNDomEigEst.SUNSuppliedFn: -Functions provided by SUNDIALS packages +User or SUNDIALS package provided functions --------------------------------------------- -To interface with SUNDomEigEst modules, the SUNDIALS packages supply -:c:type:`SUNATimesFn` and :c:type:`SUNRhsFn` functions for evaluating the matrix-vector +To interface with SUNDomEigEst modules, the SUNDIALS packages supply a +:c:type:`SUNATimesFn` function for evaluating the matrix-vector product. This package-provided routine translates between the user-supplied ODE or DAE -systems and the generic dominant eigenvalue estimator API. The function types for these -routines are defined in the header file ``sundials/sundials_iterative.h``. +systems and the generic dominant eigenvalue estimator API. The function type :c:type:`SUNATimesFn` is defined in the header file ``sundials/sundials_iterative.h``. + +Users who wish to use a SUNDomEigEst module in "standalone" mode, however, must provide either a :c:type:`SUNATimesFn` or a :c:type:`SUNRHSFn`, as described below. .. c:type:: int (*SUNRhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* rhs_data) - Used to compute the right-hand side of an ODE or DAE system. This function is used + Used to compute the right-hand side of an ODE system. This function is used when the dominant eigenvalue estimator is configured to perform a discrete Jacobian-vector product using quotient approximations of the Jacobian. The parameter *rhs_data* is a pointer to any information about RHS which the function needs in order diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst index 29dcde5400..76c16f2246 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Arnoldi.rst @@ -155,14 +155,14 @@ information: * ``num_iters`` - number of iterations (preprocessing and estimation) in the last :c:func:`SUNDomEigEstimator_Estimate` call, -* ``warmup_to_tol`` - type of warmup iterations (default is ``SUNFALSE``) +* ``warmup_to_tol`` - enable warmup iterations (default is ``SUNFALSE``) * ``tol_preprocess`` - tolerance for preprocessing iterations (default is 0.005; only used if ``warmup_to_tol`` is ``SUNTRUE``), * ``rhs_linY`` - state vector for linearization point, -* ``rhs_linT`` - time value for linearization point (default is 0.0), +* ``rhs_linT`` - time value for linearization point, * ``rhsfn`` - user provided RHS function, diff --git a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst index c075c5f99f..94d6bcca0b 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_Power.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_Power.rst @@ -116,18 +116,17 @@ routines: :numref:`SUNDomEigEst.Introduction` can be omitted. :param DEE: the dominant eigenvalue estimator object. - :param real: the value to set the ``real`` flag to. + :param real: flag indicating that the dominant eigenvalue is real-valued. - :returns: If successful, ``SUN_SUCCESS`` otherwise an appropriate error code. + :returns: ``SUN_SUCCESS`` if successful, otherwise an appropriate error code. .. note:: - If ``real`` is ``SUNTRUE``, then the convergence criterion is based on the relative change - in the magnitude of successive eigenvalue estimates. If ``real`` is ``SUNFALSE``, then a - postprocessing step is performed to compute the complex-valued dominant eigenvalue estimate, - and the convergence criterion is based on the relative change in the magnitude of successive - eigenvalue estimates. :c:func:`SUNDomEigEstimator_SetRelTol` can be used to set - the relative tolerance for this convergence criterion. + No matter the value of ``real``, the convergence criterion is based on the relative change in the + magnitude of successive eigenvalue estimates (with tolerance set using + :c:func:`SUNDomEigEstimator_SetRelTol`). If ``real`` is ``SUNTRUE``, then the final Power + Iteration estimate is returned. Otherwise, a postprocessing step is performed to compute + the complex-valued dominant eigenvalue estimate. The default value is ``SUNFALSE``. @@ -186,7 +185,7 @@ information: * ``rhs_linY`` - state vector for linearization point, -* ``rhs_linT`` - time value for linearization point (default is 0.0), +* ``rhs_linT`` - time value for linearization point, * ``rel_tol`` - relative tolerance for the convergence criteria (default is 0.005), diff --git a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c index 40613ea9dd..4c7a19b4d9 100644 --- a/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c +++ b/examples/arkode/C_serial/ark_brusselator_lsrk_externaldomeigest.c @@ -313,8 +313,7 @@ static int dom_eig(sunrealtype t, N_Vector y, N_Vector fn, sunrealtype* lambdaR, if (check_flag(&flag, "SUNDomEigEstimator_SetRhs", 1)) { return 1; } /* Set the linearization vector for the Jacobian-vector products */ - flag = SUNDomEigEstimator_SetRhsLinearizationPoint(DEE, t, - y); // set the time t as well + flag = SUNDomEigEstimator_SetRhsLinearizationPoint(DEE, t, y); if (check_flag(&flag, "SUNDomEigEstimator_SetRhsLinearizationPoint", 1)) { return 1; diff --git a/include/sundomeigest/sundomeigest_arnoldi.h b/include/sundomeigest/sundomeigest_arnoldi.h index 9e93c6d7ac..846aad3588 100644 --- a/include/sundomeigest/sundomeigest_arnoldi.h +++ b/include/sundomeigest/sundomeigest_arnoldi.h @@ -52,7 +52,7 @@ struct SUNDomEigEstimatorContent_Arnoldi_ int kry_dim; /* Krylov subspace dimension */ int num_warmups; /* Number of preprocessing iterations */ long int num_iters; /* Number of iterations in last Estimate call */ - sunbooleantype warmup_to_tol; /* Type of warmup iterations */ + sunbooleantype warmup_to_tol; /* Whether to use warmup iterations */ sunrealtype tol_preprocess; /* Tolerance for preprocessing iterations */ sunrealtype rhs_linT; /* Time value for linearization point */ diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index d1381dfd8f..d7a854dc19 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -595,10 +595,17 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (retval != ARK_SUCCESS) { return retval; } } - /* Compute number of stages based on current step size and - dominant eigenvalue using Eq. (2.7) in Verwer et al. (2004) */ - sunrealtype zR = SUNRabs(ark_mem->h) * step_mem->lambdaR; - sunrealtype ss = SUNRceil(SUNRsqrt(ONE - coefz * zR)); + /* Compute the number of stages based on the current step size and dominant + eigenvalue using Eq. 2.7 in Verwer et al. (2004) + https://doi.org/10.1016/j.jcp.2004.05.002 + + Note beta(s) in Eq. 2.7 is positive (i.e., beta = -zR = h * lambdaR assuming + that h * lambdaR < 0) and we have incorporated the minus sign on zR below. We + rely on SUNRsqrt(x) returning 0 for x <= 0, to ensure we use the minimum number + of stages (ss = 2) for zR > 0. */ + sunrealtype zR = ark_mem->h * step_mem->lambdaR; + sunrealtype zI = ark_mem->h * step_mem->lambdaI; + sunrealtype ss = zR > ZERO ? SUN_RCONST(2.0) : SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); /* Check if number of stages exceeds maximum allowed. @@ -635,59 +642,69 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) int req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an - inscribed ellipse approximation. If the stability norm is greater than - one, first check whether the method is stable at stage_max_limit. If so, - increase the number of stages until stability is obtained. Otherwise, - keep the existing fixed-step error and adaptive-step eta update logic. */ - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, - &stability_norm); - if (retval != ARK_SUCCESS) { return retval; } - - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) + if (zR < ZERO) { - sunrealtype initial_stability_norm = stability_norm; - sunbooleantype max_stage_is_stable = SUNFALSE; + /* We first check whether the combination of ss, step size, and dominant + eigenvalue, is stable. If not, we then check whether it would be stable + when using ss = stage_max_limit -- if so, we increase ss until stability is + obtained. Otherwise, we reject the step, resulting either in method failure + when using fixed step sizes, or time step reduction when using adaptive + steps. */ + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, + &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } - if (req_stages < step_mem->stage_max_limit) + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, - step_mem->stage_max_limit, - ark_mem->h, &stability_norm); - if (retval != ARK_SUCCESS) { return retval; } - - max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); - stability_norm = initial_stability_norm; - } + sunrealtype initial_stability_norm = stability_norm; + sunbooleantype max_stage_is_stable = SUNFALSE; - if (max_stage_is_stable) - { - while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && - (req_stages < step_mem->stage_max_limit)) + if (req_stages < step_mem->stage_max_limit) { - req_stages += 1; - retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, - ark_mem->h, &stability_norm); + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, + step_mem->stage_max_limit, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } + + max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); + stability_norm = initial_stability_norm; } - } - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) - { - if (!ark_mem->fixedstep) + if (max_stage_is_stable) { - ark_mem->eta = ark_mem->hadapt_mem->safety / initial_stability_norm; - *nflagPtr = ARK_RETRY_STEP; - ark_mem->hadapt_mem->nst_exp++; - return ARK_RETRY_STEP; + while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && + (req_stages < step_mem->stage_max_limit)) + { + req_stages += 1; + retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, + ark_mem->h, &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + } } - else + + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, - __FILE__, - "Unable to achieve stable results: Either reduce the " - "step size or increase the stage_max_limit"); - return ARK_MAX_STAGE_LIMIT_FAIL; + if (!ark_mem->fixedstep) + { + /* For adaptive simulations, we adjust the step size by the ellipse approximation */ + const sunrealtype a = (TWO / THREE) * (SUNSQR(ss) - ONE) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / TWO; + const sunrealtype b = a / (ss == 2 ? SUN_RCONST(0.6) : SUN_RCONST(1.825) * ss); + + //TODO: Get opinions for negative eta if we remove the positivity restriction above for zR. + //Should we enforce a minimum eta value here? + ark_mem->eta = ark_mem->hadapt_mem->safety * (-TWO * a * b * b * zR) / (SUNSQR(b * zR) + SUNSQR(a * zI)); + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else + { + arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, + __FILE__, + "Unable to achieve stable results: Either reduce the " + "step size or increase the stage_max_limit"); + return ARK_MAX_STAGE_LIMIT_FAIL; + } } } } @@ -1015,8 +1032,10 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) /* Compute number of stages based on current step size and dominant eigenvalue using Eq. 21 in Meyer et al. (2014) */ - sunrealtype zRabs = SUNRabs(ark_mem->h * step_mem->lambdaR); - sunrealtype ss = + sunrealtype zR = ark_mem->h * step_mem->lambdaR; + sunrealtype zI = ark_mem->h * step_mem->lambdaI; + sunrealtype zRabs = SUNRabs(zR); + sunrealtype ss = zR > ZERO ? SUN_RCONST(2.0) : SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zRabs) - ONE) / TWO); ss = SUNMAX(ss, SUN_RCONST(2.0)); @@ -1056,59 +1075,91 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) int req_stages = (int)ss; - /* To check stability, we evaluate the analytic stability function or an - inscribed ellipse approximation. If the stability norm is greater than - one, first check whether the method is stable at stage_max_limit. If so, - increase the number of stages until stability is obtained. Otherwise, - keep the existing fixed-step error and adaptive-step eta update logic. */ - retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, - &stability_norm); - if (retval != ARK_SUCCESS) { return retval; } - - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) + if (zR < ZERO) { - sunrealtype initial_stability_norm = stability_norm; - sunbooleantype max_stage_is_stable = SUNFALSE; + /* To check stability, we evaluate the analytic stability function or an + inscribed ellipse approximation. If the stability norm is greater than + one, first check whether the method is stable at stage_max_limit. If so, + increase the number of stages until stability is obtained. Otherwise, + keep the existing fixed-step error and adaptive-step eta update logic. */ + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, + &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } - if (req_stages < step_mem->stage_max_limit) + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, - step_mem->stage_max_limit, - ark_mem->h, &stability_norm); - if (retval != ARK_SUCCESS) { return retval; } + sunrealtype initial_stability_norm = stability_norm; + sunbooleantype max_stage_is_stable = SUNFALSE; - max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); - stability_norm = initial_stability_norm; - } - - if (max_stage_is_stable) - { - while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && - (req_stages < step_mem->stage_max_limit)) + if (req_stages < step_mem->stage_max_limit) { - req_stages += 1; - retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, - ark_mem->h, &stability_norm); + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, + step_mem->stage_max_limit, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } + + max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); + stability_norm = initial_stability_norm; } - } - if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) - { - if (!ark_mem->fixedstep) + if (max_stage_is_stable) { - ark_mem->eta = ark_mem->hadapt_mem->safety / initial_stability_norm; - *nflagPtr = ARK_RETRY_STEP; - ark_mem->hadapt_mem->nst_exp++; - return ARK_RETRY_STEP; + while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && + (req_stages < step_mem->stage_max_limit)) + { + req_stages += 1; + retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, + ark_mem->h, &stability_norm); + if (retval != ARK_SUCCESS) { return retval; } + } } - else + + if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) { - arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, - __FILE__, - "Unable to achieve stable results: Either reduce the " - "step size or increase the stage_max_limit"); - return ARK_MAX_STAGE_LIMIT_FAIL; + if (!ark_mem->fixedstep) + { + const sunrealtype aspect_ratio[7] = { + SUN_RCONST(0.3) * ss, /* s = 2 */ + SUN_RCONST(0.75) * ss, /* s = 3 */ + SUN_RCONST(0.665) * ss, /* s = 4 */ + SUN_RCONST(0.665) * ss, /* s = 5 */ + SUN_RCONST(0.635) * ss, /* s = 6 to 20 */ + SUN_RCONST(0.6) * ss, /* s >= 20 and odd */ + SUN_RCONST(0.53) * ss /* s >= 20 and even */ + }; + const sunrealtype a = + (((TWO * ss + ONE) * (TWO * ss + ONE)) - SUN_RCONST(9.0)) / + SUN_RCONST(16.0); + sunrealtype b; + + if (ss < 7) + { + b = a / aspect_ratio[(int)ss - 2]; + } + else if (ss <= 20) + { + b = a / aspect_ratio[4]; + } + else + { + b = a / aspect_ratio[6 - (int)ss % 2]; + } + + ark_mem->eta = ark_mem->hadapt_mem->safety * + (-TWO * a * b * b * zR) / + (SUNSQR(b * zR) + SUNSQR(a * zI)); + *nflagPtr = ARK_RETRY_STEP; + ark_mem->hadapt_mem->nst_exp++; + return ARK_RETRY_STEP; + } + else + { + arkProcessError(ark_mem, ARK_MAX_STAGE_LIMIT_FAIL, __LINE__, __func__, + __FILE__, + "Unable to achieve stable results: Either reduce the " + "step size or increase the stage_max_limit"); + return ARK_MAX_STAGE_LIMIT_FAIL; + } } } } @@ -2945,32 +2996,26 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, sunrealtype h, sunrealtype* stability_norm) { sunrealtype ss = (sunrealtype)num_stages; - sunrealtype w0, w1, wr, wi, th, sh, ch, b_s, a_s, Ts, Ts_p, Ts_pp, a, b, xc, yc; - sunrealtype re_stab_min, im_stab_min; + sunrealtype w0, w1, wr, wi, th, sh, ch, b_s, a_s, Ts, Ts_p, Ts_pp; sunrealtype zR = SUNRabs(h) * step_mem->lambdaR; sunrealtype zI = SUNRabs(h) * step_mem->lambdaI; if (step_mem->use_ellipse) { - /* The stability region of the damped RKC method is approximated by an ellipse with - vertices at (0,0), (re_stab_min,0), and (re_stab_min/2,+/-im_stab_min). These vertices - depend on the damping parameter. Also, im_stab_min is estimated heuristically from - the ellipse aspect ratio, taken as approximately 3.65s, where s is the number of stages - (for s=2, the ratio is approximated as 0.6s). This heuristic reflects the observed - near-linear growth of the imaginary extent with the number of stages. The numerical - factors (3.65 and 0.6) were obtained empirically from stability-region plots using - the default damping parameter and may change if the damping is modified. */ - re_stab_min = TWO / THREE * (ONE - SUNSQR(ss)) * - (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping); - im_stab_min = -re_stab_min / - (ss == 2 ? SUN_RCONST(0.6) * ss : SUN_RCONST(3.65) * ss); - - xc = re_stab_min / TWO; - yc = ZERO; - a = SUNRabs(re_stab_min) / TWO; - b = SUNRabs(im_stab_min); - - *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); + /* The stability region of the damped RKC method is approximated by an ellipse + centered at (-a,0), with horizontal semiaxis a and vertical semiaxis b, so + that its vertices are located at (0,0), (-2a,0), and (-a,+/-b). These + quantities depend on the damping parameter. Also, b is estimated + heuristically from the ellipse aspect ratio, taken as approximately 1.825s, + where s is the number of stages (for s=2, the ratio is approximated as 0.6). + This heuristic reflects the observed near-linear growth of the imaginary + extent with the number of stages. The numerical factors (1.825 and 0.6) + were obtained empirically from stability-region plots using the default + damping parameter and may change if the damping is modified. */ + const sunrealtype a = (TWO / THREE) * (SUNSQR(ss) - ONE) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / TWO; + const sunrealtype b = a / (ss == 2 ? SUN_RCONST(0.6) : SUN_RCONST(1.825) * ss); + + *stability_norm = SUNRsqrt(SUNSQR((zR + a) / a) + SUNSQR((zI) / b)); } else { @@ -3016,54 +3061,54 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, sunrealtype h, sunrealtype* stability_norm) { sunrealtype ss = (sunrealtype)num_stages; - sunrealtype w1, wr, wi, a_s, b_s, a, b, xc, yc; - sunrealtype re_stab_min, im_stab_min; + sunrealtype w1, wr, wi, a_s, b_s; sunrealtype zR = SUNRabs(h) * step_mem->lambdaR; sunrealtype zI = SUNRabs(h) * step_mem->lambdaI; if (step_mem->use_ellipse) { - /* The inscibed ellipse parameters are estimated heuristically based on s values as follows: - s = 2 -> 0.6 - s = 3 -> 1.5 - s = 4 -> 1.33 - s = 5 -> 1.33 - s = 6 to 20 -> 1.27 - s >= 20 and odd -> 1.2 - s >= 20 and even -> 1.06 */ - const sunrealtype imag_extend_factor[7] = { - SUN_RCONST(0.6), /* s = 2 */ - SUN_RCONST(1.5), /* s = 3 */ - SUN_RCONST(1.33), /* s = 4 */ - SUN_RCONST(1.33), /* s = 5 */ - SUN_RCONST(1.27), /* s = 6 to 20 */ - SUN_RCONST(1.2), /* s >= 20 and odd */ - SUN_RCONST(1.06) /* s >= 20 and even */ + /* The stability region of the RKL method is approximated by an ellipse + centered at (-a,0), with horizontal semiaxis a and vertical semiaxis b, + so that its vertices are located at (0,0), (-2a,0), and (-a,+/-b). + The half-height b is estimated heuristically from the ellipse aspect + ratio a/b based on the number of stages as follows: + s = 2 -> 0.3 s + s = 3 -> 0.75 s + s = 4 -> 0.665 s + s = 5 -> 0.665 s + s = 6 to 20 -> 0.635 s + s >= 20 and odd -> 0.6 s + s >= 20 and even -> 0.53 s */ + const sunrealtype aspect_ratio[7] = { + SUN_RCONST(0.3) * ss, /* s = 2 */ + SUN_RCONST(0.75) * ss, /* s = 3 */ + SUN_RCONST(0.665) * ss, /* s = 4 */ + SUN_RCONST(0.665) * ss, /* s = 5 */ + SUN_RCONST(0.635) * ss, /* s = 6 to 20 */ + SUN_RCONST(0.6) * ss, /* s >= 20 and odd */ + SUN_RCONST(0.53) * ss /* s >= 20 and even */ }; - re_stab_min = -((TWO * ss + ONE) * (TWO * ss + ONE) - SUN_RCONST(9.0)) / - SUN_RCONST(8.0); + const sunrealtype a = (((TWO * ss + ONE) * (TWO * ss + ONE)) - SUN_RCONST(9.0)) / + SUN_RCONST(16.0); + sunrealtype b; + if (ss < 7) { - im_stab_min = -re_stab_min / (imag_extend_factor[(int)ss - 2] * ss); + b = a / (aspect_ratio[(int)ss - 2]); } else { if (ss <= 20) { - im_stab_min = -re_stab_min / (imag_extend_factor[4] * ss); + b = a / (aspect_ratio[4]); } else { - im_stab_min = -re_stab_min / (imag_extend_factor[6 - (int)ss % 2] * ss); + b = a / (aspect_ratio[6 - (int)ss % 2]); } } - xc = re_stab_min / TWO; - yc = ZERO; - a = SUNRabs(re_stab_min) / TWO; - b = SUNRabs(im_stab_min); - - *stability_norm = SUNRsqrt(SUNSQR((zR - xc) / a) + SUNSQR((zI - yc) / b)); + *stability_norm = SUNRsqrt(SUNSQR((zR + a) / a) + SUNSQR(zI / b)); } else { diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index 8c29c1217b..6e93f6b2c2 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -920,6 +920,8 @@ int lsrkStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) step_mem->spectral_radius); fprintf(fp, " Safety factor for the dom eig = " SUN_FORMAT_G "\n", step_mem->dom_eig_safety); + fprintf(fp, " Use elliptical stability region = %i\n", + step_mem->use_ellipse; fprintf(fp, " Damping factor for RKC = " SUN_FORMAT_G "\n", step_mem->rkc_damping); fprintf(fp, " Max num of successful steps before new dom eig update = %li\n", diff --git a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c index 2212864643..1d7be20587 100644 --- a/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c +++ b/src/sundomeigest/arnoldi/sundomeigest_arnoldi.c @@ -64,7 +64,7 @@ int sundomeigest_Compare(const void* a, const void* b); -SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv); +SUNErrCode dee_DQJtimes_Arnoldi(void* voidstarDEE, N_Vector v, N_Vector Jv); /* * ----------------------------------------------------------------- @@ -201,7 +201,7 @@ SUNErrCode SUNDomEigEstimator_SetRhs_Arnoldi(SUNDomEigEstimator DEE, Arnoldi_CONTENT(DEE)->rhsfn = RHSfn; Arnoldi_CONTENT(DEE)->rhs_data = rhs_data; - DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); + DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes_Arnoldi); SUNCheckLastErr(); return SUN_SUCCESS; @@ -685,14 +685,14 @@ int sundomeigest_Compare(const void* a, const void* b) } /*--------------------------------------------------------------- - dee_DQJtimes: + dee_DQJtimes_Arnoldi: This routine generates a difference quotient approximation to the Jacobian-vector product f_y(t,y) * v. The approximation is Jv = [f(y + v*sig) - f(y)]/sig, where sig = 1 / ||v||_WRMS, i.e. the WRMS norm of v*sig is 1. ---------------------------------------------------------------*/ -SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) +SUNErrCode dee_DQJtimes_Arnoldi(void* voidstarDEE, N_Vector v, N_Vector Jv) { SUNDomEigEstimator DEE = (SUNDomEigEstimator)voidstarDEE; SUNFunctionBegin(DEE->sunctx); diff --git a/src/sundomeigest/power/sundomeigest_power.c b/src/sundomeigest/power/sundomeigest_power.c index 577b822203..568b63a6e5 100644 --- a/src/sundomeigest/power/sundomeigest_power.c +++ b/src/sundomeigest/power/sundomeigest_power.c @@ -61,7 +61,7 @@ SUNErrCode sundomeigestimator_complex_dom_eigs_from_PI( SUNDomEigEstimator DEE, sunrealtype lambdaR, N_Vector v_prev, N_Vector v, sunrealtype* lambdaR_out, sunrealtype* lambdaI_out); -SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv); +SUNErrCode dee_DQJtimes_Power(void* voidstarDEE, N_Vector v, N_Vector Jv); /* ---------------------------------------------------------------------------- * Function to create a new PI estimator @@ -197,7 +197,7 @@ SUNErrCode SUNDomEigEstimator_SetRhs_Power(SUNDomEigEstimator DEE, PI_CONTENT(DEE)->rhsfn = RHSfn; PI_CONTENT(DEE)->rhs_data = rhs_data; - DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes); + DEE->ops->setatimes(DEE, (void*)DEE, dee_DQJtimes_Power); SUNCheckLastErr(); return SUN_SUCCESS; @@ -670,14 +670,14 @@ SUNErrCode SUNDomEigEstimator_Destroy_Power(SUNDomEigEstimator* DEEptr) } /*--------------------------------------------------------------- - dee_DQJtimes: + dee_DQJtimes_Power: This routine generates a difference quotient approximation to the Jacobian-vector product f_y(t,y) * v. The approximation is Jv = [f(y + v*sig) - f(y)]/sig, where sig = 1 / ||v||_WRMS, i.e. the WRMS norm of v*sig is 1. ---------------------------------------------------------------*/ -SUNErrCode dee_DQJtimes(void* voidstarDEE, N_Vector v, N_Vector Jv) +SUNErrCode dee_DQJtimes_Power(void* voidstarDEE, N_Vector v, N_Vector Jv) { SUNDomEigEstimator DEE = (SUNDomEigEstimator)voidstarDEE; SUNFunctionBegin(DEE->sunctx); From 7c2d46f7f65cd7f8566dc17ec4e29be8a854afac Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 10 Apr 2026 13:09:39 -0500 Subject: [PATCH 74/76] .. --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 7 ++++--- src/arkode/arkode_lsrkstep_io.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 709d80024f..05d1ae76a2 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -300,9 +300,10 @@ instead of supplying a dummy routine. .. note:: - The relative tolerance is used as a stopping criterion for the Power Iteration method. Specifically, - it defines the acceptable relative change between successive dominant eigenvalue estimates. It also - serves as a threshold for determining whether the dominant eigenvalue is real or complex. + The relative tolerance is used as a stopping criterion for either the Power Iteration method, or for the + preprocessing phase of the Arnoldi iteration. Specifically, it defines the acceptable relative change + between successive dominant eigenvalue estimates. It also serves as a threshold for determining + whether the dominant eigenvalue estimated by the Power Iteration is real- or complex-valued. When used to check convergence, we declare the iteration converged when the change in magnitude between successive estimates satisfies diff --git a/src/arkode/arkode_lsrkstep_io.c b/src/arkode/arkode_lsrkstep_io.c index 6e93f6b2c2..e425211343 100644 --- a/src/arkode/arkode_lsrkstep_io.c +++ b/src/arkode/arkode_lsrkstep_io.c @@ -921,7 +921,7 @@ int lsrkStep_WriteParameters(ARKodeMem ark_mem, FILE* fp) fprintf(fp, " Safety factor for the dom eig = " SUN_FORMAT_G "\n", step_mem->dom_eig_safety); fprintf(fp, " Use elliptical stability region = %i\n", - step_mem->use_ellipse; + step_mem->use_ellipse); fprintf(fp, " Damping factor for RKC = " SUN_FORMAT_G "\n", step_mem->rkc_damping); fprintf(fp, " Max num of successful steps before new dom eig update = %li\n", From dbc896c0fddaecffb3f7d346e69c4c2854f88ded Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 10 Apr 2026 13:22:15 -0500 Subject: [PATCH 75/76] apply formatting --- src/arkode/arkode_lsrkstep.c | 95 +++++++++++++++++------------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/src/arkode/arkode_lsrkstep.c b/src/arkode/arkode_lsrkstep.c index d7a854dc19..895cbd6761 100644 --- a/src/arkode/arkode_lsrkstep.c +++ b/src/arkode/arkode_lsrkstep.c @@ -605,7 +605,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) of stages (ss = 2) for zR > 0. */ sunrealtype zR = ark_mem->h * step_mem->lambdaR; sunrealtype zI = ark_mem->h * step_mem->lambdaI; - sunrealtype ss = zR > ZERO ? SUN_RCONST(2.0) : SUNRceil(SUNRsqrt(ONE - coefz * zR)); + sunrealtype ss = zR > ZERO ? SUN_RCONST(2.0) + : SUNRceil(SUNRsqrt(ONE - coefz * zR)); ss = SUNMAX(ss, SUN_RCONST(2.0)); /* Check if number of stages exceeds maximum allowed. @@ -651,7 +652,7 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) when using fixed step sizes, or time step reduction when using adaptive steps. */ retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, - &stability_norm); + &stability_norm); if (retval != ARK_SUCCESS) { return retval; } if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) @@ -662,8 +663,8 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (req_stages < step_mem->stage_max_limit) { retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, - step_mem->stage_max_limit, - ark_mem->h, &stability_norm); + step_mem->stage_max_limit, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); @@ -673,11 +674,11 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (max_stage_is_stable) { while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && - (req_stages < step_mem->stage_max_limit)) + (req_stages < step_mem->stage_max_limit)) { req_stages += 1; retval = lsrkStep_RKC_CheckStabilityNorm(step_mem, req_stages, - ark_mem->h, &stability_norm); + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } } @@ -687,13 +688,17 @@ int lsrkStep_TakeStepRKC(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (!ark_mem->fixedstep) { /* For adaptive simulations, we adjust the step size by the ellipse approximation */ - const sunrealtype a = (TWO / THREE) * (SUNSQR(ss) - ONE) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / TWO; - const sunrealtype b = a / (ss == 2 ? SUN_RCONST(0.6) : SUN_RCONST(1.825) * ss); + const sunrealtype a = + (TWO / THREE) * (SUNSQR(ss) - ONE) * + (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / TWO; + const sunrealtype b = a / (ss == 2 ? SUN_RCONST(0.6) + : SUN_RCONST(1.825) * ss); //TODO: Get opinions for negative eta if we remove the positivity restriction above for zR. //Should we enforce a minimum eta value here? - ark_mem->eta = ark_mem->hadapt_mem->safety * (-TWO * a * b * b * zR) / (SUNSQR(b * zR) + SUNSQR(a * zI)); - *nflagPtr = ARK_RETRY_STEP; + ark_mem->eta = ark_mem->hadapt_mem->safety * (-TWO * a * b * b * zR) / + (SUNSQR(b * zR) + SUNSQR(a * zI)); + *nflagPtr = ARK_RETRY_STEP; ark_mem->hadapt_mem->nst_exp++; return ARK_RETRY_STEP; } @@ -1035,8 +1040,11 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) sunrealtype zR = ark_mem->h * step_mem->lambdaR; sunrealtype zI = ark_mem->h * step_mem->lambdaI; sunrealtype zRabs = SUNRabs(zR); - sunrealtype ss = zR > ZERO ? SUN_RCONST(2.0) : - SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zRabs) - ONE) / TWO); + sunrealtype ss = + zR > ZERO + ? SUN_RCONST(2.0) + : SUNRceil((SUNRsqrt(SUN_RCONST(9.0) + SUN_RCONST(8.0) * zRabs) - ONE) / + TWO); ss = SUNMAX(ss, SUN_RCONST(2.0)); @@ -1083,7 +1091,7 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) increase the number of stages until stability is obtained. Otherwise, keep the existing fixed-step error and adaptive-step eta update logic. */ retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, ark_mem->h, - &stability_norm); + &stability_norm); if (retval != ARK_SUCCESS) { return retval; } if (stability_norm > ONE - SUN_UNIT_ROUNDOFF) @@ -1094,8 +1102,8 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (req_stages < step_mem->stage_max_limit) { retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, - step_mem->stage_max_limit, - ark_mem->h, &stability_norm); + step_mem->stage_max_limit, + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } max_stage_is_stable = (stability_norm <= ONE - SUN_UNIT_ROUNDOFF); @@ -1105,11 +1113,11 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) if (max_stage_is_stable) { while ((stability_norm > ONE - SUN_UNIT_ROUNDOFF) && - (req_stages < step_mem->stage_max_limit)) + (req_stages < step_mem->stage_max_limit)) { req_stages += 1; retval = lsrkStep_RKL_CheckStabilityNorm(step_mem, req_stages, - ark_mem->h, &stability_norm); + ark_mem->h, &stability_norm); if (retval != ARK_SUCCESS) { return retval; } } } @@ -1132,23 +1140,13 @@ int lsrkStep_TakeStepRKL(ARKodeMem ark_mem, sunrealtype* dsmPtr, int* nflagPtr) SUN_RCONST(16.0); sunrealtype b; - if (ss < 7) - { - b = a / aspect_ratio[(int)ss - 2]; - } - else if (ss <= 20) - { - b = a / aspect_ratio[4]; - } - else - { - b = a / aspect_ratio[6 - (int)ss % 2]; - } - - ark_mem->eta = ark_mem->hadapt_mem->safety * - (-TWO * a * b * b * zR) / - (SUNSQR(b * zR) + SUNSQR(a * zI)); - *nflagPtr = ARK_RETRY_STEP; + if (ss < 7) { b = a / aspect_ratio[(int)ss - 2]; } + else if (ss <= 20) { b = a / aspect_ratio[4]; } + else { b = a / aspect_ratio[6 - (int)ss % 2]; } + + ark_mem->eta = ark_mem->hadapt_mem->safety * (-TWO * a * b * b * zR) / + (SUNSQR(b * zR) + SUNSQR(a * zI)); + *nflagPtr = ARK_RETRY_STEP; ark_mem->hadapt_mem->nst_exp++; return ARK_RETRY_STEP; } @@ -3002,7 +3000,7 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, if (step_mem->use_ellipse) { - /* The stability region of the damped RKC method is approximated by an ellipse + /* The stability region of the damped RKC method is approximated by an ellipse centered at (-a,0), with horizontal semiaxis a and vertical semiaxis b, so that its vertices are located at (0,0), (-2a,0), and (-a,+/-b). These quantities depend on the damping parameter. Also, b is estimated @@ -3012,8 +3010,11 @@ int lsrkStep_RKC_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, extent with the number of stages. The numerical factors (1.825 and 0.6) were obtained empirically from stability-region plots using the default damping parameter and may change if the damping is modified. */ - const sunrealtype a = (TWO / THREE) * (SUNSQR(ss) - ONE) * (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / TWO; - const sunrealtype b = a / (ss == 2 ? SUN_RCONST(0.6) : SUN_RCONST(1.825) * ss); + const sunrealtype a = (TWO / THREE) * (SUNSQR(ss) - ONE) * + (ONE - TWO / SUN_RCONST(15.0) * step_mem->rkc_damping) / + TWO; + const sunrealtype b = a / + (ss == 2 ? SUN_RCONST(0.6) : SUN_RCONST(1.825) * ss); *stability_norm = SUNRsqrt(SUNSQR((zR + a) / a) + SUNSQR((zI) / b)); } @@ -3088,24 +3089,16 @@ int lsrkStep_RKL_CheckStabilityNorm(ARKodeLSRKStepMem step_mem, int num_stages, SUN_RCONST(0.6) * ss, /* s >= 20 and odd */ SUN_RCONST(0.53) * ss /* s >= 20 and even */ }; - const sunrealtype a = (((TWO * ss + ONE) * (TWO * ss + ONE)) - SUN_RCONST(9.0)) / - SUN_RCONST(16.0); + const sunrealtype a = + (((TWO * ss + ONE) * (TWO * ss + ONE)) - SUN_RCONST(9.0)) / + SUN_RCONST(16.0); sunrealtype b; - if (ss < 7) - { - b = a / (aspect_ratio[(int)ss - 2]); - } + if (ss < 7) { b = a / (aspect_ratio[(int)ss - 2]); } else { - if (ss <= 20) - { - b = a / (aspect_ratio[4]); - } - else - { - b = a / (aspect_ratio[6 - (int)ss % 2]); - } + if (ss <= 20) { b = a / (aspect_ratio[4]); } + else { b = a / (aspect_ratio[6 - (int)ss % 2]); } } *stability_norm = SUNRsqrt(SUNSQR((zR + a) / a) + SUNSQR(zI / b)); From 74b512f7c94de0897ce463f8ae229a1ee8c1cb7f Mon Sep 17 00:00:00 2001 From: maggul Date: Fri, 10 Apr 2026 18:33:21 -0500 Subject: [PATCH 76/76] typo fixes --- doc/shared/sundomeigest/SUNDomEigEst_API.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/shared/sundomeigest/SUNDomEigEst_API.rst b/doc/shared/sundomeigest/SUNDomEigEst_API.rst index 05d1ae76a2..7465d41886 100644 --- a/doc/shared/sundomeigest/SUNDomEigEst_API.rst +++ b/doc/shared/sundomeigest/SUNDomEigEst_API.rst @@ -211,7 +211,7 @@ instead of supplying a dummy routine. .. c:function:: SUNErrCode SUNDomEigEstimator_SetRhs(SUNDomEigEstimator DEE, void* rhs_data, SUNRhsFn RHSfn) - For applications that do not provide a :c:type:`SUNAtimesFn` function to :c:func:`SUNDomEigEstimator_SetATimes`, + For applications that do not provide a :c:type:`SUNATimesFn` function to :c:func:`SUNDomEigEstimator_SetATimes`, the action of this matrix-vector product may be approximated internally. If the matrix corresponds with the Jacobian of a vector-valued function, :math:`A = \frac{\partial f_{RHS}}{\partial y}(t,y)`, then the function :math:`f_{RHS}` may optionally be input via this routine, and the Jacobian-vector products will @@ -483,7 +483,7 @@ To interface with SUNDomEigEst modules, the SUNDIALS packages supply a product. This package-provided routine translates between the user-supplied ODE or DAE systems and the generic dominant eigenvalue estimator API. The function type :c:type:`SUNATimesFn` is defined in the header file ``sundials/sundials_iterative.h``. -Users who wish to use a SUNDomEigEst module in "standalone" mode, however, must provide either a :c:type:`SUNATimesFn` or a :c:type:`SUNRHSFn`, as described below. +Users who wish to use a SUNDomEigEst module in "standalone" mode, however, must provide either a :c:type:`SUNATimesFn` or a :c:type:`SUNRhsFn`, as described below. .. c:type:: int (*SUNRhsFn)(sunrealtype t, N_Vector y, N_Vector ydot, void* rhs_data)