Skip to content

Commit 4acf74a

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent 65ac3b2 commit 4acf74a

File tree

1 file changed

+78
-57
lines changed

1 file changed

+78
-57
lines changed

OMPython/ModelicaSystem.py

Lines changed: 78 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,11 +1707,11 @@ def run_doe():
17071707
simargs={"override": {'stopTime': 1.0}},
17081708
)
17091709
doe_mod.prepare()
1710-
doe_dict = doe_mod.get_doe()
1710+
doe_def = doe_mod.get_doe_definition()
17111711
doe_mod.simulate()
1712-
doe_sol = doe_mod.get_solutions()
1712+
doe_sol = doe_mod.get_doe_solutions()
17131713
1714-
# ... work with doe_df and doe_sol ...
1714+
# ... work with doe_def and doe_sol ...
17151715
17161716
17171717
if __name__ == "__main__":
@@ -1777,8 +1777,8 @@ def __init__(
17771777
else:
17781778
self._parameters = {}
17791779

1780-
self._sim_dict: Optional[dict[str, dict[str, Any]]] = None
1781-
self._sim_task_query: queue.Queue = queue.Queue()
1780+
self._doe_def: Optional[dict[str, dict[str, Any]]] = None
1781+
self._doe_cmd: Optional[dict[str, OMCSessionRunData]] = None
17821782

17831783
def prepare(self) -> int:
17841784
"""
@@ -1788,6 +1788,9 @@ def prepare(self) -> int:
17881788
The return value is the number of simulation defined.
17891789
"""
17901790

1791+
doe_sim = {}
1792+
doe_def = {}
1793+
17911794
param_structure = {}
17921795
param_simple = {}
17931796
for param_name in self._parameters.keys():
@@ -1802,18 +1805,11 @@ def prepare(self) -> int:
18021805
param_structure_combinations = list(itertools.product(*param_structure.values()))
18031806
param_simple_combinations = list(itertools.product(*param_simple.values()))
18041807

1805-
self._sim_dict = {}
18061808
for idx_pc_structure, pc_structure in enumerate(param_structure_combinations):
1807-
mod_structure = ModelicaSystem(
1808-
fileName=self._fileName,
1809-
modelName=self._modelName,
1810-
lmodel=self._lmodel,
1811-
commandLineOptions=self._CommandLineOptions,
1812-
variableFilter=self._variableFilter,
1813-
customBuildDirectory=self._customBuildDirectory,
1814-
omhome=self._omhome,
1815-
build=False,
1816-
)
1809+
1810+
build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}"
1811+
build_dir.mkdir()
1812+
self._mod.setWorkDirectory(customBuildDirectory=build_dir)
18171813

18181814
sim_param_structure = {}
18191815
for idx_structure, pk_structure in enumerate(param_structure.keys()):
@@ -1832,7 +1828,7 @@ def prepare(self) -> int:
18321828
raise ModelicaSystemError(f"Cannot set structural parameter {self._modelName}.{pk_structure} "
18331829
f"to {pk_value} using {repr(expression)}")
18341830

1835-
mod_structure.buildModel(variableFilter=self._variableFilter)
1831+
self._mod.buildModel()
18361832

18371833
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
18381834
sim_param_simple = {}
@@ -1859,23 +1855,26 @@ def prepare(self) -> int:
18591855
}
18601856
)
18611857

