@@ -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 [tuple [float , float ]]] = {}
@@ -415,44 +383,86 @@ def __init__(
415383 for opt in commandLineOptions :
416384 self .setCommandLineOptions (commandLineOptions = opt )
417385
418- if lmodel is None :
419- lmodel = []
386+ self ._simulated = False # True if the model has already been simulated
387+ self ._result_file : Optional [OMCPath ] = None # for storing result file
388+
389+ self ._work_dir : OMCPath = self .setWorkDirectory (customBuildDirectory )
390+
391+ self ._model_name : Optional [str ] = None
392+ self ._libraries : Optional [list [str | tuple [str , str ]]] = None
393+ self ._file_name : Optional [OMCPath ] = None
394+ self ._variable_filter : Optional [str ] = None
395+
396+ def model (
397+ self ,
398+ name : Optional [str ] = None ,
399+ file : Optional [str | os .PathLike ] = None ,
400+ libraries : Optional [list [str | tuple [str , str ]]] = None ,
401+ variable_filter : Optional [str ] = None ,
402+ build : bool = True ,
403+ ) -> None :
404+ """Load and build a Modelica model.
405+
406+ This method loads the model file and builds it if requested (build == True).
407+
408+ Args:
409+ file: Path to the model file. Either absolute or relative to
410+ the current working directory.
411+ name: The name of the model class. If it is contained within
412+ a package, "PackageName.ModelName" should be used.
413+ libraries: List of libraries to be loaded before the model itself is
414+ loaded. Two formats are supported for the list elements:
415+ lmodel=["Modelica"] for just the library name
416+ and lmodel=[("Modelica","3.2.3")] for specifying both the name
417+ and the version.
418+ variable_filter: A regular expression. Only variables fully
419+ matching the regexp will be stored in the result file.
420+ Leaving it unspecified is equivalent to ".*".
421+ build: Boolean controlling whether the model should be
422+ built when constructor is called. If False, the constructor
423+ simply loads the model without compiling.
424+
425+ Examples:
426+ mod = ModelicaSystem()
427+ # and then one of the lines below
428+ mod.model(name="modelName", file="ModelicaModel.mo", )
429+ mod.model(name="modelName", file="ModelicaModel.mo", libraries=["Modelica"])
430+ mod.model(name="modelName", file="ModelicaModel.mo", libraries=[("Modelica","3.2.3"), "PowerSystems"])
431+ """
432+
433+ if self ._model_name is not None :
434+ raise ModelicaSystemError ("Can not reuse this instance of ModelicaSystem "
435+ f"defined for { repr (self ._model_name )} !" )
436+
437+ if name is None or not isinstance (name , str ):
438+ raise ModelicaSystemError ("A model name must be provided!" )
439+
440+ if libraries is None :
441+ libraries = []
420442
421- if not isinstance (lmodel , list ):
422- raise ModelicaSystemError (f"Invalid input type for lmodel : { type (lmodel )} - list expected!" )
443+ if not isinstance (libraries , list ):
444+ raise ModelicaSystemError (f"Invalid input type for libraries : { type (libraries )} - list expected!" )
423445
424- self ._lmodel = lmodel # may be needed if model is derived from other model
425- self ._model_name = modelName # Model class name
426- if fileName is not None :
427- file_name = self ._session .omcpath (fileName ).resolve ()
446+ # set variables
447+ self ._model_name = name # Model class name
448+ self ._libraries = libraries # may be needed if model is derived from other model
449+ if file is not None :
450+ file_name = self ._session .omcpath (file ).resolve ()
428451 else :
429452 file_name = None
430- self ._file_name : Optional [OMCPath ] = file_name # Model file/package name
431- self ._simulated = False # True if the model has already been simulated
432- self ._result_file : Optional [OMCPath ] = None # for storing result file
433- self ._variable_filter = variableFilter
453+ self ._file_name = file_name # Model file/package name
454+ self ._variable_filter = variable_filter
434455
435456 if self ._file_name is not None and not self ._file_name .is_file (): # if file does not exist
436457 raise IOError (f"{ self ._file_name } does not exist!" )
437458
438- # set default command Line Options for linearization as
439- # linearize() will use the simulation executable and runtime
440- # flag -l to perform linearization
441- self .setCommandLineOptions ("--linearizationDumpLanguage=python" )
442- self .setCommandLineOptions ("--generateSymbolicLinearization" )
443-
444- self ._work_dir : OMCPath = self .setWorkDirectory (customBuildDirectory )
445-
459+ if self ._libraries :
460+ self ._loadLibrary (libraries = self ._libraries )
446461 if self ._file_name is not None :
447- self ._loadLibrary (lmodel = self ._lmodel )
448462 self ._loadFile (fileName = self ._file_name )
449463
450- # allow directly loading models from MSL without fileName
451- elif fileName is None and modelName is not None :
452- self ._loadLibrary (lmodel = self ._lmodel )
453-
454464 if build :
455- self .buildModel (variableFilter )
465+ self .buildModel (variable_filter )
456466
457467 def session (self ) -> OMCSessionZMQ :
458468 """
@@ -472,9 +482,9 @@ def _loadFile(self, fileName: OMCPath):
472482 self .sendExpression (f'loadFile("{ fileName .as_posix ()} ")' )
473483
474484 # for loading file/package, loading model and building model
475- def _loadLibrary (self , lmodel : list ):
485+ def _loadLibrary (self , libraries : list ):
476486 # load Modelica standard libraries or Modelica files if needed
477- for element in lmodel :
487+ for element in libraries :
478488 if element is not None :
479489 if isinstance (element , str ):
480490 if element .endswith (".mo" ):
@@ -1615,9 +1625,13 @@ def _createCSVData(self, csvfile: Optional[OMCPath] = None) -> OMCPath:
16151625
16161626 return csvfile
16171627
1618- def convertMo2Fmu (self , version : str = "2.0" , fmuType : str = "me_cs" ,
1619- fileNamePrefix : str = "<default>" ,
1620- includeResources : bool = True ) -> str :
1628+ def convertMo2Fmu (
1629+ self ,
1630+ version : str = "2.0" ,
1631+ fmuType : str = "me_cs" ,
1632+ fileNamePrefix : Optional [str ] = None ,
1633+ includeResources : bool = True ,
1634+ ) -> str :
16211635 """Translate the model into a Functional Mockup Unit.
16221636
16231637 Args:
@@ -1634,12 +1648,13 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs",
16341648 '/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu'
16351649 """
16361650
1637- if fileNamePrefix == "<default>" :
1638- fileNamePrefix = self ._model_name
1639- if includeResources :
1640- includeResourcesStr = "true"
1641- else :
1642- includeResourcesStr = "false"
1651+ if fileNamePrefix is None :
1652+ if self ._model_name is None :
1653+ fileNamePrefix = "<default>"
1654+ else :
1655+ fileNamePrefix = self ._model_name
1656+ includeResourcesStr = "true" if includeResources else "false"
1657+
16431658 properties = (f'version="{ version } ", fmuType="{ fmuType } ", '
16441659 f'fileNamePrefix="{ fileNamePrefix } ", includeResources={ includeResourcesStr } ' )
16451660 fmu = self ._requestApi (apiName = 'buildModelFMU' , entity = self ._model_name , properties = properties )
@@ -1931,15 +1946,17 @@ def __init__(
19311946 """
19321947
19331948 self ._mod = ModelicaSystem (
1934- fileName = fileName ,
1935- modelName = modelName ,
1936- lmodel = lmodel ,
19371949 commandLineOptions = commandLineOptions ,
1938- variableFilter = variableFilter ,
19391950 customBuildDirectory = customBuildDirectory ,
19401951 omhome = omhome ,
19411952 omc_process = omc_process ,
19421953 )
1954+ self ._mod .model (
1955+ file = fileName ,
1956+ name = modelName ,
1957+ libraries = lmodel ,
1958+ variable_filter = variableFilter ,
1959+ )
19431960
19441961 self ._model_name = modelName
19451962
0 commit comments