@@ -124,9 +124,12 @@ def __init__(
124124 self ,
125125 session : OMCSessionZMQ ,
126126 runpath : OMCPath ,
127- modelname : str ,
127+ modelname : Optional [ str ] = None ,
128128 timeout : Optional [float ] = None ,
129129 ) -> None :
130+ if modelname is None :
131+ raise ModelicaSystemError ("Missing model name!" )
132+
130133 self ._session = session
131134 self ._runpath = runpath
132135 self ._model_name = modelname
@@ -321,60 +324,25 @@ def parse_simflags(simflags: str) -> dict[str, Optional[str | dict[str, Any] | n
321324class ModelicaSystem :
322325 def __init__ (
323326 self ,
324- fileName : Optional [str | os .PathLike ] = None ,
325- modelName : Optional [str ] = None ,
326- lmodel : Optional [list [str | tuple [str , str ]]] = None ,
327327 commandLineOptions : Optional [list [str ]] = None ,
328- variableFilter : Optional [str ] = None ,
329328 customBuildDirectory : Optional [str | os .PathLike ] = None ,
330329 omhome : Optional [str ] = None ,
331330 omc_process : Optional [OMCProcess ] = None ,
332- build : bool = True ,
333331 ) -> None :
334- """Initialize, load and build a model.
335-
336- The constructor loads the model file and builds it, generating exe and
337- xml files, etc.
332+ """Create a ModelicaSystem instance. To define the model use model() or convertFmu2Mo().
338333
339334 Args:
340- fileName: Path to the model file. Either absolute or relative to
341- the current working directory.
342- modelName: The name of the model class. If it is contained within
343- a package, "PackageName.ModelName" should be used.
344- lmodel: List of libraries to be loaded before the model itself is
345- loaded. Two formats are supported for the list elements:
346- lmodel=["Modelica"] for just the library name
347- and lmodel=[("Modelica","3.2.3")] for specifying both the name
348- and the version.
349335 commandLineOptions: List with extra command line options as elements. The list elements are
350336 provided to omc via setCommandLineOptions(). If set, the default values will be overridden.
351337 To disable any command line options, use an empty list.
352- variableFilter: A regular expression. Only variables fully
353- matching the regexp will be stored in the result file.
354- Leaving it unspecified is equivalent to ".*".
355338 customBuildDirectory: Path to a directory to be used for temporary
356339 files like the model executable. If left unspecified, a tmp
357340 directory will be created.
358- omhome: OPENMODELICAHOME value to be used when creating the OMC
359- session.
341+ omhome: path to OMC to be used when creating the OMC session (see OMCSessionZMQ).
360342 omc_process: definition of a (local) OMC process to be used. If
361343 unspecified, a new local session will be created.
362- build: Boolean controlling whether or not the model should be
363- built when constructor is called. If False, the constructor
364- simply loads the model without compiling.
365-
366- Examples:
367- mod = ModelicaSystem("ModelicaModel.mo", "modelName")
368- mod = ModelicaSystem("ModelicaModel.mo", "modelName", ["Modelica"])
369- mod = ModelicaSystem("ModelicaModel.mo", "modelName", [("Modelica","3.2.3"), "PowerSystems"])
370344 """
371345
372- if fileName is None and modelName is None and not lmodel : # all None
373- raise ModelicaSystemError ("Cannot create ModelicaSystem object without any arguments" )
374-
375- if modelName is None :
376- raise ModelicaSystemError ("A modelname must be provided (argument modelName)!" )
377-
378346 self ._quantities : list [dict [str , Any ]] = []
379347 self ._params : dict [str , str ] = {} # even numerical values are stored as str
380348 self ._inputs : dict [str , list | None ] = {}
@@ -408,44 +376,86 @@ def __init__(
408376 for opt in commandLineOptions :
409377 self .setCommandLineOptions (commandLineOptions = opt )
410378
411- if lmodel is None :
412- lmodel = []
379+ self ._simulated = False # True if the model has already been simulated
380+ self ._result_file : Optional [OMCPath ] = None # for storing result file
381+
382+ self ._work_dir : OMCPath = self .setWorkDirectory (customBuildDirectory )
383+
384+ self ._model_name : Optional [str ] = None
385+ self ._libraries : Optional [list [str | tuple [str , str ]]] = None
386+ self ._file_name : Optional [OMCPath ] = None
387+ self ._variable_filter : Optional [str ] = None
388+
389+ def model (
390+ self ,
391+ name : Optional [str ] = None ,
392+ file : Optional [str | os .PathLike ] = None ,
393+ libraries : Optional [list [str | tuple [str , str ]]] = None ,
394+ variable_filter : Optional [str ] = None ,
395+ build : bool = True ,
396+ ) -> None :
397+ """Load and build a Modelica model.
398+
399+ This method loads the model file and builds it if requested (build == True).
400+
401+ Args:
402+ file: Path to the model file. Either absolute or relative to
403+ the current working directory.
404+ name: The name of the model class. If it is contained within
405+ a package, "PackageName.ModelName" should be used.
406+ libraries: List of libraries to be loaded before the model itself is
407+ loaded. Two formats are supported for the list elements:
408+ lmodel=["Modelica"] for just the library name
409+ and lmodel=[("Modelica","3.2.3")] for specifying both the name
410+ and the version.
411+ variable_filter: A regular expression. Only variables fully
412+ matching the regexp will be stored in the result file.
413+ Leaving it unspecified is equivalent to ".*".
414+ build: Boolean controlling whether the model should be
415+ built when constructor is called. If False, the constructor
416+ simply loads the model without compiling.
417+
418+ Examples:
419+ mod = ModelicaSystem()
420+ # and then one of the lines below
421+ mod.model(name="modelName", file="ModelicaModel.mo", )
422+ mod.model(name="modelName", file="ModelicaModel.mo", libraries=["Modelica"])
423+ mod.model(name="modelName", file="ModelicaModel.mo", libraries=[("Modelica","3.2.3"), "PowerSystems"])
424+ """
425+
426+ if self ._model_name is not None :
427+ raise ModelicaSystemError ("Can not reuse this instance of ModelicaSystem "
428+ f"defined for { repr (self ._model_name )} !" )
429+
430+ if name is None or not isinstance (name , str ):
431+ raise ModelicaSystemError ("A model name must be provided!" )
432+
433+ if libraries is None :
434+ libraries = []
413435
414- if not isinstance (lmodel , list ):
415- raise ModelicaSystemError (f"Invalid input type for lmodel : { type (lmodel )} - list expected!" )
436+ if not isinstance (libraries , list ):
437+ raise ModelicaSystemError (f"Invalid input type for libraries : { type (libraries )} - list expected!" )
416438
417- self ._lmodel = lmodel # may be needed if model is derived from other model
418- self ._model_name = modelName # Model class name
419- if fileName is not None :
420- file_name = self ._session .omcpath (fileName ).resolve ()
439+ # set variables
440+ self ._model_name = name # Model class name
441+ self ._libraries = libraries # may be needed if model is derived from other model
442+ if file is not None :
443+ file_name = self ._session .omcpath (file ).resolve ()
421444 else :
422445 file_name = None
423- self ._file_name : Optional [OMCPath ] = file_name # Model file/package name
424- self ._simulated = False # True if the model has already been simulated
425- self ._result_file : Optional [OMCPath ] = None # for storing result file
426- self ._variable_filter = variableFilter
446+ self ._file_name = file_name # Model file/package name
447+ self ._variable_filter = variable_filter
427448
428449 if self ._file_name is not None and not self ._file_name .is_file (): # if file does not exist
429450 raise IOError (f"{ self ._file_name } does not exist!" )
430451
431- # set default command Line Options for linearization as
432- # linearize() will use the simulation executable and runtime
433- # flag -l to perform linearization
434- self .setCommandLineOptions ("--linearizationDumpLanguage=python" )
435- self .setCommandLineOptions ("--generateSymbolicLinearization" )
436-
437- self ._work_dir : OMCPath = self .setWorkDirectory (customBuildDirectory )
438-
452+ if self ._libraries :
453+ self ._loadLibrary (libraries = self ._libraries )
439454 if self ._file_name is not None :
440- self ._loadLibrary (lmodel = self ._lmodel )
441455 self ._loadFile (fileName = self ._file_name )
442456
443- # allow directly loading models from MSL without fileName
444- elif fileName is None and modelName is not None :
445- self ._loadLibrary (lmodel = self ._lmodel )
446-
447457 if build :
448- self .buildModel (variableFilter )
458+ self .buildModel (variable_filter )
449459
450460 def session (self ) -> OMCSessionZMQ :
451461 """
@@ -465,9 +475,9 @@ def _loadFile(self, fileName: OMCPath):
465475 self .sendExpression (f'loadFile("{ fileName .as_posix ()} ")' )
466476
467477 # for loading file/package, loading model and building model
468- def _loadLibrary (self , lmodel : list ):
478+ def _loadLibrary (self , libraries : list ):
469479 # load Modelica standard libraries or Modelica files if needed
470- for element in lmodel :
480+ for element in libraries :
471481 if element is not None :
472482 if isinstance (element , str ):
473483 if element .endswith (".mo" ):
@@ -1587,9 +1597,13 @@ def _createCSVData(self, csvfile: Optional[OMCPath] = None) -> OMCPath:
15871597
15881598 return csvfile
15891599
1590- def convertMo2Fmu (self , version : str = "2.0" , fmuType : str = "me_cs" ,
1591- fileNamePrefix : str = "<default>" ,
1592- includeResources : bool = True ) -> str :
1600+ def convertMo2Fmu (
1601+ self ,
1602+ version : str = "2.0" ,
1603+ fmuType : str = "me_cs" ,
1604+ fileNamePrefix : Optional [str ] = None ,
1605+ includeResources : bool = True ,
1606+ ) -> str :
15931607 """Translate the model into a Functional Mockup Unit.
15941608
15951609 Args:
@@ -1606,12 +1620,13 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs",
16061620 '/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu'
16071621 """
16081622
1609- if fileNamePrefix == "<default>" :
1610- fileNamePrefix = self ._model_name
1611- if includeResources :
1612- includeResourcesStr = "true"
1613- else :
1614- includeResourcesStr = "false"
1623+ if fileNamePrefix is None :
1624+ if self ._model_name is None :
1625+ fileNamePrefix = "<default>"
1626+ else :
1627+ fileNamePrefix = self ._model_name
1628+ includeResourcesStr = "true" if includeResources else "false"
1629+
16151630 properties = (f'version="{ version } ", fmuType="{ fmuType } ", '
16161631 f'fileNamePrefix="{ fileNamePrefix } ", includeResources={ includeResourcesStr } ' )
16171632 fmu = self ._requestApi (apiName = 'buildModelFMU' , entity = self ._model_name , properties = properties )
@@ -1903,15 +1918,17 @@ def __init__(
19031918 """
19041919
19051920 self ._mod = ModelicaSystem (
1906- fileName = fileName ,
1907- modelName = modelName ,
1908- lmodel = lmodel ,
19091921 commandLineOptions = commandLineOptions ,
1910- variableFilter = variableFilter ,
19111922 customBuildDirectory = customBuildDirectory ,
19121923 omhome = omhome ,
19131924 omc_process = omc_process ,
19141925 )
1926+ self ._mod .model (
1927+ file = fileName ,
1928+ name = modelName ,
1929+ libraries = lmodel ,
1930+ variable_filter = variableFilter ,
1931+ )
19151932
19161933 self ._model_name = modelName
19171934
0 commit comments