1862-
self._sim_dict[resfilename] = df_data
1863-
1864-
mscmd = mod_structure.simulate_cmd(
1865-
result_file=resultfile.absolute().resolve(),
1858+
self._mod.setParameters(sim_param_simple)
1859+
mscmd = self._mod.simulate_cmd(
1860+
result_file=resultfile,
18661861
timeout=self._timeout,
18671862
)
18681863
if self._simargs is not None:
18691864
mscmd.args_set(args=self._simargs)
1870-
mscmd.args_set(args={"override": sim_param_simple})
1865+
cmd_definition = mscmd.definition()
1866+
del mscmd
18711867

1872-
self._sim_task_query.put(mscmd)
1868+
doe_sim[resfilename] = cmd_definition
1869+
doe_def[resfilename] = df_data
18731870

1874-
logger.info(f"Prepared {self._sim_task_query.qsize()} simulation definitions for the defined DoE.")
1871+
logger.info(f"Prepared {len(doe_sim)} simulation definitions for the defined DoE.")
1872+
self._doe_cmd = doe_sim
1873+
self._doe_def = doe_def
18751874

1876-
return self._sim_task_query.qsize()
1875+
return len(doe_sim)
18771876

1878-
def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
1877+
def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]:
18791878
"""
18801879
Get the defined DoE as a dict, where each key is the result filename and the value is a dict of simulation
18811880
settings including structural and non-structural parameters.
@@ -1885,12 +1884,18 @@ def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
18851884
```
18861885
import pandas as pd
18871886
1888-
doe_dict = doe_mod.get_doe()
1887+
doe_dict = doe_mod.get_doe_definition()
18891888
doe_df = pd.DataFrame.from_dict(data=doe_dict, orient='index')
18901889
```
18911890
18921891
"""
1893-
return self._sim_dict
1892+
return self._doe_def
1893+
1894+
def get_doe_command(self) -> Optional[dict[str, OMCSessionRunData]]:
1895+
"""
1896+
Get the definitions of simulations commands to run for this DoE.
1897+
"""
1898+
return self._doe_cmd
18941899

