Skip to content

Commit 67713a5

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent 9967a55 commit 67713a5

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
@@ -1783,11 +1783,11 @@ def run_doe():
17831783
simargs={"override": {'stopTime': 1.0}},
17841784
)
17851785
doe_mod.prepare()
1786-
doe_dict = doe_mod.get_doe()
1786+
doe_def = doe_mod.get_doe_definition()
17871787
doe_mod.simulate()
1788-
doe_sol = doe_mod.get_solutions()
1788+
doe_sol = doe_mod.get_doe_solutions()
17891789
1790-
# ... work with doe_df and doe_sol ...
1790+
# ... work with doe_def and doe_sol ...
17911791
17921792
17931793
if __name__ == "__main__":
@@ -1853,8 +1853,8 @@ def __init__(
18531853
else:
18541854
self._parameters = {}
18551855

1856-
self._sim_dict: Optional[dict[str, dict[str, Any]]] = None
1857-
self._sim_task_query: queue.Queue = queue.Queue()
1856+
self._doe_def: Optional[dict[str, dict[str, Any]]] = None
1857+
self._doe_cmd: Optional[dict[str, OMCSessionRunData]] = None
18581858

18591859
def prepare(self) -> int:
18601860
"""
@@ -1864,6 +1864,9 @@ def prepare(self) -> int:
18641864
The return value is the number of simulation defined.
18651865
"""
18661866

1867+
doe_sim = {}
1868+
doe_def = {}
1869+
18671870
param_structure = {}
18681871
param_simple = {}
18691872
for param_name in self._parameters.keys():
@@ -1878,18 +1881,11 @@ def prepare(self) -> int:
18781881
param_structure_combinations = list(itertools.product(*param_structure.values()))
18791882
param_simple_combinations = list(itertools.product(*param_simple.values()))
18801883

1881-
self._sim_dict = {}
18821884
for idx_pc_structure, pc_structure in enumerate(param_structure_combinations):
1883-
mod_structure = ModelicaSystem(
1884-
fileName=self._fileName,
1885-
modelName=self._modelName,
1886-
lmodel=self._lmodel,
1887-
commandLineOptions=self._CommandLineOptions,
1888-
variableFilter=self._variableFilter,
1889-
customBuildDirectory=self._customBuildDirectory,
1890-
omhome=self._omhome,
1891-
build=False,
1892-
)
1885+
1886+
build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}"
1887+
build_dir.mkdir()
1888+
self._mod.setWorkDirectory(customBuildDirectory=build_dir)
18931889

18941890
sim_param_structure = {}
18951891
for idx_structure, pk_structure in enumerate(param_structure.keys()):
@@ -1908,7 +1904,7 @@ def prepare(self) -> int:
19081904
raise ModelicaSystemError(f"Cannot set structural parameter {self._modelName}.{pk_structure} "
19091905
f"to {pk_value} using {repr(expression)}")
19101906

1911-
mod_structure.buildModel(variableFilter=self._variableFilter)
1907+
self._mod.buildModel()
19121908

19131909
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
19141910
sim_param_simple = {}
@@ -1935,23 +1931,26 @@ def prepare(self) -> int:
19351931
}
19361932
)
19371933

1938-
self._sim_dict[resfilename] = df_data
1939-
1940-
mscmd = mod_structure.simulate_cmd(
1941-
result_file=resultfile.absolute().resolve(),
1934+
self._mod.setParameters(sim_param_simple)
1935+
mscmd = self._mod.simulate_cmd(
1936+
result_file=resultfile,
19421937
timeout=self._timeout,
19431938
)
19441939
if self._simargs is not None:
19451940
mscmd.args_set(args=self._simargs)
1946-
mscmd.args_set(args={"override": sim_param_simple})
1941+
cmd_definition = mscmd.definition()
1942+
del mscmd
19471943

1948-
self._sim_task_query.put(mscmd)
1944+
doe_sim[resfilename] = cmd_definition
1945+
doe_def[resfilename] = df_data
19491946

1950-
logger.info(f"Prepared {self._sim_task_query.qsize()} simulation definitions for the defined DoE.")
1947+
logger.info(f"Prepared {len(doe_sim)} simulation definitions for the defined DoE.")
1948+
self._doe_cmd = doe_sim
1949+
self._doe_def = doe_def
19511950

1952-
return self._sim_task_query.qsize()
1951+
return len(doe_sim)
19531952

1954-
def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
1953+
def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]:
19551954
"""
19561955
Get the defined DoE as a dict, where each key is the result filename and the value is a dict of simulation
19571956
settings including structural and non-structural parameters.
@@ -1961,12 +1960,18 @@ def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
19611960
```
19621961
import pandas as pd
19631962
1964-
doe_dict = doe_mod.get_doe()
1963+
doe_dict = doe_mod.get_doe_definition()
19651964
doe_df = pd.DataFrame.from_dict(data=doe_dict, orient='index')
19661965
```
19671966
19681967
"""
1969-
return self._sim_dict
1968+
return self._doe_def
1969+
1970+
def get_doe_command(self) -> Optional[dict[str, OMCSessionRunData]]:
1971+
"""
1972+
Get the definitions of simulations commands to run for this DoE.
1973+
"""
1974+
return self._doe_cmd
19701975

