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 ,
@@ -263,8 +262,10 @@ def parse_simflags(simflags: str) -> dict[str, Optional[str | dict[str, Any] | n
263262
264263 The return data can be used as input for self.args_set().
265264 """
266- warnings .warn ("The argument 'simflags' is depreciated and will be removed in future versions; "
267- "please use 'simargs' instead" , DeprecationWarning , stacklevel = 2 )
265+ warnings .warn (message = "The argument 'simflags' is depreciated and will be removed in future versions; "
266+ "please use 'simargs' instead" ,
267+ category = DeprecationWarning ,
268+ stacklevel = 2 )
268269
269270 simargs : dict [str , Optional [str | dict [str , Any ] | numbers .Number ]] = {}
270271
@@ -332,14 +333,14 @@ def __init__(
332333 self ._simulate_options : dict [str , str ] = {}
333334 self ._override_variables : dict [str , str ] = {}
334335 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 ,
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 ) ,
340341 }
341342 self ._optimization_options = self ._linearization_options | {
342- 'numberOfIntervals' : 500 ,
343+ 'numberOfIntervals' : str ( 500 ) ,
343344 }
344345 self ._linearized_inputs : list [str ] = [] # linearization input list
345346 self ._linearized_outputs : list [str ] = [] # linearization output list
@@ -351,7 +352,8 @@ def __init__(
351352 self ._session = OMCSessionLocal (omhome = omhome )
352353
353354 # get OpenModelica version
354- 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 )
355357 # set commandLineOptions using default values or the user defined list
356358 if command_line_options is None :
357359 # set default command line options to improve the performance of linearization and to avoid recompilation if
@@ -559,7 +561,7 @@ def buildModel(self, variableFilter: Optional[str] = None):
559561
560562 def sendExpression (self , expr : str , parsed : bool = True ) -> Any :
561563 try :
562- retval = self ._session .sendExpression (expr , parsed )
564+ retval = self ._session .sendExpression (command = expr , parsed = parsed )
563565 except OMCSessionException as ex :
564566 raise ModelicaSystemError (f"Error executing { repr (expr )} : { ex } " ) from ex
565567
@@ -950,7 +952,7 @@ def getSimulationOptions(
950952 def getLinearizationOptions (
951953 self ,
952954 names : Optional [str | list [str ]] = None ,
953- ) -> dict [str , str | float ] | list [str | float ]:
955+ ) -> dict [str , str ] | list [str ]:
954956 """Get simulation options used for linearization.
955957
956958 Args:
@@ -964,17 +966,16 @@ def getLinearizationOptions(
964966 returned.
965967 If `names` is a list, a list with one value for each option name
966968 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.
969+
970+ The option values are always returned as strings.
970971
971972 Examples:
972973 >>> mod.getLinearizationOptions()
973- {'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' }
974975 >>> mod.getLinearizationOptions("stopTime")
975- [1.0]
976+ [' 1.0' ]
976977 >>> mod.getLinearizationOptions(["tolerance", "stopTime"])
977- [1e-08, 1.0]
978+ [' 1e-08', ' 1.0' ]
978979 """
979980 if names is None :
980981 return self ._linearization_options
@@ -988,7 +989,7 @@ def getLinearizationOptions(
988989 def getOptimizationOptions (
989990 self ,
990991 names : Optional [str | list [str ]] = None ,
991- ) -> dict [str , str | float ] | list [str | float ]:
992+ ) -> dict [str , str ] | list [str ]:
992993 """Get simulation options used for optimization.
993994
994995 Args:
@@ -1002,9 +1003,8 @@ def getOptimizationOptions(
10021003 returned.
10031004 If `names` is a list, a list with one value for each option name
10041005 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.
1006+
1007+ The option values are always returned as string.
10081008
10091009 Examples:
10101010 >>> mod.getOptimizationOptions()
@@ -1023,13 +1023,47 @@ def getOptimizationOptions(
10231023
10241024 raise ModelicaSystemError ("Unhandled input for getOptimizationOptions()" )
10251025
1026- def parse_om_version (self , version : str ) -> tuple [int , int , int ]:
1026+ def _parse_om_version (self , version : str ) -> tuple [int , int , int ]:
10271027 match = re .search (r"v?(\d+)\.(\d+)\.(\d+)" , version )
10281028 if not match :
10291029 raise ValueError (f"Version not found in: { version } " )
10301030 major , minor , patch = map (int , match .groups ())
1031+
10311032 return major , minor , patch
10321033
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+
10331067 def simulate_cmd (
10341068 self ,
10351069 result_file : OMCPath ,
@@ -1073,29 +1107,12 @@ def simulate_cmd(
10731107 if simargs :
10741108 om_cmd .args_set (args = simargs )
10751109
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 ())
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+ )
10991116
11001117 if self ._inputs : # if model has input quantities
11011118 for key , val in self ._inputs .items ():
@@ -1605,9 +1622,9 @@ def _createCSVData(self, csvfile: Optional[OMCPath] = None) -> OMCPath:
16051622 for signal_name , signal_values in inputs .items ():
16061623 signal = np .array (signal_values )
16071624 interpolated_inputs [signal_name ] = np .interp (
1608- all_times ,
1609- signal [:, 0 ], # times
1610- signal [:, 1 ], # values
1625+ x = all_times ,
1626+ xp = signal [:, 0 ], # times
1627+ fp = signal [:, 1 ], # values
16111628 )
16121629
16131630 # Write CSV file
@@ -1775,26 +1792,12 @@ def linearize(
17751792 modelname = self ._model_name ,
17761793 )
17771794
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 ())
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+ )
17981801
17991802 if self ._inputs :
18001803 for key , data in self ._inputs .items ():
0 commit comments