Light-weight serverless API for OpenModelica
Project description
PyDelica: Serverless OpenModelica with Python
About
PyDelica is an API providing a quick and easy to use interface to compile, customise and run OpenModelica models with Python. Unlike OMPython it does not require the launch of a server session to use OMShell but rather dynamically adjusts files produced after model compilation in order to update options and parameters. The lack of server requirement means models can be run in tandem without calling multiple OMC sessions which can be very taxing on CPU. Furthermore PyDelica is able to detect errors during model runs by reading the stderr
and stdout
from OpenModelica and throw appropriate exceptions to terminate the program execution.
Installation
To use PyDelica you will require an installation of OpenModelica on your system, the API has been confirmed to work on both Windows and Linux, but if OM is installable on macOS it should also be possible to still use it.
To install run:
pip install pydelica
Getting Started
For the purposes of demonstration the included test model tests/models/SineCurrent.mo
will be used.
PyDelica Session
All uses of PyDelica require an instance of the Session
class:
from pydelica import Session
with Session() as session:
...
It is strongly recommended that this class be used via the context manager to ensure cleanup of temporary directories.
Logging
The Session
class has one optional argument which is used to set the log level output within OpenModelica itself. The options are based on the -lv
flag within OM. By default the level is set to Normal
which means no log level output.
As an example if you wanted to run with statistics logging -lv=LOG_STATS
you would setup with the following:
from pydelica import Session
from pydelica.logger import OMLogLevel
with Session(log_level=OMLogLevel.STATS) as session:
...
See the source for more options here.
Building/Compiling Models
Before you can run a model you must first compile it. This is done using the build_model
member function which takes the path to the Modelica source file.
model_path = os.path.join('tests', 'models', 'SineCurrent.mo')
session.build_model(model_path)
If the required model is not top level, that is to say it exists within a module or , we can optionally specify the address within Modelica. This is also required if the required model is not the default. For example say model A
existed within module M
:
model_path = 'FictionalModelFile.mo'
session.build_model(model_path, 'M.A')
The build_model
function also allows you to specify additional flags/options to hand to the OMC compiler, these are given
in the form of a dictionary where the value can be None
if the flag does not take any input. You can also directly set the profiling level for profiling the Modelica code. When set, the profile dictionary is also stored in the session after the simulation and is accessible via the code_profile
and code_info
attributes:
session.build_model(
model_path,
model_addr='M.A'
profiling="all",
omc_build_flags={"-g": "MetaModelica"}
)
session.simulate()
print(session.code_profile)
print(session.code_info)
Specifying Additional Model-Based Dependencies
If additional model files are required to execute the main model these can be specified with the extra_models
argument:
session.build_model(
model_path,
extra_models=["extra_model.mo"]
)
Using Alternative Inputs Location
If your model inputs are stored in an alternative directory, this can be specified with the update_input_paths_to
argument:
session.build_model(
model_path,
update_input_paths_to="/path/to/inputs"
)
Examining Parameters and Options
We can examine all parameters for a given model using the get_parameters
method which will return a Python dictionary:
session.get_parameters('SineCurrentModel')
if the parameter is unique to a single model then the model name argument can be dropped. Returning the value for a single parameter is as simple as:
session.get_parameter(<parameter-name>)
For simulation options the analogous methods are get_simulation_options
and get_simulation_option
respectively for general case, for more specific see below.
Setting Parameters and Options
Set a parameter to a different value using the set_parameter
function:
session.set_parameter(<parameter-name>, <new-value>)
Setting C Runtime Simulation flags
To set options provided to the command line during simulation execution you can use get_runtime_options
:
runtime_options = session.get_runtime_options(<model-name>)
This will return a RuntimeOptions
instance with configurable attributes, use help(session.get_runtime_options)
to see the docstring detailing each,
or by going to the C Runtime Simulation Flags OM manual page.
runtime_options.nls = "homotopy"
Further Configuration
The output file type can be specified:
from pydelica.options import OutputFormat
session.set_output_format(OutputFormat.CSV) # Other options are MAT and PLT
Set the solver:
from pydelica.options import Solver
session.set_solver(Solver.DASSL) # Other options are EULER and RUNGE_KUTTA
Set the time range:
# Each argument is optional
session.set_time_range(start_time=0, stop_time=10, model_name='SineCurrentModel')
Set tolerance:
# Model name is optional
session.set_tolerance(tolerance=1E-9, model_name='SineCurrentModel')
Set variable filter for outputs:
# Model name is optional
session.set_variable_filter(filter_str='output*', model_name='SineCurrentModel')
Failing Simulation on Lower Assertion Level
By default PyDelica will look for the expression assert | error
as an indication of a Modelica assertion
failure and then terminate when this is violated. You can override this behaviour using the fail_on_assert_level
method of the Session
class:
from pydelica import Session
with Session() as pd_session:
pd_session.fail_on_assert_level('warning')
Possible values ranked by order (highest at the top):
Value | Description |
---|---|
'never' |
Do not throw an exception on Modelica assertion violation |
'error' |
Default. Throw an exception on an assertion of level AssertionLevel.error |
'warning' |
Throw an exception on assertion of level AssertionLevel.warning |
'info' |
Throw an exception on any assert | info statement |
'debug' |
Throw an exception on any assert | debug statement |
Running the Simulation
To run the simulation use the simulate
method. If a model name is specified then that model is run,
else this is the first model in the model list. At the simulation step parameter values are written to the
XML file read by the binary before the model binary is executed.
# Model name is optional, verbosity is also optional and overwrites that of the session
session.simulate(model_name='SineCurrentModel')
Retrieving Results
To view the results use the get_solutions
method which will return a python dictionary containing
the solutions for all models after a model run:
solutions = session.get_solutions()
The variables for each model are stored as a Pandas dataframe.
Using Alternative Libraries
NOTE: Currently only works in WSL on Windows machines.
You can use an alternative library version via the use_library
method:
session.use_library("Modelica", "3.2.3")
you can also optionally specify the location of this library:
session.use_library("Modelica", "3.2.3", library_directory="/home/user/my_om_libraries")
Including Extra C Resources
When building a model extra C file resources can be specified using the c_source_dir
argument to build_model
:
session.build_model(
model_path,
c_source_dir=os.path.join(model_dir, "Resources", "Include")
)
Docker
A Docker image is available for OpenModelica with Pydelica:
$ docker pull artemisbeta/pydelica
You can try out Pydelica within a Jupyter notebook by running:
$ docker run -ti artemisbeta/pydelica jupyter notebook --ip 0.0.0.0 --no-browser
and opening the resulting URL within your browser.
Troubleshooting
Simulation fails with no error thrown
Try setting the assertion level to a lower level, for some reason OM ranks missing input file errors
as type debug
, see here.
stdout | info | ... loading "data" from "Default/myInput.mat"
assert | debug | Not possible to open file "Default/myInput.mat": No such file or directory
assert | info | simulation terminated by an assertion at initialization
PyDelica cannot find OMC
PyDelica relies on either locating OMC on UNIX using the which
command, or in the case of Windows using the OPENMODELICAHOME
environment variable. Ensure at least one of these is available after installating OpenModelica.
Use Cases
Pydelica is currently being used in the following projects, if you would like to be included in this list please open an issue:
- Power Balance Models, United Kingdom Atomic Energy Authority: A tokamak power balance model with Python API and CLI
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pydelica-0.6.1.tar.gz
.
File metadata
- Download URL: pydelica-0.6.1.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.13.0 Linux/6.11.0-9-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6b3685c538650385c3fdd76ee8dec91232d8f37b082a54720492e92320561090 |
|
MD5 | f8ba2733163aef716124672f8aaf845b |
|
BLAKE2b-256 | 9c075c6fdc0f5676ee2d94e3363343b1c1b2f17068f7fe1d83f6eeae62e8fb99 |
File details
Details for the file pydelica-0.6.1-py3-none-any.whl
.
File metadata
- Download URL: pydelica-0.6.1-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.13.0 Linux/6.11.0-9-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 02aa0979564badd5887bcb99b3b04bfda34cb5df666a9a8c36af70df98c31dec |
|
MD5 | a65455f57858ddb56f69b21cd64eb392 |
|
BLAKE2b-256 | 37408228b76e1a1cbc1a8c1705943848497d02ea111d1f32ee0f4cd4b5d6c9e3 |