Skip to content

[ModelicaSystem] update handling of work directory #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 40 additions & 25 deletions OMPython/ModelicaSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def __init__(
lmodel: Optional[list[str | tuple[str, str]]] = None,
commandLineOptions: Optional[str] = None,
variableFilter: Optional[str] = None,
customBuildDirectory: Optional[str | os.PathLike | pathlib.Path] = None,
customBuildDirectory: Optional[str | os.PathLike] = None,
omhome: Optional[str] = None,
omc_process: Optional[OMCProcessLocal] = None,
build: bool = True,
Expand Down Expand Up @@ -397,7 +397,7 @@ def __init__(
self.setCommandLineOptions("--linearizationDumpLanguage=python")
self.setCommandLineOptions("--generateSymbolicLinearization")

self._tempdir = self.setTempDirectory(customBuildDirectory)
self._work_dir: pathlib.Path = self.setWorkDirectory(customBuildDirectory)

if self._file_name is not None:
self._loadLibrary(lmodel=self._lmodel)
Expand Down Expand Up @@ -445,25 +445,34 @@ def _loadLibrary(self, lmodel: list):
'1)["Modelica"]\n'
'2)[("Modelica","3.2.3"), "PowerSystems"]\n')

def setTempDirectory(self, customBuildDirectory: Optional[str | os.PathLike | pathlib.Path] = None) -> pathlib.Path:
# create a unique temp directory for each session and build the model in that directory
def setWorkDirectory(self, customBuildDirectory: Optional[str | os.PathLike] = None) -> pathlib.Path:
"""
Define the work directory for the ModelicaSystem / OpenModelica session. The model is build within this
directory. If no directory is defined a unique temporary directory is created.
"""
if customBuildDirectory is not None:
if not os.path.exists(customBuildDirectory):
raise IOError(f"{customBuildDirectory} does not exist")
tempdir = pathlib.Path(customBuildDirectory).absolute()
workdir = pathlib.Path(customBuildDirectory).absolute()
if not workdir.is_dir():
raise IOError(f"Provided work directory does not exists: {customBuildDirectory}!")
else:
tempdir = pathlib.Path(tempfile.mkdtemp()).absolute()
if not tempdir.is_dir():
raise IOError(f"{tempdir} could not be created")
workdir = pathlib.Path(tempfile.mkdtemp()).absolute()
if not workdir.is_dir():
raise IOError(f"{workdir} could not be created")

logger.info("Define tempdir as %s", tempdir)
exp = f'cd("{tempdir.as_posix()}")'
logger.info("Define work dir as %s", workdir)
exp = f'cd("{workdir.as_posix()}")'
self.sendExpression(exp)

return tempdir
# set the class variable _work_dir ...
self._work_dir = workdir
# ... and also return the defined path
return workdir

def getWorkDirectory(self) -> pathlib.Path:
return self._tempdir
"""
Return the defined working directory for this ModelicaSystem / OpenModelica session.
"""
return self._work_dir

def buildModel(self, variableFilter: Optional[str] = None):
if variableFilter is not None:
Expand Down Expand Up @@ -951,7 +960,11 @@ def simulate_cmd(
An instance if ModelicaSystemCmd to run the requested simulation.
"""

om_cmd = ModelicaSystemCmd(runpath=self._tempdir, modelname=self._model_name, timeout=timeout)
om_cmd = ModelicaSystemCmd(
runpath=self.getWorkDirectory(),
modelname=self._model_name,
timeout=timeout,
)

# always define the result file to use
om_cmd.arg_set(key="r", val=result_file.as_posix())
Expand Down Expand Up @@ -1023,11 +1036,11 @@ def simulate(

if resultfile is None:
# default result file generated by OM
self._result_file = self._tempdir / f"{self._model_name}_res.mat"
self._result_file = self.getWorkDirectory() / f"{self._model_name}_res.mat"
elif os.path.exists(resultfile):
self._result_file = pathlib.Path(resultfile)
else:
self._result_file = self._tempdir / resultfile
self._result_file = self.getWorkDirectory() / resultfile

om_cmd = self.simulate_cmd(
result_file=self._result_file,
Expand Down Expand Up @@ -1429,7 +1442,7 @@ def _createCSVData(self, csvfile: Optional[pathlib.Path] = None) -> pathlib.Path
csv_rows.append(row)

if csvfile is None:
csvfile = self._tempdir / f'{self._model_name}.csv'
csvfile = self.getWorkDirectory() / f'{self._model_name}.csv'

# basic definition of a CSV file using csv_rows as input
csv_content = "\n".join([",".join(map(str, row)) for row in csv_rows]) + "\n"
Expand Down Expand Up @@ -1553,9 +1566,13 @@ def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = N
"use ModelicaSystem() to build the model first"
)

om_cmd = ModelicaSystemCmd(runpath=self._tempdir, modelname=self._model_name, timeout=timeout)
om_cmd = ModelicaSystemCmd(
runpath=self.getWorkDirectory(),
modelname=self._model_name,
timeout=timeout,
)

overrideLinearFile = self._tempdir / f'{self._model_name}_override_linear.txt'
overrideLinearFile = self.getWorkDirectory() / f'{self._model_name}_override_linear.txt'

with open(file=overrideLinearFile, mode="w", encoding="utf-8") as fh:
for key1, value1 in self._override_variables.items():
Expand Down Expand Up @@ -1585,19 +1602,17 @@ def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = N
om_cmd.args_set(args=simargs)

# the file create by the model executable which contains the matrix and linear inputs, outputs and states
linear_file = self._tempdir / "linearized_model.py"

linear_file = self.getWorkDirectory() / "linearized_model.py"
linear_file.unlink(missing_ok=True)

returncode = om_cmd.run()
if returncode != 0:
raise ModelicaSystemError(f"Linearize failed with return code: {returncode}")

self._simulated = True

if not linear_file.exists():
raise ModelicaSystemError(f"Linearization failed: {linear_file} not found!")

self._simulated = True

# extract data from the python file with the linearized model using the ast module - this allows to get the
# needed information without executing the created code
linear_data = {}
Expand Down
Loading