Skip to content

Commit e044f5b

Browse files
committed
[ModelicaSystemDoE] rename variables & cleanup
1 parent ad19fe9 commit e044f5b

1 file changed

Lines changed: 77 additions & 57 deletions

File tree

OMPython/ModelicaSystem.py

Lines changed: 77 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,11 +1717,11 @@ def run_doe():
17171717
simargs={"override": {'stopTime': 1.0}},
17181718
)
17191719
doe_mod.prepare()
1720-
doe_dict = doe_mod.get_doe()
1720+
doe_def = doe_mod.get_doe_definition()
17211721
doe_mod.simulate()
1722-
doe_sol = doe_mod.get_solutions()
1722+
doe_sol = doe_mod.get_doe_solutions()
17231723
1724-
# ... work with doe_df and doe_sol ...
1724+
# ... work with doe_def and doe_sol ...
17251725
17261726
17271727
if __name__ == "__main__":
@@ -1787,8 +1787,8 @@ def __init__(
17871787
else:
17881788
self._parameters = {}
17891789

1790-
self._sim_dict: Optional[dict[str, dict[str, Any]]] = None
1791-
self._sim_task_query: queue.Queue = queue.Queue()
1790+
self._doe_def: Optional[dict[str, dict[str, Any]]] = None
1791+
self._doe_cmd: Optional[dict[str, OMCSessionRunData]] = None
17921792

17931793
def prepare(self) -> int:
17941794
"""
@@ -1798,6 +1798,9 @@ def prepare(self) -> int:
17981798
The return value is the number of simulation defined.
17991799
"""
18001800

1801+
doe_sim = {}
1802+
doe_def = {}
1803+
18011804
param_structure = {}
18021805
param_simple = {}
18031806
for param_name in self._parameters.keys():
@@ -1812,18 +1815,11 @@ def prepare(self) -> int:
18121815
param_structure_combinations = list(itertools.product(*param_structure.values()))
18131816
param_simple_combinations = list(itertools.product(*param_simple.values()))
18141817

1815-
self._sim_dict = {}
18161818
for idx_pc_structure, pc_structure in enumerate(param_structure_combinations):
1817-
mod_structure = ModelicaSystem(
1818-
fileName=self._fileName,
1819-
modelName=self._modelName,
1820-
lmodel=self._lmodel,
1821-
commandLineOptions=self._CommandLineOptions,
1822-
variableFilter=self._variableFilter,
1823-
customBuildDirectory=self._customBuildDirectory,
1824-
omhome=self._omhome,
1825-
build=False,
1826-
)
1819+
1820+
build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}"
1821+
build_dir.mkdir()
1822+
self._mod.setWorkDirectory(customBuildDirectory=build_dir)
18271823

18281824
sim_param_structure = {}
18291825
for idx_structure, pk_structure in enumerate(param_structure.keys()):
@@ -1842,7 +1838,7 @@ def prepare(self) -> int:
18421838
raise ModelicaSystemError(f"Cannot set structural parameter {self._modelName}.{pk_structure} "
18431839
f"to {pk_value} using {repr(expression)}")
18441840

1845-
mod_structure.buildModel(variableFilter=self._variableFilter)
1841+
self._mod.buildModel()
18461842

18471843
for idx_pc_simple, pc_simple in enumerate(param_simple_combinations):
18481844
sim_param_simple = {}
@@ -1869,23 +1865,26 @@ def prepare(self) -> int:
18691865
}
18701866
)
18711867

