Skip to main content

Python wrapper for the libcosim library

Project description

libcosimpy

Python wrapper for the libcosim library. The wrapper uses the libcosimc C wrapper and the ctypes library to make OSP accessible to Python developers.

Getting Started

libcosimpy is available from PyPI. Run the following command to install the package:

pip install libcosimpy

To install from the source, run the following command at the root directory of the repository:

pip install .

libcosimpy requires ctypes to call libcosimc functions. ctypes is included with Python and does not have to be installed.

Usage

Create execution

Import CosimExecution from libcosimpy

from libcosimpy.CosimExecution import CosimExecution

Empty execution object

execution = CosimExecution.from_step_size(step_size=1e3)

With a 0.01s fixed time step

From OSP config

execution = CosimExecution.from_osp_config_file(osp_path=f'[PATH_TO_OSP_DIRECTORY]')

From SSP config

execution = CosimExecution.from_ssp_file(ssp_path=f'[PATH_TO_SSP_DIRECTORY]')

Add slave

FMUs can be added manually to execution. OSP and SSP config executions will import all required slaves automatically and this step is not required

Import CosimLocalSlave from libcosimpy

from libcosimpy.CosimSlave import CosimLocalSlave

Add slave to existing execution

local_slave = CosimLocalSlave(fmu_path=f'[PATH_WITH_FILENAME_TO_FMU]', instance_name='[SOME_UNIQUE_NAME]')
slave_index = execution.add_local_slave(local_slave=local_slave)

Slave index is used for future referencing to the model

Run simulation

Simulations can either be run continiously for a duration

execution.simulate_until(target_time=10e9)

To simulate for 10s

Or stepped manually

execution.step()

With option for stepping multiple steps at once

execution.step(step_count=10)

Finding slave and variable indices

List of slave indices and corresponding indices can be fetched from execution

slave_infos = list(execution.slave_infos())

List of model variables and corresponding indices can be fetched

variables = execution.slave_variables(slave_index=slave_index)

The indices can also be found by unzipping the FMU-file and inspecting the modelDescription.xml file

Retrieving values from simulation

Import CosimObserver from libcosimpy

from libcosimpy.CosimObserver import CosimObserver

Observers can be used to retrieve values as Python list

observer = CosimObserver.create_last_value()
execution.add_observer(observer=observer)

# Run simulation
...
# Retrieve floating point values
values = observer.last_real_values(slave_index=[SLAVE_INDEX], # Model to monitor (integer)
                                   variable_references=[VALUE_REFERENCE(s)]) # List of indices to monitor (integer)

Time series and file export observers are also supported

Overriding values in simulation

Import CosimManipulator from libcosimpy

from libcosimpy.CosimManipulator import CosimManipulator

Manipulators are used to override values

manipulator = CosimManipulator.create_override()
execution.add_manipulator(manipulator=manipulator)

# Run simulation
...
# Override floating point values
manipulator.slave_real_values(slave_index=[SLAVE_INDEX], # Model to monitor (integer) 
                              variable_references=[VALUE_REFERENCE(s)], # Index or list of indices to manipulate (integer)
                              values=[SOME_OVERRIDE_VALUE(s)]) # Floating point values used for override. Equal length to variable references
execution.step()

Scenario manipulators are also supported

Using ECCO algorithm

Libcosimpy supports ECCO (Energy-Conservation-based Co-Simulation) algorithm based on the work in [1] for adaptively updating the step size of the simulation. The algorithm uses the law of conservation of energy between FMU models that represent power bonds from bond graph theory.

Creating ECCO algorithm manually

The parameters of the algorithm can be specified via the EccoParam class:

params = EccoParams(
    safety_factor=0.8,
    step_size=1e-4,
    min_step_size=1e-4,
    max_step_size=0.01,
    min_change_rate=0.2,
    max_change_rate=1.5,
    abs_tolerance=1e-4,
    rel_tolerance=1e-4,
    p_gain=0.2,
    i_gain=0.15,
)

The algorithm be created via create_ecco_algorithm, which can be used to create a new execution instance:

# Create an algorithm instance
ecco_algorithm = CosimAlgorithm.create_ecco_algorithm(params)

# Create execution
execution = CosimExecution.from_algorithm(ecco_algorithm)

The power bond between models is represented by input and output connection pair between two models:

# Indicating a power bond between models (indicated by index chassis_index and wheel_index)
ecco_algorithm.add_power_bond(
    chassis_index,
    chassis_v_out,
    chassis_f_in,
    wheel_index,
    wheel_f_out,
    wheel_v_in,
)

The simulation is started as usual via simulate_until function from CosimExecution:

execution.simulate_until(target_time=10e9)

See test_ecco_algorithm for detailed usage of ECCO algorithm.

Creating ECCO algorithm via system structure file

Alternatively, ECCO algorithm can also be created via system structure file:

