Skip to content

Commit 0737297

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent b6c0119 commit 0737297

1 file changed

Lines changed: 76 additions & 55 deletions

File tree

OMPython/ModelicaSystem.py

Lines changed: 76 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,11 +1850,11 @@ def run_doe():
18501850
simargs={"override": {'stopTime': 1.0}},
18511851
)
18521852
doe_mod.prepare()
1853-
doe_dict = doe_mod.get_doe()
1853+
doe_def = doe_mod.get_doe_definition()
18541854
doe_mod.simulate()
1855-
doe_sol = doe_mod.get_solutions()
1855+
doe_sol = doe_mod.get_doe_solutions()
18561856
1857-
# ... work with doe_df and doe_sol ...
1857+
# ... work with doe_def and doe_sol ...
18581858
18591859
18601860
if __name__ == "__main__":
@@ -1926,8 +1926,8 @@ def __init__(
19261926
else:
19271927
self._parameters = {}
19281928

1929-
self._sim_dict: Optional[dict[str, dict[str, Any]]] = None
1930-
self._sim_task_query: queue.Queue = queue.Queue()
1929+
self._doe_def: Optional[dict[str, dict[str, Any]]] = None
1930+
self._doe_cmd: Optional[dict[str, OMCSessionRunData]] = None
19311931

19321932
def session(self) -> OMCSessionZMQ:
19331933
"""
@@ -1943,6 +1943,9 @@ def prepare(self) -> int:
19431943
The return value is the number of simulation defined.
19441944
"""
19451945

1946+
doe_sim = {}
1947+
doe_def = {}
1948+
19461949
param_structure = {}
19471950
param_non_structure = {}
19481951
for param_name in self._parameters.keys():
@@ -1957,18 +1960,11 @@ def prepare(self) -> int:
19571960
param_structure_combinations = list(itertools.product(*param_structure.values()))
19581961
param_simple_combinations = list(itertools.product(*param_non_structure.values()))
19591962

1960-
self._sim_dict = {}
19611963
for idx_pc_structure, pc_structure in enumerate(param_structure_combinations):
1962-
mod_structure = ModelicaSystem(
1963-
fileName=self._fileName,
1964-
modelName=self._modelName,
1965-
lmodel=self._lmodel,
1966-
commandLineOptions=self._CommandLineOptions,
1967-
variableFilter=self._variableFilter,
1968-
customBuildDirectory=self._customBuildDirectory,
1969-
omhome=self._omhome,
1970-
build=False,
1971-
)
1964+
1965+
build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}"
1966+
build_dir.mkdir()
1967+
self._mod.setWorkDirectory(customBuildDirectory=build_dir)
19721968

19731969
sim_param_structure = {}
19741970
for idx_structure, pk_structure in enumerate(param_structure.keys()):
@@ -1983,12 +1979,12 @@ def prepare(self) -> int:
19831979
expression = f"setParameterValue({self._modelName}, {pk_structure}, {pk_value_bool_str});"
19841980
else:
19851981
expression = f"setParameterValue({self._modelName}, {pk_structure}, {pk_value})"
1986-
res = mod_structure.sendExpression(expression)
1982+
res = self._mod.sendExpression(expression)
19871983
if not res:
19881984
raise ModelicaSystemError(f"Cannot set structural parameter {self._modelName}.{pk_structure} "
19891985
f"to {pk_value} using {repr(expression)}")
19901986

1991-
mod_structure.buildModel(variableFilter=self._variableFilter)
1987+
self._mod.buildModel()
19921988

19931989
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
19941990
sim_param_simple = {}
@@ -2015,23 +2011,26 @@ def prepare(self) -> int:
20152011
}
20162012
)
20172013