1872-
self._sim_dict[resfilename] = df_data
1873-
1874-
mscmd = mod_structure.simulate_cmd(
1875-
result_file=resultfile.absolute().resolve(),
1868+
self._mod.setParameters(sim_param_simple)
1869+
mscmd = self._mod.simulate_cmd(
1870+
result_file=resultfile,
18761871
timeout=self._timeout,
18771872
)
18781873
if self._simargs is not None:
18791874
mscmd.args_set(args=self._simargs)
1880-
mscmd.args_set(args={"override": sim_param_simple})
1875+
cmd_definition = mscmd.definition()
1876+
del mscmd
18811877

1882-
self._sim_task_query.put(mscmd)
1878+
doe_sim[resfilename] = cmd_definition
1879+
doe_def[resfilename] = df_data
18831880

1884-
logger.info(f"Prepared {self._sim_task_query.qsize()} simulation definitions for the defined DoE.")
1881+
logger.info(f"Prepared {len(doe_sim)} simulation definitions for the defined DoE.")
1882+
self._doe_cmd = doe_sim
1883+
self._doe_def = doe_def
18851884

1886-
return self._sim_task_query.qsize()
1885+
return len(doe_sim)
18871886

1888-
def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
1887+
def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]:
18891888
"""
18901889
Get the defined DoE as a dict, where each key is the result filename and the value is a dict of simulation
18911890
settings including structural and non-structural parameters.
@@ -1895,12 +1894,18 @@ def get_doe(self) -> Optional[dict[str, dict[str, Any]]]:
18951894
```
18961895
import pandas as pd
18971896
1898-
doe_dict = doe_mod.get_doe()
1897+
doe_dict = doe_mod.get_doe_definition()
18991898
doe_df = pd.DataFrame.from_dict(data=doe_dict, orient='index')
19001899
```
19011900
19021901
"""
1903-
return self._sim_dict
1902+
return self._doe_def
1903+
1904+
def get_doe_command(self) -> Optional[dict[str, OMCSessionRunData]]:
1905+
"""
1906+
Get the definitions of simulations commands to run for this DoE.
1907+
"""
1908+
return self._doe_cmd
19041909

