Skip to content

Commit f2e88fa

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent d37f6ff commit f2e88fa

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
@@ -1851,11 +1851,11 @@ def run_doe():
18511851
simargs={"override": {'stopTime': 1.0}},
18521852
)
18531853
doe_mod.prepare()
1854-
doe_dict = doe_mod.get_doe()
1854+
doe_def = doe_mod.get_doe_definition()
18551855
doe_mod.simulate()
1856-
doe_sol = doe_mod.get_solutions()
1856+
doe_sol = doe_mod.get_doe_solutions()
18571857
1858-
# ... work with doe_df and doe_sol ...
1858+
# ... work with doe_def and doe_sol ...
18591859
18601860
18611861
if __name__ == "__main__":
@@ -1927,8 +1927,8 @@ def __init__(
19271927
else:
19281928
self._parameters = {}
19291929

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

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

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

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

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

1992-
mod_structure.buildModel(variableFilter=self._variableFilter)
1988+
self._mod.buildModel()
19931989

19941990
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
19951991
sim_param_simple = {}
@@ -2016,23 +2012,26 @@ def prepare(self) -> int:
20162012
}
20172013
)
20182014

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

2029-
self._sim_task_query.put(mscmd)
2025+
doe_sim[resfilename] = cmd_definition
2026+
doe_def[resfilename] = df_data
20302027

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

2033-
return self._sim_task_query.qsize()
2032+
return len(doe_sim)
20342033

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

20522057
def simulate(
20532058
self,
@@ -2059,71 +2064,85 @@ def simulate(
20592064
Returns True if all simulations were done successfully, else False.
20602065
"""
20612066

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

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

2076-
if mscmd is None:
2094+
if cmd_definition is None:
20772095
raise ModelicaSystemError("Missing simulation definition!")
20782096

2079-
resultfile = mscmd.arg_get(key='r')
2097+
resultfile = cmd_definition.cmd_result_path
20802098
resultpath = self.session().omcpath(resultfile)
20812099

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

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

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

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

21002117
# Create and start worker threads
2118+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
2119+
f"using {num_workers} workers ...")
21012120
threads = []
21022121
for i in range(num_workers):
2103-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
2122+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
21042123
thread.start()
21052124
threads.append(thread)
21062125

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

2111-
sim_dict_done = 0
2112-
for resultfilename in self._sim_dict:
2130+
doe_def_done = 0
2131+
for resultfilename in self._doe_def:
21132132
resultfile = self._resultpath / resultfilename
21142133

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

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

2124-
return sim_dict_total == sim_dict_done
2143+
return doe_def_total == doe_def_done
21252144

2126-
def get_solutions(
2145+
def get_doe_solutions(
21272146
self,
21282147
var_list: Optional[list] = None,
21292148
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -2139,7 +2158,7 @@ def get_solutions(
21392158
```
21402159
import pandas as pd
21412160
2142-
doe_sol = doe_mod.get_solutions()
2161+
doe_sol = doe_mod.get_doe_solutions()
21432162
for key in doe_sol:
21442163
data = doe_sol[key]['data']
21452164
if data:
@@ -2149,20 +2168,22 @@ def get_solutions(
21492168
```
21502169
21512170
"""
2152-
if not isinstance(self._sim_dict, dict):
2171+
if not isinstance(self._doe_def, dict):
21532172
return None
21542173

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

21582177
sol_dict: dict[str, dict[str, Any]] = {}
2159-
for resultfilename in self._sim_dict:
2178+
for resultfilename in self._doe_def:
21602179
resultfile = self._resultpath / resultfilename
21612180

21622181
sol_dict[resultfilename] = {}
21632182

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

0 commit comments

Comments
 (0)