Skip to content

Commit a8f1c0a

Browse files
authored
Merge pull request #16 from dnv-opensource/eis
Merge latest changes
2 parents dc1aea1 + 6c0302b commit a8f1c0a

54 files changed

Lines changed: 3472 additions & 1775 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/_code_quality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ jobs:
7878
python-version: "3.12.8"
7979
python-version-file: "pyproject.toml"
8080
- name: Install the project
81-
run: uv sync --upgrade
81+
run: uv sync --upgrade --extra tests
8282
- name: Run mypy
8383
run: uv run mypy

.github/workflows/_test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
- runner: windows-latest
1414
# - runner: macos-latest
1515
python:
16-
- version: '3.10'
1716
- version: '3.11'
1817
- version: '3.12'
18+
- version: '3.13'
1919
steps:
2020
- uses: actions/checkout@v4
2121
- name: Install uv
@@ -28,7 +28,7 @@ jobs:
2828
with:
2929
python-version: ${{ matrix.python.version }}
3030
- name: Install the project
31-
run: uv sync --upgrade -p ${{ matrix.python.version }} --no-dev --extra modelTest
31+
run: uv sync --upgrade -p ${{ matrix.python.version }} --no-dev --extra tests
3232
- name: Install pytest
3333
run: |
3434
uv pip install pytest

.github/workflows/_test_future.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
name: Unit Tests (py313)
2-
# Test also with Python 3.13 (experimental; workflow will not fail on error.)
1+
name: Unit Tests (py314)
2+
# Test also with Python 3.14 (experimental; workflow will not fail on error.)
33

44
on: workflow_call
55

66
jobs:
7-
test313:
7+
test314:
88
name: Test on ${{matrix.python.version}}-${{matrix.platform.runner}} (experimental)
99
continue-on-error: true
1010
runs-on: ${{ matrix.platform.runner }}
@@ -14,8 +14,8 @@ jobs:
1414
- runner: ubuntu-latest
1515
- runner: windows-latest
1616
python:
17-
- version: '3.13.0-alpha - 3.13.0'
18-
uvpy: '3.13'
17+
- version: '3.14.0-alpha - 3.14.0'
18+
uvpy: '3.14'
1919
steps:
2020
- uses: actions/checkout@v4
2121
- name: Install uv
@@ -28,7 +28,7 @@ jobs:
2828
with:
2929
python-version: ${{ matrix.python.version }}
3030
- name: Install the project
31-
run: uv sync --upgrade -p ${{ matrix.python.uvpy }} --no-dev --extra modelTest
31+
run: uv sync --upgrade -p ${{ matrix.python.uvpy }} --no-dev --extra tests
3232
- name: Install pytest
3333
run: |
3434
uv pip install pytest

docs/_ext/get_from_code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def run(self):
5151
par = nodes.paragraph(text=text)
5252
if self.typ is None: # need to parse the extracted text
5353
parNode = nodes.paragraph(text="") # use an empty paragraph node as parent
54-
self.state.nested_parse(par, 0, parNode) # here the content of the retrieved text is parsed
54+
self.state.nested_parse(par, 0, parNode) # type: ignore #here the content of the retrieved text is parsed
5555
else: # use the text as is
5656
parNode = par
5757
return [parNode]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
*******************************************************
2+
Guideline on how to develop a FMU using component-model
3+
*******************************************************
4+
5+
The development process follows the steps
6+
7+
#. Develop a functional model using Python (>=3.10.) as a Python class. Called *basic model* here.
8+
#. Thoroughly test the basic model.
9+
#. Define the FMU interface using component-model functions
10+
#. Build the FMU calling `Model.build()`, optionally overwriting optional argument of the model class.
11+
#. Test the FMU standalone, e.g. using the `FMPy` package or in conjunction with other FMUs using the `sim-explorer` package.
12+
13+
Develop a basic model
14+
=====================
15+
Define a functional model as a Python class. We refer to this model as the *basic model*.
16+
At this stage the emerging model class does not need to refer to the `component-model` package.
17+
In fact it is **not recommended** to derive the basic model from `Model`class of component-model.
18+
The basic model might import any Python package (e.g. numpy), as needed to satisfy the functionality.
19+
20+
Testing the basic model
21+
=======================
22+
The basic model should be thoroughly tested.
23+
This cannot be emphasised too much, as test possibilities and feadback is limited in the FMU domain,
24+
while Python offers proper test and debugging facilities.
25+
26+
27+
Defining the FMU interface
28+
==========================
29+
A FMU interface must be added to the model prior to package the model as FMU. This concerns basically
30+
31+
* component model parameters, i.e. settings which can be changed prior to a simulation run, but are typically constant during the run
32+
* component model input variables, i.e. variables which can be changed based on the output from other component models
33+
* component model output variables, i.e. results which are provided to any connected component model, or the system.
34+
35+
Defining the interface is done like
36+
37+
.. code-block:: Python
38+
39+
class <basic-model>_FMU(Model, <basic-model>):
40+
def __init__(self, <basic_model_args, **kwargs):
41+
Model.__init__(self,name,description,author,version, kwargs)
42+
<basic-model>.__init__(<basic-model-args>)
43+
44+
45+
Virtual derivatives
46+
-------------------
47+
Running component models in scenarios it is often necessary to change variables during the simulation run.
48+
As in the reality it is often not a good idea to step values in huge steps, as this resembles a 'hammer stroke',
49+
which the system might not tolerate. The simulation dynamics does often not handle such a situation properly either.
50+
It is therefore often necessary to ramp up or down values to the desired final values,
51+
i.e. changing the derivative of the input variable to a non-zero value
52+
until the desired value of the parent variable is reached and then setting the derivative back to zero.
53+
54+
It is cumbersome to introduce derivative variables for every parent variable which might be changed during the simulation.
55+
Therefore. component-model introduces the concept of *virtual derivatives*,
56+
which are derivative interface variables which are not linked to variables in the basic model.
57+
When defining such variables and setting them to non-zero values,
58+
the parent variable is changed with the given slope at every time step,
59+
i.e.
60+
61+
`<parent-variable> += d<parent-variable>/dt * <step-size>`
62+
63+
where `d<parent-variable>/dt` is the non-zero derivative value (slope).
64+
65+
In practical terms, virtual derivatives are defined using FMI structured variables syntax:
66+
67+
.. code-block:: Python
68+
69+
Variable( name='der(<parent-variable-name>)', causality='input', variability='continuous', ...)
70+
71+
Explicit specification of the arguments `owner` and `local_name` should be avoided.
72+
Specification of `local_name` changes the virtual derivative into a non-virtual derivative,
73+
i.e. the variable is expected to exist in the basic model.
74+
The `on_step` argument is automatically set to change the parent variable at every time step if the derivative is non-zero.
75+
Explicitly overwriting the automatic `on_step` function is allowed at one's own expense.
76+
77+
78+
Building the FMU
79+
================
80+
81+
Testing the FMU
82+
===============

