Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 65 additions & 39 deletions .github/workflows/ci-cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ jobs:
linux:
name: Linux
runs-on: ubuntu-latest
container:
image: debian:bookworm
strategy:
fail-fast: false
matrix:
Expand All @@ -15,45 +17,69 @@ jobs:
timeout-minutes: 35

steps:
- uses: actions/checkout@v4
- name: Generate Dockerfile
- name: Install Debian prerequisites
shell: bash
run: |
mkdir /tmp/osp-builder-docker
cat <<EOF >/tmp/osp-builder-docker/Dockerfile
FROM debian:bookworm
RUN apt-get update && apt-get install -y --no-install-recommends \
cmake \
build-essential \
doxygen \
wget \
libboost-all-dev \
libmsgsl-dev \
libyaml-cpp-dev \
libxerces-c-dev \
libzip-dev zipcmp zipmerge ziptool
RUN wget \
--no-check-certificate \
"https://github.com/viproma/debian-fmilib/releases/download/debian%2F2.0.3-1/libfmilib2_2.0.3-1_amd64.deb" \
"https://github.com/viproma/debian-fmilib/releases/download/debian%2F2.0.3-1/libfmilib2-dev_2.0.3-1_amd64.deb"
RUN dpkg -i libfmilib2_2.0.3-1_amd64.deb libfmilib2-dev_2.0.3-1_amd64.deb
RUN wget --no-check-certificate https://github.com/PJK/libcbor/archive/refs/tags/v0.11.0.tar.gz && \
tar xaf v0.11.0.tar.gz && cd libcbor-0.11.0 && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON . && make && make install
COPY entrypoint.sh /
ENTRYPOINT /entrypoint.sh
EOF
- name: Generate entrypoint.sh
set -euxo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
cmake \
doxygen \
git \
libboost-all-dev \
libmsgsl-dev \
libyaml-cpp-dev \
libxerces-c-dev \
libzip-dev \
wget \
zipcmp \
zipmerge \
ziptool
- uses: actions/checkout@v4
- name: Install FMI Library and libcbor
shell: bash
run: |
cat <<'EOF' >/tmp/osp-builder-docker/entrypoint.sh
#!/bin/bash
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_${{ matrix.shared_libs }} /mnt/source
cmake --build .
ctest --output-on-failure
EOF
chmod 0755 /tmp/osp-builder-docker/entrypoint.sh
- name: Build Docker image
run: docker build -t osp-builder /tmp/osp-builder-docker/
set -euxo pipefail
cd /tmp
FMILIB_VERSION=3.0.4
wget \
-O "fmi-library-${FMILIB_VERSION}.tar.gz" \
"https://github.com/modelon-community/fmi-library/archive/refs/tags/${FMILIB_VERSION}.tar.gz"
tar xaf "fmi-library-${FMILIB_VERSION}.tar.gz"
cmake \
-S "fmi-library-${FMILIB_VERSION}" \
-B fmi-library-build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_INSTALL_LIBDIR=lib \
-DFMILIB_BUILD_STATIC_LIB=ON \
-DFMILIB_BUILD_SHARED_LIB=ON \
-DFMILIB_BUILD_TESTS=OFF \
-DFMILIB_GENERATE_DOXYGEN_DOC=OFF
cmake --build fmi-library-build
cmake --install fmi-library-build
wget \
--no-check-certificate \
https://github.com/PJK/libcbor/archive/refs/tags/v0.11.0.tar.gz
tar xaf v0.11.0.tar.gz
cmake \
-S libcbor-0.11.0 \
-B libcbor-0.11.0/build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
cmake --build libcbor-0.11.0/build
cmake --install libcbor-0.11.0/build
- name: Build cosim
run: docker run --rm -v $(pwd):/mnt/source:ro osp-builder
shell: bash
run: |
set -euxo pipefail
cmake \
-S . \
-B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DBUILD_${{ matrix.shared_libs }}
cmake --build build
ctest --test-dir build --output-on-failure
10 changes: 6 additions & 4 deletions .github/workflows/ci-conan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
env:
CONAN_LOGIN_USERNAME_OSP: ${{ secrets.osp_artifactory_usr }}
CONAN_PASSWORD_OSP: ${{ secrets.osp_artifactory_pwd }}
CONAN_HOME: ${{ github.workspace }}/.conan2
LIBCOSIM_RUN_TESTS_ON_CONAN_BUILD: 1
timeout-minutes: 35

Expand All @@ -32,8 +33,8 @@ jobs:
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Configure Conan
run: |
conan profile detect
conan remote add osp https://osp.jfrog.io/artifactory/api/conan/conan-local
conan profile detect -f
conan remote add osp https://osp.jfrog.io/artifactory/api/conan/conan-local --force
- name: Build package
shell: bash
run: |
Expand Down Expand Up @@ -65,11 +66,12 @@ jobs:
env:
CONAN_LOGIN_USERNAME_OSP: ${{ secrets.osp_artifactory_usr }}
CONAN_PASSWORD_OSP: ${{ secrets.osp_artifactory_pwd }}
CONAN_HOME: ${{ github.workspace }}/.conan2
LIBCOSIM_RUN_TESTS_ON_CONAN_BUILD: 1
strategy:
fail-fast: false
matrix:
os: [windows-2022]
os: [windows-2025]
build_type: [Debug, Release]
option_proxyfmu: ['proxyfmu=True', 'proxyfmu=False']
option_shared: ['shared=True', 'shared=False']
Expand All @@ -83,7 +85,7 @@ jobs:
pip3 install conan cmake ninja
- name: Configure Conan
run: |
conan profile detect
conan profile detect -f
conan remote add osp https://osp.jfrog.io/artifactory/api/conan/conan-local --force
- name: Conan create
shell: bash
Expand Down
23 changes: 21 additions & 2 deletions cmake/AddTestExecutable.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@
# SOURCES <sources...>
# DEPENDENCIES <targets...>
# DATA_DIR <directory>
# REFERENCE_FMU_V2_DIR <directory>
# GEN_TEST_DATA_DIR <directory>
# )
#
# "target folder" is just a human-readable name for the IDE folder that the
# target will be grouped under. If omitted, it will be a top-level target.
function(add_test_executable name)
# Parse argument list
set(params "FOLDER" "SOURCES" "DEPENDENCIES" "DATA_DIR")
set(params
"FOLDER"
"SOURCES"
"DEPENDENCIES"
"DATA_DIR"
"REFERENCE_FMU_V2_DIR"
"GEN_TEST_DATA_DIR")
foreach(p IN LISTS params)
set(arg_${p})
endforeach()
Expand All @@ -37,7 +45,18 @@ function(add_test_executable name)

