Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Parsing of ensemble profiles when using input profiles from csv.
- Maximum profile constraint for PV asset is considered in PV sizing
- Cater for input via esdl constraints to specify the upper limit for OPTIONAL assets in DTK
- Initial implementation of adaptable pipe DN lower limit per pipe

## Changed
- Speed-up timeseries check in from InfluxDB
Expand Down
41 changes: 34 additions & 7 deletions src/mesido/esdl/esdl_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class ESDLMixin(

# TODO: remove this once ESDL allows specifying a minimum pipe size for an optional pipe.
__minimum_pipe_size_name: str = "DN150"
__use_user_defined_minimum_pipe_size: bool = False

def __init__(self, *args, **kwargs) -> None:
"""
Expand Down Expand Up @@ -271,6 +272,15 @@ def pre(self) -> None:
)
self.name_to_esdl_id_map[esdl_asset.name] = esdl_id

def find_index_of_pipe_or_next_up(self, pipes, target_dn):
"""
Find the index of the first pipe in the ordered pipes that meets the specified size
"""
for ii, p in enumerate(pipes):
if float(p.name.replace("DN", "")) >= target_dn:
return ii
return None

def _get_pipe_max_size_input(
self,
asset: Asset,
Expand Down Expand Up @@ -356,17 +366,29 @@ def __override_pipe_classes_dicts(
c = override_classes[p] = []
c.append(no_pipe_class)

min_size = self.__minimum_pipe_size_name
min_size_idx = [idx for idx, pipe in enumerate(pipe_classes) if pipe.name == min_size]
assert len(min_size_idx) == 1
min_size_idx = min_size_idx[0]

max_size = self._get_pipe_max_size_input(asset)
max_size_name = self._get_pipe_max_size_input(asset)

max_size_idx = [idx for idx, pipe in enumerate(pipe_classes) if pipe.name == max_size]
max_size_idx = [
idx for idx, pipe in enumerate(pipe_classes) if pipe.name == max_size_name
]
assert len(max_size_idx) == 1
max_size_idx = max_size_idx[0]

# Update the minimum pipe DN size if user specified limit is allowed
# TODO: in the future the lower limit will make use of PipeDiameterConstriant
if self._ESDLMixin__use_user_defined_minimum_pipe_size:
user_defined_lower_limit_dn_mm = 40.0
pipe_dn_max_vs_min_ratio = 10.0 # Relates to area ratio of 100.0
max_size_dn_mm = float(pipe_classes[max_size_idx].name.replace("DN", ""))
min_dn_by_factor_mm = max_size_dn_mm / pipe_dn_max_vs_min_ratio
min_dn_mm = max(min_dn_by_factor_mm, user_defined_lower_limit_dn_mm)
min_size_idx = self.find_index_of_pipe_or_next_up(pipe_classes, min_dn_mm)
else: # use default minimum pipe DN size
min_size_idx = self.find_index_of_pipe_or_next_up(
pipe_classes, float(self.__minimum_pipe_size_name.replace("DN", ""))
)
assert min_size_idx

if max_size_idx < min_size_idx:
logger.warning(
f"{p} has an upper DN size smaller than the used minimum size "
Expand Down Expand Up @@ -422,6 +444,11 @@ def override_pipe_classes(self) -> None:
pipe_classes[i],
investment_costs=pipe_diameter_cost_map[pipe_class.name],
)
if (
not self._ESDLMixin__use_user_defined_minimum_pipe_size
and float(pipe_classes[i].name.replace("DN", "")) != 20.0
):
self._ESDLMixin__use_user_defined_minimum_pipe_size = True
else:
del pipe_classes[i]

Expand Down
Loading
Loading