docs/source/component-model.pptx

7.24 KB
Binary file not shown.

examples/BouncingBallStructure.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<OspSystemStructure xmlns="http://opensimulationplatform.com/MSMI/OSPSystemStructure" version="0.1">
2+
<StartTime>0.0</StartTime>
3+
<BaseStepSize>0.1</BaseStepSize>
4+
<Simulators>
5+
<Simulator name="bb" source="BouncingBall3D.fmu" stepSize="0.1" />
6+
</Simulators>
7+
<Functions />
8+
<Connections />
9+
</OspSystemStructure>

examples/DrivingForce.fmu

788 KB
Binary file not shown.

examples/ForcedOscillator.xml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
<OspSystemStructure xmlns="http://opensimulationplatform.com/MSMI/OSPSystemStructure" version="0.1">
22
<StartTime>0.0</StartTime>
33
<BaseStepSize>0.01</BaseStepSize>
4+
<Algorithm>fixedStep</Algorithm>
45
<Simulators>
56
<Simulator name="osc" source="HarmonicOscillator.fmu" stepSize="0.01" />
67
<Simulator name="drv" source="DrivingForce.fmu" stepSize="0.01" />
78
</Simulators>
8-
<Functions />
99
<Connections>
10-
<VariableConnection>
11-
<Variable simulator="drv" name="f[2]" />
12-
<Variable simulator="osc" name="f[2]" />
10+
<VariableConnection powerBond="force-velocity">
11+
<Variable simulator="drv" name="f[2]" causality="output"/>
12+
<Variable simulator="osc" name="f[2]" causality="input"/>
13+
</VariableConnection>
14+
<VariableConnection powerBond="force-velocity">
15+
<Variable simulator="osc" name="v[2]" causality="output"/>
16+
<Variable simulator="drv" name="v_osc[2]" causality="input"/>
1317
</VariableConnection>
1418
</Connections>
19+
<EccoConfiguration>
20+
<SafetyFactor>0.99</SafetyFactor>
21+
<StepSize>0.0001</StepSize>
22+
<MinimumStepSize>0.00001</MinimumStepSize>
23+
<MaximumStepSize>0.01</MaximumStepSize>
24+
<MinimumChangeRate>0.2</MinimumChangeRate>
25+
<MaximumChangeRate>1.5</MaximumChangeRate>
26+
<ProportionalGain>0.2</ProportionalGain>
27+
<IntegralGain>0.15</IntegralGain>
28+
<RelativeTolerance>1e-6</RelativeTolerance>
29+
<AbsoluteTolerance>1e-6</AbsoluteTolerance>
30+
</EccoConfiguration>
1531
</OspSystemStructure>

examples/ForcedOscillator6D.xml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<OspSystemStructure xmlns="http://opensimulationplatform.com/MSMI/OSPSystemStructure" version="0.1">
2+
<StartTime>0.0</StartTime>
3+
<BaseStepSize>0.01</BaseStepSize>
4+
<Algorithm>fixedStep</Algorithm>
5+
<Simulators>
6+
<Simulator name="osc" source="HarmonicOscillator6D.fmu" stepSize="0.01" />
7+
<Simulator name="drv" source="DrivingForce6D.fmu" stepSize="0.01" />
8+
</Simulators>
9+
<Connections>
10+
<VariableConnection powerBond="force-velocity">
11+
<Variable simulator="drv" name="f[5]" causality="output"/>
12+
<Variable simulator="osc" name="f[5]" causality="input"/>
13+
</VariableConnection>
14+
<VariableConnection powerBond="force-velocity">
15+
<Variable simulator="osc" name="v[5]" causality="output"/>
16+
<Variable simulator="drv" name="v_osc[5]" causality="input"/>
17+
</VariableConnection>
18+
</Connections>
19+
<EccoConfiguration>
20+
<SafetyFactor>0.99</SafetyFactor>
21+
<StepSize>0.0001</StepSize>
22+
<MinimumStepSize>0.00001</MinimumStepSize>
23+
<MaximumStepSize>0.01</MaximumStepSize>
24+
<MinimumChangeRate>0.2</MinimumChangeRate>
25+
<MaximumChangeRate>1.5</MaximumChangeRate>
26+
<ProportionalGain>0.2</ProportionalGain>
27+
<IntegralGain>0.15</IntegralGain>
28+
<RelativeTolerance>1e-6</RelativeTolerance>
29+
<AbsoluteTolerance>1e-6</AbsoluteTolerance>
30+
</EccoConfiguration>
31+
</OspSystemStructure>

0 commit comments

Comments
 (0)