2018-
self._sim_dict[resfilename] = df_data
2019-
2020-
mscmd = mod_structure.simulate_cmd(
2014+
self._mod.setParameters(sim_param_simple)
2015+
mscmd = self._mod.simulate_cmd(
20212016
result_file=resultfile,
20222017
timeout=self._timeout,
20232018
)
20242019
if self._simargs is not None:
20252020
mscmd.args_set(args=self._simargs)
2026-
mscmd.args_set(args={"override": sim_param_simple})
2021+
cmd_definition = mscmd.definition()
2022+
del mscmd
20272023

2028-
self._sim_task_query.put(mscmd)
2024+
doe_sim[resfilename] = cmd_definition
2025+
doe_def[resfilename] = df_data
20292026

2030-
logger.info(f"Prepared {self._sim_task_query.qsize()} simulation definitions for the defined DoE.")
2027+
logger.info(f"Prepared {len(doe_sim)} simulation definitions for the defined DoE.")
2028+
self._doe_cmd = doe_sim
2029+
self._doe_def = doe_def
20312030

2032-
return self._sim_task_query.qsize()
2031+
return len(doe_sim)
20332032

2034-
def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
2033+
def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]:
20352034
"""
20362035
Get the defined DoE as a dict, where each key is the result filename and the value is a dict of simulation
20372036
settings including structural and non-structural parameters.
@@ -2041,12 +2040,18 @@ def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
20412040
```
20422041
import pandas as pd
20432042
2044-
doe_dict = doe_mod.get_doe()
2043+
doe_dict = doe_mod.get_doe_definition()
20452044
doe_df = pd.DataFrame.from_dict(data=doe_dict, orient='index')
20462045
```
20472046
20482047
"""
2049-
return self._sim_dict
2048+
return self._doe_def
2049+
2050+
def get_doe_command(self) -> Optional[dict[str, OMCSessionRunData]]:
2051+
"""
2052+
Get the definitions of simulations commands to run for this DoE.
2053+
"""
2054+
return self._doe_cmd
20502055