19711976
def simulate(
19721977
self,
@@ -1978,71 +1983,85 @@ def simulate(
19781983
Returns True if all simulations were done successfully, else False.
19791984
"""
19801985

1981-
sim_query_total = self._sim_task_query.qsize()
1982-
if not isinstance(self._sim_dict, dict) or len(self._sim_dict) == 0:
1986+
if self._doe_cmd is None or self._doe_def is None:
1987+
raise ModelicaSystemError("DoE preparation missing - call prepare() first!")
1988+
1989+
doe_cmd_total = len(self._doe_cmd)
1990+
doe_def_total = len(self._doe_def)
1991+
1992+
if doe_cmd_total != doe_def_total:
1993+
raise ModelicaSystemError(f"Mismatch between number simulation commands ({doe_cmd_total}) "
1994+
f"and simulation definitions ({doe_def_total}).")
1995+
1996+
doe_task_query: queue.Queue = queue.Queue()
1997+
if self._doe_cmd is not None:
1998+
for doe_cmd in self._doe_cmd.values():
1999+
doe_task_query.put(doe_cmd)
2000+
2001+
if not isinstance(self._doe_def, dict) or len(self._doe_def) == 0:
19832002
raise ModelicaSystemError("Missing Doe Summary!")
1984-
sim_dict_total = len(self._sim_dict)
19852003

19862004
def worker(worker_id, task_queue):
19872005
while True:
19882006
try:
19892007
# Get the next task from the queue
1990-
mscmd = task_queue.get(block=False)
2008+
cmd_definition = task_queue.get(block=False)
19912009
except queue.Empty:
19922010
logger.info(f"[Worker {worker_id}] No more simulations to run.")
19932011
break
19942012

1995-
if mscmd is None:
2013+
if cmd_definition is None:
19962014
raise ModelicaSystemError("Missing simulation definition!")
19972015

1998-
resultfile = mscmd.arg_get(key='r')
1999-
resultpath = pathlib.Path(resultfile)
2016+
resultfile = cmd_definition.cmd_result_path
2017+
resultpath = self._mod._getconn.omcpath(resultfile)
20002018

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

20032021
try:
2004-
mscmd.run()
2022+
returncode = self._mod._getconn.run_model_executable(cmd_run_data=cmd_definition)
2023+
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
2024+
f"finished with return code: {returncode}")
20052025
except ModelicaSystemError as ex:
20062026
logger.warning(f"Simulation error for {resultpath.name}: {ex}")
20072027

20082028
# Mark the task as done
20092029
task_queue.task_done()
20102030

2011-
sim_query_done = sim_query_total - self._sim_task_query.qsize()
2031+
sim_query_done = doe_cmd_total - doe_task_query.qsize()
20122032
logger.info(f"[Worker {worker_id}] Task completed: {resultpath.name} "
2013-
f"({sim_query_total - sim_query_done}/{sim_query_total} = "
2014-
f"{(sim_query_total - sim_query_done) / sim_query_total * 100:.2f}% of tasks left)")
2015-
2016-
logger.info(f"Start simulations for DoE with {sim_query_total} simulations "
2017-
f"using {num_workers} workers ...")
2033+
f"({doe_cmd_total - sim_query_done}/{doe_cmd_total} = "
2034+
f"{(doe_cmd_total - sim_query_done) / doe_cmd_total * 100:.2f}% of tasks left)")
20182035

20192036
# Create and start worker threads
2037+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
2038+
f"using {num_workers} workers ...")
20202039
threads = []
20212040
for i in range(num_workers):
2022-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
2041+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
20232042
thread.start()
20242043
threads.append(thread)
20252044

20262045
# Wait for all threads to complete
20272046
for thread in threads:
20282047
thread.join()
20292048

2030-
sim_dict_done = 0
2031-
for resultfilename in self._sim_dict:
2049+
doe_def_done = 0
2050+
for resultfilename in self._doe_def:
20322051
resultfile = self._resultpath / resultfilename
20332052

20342053
# include check for an empty (=> 0B) result file which indicates a crash of the model executable
20352054
# see: https://github.com/OpenModelica/OMPython/issues/261
20362055
# https://github.com/OpenModelica/OpenModelica/issues/13829
2037-
if resultfile.is_file() and resultfile.stat().st_size > 0:
2038-
self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE] = True
2039-
sim_dict_done += 1
2056+
if resultfile.is_file() and resultfile.size() > 0:
2057+
self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE] = True
2058+
doe_def_done += 1
20402059

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

2043-
return sim_dict_total == sim_dict_done
2062+
return doe_def_total == doe_def_done
20442063

2045-
def get_solutions(
2064+
def get_doe_solutions(
20462065
self,
20472066
var_list: Optional[list] = None,
20482067
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -2058,7 +2077,7 @@ def get_solutions(
20582077
```
20592078
import pandas as pd
20602079
2061-
doe_sol = doe_mod.get_solutions()
2080+
doe_sol = doe_mod.get_doe_solutions()
20622081
for key in doe_sol:
20632082
data = doe_sol[key]['data']
20642083
if data:
@@ -2068,20 +2087,22 @@ def get_solutions(
20682087
```
20692088
20702089
"""
2071-
if not isinstance(self._sim_dict, dict):
2090+
if not isinstance(self._doe_def, dict):
20722091
return None
20732092

2074-
if len(self._sim_dict) == 0:
2093+
if len(self._doe_def) == 0:
20752094
raise ModelicaSystemError("No result files available - all simulations did fail?")
20762095

20772096
sol_dict: dict[str, dict[str, Any]] = {}
2078-
for resultfilename in self._sim_dict:
2097+
for resultfilename in self._doe_def:
20792098
resultfile = self._resultpath / resultfilename
20802099

20812100
sol_dict[resultfilename] = {}
20822101

2083-
if not self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE]:
2084-
sol_dict[resultfilename]['msg'] = 'No result file available!'
2102+
if not self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE]:
2103+
msg = f"No result file available for {resultfilename}"
2104+
logger.warning(msg)
2105+
sol_dict[resultfilename]['msg'] = msg
20852106
sol_dict[resultfilename]['data'] = {}
20862107
continue
20872108

0 commit comments

Comments
 (0)