|
15 | 15 | import re |
16 | 16 | import textwrap |
17 | 17 | import threading |
18 | | -from typing import Any, cast, Optional |
| 18 | +from typing import Any, cast, Optional, Tuple |
19 | 19 | import warnings |
20 | 20 | import xml.etree.ElementTree as ET |
21 | 21 |
|
@@ -2108,9 +2108,9 @@ class ModelicaSystem(ModelicaSystemOMC): |
2108 | 2108 | """ |
2109 | 2109 |
|
2110 | 2110 |
|
2111 | | -class ModelicaSystemDoE: |
| 2111 | +class ModelicaDoEABC(metaclass=abc.ABCMeta): |
2112 | 2112 | """ |
2113 | | - Class to run DoEs based on a (Open)Modelica model using ModelicaSystem |
| 2113 | + Base class to run DoEs based on a (Open)Modelica model using ModelicaSystem |
2114 | 2114 |
|
2115 | 2115 | Example |
2116 | 2116 | ------- |
@@ -2252,30 +2252,11 @@ def prepare(self) -> int: |
2252 | 2252 | param_non_structural_combinations = list(itertools.product(*param_non_structure.values())) |
2253 | 2253 |
|
2254 | 2254 | for idx_pc_structure, pc_structure in enumerate(param_structure_combinations): |
2255 | | - |
2256 | | - build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}" |
2257 | | - build_dir.mkdir() |
2258 | | - self._mod.setWorkDirectory(work_directory=build_dir) |
2259 | | - |
2260 | | - sim_param_structure = {} |
2261 | | - for idx_structure, pk_structure in enumerate(param_structure.keys()): |
2262 | | - sim_param_structure[pk_structure] = pc_structure[idx_structure] |
2263 | | - |
2264 | | - pk_value = pc_structure[idx_structure] |
2265 | | - if isinstance(pk_value, str): |
2266 | | - pk_value_str = self.get_session().escape_str(pk_value) |
2267 | | - expr = f"setParameterValue({self._model_name}, {pk_structure}, \"{pk_value_str}\")" |
2268 | | - elif isinstance(pk_value, bool): |
2269 | | - pk_value_bool_str = "true" if pk_value else "false" |
2270 | | - expr = f"setParameterValue({self._model_name}, {pk_structure}, {pk_value_bool_str});" |
2271 | | - else: |
2272 | | - expr = f"setParameterValue({self._model_name}, {pk_structure}, {pk_value})" |
2273 | | - res = self._mod.sendExpression(expr=expr) |
2274 | | - if not res: |
2275 | | - raise ModelicaSystemError(f"Cannot set structural parameter {self._model_name}.{pk_structure} " |
2276 | | - f"to {pk_value} using {repr(expr)}") |
2277 | | - |
2278 | | - self._mod.buildModel() |
| 2255 | + sim_param_structure = self._prepare_structure_parameters( |
| 2256 | + idx_pc_structure=idx_pc_structure, |
| 2257 | + pc_structure=pc_structure, |
| 2258 | + param_structure=param_structure, |
| 2259 | + ) |
2279 | 2260 |
|
2280 | 2261 | for idx_non_structural, pk_non_structural in enumerate(param_non_structural_combinations): |
2281 | 2262 | sim_param_non_structural = {} |
@@ -2320,6 +2301,17 @@ def prepare(self) -> int: |
2320 | 2301 |
|
2321 | 2302 | return len(doe_sim) |
2322 | 2303 |
|
| 2304 | + @abc.abstractmethod |
| 2305 | + def _prepare_structure_parameters( |
| 2306 | + self, |
| 2307 | + idx_pc_structure: int, |
| 2308 | + pc_structure: Tuple, |
| 2309 | + param_structure: dict[str, list[str] | list[int] | list[float]], |
| 2310 | + ) -> dict[str, str | int | float]: |
| 2311 | + """ |
| 2312 | + Handle structural parameters. This should be implemented by the derived class |
| 2313 | + """ |
| 2314 | + |
2323 | 2315 | def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]: |
2324 | 2316 | """ |
2325 | 2317 | Get the defined DoE as a dict, where each key is the result filename and the value is a dict of simulation |
@@ -2431,6 +2423,64 @@ def worker(worker_id, task_queue): |
2431 | 2423 |
|
2432 | 2424 | return doe_def_total == doe_def_done |
2433 | 2425 |
|
| 2426 | + |
| 2427 | +class ModelicaSystemDoE(ModelicaDoEABC): |
| 2428 | + """ |
| 2429 | + Class to run DoEs based on a (Open)Modelica model using ModelicaSystemOMC |
| 2430 | +
|
| 2431 | + The example is the same as defined for ModelicaDoEABC |
| 2432 | + """ |
| 2433 | + |
| 2434 | + def __init__( |
| 2435 | + self, |
| 2436 | + # ModelicaSystem definition to use |
| 2437 | + mod: ModelicaSystemOMC, |
| 2438 | + # simulation specific input |
| 2439 | + # TODO: add more settings (simulation options, input options, ...) |
| 2440 | + simargs: Optional[dict[str, Optional[str | dict[str, str] | numbers.Number]]] = None, |
| 2441 | + # DoE specific inputs |
| 2442 | + resultpath: Optional[str | os.PathLike] = None, |
| 2443 | + parameters: Optional[dict[str, list[str] | list[int] | list[float]]] = None, |
| 2444 | + ) -> None: |
| 2445 | + super().__init__( |
| 2446 | + mod=mod, |
| 2447 | + simargs=simargs, |
| 2448 | + resultpath=resultpath, |
| 2449 | + parameters=parameters, |
| 2450 | + ) |
| 2451 | + |
| 2452 | + def _prepare_structure_parameters( |
| 2453 | + self, |
| 2454 | + idx_pc_structure: int, |
| 2455 | + pc_structure: Tuple, |
| 2456 | + param_structure: dict[str, list[str] | list[int] | list[float]], |
| 2457 | + ) -> dict[str, str | int | float]: |
| 2458 | + build_dir = self._resultpath / f"DOE_{idx_pc_structure:09d}" |
| 2459 | + build_dir.mkdir() |
| 2460 | + self._mod.setWorkDirectory(work_directory=build_dir) |
| 2461 | + |
| 2462 | + sim_param_structure = {} |
| 2463 | + for idx_structure, pk_structure in enumerate(param_structure.keys()): |
| 2464 | + sim_param_structure[pk_structure] = pc_structure[idx_structure] |
| 2465 | + |
| 2466 | + pk_value = pc_structure[idx_structure] |
| 2467 | + if isinstance(pk_value, str): |
| 2468 | + pk_value_str = self.get_session().escape_str(pk_value) |
| 2469 | + expr = f"setParameterValue({self._model_name}, {pk_structure}, \"{pk_value_str}\")" |
| 2470 | + elif isinstance(pk_value, bool): |
| 2471 | + pk_value_bool_str = "true" if pk_value else "false" |
| 2472 | + expr = f"setParameterValue({self._model_name}, {pk_structure}, {pk_value_bool_str});" |
| 2473 | + else: |
| 2474 | + expr = f"setParameterValue({self._model_name}, {pk_structure}, {pk_value})" |
| 2475 | + res = self._mod.sendExpression(expr=expr) |
| 2476 | + if not res: |
| 2477 | + raise ModelicaSystemError(f"Cannot set structural parameter {self._model_name}.{pk_structure} " |
| 2478 | + f"to {pk_value} using {repr(expr)}") |
| 2479 | + |
| 2480 | + self._mod.buildModel() |
| 2481 | + |
| 2482 | + return sim_param_structure |
| 2483 | + |
2434 | 2484 | def get_doe_solutions( |
2435 | 2485 | self, |
2436 | 2486 | var_list: Optional[list] = None, |
|
0 commit comments