From e30c81a891c9916835b915d4480300565ea1936a Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Sun, 30 Apr 2023 14:04:07 +0800 Subject: [PATCH] Support water distribution --- api/__init__.py | 3 + api/batch_exe.py | 18 +- api/s32_region_util.py | 91 ++++--- api/s34_water_distribution.py | 52 ++++ test_tjnetwork.py | 484 ++++++++++++++++++++++++++++++++++ tjnetwork.py | 20 +- 6 files changed, 618 insertions(+), 50 deletions(-) create mode 100644 api/s34_water_distribution.py diff --git a/api/__init__.py b/api/__init__.py index 79f4a17..c22bd76 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -136,4 +136,7 @@ from .s32_region_util import get_nodes_in_boundary, get_nodes_in_region, calcula from .s33_region import get_region_schema, get_region, set_region, add_region, delete_region +from .s34_water_distribution import DISTRIBUTION_TYPE_ADD, DISTRIBUTION_TYPE_OVERRIDE +from .s34_water_distribution import distribute_demand_to_nodes, distribute_demand_to_region + from .s37_virtual_district import calculate_virtual_district diff --git a/api/batch_exe.py b/api/batch_exe.py index cb41355..7f28c4e 100644 --- a/api/batch_exe.py +++ b/api/batch_exe.py @@ -32,7 +32,7 @@ from .s31_scada_element import set_scada_element, add_scada_element, delete_scad from .batch_api_cs import rewrite_batch_api -def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet: +def _execute_add_command(name: str, cs: ChangeSet) -> ChangeSet: type = cs.operations[0]['type'] if type == s1_title: @@ -109,7 +109,7 @@ def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet: return ChangeSet() -def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet: +def _execute_update_command(name: str, cs: ChangeSet) -> ChangeSet: type = cs.operations[0]['type'] if type == s1_title: @@ -186,7 +186,7 @@ def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet: return ChangeSet() -def execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet: +def _execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet: type = cs.operations[0]['type'] if type == s1_title: @@ -277,11 +277,11 @@ def execute_batch_commands(name: str, cs: ChangeSet) -> ChangeSet: todo = op operation = op['operation'] if operation == API_ADD: - result.merge(execute_add_command(name, ChangeSet(op))) + result.merge(_execute_add_command(name, ChangeSet(op))) elif operation == API_UPDATE: - result.merge(execute_update_command(name, ChangeSet(op))) + result.merge(_execute_update_command(name, ChangeSet(op))) elif operation == API_DELETE: - result.merge(execute_delete_command(name, ChangeSet(op))) + result.merge(_execute_delete_command(name, ChangeSet(op))) except: print(f'ERROR: Fail to execute {todo}') @@ -305,11 +305,11 @@ def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet: todo = op operation = op['operation'] if operation == API_ADD: - result.merge(execute_add_command(name, ChangeSet(op))) + result.merge(_execute_add_command(name, ChangeSet(op))) elif operation == API_UPDATE: - result.merge(execute_update_command(name, ChangeSet(op))) + result.merge(_execute_update_command(name, ChangeSet(op))) elif operation == API_DELETE: - result.merge(execute_delete_command(name, ChangeSet(op))) + result.merge(_execute_delete_command(name, ChangeSet(op))) except: print(f'ERROR: Fail to execute {todo}') diff --git a/api/s32_region_util.py b/api/s32_region_util.py index 6e1f7f9..d193063 100644 --- a/api/s32_region_util.py +++ b/api/s32_region_util.py @@ -2,8 +2,9 @@ import ctypes import platform import os import math -import collections -from .s0_base import get_node_links, get_link_nodes +from typing import Any +from .s0_base import get_node_links, get_link_nodes, is_pipe +from .s5_pipes import get_pipe from .database import read, try_read, read_all, write from .s24_coordinates import node_has_coord, get_node_coord @@ -89,35 +90,53 @@ def _angle_of_node_link(node: str, link: str, nodes, links) -> float: return _angle(v) +class Topology: + def __init__(self, db: str, nodes: list[str]) -> None: + self._nodes: dict[str, Any] = {} + self._max_x_node = '' + for node in nodes: + if not node_has_coord(db, node): + continue + if get_node_links(db, node) == 0: + continue + self._nodes[node] = get_node_coord(db, node) | { 'links': [] } + if self._max_x_node == '' or self._nodes[node]['x'] > self._nodes[self._max_x_node]['x']: + self._max_x_node = node + + self._links = {} + for node in self._nodes: + for link in get_node_links(db, node): + candidate = True + link_nodes = get_link_nodes(db, link) + for link_node in link_nodes: + if link_node not in self._nodes: + candidate = False + break + if candidate: + length = get_pipe(db, link)['length'] if is_pipe(db, link) else 0.0 + self._links[link] = { 'node1' : link_nodes[0], 'node2' : link_nodes[1], 'length' : length } + + if link not in self._nodes[link_nodes[0]]['links']: + self._nodes[link_nodes[0]]['links'].append(link) + if link not in self._nodes[link_nodes[1]]['links']: + self._nodes[link_nodes[1]]['links'].append(link) + + def nodes(self): + return self._nodes + + def max_x_node(self): + return self._max_x_node + + def links(self): + return self._links + + def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]: - new_nodes = {} - max_x_node = '' - for node in nodes: - if not node_has_coord(name, node): - continue - if get_node_links(name, node) == 0: - continue - new_nodes[node] = get_node_coord(name, node) | { 'links': [] } - if max_x_node == '' or new_nodes[node]['x'] > new_nodes[max_x_node]['x']: - max_x_node = node + topology = Topology(name, nodes) + t_nodes = topology.nodes() + t_links = topology.links() - new_links = {} - for node in new_nodes: - for link in get_node_links(name, node): - candidate = True - link_nodes = get_link_nodes(name, link) - for link_node in link_nodes: - if link_node not in new_nodes: - candidate = False - break - if candidate: - new_links[link] = { 'node1' : link_nodes[0], 'node2' : link_nodes[1] } - if link not in new_nodes[link_nodes[0]]['links']: - new_nodes[link_nodes[0]]['links'].append(link) - if link not in new_nodes[link_nodes[1]]['links']: - new_nodes[link_nodes[1]]['links'].append(link) - - cursor = max_x_node + cursor = topology.max_x_node() in_angle = 0 paths: list[str] = [] @@ -125,8 +144,8 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] paths.append(cursor) sorted_links = [] overlapped_link = '' - for link in new_nodes[cursor]['links']: - angle = _angle_of_node_link(cursor, link, new_nodes, new_links) + for link in t_nodes[cursor]['links']: + angle = _angle_of_node_link(cursor, link, t_nodes, t_links) if angle == in_angle: overlapped_link = link continue @@ -135,7 +154,7 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] # work into a branch, return if len(sorted_links) == 0: cursor = paths[-2] - in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, new_nodes, new_links) + in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links) continue sorted_links = sorted(sorted_links, key=lambda s:s[0]) @@ -145,17 +164,17 @@ def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]] out_link = link break - cursor = new_links[out_link]['node1'] if cursor == new_links[out_link]['node2'] else new_links[out_link]['node2'] + cursor = t_links[out_link]['node1'] if cursor == t_links[out_link]['node2'] else t_links[out_link]['node2'] # end up trip :) - if cursor == max_x_node: + if cursor == topology.max_x_node(): paths.append(cursor) break - in_angle = _angle_of_node_link(cursor, out_link, new_nodes, new_links) + in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links) boundary: list[tuple[float, float]] = [] for node in paths: - boundary.append((new_nodes[node]['x'], new_nodes[node]['y'])) + boundary.append((t_nodes[node]['x'], t_nodes[node]['y'])) return boundary diff --git a/api/s34_water_distribution.py b/api/s34_water_distribution.py new file mode 100644 index 0000000..de444eb --- /dev/null +++ b/api/s34_water_distribution.py @@ -0,0 +1,52 @@ +from .database import ChangeSet +from .s0_base import is_junction +from .s9_demands import get_demand +from .s32_region_util import Topology, get_nodes_in_region +from .batch_exe import execute_batch_command + +DISTRIBUTION_TYPE_ADD = 'ADD' +DISTRIBUTION_TYPE_OVERRIDE = 'OVERRIDE' + +def distribute_demand_to_nodes(name: str, demand: float, nodes: list[str], type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet: + if len(nodes) == 0 or demand == 0.0: + return ChangeSet() + if type != DISTRIBUTION_TYPE_ADD and type != DISTRIBUTION_TYPE_OVERRIDE: + return ChangeSet() + + topology = Topology(name, nodes) + t_nodes = topology.nodes() + t_links = topology.links() + + length_sum = 0.0 + for value in t_links.values(): + length_sum += abs(value['length']) + + if length_sum <= 0.0: + return ChangeSet() + + demand_per_length = demand / length_sum + + cs = ChangeSet() + + for node, value in t_nodes.items(): + if not is_junction(name, node): + continue + demand_per_node = 0.0 + for link in value['links']: + demand_per_node += abs(t_links[link]['length']) * demand_per_length * 0.5 + + ds = get_demand(name, node)['demands'] + if len(ds) == 0: + ds = [{'demand': demand_per_node, 'pattern': None, 'category': None}] + elif type == DISTRIBUTION_TYPE_ADD: + ds[0]['demand'] += demand_per_node + else: + ds[0]['demand'] = demand_per_node + cs.update({'type': 'demand', 'junction': node, 'demands': ds}) + + return execute_batch_command(name, cs) + + +def distribute_demand_to_region(name: str, demand: float, region: str, type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet: + nodes = get_nodes_in_region(name, region) + return distribute_demand_to_nodes(name, demand, nodes, type) diff --git a/test_tjnetwork.py b/test_tjnetwork.py index bbad971..724f013 100644 --- a/test_tjnetwork.py +++ b/test_tjnetwork.py @@ -5732,6 +5732,490 @@ class TestApi: self.leave(p) + # 34 water_distribution + + + def test_distribute_demand_to_nodes(self): + p = 'test_distribute_demand_to_nodes' + read_inp(p, f'./inp/net3.inp', '3') + open_project(p) + + vds = calculate_virtual_district(p, ['107', '139', '267', '211'])['virtual_districts'] + nodes = vds[0]['nodes'] + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + distribute_demand_to_nodes(p, 100.0, nodes, DISTRIBUTION_TYPE_ADD) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + distribute_demand_to_nodes(p, -100.0, nodes, DISTRIBUTION_TYPE_ADD) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + distribute_demand_to_nodes(p, 100.0, nodes, DISTRIBUTION_TYPE_OVERRIDE) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + distribute_demand_to_nodes(p, -100.0, nodes, DISTRIBUTION_TYPE_OVERRIDE) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == -17.357291284684024 + assert demands[1] == -22.112211221122113 + assert demands[2] == -6.466202175773133 + assert demands[3] == -8.232489915658233 + assert demands[4] == -4.180418041804181 + assert demands[5] == -7.260726072607261 + assert demands[6] == -3.862608483070529 + assert demands[7] == -6.466202175773133 + assert demands[8] == -5.738907224055739 + assert demands[9] == -0.892311453367559 + assert demands[10] == -3.9665077618873 + assert demands[11] == -2.9275149737195942 + assert demands[12] == -2.1391027991688056 + assert demands[13] == -2.9275149737195942 + assert demands[14] == -5.469991443588803 + + self.leave(p) + + + def test_distribute_demand_to_nodes_op(self): + p = 'test_distribute_demand_to_nodes' + read_inp(p, f'./inp/net3.inp', '3') + open_project(p) + + vds = calculate_virtual_district(p, ['107', '139', '267', '211'])['virtual_districts'] + nodes = vds[0]['nodes'] + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + cs = distribute_demand_to_nodes(p, 100.0, nodes, DISTRIBUTION_TYPE_ADD).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_undo(p).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + demands.reverse() + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + cs = execute_redo(p).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = distribute_demand_to_nodes(p, 100.0, nodes, DISTRIBUTION_TYPE_OVERRIDE).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_undo(p).operations + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + demands.reverse() + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_redo(p).operations + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + self.leave(p) + + + def test_distribute_demand_to_region(self): + p = 'test_distribute_demand_to_region' + read_inp(p, f'./inp/net3.inp', '3') + open_project(p) + + vds = calculate_virtual_district(p, ['107', '139', '267', '211'])['virtual_districts'] + nodes = vds[0]['nodes'] + boundary = calculate_boundary(p, nodes) + boundary = inflate_boundary(p, boundary, 0.1) + add_region(p, ChangeSet({'id': 'r', 'boundary': boundary})) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + distribute_demand_to_region(p, 100.0, 'r', DISTRIBUTION_TYPE_ADD) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + distribute_demand_to_region(p, -100.0, 'r', DISTRIBUTION_TYPE_ADD) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + distribute_demand_to_region(p, 100.0, 'r', DISTRIBUTION_TYPE_OVERRIDE) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + distribute_demand_to_region(p, -100.0, 'r', DISTRIBUTION_TYPE_OVERRIDE) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == -17.357291284684024 + assert demands[1] == -22.112211221122113 + assert demands[2] == -6.466202175773133 + assert demands[3] == -8.232489915658233 + assert demands[4] == -4.180418041804181 + assert demands[5] == -7.260726072607261 + assert demands[6] == -3.862608483070529 + assert demands[7] == -6.466202175773133 + assert demands[8] == -5.738907224055739 + assert demands[9] == -0.892311453367559 + assert demands[10] == -3.9665077618873 + assert demands[11] == -2.9275149737195942 + assert demands[12] == -2.1391027991688056 + assert demands[13] == -2.9275149737195942 + assert demands[14] == -5.469991443588803 + + self.leave(p) + + + def test_distribute_demand_to_region_op(self): + p = 'test_distribute_demand_to_region_op' + read_inp(p, f'./inp/net3.inp', '3') + open_project(p) + + vds = calculate_virtual_district(p, ['107', '139', '267', '211'])['virtual_districts'] + nodes = vds[0]['nodes'] + boundary = calculate_boundary(p, nodes) + boundary = inflate_boundary(p, boundary, 0.1) + add_region(p, ChangeSet({'id': 'r', 'boundary': boundary})) + + demands = [] + for node in nodes: + if not is_junction(p, node): + continue + ds = get_demand(p, node)['demands'] + demands.append(ds[0]['demand']) + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + cs = distribute_demand_to_region(p, 100.0, 'r', DISTRIBUTION_TYPE_ADD).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_undo(p).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + demands.reverse() + assert demands == [0.0, 189.95, 133.2, 135.37, 54.64, 231.4, 141.94, 52.1, 117.71, 176.13, 0.0, 0.0, 0.0, 0.0, 0.0] + + cs = execute_redo(p).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = distribute_demand_to_region(p, 100.0, 'r', DISTRIBUTION_TYPE_OVERRIDE).operations + + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_undo(p).operations + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + demands.reverse() + assert demands[0] == 17.357291284684024 + assert demands[1] == 212.0622112211221 + assert demands[2] == 139.66620217577312 + assert demands[3] == 143.60248991565823 + assert demands[4] == 58.82041804180418 + assert demands[5] == 238.66072607260728 + assert demands[6] == 145.80260848307051 + assert demands[7] == 58.566202175773135 + assert demands[8] == 123.44890722405573 + assert demands[9] == 177.02231145336756 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + cs = execute_redo(p).operations + demands = [] + for value in cs: + ds = value['demands'] + demands.append(ds[0]['demand']) + assert demands[0] == 17.357291284684024 + assert demands[1] == 22.112211221122113 + assert demands[2] == 6.466202175773133 + assert demands[3] == 8.232489915658233 + assert demands[4] == 4.180418041804181 + assert demands[5] == 7.260726072607261 + assert demands[6] == 3.862608483070529 + assert demands[7] == 6.466202175773133 + assert demands[8] == 5.738907224055739 + assert demands[9] == 0.892311453367559 + assert demands[10] == 3.9665077618873 + assert demands[11] == 2.9275149737195942 + assert demands[12] == 2.1391027991688056 + assert demands[13] == 2.9275149737195942 + assert demands[14] == 5.469991443588803 + + self.leave(p) + # 37 virtual_district def test_virtual_district(self): diff --git a/tjnetwork.py b/tjnetwork.py index 8a78435..7c2fc73 100644 --- a/tjnetwork.py +++ b/tjnetwork.py @@ -151,18 +151,22 @@ SCADA_DEVICE_TYPE_LEVEL = api.SCADA_DEVICE_TYPE_LEVEL SCADA_DEVICE_TYPE_FLOW = api.SCADA_DEVICE_TYPE_FLOW -SCADA_MODEL_TYPE_JUNCTION = api.SCADA_MODEL_TYPE_JUNCTION +SCADA_MODEL_TYPE_JUNCTION = api.SCADA_MODEL_TYPE_JUNCTION SCADA_MODEL_TYPE_RESERVOIR = api.SCADA_MODEL_TYPE_RESERVOIR -SCADA_MODEL_TYPE_TANK = api.SCADA_MODEL_TYPE_TANK -SCADA_MODEL_TYPE_PIPE = api.SCADA_MODEL_TYPE_PIPE -SCADA_MODEL_TYPE_PUMP = api.SCADA_MODEL_TYPE_PUMP -SCADA_MODEL_TYPE_VALVE = api.SCADA_MODEL_TYPE_VALVE +SCADA_MODEL_TYPE_TANK = api.SCADA_MODEL_TYPE_TANK +SCADA_MODEL_TYPE_PIPE = api.SCADA_MODEL_TYPE_PIPE +SCADA_MODEL_TYPE_PUMP = api.SCADA_MODEL_TYPE_PUMP +SCADA_MODEL_TYPE_VALVE = api.SCADA_MODEL_TYPE_VALVE SCADA_ELEMENT_STATUS_ONLINE = api.SCADA_ELEMENT_STATUS_ONLINE SCADA_ELEMENT_STATUS_OFFLINE = api.SCADA_ELEMENT_STATUS_OFFLINE +DISTRIBUTION_TYPE_ADD = api.DISTRIBUTION_TYPE_ADD +DISTRIBUTION_TYPE_OVERRIDE = api.DISTRIBUTION_TYPE_OVERRIDE + + ############################################################ # project ############################################################ @@ -983,6 +987,12 @@ def delete_region(name: str, cs: ChangeSet) -> ChangeSet: # water_distribution 34 ############################################################ +def distribute_demand_to_nodes(name: str, demand: float, nodes: list[str], type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet: + return api.distribute_demand_to_nodes(name, demand, nodes, type) + +def distribute_demand_to_region(name: str, demand: float, region: str, type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet: + return api.distribute_demand_to_region(name, demand, region, type) + ############################################################ # district_metering_area 35