18951900
def simulate(
18961901
self,
@@ -1902,71 +1907,85 @@ def simulate(
19021907
Returns True if all simulations were done successfully, else False.
19031908
"""
19041909

1905-
sim_query_total = self._sim_task_query.qsize()
1906-
if not isinstance(self._sim_dict, dict) or len(self._sim_dict) == 0:
1910+
if self._doe_cmd is None or self._doe_def is None:
1911+
raise ModelicaSystemError("DoE preparation missing - call prepare() first!")
1912+
1913+
doe_cmd_total = len(self._doe_cmd)
1914+
doe_def_total = len(self._doe_def)
1915+
1916+
if doe_cmd_total != doe_def_total:
1917+
raise ModelicaSystemError(f"Mismatch between number simulation commands ({doe_cmd_total}) "
1918+
f"and simulation definitions ({doe_def_total}).")
1919+
1920+
doe_task_query: queue.Queue = queue.Queue()
1921+
if self._doe_cmd is not None:
1922+
for doe_cmd in self._doe_cmd.values():
1923+
doe_task_query.put(doe_cmd)
1924+
1925+
if not isinstance(self._doe_def, dict) or len(self._doe_def) == 0:
19071926
raise ModelicaSystemError("Missing Doe Summary!")
1908-
sim_dict_total = len(self._sim_dict)
19091927

19101928
def worker(worker_id, task_queue):
19111929
while True:
19121930
try:
19131931
# Get the next task from the queue
1914-
mscmd = task_queue.get(block=False)
1932+
cmd_definition = task_queue.get(block=False)
19151933
except queue.Empty:
19161934
logger.info(f"[Worker {worker_id}] No more simulations to run.")
19171935
break
19181936

1919-
if mscmd is None:
1937+
if cmd_definition is None:
19201938
raise ModelicaSystemError("Missing simulation definition!")
19211939

1922-
resultfile = mscmd.arg_get(key='r')
1923-
resultpath = pathlib.Path(resultfile)
1940+
resultfile = cmd_definition.cmd_result_path
1941+
resultpath = self._mod._getconn.omcpath(resultfile)
19241942

19251943
logger.info(f"[Worker {worker_id}] Performing task: {resultpath.name}")
19261944

19271945
try:
1928-
mscmd.run()
1946+
returncode = self._mod._getconn.run_model_executable(cmd_run_data=cmd_definition)
1947+
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
1948+
f"finished with return code: {returncode}")
19291949
except ModelicaSystemError as ex:
19301950
logger.warning(f"Simulation error for {resultpath.name}: {ex}")
19311951

19321952
# Mark the task as done
19331953
task_queue.task_done()
19341954

1935-
sim_query_done = sim_query_total - self._sim_task_query.qsize()
1955+
sim_query_done = doe_cmd_total - doe_task_query.qsize()
19361956
logger.info(f"[Worker {worker_id}] Task completed: {resultpath.name} "
1937-
f"({sim_query_total - sim_query_done}/{sim_query_total} = "
1938-
f"{(sim_query_total - sim_query_done) / sim_query_total * 100:.2f}% of tasks left)")
1939-
1940-
logger.info(f"Start simulations for DoE with {sim_query_total} simulations "
1941-
f"using {num_workers} workers ...")
1957+
f"({doe_cmd_total - sim_query_done}/{doe_cmd_total} = "
1958+
f"{(doe_cmd_total - sim_query_done) / doe_cmd_total * 100:.2f}% of tasks left)")
19421959

19431960
# Create and start worker threads
1961+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
1962+
f"using {num_workers} workers ...")
19441963
threads = []
19451964
for i in range(num_workers):
1946-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
1965+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
19471966
thread.start()
19481967
threads.append(thread)
19491968

19501969
# Wait for all threads to complete
19511970
for thread in threads:
19521971
thread.join()
19531972

1954-
sim_dict_done = 0
1955-
for resultfilename in self._sim_dict:
1973+
doe_def_done = 0
1974+
for resultfilename in self._doe_def:
19561975
resultfile = self._resultpath / resultfilename
19571976

19581977
# include check for an empty (=> 0B) result file which indicates a crash of the model executable
19591978
# see: https://github.com/OpenModelica/OMPython/issues/261
19601979
# https://github.com/OpenModelica/OpenModelica/issues/13829
1961-
if resultfile.is_file() and resultfile.stat().st_size > 0:
1962-
self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE] = True
1963-
sim_dict_done += 1
1980+
if resultfile.is_file() and resultfile.size() > 0:
1981+
self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE] = True
1982+
doe_def_done += 1
19641983

1965-
logger.info(f"All workers finished ({sim_dict_done} of {sim_dict_total} simulations with a result file).")
1984+
logger.info(f"All workers finished ({doe_def_done} of {doe_def_total} simulations with a result file).")
19661985

1967-
return sim_dict_total == sim_dict_done
1986+
return doe_def_total == doe_def_done
19681987

1969-
def get_solutions(
1988+
def get_doe_solutions(
19701989
self,
19711990
var_list: Optional[list] = None,
19721991
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -1982,7 +2001,7 @@ def get_solutions(
19822001
```
19832002
import pandas as pd
19842003
1985-
doe_sol = doe_mod.get_solutions()
2004+
doe_sol = doe_mod.get_doe_solutions()
19862005
for key in doe_sol:
19872006
data = doe_sol[key]['data']
19882007
if data:
@@ -1992,20 +2011,22 @@ def get_solutions(
19922011
```
19932012
19942013
"""
1995-
if not isinstance(self._sim_dict, dict):
2014+
if not isinstance(self._doe_def, dict):
19962015
return None
19972016

1998-
if len(self._sim_dict) == 0:
2017+
if len(self._doe_def) == 0:
19992018
raise ModelicaSystemError("No result files available - all simulations did fail?")
20002019

20012020
sol_dict: dict[str, dict[str, Any]] = {}
2002-
for resultfilename in self._sim_dict:
2021+
for resultfilename in self._doe_def:
20032022
resultfile = self._resultpath / resultfilename
20042023

20052024
sol_dict[resultfilename] = {}
20062025

2007-
if not self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE]:
2008-
sol_dict[resultfilename]['msg'] = 'No result file available!'
2026+
if not self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE]:
2027+
msg = f"No result file available for {resultfilename}"
2028+
logger.warning(msg)
2029+
sol_dict[resultfilename]['msg'] = msg
20092030
sol_dict[resultfilename]['data'] = {}
20102031
continue
20112032

0 commit comments

Comments
 (0)