Skip to content

Commit 78a1195

Browse files
committed
Merge branch 'update_override' into v4.1.0-status20260123
2 parents e588845 + 86af54f commit 78a1195

1 file changed

Lines changed: 65 additions & 64 deletions

File tree

OMPython/ModelicaSystem.py

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import os
1212
import pathlib
1313
import queue
14+
import re
1415
import textwrap
1516
import threading
1617
from typing import Any, cast, Optional
@@ -19,8 +20,6 @@
1920

2021
import numpy as np
2122

22-
import re
23-
2423
from OMPython.OMCSession import (
2524
OMCSessionException,
2625
OMCSessionRunData,
@@ -332,14 +331,14 @@ def __init__(
332331
self._simulate_options: dict[str, str] = {}
333332
self._override_variables: dict[str, str] = {}
334333
self._simulate_options_override: dict[str, str] = {}
335-
self._linearization_options: dict[str, str | float] = {
336-
'startTime': 0.0,
337-
'stopTime': 1.0,
338-
'stepSize': 0.002,
339-
'tolerance': 1e-8,
334+
self._linearization_options: dict[str, str] = {
335+
'startTime': str(0.0),
336+
'stopTime': str(1.0),
337+
'stepSize': str(0.002),
338+
'tolerance': str(1e-8),
340339
}
341340
self._optimization_options = self._linearization_options | {
342-
'numberOfIntervals': 500,
341+
'numberOfIntervals': str(500),
343342
}
344343
self._linearized_inputs: list[str] = [] # linearization input list
345344
self._linearized_outputs: list[str] = [] # linearization output list
@@ -351,7 +350,8 @@ def __init__(
351350
self._session = OMCSessionLocal(omhome=omhome)
352351

353352
# get OpenModelica version
354-
self._version = self._session.sendExpression("getVersion()", parsed=True)
353+
version_str = self.sendExpression(expr="getVersion()")
354+
self._version = self._parse_om_version(version=version_str)
355355
# set commandLineOptions using default values or the user defined list
356356
if command_line_options is None:
357357
# set default command line options to improve the performance of linearization and to avoid recompilation if
@@ -950,7 +950,7 @@ def getSimulationOptions(
950950
def getLinearizationOptions(
951951
self,
952952
names: Optional[str | list[str]] = None,
953-
) -> dict[str, str | float] | list[str | float]:
953+
) -> dict[str, str] | list[str]:
954954
"""Get simulation options used for linearization.
955955
956956
Args:
@@ -964,17 +964,16 @@ def getLinearizationOptions(
964964
returned.
965965
If `names` is a list, a list with one value for each option name
966966
in names is returned: [option1_value, option2_value, ...].
967-
Some option values are returned as float when first initialized,
968-
but always as strings after setLinearizationOptions is used to
969-
change them.
967+
968+
The option values are always returned as strings.
970969
971970
Examples:
972971
>>> mod.getLinearizationOptions()
973-
{'startTime': 0.0, 'stopTime': 1.0, 'stepSize': 0.002, 'tolerance': 1e-08}
972+
{'startTime': '0.0', 'stopTime': '1.0', 'stepSize': '0.002', 'tolerance': '1e-08'}
974973
>>> mod.getLinearizationOptions("stopTime")
975-
[1.0]
974+
['1.0']
976975
>>> mod.getLinearizationOptions(["tolerance", "stopTime"])
977-
[1e-08, 1.0]
976+
['1e-08', '1.0']
978977
"""
979978
if names is None:
980979
return self._linearization_options
@@ -988,7 +987,7 @@ def getLinearizationOptions(
988987
def getOptimizationOptions(
989988
self,
990989
names: Optional[str | list[str]] = None,
991-
) -> dict[str, str | float] | list[str | float]:
990+
) -> dict[str, str] | list[str]:
992991
"""Get simulation options used for optimization.
993992
994993
Args:
@@ -1002,9 +1001,8 @@ def getOptimizationOptions(
10021001
returned.
10031002
If `names` is a list, a list with one value for each option name
10041003
in names is returned: [option1_value, option2_value, ...].
1005-
Some option values are returned as float when first initialized,
1006-
but always as strings after setOptimizationOptions is used to
1007-
change them.
1004+
1005+
The option values are always returned as string.
10081006
10091007
Examples:
10101008
>>> mod.getOptimizationOptions()
@@ -1023,13 +1021,47 @@ def getOptimizationOptions(
10231021

10241022
raise ModelicaSystemError("Unhandled input for getOptimizationOptions()")
10251023

1026-
def parse_om_version(self, version: str) -> tuple[int, int, int]:
1024+
def _parse_om_version(self, version: str) -> tuple[int, int, int]:
10271025
match = re.search(r"v?(\d+)\.(\d+)\.(\d+)", version)
10281026
if not match:
10291027
raise ValueError(f"Version not found in: {version}")
10301028
major, minor, patch = map(int, match.groups())
1029+
10311030
return major, minor, patch
10321031

1032+
def _process_override_data(
1033+
self,
1034+
om_cmd: ModelicaSystemCmd,
1035+
override_file: OMCPath,
1036+
override_var: dict[str, str],
1037+
override_sim: dict[str, str],
1038+
) -> None:
1039+
"""
1040+
Define the override parameters. As the definition of simulation specific override parameter changes with OM
1041+
1.26.0, version specific code is needed. Please keep in mind, that this will fail if OMC is not used to run the
1042+
model executable.
1043+
"""
1044+
if len(override_var) == 0 and len(override_sim) == 0:
1045+
return
1046+
1047+
override_content = ""
1048+
if override_var:
1049+
override_content += "\n".join([f"{key}={value}" for key, value in override_var.items()]) + "\n"
1050+
1051+
# simulation options are not read from override file from version >= 1.26.0,
1052+
# pass them to simulation executable directly as individual arguments
1053+
# see https://github.com/OpenModelica/OpenModelica/pull/14813
1054+
if override_sim:
1055+
if self._version >= (1, 26, 0):
1056+
for key, opt_value in override_sim.items():
1057+
om_cmd.arg_set(key=key, val=str(opt_value))
1058+
else:
1059+
override_content += "\n".join([f"{key}={value}" for key, value in override_sim.items()]) + "\n"
1060+
1061+
if override_content:
1062+
override_file.write_text(override_content)
1063+
om_cmd.arg_set(key="overrideFile", val=override_file.as_posix())
1064+
10331065
def simulate_cmd(
10341066
self,
10351067
result_file: OMCPath,
@@ -1073,29 +1105,12 @@ def simulate_cmd(
10731105
if simargs:
10741106
om_cmd.args_set(args=simargs)
10751107

1076-
if self._override_variables or self._simulate_options_override:
1077-
override_file = result_file.parent / f"{result_file.stem}_override.txt"
1078-
1079-
# simulation options are not read from override file from version >= 1.26.0,
1080-
# pass them to simulation executable directly as individual arguments
1081-
# see https://github.com/OpenModelica/OpenModelica/pull/14813
1082-
major, minor, patch = self.parse_om_version(self._version)
1083-
if (major, minor, patch) >= (1, 26, 0):
1084-
for key, opt_value in self._simulate_options_override.items():
1085-
om_cmd.arg_set(key=key, val=str(opt_value))
1086-
override_content = (
1087-
"\n".join([f"{key}={value}" for key, value in self._override_variables.items()])
1088-
+ "\n"
1089-
)
1090-
else:
1091-
override_content = (
1092-
"\n".join([f"{key}={value}" for key, value in self._override_variables.items()])
1093-
+ "\n".join([f"{key}={value}" for key, value in self._simulate_options_override.items()])
1094-
+ "\n"
1095-
)
1096-
1097-
override_file.write_text(override_content)
1098-
om_cmd.arg_set(key="overrideFile", val=override_file.as_posix())
1108+
self._process_override_data(
1109+
om_cmd=om_cmd,
1110+
override_file=result_file.parent / f"{result_file.stem}_override.txt",
1111+
override_var=self._override_variables,
1112+
override_sim=self._simulate_options_override,
1113+
)
10991114

11001115
if self._inputs: # if model has input quantities
11011116
for key, val in self._inputs.items():
@@ -1775,26 +1790,12 @@ def linearize(
17751790
modelname=self._model_name,
17761791
)
17771792

1778-
# See comment in simulate_cmd regarding override file and OM version
1779-
major, minor, patch = self.parse_om_version(self._version)
1780-
if (major, minor, patch) >= (1, 26, 0):
1781-
for key, opt_value in self._linearization_options.items():
1782-
om_cmd.arg_set(key=key, val=str(opt_value))
1783-
override_content = (
1784-
"\n".join([f"{key}={value}" for key, value in self._override_variables.items()])
1785-
+ "\n"
1786-
)
1787-
else:
1788-
override_content = (
1789-
"\n".join([f"{key}={value}" for key, value in self._override_variables.items()])
1790-
+ "\n".join([f"{key}={value}" for key, value in self._linearization_options.items()])
1791-
+ "\n"
1792-
)
1793-
1794-
override_file = self.getWorkDirectory() / f'{self._model_name}_override_linear.txt'
1795-
override_file.write_text(override_content)
1796-
1797-
om_cmd.arg_set(key="overrideFile", val=override_file.as_posix())
1793+
self._process_override_data(
1794+
om_cmd=om_cmd,
1795+
override_file=self.getWorkDirectory() / f'{self._model_name}_override_linear.txt',
1796+
override_var=self._override_variables,
1797+
override_sim=self._linearization_options,
1798+
)
17981799

17991800
if self._inputs:
18001801
for key, data in self._inputs.items():

0 commit comments

Comments
 (0)