# Add test
add_test(NAME "${name}" COMMAND "${name}")
set(environment)
if(arg_DATA_DIR)
set_property(TEST "${name}" PROPERTY ENVIRONMENT "TEST_DATA_DIR=${arg_DATA_DIR}")
list(APPEND environment "TEST_DATA_DIR=${arg_DATA_DIR}")
endif()
if(arg_REFERENCE_FMU_V2_DIR)
list(APPEND environment
"REFERENCE_FMU_V2_DIR=${arg_REFERENCE_FMU_V2_DIR}")
endif()
if(arg_GEN_TEST_DATA_DIR)
list(APPEND environment "GEN_TEST_DATA_DIR=${arg_GEN_TEST_DATA_DIR}")
endif()
if(environment)
set_property(TEST "${name}" PROPERTY ENVIRONMENT ${environment})
endif()
endfunction()
4 changes: 2 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ def set_version(self):
# Dependencies/requirements
def requirements(self):
self.tool_requires("cmake/[>=4.0]")
self.requires("fmilibrary/[~2.3]")
self.requires("fmilibrary/[~3.0.4]")
self.requires("libcbor/0.11.0")
self.requires("libzip/[~1.11]")
self.requires("ms-gsl/[>=3 <5]", transitive_headers=True)
self.requires("boost/[~1.85]", transitive_headers=True, transitive_libs=True) # Required by Thrift
if self.options.proxyfmu:
self.requires("proxyfmu/0.4.2@osp/stable",
self.requires("proxyfmu/0.4.3@osp/testing",
transitive_headers=True,
transitive_libs=True)
self.requires("yaml-cpp/[~0.9]")
Expand Down
5 changes: 4 additions & 1 deletion include/cosim/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ enum class errc
invalid_system_structure,

/// ZIP file error
zip_error
zip_error,

/// Invalid operation (e.g. calling a function at the invalid time in the simulation lifecycle)
invalid_operation
};


Expand Down
33 changes: 29 additions & 4 deletions include/cosim/fmi/v2/fmu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,46 @@ class slave_instance : public fmi::slave_instance
/// Returns the underlying C API handle (for FMI Library)
fmi2_import_t* fmilib_handle() const;

/// Reports whether the FMU provides directional derivatives.
bool provides_directional_derivatives() const noexcept;

/**
* Computes directional derivatives of unknown Real variables with respect
* to known Real variables.
*/
void get_directional_derivative(
gsl::span<const value_reference> unknowns,
gsl::span<const value_reference> knowns,
gsl::span<const double> seed,
gsl::span<double> sensitivity) const;

private:
enum class lifecycle_state : std::int32_t
{
instantiated = 0,
initialization = 1,
step = 2,
terminated = 3
};

struct saved_state
{
fmi2_FMU_state_t fmuState = nullptr;
bool setupComplete = false;
bool simStarted = false;
lifecycle_state lifecycleState = lifecycle_state::instantiated;
};
void copy_current_state(saved_state& state);
state_index store_new_state(saved_state state);
void cache_directional_derivative_metadata();

std::shared_ptr<v2::fmu> fmu_;
fmi2_import_t* handle_;

bool setupComplete_ = false;
bool simStarted_ = false;
lifecycle_state lifecycleState_ = lifecycle_state::instantiated;
bool providesDirectionalDerivatives_ = false;
std::vector<value_reference> outputReferences_;
std::vector<value_reference> derivativeReferences_;
std::vector<value_reference> initialUnknownReferences_;
std::vector<value_reference> continuousStateReferences_;

std::string instanceName_;

Expand Down
8 changes: 4 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,14 @@ endif ()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_link_libraries(cosim INTERFACE "atomic" "stdc++fs")
endif()

if(WIN32)
target_link_libraries(cosim PUBLIC "Bcrypt")
if(BUILD_SHARED_LIBS)
target_link_libraries(cosim PUBLIC "Shlwapi") # Windows API DLLs
else()
target_link_libraries(cosim PUBLIC "Bcrypt" "Shlwapi")
if(NOT BUILD_SHARED_LIBS)
set_target_properties(cosim PROPERTIES OUTPUT_NAME "libcosim")
endif()
endif()

if(LIBCOSIM_STANDALONE_INSTALLATION)
set_target_properties(cosim PROPERTIES INSTALL_RPATH "\$ORIGIN")
endif()
Expand Down
2 changes: 2 additions & 0 deletions src/cosim/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class my_error_category : public std::error_category
return "Invalid system structure";
case errc::zip_error:
return "ZIP file error";
case errc::invalid_operation:
return "Invalid operation";
default:
COSIM_PANIC();
}
Expand Down
Loading
Loading