From b069f2ae49bd2f8cc053fe1f72fc66f6e8eac1de Mon Sep 17 00:00:00 2001 From: SRDM Date: Thu, 23 May 2024 13:40:21 +0200 Subject: [PATCH 01/10] get realistic results at circ pump tout even though they are not relevant --- .../abstract_models/circulation_pump.py | 94 +++++++++++-------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/src/pandapipes/component_models/abstract_models/circulation_pump.py b/src/pandapipes/component_models/abstract_models/circulation_pump.py index c678b44a..9cf80278 100644 --- a/src/pandapipes/component_models/abstract_models/circulation_pump.py +++ b/src/pandapipes/component_models/abstract_models/circulation_pump.py @@ -4,13 +4,12 @@ import numpy as np -from pandapipes.component_models.abstract_models.branch_wzerolength_models import \ - BranchWZeroLengthComponent -from pandapipes.component_models.component_toolbox import set_fixed_node_entries, \ - get_mass_flow_at_nodes -from pandapipes.idx_branch import D, AREA, ACTIVE -from pandapipes.idx_node import PINIT -from pandapipes.pf.pipeflow_setup import get_lookup +from pandapipes.component_models.abstract_models.branch_wzerolength_models import BranchWZeroLengthComponent +from pandapipes.component_models.component_toolbox import set_fixed_node_entries, standard_branch_wo_internals_result_lookup +from pandapipes.idx_branch import D, AREA, PUMP_TYPE, CIRC, LOAD_VEC_BRANCHES_T, TO_NODE, JAC_DERIV_DTOUT, JAC_DERIV_DT, MDOTINIT +from pandapipes.idx_node import MDOTSLACKINIT, CIRC_PUMP_OCCURENCE, EXT_GRID_OCCURENCE +from pandapipes.pf.pipeflow_setup import get_fluid +from pandapipes.pf.result_extraction import extract_branch_results_without_internals try: import pandaplan.core.pplog as logging @@ -40,7 +39,14 @@ def get_result_table(cls, net): if False, returns columns as tuples also specifying the dtypes :rtype: (list, bool) """ - return ["mdot_flow_kg_per_s", "deltap_bar"], True + if get_fluid(net).is_gas: + output = ["v_from_m_per_s", "v_to_m_per_s", "v_mean_m_per_s", "p_from_bar", "p_to_bar", "t_from_k", + "t_to_k", "mdot_from_kg_per_s", "mdot_to_kg_per_s", "vdot_norm_m3_per_s", "reynolds", "lambda", + "normfactor_from", "normfactor_to", "qext_w"] + else: + output = ["v_mean_m_per_s", "p_from_bar", "p_to_bar", "t_from_k", "t_to_k", "mdot_from_kg_per_s", + "mdot_to_kg_per_s", "vdot_norm_m3_per_s", "reynolds", "lambda", "qext_w"] + return output, True @classmethod def active_identifier(cls): @@ -73,8 +79,8 @@ def create_pit_node_entries(cls, net, node_pit): # TODO: there should be a warning, if any p_bar value is not given or any of the types does # not contain "p", as this should not be allowed for this component press = circ_pump_tbl.p_flow_bar.values - set_fixed_node_entries(net, node_pit, junction, circ_pump_tbl.type.values, press, - circ_pump_tbl.t_flow_k.values, cls.get_connected_node_type()) + set_fixed_node_entries(net, node_pit, junction, circ_pump_tbl.type.values, press, circ_pump_tbl.t_flow_k.values, + cls.get_connected_node_type()) return circ_pump_tbl, press @classmethod @@ -90,7 +96,41 @@ def create_pit_branch_entries(cls, net, branch_pit): circ_pump_pit = super().create_pit_branch_entries(net, branch_pit) circ_pump_pit[:, D] = 0.1 circ_pump_pit[:, AREA] = circ_pump_pit[:, D] ** 2 * np.pi / 4 - circ_pump_pit[:, ACTIVE] = False + circ_pump_pit[:, PUMP_TYPE] = CIRC + return circ_pump_pit + + @classmethod + def adaption_after_derivatives_hydraulic(cls, net, branch_pit, node_pit, idx_lookups, options): + """ + Function which creates pit branch entries with a specific table. + :param net: The pandapipes network + :type net: pandapipesNet + :param branch_pit: + :type branch_pit: + :return: No Output. + """ + f, t = idx_lookups[cls.table_name()] + circ_pump_pit = branch_pit[f:t, :] + tn = circ_pump_pit[:, TO_NODE].astype(np.int32) + mask = node_pit[tn, CIRC_PUMP_OCCURENCE] == node_pit[tn, EXT_GRID_OCCURENCE] + node_pit[tn[mask], MDOTSLACKINIT] = 0 + return circ_pump_pit + + @classmethod + def adaption_after_derivatives_thermal(cls, net, branch_pit, node_pit, idx_lookups, options): + """ + Function which creates pit branch entries with a specific table. + :param net: The pandapipes network + :type net: pandapipesNet + :param branch_pit: + :type branch_pit: + :return: No Output. + """ + f, t = idx_lookups[cls.table_name()] + circ_pump_pit = branch_pit[f:t, :] + circ_pump_pit[:, LOAD_VEC_BRANCHES_T] = 0 + circ_pump_pit[:, JAC_DERIV_DTOUT] = 1 + circ_pump_pit[:, JAC_DERIV_DT] = 0 @classmethod def extract_results(cls, net, options, branch_results, mode): @@ -107,34 +147,8 @@ def extract_results(cls, net, options, branch_results, mode): :type options: :return: No Output. """ - circ_pump_tbl = net[cls.table_name()] - - if len(circ_pump_tbl) == 0: - return - - res_table = net["res_" + cls.table_name()] - - branch_pit = net['_pit']['branch'] - node_pit = net["_pit"]["node"] - - junction_lookup = get_lookup(net, "node", "index")[ - cls.get_connected_node_type().table_name()] - fn_col, tn_col = cls.from_to_node_cols() - # get indices in internal structure for flow_junctions in circ_pump tables which are - # "active" - flow_junctions = circ_pump_tbl[tn_col].values - flow_nodes = junction_lookup[flow_junctions] - in_service = circ_pump_tbl.in_service.values - p_grids = np.isin(circ_pump_tbl.type.values, ["p", "pt"]) & in_service - sum_mass_flows, inverse_nodes, counts = get_mass_flow_at_nodes(net, node_pit, branch_pit, - flow_nodes[p_grids], cls) - - # positive results mean that the circ_pump feeds in, negative means that the ext grid - # extracts (like a load) - res_table["mdot_flow_kg_per_s"].values[p_grids] = - (sum_mass_flows / counts)[inverse_nodes] - return_junctions = circ_pump_tbl[fn_col].values - return_nodes = junction_lookup[return_junctions] + required_results_hyd, required_results_ht = standard_branch_wo_internals_result_lookup(net) - deltap_bar = node_pit[flow_nodes, PINIT] - node_pit[return_nodes, PINIT] - res_table["deltap_bar"].values[in_service] = deltap_bar[in_service] + extract_branch_results_without_internals(net, branch_results, required_results_hyd, required_results_ht, + cls.table_name(), mode) From 64caedb948b2fc6b70ae40b52eafcda8fe7a504d Mon Sep 17 00:00:00 2001 From: SRDM Date: Thu, 23 May 2024 13:40:37 +0200 Subject: [PATCH 02/10] bugfix setting infeed nodes --- src/pandapipes/pf/derivative_calculation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pandapipes/pf/derivative_calculation.py b/src/pandapipes/pf/derivative_calculation.py index 1d006c4e..775b60c0 100644 --- a/src/pandapipes/pf/derivative_calculation.py +++ b/src/pandapipes/pf/derivative_calculation.py @@ -80,6 +80,7 @@ def calculate_derivatives_hydraulic(net, branch_pit, node_pit, options): def calculate_derivatives_thermal(net, branch_pit, node_pit, options): + node_pit[:, INFEED] = False fluid = get_fluid(net) cp = get_branch_cp(net, fluid, node_pit, branch_pit) m_init = branch_pit[:, MDOTINIT_T] From 5145ac99291e393049760ece9f6ffa63452300f4 Mon Sep 17 00:00:00 2001 From: SRDM Date: Thu, 23 May 2024 13:41:02 +0200 Subject: [PATCH 03/10] pressure control adaption --- src/pandapipes/create.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pandapipes/create.py b/src/pandapipes/create.py index 641c9800..713f75a2 100644 --- a/src/pandapipes/create.py +++ b/src/pandapipes/create.py @@ -865,8 +865,8 @@ def create_compressor(net, from_junction, to_junction, pressure_ratio, name=None def create_pressure_control(net, from_junction, to_junction, controlled_junction, controlled_p_bar, control_active=True, - loss_coefficient=0., name=None, index=None, in_service=True, type="pressure_control", - **kwargs): + loss_coefficient=0., max_mdot_kg_per_s=None, name=None, index=None, in_service=True, + type="pressure_control", **kwargs): """Adds one pressure control that enforces a pressure at a specific junction. The pressure control unit creates a pressure drop / lift between the 'from' and the 'to' @@ -933,7 +933,7 @@ def create_pressure_control(net, from_junction, to_junction, controlled_junction _set_entries(net, "press_control", index, name=name, from_junction=from_junction, to_junction=to_junction, controlled_junction=controlled_junction, control_active=bool(control_active), loss_coefficient=loss_coefficient, controlled_p_bar=controlled_p_bar, in_service=bool(in_service), - type=type, **kwargs) + max_mdot_kg_per_s=max_mdot_kg_per_s, type=type, **kwargs) if controlled_junction != from_junction and controlled_junction != to_junction: logger.warning("The pressure controller %d controls the pressure at a junction that it is " @@ -1471,7 +1471,7 @@ def create_valves(net, from_junctions, to_junctions, diameter_m, opened=True, lo def create_pressure_controls(net, from_junctions, to_junctions, controlled_junctions, controlled_p_bar, control_active=True, loss_coefficient=0., name=None, index=None, in_service=True, - type="pressure_control", **kwargs): + max_mdot_kg_per_s=None, type="pressure_control", **kwargs): """ Convenience function for creating many pressure controls at once. Parameters 'from_junctions'\ and 'to_junctions' must be arrays of equal length. Other parameters may be either arrays of the\ @@ -1535,7 +1535,7 @@ def create_pressure_controls(net, from_junctions, to_junctions, controlled_junct entries = {"name": name, "from_junction": from_junctions, "to_junction": to_junctions, "controlled_junction": controlled_junctions, "controlled_p_bar": controlled_p_bar, "control_active": control_active, "loss_coefficient": loss_coefficient, "in_service": in_service, - "type": type} + "max_mdot_kg_per_s": max_mdot_kg_per_s, "type": type} _set_multiple_entries(net, "press_control", index, **entries, **kwargs) controlled_elsewhere = (controlled_junctions != from_junctions) & (controlled_junctions != to_junctions) @@ -1908,7 +1908,7 @@ def _auto_ext_grid_types(p_bar, t_k, typ, comp): overview = pd.DataFrame({"Position": pos_not_allowed_types, "Type": typ_not_allowed_types}) logger.warning("Please check the following types for component %s, as they must be one of " "the following for correct model implementation: %s. \n%s" % ( - comp.__name__, ALLOWED_EG_TYPES, overview)) + comp.__name__, ALLOWED_EG_TYPES, overview)) p_types = np.isin(typ, [tp for tp in ALLOWED_EG_TYPES if tp not in ["t", "auto"]]) t_types = np.isin(typ, [tp for tp in ALLOWED_EG_TYPES if tp not in ["p", "auto"]]) From 1acc41bf3e8b85cadab827c9f0692073631ce969 Mon Sep 17 00:00:00 2001 From: SRDM Date: Thu, 23 May 2024 13:41:35 +0200 Subject: [PATCH 04/10] considering alpha in mdot as it is sensitive in bidirectional simulations --- src/pandapipes/pipeflow.py | 42 +++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/pandapipes/pipeflow.py b/src/pandapipes/pipeflow.py index 8b25a98a..12e8b1b1 100644 --- a/src/pandapipes/pipeflow.py +++ b/src/pandapipes/pipeflow.py @@ -4,16 +4,15 @@ import numpy as np from numpy import linalg -from scipy.sparse.linalg import spsolve - from pandapipes.idx_branch import FROM_NODE, TO_NODE, FROM_NODE_T, TO_NODE_T, MDOTINIT, TOUTINIT, MDOTINIT_T -from pandapipes.idx_node import PINIT, TINIT +from pandapipes.idx_node import PINIT, TINIT, MDOTSLACKINIT, NODE_TYPE, P from pandapipes.pf.build_system_matrix import build_system_matrix from pandapipes.pf.derivative_calculation import calculate_derivatives_hydraulic, calculate_derivatives_thermal from pandapipes.pf.pipeflow_setup import get_net_option, get_net_options, set_net_option, init_options, \ create_internal_results, write_internal_results, get_lookup, create_lookups, initialize_pit, reduce_pit, \ set_user_pf_options, init_all_result_tables, identify_active_nodes_branches, PipeflowNotConverged from pandapipes.pf.result_extraction import extract_all_results, extract_results_active_pit +from scipy.sparse.linalg import spsolve try: import pandaplan.core.pplog as logging @@ -162,9 +161,19 @@ def hydraulics(net): reduce_pit(net, mode="hydraulics") if not get_net_option(net, "reuse_internal_data") or "_internal_data" not in net: net["_internal_data"] = dict() - vars = ['mdot', 'p'] - tol_p, tol_m = get_net_options(net, 'tol_m', 'tol_p') - newton_raphson(net, solve_hydraulics, 'hydraulics', vars, [tol_m, tol_p], ['branch', 'node'], 'max_iter_hyd') + vars = ['mdot', 'p', 'mdotslack'] + tol_p, tol_m, tol_msl = get_net_options(net, 'tol_m', 'tol_p', 'tol_m') + newton_raphson(net, solve_hydraulics, 'hydraulics', vars, [tol_m, tol_p, tol_msl], ['branch', 'node', 'node'], + 'max_iter_hyd') + if net.converged: + rerun = False + for comp in net['component_list']: + rerun |= comp.rerun_hydraulics(net) + if rerun: + extract_results_active_pit(net, 'hydraulics') + identify_active_nodes_branches(net) + hydraulics(net) + if net.converged: set_user_pf_options(net, hyd_flag=True) @@ -188,6 +197,15 @@ def heat_transfer(net): vars = ['Tout', 'T'] tol_T = next(get_net_options(net, 'tol_T')) newton_raphson(net, solve_temperature, 'heat', vars, [tol_T, tol_T], ['branch', 'node'], 'max_iter_therm') + + rerun = False + for comp in net['component_list']: + rerun = max(comp.rerun_heat_transfer(net), rerun) + if rerun: + extract_results_active_pit(net, mode="heat_transfer") + identify_active_nodes_branches(net, False) + heat_transfer(net) + if not net.converged: raise PipeflowNotConverged("The heat transfer calculation did not converge to a " "solution.") @@ -232,13 +250,17 @@ def solve_hydraulics(net): m_init_old = branch_pit[:, MDOTINIT].copy() p_init_old = node_pit[:, PINIT].copy() + slack_nodes = np.where(node_pit[:, NODE_TYPE] == P)[0] + msl_init_old = node_pit[slack_nodes, MDOTSLACKINIT].copy() x = spsolve(jacobian, epsilon) - branch_pit[:, MDOTINIT] -= x[len(node_pit):] + branch_pit[:, MDOTINIT] -= x[len(node_pit):len(node_pit) + len(branch_pit)] * options["alpha"] node_pit[:, PINIT] -= x[:len(node_pit)] * options["alpha"] + node_pit[slack_nodes, MDOTSLACKINIT] -= x[len(node_pit) + len(branch_pit):] - return [branch_pit[:, MDOTINIT], m_init_old, node_pit[:, PINIT], p_init_old], epsilon + return [branch_pit[:, MDOTINIT], m_init_old, node_pit[:, PINIT], p_init_old, msl_init_old, + node_pit[slack_nodes, MDOTSLACKINIT]], epsilon def solve_temperature(net): @@ -281,8 +303,8 @@ def solve_temperature(net): x = spsolve(jacobian, epsilon) - node_pit[:, TINIT] += x[:len(node_pit)] * options["alpha"] - branch_pit[:, TOUTINIT] += x[len(node_pit):] + node_pit[:, TINIT] -= x[:len(node_pit)] * options["alpha"] + branch_pit[:, TOUTINIT] -= x[len(node_pit):] return [branch_pit[:, TOUTINIT], t_out_old, node_pit[:, TINIT], t_init_old], epsilon From ad1270869c7124b7b5d14adbfd75778d0ff6f548 Mon Sep 17 00:00:00 2001 From: srdm Date: Sat, 12 Oct 2024 12:00:21 +0200 Subject: [PATCH 05/10] idx branch adapted --- src/pandapipes/idx_branch.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pandapipes/idx_branch.py b/src/pandapipes/idx_branch.py index 80eb33d8..159e5425 100644 --- a/src/pandapipes/idx_branch.py +++ b/src/pandapipes/idx_branch.py @@ -38,5 +38,7 @@ PL = 29 # Pressure lift [bar] TL = 30 # Temperature lift [K] BRANCH_TYPE = 31 # branch type relevant for the pressure controller +PUMP_TYPE = 32 +CIRC = 33 -branch_cols = 32 +branch_cols = 34 From 8604b8625612ce324662e37025616889a7e6c1ee Mon Sep 17 00:00:00 2001 From: srdm Date: Thu, 7 Nov 2024 11:20:44 +0100 Subject: [PATCH 06/10] - remove D and AREA from import as not required - adapt wrong input in press control - set heat consumer with q_ext = 0 out of service if mdot is not defined - if there is only on node left, the pipeflow should still converge --- .../component_models/flow_control_component.py | 2 +- .../component_models/heat_consumer_component.py | 10 ++++++++-- src/pandapipes/create.py | 12 ++++++------ src/pandapipes/pf/pipeflow_setup.py | 2 ++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/pandapipes/component_models/flow_control_component.py b/src/pandapipes/component_models/flow_control_component.py index 57e2d08f..78db23dc 100644 --- a/src/pandapipes/component_models/flow_control_component.py +++ b/src/pandapipes/component_models/flow_control_component.py @@ -10,7 +10,7 @@ from pandapipes.component_models.component_toolbox import \ standard_branch_wo_internals_result_lookup, get_component_array from pandapipes.component_models.junction_component import Junction -from pandapipes.idx_branch import D, AREA, JAC_DERIV_DP, JAC_DERIV_DP1, JAC_DERIV_DM, MDOTINIT, LOAD_VEC_BRANCHES +from pandapipes.idx_branch import JAC_DERIV_DP, JAC_DERIV_DP1, JAC_DERIV_DM, MDOTINIT, LOAD_VEC_BRANCHES from pandapipes.pf.result_extraction import extract_branch_results_without_internals diff --git a/src/pandapipes/component_models/heat_consumer_component.py b/src/pandapipes/component_models/heat_consumer_component.py index 425d9e6b..b17f3fd4 100644 --- a/src/pandapipes/component_models/heat_consumer_component.py +++ b/src/pandapipes/component_models/heat_consumer_component.py @@ -8,9 +8,9 @@ from pandapipes.component_models import (get_fluid, BranchWZeroLengthComponent, get_component_array, standard_branch_wo_internals_result_lookup) from pandapipes.component_models.junction_component import Junction -from pandapipes.idx_branch import (D, AREA, MDOTINIT, QEXT, JAC_DERIV_DP1, JAC_DERIV_DM, +from pandapipes.idx_branch import (MDOTINIT, QEXT, JAC_DERIV_DP1, JAC_DERIV_DM, JAC_DERIV_DP, LOAD_VEC_BRANCHES, TOUTINIT, JAC_DERIV_DT, - JAC_DERIV_DTOUT, LOAD_VEC_BRANCHES_T) + JAC_DERIV_DTOUT, LOAD_VEC_BRANCHES_T, ACTIVE) from pandapipes.idx_node import TINIT from pandapipes.pf.internals_toolbox import get_from_nodes_corrected from pandapipes.pf.pipeflow_setup import get_lookup @@ -71,6 +71,12 @@ def create_pit_branch_entries(cls, net, branch_pit): hc_pit[~np.isnan(mdot), MDOTINIT] = mdot[~np.isnan(mdot)] treturn = net[cls.table_name()].treturn_k.values hc_pit[~np.isnan(treturn), TOUTINIT] = treturn[~np.isnan(treturn)] + mask_q0 = hc_pit[:, QEXT] == 0 & np.isnan(hc_pit[:, MDOTINIT]) + hc_pit[mask_q0, ACTIVE] = False + if any(mask_q0): + logger.warning(r'qext_w is equals to zero for heat consumers with index %s. ' + r'Therefore, the defined temperature control cannot be maintained.' \ + %net[cls.table_name()].index[mask_q0]) return hc_pit @classmethod diff --git a/src/pandapipes/create.py b/src/pandapipes/create.py index cca68b3e..dbf233f6 100644 --- a/src/pandapipes/create.py +++ b/src/pandapipes/create.py @@ -881,8 +881,8 @@ def create_compressor(net, from_junction, to_junction, pressure_ratio, name=None def create_pressure_control(net, from_junction, to_junction, controlled_junction, controlled_p_bar, control_active=True, - loss_coefficient=0., max_mdot_kg_per_s=None, name=None, index=None, in_service=True, - type="pressure_control", **kwargs): + loss_coefficient=0., name=None, index=None, in_service=True, type="pressure_control", + **kwargs): """Adds one pressure control that enforces a pressure at a specific junction. The pressure control unit creates a pressure drop / lift between the 'from' and the 'to' @@ -949,7 +949,7 @@ def create_pressure_control(net, from_junction, to_junction, controlled_junction _set_entries(net, "press_control", index, name=name, from_junction=from_junction, to_junction=to_junction, controlled_junction=controlled_junction, control_active=bool(control_active), loss_coefficient=loss_coefficient, controlled_p_bar=controlled_p_bar, in_service=bool(in_service), - max_mdot_kg_per_s=max_mdot_kg_per_s, type=type, **kwargs) + type=type, **kwargs) if controlled_junction != from_junction and controlled_junction != to_junction: logger.warning("The pressure controller %d controls the pressure at a junction that it is " @@ -1507,7 +1507,7 @@ def create_valves(net, from_junctions, to_junctions, diameter_m, opened=True, lo def create_pressure_controls(net, from_junctions, to_junctions, controlled_junctions, controlled_p_bar, control_active=True, loss_coefficient=0., name=None, index=None, in_service=True, - max_mdot_kg_per_s=None, type="pressure_control", **kwargs): + type="pressure_control", **kwargs): """ Convenience function for creating many pressure controls at once. Parameters 'from_junctions'\ and 'to_junctions' must be arrays of equal length. Other parameters may be either arrays of the\ @@ -1571,7 +1571,7 @@ def create_pressure_controls(net, from_junctions, to_junctions, controlled_junct entries = {"name": name, "from_junction": from_junctions, "to_junction": to_junctions, "controlled_junction": controlled_junctions, "controlled_p_bar": controlled_p_bar, "control_active": control_active, "loss_coefficient": loss_coefficient, "in_service": in_service, - "max_mdot_kg_per_s": max_mdot_kg_per_s, "type": type} + "type": type} _set_multiple_entries(net, "press_control", index, **entries, **kwargs) controlled_elsewhere = (controlled_junctions != from_junctions) & (controlled_junctions != to_junctions) @@ -1946,7 +1946,7 @@ def _auto_ext_grid_types(p_bar, t_k, typ, comp): overview = pd.DataFrame({"Position": pos_not_allowed_types, "Type": typ_not_allowed_types}) logger.warning("Please check the following types for component %s, as they must be one of " "the following for correct model implementation: %s. \n%s" % ( - comp.__name__, ALLOWED_EG_TYPES, overview)) + comp.__name__, ALLOWED_EG_TYPES, overview)) p_types = np.isin(typ, [tp for tp in ALLOWED_EG_TYPES if tp not in ["t", "auto"]]) t_types = np.isin(typ, [tp for tp in ALLOWED_EG_TYPES if tp not in ["p", "auto"]]) diff --git a/src/pandapipes/pf/pipeflow_setup.py b/src/pandapipes/pf/pipeflow_setup.py index cb4e3fe6..a0fa6bee 100644 --- a/src/pandapipes/pf/pipeflow_setup.py +++ b/src/pandapipes/pf/pipeflow_setup.py @@ -775,6 +775,8 @@ def reduce_pit(net, mode="hydraulics"): def check_infeed_number(node_pit): slack_nodes = node_pit[:, NODE_TYPE_T] == T + if len(node_pit) == 1: + node_pit[slack_nodes, INFEED] = True infeed_nodes = node_pit[:, INFEED] if sum(infeed_nodes) != sum(slack_nodes): raise PipeflowNotConverged(r'The number of infeeding nodes and slacks do not match') From b36f558c882f0b555e4ed2a600626ee9ae7b9168 Mon Sep 17 00:00:00 2001 From: srdm Date: Thu, 7 Nov 2024 11:21:52 +0100 Subject: [PATCH 07/10] -define logger --- src/pandapipes/component_models/heat_consumer_component.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pandapipes/component_models/heat_consumer_component.py b/src/pandapipes/component_models/heat_consumer_component.py index b17f3fd4..394aea5e 100644 --- a/src/pandapipes/component_models/heat_consumer_component.py +++ b/src/pandapipes/component_models/heat_consumer_component.py @@ -17,6 +17,12 @@ from pandapipes.pf.result_extraction import extract_branch_results_without_internals from pandapipes.properties.properties_toolbox import get_branch_cp +try: + import pandaplan.core.pplog as logging +except ImportError: + import logging + +logger = logging.getLogger(__name__) class HeatConsumer(BranchWZeroLengthComponent): """ From c8b834da9aa90a396bb335cd4f98c383193e4e90 Mon Sep 17 00:00:00 2001 From: Daniel Lohmeier <31214121+dlohmeier@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:34:57 +0100 Subject: [PATCH 08/10] use np.any in heat_consumer_component.py --- src/pandapipes/component_models/heat_consumer_component.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pandapipes/component_models/heat_consumer_component.py b/src/pandapipes/component_models/heat_consumer_component.py index 394aea5e..d3bcf11b 100644 --- a/src/pandapipes/component_models/heat_consumer_component.py +++ b/src/pandapipes/component_models/heat_consumer_component.py @@ -78,8 +78,8 @@ def create_pit_branch_entries(cls, net, branch_pit): treturn = net[cls.table_name()].treturn_k.values hc_pit[~np.isnan(treturn), TOUTINIT] = treturn[~np.isnan(treturn)] mask_q0 = hc_pit[:, QEXT] == 0 & np.isnan(hc_pit[:, MDOTINIT]) - hc_pit[mask_q0, ACTIVE] = False - if any(mask_q0): + if np.any(mask_q0): + hc_pit[mask_q0, ACTIVE] = False logger.warning(r'qext_w is equals to zero for heat consumers with index %s. ' r'Therefore, the defined temperature control cannot be maintained.' \ %net[cls.table_name()].index[mask_q0]) From 53a12b303ae4053b408e8f264098dcba0d400c80 Mon Sep 17 00:00:00 2001 From: Daniel Lohmeier <31214121+dlohmeier@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:36:06 +0100 Subject: [PATCH 09/10] use np.sum in pipeflow_setup.py --- src/pandapipes/pf/pipeflow_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pandapipes/pf/pipeflow_setup.py b/src/pandapipes/pf/pipeflow_setup.py index a0fa6bee..fe1e7dcd 100644 --- a/src/pandapipes/pf/pipeflow_setup.py +++ b/src/pandapipes/pf/pipeflow_setup.py @@ -778,7 +778,7 @@ def check_infeed_number(node_pit): if len(node_pit) == 1: node_pit[slack_nodes, INFEED] = True infeed_nodes = node_pit[:, INFEED] - if sum(infeed_nodes) != sum(slack_nodes): + if np.sum(infeed_nodes) != np.sum(slack_nodes): raise PipeflowNotConverged(r'The number of infeeding nodes and slacks do not match') From 2883737752e4c264c483db1d845e6722b8abcf6c Mon Sep 17 00:00:00 2001 From: srdm Date: Thu, 7 Nov 2024 11:36:50 +0100 Subject: [PATCH 10/10] small bugfixes --- src/pandapipes/component_models/heat_consumer_component.py | 6 +++--- src/pandapipes/pf/pipeflow_setup.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pandapipes/component_models/heat_consumer_component.py b/src/pandapipes/component_models/heat_consumer_component.py index 394aea5e..2d7eac6a 100644 --- a/src/pandapipes/component_models/heat_consumer_component.py +++ b/src/pandapipes/component_models/heat_consumer_component.py @@ -77,9 +77,9 @@ def create_pit_branch_entries(cls, net, branch_pit): hc_pit[~np.isnan(mdot), MDOTINIT] = mdot[~np.isnan(mdot)] treturn = net[cls.table_name()].treturn_k.values hc_pit[~np.isnan(treturn), TOUTINIT] = treturn[~np.isnan(treturn)] - mask_q0 = hc_pit[:, QEXT] == 0 & np.isnan(hc_pit[:, MDOTINIT]) - hc_pit[mask_q0, ACTIVE] = False - if any(mask_q0): + mask_q0 = qext == 0 & np.isnan(mdot) + if np.any(mask_q0): + hc_pit[mask_q0, ACTIVE] = False logger.warning(r'qext_w is equals to zero for heat consumers with index %s. ' r'Therefore, the defined temperature control cannot be maintained.' \ %net[cls.table_name()].index[mask_q0]) diff --git a/src/pandapipes/pf/pipeflow_setup.py b/src/pandapipes/pf/pipeflow_setup.py index a0fa6bee..fe1e7dcd 100644 --- a/src/pandapipes/pf/pipeflow_setup.py +++ b/src/pandapipes/pf/pipeflow_setup.py @@ -778,7 +778,7 @@ def check_infeed_number(node_pit): if len(node_pit) == 1: node_pit[slack_nodes, INFEED] = True infeed_nodes = node_pit[:, INFEED] - if sum(infeed_nodes) != sum(slack_nodes): + if np.sum(infeed_nodes) != np.sum(slack_nodes): raise PipeflowNotConverged(r'The number of infeeding nodes and slacks do not match')