20512056
def simulate(
20522057
self,
@@ -2058,71 +2063,85 @@ def simulate(
20582063
Returns True if all simulations were done successfully, else False.
20592064
"""
20602065

2061-
sim_query_total = self._sim_task_query.qsize()
2062-
if not isinstance(self._sim_dict, dict) or len(self._sim_dict) == 0:
2066+
if self._doe_cmd is None or self._doe_def is None:
2067+
raise ModelicaSystemError("DoE preparation missing - call prepare() first!")
2068+
2069+
doe_cmd_total = len(self._doe_cmd)
2070+
doe_def_total = len(self._doe_def)
2071+
2072+
if doe_cmd_total != doe_def_total:
2073+
raise ModelicaSystemError(f"Mismatch between number simulation commands ({doe_cmd_total}) "
2074+
f"and simulation definitions ({doe_def_total}).")
2075+
2076+
doe_task_query: queue.Queue = queue.Queue()
2077+
if self._doe_cmd is not None:
2078+
for doe_cmd in self._doe_cmd.values():
2079+
doe_task_query.put(doe_cmd)
2080+
2081+
if not isinstance(self._doe_def, dict) or len(self._doe_def) == 0:
20632082
raise ModelicaSystemError("Missing Doe Summary!")
2064-
sim_dict_total = len(self._sim_dict)
20652083

20662084
def worker(worker_id, task_queue):
20672085
while True:
20682086
try:
20692087
# Get the next task from the queue
2070-
mscmd = task_queue.get(block=False)
2088+
cmd_definition = task_queue.get(block=False)
20712089
except queue.Empty:
20722090
logger.info(f"[Worker {worker_id}] No more simulations to run.")
20732091
break
20742092

2075-
if mscmd is None:
2093+
if cmd_definition is None:
20762094
raise ModelicaSystemError("Missing simulation definition!")
20772095

2078-
resultfile = mscmd.arg_get(key='r')
2096+
resultfile = cmd_definition.cmd_result_path
20792097
resultpath = self.session().omcpath(resultfile)
20802098

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

20832101
try:
2084-
mscmd.run()
2102+
returncode = self._mod._getconn.run_model_executable(cmd_run_data=cmd_definition)
2103+
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
2104+
f"finished with return code: {returncode}")
20852105
except ModelicaSystemError as ex:
20862106
logger.warning(f"Simulation error for {resultpath.name}: {ex}")
20872107

20882108
# Mark the task as done
20892109
task_queue.task_done()
20902110

2091-
sim_query_done = sim_query_total - self._sim_task_query.qsize()
2111+
sim_query_done = doe_cmd_total - doe_task_query.qsize()
20922112
logger.info(f"[Worker {worker_id}] Task completed: {resultpath.name} "
2093-
f"({sim_query_total - sim_query_done}/{sim_query_total} = "
2094-
f"{(sim_query_total - sim_query_done) / sim_query_total * 100:.2f}% of tasks left)")
2095-
2096-
logger.info(f"Start simulations for DoE with {sim_query_total} simulations "
2097-
f"using {num_workers} workers ...")
2113+
f"({doe_cmd_total - sim_query_done}/{doe_cmd_total} = "
2114+
f"{(doe_cmd_total - sim_query_done) / doe_cmd_total * 100:.2f}% of tasks left)")
20982115

20992116
# Create and start worker threads
2117+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
2118+
f"using {num_workers} workers ...")
21002119
threads = []
21012120
for i in range(num_workers):
2102-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
2121+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
21032122
thread.start()
21042123
threads.append(thread)
21052124

21062125
# Wait for all threads to complete
21072126
for thread in threads:
21082127
thread.join()
21092128

2110-
sim_dict_done = 0
2111-
for resultfilename in self._sim_dict:
2129+
doe_def_done = 0
2130+
for resultfilename in self._doe_def:
21122131
resultfile = self._resultpath / resultfilename
21132132

21142133
# include check for an empty (=> 0B) result file which indicates a crash of the model executable
21152134
# see: https://github.com/OpenModelica/OMPython/issues/261
21162135
# https://github.com/OpenModelica/OpenModelica/issues/13829
21172136
if resultfile.is_file() and resultfile.size() > 0:
2118-
self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE] = True
2119-
sim_dict_done += 1
2137+
self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE] = True
2138+
doe_def_done += 1
21202139

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

2123-
return sim_dict_total == sim_dict_done
2142+
return doe_def_total == doe_def_done
21242143

2125-
def get_solutions(
2144+
def get_doe_solutions(
21262145
self,
21272146
var_list: Optional[list] = None,
21282147
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -2138,7 +2157,7 @@ def get_solutions(
21382157
```
21392158
import pandas as pd
21402159
2141-
doe_sol = doe_mod.get_solutions()
2160+
doe_sol = doe_mod.get_doe_solutions()
21422161
for key in doe_sol:
21432162
data = doe_sol[key]['data']
21442163
if data:
@@ -2148,20 +2167,22 @@ def get_solutions(
21482167
```
21492168
21502169
"""
2151-
if not isinstance(self._sim_dict, dict):
2170+
if not isinstance(self._doe_def, dict):
21522171
return None
21532172

2154-
if len(self._sim_dict) == 0:
2173+
if len(self._doe_def) == 0:
21552174
raise ModelicaSystemError("No result files available - all simulations did fail?")
21562175

21572176
sol_dict: dict[str, dict[str, Any]] = {}
2158-
for resultfilename in self._sim_dict:
2177+
for resultfilename in self._doe_def:
21592178
resultfile = self._resultpath / resultfilename
21602179

21612180
sol_dict[resultfilename] = {}
21622181

2163-
if not self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE]:
2164-
sol_dict[resultfilename]['msg'] = 'No result file available!'
2182+
if not self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE]:
2183+
msg = f"No result file available for {resultfilename}"
2184+
logger.warning(msg)
2185+
sol_dict[resultfilename]['msg'] = msg
21652186
sol_dict[resultfilename]['data'] = {}
21662187
continue
21672188

0 commit comments

Comments
 (0)