1111import os
1212import pathlib
1313import queue
14+ import re
1415import textwrap
1516import threading
1617from typing import Any , cast , Optional
1920
2021import numpy as np
2122
22- import re
23-
2423from OMPython .OMCSession import (
2524 OMCSessionException ,
2625 OMCSessionRunData ,
@@ -334,14 +333,14 @@ def __init__(
334333 self ._simulate_options : dict [str , str ] = {}
335334 self ._override_variables : dict [str , str ] = {}
336335 self ._simulate_options_override : dict [str , str ] = {}
337- self ._linearization_options : dict [str , str | float ] = {
338- 'startTime' : 0.0 ,
339- 'stopTime' : 1.0 ,
340- 'stepSize' : 0.002 ,
341- 'tolerance' : 1e-8 ,
336+ self ._linearization_options : dict [str , str ] = {
337+ 'startTime' : str ( 0.0 ) ,
338+ 'stopTime' : str ( 1.0 ) ,
339+ 'stepSize' : str ( 0.002 ) ,
340+ 'tolerance' : str ( 1e-8 ) ,
342341 }
343342 self ._optimization_options = self ._linearization_options | {
344- 'numberOfIntervals' : 500 ,
343+ 'numberOfIntervals' : str ( 500 ) ,
345344 }
346345 self ._linearized_inputs : list [str ] = [] # linearization input list
347346 self ._linearized_outputs : list [str ] = [] # linearization output list
@@ -353,7 +352,8 @@ def __init__(
353352 self ._session = OMCSessionLocal (omhome = omhome )
354353
355354 # get OpenModelica version
356- self ._version = self ._session .sendExpression ("getVersion()" , parsed = True )
355+ version_str = self .sendExpression (expr = "getVersion()" )
356+ self ._version = self ._parse_om_version (version = version_str )
357357 # set commandLineOptions using default values or the user defined list
358358 if command_line_options is None :
359359 # set default command line options to improve the performance of linearization and to avoid recompilation if
@@ -952,7 +952,7 @@ def getSimulationOptions(
952952 def getLinearizationOptions (
953953 self ,
954954 names : Optional [str | list [str ]] = None ,
955- ) -> dict [str , str | float ] | list [str | float ]:
955+ ) -> dict [str , str ] | list [str ]:
956956 """Get simulation options used for linearization.
957957
958958 Args:
@@ -966,17 +966,16 @@ def getLinearizationOptions(
966966 returned.
967967 If `names` is a list, a list with one value for each option name
968968 in names is returned: [option1_value, option2_value, ...].
969- Some option values are returned as float when first initialized,
970- but always as strings after setLinearizationOptions is used to
971- change them.
969+
970+ The option values are always returned as strings.
972971
973972 Examples:
974973 >>> mod.getLinearizationOptions()
975- {'startTime': 0.0, 'stopTime': 1.0, 'stepSize': 0.002, 'tolerance': 1e-08}
974+ {'startTime': ' 0.0' , 'stopTime': ' 1.0' , 'stepSize': ' 0.002' , 'tolerance': ' 1e-08' }
976975 >>> mod.getLinearizationOptions("stopTime")
977- [1.0]
976+ [' 1.0' ]
978977 >>> mod.getLinearizationOptions(["tolerance", "stopTime"])
979- [1e-08, 1.0]
978+ [' 1e-08', ' 1.0' ]
980979 """
981980 if names is None :
982981 return self ._linearization_options
@@ -990,7 +989,7 @@ def getLinearizationOptions(
990989 def getOptimizationOptions (
991990 self ,
992991 names : Optional [str | list [str ]] = None ,
993- ) -> dict [str , str | float ] | list [str | float ]:
992+ ) -> dict [str , str ] | list [str ]:
994993 """Get simulation options used for optimization.
995994
996995 Args:
@@ -1004,9 +1003,8 @@ def getOptimizationOptions(
10041003 returned.
10051004 If `names` is a list, a list with one value for each option name
10061005 in names is returned: [option1_value, option2_value, ...].
1007- Some option values are returned as float when first initialized,
1008- but always as strings after setOptimizationOptions is used to
1009- change them.
1006+
1007+ The option values are always returned as string.
10101008
10111009 Examples:
10121010 >>> mod.getOptimizationOptions()
@@ -1025,13 +1023,47 @@ def getOptimizationOptions(
10251023
10261024 raise ModelicaSystemError ("Unhandled input for getOptimizationOptions()" )
10271025
1028- def parse_om_version (self , version : str ) -> tuple [int , int , int ]:
1026+ def _parse_om_version (self , version : str ) -> tuple [int , int , int ]:
10291027 match = re .search (r"v?(\d+)\.(\d+)\.(\d+)" , version )
10301028 if not match :
10311029 raise ValueError (f"Version not found in: { version } " )
10321030 major , minor , patch = map (int , match .groups ())
1031+
10331032 return major , minor , patch
10341033
1034+ def _process_override_data (
1035+ self ,
1036+ om_cmd : ModelicaSystemCmd ,
1037+ override_file : OMCPath ,
1038+ override_var : dict [str , str ],
1039+ override_sim : dict [str , str ],
1040+ ) -> None :
1041+ """
1042+ Define the override parameters. As the definition of simulation specific override parameter changes with OM
1043+ 1.26.0, version specific code is needed. Please keep in mind, that this will fail if OMC is not used to run the
1044+ model executable.
1045+ """
1046+ if len (override_var ) == 0 and len (override_sim ) == 0 :
1047+ return
1048+
1049+ override_content = ""
1050+ if override_var :
1051+ override_content += "\n " .join ([f"{ key } ={ value } " for key , value in override_var .items ()]) + "\n "
1052+
1053+ # simulation options are not read from override file from version >= 1.26.0,
1054+ # pass them to simulation executable directly as individual arguments
1055+ # see https://github.com/OpenModelica/OpenModelica/pull/14813
1056+ if override_sim :
1057+ if self ._version >= (1 , 26 , 0 ):
1058+ for key , opt_value in override_sim .items ():
1059+ om_cmd .arg_set (key = key , val = str (opt_value ))
1060+ else :
1061+ override_content += "\n " .join ([f"{ key } ={ value } " for key , value in override_sim .items ()]) + "\n "
1062+
1063+ if override_content :
1064+ override_file .write_text (override_content )
1065+ om_cmd .arg_set (key = "overrideFile" , val = override_file .as_posix ())
1066+
10351067 def simulate_cmd (
10361068 self ,
10371069 result_file : OMCPath ,
@@ -1075,29 +1107,12 @@ def simulate_cmd(
10751107 if simargs :
10761108 om_cmd .args_set (args = simargs )
10771109
1078- if self ._override_variables or self ._simulate_options_override :
1079- override_file = result_file .parent / f"{ result_file .stem } _override.txt"
1080-
1081- # simulation options are not read from override file from version >= 1.26.0,
1082- # pass them to simulation executable directly as individual arguments
1083- # see https://github.com/OpenModelica/OpenModelica/pull/14813
1084- major , minor , patch = self .parse_om_version (self ._version )
1085- if (major , minor , patch ) >= (1 , 26 , 0 ):
1086- for key , opt_value in self ._simulate_options_override .items ():
1087- om_cmd .arg_set (key = key , val = str (opt_value ))
1088- override_content = (
1089- "\n " .join ([f"{ key } ={ value } " for key , value in self ._override_variables .items ()])
1090- + "\n "
1091- )
1092- else :
1093- override_content = (
1094- "\n " .join ([f"{ key } ={ value } " for key , value in self ._override_variables .items ()])
1095- + "\n " .join ([f"{ key } ={ value } " for key , value in self ._simulate_options_override .items ()])
1096- + "\n "
1097- )
1098-
1099- override_file .write_text (override_content )
1100- om_cmd .arg_set (key = "overrideFile" , val = override_file .as_posix ())
1110+ self ._process_override_data (
1111+ om_cmd = om_cmd ,
1112+ override_file = result_file .parent / f"{ result_file .stem } _override.txt" ,
1113+ override_var = self ._override_variables ,
1114+ override_sim = self ._simulate_options_override ,
1115+ )
11011116
11021117 if self ._inputs : # if model has input quantities
11031118 for key , val in self ._inputs .items ():
@@ -1777,26 +1792,12 @@ def linearize(
17771792 modelname = self ._model_name ,
17781793 )
17791794
1780- # See comment in simulate_cmd regarding override file and OM version
1781- major , minor , patch = self .parse_om_version (self ._version )
1782- if (major , minor , patch ) >= (1 , 26 , 0 ):
1783- for key , opt_value in self ._linearization_options .items ():
1784- om_cmd .arg_set (key = key , val = str (opt_value ))
1785- override_content = (
1786- "\n " .join ([f"{ key } ={ value } " for key , value in self ._override_variables .items ()])
1787- + "\n "
1788- )
1789- else :
1790- override_content = (
1791- "\n " .join ([f"{ key } ={ value } " for key , value in self ._override_variables .items ()])
1792- + "\n " .join ([f"{ key } ={ value } " for key , value in self ._linearization_options .items ()])
1793- + "\n "
1794- )
1795-
1796- override_file = self .getWorkDirectory () / f'{ self ._model_name } _override_linear.txt'
1797- override_file .write_text (override_content )
1798-
1799- om_cmd .arg_set (key = "overrideFile" , val = override_file .as_posix ())
1795+ self ._process_override_data (
1796+ om_cmd = om_cmd ,
1797+ override_file = self .getWorkDirectory () / f'{ self ._model_name } _override_linear.txt' ,
1798+ override_var = self ._override_variables ,
1799+ override_sim = self ._linearization_options ,
1800+ )
18001801
18011802 if self ._inputs :
18021803 for key , data in self ._inputs .items ():
0 commit comments