From e52d7e316f90c9f83d92ead7ef1ef1bcba4814eb Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 25 Sep 2024 18:00:16 +0200 Subject: [PATCH] more sundials --- .../sundials/include/cvodes/cvodes_proj.h | 57 ++ .../sunadaptcontroller_imexgus.h | 88 +++ .../sunadaptcontroller_soderlind.h | 132 +++++ .../sundials/priv/sundials_context_impl.h | 45 ++ .../sundials/priv/sundials_errors_impl.h | 557 ++++++++++++++++++ .../sundials/sundials_adaptcontroller.h | 157 +++++ .../include/sundials/sundials_base.hpp | 151 +++++ .../include/sundials/sundials_context.h | 66 +++ .../include/sundials/sundials_context.hpp | 64 ++ .../sundials/sundials_convertibleto.hpp | 39 ++ .../sundials/include/sundials/sundials_core.h | 38 ++ .../include/sundials/sundials_core.hpp | 25 + .../include/sundials/sundials_errors.h | 116 ++++ .../sundials/sundials_linearsolver.hpp | 43 ++ .../include/sundials/sundials_logger.h | 74 +++ .../include/sundials/sundials_matrix.hpp | 42 ++ .../include/sundials/sundials_memory.hpp | 42 ++ .../sundials/sundials_nonlinearsolver.hpp | 44 ++ .../include/sundials/sundials_nvector.hpp | 42 ++ .../include/sundials/sundials_profiler.h | 101 ++++ .../include/sundials/sundials_profiler.hpp | 52 ++ ThirdParty/sundials/src/cvodes/cvodes_proj.c | 453 ++++++++++++++ .../sundials/src/cvodes/cvodes_proj_impl.h | 75 +++ .../src/sunadaptcontroller/CMakeLists.txt | 19 + .../sunadaptcontroller/imexgus/CMakeLists.txt | 31 + .../imexgus/sunadaptcontroller_imexgus.c | 234 ++++++++ .../soderlind/CMakeLists.txt | 31 + .../soderlind/sunadaptcontroller_soderlind.c | 435 ++++++++++++++ .../src/sundials/sundials_adaptcontroller.c | 199 +++++++ .../sundials/src/sundials/sundials_context.c | 299 ++++++++++ .../sundials/src/sundials/sundials_errors.c | 116 ++++ .../sundials/src/sundials/sundials_logger.c | 474 +++++++++++++++ .../src/sundials/sundials_logger_impl.h | 84 +++ .../src/sunmemory/system/CMakeLists.txt | 26 + .../sunmemory/system/sundials_system_memory.c | 170 ++++++ 35 files changed, 4621 insertions(+) create mode 100644 ThirdParty/sundials/include/cvodes/cvodes_proj.h create mode 100644 ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_imexgus.h create mode 100644 ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_soderlind.h create mode 100644 ThirdParty/sundials/include/sundials/priv/sundials_context_impl.h create mode 100644 ThirdParty/sundials/include/sundials/priv/sundials_errors_impl.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_adaptcontroller.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_base.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_context.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_context.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_convertibleto.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_core.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_core.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_errors.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_linearsolver.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_logger.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_matrix.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_memory.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_nonlinearsolver.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_nvector.hpp create mode 100644 ThirdParty/sundials/include/sundials/sundials_profiler.h create mode 100644 ThirdParty/sundials/include/sundials/sundials_profiler.hpp create mode 100644 ThirdParty/sundials/src/cvodes/cvodes_proj.c create mode 100644 ThirdParty/sundials/src/cvodes/cvodes_proj_impl.h create mode 100644 ThirdParty/sundials/src/sunadaptcontroller/CMakeLists.txt create mode 100644 ThirdParty/sundials/src/sunadaptcontroller/imexgus/CMakeLists.txt create mode 100644 ThirdParty/sundials/src/sunadaptcontroller/imexgus/sunadaptcontroller_imexgus.c create mode 100644 ThirdParty/sundials/src/sunadaptcontroller/soderlind/CMakeLists.txt create mode 100644 ThirdParty/sundials/src/sunadaptcontroller/soderlind/sunadaptcontroller_soderlind.c create mode 100644 ThirdParty/sundials/src/sundials/sundials_adaptcontroller.c create mode 100644 ThirdParty/sundials/src/sundials/sundials_context.c create mode 100644 ThirdParty/sundials/src/sundials/sundials_errors.c create mode 100644 ThirdParty/sundials/src/sundials/sundials_logger.c create mode 100644 ThirdParty/sundials/src/sundials/sundials_logger_impl.h create mode 100644 ThirdParty/sundials/src/sunmemory/system/CMakeLists.txt create mode 100644 ThirdParty/sundials/src/sunmemory/system/sundials_system_memory.c diff --git a/ThirdParty/sundials/include/cvodes/cvodes_proj.h b/ThirdParty/sundials/include/cvodes/cvodes_proj.h new file mode 100644 index 0000000000..8ff792e218 --- /dev/null +++ b/ThirdParty/sundials/include/cvodes/cvodes_proj.h @@ -0,0 +1,57 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * Based on CPODES by Radu Serban @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * This is the header file for CVODE's projection interface. + * ---------------------------------------------------------------------------*/ + +#ifndef _CVPROJ_H +#define _CVPROJ_H + +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ----------------------------------------------------------------------------- + * CVProj user-supplied function prototypes + * ---------------------------------------------------------------------------*/ + +typedef int (*CVProjFn)(sunrealtype t, N_Vector ycur, N_Vector corr, + sunrealtype epsProj, N_Vector err, void* user_data); + +/* ----------------------------------------------------------------------------- + * CVProj Exported functions + * ---------------------------------------------------------------------------*/ + +/* Projection initialization functions */ +SUNDIALS_EXPORT int CVodeSetProjFn(void* cvode_mem, CVProjFn pfun); + +/* Optional input functions */ +SUNDIALS_EXPORT int CVodeSetProjErrEst(void* cvode_mem, sunbooleantype onoff); +SUNDIALS_EXPORT int CVodeSetProjFrequency(void* cvode_mem, long int proj_freq); +SUNDIALS_EXPORT int CVodeSetMaxNumProjFails(void* cvode_mem, int max_fails); +SUNDIALS_EXPORT int CVodeSetEpsProj(void* cvode_mem, sunrealtype eps); +SUNDIALS_EXPORT int CVodeSetProjFailEta(void* cvode_mem, sunrealtype eta); + +/* Optional output functions */ +SUNDIALS_EXPORT int CVodeGetNumProjEvals(void* cvode_mem, long int* nproj); +SUNDIALS_EXPORT int CVodeGetNumProjFails(void* cvode_mem, long int* nprf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_imexgus.h b/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_imexgus.h new file mode 100644 index 0000000000..7235bec0a5 --- /dev/null +++ b/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_imexgus.h @@ -0,0 +1,88 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the header file for the SUNAdaptController_ImExGus module. + * -----------------------------------------------------------------*/ + +#ifndef _SUNADAPTCONTROLLER_IMEXGUS_H +#define _SUNADAPTCONTROLLER_IMEXGUS_H + +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ---------------------------------------------------- + * ImEx Gustafsson implementation of SUNAdaptController + * ---------------------------------------------------- */ + +struct _SUNAdaptControllerContent_ImExGus +{ + sunrealtype k1i; /* internal controller parameters */ + sunrealtype k2i; + sunrealtype k1e; + sunrealtype k2e; + sunrealtype bias; /* error bias factor */ + sunrealtype ep; /* error from previous step */ + sunrealtype hp; /* previous step size */ + sunbooleantype firststep; /* flag indicating first step */ +}; + +typedef struct _SUNAdaptControllerContent_ImExGus* SUNAdaptControllerContent_ImExGus; + +/* ------------------ + * Exported Functions + * ------------------ */ + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_ImExGus(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_ImExGus(SUNAdaptController C, + sunrealtype k1e, sunrealtype k2e, + sunrealtype k1i, sunrealtype k2i); +SUNDIALS_EXPORT +SUNAdaptController_Type SUNAdaptController_GetType_ImExGus(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_EstimateStep_ImExGus(SUNAdaptController C, + sunrealtype h, int p, + sunrealtype dsm, + sunrealtype* hnew); +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Reset_ImExGus(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetDefaults_ImExGus(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Write_ImExGus(SUNAdaptController C, FILE* fptr); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetErrorBias_ImExGus(SUNAdaptController C, + sunrealtype bias); +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_UpdateH_ImExGus(SUNAdaptController C, + sunrealtype h, sunrealtype dsm); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Space_ImExGus(SUNAdaptController C, + long int* lenrw, long int* leniw); + +#ifdef __cplusplus +} +#endif + +#endif /* _SUNADAPTCONTROLLER_IMEXGUS_H */ diff --git a/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_soderlind.h b/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_soderlind.h new file mode 100644 index 0000000000..898e8be117 --- /dev/null +++ b/ThirdParty/sundials/include/sunadaptcontroller/sunadaptcontroller_soderlind.h @@ -0,0 +1,132 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the header file for the SUNAdaptController_Soderlind + * module. + * -----------------------------------------------------------------*/ + +#ifndef _SUNADAPTCONTROLLER_SODERLIND_H +#define _SUNADAPTCONTROLLER_SODERLIND_H + +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ---------------------------------------------------- + * Soderlind implementation of SUNAdaptController + * ---------------------------------------------------- */ + +struct _SUNAdaptControllerContent_Soderlind +{ + sunrealtype k1; /* internal controller parameters */ + sunrealtype k2; + sunrealtype k3; + sunrealtype k4; + sunrealtype k5; + sunrealtype bias; /* error bias factor */ + sunrealtype ep; /* error from previous step */ + sunrealtype epp; /* error from 2 steps ago */ + sunrealtype hp; /* previous step size */ + sunrealtype hpp; /* step size from 2 steps ago */ + int firststeps; /* flag to handle first few steps */ +}; + +typedef struct _SUNAdaptControllerContent_Soderlind* SUNAdaptControllerContent_Soderlind; + +/* ------------------ + * Exported Functions + * ------------------ */ + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_Soderlind(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_Soderlind(SUNAdaptController C, + sunrealtype k1, sunrealtype k2, + sunrealtype k3, sunrealtype k4, + sunrealtype k5); + +SUNDIALS_EXPORT +SUNAdaptController_Type SUNAdaptController_GetType_Soderlind(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_EstimateStep_Soderlind(SUNAdaptController C, + sunrealtype h, int p, + sunrealtype dsm, + sunrealtype* hnew); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Reset_Soderlind(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetDefaults_Soderlind(SUNAdaptController C); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Write_Soderlind(SUNAdaptController C, FILE* fptr); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetErrorBias_Soderlind(SUNAdaptController C, + sunrealtype bias); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_UpdateH_Soderlind(SUNAdaptController C, + sunrealtype h, sunrealtype dsm); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Space_Soderlind(SUNAdaptController C, + long int* lenrw, long int* leniw); + +/* Convenience routines to construct subsidiary controllers */ + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_PID(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_PID(SUNAdaptController C, sunrealtype k1, + sunrealtype k2, sunrealtype k3); + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_PI(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_PI(SUNAdaptController C, sunrealtype k1, + sunrealtype k2); + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_I(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_I(SUNAdaptController C, sunrealtype k1); + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_ExpGus(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_ExpGus(SUNAdaptController C, + sunrealtype k1, sunrealtype k2); + +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_ImpGus(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetParams_ImpGus(SUNAdaptController C, + sunrealtype k1, sunrealtype k2); + +#ifdef __cplusplus +} +#endif + +#endif /* _SUNADAPTCONTROLLER_SODERLIND_H */ diff --git a/ThirdParty/sundials/include/sundials/priv/sundials_context_impl.h b/ThirdParty/sundials/include/sundials/priv/sundials_context_impl.h new file mode 100644 index 0000000000..1281333cef --- /dev/null +++ b/ThirdParty/sundials/include/sundials/priv/sundials_context_impl.h @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * !!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This is a 'private' header file and should not be used in user + * code. It is subject to change without warning. + * !!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ----------------------------------------------------------------- + * SUNDIALS context class implementation. + * ----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CONTEXT_IMPL_H +#define _SUNDIALS_CONTEXT_IMPL_H + +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +struct SUNContext_ +{ + SUNProfiler profiler; + sunbooleantype own_profiler; + SUNLogger logger; + sunbooleantype own_logger; + SUNErrCode last_err; + SUNErrHandler err_handler; + SUNComm comm; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/sundials/include/sundials/priv/sundials_errors_impl.h b/ThirdParty/sundials/include/sundials/priv/sundials_errors_impl.h new file mode 100644 index 0000000000..115b5eefd9 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/priv/sundials_errors_impl.h @@ -0,0 +1,557 @@ +/* ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * !!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This is a 'private' header file and should not be used in user + * code. It is subject to change without warning. + * !!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ----------------------------------------------------------------- + * Contains all error checking macros and private error handling API. + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_ERRORS_IMPL_H +#define _SUNDIALS_ERRORS_IMPL_H + +#include + +#include "sundials/sundials_config.h" +#include "sundials/sundials_context.h" +#include "sundials/sundials_export.h" +#include "sundials/sundials_logger.h" +#include "sundials/sundials_types.h" + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ---------------------------------------------------------------------------- + * Macros used in error handling + * ---------------------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + * SUNDIALS __builtin_expect related macros. + * These macros provide hints to the compiler that the condition + * is typically false (or true) which may allow the compiler to + * optimize. + * -----------------------------------------------------------------*/ + +/* Hint to the compiler that the branch is unlikely to be taken */ +#ifdef SUNDIALS_C_COMPILER_HAS_BUILTIN_EXPECT +#define SUNHintFalse(cond) __builtin_expect((cond), 0) +#else +#define SUNHintFalse(cond) (cond) +#endif + +/* Hint to the compiler that the branch is likely to be taken */ +#ifdef SUNDIALS_C_COMPILER_HAS_BUILTIN_EXPECT +#define SUNHintTrue(cond) __builtin_expect((cond), 1) +#else +#define SUNHintTrue(cond) (cond) +#endif + +/* ------------------------------------------------------------------ + * SUNAssume + * + * This macro tells the compiler that the condition should be assumed + * to be true. The consequence is that what happens if the assumption + * is violated is undefined. If there is not compiler support for + * assumptions, then we dont do anything as there is no reliable + * way to avoid the condition being executed in all cases (such as + * the condition being an opaque function call, which we have a lot of). + * -----------------------------------------------------------------*/ + +#if __cplusplus >= 202302L +#define SUNAssume(...) [[assume(__VA_ARGS__)]] +#elif defined(SUNDIALS_C_COMPILER_HAS_ATTRIBUTE_ASSUME) +#define SUNAssume(...) __attribute__((assume(__VA_ARGS__))) +#elif defined(SUNDIALS_C_COMPILER_HAS_BUILTIN_ASSUME) +#define SUNAssume(...) __builtin_assume(__VA_ARGS__) +#elif defined(SUNDIALS_C_COMPILER_HAS_ASSUME) +#define SUNAssume(...) __assume(__VA_ARGS__) +#else +#define SUNAssume(...) +#endif + +/* ---------------------------------------------------------------------------- + * SUNErrHandler_ definition. + * ---------------------------------------------------------------------------*/ + +struct SUNErrHandler_ +{ + SUNErrHandler previous; /* next error handler to call (singly linked-list) */ + SUNErrHandlerFn call; + void* data; +}; + +/* + This function creates a new SUNErrHandler object which is a node in a + singly linked-lis of error handlers. + + :param eh_fn: An error handler callback function + :param eh_data: A pointer that will be passed back to the error handler + callback function + :param eh_out: The new SUNErrHandler object + + :return: A SUNErrCode indicating success or failure +*/ +SUNDIALS_EXPORT +SUNErrCode SUNErrHandler_Create(SUNErrHandlerFn eh_fn, void* eh_data, + SUNErrHandler* eh_out); + +/* + This function destroys and frees the memory for the given SUNErrHandler + object. + + :param eh: A pointer to a SUNErrHandler object + + :return: void +*/ +SUNDIALS_EXPORT +void SUNErrHandler_Destroy(SUNErrHandler* eh); + +/* + This function will print an error out to stderr. It is used as a fallback + when the SUNContext is NULL or corrupt. It should not be used otherwise. + + :param line: the line number of the error + :param func: the function in which the error occurred + :param file: the file in which the error occurred + :param msg: a message associated with the error + :param args: the arguments to be provided to the format message + + :return: void +*/ +SUNDIALS_EXPORT +void SUNGlobalFallbackErrHandler(int line, const char* func, const char* file, + const char* msgfmt, SUNErrCode code, ...); + +/* + This function calls the error handlers registered with the SUNContext + with the provided message. + + :param line: the line number of the error + :param func: the function in which the error occurred + :param file: the file in which the error occurred + :param msgfmt: a message associated with the error with formatting + :param code: the SUNErrCode for the error + :param sunctx: a valid SUNContext object + + :return: void +*/ +static inline void SUNHandleErrWithMsg(int line, const char* func, + const char* file, const char* msg, + SUNErrCode code, SUNContext sunctx) +{ + if (!sunctx) { SUNGlobalFallbackErrHandler(line, func, file, msg, code); } + + sunctx->last_err = code; + SUNErrHandler eh = sunctx->err_handler; + while (eh != NULL) + { + eh->call(line, func, file, msg, code, eh->data, sunctx); + eh = eh->previous; + } +} + +/* + This function calls the error handlers registered with the SUNContext + with the provided format message. + + :param line: the line number of the error + :param func: the function in which the error occurred + :param file: the file in which the error occurred + :param msgfmt: a message associated with the error with formatting + :param code: the SUNErrCode for the error + :param sunctx: a valid SUNContext object + :param args: the arguments to be provided to the format message + + :return: void +*/ +static inline void SUNHandleErrWithFmtMsg(int line, const char* func, + const char* file, const char* msgfmt, + SUNErrCode code, SUNContext sunctx, ...) +{ + size_t msglen; + char* msg; + va_list values; + va_start(values, sunctx); + msglen = (size_t)vsnprintf(NULL, (size_t)0, msgfmt, values); /* determine size + of buffer + needed */ + msg = (char*)malloc(msglen + 1); + vsnprintf(msg, msglen + 1, msgfmt, values); + SUNHandleErrWithMsg(line, func, file, msg, code, sunctx); + va_end(values); + free(msg); +} + +/* + The SUNCTX_ macro expands to the name of the local SUNContext object + defined by SUNFunctionBegin. SUNCTX_ should be used to reference the + SUNContext inside of SUNDIALS functions. + */ +#define SUNCTX_ sunctx_local_scope_ + +/* + The SUNFunctionBegin macro is used to declare the local SUNContext object to + be used a function. It should be used at the start of every SUNDIALS + functions. + + :param sunctx: the SUNContext to set the local SUNContext variable to + */ +#define SUNFunctionBegin(sunctx) \ + SUNContext SUNCTX_ = sunctx; \ + (void)SUNCTX_ + +/* ---------------------------------------------------------------------------- + * SUNCheck* family of error checking macros + * + * We define several different versions of SUNCheck* macros to cover various + * programming scenarios. + * + * SUNCheckCall* macros are used to check SUNDIALS function calls that + * return a SUNErrCode. + * + * SUNCheckLastErr* macros are used to check SUNDIALS function calls that + * do not return a SUNErrCode. + * ---------------------------------------------------------------------------*/ + +/* + SUNCheck evaluates the given expression and calls the error handler if it is + false. It should be used to check expressions that do not imply stringent + assumptions. If the expression should be strictly assumed as true, then use + SUNAssert instead. + + Use SUNAssert macros to check for conditions that do not make sense e.g., + to check if malloc returned NULL. + + :param expr: an expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheck(expr, code) \ + do { \ + if (SUNHintFalse(!(expr))) \ + { \ + SUNHandleErrWithFmtMsg(__LINE__, __func__, __FILE__, "expected %s", \ + code, SUNCTX_, #expr); \ + return code; \ + } \ + } \ + while (0) +#else +#define SUNCheck(expr, code) +#endif + +/* + SUNCheckNoRet is the same as SUNCheck but *does not return from the caller*. + Use SUNAssert macros to check for conditions that do not make sense e.g., + to check if malloc returned NULL. + + :param expr: an expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckNoRet(expr, code) \ + do { \ + if (SUNHintFalse(!(expr))) \ + { \ + SUNHandleErrWithFmtMsg(__LINE__, __func__, __FILE__, "expected %s", \ + code, SUNCTX_, #expr); \ + } \ + } \ + while (0) +#else +#define SUNCheckNoRet(expr, code) +#endif + +/* + SUNCheckNull is the same as SUNCheck but *returns NULL from the caller*. + Use SUNAssert macros to check for conditions that do not make sense e.g., + to check if malloc returned NULL. + + :param expr: an expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckNull(expr, code) \ + do { \ + if (SUNHintFalse(!(expr))) \ + { \ + SUNHandleErrWithFmtMsg(__LINE__, __func__, __FILE__, "expected %s", \ + code, SUNCTX_, #expr); \ + return NULL; \ + } \ + } \ + while (0) +#else +#define SUNCheckNull(expr, code) +#endif + +/* + SUNCheckNull is the same as SUNCheck but *returns void from the caller*. + Use SUNAssert macros to check for conditions that do not make sense e.g., + to check if malloc returned NULL. + + :param expr: an expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckVoid(expr, code) \ + do { \ + if (SUNHintFalse(!(expr))) \ + { \ + SUNHandleErrWithFmtMsg(__LINE__, __func__, __FILE__, "expected %s", \ + code, SUNCTX_, #expr); \ + return; \ + } \ + } \ + while (0) +#else +#define SUNCheckVoid(expr, code) +#endif + +/* + SUNCheckCallMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler, **and then return the error code**. + + :param call: the function call + :param msg: an error message +*/ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckCallMsg(call, msg) \ + do { \ + SUNErrCode sun_chk_call_err_code_ = call; \ + if (SUNHintFalse(sun_chk_call_err_code_ < 0)) \ + { \ + SUNHandleErrWithMsg(__LINE__, __func__, __FILE__, msg, \ + sun_chk_call_err_code_, SUNCTX_); \ + return sun_chk_call_err_code_; \ + } \ + } \ + while (0) +#else +#define SUNCheckCallMsg(call, msg) (void)call +#endif + +/* + SUNCheckCallNoRetMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, and call the error handler. **It does not return**. + + :param call: the function call + :param msg: an error message +*/ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckCallNoRetMsg(call, msg) \ + do { \ + SUNErrCode sun_chk_call_err_code_ = call; \ + if (SUNHintFalse(sun_chk_call_err_code_ < 0)) \ + { \ + SUNHandleErrWithMsg(__LINE__, __func__, __FILE__, msg, \ + sun_chk_call_err_code_, SUNCTX_); \ + } \ + } \ + while (0) +#else +#define SUNCheckCallNoRetMsg(call, msg) (void)call +#endif + +/* + SUNCheckCallNullMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler, **and then returns NULL**. + + :param call: the function call + :param msg: an error message +*/ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckCallNullMsg(call, msg) \ + do { \ + SUNErrCode sun_chk_call_err_code_ = call; \ + if (SUNHintFalse(sun_chk_call_err_code_ < 0)) \ + { \ + SUNHandleErrWithMsg(__LINE__, __func__, __FILE__, msg, \ + sun_chk_call_err_code_, SUNCTX_); \ + return NULL; \ + } \ + } \ + while (0) +#else +#define SUNCheckCallNullMsg(call, msg) (void)call +#endif + +/* + SUNCheckCallNullMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler, **and then returns void**. + + :param call: the function call + :param msg: an error message +*/ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckCallVoidMsg(call, msg) \ + do { \ + SUNErrCode sun_chk_call_err_code_ = call; \ + if (SUNHintFalse(sun_chk_call_err_code_ < 0)) \ + { \ + SUNHandleErrWithMsg(__LINE__, __func__, __FILE__, msg, \ + sun_chk_call_err_code_, SUNCTX_); \ + return; \ + } \ + } \ + while (0) +#else +#define SUNCheckCallVoidMsg(call, msg) (void)call +#endif + +/* These versions of SUNCheckCall do not take a custom message so a + default message associated with the error code will be used. */ +#define SUNCheckCall(call) SUNCheckCallMsg(call, NULL) +#define SUNCheckCallNoRet(call) SUNCheckCallNoRetMsg(call, NULL) +#define SUNCheckCallNull(call) SUNCheckCallNullMsg(call, NULL) +#define SUNCheckCallVoid(call) SUNCheckCallVoidMsg(call, NULL) + +/* SUNCheckLastErrMsg checks the last_err value in the SUNContext. + If an error occured, then it will log the error, set the last_err + value, and call the error handler, **and then returns the code**. */ +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNCheckLastErrMsg(msg) \ + do { \ + SUNCheckCallMsg(SUNContext_PeekLastError(SUNCTX_), msg); \ + } \ + while (0) + +/* + SUNCheckLastErrNoRetMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler. **It does not return.** + + :param msg: an error message +*/ +#define SUNCheckLastErrNoRetMsg(msg) \ + do { \ + SUNCheckCallNoRetMsg(SUNContext_PeekLastError(SUNCTX_), msg); \ + } \ + while (0) + +/* + SUNCheckLastErrNullMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler, **and then returns NULL**. + + :param msg: an error message +*/ +#define SUNCheckLastErrNullMsg(msg) \ + do { \ + SUNCheckCallNullMsg(SUNContext_PeekLastError(SUNCTX_), msg); \ + } \ + while (0) + +/* + SUNCheckLastErrVoidMsg performs the SUNDIALS function call, and checks the + returned error code. If an error occured, then it will log the error, set the + last_err value, call the error handler, **and then returns void**. + + :param msg: an error message +*/ +#define SUNCheckLastErrVoidMsg(msg) \ + do { \ + SUNCheckCallVoidMsg(SUNContext_PeekLastError(SUNCTX_), msg); \ + } \ + while (0) +#else +#define SUNCheckLastErrNoRetMsg(msg) +#define SUNCheckLastErrMsg(msg) +#define SUNCheckLastErrVoidMsg(msg) +#define SUNCheckLastErrNullMsg(msg) +#endif + +/* These versions of SUNCheckLastErr do not take a custom message so the + default message associated with the error code will be used. */ +#define SUNCheckLastErr() SUNCheckLastErrMsg(NULL) +#define SUNCheckLastErrNoRet() SUNCheckLastErrNoRetMsg(NULL) +#define SUNCheckLastErrVoid() SUNCheckLastErrVoidMsg(NULL) +#define SUNCheckLastErrNull() SUNCheckLastErrNullMsg(NULL) + +/* + SUNAssert checks if an expression is true. It expands to SUNCheck in debug + builds othewrise we try to expand it to an assumption, if the compiler + supports assumptions, so that the compiler can make optimizations based on the + assumption. + + :param expr: a expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNAssert(expr, code) SUNCheck(expr, code) +#else +#define SUNAssert(expr, code) +#endif + +/* + SUNAssertNoRet is the same as SUNAssert but it does not return from the + caller. + + :param expr: a expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNAssertNoRet(expr, code) SUNCheckNoRet(expr, code) +#else +#define SUNAssertNoRet(expr, code) +#endif + +/* + SUNAssertNull is the same as SUNAssert but it *returns NULL from the caller*. + + :param expr: a expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNAssertNull(expr, code) SUNCheckNull(expr, code) +#else +#define SUNAssertNull(expr, code) +#endif + +/* + SUNAssertVoid is the same as SUNAssert but it *returns void from the caller*. + + :param expr: a expression to evaluate as true or false + :param code: the error code to pass to the error handler if the expression is + false +*/ + +#if defined(SUNDIALS_ENABLE_ERROR_CHECKS) +#define SUNAssertVoid(expr, code) SUNCheckVoid(expr, code) +#else +#define SUNAssertVoid(expr, code) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SUNDIALS_ERRORS_IMPL_H */ diff --git a/ThirdParty/sundials/include/sundials/sundials_adaptcontroller.h b/ThirdParty/sundials/include/sundials/sundials_adaptcontroller.h new file mode 100644 index 0000000000..b27d7c73c8 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_adaptcontroller.h @@ -0,0 +1,157 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * SUNDIALS accuracy-based adaptivity controller class. These + * objects estimate step sizes for time integration methods such + * that the next step solution should satisfy a desired temporal + * accuracy. + * ----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_ADAPTCONTROLLER_H +#define _SUNDIALS_ADAPTCONTROLLER_H + +#include +#include +#include + +#include "sundials/sundials_types.h" + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ----------------------------------------------------------------- + * SUNAdaptController types (currently, only "H" is implemented; + * others are planned): + * NONE - empty controller (does nothing) + * H - controls a single-rate step size + * ----------------------------------------------------------------- */ + +typedef enum +{ + SUN_ADAPTCONTROLLER_NONE, + SUN_ADAPTCONTROLLER_H +} SUNAdaptController_Type; + +/* ----------------------------------------------------------------- + * Generic definition of SUNAdaptController + * ----------------------------------------------------------------- */ + +/* Forward reference for pointer to SUNAdaptController_Ops object */ +typedef _SUNDIALS_STRUCT_ _generic_SUNAdaptController_Ops* SUNAdaptController_Ops; + +/* Forward reference for pointer to SUNAdaptController object */ +typedef _SUNDIALS_STRUCT_ _generic_SUNAdaptController* SUNAdaptController; + +/* Structure containing function pointers to controller operations */ +struct _generic_SUNAdaptController_Ops +{ + /* REQUIRED of all controller implementations. */ + SUNAdaptController_Type (*gettype)(SUNAdaptController C); + + /* REQUIRED for controllers of SUN_ADAPTCONTROLLER_H type. */ + SUNErrCode (*estimatestep)(SUNAdaptController C, sunrealtype h, int p, + sunrealtype dsm, sunrealtype* hnew); + + /* OPTIONAL for all SUNAdaptController implementations. */ + SUNErrCode (*destroy)(SUNAdaptController C); + SUNErrCode (*reset)(SUNAdaptController C); + SUNErrCode (*setdefaults)(SUNAdaptController C); + SUNErrCode (*write)(SUNAdaptController C, FILE* fptr); + SUNErrCode (*seterrorbias)(SUNAdaptController C, sunrealtype bias); + SUNErrCode (*updateh)(SUNAdaptController C, sunrealtype h, sunrealtype dsm); + SUNErrCode (*space)(SUNAdaptController C, long int* lenrw, long int* leniw); +}; + +/* A SUNAdaptController is a structure with an implementation-dependent + 'content' field, and a pointer to a structure of + operations corresponding to that implementation. */ +struct _generic_SUNAdaptController +{ + void* content; + SUNAdaptController_Ops ops; + SUNContext sunctx; +}; + +/* ----------------------------------------------------------------- + * Functions exported by SUNAdaptController module + * ----------------------------------------------------------------- */ + +/* Function to create an empty SUNAdaptController data structure. */ +SUNDIALS_EXPORT +SUNAdaptController SUNAdaptController_NewEmpty(SUNContext sunctx); + +/* Function to free a generic SUNAdaptController (assumes content is already empty) */ +SUNDIALS_EXPORT +void SUNAdaptController_DestroyEmpty(SUNAdaptController C); + +/* Function to report the type of a SUNAdaptController object. */ +SUNDIALS_EXPORT +SUNAdaptController_Type SUNAdaptController_GetType(SUNAdaptController C); + +/* Function to deallocate a SUNAdaptController object. + + Any return value other than SUN_SUCCESS will be treated as + an unrecoverable failure. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Destroy(SUNAdaptController C); + +/* Main step size controller function. This is called following + a time step with size 'h' and local error factor 'dsm', and the + controller should estimate 'hnew' so that the ensuing step + will have 'dsm' value JUST BELOW 1. + + Any return value other than SUN_SUCCESS will be treated as + an unrecoverable failure. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_EstimateStep(SUNAdaptController C, sunrealtype h, + int p, sunrealtype dsm, + sunrealtype* hnew); + +/* Function to reset the controller to its initial state, e.g., if + it stores a small number of previous dsm or step size values. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Reset(SUNAdaptController C); + +/* Function to set the controller parameters to their default values. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetDefaults(SUNAdaptController C); + +/* Function to write all controller parameters to the indicated file + pointer. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Write(SUNAdaptController C, FILE* fptr); + +/* Function to set an error bias factor to use for scaling the local error + 'dsm' factors above. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_SetErrorBias(SUNAdaptController C, + sunrealtype bias); + +/* Function to notify a controller of type SUN_ADAPTCONTROLLER_H that + a successful time step was taken with stepsize h and local error factor + dsm, indicating that these can be saved for subsequent controller functions. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_UpdateH(SUNAdaptController C, sunrealtype h, + sunrealtype dsm); + +/* Function to return the memory requirements of the controller object. */ +SUNDIALS_EXPORT +SUNErrCode SUNAdaptController_Space(SUNAdaptController C, long int* lenrw, + long int* leniw); + +#ifdef __cplusplus +} +#endif + +#endif /* _SUNDIALS_ADAPTCONTROLLER_H */ diff --git a/ThirdParty/sundials/include/sundials/sundials_base.hpp b/ThirdParty/sundials/include/sundials/sundials_base.hpp new file mode 100644 index 0000000000..9a43da93f1 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_base.hpp @@ -0,0 +1,151 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * Base classes for C++ implementations of SUNDIALS objects and wrappers (views) + * of SUNDIALS objects + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_BASE_HPP +#define _SUNDIALS_BASE_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { + +// +// Common base class for C++ implementations of SUNDIALS data structures. +// +template +class BaseObject +{ +public: + BaseObject() = default; + + BaseObject(SUNContext sunctx) + : sunctx_(sunctx), + object_(std::make_unique()), + object_ops_(std::make_unique()) + { + object_->content = this; + object_->sunctx = sunctx_; + object_->ops = object_ops_.get(); + } + + // Move constructor + BaseObject(BaseObject&& other) noexcept + : sunctx_(std::move(other.sunctx_)), + object_(std::move(other.object_)), + object_ops_(std::move(other.object_ops_)) + { + object_->content = this; + object_->sunctx = sunctx_; + object_->ops = object_ops_.get(); + } + + // Copy constructor + BaseObject(const BaseObject& other) + : sunctx_(other.sunctx_), + object_(std::make_unique()), + object_ops_(std::make_unique(*other.object_ops_)) + { + object_->content = this; + object_->sunctx = other.sunctx_; + object_->ops = object_ops_.get(); + } + + // Move assignment + BaseObject& operator=(BaseObject&& rhs) noexcept + { + sunctx_ = std::move(rhs.sunctx_); + object_ops_ = std::move(rhs.object_ops_); + object_ = std::move(rhs.object_); + object_->content = this; + object_->sunctx = sunctx_; + object_->ops = object_ops_.get(); + return *this; + } + + // Copy assignment + BaseObject& operator=(const BaseObject& rhs) + { + sunctx_ = rhs.sunctx_; + object_ops_ = std::make_unique(*rhs.object_ops_); + object_ = std::make_unique(); + object_->content = this; + object_->sunctx = sunctx_; + object_->ops = object_ops_.get(); + return *this; + } + + // We have a pure virtual destructor to make this an asbtract class + virtual ~BaseObject() = 0; + + // Getters + SUNContext sunctx() const { return this->object_->sunctx; } + +protected: + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + SUNContext sunctx_{}; + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + std::unique_ptr object_; + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + std::unique_ptr object_ops_; +}; + +// Pure virtual destructor requires implementation +template +BaseObject::~BaseObject() = default; + +} // namespace impl + +namespace experimental { + +template +class ClassView : public sundials::ConvertibleTo +{ +public: + ClassView() : object_(nullptr) {} + + ClassView(T&& object) : object_(std::make_unique(object)) {} + + ClassView(const ClassView&) = delete; + ClassView(ClassView&& other) = default; + + ClassView& operator=(const ClassView&) = delete; + ClassView& operator=(ClassView&& rhs) = default; + + ~ClassView() + { + if (object_) { Deleter{}(this->Convert()); } + }; + + // Override ConvertibleTo functions + T Convert() override { return *object_.get(); } + + T Convert() const override { return *object_.get(); } + + operator T() override { return *object_.get(); } + + operator T() const override { return *object_.get(); } + +private: + std::unique_ptr object_; +}; + +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_context.h b/ThirdParty/sundials/include/sundials/sundials_context.h new file mode 100644 index 0000000000..49e2bda2dd --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_context.h @@ -0,0 +1,66 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * SUNDIALS context class. A context object holds data that all + * SUNDIALS objects in a simulation share. It is thread-safe provided + * that each thread has its own context object. + * ----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CONTEXT_H +#define _SUNDIALS_CONTEXT_H + +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +SUNDIALS_EXPORT +SUNErrCode SUNContext_Create(SUNComm comm, SUNContext* sunctx_out); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_GetLastError(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_PeekLastError(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_PushErrHandler(SUNContext sunctx, SUNErrHandlerFn err_fn, + void* err_user_data); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_PopErrHandler(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_ClearErrHandlers(SUNContext sunctx); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_GetProfiler(SUNContext sunctx, SUNProfiler* profiler); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_SetProfiler(SUNContext sunctx, SUNProfiler profiler); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_GetLogger(SUNContext sunctx, SUNLogger* logger); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_SetLogger(SUNContext sunctx, SUNLogger logger); + +SUNDIALS_EXPORT +SUNErrCode SUNContext_Free(SUNContext* ctx); + +#ifdef __cplusplus +} + +#endif +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_context.hpp b/ThirdParty/sundials/include/sundials/sundials_context.hpp new file mode 100644 index 0000000000..c28fb8026b --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_context.hpp @@ -0,0 +1,64 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ interface to the SUNDIALS context object + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CONTEXT_HPP +#define _SUNDIALS_CONTEXT_HPP + +#include +#include +#include + +#include "sundials/sundials_types.h" + +namespace sundials { + +class Context : public sundials::ConvertibleTo +{ +public: + explicit Context(SUNComm comm = SUN_COMM_NULL) + { + sunctx_ = std::make_unique(); + SUNContext_Create(comm, sunctx_.get()); + } + + /* disallow copy, but allow move construction */ + Context(const Context&) = delete; + Context(Context&&) = default; + + /* disallow copy, but allow move operators */ + Context& operator=(const Context&) = delete; + Context& operator=(Context&&) = default; + + SUNContext Convert() override { return *sunctx_.get(); } + + SUNContext Convert() const override { return *sunctx_.get(); } + + operator SUNContext() override { return *sunctx_.get(); } + + operator SUNContext() const override { return *sunctx_.get(); } + + ~Context() + { + if (sunctx_) { SUNContext_Free(sunctx_.get()); } + } + +private: + std::unique_ptr sunctx_; +}; + +} // namespace sundials + +#endif // _SUNDIALS_CONTEXT_HPP diff --git a/ThirdParty/sundials/include/sundials/sundials_convertibleto.hpp b/ThirdParty/sundials/include/sundials/sundials_convertibleto.hpp new file mode 100644 index 0000000000..7443ed4cfa --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_convertibleto.hpp @@ -0,0 +1,39 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * Base class for converting C++ wappers (views) to SUNDIALS objects + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CONVERTIBLETO_HPP +#define _SUNDIALS_CONVERTIBLETO_HPP + +namespace sundials { + +template +class ConvertibleTo +{ +public: + // Explicit conversion to the underlying type + virtual T Convert() = 0; + virtual T Convert() const = 0; + + // Implicit conversion to the underlying type + virtual operator T() = 0; + virtual operator T() const = 0; + + virtual ~ConvertibleTo() = default; +}; + +} // namespace sundials + +#endif // _SUNDIALS_CONVERTIBLETO_HPP diff --git a/ThirdParty/sundials/include/sundials/sundials_core.h b/ThirdParty/sundials/include/sundials/sundials_core.h new file mode 100644 index 0000000000..592d1d7b1e --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_core.h @@ -0,0 +1,38 @@ +/* ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * Header file that includes the SUNDIALS core. + * ----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CORE_H +#define _SUNDIALS_CORE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if SUNDIALS_MPI_ENABLED +#include +#endif + +#endif /* _SUNDIALS_CORE_H */ diff --git a/ThirdParty/sundials/include/sundials/sundials_core.hpp b/ThirdParty/sundials/include/sundials/sundials_core.hpp new file mode 100644 index 0000000000..51372a3f01 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_core.hpp @@ -0,0 +1,25 @@ +/* ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_CORE_HPP +#define _SUNDIALS_CORE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* _SUNDIALS_CORE_HPP */ diff --git a/ThirdParty/sundials/include/sundials/sundials_errors.h b/ThirdParty/sundials/include/sundials/sundials_errors.h new file mode 100644 index 0000000000..b132b0f3b0 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_errors.h @@ -0,0 +1,116 @@ +/* ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * Contains all error handling interfaces for SUNDIALS that do + * not depend on MPI. + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_ERRORS_H +#define _SUNDIALS_ERRORS_H + +#include +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------------------------- + * Error code definitions + * ---------------------------------------------------------------------------*/ + +/* SUN_ERR_CODE_LIST is an X macro that can be expanded in various ways */ +#define SUN_ERR_CODE_LIST(ENTRY) \ + ENTRY(SUN_ERR_ARG_CORRUPT, "argument provided is NULL or corrupted") \ + ENTRY(SUN_ERR_ARG_INCOMPATIBLE, "argument provided is not compatible") \ + ENTRY(SUN_ERR_ARG_OUTOFRANGE, "argument is out of the valid range") \ + ENTRY(SUN_ERR_ARG_WRONGTYPE, "argument provided is not the right type") \ + ENTRY(SUN_ERR_ARG_DIMSMISMATCH, "argument dimensions do not agree") \ + \ + ENTRY(SUN_ERR_GENERIC, "an error occurred") \ + ENTRY(SUN_ERR_CORRUPT, "value is NULL or corrupt") \ + ENTRY(SUN_ERR_OUTOFRANGE, "Value is out of the expected range") \ + ENTRY(SUN_ERR_FILE_OPEN, "Unable to open file") \ + ENTRY(SUN_ERR_OP_FAIL, "an operation failed") \ + ENTRY(SUN_ERR_MEM_FAIL, "a memory operation failed") \ + ENTRY(SUN_ERR_MALLOC_FAIL, "malloc returned NULL") \ + ENTRY(SUN_ERR_EXT_FAIL, "a failure occurred in an external library") \ + ENTRY(SUN_ERR_DESTROY_FAIL, "a destroy function returned an error") \ + ENTRY(SUN_ERR_NOT_IMPLEMENTED, \ + "operation is not implemented: function pointer is NULL") \ + ENTRY(SUN_ERR_USER_FCN_FAIL, "the user provided callback function failed") \ + \ + ENTRY(SUN_ERR_PROFILER_MAPFULL, \ + "the number of profiler entries exceeded SUNPROFILER_MAX_ENTRIES") \ + ENTRY(SUN_ERR_PROFILER_MAPGET, "unknown error getting SUNProfiler timer") \ + ENTRY(SUN_ERR_PROFILER_MAPINSERT, \ + "unknown error inserting SUNProfiler timer") \ + ENTRY(SUN_ERR_PROFILER_MAPKEYNOTFOUND, "timer was not found in SUNProfiler") \ + ENTRY(SUN_ERR_PROFILER_MAPSORT, "error sorting SUNProfiler map") \ + \ + ENTRY(SUN_ERR_SUNCTX_CORRUPT, "SUNContext is NULL or corrupt") \ + \ + ENTRY(SUN_ERR_MPI_FAIL, \ + "an MPI call returned something other than MPI_SUCCESS") \ + \ + ENTRY(SUN_ERR_UNREACHABLE, \ + "Reached code that should be unreachable: open an issue at: " \ + "https://github.com/LLNL/sundials") \ + ENTRY(SUN_ERR_UNKNOWN, "Unknown error occured: open an issue at " \ + "https://github.com/LLNL/sundials") + +/* Expand SUN_ERR_CODE_LIST to enum */ +#define SUN_EXPAND_TO_ENUM(name, description) name, + +/* SUNErrorCode range is [-10000, -1000] to avoid conflicts with package error + codes, and old/deprecated codes for matrix and (non)linear solvers. */ + +/* clang-format off */ +enum +{ + SUN_ERR_MINIMUM = -10000, + SUN_ERR_CODE_LIST(SUN_EXPAND_TO_ENUM) + SUN_ERR_MAXIMUM = -1000, + SUN_SUCCESS = 0 +}; + +/* clang-format on */ + +/* ---------------------------------------------------------------------------- + * Error handler definitions + * ---------------------------------------------------------------------------*/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +SUNDIALS_EXPORT +void SUNLogErrHandlerFn(int line, const char* func, const char* file, + const char* msg, SUNErrCode err_code, + void* err_user_data, SUNContext sunctx); + +SUNDIALS_EXPORT +void SUNAbortErrHandlerFn(int line, const char* func, const char* file, + const char* msg, SUNErrCode err_code, + void* err_user_data, SUNContext sunctx); + +/* ---------------------------------------------------------------------------- + * Error functions + * ---------------------------------------------------------------------------*/ + +/* Turn error code into error message */ +SUNDIALS_EXPORT +const char* SUNGetErrMsg(SUNErrCode code); + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +} /* extern "C" */ +#endif +#endif /* _SUNDIALS_ERRORS_H */ diff --git a/ThirdParty/sundials/include/sundials/sundials_linearsolver.hpp b/ThirdParty/sundials/include/sundials/sundials_linearsolver.hpp new file mode 100644 index 0000000000..54266119ab --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_linearsolver.hpp @@ -0,0 +1,43 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ view of SUNDIALS SUNLinaerSolver + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_LINEARSOLVER_HPP +#define _SUNDIALS_LINEARSOLVER_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { +using BaseLinearSolver = + BaseObject<_generic_SUNLinearSolver, _generic_SUNLinearSolver_Ops>; +} // namespace impl + +namespace experimental { +struct SUNLinearSolverDeleter +{ + void operator()(SUNLinearSolver LS) + { + if (LS) { SUNLinSolFree(LS); } + } +}; + +using SUNLinearSolverView = ClassView; +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_logger.h b/ThirdParty/sundials/include/sundials/sundials_logger.h new file mode 100644 index 0000000000..7525404b27 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_logger.h @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------- + * Programmer: Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_LOGGER_H +#define _SUNDIALS_LOGGER_H + +#include +#include +#include + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +typedef enum +{ + SUN_LOGLEVEL_ALL = -1, + SUN_LOGLEVEL_NONE = 0, + SUN_LOGLEVEL_ERROR = 1, + SUN_LOGLEVEL_WARNING = 2, + SUN_LOGLEVEL_INFO = 3, + SUN_LOGLEVEL_DEBUG = 4 +} SUNLogLevel; + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_Create(SUNComm comm, int output_rank, SUNLogger* logger); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_CreateFromEnv(SUNComm comm, SUNLogger* logger); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_SetErrorFilename(SUNLogger logger, + const char* error_filename); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_SetWarningFilename(SUNLogger logger, + const char* warning_filename); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_SetDebugFilename(SUNLogger logger, + const char* debug_filename); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_SetInfoFilename(SUNLogger logger, const char* info_filename); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_QueueMsg(SUNLogger logger, SUNLogLevel lvl, + const char* scope, const char* label, + const char* msg_txt, ...); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_Flush(SUNLogger logger, SUNLogLevel lvl); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_GetOutputRank(SUNLogger logger, int* output_rank); + +SUNDIALS_EXPORT +SUNErrCode SUNLogger_Destroy(SUNLogger* logger); + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +} +#endif +#endif /* SUNDIALS_LOGGER_H_ */ diff --git a/ThirdParty/sundials/include/sundials/sundials_matrix.hpp b/ThirdParty/sundials/include/sundials/sundials_matrix.hpp new file mode 100644 index 0000000000..b6b8a795cb --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_matrix.hpp @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ view of SUNDIALS SUNMatrix + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_MATRIX_HPP +#define _SUNDIALS_MATRIX_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { +using BaseMatrix = BaseObject<_generic_SUNMatrix, _generic_SUNMatrix_Ops>; +} // namespace impl + +namespace experimental { +struct SUNMatrixDeleter +{ + void operator()(SUNMatrix A) + { + if (A) { SUNMatDestroy(A); } + } +}; + +using SUNMatrixView = ClassView; +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_memory.hpp b/ThirdParty/sundials/include/sundials/sundials_memory.hpp new file mode 100644 index 0000000000..cb64279258 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_memory.hpp @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ view of SUNDIALS SUNMemoryHelper + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_MEMORY_HPP +#define _SUNDIALS_MEMORY_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { +using BaseMemoryHelper = BaseObject; +} // namespace impl + +namespace experimental { +struct SUNMemoryHelperDeleter +{ + void operator()(SUNMemoryHelper helper) + { + if (helper) { SUNMemoryHelper_Destroy(helper); } + } +}; + +using SUNMemoryHelperView = ClassView; +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_nonlinearsolver.hpp b/ThirdParty/sundials/include/sundials/sundials_nonlinearsolver.hpp new file mode 100644 index 0000000000..d4a5cae696 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_nonlinearsolver.hpp @@ -0,0 +1,44 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ view of SUNDIALS SUNNonlinearSolver + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_NONLINEARSOLVER_HPP +#define _SUNDIALS_NONLINEARSOLVER_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { +using BaseNonlinearSolver = + BaseObject<_generic_SUNNonlinearSolver, _generic_SUNNonlinearSolver_Ops>; +} // namespace impl + +namespace experimental { +struct SUNNonlinearSolverDeleter +{ + void operator()(SUNNonlinearSolver NLS) + { + if (NLS) { SUNNonlinSolFree(NLS); } + } +}; + +using SUNNonlinearSolverView = + ClassView; +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_nvector.hpp b/ThirdParty/sundials/include/sundials/sundials_nvector.hpp new file mode 100644 index 0000000000..e8151fa003 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_nvector.hpp @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * C++ view of SUNDIALS NVector + * ---------------------------------------------------------------------------*/ + +#ifndef _SUNDIALS_NVECTOR_HPP +#define _SUNDIALS_NVECTOR_HPP + +#include +#include +#include + +namespace sundials { +namespace impl { +using BaseNVector = BaseObject<_generic_N_Vector, _generic_N_Vector_Ops>; +} // namespace impl + +namespace experimental { +struct NVectorDeleter +{ + void operator()(N_Vector v) + { + if (v) { N_VDestroy(v); } + } +}; + +using NVectorView = ClassView; +} // namespace experimental +} // namespace sundials + +#endif diff --git a/ThirdParty/sundials/include/sundials/sundials_profiler.h b/ThirdParty/sundials/include/sundials/sundials_profiler.h new file mode 100644 index 0000000000..98da9e471d --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_profiler.h @@ -0,0 +1,101 @@ +/* ----------------------------------------------------------------- + * Programmer: Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_PROFILER_H +#define _SUNDIALS_PROFILER_H + +#include +#include +#include + +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && defined(SUNDIALS_CALIPER_ENABLED) +#include "caliper/cali.h" +#endif + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_Create(SUNComm comm, const char* title, SUNProfiler* p); +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_Free(SUNProfiler* p); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_Begin(SUNProfiler p, const char* name); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_End(SUNProfiler p, const char* name); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_GetTimerResolution(SUNProfiler p, double* resolution); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_GetElapsedTime(SUNProfiler p, const char* name, + double* time); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_Print(SUNProfiler p, FILE* fp); + +SUNDIALS_EXPORT +SUNErrCode SUNProfiler_Reset(SUNProfiler p); + +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && defined(SUNDIALS_CALIPER_ENABLED) + +#define SUNDIALS_MARK_FUNCTION_BEGIN(profobj) CALI_MARK_FUNCTION_BEGIN + +#define SUNDIALS_MARK_FUNCTION_END(profobj) CALI_MARK_FUNCTION_END + +#define SUNDIALS_WRAP_STATEMENT(profobj, name, stmt) \ + CALI_WRAP_STATEMENT(name, stmt) + +#define SUNDIALS_MARK_BEGIN(profobj, name) CALI_MARK_BEGIN(name) + +#define SUNDIALS_MARK_END(profobj, name) CALI_MARK_END(name) + +#elif defined(SUNDIALS_BUILD_WITH_PROFILING) + +#define SUNDIALS_MARK_FUNCTION_BEGIN(profobj) \ + SUNProfiler_Begin(profobj, __func__) + +#define SUNDIALS_MARK_FUNCTION_END(profobj) SUNProfiler_End(profobj, __func__) + +#define SUNDIALS_WRAP_STATEMENT(profobj, name, stmt) \ + SUNProfiler_Begin(profobj, (name)); \ + stmt; \ + SUNProfiler_End(profobj, (name)); + +#define SUNDIALS_MARK_BEGIN(profobj, name) SUNProfiler_Begin(profobj, (name)) + +#define SUNDIALS_MARK_END(profobj, name) SUNProfiler_End(profobj, (name)) + +#else + +#define SUNDIALS_MARK_FUNCTION_BEGIN(profobj) + +#define SUNDIALS_MARK_FUNCTION_END(profobj) + +#define SUNDIALS_WRAP_STATEMENT(profobj, name, stmt) + +#define SUNDIALS_MARK_BEGIN(profobj, name) + +#define SUNDIALS_MARK_END(profobj, name) + +#endif + +#ifdef __cplusplus +} + +#endif +#endif /* SUNDIALS_PROFILER_H */ diff --git a/ThirdParty/sundials/include/sundials/sundials_profiler.hpp b/ThirdParty/sundials/include/sundials/sundials_profiler.hpp new file mode 100644 index 0000000000..df589fa1e9 --- /dev/null +++ b/ThirdParty/sundials/include/sundials/sundials_profiler.hpp @@ -0,0 +1,52 @@ +/* ----------------------------------------------------------------- + * Programmer: Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_PROFILER_HPP +#define _SUNDIALS_PROFILER_HPP + +#include +#include +#include + +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && defined(SUNDIALS_CALIPER_ENABLED) +#define SUNDIALS_CXX_MARK_FUNCTION(projobj) CALI_CXX_MARK_FUNCTION +#elif defined(SUNDIALS_BUILD_WITH_PROFILING) +#define SUNDIALS_CXX_MARK_FUNCTION(profobj) \ + sundials::ProfilerMarkScope ProfilerMarkScope__(profobj, __func__) +#else +#define SUNDIALS_CXX_MARK_FUNCTION(profobj) +#endif + +namespace sundials { +/* Convenience class for C++ codes. + Allows for simpler profiler statements using C++ scoping rules. */ +class ProfilerMarkScope +{ +public: + ProfilerMarkScope(SUNProfiler prof, const char* name) + { + prof_ = prof; + name_ = name; + SUNProfiler_Begin(prof_, name_); + } + + ~ProfilerMarkScope() { SUNProfiler_End(prof_, name_); } + +private: + SUNProfiler prof_; + const char* name_; +}; +} // namespace sundials + +#endif /* SUNDIALS_PROFILER_HPP */ diff --git a/ThirdParty/sundials/src/cvodes/cvodes_proj.c b/ThirdParty/sundials/src/cvodes/cvodes_proj.c new file mode 100644 index 0000000000..e50682fdd1 --- /dev/null +++ b/ThirdParty/sundials/src/cvodes/cvodes_proj.c @@ -0,0 +1,453 @@ +/* --------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * --------------------------------------------------------------------------- + * Based on CPODES by Radu Serban @ LLNL + * --------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * --------------------------------------------------------------------------- + * Implementation file for projections in CVODE. + * ---------------------------------------------------------------------------*/ + +#include +#include + +#include "cvodes_impl.h" +#include "sundials/sundials_math.h" + +/* Private constants */ +#define ZERO SUN_RCONST(0.0) /* real 0.0 */ +#define ONE SUN_RCONST(1.0) /* real 1.0 */ + +#define ONEPSM SUN_RCONST(1.000001) + +/* Private utility function prototypes */ +static int cvProjCreate(CVodeProjMem* proj_mem); +static int cvProjSetDefaults(CVodeProjMem proj_mem); +static int cvAccessProjMem(void* cvode_mem, const char* fname, CVodeMem* cv_mem, + CVodeProjMem* proj_mem); + +/* =========================================================================== + * Exported Functions - projection initialization + * ===========================================================================*/ + +/* ----------------------------------------------------------------------------- + * CVodeSetProjFn sets a user defined projection function + * ---------------------------------------------------------------------------*/ +int CVodeSetProjFn(void* cvode_mem, CVProjFn pfun) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Check the CVODE memory pointer */ + if (cvode_mem == NULL) + { + cvProcessError(NULL, CV_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_CV_MEM_NULL); + return (CV_MEM_NULL); + } + cv_mem = (CVodeMem)cvode_mem; + + /* Check if the projection function is NULL */ + if (pfun == NULL) + { + cvProcessError(cv_mem, CV_ILL_INPUT, __LINE__, __func__, __FILE__, + "The projection function is NULL."); + return (CV_ILL_INPUT); + } + + /* Check for compatible method */ + if (cv_mem->cv_lmm != CV_BDF) + { + cvProcessError(cv_mem, CV_ILL_INPUT, __LINE__, __func__, __FILE__, + "Projection is only supported with BDF methods."); + return (CV_ILL_INPUT); + } + + /* Create the projection memory (if necessary) */ + retval = cvProjCreate(&(cv_mem->proj_mem)); + if (retval != CV_SUCCESS) + { + cvProcessError(cv_mem, CV_MEM_FAIL, __LINE__, __func__, __FILE__, + MSG_CV_MEM_FAIL); + return (CV_MEM_FAIL); + } + + /* Shortcut to projection memory */ + proj_mem = cv_mem->proj_mem; + + /* User-defined projection */ + proj_mem->internal_proj = SUNFALSE; + + /* Set the projection function */ + proj_mem->pfun = pfun; + + /* Enable projection */ + cv_mem->proj_enabled = SUNTRUE; + + return (CV_SUCCESS); +} + +/* =========================================================================== + * Exported Functions - projection set function + * ===========================================================================*/ + +int CVodeSetProjErrEst(void* cvode_mem, sunbooleantype onoff) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Set projection error flag */ + proj_mem->err_proj = onoff; + + return (CV_SUCCESS); +} + +int CVodeSetProjFrequency(void* cvode_mem, long int freq) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Set projection frequency */ + if (freq < 0) + { + /* Restore default */ + proj_mem->freq = 1; + cv_mem->proj_enabled = SUNTRUE; + } + else if (freq == 0) + { + /* Disable projection */ + proj_mem->freq = 0; + cv_mem->proj_enabled = SUNFALSE; + } + else + { + /* Enable projection at given frequency */ + proj_mem->freq = freq; + cv_mem->proj_enabled = SUNTRUE; + } + + return (CV_SUCCESS); +} + +int CVodeSetMaxNumProjFails(void* cvode_mem, int max_fails) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Set maximum number of projection failures in a step attempt */ + if (max_fails < 1) + { + /* Restore default */ + proj_mem->max_fails = PROJ_MAX_FAILS; + } + else + { + /* Update max number of fails */ + proj_mem->max_fails = max_fails; + } + + return (CV_SUCCESS); +} + +int CVodeSetEpsProj(void* cvode_mem, sunrealtype eps) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Set the projection tolerance */ + if (eps <= ZERO) + { + /* Restore default */ + proj_mem->eps_proj = PROJ_EPS; + } + else + { + /* Update projection tolerance */ + proj_mem->eps_proj = eps; + } + + return (CV_SUCCESS); +} + +int CVodeSetProjFailEta(void* cvode_mem, sunrealtype eta) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Set the step size reduction factor for a projection failure */ + if ((eta <= ZERO) || (eta > ONE)) + { + /* Restore detault */ + proj_mem->eta_pfail = PROJ_FAIL_ETA; + } + else + { + /* Udpate the eta value */ + proj_mem->eta_pfail = PROJ_FAIL_ETA; + } + + return (CV_SUCCESS); +} + +/* =========================================================================== + * Exported Functions - projection get functions + * ===========================================================================*/ + +int CVodeGetNumProjEvals(void* cvode_mem, long int* nproj) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Get number of projection evaluations */ + *nproj = proj_mem->nproj; + + return (CV_SUCCESS); +} + +int CVodeGetNumProjFails(void* cvode_mem, long int* npfails) +{ + int retval; + CVodeMem cv_mem; + CVodeProjMem proj_mem; + + /* Access memory structures */ + retval = cvAccessProjMem(cvode_mem, __func__, &cv_mem, &proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + + /* Get number of projection fails */ + *npfails = proj_mem->npfails; + + return (CV_SUCCESS); +} + +/* =========================================================================== + * Internal Functions + * ===========================================================================*/ + +/* + * cvProjection + * + * For user supplied projection function, use ftemp as temporary storage + * for the current error estimate (acor) and use tempv to store the + * accumulated corection due to projection, acorP (tempv is not touched + * until it is potentially used in cvCompleteStep). + */ + +int cvDoProjection(CVodeMem cv_mem, int* nflagPtr, sunrealtype saved_t, + int* npfailPtr) +{ + int retval; + N_Vector errP; + N_Vector acorP; + CVodeProjMem proj_mem; + + /* Access projection memory */ + if (cv_mem->proj_mem == NULL) + { + cvProcessError(cv_mem, CV_PROJ_MEM_NULL, __LINE__, __func__, __FILE__, + MSG_CV_PROJ_MEM_NULL); + return (CV_PROJ_MEM_NULL); + } + proj_mem = cv_mem->proj_mem; + + /* Initialize return flag to success */ + retval = CV_SUCCESS; + + /* Use tempv to store acorP and, if projecting the error, ftemp to store + errP (recall that in this case we did not allocate vectors to for + acorP and errP). */ + acorP = cv_mem->cv_tempv; + if (proj_mem->err_proj) { errP = cv_mem->cv_ftemp; } + else { errP = NULL; } + + /* Copy acor into errP (if projecting the error) */ + if (proj_mem->err_proj) { N_VScale(ONE, cv_mem->cv_acor, errP); } + + /* Call the user projection function */ + retval = proj_mem->pfun(cv_mem->cv_tn, cv_mem->cv_y, acorP, + proj_mem->eps_proj, errP, cv_mem->cv_user_data); + proj_mem->nproj++; + + /* This is not the first projection anymore */ + proj_mem->first_proj = SUNFALSE; + + /* Check the return value */ + if (retval == CV_SUCCESS) + { + /* Recompute acnrm to be used in error test (if projecting the error) */ + if (proj_mem->err_proj) + { + cv_mem->cv_acnrm = N_VWrmsNorm(errP, cv_mem->cv_ewt); + } + + /* The projection was successful, return now */ + cv_mem->proj_applied = SUNTRUE; + return (CV_SUCCESS); + } + + /* The projection failed, update the return value */ + if (retval < 0) { retval = CV_PROJFUNC_FAIL; } + if (retval > 0) { retval = PROJFUNC_RECVR; } + + /* Increment cumulative failure count and restore zn */ + proj_mem->npfails++; + cvRestore(cv_mem, saved_t); + + /* Return if failed unrecoverably */ + if (retval == CV_PROJFUNC_FAIL) { return (CV_PROJFUNC_FAIL); } + + /* Recoverable failure, increment failure count for this step attempt */ + (*npfailPtr)++; + cv_mem->cv_etamax = ONE; + + /* Check for maximum number of failures or |h| = hmin */ + if ((SUNRabs(cv_mem->cv_h) <= cv_mem->cv_hmin * ONEPSM) || + (*npfailPtr == proj_mem->max_fails)) + { + if (retval == PROJFUNC_RECVR) { return (CV_REPTD_PROJFUNC_ERR); } + } + + /* Reduce step size; return to reattempt the step */ + cv_mem->cv_eta = SUNMAX(proj_mem->eta_pfail, + cv_mem->cv_hmin / SUNRabs(cv_mem->cv_h)); + *nflagPtr = PREV_PROJ_FAIL; + cvRescale(cv_mem); + + return (PREDICT_AGAIN); +} + +int cvProjInit(CVodeProjMem proj_mem) +{ + /* check if projection memory exists */ + if (proj_mem == NULL) { return (CV_PROJ_MEM_NULL); } + + /* reset flags and counters */ + proj_mem->first_proj = SUNTRUE; + proj_mem->nstlprj = 0; + proj_mem->nproj = 0; + proj_mem->npfails = 0; + + return (CV_SUCCESS); +} + +int cvProjFree(CVodeProjMem* proj_mem) +{ + if (*proj_mem == NULL) { return (CV_SUCCESS); } + + free(*proj_mem); + *proj_mem = NULL; + + return (CV_SUCCESS); +} + +/* =========================================================================== + * Utility Functions + * ===========================================================================*/ + +static int cvProjCreate(CVodeProjMem* proj_mem) +{ + int retval; + + /* Allocate projection memory if necessary, otherwise return success */ + if (*proj_mem == NULL) + { + *proj_mem = (CVodeProjMem)malloc(sizeof(struct CVodeProjMemRec)); + if (*proj_mem == NULL) { return (CV_MEM_FAIL); } + + /* Zero out proj_mem */ + memset(*proj_mem, 0, sizeof(struct CVodeProjMemRec)); + + /* Initialize projection variables */ + retval = cvProjSetDefaults(*proj_mem); + if (retval != CV_SUCCESS) { return (retval); } + } + + return (CV_SUCCESS); +} + +static int cvProjSetDefaults(CVodeProjMem proj_mem) +{ + if (proj_mem == NULL) { return (CV_MEM_FAIL); } + + proj_mem->internal_proj = SUNTRUE; + proj_mem->err_proj = SUNTRUE; + proj_mem->first_proj = SUNTRUE; + + proj_mem->freq = 1; + proj_mem->nstlprj = 0; + + proj_mem->max_fails = PROJ_MAX_FAILS; + + proj_mem->pfun = NULL; + + proj_mem->eps_proj = PROJ_EPS; + proj_mem->eta_pfail = PROJ_FAIL_ETA; + + proj_mem->nproj = 0; + proj_mem->npfails = 0; + + return (CV_SUCCESS); +} + +static int cvAccessProjMem(void* cvode_mem, const char* fname, CVodeMem* cv_mem, + CVodeProjMem* proj_mem) +{ + /* Access cvode memory */ + if (cvode_mem == NULL) + { + cvProcessError(NULL, CV_MEM_NULL, __LINE__, fname, __FILE__, MSG_CV_MEM_NULL); + return (CV_MEM_NULL); + } + *cv_mem = (CVodeMem)cvode_mem; + + /* Access projection memory */ + if ((*cv_mem)->proj_mem == NULL) + { + cvProcessError(*cv_mem, CV_PROJ_MEM_NULL, __LINE__, fname, __FILE__, + MSG_CV_PROJ_MEM_NULL); + return (CV_PROJ_MEM_NULL); + } + *proj_mem = (CVodeProjMem)(*cv_mem)->proj_mem; + + return (CV_SUCCESS); +} diff --git a/ThirdParty/sundials/src/cvodes/cvodes_proj_impl.h b/ThirdParty/sundials/src/cvodes/cvodes_proj_impl.h new file mode 100644 index 0000000000..35290aa2d6 --- /dev/null +++ b/ThirdParty/sundials/src/cvodes/cvodes_proj_impl.h @@ -0,0 +1,75 @@ +/* ----------------------------------------------------------------------------- + * Programmer(s): David J. Gardner @ LLNL + * ----------------------------------------------------------------------------- + * Based on CPODES by Radu Serban @ LLNL + * ----------------------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------------------- + * Implementation header file for projections in CVODE. + * ---------------------------------------------------------------------------*/ + +#ifndef _CVODE_PROJ_IMPL_H +#define _CVODE_PROJ_IMPL_H + +#include "cvodes/cvodes.h" + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +/* ============================================================================= + * Default Projection Constants + * + * PROJ_MAX_FAILS max nunmber of projection failures in one step attempt + * PROJ_EPS projection solve tolerance + * PROJ_FAIL_ETA maximum step size decrease on projection failure + * ===========================================================================*/ + +#define PROJ_MAX_FAILS 10 +#define PROJ_EPS SUN_RCONST(0.1) +#define PROJ_FAIL_ETA SUN_RCONST(0.25) + +/* ============================================================================= + * Projection Data Structure + * ===========================================================================*/ + +/* ----------------------------------------------------------------------------- + * Types : struct CVodeProjMemRec, CVodeProjMem + * ----------------------------------------------------------------------------- + * The type CVodeProjMem is type pointer to struct CVodeProjMemRec. This + * structure contains data pertaining to the use of projection capabilities. + * ---------------------------------------------------------------------------*/ +typedef struct CVodeProjMemRec +{ + sunbooleantype internal_proj; /* use the internal projection algorithm? */ + sunbooleantype err_proj; /* is error projection enabled? */ + sunbooleantype first_proj; /* is this the first time we project? */ + + long int freq; /* projection frequency */ + long int nstlprj; /* step number of last projection */ + + int max_fails; /* maximum number of projection failures */ + + CVProjFn pfun; /* function to perform projection */ + + sunrealtype eps_proj; /* projection solve tolerance */ + sunrealtype eta_pfail; /* projection failure step reduction factor */ + + long int nproj; /* number of projections performed */ + long int npfails; /* number of projection failures */ + +}* CVodeProjMem; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/sundials/src/sunadaptcontroller/CMakeLists.txt b/ThirdParty/sundials/src/sunadaptcontroller/CMakeLists.txt new file mode 100644 index 0000000000..f82df5e169 --- /dev/null +++ b/ThirdParty/sundials/src/sunadaptcontroller/CMakeLists.txt @@ -0,0 +1,19 @@ +# ------------------------------------------------------------------------------ +# Programmer(s): Daniel R. Reynolds @ SMU +# ------------------------------------------------------------------------------ +# SUNDIALS Copyright Start +# Copyright (c) 2002-2024, Lawrence Livermore National Security +# and Southern Methodist University. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# ------------------------------------------------------------------------------ +# controller level CMakeLists.txt for SUNDIALS +# ------------------------------------------------------------------------------ + +# required native matrices +add_subdirectory(imexgus) +add_subdirectory(soderlind) diff --git a/ThirdParty/sundials/src/sunadaptcontroller/imexgus/CMakeLists.txt b/ThirdParty/sundials/src/sunadaptcontroller/imexgus/CMakeLists.txt new file mode 100644 index 0000000000..8bbef68cdf --- /dev/null +++ b/ThirdParty/sundials/src/sunadaptcontroller/imexgus/CMakeLists.txt @@ -0,0 +1,31 @@ +# --------------------------------------------------------------- +# Programmer(s): Daniel R. Reynolds @ SMU +# --------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2002-2024, Lawrence Livermore National Security +# and Southern Methodist University. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# --------------------------------------------------------------- + +# Create a library out of the generic sundials modules +sundials_add_library(sundials_sunadaptcontrollerimexgus + SOURCES + sunadaptcontroller_imexgus.c + HEADERS + ${SUNDIALS_SOURCE_DIR}/include/sunadaptcontroller/sunadaptcontroller_imexgus.h + LINK_LIBRARIES + PUBLIC sundials_core + INCLUDE_SUBDIR + sunadaptcontroller + OBJECT_LIB_ONLY +) + +# Add F2003 module if the interface is enabled +if(BUILD_FORTRAN_MODULE_INTERFACE) + add_subdirectory("fmod_int${SUNDIALS_INDEX_SIZE}") +endif() diff --git a/ThirdParty/sundials/src/sunadaptcontroller/imexgus/sunadaptcontroller_imexgus.c b/ThirdParty/sundials/src/sunadaptcontroller/imexgus/sunadaptcontroller_imexgus.c new file mode 100644 index 0000000000..e4bb23e6dd --- /dev/null +++ b/ThirdParty/sundials/src/sunadaptcontroller/imexgus/sunadaptcontroller_imexgus.c @@ -0,0 +1,234 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the implementation file for the SUNAdaptController_ImExGus + * module. + * -----------------------------------------------------------------*/ + +#include +#include + +#include +#include +#include +#include + +#include "sundials_macros.h" + +/* --------------- + * Macro accessors + * --------------- */ + +#define SACIMEXGUS_CONTENT(C) ((SUNAdaptControllerContent_ImExGus)(C->content)) +#define SACIMEXGUS_K1E(C) (SACIMEXGUS_CONTENT(C)->k1e) +#define SACIMEXGUS_K2E(C) (SACIMEXGUS_CONTENT(C)->k2e) +#define SACIMEXGUS_K1I(C) (SACIMEXGUS_CONTENT(C)->k1i) +#define SACIMEXGUS_K2I(C) (SACIMEXGUS_CONTENT(C)->k2i) +#define SACIMEXGUS_BIAS(C) (SACIMEXGUS_CONTENT(C)->bias) +#define SACIMEXGUS_EP(C) (SACIMEXGUS_CONTENT(C)->ep) +#define SACIMEXGUS_HP(C) (SACIMEXGUS_CONTENT(C)->hp) +#define SACIMEXGUS_FIRSTSTEP(C) (SACIMEXGUS_CONTENT(C)->firststep) + +/* ------------------ + * Default parameters + * ------------------ */ + +#define DEFAULT_K1E SUN_RCONST(0.367) +#define DEFAULT_K2E SUN_RCONST(0.268) +#define DEFAULT_K1I SUN_RCONST(0.95) +#define DEFAULT_K2I SUN_RCONST(0.95) +#define DEFAULT_BIAS SUN_RCONST(1.5) +#define TINY SUN_RCONST(1.0e-10) + +/* ----------------------------------------------------------------- + * exported functions + * ----------------------------------------------------------------- */ + +/* ----------------------------------------------------------------- + * Function to create a new ImExGus controller + */ + +SUNAdaptController SUNAdaptController_ImExGus(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + SUNAdaptControllerContent_ImExGus content; + + /* Create an empty controller object */ + C = NULL; + C = SUNAdaptController_NewEmpty(sunctx); + SUNCheckLastErrNull(); + + /* Attach operations */ + C->ops->gettype = SUNAdaptController_GetType_ImExGus; + C->ops->estimatestep = SUNAdaptController_EstimateStep_ImExGus; + C->ops->reset = SUNAdaptController_Reset_ImExGus; + C->ops->setdefaults = SUNAdaptController_SetDefaults_ImExGus; + C->ops->write = SUNAdaptController_Write_ImExGus; + C->ops->seterrorbias = SUNAdaptController_SetErrorBias_ImExGus; + C->ops->updateh = SUNAdaptController_UpdateH_ImExGus; + C->ops->space = SUNAdaptController_Space_ImExGus; + + /* Create content */ + content = NULL; + content = (SUNAdaptControllerContent_ImExGus)malloc(sizeof *content); + SUNAssertNull(content, SUN_ERR_MALLOC_FAIL); + + /* Attach content */ + C->content = content; + + /* Fill content with default/reset values */ + SUNCheckCallNull(SUNAdaptController_SetDefaults_ImExGus(C)); + SUNCheckCallNull(SUNAdaptController_Reset_ImExGus(C)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set ImExGus parameters + */ + +SUNErrCode SUNAdaptController_SetParams_ImExGus(SUNAdaptController C, + sunrealtype k1e, sunrealtype k2e, + sunrealtype k1i, sunrealtype k2i) +{ + SUNFunctionBegin(C->sunctx); + SACIMEXGUS_K1E(C) = k1e; + SACIMEXGUS_K2E(C) = k2e; + SACIMEXGUS_K1I(C) = k1i; + SACIMEXGUS_K2I(C) = k2i; + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * implementation of controller operations + * ----------------------------------------------------------------- */ + +SUNAdaptController_Type SUNAdaptController_GetType_ImExGus( + SUNDIALS_MAYBE_UNUSED SUNAdaptController C) +{ + return SUN_ADAPTCONTROLLER_H; +} + +SUNErrCode SUNAdaptController_EstimateStep_ImExGus(SUNAdaptController C, + sunrealtype h, int p, + sunrealtype dsm, + sunrealtype* hnew) +{ + SUNFunctionBegin(C->sunctx); + + SUNAssert(hnew, SUN_ERR_ARG_CORRUPT); + + /* order parameter to use */ + const int ord = p + 1; + + /* set usable time-step adaptivity parameters -- first step */ + const sunrealtype k = -SUN_RCONST(1.0) / ord; + const sunrealtype e = SUNMAX(SACIMEXGUS_BIAS(C) * dsm, TINY); + + /* set usable time-step adaptivity parameters -- subsequent steps */ + const sunrealtype k1e = -SACIMEXGUS_K1E(C) / ord; + const sunrealtype k2e = -SACIMEXGUS_K2E(C) / ord; + const sunrealtype k1i = -SACIMEXGUS_K1I(C) / ord; + const sunrealtype k2i = -SACIMEXGUS_K2I(C) / ord; + const sunrealtype e1 = SUNMAX(SACIMEXGUS_BIAS(C) * dsm, TINY); + const sunrealtype e2 = e1 / SUNMAX(SACIMEXGUS_EP(C), TINY); + const sunrealtype hrat = h / SACIMEXGUS_HP(C); + + /* compute estimated time step size, modifying the first step formula */ + if (SACIMEXGUS_FIRSTSTEP(C)) { *hnew = h * SUNRpowerR(e, k); } + else + { + *hnew = h * SUNMIN(hrat * SUNRpowerR(e1, k1i) * SUNRpowerR(e2, k2i), + SUNRpowerR(e1, k1e) * SUNRpowerR(e2, k2e)); + } + + /* return with success */ + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Reset_ImExGus(SUNAdaptController C) +{ + SACIMEXGUS_EP(C) = SUN_RCONST(1.0); + SACIMEXGUS_FIRSTSTEP(C) = SUNTRUE; + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_SetDefaults_ImExGus(SUNAdaptController C) +{ + SUNFunctionBegin(C->sunctx); + SACIMEXGUS_K1E(C) = DEFAULT_K1E; + SACIMEXGUS_K2E(C) = DEFAULT_K2E; + SACIMEXGUS_K1I(C) = DEFAULT_K1I; + SACIMEXGUS_K2I(C) = DEFAULT_K2I; + SACIMEXGUS_BIAS(C) = DEFAULT_BIAS; + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Write_ImExGus(SUNAdaptController C, FILE* fptr) +{ + SUNFunctionBegin(C->sunctx); + SUNAssert(fptr, SUN_ERR_ARG_CORRUPT); + fprintf(fptr, "ImEx Gustafsson SUNAdaptController module:\n"); +#if defined(SUNDIALS_EXTENDED_PRECISION) + fprintf(fptr, " k1e = %32Lg\n", SACIMEXGUS_K1E(C)); + fprintf(fptr, " k2e = %32Lg\n", SACIMEXGUS_K2E(C)); + fprintf(fptr, " k1i = %32Lg\n", SACIMEXGUS_K1I(C)); + fprintf(fptr, " k2i = %32Lg\n", SACIMEXGUS_K2I(C)); + fprintf(fptr, " bias factor = %22Lg\n", SACIMEXGUS_BIAS(C)); + fprintf(fptr, " previous error = %22Lg\n", SACIMEXGUS_EP(C)); + fprintf(fptr, " previous step = %22Lg\n", SACIMEXGUS_HP(C)); +#else + fprintf(fptr, " k1e = %16g\n", SACIMEXGUS_K1E(C)); + fprintf(fptr, " k2e = %16g\n", SACIMEXGUS_K2E(C)); + fprintf(fptr, " k1i = %16g\n", SACIMEXGUS_K1I(C)); + fprintf(fptr, " k2i = %16g\n", SACIMEXGUS_K2I(C)); + fprintf(fptr, " bias factor = %16g\n", SACIMEXGUS_BIAS(C)); + fprintf(fptr, " previous error = %16g\n", SACIMEXGUS_EP(C)); + fprintf(fptr, " previous step = %16g\n", SACIMEXGUS_HP(C)); +#endif + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_SetErrorBias_ImExGus(SUNAdaptController C, + sunrealtype bias) +{ + SUNFunctionBegin(C->sunctx); + /* set allowed value, otherwise set default */ + if (bias <= SUN_RCONST(0.0)) { SACIMEXGUS_BIAS(C) = DEFAULT_BIAS; } + else { SACIMEXGUS_BIAS(C) = bias; } + + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_UpdateH_ImExGus(SUNAdaptController C, + sunrealtype h, sunrealtype dsm) +{ + SUNFunctionBegin(C->sunctx); + SACIMEXGUS_EP(C) = SACIMEXGUS_BIAS(C) * dsm; + SACIMEXGUS_HP(C) = h; + SACIMEXGUS_FIRSTSTEP(C) = SUNFALSE; + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Space_ImExGus(SUNAdaptController C, + long int* lenrw, long int* leniw) +{ + SUNFunctionBegin(C->sunctx); + SUNAssert(lenrw, SUN_ERR_ARG_CORRUPT); + SUNAssert(leniw, SUN_ERR_ARG_CORRUPT); + *lenrw = 7; + *leniw = 1; + return SUN_SUCCESS; +} diff --git a/ThirdParty/sundials/src/sunadaptcontroller/soderlind/CMakeLists.txt b/ThirdParty/sundials/src/sunadaptcontroller/soderlind/CMakeLists.txt new file mode 100644 index 0000000000..50cf7330bc --- /dev/null +++ b/ThirdParty/sundials/src/sunadaptcontroller/soderlind/CMakeLists.txt @@ -0,0 +1,31 @@ +# --------------------------------------------------------------- +# Programmer(s): Daniel R. Reynolds @ SMU +# --------------------------------------------------------------- +# SUNDIALS Copyright Start +# Copyright (c) 2002-2024, Lawrence Livermore National Security +# and Southern Methodist University. +# All rights reserved. +# +# See the top-level LICENSE and NOTICE files for details. +# +# SPDX-License-Identifier: BSD-3-Clause +# SUNDIALS Copyright End +# --------------------------------------------------------------- + +# Create a library out of the generic sundials modules +sundials_add_library(sundials_sunadaptcontrollersoderlind + SOURCES + sunadaptcontroller_soderlind.c + HEADERS + ${SUNDIALS_SOURCE_DIR}/include/sunadaptcontroller/sunadaptcontroller_soderlind.h + LINK_LIBRARIES + PUBLIC sundials_core + INCLUDE_SUBDIR + sunadaptcontroller + OBJECT_LIB_ONLY +) + +# Add F2003 module if the interface is enabled +if(BUILD_FORTRAN_MODULE_INTERFACE) + add_subdirectory("fmod_int${SUNDIALS_INDEX_SIZE}") +endif() diff --git a/ThirdParty/sundials/src/sunadaptcontroller/soderlind/sunadaptcontroller_soderlind.c b/ThirdParty/sundials/src/sunadaptcontroller/soderlind/sunadaptcontroller_soderlind.c new file mode 100644 index 0000000000..bca88252cb --- /dev/null +++ b/ThirdParty/sundials/src/sunadaptcontroller/soderlind/sunadaptcontroller_soderlind.c @@ -0,0 +1,435 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the implementation file for the + * SUNAdaptController_Soderlind module. + * -----------------------------------------------------------------*/ + +#include +#include + +#include +#include +#include +#include + +#include "sundials_macros.h" + +/* --------------- + * Macro accessors + * --------------- */ + +#define SODERLIND_CONTENT(C) ((SUNAdaptControllerContent_Soderlind)(C->content)) +#define SODERLIND_K1(C) (SODERLIND_CONTENT(C)->k1) +#define SODERLIND_K2(C) (SODERLIND_CONTENT(C)->k2) +#define SODERLIND_K3(C) (SODERLIND_CONTENT(C)->k3) +#define SODERLIND_K4(C) (SODERLIND_CONTENT(C)->k4) +#define SODERLIND_K5(C) (SODERLIND_CONTENT(C)->k5) +#define SODERLIND_BIAS(C) (SODERLIND_CONTENT(C)->bias) +#define SODERLIND_EP(C) (SODERLIND_CONTENT(C)->ep) +#define SODERLIND_EPP(C) (SODERLIND_CONTENT(C)->epp) +#define SODERLIND_HP(C) (SODERLIND_CONTENT(C)->hp) +#define SODERLIND_HPP(C) (SODERLIND_CONTENT(C)->hpp) +#define SODERLIND_FIRSTSTEPS(C) (SODERLIND_CONTENT(C)->firststeps) + +/* ------------------ + * Default parameters + * ------------------ */ + +#define DEFAULT_K1 SUN_RCONST(1.25) /* H_{0}321 parameters */ +#define DEFAULT_K2 SUN_RCONST(0.5) +#define DEFAULT_K3 SUN_RCONST(-0.75) +#define DEFAULT_K4 SUN_RCONST(0.25) +#define DEFAULT_K5 SUN_RCONST(0.75) +#define DEFAULT_PID_K1 SUN_RCONST(0.58) /* PID parameters */ +#define DEFAULT_PID_K2 -SUN_RCONST(0.21) +#define DEFAULT_PID_K3 SUN_RCONST(0.1) +#define DEFAULT_PI_K1 SUN_RCONST(0.8) /* PI parameters */ +#define DEFAULT_PI_K2 -SUN_RCONST(0.31) +#define DEFAULT_I_K1 SUN_RCONST(1.0) /* I parameters */ +#define DEFAULT_EXPGUS_K1 SUN_RCONST(0.367) /* Explicit Gustafsson parameters */ +#define DEFAULT_EXPGUS_K2 SUN_RCONST(0.268) +#define DEFAULT_IMPGUS_K1 SUN_RCONST(0.98) /* Implicit Gustafsson parameters */ +#define DEFAULT_IMPGUS_K2 SUN_RCONST(0.95) +#define DEFAULT_BIAS SUN_RCONST(1.5) +#define TINY SUN_RCONST(1.0e-10) + +/* ----------------------------------------------------------------- + * exported functions + * ----------------------------------------------------------------- */ + +/* ----------------------------------------------------------------- + * Function to create a new Soderlind controller + */ + +SUNAdaptController SUNAdaptController_Soderlind(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + SUNAdaptControllerContent_Soderlind content; + + /* Create an empty controller object */ + C = NULL; + C = SUNAdaptController_NewEmpty(sunctx); + SUNCheckLastErrNull(); + + /* Attach operations */ + C->ops->gettype = SUNAdaptController_GetType_Soderlind; + C->ops->estimatestep = SUNAdaptController_EstimateStep_Soderlind; + C->ops->reset = SUNAdaptController_Reset_Soderlind; + C->ops->setdefaults = SUNAdaptController_SetDefaults_Soderlind; + C->ops->write = SUNAdaptController_Write_Soderlind; + C->ops->seterrorbias = SUNAdaptController_SetErrorBias_Soderlind; + C->ops->updateh = SUNAdaptController_UpdateH_Soderlind; + C->ops->space = SUNAdaptController_Space_Soderlind; + + /* Create content */ + content = NULL; + content = (SUNAdaptControllerContent_Soderlind)malloc(sizeof *content); + SUNAssertNull(content, SUN_ERR_MALLOC_FAIL); + + /* Attach content */ + C->content = content; + + /* Fill content with default/reset values */ + SUNCheckCallNull(SUNAdaptController_SetDefaults_Soderlind(C)); + SUNCheckCallNull(SUNAdaptController_Reset_Soderlind(C)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set Soderlind parameters + */ + +SUNErrCode SUNAdaptController_SetParams_Soderlind(SUNAdaptController C, + sunrealtype k1, + sunrealtype k2, sunrealtype k3, + sunrealtype k4, sunrealtype k5) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1; + SODERLIND_K2(C) = k2; + SODERLIND_K3(C) = k3; + SODERLIND_K4(C) = k4; + SODERLIND_K5(C) = k5; + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * Function to create a PID controller (subset of Soderlind) + */ + +SUNAdaptController SUNAdaptController_PID(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C = SUNAdaptController_Soderlind(sunctx); + SUNCheckLastErrNull(); + + SUNCheckCallNull(SUNAdaptController_SetParams_PID(C, DEFAULT_PID_K1, + DEFAULT_PID_K2, + DEFAULT_PID_K3)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set PID parameters + */ + +SUNErrCode SUNAdaptController_SetParams_PID(SUNAdaptController C, sunrealtype k1, + sunrealtype k2, sunrealtype k3) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1; + SODERLIND_K2(C) = k2; + SODERLIND_K3(C) = k3; + SODERLIND_K4(C) = SUN_RCONST(0.0); + SODERLIND_K5(C) = SUN_RCONST(0.0); + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * Function to create a PI controller (subset of Soderlind) + */ + +SUNAdaptController SUNAdaptController_PI(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + C = SUNAdaptController_Soderlind(sunctx); + SUNCheckLastErrNull(); + + SUNCheckCallNull( + SUNAdaptController_SetParams_PI(C, DEFAULT_PI_K1, DEFAULT_PI_K2)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set PI parameters + */ + +SUNErrCode SUNAdaptController_SetParams_PI(SUNAdaptController C, sunrealtype k1, + sunrealtype k2) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1; + SODERLIND_K2(C) = k2; + SODERLIND_K3(C) = SUN_RCONST(0.0); + SODERLIND_K4(C) = SUN_RCONST(0.0); + SODERLIND_K5(C) = SUN_RCONST(0.0); + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * Function to create an I controller (subset of Soderlind) + */ + +SUNAdaptController SUNAdaptController_I(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + C = SUNAdaptController_Soderlind(sunctx); + SUNCheckLastErrNull(); + + SUNCheckCallNull(SUNAdaptController_SetParams_I(C, DEFAULT_I_K1)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set PI parameters + */ + +SUNErrCode SUNAdaptController_SetParams_I(SUNAdaptController C, sunrealtype k1) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1; + SODERLIND_K2(C) = SUN_RCONST(0.0); + SODERLIND_K3(C) = SUN_RCONST(0.0); + SODERLIND_K4(C) = SUN_RCONST(0.0); + SODERLIND_K5(C) = SUN_RCONST(0.0); + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * Function to create an explicit Gustafsson controller + */ + +SUNAdaptController SUNAdaptController_ExpGus(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + C = SUNAdaptController_Soderlind(sunctx); + SUNCheckLastErrNull(); + + SUNCheckCallNull(SUNAdaptController_SetParams_ExpGus(C, DEFAULT_EXPGUS_K1, + DEFAULT_EXPGUS_K2)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set explicit Gustafsson parameters + */ + +SUNErrCode SUNAdaptController_SetParams_ExpGus(SUNAdaptController C, + sunrealtype k1, sunrealtype k2) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1 + k2; + SODERLIND_K2(C) = -k2; + SODERLIND_K3(C) = SUN_RCONST(0.0); + SODERLIND_K4(C) = SUN_RCONST(0.0); + SODERLIND_K5(C) = SUN_RCONST(0.0); + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * Function to create an implicit Gustafsson controller + */ + +SUNAdaptController SUNAdaptController_ImpGus(SUNContext sunctx) +{ + SUNFunctionBegin(sunctx); + + SUNAdaptController C; + C = SUNAdaptController_Soderlind(sunctx); + SUNCheckLastErrNull(); + + SUNCheckCallNull(SUNAdaptController_SetParams_ImpGus(C, DEFAULT_IMPGUS_K1, + DEFAULT_IMPGUS_K2)); + + return (C); +} + +/* ----------------------------------------------------------------- + * Function to set explicit Gustafsson parameters + */ + +SUNErrCode SUNAdaptController_SetParams_ImpGus(SUNAdaptController C, + sunrealtype k1, sunrealtype k2) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = k1 + k2; + SODERLIND_K2(C) = -k2; + SODERLIND_K3(C) = SUN_RCONST(0.0); + SODERLIND_K4(C) = SUN_RCONST(1.0); + SODERLIND_K5(C) = SUN_RCONST(0.0); + return SUN_SUCCESS; +} + +/* ----------------------------------------------------------------- + * implementation of controller operations + * ----------------------------------------------------------------- */ + +SUNAdaptController_Type SUNAdaptController_GetType_Soderlind( + SUNDIALS_MAYBE_UNUSED SUNAdaptController C) +{ + return SUN_ADAPTCONTROLLER_H; +} + +SUNErrCode SUNAdaptController_EstimateStep_Soderlind(SUNAdaptController C, + sunrealtype h, int p, + sunrealtype dsm, + sunrealtype* hnew) +{ + SUNFunctionBegin(C->sunctx); + SUNAssert(hnew, SUN_ERR_ARG_CORRUPT); + + /* order parameter to use */ + const int ord = p + 1; + + /* set usable time-step adaptivity parameters */ + const sunrealtype k1 = -SODERLIND_K1(C) / ord; + const sunrealtype k2 = -SODERLIND_K2(C) / ord; + const sunrealtype k3 = -SODERLIND_K3(C) / ord; + const sunrealtype k4 = SODERLIND_K4(C); + const sunrealtype k5 = SODERLIND_K5(C); + const sunrealtype e1 = SUNMAX(SODERLIND_BIAS(C) * dsm, TINY); + const sunrealtype e2 = SUNMAX(SODERLIND_EP(C), TINY); + const sunrealtype e3 = SUNMAX(SODERLIND_EPP(C), TINY); + const sunrealtype hrat = h / SODERLIND_HP(C); + const sunrealtype hrat2 = SODERLIND_HP(C) / SODERLIND_HPP(C); + + /* compute estimated optimal time step size */ + if (SODERLIND_FIRSTSTEPS(C) < 1) { *hnew = h * SUNRpowerR(e1, k1); } + else if (SODERLIND_FIRSTSTEPS(C) < 2) + { + *hnew = h * SUNRpowerR(e1, k1) * SUNRpowerR(e2, k2) * SUNRpowerR(hrat, k4); + } + else + { + *hnew = h * SUNRpowerR(e1, k1) * SUNRpowerR(e2, k2) * SUNRpowerR(e3, k3) * + SUNRpowerR(hrat, k4) * SUNRpowerR(hrat2, k5); + } + + /* return with success */ + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Reset_Soderlind(SUNAdaptController C) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_EP(C) = SUN_RCONST(1.0); + SODERLIND_EPP(C) = SUN_RCONST(1.0); + SODERLIND_HP(C) = SUN_RCONST(1.0); + SODERLIND_HPP(C) = SUN_RCONST(1.0); + SODERLIND_FIRSTSTEPS(C) = 0; + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_SetDefaults_Soderlind(SUNAdaptController C) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_K1(C) = DEFAULT_K1; + SODERLIND_K2(C) = DEFAULT_K2; + SODERLIND_K3(C) = DEFAULT_K3; + SODERLIND_K4(C) = DEFAULT_K4; + SODERLIND_K5(C) = DEFAULT_K5; + SODERLIND_BIAS(C) = DEFAULT_BIAS; + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Write_Soderlind(SUNAdaptController C, FILE* fptr) +{ + SUNFunctionBegin(C->sunctx); + SUNAssert(fptr, SUN_ERR_ARG_CORRUPT); + fprintf(fptr, "Soderlind SUNAdaptController module:\n"); +#if defined(SUNDIALS_EXTENDED_PRECISION) + fprintf(fptr, " k1 = %32Lg\n", SODERLIND_K1(C)); + fprintf(fptr, " k2 = %32Lg\n", SODERLIND_K2(C)); + fprintf(fptr, " k3 = %32Lg\n", SODERLIND_K3(C)); + fprintf(fptr, " k4 = %32Lg\n", SODERLIND_K4(C)); + fprintf(fptr, " k5 = %32Lg\n", SODERLIND_K5(C)); + fprintf(fptr, " bias factor = %22Lg\n", SODERLIND_BIAS(C)); + fprintf(fptr, " previous error = %22Lg\n", SODERLIND_EP(C)); + fprintf(fptr, " previous-previous error = %22Lg\n", SODERLIND_EPP(C)); + fprintf(fptr, " previous step = %22Lg\n", SODERLIND_HP(C)); + fprintf(fptr, " previous-previous step = %22Lg\n", SODERLIND_HPP(C)); +#else + fprintf(fptr, " k1 = %16g\n", SODERLIND_K1(C)); + fprintf(fptr, " k2 = %16g\n", SODERLIND_K2(C)); + fprintf(fptr, " k3 = %16g\n", SODERLIND_K3(C)); + fprintf(fptr, " k4 = %16g\n", SODERLIND_K4(C)); + fprintf(fptr, " k5 = %16g\n", SODERLIND_K5(C)); + fprintf(fptr, " bias factor = %16g\n", SODERLIND_BIAS(C)); + fprintf(fptr, " previous error = %16g\n", SODERLIND_EP(C)); + fprintf(fptr, " previous-previous error = %16g\n", SODERLIND_EPP(C)); + fprintf(fptr, " previous step = %16g\n", SODERLIND_HP(C)); + fprintf(fptr, " previous-previous step = %16g\n", SODERLIND_HPP(C)); +#endif + fprintf(fptr, " firststeps = %i\n", SODERLIND_FIRSTSTEPS(C)); + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_SetErrorBias_Soderlind(SUNAdaptController C, + sunrealtype bias) +{ + SUNFunctionBegin(C->sunctx); + + /* set allowed value, otherwise set default */ + if (bias <= SUN_RCONST(0.0)) { SODERLIND_BIAS(C) = DEFAULT_BIAS; } + else { SODERLIND_BIAS(C) = bias; } + + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_UpdateH_Soderlind(SUNAdaptController C, + sunrealtype h, sunrealtype dsm) +{ + SUNFunctionBegin(C->sunctx); + SODERLIND_EPP(C) = SODERLIND_EP(C); + SODERLIND_EP(C) = SODERLIND_BIAS(C) * dsm; + SODERLIND_HPP(C) = SODERLIND_HP(C); + SODERLIND_HP(C) = h; + if (SODERLIND_FIRSTSTEPS(C) < 2) { SODERLIND_FIRSTSTEPS(C) += 1; } + return SUN_SUCCESS; +} + +SUNErrCode SUNAdaptController_Space_Soderlind(SUNAdaptController C, + long int* lenrw, long int* leniw) +{ + SUNFunctionBegin(C->sunctx); + SUNAssert(lenrw, SUN_ERR_ARG_CORRUPT); + SUNAssert(leniw, SUN_ERR_ARG_CORRUPT); + *lenrw = 10; + *leniw = 1; + return SUN_SUCCESS; +} diff --git a/ThirdParty/sundials/src/sundials/sundials_adaptcontroller.c b/ThirdParty/sundials/src/sundials/sundials_adaptcontroller.c new file mode 100644 index 0000000000..39a56480d0 --- /dev/null +++ b/ThirdParty/sundials/src/sundials/sundials_adaptcontroller.c @@ -0,0 +1,199 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Daniel R. Reynolds @ SMU + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * This is the implementation file for a generic SUNAdaptController + * package. It contains the implementation of the SUNAdaptController + * operations listed in sundials_adaptcontroller.h + * -----------------------------------------------------------------*/ + +#include +#include + +#include "sundials/sundials_errors.h" + +/* ----------------------------------------------------------------- + * Create a new empty SUNAdaptController object + * ----------------------------------------------------------------- */ + +SUNAdaptController SUNAdaptController_NewEmpty(SUNContext sunctx) +{ + SUNAdaptController C; + SUNAdaptController_Ops ops; + + /* a context is required */ + if (sunctx == NULL) { return (NULL); } + + SUNFunctionBegin(sunctx); + + /* create controller object */ + C = NULL; + C = (SUNAdaptController)malloc(sizeof *C); + SUNAssertNull(C, SUN_ERR_MALLOC_FAIL); + + /* create matrix ops structure */ + ops = NULL; + ops = (SUNAdaptController_Ops)malloc(sizeof *ops); + SUNAssertNull(ops, SUN_ERR_MALLOC_FAIL); + + /* initialize operations to NULL */ + ops->gettype = NULL; + ops->destroy = NULL; + ops->reset = NULL; + ops->estimatestep = NULL; + ops->setdefaults = NULL; + ops->write = NULL; + ops->seterrorbias = NULL; + ops->updateh = NULL; + ops->space = NULL; + + /* attach ops and initialize content to NULL */ + C->ops = ops; + C->content = NULL; + C->sunctx = sunctx; + + return (C); +} + +/* ----------------------------------------------------------------- + * Free a generic SUNAdaptController (assumes content is already empty) + * ----------------------------------------------------------------- */ + +void SUNAdaptController_DestroyEmpty(SUNAdaptController C) +{ + if (C == NULL) { return; } + + /* free non-NULL ops structure */ + if (C->ops) { free(C->ops); } + C->ops = NULL; + + /* free overall SUNAdaptController object and return */ + free(C); + return; +} + +/* ----------------------------------------------------------------- + * Required functions in the 'ops' structure for non-NULL controller + * ----------------------------------------------------------------- */ + +SUNAdaptController_Type SUNAdaptController_GetType(SUNAdaptController C) +{ + if (C == NULL) { return SUN_ADAPTCONTROLLER_NONE; } + if (C->ops->gettype) { return C->ops->gettype(C); } + return SUN_ADAPTCONTROLLER_NONE; +} + +/* ----------------------------------------------------------------- + * Optional functions in the 'ops' structure + * ----------------------------------------------------------------- */ + +SUNErrCode SUNAdaptController_Destroy(SUNAdaptController C) +{ + if (C == NULL) { return (SUN_SUCCESS); } + + /* if the destroy operation exists use it */ + if (C->ops) + { + if (C->ops->destroy) { return (C->ops->destroy(C)); } + } + + /* if we reach this point, either ops == NULL or destroy == NULL, + try to cleanup by freeing the content, ops, and matrix */ + if (C->content) + { + free(C->content); + C->content = NULL; + } + if (C->ops) + { + free(C->ops); + C->ops = NULL; + } + free(C); + C = NULL; + + return (SUN_SUCCESS); +} + +SUNErrCode SUNAdaptController_EstimateStep(SUNAdaptController C, sunrealtype h, + int p, sunrealtype dsm, + sunrealtype* hnew) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + SUNAssert(hnew, SUN_ERR_ARG_CORRUPT); + *hnew = h; /* initialize output with identity */ + if (C->ops->estimatestep) { ier = C->ops->estimatestep(C, h, p, dsm, hnew); } + return (ier); +} + +SUNErrCode SUNAdaptController_Reset(SUNAdaptController C) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + if (C->ops->reset) { ier = C->ops->reset(C); } + return (ier); +} + +SUNErrCode SUNAdaptController_SetDefaults(SUNAdaptController C) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + if (C->ops->setdefaults) { ier = C->ops->setdefaults(C); } + return (ier); +} + +SUNErrCode SUNAdaptController_Write(SUNAdaptController C, FILE* fptr) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + SUNAssert(fptr, SUN_ERR_ARG_CORRUPT); + if (C->ops->write) { ier = C->ops->write(C, fptr); } + return (ier); +} + +SUNErrCode SUNAdaptController_SetErrorBias(SUNAdaptController C, sunrealtype bias) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + if (C->ops->seterrorbias) { ier = C->ops->seterrorbias(C, bias); } + return (ier); +} + +SUNErrCode SUNAdaptController_UpdateH(SUNAdaptController C, sunrealtype h, + sunrealtype dsm) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + if (C->ops->updateh) { ier = C->ops->updateh(C, h, dsm); } + return (ier); +} + +SUNErrCode SUNAdaptController_Space(SUNAdaptController C, long int* lenrw, + long int* leniw) +{ + SUNErrCode ier = SUN_SUCCESS; + if (C == NULL) { return SUN_ERR_ARG_CORRUPT; } + SUNFunctionBegin(C->sunctx); + SUNAssert(lenrw, SUN_ERR_ARG_CORRUPT); + SUNAssert(leniw, SUN_ERR_ARG_CORRUPT); + *lenrw = 0; /* initialize outputs with identity */ + *leniw = 0; + if (C->ops->space) { ier = C->ops->space(C, lenrw, leniw); } + return (ier); +} diff --git a/ThirdParty/sundials/src/sundials/sundials_context.c b/ThirdParty/sundials/src/sundials/sundials_context.c new file mode 100644 index 0000000000..86b0a49c34 --- /dev/null +++ b/ThirdParty/sundials/src/sundials/sundials_context.c @@ -0,0 +1,299 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * SUNDIALS context class. A context object holds data that all + * SUNDIALS objects in a simulation share. + * ----------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "sundials_adiak_metadata.h" +#include "sundials_macros.h" + +SUNErrCode SUNContext_Create(SUNComm comm, SUNContext* sunctx_out) +{ + SUNErrCode err = SUN_SUCCESS; + SUNProfiler profiler = NULL; + SUNLogger logger = NULL; + SUNContext sunctx = NULL; + SUNErrHandler eh = NULL; + + *sunctx_out = NULL; + sunctx = (SUNContext)malloc(sizeof(struct SUNContext_)); + + /* SUNContext_Create cannot assert or log since the SUNContext is not yet + * created */ + if (!sunctx) { return SUN_ERR_MALLOC_FAIL; } + + SUNFunctionBegin(sunctx); + +#ifdef SUNDIALS_ADIAK_ENABLED + adiak_init(&comm); + sunAdiakCollectMetadata(); +#endif + + do { +#if SUNDIALS_LOGGING_LEVEL > 0 +#if SUNDIALS_MPI_ENABLED + err = SUNLogger_CreateFromEnv(comm, &logger); + SUNCheckCallNoRet(err); + if (err) { break; } +#else + err = SUNLogger_CreateFromEnv(SUN_COMM_NULL, &logger); + SUNCheckCallNoRet(err); + if (err) { break; } +#endif +#else + err = SUNLogger_Create(SUN_COMM_NULL, 0, &logger); + SUNCheckCallNoRet(err); + if (err) { break; } + err = SUNLogger_SetErrorFilename(logger, ""); + SUNCheckCallNoRet(err); + if (err) { break; } + err = SUNLogger_SetWarningFilename(logger, ""); + SUNCheckCallNoRet(err); + if (err) { break; } + err = SUNLogger_SetInfoFilename(logger, ""); + SUNCheckCallNoRet(err); + if (err) { break; } + err = SUNLogger_SetDebugFilename(logger, ""); + SUNCheckCallNoRet(err); + if (err) { break; } +#endif + +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && !defined(SUNDIALS_CALIPER_ENABLED) + err = SUNProfiler_Create(comm, "SUNContext Default", &profiler); + SUNCheckCallNoRet(err); + if (err) { break; } +#endif + + err = SUNErrHandler_Create(SUNLogErrHandlerFn, NULL, &eh); + SUNCheckCallNoRet(err); + if (err) { break; } + + sunctx->logger = logger; + sunctx->own_logger = logger != NULL; + sunctx->profiler = profiler; + sunctx->own_profiler = profiler != NULL; + sunctx->last_err = SUN_SUCCESS; + sunctx->err_handler = eh; + sunctx->comm = comm; + } + while (0); + + if (err) + { +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && !defined(SUNDIALS_CALIPER_ENABLED) + SUNCheckCallNoRet(SUNProfiler_Free(&profiler)); +#endif + SUNCheckCallNoRet(SUNLogger_Destroy(&logger)); + free(sunctx); + } + else { *sunctx_out = sunctx; } + + return err; +} + +SUNErrCode SUNContext_GetLastError(SUNContext sunctx) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + SUNErrCode err = sunctx->last_err; + sunctx->last_err = SUN_SUCCESS; + return err; +} + +SUNErrCode SUNContext_PeekLastError(SUNContext sunctx) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + return sunctx->last_err; +} + +SUNErrCode SUNContext_PushErrHandler(SUNContext sunctx, SUNErrHandlerFn err_fn, + void* err_user_data) +{ + if (!sunctx || !err_fn) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + SUNErrHandler new_err_handler = NULL; + if (SUNErrHandler_Create(err_fn, err_user_data, &new_err_handler)) + { + return SUN_ERR_CORRUPT; + } + new_err_handler->previous = sunctx->err_handler; + sunctx->err_handler = new_err_handler; + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_PopErrHandler(SUNContext sunctx) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + if (sunctx->err_handler) + { + SUNErrHandler eh = sunctx->err_handler; + if (sunctx->err_handler->previous) + { + sunctx->err_handler = sunctx->err_handler->previous; + } + else { sunctx->err_handler = NULL; } + SUNErrHandler_Destroy(&eh); + } + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_ClearErrHandlers(SUNContext sunctx) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + while (sunctx->err_handler != NULL) + { + SUNCheckCall(SUNContext_PopErrHandler(sunctx)); + } + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_GetProfiler(SUNContext sunctx, SUNProfiler* profiler) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + +#ifdef SUNDIALS_BUILD_WITH_PROFILING + /* get profiler */ + *profiler = sunctx->profiler; +#else + *profiler = NULL; +#endif + + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_SetProfiler(SUNContext sunctx, SUNProfiler profiler) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + +#ifdef SUNDIALS_BUILD_WITH_PROFILING + /* free any existing profiler */ + if (sunctx->profiler && sunctx->own_profiler) + { + SUNCheckCall(SUNProfiler_Free(&(sunctx->profiler))); + sunctx->profiler = NULL; + } + + /* set profiler */ + sunctx->profiler = profiler; + sunctx->own_profiler = SUNFALSE; +#else + /* silence warnings when profiling is disabled */ + ((void)profiler); +#endif + + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_GetLogger(SUNContext sunctx, SUNLogger* logger) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + + /* get logger */ + *logger = sunctx->logger; + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_SetLogger(SUNContext sunctx, SUNLogger logger) +{ + if (!sunctx) { return SUN_ERR_SUNCTX_CORRUPT; } + + SUNFunctionBegin(sunctx); + + /* free any existing logger */ + if (sunctx->logger && sunctx->own_logger) + { + if (SUNLogger_Destroy(&(sunctx->logger))) { return SUN_ERR_DESTROY_FAIL; } + sunctx->logger = NULL; + } + + /* set logger */ + sunctx->logger = logger; + sunctx->own_logger = SUNFALSE; + + return SUN_SUCCESS; +} + +SUNErrCode SUNContext_Free(SUNContext* sunctx) +{ +#ifdef SUNDIALS_ADIAK_ENABLED + adiak_fini(); +#endif + + if (!sunctx || !(*sunctx)) { return SUN_SUCCESS; } + +#if defined(SUNDIALS_BUILD_WITH_PROFILING) && !defined(SUNDIALS_CALIPER_ENABLED) + /* Find out where we are printing to */ + FILE* fp = NULL; + char* sunprofiler_print_env = getenv("SUNPROFILER_PRINT"); + fp = NULL; + if (sunprofiler_print_env) + { + if (!strcmp(sunprofiler_print_env, "0")) { fp = NULL; } + else if (!strcmp(sunprofiler_print_env, "1") || + !strcmp(sunprofiler_print_env, "TRUE") || + !strcmp(sunprofiler_print_env, "stdout")) + { + fp = stdout; + } + else { fp = fopen(sunprofiler_print_env, "a"); } + } + + /* Enforce that the profiler is freed before finalizing, + if it is not owned by the sunctx. */ + if ((*sunctx)->profiler) + { + if (fp) { SUNProfiler_Print((*sunctx)->profiler, fp); } + if (fp) { fclose(fp); } + if ((*sunctx)->own_profiler) { SUNProfiler_Free(&(*sunctx)->profiler); } + } +#endif + + if ((*sunctx)->logger && (*sunctx)->own_logger) + { + SUNLogger_Destroy(&(*sunctx)->logger); + } + + SUNContext_ClearErrHandlers(*sunctx); + + free(*sunctx); + *sunctx = NULL; + + return SUN_SUCCESS; +} diff --git a/ThirdParty/sundials/src/sundials/sundials_errors.c b/ThirdParty/sundials/src/sundials/sundials_errors.c new file mode 100644 index 0000000000..acc3a0e5bc --- /dev/null +++ b/ThirdParty/sundials/src/sundials/sundials_errors.c @@ -0,0 +1,116 @@ +/* ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sundials_logger_impl.h" +#include "sundials_macros.h" +#include "sundials_utils.h" + +SUNErrCode SUNErrHandler_Create(SUNErrHandlerFn eh_fn, void* eh_data, + SUNErrHandler* eh_out) +{ + SUNErrHandler eh = NULL; + + eh = (SUNErrHandler)malloc(sizeof(struct SUNErrHandler_)); + if (!eh) { return SUN_ERR_MALLOC_FAIL; } + + eh->previous = NULL; + eh->call = eh_fn; + eh->data = eh_data; + + *eh_out = eh; + return SUN_SUCCESS; +} + +void SUNErrHandler_Destroy(SUNErrHandler* eh) +{ + if (!eh || !(*eh)) { return; } + free(*eh); + *eh = NULL; +} + +const char* SUNGetErrMsg(SUNErrCode code) +{ +#define SUN_EXPAND_TO_CASES(name, description) \ + case name: return description; break; + + switch (code) + { + SUN_ERR_CODE_LIST(SUN_EXPAND_TO_CASES) + default: return "unknown error"; + } + + return NULL; +} + +void SUNLogErrHandlerFn(int line, const char* func, const char* file, + const char* msg, SUNErrCode err_code, + SUNDIALS_MAYBE_UNUSED void* err_user_data, + SUNContext sunctx) +{ + char* file_and_line = sunCombineFileAndLine(line, file); + if (msg == NULL) { msg = SUNGetErrMsg(err_code); } + SUNLogger_QueueMsg(sunctx->logger, SUN_LOGLEVEL_ERROR, file_and_line, func, + msg); + free(file_and_line); +} + +void SUNAbortErrHandlerFn(int line, const char* func, const char* file, + SUNDIALS_MAYBE_UNUSED const char* msg, + SUNDIALS_MAYBE_UNUSED SUNErrCode err_code, + SUNDIALS_MAYBE_UNUSED void* err_user_data, + SUNContext sunctx) +{ + char* file_and_line = sunCombineFileAndLine(line, file); + SUNLogger_QueueMsg(sunctx->logger, SUN_LOGLEVEL_ERROR, file_and_line, func, + "SUNAbortErrHandler: Calling abort now, use a different " + "error handler to avoid program termination.\n"); + free(file_and_line); + abort(); +} + +void SUNGlobalFallbackErrHandler(int line, const char* func, const char* file, + const char* msgfmt, SUNErrCode err_code, ...) +{ + va_list ap; + char* log_msg = NULL; + char* file_and_line = NULL; + + va_start(ap, err_code); + + file_and_line = sunCombineFileAndLine(__LINE__, __FILE__); + sunCreateLogMessage(SUN_LOGLEVEL_ERROR, 0, file_and_line, + __func__, "The SUNDIALS SUNContext was corrupt or NULL when an error occurred. As such, error messages have been printed to stderr.", + ap, &log_msg); + fprintf(stderr, "%s", log_msg); + free(log_msg); + free(file_and_line); + + file_and_line = sunCombineFileAndLine(line, file); + if (msgfmt == NULL) { msgfmt = SUNGetErrMsg(err_code); } + sunCreateLogMessage(SUN_LOGLEVEL_ERROR, 0, file_and_line, func, msgfmt, ap, + &log_msg); + fprintf(stderr, "%s", log_msg); + free(log_msg); + free(file_and_line); + + va_end(ap); +} diff --git a/ThirdParty/sundials/src/sundials/sundials_logger.c b/ThirdParty/sundials/src/sundials/sundials_logger.c new file mode 100644 index 0000000000..bc4d6869ae --- /dev/null +++ b/ThirdParty/sundials/src/sundials/sundials_logger.c @@ -0,0 +1,474 @@ +/* ----------------------------------------------------------------- + * Programmer: Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * -----------------------------------------------------------------*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if SUNDIALS_MPI_ENABLED +#include +#endif + +#include "sundials_logger_impl.h" +#include "sundials_macros.h" +#include "sundials_utils.h" + +/* max number of files that can be opened */ +#define SUN_MAX_LOGFILE_HANDLES_ 8 + +void sunCreateLogMessage(SUNLogLevel lvl, int rank, const char* scope, + const char* label, const char* txt, va_list args, + char** log_msg) +{ + char* prefix; + char* formatted_txt; + int msg_length; + + prefix = NULL; + formatted_txt = NULL; + msg_length = 0; + *log_msg = NULL; + + msg_length = sunvasnprintf(&formatted_txt, txt, args); + if (msg_length < 0) + { + fprintf(stderr, "[FATAL LOGGER ERROR] %s\n", "message size too large"); + } + + if (lvl == SUN_LOGLEVEL_DEBUG) { prefix = (char*)"DEBUG"; } + else if (lvl == SUN_LOGLEVEL_WARNING) { prefix = (char*)"WARNING"; } + else if (lvl == SUN_LOGLEVEL_INFO) { prefix = (char*)"INFO"; } + else if (lvl == SUN_LOGLEVEL_ERROR) { prefix = (char*)"ERROR"; } + + msg_length = sunsnprintf(NULL, 0, "[%s][rank %d][%s][%s] %s\n", prefix, rank, + scope, label, formatted_txt); + *log_msg = (char*)malloc(msg_length + 1); + sunsnprintf(*log_msg, msg_length + 1, "[%s][rank %d][%s][%s] %s\n", prefix, + rank, scope, label, formatted_txt); + free(formatted_txt); +} + +#if SUNDIALS_LOGGING_LEVEL > 0 +static FILE* sunOpenLogFile(const char* fname, const char* mode) +{ + FILE* fp = NULL; + + if (fname) + { + if (!strcmp(fname, "stdout")) { fp = stdout; } + else if (!strcmp(fname, "stderr")) { fp = stderr; } + else { fp = fopen(fname, mode); } + } + + return fp; +} +#endif + +static void sunCloseLogFile(void* fp) +{ + if (fp && fp != stdout && fp != stderr) { fclose((FILE*)fp); } +} + +static sunbooleantype sunLoggerIsOutputRank(SUNDIALS_MAYBE_UNUSED SUNLogger logger, + int* rank_ref) +{ + sunbooleantype retval; + +#if SUNDIALS_MPI_ENABLED + int rank = 0; + + if (logger->comm != SUN_COMM_NULL) + { + MPI_Comm_rank(logger->comm, &rank); + + if (logger->output_rank < 0) + { + if (rank_ref) { *rank_ref = rank; } + retval = SUNTRUE; /* output all ranks */ + } + else + { + if (rank_ref) { *rank_ref = rank; } + retval = logger->output_rank == rank; + } + } + else { retval = SUNTRUE; /* output all ranks */ } +#else + if (rank_ref) { *rank_ref = 0; } + retval = SUNTRUE; +#endif + + return retval; +} + +SUNErrCode SUNLogger_Create(SUNComm comm, int output_rank, SUNLogger* logger_ptr) +{ + SUNLogger logger = NULL; + + *logger_ptr = logger = (SUNLogger)malloc(sizeof(struct SUNLogger_)); + if (logger == NULL) { return SUN_ERR_MALLOC_FAIL; } + + /* Attach the comm, duplicating it if MPI is used. */ +#if SUNDIALS_MPI_ENABLED + logger->comm = SUN_COMM_NULL; + if (comm != SUN_COMM_NULL) { MPI_Comm_dup(comm, &logger->comm); } +#else + logger->comm = SUN_COMM_NULL; + if (comm != SUN_COMM_NULL) + { + free(logger); + return SUN_ERR_ARG_CORRUPT; + } +#endif + logger->output_rank = output_rank; + logger->content = NULL; + + /* use default routines */ + logger->queuemsg = NULL; + logger->flush = NULL; + logger->destroy = NULL; + + /* set the output file handles */ + logger->filenames = NULL; + logger->error_fp = stderr; + logger->warning_fp = stdout; + logger->debug_fp = NULL; + logger->info_fp = NULL; + if (sunLoggerIsOutputRank(logger, NULL)) + { + /* We store the FILE* in a hash map so that we can ensure + that we do not open a file twice if the same file is used + for multiple output levels */ + SUNHashMap_New(SUN_MAX_LOGFILE_HANDLES_, &logger->filenames); + } + + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_CreateFromEnv(SUNComm comm, SUNLogger* logger_out) +{ + SUNErrCode err = SUN_SUCCESS; + SUNLogger logger = NULL; + + const char* output_rank_env = getenv("SUNLOGGER_OUTPUT_RANK"); + int output_rank = (output_rank_env) ? atoi(output_rank_env) : 0; + const char* error_fname_env = getenv("SUNLOGGER_ERROR_FILENAME"); + const char* warning_fname_env = getenv("SUNLOGGER_WARNING_FILENAME"); + const char* info_fname_env = getenv("SUNLOGGER_INFO_FILENAME"); + const char* debug_fname_env = getenv("SUNLOGGER_DEBUG_FILENAME"); + + if (SUNLogger_Create(comm, output_rank, &logger)) + { + err = SUN_ERR_CORRUPT; + return err; + } + + do { + err = SUNLogger_SetErrorFilename(logger, error_fname_env); + if (err) { break; } + err = SUNLogger_SetWarningFilename(logger, warning_fname_env); + if (err) { break; } + err = SUNLogger_SetDebugFilename(logger, debug_fname_env); + if (err) { break; } + err = SUNLogger_SetInfoFilename(logger, info_fname_env); + } + while (0); + + if (err) { SUNLogger_Destroy(&logger); } + else { *logger_out = logger; } + + return err; +} + +SUNErrCode SUNLogger_SetErrorFilename(SUNLogger logger, const char* error_filename) +{ + if (!logger) { return SUN_ERR_ARG_CORRUPT; } + + if (!sunLoggerIsOutputRank(logger, NULL)) { return SUN_SUCCESS; } + + if (error_filename && strcmp(error_filename, "")) + { +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_ERROR + FILE* fp = NULL; + if (!SUNHashMap_GetValue(logger->filenames, error_filename, (void*)&fp)) + { + logger->error_fp = fp; + } + else + { + logger->error_fp = sunOpenLogFile(error_filename, "w+"); + if (logger->error_fp) + { + SUNHashMap_Insert(logger->filenames, error_filename, + (void*)logger->error_fp); + } + else { return SUN_ERR_FILE_OPEN; } + } +#endif + } + + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_SetWarningFilename(SUNLogger logger, + const char* warning_filename) +{ + if (!logger) { return SUN_ERR_ARG_CORRUPT; } + + if (!sunLoggerIsOutputRank(logger, NULL)) { return SUN_SUCCESS; } + + if (warning_filename && strcmp(warning_filename, "")) + { +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_WARNING + FILE* fp = NULL; + if (!SUNHashMap_GetValue(logger->filenames, warning_filename, (void*)&fp)) + { + logger->warning_fp = fp; + } + else + { + logger->warning_fp = sunOpenLogFile(warning_filename, "w+"); + if (logger->warning_fp) + { + SUNHashMap_Insert(logger->filenames, warning_filename, + (void*)logger->warning_fp); + } + else { return SUN_ERR_FILE_OPEN; } + } +#endif + } + + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_SetInfoFilename(SUNLogger logger, const char* info_filename) +{ + if (!logger) { return SUN_ERR_ARG_CORRUPT; } + + if (!sunLoggerIsOutputRank(logger, NULL)) { return SUN_SUCCESS; } + + if (info_filename && strcmp(info_filename, "")) + { +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_INFO + FILE* fp = NULL; + if (!SUNHashMap_GetValue(logger->filenames, info_filename, (void*)&fp)) + { + logger->info_fp = fp; + } + else + { + logger->info_fp = sunOpenLogFile(info_filename, "w+"); + if (logger->info_fp) + { + SUNHashMap_Insert(logger->filenames, info_filename, + (void*)logger->info_fp); + } + else { return SUN_ERR_FILE_OPEN; } + } +#endif + } + + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_SetDebugFilename(SUNLogger logger, const char* debug_filename) +{ + if (!logger) { return SUN_ERR_ARG_CORRUPT; } + + if (!sunLoggerIsOutputRank(logger, NULL)) { return SUN_SUCCESS; } + + if (debug_filename && strcmp(debug_filename, "")) + { +#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG + FILE* fp = NULL; + if (!SUNHashMap_GetValue(logger->filenames, debug_filename, (void*)&fp)) + { + logger->debug_fp = fp; + } + else + { + logger->debug_fp = sunOpenLogFile(debug_filename, "w+"); + if (logger->debug_fp) + { + SUNHashMap_Insert(logger->filenames, debug_filename, + (void*)logger->debug_fp); + } + else { return SUN_ERR_FILE_OPEN; } + } +#endif + } + + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_QueueMsg(SUNLogger logger, SUNLogLevel lvl, + const char* scope, const char* label, + const char* msg_txt, ...) +{ + SUNErrCode retval = SUN_SUCCESS; + +#if SUNDIALS_LOGGING_LEVEL > 0 + { + if (!logger) + { + retval = SUN_ERR_ARG_CORRUPT; + return retval; + } + + va_list args; + va_start(args, msg_txt); + + if (logger->queuemsg) + { + retval = logger->queuemsg(logger, lvl, scope, label, msg_txt, args); + } + else + { + /* Default implementation */ + int rank = 0; + if (sunLoggerIsOutputRank(logger, &rank)) + { + char* log_msg = NULL; + sunCreateLogMessage(lvl, rank, scope, label, msg_txt, args, &log_msg); + + switch (lvl) + { + case (SUN_LOGLEVEL_DEBUG): + if (logger->debug_fp) { fprintf(logger->debug_fp, "%s", log_msg); } + break; + case (SUN_LOGLEVEL_WARNING): + if (logger->warning_fp) + { + fprintf(logger->warning_fp, "%s", log_msg); + } + break; + case (SUN_LOGLEVEL_INFO): + if (logger->info_fp) { fprintf(logger->info_fp, "%s", log_msg); } + break; + case (SUN_LOGLEVEL_ERROR): + if (logger->error_fp) { fprintf(logger->error_fp, "%s", log_msg); } + break; + default: retval = SUN_ERR_UNREACHABLE; + } + + free(log_msg); + } + } + + va_end(args); + } +#else + /* silence warnings when all logging is disabled */ + ((void)logger); + ((void)lvl); + ((void)scope); + ((void)label); + ((void)msg_txt); +#endif + + return retval; +} + +SUNErrCode SUNLogger_Flush(SUNLogger logger, SUNLogLevel lvl) +{ + SUNErrCode retval = SUN_SUCCESS; + + if (!logger) + { + retval = SUN_ERR_ARG_CORRUPT; + return retval; + } + +#if SUNDIALS_LOGGING_LEVEL > 0 + if (logger->flush) { retval = logger->flush(logger, lvl); } + else + { + /* Default implementation */ + if (sunLoggerIsOutputRank(logger, NULL)) + { + switch (lvl) + { + case (SUN_LOGLEVEL_DEBUG): + if (logger->debug_fp) { fflush(logger->debug_fp); } + break; + case (SUN_LOGLEVEL_WARNING): + if (logger->warning_fp) { fflush(logger->warning_fp); } + break; + case (SUN_LOGLEVEL_INFO): + if (logger->info_fp) { fflush(logger->info_fp); } + break; + case (SUN_LOGLEVEL_ERROR): + if (logger->error_fp) { fflush(logger->error_fp); } + break; + case (SUN_LOGLEVEL_ALL): + if (logger->debug_fp) { fflush(logger->debug_fp); } + if (logger->warning_fp) { fflush(logger->warning_fp); } + if (logger->info_fp) { fflush(logger->info_fp); } + if (logger->error_fp) { fflush(logger->error_fp); } + break; + default: retval = SUN_ERR_UNREACHABLE; + } + } + } +#else + /* silence warnings when all logging is disabled */ + ((void)lvl); +#endif + + return retval; +} + +SUNErrCode SUNLogger_GetOutputRank(SUNLogger logger, int* output_rank) +{ + if (!logger) { return SUN_ERR_ARG_CORRUPT; } + *output_rank = logger->output_rank; + return SUN_SUCCESS; +} + +SUNErrCode SUNLogger_Destroy(SUNLogger* logger_ptr) +{ + int retval = 0; + SUNLogger logger = NULL; + + if (!logger_ptr) { return SUN_SUCCESS; } + + logger = *logger_ptr; + + if (logger && logger->destroy) { retval = logger->destroy(logger_ptr); } + else if (logger) + { + /* Default implementation */ + + if (sunLoggerIsOutputRank(logger, NULL)) + { + SUNHashMap_Destroy(&logger->filenames, sunCloseLogFile); + } + +#if SUNDIALS_MPI_ENABLED + if (logger->comm != SUN_COMM_NULL) { MPI_Comm_free(&logger->comm); } +#endif + + free(logger); + logger = NULL; + } + + return retval; +} diff --git a/ThirdParty/sundials/src/sundials/sundials_logger_impl.h b/ThirdParty/sundials/src/sundials/sundials_logger_impl.h new file mode 100644 index 0000000000..6fbb7cac49 --- /dev/null +++ b/ThirdParty/sundials/src/sundials/sundials_logger_impl.h @@ -0,0 +1,84 @@ +/* ----------------------------------------------------------------- + * Programmer(s): Cody J. Balos @ LLNL + * ----------------------------------------------------------------- + * SUNDIALS Copyright Start + * Copyright (c) 2002-2024, Lawrence Livermore National Security + * and Southern Methodist University. + * All rights reserved. + * + * See the top-level LICENSE and NOTICE files for details. + * + * SPDX-License-Identifier: BSD-3-Clause + * SUNDIALS Copyright End + * ----------------------------------------------------------------- + * SUNDIALS logging class implementation. + * ----------------------------------------------------------------*/ + +#ifndef _SUNDIALS_LOGGER_IMPL_H +#define _SUNDIALS_LOGGER_IMPL_H + +#include +#include +#include + +#include "sundials_hashmap_impl.h" +#include "sundials_utils.h" + +#define SUNDIALS_LOGGING_ERROR 1 +#define SUNDIALS_LOGGING_WARNING 2 +#define SUNDIALS_LOGGING_INFO 3 +#define SUNDIALS_LOGGING_DEBUG 4 +#if SUNDIALS_LOGGING_LEVEL > SUNDIALS_LOGGING_DEBUG +#define SUNDIALS_LOGGING_EXTRA_DEBUG +#endif + +struct SUNLogger_ +{ + /* MPI information */ + SUNComm comm; + int output_rank; + + /* Ouput files */ + FILE* debug_fp; + FILE* warning_fp; + FILE* info_fp; + FILE* error_fp; + + /* Hashmap used to store filename, FILE* pairs */ + SUNHashMap filenames; + + /* Slic-style format string */ + const char* format; + + /* Content for custom implementations */ + void* content; + + /* Overridable operations */ + SUNErrCode (*queuemsg)(SUNLogger logger, SUNLogLevel lvl, const char* scope, + const char* label, const char* msg_txt, va_list args); + SUNErrCode (*flush)(SUNLogger logger, SUNLogLevel lvl); + SUNErrCode (*destroy)(SUNLogger* logger); +}; + +/* + This function creates a log message string in the correct format. + It allocates the log_msg parameter, which must be freed by the caller. + The format of the log message is: + + [ERROR][rank ][][