19051910
def simulate(
19061911
self,
@@ -1912,71 +1917,84 @@ def simulate(
19121917
Returns True if all simulations were done successfully, else False.
19131918
"""
19141919

1915-
sim_query_total = self._sim_task_query.qsize()
1916-
if not isinstance(self._sim_dict, dict) or len(self._sim_dict) == 0:
1920+
if self._doe_cmd is None or self._doe_def is None:
1921+
raise ModelicaSystemError("DoE preparation missing - call prepare() first!")
1922+
1923+
doe_cmd_total = len(self._doe_cmd)
1924+
doe_def_total = len(self._doe_def)
1925+
1926+
if doe_cmd_total != doe_def_total:
1927+
raise ModelicaSystemError(f"Mismatch between number simulation commands ({doe_cmd_total}) "
1928+
f"and simulation definitions ({doe_def_total}).")
1929+
1930+
doe_task_query: queue.Queue = queue.Queue()
1931+
for doe_cmd in self._doe_cmd.values():
1932+
doe_task_query.put(doe_cmd)
1933+
1934+
if not isinstance(self._doe_def, dict) or len(self._doe_def) == 0:
19171935
raise ModelicaSystemError("Missing Doe Summary!")
1918-
sim_dict_total = len(self._sim_dict)
19191936

19201937
def worker(worker_id, task_queue):
19211938
while True:
19221939
try:
19231940
# Get the next task from the queue
1924-
mscmd = task_queue.get(block=False)
1941+
cmd_definition = task_queue.get(block=False)
19251942
except queue.Empty:
19261943
logger.info(f"[Worker {worker_id}] No more simulations to run.")
19271944
break
19281945

1929-
if mscmd is None:
1946+
if cmd_definition is None:
19301947
raise ModelicaSystemError("Missing simulation definition!")
19311948

1932-
resultfile = mscmd.arg_get(key='r')
1933-
resultpath = pathlib.Path(resultfile)
1949+
resultfile = cmd_definition.cmd_result_path
1950+
resultpath = self._mod._getconn.omcpath(resultfile)
19341951

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

19371954
try:
1938-
mscmd.run()
1955+
returncode = self._mod._getconn.run_model_executable(cmd_run_data=cmd_definition)
1956+
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
1957+
f"finished with return code: {returncode}")
19391958
except ModelicaSystemError as ex:
19401959
logger.warning(f"Simulation error for {resultpath.name}: {ex}")
19411960

19421961
# Mark the task as done
19431962
task_queue.task_done()
19441963

1945-
sim_query_done = sim_query_total - self._sim_task_query.qsize()
1964+
sim_query_done = doe_cmd_total - doe_task_query.qsize()
19461965
logger.info(f"[Worker {worker_id}] Task completed: {resultpath.name} "
1947-
f"({sim_query_total - sim_query_done}/{sim_query_total} = "
1948-
f"{(sim_query_total - sim_query_done) / sim_query_total * 100:.2f}% of tasks left)")
1949-
1950-
logger.info(f"Start simulations for DoE with {sim_query_total} simulations "
1951-
f"using {num_workers} workers ...")
1966+
f"({doe_cmd_total - sim_query_done}/{doe_cmd_total} = "
1967+
f"{(doe_cmd_total - sim_query_done) / doe_cmd_total * 100:.2f}% of tasks left)")
19521968

19531969
# Create and start worker threads
1970+
logger.info(f"Start simulations for DoE with {doe_cmd_total} simulations "
1971+
f"using {num_workers} workers ...")
19541972
threads = []
19551973
for i in range(num_workers):
1956-
thread = threading.Thread(target=worker, args=(i, self._sim_task_query))
1974+
thread = threading.Thread(target=worker, args=(i, doe_task_query))
19571975
thread.start()
19581976
threads.append(thread)
19591977

19601978
# Wait for all threads to complete
19611979
for thread in threads:
19621980
thread.join()
19631981

1964-
sim_dict_done = 0
1965-
for resultfilename in self._sim_dict:
1982+
doe_def_done = 0
1983+
for resultfilename in self._doe_def:
19661984
resultfile = self._resultpath / resultfilename
19671985

19681986
# include check for an empty (=> 0B) result file which indicates a crash of the model executable
19691987
# see: https://github.com/OpenModelica/OMPython/issues/261
19701988
# https://github.com/OpenModelica/OpenModelica/issues/13829
1971-
if resultfile.is_file() and resultfile.stat().st_size > 0:
1972-
self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE] = True
1973-
sim_dict_done += 1
1989+
if resultfile.is_file() and resultfile.size() > 0:
1990+
self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE] = True
1991+
doe_def_done += 1
19741992

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

1977-
return sim_dict_total == sim_dict_done
1995+
return doe_def_total == doe_def_done
19781996

1979-
def get_solutions(
1997+
def get_doe_solutions(
19801998
self,
19811999
var_list: Optional[list] = None,
19822000
) -> Optional[tuple[str] | dict[str, dict[str, np.ndarray]]]:
@@ -1992,7 +2010,7 @@ def get_solutions(
19922010
```
19932011
import pandas as pd
19942012
1995-
doe_sol = doe_mod.get_solutions()
2013+
doe_sol = doe_mod.get_doe_solutions()
19962014
for key in doe_sol:
19972015
data = doe_sol[key]['data']
19982016
if data:
@@ -2002,20 +2020,22 @@ def get_solutions(
20022020
```
20032021
20042022
"""
2005-
if not isinstance(self._sim_dict, dict):
2023+
if not isinstance(self._doe_def, dict):
20062024
return None
20072025

2008-
if len(self._sim_dict) == 0:
2026+
if len(self._doe_def) == 0:
20092027
raise ModelicaSystemError("No result files available - all simulations did fail?")
20102028

20112029
sol_dict: dict[str, dict[str, Any]] = {}
2012-
for resultfilename in self._sim_dict:
2030+
for resultfilename in self._doe_def:
20132031
resultfile = self._resultpath / resultfilename
20142032

20152033
sol_dict[resultfilename] = {}
20162034

2017-
if not self._sim_dict[resultfilename][self.DICT_RESULT_AVAILABLE]:
2018-
sol_dict[resultfilename]['msg'] = 'No result file available!'
2035+
if not self._doe_def[resultfilename][self.DICT_RESULT_AVAILABLE]:
2036+
msg = f"No result file available for {resultfilename}"
2037+
logger.warning(msg)
2038+
sol_dict[resultfilename]['msg'] = msg
20192039
sol_dict[resultfilename]['data'] = {}
20202040
continue
20212041

0 commit comments

Comments
 (0)