From 2e5f1a367bee44927f3ef0353bdd14d3d69eb6ba Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Sep 2026 15:44:10 +0200 Subject: [PATCH 1/3] Build SUNDIALS IDA and alias it OMSimulator's strongly coupled system gains a DAE mode (fmi-ls-dae): where a component exposes the residuals of F(t, x, x', z) = 0 instead of an explicit ODE, the master integrates them with IDA rather than differentiating them into something CVODE can take. That wants the IDA library built and an alias beside the CVODE and KINSOL ones. Refs OpenModelica/OMSimulator#1645 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01EfnWV25k2u9x4CHxcnQbF7 --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 796e4c96..048e2880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,9 @@ if(NOT OPENMODELICA_NEW_CMAKE_BUILD) set(SUNDIALS_ENABLE_KINSOL ON CACHE BOOL "Enable the KINSOL library" FORCE) set(SUNDIALS_ENABLE_ARKODE OFF CACHE BOOL "Enable the ARKODE library" FORCE) set(SUNDIALS_ENABLE_CVODES OFF CACHE BOOL "Enable the CVODES library" FORCE) - set(SUNDIALS_ENABLE_IDA OFF CACHE BOOL "Enable the IDA library" FORCE) + # IDA: the DAE mode of the strongly coupled system (fmi-ls-dae), where the + # master integrates the components' residuals instead of their derivatives. + set(SUNDIALS_ENABLE_IDA ON CACHE BOOL "Enable the IDA library" FORCE) set(SUNDIALS_ENABLE_IDAS OFF CACHE BOOL "Enable the IDAS library" FORCE) set(SUNDIALS_ENABLE_KLU OFF CACHE BOOL "Enable KLU support" FORCE) set(SUNDIALS_ENABLE_LAPACK OFF CACHE BOOL "Enable LAPACK support" FORCE) @@ -73,6 +75,7 @@ endif() ## need an interface library of our own on top. add_library(oms::3rd::sundials::cvode ALIAS sundials_cvode_static) +add_library(oms::3rd::sundials::ida ALIAS sundials_ida_static) add_library(oms::3rd::sundials::kinsol ALIAS sundials_kinsol_static) ######################################################################### From 048a84baa51074fe06a4aba0d76b1871406c6c86 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Sep 2026 17:17:46 +0200 Subject: [PATCH 2/3] Add SuiteSparse and build SUNDIALS' KLU against it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OMSimulator's strongly coupled system gains a DAE mode (fmi-ls-dae) whose Jacobian has a structure — the components' manifests say which unknowns each residual reaches — so it is held sparse and wants a sparse factorization. SUNDIALS_ENABLE_KLU was off for want of a SuiteSparse to build it against. SuiteSparse comes in as a submodule pinned to v7.12.2, the same release OpenModelica carries, and the build is delegated to its own CMakeLists exactly as OMCompiler/3rdParty does it: only suitesparse_config, amd, colamd, btf and klu are enabled, static, no OpenMP, CUDA, Fortran or demos. KLU_USE_CHOLMOD is off, so CHOLMOD and its dependencies are not needed. SUNDIALS' FindKLU prefers an existing SuiteSparse::KLU target as long as it is not pointed at a KLU elsewhere, so it picks up the in-tree one on its own; the compatibility checks have to be off because they try_compile() against a target that is in-tree rather than imported. SUNDIALS_INDEX_SIZE was already 64, which is what SuiteSparse' int64 KLU entry points want. Refs OpenModelica/OMSimulator#1645 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01EfnWV25k2u9x4CHxcnQbF7 --- .gitmodules | 5 +++++ CMakeLists.txt | 37 +++++++++++++++++++++++++++++++++---- SuiteSparse | 1 + 3 files changed, 39 insertions(+), 4 deletions(-) create mode 160000 SuiteSparse diff --git a/.gitmodules b/.gitmodules index ef784638..b9da387a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,8 @@ url = https://github.com/llnl/sundials.git branch = v7.8.0 shallow = true +[submodule "SuiteSparse"] + path = SuiteSparse + url = https://github.com/DrTimothyAldenDavis/SuiteSparse.git + branch = v7.12.2 + shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index 048e2880..e5ce9a45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,10 @@ if(NOT OPENMODELICA_NEW_CMAKE_BUILD) set(BUILD_STATIC_LIBS ON CACHE BOOL "Build SUNDIALS static libraries" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build SUNDIALS shared libraries" FORCE) - # OMSimulator only uses CVODE (SystemSC/SystemSC3) and KINSOL (AlgLoop), both - # with the dense linear solver. No ARKODE/CVODES/IDA/IDAS, and no KLU - unlike - # OMC we have no SuiteSparse in 3rdParty to build it against. + # OMSimulator uses CVODE (SystemSC/SystemSC3), KINSOL (AlgLoop) and IDA (the + # DAE mode of SystemSC), the first two with the dense linear solver and IDA + # with KLU over the structure the components' fmi-ls-dae manifests give. + # No ARKODE/CVODES/IDAS. set(SUNDIALS_ENABLE_CVODE ON CACHE BOOL "Enable the CVODE library" FORCE) set(SUNDIALS_ENABLE_KINSOL ON CACHE BOOL "Enable the KINSOL library" FORCE) set(SUNDIALS_ENABLE_ARKODE OFF CACHE BOOL "Enable the ARKODE library" FORCE) @@ -36,7 +37,10 @@ if(NOT OPENMODELICA_NEW_CMAKE_BUILD) # master integrates the components' residuals instead of their derivatives. set(SUNDIALS_ENABLE_IDA ON CACHE BOOL "Enable the IDA library" FORCE) set(SUNDIALS_ENABLE_IDAS OFF CACHE BOOL "Enable the IDAS library" FORCE) - set(SUNDIALS_ENABLE_KLU OFF CACHE BOOL "Enable KLU support" FORCE) + # KLU, against the in-tree SuiteSparse below: the sparse factorization for the + # DAE mode of the strongly coupled system. SUNDIALS_INDEX_SIZE is 64 above, + # which matches SuiteSparse' int64 KLU entry points. + set(SUNDIALS_ENABLE_KLU ON CACHE BOOL "Enable KLU support" FORCE) set(SUNDIALS_ENABLE_LAPACK OFF CACHE BOOL "Enable LAPACK support" FORCE) # Doubles and a 64 bit sunindextype, matching OMC's settings. @@ -56,6 +60,30 @@ if(NOT OPENMODELICA_NEW_CMAKE_BUILD) # same way in all build types. set(SUNDIALS_ENABLE_ERROR_CHECKS OFF CACHE BOOL "Enable SUNDIALS error checking" FORCE) + # SuiteSparse (DrTimothyAldenDavis/SuiteSparse, submodule pinned to v7.12.2), + # for SUNDIALS' KLU: the sparse linear solver the DAE mode of the strongly + # coupled system factorizes its Jacobian with. Only the subset KLU needs is + # built, and the build is delegated to SuiteSparse' own CMakeLists as + # OpenModelica does it (OMCompiler/3rdParty/CMakeLists.txt). + set(SUITESPARSE_ENABLE_PROJECTS "suitesparse_config;amd;colamd;btf;klu" CACHE STRING "SuiteSparse projects to build" FORCE) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) + set(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE) + set(SUITESPARSE_USE_OPENMP OFF CACHE BOOL "" FORCE) + set(SUITESPARSE_USE_CUDA OFF CACHE BOOL "" FORCE) + set(SUITESPARSE_USE_FORTRAN OFF CACHE BOOL "" FORCE) + set(SUITESPARSE_DEMOS OFF CACHE BOOL "" FORCE) + set(SUITESPARSE_USE_STRICT OFF CACHE BOOL "" FORCE) + set(KLU_USE_CHOLMOD OFF CACHE BOOL "" FORCE) + add_subdirectory(SuiteSparse EXCLUDE_FROM_ALL) + + # SUNDIALS' FindKLU prefers an existing SuiteSparse::KLU target as long as it + # is not pointed at a KLU somewhere else, so it picks up the one built above on + # its own — do not hand it KLU_INCLUDE_DIR/KLU_LIBRARY_DIR. The compatibility + # checks have to be off: they try_compile() against SUNDIALS::KLU, which here + # aliases an in-tree target rather than an imported one and is invisible to the + # separate try_compile project. + set(SUNDIALS_ENABLE_KLU_CHECKS OFF CACHE BOOL "Enable KLU compatibility checks" FORCE) + add_subdirectory(sundials EXCLUDE_FROM_ALL) # SUNDIALS declares CMAKE_C_STANDARD and CMAKE_C_EXTENSIONS as *cache* variables @@ -76,6 +104,7 @@ endif() add_library(oms::3rd::sundials::cvode ALIAS sundials_cvode_static) add_library(oms::3rd::sundials::ida ALIAS sundials_ida_static) +add_library(oms::3rd::sundials::sunlinsolklu ALIAS sundials_sunlinsolklu_static) add_library(oms::3rd::sundials::kinsol ALIAS sundials_kinsol_static) ######################################################################### diff --git a/SuiteSparse b/SuiteSparse new file mode 160000 index 00000000..42151688 --- /dev/null +++ b/SuiteSparse @@ -0,0 +1 @@ +Subproject commit 42151688813c45846a597edcb601435a0e38f3dd From 35a121c27488587b382956771b68da83a70b5d52 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Sep 2026 18:01:47 +0200 Subject: [PATCH 3/3] Do not make SuiteSparse look for a BLAS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configuring failed on the Linux and Windows CI images, which have no BLAS: Could NOT find BLAS (missing: BLAS_LIBRARIES) SuiteSparse/SuiteSparse_config/cmake_modules/SuiteSparseBLAS.cmake:276 SuiteSparse_config looks for one unless told that nothing needs it, and nothing here does: BLAS is used by CHOLMOD, UMFPACK and SPQR, none of which are enabled, and KLU only reaches them through KLU_USE_CHOLMOD, which is off. Neither AMD, COLAMD, BTF nor KLU names BLAS in its build or its sources. OpenModelica does not hit this because it requires BLAS/LAPACK anyway; OMSimulator does not. SUITESPARSE_REQUIRE_BLAS OFF skips the search, but the path it takes instead still labels the BLAS it did not look for and its threading checks dereference that label unguarded, so an empty BLA_VENDOR is a configure error one file later. Any non-empty value does — the checks are all guarded on a specific vendor, nothing is searched for and nothing is linked — so it is set to "Generic". Checked with a clean configure and build without a BLAS on the search path: KLU builds and links, and OMSimulator's testsuite passes 117/117. Refs OpenModelica/OMSimulator#1645 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01EfnWV25k2u9x4CHxcnQbF7 --- CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5ce9a45..426c8432 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,18 @@ if(NOT OPENMODELICA_NEW_CMAKE_BUILD) set(SUITESPARSE_DEMOS OFF CACHE BOOL "" FORCE) set(SUITESPARSE_USE_STRICT OFF CACHE BOOL "" FORCE) set(KLU_USE_CHOLMOD OFF CACHE BOOL "" FORCE) + # SuiteSparse_config looks for a BLAS unless told that nothing needs one, and + # nothing here does: BLAS is used by CHOLMOD, UMFPACK and SPQR, none of which + # are enabled, and KLU only reaches them through KLU_USE_CHOLMOD, which is off. + # OpenModelica does not hit this because it requires BLAS/LAPACK anyway; + # OMSimulator does not, and its Linux and Windows CI images have none. + set(SUITESPARSE_REQUIRE_BLAS OFF CACHE BOOL "" FORCE) + # With the requirement off SuiteSparse skips the search but still labels the + # BLAS it did not look for, and its threading checks dereference that label + # unguarded — an empty BLA_VENDOR is a configure error there. Any non-empty + # value does, since the checks are all guarded on a specific vendor; nothing + # is searched for and nothing is linked. + set(BLA_VENDOR "Generic" CACHE STRING "" FORCE) add_subdirectory(SuiteSparse EXCLUDE_FROM_ALL) # SUNDIALS' FindKLU prefers an existing SuiteSparse::KLU target as long as it