Skip to content

Commit 53f4ec4

Browse files
committed
[ModelicaSystem] split ModelicaSystemDoE into ModelicaDoEABC and ModelicaDoE
1 parent ca5ef4e commit 53f4ec4

1 file changed

Lines changed: 77 additions & 27 deletions

File tree

OMPython/ModelicaSystem.py

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import re
1616
import textwrap
1717
import threading
18-
from typing import Any, cast, Optional
18+
from typing import Any, cast, Optional, Tuple
1919
import warnings
2020
import xml.etree.ElementTree as ET
2121

@@ -2108,9 +2108,9 @@ class ModelicaSystem(ModelicaSystemOMC):
21082108
"""
21092109

21102110

2111-
class ModelicaSystemDoE:
2111+
class ModelicaDoEABC(metaclass=abc.ABCMeta):
21122112
"""
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
21142114
21152115
Example
21162116
-------
@@ -2252,30 +2252,11 @@ def prepare(self) -> int:
22522252
param_non_structural_combinations = list(itertools.product(*param_non_structure.values()))
22532253

22542254
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+
)
22792260

22802261
for idx_non_structural, pk_non_structural in enumerate(param_non_structural_combinations):
22812262
sim_param_non_structural = {}
@@ -2320,6 +2301,17 @@ def prepare(self) -> int:
23202301

23212302
return len(doe_sim)
23222303

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+
23232315
def get_doe_definition(self) -> Optional[dict[str, dict[str, Any]]]:
23242316
"""
23252317
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):
24312423

24322424
return doe_def_total == doe_def_done
24332425

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+
24342484
def get_doe_solutions(
24352485
self,
24362486
var_list: Optional[list] = None,

0 commit comments

Comments
 (0)