diff --git a/.github/workflows/test_pypi.yml b/.github/workflows/test_pypi.yml index da50ad7389..4b68180830 100644 --- a/.github/workflows/test_pypi.yml +++ b/.github/workflows/test_pypi.yml @@ -31,7 +31,11 @@ jobs: - name: homebrew run: | if [[ ${{ matrix.os }} == macos* ]] ; then \ - brew install hdf5 swig gcc libomp + brew install hdf5@1.10 swig gcc libomp \ + && echo "/usr/local/opt/hdf5@1.10/bin" >> $GITHUB_PATH \ + && echo LDFLAGS="-L/usr/local/lib/ -L/usr/local/opt/hdf5@1.10/lib" >> $GITHUB_ENV \ + && echo CPPFLAGS="-I/usr/local/opt/hdf5@1.10/include" >> $GITHUB_ENV \ + && echo HDF5_BASE="/usr/local/opt/hdf5@1.10/" >> $GITHUB_ENV fi - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/test_python_cplusplus.yml b/.github/workflows/test_python_cplusplus.yml index cb8da194a1..ac3a10fa76 100644 --- a/.github/workflows/test_python_cplusplus.yml +++ b/.github/workflows/test_python_cplusplus.yml @@ -152,7 +152,13 @@ jobs: # install amici dependencies - name: homebrew run: | - brew install hdf5 swig gcc cppcheck libomp boost + brew install hdf5@1.10 swig gcc cppcheck libomp boost \ + && brew ls -v boost \ + && brew ls -v libomp \ + && echo "/usr/local/opt/hdf5@1.10/bin" >> $GITHUB_PATH \ + && echo LDFLAGS="-L/usr/local/lib/ -L/usr/local/opt/hdf5@1.10/lib -L/usr/local/Cellar/boost/1.78.0_1/lib/" >> $GITHUB_ENV \ + && echo CPPFLAGS="-I/usr/local/opt/hdf5@1.10/include -I/usr/local/Cellar/boost/1.78.0_1/include/" >> $GITHUB_ENV \ + && echo HDF5_BASE="/usr/local/opt/hdf5@1.10/" >> $GITHUB_ENV - name: Build AMICI run: | diff --git a/.github/workflows/test_valgrind.yml b/.github/workflows/test_valgrind.yml index 17b39b5a24..5e63d84ee9 100644 --- a/.github/workflows/test_valgrind.yml +++ b/.github/workflows/test_valgrind.yml @@ -10,7 +10,7 @@ on: workflow_dispatch: jobs: - build: + valgrind: name: Tests Valgrind # TODO: prepare image with more deps preinstalled @@ -20,6 +20,9 @@ jobs: matrix: python-version: [ 3.8 ] + env: + ENABLE_AMICI_DEBUGGING: "TRUE" + steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 diff --git a/.gitignore b/.gitignore index cd75359839..6b0a18901b 100644 --- a/.gitignore +++ b/.gitignore @@ -136,6 +136,7 @@ tests/test/* */tests/fricker_2010_apoptosis_amici/* */tests/explicit_amici/* */tests/fixed_initial_amici/* +*/tests/localfunc_amici/* tests/cpp/writeResults.h5 tests/cpp/writeResults.h5.bak tests/sbml-test-suite/* @@ -191,6 +192,6 @@ tests/performance/CS_Signalling_ERBB_RAS_AKT/ tests/performance/CS_Signalling_ERBB_RAS_AKT_petab/* coverage_SBMLSuite.xml Benchmark-Models-PEtab/ - +/test_bmc/ CS_Signalling_ERBB_RAS_AKT/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 5adefb5033..207072c787 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ ## v0.X Series +### v0.11.26 (2022-03-14) + +New features: +* Import of BioNetGenLanguage (BNGL) models by @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1709 +* Added support for observable-dependent sigmas by @dweindl, @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1692 +* Added support for pysb local functions by @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1666 +* Added experimental support for conservation laws for non-constant species to + SBML import: conservation laws for non-constant species + by @stephanmg, @dweindl in https://github.com/AMICI-dev/AMICI/pull/1669 + Enable this feature by setting environment variable + `AMICI_EXPERIMENTAL_SBML_NONCONST_CLS` to any value + * Allow using states eliminated by conservation laws to be used in root + functions by @dweindl in https://github.com/AMICI-dev/AMICI/pull/1677 + * Added support for parameter-dependent conservation laws by @dweindl, + @FFroehlich in https://github.com/AMICI-dev/AMICI/pull/1678 +* Added optional caching for symbolic simplifications in ODE export by @dilpath + in https://github.com/AMICI-dev/AMICI/pull/1672 +* Added CLI option `--no-sensitivities` to `amici_import_petab` by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1688 + +Fixes: +* SBML import: Raise in case of nested observables by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1690 +* Sympy 1.10 compatibility by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1694 + +**Full Changelog**: https://github.com/AMICI-dev/AMICI/compare/v0.11.25...v0.11.26 + ### v0.11.25 (2022-02-09) * Fixed a bug diff --git a/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake b/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake deleted file mode 100644 index f7c04df036..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# --------------------------------------------------------------- -# Setup the CUDA languge and CUDA libraries. -# --------------------------------------------------------------- - -# =============================================================== -# Configure options needed prior to enabling the CUDA language -# =============================================================== - -if(NOT CMAKE_CUDA_HOST_COMPILER) - # If a user did not provide the host compiler, then we - # assume that they want to use the CXX compiler that was set. - set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} CACHE FILEPATH "NVCC host compiler") -endif() - -# =============================================================== -# Configure the CUDA flags -# =============================================================== - -set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-extended-lambda") - -if(${CMAKE_VERSION} VERSION_LESS "3.18.0") - if(CMAKE_CUDA_ARCHITECTURES) - foreach(arch ${CMAKE_CUDA_ARCHITECTURES}) - # Remove real/virtual specifiers - string(REGEX MATCH "[0-9]+" arch_name "${arch}") - string(APPEND _nvcc_arch_flags " -gencode=arch=compute_${arch_name},code=sm_${arch_name}") - endforeach() - - set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${_nvcc_arch_flags}") - endif() -endif() - -if( (CMAKE_CXX_COMPILER_ID MATCHES GNU) - OR (CMAKE_CXX_COMPILER_ID MATCHES Clang) - AND (CMAKE_SYSTEM_PROCESSOR MATCHES ppc64le) ) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-mno-float128 _hasflag) - if(_hasflag) - set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=-mno-float128") - endif() -endif() - -# Need c++11 for the CUDA compiler check. -set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -std=c++11") - -# =============================================================== -# Enable CUDA lang and find the CUDA libraries. -# =============================================================== - -enable_language(CUDA) -set(CUDA_FOUND TRUE) - -# Need this as long as CUDA libraries like cuSOLVER are not available -# through some other way. -find_package(CUDA REQUIRED) - -# Hide legacy FindCUDA variables -get_cmake_property(_variables VARIABLES) -foreach(_var ${_variables}) - if("${_var}" MATCHES "^CUDA_[A-z]+_LIBRARY") - # do nothing - elseif("${_var}" MATCHES "^CUDA_.*") - mark_as_advanced(${_var}) - endif() -endforeach() - -# Make the CUDA_rt_LIBRARY advanced like the other CUDA_*_LIBRARY variables -mark_as_advanced(FORCE CUDA_rt_LIBRARY) - -# Show CUDA flags -mark_as_advanced(CLEAR CMAKE_CUDA_FLAGS) - -# We need c++11 for the CUDA compiler check, but if we don't remove it, -# then we will get a redefinition error. CMAKE_CUDA_STANDARD ends up -# setting the proper version. -if(CMAKE_CUDA_FLAGS) - STRING(REPLACE "-std=c++11" " " CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS}) -endif() -set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD}) - -# =============================================================== -# Print out information about CUDA. -# =============================================================== - -message(STATUS "CUDA Version: ${CUDA_VERSION_STRING}") -message(STATUS "CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}") -message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}") -message(STATUS "CUDA Host Compiler: ${CMAKE_CUDA_HOST_COMPILER}") -message(STATUS "CUDA Include Path: ${CUDA_INCLUDE_DIRS}") -message(STATUS "CUDA Libraries: ${CUDA_LIBRARIES}") -message(STATUS "CUDA Compile Flags: ${CMAKE_CUDA_FLAGS}") -message(STATUS "CUDA Link Flags: ${CMAKE_CUDA_LINK_FLAGS}") -message(STATUS "CUDA Link Executable: ${CMAKE_CUDA_LINK_EXECUTABLE}") -message(STATUS "CUDA Separable Compilation: ${CMAKE_CUDA_SEPARABLE_COMPILATION}") diff --git a/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake b/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake deleted file mode 100644 index 06f388a831..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake +++ /dev/null @@ -1,339 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Radu Serban, David Gardner, Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# Module which enables Fortran and tests for support of necessary -# compiler features for the current SUNDIALS configuration. -# Will define the variables: -# Fortran_FOUND - TRUE if a Fortran compiler is found -# F77_FOUND - equivalent to Fortran_FOUND -# F90_FOUND - TRUE if the Fortran compiler supports Fortran 90 -# F2003_FOUND - TRUE if the Fortran compiler supports the -# Fortran 2003 standard -# --------------------------------------------------------------- - -# If the Fortran compiler flags are set using environemnt variables (i.e., -# CMAKE_Fortran_FLAGS is not set), then check if both FFLAGS and FCFLAGS are -# set. If both are set and not the same then a fatal error occurs. -# -# NOTE: This check must occur before 'enable_language(Fortran)' as it will use -# the value of FFLAGS to set CMAKE_Fortran_FLAGS -set(ENV_FFLAGS "$ENV{FFLAGS}") -set(ENV_FCFLAGS "$ENV{FCFLAGS}") - -# check if environment variables are used and CMAKE_Fortran_FLAGS is not -if ((NOT "${ENV_FFLAGS}" STREQUAL "") AND (NOT "${ENV_FCFLAGS}" STREQUAL "") - AND ("${CMAKE_Fortran_FLAGS}" STREQUAL "")) - - # check if environment variables are equal - if (NOT "${ENV_FFLAGS}" STREQUAL "${ENV_FCFLAGS}") - print_error("FFLAGS='${ENV_FFLAGS}' and FCFLAGS='${ENV_FCFLAGS}' are both set but are not equal.") - endif() -endif() - -# ----------------------------------------------------------------------------- -# Enable Fortran -# ----------------------------------------------------------------------------- -enable_language(Fortran) -set(Fortran_FOUND TRUE) -set(F77_FOUND TRUE) - -# ----------------------------------------------------------------------------- -# Check if Fortran 90 is supported -# ----------------------------------------------------------------------------- -if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - set(F90_FOUND TRUE) -else() - set(F90_FOUND FALSE) - print_warning("Fortran compiler does not support F90" "F90 support will not be provided") -endif() - -# ----------------------------------------------------------------------------- -# Check if Fortran 2003 is supported -# ----------------------------------------------------------------------------- -if(BUILD_FORTRAN_MODULE_INTERFACE) - if(NOT F2003_FOUND) - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003") - - set(F2003Test_DIR ${PROJECT_BINARY_DIR}/F2003Test_DIR) - file(MAKE_DIRECTORY ${F2003Test_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${F2003Test_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.1.3)\n" - "PROJECT(ftest Fortran)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_Fortran_COMPILER \"${CMAKE_Fortran_COMPILER}\")\n" - "SET(CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELEASE \"${CMAKE_Fortran_FLAGS_RELEASE}\")\n" - "SET(CMAKE_Fortran_FLAGS_DEBUG \"${CMAKE_Fortran_FLAGS_DEBUG}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO \"${CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_Fortran_FLAGS_MINSIZE \"${CMAKE_Fortran_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ftest ftest.f90)\n") - - # Create a Fortran source file which tries to use iso_c_binding - file(WRITE ${F2003Test_DIR}/ftest.f90 - "program main\n" - "use, intrinsic :: iso_c_binding\n" - "end program main\n") - - # Attempt compile the executable - try_compile(FTEST_OK ${F2003Test_DIR} ${F2003Test_DIR} - ftest OUTPUT_VARIABLE COMPILE_OUTPUT) - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${F2003Test_DIR}/CMakeFiles) - - if(FTEST_OK) - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003 -- yes") - set(F2003_FOUND TRUE CACHE BOOL "${CMAKE_Fortran_COMPILER} supports F2003" FORCE) - else() - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003 -- no") - message(STATUS "Check output:") - message("${COMPILE_OUTPUT}") - print_error("BUILD_FORTRAN_MODULE_INTERFACE is set to ON, but the CMAKE_Fortran_COMPILER does not support F2003") - endif() - else() - message(STATUS "Skipped F2003 tests, assuming ${CMAKE_Fortran_COMPILER} supports the f2003 standard. To rerun the F2003 tests, set F2003_FOUND to FALSE.") - endif() -endif() - -# Ensure that F90 compiler is found if F90 examples are enabled -if (EXAMPLES_ENABLE_F90 AND (NOT F90_FOUND)) - print_error("Compiler with F90 support not found" "Disabling F90 Examples") - set(DOCSTR "Build SUNDIALS F90 examples") - force_variable(EXAMPLES_ENABLE_F90 BOOL "${DOCSTR}" OFF) -endif() - -# Put all F2003 modules into one build directory -set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/fortran") - -# --------------------------------------------------------------- -# Determining the name-mangling scheme if needed -# --------------------------------------------------------------- -# In general, names of symbols with and without underscore may be mangled -# differently (e.g. g77 mangles mysub to mysub_ and my_sub to my_sub__), -# we have to consider both cases. -# -# Method: -# 1) create a library from a Fortran source file which defines a function "mysub" -# 2) attempt to link with this library a C source file which calls the "mysub" -# function using various possible schemes (6 different schemes, corresponding -# to all combinations lower/upper case and none/one/two underscores). -# 3) define the name-mangling scheme based on the test that was successful. -# -# On exit, if we were able to infer the scheme, the variables -# CMAKE_Fortran_SCHEME_NO_UNDERSCORES and CMAKE_Fortran_SCHEME_WITH_UNDERSCORES -# contain the mangled names for "mysub" and "my_sub", respectively. -# --------------------------------------------------------------- -if(NEED_FORTRAN_NAME_MANGLING) - - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES "") - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES "") - - # Create the FortranTest directory - set(FortranTest_DIR ${PROJECT_BINARY_DIR}/FortranTest) - file(MAKE_DIRECTORY ${FortranTest_DIR}) - - # Create a CMakeLists.txt file which will generate the "flib" library - # and an executable "ftest" - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ftest Fortran)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_Fortran_COMPILER \"${CMAKE_Fortran_COMPILER}\")\n" - "SET(CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELEASE \"${CMAKE_Fortran_FLAGS_RELEASE}\")\n" - "SET(CMAKE_Fortran_FLAGS_DEBUG \"${CMAKE_Fortran_FLAGS_DEBUG}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO \"${CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_Fortran_FLAGS_MINSIZE \"${CMAKE_Fortran_FLAGS_MINSIZE}\")\n" - "ADD_LIBRARY(flib flib.f)\n" - "ADD_EXECUTABLE(ftest ftest.f)\n" - "TARGET_LINK_LIBRARIES(ftest flib)\n") - - # Create the Fortran source flib.f which defines two subroutines, "mysub" and "my_sub" - file(WRITE ${FortranTest_DIR}/flib.f - " SUBROUTINE mysub\n" - " RETURN\n" - " END\n" - " SUBROUTINE my_sub\n" - " RETURN\n" - " END\n") - - # Create the Fortran source ftest.f which calls "mysub" and "my_sub" - file(WRITE ${FortranTest_DIR}/ftest.f - " PROGRAM ftest\n" - " CALL mysub()\n" - " CALL my_sub()\n" - " END\n") - - # Use TRY_COMPILE to make the targets "flib" and "ftest" - try_compile(FTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ftest OUTPUT_VARIABLE MY_OUTPUT) - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - - # Proceed based on test results - if(FTEST_OK) - - # Infer Fortran name-mangling scheme for symbols WITHOUT underscores. - # Overwrite CMakeLists.txt with one which will generate the "ctest1" executable - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ctest1 C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ctest1 ctest1.c)\n" - "FIND_LIBRARY(FLIB flib \"${FortranTest_DIR}\")\n" - "TARGET_LINK_LIBRARIES(ctest1 \${FLIB})\n") - - # Define the list "options" of all possible schemes that we want to consider - # Get its length and initialize the counter "iopt" to zero - set(options mysub mysub_ mysub__ MYSUB MYSUB_ MYSUB__) - list(LENGTH options imax) - set(iopt 0) - - # We will attempt to sucessfully generate the "ctest1" executable as long as - # there still are entries in the "options" list - while(${iopt} LESS ${imax}) - # Get the current list entry (current scheme) - list(GET options ${iopt} opt) - # Generate C source which calls the "mysub" function using the current scheme - file(WRITE ${FortranTest_DIR}/ctest1.c - "extern void ${opt}();\n" - "int main(){${opt}();return(0);}\n") - # Use TRY_COMPILE to make the "ctest1" executable from the current C source - # and linking to the previously created "flib" library. - try_compile(CTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ctest1 OUTPUT_VARIABLE MY_OUTPUT) - # Write output compiling the test code - file(WRITE ${FortranTest_DIR}/ctest1_${opt}.out "${MY_OUTPUT}") - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - # Test if we successfully created the "ctest" executable. - # If yes, save the current scheme, and set the counter "iopt" to "imax" - # so that we exit the while loop. - # Otherwise, increment the counter "iopt" and go back in the while loop. - if(CTEST_OK) - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES ${opt}) - set(iopt ${imax}) - else(CTEST_OK) - math(EXPR iopt ${iopt}+1) - endif() - endwhile(${iopt} LESS ${imax}) - - # Infer Fortran name-mangling scheme for symbols WITH underscores. - # Practically a duplicate of the previous steps. - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ctest2 C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ctest2 ctest2.c)\n" - "FIND_LIBRARY(FLIB flib ${FortranTest_DIR})\n" - "TARGET_LINK_LIBRARIES(ctest2 \${FLIB})\n") - - set(options my_sub my_sub_ my_sub__ MY_SUB MY_SUB_ MY_SUB__) - list(LENGTH options imax) - set(iopt 0) - while(${iopt} LESS ${imax}) - list(GET options ${iopt} opt) - file(WRITE ${FortranTest_DIR}/ctest2.c - "extern void ${opt}();\n" - "int main(){${opt}();return(0);}\n") - try_compile(CTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ctest2 OUTPUT_VARIABLE MY_OUTPUT) - file(WRITE ${FortranTest_DIR}/ctest2_${opt}.out "${MY_OUTPUT}") - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - if(CTEST_OK) - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES ${opt}) - set(iopt ${imax}) - else(CTEST_OK) - math(EXPR iopt ${iopt}+1) - endif() - endwhile(${iopt} LESS ${imax}) - - # If a name-mangling scheme was found set the C preprocessor macros to use - # that scheme. Otherwise default to lower case with one underscore. - if(CMAKE_Fortran_SCHEME_NO_UNDERSCORES AND CMAKE_Fortran_SCHEME_WITH_UNDERSCORES) - message(STATUS "Determining Fortran name-mangling scheme... OK") - else() - message(STATUS "Determining Fortran name-mangling scheme... DEFAULT") - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES "mysub_") - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES "my_sub_") - endif() - - # Symbols NO underscores - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub_") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## _") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub__") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## __") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB_") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## _") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB__") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## __") - endif() - - # Symbols WITH underscores - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub_") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## _") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub__") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## __") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB_") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## _") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB__") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## __") - endif() - - # name-mangling scheme has been set - set(NEED_FORTRAN_NAME_MANGLING FALSE) - else(FTEST_OK) - message(STATUS "Determining Fortran name-mangling scheme... FAILED") - endif() - -endif() \ No newline at end of file diff --git a/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake b/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake deleted file mode 100644 index f120080377..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# --------------------------------------------------------------- -# Setup the HIP language and libraries. -# --------------------------------------------------------------- - -if(NOT DEFINED ROCM_PATH) - if(NOT DEFINED ENV{ROCM_PATH}) - set(ROCM_PATH "/opt/rocm/" CACHE PATH "Path to which ROCm has been installed") - else() - set(ROCM_PATH "$ENV{ROCM_PATH}" CACHE PATH "Path to which ROCm has been installed") - endif() -endif() - -if(NOT DEFINED HIP_PATH) - if(NOT DEFINED ENV{HIP_PATH}) - set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to which HIP has been installed") - else() - set(HIP_PATH "$ENV{HIP_PATH}" CACHE PATH "Path to which HIP has been installed") - endif() -endif() - -if(NOT DEFINED HIP_PLATFORM) - if(NOT DEFINED ENV{HIP_PLATFORM}) - set(HIP_PLATFORM "hcc" CACHE STRING "HIP platform (hcc, nvcc)") - else() - set(HIP_PLATFORM "$ENV{HIP_PLATFORM}" CACHE STRING "HIP platform (hcc, nvcc)") - endif() -endif() - -# Set CMAKE_PREFIX_PATH as the hip-config.cmake has some find_package calls -# which don't have the proper path set (not sure if this is a bug or -# intentional), so without this they will fail even if we provide the PATH -# option to find_package(HIP). -set(CMAKE_PREFIX_PATH "${ROCM_PATH};${HIP_PATH}") -find_package(HIP REQUIRED) - -if("${HIP_COMPILER}" STREQUAL "hcc") - print_error("Deprecated HCC compiler is not supported" "Please update ROCm") -endif() - -message(STATUS "HIP version: ${HIP_VERSION}") -message(STATUS "HIP platform: ${HIP_PLATFORM}") -message(STATUS "HIP compiler: ${HIP_COMPILER}") -message(STATUS "HIP linker: ${CMAKE_CXX_LINK_EXECUTABLE}") -message(STATUS "AMD targets: ${AMDGPU_TARGETS}") diff --git a/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake b/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake deleted file mode 100644 index 168b8da621..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Eddy Banks, Slaven Peles, Cody J. Balos, and -# Jean Sexton @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# --------------------------------------------------------------- -# HYPRE find module that creates an imported target for HYPRE. -# The target is SUNDIALS::HYPRE. -# -# The variable HYPRE_LIBRARY_DIR can be used to control -# where the module looks for the library. -# -# The variable HYPRE_INCLUDE_DIR can be used to set the -# include path for the library. -# -# This module also defines variables, but it is best to use -# the defined target to ensure includes and compile/link -# options are correctly passed to consumers. -# -# HYPRE_FOUND - system has HYPRE library -# HYPRE_LIBRARY - the HYPRE library -# HYPRE_INCLUDE_DIR - the HYPRE include path -# HYPRE_LIBRARIES - all of the libraries needed for HYPRE -# --------------------------------------------------------------- - -### Find include dir -find_path(temp_HYPRE_INCLUDE_DIR hypre.h ${HYPRE_INCLUDE_DIR}) -if (temp_HYPRE_INCLUDE_DIR) - set(HYPRE_INCLUDE_DIR ${temp_HYPRE_INCLUDE_DIR}) -endif() -unset(temp_HYPRE_INCLUDE_DIR CACHE) - -if (HYPRE_LIBRARY) - # We have (or were given) HYPRE_LIBRARY - get path to use for any related libs - get_filename_component(HYPRE_LIBRARY_DIR ${HYPRE_LIBRARY} PATH) - - # force CACHE update to show user DIR that will be used - set(HYPRE_LIBRARY_DIR ${HYPRE_LIBRARY_DIR} CACHE PATH "" FORCE) -else () - # find library with user provided directory path - set(HYPRE_LIBRARY_NAMES hypre HYPRE) - find_library(HYPRE_LIBRARY - NAMES ${HYPRE_LIBRARY_NAMES} - PATHS ${HYPRE_LIBRARY_DIR} NO_DEFAULT_PATH - ) -endif () -mark_as_advanced(HYPRE_LIBRARY) - -list(FIND HYPRE_LIBRARIES ${HYPRE_LIBRARY} _idx) -if (_idx EQUAL -1) - set(HYPRE_LIBRARIES "${HYPRE_LIBRARY};${HYPRE_LIBRARIES}" CACHE STRING "" FORCE) -endif () - -# set a more informative error message in case the library was not found -set(HYPRE_NOT_FOUND_MESSAGE "\ -************************************************************************\n\ -ERROR: Could not find HYPRE. Please check the variables:\n\ - HYPRE_INCLUDE_DIR and HYPRE_LIBRARY_DIR\n\ -************************************************************************") - -# set package variables including HYPRE_FOUND -find_package_handle_standard_args(HYPRE - REQUIRED_VARS - HYPRE_LIBRARY - HYPRE_LIBRARIES - HYPRE_INCLUDE_DIR - FAIL_MESSAGE - "${HYPRE_NOT_FOUND_MESSAGE}" - ) - -# Create target for HYPRE -if(HYPRE_FOUND) - - if(NOT TARGET SUNDIALS::HYPRE) - add_library(SUNDIALS::HYPRE UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::HYPRE PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${HYPRE_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${HYPRE_LIBRARIES}" - IMPORTED_LOCATION "${HYPRE_LIBRARY}") - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake b/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake deleted file mode 100644 index c621b88204..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake +++ /dev/null @@ -1,111 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# ----------------------------------------------------------------------------- -# Find module that locates the MAGMA linear algebra library. -# ----------------------------------------------------------------------------- - -# find the MAGMA include path -find_path(MAGMA_INCLUDE_DIR magma_v2.h - NAMES magma_v2.h - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES include - NO_DEFAULT_PATH - DOC "Directory with MAGMA header" -) - -# find the main MAGMA library -find_library(MAGMA_LIBRARY - NAMES magma - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES lib lib64 - NO_DEFAULT_PATH - DOC "The MAGMA library.") - -# Find the optional sparse component -if("SPARSE" IN_LIST MAGMA_FIND_COMPONENTS) - set(_sparse_required MAGMA_SPARSE_LIBRARY) - find_library(MAGMA_SPARSE_LIBRARY - NAMES magma_sparse - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES lib lib64 - NO_DEFAULT_PATH - DOC "The MAGMA sparse library.") -else() - set(_sparse_required ) -endif() - -# Determine MAGMA version and libraries it depends on -if(MAGMA_LIBRARY AND MAGMA_INCLUDE_DIR) - get_filename_component(libdir ${MAGMA_LIBRARY} DIRECTORY) - find_file(MAGMA_PKG_CONFIG_PATH magma.pc PATHS "${libdir}/pkgconfig") - - if(MAGMA_PKG_CONFIG_PATH) - file(STRINGS ${MAGMA_PKG_CONFIG_PATH} _version_string REGEX "Version: [0-9].[0-9].[0-9]") - string(REGEX MATCHALL "[0-9]" _version_full "${_version_string}") - - list(GET _version_full 0 _version_major) - list(GET _version_full 1 _version_minor) - list(GET _version_full 2 _version_patch) - - set(MAGMA_VERSION "${_version_major}.${_version_minor}.${_version_patch}") - - file(STRINGS ${MAGMA_PKG_CONFIG_PATH} _libraries_string REGEX "Libs:.*") - string(REPLACE " " ";" _libraries_list ${_libraries_string}) - list(SUBLIST _libraries_list 1 -1 _libraries_list) # remove 'Libs:' part - - set(_interface_libraires ) - foreach(lib ${_libraries_list}) - if(NOT (lib STREQUAL "-lmagma" OR lib STREQUAL "-lmagma_sparse" OR lib STREQUAL "-L\${libdir}" OR lib STREQUAL "") ) - string(REPLACE "-l" "" lib ${lib}) - list(APPEND _interface_libraires ${lib}) - endif() - endforeach() - endif() -endif() - -set(MAGMA_LIBRARIES "${MAGMA_LIBRARY};${_interface_libraires}") - -find_package_handle_standard_args(MAGMA - REQUIRED_VARS - MAGMA_LIBRARY - MAGMA_LIBRARIES - MAGMA_INCLUDE_DIR - ${_sparse_required} - VERSION_VAR - MAGMA_VERSION - ) - -# Create target for MAGMA -if(MAGMA_FOUND) - - if(NOT TARGET SUNDIALS::MAGMA) - add_library(SUNDIALS::MAGMA UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::MAGMA PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${MAGMA_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${_interface_libraires}" - IMPORTED_LOCATION "${MAGMA_LIBRARY}") - - if(MAGMA_SPARSE_LIBRARY) - if(NOT TARGET SUNDIALS::MAGMA_SPARSE) - add_library(SUNDIALS::MAGMA_SPARSE UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::MAGMA_SPARSE PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${MAGMA_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${MAGMA_LIBRARY};${_interface_libraires}" - IMPORTED_LOCATION "${MAGMA_SPARSE_LIBRARY}") - endif() - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake b/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake deleted file mode 100644 index 1ef09d53dc..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake +++ /dev/null @@ -1,777 +0,0 @@ -# ------------------------------------------------------------------------------ -# Programmer(s): Cody J. Balos and David J. Gardner @ LLNL -# ------------------------------------------------------------------------------ -# Based on the FindPETSC module by Jed Brown. -# ------------------------------------------------------------------------------ -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# ------------------------------------------------------------------------------ -# Copyright Jed Brown -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ------------------------------------------------------------------------------ -# Try to find PETSC. This has three usage modes. -# -# The first usage mode is to find PETSC by introspection. -# This case is triggered when PETSC_DIR is not set by the user. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_DIR - directory in which PETSC resides -# PETSC_ARCH - build architecture -# PETSC_CURRENT - (advanced) redo the find stage and executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# The second usage mode is to find PETSC based on the user-provided -# PETSC_DIR, and optionally PETSC_ARCH, variables. This case is triggered -# when just PETSC_DIR, and optionally PETSC_ARCH, are set by the user. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_DIR - directory in which PETSC resides -# PETSC_ARCH - build architecture -# PETSC_CURRENT - (advanced) redo the find stage and executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# The third usage mode is to 'find' PETSC based on the user-provided list -# of include directories and libraries. This mode will only use the includes -# and libraries provided in the PETSC_INCLUDES and PETSC_LIBRARIES variable. -# This case is triggered when PETSC_INCLUDES, and PETSC_LIBRARIES are set. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_LIBRARIES - (advanced) link these to use PETSC -# PETSC_INCLUDES - (advanced) the PETSC include directories -# PETSC_CURRENT - (advanced) redo the executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# Note that setting PETSC_LIBRARIES and PETSC_INCLUDES takes precedence over -# setting PETSC_DIR. -# -# Once done this will define the targets: -# -# SUNDIALS::PETSC_ALL - a CMake target for all of PETSc -# SUNDIALS::PETSC_SYS - a CMake target for the main PETSc library -# SUNDIALS::PETSC_VEC - a CMake target for the PETSc vector library -# SUNDIALS::PETSC_MAT - a CMake target for the PETSc matrix library -# SUNDIALS::PETSC_DM - a CMake target for the PETSc DM library -# SUNDIALS::PETSC_KSP - a CMake target for the PETSc KSP library -# SUNDIALS::PETSC_SNES - a CMake target for the PETSc SNES library -# SUNDIALS::PETSC_TS - a CMake target for the PETSc TS library -# -# It will also define the following, potentially useful, variables: -# -# PETSC_COMPILER - (advanced) Compiler used by PETSC, helpful to find a compatible MPI -# PETSC_DEFINITIONS - (advanced) Compiler switches for using PETSC -# PETSC_MPIEXEC - (advanced) Executable for running MPI programs -# PETSC_INDEX_SIZE - (internal) the size of indices in PETSC -# PETSC_PRECISION - (internal) the real type precision in PETSC -# PETSC_VERSION - (internal) Version string (MAJOR.MINOR.SUBMINOR) -# -# Usage: -# find_package(PETSC COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 -# find_package(PETSC COMPONENTS C) - standard behavior of checking build using a C compiler -# find_package(PETSC) - same as above -# -# Redistribution and use is allowed according to the terms of the BSD license. -# ------------------------------------------------------------------------------ - -# ------------------------------------------------------------------------------ -# helper macros and functions -# ------------------------------------------------------------------------------ - -function (PETSC_GET_VERSION) - if (EXISTS "${PETSC_INCLUDE_DIR}/petscversion.h") - file (STRINGS "${PETSC_INCLUDE_DIR}/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ") - foreach (line ${vstrings}) - string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define") - list (GET fields 1 var) - list (GET fields 2 val) - set (${var} ${val} PARENT_SCOPE) - set (${var} ${val}) # Also in local scope so we have access below - endforeach () - if (PETSC_VERSION_RELEASE) - if ($(PETSC_VERSION_PATCH) GREATER 0) - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" CACHE INTERNAL "PETSC version" FORCE) - else () - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}" CACHE INTERNAL "PETSC version" FORCE) - endif () - else () - # make dev version compare higher than any patch level of a released version - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" CACHE INTERNAL "PETSC version" FORCE) - endif () - else () - message (SEND_ERROR "${PETSC_INCLUDE_DIR}/petscversion.h does not exist") - endif () -endfunction () - -macro (PETSC_GET_VARIABLE name var) - if (NOT DEFINED MAKE_EXECUTABLE) - # need to find the make executable the first time this macro is used - find_program (MAKE_EXECUTABLE NAMES make gmake) - if (MAKE_EXECUTABLE MATCHES "NOTFOUND") - message(SEND_ERROR "MAKE_EXECUTABLE could not be found (looked for `make` and `gmake`)") - endif () - endif () - set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name} - OUTPUT_VARIABLE ${var} - RESULT_VARIABLE petsc_return) -endmacro (PETSC_GET_VARIABLE) - -macro (PETSC_TEST_RUNS includes libraries runs) - if (PETSC_VERSION VERSION_GREATER 3.1) - set (_PETSC_TSDestroy "TSDestroy(&ts)") - else () - set (_PETSC_TSDestroy "TSDestroy(ts)") - endif () - - set (_PETSC_TEST_SOURCE " -static const char help[] = \"PETSC test program.\"; -#include -int main(int argc,char *argv[]) { - PetscErrorCode ierr; - TS ts; - - ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); - ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); - ierr = TSSetFromOptions(ts);CHKERRQ(ierr); - ierr = ${_PETSC_TSDestroy};CHKERRQ(ierr); - ierr = PetscFinalize();CHKERRQ(ierr); - return 0; -} -") - - multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}") - - if (${${runs}}) - set (PETSC_EXECUTABLE_RUNS "YES" CACHE INTERNAL - "The system can successfully run a PETSC executable" FORCE) - else() - set (PETSC_EXECUTABLE_RUNS "NO" CACHE INTERNAL - "The system can NOT successfully run a PETSC executable" FORCE) - endif () -endmacro (PETSC_TEST_RUNS) - -macro (PETSC_FIND_LIBRARY suffix name) - # Clear any stale value, if we got here, we need to find it again - set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - if (WIN32) - set (libname lib${name}) # windows expects "libfoo", linux expects "foo" - else (WIN32) - set (libname ${name}) - endif (WIN32) - - find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH) - set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}" CACHE INTERNAL "PETSC ${suffix} libraries" FORCE) - mark_as_advanced(PETSC_LIBRARY_${suffix}) -endmacro (PETSC_FIND_LIBRARY suffix name) - -macro (PETSC_FIND_LIBRARY_IN_LIST suffix names liblist) - # Clear any stale value, if we got here, we need to find it again - set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - foreach (name ${names}) - if (WIN32) - set (libname lib${name}) # windows expects "libfoo", linux expects "foo" - else (WIN32) - set (libname ${name}) - endif (WIN32) - foreach (lib ${${liblist}}) - if ("${lib}" MATCHES "${libname}[.].*") - set (PETSC_LIBRARY_${suffix} ${lib} CACHE INTERNAL "" FORCE) - list (REMOVE_ITEM ${liblist} ${lib}) - break () - endif () - endforeach () - endforeach () - set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}" CACHE INTERNAL "PETSC ${suffix} libraries" FORCE) - mark_as_advanced(PETSC_LIBRARY_${suffix}) - -endmacro (PETSC_FIND_LIBRARY_IN_LIST suffix names liblist) - -macro (PETSC_JOIN libs deps) - list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${libs}} CACHE INTERNAL "PETSC ${libs} libraries" FORCE) -endmacro (PETSC_JOIN libs deps) - -# ------------------------------------------------------------------------------ -# FindPETSC -# ------------------------------------------------------------------------------ - -set (PETSC_VALID_COMPONENTS C CXX) - -if (NOT PETSC_FIND_COMPONENTS) - - get_property (_enabled_langs GLOBAL PROPERTY ENABLED_LANGUAGES) - list(FIND _enabled_langs "C" _c_index) - if (${_c_index} GREATER -1) - set (PETSC_LANGUAGE_BINDINGS "C") - else () - set (PETSC_LANGUAGE_BINDINGS "CXX") - endif () - -else() - - # Right now, this is designed for compatability with the --with-clanguage option, so - # only allow one item in the components list. - list(LENGTH ${PETSC_FIND_COMPONENTS} components_length) - if(${components_length} GREATER 1) - message(FATAL_ERROR "Only one component for PETSC is allowed to be specified") - endif() - # This is a stub for allowing multiple components should that time ever come. Perhaps - # to also test Fortran bindings? - foreach(component ${PETSC_FIND_COMPONENTS}) - list(FIND PETSC_VALID_COMPONENTS ${component} component_location) - if(${component_location} EQUAL -1) - message(FATAL_ERROR "\"${component}\" is not a valid PETSC component.") - else() - list(APPEND PETSC_LANGUAGE_BINDINGS ${component}) - endif() - endforeach() - -endif() - -# Set which state variables to check to determine if the PETSC configuration is -# current and clear the other state variables -if (PETSC_INCLUDES OR PETSC_LIBRARIES) - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - set (PETSC_STATES "LIBRARIES;INCLUDES" CACHE INTERNAL "" FORCE) - set (PETSC_DIR "" CACHE PATH "Path to the root of a PETSc installation" FORCE) - set (PETSC_ARCH "" CACHE STRING "PETSc architecture" FORCE) - - else () - - string (CONCAT msg - "Both PETSC_INCLUDES and PETSC_LIBRARIES must be provided:\n" - " PETSC_INCLUDES=${PETSC_INCLUDES}\n" - " PETSC_LIBRARIES=${PETSC_LIBRARIES}") - message (FATAL_ERROR ${msg}) - - endif () - -else () - - set (PETSC_STATES "DIR;ARCH" CACHE INTERNAL "" FORCE) - set (PETSC_INCLUDES "" CACHE STRING "Semi-colon separated list of PETSc include directories" FORCE) - set (PETSC_LIBRARIES "" CACHE STRING "Semi-colon separated list of PETSc link libraries" FORCE) - -endif () - -# Keep track of FindPETSC state so that we do not do the complete -# set of tests and variable lookups every time cmake is run. -include (FindPackageMultipass) -set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS) -set (petsc_deps LIBRARY_DIR INCLUDE_DIR LIBRARIES_ INCLUDES_ COMPILER MPIEXEC EXECUTABLE_RUNS ${petsc_slaves}) -find_package_multipass (PETSC petsc_config_current STATES ${PETSC_STATES} DEPENDENTS ${petsc_deps}) - -# This runs anytime the current configuration is not current. -# This happens either when a user sets PETSC_CURRENT=FALSE, -# or when one of the dependents given to find_package_multipass changes. -if (NOT petsc_config_current) - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - message (STATUS "Finding PETSC using PETSC_INCLUDES and PETSC_LIBRARIES") - - # extract path from PETSC_INCLUDES - foreach (_include_dir ${PETSC_INCLUDES}) - if (EXISTS "${_include_dir}/petsc.h") - set (PETSC_INCLUDE_DIR "${_include_dir}" CACHE INTERNAL "Internal PETSc include directory" FORCE) - break () - endif () - endforeach () - - # check if the include directory was found - if (NOT PETSC_INCLUDE_DIR) - string (CONCAT msg - "Could not determine PETSc include directory from PETSC_INCLUDES:\n" - " PETSC_INCLUDES=${PETSC_INCLUDES}\n") - message (FATAL_ERROR ${msg}) - endif() - - # extract path from PETSC_LIBRARIES - foreach (_library_path ${PETSC_LIBRARIES}) - get_filename_component (_library_name "${_library_path}" NAME) - if (_library_name MATCHES "petsc") - get_filename_component (_library_dir "${_library_path}" DIRECTORY) - set (PETSC_LIBRARY_DIR "${_library_dir}" CACHE INTERNAL "Internal PETSc library directory" FORCE) - break () - endif () - endforeach () - - # check if the library directory was found - if (NOT PETSC_LIBRARY_DIR) - string (CONCAT msg - "Could not DETERMINE PETSc library directory from PETSC_LIBRARIES:\n" - " PETSC_LIBRARIES=${PETSC_LIBRARIES}") - message (FATAL_ERROR ${msg}) - endif() - - # set internal PETSC_DIR and PETSC_ARCH variables - set (PETSC_DIR_ "${PETSC_LIBRARY_DIR}/.." CACHE INTERNAL "Internal PETSC_DIR" FORCE) - set (PETSC_ARCH_ "" CACHE INTERNAL "Internal PETSC_ARCH" FORCE) - - else() - - message (STATUS "Finding PETSC using PETSC_DIR") - - # find PETSC_DIR - if (NOT PETSC_DIR) - - message (STATUS "Looking for PETSc in common install locations") - - # Debian uses versioned paths e.g /usr/lib/petscdir/3.5/ - file (GLOB DEB_PATHS "/usr/lib/petscdir/*") - - find_path (PETSC_DIR include/petsc.h - HINTS ENV PETSC_DIR - PATHS - /usr/lib/petsc - # Debian paths - ${DEB_PATHS} - # Arch Linux path - /opt/petsc/linux-c-opt - # MacPorts path - /opt/local/lib/petsc - $ENV{HOME}/petsc - DOC "PETSC Directory") - - # check if PETSC_DIR was set/found - if (NOT PETSC_DIR) - - string (CONCAT msg - "Could not locate PETSc install directory please set:\n" - " - PETSC_DIR and (optionally) PETSC_ARCH\n" - "or used the advanced options\n" - " - PETSC_INCLUDES and PETSC_LIBRARIES.") - message (FATAL_ERROR ${msg}) - - endif () - - endif() - - # find PETSC_ARCH - if (NOT PETSC_ARCH) - - set (_petsc_arches - $ENV{PETSC_ARCH} # If set, use environment variable first - linux-gnu-c-debug linux-gnu-c-opt # Debian defaults - x86_64-unknown-linux-gnu i386-unknown-linux-gnu) - set (PETSCCONF "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - foreach (arch ${_petsc_arches}) - find_path (PETSCCONF petscconf.h - HINTS ${PETSC_DIR} - PATH_SUFFIXES ${arch}/include bmake/${arch} - NO_DEFAULT_PATH) - if (PETSCCONF) - set (PETSC_ARCH "${arch}" CACHE STRING "PETSC build architecture" FORCE) - break () - endif () - endforeach () - set (PETSCCONF "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) - - endif () - - if (PETSC_ARCH) - set (PETSC_INCLUDE_DIR "${PETSC_DIR}/${PETSC_ARCH}/include" CACHE INTERNAL "Internal PETSc include directory" FORCE) - set (PETSC_LIBRARY_DIR "${PETSC_DIR}/${PETSC_ARCH}/lib" CACHE INTERNAL "Internal PETSc library directory" FORCE) - else () - set (PETSC_INCLUDE_DIR "${PETSC_DIR}/include" CACHE INTERNAL "Internal PETSc include directory" FORCE) - set (PETSC_LIBRARY_DIR "${PETSC_DIR}/lib" CACHE INTERNAL "Internal PETSc library directory" FORCE) - endif () - - # set internal PETSC_DIR and PETSC_ARCH variables - set (PETSC_DIR_ "${PETSC_DIR}" CACHE INTERNAL "Internal PETS_DIR" FORCE) - set (PETSC_ARCH_ "${PETSC_ARCH}" CACHE INTERNAL "Internal PETS_ARCH" FORCE) - - endif () - - # Resolve the conf/rules and conf/variables files. - # The location of these files has changed with different PETSc versions, - # so look in a few different locations for them. - if (EXISTS "${PETSC_LIBRARY_DIR}/petsc/conf/petscvariables") # > 3.5 - set (petsc_conf_rules "${PETSC_LIBRARY_DIR}/petsc/conf/rules") - set (petsc_conf_variables "${PETSC_LIBRARY_DIR}/petsc/conf/variables") - elseif (EXISTS "${PETSC_INCLUDE_DIR}/petscconf.h") # > 2.3.3 - set (petsc_conf_rules "${PETSC_DIR_}/conf/rules") - set (petsc_conf_variables "${PETSC_DIR_}/conf/variables") - elseif (EXISTS "${PETSC_DIR_}/bmake/${PETSC_ARCH_}/petscconf.h") # <= 2.3.3 - set (petsc_conf_rules "${PETSC_DIR_}/bmake/common/rules") - set (petsc_conf_variables "${PETSC_DIR_}/bmake/common/variables") - elseif (PETSC_LIBRARIES AND PETSC_INCLUDES) - message (FATAL_ERROR "PETSC_LIBRARIES=${PETSC_LIBRARIES} and PETSC_INCLUDES=${PETSC_INCLUDES} do not specify a valid PETSC installation") - else () - message (FATAL_ERROR "PETSC_DIR=${PETSC_DIR} and PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSC installation") - endif () - - # ---------------------------------------------------------------------------- - # Probe the PETSc installation for information about how it was configured. - # ---------------------------------------------------------------------------- - - # Get the PETSc version - petsc_get_version() - - # Put variables into environment since they are needed to get - # configuration (petscvariables) in the PETSC makefile - set (ENV{PETSC_DIR} "${PETSC_DIR_}") - set (ENV{PETSC_ARCH} "${PETSC_ARCH_}") - - # A temporary makefile to probe the PETSC configuration - set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") - file (WRITE "${petsc_config_makefile}" -"## This file was autogenerated by FindPETSC.cmake -# PETSC_DIR = ${PETSC_DIR_} -# PETSC_ARCH = ${PETSC_ARCH_} -include ${petsc_conf_rules} -include ${petsc_conf_variables} -show : -\t-@echo -n \${\${VARIABLE}} -") - - # Extract information about the PETSC configuration - petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir) - petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external) - petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line) - petsc_get_variable (PETSC_INCLUDE petsc_include) - petsc_get_variable (PCC petsc_cc) - petsc_get_variable (PCC_FLAGS petsc_cc_flags) - petsc_get_variable (MPIEXEC petsc_mpiexec) - petsc_get_variable (PETSC_INDEX_SIZE petsc_index_size) - petsc_get_variable (PETSC_PRECISION petsc_precision) - - # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! - file (REMOVE ${petsc_config_makefile}) - - # ---------------------------------------------------------------------------- - # Determine what libraries and includes are needed. - # ---------------------------------------------------------------------------- - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - # If the user manually set PETSC_INCUDES and PETSC_LIBRARIES, we work off of - # what they provided. - - # Make a copy of the user-provided library list to modify as libraries are - # found and extracted - set (PETSC_LIBRARIES_REMAINING ${PETSC_LIBRARIES}) - - # Look for petscvec first, if it doesn't exist, we must be using single-library - petsc_find_library_in_list (VEC petscvec PETSC_LIBRARIES_REMAINING) - - if (PETSC_LIBRARY_VEC) - - # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) - petsc_find_library_in_list (SYS "petscsys;petsc" PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (MAT petscmat PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (DM petscdm PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (KSP petscksp PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (SNES petscsnes PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (TS petscts PETSC_LIBRARIES_REMAINING) - petsc_join (SYS REMAINING) - petsc_join (VEC SYS) - petsc_join (MAT VEC) - petsc_join (DM MAT) - petsc_join (KSP DM) - petsc_join (SNES KSP) - petsc_join (TS SNES) - - set (PETSC_LIBRARY_ALL ${PETSC_LIBRARY_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - set (PETSC_LIBRARIES_ALL ${PETSC_LIBRARIES_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - - message (STATUS "Recognized PETSC install with separate libraries for each package") - - else () - - # There is no libpetscvec - set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - petsc_find_library_in_list (SINGLE petsc PETSC_LIBRARIES_REMAINING) - # Debian 9/Ubuntu 16.04 uses _real and _complex extensions when using libraries in /usr/lib/petsc. - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library_in_list (SINGLE petsc_real PETSC_LIBRARIES_REMAINING) - endif() - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library_in_list (SINGLE petsc_complex PETSC_LIBRARIES_REMAINING) - endif() - - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - message (STATUS "Recognized PETSC install with single library for all packages") - - endif () - - # At this point PETSC_LIBRARIES_REMAINING should only contain external - # libraries needed by PETSc. These may (e.g., static build) or may not - # (e.g., shared build) be needed to compile but are added to the package - # libraries regardless. - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - list (APPEND PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_REMAINING}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_${pkg}} CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - # Try to run a simple executable - petsc_test_runs ("${PETSC_INCLUDES}" "${PETSC_LIBRARIES_TS}" petsc_works_userprovided) - if (petsc_works_userprovided) - message (STATUS "PETSC works with the includes and libraries given.") - else () - message (STATUS "PETSC could not be used, maybe the install is broken.") - endif () - - # set include and library variables needed to create targets below - set (petsc_includes_needed ${PETSC_INCLUDES}) - set (petsc_libraries_needed ${PETSC_LIBRARIES}) - - else () - - include (ResolveCompilerPaths) - # Extract include paths and libraries from compile command line - resolve_includes (petsc_includes_all "${petsc_cpp_line}") - - # On windows we need to make sure we're linking against the right - # runtime library - if (WIN32) - if (petsc_cc_flags MATCHES "-MT") - - set (using_md False) - foreach(flag_var - CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - set (using_md True) - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - if(${using_md} MATCHES "True") - string(CONCAT msg "PETSC was built with /MT, but /MD is currently set.\n" - "See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F") - message(WARNING ${msg}) - endif(${using_md} MATCHES "True") - - endif (petsc_cc_flags MATCHES "-MT") - endif (WIN32) - - include (CorrectWindowsPaths) - convert_cygwin_path(petsc_lib_dir) - - # Look for petscvec first, if it doesn't exist, we must be using single-library - petsc_find_library (VEC petscvec) - if (PETSC_LIBRARY_VEC) - - petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) - petsc_find_library (MAT petscmat) - petsc_find_library (DM petscdm) - petsc_find_library (KSP petscksp) - petsc_find_library (SNES petscsnes) - petsc_find_library (TS petscts) - petsc_join (VEC SYS) - petsc_join (MAT VEC) - petsc_join (DM MAT) - petsc_join (KSP DM) - petsc_join (SNES KSP) - petsc_join (TS SNES) - - set (PETSC_LIBRARY_ALL ${PETSC_LIBRARY_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - set (PETSC_LIBRARIES_ALL ${PETSC_LIBRARIES_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - - message (STATUS "Recognized PETSC install with separate libraries for each package") - - else () - - # There is no libpetscvec - set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - petsc_find_library (SINGLE petsc) - # Debian 9/Ubuntu 16.04 uses _real and _complex extensions when using libraries in /usr/lib/petsc. - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library (SINGLE petsc_real) - endif() - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library (SINGLE petsc_complex) - endif() - - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - message (STATUS "Recognized PETSC install with single library for all packages") - - endif () - - # determine the include and library variables needed to create targets below - - find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_INCLUDE_DIR}" "${PETSC_DIR_}/bmake/${PETSC_ARCH_}" NO_DEFAULT_PATH) - mark_as_advanced (PETSC_INCLUDE_CONF) - - set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) - - petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal) - if (petsc_works_minimal) - - message (STATUS "Minimal PETSC includes and libraries work. This probably means we are building with shared libs.") - set (petsc_includes_needed "${petsc_includes_minimal}") - - else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it - - petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes) - if (petsc_works_allincludes) # It does, we just need all the includes - - string (CONCAT msg "PETSC requires extra include paths, but links correctly with only interface libraries.\n" - "This is an unexpected configuration (but it seems to work fine).") - message (STATUS ${msg}) - set (petsc_includes_needed ${petsc_includes_all}) - - else (petsc_works_allincludes) # We are going to need to link the external libs explicitly - - resolve_libraries (petsc_libraries_external "${petsc_libs_external}") - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_${pkg}} CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach (pkg) - - petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries) - if (petsc_works_alllibraries) - - string (CONCAT msg "PETSC only need minimal includes, but requires explicit linking to all dependencies.\n" - "This is expected when PETSC is built with static libraries.") - message(STATUS ${msg}) - set (petsc_includes_needed ${petsc_includes_minimal}) - - else (petsc_works_alllibraries) - - # It looks like we really need everything, should have listened to Matt - set (petsc_includes_needed ${petsc_includes_all}) - petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all) - if (petsc_works_all) # We fail anyways - string (CONCAT msg "PETSC requires extra include paths and explicit linking to all dependencies.\n" - "This probably means you have static libraries and something unexpected in PETSC headers.") - message (STATUS ${msg}) - else (petsc_works_all) # We fail anyways - message (STATUS "PETSC could not be used, maybe the install is broken.") - endif (petsc_works_all) - - endif (petsc_works_alllibraries) - - endif (petsc_works_allincludes) - - endif (petsc_works_minimal) - - set (petsc_libraries_needed ${PETSC_LIBRARIES_ALL}) - - endif () - - # ---------------------------------------------------------------------------- - # Now we set all of the variables needed to build targets. - # ---------------------------------------------------------------------------- - - # If PETSC_WORKS is set override the executable test results. This variable - # can be manually set to ON to force CMake to accept a given PETSC - # configuration, but this will almost always result in a broken build. - if (PETSC_WORKS) - message (STATUS "Overwriting PETSc test results with PETSC_WORKS = ${PETSC_WORKS}") - set (PETSC_EXECUTABLE_RUNS ${PETSC_WORKS} CACHE INTERNAL "Overwritten by PETSC_WORKS" FORCE) - endif () - - # We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous - if (${PETSC_VERSION} VERSION_LESS 3.1) - set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSC definitions" FORCE) - else () - set (PETSC_DEFINITIONS "-D__INSDIR__=\"\"" CACHE STRING "PETSC definitions" FORCE) - endif () - - # Sometimes this can be used to assist FindMPI.cmake - set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSC compiler" FORCE) - set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSC MPI programs" FORCE) - - # Internal variables needed for configuring targets - set (PETSC_INDEX_SIZE ${petsc_index_size} CACHE INTERNAL "PETSC index size" FORCE) - set (PETSC_PRECISION ${petsc_precision} CACHE INTERNAL "PETSC real type precision" FORCE) - set (PETSC_INCLUDES_ ${petsc_includes_needed} CACHE INTERNAL "PETSC include paths to be used" FORCE) - set (PETSC_LIBRARIES_ ${petsc_libraries_needed} CACHE INTERNAL "PETSC libraries to be used" FORCE) - - # Note that we have forced values for all these choices. If you - # change these, you are telling the system to trust you that they - # work. It is likely that you will end up with a broken build. - mark_as_advanced (PETSC_CURRENT PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS) - -endif () - -include (FindPackageHandleStandardArgs) -find_package_handle_standard_args (PETSC - REQUIRED_VARS PETSC_EXECUTABLE_RUNS - VERSION_VAR PETSC_VERSION - FAIL_MESSAGE "PETSC could not be found.") - -# Create targets -if (PETSC_FOUND) - if (PETSC_LIBRARY_SINGLE) - foreach (suffix SYS VEC MAT DM KSP SNES TS ALL) - if (NOT TARGET SUNDIALS::PETSC_${suffix}) - add_library (SUNDIALS::PETSC_${suffix} UNKNOWN IMPORTED) - # add properties one-by-one for easier debugging - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PETSC_INCLUDES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_LINK_LIBRARIES "${PETSC_LIBRARIES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_COMPILE_OPTIONS ${PETSC_DEFINITIONS}) - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - IMPORTED_LOCATION ${PETSC_LIBRARY_SINGLE}) - endif () - endforeach () - else () - foreach (suffix SYS VEC MAT DM KSP SNES TS ALL) - if (PETSC_LIBRARY_${suffix} AND (NOT TARGET SUNDIALS::PETSC_${suffix})) - add_library (SUNDIALS::PETSC_${suffix} UNKNOWN IMPORTED) - # add properties one-by-one for easier debugging - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PETSC_INCLUDES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_LINK_LIBRARIES "${PETSC_LIBRARIES_${suffix}}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_COMPILE_OPTIONS ${PETSC_DEFINITIONS}) - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - IMPORTED_LOCATION ${PETSC_LIBRARY_${suffix}}) - endif () - endforeach () - endif () -endif (PETSC_FOUND) diff --git a/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake b/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake deleted file mode 100644 index eb78f834e3..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Slaven Peles and Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# ----------------------------------------------------------------------------- -# Find module for Trilinos that uses the TrilinosConfig.cmake that is installed -# with Trilinos. The module will also create a SUNDIALS::TRILINOS target. -# ----------------------------------------------------------------------------- - -# First try and find Trilinos using Trilinos_DIR only. -find_package(Trilinos - NAMES Trilinos TRILINOS - PATHS - ${Trilinos_DIR}/lib/cmake/Trilinos - ${Trilinos_DIR} - NO_DEFAULT_PATH - QUIET) - -# set package variables including Trilinos_FOUND -find_package_handle_standard_args(Trilinos - REQUIRED_VARS - Trilinos_LIBRARIES # defined in TrilinosConfig.cmake - Trilinos_INCLUDE_DIRS # defined in TrilinosConfig.cmake - ) - -# Create Trilinos target -if(Trilinos_FOUND) - - if(NOT TARGET SUNDIALS::TRILINOS) - add_library(SUNDIALS::TRILINOS IMPORTED INTERFACE) - endif() - - set_target_properties(SUNDIALS::TRILINOS PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Trilinos_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES "${Trilinos_LIBRARIES}") - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake b/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake deleted file mode 100644 index 6b2d8b0521..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake +++ /dev/null @@ -1,196 +0,0 @@ -# ------------------------------------------------------------------------------ -# Programmer(s): David J. Gardner @ LLNL -# ------------------------------------------------------------------------------ -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# ------------------------------------------------------------------------------ -# XBRAID find module that creates an imported target for XBRAID. -# The target is SUNDIALS::XBRAID. -# -# The variable XBRAID_DIR can be used to control where the module -# looks for the library. -# -# XBRAID_LIBRARIES - (advanced) the libraries to link against -# XBRAID_INCLUDES - (advanced) the directories to include -# -# This module also defines variables, but it is best to use -# the defined target to ensure includes and compile/link -# options are correctly passed to consumers. -# -# XBRAID_FOUND - system has the XBRAID library -# ------------------------------------------------------------------------------ - -# Check if we are locating XBraid using the root install directory or a list of -# include directories and link libraries -if (XBRAID_INCLUDES OR XBRAID_LIBRARIES) - - if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - - set(XBRAID_DIR "" CACHE PATH "Path to the root of XBraid installation" FORCE) - - else () - - string(CONCAT msg - "Both XBRAID_INCLUDES and XBRAID_LIBRARIES must be provided:\n" - " XBRAID_INCLUDES=${XBRAID_INCLUDES}\n" - " XBRAID_LIBRARIES=${XBRAID_LIBRARIES}") - message(FATAL_ERROR ${msg}) - - endif () - -else () - - set(XBRAID_INCLUDES "" CACHE STRING "Semi-colon separated list of XBraid include directories" FORCE) - set(XBRAID_LIBRARIES "" CACHE STRING "Semi-colon separated list of XBraid link libraries" FORCE) - -endif () - -# unset cache values for multiple passes -unset(XBRAID_INCLUDE_DIR CACHE) -unset(XBRAID_LIBRARY CACHE) - -unset(XBRAID_INCS CACHE) -unset(XBRAID_LIBS CACHE) - -if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - - message(STATUS "Finding XBraid using XBRAID_INCLUDES and XBRAID_LIBRARIES") - - # extract path from XBRAID_INCLUDES - foreach (include_dir ${XBRAID_INCLUDES}) - if (EXISTS "${include_dir}/braid.h") - set(XBRAID_INCLUDE_DIR "${include_dir}" CACHE "XBraid include directory") - break() - endif () - endforeach () - - # check if the include directory was found - if (NOT XBRAID_INCLUDE_DIR) - string(CONCAT msg - "Could not determine XBraid include directory from XBRAID_INCLUDES:\n" - " XBRAID_INCLUDES=${XBRAID_INCLUDES}\n") - message(FATAL_ERROR ${msg}) - endif () - - # extract library from XBRAID_LIBRARIES - foreach (library_path ${XBRAID_LIBRARIES}) - get_filename_component(library_name "${library_path}" NAME) - if (library_name MATCHES "braid") - set(XBRAID_LIBRARY "${library_path}" CACHE "XBraid library") - break() - endif () - endforeach () - - # check if the library directory was found - if (NOT XBRAID_LIBRARY) - string(CONCAT msg - "Could not determine XBraid library from XBRAID_LIBRARIES:\n" - " XBRAID_LIBRARIES=${XBRAID_LIBRARIES}") - message(FATAL_ERROR ${msg}) - endif () - -else () - - message(STATUS "Finding XBraid using XBRAID_DIR") - - # find XBRAID_DIR - if (NOT XBRAID_DIR) - - message(STATUS "Looking for XBraid in common install locations") - find_path(XBRAID_DIR include/braid.h braid/braid.h) - - endif () - - # check if XBRAID_DIR was set/found - if (NOT XBRAID_DIR) - - string(CONCAT msg - "Could not locate XBraid install directory please set:\n" - " - XBRAID_DIR\n" - "or used the advanced options\n" - " - XBRAID_INCLUDES and XBRAID_LIBRARIES.") - message(FATAL_ERROR ${msg}) - - endif () - - # Find the include dir - find_path(XBRAID_INCLUDE_DIR braid.h - PATHS - ${XBRAID_DIR} - PATH_SUFFIXES - include braid - DOC - "XBraid include directory" - NO_DEFAULT_PATH) - - # check if the include directory was found - if (NOT XBRAID_INCLUDE_DIR) - string(CONCAT msg - "Could not determine XBraid include directory from XBRAID_DIR:\n" - " XBRAID_DIR=${XBRAID_DIR}\n") - message(FATAL_ERROR ${msg}) - endif () - - # Find the library - find_library(XBRAID_LIBRARY braid - PATHS - ${XBRAID_DIR} - PATH_SUFFIXES - lib braid - DOC - "XBraid library" - NO_DEFAULT_PATH) - - # check if the library was found - if (NOT XBRAID_LIBRARY) - string(CONCAT msg - "Could not determine XBraid library from XBRAID_DIR:\n" - " XBRAID_DIR=${XBRAID_DIR}\n") - message(FATAL_ERROR ${msg}) - endif () - -endif () - -# set package variables including XBRAID_FOUND -find_package_handle_standard_args(XBRAID - REQUIRED_VARS - XBRAID_INCLUDE_DIR - XBRAID_LIBRARY - ) - -# XBraid target -if (XBRAID_FOUND) - - # create target if necessary - if (NOT TARGET SUNDIALS::XBRAID) - add_library(SUNDIALS::XBRAID UNKNOWN IMPORTED) - endif () - - # update target properties (for multiple passes) - set_target_properties(SUNDIALS::XBRAID PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${XBRAID_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${XBRAID_LIBRARIES}" - IMPORTED_LOCATION "${XBRAID_LIBRARY}") - - # set variables for output message, compile tests, and - # CMake/Makefile templates - if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - set(XBRAID_INCS "${XBRAID_INCLUDES}" CACHE INTERNAL - "Internal XBraid includes") - set(XBRAID_LIBS "${XBRAID_LIBRARIES}" CACHE INTERNAL - "Internal XBraid libraries") - else () - set(XBRAID_INCS "${XBRAID_INCLUDE_DIR}" CACHE INTERNAL - "Internal XBraid includes") - set(XBRAID_LIBS "${XBRAID_LIBRARY}" CACHE INTERNAL - "Internal XBraid libraries") - endif () - -endif () diff --git a/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake b/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake deleted file mode 100644 index b2fb7af2d0..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake +++ /dev/null @@ -1,113 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup HYPRE correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_HYPRE_INCLUDED) - set(SUNDIALS_HYPRE_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using hypre requres building with MPI enabled -if(ENABLE_HYPRE AND NOT ENABLE_MPI) - print_error("MPI is required for hypre support. Set ENABLE_MPI to ON.") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(HYPRE REQUIRED) - -message(STATUS "HYPRE_LIBRARIES: ${HYPRE_LIBRARIES}") -message(STATUS "HYPRE_INCLUDE_DIR: ${HYPRE_INCLUDE_DIR}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(HYPRE_FOUND AND (NOT HYPRE_WORKS)) - # Do any checks which don't require compilation first. - - # Create the HYPRE_TEST directory - set(HYPRE_TEST_DIR ${PROJECT_BINARY_DIR}/HYPRE_TEST) - file(MAKE_DIRECTORY ${HYPRE_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${HYPRE_TEST_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ltest C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER ${MPI_C_COMPILER})\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "SET(CMAKE_EXE_LINKER_FLAGS \"${LINK_MATH_LIB}\")\n" - "INCLUDE_DIRECTORIES(${HYPRE_INCLUDE_DIR})\n" - "ADD_EXECUTABLE(ltest ltest.c)\n" - "TARGET_LINK_LIBRARIES(ltest ${HYPRE_LIBRARIES})\n") - - file(WRITE ${HYPRE_TEST_DIR}/ltest.c - "\#include \"HYPRE_parcsr_ls.h\"\n" - "int main(){\n" - "HYPRE_ParVector par_b;\n" - "HYPRE_IJVector b;\n" - "par_b = 0;\n" - "b = 0;\n" - "if (par_b != 0 || b != 0) return(1);\n" - "else return(0);\n" - "}\n") - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${HYPRE_TEST_DIR}/CMakeFiles) - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${HYPRE_TEST_DIR} ${HYPRE_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if HYPRE works... OK") - set(HYPRE_WORKS TRUE CACHE BOOL "HYPRE works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if HYPRE works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to HYPRE is not functional.") - endif() - -elseif(HYPRE_FOUND AND HYPRE_WORKS) - message(STATUS "Skipped HYPRE tests, assuming HYPRE works with SUNDIALS. Set HYPRE_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake b/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake deleted file mode 100644 index 671fac1aaf..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake +++ /dev/null @@ -1,109 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup MAGMA correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_MAGMA_INCLUDED) - set(SUNDIALS_MAGMA_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -if(SUNDIALS_PRECISION MATCHES "extended") - print_error("SUNDIALS MAGMA interface is not compatible with extended precision") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(MAGMA REQUIRED) - -message(STATUS "MAGMA_VERSION: ${MAGMA_VERSION}") -message(STATUS "MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}") -message(STATUS "MAGMA_INCLUDE_DIR: ${MAGMA_INCLUDE_DIR}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA" AND NOT ENABLE_CUDA) - print_error("SUNDIALS_MAGMA_BACKENDS includes CUDA but CUDA is not enabled. Set ENABLE_CUDA=ON or change the backend.") -endif() -if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP" AND NOT ENABLE_HIP) - print_error("SUNDIALS_MAGMA_BACKENDS includes HIP but HIP is not enabled. Set ENABLE_HIP=ON or change the backend.") -endif() - -if(MAGMA_FOUND AND (NOT MAGMA_WORKS)) - # Create the MAGMA_TEST directory - set(MAGMA_TEST_DIR ${PROJECT_BINARY_DIR}/CMakeFiles/MAGMA_TEST) - file(MAKE_DIRECTORY ${MAGMA_TEST_DIR}) - - if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") - set(lang CXX) - set(ext cxx) - set(define_have "\#define HAVE_HIP") - set(lib hip::host) - elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") - set(lang CUDA) - set(ext cu) - set(define_have "\#define HAVE_CUBLAS") - set(lib ) - endif() - - file(WRITE ${MAGMA_TEST_DIR}/ltest.${ext} - "${define_have}\n" - "\#include \"magma_v2.h\"\n" - "int main(){\n" - "magma_int_t a=0;\n" - "return(a);\n" - "}\n") - - try_compile(COMPILE_OK ${MAGMA_TEST_DIR} ${MAGMA_TEST_DIR}/ltest.${ext} - CMAKE_FLAGS - "-DINCLUDE_DIRECTORIES=${MAGMA_INCLUDE_DIR}" - LINK_LIBRARIES ${MAGMA_LIBRARIES} ${lib} - OUTPUT_VARIABLE COMPILE_OUTPUT - ${lang}_STANDARD ${CMAKE_${lang}_STANDARD} - ) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if MAGMA works... OK") - set(MAGMA_WORKS TRUE CACHE BOOL "MAGMA works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if MAGMA works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to MAGMA is not functional.") - endif() -elseif(MAGMA_FOUND AND MAGMA_WORKS) - message(STATUS "Skipped MAGMA tests, assuming MAGMA works with SUNDIALS.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake b/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake deleted file mode 100644 index ad5d721c04..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake +++ /dev/null @@ -1,89 +0,0 @@ -# --------------------------------------------------------------------------- -# Programmer(s): David J. Gardner @ LLNL -# --------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, 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 -# --------------------------------------------------------------------------- -# Setup MPI for SUNDIALS CMake-based configuration. -# --------------------------------------------------------------------------- -# Prior to CMake 3.10 the CMake FindMPI module considers: -# 1. Inspect MPI wrappers (MPI__COMPILER) -# 2. Try guesses -# 3. Try the compiler (CMAKE__COMPILER) -# -# Starting with CMake 3.10 the CMake FindMPI module considers: -# 1. Try the compiler (CMAKE__COMPILER) -# 2. Inspect MPI wrappers (MPI__COMPILER) -# 3. Try guesses -# --------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_MPI_INCLUDED) - set(SUNDIALS_MPI_INCLUDED) -else() - return() -endif() - -# --------------------------------------------------------------------------- -# If MPI__COMPILER is set, FindMPI will try to set the below variables -# for the given compiler wrapper. If MPI__COMPILER is unset FindMPI -# will attempt to locate an installed MPI library and set the below -# variables. -# -# MPI__FOUND TRUE if FindMPI found MPI flags for -# MPI__COMPILER MPI Compiler wrapper for -# MPI__COMPILE_FLAGS Compilation flags for MPI programs -# MPI__INCLUDE_PATH Include path(s) for MPI header -# MPI__LINK_FLAGS Linking flags for MPI programs -# MPI__LIBRARIES All libraries to link MPI programs against -# -# MPIEXEC_EXECUTABLE Executable for running MPI programs -# MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC_EXECUTABLE before -# giving it the number of processors to run on -# MPIEXEC_PREFLAGS Flags to pass to MPIEXEC_EXECUTABLE directly -# before the executable to run. -# MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC_EXECUTABLE after -# other flags -# --------------------------------------------------------------------------- - -mark_as_advanced(MPI_EXTRA_LIBRARY) -mark_as_advanced(MPI_LIBRARY) - -foreach(lang ${_SUNDIALS_ENABLED_LANGS}) - mark_as_advanced(CLEAR MPI_${lang}_COMPILER) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_COMPILE_FLAGS) - mark_as_advanced(MPI_${lang}_INCLUDE_PATH) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_LINK_FLAGS) -endforeach() - -find_package(MPI 2.0.0 REQUIRED) - -# --------------------------------------------------------------------------- -# Configure the presentation of MPI options in the GUI. -# --------------------------------------------------------------------------- - -mark_as_advanced(CLEAR MPIEXEC_EXECUTABLE) - -mark_as_advanced(MPI_EXTRA_LIBRARY) -mark_as_advanced(MPI_LIBRARY) - -foreach(lang ${_SUNDIALS_ENABLED_LANGS}) - mark_as_advanced(CLEAR MPI_${lang}_COMPILER) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_COMPILE_FLAGS) - mark_as_advanced(MPI_${lang}_INCLUDE_PATH) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_LINK_FLAGS) -endforeach() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake b/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake deleted file mode 100644 index 822c763fd4..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup PETSC correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_PETSC_INCLUDED) - set(SUNDIALS_PETSC_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using PETSc requires building with MPI enabled -if(ENABLE_PETSC AND NOT ENABLE_MPI) - print_error("MPI is required for PETSc support. Set ENABLE_MPI to ON.") -endif() - -if(SUNDIALS_PRECISION MATCHES "EXTENDED") - print_error("SUNDIALS is not compatible with PETSc when using ${SUNDIALS_PRECISION} precision") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(PETSC REQUIRED) - -message(STATUS "PETSC_DIR: ${PETSC_DIR}") -message(STATUS "PETSC_LIBRARIES: ${PETSC_LIBRARIES_}") -message(STATUS "PETSC_INCLUDES: ${PETSC_INCLUDES_}") -message(STATUS "PETSC_INDEX_SIZE: ${PETSC_INDEX_SIZE}") -message(STATUS "PETSC_PRECISION: ${PETSC_PRECISION}\n") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(PETSC_FOUND AND (NOT PETSC_WORKS)) - # No need for any compile tests because the FindPETSC module - # does compile tests already. - - if(NOT ("${SUNDIALS_INDEX_SIZE}" MATCHES "${PETSC_INDEX_SIZE}")) - string(CONCAT _err_msg_string - "PETSc not functional due to index size mismatch:\n" - "SUNDIALS_INDEX_SIZE=${SUNDIALS_INDEX_SIZE}, " - "but PETSc was built with ${PETSC_INDEX_SIZE}-bit indices\n" - "PETSC_DIR: ${PETSC_DIR}\n") - print_error("${_err_msg_string}") - endif() - - string(TOUPPER "${PETSC_PRECISION}" _petsc_precision) - string(TOUPPER "${SUNDIALS_PRECISION}" _sundials_precision) - if(NOT ("${_sundials_precision}" MATCHES "${_petsc_precision}")) - string(CONCAT _err_msg_string - "PETSc not functional due to real type precision mismatch:\n" - "SUNDIALS_PRECISION=${_sundials_precision}, " - "but PETSc was built with ${_petsc_precision} precision\n" - "PETSC_DIR: ${PETSC_DIR}\n") - print_error("${_err_msg_string}") - endif() - - set(PETSC_WORKS TRUE CACHE BOOL "PETSC works with SUNDIALS as configured" FORCE) -elseif(PETSC_FOUND AND PETSC_WORKS) - message(STATUS "Skipped PETSC tests, assuming PETSC works with SUNDIALS. Set PETSC_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake b/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake deleted file mode 100644 index 4a7a0ab411..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake +++ /dev/null @@ -1,87 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup RAJA correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_RAJA_INCLUDED) - set(SUNDIALS_RAJA_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -# find the library configuration file -find_file(RAJA_CONFIGHPP_PATH config.hpp - HINTS "${RAJA_DIR}" - PATH_SUFFIXES include include/RAJA - NO_DEFAULT_PATH) -mark_as_advanced(FORCE RAJA_CONFIGHPP_PATH) - -# Look for CMake configuration file in RAJA installation -find_package(RAJA CONFIG - PATHS "${RAJA_DIR}" "${RAJA_DIR}/share/raja/cmake" - NO_DEFAULT_PATH - REQUIRED) - -# determine the backends -foreach(_backend CUDA HIP OPENMP TARGET_OPENMP) - file(STRINGS "${RAJA_CONFIGHPP_PATH}" _raja_has_backend REGEX "^#define RAJA_ENABLE_${_backend}\$") - if(_raja_has_backend) - set(RAJA_BACKENDS "${_backend};${RAJA_BACKENDS}") - endif() -endforeach() - -message(STATUS "RAJA Version: ${RAJA_VERSION_MAJOR}.${RAJA_VERSION_MINOR}.${RAJA_VERSION_PATCHLEVEL}") -message(STATUS "RAJA Backends: ${RAJA_BACKENDS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if((SUNDIALS_RAJA_BACKENDS MATCHES "CUDA") AND - (NOT RAJA_BACKENDS MATCHES "CUDA")) - print_error("Requested that SUNDIALS uses the CUDA RAJA backend, but RAJA was not built with the CUDA backend.") -endif() - -if((SUNDIALS_RAJA_BACKENDS MATCHES "HIP") AND - (NOT RAJA_BACKENDS MATCHES "HIP")) - print_error("Requested that SUNDIALS uses the HIP RAJA backend, but RAJA was not built with the HIP backend.") -endif() - -if(NOT ENABLE_OPENMP AND RAJA_BACKENDS MATCHES "OPENMP") - print_error("RAJA was built with OpenMP, but OpenMP is not enabled. Set ENABLE_OPENMP to ON.") -endif() - -if(NOT ENABLE_OPENMP_DEVICE AND RAJA_BACKENDS MATCHES "TARGET_OPENMP") - print_error("RAJA was built with OpenMP device offloading, but OpenMP with device offloading is not enabled. Set ENABLE_OPENMP_DEVICE to ON.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake b/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake deleted file mode 100644 index e995b0fec8..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake +++ /dev/null @@ -1,140 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup Trilinos correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_TRILINOS_INCLUDED) - set(SUNDIALS_TRILINOS_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -# Find Trilinos -find_package(Trilinos REQUIRED) - -# Check if Trilinos was built with MPI -if(";${Trilinos_TPL_LIST};" MATCHES ";MPI;") - set(Trilinos_MPI TRUE) -else() - set(Trilinos_MPI FALSE) -endif() - -# For XSDK compatibility, only use the user/spack provided compiler and flags to build -# SUNDIALS modules that use Trilinos. If we are not in XSDK mode, we can use the imported -# Trilinos compiler and flags by default, but allow the user to change it through CMake -# the Trilinos_INTERFACE_* options. - -if(USE_XSDK_DEFAULTS) - if(Trilinos_MPI AND MPI_CXX_FOUND) - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C++ compiler for Trilinos interface" "${MPI_CXX_COMPILER}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - else() - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C compiler for Trilinos interface" "${CMAKE_CXX_COMPILER}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - endif() - if(Trilinos_MPI AND MPI_C_FOUND) - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${MPI_C_COMPILER}") - set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI") - else() - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${CMAKE_C_COMPILER}") - set(Trilinos_INTERFACE_MPI_C_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C compiler MPI") - endif() - force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags specific to Trilinos interface" "") - force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS STRING "C compiler flags specific to Trilinos interface" "") - force_variable(Trilinos_INTERFACE_MPIEXEC STRING "MPI executable for Trilinos interface" "${MPIEXEC_EXECUTABLE}") -else() - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C++ compiler for Trilinos interface" "${Trilinos_CXX_COMPILER}") - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${Trilinos_C_COMPILER}") - force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags for Trilinos interface" "${Trilinos_CXX_COMPILER_FLAGS}") - force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS STRING "C compiler flags for Trilinos interface" "${Trilinos_C_COMPILER_FLAGS}") - force_variable(Trilinos_INTERFACE_MPIEXEC STRING "MPI executable for Trilinos interface" "${Trilinos_MPI_EXEC}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI") -endif() - -message(STATUS "Trilinos_MPI: ${Trilinos_MPI}") -message(STATUS "Trilinos_LIBRARIES: ${Trilinos_LIBRARIES}") -message(STATUS "Trilinos_INCLUDE_DIRS: ${Trilinos_INCLUDE_DIRS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(Trilinos_FOUND AND (NOT Trilinos_WORKS)) - # Do any checks which don't require compilation first. - - # Create the Trilinos_TEST directory - set(Trilinos_TEST_DIR ${PROJECT_BINARY_DIR}/Trilinos_TEST) - file(MAKE_DIRECTORY ${Trilinos_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${Trilinos_TEST_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.1.3)\n" - "PROJECT(ltest CXX)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_CXX_COMPILER \"${Trilinos_INTERFACE_CXX_COMPILER}\")\n" - "SET(CMAKE_CXX_FLAGS \"${Trilinos_INTERFACE_CXX_COMPILER_FLAGS}\")\n" - "SET(Trilinos_DIR \"${Trilinos_DIR}\")\n" - "INCLUDE(FindPackageHandleStandardArgs)\n" - "INCLUDE(${PROJECT_SOURCE_DIR}/cmake/tpl/FindTrilinos.cmake)\n" - "ADD_EXECUTABLE(ltest ltest.cpp)\n" - "TARGET_LINK_LIBRARIES(ltest SUNDIALS::TRILINOS)\n") - - # Create a C++ source file which calls a Trilinos function - file(WRITE ${Trilinos_TEST_DIR}/ltest.cpp - "#include \n" - "int main(){\n" - "std::cout << Tpetra::version() << std::endl;\n" - "return(0);\n" - "}\n") - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${Trilinos_TEST_DIR} ${Trilinos_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if Trilinos works with SUNDIALS... OK") - set(Trilinos_WORKS TRUE CACHE BOOL "Trilinos works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if Trilinos works with SUNDIALS... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to Trilinos is not functional.") - endif() - -elseif(Trilinos_FOUND AND Trilinos_WORKS) - message(STATUS "Skipped Trilinos tests, assuming Trilinos works with SUNDIALS. Set Trilinos_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake b/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake deleted file mode 100644 index 91b99669f2..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake +++ /dev/null @@ -1,129 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): David J. Gardner @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_XBRAID_INCLUDED) - set(SUNDIALS_XBRAID_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using XBRAID requires building with MPI enabled -if(NOT ENABLE_MPI) - message(FATAL_ERROR - "MPI is required for XBraid support. Set ENABLE_MPI to ON.") -endif() - -# XBraid does not support single or extended precision -if(SUNDIALS_PRECISION MATCHES "SINGLE" OR SUNDIALS_PRECISION MATCHES "EXTENDED") - message(FATAL_ERROR - "XBraid is not compatible with ${SUNDIALS_PRECISION} precision") -endif() - -# XBraid does not support 64-bit index sizes -if(SUNDIALS_INDEX_SIZE MATCHES "64") - message(FATAL_ERROR - "XBraid is not compatible with ${SUNDIALS_INDEX_SIZE}-bit indices") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(XBRAID REQUIRED) - -message(STATUS "XBRAID_LIBRARIES: ${XBRAID_LIBS}") -message(STATUS "XBRAID_INCLUDES: ${XBRAID_INCS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -# Add works variable - -if(XBRAID_FOUND AND (NOT XBRAID_WORKS)) - - # Create the XBRAID_TEST directory - set(XBRAID_TEST_DIR ${PROJECT_BINARY_DIR}/XBRAID_TEST) - file(MAKE_DIRECTORY ${XBRAID_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${XBRAID_TEST_DIR}/CMakeLists.txt - "cmake_minimum_required(VERSION ${CMAKE_VERSION})\n" - "project(ltest C)\n" - "set(CMAKE_VERBOSE_MAKEFILE ON)\n" - "set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "set(CMAKE_C_COMPILER ${MPI_C_COMPILER})\n" - "set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "set(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "set(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "set(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "set(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "add_executable(ltest ltest.c)\n" - "target_include_directories(ltest PRIVATE \"${XBRAID_INCS}\")\n" - "target_link_libraries(ltest \"${XBRAID_LIBS}\")\n" - "target_link_libraries(ltest m)\n") - - # Create a C source file - file(WRITE ${XBRAID_TEST_DIR}/ltest.c - "\#include \n" - "\#include \"braid.h\"\n" - "int main(){\n" - "braid_Int rand;\n" - "rand = braid_Rand();\n" - "if (rand < 0) return 1;\n" - "return 0;\n" - "}\n") - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${XBRAID_TEST_DIR}/CMakeFiles) - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${XBRAID_TEST_DIR} ${XBRAID_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if XBRAID works... OK") - set(XBRAID_WORKS TRUE CACHE BOOL "XBRAID works as configured" FORCE) - else() - message(STATUS "Checking if XBRAID works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - message(FATAL_ERROR "XBRAID compile test failed.") - endif() - - message(STATUS "XBRAID tests passed") - -else() - message(STATUS "Skipped XBRAID tests, assuming XBRAID works with SUNDIALS.") -endif() diff --git a/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h b/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h deleted file mode 100644 index b4729f1944..0000000000 --- a/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ---------------------------------------------------------------------------- - * Programmer(s): Cody J. Balos @ LLNL - * ---------------------------------------------------------------------------- - * Based on work by Donald Wilcox @ LBNL - * ---------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ---------------------------------------------------------------------------- - * Header file for cuSolverSp batched QR SUNLinearSolver interface. - * ----------------------------------------------------------------------------*/ - -#ifndef _SUNLINSOL_CUSOLVERSP_H -#define _SUNLINSOL_CUSOLVERSP_H - -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * ---------------------------------------------------------------------------- - * PART I: cuSolverSp implementation of SUNLinearSolver - * ---------------------------------------------------------------------------- - */ - -struct _SUNLinearSolverContent_cuSolverSp_batchQR { - int last_flag; /* last return flag */ - booleantype first_factorize; /* is this the first factorization? */ - size_t internal_size; /* size of cusolver internal buffer for Q and R */ - size_t workspace_size; /* size of cusolver memory block for num. factorization */ - cusolverSpHandle_t cusolver_handle; /* cuSolverSp context */ - csrqrInfo_t info; /* opaque cusolver data structure */ - void* workspace; /* memory block used by cusolver */ - const char* desc; /* description of this linear solver */ -}; - -typedef struct _SUNLinearSolverContent_cuSolverSp_batchQR *SUNLinearSolverContent_cuSolverSp_batchQR; - - -/* - * ---------------------------------------------------------------------------- - * PART II: Functions exported by sunlinsol_sludist - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT SUNLinearSolver SUNLinSol_cuSolverSp_batchQR(N_Vector y, SUNMatrix A, - cusolverSpHandle_t cusol_handle); - - -/* - * ---------------------------------------------------------------------------- - * cuSolverSp implementations of SUNLinearSolver operations - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT SUNLinearSolver_Type SUNLinSolGetType_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT SUNLinearSolver_ID SUNLinSolGetID_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolInitialize_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolSetup_cuSolverSp_batchQR(SUNLinearSolver S, - SUNMatrix A); - -SUNDIALS_EXPORT int SUNLinSolSolve_cuSolverSp_batchQR(SUNLinearSolver S, - SUNMatrix A, - N_Vector x, - N_Vector b, - realtype tol); - -SUNDIALS_EXPORT sunindextype SUNLinSolLastFlag_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolFree_cuSolverSp_batchQR(SUNLinearSolver S); - - -/* - * ---------------------------------------------------------------------------- - * Additional get and set functions. - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_GetDescription(SUNLinearSolver S, - char** desc); - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_SetDescription(SUNLinearSolver S, - const char* desc); - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_GetDeviceSpace(SUNLinearSolver S, - size_t* cuSolverInternal, - size_t* cuSolverWorkspace); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h b/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h deleted file mode 100644 index 458413826e..0000000000 --- a/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Cody J. Balos @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 is for the cuSPARSE implementation of the - * SUNMATRIX module. - * ----------------------------------------------------------------- - */ - -#ifndef _SUNMATRIX_CUSPARSE_H -#define _SUNMATRIX_CUSPARSE_H - -#include - -#include -#include - -#include -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/* ------------------------------------------ - * Implementation of SUNMATRIX_CUSPARSE - * ------------------------------------------ */ - -/* storage formats */ -#define SUNMAT_CUSPARSE_CSR 0 -#define SUNMAT_CUSPARSE_BCSR 1 - -struct _SUNMatrix_Content_cuSparse { - int M; - int N; - int NNZ; - int nblocks; - int blockrows; - int blockcols; - int blocknnz; - int sparse_type; - booleantype own_matd; - booleantype own_exec; - booleantype fixed_pattern; - booleantype matvec_issetup; - SUNMemory colind; - SUNMemory rowptrs; - SUNMemory data; - SUNMemoryHelper mem_helper; - cusparseMatDescr_t mat_descr; -#if CUDART_VERSION >= 11000 - SUNMemory dBufferMem; - size_t bufferSize; - cusparseDnVecDescr_t vecX, vecY; - cusparseSpMatDescr_t spmat_descr; -#endif - cusparseHandle_t cusp_handle; - SUNCudaExecPolicy* exec_policy; -}; - -typedef struct _SUNMatrix_Content_cuSparse *SUNMatrix_Content_cuSparse; - -/* ------------------------------------------------------------------ - * Constructors. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_NewCSR(int M, int N, int NNZ, cusparseHandle_t cusp); -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_MakeCSR(cusparseMatDescr_t mat_descr, int M, int N, int NNZ, - int *rowptrs , int *colind , realtype *data, - cusparseHandle_t cusp); - -/* Creates a CSR block-diagonal matrix where each block shares the same sparsity structure. - Reduces memory usage by only storing the row pointers and column indices for one block. */ -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_NewBlockCSR(int nblocks, int blockrows, int blockcols, - int blocknnz, cusparseHandle_t cusp); - - -/* ------------------------------------------------------------------ - * Implementation specific routines. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SparseType(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_Rows(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_Columns(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_NNZ(SUNMatrix A); -SUNDIALS_EXPORT int* SUNMatrix_cuSparse_IndexPointers(SUNMatrix A); -SUNDIALS_EXPORT int* SUNMatrix_cuSparse_IndexValues(SUNMatrix A); -SUNDIALS_EXPORT realtype* SUNMatrix_cuSparse_Data(SUNMatrix A); - -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SetFixedPattern(SUNMatrix A, booleantype yesno); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SetKernelExecPolicy(SUNMatrix A, SUNCudaExecPolicy* exec_policy); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_NumBlocks(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockRows(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockColumns(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockNNZ(SUNMatrix A); -SUNDIALS_EXPORT realtype* SUNMatrix_cuSparse_BlockData(SUNMatrix A, int blockidx); -SUNDIALS_EXPORT cusparseMatDescr_t SUNMatrix_cuSparse_MatDescr(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_CopyToDevice(SUNMatrix device, realtype* h_data, - int* h_idxptrs, int* h_idxvals); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_CopyFromDevice(SUNMatrix device, realtype* h_data, - int* h_idxptrs, int* h_idxvals); - - -/* ------------------------------------------------------------------ - * SUNMatrix API routines. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT SUNMatrix_ID SUNMatGetID_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT SUNMatrix SUNMatClone_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT void SUNMatDestroy_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatZero_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatCopy_cuSparse(SUNMatrix A, SUNMatrix B); -SUNDIALS_EXPORT int SUNMatScaleAdd_cuSparse(realtype c, SUNMatrix A, SUNMatrix B); -SUNDIALS_EXPORT int SUNMatScaleAddI_cuSparse(realtype c, SUNMatrix A); -SUNDIALS_EXPORT int SUNMatMatvecSetup_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatMatvec_cuSparse(SUNMatrix A, N_Vector x, N_Vector y); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/CMakeLists.txt b/ThirdParty/sundials/src/kinsol/CMakeLists.txt deleted file mode 100644 index e6bb1a9079..0000000000 --- a/ThirdParty/sundials/src/kinsol/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Daniel R. Reynolds @ SMU -# Radu Serban, Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the KINSOL library -# --------------------------------------------------------------- - -install(CODE "MESSAGE(\"\nInstall KINSOL\n\")") - -# Add variable kinsol_SOURCES with the sources for the KINSOL library -set(kinsol_SOURCES - kinsol.c - kinsol_bbdpre.c - kinsol_direct.c - kinsol_io.c - kinsol_ls.c - kinsol_spils.c - ) - -# Add variable kinsol_HEADERS with the exported KINSOL header files -set(kinsol_HEADERS - kinsol.h - kinsol_bbdpre.h - kinsol_direct.h - kinsol_ls.h - kinsol_spils.h - ) - -# Add prefix with complete path to the KINSOL header files -add_prefix(${SUNDIALS_SOURCE_DIR}/include/kinsol/ kinsol_HEADERS) - -# Create the library -sundials_add_library(sundials_kinsol - SOURCES - ${kinsol_SOURCES} - HEADERS - ${kinsol_HEADERS} - INCLUDE_SUBDIR - kinsol - OBJECT_LIBRARIES - sundials_generic_obj - sundials_nvecserial_obj - sundials_sunmatrixband_obj - sundials_sunmatrixdense_obj - sundials_sunmatrixsparse_obj - sundials_sunlinsolband_obj - sundials_sunlinsoldense_obj - sundials_sunlinsolspbcgs_obj - sundials_sunlinsolspfgmr_obj - sundials_sunlinsolspgmr_obj - sundials_sunlinsolsptfqmr_obj - sundials_sunlinsolpcg_obj - OUTPUT_NAME - sundials_kinsol - VERSION - ${kinsollib_VERSION} - SOVERSION - ${kinsollib_SOVERSION} -) - -# Finished KINSOL -message(STATUS "Added KINSOL module") - -# Add F2003 module if the interface is enabled -if(BUILD_FORTRAN_MODULE_INTERFACE) - add_subdirectory(fmod) -endif() - -if(BUILD_FORTRAN77_INTERFACE) - add_subdirectory(fcmix) -endif() diff --git a/ThirdParty/sundials/src/kinsol/LICENSE b/ThirdParty/sundials/src/kinsol/LICENSE deleted file mode 100644 index 4ba2c48483..0000000000 --- a/ThirdParty/sundials/src/kinsol/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2002-2021, Lawrence Livermore National Security and Southern Methodist University. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ThirdParty/sundials/src/kinsol/NOTICE b/ThirdParty/sundials/src/kinsol/NOTICE deleted file mode 100644 index 329b142ee6..0000000000 --- a/ThirdParty/sundials/src/kinsol/NOTICE +++ /dev/null @@ -1,21 +0,0 @@ -This work was produced under the auspices of the U.S. Department of -Energy by Lawrence Livermore National Laboratory under Contract -DE-AC52-07NA27344. - -This work was prepared as an account of work sponsored by an agency of -the United States Government. Neither the United States Government nor -Lawrence Livermore National Security, LLC, nor any of their employees -makes any warranty, expressed or implied, or assumes any legal liability -or responsibility for the accuracy, completeness, or usefulness of any -information, apparatus, product, or process disclosed, or represents that -its use would not infringe privately owned rights. - -Reference herein to any specific commercial product, process, or service -by trade name, trademark, manufacturer, or otherwise does not necessarily -constitute or imply its endorsement, recommendation, or favoring by the -United States Government or Lawrence Livermore National Security, LLC. - -The views and opinions of authors expressed herein do not necessarily -state or reflect those of the United States Government or Lawrence -Livermore National Security, LLC, and shall not be used for advertising -or product endorsement purposes. \ No newline at end of file diff --git a/ThirdParty/sundials/src/kinsol/README.md b/ThirdParty/sundials/src/kinsol/README.md deleted file mode 100644 index 2f73f75ff8..0000000000 --- a/ThirdParty/sundials/src/kinsol/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# KINSOL -### Version 5.7.0 (Jan 2021) - -**Alan C. Hindmarsh, Radu Serban, Cody J. Balos, David J. Gardner, - and Carol S. Woodward, Center for Applied Scientific Computing, LLNL** - -**Daniel R. Reynolds, Department of Mathematics, Southern Methodist University** - - -KINSOL is a package for the solution for nonlinear algebraic systems -``` -F(u) = 0. -``` -Nonlinear solver methods available include Newton-Krylov, Picard, and -fixed-point. Both Picard and fixed point can be accelerated with Anderson -acceleration. - -KINSOL is part of the SUNDIALS Suite of Nonlinear and Differential/Algebraic -equation Solvers which consists of ARKode, CVODE, CVODES, IDA, IDAS and KINSOL. -It is written in ANSI standard C, but is based on the previous Fortran package -NKSOL, written by Peter Brown and Youcef Saad. KINSOL can be used in a variety -of computing environments including serial, shared memory, distributed memory, -and accelerator-based (e.g., GPU) systems. This flexibility is obtained from a -modular design that leverages the shared vector, matrix, and linear solver APIs -used across SUNDIALS packages. - -For use with Fortran applications, a set of Fortran/C interface routines, called -FKINSOL, is also supplied. These are written in C, but assume that the user -calling program and all user-supplied routines are in Fortran. - -## Documentation - -See the [KINSOL User Guide](/doc/kinsol/kin_guide.pdf) and -[KINSOL Examples](/doc/kinsol/kin_examples.pdf) document for more information -about IDA usage and the provided example programs respectively. - -## Installation - -For installation instructions see the [INSTALL_GUIDE](/INSTALL_GUIDE.pdf) -or the "Installation Procedure" chapter in the KINSOL User Guide. - -## Release History - -Information on recent changes to KINSOL can be found in the "Introduction" -chapter of the KINSOL User Guide and a complete release history is available in -the "SUNDIALS Release History" appendix of the KINSOL User Guide. - -## References - -* A. C. Hindmarsh, R. Serban, C. J. Balos, D. J. Gardner, - D. R. Reynolds and C. S. Woodward, - "User Documentation for KINSOL v5.7.0," LLNL technical report - UCRL-SM-208116, Jan 2021. - -* A. M. Collier and R. Serban, "Example Programs for KINSOL v5.7.0," - LLNL technical report UCRL-SM-208114, Jan 2021. - -* A. C. Hindmarsh, P. N. Brown, K. E. Grant, S. L. Lee, R. Serban, - D. E. Shumaker, and C. S. Woodward, "SUNDIALS, Suite of Nonlinear and - Differential/Algebraic Equation Solvers," ACM Trans. Math. Softw., - 31(3), pp. 363-396, 2005. - -* Peter N. Brown and Youcef Saad, "Hybrid Krylov Methods for - Nonlinear Systems of Equations," SIAM J. Sci. Stat. Comput., - Vol 11, no 3, pp. 450-481, May 1990. - -* A. G. Taylor and A. C. Hindmarsh, "User Documentation for KINSOL, - A Nonlinear Solver for Sequential and Parallel Computers," LLNL - technical report UCRL-ID-131185, July 1998. diff --git a/ThirdParty/sundials/src/kinsol/kinsol.c b/ThirdParty/sundials/src/kinsol/kinsol.c deleted file mode 100644 index 5d6e994232..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol.c +++ /dev/null @@ -1,2702 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, Carol Woodward, - * John Loffeld, and Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 main KINSol solver. - * It is independent of the KINSol linear solver in use. - * ----------------------------------------------------------------- - * - * EXPORTED FUNCTIONS - * ------------------ - * Creation and allocation functions - * KINCreate - * KINInit - * Main solver function - * KINSol - * Deallocation function - * KINFree - * - * PRIVATE FUNCTIONS - * ----------------- - * KINCheckNvector - * Memory allocation/deallocation - * KINAllocVectors - * KINFreeVectors - * Initial setup - * KINSolInit - * Step functions - * KINLinSolDrv - * KINFullNewton - * KINLineSearch - * KINConstraint - * KINFP - * KINPicardAA - * Stopping tests - * KINStop - * KINForcingTerm - * Norm functions - * KINScFNorm - * KINScSNorm - * KINSOL Verbose output functions - * KINPrintInfo - * KINInfoHandler - * KINSOL Error Handling functions - * KINProcessError - * KINErrHandler - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * IMPORTED HEADER FILES - * ================================================================= - */ - -#include -#include -#include -#include - -#include - -#include "kinsol_impl.h" -#include - -/* - * ================================================================= - * KINSOL PRIVATE CONSTANTS - * ================================================================= - */ - -#define HALF RCONST(0.5) -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define ONEPT5 RCONST(1.5) -#define TWO RCONST(2.0) -#define THREE RCONST(3.0) -#define FIVE RCONST(5.0) -#define TWELVE RCONST(12.0) -#define POINT1 RCONST(0.1) -#define POINT01 RCONST(0.01) -#define POINT99 RCONST(0.99) -#define THOUSAND RCONST(1000.0) -#define ONETHIRD RCONST(0.3333333333333333) -#define TWOTHIRDS RCONST(0.6666666666666667) -#define POINT9 RCONST(0.9) -#define POINT0001 RCONST(0.0001) - -/* - * ================================================================= - * KINSOL ROUTINE-SPECIFIC CONSTANTS - * ================================================================= - */ - -/* - * Control constants for lower-level functions used by KINSol - * ---------------------------------------------------------- - * - * KINStop return value requesting more iterations - * RETRY_ITERATION - * CONTINUE_ITERATIONS - * - * KINFullNewton, KINLineSearch, KINFP, and KINPicardAA return values: - * KIN_SUCCESS - * KIN_SYSFUNC_FAIL - * STEP_TOO_SMALL - * - * KINConstraint return values: - * KIN_SUCCESS - * CONSTR_VIOLATED - */ - -#define RETRY_ITERATION -998 -#define CONTINUE_ITERATIONS -999 -#define STEP_TOO_SMALL -997 -#define CONSTR_VIOLATED -996 - -/* - * Algorithmic constants - * --------------------- - * - * MAX_RECVR max. no. of attempts to correct a recoverable func error - */ - -#define MAX_RECVR 5 - -/* - * Keys for KINPrintInfo - * --------------------- - */ - -#define PRNT_RETVAL 1 -#define PRNT_NNI 2 -#define PRNT_TOL 3 -#define PRNT_FMAX 4 -#define PRNT_PNORM 5 -#define PRNT_PNORM1 6 -#define PRNT_FNORM 7 -#define PRNT_LAM 8 -#define PRNT_ALPHA 9 -#define PRNT_BETA 10 -#define PRNT_ALPHABETA 11 -#define PRNT_ADJ 12 - -/* - * ================================================================= - * PRIVATE FUNCTION PROTOTYPES - * ================================================================= - */ - -static booleantype KINCheckNvector(N_Vector tmpl); -static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl); -static int KINSolInit(KINMem kin_mem); -static int KINConstraint(KINMem kin_mem ); -static void KINForcingTerm(KINMem kin_mem, realtype fnormp); -static void KINFreeVectors(KINMem kin_mem); - -static int KINFullNewton(KINMem kin_mem, realtype *fnormp, - realtype *f1normp, booleantype *maxStepTaken); -static int KINLineSearch(KINMem kin_mem, realtype *fnormp, - realtype *f1normp, booleantype *maxStepTaken); -static int KINPicardAA(KINMem kin_mem, long int *iter, realtype *R, - realtype *gamma, realtype *fmax); -static int KINFP(KINMem kin_mem); - -static int KINLinSolDrv(KINMem kinmem); -static int KINPicardFcnEval(KINMem kin_mem, N_Vector gval, N_Vector uval, - N_Vector fval1); -static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale); -static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u); -static int KINStop(KINMem kin_mem, booleantype maxStepTaken, - int sflag); -static int AndersonAcc(KINMem kin_mem, N_Vector gval, N_Vector fv, N_Vector x, - N_Vector x_old, long int iter, realtype *R, realtype *gamma); - -/* - * ================================================================= - * EXPORTED FUNCTIONS IMPLEMENTATION - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Creation and allocation functions - * ----------------------------------------------------------------- - */ - -/* - * Function : KINCreate - * - * KINCreate creates an internal memory block for a problem to - * be solved by KINSOL. If successful, KINCreate returns a pointer - * to the problem memory. This pointer should be passed to - * KINInit. If an initialization error occurs, KINCreate prints - * an error message to standard error and returns NULL. - */ - -void *KINCreate(void) -{ - KINMem kin_mem; - realtype uround; - - kin_mem = NULL; - kin_mem = (KINMem) malloc(sizeof(struct KINMemRec)); - if (kin_mem == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINCreate", MSG_MEM_FAIL); - return(NULL); - } - - /* Zero out kin_mem */ - memset(kin_mem, 0, sizeof(struct KINMemRec)); - - /* set uround (unit roundoff) */ - - kin_mem->kin_uround = uround = UNIT_ROUNDOFF; - - /* set default values for solver optional inputs */ - - kin_mem->kin_func = NULL; - kin_mem->kin_user_data = NULL; - kin_mem->kin_uu = NULL; - kin_mem->kin_unew = NULL; - kin_mem->kin_fval = NULL; - kin_mem->kin_gval = NULL; - kin_mem->kin_uscale = NULL; - kin_mem->kin_fscale = NULL; - kin_mem->kin_pp = NULL; - kin_mem->kin_constraints = NULL; - kin_mem->kin_vtemp1 = NULL; - kin_mem->kin_vtemp2 = NULL; - kin_mem->kin_fold_aa = NULL; - kin_mem->kin_gold_aa = NULL; - kin_mem->kin_df_aa = NULL; - kin_mem->kin_dg_aa = NULL; - kin_mem->kin_q_aa = NULL; - kin_mem->kin_gamma_aa = NULL; - kin_mem->kin_R_aa = NULL; - kin_mem->kin_ipt_map = NULL; - kin_mem->kin_cv = NULL; - kin_mem->kin_Xv = NULL; - kin_mem->kin_lmem = NULL; - kin_mem->kin_m_aa = 0; - kin_mem->kin_aamem_aa = 0; - kin_mem->kin_setstop_aa = 0; - kin_mem->kin_beta_aa = ONE; - kin_mem->kin_damping_aa = SUNFALSE; - kin_mem->kin_constraintsSet = SUNFALSE; - kin_mem->kin_ehfun = KINErrHandler; - kin_mem->kin_eh_data = kin_mem; - kin_mem->kin_errfp = stderr; - kin_mem->kin_ihfun = KINInfoHandler; - kin_mem->kin_ih_data = kin_mem; - kin_mem->kin_infofp = stdout; - kin_mem->kin_printfl = PRINTFL_DEFAULT; - kin_mem->kin_mxiter = MXITER_DEFAULT; - kin_mem->kin_noInitSetup = SUNFALSE; - kin_mem->kin_msbset = MSBSET_DEFAULT; - kin_mem->kin_noResMon = SUNFALSE; - kin_mem->kin_msbset_sub = MSBSET_SUB_DEFAULT; - kin_mem->kin_update_fnorm_sub = SUNFALSE; - kin_mem->kin_mxnbcf = MXNBCF_DEFAULT; - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_noMinEps = SUNFALSE; - kin_mem->kin_mxnstepin = ZERO; - kin_mem->kin_sqrt_relfunc = SUNRsqrt(uround); - kin_mem->kin_scsteptol = SUNRpowerR(uround,TWOTHIRDS); - kin_mem->kin_fnormtol = SUNRpowerR(uround,ONETHIRD); - kin_mem->kin_etaflag = KIN_ETACHOICE1; - kin_mem->kin_eta = POINT1; /* default for KIN_ETACONSTANT */ - kin_mem->kin_eta_alpha = TWO; /* default for KIN_ETACHOICE2 */ - kin_mem->kin_eta_gamma = POINT9; /* default for KIN_ETACHOICE2 */ - kin_mem->kin_MallocDone = SUNFALSE; - kin_mem->kin_eval_omega = SUNTRUE; - kin_mem->kin_omega = ZERO; /* default to using min/max */ - kin_mem->kin_omega_min = OMEGA_MIN; - kin_mem->kin_omega_max = OMEGA_MAX; - - /* initialize lrw and liw */ - - kin_mem->kin_lrw = 17; - kin_mem->kin_liw = 22; - - /* NOTE: needed since KINInit could be called after KINSetConstraints */ - - kin_mem->kin_lrw1 = 0; - kin_mem->kin_liw1 = 0; - - return((void *) kin_mem); -} - -/* - * Function : KINInit - * - * KINInit allocates memory for a problem or execution of KINSol. - * If memory is successfully allocated, KIN_SUCCESS is returned. - * Otherwise, an error message is printed and an error flag - * returned. - */ - -int KINInit(void *kinmem, KINSysFn func, N_Vector tmpl) -{ - sunindextype liw1, lrw1; - KINMem kin_mem; - booleantype allocOK, nvectorOK; - - /* check kinmem */ - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINInit", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (func == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINInit", MSG_FUNC_NULL); - return(KIN_ILL_INPUT); - } - - /* check if all required vector operations are implemented */ - - nvectorOK = KINCheckNvector(tmpl); - if (!nvectorOK) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINInit", MSG_BAD_NVECTOR); - return(KIN_ILL_INPUT); - } - - /* set space requirements for one N_Vector */ - - if (tmpl->ops->nvspace != NULL) { - N_VSpace(tmpl, &lrw1, &liw1); - kin_mem->kin_lrw1 = lrw1; - kin_mem->kin_liw1 = liw1; - } - else { - kin_mem->kin_lrw1 = 0; - kin_mem->kin_liw1 = 0; - } - - /* allocate necessary vectors */ - - allocOK = KINAllocVectors(kin_mem, tmpl); - if (!allocOK) { - KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINInit", MSG_MEM_FAIL); - free(kin_mem); kin_mem = NULL; - return(KIN_MEM_FAIL); - } - - /* copy the input parameter into KINSol state */ - - kin_mem->kin_func = func; - - /* set the linear solver addresses to NULL */ - - kin_mem->kin_linit = NULL; - kin_mem->kin_lsetup = NULL; - kin_mem->kin_lsolve = NULL; - kin_mem->kin_lfree = NULL; - kin_mem->kin_lmem = NULL; - - /* problem memory has been successfully allocated */ - - kin_mem->kin_MallocDone = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Main solver function - * ----------------------------------------------------------------- - */ - -/* - * Function : KINSol - * - * KINSol (main KINSOL driver routine) manages the computational - * process of computing an approximate solution of the nonlinear - * system F(uu) = 0. The KINSol routine calls the following - * subroutines: - * - * KINSolInit checks if initial guess satisfies user-supplied - * constraints and initializes linear solver - * - * KINLinSolDrv interfaces with linear solver to find a - * solution of the system J(uu)*x = b (calculate - * Newton step) - * - * KINFullNewton/KINLineSearch implement the global strategy - * - * KINForcingTerm computes the forcing term (eta) - * - * KINStop determines if an approximate solution has been found - */ - -int KINSol(void *kinmem, N_Vector u, int strategy_in, - N_Vector u_scale, N_Vector f_scale) -{ - realtype fnormp, f1normp, epsmin, fmax=ZERO; - KINMem kin_mem; - int ret, sflag; - booleantype maxStepTaken; - - /* intialize to avoid compiler warning messages */ - - maxStepTaken = SUNFALSE; - f1normp = fnormp = -ONE; - - /* initialize epsmin to avoid compiler warning message */ - - epsmin = ZERO; - - /* check for kinmem non-NULL */ - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if(kin_mem->kin_MallocDone == SUNFALSE) { - KINProcessError(NULL, KIN_NO_MALLOC, "KINSOL", "KINSol", MSG_NO_MALLOC); - return(KIN_NO_MALLOC); - } - - /* load input arguments */ - - kin_mem->kin_uu = u; - kin_mem->kin_uscale = u_scale; - kin_mem->kin_fscale = f_scale; - kin_mem->kin_globalstrategy = strategy_in; - - /* CSW: - Call fixed point solver if requested. Note that this should probably - be forked off to a FPSOL solver instead of kinsol in the future. */ - if ( kin_mem->kin_globalstrategy == KIN_FP ) { - if (kin_mem->kin_uu == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSol", MSG_UU_NULL); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_constraintsSet != SUNFALSE) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSol", MSG_CONSTRAINTS_NOTOK); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSol", INFO_TOL, kin_mem->kin_scsteptol, kin_mem->kin_fnormtol); - - kin_mem->kin_nfe = kin_mem->kin_nnilset = kin_mem->kin_nnilset_sub = kin_mem->kin_nni = kin_mem->kin_nbcf = kin_mem->kin_nbktrk = 0; - ret = KINFP(kin_mem); - - switch(ret) { - case KIN_SYSFUNC_FAIL: - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED); - break; - case KIN_MAXITER_REACHED: - KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED); - break; - } - - return(ret); - } - - /* initialize solver */ - ret = KINSolInit(kin_mem); - if (ret != KIN_SUCCESS) return(ret); - - kin_mem->kin_ncscmx = 0; - - /* Note: The following logic allows the choice of whether or not - to force a call to the linear solver setup upon a given call to - KINSol */ - - if (kin_mem->kin_noInitSetup) kin_mem->kin_sthrsh = ONE; - else kin_mem->kin_sthrsh = TWO; - - /* if eps is to be bounded from below, set the bound */ - - if (kin_mem->kin_inexact_ls && !(kin_mem->kin_noMinEps)) - epsmin = POINT01 * kin_mem->kin_fnormtol; - - - /* if omega is zero at this point, make sure it will be evaluated - at each iteration based on the provided min/max bounds and the - current function norm. */ - if (kin_mem->kin_omega == ZERO) kin_mem->kin_eval_omega = SUNTRUE; - else kin_mem->kin_eval_omega = SUNFALSE; - - - /* CSW: - Call fixed point solver for Picard method if requested. - Note that this should probably be forked off to a part of an - FPSOL solver instead of kinsol in the future. */ - if ( kin_mem->kin_globalstrategy == KIN_PICARD ) { - - if (kin_mem->kin_gval == NULL) { - kin_mem->kin_gval = N_VClone(kin_mem->kin_unew); - if (kin_mem->kin_gval == NULL) { - KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINSol", MSG_MEM_FAIL); - return(KIN_MEM_FAIL); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - ret = KINPicardAA(kin_mem, &(kin_mem->kin_nni), kin_mem->kin_R_aa, kin_mem->kin_gamma_aa, &fmax); - - return(ret); - } - - - for(;;){ - - kin_mem->kin_retry_nni = SUNFALSE; - - kin_mem->kin_nni++; - - /* calculate the epsilon (stopping criteria for iterative linear solver) - for this iteration based on eta from the routine KINForcingTerm */ - - if (kin_mem->kin_inexact_ls) { - kin_mem->kin_eps = (kin_mem->kin_eta + kin_mem->kin_uround) * kin_mem->kin_fnorm; - if(!(kin_mem->kin_noMinEps)) kin_mem->kin_eps = SUNMAX(epsmin, kin_mem->kin_eps); - } - - repeat_nni: - - /* call the appropriate routine to calculate an acceptable step pp */ - - sflag = 0; - - if (kin_mem->kin_globalstrategy == KIN_NONE) { - - /* Full Newton Step*/ - - /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ - ret = KINLinSolDrv(kin_mem); - if (ret != KIN_SUCCESS) break; - - sflag = KINFullNewton(kin_mem, &fnormp, &f1normp, &maxStepTaken); - - /* if sysfunc failed unrecoverably, stop */ - if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) { - ret = sflag; - break; - } - - } else if (kin_mem->kin_globalstrategy == KIN_LINESEARCH) { - - /* Line Search */ - - /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ - ret = KINLinSolDrv(kin_mem); - if (ret != KIN_SUCCESS) break; - - sflag = KINLineSearch(kin_mem, &fnormp, &f1normp, &maxStepTaken); - - /* if sysfunc failed unrecoverably, stop */ - if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) { - ret = sflag; - break; - } - - /* if too many beta condition failures, then stop iteration */ - if (kin_mem->kin_nbcf > kin_mem->kin_mxnbcf) { - ret = KIN_LINESEARCH_BCFAIL; - break; - } - - } - - if ( (kin_mem->kin_globalstrategy != KIN_PICARD) && - (kin_mem->kin_globalstrategy != KIN_FP) ) { - - /* evaluate eta by calling the forcing term routine */ - if (kin_mem->kin_callForcingTerm) KINForcingTerm(kin_mem, fnormp); - - kin_mem->kin_fnorm = fnormp; - - /* call KINStop to check if tolerances where met by this iteration */ - ret = KINStop(kin_mem, maxStepTaken, sflag); - - if (ret == RETRY_ITERATION) { - kin_mem->kin_retry_nni = SUNTRUE; - goto repeat_nni; - } - } - - /* update uu after the iteration */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - - kin_mem->kin_f1norm = f1normp; - - /* print the current nni, fnorm, and nfe values if printfl > 0 */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSol", INFO_NNI, kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - if (ret != CONTINUE_ITERATIONS) break; - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINSol", INFO_RETVAL, ret); - - switch(ret) { - case KIN_SYSFUNC_FAIL: - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED); - break; - case KIN_REPTD_SYSFUNC_ERR: - KINProcessError(kin_mem, KIN_REPTD_SYSFUNC_ERR, "KINSOL", "KINSol", MSG_SYSFUNC_REPTD); - break; - case KIN_LSETUP_FAIL: - KINProcessError(kin_mem, KIN_LSETUP_FAIL, "KINSOL", "KINSol", MSG_LSETUP_FAILED); - break; - case KIN_LSOLVE_FAIL: - KINProcessError(kin_mem, KIN_LSOLVE_FAIL, "KINSOL", "KINSol", MSG_LSOLVE_FAILED); - break; - case KIN_LINSOLV_NO_RECOVERY: - KINProcessError(kin_mem, KIN_LINSOLV_NO_RECOVERY, "KINSOL", "KINSol", MSG_LINSOLV_NO_RECOVERY); - break; - case KIN_LINESEARCH_NONCONV: - KINProcessError(kin_mem, KIN_LINESEARCH_NONCONV, "KINSOL", "KINSol", MSG_LINESEARCH_NONCONV); - break; - case KIN_LINESEARCH_BCFAIL: - KINProcessError(kin_mem, KIN_LINESEARCH_BCFAIL, "KINSOL", "KINSol", MSG_LINESEARCH_BCFAIL); - break; - case KIN_MAXITER_REACHED: - KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED); - break; - case KIN_MXNEWT_5X_EXCEEDED: - KINProcessError(kin_mem, KIN_MXNEWT_5X_EXCEEDED, "KINSOL", "KINSol", MSG_MXNEWT_5X_EXCEEDED); - break; - } - - return(ret); -} - -/* - * ----------------------------------------------------------------- - * Deallocation function - * ----------------------------------------------------------------- - */ - -/* - * Function : KINFree - * - * This routine frees the problem memory allocated by KINInit. - * Such memory includes all the vectors allocated by - * KINAllocVectors, and the memory lmem for the linear solver - * (deallocated by a call to lfree). - */ - -void KINFree(void **kinmem) -{ - KINMem kin_mem; - - if (*kinmem == NULL) return; - - kin_mem = (KINMem) (*kinmem); - KINFreeVectors(kin_mem); - - /* call lfree if non-NULL */ - - if (kin_mem->kin_lfree != NULL) kin_mem->kin_lfree(kin_mem); - - free(*kinmem); - *kinmem = NULL; -} - -/* - * ================================================================= - * PRIVATE FUNCTIONS - * ================================================================= - */ - -/* - * Function : KINCheckNvector - * - * This routine checks if all required vector operations are - * implemented (excluding those required by KINConstraint). If all - * necessary operations are present, then KINCheckNvector returns - * SUNTRUE. Otherwise, SUNFALSE is returned. - */ - -static booleantype KINCheckNvector(N_Vector tmpl) -{ - if ((tmpl->ops->nvclone == NULL) || - (tmpl->ops->nvdestroy == NULL) || - (tmpl->ops->nvlinearsum == NULL) || - (tmpl->ops->nvprod == NULL) || - (tmpl->ops->nvdiv == NULL) || - (tmpl->ops->nvscale == NULL) || - (tmpl->ops->nvabs == NULL) || - (tmpl->ops->nvinv == NULL) || - (tmpl->ops->nvmaxnorm == NULL) || - (tmpl->ops->nvmin == NULL) || - (tmpl->ops->nvwl2norm == NULL)) return(SUNFALSE); - else return(SUNTRUE); -} - -/* - * ----------------------------------------------------------------- - * Memory allocation/deallocation - * ----------------------------------------------------------------- - */ - -/* - * Function : KINAllocVectors - * - * This routine allocates the KINSol vectors. If all memory - * allocations are successful, KINAllocVectors returns SUNTRUE. - * Otherwise all allocated memory is freed and KINAllocVectors - * returns SUNFALSE. - */ - -static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl) -{ - /* allocate unew, fval, pp, vtemp1 and vtemp2. */ - /* allocate df, dg, q, for Anderson Acceleration, Broyden and EN */ - - if (kin_mem->kin_unew == NULL) { - kin_mem->kin_unew = N_VClone(tmpl); - if (kin_mem->kin_unew == NULL) return(SUNFALSE); - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_fval == NULL) { - kin_mem->kin_fval = N_VClone(tmpl); - if (kin_mem->kin_fval == NULL) { - N_VDestroy(kin_mem->kin_unew); - kin_mem->kin_liw -= kin_mem->kin_liw1; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_pp == NULL) { - kin_mem->kin_pp = N_VClone(tmpl); - if (kin_mem->kin_pp == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - kin_mem->kin_liw -= 2*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 2*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_vtemp1 == NULL) { - kin_mem->kin_vtemp1 = N_VClone(tmpl); - if (kin_mem->kin_vtemp1 == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - kin_mem->kin_liw -= 3*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 3*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_vtemp2 == NULL) { - kin_mem->kin_vtemp2 = N_VClone(tmpl); - if (kin_mem->kin_vtemp2 == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - kin_mem->kin_liw -= 4*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 4*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - /* Vectors for Anderson acceleration */ - - if (kin_mem->kin_m_aa) { - - if (kin_mem->kin_R_aa == NULL) { - kin_mem->kin_R_aa = (realtype *) malloc((kin_mem->kin_m_aa*kin_mem->kin_m_aa) * sizeof(realtype)); - if (kin_mem->kin_R_aa == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_gamma_aa == NULL) { - kin_mem->kin_gamma_aa = (realtype *) malloc(kin_mem->kin_m_aa * sizeof(realtype)); - if (kin_mem->kin_gamma_aa == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_ipt_map == NULL) { - kin_mem->kin_ipt_map = (long int *) malloc(kin_mem->kin_m_aa * sizeof(long int)); - if (kin_mem->kin_ipt_map == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_cv == NULL) { - kin_mem->kin_cv = (realtype *) malloc(2 * (kin_mem->kin_m_aa+1) * sizeof(realtype)); - if (kin_mem->kin_cv == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_Xv == NULL) { - kin_mem->kin_Xv = (N_Vector *) malloc(2 * (kin_mem->kin_m_aa+1) * sizeof(N_Vector)); - if (kin_mem->kin_Xv == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_fold_aa == NULL) { - kin_mem->kin_fold_aa = N_VClone(tmpl); - if (kin_mem->kin_fold_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_gold_aa == NULL) { - kin_mem->kin_gold_aa = N_VClone(tmpl); - if (kin_mem->kin_gold_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - kin_mem->kin_liw -= 6*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 6*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_df_aa == NULL) { - kin_mem->kin_df_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_df_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - kin_mem->kin_liw -= 7*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 7*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - - if (kin_mem->kin_dg_aa == NULL) { - kin_mem->kin_dg_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_dg_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_liw -= (7 + kin_mem->kin_m_aa) * kin_mem->kin_liw1; - kin_mem->kin_lrw -= (7 + kin_mem->kin_m_aa) * kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - - if (kin_mem->kin_q_aa == NULL) { - kin_mem->kin_q_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_q_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - N_VDestroyVectorArray(kin_mem->kin_dg_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_liw -= (7 + 2 * kin_mem->kin_m_aa) * kin_mem->kin_liw1; - kin_mem->kin_lrw -= (7 + 2 * kin_mem->kin_m_aa) * kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - } - - return(SUNTRUE); -} - -/* - * KINFreeVectors - * - * This routine frees the KINSol vectors allocated by - * KINAllocVectors. - */ - -static void KINFreeVectors(KINMem kin_mem) -{ - if (kin_mem->kin_unew != NULL) { - N_VDestroy(kin_mem->kin_unew); - kin_mem->kin_unew = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_fval != NULL) { - N_VDestroy(kin_mem->kin_fval); - kin_mem->kin_fval = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_pp != NULL) { - N_VDestroy(kin_mem->kin_pp); - kin_mem->kin_pp = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_vtemp1 != NULL) { - N_VDestroy(kin_mem->kin_vtemp1); - kin_mem->kin_vtemp1 = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_vtemp2 != NULL) { - N_VDestroy(kin_mem->kin_vtemp2); - kin_mem->kin_vtemp2 = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_gval != NULL) { - N_VDestroy(kin_mem->kin_gval); - kin_mem->kin_gval = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_R_aa != NULL) { - free(kin_mem->kin_R_aa); - kin_mem->kin_R_aa = NULL; - } - - if (kin_mem->kin_gamma_aa != NULL) { - free(kin_mem->kin_gamma_aa); - kin_mem->kin_gamma_aa = NULL; - } - - if (kin_mem->kin_ipt_map != NULL) { - free(kin_mem->kin_ipt_map); - kin_mem->kin_ipt_map = NULL; - } - - if (kin_mem->kin_cv != NULL) { - free(kin_mem->kin_cv); - kin_mem->kin_cv = NULL; - } - - if (kin_mem->kin_Xv != NULL) { - free(kin_mem->kin_Xv); - kin_mem->kin_Xv = NULL; - } - - if (kin_mem->kin_fold_aa != NULL) { - N_VDestroy(kin_mem->kin_fold_aa); - kin_mem->kin_fold_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_gold_aa != NULL) { - N_VDestroy(kin_mem->kin_gold_aa); - kin_mem->kin_gold_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_df_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_df_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_dg_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_dg_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_dg_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_q_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_q_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_q_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_constraints != NULL) { - N_VDestroy(kin_mem->kin_constraints); - kin_mem->kin_constraints = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - return; -} - -/* - * ----------------------------------------------------------------- - * Initial setup - * ----------------------------------------------------------------- - */ - -/* - * KINSolInit - * - * KINSolInit initializes the problem for the specific input - * received in this call to KINSol (which calls KINSolInit). All - * problem specification inputs are checked for errors. If any error - * occurs during initialization, it is reported to the file whose - * file pointer is errfp. - * - * The possible return values for KINSolInit are: - * KIN_SUCCESS : indicates a normal initialization - * - * KIN_ILL_INPUT : indicates that an input error has been found - * - * KIN_INITIAL_GUESS_OK : indicates that the guess uu - * satisfied the system func(uu) = 0 - * within the tolerances specified - */ - -static int KINSolInit(KINMem kin_mem) -{ - int retval; - realtype fmax; - - /* check for illegal input parameters */ - - if (kin_mem->kin_uu == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_UU_NULL); - return(KIN_ILL_INPUT); - } - - /* check for valid strategy */ - - if ( (kin_mem->kin_globalstrategy != KIN_NONE) && - (kin_mem->kin_globalstrategy != KIN_LINESEARCH) && - (kin_mem->kin_globalstrategy != KIN_PICARD) && - (kin_mem->kin_globalstrategy != KIN_FP) ) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_GLSTRAT); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_uscale == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_USCALE); - return(KIN_ILL_INPUT); - } - - if (N_VMin(kin_mem->kin_uscale) <= ZERO){ - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_USCALE_NONPOSITIVE); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_fscale == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_FSCALE); - return(KIN_ILL_INPUT); - } - - if (N_VMin(kin_mem->kin_fscale) <= ZERO){ - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_FSCALE_NONPOSITIVE); - return(KIN_ILL_INPUT); - } - - if ( (kin_mem->kin_constraints != NULL) && - ( (kin_mem->kin_globalstrategy == KIN_PICARD) || - (kin_mem->kin_globalstrategy == KIN_FP) ) ) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_CONSTRAINTS_NOTOK); - return(KIN_ILL_INPUT); - } - - - /* set the constraints flag */ - - if (kin_mem->kin_constraints == NULL) - kin_mem->kin_constraintsSet = SUNFALSE; - else { - kin_mem->kin_constraintsSet = SUNTRUE; - if ((kin_mem->kin_constraints->ops->nvconstrmask == NULL) || - (kin_mem->kin_constraints->ops->nvminquotient == NULL)) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_NVECTOR); - return(KIN_ILL_INPUT); - } - } - - /* check the initial guess uu against the constraints */ - - if (kin_mem->kin_constraintsSet) { - if (!N_VConstrMask(kin_mem->kin_constraints, kin_mem->kin_uu, kin_mem->kin_vtemp1)) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_INITIAL_CNSTRNT); - return(KIN_ILL_INPUT); - } - } - - /* all error checking is complete at this point */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSolInit", INFO_TOL, kin_mem->kin_scsteptol, kin_mem->kin_fnormtol); - - /* calculate the default value for mxnewtstep (maximum Newton step) */ - - if (kin_mem->kin_mxnstepin == ZERO) kin_mem->kin_mxnewtstep = THOUSAND * N_VWL2Norm(kin_mem->kin_uu, kin_mem->kin_uscale); - else kin_mem->kin_mxnewtstep = kin_mem->kin_mxnstepin; - - if (kin_mem->kin_mxnewtstep < ONE) kin_mem->kin_mxnewtstep = ONE; - - /* additional set-up for inexact linear solvers */ - - if (kin_mem->kin_inexact_ls) { - - /* set up the coefficients for the eta calculation */ - - kin_mem->kin_callForcingTerm = (kin_mem->kin_etaflag != KIN_ETACONSTANT); - - /* this value is always used for choice #1 */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE1) kin_mem->kin_eta_alpha = (ONE + SUNRsqrt(FIVE)) * HALF; - - /* initial value for eta set to 0.5 for other than the - KIN_ETACONSTANT option */ - - if (kin_mem->kin_etaflag != KIN_ETACONSTANT) kin_mem->kin_eta = HALF; - - /* disable residual monitoring if using an inexact linear solver */ - - kin_mem->kin_noResMon = SUNTRUE; - - } else { - - kin_mem->kin_callForcingTerm = SUNFALSE; - - } - - /* initialize counters */ - - kin_mem->kin_nfe = kin_mem->kin_nnilset = kin_mem->kin_nnilset_sub = kin_mem->kin_nni = kin_mem->kin_nbcf = kin_mem->kin_nbktrk = 0; - - /* see if the initial guess uu satisfies the nonlinear system */ - retval = kin_mem->kin_func(kin_mem->kin_uu, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - if (retval < 0) { - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSolInit", - MSG_SYSFUNC_FAILED); - return(KIN_SYSFUNC_FAIL); - } else if (retval > 0) { - KINProcessError(kin_mem, KIN_FIRST_SYSFUNC_ERR, "KINSOL", "KINSolInit", - MSG_SYSFUNC_FIRST); - return(KIN_FIRST_SYSFUNC_ERR); - } - - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); - if (fmax <= (POINT01 * kin_mem->kin_fnormtol)) { - kin_mem->kin_fnorm = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - return(KIN_INITIAL_GUESS_OK); - } - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINSolInit", INFO_FMAX, fmax); - - /* initialize the linear solver if linit != NULL */ - - if (kin_mem->kin_linit != NULL) { - retval = kin_mem->kin_linit(kin_mem); - if (retval != 0) { - KINProcessError(kin_mem, KIN_LINIT_FAIL, "KINSOL", "KINSolInit", MSG_LINIT_FAIL); - return(KIN_LINIT_FAIL); - } - } - - /* initialize the L2 (Euclidean) norms of f for the linear iteration steps */ - - kin_mem->kin_fnorm = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - kin_mem->kin_f1norm = HALF * kin_mem->kin_fnorm * kin_mem->kin_fnorm; - kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSolInit", - INFO_NNI, kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* problem has now been successfully initialized */ - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Step functions - * ----------------------------------------------------------------- - */ - -/* - * KINLinSolDrv - * - * This routine handles the process of solving for the approximate - * solution of the Newton equations in the Newton iteration. - * Subsequent routines handle the nonlinear aspects of its - * application. - */ - -static int KINLinSolDrv(KINMem kin_mem) -{ - N_Vector x, b; - int retval; - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset) >= kin_mem->kin_msbset) { - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_update_fnorm_sub = SUNTRUE; - } - - for(;;){ - - kin_mem->kin_jacCurrent = SUNFALSE; - - if ((kin_mem->kin_sthrsh > ONEPT5) && (kin_mem->kin_lsetup != NULL)) { - retval = kin_mem->kin_lsetup(kin_mem); - kin_mem->kin_jacCurrent = SUNTRUE; - kin_mem->kin_nnilset = kin_mem->kin_nni; - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - if (retval != 0) return(KIN_LSETUP_FAIL); - } - - /* rename vectors for readability */ - - b = kin_mem->kin_unew; - x = kin_mem->kin_pp; - - /* load b with the current value of -fval */ - - N_VScale(-ONE, kin_mem->kin_fval, b); - - /* call the generic 'lsolve' routine to solve the system Jx = b */ - - retval = kin_mem->kin_lsolve(kin_mem, x, b, &(kin_mem->kin_sJpnorm), - &(kin_mem->kin_sFdotJp)); - - if (retval == 0) return(KIN_SUCCESS); - else if (retval < 0) return(KIN_LSOLVE_FAIL); - else if ((kin_mem->kin_lsetup == NULL) || (kin_mem->kin_jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY); - - /* loop back only if the linear solver setup is in use - and Jacobian information is not current */ - - kin_mem->kin_sthrsh = TWO; - - } -} - -/* - * KINFullNewton - * - * This routine is the main driver for the Full Newton - * algorithm. Its purpose is to compute unew = uu + pp in the - * direction pp from uu, taking the full Newton step. The - * step may be constrained if the constraint conditions are - * violated, or if the norm of pp is greater than mxnewtstep. - */ - -static int KINFullNewton(KINMem kin_mem, realtype *fnormp, realtype *f1normp, - booleantype *maxStepTaken) -{ - realtype pnorm, ratio; - booleantype fOK; - int ircvr, retval; - - *maxStepTaken = SUNFALSE; - pnorm = N_VWL2Norm(kin_mem->kin_pp, kin_mem->kin_uscale); - ratio = ONE; - if (pnorm > kin_mem->kin_mxnewtstep) { - ratio = kin_mem->kin_mxnewtstep / pnorm; - N_VScale(ratio, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm = kin_mem->kin_mxnewtstep; - } - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm); - - /* If constraints are active, then constrain the step accordingly */ - - kin_mem->kin_stepl = pnorm; - kin_mem->kin_stepmul = ONE; - if (kin_mem->kin_constraintsSet) { - retval = KINConstraint(kin_mem); - if (retval == CONSTR_VIOLATED) { - /* Apply stepmul set in KINConstraint */ - ratio *= kin_mem->kin_stepmul; - N_VScale(kin_mem->kin_stepmul, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm *= kin_mem->kin_stepmul; - kin_mem->kin_stepl = pnorm; - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm); - if (pnorm <= kin_mem->kin_scsteptol) { - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - return(STEP_TOO_SMALL);} - } - } - - /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */ - - fOK = SUNFALSE; - - for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) { - - /* compute the iterate unew = uu + pp */ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - - /* evaluate func(unew) and its norm, and return */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - /* if func was successful, accept pp */ - if (retval == 0) {fOK = SUNTRUE; break;} - - /* if func failed unrecoverably, give up */ - else if (retval < 0) return(KIN_SYSFUNC_FAIL); - - /* func failed recoverably; cut step in half and try again */ - ratio *= HALF; - N_VScale(HALF, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm *= HALF; - kin_mem->kin_stepl = pnorm; - } - - /* If func() failed recoverably MAX_RECVR times, give up */ - - if (!fOK) return(KIN_REPTD_SYSFUNC_ERR); - - /* Evaluate function norms */ - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - /* scale sFdotJp and sJpnorm by ratio for later use in KINForcingTerm */ - - kin_mem->kin_sFdotJp *= ratio; - kin_mem->kin_sJpnorm *= ratio; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FNORM, "KINSOL", "KINFullNewton", INFO_FNORM, *fnormp); - - if (pnorm > (POINT99 * kin_mem->kin_mxnewtstep)) *maxStepTaken = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * KINLineSearch - * - * The routine KINLineSearch implements the LineSearch algorithm. - * Its purpose is to find unew = uu + rl * pp in the direction pp - * from uu so that: - * t - * func(unew) <= func(uu) + alpha * g (unew - uu) (alpha = 1.e-4) - * - * and - * t - * func(unew) >= func(uu) + beta * g (unew - uu) (beta = 0.9) - * - * where 0 < rlmin <= rl <= rlmax. - * - * Note: - * mxnewtstep - * rlmax = ---------------- if uu+pp is feasible - * ||uscale*pp||_L2 - * - * rlmax = 1 otherwise - * - * and - * - * scsteptol - * rlmin = -------------------------- - * || pp || - * || -------------------- ||_L-infinity - * || (1/uscale + SUNRabs(uu)) || - * - * - * If the system function fails unrecoverably at any time, KINLineSearch - * returns KIN_SYSFUNC_FAIL which will halt the solver. - * - * We attempt to corect recoverable system function failures only before - * the alpha-condition loop; i.e. when the solution is updated with the - * full Newton step (possibly reduced due to constraint violations). - * Once we find a feasible pp, we assume that any update up to pp is - * feasible. - * - * If the step size is limited due to constraint violations and/or - * recoverable system function failures, we set rlmax=1 to ensure - * that the update remains feasible during the attempts to enforce - * the beta-condition (this is not an issue while enforcing the alpha - * condition, as rl can only decrease from 1 at that stage) - */ - -static int KINLineSearch(KINMem kin_mem, realtype *fnormp, realtype *f1normp, - booleantype *maxStepTaken) -{ - realtype pnorm, ratio, slpi, rlmin, rlength, rl, rlmax, rldiff; - realtype rltmp, rlprev, pt1trl, f1nprv, rllo, rlinc, alpha, beta; - realtype alpha_cond, beta_cond, rl_a, tmp1, rl_b, tmp2, disc; - int ircvr, nbktrk_l, retval; - booleantype firstBacktrack, fOK; - - /* Initializations */ - - nbktrk_l = 0; /* local backtracking counter */ - ratio = ONE; /* step change ratio */ - alpha = POINT0001; - beta = POINT9; - - firstBacktrack = SUNTRUE; - *maxStepTaken = SUNFALSE; - - rlprev = f1nprv = ZERO; - - /* Compute length of Newton step */ - - pnorm = N_VWL2Norm(kin_mem->kin_pp, kin_mem->kin_uscale); - rlmax = kin_mem->kin_mxnewtstep / pnorm; - kin_mem->kin_stepl = pnorm; - - /* If the full Newton step is too large, set it to the maximum allowable value */ - - if(pnorm > kin_mem->kin_mxnewtstep ) { - ratio = kin_mem->kin_mxnewtstep / pnorm; - N_VScale(ratio, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm = kin_mem->kin_mxnewtstep; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - } - - /* If constraint checking is activated, check and correct violations */ - - kin_mem->kin_stepmul = ONE; - - if(kin_mem->kin_constraintsSet){ - retval = KINConstraint(kin_mem); - if(retval == CONSTR_VIOLATED){ - /* Apply stepmul set in KINConstraint */ - N_VScale(kin_mem->kin_stepmul, kin_mem->kin_pp, kin_mem->kin_pp); - ratio *= kin_mem->kin_stepmul; - pnorm *= kin_mem->kin_stepmul; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - if (kin_mem->kin_printfl > 0) KINPrintInfo(kin_mem, PRNT_PNORM1, "KINSOL", "KINLineSearch", INFO_PNORM1, pnorm); - if (pnorm <= kin_mem->kin_scsteptol) { - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - return(STEP_TOO_SMALL);} - } - } - - /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */ - - fOK = SUNFALSE; - - for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) { - - /* compute the iterate unew = uu + pp */ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - - /* evaluate func(unew) and its norm, and return */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - /* if func was successful, accept pp */ - if (retval == 0) {fOK = SUNTRUE; break;} - - /* if func failed unrecoverably, give up */ - else if (retval < 0) return(KIN_SYSFUNC_FAIL); - - /* func failed recoverably; cut step in half and try again */ - N_VScale(HALF, kin_mem->kin_pp, kin_mem->kin_pp); - ratio *= HALF; - pnorm *= HALF; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - - } - - /* If func() failed recoverably MAX_RECVR times, give up */ - - if (!fOK) return(KIN_REPTD_SYSFUNC_ERR); - - /* Evaluate function norms */ - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp) ; - - /* Estimate the line search value rl (lambda) to satisfy both ALPHA and BETA conditions */ - - slpi = kin_mem->kin_sFdotJp * ratio; - rlength = KINScSNorm(kin_mem, kin_mem->kin_pp, kin_mem->kin_uu); - rlmin = (kin_mem->kin_scsteptol) / rlength; - rl = ONE; - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_LAM, "KINSOL", "KINLineSearch", INFO_LAM, rlmin, kin_mem->kin_f1norm, pnorm); - - /* Loop until the ALPHA condition is satisfied. Terminate if rl becomes too small */ - - for(;;) { - - /* Evaluate test quantity */ - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_ALPHA, "KINSOL", "KINLinesearch", - INFO_ALPHA, *fnormp, *f1normp, alpha_cond, rl); - - /* If ALPHA condition is satisfied, break out from loop */ - - if ((*f1normp) <= alpha_cond) break; - - /* Backtracking. Use quadratic fit the first time and cubic fit afterwards. */ - - if (firstBacktrack) { - - rltmp = -slpi / (TWO * ((*f1normp) - kin_mem->kin_f1norm - slpi)); - firstBacktrack = SUNFALSE; - - } else { - - tmp1 = (*f1normp) - kin_mem->kin_f1norm - (rl * slpi); - tmp2 = f1nprv - kin_mem->kin_f1norm - (rlprev * slpi); - rl_a = ((ONE / (rl * rl)) * tmp1) - ((ONE / (rlprev * rlprev)) * tmp2); - rl_b = ((-rlprev / (rl * rl)) * tmp1) + ((rl / (rlprev * rlprev)) * tmp2); - tmp1 = ONE / (rl - rlprev); - rl_a *= tmp1; - rl_b *= tmp1; - disc = (rl_b * rl_b) - (THREE * rl_a * slpi); - - if (SUNRabs(rl_a) < kin_mem->kin_uround) { /* cubic is actually just a quadratic (rl_a ~ 0) */ - rltmp = -slpi / (TWO * rl_b); - } else { /* real cubic */ - rltmp = (-rl_b + SUNRsqrt(disc)) / (THREE * rl_a); - } - } - if (rltmp > (HALF * rl)) rltmp = HALF * rl; - - /* Set new rl (do not allow a reduction by a factor larger than 10) */ - - rlprev = rl; - f1nprv = (*f1normp); - pt1trl = POINT1 * rl; - rl = SUNMAX(pt1trl, rltmp); - nbktrk_l++; - - /* Update unew and re-evaluate function */ - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp) ; - - /* Check if rl (lambda) is too small */ - - if (rl < rlmin) { - /* unew sufficiently distinct from uu cannot be found. - copy uu into unew (step remains unchanged) and - return STEP_TOO_SMALL */ - N_VScale(ONE, kin_mem->kin_uu, kin_mem->kin_unew); - return(STEP_TOO_SMALL); - } - - } /* end ALPHA condition loop */ - - - /* ALPHA condition is satisfied. Now check the BETA condition */ - - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if ((*f1normp) < beta_cond) { - - /* BETA condition not satisfied */ - - if ((rl == ONE) && (pnorm < kin_mem->kin_mxnewtstep)) { - - do { - - rlprev = rl; - f1nprv = *f1normp; - rl = SUNMIN((TWO * rl), rlmax); - nbktrk_l++; - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_BETA, "KINSOL", "KINLineSearch", - INFO_BETA, *f1normp, beta_cond, rl); - - } while (((*f1normp) <= alpha_cond) && - ((*f1normp) < beta_cond) && (rl < rlmax)); - - } /* end if (rl == ONE) block */ - - if ((rl < ONE) || ((rl > ONE) && (*f1normp > alpha_cond))) { - - rllo = SUNMIN(rl, rlprev); - rldiff = SUNRabs(rlprev - rl); - - do { - - rlinc = HALF * rldiff; - rl = rllo + rlinc; - nbktrk_l++; - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_ALPHABETA, "KINSOL", "KINLineSearch", - INFO_ALPHABETA, *f1normp, alpha_cond, beta_cond, rl); - - if ((*f1normp) > alpha_cond) rldiff = rlinc; - else if (*f1normp < beta_cond) { - rllo = rl; - rldiff = rldiff - rlinc; - } - - } while ((*f1normp > alpha_cond) || - ((*f1normp < beta_cond) && (rldiff >= rlmin))); - - if ( (*f1normp < beta_cond) || ((rldiff < rlmin) && (*f1normp > alpha_cond)) ) { - - /* beta condition could not be satisfied or rldiff too small - and alpha_cond not satisfied, so set unew to last u value - that satisfied the alpha condition and continue */ - - N_VLinearSum(ONE, kin_mem->kin_uu, rllo, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - /* increment beta-condition failures counter */ - - kin_mem->kin_nbcf++; - - } - - } /* end of if (rl < ONE) block */ - - } /* end of if (f1normp < beta_cond) block */ - - /* Update number of backtracking operations */ - - kin_mem->kin_nbktrk += nbktrk_l; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_ADJ, "KINSOL", "KINLineSearch", INFO_ADJ, nbktrk_l); - - /* scale sFdotJp and sJpnorm by rl * ratio for later use in KINForcingTerm */ - - kin_mem->kin_sFdotJp = kin_mem->kin_sFdotJp * rl * ratio; - kin_mem->kin_sJpnorm = kin_mem->kin_sJpnorm * rl * ratio; - - if ((rl * pnorm) > (POINT99 * kin_mem->kin_mxnewtstep)) *maxStepTaken = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * Function : KINConstraint - * - * This routine checks if the proposed solution vector uu + pp - * violates any constraints. If a constraint is violated, then the - * scalar stepmul is determined such that uu + stepmul * pp does - * not violate any constraints. - * - * Note: This routine is called by the functions - * KINLineSearch and KINFullNewton. - */ - -static int KINConstraint(KINMem kin_mem) -{ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_vtemp1); - - /* if vtemp1[i] violates constraint[i] then vtemp2[i] = 1 - else vtemp2[i] = 0 (vtemp2 is the mask vector) */ - - if(N_VConstrMask(kin_mem->kin_constraints, kin_mem->kin_vtemp1, kin_mem->kin_vtemp2)) return(KIN_SUCCESS); - - /* vtemp1[i] = SUNRabs(pp[i]) */ - - N_VAbs(kin_mem->kin_pp, kin_mem->kin_vtemp1); - - /* consider vtemp1[i] only if vtemp2[i] = 1 (constraint violated) */ - - N_VProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - N_VAbs(kin_mem->kin_uu, kin_mem->kin_vtemp2); - kin_mem->kin_stepmul = POINT9 * N_VMinQuotient(kin_mem->kin_vtemp2, kin_mem->kin_vtemp1); - - return(CONSTR_VIOLATED); -} - -/* - * ----------------------------------------------------------------- - * Stopping tests - * ----------------------------------------------------------------- - */ - -/* - * KINStop - * - * This routine checks the current iterate unew to see if the - * system func(unew) = 0 is satisfied by a variety of tests. - * - * strategy is one of KIN_NONE or KIN_LINESEARCH - * sflag is one of KIN_SUCCESS, STEP_TOO_SMALL - */ - -static int KINStop(KINMem kin_mem, booleantype maxStepTaken, int sflag) -{ - realtype fmax, rlength, omexp; - N_Vector delta; - - /* Check for too small a step */ - - if (sflag == STEP_TOO_SMALL) { - - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(RETRY_ITERATION); - } else { - /* Give up */ - if (kin_mem->kin_globalstrategy == KIN_NONE) return(KIN_STEP_LT_STPTOL); - else return(KIN_LINESEARCH_NONCONV); - } - - } - - /* Check tolerance on scaled function norm at the current iterate */ - - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINStop", INFO_FMAX, fmax); - - if (fmax <= kin_mem->kin_fnormtol) return(KIN_SUCCESS); - - /* Check if the scaled distance between the last two steps is too small */ - /* NOTE: pp used as work space to store this distance */ - - delta = kin_mem->kin_pp; - N_VLinearSum(ONE, kin_mem->kin_unew, -ONE, kin_mem->kin_uu, delta); - rlength = KINScSNorm(kin_mem, delta, kin_mem->kin_unew); - - if (rlength <= kin_mem->kin_scsteptol) { - - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(CONTINUE_ITERATIONS); - } else { - /* give up */ - return(KIN_STEP_LT_STPTOL); - } - - } - - /* Check if the maximum number of iterations is reached */ - - if (kin_mem->kin_nni >= kin_mem->kin_mxiter) return(KIN_MAXITER_REACHED); - - /* Check for consecutive number of steps taken of size mxnewtstep - and if not maxStepTaken, then set ncscmx to 0 */ - - if (maxStepTaken) kin_mem->kin_ncscmx++; - else kin_mem->kin_ncscmx = 0; - - if (kin_mem->kin_ncscmx == 5) return(KIN_MXNEWT_5X_EXCEEDED); - - /* Proceed according to the type of linear solver used */ - - if (kin_mem->kin_inexact_ls) { - - /* We're doing inexact Newton. - Load threshold for reevaluating the Jacobian. */ - - kin_mem->kin_sthrsh = rlength; - - } else if (!(kin_mem->kin_noResMon)) { - - /* We're doing modified Newton and the user did not disable residual monitoring. - Check if it is time to monitor residual. */ - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset_sub) >= kin_mem->kin_msbset_sub) { - - /* Residual monitoring needed */ - - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - - /* If indicated, estimate new OMEGA value */ - if (kin_mem->kin_eval_omega) { - omexp = SUNMAX(ZERO,((kin_mem->kin_fnorm)/(kin_mem->kin_fnormtol))-ONE); - kin_mem->kin_omega = (omexp > TWELVE)? kin_mem->kin_omega_max : SUNMIN(kin_mem->kin_omega_min * SUNRexp(omexp), kin_mem->kin_omega_max); - } - /* Check if making satisfactory progress */ - - if (kin_mem->kin_fnorm > kin_mem->kin_omega * kin_mem->kin_fnorm_sub) { - /* Insufficient progress */ - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(CONTINUE_ITERATIONS); - } else { - /* Otherwise, we cannot do anything, so just return. */ - } - } else { - /* Sufficient progress */ - kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - kin_mem->kin_sthrsh = ONE; - } - - } else { - - /* Residual monitoring not needed */ - - /* Reset sthrsh */ - if (kin_mem->kin_retry_nni || kin_mem->kin_update_fnorm_sub) kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - if (kin_mem->kin_update_fnorm_sub) kin_mem->kin_update_fnorm_sub = SUNFALSE; - kin_mem->kin_sthrsh = ONE; - - } - - } - - /* if made it to here, then the iteration process is not finished - so return CONTINUE_ITERATIONS flag */ - - return(CONTINUE_ITERATIONS); -} - -/* - * KINForcingTerm - * - * This routine computes eta, the scaling factor in the linear - * convergence stopping tolerance eps when choice #1 or choice #2 - * forcing terms are used. Eta is computed here for all but the - * first iterative step, which is set to the default in routine - * KINSolInit. - * - * This routine was written by Homer Walker of Utah State - * University with subsequent modifications by Allan Taylor @ LLNL. - * - * It is based on the concepts of the paper 'Choosing the forcing - * terms in an inexact Newton method', SIAM J Sci Comput, 17 - * (1996), pp 16 - 32, or Utah State University Research Report - * 6/94/75 of the same title. - */ - -static void KINForcingTerm(KINMem kin_mem, realtype fnormp) -{ - realtype eta_max, eta_min, eta_safe, linmodel_norm; - - eta_max = POINT9; - eta_min = POINT0001; - eta_safe = HALF; - - /* choice #1 forcing term */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE1) { - - /* compute the norm of f + Jp , scaled L2 norm */ - - linmodel_norm = SUNRsqrt((kin_mem->kin_fnorm * kin_mem->kin_fnorm) + - (TWO * kin_mem->kin_sFdotJp) + - (kin_mem->kin_sJpnorm * kin_mem->kin_sJpnorm)); - - /* form the safeguarded for choice #1 */ - - eta_safe = SUNRpowerR(kin_mem->kin_eta, kin_mem->kin_eta_alpha); - kin_mem->kin_eta = SUNRabs(fnormp - linmodel_norm) / kin_mem->kin_fnorm; - } - - /* choice #2 forcing term */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE2) { - eta_safe = kin_mem->kin_eta_gamma * - SUNRpowerR(kin_mem->kin_eta, kin_mem->kin_eta_alpha); - - kin_mem->kin_eta = kin_mem->kin_eta_gamma * - SUNRpowerR((fnormp / kin_mem->kin_fnorm), kin_mem->kin_eta_alpha); - } - - /* apply safeguards */ - - if(eta_safe < POINT1) eta_safe = ZERO; - kin_mem->kin_eta = SUNMAX(kin_mem->kin_eta, eta_safe); - kin_mem->kin_eta = SUNMAX(kin_mem->kin_eta, eta_min); - kin_mem->kin_eta = SUNMIN(kin_mem->kin_eta, eta_max); - - return; -} - - -/* - * ----------------------------------------------------------------- - * Norm functions - * ----------------------------------------------------------------- - */ - -/* - * Function : KINScFNorm - * - * This routine computes the max norm for scaled vectors. The - * scaling vector is scale, and the vector of which the norm is to - * be determined is vv. The returned value, fnormval, is the - * resulting scaled vector norm. This routine uses N_Vector - * functions from the vector module. - */ - -static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale) -{ - N_VProd(scale, v, kin_mem->kin_vtemp1); - return(N_VMaxNorm(kin_mem->kin_vtemp1)); -} - -/* - * Function : KINScSNorm - * - * This routine computes the max norm of the scaled steplength, ss. - * Here ucur is the current step and usc is the u scale factor. - */ - -static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u) -{ - realtype length; - - N_VInv(kin_mem->kin_uscale, kin_mem->kin_vtemp1); - N_VAbs(u, kin_mem->kin_vtemp2); - N_VLinearSum(ONE, kin_mem->kin_vtemp1, ONE, kin_mem->kin_vtemp2, kin_mem->kin_vtemp1); - N_VDiv(v, kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - length = N_VMaxNorm(kin_mem->kin_vtemp1); - - return(length); -} - -/* - * ================================================================= - * KINSOL Verbose output functions - * ================================================================= - */ - -/* - * KINPrintInfo - * - * KINPrintInfo is a high level error handling function - * Based on the value info_code, it composes the info message and - * passes it to the info handler function. - */ - -void KINPrintInfo(KINMem kin_mem, - int info_code, const char *module, const char *fname, - const char *msgfmt, ...) -{ - va_list ap; - char msg[256], msg1[40]; - char retstr[30]; - int ret; - - /* Initialize argument processing - (msgfrmt is the last required argument) */ - - va_start(ap, msgfmt); - - if (info_code == PRNT_RETVAL) { - - /* If info_code = PRNT_RETVAL, decode the numeric value */ - - ret = va_arg(ap, int); - - switch(ret) { - case KIN_SUCCESS: - sprintf(retstr, "KIN_SUCCESS"); - break; - case KIN_SYSFUNC_FAIL: - sprintf(retstr, "KIN_SYSFUNC_FAIL"); - break; - case KIN_REPTD_SYSFUNC_ERR: - sprintf(retstr, "KIN_REPTD_SYSFUNC_ERR"); - break; - case KIN_STEP_LT_STPTOL: - sprintf(retstr, "KIN_STEP_LT_STPTOL"); - break; - case KIN_LINESEARCH_NONCONV: - sprintf(retstr, "KIN_LINESEARCH_NONCONV"); - break; - case KIN_LINESEARCH_BCFAIL: - sprintf(retstr, "KIN_LINESEARCH_BCFAIL"); - break; - case KIN_MAXITER_REACHED: - sprintf(retstr, "KIN_MAXITER_REACHED"); - break; - case KIN_MXNEWT_5X_EXCEEDED: - sprintf(retstr, "KIN_MXNEWT_5X_EXCEEDED"); - break; - case KIN_LINSOLV_NO_RECOVERY: - sprintf(retstr, "KIN_LINSOLV_NO_RECOVERY"); - break; - case KIN_LSETUP_FAIL: - sprintf(retstr, "KIN_PRECONDSET_FAILURE"); - break; - case KIN_LSOLVE_FAIL: - sprintf(retstr, "KIN_PRECONDSOLVE_FAILURE"); - break; - } - - /* Compose the message */ - - sprintf(msg1, msgfmt, ret); - sprintf(msg,"%s (%s)",msg1,retstr); - - - } else { - - /* Compose the message */ - - vsprintf(msg, msgfmt, ap); - - } - - /* call the info message handler */ - - kin_mem->kin_ihfun(module, fname, msg, kin_mem->kin_ih_data); - - /* finalize argument processing */ - - va_end(ap); - - return; -} - - -/* - * KINInfoHandler - * - * This is the default KINSOL info handling function. - * It sends the info message to the stream pointed to by kin_infofp - */ - -void KINInfoHandler(const char *module, const char *function, - char *msg, void *data) -{ - KINMem kin_mem; - - /* data points to kin_mem here */ - - kin_mem = (KINMem) data; - -#ifndef NO_FPRINTF_OUTPUT - if (kin_mem->kin_infofp != NULL) { - fprintf(kin_mem->kin_infofp,"\n[%s] %s\n",module, function); - fprintf(kin_mem->kin_infofp," %s\n",msg); - } -#endif - -} - -/* - * ================================================================= - * KINSOL Error Handling functions - * ================================================================= - */ - -/* - * KINProcessError - * - * KINProcessError is a high level error handling function. - * - If cv_mem==NULL it prints the error message to stderr. - * - Otherwise, it sets up and calls the error handling function - * pointed to by cv_ehfun. - */ - -void KINProcessError(KINMem kin_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...) -{ - va_list ap; - char msg[256]; - - /* Initialize the argument pointer variable - (msgfmt is the last required argument to KINProcessError) */ - - va_start(ap, msgfmt); - - /* Compose the message */ - - vsprintf(msg, msgfmt, ap); - - if (kin_mem == NULL) { /* We write to stderr */ -#ifndef NO_FPRINTF_OUTPUT - fprintf(stderr, "\n[%s ERROR] %s\n ", module, fname); - fprintf(stderr, "%s\n\n", msg); -#endif - - } else { /* We can call ehfun */ - kin_mem->kin_ehfun(error_code, module, fname, msg, kin_mem->kin_eh_data); - } - - /* Finalize argument processing */ - va_end(ap); - - return; -} - -/* - * KINErrHandler - * - * This is the default error handling function. - * It sends the error message to the stream pointed to by kin_errfp - */ - -void KINErrHandler(int error_code, const char *module, - const char *function, char *msg, void *data) -{ - KINMem kin_mem; - char err_type[10]; - - /* data points to kin_mem here */ - - kin_mem = (KINMem) data; - - if (error_code == KIN_WARNING) - sprintf(err_type,"WARNING"); - else - sprintf(err_type,"ERROR"); - -#ifndef NO_FPRINTF_OUTPUT - if (kin_mem->kin_errfp != NULL) { - fprintf(kin_mem->kin_errfp,"\n[%s %s] %s\n",module,err_type,function); - fprintf(kin_mem->kin_errfp," %s\n\n",msg); - } -#endif - - return; -} - - -/* - * ======================================================================= - * Picard and fixed point solvers - * ======================================================================= - */ - -/* - * KINPicardAA - * - * This routine is the main driver for the Picard iteration with - * acclerated fixed point. - */ - -static int KINPicardAA(KINMem kin_mem, long int *iterp, realtype *R, - realtype *gamma, realtype *fmaxptr) -{ - int retval, ret; - long int iter; - realtype fmax, epsmin, fnormp; - N_Vector delta, gval; - - delta = kin_mem->kin_vtemp1; - gval = kin_mem->kin_gval; - ret = CONTINUE_ITERATIONS; - fmax = kin_mem->kin_fnormtol + ONE; - iter = 0; - epsmin = ZERO; - fnormp = -ONE; - - N_VConst(ZERO, gval); - - /* if eps is to be bounded from below, set the bound */ - if (kin_mem->kin_inexact_ls && !(kin_mem->kin_noMinEps)) epsmin = POINT01 * kin_mem->kin_fnormtol; - - while (ret == CONTINUE_ITERATIONS) { - - iter++; - - /* Update the forcing term for the inexact linear solves */ - if (kin_mem->kin_inexact_ls) { - kin_mem->kin_eps = (kin_mem->kin_eta + kin_mem->kin_uround) * kin_mem->kin_fnorm; - if(!(kin_mem->kin_noMinEps)) kin_mem->kin_eps = SUNMAX(epsmin, kin_mem->kin_eps); - } - - /* evaluate g = uu - L^{-1}func(uu) and return if failed. - For Picard, assume that the fval vector has been filled - with an eval of the nonlinear residual prior to this call. */ - retval = KINPicardFcnEval(kin_mem, gval, kin_mem->kin_uu, kin_mem->kin_fval); - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - if (kin_mem->kin_m_aa == 0) { - N_VScale(ONE, gval, kin_mem->kin_unew); - } - else { /* use Anderson, if desired */ - N_VScale(ONE, kin_mem->kin_uu, kin_mem->kin_unew); - AndersonAcc(kin_mem, gval, delta, kin_mem->kin_unew, kin_mem->kin_uu, iter-1, R, gamma); - } - - /* Fill the Newton residual based on the new solution iterate */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - /* Evaluate function norms */ - fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); /* measure || F(x) ||_max */ - kin_mem->kin_fnorm = fmax; - *fmaxptr = fmax; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINPicardAA", INFO_FMAX, fmax); - - /* print the current iter, fnorm, and nfe values if printfl > 0 */ - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINPicardAA", INFO_NNI, iter, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* Check if the maximum number of iterations is reached */ - if (iter >= kin_mem->kin_mxiter) { - ret = KIN_MAXITER_REACHED; - } - if (fmax <= kin_mem->kin_fnormtol) { - ret = KIN_SUCCESS; - } - - /* Update with new iterate. */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - - if (ret == CONTINUE_ITERATIONS) { - /* evaluate eta by calling the forcing term routine */ - if (kin_mem->kin_callForcingTerm) KINForcingTerm(kin_mem, fnormp); - } - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - *iterp = iter; - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINPicardAA", INFO_RETVAL, ret); - - return(ret); -} - -/* - * KINPicardFcnEval - * - * This routine evaluates the Picard fixed point function - * using the linear solver, gval = u - L^{-1}F(u). - * The function assumes the user has defined L either through - * a user-supplied matvec if using a SPILS solver or through - * a supplied matrix if using a dense solver. This assumption is - * tested by a check on the strategy and the requisite functionality - * within the linear solve routines. - * - * This routine fills gval = uu - L^{-1}F(uu) given uu and fval = F(uu). - */ - -static int KINPicardFcnEval(KINMem kin_mem, N_Vector gval, N_Vector uval, N_Vector fval1) -{ - int retval; - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset) >= kin_mem->kin_msbset) { - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_update_fnorm_sub = SUNTRUE; - } - - for(;;){ - - kin_mem->kin_jacCurrent = SUNFALSE; - - if ((kin_mem->kin_sthrsh > ONEPT5) && (kin_mem->kin_lsetup != NULL)) { - retval = kin_mem->kin_lsetup(kin_mem); - kin_mem->kin_jacCurrent = SUNTRUE; - kin_mem->kin_nnilset = kin_mem->kin_nni; - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - if (retval != 0) return(KIN_LSETUP_FAIL); - } - - /* call the generic 'lsolve' routine to solve the system Lx = -fval - Note that we are using gval to hold x. */ - N_VScale(-ONE, fval1, fval1); - retval = kin_mem->kin_lsolve(kin_mem, gval, fval1, &(kin_mem->kin_sJpnorm), - &(kin_mem->kin_sFdotJp)); - - if (retval == 0) { - /* Update gval = uval + gval since gval = -L^{-1}F(uu) */ - N_VLinearSum(ONE, uval, ONE, gval, gval); - return(KIN_SUCCESS); - } - else if (retval < 0) return(KIN_LSOLVE_FAIL); - else if ((kin_mem->kin_lsetup == NULL) || (kin_mem->kin_jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY); - - /* loop back only if the linear solver setup is in use - and matrix information is not current */ - - kin_mem->kin_sthrsh = TWO; - } - -} - - -/* - * KINFP - * - * This routine is the main driver for the fixed point iteration with - * Anderson Acceleration. - */ - -static int KINFP(KINMem kin_mem) -{ - int retval; /* return value from user func */ - int ret; /* iteration status */ - realtype fmax; /* max norm of residual func */ - N_Vector delta; /* temporary workspace vector */ - - delta = kin_mem->kin_vtemp1; - ret = CONTINUE_ITERATIONS; - fmax = kin_mem->kin_fnormtol + ONE; - - /* initialize iteration count */ - kin_mem->kin_nni = 0; - - while (ret == CONTINUE_ITERATIONS) { - - /* update iteration count */ - kin_mem->kin_nni++; - - /* evaluate func(uu) and return if failed */ - retval = kin_mem->kin_func(kin_mem->kin_uu, kin_mem->kin_fval, - kin_mem->kin_user_data); - kin_mem->kin_nfe++; - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - /* compute new solution */ - if (kin_mem->kin_m_aa == 0) { - /* standard fixed point */ - N_VScale(ONE, kin_mem->kin_fval, kin_mem->kin_unew); - } else { - /* apply Anderson acceleration */ - AndersonAcc(kin_mem, kin_mem->kin_fval, delta, kin_mem->kin_unew, - kin_mem->kin_uu, kin_mem->kin_nni - 1, kin_mem->kin_R_aa, - kin_mem->kin_gamma_aa); - } - - /* compute change between iterations */ - N_VLinearSum(ONE, kin_mem->kin_unew, -ONE, kin_mem->kin_uu, delta); - - fmax = KINScFNorm(kin_mem, delta, kin_mem->kin_fscale); /* measure || g(x)-x || */ - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINFP", INFO_FMAX, fmax); - - kin_mem->kin_fnorm = fmax; - - /* print the current iter, fnorm, and nfe values if printfl > 0 */ - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINFP", INFO_NNI, - kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* Check if the maximum number of iterations is reached */ - if (kin_mem->kin_nni >= kin_mem->kin_mxiter) { - ret = KIN_MAXITER_REACHED; - } - if (fmax <= kin_mem->kin_fnormtol) { - ret = KIN_SUCCESS; - } - - if (ret == CONTINUE_ITERATIONS) { - /* Only update solution if taking a next iteration. */ - /* CSW Should put in a conditional to send back the newest iterate or - the one consistent with the fval */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - } - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINFP", INFO_RETVAL, ret); - - return(ret); -} - - -/* ----------------------------------------------------------------- - * Stopping tests - * ----------------------------------------------------------------- - */ - - -/* - * ======================================================================== - * Anderson Acceleration - * ======================================================================== - */ - -static int AndersonAcc(KINMem kin_mem, N_Vector gval, N_Vector fv, - N_Vector x, N_Vector xold, - long int iter, realtype *R, realtype *gamma) -{ - int retval; - long int i_pt, i, j, lAA; - long int *ipt_map; - realtype alfa; - realtype onembeta; - realtype a, b, temp, c, s; - - /* local shortcuts for fused vector operation */ - int nvec=0; - realtype* cv=kin_mem->kin_cv; - N_Vector* Xv=kin_mem->kin_Xv; - - ipt_map = kin_mem->kin_ipt_map; - i_pt = iter-1 - ((iter-1) / kin_mem->kin_m_aa) * kin_mem->kin_m_aa; - N_VLinearSum(ONE, gval, -ONE, xold, fv); - if (iter > 0) { - /* compute dg_new = gval - gval_old */ - N_VLinearSum(ONE, gval, -ONE, kin_mem->kin_gold_aa, kin_mem->kin_dg_aa[i_pt]); - /* compute df_new = fval - fval_old */ - N_VLinearSum(ONE, fv, -ONE, kin_mem->kin_fold_aa, kin_mem->kin_df_aa[i_pt]); - } - - N_VScale(ONE, gval, kin_mem->kin_gold_aa); - N_VScale(ONE, fv, kin_mem->kin_fold_aa); - - /* on first iteration, just do basic fixed-point update */ - if (iter == 0) { - N_VScale(ONE, gval, x); - return(0); - } - - /* update data structures based on current iteration index */ - - if (iter == 1) { - - /* second iteration */ - R[0] = SUNRsqrt(N_VDotProd(kin_mem->kin_df_aa[i_pt], kin_mem->kin_df_aa[i_pt])); - alfa = ONE/R[0]; - N_VScale(alfa, kin_mem->kin_df_aa[i_pt], kin_mem->kin_q_aa[i_pt]); - ipt_map[0] = 0; - - } else if (iter <= kin_mem->kin_m_aa) { - - /* another iteration before we've reached maa */ - N_VScale(ONE, kin_mem->kin_df_aa[i_pt], kin_mem->kin_vtemp2); - for (j=0; j < (iter-1); j++) { - ipt_map[j] = j; - R[(iter-1)*kin_mem->kin_m_aa+j] = N_VDotProd(kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - N_VLinearSum(ONE,kin_mem->kin_vtemp2, -R[(iter-1)*kin_mem->kin_m_aa+j], kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - } - R[(iter-1)*kin_mem->kin_m_aa+iter-1] = SUNRsqrt(N_VDotProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp2)); - N_VScale((1/R[(iter-1)*kin_mem->kin_m_aa+iter-1]), kin_mem->kin_vtemp2, kin_mem->kin_q_aa[i_pt]); - ipt_map[iter-1] = iter-1; - - } else { - - /* we've filled the acceleration subspace, so start recycling */ - - /* Delete left-most column vector from QR factorization */ - for (i=0; i < kin_mem->kin_m_aa-1; i++) { - a = R[(i+1)*kin_mem->kin_m_aa + i]; - b = R[(i+1)*kin_mem->kin_m_aa + i+1]; - temp = SUNRsqrt(a*a + b*b); - c = a / temp; - s = b / temp; - R[(i+1)*kin_mem->kin_m_aa + i] = temp; - R[(i+1)*kin_mem->kin_m_aa + i+1] = ZERO; - /* OK to re-use temp */ - if (i < kin_mem->kin_m_aa-1) { - for (j = i+2; j < kin_mem->kin_m_aa; j++) { - a = R[j*kin_mem->kin_m_aa + i]; - b = R[j*kin_mem->kin_m_aa + i+1]; - temp = c * a + s * b; - R[j*kin_mem->kin_m_aa + i+1] = -s*a + c*b; - R[j*kin_mem->kin_m_aa + i] = temp; - } - } - N_VLinearSum(c, kin_mem->kin_q_aa[i], s, kin_mem->kin_q_aa[i+1], kin_mem->kin_vtemp2); - N_VLinearSum(-s, kin_mem->kin_q_aa[i], c, kin_mem->kin_q_aa[i+1], kin_mem->kin_q_aa[i+1]); - N_VScale(ONE, kin_mem->kin_vtemp2, kin_mem->kin_q_aa[i]); - } - - /* Shift R to the left by one. */ - for (i = 1; i < kin_mem->kin_m_aa; i++) { - for (j = 0; j < kin_mem->kin_m_aa-1; j++) { - R[(i-1)*kin_mem->kin_m_aa + j] = R[i*kin_mem->kin_m_aa + j]; - } - } - - /* Add the new df vector */ - N_VScale(ONE, kin_mem->kin_df_aa[i_pt], kin_mem->kin_vtemp2); - for (j=0; j < (kin_mem->kin_m_aa-1); j++) { - R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+j] = N_VDotProd(kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - N_VLinearSum(ONE, kin_mem->kin_vtemp2, -R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+j], kin_mem->kin_q_aa[j],kin_mem->kin_vtemp2); - } - R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+kin_mem->kin_m_aa-1] = SUNRsqrt(N_VDotProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp2)); - N_VScale((1/R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+kin_mem->kin_m_aa-1]), kin_mem->kin_vtemp2, kin_mem->kin_q_aa[kin_mem->kin_m_aa-1]); - - /* Update the iteration map */ - j = 0; - for (i=i_pt+1; i < kin_mem->kin_m_aa; i++) - ipt_map[j++] = i; - for (i=0; i < (i_pt+1); i++) - ipt_map[j++] = i; - } - - /* Solve least squares problem and update solution */ - lAA = iter; - if (kin_mem->kin_m_aa < iter) lAA = kin_mem->kin_m_aa; - - retval = N_VDotProdMulti((int) lAA, fv, kin_mem->kin_q_aa, gamma); - if (retval != KIN_SUCCESS) return(KIN_VECTOROP_ERR); - - /* set arrays for fused vector operation */ - cv[0] = ONE; - Xv[0] = gval; - nvec = 1; - - for (i=lAA-1; i > -1; i--) { - for (j=i+1; j < lAA; j++) { - gamma[i] = gamma[i]-R[j*kin_mem->kin_m_aa+i]*gamma[j]; - } - gamma[i] = gamma[i]/R[i*kin_mem->kin_m_aa+i]; - - cv[nvec] = -gamma[i]; - Xv[nvec] = kin_mem->kin_dg_aa[ipt_map[i]]; - nvec += 1; - } - - /* if enabled, apply damping */ - if (kin_mem->kin_damping_aa) { - onembeta = (ONE - kin_mem->kin_beta_aa); - cv[nvec] = -onembeta; - Xv[nvec] = fv; - nvec += 1; - for (i = lAA - 1; i > -1; i--) { - cv[nvec] = onembeta * gamma[i]; - Xv[nvec] = kin_mem->kin_df_aa[ipt_map[i]]; - nvec += 1; - } - } - - /* update solution */ - retval = N_VLinearCombination(nvec, cv, Xv, x); - if (retval != KIN_SUCCESS) return(KIN_VECTOROP_ERR); - - return 0; -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c b/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c deleted file mode 100644 index 4bdff30790..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c +++ /dev/null @@ -1,582 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * This file contains implementations of routines for a - * band-block-diagonal preconditioner, i.e. a block-diagonal - * matrix with banded blocks, for use with KINSol and the - * KINLS linear solver interface. - * - * Note: With only one process, a banded matrix results - * rather than a b-b-d matrix with banded blocks. Diagonal - * blocking occurs at the process level. - * -----------------------------------------------------------------*/ - -#include -#include - -#include "kinsol_impl.h" -#include "kinsol_ls_impl.h" -#include "kinsol_bbdpre_impl.h" - -#include -#include - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) - -/* Prototypes of functions KINBBDPrecSetup and KINBBDPrecSolve */ -static int KINBBDPrecSetup(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - void *pdata); - -static int KINBBDPrecSolve(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - N_Vector vv, void *pdata); - -/* Prototype for KINBBDPrecFree */ -static int KINBBDPrecFree(KINMem kin_mem); - -/* Prototype for difference quotient jacobian calculation routine */ -static int KBBDDQJac(KBBDPrecData pdata, - N_Vector uu, N_Vector uscale, - N_Vector gu, N_Vector gtemp, N_Vector utemp); - -/*------------------------------------------------------------------ - user-callable functions - ------------------------------------------------------------------*/ - -/*------------------------------------------------------------------ - KINBBDPrecInit - ------------------------------------------------------------------*/ -int KINBBDPrecInit(void *kinmem, sunindextype Nlocal, - sunindextype mudq, sunindextype mldq, - sunindextype mukeep, sunindextype mlkeep, - realtype dq_rel_uu, - KINBBDLocalFn gloc, KINBBDCommFn gcomm) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - sunindextype muk, mlk, storage_mu, lrw1, liw1; - long int lrw, liw; - int flag; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - /* Test if the LS linear solver interface has been created */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Test compatibility of NVECTOR package with the BBD preconditioner */ - /* Note: Do NOT need to check for N_VScale since has already been checked for in KINSOL */ - if (kin_mem->kin_vtemp1->ops->nvgetarraypointer == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* Allocate data memory */ - pdata = NULL; - pdata = (KBBDPrecData) malloc(sizeof *pdata); - if (pdata == NULL) { - KINProcessError(kin_mem, KINLS_MEM_FAIL, - "KINBBDPRE", "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Set pointers to gloc and gcomm; load half-bandwidths */ - pdata->kin_mem = kinmem; - pdata->gloc = gloc; - pdata->gcomm = gcomm; - pdata->mudq = SUNMIN(Nlocal-1, SUNMAX(0, mudq)); - pdata->mldq = SUNMIN(Nlocal-1, SUNMAX(0, mldq)); - muk = SUNMIN(Nlocal-1, SUNMAX(0, mukeep)); - mlk = SUNMIN(Nlocal-1, SUNMAX(0, mlkeep)); - pdata->mukeep = muk; - pdata->mlkeep = mlk; - - /* Set extended upper half-bandwidth for PP (required for pivoting) */ - storage_mu = SUNMIN(Nlocal-1, muk+mlk); - - /* Allocate memory for preconditioner matrix */ - pdata->PP = NULL; - pdata->PP = SUNBandMatrixStorage(Nlocal, muk, mlk, storage_mu); - if (pdata->PP == NULL) { - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Allocate memory for temporary N_Vectors */ - pdata->zlocal = NULL; - pdata->zlocal = N_VNew_Serial(Nlocal); - if (pdata->zlocal == NULL) { - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->rlocal = NULL; - pdata->rlocal = N_VNewEmpty_Serial(Nlocal); /* empty vector */ - if (pdata->rlocal == NULL) { - N_VDestroy(pdata->zlocal); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv1 = NULL; - pdata->tempv1 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv1 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv2 = NULL; - pdata->tempv2 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv2 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv3 = NULL; - pdata->tempv3 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv3 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Allocate memory for banded linear solver */ - pdata->LS = NULL; - pdata->LS = SUNLinSol_Band(pdata->zlocal, pdata->PP); - if (pdata->LS == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* initialize band linear solver object */ - flag = SUNLinSolInitialize(pdata->LS); - if (flag != SUNLS_SUCCESS) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - SUNLinSolFree(pdata->LS); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_SUNLS_FAIL); - return(KINLS_SUNLS_FAIL); - } - - /* Set rel_uu based on input value dq_rel_uu (0 implies default) */ - pdata->rel_uu = (dq_rel_uu > ZERO) ? dq_rel_uu : SUNRsqrt(kin_mem->kin_uround); - - /* Store Nlocal to be used in KINBBDPrecSetup */ - pdata->n_local = Nlocal; - - /* Set work space sizes and initialize nge */ - pdata->rpwsize = 0; - pdata->ipwsize = 0; - if (kin_mem->kin_vtemp1->ops->nvspace) { - N_VSpace(kin_mem->kin_vtemp1, &lrw1, &liw1); - pdata->rpwsize += 3*lrw1; - pdata->ipwsize += 3*liw1; - } - if (pdata->zlocal->ops->nvspace) { - N_VSpace(pdata->zlocal, &lrw1, &liw1); - pdata->rpwsize += lrw1; - pdata->ipwsize += liw1; - } - if (pdata->rlocal->ops->nvspace) { - N_VSpace(pdata->rlocal, &lrw1, &liw1); - pdata->rpwsize += lrw1; - pdata->ipwsize += liw1; - } - if (pdata->PP->ops->space) { - flag = SUNMatSpace(pdata->PP, &lrw, &liw); - pdata->rpwsize += lrw; - pdata->ipwsize += liw; - } - if (pdata->LS->ops->space) { - flag = SUNLinSolSpace(pdata->LS, &lrw, &liw); - pdata->rpwsize += lrw; - pdata->ipwsize += liw; - } - pdata->nge = 0; - - /* make sure pdata is free from any previous allocations */ - if (kinls_mem->pfree != NULL) - kinls_mem->pfree(kin_mem); - - /* Point to the new pdata field in the LS memory */ - kinls_mem->pdata = pdata; - - /* Attach the pfree function */ - kinls_mem->pfree = KINBBDPrecFree; - - /* Attach preconditioner solve and setup functions */ - flag = KINSetPreconditioner(kinmem, KINBBDPrecSetup, - KINBBDPrecSolve); - - return(flag); -} - - -/*------------------------------------------------------------------ - KINBBDPrecGetWorkSpace - ------------------------------------------------------------------*/ -int KINBBDPrecGetWorkSpace(void *kinmem, - long int *lenrwBBDP, - long int *leniwBBDP) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) { - KINProcessError(kin_mem, KINLS_PMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_PMEM_NULL); - return(KINLS_PMEM_NULL); - } - pdata = (KBBDPrecData) kinls_mem->pdata; - - *lenrwBBDP = pdata->rpwsize; - *leniwBBDP = pdata->ipwsize; - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINBBDPrecGetNumGfnEvals - -------------------------------------------------------------------*/ -int KINBBDPrecGetNumGfnEvals(void *kinmem, - long int *ngevalsBBDP) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) { - KINProcessError(kin_mem, KINLS_PMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_PMEM_NULL); - return(KINLS_PMEM_NULL); - } - pdata = (KBBDPrecData) kinls_mem->pdata; - - *ngevalsBBDP = pdata->nge; - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINBBDPrecSetup - - KINBBDPrecSetup generates and factors a banded block of the - preconditioner matrix on each processor, via calls to the - user-supplied gloc and gcomm functions. It uses difference - quotient approximations to the Jacobian elements. - - KINBBDPrecSetup calculates a new Jacobian, stored in banded - matrix PP and does an LU factorization of P in place in PP. - - The parameters of KINBBDPrecSetup are as follows: - - uu is the current value of the dependent variable vector, - namely the solutin to func(uu)=0 - - uscale is the dependent variable scaling vector (i.e. uu) - - fval is the vector f(u) - - fscale is the function scaling vector - - bbd_data is the pointer to BBD data set by KINBBDInit. - - Note: The value to be returned by the KINBBDPrecSetup function - is a flag indicating whether it was successful. This value is: - 0 if successful, - > 0 for a recoverable error - step will be retried. - ------------------------------------------------------------------*/ -static int KINBBDPrecSetup(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - void *bbd_data) -{ - KBBDPrecData pdata; - KINMem kin_mem; - int retval; - - pdata = (KBBDPrecData) bbd_data; - - kin_mem = (KINMem) pdata->kin_mem; - - /* Call KBBDDQJac for a new Jacobian calculation and store in PP */ - retval = SUNMatZero(pdata->PP); - if (retval != 0) { - KINProcessError(kin_mem, -1, "KINBBDPRE", "KINBBDPrecSetup", - MSGBBD_SUNMAT_FAIL); - return(-1); - } - - retval = KBBDDQJac(pdata, uu, uscale, - pdata->tempv1, pdata->tempv2, pdata->tempv3); - if (retval != 0) { - KINProcessError(kin_mem, -1, "KINBBDPRE", "KINBBDPrecSetup", - MSGBBD_FUNC_FAILED); - return(-1); - } - - /* Do LU factorization of P and return error flag */ - retval = SUNLinSolSetup_Band(pdata->LS, pdata->PP); - return(retval); -} - -/*------------------------------------------------------------------ - INBBDPrecSolve - - KINBBDPrecSolve solves a linear system P z = r, with the - banded blocked preconditioner matrix P generated and factored - by KINBBDPrecSetup. Here, r comes in as vv and z is - returned in vv as well. - - The parameters for KINBBDPrecSolve are as follows: - - uu an N_Vector giving the current iterate for the system - - uscale an N_Vector giving the diagonal entries of the - uu scaling matrix - - fval an N_Vector giving the current function value - - fscale an N_Vector giving the diagonal entries of the - function scaling matrix - - vv vector initially set to the right-hand side vector r, but - which upon return contains a solution of the linear system - P*z = r - - bbd_data is the pointer to BBD data set by KINBBDInit. - - Note: The value returned by the KINBBDPrecSolve function is a - flag returned from the lienar solver object. - ------------------------------------------------------------------*/ - -static int KINBBDPrecSolve(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - N_Vector vv, void *bbd_data) -{ - KBBDPrecData pdata; - realtype *vd; - realtype *zd; - int i, retval; - - pdata = (KBBDPrecData) bbd_data; - - /* Get data pointers */ - vd = N_VGetArrayPointer(vv); - zd = N_VGetArrayPointer(pdata->zlocal); - - /* Attach local data array for vv to rlocal */ - N_VSetArrayPointer(vd, pdata->rlocal); - - /* Call banded solver object to do the work */ - retval = SUNLinSolSolve(pdata->LS, pdata->PP, pdata->zlocal, - pdata->rlocal, ZERO); - - /* Copy result into vv */ - for (i=0; in_local; i++) - vd[i] = zd[i]; - - return(retval); -} - - -/*------------------------------------------------------------------ - KINBBDPrecFree - ------------------------------------------------------------------*/ -static int KINBBDPrecFree(KINMem kin_mem) -{ - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kin_mem->kin_lmem == NULL) return(0); - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) return(0); - pdata = (KBBDPrecData) kinls_mem->pdata; - - SUNLinSolFree(pdata->LS); - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - - free(pdata); - pdata = NULL; - - return(0); -} - - -/*------------------------------------------------------------------ - KBBDDQJac - - This routine generates a banded difference quotient - approximation to the Jacobian of f(u). It assumes that a band - matrix of type SUNMatrix is stored column-wise, and that elements - within each column are contiguous. All matrix elements are - generated as difference quotients, by way of calls to the user - routine gloc. By virtue of the band structure, the number of - these calls is bandwidth + 1, where bandwidth = ml + mu + 1. - This routine also assumes that the local elements of a vector - are stored contiguously. - ------------------------------------------------------------------*/ -static int KBBDDQJac(KBBDPrecData pdata, - N_Vector uu, N_Vector uscale, - N_Vector gu, N_Vector gtemp, N_Vector utemp) -{ - KINMem kin_mem; - realtype inc, inc_inv; - int retval; - sunindextype group, i, j, width, ngroups, i1, i2; - realtype *udata, *uscdata, *gudata, *gtempdata, *utempdata, *col_j; - - kin_mem = (KINMem) pdata->kin_mem; - - /* load utemp with uu = predicted solution vector */ - N_VScale(ONE, uu, utemp); - - /* set pointers to the data for all vectors */ - udata = N_VGetArrayPointer(uu); - uscdata = N_VGetArrayPointer(uscale); - gudata = N_VGetArrayPointer(gu); - gtempdata = N_VGetArrayPointer(gtemp); - utempdata = N_VGetArrayPointer(utemp); - - /* Call gcomm and gloc to get base value of g(uu) */ - if (pdata->gcomm != NULL) { - retval = pdata->gcomm(pdata->n_local, uu, kin_mem->kin_user_data); - if (retval != 0) return(retval); - } - - retval = pdata->gloc(pdata->n_local, uu, gu, kin_mem->kin_user_data); - pdata->nge++; - if (retval != 0) return(retval); - - /* Set bandwidth and number of column groups for band differencing */ - width = pdata->mldq + pdata->mudq + 1; - ngroups = SUNMIN(width, pdata->n_local); - - /* Loop over groups */ - for(group = 1; group <= ngroups; group++) { - - /* increment all u_j in group */ - for(j = group - 1; j < pdata->n_local; j += width) { - inc = pdata->rel_uu * SUNMAX(SUNRabs(udata[j]), (ONE / uscdata[j])); - utempdata[j] += inc; - } - - /* Evaluate g with incremented u */ - retval = pdata->gloc(pdata->n_local, utemp, gtemp, kin_mem->kin_user_data); - pdata->nge++; - if (retval != 0) return(retval); - - /* restore utemp, then form and load difference quotients */ - for (j = group - 1; j < pdata->n_local; j += width) { - utempdata[j] = udata[j]; - col_j = SUNBandMatrix_Column(pdata->PP,j); - inc = pdata->rel_uu * SUNMAX(SUNRabs(udata[j]) , (ONE / uscdata[j])); - inc_inv = ONE / inc; - i1 = SUNMAX(0, (j - pdata->mukeep)); - i2 = SUNMIN((j + pdata->mlkeep), (pdata->n_local - 1)); - for (i = i1; i <= i2; i++) - SM_COLUMN_ELEMENT_B(col_j, i, j) = inc_inv * (gtempdata[i] - gudata[i]); - } - } - - return(0); -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h deleted file mode 100644 index 6541a32be0..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 - * ----------------------------------------------------------------- - * KINBBDPRE module header file (private version) - * -----------------------------------------------------------------*/ - -#ifndef _KINBBDPRE_IMPL_H -#define _KINBBDPRE_IMPL_H - -#include -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*------------------------------------------------------------------ - Definition of KBBDData - ------------------------------------------------------------------*/ - -typedef struct KBBDPrecDataRec { - - /* passed by user to KINBBDPrecAlloc, used by pset/psolve functions */ - sunindextype mudq, mldq, mukeep, mlkeep; - realtype rel_uu; /* relative error for the Jacobian DQ routine */ - KINBBDLocalFn gloc; - KINBBDCommFn gcomm; - - /* set by KINBBDPrecSetup and used by KINBBDPrecSetup and - KINBBDPrecSolve functions */ - sunindextype n_local; - SUNMatrix PP; - SUNLinearSolver LS; - N_Vector rlocal; - N_Vector zlocal; - N_Vector tempv1; - N_Vector tempv2; - N_Vector tempv3; - - /* available for optional output */ - long int rpwsize; - long int ipwsize; - long int nge; - - /* pointer to KINSol memory */ - void *kin_mem; - -} *KBBDPrecData; - -/* - *----------------------------------------------------------------- - * KINBBDPRE error messages - *----------------------------------------------------------------- - */ - -#define MSGBBD_MEM_NULL "KINSOL Memory is NULL." -#define MSGBBD_LMEM_NULL "Linear solver memory is NULL. One of the SPILS linear solvers must be attached." -#define MSGBBD_MEM_FAIL "A memory request failed." -#define MSGBBD_BAD_NVECTOR "A required vector operation is not implemented." -#define MSGBBD_SUNMAT_FAIL "An error arose from a SUNBandMatrix routine." -#define MSGBBD_SUNLS_FAIL "An error arose from a SUNBandLinearSolver routine." -#define MSGBBD_PMEM_NULL "BBD peconditioner memory is NULL. IDABBDPrecInit must be called." -#define MSGBBD_FUNC_FAILED "The gloc or gcomm routine failed in an unrecoverable manner." - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_direct.c b/ThirdParty/sundials/src/kinsol/kinsol_direct.c deleted file mode 100644 index d5b0e3805f..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_direct.c +++ /dev/null @@ -1,55 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * Radu Serban @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 the deprecated direct linear solver interface in - * KINSOL; these routines now just wrap the updated KINSOL generic - * linear solver interface in kinsol_ls.h. - *-----------------------------------------------------------------*/ - -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*================================================================= - Exported Functions (wrappers for equivalent routines in kinsol_ls.h) - =================================================================*/ - -int KINDlsSetLinearSolver(void *kinmem, SUNLinearSolver LS, SUNMatrix A) -{ return(KINSetLinearSolver(kinmem, LS, A)); } - -int KINDlsSetJacFn(void *kinmem, KINDlsJacFn jac) -{ return(KINSetJacFn(kinmem, jac)); } - -int KINDlsGetWorkSpace(void *kinmem, long int *lenrw, long int *leniw) -{ return(KINGetLinWorkSpace(kinmem, lenrw, leniw)); } - -int KINDlsGetNumJacEvals(void *kinmem, long int *njevals) -{ return(KINGetNumJacEvals(kinmem, njevals)); } - -int KINDlsGetNumFuncEvals(void *kinmem, long int *nfevals) -{ return(KINGetNumLinFuncEvals(kinmem, nfevals)); } - -int KINDlsGetLastFlag(void *kinmem, long int *flag) -{ return(KINGetLastLinFlag(kinmem, flag)); } - -char *KINDlsGetReturnFlagName(long int flag) -{ return(KINGetLinReturnFlagName(flag)); } - -#ifdef __cplusplus -} -#endif - diff --git a/ThirdParty/sundials/src/kinsol/kinsol_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_impl.h deleted file mode 100644 index ad1ccb6564..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_impl.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 - * ----------------------------------------------------------------- - * KINSOL solver module header file (private version) - * ----------------------------------------------------------------- - */ - -#ifndef _KINSOL_IMPL_H -#define _KINSOL_IMPL_H - -#include - -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/* - * ================================================================= - * M A I N S O L V E R M E M O R Y B L O C K - * ================================================================= - */ - -/* KINSOL default constants */ - -#define PRINTFL_DEFAULT 0 -#define MXITER_DEFAULT 200 -#define MXNBCF_DEFAULT 10 -#define MSBSET_DEFAULT 10 -#define MSBSET_SUB_DEFAULT 5 - -#define OMEGA_MIN RCONST(0.00001) -#define OMEGA_MAX RCONST(0.9) - -/* - * ----------------------------------------------------------------- - * Types : struct KINMemRec and struct *KINMem - * ----------------------------------------------------------------- - * A variable declaration of type struct *KINMem denotes a - * pointer to a data structure of type struct KINMemRec. The - * KINMemRec structure contains numerous fields that must be - * accessible by KINSOL solver module routines. - * ----------------------------------------------------------------- - */ - -typedef struct KINMemRec { - - realtype kin_uround; /* machine epsilon (or unit roundoff error) - (defined in sundials_types.h) */ - - /* problem specification data */ - - KINSysFn kin_func; /* nonlinear system function implementation */ - void *kin_user_data; /* work space available to func routine */ - realtype kin_fnormtol; /* stopping tolerance on L2-norm of function - value */ - realtype kin_scsteptol; /* scaled step length tolerance */ - int kin_globalstrategy; /* choices are KIN_NONE, KIN_LINESEARCH - KIN_PICARD and KIN_FP */ - int kin_printfl; /* level of verbosity of output */ - long int kin_mxiter; /* maximum number of nonlinear iterations */ - long int kin_msbset; /* maximum number of nonlinear iterations that - may be performed between calls to the - linear solver setup routine (lsetup) */ - long int kin_msbset_sub; /* subinterval length for residual monitoring */ - long int kin_mxnbcf; /* maximum number of beta condition failures */ - int kin_etaflag; /* choices are KIN_ETACONSTANT, KIN_ETACHOICE1 - and KIN_ETACHOICE2 */ - booleantype kin_noMinEps; /* flag controlling whether or not the value - of eps is bounded below */ - booleantype kin_constraintsSet; /* flag indicating if constraints are being - used */ - booleantype kin_jacCurrent; /* flag indicating if the Jacobian info. - used by the linear solver is current */ - booleantype kin_callForcingTerm; /* flag set if using either KIN_ETACHOICE1 - or KIN_ETACHOICE2 */ - booleantype kin_noResMon; /* flag indicating if the nonlinear - residual monitoring scheme should be - used */ - booleantype kin_retry_nni; /* flag indicating if nonlinear iteration - should be retried (set by residual - monitoring algorithm) */ - booleantype kin_update_fnorm_sub; /* flag indicating if the fnorm associated - with the subinterval needs to be - updated (set by residual monitoring - algorithm) */ - - realtype kin_mxnewtstep; /* maximum allowable scaled step length */ - realtype kin_mxnstepin; /* input (or preset) value for mxnewtstep */ - realtype kin_sqrt_relfunc; /* relative error bound for func(u) */ - realtype kin_stepl; /* scaled length of current step */ - realtype kin_stepmul; /* step scaling factor */ - realtype kin_eps; /* current value of eps */ - realtype kin_eta; /* current value of eta */ - realtype kin_eta_gamma; /* gamma value used in eta calculation - (choice #2) */ - realtype kin_eta_alpha; /* alpha value used in eta calculation - (choice #2) */ - booleantype kin_noInitSetup; /* flag controlling whether or not the KINSol - routine makes an initial call to the - linear solver setup routine (lsetup) */ - realtype kin_sthrsh; /* threshold value for calling the linear - solver setup routine */ - - /* counters */ - - long int kin_nni; /* number of nonlinear iterations */ - long int kin_nfe; /* number of calls made to func routine */ - long int kin_nnilset; /* value of nni counter when the linear solver - setup was last called */ - long int kin_nnilset_sub; /* value of nni counter when the linear solver - setup was last called (subinterval) */ - long int kin_nbcf; /* number of times the beta-condition could not - be met in KINLineSearch */ - long int kin_nbktrk; /* number of backtracks performed by - KINLineSearch */ - long int kin_ncscmx; /* number of consecutive steps of size - mxnewtstep taken */ - - /* vectors */ - - N_Vector kin_uu; /* solution vector/current iterate (initially - contains initial guess, but holds approximate - solution upon completion if no errors occurred) */ - N_Vector kin_unew; /* next iterate (unew = uu+pp) */ - N_Vector kin_fval; /* vector containing result of nonlinear system - function evaluated at a given iterate - (fval = func(uu)) */ - N_Vector kin_gval; /* vector containing result of the fixed point - function evaluated at a given iterate; - used in KIN_PICARD strategy only. - (gval = uu - L^{-1}fval(uu)) */ - N_Vector kin_uscale; /* iterate scaling vector */ - N_Vector kin_fscale; /* fval scaling vector */ - N_Vector kin_pp; /* incremental change vector (pp = unew-uu) */ - N_Vector kin_constraints; /* constraints vector */ - N_Vector kin_vtemp1; /* scratch vector #1 */ - N_Vector kin_vtemp2; /* scratch vector #2 */ - - /* space requirements for AA, Broyden and NLEN */ - N_Vector kin_fold_aa; /* vector needed for AA, Broyden, and NLEN */ - N_Vector kin_gold_aa; /* vector needed for AA, Broyden, and NLEN */ - N_Vector *kin_df_aa; /* vector array needed for AA, Broyden, and NLEN */ - N_Vector *kin_dg_aa; /* vector array needed for AA, Broyden and NLEN */ - N_Vector *kin_q_aa; /* vector array needed for AA */ - realtype kin_beta_aa; /* beta damping parameter for AA */ - realtype *kin_gamma_aa; /* array of size maa used in AA */ - realtype *kin_R_aa; /* array of size maa*maa used in AA */ - long int *kin_ipt_map; /* array of size maa used in AA */ - long int kin_m_aa; /* parameter for AA, Broyden or NLEN */ - booleantype kin_aamem_aa; /* sets additional memory needed for Anderson Acc */ - booleantype kin_setstop_aa; /* determines whether user will set stopping criterion */ - booleantype kin_damping_aa; /* flag to apply damping in AA */ - realtype *kin_cv; /* scalar array for fused vector operations */ - N_Vector *kin_Xv; /* vector array for fused vector operations */ - - /* space requirements for vector storage */ - - sunindextype kin_lrw1; /* number of realtype-sized memory blocks needed - for a single N_Vector */ - sunindextype kin_liw1; /* number of int-sized memory blocks needed for - a single N_Vecotr */ - long int kin_lrw; /* total number of realtype-sized memory blocks - needed for all KINSOL work vectors */ - long int kin_liw; /* total number of int-sized memory blocks needed - for all KINSOL work vectors */ - - /* linear solver data */ - - /* function prototypes (pointers) */ - - int (*kin_linit)(struct KINMemRec *kin_mem); - - int (*kin_lsetup)(struct KINMemRec *kin_mem); - - int (*kin_lsolve)(struct KINMemRec *kin_mem, N_Vector xx, N_Vector bb, - realtype *sJpnorm, realtype *sFdotJp); - - int (*kin_lfree)(struct KINMemRec *kin_mem); - - booleantype kin_inexact_ls; /* flag set by the linear solver module - (in linit) indicating whether this is an - iterative linear solver (SUNTRUE), or a direct - linear solver (SUNFALSE) */ - - void *kin_lmem; /* pointer to linear solver memory block */ - - realtype kin_fnorm; /* value of L2-norm of fscale*fval */ - realtype kin_f1norm; /* f1norm = 0.5*(fnorm)^2 */ - realtype kin_sFdotJp; /* value of scaled F(u) vector (fscale*fval) - dotted with scaled J(u)*pp vector (set by lsolve) */ - realtype kin_sJpnorm; /* value of L2-norm of fscale*(J(u)*pp) - (set by lsolve) */ - - realtype kin_fnorm_sub; /* value of L2-norm of fscale*fval (subinterval) */ - booleantype kin_eval_omega; /* flag indicating that omega must be evaluated. */ - realtype kin_omega; /* constant value for real scalar used in test to - determine if reduction of norm of nonlinear - residual is sufficient. Unless a valid constant - value is specified by the user, omega is estimated - from omega_min and omega_max at each iteration. */ - realtype kin_omega_min; /* lower bound on omega */ - realtype kin_omega_max; /* upper bound on omega */ - - /* - * ----------------------------------------------------------------- - * Note: The KINLineSearch subroutine scales the values of the - * variables sFdotJp and sJpnorm by a factor rl (lambda) that is - * chosen by the line search algorithm such that the sclaed Newton - * step satisfies the following conditions: - * - * F(u_k+1) <= F(u_k) + alpha*(F(u_k)^T * J(u_k))*p*rl - * - * F(u_k+1) >= F(u_k) + beta*(F(u_k)^T * J(u_k))*p*rl - * - * where alpha = 1.0e-4, beta = 0.9, u_k+1 = u_k + rl*p, - * 0 < rl <= 1, J denotes the system Jacobian, and F represents - * the nonliner system function. - * ----------------------------------------------------------------- - */ - - booleantype kin_MallocDone; /* flag indicating if KINMalloc has been - called yet */ - - /* message files */ - /*------------------------------------------- - Error handler function and error ouput file - -------------------------------------------*/ - - KINErrHandlerFn kin_ehfun; /* Error messages are handled by ehfun */ - void *kin_eh_data; /* dats pointer passed to ehfun */ - FILE *kin_errfp; /* KINSOL error messages are sent to errfp */ - - KINInfoHandlerFn kin_ihfun; /* Info messages are handled by ihfun */ - void *kin_ih_data; /* dats pointer passed to ihfun */ - FILE *kin_infofp; /* where KINSol info messages are sent */ - -} *KINMem; - -/* - * ================================================================= - * I N T E R F A C E T O L I N E A R S O L V E R - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_linit)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_linit initializes solver-specific data structures (including - * variables used as counters or for storing statistical information), - * but system memory allocation should be done by the subroutine - * that actually initializes the environment for liner solver - * package. If the linear system is to be preconditioned, then the - * variable setupNonNull (type booleantype) should be set to SUNTRUE - * (predefined constant) and the kin_lsetup routine should be - * appropriately defined. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * If the necessary variables have been successfully initialized, - * then the kin_linit function should return 0 (zero). Otherwise, - * the subroutine should indicate a failure has occurred by - * returning a non-zero integer value. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lsetup)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_lsetup interfaces with the user-supplied pset subroutine (the - * preconditioner setup routine), and updates relevant variable - * values (see KINSpgmrSetup/KINSpbcgSetup). Simply stated, the - * kin_lsetup routine prepares the linear solver for a subsequent - * call to the user-supplied kin_lsolve function. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * If successful, the kin_lsetup routine should return 0 (zero). - * Otherwise it should return a non-zero value. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lsolve)(KINMem kin_mem, N_Vector xx, - * N_Vector bb, realtype *sJpnorm, realtype *sFdotJp) - * ----------------------------------------------------------------- - * kin_lsolve interfaces with the subroutine implementing the - * numerical method to be used to solve the linear system J*xx = bb, - * and must increment the relevant counter variable values in - * addition to computing certain values used by the global strategy - * and forcing term routines (see KINInexactNewton, KINLineSearch, - * KINForcingTerm, and KINSpgmrSolve/KINSpbcgSolve). - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * xx vector (type N_Vector) set to initial guess by kin_lsolve - * routine prior to calling the linear solver, but which upon - * return contains an approximate solution of the linear - * system J*xx = bb, where J denotes the system Jacobian - * - * bb vector (type N_Vector) set to -func(u) (negative of the - * value of the system function evaluated at the current - * iterate) by KINLinSolDrv before kin_lsolve is called - * - * sJpnorm holds the value of the L2-norm (Euclidean norm) of - * fscale*(J(u)*pp) upon return - * - * sFdotJp holds the value of the scaled F(u) (fscale*F) dotted - * with the scaled J(u)*pp vector upon return - * - * If successful, the kin_lsolve routine should return 0 (zero). - * Otherwise it should return a positive value if a re-evaluation - * of the lsetup function could recover, or a negative value if - * no such recovery is possible. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lfree)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_lfree is called by KINFree and should free (deallocate) all - * system memory resources allocated for the linear solver module - * (see KINSpgmrFree/KINSpbcgFree). It should return 0 upon - * success, nonzero on failure. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * K I N S O L I N T E R N A L F U N C T I O N S - * ================================================================= - */ - - -/* High level error handler */ - -void KINProcessError(KINMem kin_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...); - -/* Prototype of internal errHandler function */ - -void KINErrHandler(int error_code, const char *module, const char *function, - char *msg, void *user_data); - - -/* High level info handler */ - -void KINPrintInfo(KINMem kin_mem, - int info_code, const char *module, const char *fname, - const char *msgfmt, ...); - -/* Prototype of internal infoHandler function */ - -void KINInfoHandler(const char *module, const char *function, - char *msg, void *user_data); - -/* - * ================================================================= - * K I N S O L E R R O R M E S S A G E S - * ================================================================= - */ - -#define MSG_MEM_FAIL "A memory request failed." -#define MSG_NO_MEM "kinsol_mem = NULL illegal." -#define MSG_BAD_NVECTOR "A required vector operation is not implemented." -#define MSG_FUNC_NULL "func = NULL illegal." -#define MSG_NO_MALLOC "Attempt to call before KINMalloc illegal." - -#define MSG_BAD_PRINTFL "Illegal value for printfl." -#define MSG_BAD_MXITER "Illegal value for mxiter." -#define MSG_BAD_MSBSET "Illegal msbset < 0." -#define MSG_BAD_MSBSETSUB "Illegal msbsetsub < 0." -#define MSG_BAD_ETACHOICE "Illegal value for etachoice." -#define MSG_BAD_ETACONST "eta out of range." -#define MSG_BAD_GAMMA "gamma out of range." -#define MSG_BAD_ALPHA "alpha out of range." -#define MSG_BAD_MXNEWTSTEP "Illegal mxnewtstep < 0." -#define MSG_BAD_RELFUNC "relfunc < 0 illegal." -#define MSG_BAD_FNORMTOL "fnormtol < 0 illegal." -#define MSG_BAD_SCSTEPTOL "scsteptol < 0 illegal." -#define MSG_BAD_MXNBCF "mxbcf < 0 illegal." -#define MSG_BAD_CONSTRAINTS "Illegal values in constraints vector." -#define MSG_BAD_OMEGA "scalars < 0 illegal." -#define MSG_BAD_MAA "maa < 0 illegal." -#define MSG_ZERO_MAA "maa = 0 illegal." - -#define MSG_LSOLV_NO_MEM "The linear solver memory pointer is NULL." -#define MSG_UU_NULL "uu = NULL illegal." -#define MSG_BAD_GLSTRAT "Illegal value for global strategy." -#define MSG_BAD_USCALE "uscale = NULL illegal." -#define MSG_USCALE_NONPOSITIVE "uscale has nonpositive elements." -#define MSG_BAD_FSCALE "fscale = NULL illegal." -#define MSG_FSCALE_NONPOSITIVE "fscale has nonpositive elements." -#define MSG_CONSTRAINTS_NOTOK "Constraints not allowed with fixed point or Picard iterations" -#define MSG_INITIAL_CNSTRNT "Initial guess does NOT meet constraints." -#define MSG_LINIT_FAIL "The linear solver's init routine failed." - -#define MSG_SYSFUNC_FAILED "The system function failed in an unrecoverable manner." -#define MSG_SYSFUNC_FIRST "The system function failed at the first call." -#define MSG_LSETUP_FAILED "The linear solver's setup function failed in an unrecoverable manner." -#define MSG_LSOLVE_FAILED "The linear solver's solve function failed in an unrecoverable manner." -#define MSG_LINSOLV_NO_RECOVERY "The linear solver's solve function failed recoverably, but the Jacobian data is already current." -#define MSG_LINESEARCH_NONCONV "The line search algorithm was unable to find an iterate sufficiently distinct from the current iterate." -#define MSG_LINESEARCH_BCFAIL "The line search algorithm was unable to satisfy the beta-condition for nbcfails iterations." -#define MSG_MAXITER_REACHED "The maximum number of iterations was reached before convergence." -#define MSG_MXNEWT_5X_EXCEEDED "Five consecutive steps have been taken that satisfy a scaled step length test." -#define MSG_SYSFUNC_REPTD "Unable to correct repeated recoverable system function errors." -#define MSG_NOL_FAIL "Unable to find user's Linear Jacobian, which is required for the KIN_PICARD Strategy" - -/* - * ================================================================= - * K I N S O L I N F O M E S S A G E S - * ================================================================= - */ - -#define INFO_RETVAL "Return value: %d" -#define INFO_ADJ "no. of lambda adjustments = %ld" - -#if defined(SUNDIALS_EXTENDED_PRECISION) - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16Lg" -#define INFO_TOL "scsteptol = %12.3Lg fnormtol = %12.3Lg" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3Lg" -#define INFO_PNORM "pnorm = %12.4Le" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4Le" -#define INFO_FNORM "fnorm(L2) = %20.8Le" -#define INFO_LAM "min_lam = %11.4Le f1norm = %11.4Le pnorm = %11.4Le" -#define INFO_ALPHA "fnorm = %15.8Le f1norm = %15.8Le alpha_cond = %15.8Le lam = %15.8Le" -#define INFO_BETA "f1norm = %15.8Le beta_cond = %15.8Le lam = %15.8Le" -#define INFO_ALPHABETA "f1norm = %15.8Le alpha_cond = %15.8Le beta_cond = %15.8Le lam = %15.8Le" - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16lg" -#define INFO_TOL "scsteptol = %12.3lg fnormtol = %12.3lg" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3lg" -#define INFO_PNORM "pnorm = %12.4le" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4le" -#define INFO_FNORM "fnorm(L2) = %20.8le" -#define INFO_LAM "min_lam = %11.4le f1norm = %11.4le pnorm = %11.4le" -#define INFO_ALPHA "fnorm = %15.8le f1norm = %15.8le alpha_cond = %15.8le lam = %15.8le" -#define INFO_BETA "f1norm = %15.8le beta_cond = %15.8le lam = %15.8le" -#define INFO_ALPHABETA "f1norm = %15.8le alpha_cond = %15.8le beta_cond = %15.8le lam = %15.8le" - -#else - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16g" -#define INFO_TOL "scsteptol = %12.3g fnormtol = %12.3g" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3g" -#define INFO_PNORM "pnorm = %12.4e" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4e" -#define INFO_FNORM "fnorm(L2) = %20.8e" -#define INFO_LAM "min_lam = %11.4e f1norm = %11.4e pnorm = %11.4e" -#define INFO_ALPHA "fnorm = %15.8e f1norm = %15.8e alpha_cond = %15.8e lam = %15.8e" -#define INFO_BETA "f1norm = %15.8e beta_cond = %15.8e lam = %15.8e" -#define INFO_ALPHABETA "f1norm = %15.8e alpha_cond = %15.8e beta_cond = %15.8e lam = %15.8e" - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_io.c b/ThirdParty/sundials/src/kinsol/kinsol_io.c deleted file mode 100644 index 5f11b0dda7..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_io.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 optional input and output - * functions for the KINSOL solver. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "kinsol_impl.h" -#include -#include - -#define ZERO RCONST(0.0) -#define POINT1 RCONST(0.1) -#define ONETHIRD RCONST(0.3333333333333333) -#define HALF RCONST(0.5) -#define TWOTHIRDS RCONST(0.6666666666666667) -#define POINT9 RCONST(0.9) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) -#define TWOPT5 RCONST(2.5) - -/* - * ================================================================= - * KINSOL optional input functions - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * KINSetErrHandlerFn - * ----------------------------------------------------------------- - */ - -int KINSetErrHandlerFn(void *kinmem, KINErrHandlerFn ehfun, void *eh_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetErrHandlerFn", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - kin_mem->kin_ehfun = ehfun; - kin_mem->kin_eh_data = eh_data; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetErrFile - * ----------------------------------------------------------------- - */ - -int KINSetErrFile(void *kinmem, FILE *errfp) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetErrFile", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_errfp = errfp; - - return(KIN_SUCCESS); -} - -#define errfp (kin_mem->kin_errfp) - -/* - * ----------------------------------------------------------------- - * Function : KINSetPrintLevel - * ----------------------------------------------------------------- - */ - -int KINSetPrintLevel(void *kinmem, int printfl) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetPrintLevel", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((printfl < 0) || (printfl > 3)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetPrintLevel", MSG_BAD_PRINTFL); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_printfl = printfl; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * KINSetInfoHandlerFn - * ----------------------------------------------------------------- - */ - -int KINSetInfoHandlerFn(void *kinmem, KINInfoHandlerFn ihfun, void *ih_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetInfoHandlerFn", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - kin_mem->kin_ihfun = ihfun; - kin_mem->kin_ih_data = ih_data; - - return(KIN_SUCCESS); -} - - -/* - * ----------------------------------------------------------------- - * Function : KINSetInfoFile - * ----------------------------------------------------------------- - */ - -int KINSetInfoFile(void *kinmem, FILE *infofp) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetInfoFile", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_infofp = infofp; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetUserData - * ----------------------------------------------------------------- - */ - -int KINSetUserData(void *kinmem, void *user_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetUserData", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_user_data = user_data; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMAA - * ----------------------------------------------------------------- - */ - -int KINSetMAA(void *kinmem, long int maa) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMAA", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (maa < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMAA", MSG_BAD_MAA); - return(KIN_ILL_INPUT); - } - - if (maa > kin_mem->kin_mxiter) maa = kin_mem->kin_mxiter; - - kin_mem->kin_m_aa = maa; - kin_mem->kin_aamem_aa = (maa == 0) ? SUNFALSE : SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetDampingAA - * ----------------------------------------------------------------- - */ - -int KINSetDampingAA(void *kinmem, realtype beta) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMAA", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check for illegal input value */ - if (beta <= ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetDampingAA", - "beta <= 0 illegal"); - return(KIN_ILL_INPUT); - } - - if (beta < ONE) { - /* enable damping */ - kin_mem->kin_beta_aa = beta; - kin_mem->kin_damping_aa = SUNTRUE; - } else { - /* disable damping */ - kin_mem->kin_beta_aa = ONE; - kin_mem->kin_damping_aa = SUNFALSE; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetAAStopCrit - * ----------------------------------------------------------------- - */ - -/* CSW: This function is currently not supported. - -int KINSetAAStopCrit(void *kinmem, booleantype setstop) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetAAStopCrit", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_setstop_aa = setstop; - - return(KIN_SUCCESS); -} -*/ - -/* - * ----------------------------------------------------------------- - * Function : KINSetNumMaxIters - * ----------------------------------------------------------------- - */ - -int KINSetNumMaxIters(void *kinmem, long int mxiter) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNumMaxIters", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxiter < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetNumMaxIters", MSG_BAD_MXITER); - return(KIN_ILL_INPUT); - } - - if (mxiter == 0) - kin_mem->kin_mxiter = MXITER_DEFAULT; - else - kin_mem->kin_mxiter = mxiter; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoInitSetup - * ----------------------------------------------------------------- - */ - -int KINSetNoInitSetup(void *kinmem, booleantype noInitSetup) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoInitSetup", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noInitSetup = noInitSetup; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoResMon - * ----------------------------------------------------------------- - */ - -int KINSetNoResMon(void *kinmem, booleantype noResMon) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoResMon", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noResMon = noResMon; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxSetupCalls - * ----------------------------------------------------------------- - */ - -int KINSetMaxSetupCalls(void *kinmem, long int msbset) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxSetupCalls", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (msbset < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxSetupCalls", MSG_BAD_MSBSET); - return(KIN_ILL_INPUT); - } - - if (msbset == 0) - kin_mem->kin_msbset = MSBSET_DEFAULT; - else - kin_mem->kin_msbset = msbset; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxSubSetupCalls - * ----------------------------------------------------------------- - */ - -int KINSetMaxSubSetupCalls(void *kinmem, long int msbsetsub) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxSubSetupCalls", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (msbsetsub < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxSubSetupCalls", MSG_BAD_MSBSETSUB); - return(KIN_ILL_INPUT); - } - - if (msbsetsub == 0) - kin_mem->kin_msbset_sub = MSBSET_SUB_DEFAULT; - else - kin_mem->kin_msbset_sub = msbsetsub; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaForm - * ----------------------------------------------------------------- - */ - -int KINSetEtaForm(void *kinmem, int etachoice) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaForm", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((etachoice != KIN_ETACONSTANT) && - (etachoice != KIN_ETACHOICE1) && - (etachoice != KIN_ETACHOICE2)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaForm", MSG_BAD_ETACHOICE); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_etaflag = etachoice; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaConstValue - * ----------------------------------------------------------------- - */ - -int KINSetEtaConstValue(void *kinmem, realtype eta) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaConstValue", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((eta < ZERO) || (eta > ONE)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaConstValue", MSG_BAD_ETACONST); - return(KIN_ILL_INPUT); - } - - if (eta == ZERO) - kin_mem->kin_eta = POINT1; - else - kin_mem->kin_eta = eta; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaParams - * ----------------------------------------------------------------- - */ - -int KINSetEtaParams(void *kinmem, realtype egamma, realtype ealpha) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaParams", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((ealpha <= ONE) || (ealpha > TWO)) - if (ealpha != ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaParams", MSG_BAD_ALPHA); - return(KIN_ILL_INPUT); - } - - if (ealpha == ZERO) - kin_mem->kin_eta_alpha = TWO; - else - kin_mem->kin_eta_alpha = ealpha; - - if ((egamma <= ZERO) || (egamma > ONE)) - if (egamma != ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaParams", MSG_BAD_GAMMA); - return(KIN_ILL_INPUT); - } - - if (egamma == ZERO) - kin_mem->kin_eta_gamma = POINT9; - else - kin_mem->kin_eta_gamma = egamma; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetResMonParams - * ----------------------------------------------------------------- - */ - -int KINSetResMonParams(void *kinmem, realtype omegamin, realtype omegamax) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetResMonParams", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check omegamin */ - - if (omegamin < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - if (omegamin == ZERO) - kin_mem->kin_omega_min = OMEGA_MIN; - else - kin_mem->kin_omega_min = omegamin; - - /* check omegamax */ - - if (omegamax < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - if (omegamax == ZERO) { - - if (kin_mem->kin_omega_min > OMEGA_MAX) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - else kin_mem->kin_omega_max = OMEGA_MAX; - - } else { - - if (kin_mem->kin_omega_min > omegamax) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - else kin_mem->kin_omega_max = omegamax; - - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetResMonConstValue - * ----------------------------------------------------------------- - */ - -int KINSetResMonConstValue(void *kinmem, realtype omegaconst) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetResMonConstValue", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check omegaconst */ - - if (omegaconst < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonConstValue", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - /* Load omega value. A value of 0 will force using omega_min and omega_max */ - kin_mem->kin_omega = omegaconst; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoMinEps - * ----------------------------------------------------------------- - */ - -int KINSetNoMinEps(void *kinmem, booleantype noMinEps) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoMinEps", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noMinEps = noMinEps; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxNewtonStep - * ----------------------------------------------------------------- - */ - -int KINSetMaxNewtonStep(void *kinmem, realtype mxnewtstep) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxNewtonStep", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxnewtstep < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxNewtonStep", MSG_BAD_MXNEWTSTEP); - return(KIN_ILL_INPUT); - } - - /* Note: passing a value of 0.0 will use the default - value (computed in KINSolInit) */ - - kin_mem->kin_mxnstepin = mxnewtstep; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxBetaFails - * ----------------------------------------------------------------- - */ - -int KINSetMaxBetaFails(void *kinmem, long int mxnbcf) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxBetaFails", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxnbcf < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxBetaFails", MSG_BAD_MXNBCF); - return(KIN_ILL_INPUT); - } - - if (mxnbcf == 0) - kin_mem->kin_mxnbcf = MXNBCF_DEFAULT; - else - kin_mem->kin_mxnbcf = mxnbcf; - - return(KIN_SUCCESS); - -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetRelErrFunc - * ----------------------------------------------------------------- - */ - -int KINSetRelErrFunc(void *kinmem, realtype relfunc) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetRelErrFunc", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (relfunc < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetRelErrFunc", MSG_BAD_RELFUNC); - return(KIN_ILL_INPUT); - } - - if (relfunc == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_sqrt_relfunc = SUNRsqrt(uround); - } else { - kin_mem->kin_sqrt_relfunc = SUNRsqrt(relfunc); - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetFuncNormTol - * ----------------------------------------------------------------- - */ - -int KINSetFuncNormTol(void *kinmem, realtype fnormtol) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetFuncNormTol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (fnormtol < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetFuncNormTol", MSG_BAD_FNORMTOL); - return(KIN_ILL_INPUT); - } - - if (fnormtol == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_fnormtol = SUNRpowerR(uround,ONETHIRD); - } else { - kin_mem->kin_fnormtol = fnormtol; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetScaledStepTol - * ----------------------------------------------------------------- - */ - -int KINSetScaledStepTol(void *kinmem, realtype scsteptol) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetScaledStepTol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (scsteptol < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetScaledStepTol", MSG_BAD_SCSTEPTOL); - return(KIN_ILL_INPUT); - } - - if (scsteptol == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_scsteptol = SUNRpowerR(uround,TWOTHIRDS); - } else { - kin_mem->kin_scsteptol = scsteptol; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetConstraints - * ----------------------------------------------------------------- - */ - -int KINSetConstraints(void *kinmem, N_Vector constraints) -{ - KINMem kin_mem; - realtype temptest; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetConstraints", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (constraints == NULL) { - if (kin_mem->kin_constraintsSet) { - N_VDestroy(kin_mem->kin_constraints); - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - kin_mem->kin_constraintsSet = SUNFALSE; - return(KIN_SUCCESS); - } - - /* Check the constraints vector */ - - temptest = N_VMaxNorm(constraints); - if (temptest > TWOPT5){ - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetConstraints", MSG_BAD_CONSTRAINTS); - return(KIN_ILL_INPUT); - } - - if (!kin_mem->kin_constraintsSet) { - kin_mem->kin_constraints = N_VClone(constraints); - kin_mem->kin_lrw += kin_mem->kin_lrw1; - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_constraintsSet = SUNTRUE; - } - - /* Load the constraint vector */ - - N_VScale(ONE, constraints, kin_mem->kin_constraints); - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetSysFunc - * ----------------------------------------------------------------- - */ - -int KINSetSysFunc(void *kinmem, KINSysFn func) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetSysFunc", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (func == NULL) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetSysFunc", MSG_FUNC_NULL); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_func = func; - - return(KIN_SUCCESS); -} - - -/* - * ================================================================= - * KINSOL optional output functions - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Function : KINGetWorkSpace - * ----------------------------------------------------------------- - */ - -int KINGetWorkSpace(void *kinmem, long int *lenrw, long int *leniw) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetWorkSpace", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - *lenrw = kin_mem->kin_lrw; - *leniw = kin_mem->kin_liw; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumNonlinSolvIters - * ----------------------------------------------------------------- - */ - -int KINGetNumNonlinSolvIters(void *kinmem, long int *nniters) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumNonlinSolvIters", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nniters = kin_mem->kin_nni; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumFuncEvals - * ----------------------------------------------------------------- - */ - -int KINGetNumFuncEvals(void *kinmem, long int *nfevals) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumFuncEvals", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nfevals = kin_mem->kin_nfe; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumBetaCondFails - * ----------------------------------------------------------------- - */ - -int KINGetNumBetaCondFails(void *kinmem, long int *nbcfails) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumBetaCondFails", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nbcfails = kin_mem->kin_nbcf; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumBacktrackOps - * ----------------------------------------------------------------- - */ - -int KINGetNumBacktrackOps(void *kinmem, long int *nbacktr) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumBacktrackOps", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nbacktr = kin_mem->kin_nbktrk; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetFuncNorm - * ----------------------------------------------------------------- - */ - -int KINGetFuncNorm(void *kinmem, realtype *funcnorm) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetFuncNorm", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *funcnorm = kin_mem->kin_fnorm; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetStepLength - * ----------------------------------------------------------------- - */ - -int KINGetStepLength(void *kinmem, realtype *steplength) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetStepLength", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *steplength = kin_mem->kin_stepl; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetReturnFlagName - * ----------------------------------------------------------------- - */ - -char *KINGetReturnFlagName(long int flag) -{ - char *name; - - name = (char *)malloc(24*sizeof(char)); - - switch(flag) { - case KIN_SUCCESS: - sprintf(name, "KIN_SUCCESS"); - break; - case KIN_INITIAL_GUESS_OK: - sprintf(name, "KIN_INITIAL_GUESS_OK"); - break; - case KIN_STEP_LT_STPTOL: - sprintf(name, "KIN_STEP_LT_STPTOL"); - break; - case KIN_WARNING: - sprintf(name, "KIN_WARNING"); - break; - case KIN_MEM_NULL: - sprintf(name, "KIN_MEM_NULL"); - break; - case KIN_ILL_INPUT: - sprintf(name, "KIN_ILL_INPUT"); - break; - case KIN_NO_MALLOC: - sprintf(name, "KIN_NO_MALLOC"); - break; - case KIN_MEM_FAIL: - sprintf(name, "KIN_MEM_FAIL"); - break; - case KIN_LINESEARCH_NONCONV: - sprintf(name, "KIN_LINESEARCH_NONCONV"); - break; - case KIN_MAXITER_REACHED: - sprintf(name, "KIN_MAXITER_REACHED"); - break; - case KIN_MXNEWT_5X_EXCEEDED: - sprintf(name, "KIN_MXNEWT_5X_EXCEEDED"); - break; - case KIN_LINESEARCH_BCFAIL: - sprintf(name, "KIN_LINESEARCH_BCFAIL"); - break; - case KIN_LINSOLV_NO_RECOVERY: - sprintf(name, "KIN_LINSOLV_NO_RECOVERY"); - break; - case KIN_LINIT_FAIL: - sprintf(name, "KIN_LINIT_FAIL"); - break; - case KIN_LSETUP_FAIL: - sprintf(name, "KIN_LSETUP_FAIL"); - break; - case KIN_LSOLVE_FAIL: - sprintf(name, "KIN_LSOLVE_FAIL"); - break; - default: - sprintf(name, "NONE"); - } - - return(name); -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_ls.c b/ThirdParty/sundials/src/kinsol/kinsol_ls.c deleted file mode 100644 index 28128614b1..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_ls.c +++ /dev/null @@ -1,1365 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * David J. Gardner, Radu Serban and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 KINSOL's linear solver interface. - *-----------------------------------------------------------------*/ - -#include -#include -#include -#include - -#include "kinsol_impl.h" -#include "kinsol_ls_impl.h" - -#include -#include -#include -#include - -/* constants */ -#define MIN_INC_MULT RCONST(1000.0) -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) - - -/*================================================================== - KINLS Exported functions -- Required - ==================================================================*/ - -/*--------------------------------------------------------------- - KINSetLinearSolver specifies the linear solver - ---------------------------------------------------------------*/ -int KINSetLinearSolver(void *kinmem, SUNLinearSolver LS, SUNMatrix A) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval, LSType; - booleantype iterative; /* is the solver iterative? */ - booleantype matrixbased; /* is a matrix structure used? */ - - /* Return immediately if either kinmem or LS inputs are NULL */ - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - "KINSetLinearSolver", MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - if (LS == NULL) { - KINProcessError(NULL, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", - "LS must be non-NULL"); - return(KINLS_ILL_INPUT); - } - kin_mem = (KINMem) kinmem; - - /* Test if solver is compatible with LS interface */ - if ( (LS->ops->gettype == NULL) || (LS->ops->solve == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", - "LS object is missing a required operation"); - return(KINLS_ILL_INPUT); - } - - /* Retrieve the LS type */ - LSType = SUNLinSolGetType(LS); - - /* Set flags based on LS type */ - iterative = (LSType != SUNLINEARSOLVER_DIRECT); - matrixbased = (LSType != SUNLINEARSOLVER_ITERATIVE); - - /* check for required vector operations for KINLS interface */ - if ( (kin_mem->kin_vtemp1->ops->nvconst == NULL) || - (kin_mem->kin_vtemp1->ops->nvdotprod == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* Check for compatible LS type, matrix and "atimes" support */ - if (iterative) { - - if ((LS->ops->setscalingvectors == NULL) && - (kin_mem->kin_vtemp1->ops->nvgetlength == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - if (!matrixbased && (LS->ops->setatimes == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: iterative LS must support ATimes routine"); - return(KINLS_ILL_INPUT); - } - - if (matrixbased && A == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: matrix-iterative LS requires non-NULL matrix"); - return(KINLS_ILL_INPUT); - } - - } else if (A == NULL) { - - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: direct LS requires non-NULL matrix"); - return(KINLS_ILL_INPUT); - } - - /* free any existing system solver attached to KIN */ - if (kin_mem->kin_lfree) kin_mem->kin_lfree(kin_mem); - - /* Determine if this is an iterative linear solver */ - kin_mem->kin_inexact_ls = iterative; - - /* Set four main system linear solver function fields in kin_mem */ - kin_mem->kin_linit = kinLsInitialize; - kin_mem->kin_lsetup = kinLsSetup; - kin_mem->kin_lsolve = kinLsSolve; - kin_mem->kin_lfree = kinLsFree; - - /* Get memory for KINLsMemRec */ - kinls_mem = NULL; - kinls_mem = (KINLsMem) malloc(sizeof(struct KINLsMemRec)); - if (kinls_mem == NULL) { - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINLS", - "KINSetLinearSolver", MSG_LS_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - memset(kinls_mem, 0, sizeof(struct KINLsMemRec)); - - /* set SUNLinearSolver pointer */ - kinls_mem->LS = LS; - - /* Set defaults for Jacobian-related fields */ - if (A != NULL) { - kinls_mem->jacDQ = SUNTRUE; - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } else { - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = NULL; - kinls_mem->J_data = NULL; - } - kinls_mem->jtimesDQ = SUNTRUE; - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_func = kin_mem->kin_func; - kinls_mem->jt_data = kin_mem; - - /* Set defaults for preconditioner-related fields */ - kinls_mem->pset = NULL; - kinls_mem->psolve = NULL; - kinls_mem->pfree = NULL; - kinls_mem->pdata = kin_mem->kin_user_data; - - /* Initialize counters */ - kinLsInitializeCounters(kinls_mem); - - /* Set default values for the rest of the LS parameters */ - kinls_mem->last_flag = KINLS_SUCCESS; - - /* If LS supports ATimes, attach KINLs routine */ - if (LS->ops->setatimes) { - retval = SUNLinSolSetATimes(LS, kin_mem, kinLsATimes); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", - "KINSetLinearSolver", - "Error in calling SUNLinSolSetATimes"); - free(kinls_mem); kinls_mem = NULL; - return(KINLS_SUNLS_FAIL); - } - } - - /* If LS supports preconditioning, initialize pset/psol to NULL */ - if (LS->ops->setpreconditioner) { - retval = SUNLinSolSetPreconditioner(LS, kin_mem, NULL, NULL); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", - "KINSetLinearSolver", - "Error in calling SUNLinSolSetPreconditioner"); - free(kinls_mem); kinls_mem = NULL; - return(KINLS_SUNLS_FAIL); - } - } - - /* initialize tolerance scaling factor */ - kinls_mem->tol_fac = -ONE; - - /* set SUNMatrix pointer (can be NULL) */ - kinls_mem->J = A; - - /* Attach linear solver memory to integrator memory */ - kin_mem->kin_lmem = kinls_mem; - - return(KINLS_SUCCESS); -} - - -/*================================================================== - Optional input/output routines - ==================================================================*/ - -/*------------------------------------------------------------------ - KINSetJacFn specifies the Jacobian function - ------------------------------------------------------------------*/ -int KINSetJacFn(void *kinmem, KINLsJacFn jac) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetJacFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* return with failure if jac cannot be used */ - if ((jac != NULL) && (kinls_mem->J == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacFn", - "Jacobian routine cannot be supplied for NULL SUNMatrix"); - return(KINLS_ILL_INPUT); - } - - if (jac != NULL) { - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = jac; - kinls_mem->J_data = kin_mem->kin_user_data; - } else { - kinls_mem->jacDQ = SUNTRUE; - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINSetPreconditioner sets the preconditioner setup and solve - functions - ------------------------------------------------------------------*/ -int KINSetPreconditioner(void *kinmem, - KINLsPrecSetupFn psetup, - KINLsPrecSolveFn psolve) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - PSetupFn kinls_psetup; - PSolveFn kinls_psolve; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetPreconditioner", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* store function pointers for user-supplied routines in KINLS interface */ - kinls_mem->pset = psetup; - kinls_mem->psolve = psolve; - - /* issue error if LS object does not support user-supplied preconditioning */ - if (kinls_mem->LS->ops->setpreconditioner == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetPreconditioner", - "SUNLinearSolver object does not support user-supplied preconditioning"); - return(KINLS_ILL_INPUT); - } - - /* notify iterative linear solver to call KINLs interface routines */ - kinls_psetup = (psetup == NULL) ? NULL : kinLsPSetup; - kinls_psolve = (psolve == NULL) ? NULL : kinLsPSolve; - retval = SUNLinSolSetPreconditioner(kinls_mem->LS, kin_mem, - kinls_psetup, kinls_psolve); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", "KINSetPreconditioner", - "Error in calling SUNLinSolSetPreconditioner"); - return(KINLS_SUNLS_FAIL); - } - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINSetJacTimesVecFn sets the matrix-vector product function - ------------------------------------------------------------------*/ -int KINSetJacTimesVecFn(void *kinmem, KINLsJacTimesVecFn jtv) -{ - int retval; - KINMem kin_mem; - KINLsMem kinls_mem; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetJacTimesVecFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* issue error if LS object does not support user-supplied ATimes */ - if (kinls_mem->LS->ops->setatimes == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacTimesVecFn", - "SUNLinearSolver object does not support user-supplied ATimes routine"); - return(KINLS_ILL_INPUT); - } - - /* store function pointers for user-supplied routine in KINLs - interface (NULL jtimes implies use of DQ default) */ - if (jtv != NULL) { - kinls_mem->jtimesDQ = SUNFALSE; - kinls_mem->jtimes = jtv; - kinls_mem->jt_data = kin_mem->kin_user_data; - } else { - kinls_mem->jtimesDQ = SUNTRUE; - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_func = kin_mem->kin_func; - kinls_mem->jt_data = kin_mem; - } - - return(KINLS_SUCCESS); -} - - -/* KINSetJacTimesVecSysFn specifies an alternative user-supplied system function - to use in the internal finite difference Jacobian-vector product */ -int KINSetJacTimesVecSysFn(void *kinmem, KINSysFn jtimesSysFn) -{ - int retval; - KINMem kin_mem = NULL; - KINLsMem kinls_mem = NULL; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kin_mem, "KINSetJacTimesVecSysFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* check if using internal finite difference approximation */ - if (!(kinls_mem->jtimesDQ)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacTimesVecSysFn", - "Internal finite-difference Jacobian-vector product is disabled."); - return(KINLS_ILL_INPUT); - } - - /* store function pointers for system function (NULL implies use kin_func) */ - if (jtimesSysFn != NULL) - kinls_mem->jt_func = jtimesSysFn; - else - kinls_mem->jt_func = kin_mem->kin_func; - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINGetLinWorkSpace returns the integer and real workspace size - ------------------------------------------------------------------*/ -int KINGetLinWorkSpace(void *kinmem, long int *lenrwLS, long int *leniwLS) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - sunindextype lrw1, liw1; - long int lrw, liw; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINGetLinWorkSpace", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* start with fixed sizes plus vector/matrix pointers */ - *lenrwLS = 1; - *leniwLS = 21; - - /* add N_Vector sizes */ - if (kin_mem->kin_vtemp1->ops->nvspace) { - N_VSpace(kin_mem->kin_vtemp1, &lrw1, &liw1); - *lenrwLS += lrw1; - *leniwLS += liw1; - } - - /* add LS sizes */ - if (kinls_mem->LS->ops->space) { - retval = SUNLinSolSpace(kinls_mem->LS, &lrw, &liw); - if (retval == 0) { - *lenrwLS += lrw; - *leniwLS += liw; - } - } - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumJacEvals returns the number of Jacobian evaluations - ------------------------------------------------------------------*/ -int KINGetNumJacEvals(void *kinmem, long int *njevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumJacEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *njevals = kinls_mem->nje; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumPrecEvals returns the total number of preconditioner - evaluations - ------------------------------------------------------------------*/ -int KINGetNumPrecEvals(void *kinmem, long int *npevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumPrecEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *npevals = kinls_mem->npe; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumPrecSolves returns the total number of times the - preconditioner was applied - ------------------------------------------------------------------*/ -int KINGetNumPrecSolves(void *kinmem, long int *npsolves) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumPrecSolves", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *npsolves = kinls_mem->nps; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinIters returns the total number of linear - iterations - ------------------------------------------------------------------*/ -int KINGetNumLinIters(void *kinmem, long int *nliters) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinIters", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nliters = kinls_mem->nli; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinConvFails returns the total numbe of convergence - failures - ------------------------------------------------------------------*/ -int KINGetNumLinConvFails(void *kinmem, long int *nlcfails) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinConvFails", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nlcfails = kinls_mem->ncfl; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumJtimesEvals returns the number of times the matrix - vector product was computed - ------------------------------------------------------------------*/ -int KINGetNumJtimesEvals(void *kinmem, long int *njvevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumJtimesEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *njvevals = kinls_mem->njtimes; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinFuncEvals returns the number of calls to the user's - F routine by the linear solver module - ------------------------------------------------------------------*/ -int KINGetNumLinFuncEvals(void *kinmem, long int *nfevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinFuncEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nfevals = kinls_mem->nfeDQ; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetLastLinFlag returns the last flag set in the KINLS - function - ------------------------------------------------------------------*/ -int KINGetLastLinFlag(void *kinmem, long int *flag) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetLastLinFlag", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *flag = kinls_mem->last_flag; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetLinReturnFlagName - ------------------------------------------------------------------*/ -char *KINGetLinReturnFlagName(long int flag) -{ - char *name; - - name = (char *)malloc(30*sizeof(char)); - - switch(flag) { - case KINLS_SUCCESS: - sprintf(name, "KINLS_SUCCESS"); - break; - case KINLS_MEM_NULL: - sprintf(name, "KINLS_MEM_NULL"); - break; - case KINLS_LMEM_NULL: - sprintf(name, "KINLS_LMEM_NULL"); - break; - case KINLS_ILL_INPUT: - sprintf(name, "KINLS_ILL_INPUT"); - break; - case KINLS_MEM_FAIL: - sprintf(name, "KINLS_MEM_FAIL"); - break; - case KINLS_PMEM_NULL: - sprintf(name, "KINLS_PMEM_NULL"); - break; - case KINLS_JACFUNC_ERR: - sprintf(name,"KINLS_JACFUNC_ERR"); - break; - case KINLS_SUNMAT_FAIL: - sprintf(name,"KINLS_SUNMAT_FAIL"); - break; - case KINLS_SUNLS_FAIL: - sprintf(name,"KINLS_SUNLS_FAIL"); - break; - default: - sprintf(name, "NONE"); - } - - return(name); -} - - -/*================================================================== - KINLS Private functions - ==================================================================*/ - -/*------------------------------------------------------------------ - kinLsATimes - - This routine coordinates the generation of the matrix-vector - product z = J*v by calling either kinLsDQJtimes, which uses - a difference quotient approximation for J*v, or by calling the - user-supplied routine KINLsJacTimesVecFn if it is non-null. - ------------------------------------------------------------------*/ -int kinLsATimes(void *kinmem, N_Vector v, N_Vector z) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsATimes", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* call Jacobian-times-vector product routine - (either user-supplied or internal DQ) */ - retval = kinls_mem->jtimes(v, z, kin_mem->kin_uu, - &(kinls_mem->new_uu), - kinls_mem->jt_data); - kinls_mem->njtimes++; - return(retval); -} - - -/*--------------------------------------------------------------- - kinLsPSetup: - - This routine interfaces between the generic iterative linear - solvers and the user's psetup routine. It passes to psetup all - required state information from kin_mem. Its return value - is the same as that returned by psetup. Note that the generic - iterative linear solvers guarantee that kinLsPSetup will only - be called in the case that the user's psetup routine is non-NULL. - ---------------------------------------------------------------*/ -int kinLsPSetup(void *kinmem) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsPSetup", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* Call user pset routine to update preconditioner */ - retval = kinls_mem->pset(kin_mem->kin_uu, kin_mem->kin_uscale, - kin_mem->kin_fval, kin_mem->kin_fscale, - kinls_mem->pdata); - kinls_mem->npe++; - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsPSolve - - This routine interfaces between the generic iterative linear - solvers and the user's psolve routine. It passes to psolve all - required state information from kinsol_mem. Its return value is - the same as that returned by psolve. Note that the generic - SUNLinSol solver guarantees that kinLsPSolve will not be called - in the case in which preconditioning is not done. This is the only - case in which the user's psolve routine is allowed to be NULL. - ------------------------------------------------------------------*/ -int kinLsPSolve(void *kinmem, N_Vector r, N_Vector z, realtype tol, int lr) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsPSolve", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* copy the rhs into z before the psolve call */ - /* Note: z returns with the solution */ - N_VScale(ONE, r, z); - - /* note: user-supplied preconditioning with KINSOL does not - support either the 'tol' or 'lr' inputs */ - retval = kinls_mem->psolve(kin_mem->kin_uu, kin_mem->kin_uscale, - kin_mem->kin_fval, kin_mem->kin_fscale, - z, kinls_mem->pdata); - kinls_mem->nps++; - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsDQJac - - This routine is a wrapper for the Dense and Band implementations - of the difference quotient Jacobian approximation routines. - ------------------------------------------------------------------*/ -int kinLsDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - void *kinmem, N_Vector tmp1, N_Vector tmp2) -{ - KINMem kin_mem; - int retval; - - /* access KINMem structure */ - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - "kinLsDQJac", MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - /* verify that Jac is non-NULL */ - if (Jac == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsDQJac", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - - /* Call the matrix-structure-specific DQ approximation routine */ - if (SUNMatGetID(Jac) == SUNMATRIX_DENSE) { - retval = kinLsDenseDQJac(u, fu, Jac, kin_mem, tmp1, tmp2); - } else if (SUNMatGetID(Jac) == SUNMATRIX_BAND) { - retval = kinLsBandDQJac(u, fu, Jac, kin_mem, tmp1, tmp2); - } else { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINLS", "kinLsDQJac", - "unrecognized matrix type for kinLsDQJac"); - retval = KIN_ILL_INPUT; - } - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsDenseDQJac - - This routine generates a dense difference quotient approximation - to the Jacobian of F(u). It assumes a dense SUNMatrix input - stored column-wise, and that elements within each column are - contiguous. The address of the jth column of J is obtained via - the function SUNDenseMatrix_Column() and this pointer is - associated with an N_Vector using the N_VGetArrayPointer and - N_VSetArrayPointer functions. Finally, the actual computation of - the jth column of the Jacobian is done with a call to N_VLinearSum. - - The increment used in the finite-difference approximation - J_ij = ( F_i(u+sigma_j * e_j) - F_i(u) ) / sigma_j - is - sigma_j = max{|u_j|, |1/uscale_j|} * sqrt(uround) - - Note: uscale_j = 1/typ(u_j) - - NOTE: Any type of failure of the system function here leads to an - unrecoverable failure of the Jacobian function and thus of - the linear solver setup function, stopping KINSOL. - ------------------------------------------------------------------*/ -int kinLsDenseDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2) -{ - realtype inc, inc_inv, ujsaved, ujscale, sign; - realtype *tmp2_data, *u_data, *uscale_data; - N_Vector ftemp, jthCol; - sunindextype j, N; - KINLsMem kinls_mem; - int retval = 0; - - /* access LsMem interface structure */ - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* access matrix dimension */ - N = SUNDenseMatrix_Columns(Jac); - - /* Save pointer to the array in tmp2 */ - tmp2_data = N_VGetArrayPointer(tmp2); - - /* Rename work vectors for readibility */ - ftemp = tmp1; - jthCol = tmp2; - - /* Obtain pointers to the data for u and uscale */ - u_data = N_VGetArrayPointer(u); - uscale_data = N_VGetArrayPointer(kin_mem->kin_uscale); - - /* This is the only for loop for 0..N-1 in KINSOL */ - - for (j = 0; j < N; j++) { - - /* Generate the jth col of J(u) */ - - /* Set data address of jthCol, and save u_j values and scaling */ - N_VSetArrayPointer(SUNDenseMatrix_Column(Jac,j), jthCol); - ujsaved = u_data[j]; - ujscale = ONE/uscale_data[j]; - - /* Compute increment */ - sign = (ujsaved >= ZERO) ? ONE : -ONE; - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(ujsaved), ujscale)*sign; - - /* Increment u_j, call F(u), and return if error occurs */ - u_data[j] += inc; - - retval = kin_mem->kin_func(u, ftemp, kin_mem->kin_user_data); - kinls_mem->nfeDQ++; - if (retval != 0) break; - - /* reset u_j */ - u_data[j] = ujsaved; - - /* Construct difference quotient in jthCol */ - inc_inv = ONE/inc; - N_VLinearSum(inc_inv, ftemp, -inc_inv, fu, jthCol); - } - - /* Restore original array pointer in tmp2 */ - N_VSetArrayPointer(tmp2_data, tmp2); - - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsBandDQJac - - This routine generates a banded difference quotient approximation - to the Jacobian of F(u). It assumes a SUNBandMatrix input stored - column-wise, and that elements within each column are contiguous. - This makes it possible to get the address of a column of J via the - function SUNBandMatrix_Column() and to write a simple for loop to - set each of the elements of a column in succession. - - NOTE: Any type of failure of the system function her leads to an - unrecoverable failure of the Jacobian function and thus of - the linear solver setup function, stopping KINSOL. - ------------------------------------------------------------------*/ -int kinLsBandDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2) -{ - realtype inc, inc_inv; - N_Vector futemp, utemp; - sunindextype group, i, j, width, ngroups, i1, i2; - sunindextype N, mupper, mlower; - realtype *col_j, *fu_data, *futemp_data, *u_data, *utemp_data, *uscale_data; - KINLsMem kinls_mem; - int retval = 0; - - /* access LsMem interface structure */ - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* access matrix dimensions */ - N = SUNBandMatrix_Columns(Jac); - mupper = SUNBandMatrix_UpperBandwidth(Jac); - mlower = SUNBandMatrix_LowerBandwidth(Jac); - - /* Rename work vectors for use as temporary values of u and fu */ - futemp = tmp1; - utemp = tmp2; - - /* Obtain pointers to the data for ewt, fy, futemp, y, ytemp */ - fu_data = N_VGetArrayPointer(fu); - futemp_data = N_VGetArrayPointer(futemp); - u_data = N_VGetArrayPointer(u); - uscale_data = N_VGetArrayPointer(kin_mem->kin_uscale); - utemp_data = N_VGetArrayPointer(utemp); - - /* Load utemp with u */ - N_VScale(ONE, u, utemp); - - /* Set bandwidth and number of column groups for band differencing */ - width = mlower + mupper + 1; - ngroups = SUNMIN(width, N); - - for (group=1; group <= ngroups; group++) { - - /* Increment all utemp components in group */ - for(j=group-1; j < N; j+=width) { - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(u_data[j]), - ONE/SUNRabs(uscale_data[j])); - utemp_data[j] += inc; - } - - /* Evaluate f with incremented u */ - retval = kin_mem->kin_func(utemp, futemp, kin_mem->kin_user_data); - if (retval != 0) return(retval); - - /* Restore utemp components, then form and load difference quotients */ - for (j=group-1; j < N; j+=width) { - utemp_data[j] = u_data[j]; - col_j = SUNBandMatrix_Column(Jac, j); - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(u_data[j]), - ONE/SUNRabs(uscale_data[j])); - inc_inv = ONE/inc; - i1 = SUNMAX(0, j-mupper); - i2 = SUNMIN(j+mlower, N-1); - for (i=i1; i <= i2; i++) - SM_COLUMN_ELEMENT_B(col_j,i,j) = inc_inv * (futemp_data[i] - fu_data[i]); - } - } - - /* Increment counter nfeDQ */ - kinls_mem->nfeDQ += ngroups; - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsDQJtimes - - This routine generates the matrix-vector product z = J*v using a - difference quotient approximation. The approximation is - J*v = [func(uu + sigma*v) - func(uu)]/sigma. Here sigma is based - on the dot products (uscale*uu, uscale*v) and - (uscale*v, uscale*v), the L1Norm(uscale*v), and on sqrt_relfunc - (the square root of the relative error in the function). Note - that v in the argument list has already been both preconditioned - and unscaled. - - NOTE: Unlike the DQ Jacobian functions for direct linear solvers - (which are called from within the lsetup function), this - function is called from within the lsolve function and thus - a recovery may still be possible even if the system function - fails (recoverably). - ------------------------------------------------------------------*/ -int kinLsDQJtimes(N_Vector v, N_Vector Jv, N_Vector u, - booleantype *new_u, void *kinmem) -{ - realtype sigma, sigma_inv, sutsv, sq1norm, sign, vtv; - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsDQJtimes", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* ensure that NVector supplies requisite routines */ - if ( (v->ops->nvprod == NULL) || (v->ops->nvdotprod == NULL) || - (v->ops->nvl1norm == NULL) || (v->ops->nvlinearsum == NULL) ){ - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsDQJtimes", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* scale the vector v and put Du*v into vtemp1 */ - N_VProd(v, kin_mem->kin_uscale, kin_mem->kin_vtemp1); - - /* scale u and put into Jv (used as a temporary storage) */ - N_VProd(u, kin_mem->kin_uscale, Jv); - - /* compute dot product (Du*u).(Du*v) */ - sutsv = N_VDotProd(Jv, kin_mem->kin_vtemp1); - - /* compute dot product (Du*v).(Du*v) */ - vtv = N_VDotProd(kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - /* compute differencing factor -- this is from p. 469, Brown and Saad paper */ - sq1norm = N_VL1Norm(kin_mem->kin_vtemp1); - sign = (sutsv >= ZERO) ? ONE : -ONE ; - sigma = sign*(kin_mem->kin_sqrt_relfunc)*SUNMAX(SUNRabs(sutsv),sq1norm)/vtv; - sigma_inv = ONE/sigma; - - /* compute the u-prime at which to evaluate the function func */ - N_VLinearSum(ONE, u, sigma, v, kin_mem->kin_vtemp1); - - /* call the system function to calculate func(u+sigma*v) */ - retval = kinls_mem->jt_func(kin_mem->kin_vtemp1, kin_mem->kin_vtemp2, - kin_mem->kin_user_data); - kinls_mem->nfeDQ++; - if (retval != 0) return(retval); - - /* finish the computation of the difference quotient */ - N_VLinearSum(sigma_inv, kin_mem->kin_vtemp2, -sigma_inv, kin_mem->kin_fval, Jv); - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsInitialize performs remaining initializations specific - to the iterative linear solver interface (and solver itself) - ------------------------------------------------------------------*/ -int kinLsInitialize(KINMem kin_mem) -{ - KINLsMem kinls_mem; - int retval; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsInitialize", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Test for valid combinations of matrix & Jacobian routines: */ - if (kinls_mem->J == NULL) { - - /* If SUNMatrix A is NULL: ensure 'jac' function pointer is NULL */ - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = NULL; - kinls_mem->J_data = NULL; - - } else if (kinls_mem->jacDQ) { - - /* If J is non-NULL, and 'jac' is not user-supplied: - - if A is dense or band, ensure that our DQ approx. is used - - otherwise => error */ - retval = 0; - if (kinls_mem->J->ops->getid) { - - if ( (SUNMatGetID(kinls_mem->J) == SUNMATRIX_DENSE) || - (SUNMatGetID(kinls_mem->J) == SUNMATRIX_BAND) ) { - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } else { - retval++; - } - - } else { - retval++; - } - if (retval) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "kinLsInitialize", - "No Jacobian constructor available for SUNMatrix type"); - kinls_mem->last_flag = KINLS_ILL_INPUT; - return(KINLS_ILL_INPUT); - } - - /* check for required vector operations for kinLsDQJac routine */ - if ( (kin_mem->kin_vtemp1->ops->nvlinearsum == NULL) || - (kin_mem->kin_vtemp1->ops->nvscale == NULL) || - (kin_mem->kin_vtemp1->ops->nvgetarraypointer == NULL) || - (kin_mem->kin_vtemp1->ops->nvsetarraypointer == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsInitialize", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - } else { - - /* If J is non-NULL, and 'jac' is user-supplied, - reset J_data pointer (just in case) */ - kinls_mem->J_data = kin_mem->kin_user_data; - } - - /* Prohibit Picard iteration with DQ Jacobian approximation or difference-quotient J*v */ - if ( (kin_mem->kin_globalstrategy == KIN_PICARD) && - kinls_mem->jacDQ && kinls_mem->jtimesDQ ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsInitialize", MSG_NOL_FAIL); - return(KINLS_ILL_INPUT); - } - - - /** error-checking is complete, begin initializtions **/ - - /* Initialize counters */ - kinLsInitializeCounters(kinls_mem); - - /* Set Jacobian-related fields, based on jtimesDQ */ - if (kinls_mem->jtimesDQ) { - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_data = kin_mem; - } else { - kinls_mem->jt_data = kin_mem->kin_user_data; - } - - /* if J is NULL and: NOT preconditioning or do NOT need to setup the - preconditioner, then set the lsetup function to NULL */ - if (kinls_mem->J == NULL) - if ((kinls_mem->psolve == NULL) || (kinls_mem->pset == NULL)) - kin_mem->kin_lsetup = NULL; - - /* Set scaling vectors assuming RIGHT preconditioning */ - /* NOTE: retval is non-zero only if LS == NULL */ - if (kinls_mem->LS->ops->setscalingvectors) { - retval = SUNLinSolSetScalingVectors(kinls_mem->LS, - kin_mem->kin_fscale, - kin_mem->kin_fscale); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", "kinLsInitialize", - "Error in calling SUNLinSolSetScalingVectors"); - return(KINLS_SUNLS_FAIL); - } - } - - /* If the linear solver is iterative or matrix-iterative, and if left/right - scaling are not supported, we must update linear solver tolerances in an - attempt to account for the fscale vector. We make the following assumptions: - 1. fscale_i = fs_mean, for i=0,...,n-1 (i.e. the weights are homogeneous) - 2. the linear solver uses a basic 2-norm to measure convergence - Hence (using the notation from sunlinsol_spgmr.h, with S = diag(fscale)), - || bbar - Abar xbar ||_2 < tol - <=> || S b - S A x ||_2 < tol - <=> || S (b - A x) ||_2 < tol - <=> \sum_{i=0}^{n-1} (fscale_i (b - A x)_i)^2 < tol^2 - <=> fs_mean^2 \sum_{i=0}^{n-1} (b - A x_i)^2 < tol^2 - <=> \sum_{i=0}^{n-1} (b - A x_i)^2 < tol^2 / fs_mean^2 - <=> || b - A x ||_2 < tol / fs_mean - <=> || b - A x ||_2 < tol * tol_fac - So we compute tol_fac = sqrt(N) / ||fscale||_L2 for scaling desired tolerances */ - if (kinls_mem->iterative && kinls_mem->LS->ops->setscalingvectors == NULL) { - N_VConst(ONE, kin_mem->kin_vtemp1); - kinls_mem->tol_fac = SUNRsqrt(N_VGetLength(kin_mem->kin_vtemp1)) - / N_VWL2Norm(kin_mem->kin_fscale, kin_mem->kin_vtemp1); - } else { - kinls_mem->tol_fac = ONE; - } - - /* Call LS initialize routine, and return result */ - kinls_mem->last_flag = SUNLinSolInitialize(kinls_mem->LS); - return(kinls_mem->last_flag); -} - - -/*------------------------------------------------------------------ - kinLsSetup call the LS setup routine - ------------------------------------------------------------------*/ -int kinLsSetup(KINMem kin_mem) -{ - KINLsMem kinls_mem; - int retval; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsSetup", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* recompute if J if it is non-NULL */ - if (kinls_mem->J) { - - /* Increment nje counter. */ - kinls_mem->nje++; - - /* Clear the linear system matrix if necessary */ - if (SUNLinSolGetType(kinls_mem->LS) == SUNLINEARSOLVER_DIRECT) { - retval = SUNMatZero(kinls_mem->J); - if (retval != 0) { - KINProcessError(kin_mem, KINLS_SUNMAT_FAIL, "KINLS", - "kinLsSetup", MSG_LS_MATZERO_FAILED); - kinls_mem->last_flag = KINLS_SUNMAT_FAIL; - return(kinls_mem->last_flag); - } - } - - /* Call Jacobian routine */ - retval = kinls_mem->jac(kin_mem->kin_uu, kin_mem->kin_fval, - kinls_mem->J, kinls_mem->J_data, - kin_mem->kin_vtemp1, kin_mem->kin_vtemp2); - if (retval != 0) { - KINProcessError(kin_mem, KINLS_JACFUNC_ERR, "KINLS", - "kinLsSetup", MSG_LS_JACFUNC_FAILED); - kinls_mem->last_flag = KINLS_JACFUNC_ERR; - return(kinls_mem->last_flag); - } - - } - - /* Call LS setup routine -- the LS will call kinLsPSetup (if applicable) */ - kinls_mem->last_flag = SUNLinSolSetup(kinls_mem->LS, kinls_mem->J); - - /* save nni value from most recent lsetup call */ - kin_mem->kin_nnilset = kin_mem->kin_nni; - - return(kinls_mem->last_flag); -} - - -/*------------------------------------------------------------------ - kinLsSolve interfaces between KINSOL and the generic - SUNLinearSolver object - ------------------------------------------------------------------*/ -int kinLsSolve(KINMem kin_mem, N_Vector xx, N_Vector bb, - realtype *sJpnorm, realtype *sFdotJp) -{ - KINLsMem kinls_mem; - int nli_inc, retval; - realtype res_norm, tol; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsSolve", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Set linear solver tolerance as input value times scaling factor - (to account for possible lack of support for left/right scaling - vectors in SUNLinSol object) */ - tol = kin_mem->kin_eps * kinls_mem->tol_fac; - - /* Set initial guess x = 0 to LS */ - N_VConst(ZERO, xx); - - /* set flag required for user-supplied J*v routine */ - kinls_mem->new_uu = SUNTRUE; - - /* Call solver */ - retval = SUNLinSolSolve(kinls_mem->LS, kinls_mem->J, xx, bb, tol); - - /* Retrieve solver statistics */ - res_norm = ZERO; - if (kinls_mem->LS->ops->resnorm) - res_norm = SUNLinSolResNorm(kinls_mem->LS); - nli_inc = 0; - if (kinls_mem->LS->ops->numiters) - nli_inc = SUNLinSolNumIters(kinls_mem->LS); - - if (kinls_mem->iterative && kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_NLI, "KINLS", "kinLsSolve", - INFO_NLI, nli_inc); - - /* Increment counters nli and ncfl */ - kinls_mem->nli += nli_inc; - if (retval != SUNLS_SUCCESS) kinls_mem->ncfl++; - - /* Interpret solver return value */ - kinls_mem->last_flag = retval; - - if ( (retval != 0) && (retval != SUNLS_RES_REDUCED) ) { - - switch(retval) { - case SUNLS_ATIMES_FAIL_REC: - case SUNLS_PSOLVE_FAIL_REC: - return(1); - break; - case SUNLS_MEM_NULL: - case SUNLS_ILL_INPUT: - case SUNLS_MEM_FAIL: - case SUNLS_GS_FAIL: - case SUNLS_CONV_FAIL: - case SUNLS_QRFACT_FAIL: - case SUNLS_LUFACT_FAIL: - case SUNLS_QRSOL_FAIL: - break; - case SUNLS_PACKAGE_FAIL_REC: - KINProcessError(kin_mem, SUNLS_PACKAGE_FAIL_REC, "KINLS", - "kinLsSolve", - "Failure in SUNLinSol external package"); - break; - case SUNLS_PACKAGE_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_PACKAGE_FAIL_UNREC, "KINLS", - "kinLsSolve", - "Failure in SUNLinSol external package"); - break; - case SUNLS_ATIMES_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_ATIMES_FAIL_UNREC, "KINLS", - "kinLsSolve", MSG_LS_JTIMES_FAILED); - break; - case SUNLS_PSOLVE_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_PSOLVE_FAIL_UNREC, "KINLS", - "kinLsSolve", MSG_LS_PSOLVE_FAILED); - break; - } - return(retval); - } - - /* SUNLinSolSolve returned SUNLS_SUCCESS or SUNLS_RES_REDUCED */ - - /* Compute auxiliary values for use in the linesearch and in KINForcingTerm. - These will be subsequently corrected if the step is reduced by constraints - or the linesearch. */ - if (kin_mem->kin_globalstrategy != KIN_FP) { - - /* sJpnorm is the norm of the scaled product (scaled by fscale) of the - current Jacobian matrix J and the step vector p (= solution vector xx) */ - if (kin_mem->kin_inexact_ls && kin_mem->kin_etaflag == KIN_ETACHOICE1) { - retval = kinLsATimes(kin_mem, xx, bb); - if (retval > 0) { - kinls_mem->last_flag = SUNLS_ATIMES_FAIL_REC; - return(1); - } - else if (retval < 0) { - kinls_mem->last_flag = SUNLS_ATIMES_FAIL_UNREC; - return(-1); - } - *sJpnorm = N_VWL2Norm(bb, kin_mem->kin_fscale); - } - - /* sFdotJp is the dot product of the scaled f vector and the scaled - vector J*p, where the scaling uses fscale */ - if ((kin_mem->kin_inexact_ls && kin_mem->kin_etaflag == KIN_ETACHOICE1) || - kin_mem->kin_globalstrategy == KIN_LINESEARCH) { - N_VProd(bb, kin_mem->kin_fscale, bb); - N_VProd(bb, kin_mem->kin_fscale, bb); - *sFdotJp = N_VDotProd(kin_mem->kin_fval, bb); - } - } - - if (kin_mem->kin_inexact_ls && kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_EPS, "KINLS", "kinLsSolve", - INFO_EPS, res_norm, kin_mem->kin_eps); - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsFree frees memory associated with the KINLs system - solver interface - ------------------------------------------------------------------*/ -int kinLsFree(KINMem kin_mem) -{ - KINLsMem kinls_mem; - - /* Return immediately if kin_mem or kin_mem->kin_lmem are NULL */ - if (kin_mem == NULL) return (KINLS_SUCCESS); - if (kin_mem->kin_lmem == NULL) return(KINLS_SUCCESS); - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Nullify SUNMatrix pointer */ - kinls_mem->J = NULL; - - /* Free preconditioner memory (if applicable) */ - if (kinls_mem->pfree) kinls_mem->pfree(kin_mem); - - /* free KINLs interface structure */ - free(kin_mem->kin_lmem); - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - kinLsInitializeCounters resets counters for the LS interface - ------------------------------------------------------------------*/ -int kinLsInitializeCounters(KINLsMem kinls_mem) -{ - kinls_mem->nje = 0; - kinls_mem->nfeDQ = 0; - kinls_mem->npe = 0; - kinls_mem->nli = 0; - kinls_mem->nps = 0; - kinls_mem->ncfl = 0; - kinls_mem->njtimes = 0; - return(0); -} - - -/*--------------------------------------------------------------- - kinLs_AccessLMem - - This routine unpacks the kin_mem and ls_mem structures from - void* pointer. If either is missing it returns KINLS_MEM_NULL - or KINLS_LMEM_NULL. - ---------------------------------------------------------------*/ -int kinLs_AccessLMem(void* kinmem, const char *fname, - KINMem *kin_mem, KINLsMem *kinls_mem) -{ - if (kinmem==NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - fname, MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - *kin_mem = (KINMem) kinmem; - if ((*kin_mem)->kin_lmem==NULL) { - KINProcessError(*kin_mem, KINLS_LMEM_NULL, "KINLS", - fname, MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - *kinls_mem = (KINLsMem) (*kin_mem)->kin_lmem; - return(KINLS_SUCCESS); -} - - -/*--------------------------------------------------------------- - EOF - ---------------------------------------------------------------*/ diff --git a/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h deleted file mode 100644 index 1977887e2a..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h +++ /dev/null @@ -1,185 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * David J. Gardner, Radu Serban and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, 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 KINSOL's linear solver interface. - *-----------------------------------------------------------------*/ - -#ifndef _KINLS_IMPL_H -#define _KINLS_IMPL_H - -#include -#include "kinsol_impl.h" - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - - -/*------------------------------------------------------------------ - keys for KINPrintInfo (do not use 1 -> conflict with PRNT_RETVAL) - ------------------------------------------------------------------*/ -#define PRNT_NLI 101 -#define PRNT_EPS 102 - - -/*------------------------------------------------------------------ - Types : struct KINLsMemRec, struct *KINLsMem - - The type KINLsMem is a pointer to a KINLsMemRec, which is a - structure containing fields that must be accessible by LS module - routines. - ------------------------------------------------------------------*/ -typedef struct KINLsMemRec { - - /* Linear solver type information */ - booleantype iterative; /* is the solver iterative? */ - booleantype matrixbased; /* is a matrix structure used? */ - - /* Jacobian construction & storage */ - booleantype jacDQ; /* SUNTRUE if using internal DQ Jacobian approx. */ - KINLsJacFn jac; /* Jacobian routine to be called */ - void *J_data; /* J_data is passed to jac */ - - /* Linear solver, matrix and vector objects/pointers */ - SUNLinearSolver LS; /* generic iterative linear solver object */ - SUNMatrix J; /* problem Jacobian */ - - /* Solver tolerance adjustment factor (if needed, see kinLsSolve) */ - realtype tol_fac; - - /* Statistics and associated parameters */ - long int nje; /* no. of calls to jac */ - long int nfeDQ; /* no. of calls to F due to DQ Jacobian or J*v - approximations */ - long int npe; /* npe = total number of precond calls */ - long int nli; /* nli = total number of linear iterations */ - long int nps; /* nps = total number of psolve calls */ - long int ncfl; /* ncfl = total number of convergence failures */ - long int njtimes; /* njtimes = total number of calls to jtimes */ - - booleantype new_uu; /* flag indicating if the iterate has been - updated - the Jacobian must be updated or - reevaluated (meant to be used by a - user-supplied jtimes function */ - - int last_flag; /* last error return flag */ - - /* Preconditioner computation - (a) user-provided: - - pdata == user_data - - pfree == NULL (the user dealocates memory) - (b) internal preconditioner module - - pdata == kin_mem - - pfree == set by the prec. module and called in kinLsFree */ - KINLsPrecSetupFn pset; - KINLsPrecSolveFn psolve; - int (*pfree)(KINMem kin_mem); - void *pdata; - - /* Jacobian times vector compuation - (a) jtimes function provided by the user: - - jt_data == user_data - - jtimesDQ == SUNFALSE - (b) internal jtimes - - jt_data == kin_mem - - jtimesDQ == SUNTRUE */ - booleantype jtimesDQ; - KINLsJacTimesVecFn jtimes; - KINSysFn jt_func; - void *jt_data; - -} *KINLsMem; - - -/*------------------------------------------------------------------ - Prototypes of internal functions - ------------------------------------------------------------------*/ - -/* Interface routines called by system SUNLinearSolvers */ -int kinLsATimes(void *kinmem, N_Vector v, N_Vector z); -int kinLsPSetup(void *kinmem); -int kinLsPSolve(void *kinmem, N_Vector r, N_Vector z, - realtype tol, int lr); - -/* Difference quotient approximation for Jacobian times vector */ -int kinLsDQJtimes(N_Vector v, N_Vector Jv, N_Vector u, - booleantype *new_u, void *data); - -/* Difference-quotient Jacobian approximation routines */ -int kinLsDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - void *data, N_Vector tmp1, N_Vector tmp2); - -int kinLsDenseDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2); - -int kinLsBandDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2); - -/* Generic linit/lsetup/lsolve/lfree interface routines for KINSOL to call */ -int kinLsInitialize(KINMem kin_mem); -int kinLsSetup(KINMem kin_mem); -int kinLsSolve(KINMem kin_mem, N_Vector x, N_Vector b, - realtype *sJpnorm, realtype *sFdotJp); -int kinLsFree(KINMem kin_mem); - -/* Auxilliary functions */ -int kinLsInitializeCounters(KINLsMem kinls_mem); -int kinLs_AccessLMem(void* kinmem, const char *fname, - KINMem* kin_mem, KINLsMem *kinls_mem); - - -/*------------------------------------------------------------------ - Error messages - ------------------------------------------------------------------*/ - -#define MSG_LS_KINMEM_NULL "KINSOL memory is NULL." -#define MSG_LS_MEM_FAIL "A memory request failed." -#define MSG_LS_BAD_NVECTOR "A required vector operation is not implemented." -#define MSG_LS_LMEM_NULL "Linear solver memory is NULL." -#define MSG_LS_NEG_MAXRS "maxrs < 0 illegal." -#define MSG_LS_BAD_SIZES "Illegal bandwidth parameter(s). Must have 0 <= ml, mu <= N-1." - -#define MSG_LS_JACFUNC_FAILED "The Jacobian routine failed in an unrecoverable manner." -#define MSG_LS_PSET_FAILED "The preconditioner setup routine failed in an unrecoverable manner." -#define MSG_LS_PSOLVE_FAILED "The preconditioner solve routine failed in an unrecoverable manner." -#define MSG_LS_JTIMES_FAILED "The Jacobian x vector routine failed in an unrecoverable manner." -#define MSG_LS_MATZERO_FAILED "The SUNMatZero routine failed in an unrecoverable manner." - - -/*------------------------------------------------------------------ - Info messages - ------------------------------------------------------------------*/ - -#define INFO_NLI "nli_inc = %d" - -#if defined(SUNDIALS_EXTENDED_PRECISION) - -#define INFO_EPS "residual norm = %12.3Lg eps = %12.3Lg" - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -#define INFO_EPS "residual norm = %12.3lg eps = %12.3lg" - -#else - -#define INFO_EPS "residual norm = %12.3g eps = %12.3g" - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_spils.c b/ThirdParty/sundials/src/kinsol/kinsol_spils.c deleted file mode 100644 index 9af333554d..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_spils.c +++ /dev/null @@ -1,73 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * Scott Cohen, Alan Hindmarsh, Radu Serban, - * and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *----------------------------------------------------------------- - * Header file for the deprecated Scaled Preconditioned Iterative - * Linear Solver interface in KINSOL; these routines now just wrap - * the updated KINSOL generic linear solver interface in kinsol_ls.h. - *-----------------------------------------------------------------*/ - -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*================================================================= - Exported Functions (wrappers for equivalent routines in kinsol_ls.h) - =================================================================*/ - -int KINSpilsSetLinearSolver(void *kinmem, SUNLinearSolver LS) -{ return(KINSetLinearSolver(kinmem, LS, NULL)); } - -int KINSpilsSetPreconditioner(void *kinmem, KINSpilsPrecSetupFn psetup, - KINSpilsPrecSolveFn psolve) -{ return(KINSetPreconditioner(kinmem, psetup, psolve)); } - -int KINSpilsSetJacTimesVecFn(void *kinmem, KINSpilsJacTimesVecFn jtv) -{ return(KINSetJacTimesVecFn(kinmem, jtv)); } - -int KINSpilsGetWorkSpace(void *kinmem, long int *lenrwLS, long int *leniwLS) -{ return(KINGetLinWorkSpace(kinmem, lenrwLS, leniwLS)); } - -int KINSpilsGetNumPrecEvals(void *kinmem, long int *npevals) -{ return(KINGetNumPrecEvals(kinmem, npevals)); } - -int KINSpilsGetNumPrecSolves(void *kinmem, long int *npsolves) -{ return(KINGetNumPrecSolves(kinmem, npsolves)); } - -int KINSpilsGetNumLinIters(void *kinmem, long int *nliters) -{ return(KINGetNumLinIters(kinmem, nliters)); } - -int KINSpilsGetNumConvFails(void *kinmem, long int *nlcfails) -{ return(KINGetNumLinConvFails(kinmem, nlcfails)); } - -int KINSpilsGetNumJtimesEvals(void *kinmem, long int *njvevals) -{ return(KINGetNumJtimesEvals(kinmem, njvevals)); } - -int KINSpilsGetNumFuncEvals(void *kinmem, long int *nfevals) -{ return(KINGetNumLinFuncEvals(kinmem, nfevals)); } - -int KINSpilsGetLastFlag(void *kinmem, long int *flag) -{ return(KINGetLastLinFlag(kinmem, flag)); } - -char *KINSpilsGetReturnFlagName(long int flag) -{ return(KINGetLinReturnFlagName(flag)); } - - -#ifdef __cplusplus -} -#endif - diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt deleted file mode 100644 index a5ded42bc5..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the F2003 fixed-point SUNNonlinearSolver -# object library -# --------------------------------------------------------------- - -sundials_add_f2003_library(sundials_fsunnonlinsolfixedpoint_mod - SOURCES - fsunnonlinsol_fixedpoint_mod.f90 fsunnonlinsol_fixedpoint_mod.c - OBJECT_LIBRARIES - sundials_fgeneric_mod_obj - OUTPUT_NAME - sundials_fsunnonlinsolfixedpoint_mod - VERSION - ${sunnonlinsollib_VERSION} - SOVERSION - ${sunnonlinsollib_SOVERSION} -) - -message(STATUS "Added SUNNONLINSOL_FIXEDPOINT F2003 interface") diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c deleted file mode 100644 index 1a01c6da84..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c +++ /dev/null @@ -1,443 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 4.0.0 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------- - * Programmer(s): Auto-generated by swig. - * --------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * -------------------------------------------------------------*/ - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* qualifier for exported *const* global data variables*/ -#ifndef SWIGEXTERN -# ifdef __cplusplus -# define SWIGEXTERN extern -# else -# define SWIGEXTERN -# endif -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -#include -#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ - { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } - - -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif - - -/* Support for the `contract` feature. - * - * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in - * the fortran.cxx file. - */ -#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ - if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } - - -#define SWIGVERSION 0x040000 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "sundials/sundials_nonlinearsolver.h" - - -#include "sunnonlinsol/sunnonlinsol_fixedpoint.h" - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_FixedPoint(N_Vector farg1, int const *farg2) { - SUNNonlinearSolver fresult ; - N_Vector arg1 = (N_Vector) 0 ; - int arg2 ; - SUNNonlinearSolver result; - - arg1 = (N_Vector)(farg1); - arg2 = (int)(*farg2); - result = (SUNNonlinearSolver)SUNNonlinSol_FixedPoint(arg1,arg2); - fresult = result; - return fresult; -} - - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_FixedPointSens(int const *farg1, N_Vector farg2, int const *farg3) { - SUNNonlinearSolver fresult ; - int arg1 ; - N_Vector arg2 = (N_Vector) 0 ; - int arg3 ; - SUNNonlinearSolver result; - - arg1 = (int)(*farg1); - arg2 = (N_Vector)(farg2); - arg3 = (int)(*farg3); - result = (SUNNonlinearSolver)SUNNonlinSol_FixedPointSens(arg1,arg2,arg3); - fresult = result; - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetType_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinearSolver_Type result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (SUNNonlinearSolver_Type)SUNNonlinSolGetType_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolInitialize_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolInitialize_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSolve_FixedPoint(SUNNonlinearSolver farg1, N_Vector farg2, N_Vector farg3, N_Vector farg4, double const *farg5, int const *farg6, void *farg7) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - N_Vector arg2 = (N_Vector) 0 ; - N_Vector arg3 = (N_Vector) 0 ; - N_Vector arg4 = (N_Vector) 0 ; - realtype arg5 ; - int arg6 ; - void *arg7 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (N_Vector)(farg2); - arg3 = (N_Vector)(farg3); - arg4 = (N_Vector)(farg4); - arg5 = (realtype)(*farg5); - arg6 = (int)(*farg6); - arg7 = (void *)(farg7); - result = (int)SUNNonlinSolSolve_FixedPoint(arg1,arg2,arg3,arg4,arg5,arg6,arg7); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolFree_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolFree_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetSysFn_FixedPoint(SUNNonlinearSolver farg1, SUNNonlinSolSysFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn arg2 = (SUNNonlinSolSysFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn)(farg2); - result = (int)SUNNonlinSolSetSysFn_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetConvTestFn_FixedPoint(SUNNonlinearSolver farg1, SUNNonlinSolConvTestFn farg2, void *farg3) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolConvTestFn arg2 = (SUNNonlinSolConvTestFn) 0 ; - void *arg3 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolConvTestFn)(farg2); - arg3 = (void *)(farg3); - result = (int)SUNNonlinSolSetConvTestFn_FixedPoint(arg1,arg2,arg3); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetMaxIters_FixedPoint(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetMaxIters_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetDamping_FixedPoint(SUNNonlinearSolver farg1, double const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - realtype arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (realtype)(*farg2); - result = (int)SUNNonlinSolSetDamping_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumIters_FixedPoint(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumIters_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetCurIter_FixedPoint(SUNNonlinearSolver farg1, int *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int *arg2 = (int *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int *)(farg2); - result = (int)SUNNonlinSolGetCurIter_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumConvFails_FixedPoint(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumConvFails_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetSysFn_FixedPoint(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn *arg2 = (SUNNonlinSolSysFn *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn *)(farg2); - result = (int)SUNNonlinSolGetSysFn_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetInfoFile_FixedPoint(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - FILE *arg2 = (FILE *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (FILE *)(farg2); - result = (int)SUNNonlinSolSetInfoFile_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetPrintLevel_FixedPoint(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetPrintLevel_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - - diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 deleted file mode 100644 index 4b5531731e..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 +++ /dev/null @@ -1,473 +0,0 @@ -! This file was automatically generated by SWIG (http://www.swig.org). -! Version 4.0.0 -! -! Do not make changes to this file unless you know what you are doing--modify -! the SWIG interface file instead. - -! --------------------------------------------------------------- -! Programmer(s): Auto-generated by swig. -! --------------------------------------------------------------- -! SUNDIALS Copyright Start -! Copyright (c) 2002-2021, Lawrence Livermore National Security -! and Southern Methodist University. -! All rights reserved. -! -! See the top-level LICENSE and NOTICE files for details. -! -! SPDX-License-Identifier: BSD-3-Clause -! SUNDIALS Copyright End -! --------------------------------------------------------------- - -module fsunnonlinsol_fixedpoint_mod - use, intrinsic :: ISO_C_BINDING - use fsundials_nvector_mod - use fsundials_types_mod - use fsundials_nonlinearsolver_mod - use fsundials_nvector_mod - use fsundials_types_mod - implicit none - private - - ! DECLARATION CONSTRUCTS - public :: FSUNNonlinSol_FixedPoint - public :: FSUNNonlinSol_FixedPointSens - public :: FSUNNonlinSolGetType_FixedPoint - public :: FSUNNonlinSolInitialize_FixedPoint - public :: FSUNNonlinSolSolve_FixedPoint - public :: FSUNNonlinSolFree_FixedPoint - public :: FSUNNonlinSolSetSysFn_FixedPoint - public :: FSUNNonlinSolSetConvTestFn_FixedPoint - public :: FSUNNonlinSolSetMaxIters_FixedPoint - public :: FSUNNonlinSolSetDamping_FixedPoint - public :: FSUNNonlinSolGetNumIters_FixedPoint - public :: FSUNNonlinSolGetCurIter_FixedPoint - public :: FSUNNonlinSolGetNumConvFails_FixedPoint - public :: FSUNNonlinSolGetSysFn_FixedPoint - public :: FSUNNonlinSolSetInfoFile_FixedPoint - public :: FSUNNonlinSolSetPrintLevel_FixedPoint - -! WRAPPER DECLARATIONS -interface -function swigc_FSUNNonlinSol_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSol_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSol_FixedPointSens(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSol_FixedPointSens") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -integer(C_INT), intent(in) :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT), intent(in) :: farg3 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSolGetType_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolGetType_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolInitialize_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolInitialize_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSolve_FixedPoint(farg1, farg2, farg3, farg4, farg5, farg6, farg7) & -bind(C, name="_wrap_FSUNNonlinSolSolve_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR), value :: farg3 -type(C_PTR), value :: farg4 -real(C_DOUBLE), intent(in) :: farg5 -integer(C_INT), intent(in) :: farg6 -type(C_PTR), value :: farg7 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolFree_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolFree_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetSysFn_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetSysFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetConvTestFn_FixedPoint(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSolSetConvTestFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -type(C_PTR), value :: farg3 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetMaxIters_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetMaxIters_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetDamping_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetDamping_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumIters_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumIters_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetCurIter_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetCurIter_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumConvFails_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumConvFails_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetSysFn_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetSysFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetInfoFile_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetInfoFile_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetPrintLevel_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetPrintLevel_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -end interface - - -contains - ! MODULE SUBPROGRAMS -function FSUNNonlinSol_FixedPoint(y, m) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -type(N_Vector), target, intent(inout) :: y -integer(C_INT), intent(in) :: m -type(C_PTR) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(y) -farg2 = m -fresult = swigc_FSUNNonlinSol_FixedPoint(farg1, farg2) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSol_FixedPointSens(count, y, m) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -integer(C_INT), intent(in) :: count -type(N_Vector), target, intent(inout) :: y -integer(C_INT), intent(in) :: m -type(C_PTR) :: fresult -integer(C_INT) :: farg1 -type(C_PTR) :: farg2 -integer(C_INT) :: farg3 - -farg1 = count -farg2 = c_loc(y) -farg3 = m -fresult = swigc_FSUNNonlinSol_FixedPointSens(farg1, farg2, farg3) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSolGetType_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(SUNNonlinearSolver_Type) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolGetType_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolInitialize_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolInitialize_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSolve_FixedPoint(nls, y0, y, w, tol, callsetup, mem) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(N_Vector), target, intent(inout) :: y0 -type(N_Vector), target, intent(inout) :: y -type(N_Vector), target, intent(inout) :: w -real(C_DOUBLE), intent(in) :: tol -integer(C_INT), intent(in) :: callsetup -type(C_PTR) :: mem -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 -type(C_PTR) :: farg3 -type(C_PTR) :: farg4 -real(C_DOUBLE) :: farg5 -integer(C_INT) :: farg6 -type(C_PTR) :: farg7 - -farg1 = c_loc(nls) -farg2 = c_loc(y0) -farg3 = c_loc(y) -farg4 = c_loc(w) -farg5 = tol -farg6 = callsetup -farg7 = mem -fresult = swigc_FSUNNonlinSolSolve_FixedPoint(farg1, farg2, farg3, farg4, farg5, farg6, farg7) -swig_result = fresult -end function - -function FSUNNonlinSolFree_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolFree_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSetSysFn_FixedPoint(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = sysfn -fresult = swigc_FSUNNonlinSolSetSysFn_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetConvTestFn_FixedPoint(nls, ctestfn, ctest_data) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: ctestfn -type(C_PTR) :: ctest_data -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 -type(C_PTR) :: farg3 - -farg1 = c_loc(nls) -farg2 = ctestfn -farg3 = ctest_data -fresult = swigc_FSUNNonlinSolSetConvTestFn_FixedPoint(farg1, farg2, farg3) -swig_result = fresult -end function - -function FSUNNonlinSolSetMaxIters_FixedPoint(nls, maxiters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: maxiters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = maxiters -fresult = swigc_FSUNNonlinSolSetMaxIters_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetDamping_FixedPoint(nls, beta) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -real(C_DOUBLE), intent(in) :: beta -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = c_loc(nls) -farg2 = beta -fresult = swigc_FSUNNonlinSolSetDamping_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumIters_FixedPoint(nls, niters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: niters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(niters(1)) -fresult = swigc_FSUNNonlinSolGetNumIters_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetCurIter_FixedPoint(nls, iter) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), dimension(*), target, intent(inout) :: iter -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(iter(1)) -fresult = swigc_FSUNNonlinSolGetCurIter_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumConvFails_FixedPoint(nls, nconvfails) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: nconvfails -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(nconvfails(1)) -fresult = swigc_FSUNNonlinSolGetNumConvFails_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetSysFn_FixedPoint(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), target, intent(inout) :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(sysfn) -fresult = swigc_FSUNNonlinSolGetSysFn_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetInfoFile_FixedPoint(nls, info_file) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_PTR) :: info_file -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = info_file -fresult = swigc_FSUNNonlinSolSetInfoFile_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetPrintLevel_FixedPoint(nls, print_level) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: print_level -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = print_level -fresult = swigc_FSUNNonlinSolSetPrintLevel_FixedPoint(farg1, farg2) -swig_result = fresult -end function - - -end module diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt deleted file mode 100644 index 16be4d4387..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the F2003 Newton SUNNonlinearSolver -# object library -# --------------------------------------------------------------- - -sundials_add_f2003_library(sundials_fsunnonlinsolnewton_mod - SOURCES - fsunnonlinsol_newton_mod.f90 fsunnonlinsol_newton_mod.c - OBJECT_LIBRARIES - sundials_fgeneric_mod_obj - OUTPUT_NAME - sundials_fsunnonlinsolnewton_mod - VERSION - ${sunnonlinsollib_VERSION} - SOVERSION - ${sunnonlinsollib_SOVERSION} -) - -message(STATUS "Added SUNNONLINSOL_NEWTON F2003 interface") diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c deleted file mode 100644 index e011e8006f..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c +++ /dev/null @@ -1,453 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 4.0.0 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------- - * Programmer(s): Auto-generated by swig. - * --------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * -------------------------------------------------------------*/ - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* qualifier for exported *const* global data variables*/ -#ifndef SWIGEXTERN -# ifdef __cplusplus -# define SWIGEXTERN extern -# else -# define SWIGEXTERN -# endif -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -#include -#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ - { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } - - -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif - - -/* Support for the `contract` feature. - * - * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in - * the fortran.cxx file. - */ -#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ - if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } - - -#define SWIGVERSION 0x040000 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "sundials/sundials_nonlinearsolver.h" - - -#include "sunnonlinsol/sunnonlinsol_newton.h" - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_Newton(N_Vector farg1) { - SUNNonlinearSolver fresult ; - N_Vector arg1 = (N_Vector) 0 ; - SUNNonlinearSolver result; - - arg1 = (N_Vector)(farg1); - result = (SUNNonlinearSolver)SUNNonlinSol_Newton(arg1); - fresult = result; - return fresult; -} - - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_NewtonSens(int const *farg1, N_Vector farg2) { - SUNNonlinearSolver fresult ; - int arg1 ; - N_Vector arg2 = (N_Vector) 0 ; - SUNNonlinearSolver result; - - arg1 = (int)(*farg1); - arg2 = (N_Vector)(farg2); - result = (SUNNonlinearSolver)SUNNonlinSol_NewtonSens(arg1,arg2); - fresult = result; - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetType_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinearSolver_Type result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (SUNNonlinearSolver_Type)SUNNonlinSolGetType_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolInitialize_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolInitialize_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSolve_Newton(SUNNonlinearSolver farg1, N_Vector farg2, N_Vector farg3, N_Vector farg4, double const *farg5, int const *farg6, void *farg7) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - N_Vector arg2 = (N_Vector) 0 ; - N_Vector arg3 = (N_Vector) 0 ; - N_Vector arg4 = (N_Vector) 0 ; - realtype arg5 ; - int arg6 ; - void *arg7 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (N_Vector)(farg2); - arg3 = (N_Vector)(farg3); - arg4 = (N_Vector)(farg4); - arg5 = (realtype)(*farg5); - arg6 = (int)(*farg6); - arg7 = (void *)(farg7); - result = (int)SUNNonlinSolSolve_Newton(arg1,arg2,arg3,arg4,arg5,arg6,arg7); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolFree_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolFree_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetSysFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolSysFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn arg2 = (SUNNonlinSolSysFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn)(farg2); - result = (int)SUNNonlinSolSetSysFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetLSetupFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolLSetupFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolLSetupFn arg2 = (SUNNonlinSolLSetupFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolLSetupFn)(farg2); - result = (int)SUNNonlinSolSetLSetupFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetLSolveFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolLSolveFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolLSolveFn arg2 = (SUNNonlinSolLSolveFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolLSolveFn)(farg2); - result = (int)SUNNonlinSolSetLSolveFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetConvTestFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolConvTestFn farg2, void *farg3) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolConvTestFn arg2 = (SUNNonlinSolConvTestFn) 0 ; - void *arg3 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolConvTestFn)(farg2); - arg3 = (void *)(farg3); - result = (int)SUNNonlinSolSetConvTestFn_Newton(arg1,arg2,arg3); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetMaxIters_Newton(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetMaxIters_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumIters_Newton(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumIters_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetCurIter_Newton(SUNNonlinearSolver farg1, int *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int *arg2 = (int *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int *)(farg2); - result = (int)SUNNonlinSolGetCurIter_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumConvFails_Newton(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumConvFails_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetSysFn_Newton(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn *arg2 = (SUNNonlinSolSysFn *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn *)(farg2); - result = (int)SUNNonlinSolGetSysFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetInfoFile_Newton(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - FILE *arg2 = (FILE *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (FILE *)(farg2); - result = (int)SUNNonlinSolSetInfoFile_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetPrintLevel_Newton(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetPrintLevel_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - - diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 deleted file mode 100644 index 8d6ab88250..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 +++ /dev/null @@ -1,491 +0,0 @@ -! This file was automatically generated by SWIG (http://www.swig.org). -! Version 4.0.0 -! -! Do not make changes to this file unless you know what you are doing--modify -! the SWIG interface file instead. - -! --------------------------------------------------------------- -! Programmer(s): Auto-generated by swig. -! --------------------------------------------------------------- -! SUNDIALS Copyright Start -! Copyright (c) 2002-2021, Lawrence Livermore National Security -! and Southern Methodist University. -! All rights reserved. -! -! See the top-level LICENSE and NOTICE files for details. -! -! SPDX-License-Identifier: BSD-3-Clause -! SUNDIALS Copyright End -! --------------------------------------------------------------- - -module fsunnonlinsol_newton_mod - use, intrinsic :: ISO_C_BINDING - use fsundials_nvector_mod - use fsundials_types_mod - use fsundials_nonlinearsolver_mod - use fsundials_nvector_mod - use fsundials_types_mod - implicit none - private - - ! DECLARATION CONSTRUCTS - public :: FSUNNonlinSol_Newton - public :: FSUNNonlinSol_NewtonSens - public :: FSUNNonlinSolGetType_Newton - public :: FSUNNonlinSolInitialize_Newton - public :: FSUNNonlinSolSolve_Newton - public :: FSUNNonlinSolFree_Newton - public :: FSUNNonlinSolSetSysFn_Newton - public :: FSUNNonlinSolSetLSetupFn_Newton - public :: FSUNNonlinSolSetLSolveFn_Newton - public :: FSUNNonlinSolSetConvTestFn_Newton - public :: FSUNNonlinSolSetMaxIters_Newton - public :: FSUNNonlinSolGetNumIters_Newton - public :: FSUNNonlinSolGetCurIter_Newton - public :: FSUNNonlinSolGetNumConvFails_Newton - public :: FSUNNonlinSolGetSysFn_Newton - public :: FSUNNonlinSolSetInfoFile_Newton - public :: FSUNNonlinSolSetPrintLevel_Newton - -! WRAPPER DECLARATIONS -interface -function swigc_FSUNNonlinSol_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSol_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSol_NewtonSens(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSol_NewtonSens") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -integer(C_INT), intent(in) :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSolGetType_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolGetType_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolInitialize_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolInitialize_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSolve_Newton(farg1, farg2, farg3, farg4, farg5, farg6, farg7) & -bind(C, name="_wrap_FSUNNonlinSolSolve_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR), value :: farg3 -type(C_PTR), value :: farg4 -real(C_DOUBLE), intent(in) :: farg5 -integer(C_INT), intent(in) :: farg6 -type(C_PTR), value :: farg7 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolFree_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolFree_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetSysFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetSysFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetLSetupFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetLSetupFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetLSolveFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetLSolveFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetConvTestFn_Newton(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSolSetConvTestFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -type(C_PTR), value :: farg3 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetMaxIters_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetMaxIters_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumIters_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumIters_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetCurIter_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetCurIter_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumConvFails_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumConvFails_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetSysFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetSysFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetInfoFile_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetInfoFile_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetPrintLevel_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetPrintLevel_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -end interface - - -contains - ! MODULE SUBPROGRAMS -function FSUNNonlinSol_Newton(y) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -type(N_Vector), target, intent(inout) :: y -type(C_PTR) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(y) -fresult = swigc_FSUNNonlinSol_Newton(farg1) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSol_NewtonSens(count, y) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -integer(C_INT), intent(in) :: count -type(N_Vector), target, intent(inout) :: y -type(C_PTR) :: fresult -integer(C_INT) :: farg1 -type(C_PTR) :: farg2 - -farg1 = count -farg2 = c_loc(y) -fresult = swigc_FSUNNonlinSol_NewtonSens(farg1, farg2) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSolGetType_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(SUNNonlinearSolver_Type) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolGetType_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolInitialize_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolInitialize_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSolve_Newton(nls, y0, y, w, tol, calllsetup, mem) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(N_Vector), target, intent(inout) :: y0 -type(N_Vector), target, intent(inout) :: y -type(N_Vector), target, intent(inout) :: w -real(C_DOUBLE), intent(in) :: tol -integer(C_INT), intent(in) :: calllsetup -type(C_PTR) :: mem -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 -type(C_PTR) :: farg3 -type(C_PTR) :: farg4 -real(C_DOUBLE) :: farg5 -integer(C_INT) :: farg6 -type(C_PTR) :: farg7 - -farg1 = c_loc(nls) -farg2 = c_loc(y0) -farg3 = c_loc(y) -farg4 = c_loc(w) -farg5 = tol -farg6 = calllsetup -farg7 = mem -fresult = swigc_FSUNNonlinSolSolve_Newton(farg1, farg2, farg3, farg4, farg5, farg6, farg7) -swig_result = fresult -end function - -function FSUNNonlinSolFree_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolFree_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSetSysFn_Newton(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = sysfn -fresult = swigc_FSUNNonlinSolSetSysFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetLSetupFn_Newton(nls, lsetupfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: lsetupfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = lsetupfn -fresult = swigc_FSUNNonlinSolSetLSetupFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetLSolveFn_Newton(nls, lsolvefn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: lsolvefn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = lsolvefn -fresult = swigc_FSUNNonlinSolSetLSolveFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetConvTestFn_Newton(nls, ctestfn, ctest_data) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: ctestfn -type(C_PTR) :: ctest_data -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 -type(C_PTR) :: farg3 - -farg1 = c_loc(nls) -farg2 = ctestfn -farg3 = ctest_data -fresult = swigc_FSUNNonlinSolSetConvTestFn_Newton(farg1, farg2, farg3) -swig_result = fresult -end function - -function FSUNNonlinSolSetMaxIters_Newton(nls, maxiters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: maxiters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = maxiters -fresult = swigc_FSUNNonlinSolSetMaxIters_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumIters_Newton(nls, niters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: niters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(niters(1)) -fresult = swigc_FSUNNonlinSolGetNumIters_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetCurIter_Newton(nls, iter) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), dimension(*), target, intent(inout) :: iter -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(iter(1)) -fresult = swigc_FSUNNonlinSolGetCurIter_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumConvFails_Newton(nls, nconvfails) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: nconvfails -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(nconvfails(1)) -fresult = swigc_FSUNNonlinSolGetNumConvFails_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetSysFn_Newton(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), target, intent(inout) :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(sysfn) -fresult = swigc_FSUNNonlinSolGetSysFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetInfoFile_Newton(nls, info_file) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_PTR) :: info_file -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = info_file -fresult = swigc_FSUNNonlinSolSetInfoFile_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetPrintLevel_Newton(nls, print_level) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: print_level -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = print_level -fresult = swigc_FSUNNonlinSolSetPrintLevel_Newton(farg1, farg2) -swig_result = fresult -end function - - -end module diff --git a/documentation/INSTALL.md b/documentation/INSTALL.md deleted file mode 120000 index 71db8b4934..0000000000 --- a/documentation/INSTALL.md +++ /dev/null @@ -1 +0,0 @@ -../INSTALL.md \ No newline at end of file diff --git a/documentation/amici_refs.bib b/documentation/amici_refs.bib index 6a0b18243f..9eaf4c9db7 100644 --- a/documentation/amici_refs.bib +++ b/documentation/amici_refs.bib @@ -999,6 +999,32 @@ @Article{AdlungSta2021 url = {https://www.sciencedirect.com/science/article/pii/S2211124721009372}, } +@article {Sundqvist2022.02.15.480629, + author = {Sundqvist, Nicolas and Sten, Sebastian and Engstr{\"o}m, Maria and Cedersund, Gunnar}, + title = {Mechanistic model for human brain metabolism and the neurovascular coupling.}, + elocation-id = {2022.02.15.480629}, + year = {2022}, + doi = {10.1101/2022.02.15.480629}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {The neurovascular coupling (NVC) connects cerebral activity, blood flow, and metabolism. This interconnection is used in for instance functional imaging, which analyses the blood-oxygen-dependent (BOLD) signal. The mechanisms underlying the NVC are complex, which warrants a model-based analysis of data. We have previously developed a mechanistically detailed model for the NVC, and others have proposed detailed models for cerebral metabolism. However, existing metabolic models are still not fully utilizing available magnetic resonance spectroscopy (MRS) data and are not connected to detailed models for NVC. Therefore, we herein present a new model that integrates mechanistic modelling of both MRS and BOLD data. The metabolic model covers central metabolism, and can describe time-series data for glucose, lactate, aspartate, and glutamine, measured after visual stimuli. Statistical tests confirm that the model can describe both estimation data and predict independent validation data, not used for model training. The interconnected NVC model can simultaneously describe BOLD data and can be used to predict expected metabolic responses in experiments where metabolism has not been measured. This model is a step towards a useful and mechanistically detailed model for cerebral blood flow and metabolism, with potential applications in both basic research and clinical applications.Competing Interest StatementThe authors have declared no competing interest.}, + URL = {https://www.biorxiv.org/content/early/2022/02/19/2022.02.15.480629}, + eprint = {https://www.biorxiv.org/content/early/2022/02/19/2022.02.15.480629.full.pdf}, + journal = {bioRxiv} +} + +@article {Froehlich2022.02.17.480899, + author = {Fr{\"o}hlich, Fabian and Gerosa, Luca and Muhlich, Jeremy and Sorger, Peter K.}, + title = {Mechanistic model of MAPK signaling reveals how allostery and rewiring contribute to drug resistance}, + elocation-id = {2022.02.17.480899}, + year = {2022}, + doi = {10.1101/2022.02.17.480899}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {BRAFV600E is prototypical of oncogenic mutations that can be targeted therapeutically and treatment of BRAF-mutant melanomas with RAF and MEK inhibitors results in rapid tumor regression. However, drug-induced rewiring causes BRAFV600E melanoma cells to rapidly acquire a drug-adapted state. In patients this is thought to promote acquisition or selection for resistance mutations and disease recurrence. In this paper we use an energy-based implementation of ordinary differential equations in combination with proteomic, transcriptomic and imaging data from melanoma cells, to model the precise mechanisms responsible for adaptive rewiring. We demonstrate the presence of two parallel MAPK (RAF-MEK-ERK kinase) reaction channels in BRAFV600E melanoma cells that are differentially sensitive to RAF and MEK inhibitors. This arises from differences in protein oligomerization and allosteric regulation induced by oncogenic mutations and drug binding. As a result, the RAS-regulated MAPK channel can be active under conditions in which the BRAFV600E-driven channel is fully inhibited. Causal tracing demonstrates that this provides a sufficient quantitative explanation for initial and acquired responses to multiple different RAF and MEK inhibitors individually and in combination.HighlightsA thermodynamic framework enables structure-based description of allosteric interactions in the EGFR and MAPK pathwaysCausal decomposition of efficacy of targeted drugs elucidates rewiring of MAPK channelsModel-based extrapolation from type I{\textonehalf} RAF inhibitors to type II RAF inhibitorsA unified mechanistic explanation for adaptive and genetic resistance across BRAF-cancersCompeting Interest StatementPKS is a member of the SAB or Board of Directors of Glencoe Software, Applied Biomath, and RareCyte Inc. and has equity in these companies; PKS is also a member of the SAB of NanoString and a consultant for Montai Health and Merck. LG is currently an employee of Genentech. PKS and LG declare that none of these relationships are directly or indirectly related to the content of this manuscript.}, + URL = {https://www.biorxiv.org/content/early/2022/02/18/2022.02.17.480899}, + eprint = {https://www.biorxiv.org/content/early/2022/02/18/2022.02.17.480899.full.pdf}, + journal = {bioRxiv} +} + @Comment{jabref-meta: databaseType:bibtex;} @Comment{jabref-meta: grouping: diff --git a/documentation/conf.py b/documentation/conf.py index 99dfa29b85..f9dbc3fb94 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -20,8 +20,9 @@ # need to import before setting typing.TYPE_CHECKING=True, fails otherwise import pandas as pd +import sympy as sp -exhale_multiproject_monkeypatch, pd # to avoid removal of unused import +exhale_multiproject_monkeypatch, pd, sp # to avoid removal of unused import # BEGIN Monkeypatch exhale from exhale.deploy import _generate_doxygen as exhale_generate_doxygen diff --git a/documentation/development.rst b/documentation/development.rst index 2b6bd563e8..b26980ceda 100644 --- a/documentation/development.rst +++ b/documentation/development.rst @@ -56,7 +56,7 @@ process described below: - Run ``scripts/run-doxygen.sh`` to check completeness of your documentation -- Make sure your code is compatible with C++11, ``gcc`` and ``clang`` +- Make sure your code is compatible with C++14, ``gcc`` and ``clang`` (our CI pipeline will do this for you) - When adding new functionality, please also provide test cases (see @@ -99,7 +99,7 @@ General Python ^^^^^^ -- We want to be compatible with Python 3.7 +- We want to be compatible with Python 3.8 - For the Python code we want to follow `PEP8 `__. Although this diff --git a/documentation/glossary.rst b/documentation/glossary.rst index 4f92d18e1a..c732af7a3a 100644 --- a/documentation/glossary.rst +++ b/documentation/glossary.rst @@ -5,6 +5,10 @@ Glossary .. glossary:: :sorted: + BNGL + `BioNetGenLanguage `_ is a language for + modular, structure-based modeling of biochemical reaction networks. + CVODES `CVODES `_ is a solver for stiff and non-stiff :term:`ODE` systems with sensitivity @@ -46,8 +50,8 @@ Glossary biology models as Python code. SBML - `SBML `_ is a commonly used format for specifying - systems biology models. + The `Systems Biology Markup Language `_ is a + commonly used format for specifying systems biology models. SUNDIALS `SUNDIALS `_: diff --git a/documentation/model_steadystate_scaled_without_observables.xml b/documentation/model_steadystate_scaled_without_observables.xml new file mode 120000 index 0000000000..be8991d93e --- /dev/null +++ b/documentation/model_steadystate_scaled_without_observables.xml @@ -0,0 +1 @@ +../python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml \ No newline at end of file diff --git a/documentation/python_interface.rst b/documentation/python_interface.rst index 9db3a06c7c..bea321b4ab 100644 --- a/documentation/python_interface.rst +++ b/documentation/python_interface.rst @@ -104,9 +104,11 @@ PySB import AMICI can import :term:`PySB` models via :py:func:`amici.pysb_import.pysb2amici`. -`BioNetGen `_ and -`Kappa `_ models can be imported into AMICI using -PySB. +BNGL import +----------- + +AMICI can import :term:`BNGL` models via +:py:func:`amici.bngl_import.bngl2amici`. PEtab import ------------ diff --git a/documentation/python_modules.rst b/documentation/python_modules.rst index b493fb7ff7..080e512a49 100644 --- a/documentation/python_modules.rst +++ b/documentation/python_modules.rst @@ -10,14 +10,17 @@ AMICI Python API amici.amici amici.sbml_import amici.pysb_import + amici.bngl_import amici.petab_import amici.petab_import_pysb amici.petab_objective amici.petab_simulate amici.import_utils amici.ode_export + amici.ode_model amici.plotting amici.pandas amici.logging amici.gradient_check amici.parameter_mapping + amici.conserved_moieties diff --git a/documentation/references.md b/documentation/references.md index 7c559496c0..e21c044115 100644 --- a/documentation/references.md +++ b/documentation/references.md @@ -1,17 +1,23 @@ # References -List of publications using AMICI. Total number is 64. +List of publications using AMICI. Total number is 66. If you applied AMICI in your work and your publication is missing, please let us know via a new Github issue.

2022

+
+

Fröhlich, Fabian, Luca Gerosa, Jeremy Muhlich, and Peter K. Sorger. 2022. “Mechanistic Model of Mapk Signaling Reveals How Allostery and Rewiring Contribute to Drug Resistance.” bioRxiv. https://doi.org/10.1101/2022.02.17.480899.

+

Schmucker, Robin, Gabriele Farina, James Faeder, Fabian Fröhlich, Ali Sinan Saglam, and Tuomas Sandholm. 2022. “Combination Treatment Optimization Using a Pan-Cancer Pathway Model.” PLOS Computational Biology 17 (12): 1–22. https://doi.org/10.1371/journal.pcbi.1009689.

Stapor, Paul, Leonard Schmiester, Christoph Wierling, Simon Merkt, Dilan Pathirana, Bodo M. H. Lange, Daniel Weindl, and Jan Hasenauer. 2022. “Mini-batch optimization enables training of ODE models on large-scale datasets.” Nature Communications 13 (1): 34. https://doi.org/10.1038/s41467-021-27374-6.

+
+

Sundqvist, Nicolas, Sebastian Sten, Maria Engström, and Gunnar Cedersund. 2022. “Mechanistic Model for Human Brain Metabolism and the Neurovascular Coupling.” bioRxiv. https://doi.org/10.1101/2022.02.15.480629.

+

2021

diff --git a/documentation/rtd_requirements.txt b/documentation/rtd_requirements.txt index fcb9061795..d386993726 100644 --- a/documentation/rtd_requirements.txt +++ b/documentation/rtd_requirements.txt @@ -5,6 +5,9 @@ pysb>=1.11.0 matplotlib>=3.4.3 pkgconfig>=1.5.5 nbsphinx>=0.8.7 +# nbformat-5.2.0 fails with: +# Could not import extension nbsphinx (exception: No module named 'ipython_genutils') +nbformat==5.1.3 recommonmark>=0.6.0 sphinx_rtd_theme>=1.0.0 petab>=0.1.20 diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index dc11b13e9f..2d703a93ba 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -282,13 +282,14 @@ class AbstractModel { * @param p parameter vector * @param k constant vector * @param h Heaviside vector + * @param tcl total abundances for conservation laws * @param sx current state sensitivity * @param ip sensitivity index * @param ie event index */ virtual void fstau(realtype *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, - const realtype *sx, int ip, int ie); + const realtype *tcl, const realtype *sx, int ip, int ie); /** * @brief Model-specific implementation of fy @@ -305,7 +306,7 @@ class AbstractModel { const realtype *w); /** - * @brief Model-specific implementation of fdydp + * @brief Model-specific implementation of fdydp (MATLAB-only) * @param dydp partial derivative of observables y w.r.t. model parameters p * @param t current time * @param x current state @@ -320,6 +321,24 @@ class AbstractModel { const realtype *p, const realtype *k, const realtype *h, int ip, const realtype *w, const realtype *dwdp); + /** + * @brief Model-specific implementation of fdydp (Python) + * @param dydp partial derivative of observables y w.r.t. model parameters p + * @param t current time + * @param x current state + * @param p parameter vector + * @param k constant vector + * @param h Heaviside vector + * @param ip parameter index w.r.t. which the derivative is requested + * @param w repeating elements vector + * @param tcl total abundances for conservation laws + * @param dtcldp Sensitivities of total abundances for conservation laws + */ + virtual void fdydp(realtype *dydp, const realtype t, const realtype *x, + const realtype *p, const realtype *k, const realtype *h, + int ip, const realtype *w, const realtype *tcl, + const realtype *dtcldp); + /** * @brief Model-specific implementation of fdydx * @param dydx partial derivative of observables y w.r.t. model states x @@ -487,13 +506,15 @@ class AbstractModel { * @param xdot_old previous model right hand side * @param sx state sensitivity * @param stau event-time sensitivity + * @param tcl total abundances for conservation laws */ virtual void fdeltasx(realtype *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, int ip, int ie, const realtype *xdot, const realtype *xdot_old, - const realtype *sx, const realtype *stau); + const realtype *sx, const realtype *stau, + const realtype *tcl); /** * @brief Model-specific implementation of fdeltaxB @@ -540,20 +561,36 @@ class AbstractModel { * @param t current time * @param p parameter vector * @param k constant vector + * @param y model output at timepoint t */ virtual void fsigmay(realtype *sigmay, const realtype t, const realtype *p, - const realtype *k); + const realtype *k, const realtype *y); /** - * @brief Model-specific implementation of fsigmay + * @brief Model-specific implementation of fdsigmaydp * @param dsigmaydp partial derivative of standard deviation of measurements * @param t current time * @param p parameter vector * @param k constant vector + * @param y model output at timepoint t * @param ip sensitivity index */ virtual void fdsigmaydp(realtype *dsigmaydp, const realtype t, - const realtype *p, const realtype *k, int ip); + const realtype *p, const realtype *k, + const realtype *y, int ip); + /** + * @brief Model-specific implementation of fsigmay + * @param dsigmaydy partial derivative of standard deviation of measurements + * w.r.t. model outputs + * @param t current time + * @param p parameter vector + * @param k constant vector + * @param y model output at timepoint t + */ + virtual void fdsigmaydy(realtype *dsigmaydy, const realtype t, + const realtype *p, const realtype *k, + const realtype *y); + /** * @brief Model-specific implementation of fsigmaz @@ -833,6 +870,106 @@ class AbstractModel { * @param dwdw sparse matrix to which rowvals will be written */ virtual void fdwdw_rowvals(SUNMatrixWrapper &dwdw); + + /** + * @brief Compute dx_rdata / dx_solver + * @param dx_rdatadx_solver dx_rdata / dx_solver + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + */ + virtual void fdx_rdatadx_solver(realtype *dx_rdatadx_solver, + const realtype *x, const realtype *tcl, + const realtype *p, const realtype *k); + + /** + * @brief Model-specific implementation of fdx_rdatadx_solver, colptrs part + * @param dxrdatadxsolver sparse matrix to which colptrs will be written + */ + virtual void fdx_rdatadx_solver_colptrs(SUNMatrixWrapper &dxrdatadxsolver); + + /** + * @brief Model-specific implementation of fdx_rdatadx_solver, rowvals part + * @param dxrdatadxsolver sparse matrix to which rowvals will be written + */ + virtual void fdx_rdatadx_solver_rowvals(SUNMatrixWrapper &dxrdatadxsolver); + + /** + * @brief Compute dx_rdata / dp + * @param dx_rdatadp dx_rdata / dp + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + * @param ip Sensitivity index + */ + virtual void fdx_rdatadp(realtype *dx_rdatadp, const realtype *x, + const realtype *tcl, const realtype *p, + const realtype *k, const int ip); + + /** + * @brief Compute dx_rdata / dtcl + * @param dx_rdatadtcl dx_rdata / dtcl + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + */ + virtual void fdx_rdatadtcl(realtype *dx_rdatadtcl, const realtype *x, + const realtype *tcl, const realtype *p, + const realtype *k); + + /** + * @brief Model-specific implementation of fdx_rdatadtcl, colptrs part + * @param dx_rdatadtcl sparse matrix to which colptrs will be written + */ + virtual void fdx_rdatadtcl_colptrs(SUNMatrixWrapper &dx_rdatadtcl); + + /** + * @brief Model-specific implementation of fdx_rdatadtcl, rowvals part + * @param dx_rdatadtcl sparse matrix to which rowvals will be written + */ + virtual void fdx_rdatadtcl_rowvals(SUNMatrixWrapper &dx_rdatadtcl); + + /** + * @brief Compute dtotal_cl / dp + * @param dtotal_cldp dtotal_cl / dp + * @param x_rdata State variables with conservation laws applied + * @param p parameter vector + * @param k constant vector + * @param ip Sensitivity index + */ + virtual void fdtotal_cldp(realtype *dtotal_cldp, const realtype *x_rdata, + const realtype *p, const realtype *k, + const int ip); + + /** + * @brief Compute dtotal_cl / dx_rdata + * @param dtotal_cldx_rdata dtotal_cl / dx_rdata + * @param x_rdata State variables with conservation laws applied + * @param p parameter vector + * @param k constant vector + * @param tcl Total abundances for conservation laws + */ + virtual void fdtotal_cldx_rdata(realtype *dtotal_cldx_rdata, + const realtype *x_rdata, const realtype *p, + const realtype *k, const realtype *tcl); + + /** + * @brief Model-specific implementation of fdtotal_cldx_rdata, colptrs part + * @param dtotal_cldx_rdata sparse matrix to which colptrs will be written + */ + virtual void fdtotal_cldx_rdata_colptrs( + SUNMatrixWrapper &dtotal_cldx_rdata); + + /** + * @brief Model-specific implementation of fdtotal_cldx_rdata, rowvals part + * @param dtotal_cldx_rdata sparse matrix to which rowvals will be written + */ + virtual void fdtotal_cldx_rdata_rowvals( + SUNMatrixWrapper &dtotal_cldx_rdata); + }; } // namespace amici diff --git a/include/amici/cblas.h b/include/amici/cblas.h index 6aed56ba43..bbfef955fe 100644 --- a/include/amici/cblas.h +++ b/include/amici/cblas.h @@ -6,18 +6,19 @@ namespace amici { /** - * amici_dgemm provides an interface to the CBlas matrix vector multiplication - * routine dgemv. This routines computes - * y = alpha*A*x + beta*y with A: [MxN] x:[Nx1] y:[Mx1] + * @brief CBLAS matrix vector multiplication (dgemv). * - * @param layout always needs to be AMICI_BLAS_ColMajor. + * Computes \f$ y = alpha*A*x + beta*y \f$ with A: [MxN] x:[Nx1] y:[Mx1] + * + * @param layout Matrix layout, column major or row major. * @param TransA flag indicating whether A should be transposed before * multiplication * @param M number of rows in A * @param N number of columns in A * @param alpha coefficient alpha * @param A matrix A - * @param lda leading dimension of A (m or n) + * @param lda leading dimension / stride of A (>=N if row-major, + * >=M if col-major) * @param X vector X * @param incX increment for entries of X * @param beta coefficient beta @@ -30,9 +31,10 @@ void amici_dgemv(BLASLayout layout, BLASTranspose TransA, double beta, double *Y, int incY); /** - * amici_dgemm provides an interface to the CBlas matrix matrix multiplication - * routine dgemm. This routines computes - * C = alpha*A*B + beta*C with A: [MxK] B:[KxN] C:[MxN] + * @brief CBLAS matrix matrix multiplication (dgemm) + * + * This routines computes \f$ C = alpha*A*B + beta*C \f$ + * with A: [MxK] B:[KxN] C:[MxN] * * @param layout memory layout. * @param TransA flag indicating whether A should be transposed before @@ -44,12 +46,12 @@ void amici_dgemv(BLASLayout layout, BLASTranspose TransA, * @param K number of rows in B, number of columns in A * @param alpha coefficient alpha * @param A matrix A - * @param lda leading dimension of A (m or k) + * @param lda leading dimension of A (>=M or >=K) * @param B matrix B - * @param ldb leading dimension of B (k or n) + * @param ldb leading dimension of B (>=K or >=N) * @param beta coefficient beta * @param C matrix C - * @param ldc leading dimension of C (m or n) + * @param ldc leading dimension of C (>=M or >= N) */ void amici_dgemm(BLASLayout layout, BLASTranspose TransA, BLASTranspose TransB, int M, int N, diff --git a/include/amici/model.h b/include/amici/model.h index 7de98177e8..fac088af2c 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -115,6 +115,7 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fdrzdp; using AbstractModel::fdrzdx; using AbstractModel::fdsigmaydp; + using AbstractModel::fdsigmaydy; using AbstractModel::fdsigmazdp; using AbstractModel::fdwdp; using AbstractModel::fdwdp_colptrs; @@ -145,6 +146,17 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fx0_fixedParameters; using AbstractModel::fy; using AbstractModel::fz; + using AbstractModel::fdx_rdatadx_solver; + using AbstractModel::fdx_rdatadx_solver_colptrs; + using AbstractModel::fdx_rdatadx_solver_rowvals; + using AbstractModel::fdx_rdatadp; + using AbstractModel::fdx_rdatadtcl; + using AbstractModel::fdx_rdatadtcl_colptrs; + using AbstractModel::fdx_rdatadtcl_rowvals; + using AbstractModel::fdtotal_cldx_rdata; + using AbstractModel::fdtotal_cldx_rdata_colptrs; + using AbstractModel::fdtotal_cldx_rdata_rowvals; + using AbstractModel::fdtotal_cldp; /** * @brief Initialize model properties. @@ -851,11 +863,13 @@ class Model : public AbstractModel, public ModelDimensions { * Total derivative (can be used with both adjoint and forward sensitivity). * * @param ssigmay Buffer (shape `ny` x `nplist`, row-major) + * @param sy Sensitivity of time-resolved observables for current timepoint * @param it Timepoint index * @param edata Pointer to experimental data instance (optional, pass * `nullptr` to ignore) */ void getObservableSigmaSensitivity(gsl::span ssigmay, + gsl::span sy, const int it, const ExpData *edata); /** @@ -1265,8 +1279,11 @@ class Model : public AbstractModel, public ModelDimensions { * conservation laws expanded (stored in `amici::ReturnData`). * @param sx_solver State variables sensitivities with conservation laws * applied (solver returns this) + * @param x_solver State variables with conservation laws + * applied (solver returns this) */ - void fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx_solver); + void fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx_solver, + const AmiVector &x_solver); /** * @brief Set indices of states to be reinitialized based on provided @@ -1393,6 +1410,14 @@ class Model : public AbstractModel, public ModelDimensions { */ void fdsigmaydp(int it, const ExpData *edata); + /** + * @brief Compute partial derivative of standard deviation of measurements + * w.r.t. model outputs. + * @param it Timepoint index + * @param edata pointer to `amici::ExpData` data instance holding sigma values + */ + void fdsigmaydy(int it, const ExpData *edata); + /** * @brief Compute negative log-likelihood of measurements \f$ y \f$. * @@ -1644,9 +1669,12 @@ class Model : public AbstractModel, public ModelDimensions { * @param x_rdata State variables with conservation laws expanded * @param x_solver State variables with conservation laws applied * @param tcl Total abundances for conservation laws + * @param p parameter vector + * @param k constant vector */ virtual void fx_rdata(realtype *x_rdata, const realtype *x_solver, - const realtype *tcl); + const realtype *tcl, const realtype *p, + const realtype *k); /** * @brief Compute fsx_solver. @@ -1658,10 +1686,17 @@ class Model : public AbstractModel, public ModelDimensions { * @param sx_solver State sensitivity variables with conservation laws * applied * @param stcl Sensitivities of total abundances for conservation laws + * @param p parameter vector + * @param k constant vector + * @param x_solver State variables with conservation laws applied + * @param tcl Total abundances for conservation laws * @param ip Sensitivity index */ virtual void fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, - const realtype *stcl, int ip); + const realtype *stcl, const realtype *p, + const realtype *k, const realtype *x_solver, + const realtype *tcl, + const int ip); /** * @brief Compute fx_solver. @@ -1692,8 +1727,11 @@ class Model : public AbstractModel, public ModelDimensions { * * @param total_cl Total abundances of conservation laws * @param x_rdata State variables with conservation laws expanded + * @param p parameter vector + * @param k constant vector */ - virtual void ftotal_cl(realtype *total_cl, const realtype *x_rdata); + virtual void ftotal_cl(realtype *total_cl, const realtype *x_rdata, + const realtype *p, const realtype *k); /** * @brief Compute fstotal_cl @@ -1705,9 +1743,15 @@ class Model : public AbstractModel, public ModelDimensions { * @param sx_rdata State sensitivity variables with conservation laws * expanded * @param ip Sensitivity index + * @param x_rdata State variables with conservation laws expanded + * @param p parameter vector + * @param k constant vector + * @param tcl Total abundances for conservation laws */ virtual void fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, - int ip); + const int ip, const realtype *x_rdata, + const realtype *p, const realtype *k, + const realtype *tcl); /** * @brief Compute non-negative state vector. @@ -1723,7 +1767,7 @@ class Model : public AbstractModel, public ModelDimensions { * stateIsNonNegative */ const_N_Vector computeX_pos(const_N_Vector x); - + /** * @brief Compute non-negative state vector. * diff --git a/include/amici/model_dimensions.h b/include/amici/model_dimensions.h index ca7f0f1af0..eb53756e44 100644 --- a/include/amici/model_dimensions.h +++ b/include/amici/model_dimensions.h @@ -39,8 +39,16 @@ struct ModelDimensions { * repeating elements * @param ndwdw Number of nonzero elements in the `w` derivative of the * repeating elements - * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of \f$ xdot\f$ - * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of \f$ dJy\f$ (shape `nytrue`) + * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of + * \f$ xdot\f$ + * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of + * \f$ dJy\f$ (shape `nytrue`) + * @param ndxrdatadxsolver Number of nonzero elements in the \f$ x\f$ + * derivative of \f$ x_rdata\f$ + * @param ndxrdatadtcl Number of nonzero elements in the \f$ tcl\f$ + * derivative of \f$ x_rdata\f$ + * @param ndtotal_cldx_rdata Number of nonzero elements in the + * \f$ x_rdata \f$ derivative of \f$ total_cl \f$ * @param nnz Number of nonzero elements in Jacobian * @param ubw Upper matrix bandwidth in the Jacobian * @param lbw Lower matrix bandwidth in the Jacobian @@ -52,6 +60,8 @@ struct ModelDimensions { const int nytrue, const int nz, const int nztrue, const int ne, const int nJ, const int nw, const int ndwdx, const int ndwdp, const int ndwdw, const int ndxdotdw, std::vector ndJydy, + const int ndxrdatadxsolver, const int ndxrdatadtcl, + const int ndtotal_cldx_rdata, const int nnz, const int ubw, const int lbw) : nx_rdata(nx_rdata), nxtrue_rdata(nxtrue_rdata), nx_solver(nx_solver), nxtrue_solver(nxtrue_solver), nx_solver_reinit(nx_solver_reinit), @@ -59,6 +69,8 @@ struct ModelDimensions { ny(ny), nytrue(nytrue), nz(nz), nztrue(nztrue), ne(ne), nw(nw), ndwdx(ndwdx), ndwdp(ndwdp), ndwdw(ndwdw), ndxdotdw(ndxdotdw), ndJydy(std::move(ndJydy)), + ndxrdatadxsolver(ndxrdatadxsolver), ndxrdatadtcl(ndxrdatadtcl), + ndtotal_cldx_rdata(ndtotal_cldx_rdata), nnz(nnz), nJ(nJ), ubw(ubw), lbw(lbw) { Expects(nxtrue_rdata >= 0); Expects(nxtrue_rdata <= nx_rdata); @@ -82,6 +94,12 @@ struct ModelDimensions { Expects(ndwdw >= 0); Expects(ndwdw <= nw * nw); Expects(ndxdotdw >= 0); + Expects(ndxrdatadxsolver >= 0); + Expects(ndxrdatadxsolver <= nx_rdata * nx_solver); + Expects(ndxrdatadtcl >= 0); + Expects(ndxrdatadtcl <= nx_rdata * (nx_rdata-nx_solver)); + Expects(ndtotal_cldx_rdata >= 0); + Expects(ndtotal_cldx_rdata <= (nx_rdata-nx_solver) * nx_rdata); Expects(nnz >= 0); Expects(nJ >= 0); Expects(ubw >= 0); @@ -157,6 +175,16 @@ struct ModelDimensions { */ std::vector ndJydy; + /** Number of nonzero elements in the \f$ x \f$ derivative of \f$ x_rdata \f$ */ + int ndxrdatadxsolver{0}; + + /** Number of nonzero elements in the \f$ tcl\f$ derivative of \f$ x_rdata \f$ */ + int ndxrdatadtcl{0}; + + /** Number of nonzero elements in the \f$ x_rdata\f$ derivative of + * \f$ total_cl \f$ */ + int ndtotal_cldx_rdata{0}; + /** Number of nonzero entries in Jacobian */ int nnz{0}; diff --git a/include/amici/model_ode.h b/include/amici/model_ode.h index 4a11ab4101..a7c701a90c 100644 --- a/include/amici/model_ode.h +++ b/include/amici/model_ode.h @@ -317,9 +317,11 @@ class Model_ODE : public Model { * @param p parameter vector * @param k constants vector * @param h Heaviside vector + * @param tcl total abundances for conservation laws **/ virtual void froot(realtype *root, realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h); + const realtype *p, const realtype *k, const realtype *h, + const realtype *tcl); /** * @brief Model specific implementation for fxdot diff --git a/include/amici/model_state.h b/include/amici/model_state.h index 578835283a..2523dce21f 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -116,6 +116,25 @@ struct ModelStateDerived { */ SUNMatrixWrapper dxdotdx_implicit; + /** + * Temporary storage for `dx_rdatadx_solver` + * (dimension: `nx_rdata` x `nx_solver`, nnz: `ndxrdatadxsolver`, type: `CSC_MAT`) + */ + SUNMatrixWrapper dx_rdatadx_solver; + + /** + * Temporary storage for `dx_rdatadtcl` + * (dimension: `nx_rdata` x `ncl`, nnz: `ndxrdatadtclr`, type: `CSC_MAT`) + */ + SUNMatrixWrapper dx_rdatadtcl; + + /** + * Temporary storage for `dtotal_cldx_rdata` + * (dimension: `ncl` x `nx_rdata`, nnz: `ndtotal_cldx_rdata`, + * type: `CSC_MAT`) + */ + SUNMatrixWrapper dtotal_cldx_rdata; + /** * Temporary storage of `dxdotdp` data across functions, Matlab only * (dimension: `nplist` x `nx_solver` , row-major) @@ -228,11 +247,16 @@ struct ModelStateDerived { /** data standard deviation for current timepoint (dimension: ny) */ std::vector sigmay_; - /** temporary storage for parameter derivative of data standard deviation, + /** temporary storage for parameter derivative of data standard deviation, * (dimension: ny x nplist, row-major) */ std::vector dsigmaydp_; + /** temporary storage for observable derivative of data standard deviation, + * (dimension: ny x ny, row-major) + */ + std::vector dsigmaydy_; + /** temporary storage for event-resolved observable (dimension: nz) */ std::vector z_; diff --git a/include/amici/rdata.h b/include/amici/rdata.h index d83c775b6a..f8b82875b3 100644 --- a/include/amici/rdata.h +++ b/include/amici/rdata.h @@ -125,12 +125,14 @@ class ReturnData: public ModelDimensions { std::vector sigmaz; /** - * parameter derivative of event output (shape `nmaxevent` x `nz`, row-major) + * parameter derivative of event output + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector sz; /** - * parameter derivative of event output standard deviation (shape `nmaxevent` x `nz`, row-major) + * parameter derivative of event output standard deviation + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector ssigmaz; @@ -138,7 +140,8 @@ class ReturnData: public ModelDimensions { std::vector rz; /** - * parameter derivative of event trigger output (shape `nmaxevent` x `nz` x `nplist`, row-major) + * parameter derivative of event trigger output + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector srz; @@ -169,7 +172,8 @@ class ReturnData: public ModelDimensions { std::vector sy; /** - * parameter derivative of observable standard deviation (shape `nt` x `nplist` x `ny`, row-major) + * parameter derivative of observable standard deviation + * (shape `nt` x `nplist` x `ny`, row-major) */ std::vector ssigmay; diff --git a/matlab/@amifun/getArgs.m b/matlab/@amifun/getArgs.m index 65499d43ae..e59c10173c 100644 --- a/matlab/@amifun/getArgs.m +++ b/matlab/@amifun/getArgs.m @@ -42,7 +42,11 @@ case 'sx0' this.argstr = '(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip)'; case 'root' - this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h' dx ')']; + if(strcmp(model.wtype,'iw')) + this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h' dx ')']; + else + this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl' dx ')']; + end case 'y' this.argstr = '(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w)'; case 'z' @@ -72,19 +76,19 @@ case 'deltaqB' this.argstr = '(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB)'; case 'deltasx' - this.argstr = '(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau)'; + this.argstr = '(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl)'; case 'dxdotdp' this.argstr = ['(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip' dx ', const realtype *w, const realtype *dwdp)']; case 'sigma_y' - this.argstr = '(double *sigmay, const realtype t, const realtype *p, const realtype *k)'; + this.argstr = '(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y)'; case 'dsigma_ydp' - this.argstr = '(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip)'; + this.argstr = '(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip)'; case 'sigma_z' this.argstr = '(double *sigmaz, const realtype t, const realtype *p, const realtype *k)'; case 'dsigma_zdp' this.argstr = '(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip)'; case 'stau' - this.argstr = '(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie)'; + this.argstr = '(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie)'; case 'Jy' this.argstr = '(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my)'; case 'dJydy' diff --git a/matlab/@amimodel/generateC.m b/matlab/@amimodel/generateC.m index d2d0435a32..331b17ba6f 100644 --- a/matlab/@amimodel/generateC.m +++ b/matlab/@amimodel/generateC.m @@ -170,6 +170,9 @@ function generateC(this) fprintf(fid,[' 0,\n']); fprintf(fid,[' 0,\n']); fprintf(fid,[' {},\n']); +fprintf(fid,[' 0,\n']); +fprintf(fid,[' 0,\n']); +fprintf(fid,[' 0,\n']); fprintf(fid,[' ' num2str(this.nnz) ',\n']); fprintf(fid,[' ' num2str(this.ubw) ',\n']); fprintf(fid,[' ' num2str(this.lbw) '\n']); diff --git a/models/model_calvetti/model_calvetti.h b/models/model_calvetti/model_calvetti.h index 27fad45d3e..10db9447c5 100644 --- a/models/model_calvetti/model_calvetti.h +++ b/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -22,7 +22,7 @@ extern void dJydy_model_calvetti(double *dJydy, const int iy, const realtype *p, extern void dwdx_model_calvetti(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dydx_model_calvetti(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void root_model_calvetti(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx); -extern void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_calvetti(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_calvetti(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_calvetti(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w); @@ -52,6 +52,9 @@ class Model_model_calvetti : public amici::Model_DAE { 0, 0, {}, + 0, + 0, + 0, 26, 5, 3 @@ -67,7 +70,7 @@ class Model_model_calvetti : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -110,7 +113,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -125,7 +128,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -161,8 +164,8 @@ class Model_model_calvetti : public amici::Model_DAE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_calvetti(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_calvetti(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -171,7 +174,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_calvetti/model_calvetti_sigmay.cpp b/models/model_calvetti/model_calvetti_sigmay.cpp index a970a9b280..690d1a01a9 100644 --- a/models/model_calvetti/model_calvetti_sigmay.cpp +++ b/models/model_calvetti/model_calvetti_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_calvetti{ -void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/models/model_dirac/model_dirac.h b/models/model_dirac/model_dirac.h index 481522b282..cc6ce2f222 100644 --- a/models/model_dirac/model_dirac.h +++ b/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_dirac(SUNMatrixContent_Sparse JSparse, const realtype extern void Jy_model_dirac(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_dirac(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_dirac(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_dirac(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void dxdotdp_model_dirac(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_dirac(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k); -extern void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); +extern void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); +extern void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void xdot_model_dirac(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); extern void y_model_dirac(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -52,6 +52,9 @@ class Model_model_dirac : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 3, 0, 1 @@ -67,7 +70,7 @@ class Model_model_dirac : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_dirac(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); @@ -106,8 +109,8 @@ class Model_model_dirac : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_dirac(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_dirac(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -123,7 +126,7 @@ class Model_model_dirac : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -152,15 +155,15 @@ class Model_model_dirac : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_dirac(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_dirac(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_dirac(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_dirac(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -169,8 +172,8 @@ class Model_model_dirac : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_dirac(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_dirac(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_dirac/model_dirac_deltasx.cpp b/models/model_dirac/model_dirac_deltasx.cpp index 12b79f9371..ebb0be64cb 100644 --- a/models/model_dirac/model_dirac_deltasx.cpp +++ b/models/model_dirac/model_dirac_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_dirac/model_dirac_root.cpp b/models/model_dirac/model_dirac_root.cpp index a54473970a..ce1c5f4364 100644 --- a/models/model_dirac/model_dirac_root.cpp +++ b/models/model_dirac/model_dirac_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = -t+p[1]; root[1] = t-p[1]; } diff --git a/models/model_dirac/model_dirac_sigmay.cpp b/models/model_dirac/model_dirac_sigmay.cpp index 97538bff2a..9b5782f79f 100644 --- a/models/model_dirac/model_dirac_sigmay.cpp +++ b/models/model_dirac/model_dirac_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_dirac/model_dirac_stau.cpp b/models/model_dirac/model_dirac_stau.cpp index 24fb6db818..67c725fcea 100644 --- a/models/model_dirac/model_dirac_stau.cpp +++ b/models/model_dirac/model_dirac_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 1: { switch(ie) { diff --git a/models/model_events/model_events.h b/models/model_events/model_events.h index 56e90327e4..16272b1be0 100644 --- a/models/model_events/model_events.h +++ b/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -24,18 +24,18 @@ extern void dJydsigma_model_events(double *dJydsigma, const int iy, const realty extern void dJydy_model_events(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJzdsigma_model_events(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_events(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); -extern void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void drzdx_model_events(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void dxdotdp_model_events(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_events(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_events(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_events(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_events(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_events(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_events(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sz_model_events(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void x0_model_events(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_events(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -66,6 +66,9 @@ class Model_model_events : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 4, 0, 1 @@ -81,7 +84,7 @@ class Model_model_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_events(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); @@ -126,8 +129,8 @@ class Model_model_events : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -143,7 +146,7 @@ class Model_model_events : public amici::Model_ODE { drzdx_model_events(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -174,16 +177,16 @@ class Model_model_events : public amici::Model_ODE { dzdx_model_events(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_events(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_events(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_events(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_events(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_events(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -194,8 +197,8 @@ class Model_model_events : public amici::Model_ODE { srz_model_events(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_events(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_events(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_events/model_events_deltasx.cpp b/models/model_events/model_events_deltasx.cpp index 62516b1ab3..9dacb2ee54 100644 --- a/models/model_events/model_events_deltasx.cpp +++ b/models/model_events/model_events_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_events/model_events_root.cpp b/models/model_events/model_events_root.cpp index 4da74dc79a..9207a8a25f 100644 --- a/models/model_events/model_events_root.cpp +++ b/models/model_events/model_events_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[1]-x[2]; root[1] = x[0]-x[2]; root[2] = -t+4.0; diff --git a/models/model_events/model_events_sigmay.cpp b/models/model_events/model_events_sigmay.cpp index 42fac3dfbf..87bd4ffb30 100644 --- a/models/model_events/model_events_sigmay.cpp +++ b/models/model_events/model_events_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_events/model_events_stau.cpp b/models/model_events/model_events_stau.cpp index 9649efab4c..6a192189e1 100644 --- a/models/model_events/model_events_stau.cpp +++ b/models/model_events/model_events_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/models/model_jakstat_adjoint/model_jakstat_adjoint.h index 418acbf2f5..ffd1e7fe34 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_jakstat_adjoint(SUNMatrixContent_Sparse JSparse, const extern void Jy_model_jakstat_adjoint(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_jakstat_adjoint(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_jakstat_adjoint(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip); +extern void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip); extern void dwdp_model_jakstat_adjoint(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl); extern void dwdx_model_jakstat_adjoint(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_jakstat_adjoint(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_jakstat_adjoint(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_jakstat_adjoint(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sx0_model_jakstat_adjoint(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void w_model_jakstat_adjoint(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_jakstat_adjoint(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -55,6 +55,9 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 18, 8, 1 @@ -70,7 +73,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); @@ -109,7 +112,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -124,8 +127,8 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { - dsigmaydp_model_jakstat_adjoint(dsigmaydp, t, p, k, ip); + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { + dsigmaydp_model_jakstat_adjoint(dsigmaydp, t, p, k, y, ip); } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -157,14 +160,14 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_jakstat_adjoint(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_jakstat_adjoint(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -173,7 +176,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp b/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp index 38045122ba..7313fb731b 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint{ -void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) { +void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) { switch (ip) { case 14: { dsigmaydp[0] = 1.0; diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp b/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp index 18172dff23..99dd28dff6 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint{ -void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = p[14]; sigmay[1] = p[15]; sigmay[2] = p[16]; diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index 33a5beb306..bec91a063e 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_jakstat_adjoint_o2(SUNMatrixContent_Sparse JSparse, co extern void Jy_model_jakstat_adjoint_o2(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_jakstat_adjoint_o2(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_jakstat_adjoint_o2(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip); +extern void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip); extern void dwdp_model_jakstat_adjoint_o2(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl); extern void dwdx_model_jakstat_adjoint_o2(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_jakstat_adjoint_o2(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_jakstat_adjoint_o2(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_jakstat_adjoint_o2(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sx0_model_jakstat_adjoint_o2(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void w_model_jakstat_adjoint_o2(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_jakstat_adjoint_o2(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -55,6 +55,9 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 384, 8, 154 @@ -70,7 +73,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -109,7 +112,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -124,8 +127,8 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { - dsigmaydp_model_jakstat_adjoint_o2(dsigmaydp, t, p, k, ip); + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { + dsigmaydp_model_jakstat_adjoint_o2(dsigmaydp, t, p, k, y, ip); } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -157,14 +160,14 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_jakstat_adjoint_o2(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_jakstat_adjoint_o2(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -173,7 +176,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp index 7ebea670ba..ac9cb8730d 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint_o2{ -void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) { +void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) { switch (ip) { case 14: { dsigmaydp[0] = 1.0; diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp index 26120455ae..6b162c6f03 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint_o2{ -void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = p[14]; sigmay[1] = p[15]; sigmay[2] = p[16]; diff --git a/models/model_nested_events/model_nested_events.h b/models/model_nested_events/model_nested_events.h index 8f85951440..b40ec0e0fc 100644 --- a/models/model_nested_events/model_nested_events.h +++ b/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -19,13 +19,13 @@ extern void Jy_model_nested_events(double *nllh, const int iy, const realtype *p extern void dJydsigma_model_nested_events(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_nested_events(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void deltaqB_model_nested_events(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_nested_events(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void dxdotdp_model_nested_events(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_nested_events(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); -extern void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); +extern void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); +extern void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_nested_events(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void x0_model_nested_events(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_nested_events(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -55,6 +55,9 @@ class Model_model_nested_events : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 1, 0, 0 @@ -70,7 +73,7 @@ class Model_model_nested_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); @@ -110,8 +113,8 @@ class Model_model_nested_events : public amici::Model_ODE { deltaqB_model_nested_events(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_nested_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_nested_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -127,7 +130,7 @@ class Model_model_nested_events : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -156,15 +159,15 @@ class Model_model_nested_events : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_nested_events(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_nested_events(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_nested_events(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_nested_events(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -173,8 +176,8 @@ class Model_model_nested_events : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_nested_events(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_nested_events(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_nested_events/model_nested_events_deltasx.cpp b/models/model_nested_events/model_nested_events_deltasx.cpp index d464477b44..15b55bb525 100644 --- a/models/model_nested_events/model_nested_events_deltasx.cpp +++ b/models/model_nested_events/model_nested_events_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_nested_events/model_nested_events_root.cpp b/models/model_nested_events/model_nested_events_root.cpp index c18683f8ec..0cf33d2d57 100644 --- a/models/model_nested_events/model_nested_events_root.cpp +++ b/models/model_nested_events/model_nested_events_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = -x[0]+1.0; root[1] = x[0]-1.0; root[2] = t-p[2]; diff --git a/models/model_nested_events/model_nested_events_sigmay.cpp b/models/model_nested_events/model_nested_events_sigmay.cpp index 4852d83e1f..0f928ca69a 100644 --- a/models/model_nested_events/model_nested_events_sigmay.cpp +++ b/models/model_nested_events/model_nested_events_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_nested_events/model_nested_events_stau.cpp b/models/model_nested_events/model_nested_events_stau.cpp index c97800dea3..bfaad2f012 100644 --- a/models/model_nested_events/model_nested_events_stau.cpp +++ b/models/model_nested_events/model_nested_events_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron/model_neuron.h b/models/model_neuron/model_neuron.h index bd12dd9b5d..92a8e71262 100644 --- a/models/model_neuron/model_neuron.h +++ b/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -25,19 +25,19 @@ extern void dJydy_model_neuron(double *dJydy, const int iy, const realtype *p, c extern void dJzdsigma_model_neuron(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_neuron(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void deltaqB_model_neuron(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_neuron(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void deltaxB_model_neuron(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); extern void drzdx_model_neuron(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void dxdotdp_model_neuron(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_neuron(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_neuron(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_neuron(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_neuron(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void sz_model_neuron(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void x0_model_neuron(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -69,6 +69,9 @@ class Model_model_neuron : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 4, 1, 1 @@ -84,7 +87,7 @@ class Model_model_neuron : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); @@ -130,8 +133,8 @@ class Model_model_neuron : public amici::Model_ODE { deltaqB_model_neuron(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_neuron(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_neuron(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -149,7 +152,7 @@ class Model_model_neuron : public amici::Model_ODE { drzdx_model_neuron(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -179,16 +182,16 @@ class Model_model_neuron : public amici::Model_ODE { dzdx_model_neuron(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_neuron(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_neuron(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_neuron(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_neuron(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_neuron(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -199,8 +202,8 @@ class Model_model_neuron : public amici::Model_ODE { srz_model_neuron(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_neuron(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_neuron(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_neuron/model_neuron_deltasx.cpp b/models/model_neuron/model_neuron_deltasx.cpp index 35dc79a782..29bd503840 100644 --- a/models/model_neuron/model_neuron_deltasx.cpp +++ b/models/model_neuron/model_neuron_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron/model_neuron_root.cpp b/models/model_neuron/model_neuron_root.cpp index 516bc91304..6a68f67719 100644 --- a/models/model_neuron/model_neuron_root.cpp +++ b/models/model_neuron/model_neuron_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[0]-3.0E1; } diff --git a/models/model_neuron/model_neuron_sigmay.cpp b/models/model_neuron/model_neuron_sigmay.cpp index 092c626156..8bc0d292f8 100644 --- a/models/model_neuron/model_neuron_sigmay.cpp +++ b/models/model_neuron/model_neuron_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_neuron/model_neuron_stau.cpp b/models/model_neuron/model_neuron_stau.cpp index 66b3518578..d77cfb5bdc 100644 --- a/models/model_neuron/model_neuron_stau.cpp +++ b/models/model_neuron/model_neuron_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron_o2/model_neuron_o2.h b/models/model_neuron_o2/model_neuron_o2.h index d1d2fc1734..800e76282a 100644 --- a/models/model_neuron_o2/model_neuron_o2.h +++ b/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -25,7 +25,7 @@ extern void dJydy_model_neuron_o2(double *dJydy, const int iy, const realtype *p extern void dJzdsigma_model_neuron_o2(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_neuron_o2(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void deltaqB_model_neuron_o2(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_neuron_o2(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void deltaxB_model_neuron_o2(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); extern void drzdx_model_neuron_o2(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); @@ -33,12 +33,12 @@ extern void dwdx_model_neuron_o2(realtype *dwdx, const realtype t, const realtyp extern void dxdotdp_model_neuron_o2(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_neuron_o2(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_neuron_o2(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron_o2(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_neuron_o2(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron_o2(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_neuron_o2(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void sz_model_neuron_o2(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void w_model_neuron_o2(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); @@ -71,6 +71,9 @@ class Model_model_neuron_o2 : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 27, 1, 8 @@ -86,7 +89,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -132,8 +135,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { deltaqB_model_neuron_o2(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_neuron_o2(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_neuron_o2(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -151,7 +154,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { drzdx_model_neuron_o2(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -182,16 +185,16 @@ class Model_model_neuron_o2 : public amici::Model_ODE { dzdx_model_neuron_o2(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_neuron_o2(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_neuron_o2(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_neuron_o2(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_neuron_o2(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_neuron_o2(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -202,8 +205,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { srz_model_neuron_o2(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_neuron_o2(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_neuron_o2(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_neuron_o2/model_neuron_o2_deltasx.cpp b/models/model_neuron_o2/model_neuron_o2_deltasx.cpp index 621cb92ed4..10c0d6a052 100644 --- a/models/model_neuron_o2/model_neuron_o2_deltasx.cpp +++ b/models/model_neuron_o2/model_neuron_o2_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron_o2/model_neuron_o2_root.cpp b/models/model_neuron_o2/model_neuron_o2_root.cpp index 852a2806b6..7fba331de0 100644 --- a/models/model_neuron_o2/model_neuron_o2_root.cpp +++ b/models/model_neuron_o2/model_neuron_o2_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[0]-3.0E1; } diff --git a/models/model_neuron_o2/model_neuron_o2_sigmay.cpp b/models/model_neuron_o2/model_neuron_o2_sigmay.cpp index 5938f5e08f..3e5743cb70 100644 --- a/models/model_neuron_o2/model_neuron_o2_sigmay.cpp +++ b/models/model_neuron_o2/model_neuron_o2_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_neuron_o2/model_neuron_o2_stau.cpp b/models/model_neuron_o2/model_neuron_o2_stau.cpp index 70a8cf3a58..c639781b90 100644 --- a/models/model_neuron_o2/model_neuron_o2_stau.cpp +++ b/models/model_neuron_o2/model_neuron_o2_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_robertson/model_robertson.h b/models/model_robertson/model_robertson.h index a83d68d8d7..a1d9a3cfa8 100644 --- a/models/model_robertson/model_robertson.h +++ b/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -23,7 +23,7 @@ extern void dwdp_model_robertson(realtype *dwdp, const realtype t, const realtyp extern void dwdx_model_robertson(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_robertson(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp); extern void dydx_model_robertson(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_robertson(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_robertson(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_robertson(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w); @@ -53,6 +53,9 @@ class Model_model_robertson : public amici::Model_DAE { 0, 0, {}, + 0, + 0, + 0, 9, 2, 2 @@ -68,7 +71,7 @@ class Model_model_robertson : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_robertson(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -111,7 +114,7 @@ class Model_model_robertson : public amici::Model_DAE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -126,7 +129,7 @@ class Model_model_robertson : public amici::Model_DAE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -163,8 +166,8 @@ class Model_model_robertson : public amici::Model_DAE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_robertson(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_robertson(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -173,7 +176,7 @@ class Model_model_robertson : public amici::Model_DAE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_robertson/model_robertson_sigmay.cpp b/models/model_robertson/model_robertson_sigmay.cpp index 6e57e3c50f..9e1e5e019c 100644 --- a/models/model_robertson/model_robertson_sigmay.cpp +++ b/models/model_robertson/model_robertson_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_robertson{ -void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/models/model_steadystate/model_steadystate.h b/models/model_steadystate/model_steadystate.h index 0da7d77631..0238e21c52 100644 --- a/models/model_steadystate/model_steadystate.h +++ b/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -22,7 +22,7 @@ extern void dwdp_model_steadystate(realtype *dwdp, const realtype t, const realt extern void dwdx_model_steadystate(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_steadystate(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_steadystate(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_steadystate(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_steadystate(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_steadystate(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -52,6 +52,9 @@ class Model_model_steadystate : public amici::Model_ODE { 0, 0, {}, + 0, + 0, + 0, 9, 2, 2 @@ -67,7 +70,7 @@ class Model_model_steadystate : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); @@ -106,7 +109,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -121,7 +124,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -152,14 +155,14 @@ class Model_model_steadystate : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_steadystate(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_steadystate(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { @@ -168,7 +171,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_steadystate/model_steadystate_sigmay.cpp b/models/model_steadystate/model_steadystate_sigmay.cpp index 8e9ebc4417..d895acd6ca 100644 --- a/models/model_steadystate/model_steadystate_sigmay.cpp +++ b/models/model_steadystate/model_steadystate_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_steadystate{ -void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/python/amici/__init__.py b/python/amici/__init__.py index 40d6966420..9b2d6158cc 100644 --- a/python/amici/__init__.py +++ b/python/amici/__init__.py @@ -24,9 +24,8 @@ import os import re import sys -from contextlib import suppress, contextmanager from types import ModuleType as ModelModule -from typing import Any, Dict, Optional, Union, Sequence, List +from typing import Optional def _get_amici_path(): @@ -81,23 +80,6 @@ def _imported_from_setup() -> bool: return False -try: - from wurlitzer import sys_pipes -except ModuleNotFoundError: - sys_pipes = suppress - - -@contextmanager -def _capture_cstdout(): - """Redirect C/C++ stdout to python stdout if python stdout is redirected, - e.g. in ipython notebook""" - if sys.stdout == sys.__stdout__: - yield - else: - with sys_pipes(): - yield - - # Initialize AMICI paths amici_path = _get_amici_path() amiciSwigPath = os.path.join(amici_path, 'swig') @@ -106,12 +88,7 @@ def _capture_cstdout(): has_clibs = any([os.path.isfile(os.path.join(amici_path, wrapper)) for wrapper in ['amici.py', 'amici_without_hdf5.py']]) - -AmiciModel = Union['amici.Model', 'amici.ModelPtr'] -AmiciSolver = Union['amici.Solver', 'amici.SolverPtr'] -AmiciExpData = Union['amici.ExpData', 'amici.ExpDataPtr'] -AmiciReturnData = Union['amici.ReturnData', 'amici.ReturnDataPtr'] -AmiciExpDataVector = Union['amici.ExpDataPtrVector', Sequence[AmiciExpData]] +hdf5_enabled = False # Get version number from file with open(os.path.join(amici_path, 'version.txt')) as f: @@ -124,8 +101,12 @@ def _capture_cstdout(): if has_clibs: from . import amici from .amici import * + # has to be done before importing readSolverSettingsFromHDF5 + # from .swig_wrappers + hdf5_enabled = 'readSolverSettingsFromHDF5' in dir() + from .swig_wrappers import * - # These module require the swig interface and other dependencies + # These modules require the swig interface and other dependencies from .numpy import ReturnDataView, ExpDataView from .pandas import * @@ -133,205 +114,14 @@ def _capture_cstdout(): from .sbml_import import SbmlImporter, assignmentRules2observables from .ode_export import ODEModel, ODEExporter - try: - # Requires Python>=3.8 - from typing import Protocol - - class ModelModule(Protocol): - """Enable Python static type checking for AMICI-generated model - modules""" - def getModel(self) -> amici.Model: - pass - except ImportError: - pass - -hdf5_enabled = 'readSolverSettingsFromHDF5' in dir() - - -def _get_ptr(obj: Union[AmiciModel, AmiciExpData, AmiciSolver, AmiciReturnData] - ) -> Union['amici.Model', 'amici.ExpData', 'amici.Solver', - 'amici.ReturnData']: - """ - Convenience wrapper that returns the smart pointer pointee, if applicable - - :param obj: - Potential smart pointer - - :returns: - Non-smart pointer - """ - if isinstance(obj, (amici.ModelPtr, amici.ExpDataPtr, amici.SolverPtr, - amici.ReturnDataPtr)): - return obj.get() - return obj - - -def runAmiciSimulation( - model: AmiciModel, - solver: AmiciSolver, - edata: Optional[AmiciExpData] = None -) -> 'numpy.ReturnDataView': - """ - Convenience wrapper around :py:func:`amici.amici.runAmiciSimulation` - (generated by swig) - - :param model: - Model instance - -` :param solver: - Solver instance, must be generated from - :py:meth:`amici.amici.Model.getSolver` - - :param edata: - ExpData instance (optional) - - :returns: - ReturnData object with simulation results - """ - with _capture_cstdout(): - rdata = amici.runAmiciSimulation(_get_ptr(solver), _get_ptr(edata), - _get_ptr(model)) - return numpy.ReturnDataView(rdata) - - -def ExpData(*args) -> 'amici.ExpData': - """ - Convenience wrapper for :py:class:`amici.amici.ExpData` constructors - - :param args: arguments - - :returns: ExpData Instance - """ - if isinstance(args[0], ReturnDataView): - return amici.ExpData(_get_ptr(args[0]['ptr']), *args[1:]) - elif isinstance(args[0], (amici.ExpData, amici.ExpDataPtr)): - # the *args[:1] should be empty, but by the time you read this, - # the constructor signature may have changed and you are glad this - # wrapper did not break. - return amici.ExpData(_get_ptr(args[0]), *args[1:]) - elif isinstance(args[0], (amici.Model, amici.ModelPtr)): - return amici.ExpData(_get_ptr(args[0])) - else: - return amici.ExpData(*args) - - -def runAmiciSimulations( - model: AmiciModel, - solver: AmiciSolver, - edata_list: AmiciExpDataVector, - failfast: bool = True, - num_threads: int = 1, -) -> List['numpy.ReturnDataView']: - """ - Convenience wrapper for loops of amici.runAmiciSimulation - - :param model: Model instance - :param solver: Solver instance, must be generated from Model.getSolver() - :param edata_list: list of ExpData instances - :param failfast: returns as soon as an integration failure is encountered - :param num_threads: number of threads to use (only used if compiled - with openmp) - - :returns: list of simulation results - """ - with _capture_cstdout(): - edata_ptr_vector = amici.ExpDataPtrVector(edata_list) - rdata_ptr_list = amici.runAmiciSimulations(_get_ptr(solver), - edata_ptr_vector, - _get_ptr(model), - failfast, - num_threads) - return [numpy.ReturnDataView(r) for r in rdata_ptr_list] - - -def readSolverSettingsFromHDF5( - file: str, - solver: AmiciSolver, - location: Optional[str] = 'solverSettings' -) -> None: - """ - Convenience wrapper for :py:func:`amici.readSolverSettingsFromHDF5` - - :param file: hdf5 filename - :param solver: Solver instance to which settings will be transferred - :param location: location of solver settings in hdf5 file - """ - amici.readSolverSettingsFromHDF5(file, _get_ptr(solver), location) - + from typing import Protocol -def writeSolverSettingsToHDF5( - solver: AmiciSolver, - file: Union[str, object], - location: Optional[str] = 'solverSettings' -) -> None: - """ - Convenience wrapper for :py:func:`amici.amici.writeSolverSettingsToHDF5` - :param file: hdf5 filename, can also be object created by - :py:func:`amici.amici.createOrOpenForWriting` - :param solver: Solver instance from which settings will stored - :param location: location of solver settings in hdf5 file - """ - amici.writeSolverSettingsToHDF5(_get_ptr(solver), file, location) - - -# Values are suffixes of `get[...]` and `set[...]` `amici.Model` methods. -# If either the getter or setter is not named with this pattern, then the value -# is a tuple where the first and second elements are the getter and setter -# methods, respectively. -model_instance_settings = [ - 'AddSigmaResiduals', - 'AlwaysCheckFinite', - 'FixedParameters', - 'InitialStates', - 'InitialStateSensitivities', - 'MinimumSigmaResiduals', - ('nMaxEvent', 'setNMaxEvent'), - 'Parameters', - 'ParameterList', - 'ParameterScale', # getter returns a SWIG object - 'ReinitializationStateIdxs', - 'ReinitializeFixedParameterInitialStates', - 'StateIsNonNegative', - 'SteadyStateSensitivityMode', - ('t0', 'setT0'), - 'Timepoints', -] - - -def get_model_settings( - model: AmiciModel, -) -> Dict[str, Any]: - """Get model settings that are set independently of the compiled model. - - :param model: The AMICI model instance. - - :returns: Keys are AMICI model attributes, values are attribute values. - """ - settings = {} - for setting in model_instance_settings: - getter = setting[0] if isinstance(setting, tuple) else f'get{setting}' - settings[setting] = getattr(model, getter)() - # TODO `amici.Model.getParameterScale` returns a SWIG object instead - # of a Python list/tuple. - if setting == 'ParameterScale': - settings[setting] = tuple(settings[setting]) - return settings - - -def set_model_settings( - model: AmiciModel, - settings: Dict[str, Any], -) -> None: - """Set model settings. - - :param model: The AMICI model instance. - :param settings: Keys are callable attributes (setters) of an AMICI model, - values are provided to the setters. - """ - for setting, value in settings.items(): - setter = setting[1] if isinstance(setting, tuple) else f'set{setting}' - getattr(model, setter)(value) + class ModelModule(Protocol): + """Enable Python static type checking for AMICI-generated model + modules""" + def getModel(self) -> amici.Model: + pass class add_path: diff --git a/python/amici/bngl_import.py b/python/amici/bngl_import.py new file mode 100644 index 0000000000..840e4a4229 --- /dev/null +++ b/python/amici/bngl_import.py @@ -0,0 +1,32 @@ +""" +BNGL Import +------------ +This module provides all necessary functionality to import a model specified +in the :term:`BNGL` format. +""" + + +from pysb.importers.bngl import model_from_bngl + +from .pysb_import import pysb2amici + + +def bngl2amici(bngl_model: str, *args, **kwargs) -> None: + r""" + Generate AMICI C++ files for the provided model. + + :param bngl_model: + bngl model file, model name will determine the name of the generated + module + + :param args: + see :func:`amici.pysb_import.pysb2amici` for additional arguments + + :param kwargs: + see :func:`amici.pysb_import.pysb2amici` for additional arguments + + """ + if 'model' in kwargs: + raise ValueError('model argument not allowed') + pysb_model = model_from_bngl(bngl_model) + pysb2amici(pysb_model, *args, **kwargs) diff --git a/python/amici/conserved_moieties.py b/python/amici/conserved_moieties.py new file mode 100644 index 0000000000..28fe3f9e77 --- /dev/null +++ b/python/amici/conserved_moieties.py @@ -0,0 +1,911 @@ +import logging +import math +import random +import sys +from typing import List, MutableSequence, Sequence, Tuple, Union, Optional + +from .logging import get_logger + +logger = get_logger(__name__, logging.ERROR) + +# increase recursion limit for recursive quicksort +sys.setrecursionlimit(3000) + +_MIN = 1e-9 +_MAX = 1e9 + + +def compute_moiety_conservation_laws( + stoichiometric_list: Sequence[float], + num_species: int, + num_reactions: int, + max_num_monte_carlo: int = 20, + rng_seed: Union[None, bool, int] = False, + species_names: Optional[Sequence[str]] = None, +) -> Tuple[List[List[int]], List[List[float]]]: + """Compute moiety conservation laws. + + According to the algorithm proposed by De Martino et al. (2014) + https://doi.org/10.1371/journal.pone.0100750 + + :param stoichiometric_list: + the stoichiometric matrix as a list (species x reactions, + column-major ordering) + :param num_species: + total number of species in the reaction network + :param num_reactions: + total number of reactions in the reaction network + :param max_num_monte_carlo: + maximum number of MonteCarlo steps before changing to relaxation + :param rng_seed: + Seed for the random number generator. If `False`, the RNG will not be + re-initialized. Other values will be passed to :func:`random.seed`. + :param species_names: + Species names. Optional and only used for logging. + :returns: + Integer MCLs as list of lists of indices of involved species and + list of lists of corresponding coefficients. + """ + # compute semi-positive conservation laws + (kernel_dim, engaged_species, int_kernel_dim, conserved_moieties, + cls_species_idxs, cls_coefficients) = _kernel( + stoichiometric_list, num_species, num_reactions) + # if the number of integer MCLs equals total MCLS no MC relaxation + done = (int_kernel_dim == kernel_dim) + + if not done: + # construct interaction matrix + J, J2, fields = _fill(stoichiometric_list, engaged_species, + num_species) + + # seed random number generator + if rng_seed is not False: + random.seed(rng_seed) + + timer = 0 + # maximum number of montecarlo search before starting relaxation + while not done: + yes, int_kernel_dim, conserved_moieties = _monte_carlo( + engaged_species, J, J2, fields, conserved_moieties, + int_kernel_dim, cls_species_idxs, cls_coefficients, + num_species, max_iter=max_num_monte_carlo + ) + # if the number of integer MCLs equals total MCLS then MC done + done = (int_kernel_dim == kernel_dim) + timer = 0 if yes else timer + 1 + + if timer == max_num_monte_carlo: + done = _relax(stoichiometric_list, conserved_moieties, + num_reactions, num_species) + timer = 0 + _reduce(int_kernel_dim, cls_species_idxs, cls_coefficients, num_species) + _output(int_kernel_dim, kernel_dim, engaged_species, cls_species_idxs, + cls_coefficients, species_names, verbose=True) + + return cls_species_idxs[:int_kernel_dim], cls_coefficients[:int_kernel_dim] + + +def _output( + int_kernel_dim: int, + kernel_dim: int, + int_matched: List[int], + species_indices: List[List[int]], + species_coefficients: List[List[float]], + species_names: Optional[Sequence[str]] = None, + verbose: bool = False, + log_level: int = logging.DEBUG +): + """Log infos on identified conservation laws""" + def log(*args, **kwargs): + logger.log(log_level, *args, **kwargs) + + log(f"There are {int_kernel_dim} linearly independent conserved " + f"moieties, engaging {len(int_matched)} state variables.") + if int_kernel_dim == kernel_dim: + log("They generate all the conservation laws") + else: + log(f"They don't generate all the conservation laws, " + f"{kernel_dim - int_kernel_dim} of them are not reducible to " + "moieties") + # print all conserved quantities + if verbose: + for i, (coefficients, engaged_species_idxs) \ + in enumerate(zip(species_coefficients, species_indices)): + if not engaged_species_idxs: + continue + log(f"Moiety number {i + 1} engages {len(engaged_species_idxs)} " + "species:") + for species_idx, coefficient \ + in zip(engaged_species_idxs, coefficients): + name = species_names[species_idx] if species_names \ + else species_idx + log(f"\t{name}\t{coefficient}") + + +def _qsort( + k: int, + km: int, + order: MutableSequence[int], + pivots: Sequence[int] +) -> None: + """Quicksort + + Recursive implementation of the quicksort algorithm + + :param k: + number of elements to sort + :param km: + current center element + :param order: + ordering of the elements + :param pivots: + corresponding pivot elements from scaled partial pivoting strategy + """ + # TODO: Rewrite into an iterative algorithm with pivoting strategy + + if k - km < 1: + # nothing to sort + return + + pivot = km + int((k - km) / 2) + l = 0 + p = k - km - 1 + new_order = [0] * (k - km) + for i in range(km, k): + if i != pivot: + if pivots[order[i]] < pivots[order[pivot]]: + new_order[l] = order[i] + l += 1 + else: + new_order[p] = order[i] + p -= 1 + new_order[p] = order[pivot] + order[km:k] = new_order + + # calculate center, then recursive calls on left and right intervals + centre = p + km + _qsort(k, centre + 1, order, pivots) + _qsort(centre, km, order, pivots) + + +def _kernel( + stoichiometric_list: Sequence[float], + num_species: int, + num_reactions: int +) -> Tuple[int, List[int], int, List[int], + List[List[int]], List[List[float]]]: + """ + Kernel (left nullspace of :math:`S`) calculation by Gaussian elimination + + To compute the left nullspace of the stoichiometric matrix :math:`S`, + a Gaussian elimination method with partial scaled pivoting is used to deal + effectively with a possibly ill-conditioned stoichiometric matrix + :math:`S`. + + Note that this is the Python reimplementation of the algorithm proposed by + `De Martino et al. (2014) `_ + and thus a direct adaption of the original implementation in C++. + + :param stoichiometric_list: + the stoichiometric matrix as a list (species x reactions, + col-major ordering) + :param num_species: + total number of species in the reaction network + :param num_reactions: + total number of reactions in the reaction network + :returns: + kernel dimension, MCLs, integer kernel dimension, integer MCLs and + indices to species and reactions in the preceding order as a tuple + """ + matrix: List[List[int]] = [[] for _ in range(num_species)] + matrix2: List[List[float]] = [[] for _ in range(num_species)] + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + if val != 0: + matrix[i_species].append(i_reaction) + matrix2[i_species].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + for i in range(num_species): + matrix[i].append(num_reactions + i) + matrix2[i].append(1) + + order: List[int] = list(range(num_species)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX + for i in range(num_species)] + + done = False + while not done: + _qsort(num_species, 0, order, pivots) + for j in range(num_species - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + done = True + + for j in range(num_species - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * (num_species + num_reactions) + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + matrix[k1].append(col_idx) + matrix2[k1].append(col_val) + + done = False + if len(matrix[order[j + 1]]): + pivots[order[j + 1]] = matrix[order[j + 1]][0] + else: + pivots[order[j + 1]] = _MAX + + RSolutions = [[] for _ in range(num_species)] + RSolutions2 = [[] for _ in range(num_species)] + kernel_dim = 0 + + for i in range(num_species): + done = all(matrix[i][j] >= num_reactions + for j in range(len(matrix[i]))) + if done and len(matrix[i]): + for j in range(len(matrix[i])): + RSolutions[kernel_dim].append(matrix[i][j] - num_reactions) + RSolutions2[kernel_dim].append(matrix2[i][j]) + kernel_dim += 1 + del matrix, matrix2 + + matched = [] + int_matched = [] + cls_species_idxs = [[] for _ in range(num_species)] + cls_coefficients = [[] for _ in range(num_species)] + + i2 = 0 + for i in range(kernel_dim): + ok2 = True + for j in range(len(RSolutions[i])): + if RSolutions2[i][j] * RSolutions2[i][0] < 0: + ok2 = False + if not matched or all( + cur_matched != RSolutions[i][j] for cur_matched in + matched + ): + matched.append(RSolutions[i][j]) + if ok2 and len(RSolutions[i]): + min_value = _MAX + for j in range(len(RSolutions[i])): + cls_species_idxs[i2].append(RSolutions[i][j]) + cls_coefficients[i2].append(abs(RSolutions2[i][j])) + min_value = min(min_value, abs(RSolutions2[i][j])) + if not int_matched or all( + cur_int_matched != cls_species_idxs[i2][j] + for cur_int_matched in int_matched + ): + int_matched.append(cls_species_idxs[i2][j]) + for j in range(len(cls_species_idxs[i2])): + cls_coefficients[i2][j] /= min_value + i2 += 1 + int_kernel_dim = i2 + + assert int_kernel_dim <= kernel_dim + assert len(cls_species_idxs) == len(cls_coefficients), \ + "Inconsistent number of conserved quantities in coefficients and " \ + "species" + return (kernel_dim, matched, int_kernel_dim, int_matched, cls_species_idxs, + cls_coefficients) + + +def _fill( + stoichiometric_list: Sequence[float], + matched: Sequence[int], + num_species: int +) -> Tuple[List[List[int]], List[List[int]], List[int]]: + """Construct interaction matrix + + Construct the interaction matrix out of the given stoichiometric matrix + :math:`S`. + + :param stoichiometric_list: + the stoichiometric matrix given as a flat list + :param matched: + found and independent moiety conservation laws (MCL) + :param num_species: + number of rows in :math:`S` + :returns: + interactions of metabolites and reactions, and matrix of interaction + """ + dim = len(matched) + + # for each entry in the stoichiometric matrix save interaction + i_reaction = 0 + i_species = 0 + matrix = [[] for _ in range(dim)] + matrix2 = [[] for _ in range(dim)] + for val in stoichiometric_list: + if val != 0: + take = dim + for matched_idx, matched_val in enumerate(matched): + if i_species == matched_val: + take = matched_idx + if take < dim: + matrix[take].append(i_reaction) + matrix2[take].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + + J = [[] for _ in range(num_species)] + J2 = [[] for _ in range(num_species)] + fields = [0] * num_species + for i in range(dim): + for j in range(i, dim): + interactions = 0 + for po in range(len(matrix[i])): + for pu in range(len(matrix[j])): + if matrix[i][po] == matrix[j][pu]: + interactions += matrix2[i][po] * matrix2[j][pu] + if j == i: + fields[i] = interactions + elif abs(interactions) > _MIN: + J[i].append(j) + J2[i].append(interactions) + J[j].append(i) + J2[j].append(interactions) + return J, J2, fields + + +def _is_linearly_dependent( + vector: Sequence[float], + int_kernel_dim: int, + cls_species_idxs: Sequence[Sequence[int]], + cls_coefficients: Sequence[Sequence[float]], + matched: Sequence[int], + num_species: int +) -> bool: + """Check for linear dependence between MCLs + + Check if the solutions found with Monte Carlo are linearly independent + with respect to the previous found solution for all MCLs involved + + :param vector: + found basis + :param int_kernel_dim: + number of integer conservative laws + :param cls_species_idxs: + NSolutions contains the species involved in the MCL + :param cls_coefficients: + NSolutions2 contains the corresponding coefficients in the MCL + :param matched: + actual found MCLs + :param num_species: + number of rows in :math:`S` + :returns: + boolean indicating linear dependence (true) or not (false) + """ + K = int_kernel_dim + 1 + matrix: List[List[int]] = [[] for _ in range(K)] + matrix2: List[List[float]] = [[] for _ in range(K)] + # Populate matrices with species ids and coefficients for CLs + for i in range(K - 1): + for j in range(len(cls_species_idxs[i])): + matrix[i].append(cls_species_idxs[i][j]) + matrix2[i].append(cls_coefficients[i][j]) + + order2 = list(range(len(matched))) + pivots2 = matched[:] + _qsort(len(matched), 0, order2, pivots2) + + # ensure positivity + for i in range(len(matched)): + if vector[order2[i]] > _MIN: + matrix[K - 1].append(matched[order2[i]]) + matrix2[K - 1].append(vector[order2[i]]) + + order = list(range(K)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX for i in range(K)] + + # check for linear independence of the solution + ok = False + while not ok: + _qsort(K, 0, order, pivots) + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + ok = True + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * num_species + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for i in range(num_species): + if abs(column[i]) > _MIN: + matrix[k1].append(i) + matrix2[k1].append(column[i]) + ok = False + pivots[k1] = matrix[k1][0] if len(matrix[k1]) else _MAX + K1 = sum(len(matrix[i]) > 0 for i in range(K)) + return K == K1 + + +def _monte_carlo( + matched: Sequence[int], + J: Sequence[Sequence[int]], + J2: Sequence[Sequence[float]], + fields: Sequence[float], + int_matched: MutableSequence[int], + int_kernel_dim: int, + cls_species_idxs: MutableSequence[MutableSequence[int]], + cls_coefficients: MutableSequence[MutableSequence[float]], + num_species: int, + initial_temperature: float = 1, + cool_rate: float = 1e-3, + max_iter: int = 10 +) -> Tuple[bool, int, Sequence[int]]: + """MonteCarlo simulated annealing for finding integer MCLs + + Finding integer solutions for the MCLs by Monte Carlo, see step (b) in + the De Martino (2014) paper and Eqs. 11-13 in the publication + + :param matched: + number of found MCLs + :param J: + index of metabolites involved in a MCL + :param J2: + coefficients of metabolites involved in a MCL + :param fields: + actual number of metabolites involved in a MCL + :param int_matched: + actual matched MCLs + :param int_kernel_dim: + number of MCLs found in :math:`S` + :param cls_species_idxs: + Modified in-place. + :param cls_coefficients: + Modified in-place. + :param initial_temperature: + initial temperature + :param cool_rate: + cooling rate of simulated annealing + :param max_iter: + maximum number of MonteCarlo steps before changing to relaxation + :returns: + status of MC iteration, number of integer MCLs, number of MCLs, + metabolites and reaction indices, MCLs and integer MCLs as a tuple + + status indicates if the currently found moiety by the Monte Carlo + process is linearly dependent (False) or linearly independent (True) + in case of linear dependence, the current Monte Carlo cycle can be + considered otherwise the algorithm retries Monte Carlo up to max_iter + """ + dim = len(matched) + num = [int(2 * random.uniform(0, 1)) if len(J[i]) else 0 + for i in range(dim)] + numtot = sum(num) + + def compute_h(): + H = 0 + for i in range(dim): + H += fields[i] * num[i] ** 2 + for j in range(len(J[i])): + H += J2[i][j] * num[i] * num[J[i][j]] + return H + + H = compute_h() + + count = 0 + howmany = 0 + T1 = initial_temperature + e = math.exp(-1 / T1) + while True: + en = int(random.uniform(0, 1) * dim) + while not len(J[en]): + en = int(random.uniform(0, 1) * dim) + + p = -1 if num[en] > 0 and random.uniform(0, 1) < 0.5 else 1 + delta = fields[en] * num[en] + for i in range(len(J[en])): + delta += J2[en][i] * num[J[en][i]] + delta = 2 * p * delta + fields[en] + + if delta < 0 or random.uniform(0, 1) < math.pow(e, delta): + num[en] += p + numtot += p + H += delta + + count += 1 + if count % dim == 0: + T1 -= cool_rate + if T1 <= 0: + T1 = cool_rate + e = math.exp(-1 / T1) + + if count == dim // cool_rate: + count = 0 + T1 = initial_temperature + e = math.exp(-1 / T1) + en = int(random.uniform(0, 1) * dim) + while not len(J[en]): + en = int(random.uniform(0, 1) * dim) + num = [0] * dim + num[en] = 1 + numtot = 1 + + H = compute_h() + howmany += 1 + + if (H < _MIN and numtot > 0) or (howmany == 10 * max_iter): + break + + if howmany >= 10 * max_iter: + return False, int_kernel_dim, int_matched + + # founds MCLS? need to check for linear independence + if len(int_matched) and not _is_linearly_dependent( + num, int_kernel_dim, cls_species_idxs, + cls_coefficients, matched, num_species): + logger.debug( + "Found a moiety but it is linearly dependent... next.") + return False, int_kernel_dim, int_matched + + # reduce by MC procedure + order2 = list(range(len(matched))) + pivots2 = matched[:] + _qsort(len(matched), 0, order2, pivots2) + for i in range(len(matched)): + if num[order2[i]] > 0: + cls_species_idxs[int_kernel_dim].append(matched[order2[i]]) + cls_coefficients[int_kernel_dim].append(num[order2[i]]) + int_kernel_dim += 1 + _reduce(int_kernel_dim, cls_species_idxs, cls_coefficients, num_species) + min_value = 1000 + for i in range(len(cls_species_idxs[int_kernel_dim - 1])): + if not len(int_matched) \ + or all(cur_int_matched + != cls_species_idxs[int_kernel_dim - 1][i] + for cur_int_matched in int_matched): + int_matched.append(cls_species_idxs[int_kernel_dim - 1][i]) + + min_value = min(min_value, cls_coefficients[int_kernel_dim - 1][i]) + for i in range(len(cls_species_idxs[int_kernel_dim - 1])): + cls_coefficients[int_kernel_dim - 1][i] /= min_value + + logger.debug( + f"Found linearly independent moiety, now there are " + f"{int_kernel_dim} engaging {len(int_matched)} species") + + return True, int_kernel_dim, int_matched + + +def _relax( + stoichiometric_list: Sequence[float], + int_matched: Sequence[int], + num_reactions: int, + num_species: int, + relaxation_max: float = 1e6, + relaxation_step: float = 1.9 +) -> bool: + """Relaxation scheme for Monte Carlo final solution + + Checking for completeness using Motzkin's theorem. See Step (c) in + De Martino (2014) and the Eqs. 14-16 in the corresponding publication + + :param stoichiometric_list: + stoichiometric matrix :math:`S` as a flat list (column-major ordering) + :param int_matched: + number of matched integer CLs + :param num_reactions: + number of reactions in reaction network + :param num_species: + number of species in reaction network + :param relaxation_max: + maximum relaxation step + :param relaxation_step: + relaxation step width + :returns: + boolean indicating if relaxation has succeeded (``True``) or not + (``False``) + """ + K = len(int_matched) + matrix: List[List[int]] = [[] for _ in range(K)] + matrix2: List[List[float]] = [[] for _ in range(K)] + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + if val != 0: + take = K + if K > 0: + for i in range(K): + if i_species == int_matched[i]: + take = i + if take < K: + matrix[take].append(i_reaction) + matrix2[take].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + + # reducing the stoichiometric matrix of conserved moieties to row echelon + # form by Gaussian elimination + order = list(range(K)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX for i in range(K)] + done = False + while not done: + _qsort(K, 0, order, pivots) + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + done = True + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * num_reactions + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + matrix[k1].append(col_idx) + matrix2[k1].append(col_val) + done = False + if len(matrix[order[j + 1]]): + pivots[order[j + 1]] = matrix[order[j + 1]][0] + else: + pivots[order[j + 1]] = _MAX + + # normalize + for matrix2_i in matrix2: + if len(matrix2_i): + norm = matrix2_i[0] + for j in range(len(matrix2_i)): + matrix2_i[j] /= norm + + for k1 in reversed(range(K - 1)): + k = order[k1] + if len(matrix[k]) <= 1: + continue + + i = 0 + while i < len(matrix[k]): + for i_species in range(k1 + 1, K): + j = order[i_species] + if not len(matrix[j]) or matrix[j][0] != matrix[k][i]: + continue + + # subtract rows + # matrix2[k] = matrix2[k] - matrix2[j] * matrix2[k][i] + row_k: List[float] = [0] * num_reactions + for a in range(len(matrix[k])): + row_k[matrix[k][a]] = matrix2[k][a] + for a in range(len(matrix[j])): + row_k[matrix[j][a]] -= matrix2[j][a] * matrix2[k][i] + # filter + matrix[k] = [row_idx for row_idx, row_val in enumerate(row_k) + if row_val != 0] + matrix2[k] = [row_val for row_val in row_k if row_val != 0] + + if len(matrix[k]) <= i: + break + i += 1 + + indip = [K + 1] * num_reactions + for i in range(K): + if len(matrix[i]): + indip[matrix[i][0]] = i + M1 = 0 + for i in range(num_reactions): + if indip[i] == K + 1: + indip[i] = K + M1 + M1 += 1 + + matrixAus = [[] for _ in range(M1)] + matrixAus2 = [[] for _ in range(M1)] + i_reaction = 0 + for i in range(num_reactions): + if indip[i] >= K: + matrixAus[i_reaction].append(i) + matrixAus2[i_reaction].append(1) + i_reaction += 1 + else: + t = indip[i] + if len(matrix[t]) > 1: + for k in range(1, len(matrix[t])): + idx = indip[matrix[t][k]] - K + matrixAus[idx].append(i) + matrixAus2[idx].append(-matrix2[t][k]) + del matrix + + N1 = num_species - K + matrix_aus = [[] for _ in range(N1)] + matrix_aus2 = [[] for _ in range(N1)] + k1 = 0 + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + take = 1 + for i in range(len(int_matched)): + if i_species == int_matched[i]: + take -= 1 + if val != 0 and take == 1: + matrix_aus[k1].append(i_reaction) + matrix_aus2[k1].append(val) + i_species += 1 + k1 += take + if i_species == num_species: + i_species = 0 + k1 = 0 + i_reaction += 1 + + matrixb = [[] for _ in range(N1)] + matrixb2 = [[] for _ in range(N1)] + for i in range(M1): + for j in range(N1): + if len(matrix_aus[j]) * len(matrixAus[i]): + prod = 0 + for ib in range(len(matrixAus[i])): + for jb in range(len(matrix_aus[j])): + if matrixAus[i][ib] == matrix_aus[j][jb]: + prod += matrixAus2[i][ib] * matrix_aus2[j][jb] + if abs(prod) > _MIN: + matrixb[j].append(i) + matrixb2[j].append(prod) + del matrixAus, matrixAus2, matrix_aus, matrix_aus2 + + var = [_MIN] * M1 + time = 0 + cmin_idx = 0 + while True: + cmin = 1000 + for j in range(N1): + constr = 0 + if len(matrixb[j]): + for i in range(len(matrixb[j])): + constr += matrixb2[j][i] * var[matrixb[j][i]] + if constr < cmin: + cmin_idx = j + cmin = constr + if cmin >= 0: + # constraints satisfied + break + + # Motzkin relaxation + alpha = -relaxation_step * cmin + fact = sum(val ** 2 for val in matrixb2[cmin_idx]) + alpha /= fact + alpha = max(1e-9 * _MIN, alpha) + for j in range(len(matrixb[cmin_idx])): + var[matrixb[cmin_idx][j]] += alpha * matrixb2[cmin_idx][j] + + time += 1 + if time >= relaxation_max: + # timeout + break + + return done + + +def _reduce( + int_kernel_dim: int, + cls_species_idxs: MutableSequence[MutableSequence[int]], + cls_coefficients: MutableSequence[MutableSequence[float]], + num_species: int +) -> None: + """Reducing the solution which has been found by the Monte Carlo process + + In case of superpositions of independent MCLs one can reduce by + iteratively subtracting the other independent MCLs, taking care + to maintain then non-negativity constraint, see Eq. 13 in De Martino (2014) + + :param int_kernel_dim: + number of found MCLs + :param cls_species_idxs: + Species indices involved in each of the conservation laws. + Modified in-place. + :param cls_coefficients: + Coefficients for each of the species involved in each of the + conservation laws. Modified in-place. + :param num_species: + number of species / rows in :math:`S` + """ + K = int_kernel_dim + order = list(range(K)) + pivots = [-len(cls_species_idxs[i]) for i in range(K)] + + done = False + while not done: + _qsort(K, 0, order, pivots) + done = True + for i in range(K - 1): + k1 = order[i] + for j in range(i + 1, K): + k2 = order[j] + column: List[float] = [0] * num_species + for species_idx, coefficient \ + in zip(cls_species_idxs[k1], cls_coefficients[k1]): + column[species_idx] = coefficient + ok1 = True + for species_idx, coefficient \ + in zip(cls_species_idxs[k2], cls_coefficients[k2]): + column[species_idx] -= coefficient + if column[species_idx] < -_MIN: + ok1 = False + break + if not ok1: + continue + + done = False + cls_species_idxs[k1] = [] + cls_coefficients[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + cls_species_idxs[k1].append(col_idx) + cls_coefficients[k1].append(col_val) + pivots[k1] = -len(cls_species_idxs[k1]) diff --git a/python/amici/cxxcodeprinter.py b/python/amici/cxxcodeprinter.py index 5411010270..005d0299be 100644 --- a/python/amici/cxxcodeprinter.py +++ b/python/amici/cxxcodeprinter.py @@ -20,9 +20,26 @@ def doprint(self, expr: sp.Expr, assign_to: Optional[str] = None) -> str: return code except TypeError as e: raise ValueError( - f'Encountered unsupported function in expression "{expr}": ' - f'{e}!' - ) + f'Encountered unsupported function in expression "{expr}"' + ) from e + + def _print_min_max(self, expr, cpp_fun: str, sympy_fun): + # C++ doesn't like mixing int and double for arguments for min/max, + # therefore, we just always convert to float + arg0 = sp.Float(expr.args[0]) if expr.args[0].is_number \ + else expr.args[0] + if len(expr.args) == 1: + return self._print(arg0) + return "%s%s(%s, %s)" % (self._ns, cpp_fun, self._print(arg0), + self._print(sympy_fun(*expr.args[1:]))) + + def _print_Min(self, expr): + from sympy.functions.elementary.miscellaneous import Min + return self._print_min_max(expr, "min", Min) + + def _print_Max(self, expr): + from sympy.functions.elementary.miscellaneous import Max + return self._print_min_max(expr, "max", Max) def _get_sym_lines_array( self, diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index 054b820467..76f35a2c30 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -1,20 +1,47 @@ """Miscellaneous functions related to model import, independent of any specific model format""" - -from typing import ( - Dict, Union, Optional, Callable, Sequence, Tuple, Iterable, Any -) -import sympy as sp import enum import itertools as itt +import numbers +import sys +from typing import (Any, Callable, Dict, Iterable, Optional, Sequence, + SupportsFloat, Tuple, Union) -from toposort import toposort -from sympy.logic.boolalg import BooleanAtom +import sympy as sp from sympy.functions.elementary.piecewise import ExprCondPair +from sympy.logic.boolalg import BooleanAtom +from toposort import toposort + +RESERVED_SYMBOLS = ['x', 'k', 'p', 'y', 'w', 'h', 't', 'AMICI_EMPTY_BOLUS'] + +try: + import pysb +except ImportError: + pysb = None SymbolDef = Dict[sp.Symbol, Union[Dict[str, sp.Expr], sp.Expr]] +# Monkey-patch toposort CircularDependencyError to handle non-sortable objects, +# such as sympy objects +class CircularDependencyError(ValueError): + def __init__(self, data): + # Sort the data just to make the output consistent, for use in + # error messages. That's convenient for doctests. + s = "Circular dependencies exist among these items: {{{}}}".format( + ", ".join( + "{!r}:{!r}".format(key, value) for key, value in sorted( + {str(k): v for k, v in data.items()}.items()) + ) + ) + super(CircularDependencyError, self).__init__(s) + self.data = data + + +setattr(sys.modules["toposort"], "CircularDependencyError", + CircularDependencyError) + + class ObservableTransformation(str, enum.Enum): """ Different modes of observable transformation. @@ -233,7 +260,7 @@ def smart_subs_dict(sym: sp.Expr, for substitution in s: # note that substitution may change free symbols, so we have to do # this recursively - if substitution[0] in sym.free_symbols: + if sym.has(substitution[0]): sym = sym.subs(*substitution) return sym @@ -254,11 +281,7 @@ def smart_subs(element: sp.Expr, old: sp.Symbol, new: sp.Expr) -> sp.Expr: :return: substituted expression """ - - if old in element.free_symbols: - return element.subs(old, new) - - return element + return element.subs(old, new) if element.has(old) else element def toposort_symbols(symbols: SymbolDef, @@ -332,11 +355,6 @@ def _parse_special_functions(sym: sp.Expr, toplevel: bool = True) -> sp.Expr: } if sym.__class__.__name__ in fun_mappings: - # c++ doesnt like mixing int and double for arguments of those - # functions - if sym.__class__.__name__ in ['min', 'max']: - args = tuple(sp.Float(arg) if arg.is_number else arg - for arg in args) return fun_mappings[sym.__class__.__name__](*args) elif sym.__class__.__name__ == 'piecewise' \ @@ -550,3 +568,100 @@ def _check_unsupported_functions(sym: sp.Expr, f'{expression_type}: "{full_sym}"!') for arg in list(sym.args): _check_unsupported_functions(arg, expression_type) + + +def cast_to_sym(value: Union[SupportsFloat, sp.Expr, BooleanAtom], + input_name: str) -> sp.Expr: + """ + Typecasts the value to :py:class:`sympy.Float` if possible, and ensures the + value is a symbolic expression. + + :param value: + value to be cast + + :param input_name: + name of input variable + + :return: + typecast value + """ + if isinstance(value, (sp.RealNumber, numbers.Number)): + value = sp.Float(float(value)) + elif isinstance(value, BooleanAtom): + value = sp.Float(float(bool(value))) + + if not isinstance(value, sp.Expr): + raise TypeError(f"Couldn't cast {input_name} to sympy.Expr, was " + f"{type(value)}") + + return value + + +def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): + """ + Generates the appropriate measurement symbol for the provided observable + + :param observable_id: + symbol (or string representation) of the observable + + :return: + symbol for the corresponding measurement + """ + if not isinstance(observable_id, str): + observable_id = strip_pysb(observable_id) + return symbol_with_assumptions(f'm{observable_id}') + + +def generate_flux_symbol( + reaction_index: int, + name: Optional[str] = None +) -> sp.Symbol: + """ + Generate identifier symbol for a reaction flux. + This function will always return the same unique python object for a + given entity. + + :param reaction_index: + index of the reaction to which the flux corresponds + :param name: + an optional identifier of the reaction to which the flux corresponds + :return: + identifier symbol + """ + if name is not None: + return symbol_with_assumptions(name) + + return symbol_with_assumptions(f'flux_r{reaction_index}') + + +def symbol_with_assumptions(name: str): + """ + Central function to create symbols with consistent, canonical assumptions + + :param name: + name of the symbol + + :return: + symbol with canonical assumptions + """ + return sp.Symbol(name, real=True) + + +def strip_pysb(symbol: sp.Basic) -> sp.Basic: + """ + Strips pysb info from a :class:`pysb.Component` object + + :param symbol: + symbolic expression + + :return: + stripped expression + """ + # strip pysb type and transform into a flat sympy.Symbol. + # this ensures that the pysb type specific __repr__ is used when converting + # to string + if pysb and isinstance(symbol, pysb.Component): + return sp.Symbol(symbol.name, real=True) + else: + # in this case we will use sympy specific transform anyways + return symbol diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 48594f55c2..8c9fa7e96a 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -8,44 +8,41 @@ :py:func:`amici.sbml_import.SbmlImporter.sbml2amici` and :py:func:`amici.petab_import.import_model`. """ -import sympy as sp -import numpy as np +import contextlib +import copy +import itertools +import logging +import os import re import shutil import subprocess import sys -import os -import copy -import numbers -import logging -import itertools -import contextlib +from dataclasses import dataclass +from itertools import chain +from string import Template +from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, + Union) + +import numpy as np +import sympy as sp +from sympy.matrices.dense import MutableDenseMatrix +from sympy.matrices.immutable import ImmutableDenseMatrix + +from . import (__commit__, __version__, amiciModulePath, amiciSrcPath, + amiciSwigPath, sbml_import) +from .constants import SymbolId +from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement +from .import_utils import (ObservableTransformation, generate_flux_symbol, + smart_subs_dict, strip_pysb, + symbol_with_assumptions, toposort_symbols) +from .logging import get_logger, log_execution_time, set_log_level +from .ode_model import * try: import pysb except ImportError: pysb = None -from typing import ( - Callable, Optional, Union, List, Dict, Tuple, SupportsFloat, Sequence, - Set, Any -) -from dataclasses import dataclass -from string import Template -from sympy.matrices.immutable import ImmutableDenseMatrix -from sympy.matrices.dense import MutableDenseMatrix -from sympy.logic.boolalg import BooleanAtom -from itertools import chain -from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement - -from . import ( - amiciSwigPath, amiciSrcPath, amiciModulePath, __version__, __commit__, - sbml_import -) -from .logging import get_logger, log_execution_time, set_log_level -from .constants import SymbolId -from .import_utils import smart_subs_dict, toposort_symbols, \ - ObservableTransformation # Template for model simulation main.cpp file CXX_MAIN_TEMPLATE_FILE = os.path.join(amiciSrcPath, 'main.template.cpp') @@ -111,7 +108,8 @@ class _FunctionInfo: 'root': _FunctionInfo( 'realtype *root, const realtype t, const realtype *x, ' - 'const realtype *p, const realtype *k, const realtype *h' + 'const realtype *p, const realtype *k, const realtype *h, ' + 'const realtype *tcl' ), 'dwdp': _FunctionInfo( @@ -165,23 +163,30 @@ class _FunctionInfo: _FunctionInfo( 'realtype *dydp, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const int ip, const realtype *w, const realtype *dtcldp', + 'const int ip, const realtype *w, const realtype *tcl, ' + 'const realtype *dtcldp', + ), + 'dsigmaydy': + _FunctionInfo( + 'realtype *dsigmaydy, const realtype t, const realtype *p, ' + 'const realtype *k, const realtype *y' ), 'dsigmaydp': _FunctionInfo( 'realtype *dsigmaydp, const realtype t, const realtype *p, ' - 'const realtype *k, const int ip', + 'const realtype *k, const realtype *y, const int ip', ), 'sigmay': _FunctionInfo( 'realtype *sigmay, const realtype t, const realtype *p, ' - 'const realtype *k', + 'const realtype *k, const realtype *y', ), 'sroot': _FunctionInfo( 'realtype *stau, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const realtype *sx, const int ip, const int ie', + 'const realtype *sx, const int ip, const int ie, ' + 'const realtype *tcl', generate_body=False ), 'drootdt': @@ -196,7 +201,8 @@ class _FunctionInfo: _FunctionInfo( 'realtype *stau, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const realtype *sx, const int ip, const int ie' + 'const realtype *tcl, const realtype *sx, const int ip, ' + 'const int ie' ), 'deltax': _FunctionInfo( @@ -216,7 +222,7 @@ class _FunctionInfo: 'const realtype *p, const realtype *k, const realtype *h, ' 'const realtype *w, const int ip, const int ie, ' 'const realtype *xdot, const realtype *xdot_old, ' - 'const realtype *sx, const realtype *stau' + 'const realtype *sx, const realtype *stau, const realtype *tcl' ), 'w': _FunctionInfo( @@ -238,7 +244,7 @@ class _FunctionInfo: ), 'sx0': _FunctionInfo( - 'realtype *sx0, const realtype t,const realtype *x, ' + 'realtype *sx0, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const int ip', ), 'sx0_fixedParameters': @@ -264,13 +270,45 @@ class _FunctionInfo: ), 'x_rdata': _FunctionInfo( - 'realtype *x_rdata, const realtype *x, const realtype *tcl' + 'realtype *x_rdata, const realtype *x, const realtype *tcl, ' + 'const realtype *p, const realtype *k' ), 'total_cl': - _FunctionInfo('realtype *total_cl, const realtype *x_rdata'), - + _FunctionInfo( + 'realtype *total_cl, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k' + ), + 'dtotal_cldp': + _FunctionInfo( + 'realtype *dtotal_cldp, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k, const int ip' + ), + 'dtotal_cldx_rdata': + _FunctionInfo( + 'realtype *dtotal_cldx_rdata, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k, const realtype *tcl', + sparse=True + ), 'x_solver': - _FunctionInfo('realtype *x_solver, const realtype *x_rdata') + _FunctionInfo('realtype *x_solver, const realtype *x_rdata'), + 'dx_rdatadx_solver': + _FunctionInfo( + 'realtype *dx_rdatadx_solver, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k', + sparse=True + ), + 'dx_rdatadp': + _FunctionInfo( + 'realtype *dx_rdatadp, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k, ' + 'const int ip' + ), + 'dx_rdatadtcl': + _FunctionInfo( + 'realtype *dx_rdatadtcl, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k', + sparse=True + ), } # list of sparse functions @@ -353,429 +391,6 @@ def var_in_function_signature(name: str, varname: str) -> bool: ) -class ModelQuantity: - """ - Base class for model components - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: Union[SupportsFloat, numbers.Number, sp.Expr]): - """ - Create a new ModelQuantity instance. - - :param identifier: - unique identifier of the quantity - - :param name: - individual name of the quantity (does not need to be unique) - - :param value: - either formula, numeric value or initial value - """ - - if not isinstance(identifier, sp.Symbol): - raise TypeError(f'identifier must be sympy.Symbol, was ' - f'{type(identifier)}') - self._identifier: sp.Symbol = identifier - - if not isinstance(name, str): - raise TypeError(f'name must be str, was {type(name)}') - - self._name: str = name - - self._value: sp.Expr = cast_to_sym(value, 'value') - - def __repr__(self) -> str: - """ - Representation of the ModelQuantity object - - :return: - string representation of the ModelQuantity - """ - return str(self._identifier) - - def get_id(self) -> sp.Symbol: - """ - ModelQuantity identifier - - :return: - identifier of the ModelQuantity - """ - return self._identifier - - def get_name(self) -> str: - """ - ModelQuantity name - - :return: - name of the ModelQuantity - """ - return self._name - - def get_val(self) -> sp.Expr: - """ - ModelQuantity value - - :return: - value of the ModelQuantity - """ - return self._value - - def set_val(self, val: sp.Expr): - """ - Set ModelQuantity value - - :return: - value of the ModelQuantity - """ - self._value = cast_to_sym(val, 'value') - - -class State(ModelQuantity): - """ - A State variable defines an entity that evolves with time according to - the provided time derivative, abbreviated by ``x``. - - :ivar _conservation_law: - algebraic formula that allows computation of this - state according to a conservation law - - :ivar _dt: - algebraic formula that defines the temporal derivative of this state - - """ - - _dt: Union[sp.Expr, None] = None - _conservation_law: Union[sp.Expr, None] = None - - def __init__(self, - identifier: sp.Symbol, - name: str, - init: sp.Expr, - dt: sp.Expr): - """ - Create a new State instance. Extends :meth:`ModelQuantity.__init__` - by ``dt`` - - :param identifier: - unique identifier of the state - - :param name: - individual name of the state (does not need to be unique) - - :param init: - initial value - - :param dt: - time derivative - """ - super(State, self).__init__(identifier, name, init) - self._dt = cast_to_sym(dt, 'dt') - self._conservation_law = None - - def set_conservation_law(self, - law: sp.Expr) -> None: - """ - Sets the conservation law of a state. - - If a conservation law is set, the respective state will be replaced by - an algebraic formula according to the respective conservation law. - - :param law: - linear sum of states that if added to this state remain - constant over time - """ - if not isinstance(law, sp.Expr): - raise TypeError(f'conservation law must have type sympy.Expr, ' - f'was {type(law)}') - - self._conservation_law = law - - def set_dt(self, - dt: sp.Expr) -> None: - """ - Sets the time derivative - - :param dt: - time derivative - """ - self._dt = cast_to_sym(dt, 'dt') - - def get_dt(self) -> sp.Expr: - """ - Gets the time derivative - - :return: - time derivative - """ - return self._dt - - def get_free_symbols(self) -> Set[sp.Symbol]: - """ - Gets the set of free symbols in time derivative and initial conditions - - :return: - free symbols - """ - return self._dt.free_symbols.union(self._value.free_symbols) - - -class ConservationLaw(ModelQuantity): - """ - A conservation law defines the absolute the total amount of a - (weighted) sum of states - - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new ConservationLaw instance. - - :param identifier: - unique identifier of the ConservationLaw - - :param name: - individual name of the ConservationLaw (does not need to be - unique) - - :param value: formula (sum of states) - """ - super(ConservationLaw, self).__init__(identifier, name, value) - - -class Observable(ModelQuantity): - """ - An Observable links model simulations to experimental measurements, - abbreviated by ``y``. - - :ivar _measurement_symbol: - sympy symbol used in the objective function to represent - measurements to this observable - - :ivar trafo: - observable transformation, only applies when evaluating objective - function or residuals - """ - - _measurement_symbol: Union[sp.Symbol, None] = None - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr, - measurement_symbol: Optional[sp.Symbol] = None, - transformation: Optional[ObservableTransformation] = 'lin'): - """ - Create a new Observable instance. - - :param identifier: - unique identifier of the Observable - - :param name: - individual name of the Observable (does not need to be unique) - - :param value: - formula - - :param transformation: - observable transformation, only applies when evaluating objective - function or residuals - """ - super(Observable, self).__init__(identifier, name, value) - self._measurement_symbol = measurement_symbol - self.trafo = transformation - - def get_measurement_symbol(self) -> sp.Symbol: - if self._measurement_symbol is None: - self._measurement_symbol = generate_measurement_symbol( - self.get_id() - ) - - return self._measurement_symbol - - -class SigmaY(ModelQuantity): - """ - A Standard Deviation SigmaY rescales the distance between simulations - and measurements when computing residuals or objective functions, - abbreviated by ``sigmay``. - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Standard Deviation instance. - - :param identifier: - unique identifier of the Standard Deviation - - :param name: - individual name of the Standard Deviation (does not need to - be unique) - - :param value: - formula - """ - super(SigmaY, self).__init__(identifier, name, value) - - -class Expression(ModelQuantity): - """ - An Expression is a recurring elements in symbolic formulas. Specifying - this may yield more compact expression which may lead to substantially - shorter model compilation times, but may also reduce model simulation time. - Abbreviated by ``w``. - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Expression - - :param name: - individual name of the Expression (does not need to be unique) - - :param value: - formula - """ - super(Expression, self).__init__(identifier, name, value) - - -class Parameter(ModelQuantity): - """ - A Parameter is a free variable in the model with respect to which - sensitivities may be computed, abbreviated by ``p``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: numbers.Number): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Parameter - - :param name: - individual name of the Parameter (does not need to be - unique) - - :param value: - numeric value - """ - super(Parameter, self).__init__(identifier, name, value) - - -class Constant(ModelQuantity): - """ - A Constant is a fixed variable in the model with respect to which - sensitivities cannot be computed, abbreviated by ``k``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: numbers.Number): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Constant - - :param name: - individual name of the Constant (does not need to be unique) - - :param value: - numeric value - """ - super(Constant, self).__init__(identifier, name, value) - - -class LogLikelihood(ModelQuantity): - """ - A LogLikelihood defines the distance between measurements and - experiments for a particular observable. The final LogLikelihood value - in the simulation will be the sum of all specified LogLikelihood - instances evaluated at all timepoints, abbreviated by ``Jy``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the LogLikelihood - - :param name: - individual name of the LogLikelihood (does not need to be - unique) - - :param value: - formula - """ - super(LogLikelihood, self).__init__(identifier, name, value) - - -class Event(ModelQuantity): - """ - An Event defines either a SBML event or a root of the argument of a - Heaviside function. The Heaviside functions will be tracked via the - vector ``h`` during simulation and are needed to inform the ODE solver - about a discontinuity in either the right-hand side or the states - themselves, causing a reinitialization of the solver. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr, - state_update: Union[sp.Expr, None], - event_observable: Union[sp.Expr, None]): - """ - Create a new Event instance. - - :param identifier: - unique identifier of the Event - - :param name: - individual name of the Event (does not need to be unique) - - :param value: - formula for the root / trigger function - - :param state_update: - formula for the bolus function (None for Heaviside functions, - zero vector for events without bolus) - - :param event_observable: - formula a potential observable linked to the event - (None for Heaviside functions, empty events without observable) - """ - super(Event, self).__init__(identifier, name, value) - # add the Event specific components - self._state_update = state_update - self._observable = event_observable - - def __eq__(self, other): - """ - Check equality of events at the level of trigger/root functions, as we - need to collect unique root functions for ``roots.cpp`` - """ - return self.get_val() == other.get_val() - - # defines the type of some attributes in ODEModel symbol_to_type = { SymbolId.SPECIES: State, @@ -805,9 +420,12 @@ def smart_jacobian(eq: sp.MutableDenseMatrix, """ if min(eq.shape) and min(sym_var.shape) \ and not smart_is_zero_matrix(eq) \ - and not smart_is_zero_matrix(sym_var) \ - and not sym_var.free_symbols.isdisjoint(eq.free_symbols): - return eq.jacobian(sym_var) + and not smart_is_zero_matrix(sym_var): + return sp.Matrix([ + eq[i, :].jacobian(sym_var) if eq[i, :].has(*sym_var.flat()) + else [0] * sym_var.shape[0] + for i in range(eq.shape[0]) + ]) return sp.zeros(eq.shape[0], sym_var.shape[0]) @@ -959,7 +577,8 @@ class ODEModel: """ def __init__(self, verbose: Optional[Union[bool, int]] = False, - simplify: Optional[Callable] = sp.powsimp): + simplify: Optional[Callable] = sp.powsimp, + cache_simplify: bool = False): """ Create a new ODEModel instance. @@ -969,6 +588,10 @@ def __init__(self, verbose: Optional[Union[bool, int]] = False, :param simplify: see :meth:`ODEModel._simplify` + + :param cache_simplify: + Whether to cache calls to the simplify method. Can e.g. decrease + import times for models with events. """ self._states: List[State] = [] self._observables: List[Observable] = [] @@ -1021,22 +644,45 @@ def __init__(self, verbose: Optional[Union[bool, int]] = False, } self._total_derivative_prototypes: \ Dict[str, Dict[str, Union[str, List[str]]]] = { - 'sx_rdata': { - 'eq': 'x_rdata', - 'chainvars': ['x'], - 'var': 'p', - 'dxdz_name': 'sx', - }, 'sroot': { 'eq': 'root', 'chainvars': ['x'], 'var': 'p', 'dxdz_name': 'sx', - } - } + }, + } self._lock_total_derivative: List[str] = list() self._simplify: Callable = simplify + if cache_simplify and simplify is not None: + def cached_simplify( + expr: sp.Expr, + _simplified: Dict[str, sp.Expr] = {}, + _simplify: Callable = simplify, + ) -> sp.Expr: + """Speed up expression simplification with caching. + + NB: This can decrease model import times for models that have + many repeated expressions during C++ file generation. + For example, this can be useful for models with events. + However, for other models, this may increase model import + times. + + :param expr: + The SymPy expression. + :param _simplified: + The cache. + :param _simplify: + The simplification method. + + :return: + The simplified expression. + """ + expr_str = repr(expr) + if expr_str not in _simplified: + _simplified[expr_str] = _simplify(expr) + return _simplified[expr_str] + self._simplify = cached_simplify self._x0_fixedParameters_idx: Union[None, Sequence[int]] self._w_recursion_depth: int = 0 self._has_quadratic_nllh: bool = True @@ -1222,7 +868,7 @@ def add_conservation_law(self, total_abundance: sp.Symbol, state_expr: sp.Expr, abundance_expr: sp.Expr) -> None: - """ + r""" Adds a new conservation law to the model. A conservation law is defined by the conserved quantity :math:`T = \sum_i(a_i * x_i)`, where :math:`a_i` are coefficients and :math:`x_i` are different state @@ -1563,6 +1209,12 @@ def _generate_symbol(self, name: str, *, from_sbml: bool = False) -> None: if state._conservation_law is None ]) return + elif name == 'sx_rdata': + self._syms[name] = sp.Matrix([ + f'sx_rdata_{i}' + for i in range(len(self._states)) + ]) + return elif name == 'dtcldp': # check, whether the CL consists of only one state. Then, # sensitivities drop out, otherwise generate symbols @@ -1683,8 +1335,16 @@ def _generate_sparse_symbol(self, name: str) -> None: matrix = self.eq(name) match_deriv = re.match(r'd([\w]+)d([a-z]+)', name) if match_deriv: - rownames = self.sym(match_deriv.group(1)) - colnames = self.sym(match_deriv.group(2)) + eq = match_deriv.group(1) + var = match_deriv.group(2) + + if name == 'dtotal_cldx_rdata': + # not correctly parsed in regex + eq = 'total_cl' + var = 'x_rdata' + + rownames = self.sym(eq) + colnames = self.sym(var) if name == 'dJydy': # One entry per y-slice @@ -1788,10 +1448,9 @@ def _compute_equation(self, name: str) -> None: if not smart_is_zero_matrix(dx0_fixed_parametersdx): if isinstance(self._eqs[name], ImmutableDenseMatrix): self._eqs[name] = MutableDenseMatrix(self._eqs[name]) + tmp = smart_multiply(dx0_fixed_parametersdx, self.sym('sx0')) for ip in range(self._eqs[name].shape[1]): - self._eqs[name][:, ip] += smart_multiply( - dx0_fixed_parametersdx, self.sym('sx0') - ) + self._eqs[name][:, ip] += tmp elif name == 'x0_fixedParameters': k = self.sym('k') @@ -1817,6 +1476,34 @@ def _compute_equation(self, name: str) -> None: # force symbols self._eqs[name] = self.sym(name) + elif name == 'dx_rdatadx_solver': + if self.num_cons_law(): + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('x')) + else: + # so far, dx_rdatadx_solver is only required for sx_rdata + # in case of no conservation laws, C++ code will directly use + # sx, we don't need this + self._eqs[name] = \ + sp.zeros(self.num_states_rdata(), + self.num_states_solver()) + + elif name == 'dx_rdatadp': + if self.num_cons_law(): + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('p')) + else: + # so far, dx_rdatadp is only required for sx_rdata + # in case of no conservation laws, C++ code will directly use + # sx, we don't need this + self._eqs[name] = \ + sp.zeros(self.num_states_rdata(), + self.num_par()) + + elif name == 'dx_rdatadtcl': + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('tcl')) + elif name == 'dxdotdx_explicit': # force symbols self._derivative('xdot', 'x', name=name) @@ -2089,12 +1776,13 @@ def _total_derivative(self, name: str, eq: str, chainvars: List[str], # which is not checked for by sympy if not smart_is_zero_matrix(dydx) and not \ smart_is_zero_matrix(dxdz): + dydx_times_dxdz = smart_multiply(dydx, dxdz) if dxdz.shape[1] == 1 and \ self._eqs[name].shape[1] != dxdz.shape[1]: for iz in range(self._eqs[name].shape[1]): - self._eqs[name][:, iz] += smart_multiply(dydx, dxdz) + self._eqs[name][:, iz] += dydx_times_dxdz else: - self._eqs[name] += smart_multiply(dydx, dxdz) + self._eqs[name] += dydx_times_dxdz def sym_or_eq(self, name: str, varname: str) -> sp.Matrix: """ @@ -3032,7 +2720,8 @@ def _get_function_body( outer_cases[ie] = copy.copy(inner_lines) lines.extend(get_switch_statement('ie', outer_cases, 1)) - elif function in sensi_functions: + elif function in sensi_functions \ + and equations.shape[1] == self.model.num_par(): cases = { ipar: self.model._code_printer._get_sym_lines_array( equations[:, ipar], function, 0) @@ -3040,7 +2729,6 @@ def _get_function_body( if not smart_is_zero_matrix(equations[:, ipar]) } lines.extend(get_switch_statement('ip', cases, 1)) - elif function in multiobs_functions: if function == 'dJydy': cases = { @@ -3129,6 +2817,15 @@ def _write_model_header_cpp(self) -> None: 'NDJYDY': 'std::vector{%s}' % ','.join(str(len(x)) for x in self.model.sparsesym('dJydy')), + 'NDXRDATADXSOLVER': str( + len(self.model.sparsesym('dx_rdatadx_solver')) + ), + 'NDXRDATADTCL': str( + len(self.model.sparsesym('dx_rdatadtcl')) + ), + 'NDTOTALCLDXRDATA': str( + len(self.model.sparsesym('dtotal_cldx_rdata')) + ), 'UBW': str(self.model.num_states_solver()), 'LBW': str(self.model.num_states_solver()), 'NP': str(self.model.num_par()), @@ -3409,26 +3106,6 @@ def apply_template(source_file: str, fileout.write(result) -def strip_pysb(symbol: sp.Basic) -> sp.Basic: - """ - Strips pysb info from a :class:`pysb.Component` object - - :param symbol: - symbolic expression - - :return: - stripped expression - """ - # strip pysb type and transform into a flat sympy.Symbol. - # this ensures that the pysb type specific __repr__ is used when converting - # to string - if pysb and isinstance(symbol, pysb.Component): - return sp.Symbol(symbol.name, real=True) - else: - # in this case we will use sympy specific transform anyways - return symbol - - def get_function_extern_declaration(fun: str, name: str) -> str: """ Constructs the extern function declaration for a given function @@ -3599,83 +3276,6 @@ def is_valid_identifier(x: str) -> bool: return re.match(r'^[a-zA-Z_]\w*$', x) is not None -def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): - """ - Generates the appropriate measurement symbol for the provided observable - - :param observable_id: - symbol (or string representation) of the observable - - :return: - symbol for the corresponding measurement - """ - if not isinstance(observable_id, str): - observable_id = strip_pysb(observable_id) - return symbol_with_assumptions(f'm{observable_id}') - - -def generate_flux_symbol( - reaction_index: int, - name: Optional[str] = None -) -> sp.Symbol: - """ - Generate identifier symbol for a reaction flux. - This function will always return the same unique python object for a - given entity. - - :param reaction_index: - index of the reaction to which the flux corresponds - :param name: - an optional identifier of the reaction to which the flux corresponds - :return: - identifier symbol - """ - if name is not None: - return symbol_with_assumptions(name) - - return symbol_with_assumptions(f'flux_r{reaction_index}') - - -def symbol_with_assumptions(name: str): - """ - Central function to create symbols with consistent, canonical assumptions - - :param name: - name of the symbol - - :return: - symbol with canonical assumptions - """ - return sp.Symbol(name, real=True) - - -def cast_to_sym(value: Union[SupportsFloat, sp.Expr, BooleanAtom], - input_name: str) -> sp.Expr: - """ - Typecasts the value to :py:class:`sympy.Float` if possible, and ensures the - value is a symbolic expression. - - :param value: - value to be cast - - :param input_name: - name of input variable - - :return: - typecast value - """ - if isinstance(value, (sp.RealNumber, numbers.Number)): - value = sp.Float(float(value)) - elif isinstance(value, BooleanAtom): - value = sp.Float(float(bool(value))) - - if not isinstance(value, sp.Expr): - raise TypeError(f"Couldn't cast {input_name} to sympy.Expr, was " - f"{type(value)}") - - return value - - @contextlib.contextmanager def _monkeypatched(obj: object, name: str, patch: Any): """ diff --git a/python/amici/ode_model.py b/python/amici/ode_model.py new file mode 100644 index 0000000000..60d44147d2 --- /dev/null +++ b/python/amici/ode_model.py @@ -0,0 +1,475 @@ +"""Objects for AMICI's internal ODE model representation""" + + +import sympy as sp +import numpy as np +import re +import shutil +import subprocess +import sys +import os +import copy +import numbers +import logging +import itertools +import contextlib + +try: + import pysb +except ImportError: + pysb = None + +from typing import ( + Callable, Optional, Union, List, Dict, Tuple, SupportsFloat, Sequence, + Set, Any +) +from dataclasses import dataclass +from string import Template +from sympy.matrices.immutable import ImmutableDenseMatrix +from sympy.matrices.dense import MutableDenseMatrix +from sympy.logic.boolalg import BooleanAtom +from itertools import chain +from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement + +from . import ( + amiciSwigPath, amiciSrcPath, amiciModulePath, __version__, __commit__, + sbml_import +) +from .logging import get_logger, log_execution_time, set_log_level +from .constants import SymbolId +from .import_utils import smart_subs_dict, toposort_symbols, \ + ObservableTransformation, generate_measurement_symbol, RESERVED_SYMBOLS +from .import_utils import cast_to_sym + +__all__ = [ + 'ConservationLaw', 'Constant', 'Event', 'Expression', 'LogLikelihood', + 'ModelQuantity', 'Observable', 'Parameter', 'SigmaY', 'State' +] + +class ModelQuantity: + """ + Base class for model components + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: Union[SupportsFloat, numbers.Number, sp.Expr]): + """ + Create a new ModelQuantity instance. + + :param identifier: + unique identifier of the quantity + + :param name: + individual name of the quantity (does not need to be unique) + + :param value: + either formula, numeric value or initial value + """ + + if not isinstance(identifier, sp.Symbol): + raise TypeError(f'identifier must be sympy.Symbol, was ' + f'{type(identifier)}') + + if str(identifier) in RESERVED_SYMBOLS or \ + (hasattr(identifier, 'name') and + identifier.name in RESERVED_SYMBOLS): + raise ValueError(f'Cannot add model quantity with name "{name}", ' + f'please rename.') + self._identifier: sp.Symbol = identifier + + if not isinstance(name, str): + raise TypeError(f'name must be str, was {type(name)}') + + self._name: str = name + + self._value: sp.Expr = cast_to_sym(value, 'value') + + def __repr__(self) -> str: + """ + Representation of the ModelQuantity object + + :return: + string representation of the ModelQuantity + """ + return str(self._identifier) + + def get_id(self) -> sp.Symbol: + """ + ModelQuantity identifier + + :return: + identifier of the ModelQuantity + """ + return self._identifier + + def get_name(self) -> str: + """ + ModelQuantity name + + :return: + name of the ModelQuantity + """ + return self._name + + def get_val(self) -> sp.Expr: + """ + ModelQuantity value + + :return: + value of the ModelQuantity + """ + return self._value + + def set_val(self, val: sp.Expr): + """ + Set ModelQuantity value + + :return: + value of the ModelQuantity + """ + self._value = cast_to_sym(val, 'value') + + +class State(ModelQuantity): + """ + A State variable defines an entity that evolves with time according to + the provided time derivative, abbreviated by ``x``. + + :ivar _conservation_law: + algebraic formula that allows computation of this + state according to a conservation law + + :ivar _dt: + algebraic formula that defines the temporal derivative of this state + + """ + + _dt: Union[sp.Expr, None] = None + _conservation_law: Union[sp.Expr, None] = None + + def __init__(self, + identifier: sp.Symbol, + name: str, + init: sp.Expr, + dt: sp.Expr): + """ + Create a new State instance. Extends :meth:`ModelQuantity.__init__` + by ``dt`` + + :param identifier: + unique identifier of the state + + :param name: + individual name of the state (does not need to be unique) + + :param init: + initial value + + :param dt: + time derivative + """ + super(State, self).__init__(identifier, name, init) + self._dt = cast_to_sym(dt, 'dt') + self._conservation_law = None + + def set_conservation_law(self, + law: sp.Expr) -> None: + """ + Sets the conservation law of a state. + + If a conservation law is set, the respective state will be replaced by + an algebraic formula according to the respective conservation law. + + :param law: + linear sum of states that if added to this state remain + constant over time + """ + if not isinstance(law, sp.Expr): + raise TypeError(f'conservation law must have type sympy.Expr, ' + f'was {type(law)}') + + self._conservation_law = law + + def set_dt(self, + dt: sp.Expr) -> None: + """ + Sets the time derivative + + :param dt: + time derivative + """ + self._dt = cast_to_sym(dt, 'dt') + + def get_dt(self) -> sp.Expr: + """ + Gets the time derivative + + :return: + time derivative + """ + return self._dt + + def get_free_symbols(self) -> Set[sp.Symbol]: + """ + Gets the set of free symbols in time derivative and initial conditions + + :return: + free symbols + """ + return self._dt.free_symbols.union(self._value.free_symbols) + + +class ConservationLaw(ModelQuantity): + """ + A conservation law defines the absolute the total amount of a + (weighted) sum of states + + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new ConservationLaw instance. + + :param identifier: + unique identifier of the ConservationLaw + + :param name: + individual name of the ConservationLaw (does not need to be + unique) + + :param value: formula (sum of states) + """ + super(ConservationLaw, self).__init__(identifier, name, value) + + +class Observable(ModelQuantity): + """ + An Observable links model simulations to experimental measurements, + abbreviated by ``y``. + + :ivar _measurement_symbol: + sympy symbol used in the objective function to represent + measurements to this observable + + :ivar trafo: + observable transformation, only applies when evaluating objective + function or residuals + """ + + _measurement_symbol: Union[sp.Symbol, None] = None + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr, + measurement_symbol: Optional[sp.Symbol] = None, + transformation: Optional[ObservableTransformation] = 'lin'): + """ + Create a new Observable instance. + + :param identifier: + unique identifier of the Observable + + :param name: + individual name of the Observable (does not need to be unique) + + :param value: + formula + + :param transformation: + observable transformation, only applies when evaluating objective + function or residuals + """ + super(Observable, self).__init__(identifier, name, value) + self._measurement_symbol = measurement_symbol + self.trafo = transformation + + def get_measurement_symbol(self) -> sp.Symbol: + if self._measurement_symbol is None: + self._measurement_symbol = generate_measurement_symbol( + self.get_id() + ) + + return self._measurement_symbol + + +class SigmaY(ModelQuantity): + """ + A Standard Deviation SigmaY rescales the distance between simulations + and measurements when computing residuals or objective functions, + abbreviated by ``sigmay``. + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Standard Deviation instance. + + :param identifier: + unique identifier of the Standard Deviation + + :param name: + individual name of the Standard Deviation (does not need to + be unique) + + :param value: + formula + """ + super(SigmaY, self).__init__(identifier, name, value) + + +class Expression(ModelQuantity): + """ + An Expression is a recurring elements in symbolic formulas. Specifying + this may yield more compact expression which may lead to substantially + shorter model compilation times, but may also reduce model simulation time. + Abbreviated by ``w``. + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Expression + + :param name: + individual name of the Expression (does not need to be unique) + + :param value: + formula + """ + super(Expression, self).__init__(identifier, name, value) + + +class Parameter(ModelQuantity): + """ + A Parameter is a free variable in the model with respect to which + sensitivities may be computed, abbreviated by ``p``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: numbers.Number): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Parameter + + :param name: + individual name of the Parameter (does not need to be + unique) + + :param value: + numeric value + """ + super(Parameter, self).__init__(identifier, name, value) + + +class Constant(ModelQuantity): + """ + A Constant is a fixed variable in the model with respect to which + sensitivities cannot be computed, abbreviated by ``k``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: numbers.Number): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Constant + + :param name: + individual name of the Constant (does not need to be unique) + + :param value: + numeric value + """ + super(Constant, self).__init__(identifier, name, value) + + +class LogLikelihood(ModelQuantity): + """ + A LogLikelihood defines the distance between measurements and + experiments for a particular observable. The final LogLikelihood value + in the simulation will be the sum of all specified LogLikelihood + instances evaluated at all timepoints, abbreviated by ``Jy``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the LogLikelihood + + :param name: + individual name of the LogLikelihood (does not need to be + unique) + + :param value: + formula + """ + super(LogLikelihood, self).__init__(identifier, name, value) + + +class Event(ModelQuantity): + """ + An Event defines either a SBML event or a root of the argument of a + Heaviside function. The Heaviside functions will be tracked via the + vector ``h`` during simulation and are needed to inform the ODE solver + about a discontinuity in either the right-hand side or the states + themselves, causing a reinitialization of the solver. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr, + state_update: Union[sp.Expr, None], + event_observable: Union[sp.Expr, None]): + """ + Create a new Event instance. + + :param identifier: + unique identifier of the Event + + :param name: + individual name of the Event (does not need to be unique) + + :param value: + formula for the root / trigger function + + :param state_update: + formula for the bolus function (None for Heaviside functions, + zero vector for events without bolus) + + :param event_observable: + formula a potential observable linked to the event + (None for Heaviside functions, empty events without observable) + """ + super(Event, self).__init__(identifier, name, value) + # add the Event specific components + self._state_update = state_update + self._observable = event_observable + + def __eq__(self, other): + """ + Check equality of events at the level of trigger/root functions, as we + need to collect unique root functions for ``roots.cpp`` + """ + return self.get_val() == other.get_val() diff --git a/python/amici/petab_import.py b/python/amici/petab_import.py index 4f8ad93c9e..e2b69e424a 100644 --- a/python/amici/petab_import.py +++ b/python/amici/petab_import.py @@ -691,7 +691,7 @@ def show_model_info(sbml_model: 'libsbml.Model'): logger.info(f'Reactions: {len(sbml_model.getListOfReactions())}') -def parse_cli_args(): +def _parse_cli_args(): """ Parse command line arguments @@ -714,6 +714,9 @@ def parse_cli_args(): action='store_true', help='Flatten measurement specific overrides of ' 'observable and noise parameters') + parser.add_argument('--no-sensitivities', dest='generate_sensitivity_code', + default=True, action='store_false', + help='Skip generation of sensitivity code') # Call with set of files parser.add_argument('-s', '--sbml', dest='sbml_file_name', @@ -750,7 +753,7 @@ def main(): Command line interface to import a model in the PEtab (https://github.com/PEtab-dev/PEtab/) format into AMICI. """ - args = parse_cli_args() + args = _parse_cli_args() if args.yaml_file_name: pp = petab.Problem.from_yaml(args.yaml_file_name) @@ -775,6 +778,7 @@ def main(): measurement_table=pp.measurement_df, model_output_dir=args.model_output_dir, compile=args.compile, + generate_sensitivity_code=args.generate_sensitivity_code, verbose=args.verbose) diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index 0d38391e94..6c78d39f59 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -5,34 +5,32 @@ in the :class:`pysb.core.Model` format. """ -from .ode_export import ( - ODEExporter, ODEModel, State, Constant, Parameter, Observable, SigmaY, - Expression, LogLikelihood, generate_measurement_symbol -) -from .import_utils import ( - noise_distribution_to_cost_function, _get_str_symbol_identifiers, - noise_distribution_to_observable_transformation, _parse_special_functions -) -import logging -from .logging import get_logger, log_execution_time, set_log_level - -import sympy as sp -import numpy as np import itertools +import logging import os import sys +from typing import (Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, + Union) + +import numpy as np +import pysb +import pysb.bng +import pysb.pattern +import sympy as sp -from typing import ( - List, Union, Dict, Tuple, Set, Iterable, Any, Callable, Optional -) +from .import_utils import (_get_str_symbol_identifiers, + _parse_special_functions, + generate_measurement_symbol, + noise_distribution_to_cost_function, + noise_distribution_to_observable_transformation, + RESERVED_SYMBOLS) +from .logging import get_logger, log_execution_time, set_log_level +from .ode_export import (Constant, Expression, LogLikelihood, ODEExporter, + ODEModel, Observable, Parameter, SigmaY, State) CL_Prototype = Dict[str, Dict[str, Any]] ConservationLaw = Dict[str, Union[str, sp.Basic]] -import pysb.bng -import pysb -import pysb.pattern - logger = get_logger(__name__, logging.ERROR) @@ -49,6 +47,9 @@ def pysb2amici( compute_conservation_laws: bool = True, compile: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), + # Do not enable by default without testing. + # See https://github.com/AMICI-dev/AMICI/pull/1672 + cache_simplify: bool = False, generate_sensitivity_code: bool = True, ): r""" @@ -115,6 +116,11 @@ def pysb2amici( :param simplify: see :attr:`amici.ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + Note that there are possible issues with PySB models: + https://github.com/AMICI-dev/AMICI/pull/1672 + :param generate_sensitivity_code: if set to ``False``, code for sensitivity computation will not be generated @@ -134,6 +140,7 @@ def pysb2amici( noise_distributions=noise_distributions, compute_conservation_laws=compute_conservation_laws, simplify=simplify, + cache_simplify=cache_simplify, verbose=verbose, ) exporter = ODEExporter( @@ -160,6 +167,9 @@ def ode_model_from_pysb_importer( noise_distributions: Optional[Dict[str, Union[str, Callable]]] = None, compute_conservation_laws: bool = True, simplify: Callable = sp.powsimp, + # Do not enable by default without testing. + # See https://github.com/AMICI-dev/AMICI/pull/1672 + cache_simplify: bool = False, verbose: Union[int, bool] = False, ) -> ODEModel: """ @@ -188,6 +198,11 @@ def ode_model_from_pysb_importer( :param simplify: see :attr:`amici.ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + Note that there are possible issues with PySB models: + https://github.com/AMICI-dev/AMICI/pull/1672 + :param verbose: verbosity level for logging, True/False default to :attr:`logging.DEBUG`/:attr:`logging.ERROR` @@ -195,7 +210,11 @@ def ode_model_from_pysb_importer( New ODEModel instance according to pysbModel """ - ode = ODEModel(verbose=verbose, simplify=simplify) + ode = ODEModel( + verbose=verbose, + simplify=simplify, + cache_simplify=cache_simplify, + ) if constant_parameters is None: constant_parameters = [] @@ -325,7 +344,20 @@ def _process_pysb_expressions( # they are ordered according to their dependency and we can # evaluate them sequentially without reordering. Important to make # sure that observables are processed first though. - for expr in pysb_model.expressions: + + # we use _constant and _dynamic functions to get access to derived + # expressions that are otherwise only accessible as private attribute + for expr in pysb_model.expressions_constant(include_derived=True)\ + | pysb_model.expressions_dynamic(include_derived=True): + if any( + isinstance(symbol, pysb.Tag) + for symbol in expr.expand_expr().free_symbols + ): + # we only need explicit instantiations of expressions with tags, + # which are defined in the derived expressions. The abstract + # expressions are not needed and lead to compilation errors so + # we skip them. + continue _add_expression(expr, expr.name, expr.expr, pysb_model, ode_model, observables, sigmas, noise_distributions) diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index b86e822beb..4fd56d984e 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -4,33 +4,34 @@ This module provides all necessary functionality to import a model specified in the `Systems Biology Markup Language (SBML) `_. """ - - -import sympy as sp -import libsbml as sbml -import re -import math +import copy import itertools as itt -import warnings import logging -import copy -from typing import ( - Dict, List, Callable, Any, Iterable, Union, Optional, -) +import math +import os +import re +import warnings +from typing import (Any, Callable, Dict, Iterable, List, Optional, Union) -from .import_utils import ( - smart_subs, smart_subs_dict, toposort_symbols, - _get_str_symbol_identifiers, noise_distribution_to_cost_function, - noise_distribution_to_observable_transformation, _parse_special_functions, - _check_unsupported_functions, -) -from .ode_export import ( - ODEExporter, ODEModel, generate_measurement_symbol, - symbol_with_assumptions -) +import libsbml as sbml +import sympy as sp + +from . import has_clibs +from .conserved_moieties import compute_moiety_conservation_laws from .constants import SymbolId +from .import_utils import (CircularDependencyError, + _check_unsupported_functions, + _get_str_symbol_identifiers, + _parse_special_functions, + generate_measurement_symbol, + noise_distribution_to_cost_function, + noise_distribution_to_observable_transformation, + smart_subs, smart_subs_dict, toposort_symbols, + RESERVED_SYMBOLS) from .logging import get_logger, log_execution_time, set_log_level -from . import has_clibs +from .ode_export import ( + ODEExporter, ODEModel, symbol_with_assumptions +) class SBMLException(Exception): @@ -218,6 +219,7 @@ def sbml2amici(self, compile: bool = True, compute_conservation_laws: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), + cache_simplify: bool = False, log_as_log10: bool = True, generate_sensitivity_code: bool = True, **kwargs) -> None: @@ -282,12 +284,19 @@ def sbml2amici(self, if set to ``True``, conservation laws are automatically computed and applied such that the state-jacobian of the ODE right-hand-side has full rank. This option should be set to - ``True`` when using the newton algorithm to compute steadystate + ``True`` when using the Newton algorithm to compute steadystate sensitivities. + Conservation laws for constant species are enabled by default. + Support for conservation laws for non-constant species is + experimental and may be enabled by setting an environment variable + ``AMICI_EXPERIMENTAL_SBML_NONCONST_CLS`` to any value. :param simplify: see :attr:`ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + :param log_as_log10: If ``True``, log in the SBML model will be parsed as ``log10`` (default), if ``False``, log will be parsed as natural logarithm @@ -361,7 +370,11 @@ def sbml2amici(self, self._clean_reserved_symbols() self._process_time() - ode_model = ODEModel(verbose=verbose, simplify=simplify) + ode_model = ODEModel( + verbose=verbose, + simplify=simplify, + cache_simplify=cache_simplify, + ) ode_model.import_from_sbml_importer( self, compute_cls=compute_conservation_laws) exporter = ODEExporter( @@ -1201,6 +1214,10 @@ def _process_observables( # add user-provided observables or make all species, and compartments # with assignment rules, observable if observables: + # gather local symbols before parsing observable and sigma formulas + for obs in observables.keys(): + self.add_local_symbol(obs, symbol_with_assumptions(obs)) + self.symbols[SymbolId.OBSERVABLE] = { symbol_with_assumptions(obs): { 'name': definition.get('name', f'y{iobs}'), @@ -1216,6 +1233,16 @@ def _process_observables( } for iobs, (obs, definition) in enumerate(observables.items()) } + # check for nesting of observables (unsupported) + observable_syms = set(self.symbols[SymbolId.OBSERVABLE].keys()) + for obs in self.symbols[SymbolId.OBSERVABLE].values(): + if any(sym in observable_syms + for sym in obs['value'].free_symbols): + raise ValueError( + "Nested observables are not supported, " + f"but observable `{obs['name']} = {obs['value']}` " + "references another observable." + ) elif observables is None: self._generate_default_observables() @@ -1385,21 +1412,24 @@ def process_conservation_laws(self, ode_model) -> None: :param ode_model: ODEModel object with basic definitions - - :returns volume_updates_solver: - List (according to reduced stoichiometry) with updates for the - stoichiometric matrix accounting for compartment volumes """ conservation_laws = [] - # So far, only conservation laws for constant species are supported + # Create conservation laws for constant species species_solver = _add_conservation_for_constant_species( ode_model, conservation_laws ) + # Non-constant species processed here + if "AMICI_EXPERIMENTAL_SBML_NONCONST_CLS" in os.environ \ + or "GITHUB_ACTIONS" in os.environ: + species_solver = list(set( + self._add_conservation_for_non_constant_species( + ode_model, conservation_laws)) & set(species_solver)) # Check, whether species_solver is empty now. As currently, AMICI - # cannot handle ODEs without species, CLs must switched in this case - if len(species_solver) == 0: + # cannot handle ODEs without species, CLs must be switched off in this + # case + if not len(species_solver): conservation_laws = [] species_solver = list(range(ode_model.num_states_rdata())) @@ -1411,6 +1441,141 @@ def process_conservation_laws(self, ode_model) -> None: for cl in conservation_laws: ode_model.add_conservation_law(**cl) + def _add_conservation_for_non_constant_species( + self, + ode_model: ODEModel, + conservation_laws: List[ConservationLaw] + ) -> List[int]: + """Add non-constant species to conservation laws + + :param ode_model: + ODEModel object with basic definitions + :param conservation_laws: + List of already known conservation laws + :returns: + List of species indices which later remain in the ODE solver + """ + # indices of retained species + species_solver = list(range(ode_model.num_states_rdata())) + + try: + stoichiometric_list = [ + float(entry) for entry in self.stoichiometric_matrix.T.flat() + ] + except TypeError: + # Due to the numerical algorithm currently used to identify + # conserved quantities, we can't have symbols in the + # stoichiometric matrix + warnings.warn("Conservation laws for non-constant species in " + "combination with parameterized stoichiometric " + "coefficients are not currently supported " + "and will be turned off.") + return species_solver + + if any(rule.getTypeCode() == sbml.SBML_RATE_RULE + for rule in self.sbml.getListOfRules()): + # see SBML semantic test suite, case 33 for an example + warnings.warn("Conservation laws for non-constant species in " + "models with RateRules are not currently supported " + "and will be turned off.") + return species_solver + + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, *self.stoichiometric_matrix.shape, + rng_seed=32, + species_names=[str(x.get_id()) for x in ode_model._states] + ) + + # Sparsify conserved quantities + # ``compute_moiety_conservation_laws`` identifies conserved quantities + # with positive coefficients. The resulting system is, therefore, + # often non-sparse. This leads to circular dependencies in the + # state expressions of eliminated states. The identified conserved + # quantities are linearly independent. We can construct `A` as in + # `A * x0 = total_cl` and bring it to reduced row echelon form. The + # pivot species are the ones to be eliminated. The resulting state + # expressions are sparse and void of any circular dependencies. + A = sp.zeros(len(cls_coefficients), len(ode_model._states)) + for i_cl, (cl, coefficients) in enumerate(zip(cls_state_idxs, + cls_coefficients)): + for i, c in zip(cl, coefficients): + A[i_cl, i] = sp.Rational(c) + rref, pivots = A.rref() + species_to_be_removed = set(pivots) + + # keep new conservations laws separate until we know everything worked + new_conservation_laws = [] + # previously removed constant species + eliminated_state_ids = {cl['state'] for cl in conservation_laws} + + all_state_ids = [x.get_id() for x in ode_model._states] + all_compartment_sizes = [ + self.compartments[ + self.symbols[SymbolId.SPECIES][state_id]['compartment']] + if not self.symbols[SymbolId.SPECIES][state_id]['amount'] + else sp.Integer(1) + for state_id in all_state_ids + ] + + # iterate over list of conservation laws, create symbolic expressions, + for i_cl, target_state_model_idx in enumerate(pivots): + if all_state_ids[target_state_model_idx] in eliminated_state_ids: + # constants state, already eliminated + continue + # collect values for species engaged in the current CL + state_idxs = [i for i, coeff in enumerate(rref[i_cl, :]) + if coeff] + coefficients = [coeff for coeff in rref[i_cl, :] if coeff] + state_ids = [all_state_ids[i_state] for i_state in state_idxs] + compartment_sizes = [all_compartment_sizes[i] for i in state_idxs] + + target_state_id = all_state_ids[target_state_model_idx] + target_compartment = all_compartment_sizes[target_state_model_idx] + target_state_coeff = coefficients[0] + total_abundance = symbol_with_assumptions(f'tcl_{target_state_id}') + + # \sum coeff * state * volume + abundance_expr = sp.Add(*[ + state_id * coeff * compartment + for state_id, coeff, compartment + in zip(state_ids, coefficients, compartment_sizes) + ]) + + new_conservation_laws.append({ + 'state': target_state_id, + 'total_abundance': total_abundance, + 'state_expr': + (total_abundance - (abundance_expr + - target_state_id * target_compartment + * target_state_coeff)) + / target_state_coeff / target_compartment, + 'abundance_expr': abundance_expr + }) + species_to_be_removed.add(target_state_model_idx) + + # replace eliminated states by their state expressions, taking care of + # any (non-cyclic) dependencies + state_exprs = { + cl['state']: cl['state_expr'] + for cl in itt.chain(conservation_laws, new_conservation_laws) + } + try: + sorted_state_exprs = toposort_symbols(state_exprs) + except CircularDependencyError as e: + raise AssertionError( + "Circular dependency detected in conservation laws. " + "This should not have happened." + ) from e + + for cl in new_conservation_laws: + cl['state_expr'] = smart_subs_dict(cl['state_expr'], + sorted_state_exprs) + + conservation_laws.extend(new_conservation_laws) + + # list of species that are not determined by conservation laws + return [ix for ix in species_solver if ix not in species_to_be_removed] + def _replace_compartments_with_volumes(self): """ Replaces compartment symbols in expressions with their respective @@ -1527,9 +1692,7 @@ def _clean_reserved_symbols(self) -> None: """ Remove all reserved symbols from self.symbols """ - reserved_symbols = ['x', 'k', 'p', 'y', 'w', 'h', 't', - 'AMICI_EMPTY_BOLUS'] - for sym in reserved_symbols: + for sym in RESERVED_SYMBOLS: old_symbol = symbol_with_assumptions(sym) new_symbol = symbol_with_assumptions(f'amici_{sym}') self._replace_in_all_expressions(old_symbol, new_symbol, diff --git a/python/amici/setup.template.py b/python/amici/setup.template.py index 990b5ea232..06bfbe4e4d 100644 --- a/python/amici/setup.template.py +++ b/python/amici/setup.template.py @@ -34,6 +34,8 @@ def build_extension(self, ext): self.compiler.compile = compile_parallel.__get__( self.compiler, setuptools._distutils.ccompiler.CCompiler) + print(f"Building model extension in {os.getcwd()}") + build_ext.build_extension(self, ext) def find_swig(self) -> str: @@ -168,7 +170,7 @@ def get_extension() -> Extension: packages=find_packages(), install_requires=['amici==TPL_AMICI_VERSION'], extras_require={'wurlitzer': ['wurlitzer']}, - python_requires='>=3.7', + python_requires='>=3.8', package_data={}, zip_safe=False, include_package_data=True, diff --git a/python/amici/swig_wrappers.py b/python/amici/swig_wrappers.py new file mode 100644 index 0000000000..77008a3e31 --- /dev/null +++ b/python/amici/swig_wrappers.py @@ -0,0 +1,226 @@ +"""Convenience wrappers for the swig interface""" +import sys +from contextlib import contextmanager, suppress +from typing import List, Optional, Union, Sequence, Dict, Any +import amici.amici as amici_swig +from . import numpy + +__all__ = [ + 'runAmiciSimulation', 'runAmiciSimulations', 'ExpData', + 'readSolverSettingsFromHDF5', 'writeSolverSettingsToHDF5', + 'set_model_settings', 'get_model_settings', + 'AmiciModel', 'AmiciSolver', 'AmiciExpData', 'AmiciReturnData', + 'AmiciExpDataVector' +] + +AmiciModel = Union['amici.Model', 'amici.ModelPtr'] +AmiciSolver = Union['amici.Solver', 'amici.SolverPtr'] +AmiciExpData = Union['amici.ExpData', 'amici.ExpDataPtr'] +AmiciReturnData = Union['amici.ReturnData', 'amici.ReturnDataPtr'] +AmiciExpDataVector = Union['amici.ExpDataPtrVector', Sequence[AmiciExpData]] + + +try: + from wurlitzer import sys_pipes +except ModuleNotFoundError: + sys_pipes = suppress + + +@contextmanager +def _capture_cstdout(): + """Redirect C/C++ stdout to python stdout if python stdout is redirected, + e.g. in ipython notebook""" + if sys.stdout == sys.__stdout__: + yield + else: + with sys_pipes(): + yield + + +def _get_ptr( + obj: Union[AmiciModel, AmiciExpData, AmiciSolver, AmiciReturnData] +) -> Union['amici_swig.Model', 'amici_swig.ExpData', + 'amici_swig.Solver', 'amici_swig.ReturnData']: + """ + Convenience wrapper that returns the smart pointer pointee, if applicable + + :param obj: + Potential smart pointer + + :returns: + Non-smart pointer + """ + if isinstance(obj, (amici_swig.ModelPtr, amici_swig.ExpDataPtr, + amici_swig.SolverPtr, amici_swig.ReturnDataPtr)): + return obj.get() + return obj + + +def runAmiciSimulation( + model: AmiciModel, + solver: AmiciSolver, + edata: Optional[AmiciExpData] = None +) -> 'numpy.ReturnDataView': + """ + Convenience wrapper around :py:func:`amici.amici.runAmiciSimulation` + (generated by swig) + + :param model: + Model instance + +` :param solver: + Solver instance, must be generated from + :py:meth:`amici.amici.Model.getSolver` + + :param edata: + ExpData instance (optional) + + :returns: + ReturnData object with simulation results + """ + with _capture_cstdout(): + rdata = amici_swig.runAmiciSimulation( + _get_ptr(solver), _get_ptr(edata), _get_ptr(model)) + return numpy.ReturnDataView(rdata) + + +def ExpData(*args) -> 'amici_swig.ExpData': + """ + Convenience wrapper for :py:class:`amici.amici.ExpData` constructors + + :param args: arguments + + :returns: ExpData Instance + """ + if isinstance(args[0], numpy.ReturnDataView): + return amici_swig.ExpData(_get_ptr(args[0]['ptr']), *args[1:]) + elif isinstance(args[0], (amici_swig.ExpData, amici_swig.ExpDataPtr)): + # the *args[:1] should be empty, but by the time you read this, + # the constructor signature may have changed, and you are glad this + # wrapper did not break. + return amici_swig.ExpData(_get_ptr(args[0]), *args[1:]) + elif isinstance(args[0], (amici_swig.Model, amici_swig.ModelPtr)): + return amici_swig.ExpData(_get_ptr(args[0])) + else: + return amici_swig.ExpData(*args) + + +def runAmiciSimulations( + model: AmiciModel, + solver: AmiciSolver, + edata_list: AmiciExpDataVector, + failfast: bool = True, + num_threads: int = 1, +) -> List['numpy.ReturnDataView']: + """ + Convenience wrapper for loops of amici.runAmiciSimulation + + :param model: Model instance + :param solver: Solver instance, must be generated from Model.getSolver() + :param edata_list: list of ExpData instances + :param failfast: returns as soon as an integration failure is encountered + :param num_threads: number of threads to use (only used if compiled + with openmp) + + :returns: list of simulation results + """ + with _capture_cstdout(): + edata_ptr_vector = amici_swig.ExpDataPtrVector(edata_list) + rdata_ptr_list = amici_swig.runAmiciSimulations( + _get_ptr(solver), + edata_ptr_vector, + _get_ptr(model), + failfast, + num_threads + ) + return [numpy.ReturnDataView(r) for r in rdata_ptr_list] + + +def readSolverSettingsFromHDF5( + file: str, + solver: AmiciSolver, + location: Optional[str] = 'solverSettings' +) -> None: + """ + Convenience wrapper for :py:func:`amici.readSolverSettingsFromHDF5` + + :param file: hdf5 filename + :param solver: Solver instance to which settings will be transferred + :param location: location of solver settings in hdf5 file + """ + amici_swig.readSolverSettingsFromHDF5(file, _get_ptr(solver), location) + + +def writeSolverSettingsToHDF5( + solver: AmiciSolver, + file: Union[str, object], + location: Optional[str] = 'solverSettings' +) -> None: + """ + Convenience wrapper for :py:func:`amici.amici.writeSolverSettingsToHDF5` + + :param file: hdf5 filename, can also be an object created by + :py:func:`amici.amici.createOrOpenForWriting` + :param solver: Solver instance from which settings will be stored + :param location: location of solver settings in hdf5 file + """ + amici_swig.writeSolverSettingsToHDF5(_get_ptr(solver), file, location) + + +# Values are suffixes of `get[...]` and `set[...]` `amici.Model` methods. +# If either the getter or setter is not named with this pattern, then the value +# is a tuple where the first and second elements are the getter and setter +# methods, respectively. +model_instance_settings = [ + 'AddSigmaResiduals', + 'AlwaysCheckFinite', + 'FixedParameters', + 'InitialStates', + 'InitialStateSensitivities', + 'MinimumSigmaResiduals', + ('nMaxEvent', 'setNMaxEvent'), + 'Parameters', + 'ParameterList', + 'ParameterScale', # getter returns a SWIG object + 'ReinitializationStateIdxs', + 'ReinitializeFixedParameterInitialStates', + 'StateIsNonNegative', + 'SteadyStateSensitivityMode', + ('t0', 'setT0'), + 'Timepoints', +] + + +def get_model_settings( + model: AmiciModel, +) -> Dict[str, Any]: + """Get model settings that are set independently of the compiled model. + + :param model: The AMICI model instance. + + :returns: Keys are AMICI model attributes, values are attribute values. + """ + settings = {} + for setting in model_instance_settings: + getter = setting[0] if isinstance(setting, tuple) else f'get{setting}' + settings[setting] = getattr(model, getter)() + # TODO `amici.Model.getParameterScale` returns a SWIG object instead + # of a Python list/tuple. + if setting == 'ParameterScale': + settings[setting] = tuple(settings[setting]) + return settings + + +def set_model_settings( + model: AmiciModel, + settings: Dict[str, Any], +) -> None: + """Set model settings. + + :param model: The AMICI model instance. + :param settings: Keys are callable attributes (setters) of an AMICI model, + values are provided to the setters. + """ + for setting, value in settings.items(): + setter = setting[1] if isinstance(setting, tuple) else f'set{setting}' + getattr(model, setter)(value) diff --git a/python/examples/example_steadystate/ExampleSteadystate.ipynb b/python/examples/example_steadystate/ExampleSteadystate.ipynb index d1acfe687d..52f014dba8 100644 --- a/python/examples/example_steadystate/ExampleSteadystate.ipynb +++ b/python/examples/example_steadystate/ExampleSteadystate.ipynb @@ -16,7 +16,7 @@ "outputs": [], "source": [ "# SBML model we want to import\n", - "sbml_file = 'model_steadystate_scaled.xml'\n", + "sbml_file = 'model_steadystate_scaled_without_observables.xml'\n", "# Name of the model that will also be the name of the python module\n", "model_name = 'model_steadystate_scaled'\n", "# Directory to which the generated model code is written\n", @@ -133,7 +133,7 @@ "\n", "Specifying observables is beyond the scope of SBML. Here we define them manually.\n", "\n", - "If you are looking for a more scalable way for defining observables, then checkout [PEtab](https://github.com/PEtab-dev/PEtab). Another possibility is using SBML's [`AssignmentRule`s](http://sbml.org/Software/libSBML/5.13.0/docs//python-api/classlibsbml_1_1_rule.html) to specify model outputs within the SBML file." + "If you are looking for a more scalable way for defining observables, then checkout [PEtab](https://github.com/PEtab-dev/PEtab). Another possibility is using SBML's [`AssignmentRule`s](https://sbml.org/software/libsbml/5.18.0/docs/formatted/python-api/classlibsbml_1_1_assignment_rule.html) to specify model outputs within the SBML file." ] }, { @@ -1937,7 +1937,7 @@ ], "source": [ "# look at the States in rdata as DataFrame\n", - "amici.getSimulationStatesAsDataFrame(model, [edata], [rdata])" + "amici.getSimulationStatesAsDataFrame(model, [edata], [rdata])\n" ] } ], diff --git a/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml b/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml new file mode 100644 index 0000000000..62c673e513 --- /dev/null +++ b/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p1 + + + x1 + 2 + + + + + + + + + + + + + + + + + + p2 + x1 + x2 + + + + + + + + + + + + + + + + p3 + x2 + + + + + + + + + + + + + + + + + p4 + x3 + + + + + + + + + + + + + k0 + x3 + + + + + + + + + + + p5 + + + + + + + diff --git a/python/sdist/amici/bngl_import.py b/python/sdist/amici/bngl_import.py new file mode 120000 index 0000000000..5aa807079a --- /dev/null +++ b/python/sdist/amici/bngl_import.py @@ -0,0 +1 @@ +../../amici/bngl_import.py \ No newline at end of file diff --git a/python/sdist/amici/conserved_moieties.py b/python/sdist/amici/conserved_moieties.py new file mode 120000 index 0000000000..8e96336ae0 --- /dev/null +++ b/python/sdist/amici/conserved_moieties.py @@ -0,0 +1 @@ +../../amici/conserved_moieties.py \ No newline at end of file diff --git a/python/sdist/amici/ode_model.py b/python/sdist/amici/ode_model.py new file mode 120000 index 0000000000..cbd58833cd --- /dev/null +++ b/python/sdist/amici/ode_model.py @@ -0,0 +1 @@ +../../amici/ode_model.py \ No newline at end of file diff --git a/python/sdist/amici/swig_wrappers.py b/python/sdist/amici/swig_wrappers.py new file mode 120000 index 0000000000..83af20e099 --- /dev/null +++ b/python/sdist/amici/swig_wrappers.py @@ -0,0 +1 @@ +../../amici/swig_wrappers.py \ No newline at end of file diff --git a/python/sdist/setup.py b/python/sdist/setup.py index 2b97a5d7dd..4b35aa6ba9 100755 --- a/python/sdist/setup.py +++ b/python/sdist/setup.py @@ -12,6 +12,7 @@ import os import sys +from pathlib import Path # Add containing directory to path, as we need some modules from the AMICI # package already for installation @@ -19,7 +20,7 @@ import numpy as np import setup_clibs # Must run from within containing directory -from setuptools import find_packages, setup, Extension +from setuptools import setup, Extension from amici.custom_commands import ( AmiciInstall, AmiciBuildCLib, AmiciDevelop, @@ -32,6 +33,7 @@ add_openmp_flags, ) + def main(): # Extra compiler flags cxx_flags = [] @@ -82,12 +84,25 @@ def main(): amici_module_linker_flags.extend( os.environ['AMICI_LDFLAGS'].split(' ')) + amici_base_dir = Path('amici') + suitesparse_base_dir = amici_base_dir / 'ThirdParty' / 'SuiteSparse' + sundials_base_dir = amici_base_dir / 'ThirdParty' / 'sundials' + libamici = setup_clibs.get_lib_amici( + amici_base_dir=amici_base_dir, + sundials_base_dir=sundials_base_dir, + suitesparse_base_dir=suitesparse_base_dir, h5pkgcfg=h5pkgcfg, blaspkgcfg=blaspkgcfg, - extra_compiler_flags=cxx_flags) - libsundials = setup_clibs.get_lib_sundials(extra_compiler_flags=cxx_flags) + extra_compiler_flags=cxx_flags + ) + libsundials = setup_clibs.get_lib_sundials( + sundials_base_dir=sundials_base_dir, + suitesparse_base_dir=suitesparse_base_dir, + extra_compiler_flags=cxx_flags + ) libsuitesparse = setup_clibs.get_lib_suite_sparse( - extra_compiler_flags=cxx_flags + ['-DDLONG'] + extra_compiler_flags=cxx_flags + ['-DDLONG'], + suitesparse_base_dir=suitesparse_base_dir ) # Readme as long package description to go on PyPi @@ -100,14 +115,15 @@ def main(): amici_module = Extension( name='amici._amici', sources=extension_sources, - include_dirs=['amici/include', - 'amici/ThirdParty/gsl/', - *libsundials[1]['include_dirs'], - *libsuitesparse[1]['include_dirs'], - *h5pkgcfg['include_dirs'], - *blaspkgcfg['include_dirs'], - np.get_include() - ], + include_dirs=[ + amici_base_dir / 'include', + amici_base_dir / 'ThirdParty' / 'gsl', + *libsundials[1]['include_dirs'], + *libsuitesparse[1]['include_dirs'], + *h5pkgcfg['include_dirs'], + *blaspkgcfg['include_dirs'], + np.get_include() + ], # Cannot use here, see above # libraries=[ # 'hdf5_hl_cpp', 'hdf5_hl', 'hdf5_cpp', 'hdf5' diff --git a/python/sdist/setup_clibs.py b/python/sdist/setup_clibs.py index 1b68320f84..c570a597b9 100644 --- a/python/sdist/setup_clibs.py +++ b/python/sdist/setup_clibs.py @@ -6,154 +6,179 @@ AMICI-generated models. """ -import os -import glob import re - -from typing import Dict, List, Union, Tuple, Any, Optional +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, Union PackageInfo = Dict[str, List[Union[str, Tuple[str, Any]]]] Library = Tuple[str, PackageInfo] -# suite sparse include directories -suite_sparse_include_dirs = [ - 'amici/ThirdParty/SuiteSparse/KLU/Include/', - 'amici/ThirdParty/SuiteSparse/AMD/Include/', - 'amici/ThirdParty/SuiteSparse/COLAMD/Include/', - 'amici/ThirdParty/SuiteSparse/BTF/Include/', - 'amici/ThirdParty/SuiteSparse/SuiteSparse_config', - 'amici/ThirdParty/SuiteSparse/include' -] - -# sundials include directories -sundials_include_dirs = [ - 'amici/ThirdParty/sundials/include', - 'amici/ThirdParty/sundials/src', -] - - -def get_sundials_sources() -> List[str]: - """Get list of Sundials source files""" - srcs = [ - os.path.join('src', 'sunmatrix', 'dense', 'sunmatrix_dense.c'), - os.path.join('src', 'sunmatrix', 'band', 'sunmatrix_band.c'), - os.path.join('src', 'sunmatrix', 'sparse', 'sunmatrix_sparse.c'), - os.path.join('src', 'sunlinsol', 'spgmr', 'sunlinsol_spgmr.c'), - os.path.join('src', 'sunlinsol', 'sptfqmr', 'sunlinsol_sptfqmr.c'), - os.path.join('src', 'sunlinsol', 'klu', 'sunlinsol_klu.c'), - os.path.join('src', 'sunlinsol', 'dense', 'sunlinsol_dense.c'), - os.path.join('src', 'sunlinsol', 'spfgmr', 'sunlinsol_spfgmr.c'), - os.path.join('src', 'sunlinsol', 'pcg', 'sunlinsol_pcg.c'), - os.path.join('src', 'sunlinsol', 'spbcgs', 'sunlinsol_spbcgs.c'), - os.path.join('src', 'sunlinsol', 'band', 'sunlinsol_band.c'), - os.path.join('src', 'idas', 'idas_direct.c'), - os.path.join('src', 'idas', 'idaa.c'), - os.path.join('src', 'idas', 'idas_ic.c'), - os.path.join('src', 'idas', 'idas_nls_stg.c'), - os.path.join('src', 'idas', 'idas.c'), - os.path.join('src', 'idas', 'idas_bbdpre.c'), - os.path.join('src', 'idas', 'idas_spils.c'), - os.path.join('src', 'idas', 'idas_nls.c'), - os.path.join('src', 'idas', 'idas_ls.c'), - os.path.join('src', 'idas', 'idas_io.c'), - os.path.join('src', 'idas', 'idas_nls_sim.c'), - os.path.join('src', 'idas', 'idaa_io.c'), - os.path.join('src', 'sundials', 'sundials_math.c'), - os.path.join('src', 'sundials', 'sundials_matrix.c'), - os.path.join('src', 'sundials', 'sundials_direct.c'), - os.path.join('src', 'sundials', 'sundials_nvector_senswrapper.c'), - os.path.join('src', 'sundials', 'sundials_dense.c'), - os.path.join('src', 'sundials', 'sundials_nvector.c'), - os.path.join('src', 'sundials', 'sundials_version.c'), - os.path.join('src', 'sundials', 'sundials_iterative.c'), - os.path.join('src', 'sundials', 'sundials_nonlinearsolver.c'), - os.path.join('src', 'sundials', 'sundials_linearsolver.c'), - os.path.join('src', 'sundials', 'sundials_band.c'), - os.path.join('src', 'sundials', 'sundials_futils.c'), - os.path.join('src', 'sunnonlinsol', 'newton', 'sunnonlinsol_newton.c'), - os.path.join('src', 'sunnonlinsol', 'fixedpoint', - 'sunnonlinsol_fixedpoint.c'), - os.path.join('src', 'nvector', 'serial', 'nvector_serial.c'), - os.path.join('src', 'cvodes', 'cvodes_spils.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_stg.c'), - os.path.join('src', 'cvodes', 'cvodes_ls.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_stg1.c'), - os.path.join('src', 'cvodes', 'cvodes_bbdpre.c'), - os.path.join('src', 'cvodes', 'cvodes.c'), - os.path.join('src', 'cvodes', 'cvodes_bandpre.c'), - os.path.join('src', 'cvodes', 'cvodea.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_sim.c'), - os.path.join('src', 'cvodes', 'cvodea_io.c'), - os.path.join('src', 'cvodes', 'cvodes_nls.c'), - os.path.join('src', 'cvodes', 'cvodes_diag.c'), - os.path.join('src', 'cvodes', 'cvodes_io.c'), - os.path.join('src', 'cvodes', 'cvodes_direct.c') - ] - return [os.path.join('amici', 'ThirdParty', 'sundials', src) - for src in srcs] - - -def get_suite_sparse_sources() -> List[str]: - """Get list of SuiteSparse source files""" - srcs = [ - os.path.join('KLU', 'Source', 'klu_analyze_given.c'), - os.path.join('KLU', 'Source', 'klu_analyze.c'), - os.path.join('KLU', 'Source', 'klu_defaults.c'), - os.path.join('KLU', 'Source', 'klu_diagnostics.c'), - os.path.join('KLU', 'Source', 'klu_dump.c'), - os.path.join('KLU', 'Source', 'klu_extract.c'), - os.path.join('KLU', 'Source', 'klu_factor.c'), - os.path.join('KLU', 'Source', 'klu_free_numeric.c'), - os.path.join('KLU', 'Source', 'klu_free_symbolic.c'), - os.path.join('KLU', 'Source', 'klu_kernel.c'), - os.path.join('KLU', 'Source', 'klu_memory.c'), - os.path.join('KLU', 'Source', 'klu_refactor.c'), - os.path.join('KLU', 'Source', 'klu_scale.c'), - os.path.join('KLU', 'Source', 'klu_sort.c'), - os.path.join('KLU', 'Source', 'klu_solve.c'), - os.path.join('KLU', 'Source', 'klu_tsolve.c'), - os.path.join('KLU', 'Source', 'klu.c'), - os.path.join('AMD', 'Source', 'amd_1.c'), - os.path.join('AMD', 'Source', 'amd_2.c'), - os.path.join('AMD', 'Source', 'amd_aat.c'), - os.path.join('AMD', 'Source', 'amd_control.c'), - os.path.join('AMD', 'Source', 'amd_defaults.c'), - os.path.join('AMD', 'Source', 'amd_dump.c'), - os.path.join('AMD', 'Source', 'amd_global.c'), - os.path.join('AMD', 'Source', 'amd_info.c'), - os.path.join('AMD', 'Source', 'amd_order.c'), - os.path.join('AMD', 'Source', 'amd_post_tree.c'), - os.path.join('AMD', 'Source', 'amd_postorder.c'), - os.path.join('AMD', 'Source', 'amd_preprocess.c'), - os.path.join('AMD', 'Source', 'amd_valid.c'), - os.path.join('COLAMD', 'Source', 'colamd.c'), - os.path.join('BTF', 'Source', 'btf_maxtrans.c'), - os.path.join('BTF', 'Source', 'btf_order.c'), - os.path.join('BTF', 'Source', 'btf_strongcomp.c'), - os.path.join('SuiteSparse_config', 'SuiteSparse_config.c'), - ] - return [os.path.join('amici', 'ThirdParty', 'SuiteSparse', src) - for src in srcs] +def get_suite_sparse_include_dirs(ss_base_dir: Path) -> List[str]: + """Suite sparse include directories + + :param ss_base_dir: SuiteSparse base directory + """ + return list(map(str, [ + ss_base_dir / 'KLU' / 'Include', + ss_base_dir / 'AMD' / 'Include', + ss_base_dir / 'COLAMD' / 'Include', + ss_base_dir / 'BTF' / 'Include', + ss_base_dir / 'SuiteSparse_config', + ss_base_dir / 'include', + ])) + + +def get_sundials_include_dirs(sundials_base_dir: Path) -> List[str]: + """Sundials include directories -def get_amici_base_sources(with_hdf5: bool = True) -> List[str]: + :param sundials_base_dir: sundials base directory + """ + return list(map(str, [ + sundials_base_dir / 'include', + sundials_base_dir / 'src', + ])) + + +def get_sundials_sources(sundials_base_dir: Path) -> List[str]: + """Get list of Sundials source files + + :param sundials_base_dir: sundials base directory + """ + return list(map(str, [ + sundials_base_dir / 'src' / 'sunmatrix' / 'dense' + / 'sunmatrix_dense.c', + sundials_base_dir / 'src' / 'sunmatrix' / 'band' + / 'sunmatrix_band.c', + sundials_base_dir / 'src' / 'sunmatrix' / 'sparse' + / 'sunmatrix_sparse.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spgmr' + / 'sunlinsol_spgmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'sptfqmr' + / 'sunlinsol_sptfqmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'klu' / 'sunlinsol_klu.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'dense' + / 'sunlinsol_dense.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spfgmr' + / 'sunlinsol_spfgmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'pcg' / 'sunlinsol_pcg.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spbcgs' + / 'sunlinsol_spbcgs.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'band' / 'sunlinsol_band.c', + sundials_base_dir / 'src' / 'idas' / 'idas_direct.c', + sundials_base_dir / 'src' / 'idas' / 'idaa.c', + sundials_base_dir / 'src' / 'idas' / 'idas_ic.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls_stg.c', + sundials_base_dir / 'src' / 'idas' / 'idas.c', + sundials_base_dir / 'src' / 'idas' / 'idas_bbdpre.c', + sundials_base_dir / 'src' / 'idas' / 'idas_spils.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls.c', + sundials_base_dir / 'src' / 'idas' / 'idas_ls.c', + sundials_base_dir / 'src' / 'idas' / 'idas_io.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls_sim.c', + sundials_base_dir / 'src' / 'idas' / 'idaa_io.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_math.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_matrix.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_direct.c', + sundials_base_dir / 'src' / 'sundials' + / 'sundials_nvector_senswrapper.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_dense.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_nvector.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_version.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_iterative.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_nonlinearsolver.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_linearsolver.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_band.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_futils.c', + sundials_base_dir / 'src' / 'sunnonlinsol' / 'newton' + / 'sunnonlinsol_newton.c', + sundials_base_dir / 'src' / 'sunnonlinsol' / 'fixedpoint' + / 'sunnonlinsol_fixedpoint.c', + sundials_base_dir / 'src' / 'nvector' / 'serial' / 'nvector_serial.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_spils.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_stg.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_ls.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_stg1.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_bbdpre.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_bandpre.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodea.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_sim.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodea_io.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_diag.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_io.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_direct.c' + ])) + + +def get_suite_sparse_sources(ss_base_dir: Path) -> List[str]: + """Get list of SuiteSparse source files + + :param ss_base_dir: SuiteSparse base directory + """ + return list(map(str, [ + ss_base_dir / 'KLU' / 'Source' / 'klu_analyze_given.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_analyze.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_defaults.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_diagnostics.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_dump.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_extract.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_factor.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_free_numeric.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_free_symbolic.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_kernel.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_memory.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_refactor.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_scale.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_sort.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_solve.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_tsolve.c', + ss_base_dir / 'KLU' / 'Source' / 'klu.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_1.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_2.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_aat.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_control.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_defaults.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_dump.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_global.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_info.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_order.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_post_tree.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_postorder.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_preprocess.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_valid.c', + ss_base_dir / 'COLAMD' / 'Source' / 'colamd.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_maxtrans.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_order.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_strongcomp.c', + ss_base_dir / 'SuiteSparse_config' / 'SuiteSparse_config.c', + ])) + + +def get_amici_base_sources( + base_dir: Path, + with_hdf5: bool = True +) -> List[str]: """Get list of source files for the amici base library Expects that we are inside $AMICI_ROOT/python/sdist Arguments: + base_dir: AMICI base dir containing ``src/`` and ``include/`` with_hdf5: compile with HDF5 support """ - - amici_base_sources = glob.glob(os.path.join('amici', 'src', '*.cpp')) - amici_base_sources = [src for src in amici_base_sources - if not re.search(r'(matlab)|(\.(ODE_)?template\.)', src)] + amici_base_sources = (base_dir / 'src').glob('*.cpp') + amici_base_sources = [ + str(src) for src in amici_base_sources + if not re.search(r'(matlab)|(\.(ODE_)?template\.)', str(src)) + ] if not with_hdf5: - hdf5_cpp = os.path.join('amici', 'src', 'hdf5.cpp') + hdf5_cpp = base_dir / 'src' / 'hdf5.cpp' try: - # sometimes this fails for unknwon reasons... - amici_base_sources.remove(hdf5_cpp) + # sometimes this fails for unknown reasons... + amici_base_sources.remove(str(hdf5_cpp)) except ValueError: print(f'Warning: could not find {hdf5_cpp} in ' f'{amici_base_sources}') @@ -161,8 +186,11 @@ def get_amici_base_sources(with_hdf5: bool = True) -> List[str]: return amici_base_sources -def get_lib_sundials(extra_compiler_flags: Optional[List[str]] = None) -> \ - Library: +def get_lib_sundials( + sundials_base_dir: Path, + suitesparse_base_dir: Path, + extra_compiler_flags: Optional[List[str]] = None +) -> Library: """ Get sundials library build info for setuptools @@ -172,20 +200,25 @@ def get_lib_sundials(extra_compiler_flags: Optional[List[str]] = None) -> \ if extra_compiler_flags is None: extra_compiler_flags = [] - libsundials = ('sundials', { - 'sources': get_sundials_sources(), - 'include_dirs': [*sundials_include_dirs, - *suite_sparse_include_dirs, - ], - 'cflags': [*extra_compiler_flags], - 'cflags_mingw32': ['-Wno-misleading-indentation'], - 'cflags_unix': ['-Wno-misleading-indentation'], - }) - return libsundials - - -def get_lib_suite_sparse(extra_compiler_flags: Optional[List[str]] = None) -> \ - Library: + return ( + 'sundials', + { + 'sources': get_sundials_sources(sundials_base_dir), + 'include_dirs': [ + *get_sundials_include_dirs(sundials_base_dir), + *get_suite_sparse_include_dirs(suitesparse_base_dir), + ], + 'cflags': [*extra_compiler_flags], + 'cflags_mingw32': ['-Wno-misleading-indentation'], + 'cflags_unix': ['-Wno-misleading-indentation'], + } + ) + + +def get_lib_suite_sparse( + suitesparse_base_dir: Path, + extra_compiler_flags: Optional[List[str]] = None +) -> Library: """ Get SuiteSparse library build info for setuptools @@ -195,19 +228,26 @@ def get_lib_suite_sparse(extra_compiler_flags: Optional[List[str]] = None) -> \ if extra_compiler_flags is None: extra_compiler_flags = [] - libsuitesparse = ('suitesparse', { - 'sources': get_suite_sparse_sources(), - 'include_dirs': suite_sparse_include_dirs, - 'cflags': [*extra_compiler_flags], - 'cflags_mingw32': ['-Wno-unused-but-set-variable'], - 'cflags_unix': ['-Wno-unused-but-set-variable'] - }) - return libsuitesparse - - -def get_lib_amici(extra_compiler_flags: List[str] = None, - h5pkgcfg: Optional[PackageInfo] = None, - blaspkgcfg: Optional[PackageInfo] = None) -> Library: + return ( + 'suitesparse', + { + 'sources': get_suite_sparse_sources(suitesparse_base_dir), + 'include_dirs': + get_suite_sparse_include_dirs(suitesparse_base_dir), + 'cflags': [*extra_compiler_flags], + 'cflags_mingw32': ['-Wno-unused-but-set-variable'], + 'cflags_unix': ['-Wno-unused-but-set-variable'] + }) + + +def get_lib_amici( + amici_base_dir: Path, + sundials_base_dir: Path, + suitesparse_base_dir: Path, + extra_compiler_flags: List[str] = None, + h5pkgcfg: Optional[PackageInfo] = None, + blaspkgcfg: Optional[PackageInfo] = None, +) -> Library: """ Get AMICI core library build info for setuptools @@ -219,23 +259,24 @@ def get_lib_amici(extra_compiler_flags: List[str] = None, :param blaspkgcfg: blas package info - """ - if extra_compiler_flags is None: extra_compiler_flags = [] libamici = ('amici', { - 'sources': get_amici_base_sources( - with_hdf5=(h5pkgcfg - and 'include_dirs' in h5pkgcfg - and len(h5pkgcfg['include_dirs'])) + 'sources': + get_amici_base_sources( + amici_base_dir, + with_hdf5=(h5pkgcfg + and 'include_dirs' in h5pkgcfg + and len(h5pkgcfg['include_dirs'])) ), - 'include_dirs': ['amici/include', - *suite_sparse_include_dirs, - *sundials_include_dirs, - 'amici/ThirdParty/gsl/', - ], + 'include_dirs': [ + str(amici_base_dir / 'include'), + *get_suite_sparse_include_dirs(suitesparse_base_dir), + *get_sundials_include_dirs(sundials_base_dir), + str(amici_base_dir / 'ThirdParty' / 'gsl'), + ], 'cflags': [*extra_compiler_flags], 'cflags_mingw32': ['-std=c++14'], 'cflags_unix': ['-std=c++14'], diff --git a/python/tests/test_bngl.py b/python/tests/test_bngl.py new file mode 100644 index 0000000000..722359236d --- /dev/null +++ b/python/tests/test_bngl.py @@ -0,0 +1,85 @@ +import pytest +import os +import amici +import shutil +import numpy as np + +pysb = pytest.importorskip("pysb") + +from amici.bngl_import import bngl2amici +from pysb.simulator import ScipyOdeSimulator +from pysb.importers.bngl import model_from_bngl + +tests = [ + 'CaOscillate_Func', 'deleteMolecules', 'empty_compartments_block', + 'gene_expr', 'gene_expr_func', 'gene_expr_simple', 'isomerization', + 'Motivating_example_cBNGL', 'motor', 'simple_system', + 'test_compartment_XML', 'test_setconc', 'test_synthesis_cBNGL_simple', + 'test_synthesis_complex', 'test_synthesis_complex_0_cBNGL', + 'test_synthesis_complex_source_cBNGL', 'test_synthesis_simple', + 'univ_synth', 'Repressilator', 'test_paramname', 'tlmr' +] + + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") +@pytest.mark.parametrize('example', tests) +def test_compare_to_pysb_simulation(example): + + atol = 1e-8 + rtol = 1e-8 + + model_file = os.path.join(os.path.dirname(__file__), '..', '..', + 'ThirdParty', 'BioNetGen-2.7.0', 'Validate', + f'{example}.bngl') + + pysb_model = model_from_bngl(model_file) + + # pysb part + tspan = np.linspace(0, 100, 101) + sim = ScipyOdeSimulator( + pysb_model, + tspan=tspan, + integrator_options={'rtol': rtol, 'atol': atol}, + compiler='python' + ) + pysb_simres = sim.run() + + # amici part + + outdir = pysb_model.name + + cl = example not in ['Motivating_example_cBNGL', 'univ_synth'] + + kwargs = { + 'compute_conservation_laws': cl, + 'observables': list(pysb_model.observables.keys()) + } + if not cl: + with pytest.raises(ValueError, match="Conservation laws"): + bngl2amici(model_file, outdir, compute_conservation_laws=True) + + if example in ['empty_compartments_block', 'motor']: + with pytest.raises(ValueError, match="Cannot add"): + bngl2amici(model_file, outdir, **kwargs) + return + else: + bngl2amici(model_file, outdir, **kwargs) + + amici_model_module = amici.import_model_module(pysb_model.name, + outdir) + + model_amici = amici_model_module.getModel() + + model_amici.setTimepoints(tspan) + + solver = model_amici.getSolver() + solver.setMaxSteps(10**6) + solver.setAbsoluteTolerance(atol) + solver.setRelativeTolerance(rtol) + rdata = amici.runAmiciSimulation(model_amici, solver) + + # check agreement of species simulation + assert np.isclose(rdata.x, pysb_simres.species, 1e-4, 1e-4).all() + + shutil.rmtree(outdir, ignore_errors=True) diff --git a/python/tests/test_conserved_moieties.py b/python/tests/test_conserved_moieties.py new file mode 100644 index 0000000000..e039fe9f9e --- /dev/null +++ b/python/tests/test_conserved_moieties.py @@ -0,0 +1,272 @@ +"""Tests for conservation laws / conserved moieties""" +import os +from time import perf_counter + +import numpy as np +import pytest +import sympy as sp + +from amici.conserved_moieties import (_fill, _kernel, + compute_moiety_conservation_laws, + _output as output) +from amici.logging import get_logger, log_execution_time + +logger = get_logger(__name__) + +# reference data for `engaged_species` after kernel() +demartino2014_kernel_engaged_species = [ + 179, 181, 185, 186, 187, 190, 191, 194, 195, 197, 198, 200, 208, 209, 210, + 211, 214, 215, 218, 219, 221, 222, 224, 277, 292, 340, 422, 467, 468, 490, + 491, 598, 613, 966, 968, 1074, 1171, 1221, 1223, 1234, 1266, 1478, 1479, + 1480, 1481, 1496, 1497, 1498, 1501, 1526, 1527, 1528, 1529, 394, 1066, 398, + 465, 466, 594, 671, 429, 990, 652, 655, 662, 663, 664, 665, 666, 667, 668, + 669, 759, 760, 920, 921, 569, 1491, 1055, 1546, 276, 1333, 1421, 1429, + 1430, 1438, 1551, 1428, 1439, 1552, 1513, 1553, 1520, 1523, 1530, 1531, + 384, 1536, 440, 1537, 447, 1538, 456, 1539, 582, 1540, 876, 1541, 885, + 1542, 911, 1543, 978, 1544, 1010, 1545, 1070, 1547, 761, 1127, 1548, 1324, + 1549, 1370, 1550, 1554, 1560, 1555, 1580, 1556, 1644 +] + + +@pytest.fixture(scope="session") +def data_demartino2014(): + """Get tests from DeMartino2014 Suppl. Material""" + import urllib.request + import io + import gzip + + # stoichiometric matrix + response = urllib.request.urlopen( + r'https://chimera.roma1.infn.it/SYSBIO/test-ecoli.dat.gz', + timeout=10 + ) + data = gzip.GzipFile(fileobj=io.BytesIO(response.read())) + S = [int(item) for sl in + [entry.decode('ascii').strip().split('\t') + for entry in data.readlines()] for item in sl] + + # metabolite / row names + response = urllib.request.urlopen( + r'https://chimera.roma1.infn.it/SYSBIO/test-ecoli-met.txt', + timeout=10 + ) + row_names = [entry.decode('ascii').strip() + for entry in io.BytesIO(response.read())] + + return S, row_names + + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") +def test_kernel_demartino2014(data_demartino2014, quiet=True): + """Invoke test case and benchmarking for De Martino's published results + for E. coli network. Kernel-only.""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + num_reactions = 2381 + assert len(stoichiometric_list) == num_species * num_reactions, \ + "Unexpected dimension of stoichiometric matrix" + + # Expected number of metabolites per conservation law found after kernel() + expected_num_species = \ + [53] + [2] * 11 + [6] + [3] * 2 + [2] * 15 + [3] + [2] * 5 + + (kernel_dim, engaged_species, int_kernel_dim, conserved_moieties, + cls_species_idxs, cls_coefficients) = _kernel( + stoichiometric_list, num_species, num_reactions) + + if not quiet: + output(int_kernel_dim, kernel_dim, engaged_species, cls_species_idxs, + cls_coefficients, row_names) + + # There are 38 conservation laws, engaging 131 metabolites + # 36 are integers (conserved moieties), engaging 128 metabolites (from C++) + assert kernel_dim == 38, "Not all conservation laws found" + assert int_kernel_dim == 36, "Not all conserved moiety laws found" + assert engaged_species == demartino2014_kernel_engaged_species, \ + "Wrong engaged metabolites reported" + assert len(conserved_moieties) == 128, \ + "Wrong number of conserved moieties reported" + + # Assert that each conserved moiety has the correct number of metabolites + for i in range(int_kernel_dim - 2): + assert (len(cls_species_idxs[i]) == expected_num_species[i]), \ + f"Moiety #{i + 1} failed for test case (De Martino et al.)" + + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") +def test_fill_demartino2014(data_demartino2014): + """Test creation of interaction matrix""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + J, J2, fields = _fill(stoichiometric_list, + demartino2014_kernel_engaged_species, num_species) + ref_for_J = [ + [25, 27], [12, 42], [13, 43], [14, 44], [15, 41], [16, 45], + [17, 47], [18, 48], [19, 23, 49], [20, 50], [21, 51], [22, 52], + [1, 23, 30, 35], [2, 23, 29, 35], [3, 23, 35, 46], + [4, 23, 33, 35], [5, 23, 31, 35], [6, 23, 35, 37], + [7, 23, 28, 35], [8, 23, 32, 35], [9, 23, 34, 35], + [10, 23, 35, 40], [11, 23, 35, 36], + [8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 46], [23, 25], + [0, 23, 24, 35], [23], [0, 28], [18, 23, 27, 35], + [13, 23, 35, 42], [12, 23, 35, 47], [16, 23, 35, 47], + [19, 23, 35, 45], [15, 23, 35, 44], [20, 23, 35, 48], + [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 28, 29, + 30, 31, 32, 33, 34, 36, 37, 40, 46], [22, 23, 35, 49], + [17, 23, 35, 50], [23, 51], [23, 41], [21, 23, 35, 52], + [4, 39], [1, 29], [2, 46], [3, 33], [5, 32], [14, 23, 35, 43], + [6, 30, 31], [7, 34], [8, 36], [9, 37], [10, 38], [11, 40], + [54], [53], [58, 80], [57, 59, 82], [56], [55, 59, 80], + [56, 58, 82], [61], [60], [63], [62], [65], [64], [67, 68, 69], + [66, 68, 69], [66, 67, 69, 70, 71, 94, 95], + [66, 67, 68, 70, 71, 94, 95], [68, 69, 71], [68, 69, 70], [73], + [72], [75], [74], [77], [76], [79], [78], [55, 58, 81], [80], + [56, 59], [84], [83, 85, 87], [84, 86, 87], [85], [84, 85], + [89], [88], [91], [90], [93], [92], [68, 69, 95], [68, 69, 94], + [97], [96], [99], [98], [101], [100], [103], [102], [105], + [104], [107], [106], [109], [108], [111], [110], [113], [112], + [115], [114], [117], [116], [119], [118, 120], [119], [122], + [121], [124], [123], [126], [125], [128], [127], [130], [129] + ] + ref_for_J2 = [ + [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], + [-1, -1], [-1, -1], [-1, -2, -1], [-1, -1], [-1, -1], + [-1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], + [-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, 1, -1, -1, -1, -1, + -3, -6, -6, -1, -13, -7, -3, -3, -3, -5, -5], [-2, -1], + [-1, 1, -1, -2], [-1], [-1, -2], [-1, -1, -2, 1], + [-1, -1, 1, -2], [-1, -1, 1, -1], [-1, -3, 1, -2], + [-1, -6, 1, -2], [-1, -6, 1, -2], [-1, -1, 1, -2], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -13, -2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1], [-1, -7, 1, -2], [-1, -3, 1, -2], + [-3, -2], [-3, -2], [-1, -5, 1, -2], [-1, -2], [-1, -2], + [-1, -2], [-1, -2], [-1, -2], [-1, -5, 1, -2], [-1, -1, -2], + [-1, -2], [-1, -2], [-1, -2], [-1, -2], [-1, -2], [-2], [-2], + [1, -1], [-2, -1, -1], [-2], [1, -1, -1], [-1, -1, 1], [-1], + [-1], [-2], [-2], [-2], [-2], [-2, -1, 1], [-2, 1, -1], + [-1, 1, -3, -1, 1, -1, 1], [1, -1, -3, 1, -1, 1, -1], + [-1, 1, -2], [1, -1, -2], [-5], [-5], [-6], [-6], [-2], [-2], + [-1], [-1], [-1, -1, -1], [-1], [-1, 1], [-1], [-1, 1, -1], + [1, -1, -1], [-1], [-1, -1], [-1], [-1], [-1], [-1], [-2], + [-2], [-1, 1, -10], [1, -1, -10], [-1], [-1], [-1], [-1], + [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-2], [-2], + [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], + [-1, -1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], + [-1], [-1], [-1] + ] + ref_for_fields = [ + 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 51, 3, 3, 1, 3, 3, 3, 2, 5, 8, 8, 3, 15, 9, 5, + 5, 5, 7, 3, 3, 3, 3, 3, 7, 4, 3, 3, 3, 3, 3, 2, 2, 1, 3, + 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 5, 5, 6, 6, + 2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 10, + 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ] + # compare J from Python with reference from C++ + for i in range(len(ref_for_J)): + assert J[i] == ref_for_J[i], \ + f"J_{i} ({J[i]}) does not match J_{i}_ref ({ref_for_J[i]})" + assert not any(J[len(ref_for_J):]) + + # compare J2 from Python with reference from C++ + for i in range(len(ref_for_J2)): + assert J2[i] == ref_for_J2[i], \ + f"J_{i} ({J2[i]}) does not match J_{i}_ref ({ref_for_J2[i]})" + assert not any(J2[len(ref_for_J2):]) + + # compare fields from Python with reference from C++ + for i in range(len(ref_for_fields)): + assert fields[i] == ref_for_fields[i], \ + f"J_{i} ({fields[i]}) does not match J_{i}_ref ({ref_for_fields[i]})" + assert not any(fields[len(ref_for_fields):]) + + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") +def test_compute_moiety_conservation_laws_demartino2014( + data_demartino2014, quiet=False +): + """Invoke test case and benchmarking for De Martino's published results + for E. coli network""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + num_reactions = 2381 + assert len(stoichiometric_list) == num_species * num_reactions, \ + "Unexpected dimension of stoichiometric matrix" + + start = perf_counter() + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, + num_species=num_species, + num_reactions=num_reactions + ) + runtime = perf_counter() - start + if not quiet: + print(f"Execution time: {runtime} [s]") + + assert len(cls_state_idxs) == len(cls_coefficients) == 38 + return runtime + + +@pytest.mark.skipif( + os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Performance test under valgrind is not meaningful.") +@log_execution_time("Detecting moiety conservation laws", logger) +def test_cl_detect_execution_time(data_demartino2014): + """Test execution time stays within a certain predefined bound. + As the algorithm is non-deterministic, allow for some retries. + Only one has to succeed.""" + max_tries = 5 + # <5s on modern hardware, but leave some slack + max_time_seconds = 30 if "GITHUB_ACTIONS" in os.environ else 10 + + runtime = np.Inf + + for _ in range(max_tries): + runtime = test_compute_moiety_conservation_laws_demartino2014( + data_demartino2014, quiet=True) + if runtime < max_time_seconds: + break + assert runtime < max_time_seconds, "Took too long" + + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") +def test_compute_moiety_conservation_laws_simple(): + """Test a simple example, ensure the conservation laws are identified + reliably. Requires the Monte Carlo to identify all.""" + stoichiometric_matrix = sp.Matrix([ + [-1.0, 1.0], + [-1.0, 1.0], + [1.0, -1.0], + [1.0, -1.0]] + ) + stoichiometric_list = [ + float(entry) for entry in stoichiometric_matrix.T.flat() + ] + + num_tries = 1000 + found_all_n_times = 0 + for _ in range(num_tries): + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, *stoichiometric_matrix.shape) + + assert cls_state_idxs in ([[0, 3], [1, 2], [1, 3]], + [[0, 3], [1, 2], [0, 2]], + # should happen rarely + [[0, 3], [1, 2]]) + assert cls_coefficients in ([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]], + [[1.0, 1.0], [1.0, 1.0]]) + + num_cls_found = len(cls_state_idxs) + if num_cls_found == 3: + found_all_n_times += 1 + # sometimes we don't find all conservation laws, but this should be rare + assert found_all_n_times / num_tries >= 0.995 diff --git a/python/tests/test_parameter_mapping.py b/python/tests/test_parameter_mapping.py index 65f48d146b..73f72eef8e 100644 --- a/python/tests/test_parameter_mapping.py +++ b/python/tests/test_parameter_mapping.py @@ -1,9 +1,14 @@ """Test for ``amici.parameter_mapping``""" +import os -from amici.parameter_mapping import ( - ParameterMappingForCondition, ParameterMapping) +import pytest +from amici.parameter_mapping import (ParameterMapping, + ParameterMappingForCondition) + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_parameter_mapping_for_condition_default_args(): """Check we can initialize the mapping with default arguments.""" @@ -32,6 +37,8 @@ def test_parameter_mapping_for_condition_default_args(): expected_scale_map_sim_fix +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_parameter_mapping(): """Test :class:``amici.parameter_mapping.ParameterMapping``.""" diff --git a/python/tests/test_pregenerated_models.py b/python/tests/test_pregenerated_models.py index f746ea4d6b..77d91714c3 100755 --- a/python/tests/test_pregenerated_models.py +++ b/python/tests/test_pregenerated_models.py @@ -22,11 +22,13 @@ for case in list(expected_results[sub_test].keys())] +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") @pytest.mark.skipif(os.environ.get('AMICI_SKIP_CMAKE_TESTS', '') == 'TRUE', reason='skipping cmake based test') @pytest.mark.parametrize("sub_test,case", model_cases) def test_pregenerated_model(sub_test, case): - """Tests models that were pregenerated using the the matlab code + """Tests models that were pregenerated using the matlab code generation routines and cmake build routines. NOTE: requires having run `make python-tests` in /build/ before to build diff --git a/python/tests/test_pysb.py b/python/tests/test_pysb.py index e5559f8c9c..0fd050b596 100644 --- a/python/tests/test_pysb.py +++ b/python/tests/test_pysb.py @@ -3,7 +3,6 @@ import importlib import logging import os -import platform import shutil import pytest @@ -21,6 +20,8 @@ from amici.gradient_check import check_derivatives +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") def test_compare_to_sbml_import(pysb_example_presimulation_module, sbml_example_presimulation_module): # -------------- PYSB ----------------- @@ -93,13 +94,15 @@ def test_compare_to_sbml_import(pysb_example_presimulation_module, 'bngwiki_enzymatic_cycle_mm', 'bngwiki_simple', 'earm_1_0', 'earm_1_3', 'move_connected', 'michment', 'kinase_cascade', 'hello_pysb', 'fricker_2010_apoptosis', 'explicit', - 'fixed_initial', + 'fixed_initial', 'localfunc' ] custom_models = [ 'bngwiki_egfr_simple_deletemolecules', ] +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") @pytest.mark.parametrize('example', pysb_models + custom_models) def test_compare_to_pysb_simulation(example): @@ -109,12 +112,6 @@ def test_compare_to_pysb_simulation(example): with amici.add_path(os.path.dirname(pysb.examples.__file__)): with amici.add_path(os.path.join(os.path.dirname(__file__), '..', 'tests', 'pysb_test_models')): - - if example == 'earm_1_3' \ - and platform.sys.version_info[0] == 3 \ - and platform.sys.version_info[1] < 7: - return - # load example pysb.SelfExporter.cleanup() # reset pysb pysb.SelfExporter.do_export = True diff --git a/python/tests/test_sbml_import.py b/python/tests/test_sbml_import.py index ea624e51eb..4637e149ad 100644 --- a/python/tests/test_sbml_import.py +++ b/python/tests/test_sbml_import.py @@ -54,6 +54,25 @@ def test_sbml2amici_no_observables(simple_sbml_model): assert hasattr(module_module, 'getModel') +def test_sbml2amici_nested_observables_fail(simple_sbml_model): + """Test model generation works for model without observables""" + sbml_doc, sbml_model = simple_sbml_model + sbml_importer = SbmlImporter(sbml_source=sbml_model, + from_file=False) + + with TemporaryDirectory() as tmpdir: + with pytest.raises(ValueError, match="(?i)nested"): + sbml_importer.sbml2amici( + model_name="test", + output_dir=tmpdir, + observables={'outer': {'formula': 'inner'}, + 'inner': {'formula': 'S1'}}, + compute_conservation_laws=False, + generate_sensitivity_code=False, + compile=False, + ) + + def test_nosensi(simple_sbml_model): sbml_doc, sbml_model = simple_sbml_model sbml_importer = SbmlImporter(sbml_source=sbml_model, @@ -78,6 +97,61 @@ def test_nosensi(simple_sbml_model): assert rdata.status == amici.AMICI_ERROR +@pytest.fixture +def observable_dependent_error_model(simple_sbml_model): + sbml_doc, sbml_model = simple_sbml_model + # add parameter and rate rule + sbml_model.getSpecies("S1").setInitialConcentration(1.0) + sbml_model.getParameter("p1").setValue(0.2) + rr = sbml_model.createRateRule() + rr.setVariable("S1") + rr.setMath(libsbml.parseL3Formula("p1")) + relative_sigma = sbml_model.createParameter() + relative_sigma.setId('relative_sigma') + relative_sigma.setValue(0.05) + + sbml_importer = SbmlImporter(sbml_source=sbml_model, + from_file=False) + + with TemporaryDirectory() as tmpdir: + sbml_importer.sbml2amici( + model_name="test", + output_dir=tmpdir, + observables={'observable_s1': {'formula': 'S1'}, + 'observable_s1_scaled': {'formula': '0.5 * S1'}}, + sigmas={'observable_s1': '0.1 + relative_sigma * observable_s1', + 'observable_s1_scaled': '0.02 * observable_s1_scaled'}, + ) + yield amici.import_model_module(module_name='test', + module_path=tmpdir) + + +def test_sbml2amici_observable_dependent_error(observable_dependent_error_model): + """Check gradients for model with observable-dependent error""" + model_module = observable_dependent_error_model + model = model_module.getModel() + model.setTimepoints(np.linspace(0, 60, 61)) + solver = model.getSolver() + + # generate artificial data + rdata = amici.runAmiciSimulation(model, solver) + assert np.allclose(rdata.sigmay[:, 0], 0.1 + 0.05 * rdata.y[:, 0]) + assert np.allclose(rdata.sigmay[:, 1], 0.02 * rdata.y[:, 1]) + edata = amici.ExpData(rdata, 1.0, 0.0) + edata.setObservedDataStdDev(np.nan) + + # check sensitivities + solver.setSensitivityOrder(amici.SensitivityOrder.first) + # FSA + solver.setSensitivityMethod(amici.SensitivityMethod.forward) + rdata = amici.runAmiciSimulation(model, solver, edata) + assert np.any(rdata.ssigmay != 0.0) + check_derivatives(model, solver, edata) + # ASA + solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) + check_derivatives(model, solver, edata) + + @pytest.fixture def model_steadystate_module(): sbml_file = os.path.join(os.path.dirname(__file__), '..', diff --git a/python/tests/test_swig_interface.py b/python/tests/test_swig_interface.py index 2958539b46..63b0ae0aff 100644 --- a/python/tests/test_swig_interface.py +++ b/python/tests/test_swig_interface.py @@ -129,18 +129,20 @@ def test_model_instance_settings(pysb_example_presimulation_module): i_setter = 1 # All settings are tested. - assert set(model_instance_settings0) == set(amici.model_instance_settings) + assert set(model_instance_settings0) \ + == set(amici.swig_wrappers.model_instance_settings) # Skip settings with interdependencies. model_instance_settings = \ {k: v for k, v in model_instance_settings0.items() if v is not None} # All custom values are different to default values. - assert all([ + assert all( default != custom for name, (default, custom) in model_instance_settings.items() if name != 'ReinitializeFixedParameterInitialStates' - ]) + ) + # All default values are as expected. for name, (default, custom) in model_instance_settings.items(): @@ -173,11 +175,11 @@ def test_model_instance_settings(pysb_example_presimulation_module): if model_instance_settings0[name] is not None } amici.set_model_settings(model, custom_settings_not_none) - assert all([ + assert all( value == custom_settings_not_none[name] for name, value in amici.get_model_settings(model).items() if name in custom_settings_not_none - ]) + ) def test_interdependent_settings(pysb_example_presimulation_module): @@ -299,10 +301,10 @@ def test_unhandled_settings(pysb_example_presimulation_module): 'setParametersByNameRegex', 'setUnscaledInitialStateSensitivities', ] - + from amici.swig_wrappers import model_instance_settings handled = [ name - for names in amici.model_instance_settings + for names in model_instance_settings for name in ( names if isinstance(names, tuple) else diff --git a/scripts/run-valgrind-cpp.sh b/scripts/run-valgrind-cpp.sh index 7d868d98ef..fd08cbda54 100755 --- a/scripts/run-valgrind-cpp.sh +++ b/scripts/run-valgrind-cpp.sh @@ -8,12 +8,6 @@ AMICI_PATH=$(cd "$SCRIPT_PATH/.." && pwd) set -eou pipefail # run tests -cd "${AMICI_PATH}/build/tests/cpp/" - +cd "${AMICI_PATH}/build/" VALGRIND_OPTS="--leak-check=full --error-exitcode=1 --trace-children=yes --show-leak-kinds=definite" -set -x -for MODEL in $(ctest -N | grep "Test[ ]*#" | grep -v unittests | sed --regexp-extended 's/ *Test[ ]*#[0-9]+: model_(.*)_test/\1/') - do cd "${AMICI_PATH}/build/tests/cpp/${MODEL}/" && valgrind ${VALGRIND_OPTS} "./model_${MODEL}_test" -done -cd "${AMICI_PATH}/build/tests/cpp/unittests/" -valgrind ${VALGRIND_OPTS} ./unittests +valgrind ${VALGRIND_OPTS} ctest diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index f866eb7dbe..a610023bd1 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -79,6 +79,7 @@ AbstractModel::fstau(realtype* /*stau*/, const realtype* /*p*/, const realtype* /*k*/, const realtype* /*h*/, + const realtype* /*tcl*/, const realtype* /*sx*/, const int /*ip*/, const int /*ie*/) @@ -118,6 +119,17 @@ AbstractModel::fdydp(realtype* /*dydp*/, __func__); } +void AbstractModel::fdydp(realtype */*dydp*/, const realtype /*t*/, + const realtype */*x*/, const realtype */*p*/, + const realtype */*k*/, const realtype */*h*/, + int /*ip*/, const realtype */*w*/, + const realtype */*tcl*/, const realtype */*dtcldp*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fdydx(realtype* /*dydx*/, const realtype /*t*/, @@ -280,7 +292,8 @@ AbstractModel::fdeltasx(realtype* /*deltasx*/, const realtype* /*xdot*/, const realtype* /*xdot_old*/, const realtype* /*sx*/, - const realtype* /*stau*/) + const realtype* /*stau*/, + const realtype* /*tcl*/) { throw AmiException("Requested functionality is not supported as %s is " "not implemented for this model!", @@ -326,7 +339,8 @@ void AbstractModel::fsigmay(realtype* /*sigmay*/, const realtype /*t*/, const realtype* /*p*/, - const realtype* /*k*/) + const realtype* /*k*/, + const realtype */*y*/) { throw AmiException("Requested functionality is not supported as %s is " "not implemented for this model!", @@ -338,6 +352,7 @@ AbstractModel::fdsigmaydp(realtype* /*dsigmaydp*/, const realtype /*t*/, const realtype* /*p*/, const realtype* /*k*/, + const realtype */*y*/, const int /*ip*/) { throw AmiException("Requested functionality is not supported as %s is " @@ -345,6 +360,18 @@ AbstractModel::fdsigmaydp(realtype* /*dsigmaydp*/, __func__); } +void +AbstractModel::fdsigmaydy(realtype */*dsigmaydy*/, + const realtype /*t*/, + const realtype */*p*/, + const realtype */*k*/, + const realtype */*y*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fsigmaz(realtype* /*sigmaz*/, const realtype /*t*/, @@ -627,4 +654,97 @@ void AbstractModel::fdwdw_rowvals(SUNMatrixWrapper &/*dwdw*/) { __func__); } +void AbstractModel::fdx_rdatadx_solver(realtype */*dx_rdatadx_solver*/, + const realtype */*x*/, const realtype */*tcl*/, + const realtype */*p*/, const realtype */*k*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadx_solver_rowvals(SUNMatrixWrapper &/*dxrdxs*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadx_solver_colptrs(SUNMatrixWrapper &/*dxrdxs*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadp(realtype */*dx_rdatadp*/, const realtype */*x*/, + const realtype */*tcl*/, const realtype */*p*/, + const realtype */*k*/, const int /*ip*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadtcl(realtype */*dx_rdatadtcl*/, const realtype */*x*/, + const realtype */*tcl*/, const realtype */*p*/, + const realtype */*k*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadtcl_rowvals(SUNMatrixWrapper &/*dxrdtcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadtcl_colptrs(SUNMatrixWrapper &/*dxrdtcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldp(realtype */*dtotal_cldp*/, + const realtype */*x_rdata*/, + const realtype */*p*/, + const realtype */*k*/, + const int /*ip*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldx_rdata(realtype */*dtotal_cldx_rdata*/, + const realtype */*x_rdata*/, + const realtype */*p*/, + const realtype */*k*/, + const realtype */*tcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldx_rdata_colptrs( + SUNMatrixWrapper &/*dtotal_cldx_rdata*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldx_rdata_rowvals( + SUNMatrixWrapper &/*dtotal_cldx_rdata*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + } // namespace amici diff --git a/src/model.cpp b/src/model.cpp index 2e1a557992..f195bbd80a 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -234,7 +234,9 @@ void Model::initializeStates(AmiVector &x) { fx0(x); } else { std::vector x0_solver(nx_solver, 0.0); - ftotal_cl(state_.total_cl.data(), x0data_.data()); + ftotal_cl(state_.total_cl.data(), x0data_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); fx_solver(x0_solver.data(), x0data_.data()); std::copy(x0_solver.cbegin(), x0_solver.cend(), x.data()); } @@ -250,7 +252,11 @@ void Model::initializeStateSensitivities(AmiVectorArray &sx, for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fstotal_cl(stcl, &sx0data_.at(ip * nx_rdata), plist(ip)); + fstotal_cl(stcl, &sx0data_.at(ip * nx_rdata), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); fsx_solver(sx0_solver_slice.data(), &sx0data_.at(ip * nx_rdata)); for (int ix = 0; ix < nx_solver; ix++) { sx.at(ix, ip) = sx0_solver_slice.at(ix); @@ -843,9 +849,29 @@ void Model::getObservableSigma(gsl::span sigmay, const int it, } void Model::getObservableSigmaSensitivity(gsl::span ssigmay, + gsl::span sy, const int it, const ExpData *edata) { fdsigmaydp(it, edata); writeSlice(derived_state_.dsigmaydp_, ssigmay); + + if(pythonGenerated) { + // ssigmay = dsigmaydy*(dydx_solver*sx+dydp)+dsigmaydp + // = dsigmaydy*sy+dsigmaydp + + fdsigmaydy(it, edata); + + // compute ssigmay = 1.0 * dsigmaydp + 1.0 * dsigmaydy * sy + // dsigmaydp C[ny,nplist] += dsigmaydy A[ny,ny] * sy B[ny,nplist] + // M N M K K N + // ldc lda ldb + amici_dgemm(BLASLayout::colMajor, BLASTranspose::noTrans, + BLASTranspose::noTrans, ny, nplist(), ny, 1.0, + derived_state_.dsigmaydy_.data(), ny, + sy.data(), ny, 1.0, ssigmay.data(), ny); + } + + if (always_check_finite_) + checkFinite(ssigmay, "ssigmay"); } void Model::addObservableObjective(realtype &Jy, const int it, @@ -1076,7 +1102,7 @@ void Model::getEventTimeSensitivity(std::vector &stau, for (int ip = 0; ip < nplist(); ip++) { fstau(&stau.at(ip), t, computeX_pos(x), state_.unscaledParameters.data(), state_.fixedParameters.data(), - state_.h.data(), sx.data(ip), + state_.h.data(), state_.total_cl.data(), sx.data(ip), plist(ip), ie); } } @@ -1084,9 +1110,9 @@ void Model::getEventTimeSensitivity(std::vector &stau, void Model::addStateEventUpdate(AmiVector &x, const int ie, const realtype t, const AmiVector &xdot, const AmiVector &xdot_old) { - + derived_state_.deltax_.assign(nx_solver, 0.0); - + std::copy_n(computeX_pos(x), nx_solver, x.data()); // compute update @@ -1120,7 +1146,8 @@ void Model::addStateSensitivityEventUpdate(AmiVectorArray &sx, const int ie, state_.unscaledParameters.data(), state_.fixedParameters.data(), state_.h.data(), derived_state_.w_.data(), plist(ip), ie, - xdot.data(), xdot_old.data(), sx.data(ip), &stau.at(ip)); + xdot.data(), xdot_old.data(), sx.data(ip), &stau.at(ip), + state_.total_cl.data()); if (always_check_finite_) { app->checkFinite(derived_state_.deltasx_, "deltasx"); @@ -1214,7 +1241,9 @@ void Model::fx0(AmiVector &x) { state_.unscaledParameters.data(), state_.fixedParameters.data()); fx_solver(x.data(), derived_state_.x_rdata_.data()); - ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data()); + ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); if (always_check_finite_) { checkFinite(derived_state_.x_rdata_, "x0 x_rdata"); @@ -1225,13 +1254,14 @@ void Model::fx0(AmiVector &x) { void Model::fx0_fixedParameters(AmiVector &x) { if (!getReinitializeFixedParameterInitialStates()) return; - + /* we transform to the unreduced states x_rdata and then apply x0_fixedparameters to (i) enable updates to states that were removed from conservation laws and (ii) be able to correctly compute total abundances after updating the state variables */ fx_rdata(derived_state_.x_rdata_.data(), computeX_pos(x), - state_.total_cl.data()); + state_.total_cl.data(), state_.unscaledParameters.data(), + state_.fixedParameters.data()); fx0_fixedParameters(derived_state_.x_rdata_.data(), simulation_parameters_.tstart_, state_.unscaledParameters.data(), @@ -1240,7 +1270,9 @@ void Model::fx0_fixedParameters(AmiVector &x) { ); fx_solver(x.data(), derived_state_.x_rdata_.data()); /* update total abundances */ - ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data()); + ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); } void Model::fsx0(AmiVectorArray &sx, const AmiVector &x) { @@ -1255,7 +1287,11 @@ void Model::fsx0(AmiVectorArray &sx, const AmiVector &x) { computeX_pos(x), state_.unscaledParameters.data(), state_.fixedParameters.data(), plist(ip)); fsx_solver(sx.data(ip), derived_state_.sx_rdata_.data()); - fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip)); + fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); } } @@ -1266,7 +1302,11 @@ void Model::fsx0_fixedParameters(AmiVectorArray &sx, const AmiVector &x) { for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fsx_rdata(derived_state_.sx_rdata_.data(), sx.data(ip), stcl, plist(ip)); + fsx_rdata(derived_state_.sx_rdata_.data(), sx.data(ip), stcl, + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + x.data(), state_.total_cl.data(), + plist(ip)); fsx0_fixedParameters(derived_state_.sx_rdata_.data(), simulation_parameters_.tstart_, computeX_pos(x), @@ -1275,24 +1315,33 @@ void Model::fsx0_fixedParameters(AmiVectorArray &sx, const AmiVector &x) { plist(ip), simulation_parameters_.reinitialization_state_idxs_sim); fsx_solver(sx.data(ip), derived_state_.sx_rdata_.data()); - fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip)); + fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); } } void Model::fsdx0() {} void Model::fx_rdata(AmiVector &x_rdata, const AmiVector &x) { - fx_rdata(x_rdata.data(), computeX_pos(x), state_.total_cl.data()); + fx_rdata(x_rdata.data(), computeX_pos(x), state_.total_cl.data(), + state_.unscaledParameters.data(), state_.fixedParameters.data()); if (always_check_finite_) checkFinite(x_rdata.getVector(), "x_rdata"); } -void Model::fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx) { +void Model::fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx, + AmiVector const& x_solver) { realtype *stcl = nullptr; for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fsx_rdata(sx_rdata.data(ip), sx.data(ip), stcl, ip); + fsx_rdata(sx_rdata.data(ip), sx.data(ip), stcl, + state_.unscaledParameters.data(), + state_.fixedParameters.data(), x_solver.data(), + state_.total_cl.data(), plist(ip)); } } @@ -1347,7 +1396,7 @@ void Model::initializeVectors() { void Model::fy(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.y_.assign(ny, 0.0); @@ -1365,7 +1414,7 @@ void Model::fy(const realtype t, const AmiVector &x) { void Model::fdydp(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.dydp_.assign(ny * nplist(), 0.0); @@ -1378,7 +1427,8 @@ void Model::fdydp(const realtype t, const AmiVector &x) { fdydp(&derived_state_.dydp_.at(ip * ny), t, x_pos, state_.unscaledParameters.data(), state_.fixedParameters.data(), state_.h.data(), plist(ip), - derived_state_.w_.data(), state_.stotal_cl.data()); + derived_state_.w_.data(), state_.total_cl.data(), + state_.stotal_cl.data()); } else { fdydp(&derived_state_.dydp_.at(ip * ny), t, x_pos, state_.unscaledParameters.data(), @@ -1394,7 +1444,7 @@ void Model::fdydp(const realtype t, const AmiVector &x) { void Model::fdydx(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.dydx_.assign(ny * nx_solver, 0.0); @@ -1417,8 +1467,11 @@ void Model::fsigmay(const int it, const ExpData *edata) { derived_state_.sigmay_.assign(ny, 0.0); - fsigmay(derived_state_.sigmay_.data(), getTimepoint(it), state_.unscaledParameters.data(), - state_.fixedParameters.data()); + fsigmay(derived_state_.sigmay_.data(), + getTimepoint(it), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + derived_state_.y_.data()); if (edata) { auto sigmay_edata = edata->getObservedDataStdDevPtr(it); @@ -1451,6 +1504,7 @@ void Model::fdsigmaydp(const int it, const ExpData *edata) { fdsigmaydp(&derived_state_.dsigmaydp_.at(ip * ny), getTimepoint(it), state_.unscaledParameters.data(), state_.fixedParameters.data(), + derived_state_.y_.data(), plist(ip)); // sigmas in edata override model-sigma -> for those sigmas, set dsigmaydp @@ -1470,6 +1524,36 @@ void Model::fdsigmaydp(const int it, const ExpData *edata) { } } +void Model::fdsigmaydy(const int it, const ExpData *edata) { + if (!ny) + return; + + derived_state_.dsigmaydy_.assign(ny * ny, 0.0); + + // get dsigmaydy slice (ny) for current timepoint + fdsigmaydy(derived_state_.dsigmaydy_.data(), getTimepoint(it), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + derived_state_.y_.data()); + + // sigmas in edata override model-sigma -> for those sigmas, set dsigmaydy + // to zero + if (edata) { + for (int isigmay = 0; isigmay < nytrue; ++isigmay) { + if (!edata->isSetObservedDataStdDev(it, isigmay)) + continue; + for (int iy = 0; iy < nytrue; ++iy) { + derived_state_.dsigmaydy_.at(isigmay * ny + iy) = 0.0; + } + } + } + + if (always_check_finite_) { + app->checkFinite(derived_state_.dsigmaydy_, "dsigmaydy"); + } +} + + void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { if (!ny) return; @@ -1478,6 +1562,10 @@ void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { fsigmay(it, &edata); if (pythonGenerated) { + fdJydsigma(it, x, edata); + fdsigmaydy(it, &edata); + SUNMatrixWrapper tmp_dense(nJ, ny); + for (int iyt = 0; iyt < nytrue; iyt++) { if (!derived_state_.dJydy_.at(iyt).capacity()) continue; @@ -1494,6 +1582,25 @@ void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { derived_state_.sigmay_.data(), edata.getObservedDataPtr(it)); + // dJydy += dJydsigma * dsigmaydy + // C(nJ,ny) A(nJ,ny) * B(ny,ny) + // sparse dense dense + tmp_dense.zero(); + amici_dgemm(BLASLayout::colMajor, BLASTranspose::noTrans, + BLASTranspose::noTrans, nJ, ny, ny, 1.0, + &derived_state_.dJydsigma_.at(iyt * nJ * ny), nJ, + derived_state_.dsigmaydy_.data(), ny, 1.0, + tmp_dense.data(), nJ); + + auto tmp_sparse = SUNMatrixWrapper(tmp_dense, 0.0, CSC_MAT); + auto ret = SUNMatScaleAdd(1.0, derived_state_.dJydy_.at(iyt).get(), + tmp_sparse.get()); + if(ret != SUNMAT_SUCCESS) { + throw AmiException("SUNMatScaleAdd failed with status %d in %s", + ret, __func__); + } + derived_state_.dJydy_.at(iyt).refresh(); + if (always_check_finite_) { app->checkFinite( gsl::make_span(derived_state_.dJydy_.at(iyt).get()), @@ -1547,7 +1654,6 @@ void Model::fdJydp(const int it, const AmiVector &x, const ExpData &edata) { // dJydy nJ, nytrue x ny // dydp nplist * ny // dJydp nplist x nJ - // dJydsigma if (!ny) return; @@ -2067,7 +2173,8 @@ void Model::fdwdw(const realtype t, const realtype *x) { } void Model::fx_rdata(realtype *x_rdata, const realtype *x_solver, - const realtype * /*tcl*/) { + const realtype * /*tcl*/, const realtype */*p*/, + const realtype */*k*/) { if (nx_solver != nx_rdata) throw AmiException( "A model that has differing nx_solver and nx_rdata needs " @@ -2076,8 +2183,43 @@ void Model::fx_rdata(realtype *x_rdata, const realtype *x_solver, } void Model::fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, - const realtype *stcl, const int /*ip*/) { - fx_rdata(sx_rdata, sx_solver, stcl); + const realtype *stcl, const realtype *p, + const realtype *k, const realtype *x_solver, + const realtype *tcl, + const int ip) { + if (nx_solver == nx_rdata) { + std::copy_n(sx_solver, nx_solver, sx_rdata); + return; + } + + // sx_rdata = dx_rdata/dx_solver * sx_solver + // + dx_rdata/d_tcl * stcl + dxrdata/dp + + // 1) sx_rdata(nx_rdata, 1) = dx_rdatadp + std::fill_n(sx_rdata, nx_rdata, 0.0); + fdx_rdatadp(sx_rdata, x_solver, tcl, p, k, ip); + + + // the following could be moved to the calling function, as it's independent + // of `ip` + + // 2) sx_rdata(nx_rdata, 1) += + // dx_rdata/dx_solver(nx_rdata,nx_solver) * sx_solver(nx_solver, 1) + derived_state_.dx_rdatadx_solver.zero(); + fdx_rdatadx_solver(derived_state_.dx_rdatadx_solver.data(), + x_solver, tcl, p, k); + fdx_rdatadx_solver_colptrs(derived_state_.dx_rdatadx_solver); + fdx_rdatadx_solver_rowvals(derived_state_.dx_rdatadx_solver); + derived_state_.dx_rdatadx_solver.multiply(gsl::make_span(sx_rdata, nx_rdata), + gsl::make_span(sx_solver, nx_solver)); + + // 3) sx_rdata(nx_rdata, 1) += dx_rdata/d_tcl(nx_rdata,ntcl) * stcl + derived_state_.dx_rdatadtcl.zero(); + fdx_rdatadtcl(derived_state_.dx_rdatadtcl.data(), x_solver, tcl, p, k); + fdx_rdatadtcl_colptrs(derived_state_.dx_rdatadtcl); + fdx_rdatadtcl_rowvals(derived_state_.dx_rdatadtcl); + derived_state_.dx_rdatadtcl.multiply(gsl::make_span(sx_rdata, nx_rdata), + gsl::make_span(stcl, (nx_rdata - nx_solver))); } void Model::fx_solver(realtype *x_solver, const realtype *x_rdata) { @@ -2095,7 +2237,8 @@ void Model::fsx_solver(realtype *sx_solver, const realtype *sx_rdata) { fx_solver(sx_solver, sx_rdata); } -void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/) { +void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/, + const realtype */*p*/, const realtype */*k*/) { if (nx_solver != nx_rdata) throw AmiException( "A model that has differing nx_solver and nx_rdata needs " @@ -2103,11 +2246,30 @@ void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/) { } void Model::fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, - const int /*ip*/) { - /* for the moment we do not need an implementation of fstotal_cl as - * we can simply reuse ftotal_cl and replace states by their - * sensitivities */ - ftotal_cl(stotal_cl, sx_rdata); + const int ip, const realtype *x_rdata, + const realtype *p, const realtype *k, + const realtype *tcl) { + if (nx_solver == nx_rdata) + return; + + // stotal_cl(ncl,1) = + // dtotal_cl/dp(ncl,1) + // + dtotal_cl/dx_rdata(ncl,nx_rdata) * sx_rdata(nx_rdata,1) + + // 1) stotal_cl = dtotal_cl/dp + std::fill_n(stotal_cl, ncl(), 0.0); + fdtotal_cldp(stotal_cl, x_rdata, p, k, ip); + + + // 2) stotal_cl += dtotal_cl/dx_rdata(ncl,nx_rdata) * sx_rdata(nx_rdata,1) + derived_state_.dtotal_cldx_rdata.zero(); + fdtotal_cldx_rdata(derived_state_.dtotal_cldx_rdata.data(), + x_rdata, tcl, p, k); + fdtotal_cldx_rdata_colptrs(derived_state_.dtotal_cldx_rdata); + fdtotal_cldx_rdata_rowvals(derived_state_.dtotal_cldx_rdata); + derived_state_.dtotal_cldx_rdata.multiply( + gsl::make_span(stotal_cl, ncl()), + gsl::make_span(sx_rdata, nx_rdata)); } const_N_Vector Model::computeX_pos(const_N_Vector x) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index 96bfcbad50..27e664bd8f 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -56,6 +56,7 @@ TPL_DYDX_DEF TPL_DYDP_DEF TPL_SIGMAY_DEF TPL_DSIGMAYDP_DEF +TPL_DSIGMAYDY_DEF TPL_W_DEF TPL_X0_DEF TPL_X0_FIXEDPARAMETERS_DEF @@ -69,7 +70,17 @@ TPL_DELTASX_DEF TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF - +TPL_DX_RDATADX_SOLVER_DEF +TPL_DX_RDATADX_SOLVER_COLPTRS_DEF +TPL_DX_RDATADX_SOLVER_ROWVALS_DEF +TPL_DX_RDATADP_DEF +TPL_DX_RDATADTCL_DEF +TPL_DX_RDATADTCL_COLPTRS_DEF +TPL_DX_RDATADTCL_ROWVALS_DEF +TPL_DTOTAL_CLDP_DEF +TPL_DTOTAL_CLDX_RDATA_DEF +TPL_DTOTAL_CLDX_RDATA_COLPTRS_DEF +TPL_DTOTAL_CLDX_RDATA_ROWVALS_DEF /** * @brief AMICI-generated model subclass. */ @@ -100,6 +111,9 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_NDWDW, // ndwdw TPL_NDXDOTDW, // ndxdotdw TPL_NDJYDY, // ndjydy + TPL_NDXRDATADXSOLVER, // ndxrdatadxsolver + TPL_NDXRDATADTCL, // ndxrdatadtcl + TPL_NDTOTALCLDXRDATA, // ndtotal_cldx_rdata 0, // nnz TPL_UBW, // ubw TPL_LBW // lbw @@ -291,6 +305,8 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_DSIGMAYDP_IMPL + TPL_DSIGMAYDY_IMPL + /** * @brief model specific implementation of fsigmaz * @param dsigmazdp partial derivative of standard deviation of event @@ -464,6 +480,22 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_TOTAL_CL_IMPL + TPL_DX_RDATADX_SOLVER_IMPL + TPL_DX_RDATADX_SOLVER_COLPTRS_IMPL + TPL_DX_RDATADX_SOLVER_ROWVALS_IMPL + + TPL_DX_RDATADP_IMPL + + TPL_DX_RDATADTCL_IMPL + TPL_DX_RDATADTCL_COLPTRS_IMPL + TPL_DX_RDATADTCL_ROWVALS_IMPL + + TPL_DTOTAL_CLDP_IMPL + + TPL_DTOTAL_CLDX_RDATA_IMPL + TPL_DTOTAL_CLDX_RDATA_COLPTRS_IMPL + TPL_DTOTAL_CLDX_RDATA_ROWVALS_IMPL + std::string getName() const override { return "TPL_MODELNAME"; } diff --git a/src/model_ode.cpp b/src/model_ode.cpp index bd6e465e71..02905ef2c0 100644 --- a/src/model_ode.cpp +++ b/src/model_ode.cpp @@ -83,7 +83,7 @@ void Model_ODE::froot(realtype t, const_N_Vector x, gsl::span root) { std::fill(root.begin(), root.end(), 0.0); froot(root.data(), t, N_VGetArrayPointerConst(x_pos), state_.unscaledParameters.data(), state_.fixedParameters.data(), - state_.h.data()); + state_.h.data(), state_.total_cl.data()); } void Model_ODE::fxdot(const realtype t, const AmiVector &x, @@ -204,7 +204,8 @@ void Model_ODE::fJSparse_rowvals(SUNMatrixWrapper &/*JSparse*/) { void Model_ODE::froot(realtype * /*root*/, const realtype /*t*/, const realtype * /*x*/, const realtype * /*p*/, - const realtype * /*k*/, const realtype * /*h*/) { + const realtype * /*k*/, const realtype * /*h*/, + const realtype */*tcl*/) { throw AmiException("Requested functionality is not supported as %s is not " "implemented for this model!", __func__); // not implemented diff --git a/src/model_state.cpp b/src/model_state.cpp index 913912ae7f..6bad8db959 100644 --- a/src/model_state.cpp +++ b/src/model_state.cpp @@ -6,6 +6,12 @@ ModelStateDerived::ModelStateDerived(const ModelDimensions &dim) : J_(dim.nx_solver, dim.nx_solver, dim.nnz, CSC_MAT), JB_(dim.nx_solver, dim.nx_solver, dim.nnz, CSC_MAT), dxdotdw_(dim.nx_solver, dim.nw, dim.ndxdotdw, CSC_MAT), + dx_rdatadx_solver(dim.nx_rdata, dim.nx_solver, dim.ndxrdatadxsolver, + CSC_MAT), + dx_rdatadtcl(dim.nx_rdata, dim.nx_rdata - dim.nx_solver, dim.ndxrdatadtcl, + CSC_MAT), + dtotal_cldx_rdata(dim.nx_rdata - dim.nx_solver, dim.nx_rdata, + dim.ndtotal_cldx_rdata, CSC_MAT), w_(dim.nw), x_rdata_(dim.nx_rdata, 0.0), sx_rdata_(dim.nx_rdata, 0.0), diff --git a/src/rdata.cpp b/src/rdata.cpp index d0fe49067b..00b08e7353 100644 --- a/src/rdata.cpp +++ b/src/rdata.cpp @@ -142,7 +142,6 @@ void ReturnData::initializeFullReporting(bool quadratic_llh) { srz.resize(nmaxevent * nz * nplist, 0.0); } - ssigmay.resize(nt * ny * nplist, 0.0); ssigmaz.resize(nmaxevent * nz * nplist, 0.0); if (sensi >= SensitivityOrder::second && sensi_meth == SensitivityMethod::forward) @@ -193,7 +192,7 @@ void ReturnData::processPreEquilibration(SteadystateProblem const &preeq, writeSlice(x_rdata_, x_ss); } if (!sx_ss.empty() && sensi >= SensitivityOrder::first) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) writeSlice(sx_rdata_[ip], slice(sx_ss, ip, nx)); } @@ -254,7 +253,7 @@ void ReturnData::processForwardProblem(ForwardProblem const &fwd, Model &model, } if (!sx0.empty()) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) writeSlice(sx_rdata_[ip], slice(sx0, ip, nx)); } @@ -303,22 +302,23 @@ void ReturnData::getDataOutput(int it, Model &model, ExpData const *edata) { if (sensi >= SensitivityOrder::first && nplist > 0) { - if (!ssigmay.empty()) - model.getObservableSigmaSensitivity(slice(ssigmay, it, nplist * ny), - it, edata); - if (sensi_meth == SensitivityMethod::forward) { getDataSensisFSA(it, model, edata); } else if (edata && !sllh.empty()) { model.addPartialObservableObjectiveSensitivity( sllh, s2llh, it, x_solver_, *edata); } + + if (!ssigmay.empty()) + model.getObservableSigmaSensitivity(slice(ssigmay, it, nplist * ny), + slice(sy, it, nplist * ny), + it, edata); } } void ReturnData::getDataSensisFSA(int it, Model &model, ExpData const *edata) { if (!sx.empty()) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) { writeSlice(sx_rdata_[ip], slice(sx, it * nplist + ip, nx)); @@ -866,7 +866,7 @@ void ReturnData::fsres(const int it, Model &model, const ExpData &edata) { std::vector sigmay_it(ny, 0.0); model.getObservableSigma(sigmay_it, it, &edata); std::vector ssigmay_it(ny * nplist, 0.0); - model.getObservableSigmaSensitivity(ssigmay_it, it, &edata); + model.getObservableSigmaSensitivity(ssigmay_it, sy_it, it, &edata); auto observedData = edata.getObservedDataPtr(it); for (int iy = 0; iy < nytrue; ++iy) { @@ -904,7 +904,7 @@ void ReturnData::fFIM(int it, Model &model, const ExpData &edata) { std::vector sigmay_it(ny, 0.0); model.getObservableSigma(sigmay_it, it, &edata); std::vector ssigmay_it(ny * nplist, 0.0); - model.getObservableSigmaSensitivity(ssigmay_it, it, &edata); + model.getObservableSigmaSensitivity(ssigmay_it, sy_it, it, &edata); /* * https://www.wolframalpha.com/input/?i=d%2Fdu+d%2Fdv+log%28s%28u%2Cv%29%29+%2B+0.5+*+%28r%28u%2Cv%29%2Fs%28u%2Cv%29%29%5E2 diff --git a/src/returndata_matlab.cpp b/src/returndata_matlab.cpp index 0a1d79961a..739d23cfaf 100644 --- a/src/returndata_matlab.cpp +++ b/src/returndata_matlab.cpp @@ -82,7 +82,7 @@ mxArray *initMatlabReturnFields(ReturnData const *rdata) { } } - if (rdata->ny > 0) { + if (!rdata->ssigmay.empty()) { writeMatlabField3(matlabSolutionStruct, "ssigmay", rdata->ssigmay, rdata->nt, rdata->nplist, rdata->ny, perm2); } if ((rdata->nz > 0) & (rdata->ne > 0)) { diff --git a/swig/abstract_model.i b/swig/abstract_model.i index 73cbe9139a..75a48c1675 100644 --- a/swig/abstract_model.i +++ b/swig/abstract_model.i @@ -62,5 +62,10 @@ %ignore fx0_fixedParameters; %ignore fsx0; %ignore fsx0_fixedParameters; - +%ignore fdx_rdatadtcl_colptrs; +%ignore fdx_rdatadtcl_rowvals; +%ignore fdx_rdatadx_solver_colptrs; +%ignore fdx_rdatadx_solver_rowvals; +%ignore fdtotal_cldx_rdata_colptrs; +%ignore fdtotal_cldx_rdata_rowvals; %include "amici/abstract_model.h" diff --git a/tests/cpp/expectedResults.h5 b/tests/cpp/expectedResults.h5 index 3525c1b4b1..a24be85156 100644 Binary files a/tests/cpp/expectedResults.h5 and b/tests/cpp/expectedResults.h5 differ diff --git a/tests/cpp/unittests/testExpData.cpp b/tests/cpp/unittests/testExpData.cpp index 4cf947341c..5a77c8ad00 100644 --- a/tests/cpp/unittests/testExpData.cpp +++ b/tests/cpp/unittests/testExpData.cpp @@ -56,6 +56,9 @@ class ExpDataTest : public ::testing::Test { 0, // dwdw 0, // ndxdotdw {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 0, // nnz 0, // ubw 0 // lbw diff --git a/tests/cpp/unittests/testMisc.cpp b/tests/cpp/unittests/testMisc.cpp index 686330f4f8..a7246f5ad7 100644 --- a/tests/cpp/unittests/testMisc.cpp +++ b/tests/cpp/unittests/testMisc.cpp @@ -70,7 +70,10 @@ class ModelTest : public ::testing::Test { 0, // ndwdp 0, // dwdw 0, // ndxdotdw - {}, // ndJydy + {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 0, // nnz 0, // ubw 0 // lbw @@ -304,10 +307,13 @@ class SolverTest : public ::testing::Test { 0, // ndwdp 0, // dwdw 0, // ndxdotdw - {}, // ndJydy + {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 1, // nnz 0, // ubw - 0 // lbw + 0 // lbw ), SimulationParameters( std::vector(3, 0.0), diff --git a/tests/cpp/unittests/testSerialization.cpp b/tests/cpp/unittests/testSerialization.cpp index f349424408..61e9c7a9a3 100644 --- a/tests/cpp/unittests/testSerialization.cpp +++ b/tests/cpp/unittests/testSerialization.cpp @@ -153,9 +153,12 @@ TEST(ModelSerializationTest, ToFile) 2, // dwdw 13, // ndxdotdw {}, // ndJydy - 15, // nnz - 16, // ubw - 17 // lbw + 9, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata + 17, // nnz + 18, // ubw + 19 // lbw ), amici::SimulationParameters( std::vector(nk, 0.0), @@ -214,9 +217,12 @@ TEST(ReturnDataSerializationTest, ToString) 12, // dwdw 13, // ndxdotdw {}, // ndJydy - 15, // nnz - 16, // ubw - 17 // lbw + 9, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata + 17, // nnz + 18, // ubw + 19 // lbw ), amici::SimulationParameters( std::vector(nk, 0.0), diff --git a/tests/performance/reference.yml b/tests/performance/reference.yml index 6d8c974166..b123a95d50 100644 --- a/tests/performance/reference.yml +++ b/tests/performance/reference.yml @@ -1,5 +1,5 @@ # Reference wall times (seconds) with some buffer -create_sdist: 12 +create_sdist: 15 install_sdist: 150 petab_import: 2100 install_model: 120 diff --git a/tests/testSBMLSuite.py b/tests/testSBMLSuite.py index 9a4c9f648d..187637a15f 100755 --- a/tests/testSBMLSuite.py +++ b/tests/testSBMLSuite.py @@ -14,19 +14,20 @@ """ import copy -import importlib import os import re import shutil import sys -from typing import Tuple, Set +from typing import Set, Tuple -import amici import libsbml as sbml import numpy as np import pandas as pd import pytest + +import amici from amici.constants import SymbolId +from amici.gradient_check import check_derivatives # directory with sbml semantic test cases TEST_PATH = os.path.join(os.path.dirname(__file__), 'sbml-test-suite', 'cases', @@ -35,10 +36,7 @@ @pytest.fixture(scope="session") def result_path(): - # ensure directory for test results is empty - upload_result_path = os.path.join(os.path.dirname(__file__), - 'amici-semantic-results') - return upload_result_path + return os.path.join(os.path.dirname(__file__), 'amici-semantic-results') @pytest.fixture(scope="function", autouse=True) @@ -55,15 +53,22 @@ def sbml_test_dir(): def test_sbml_testsuite_case(test_number, result_path): - test_id = format_test_id(test_number) model_dir = None + + # test cases for which sensitivities are to be checked + # key: case ID; value: epsilon for finite differences + sensitivity_check_cases = { + # parameter-dependent conservation laws + '00783': 1.5e-2, + } + try: current_test_path = os.path.join(TEST_PATH, test_id) # parse expected results results_file = os.path.join(current_test_path, - test_id + '-results.csv') + f'{test_id}-results.csv') results = pd.read_csv(results_file, delimiter=',') results.rename(columns={c: c.replace(' ', '') for c in results.columns}, @@ -72,8 +77,9 @@ def test_sbml_testsuite_case(test_number, result_path): # setup model model_dir = os.path.join(os.path.dirname(__file__), 'SBMLTestModels', test_id) - model, solver, wrapper = compile_model(current_test_path, test_id, - model_dir) + model, solver, wrapper = compile_model( + current_test_path, test_id, model_dir, + generate_sensitivity_code=test_id in sensitivity_check_cases) settings = read_settings_file(current_test_path, test_id) atol, rtol = apply_settings(settings, solver, model) @@ -92,6 +98,12 @@ def test_sbml_testsuite_case(test_number, result_path): # record results write_result_file(simulated, test_id, result_path) + # check sensitivities for selected models + if epsilon := sensitivity_check_cases.get(test_id): + solver.setSensitivityOrder(amici.SensitivityOrder.first) + solver.setSensitivityMethod(amici.SensitivityMethod.forward) + check_derivatives(model, solver, epsilon=epsilon) + except amici.sbml_import.SBMLException as err: pytest.skip(str(err)) finally: @@ -99,8 +111,10 @@ def test_sbml_testsuite_case(test_number, result_path): shutil.rmtree(model_dir, ignore_errors=True) -def verify_results(settings, rdata, expected, wrapper, - model, atol, rtol): +def verify_results( + settings, rdata, expected, wrapper, + model, atol, rtol +): """Verify test results""" amount_species, variables = get_amount_and_variables(settings) @@ -167,7 +181,7 @@ def amounts_to_concentrations( This allows for the reuse of the concentrations_to_amounts method... """ for species in amount_species: - if not species == '': + if species != '': simulated.loc[:, species] = 1 / simulated.loc[:, species] concentrations_to_amounts([species], wrapper, simulated, requested_concentrations) @@ -200,15 +214,18 @@ def concentrations_to_amounts( continue simulated.loc[:, species] *= simulated.loc[ - :, comp if comp in simulated.columns else 'amici_' + comp + :, comp if comp in simulated.columns else f'amici_{comp}' ] -def write_result_file(simulated: pd.DataFrame, - test_id: str, result_path: str): +def write_result_file( + simulated: pd.DataFrame, + test_id: str, + result_path: str +): """ Create test result file for upload to - http://sbml.org/Facilities/Database/Submission/Create + http://raterule.caltech.edu/Facilities/Database Requires csv file with test ID in name and content of [time, Species, ...] """ @@ -254,7 +271,8 @@ def apply_settings(settings, solver, model): return atol, rtol -def compile_model(path, test_id, model_dir): +def compile_model(path, test_id, model_dir, + generate_sensitivity_code: bool = False): """Import the given test model to AMICI""" sbml_file = find_model_file(path, test_id) @@ -263,9 +281,9 @@ def compile_model(path, test_id, model_dir): if not os.path.exists(model_dir): os.makedirs(model_dir) - model_name = 'SBMLTest' + test_id + model_name = f'SBMLTest{test_id}' wrapper.sbml2amici(model_name, output_dir=model_dir, - generate_sensitivity_code=False) + generate_sensitivity_code=generate_sensitivity_code) # settings model_module = amici.import_model_module(model_name, model_dir) @@ -279,26 +297,26 @@ def compile_model(path, test_id, model_dir): def find_model_file(current_test_path: str, test_id: str): """Find model file for the given test (guess filename extension)""" - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l3v2.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l3v2.xml') # fallback l3v1 if not os.path.isfile(sbml_file): - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l3v1.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l3v1.xml') # fallback l2v5 if not os.path.isfile(sbml_file): - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l2v5.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l2v5.xml') return sbml_file def read_settings_file(current_test_path: str, test_id: str): """Read settings for the given test""" - settings_file = os.path.join(current_test_path, test_id + '-settings.txt') + settings_file = os.path.join(current_test_path, f'{test_id}-settings.txt') settings = {} with open(settings_file) as f: for line in f: - if not line == '\n': + if line != '\n': (key, val) = line.split(':') settings[key] = val return settings @@ -306,9 +324,7 @@ def read_settings_file(current_test_path: str, test_id: str): def format_test_id(test_id) -> str: """Format numeric to 0-padded string""" - test_str = str(test_id) - test_str = '0'*(5-len(test_str)) + test_str - return test_str + return f"{test_id:0>5}" def get_tags_for_test(test_id) -> Tuple[Set[str], Set[str]]: @@ -317,7 +333,6 @@ def get_tags_for_test(test_id) -> Tuple[Set[str], Set[str]]: Returns: Tuple of set of strings for componentTags and testTags """ - current_test_path = os.path.join(TEST_PATH, test_id) info_file = os.path.join(current_test_path, f'{test_id}-model.m') with open(info_file) as f: diff --git a/version.txt b/version.txt index 7874d114d3..efb9e6c966 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.11.25 +0.11.26