<OspSystemStructure xmlns="http://opensimulationplatform.com/MSMI/OSPSystemStructure" version="0.1">
    ...
    <!-- Specify ecco algorithm -->
    <Algorithm>ecco</Algorithm>
    ...
    <Connections>
        <!-- Annotate variable connection as power bond via `powerBond` attribute. Specify
             causality of the variable (input or output) -->
        <VariableConnection powerBond="wheelchassis">
            <Variable simulator="chassis" name="velocity" causality="output"/>
            <Variable simulator="wheel" name="in_vel" causality="input"/>
        </VariableConnection>
        <VariableConnection powerBond="wheelchassis">
            <Variable simulator="wheel" name="out_spring_damper_f" causality="output"/>
            <Variable simulator="chassis" name="force" causality="input"/>
        </VariableConnection>
    </Connections>
    <!-- Specify ecco algorithm parameters -->
    <EccoConfiguration>
        <SafetyFactor>0.99</SafetyFactor>
        <StepSize>0.0001</StepSize>
        <MinimumStepSize>0.00001</MinimumStepSize>
        <MaximumStepSize>0.01</MaximumStepSize>
        <MinimumChangeRate>0.2</MinimumChangeRate>
        <MaximumChangeRate>1.5</MaximumChangeRate>
        <ProportionalGain>0.2</ProportionalGain>
        <IntegralGain>0.15</IntegralGain>
        <RelativeTolerance>1e-6</RelativeTolerance>
        <AbsoluteTolerance>1e-6</AbsoluteTolerance>
    </EccoConfiguration>
</OspSystemStructure>

Then this file can be loaded via a usual way via CosimExecution.from_osp_config_file:

execution = CosimExecution.from_osp_config_file(osp_path="tests/data/fmi2/quarter_truck")

See Quarter truck example for detailed usage of ECCO algorithm via system structure file.

Reference

[1] Sadjina, S. and Pedersen, E., 2020. Energy conservation and coupling error reduction in non-iterative co-simulations. Engineering with Computers, 36, pp.1579-1587.

Tests

Tests can be run using the pytest command in the terminal. libcosimc log level for all tests can be set in the ./tests/conftest.py file.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

libcosimpy-0.0.3.post1-cp313-cp313-win_amd64.whl (8.0 MB view details)

Uploaded CPython 3.13Windows x86-64

libcosimpy-0.0.3.post1-cp313-cp313-manylinux_2_28_x86_64.whl (24.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

libcosimpy-0.0.3.post1-cp312-cp312-win_amd64.whl (8.0 MB view details)

Uploaded CPython 3.12Windows x86-64

libcosimpy-0.0.3.post1-cp312-cp312-manylinux_2_28_x86_64.whl (24.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

libcosimpy-0.0.3.post1-cp311-cp311-win_amd64.whl (8.0 MB view details)

Uploaded CPython 3.11Windows x86-64

libcosimpy-0.0.3.post1-cp311-cp311-manylinux_2_28_x86_64.whl (24.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

libcosimpy-0.0.3.post1-cp310-cp310-win_amd64.whl (8.0 MB view details)

Uploaded CPython 3.10Windows x86-64

libcosimpy-0.0.3.post1-cp310-cp310-manylinux_2_28_x86_64.whl (24.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

File details

Details for the file libcosimpy-0.0.3.post1-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 690107afc490da12e1224ee276d534466336ae5f2100899991383f33758b425b
MD5 e610c07c8b3200166623aba542ac6ae3
BLAKE2b-256 006621d98260e3c6cbfd7e5bf9573737588a6dcd3b383ba9d71d06b657bced7d

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f409a7d6addc88c83f44a1c4038c7519adde397827e7686282314eb748de7ef3
MD5 01aa896369499b5365d1490a69623703
BLAKE2b-256 638a2cbb520fba01f22b30a706ec506307f62a2c909ffa6fc7efe59348babb65

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 215867a7242ea6cebc76dfa8c1be54d3fb5c287784601ae96caa7dbf314061ac
MD5 8a1f7cb76fe32e33ccf99e05aec9e4d8
BLAKE2b-256 f08d136c07e0b4b9cf7cb2e5c1e6dd789ef6aab6d1dd8fc37e5ff039e92ac31d

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fd1410a0228c46543028399683907756c0e349745a218422e333284ef29aae3b
MD5 f6f8c1bd46d219c445b61db8c8475262
BLAKE2b-256 22c8cf3ed4edab1145ec8dd38878cfb2dc1dd5a4fa2dbfa4dfc736ce492f831f

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2929bd46aeb6e46c90c77a7b73dd3f6249a5cc3e37334a0a418bdc56c479469b
MD5 5e751040ef8ebde18da41d1c029a2ca9
BLAKE2b-256 5dfed1d0c83a19d04c14204e6b9064c66a9c476eb787d90cb9f48e5c011461af

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ad6c632b87001772ce67b044b9298ed7636f0d9120e1e308c12c35eace509a36
MD5 aa9fe85cba2a365dfe024ed635f42a2b
BLAKE2b-256 809dd026e0c133367e19bbe1dcaf4660bb7f4134463294bdad196f946b89fc2f

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 56d141ad24507587ae6bc2a59248cb414f8c54d4e826c302612a266771632c3a
MD5 ec321d34b602290f9967c8fd4562347e
BLAKE2b-256 00661beb0ac4ad9ee2be0d3c66b2977d9457fd520398d5de3ac1c3c4c7299f0e

See more details on using hashes here.

File details

Details for the file libcosimpy-0.0.3.post1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for libcosimpy-0.0.3.post1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 87c29cf4c799b7e07de7022a5a3d949e39b4c7aaaeee3c4e5d9f119adfacbe59
MD5 2ac2085f7fa120a5b198e902cb3d160f
BLAKE2b-256 8a1d5f32faf977d9501f7e08a77f793630a7bd9558411957268f201e63c9beb3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page