Skip to content

Commit b9b4189

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent f0b3105 commit b9b4189

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
@@ -1784,11 +1784,11 @@ def run_doe():
17841784
simargs={"override": {'stopTime': 1.0}},
17851785
)
17861786
doe_mod.prepare()
1787-
doe_dict = doe_mod.get_doe()
1787+
doe_def = doe_mod.get_doe_definition()
17881788
doe_mod.simulate()
1789-
doe_sol = doe_mod.get_solutions()
1789+
doe_sol = doe_mod.get_doe_solutions()
17901790
1791-
# ... work with doe_df and doe_sol ...
1791+
# ... work with doe_def and doe_sol ...
17921792
17931793
17941794
if __name__ == "__main__":
@@ -1854,8 +1854,8 @@ def __init__(
18541854
else:
18551855
self._parameters = {}
18561856

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

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

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

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

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

1912-
mod_structure.buildModel(variableFilter=self._variableFilter)
1908+
self._mod.buildModel()
19131909

19141910
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
19151911
sim_param_simple = {}
@@ -1936,23 +1932,26 @@ def prepare(self) -> int:
19361932
}
19371933
)
19381934

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

1949-
self._sim_task_query.put(mscmd)
1945+
doe_sim[resfilename] = cmd_definition
1946+
doe_def[resfilename] = df_data
19501947

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

1953-
return self._sim_task_query.qsize()
1952+
return len(doe_sim)
19541953

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

19721977
def simulate(
19731978
self,
@@ -1979,71 +1984,85 @@ def simulate(
19791984
Returns True if all simulations were done successfully, else False.
19801985
"""
19811986

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

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

1996-
if mscmd is None:
2014+
if cmd_definition is None:
19972015
raise ModelicaSystemError("Missing simulation definition!")
19982016

1999-
resultfile = mscmd.arg_get(key='r')
2000-
resultpath = pathlib.Path(resultfile)
2017+
resultfile = cmd_definition.cmd_result_path
2018+
resultpath = self._mod._getconn.omcpath(resultfile)
20012019

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

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

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

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

20202037
# Create and start worker threads
2038+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
2039+
f"using {num_workers} workers ...")
20212040
threads = []
20222041
for i in range(num_workers):
2023-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
2042+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
20242043
thread.start()
20252044
threads.append(thread)
20262045

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

2031-
sim_dict_done = 0
2032-
for resultfilename in self._sim_dict:
2050+
doe_def_done = 0
2051+
for resultfilename in self._doe_def:
20332052
resultfile = self._resultpath / resultfilename
20342053

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

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

2044-
return sim_dict_total == sim_dict_done
2063+
return doe_def_total == doe_def_done
20452064

2046-
def get_solutions(
2065+
def get_doe_solutions(
20472066
self,
20482067
var_list: Optional[list] = None,
20492068
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -2059,7 +2078,7 @@ def get_solutions(
20592078
```
20602079
import pandas as pd
20612080
2062-
doe_sol = doe_mod.get_solutions()
2081+
doe_sol = doe_mod.get_doe_solutions()
20632082
for key in doe_sol:
20642083
data = doe_sol[key]['data']
20652084
if data:
@@ -2069,20 +2088,22 @@ def get_solutions(
20692088
```
20702089
20712090
"""
2072-
if not isinstance(self._sim_dict, dict):
2091+
if not isinstance(self._doe_def, dict):
20732092
return None
20742093

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

20782097
sol_dict: dict[str, dict[str, Any]] = {}
2079-
for resultfilename in self._sim_dict:
2098+
for resultfilename in self._doe_def:
20802099
resultfile = self._resultpath / resultfilename
20812100

20822101
sol_dict[resultfilename] = {}
20832102

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

0 commit comments

Comments
 (0)