Example 8: pandapipes

This Example demonstrates a pandapipes calculation of a 1-pipe, 2-nodes SIR 3S model.

Read SIR 3S Model

[1]:
try:
    from PT3S import dxAndMxHelperFcts
except:
    import dxAndMxHelperFcts
[2]:
import logging

logger = logging.getLogger()

logFileName= r"Example8.log"

loglevel = logging.DEBUG
logging.basicConfig(filename=logFileName
                        ,filemode='w'
                        ,level=loglevel
                        ,format="%(asctime)s ; %(name)-60s ; %(levelname)-7s ; %(message)s")

fileHandler = logging.FileHandler(logFileName)

logger.addHandler(fileHandler)

consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logging.Formatter("%(levelname)-7s ; %(message)s"))
consoleHandler.setLevel(logging.INFO)
logger.addHandler(consoleHandler)

logging.getLogger('numba').setLevel(logging.ERROR)
logging.getLogger('pandapipes').setLevel(logging.ERROR)
logging.getLogger('matplotlib').setLevel(logging.ERROR)
[ ]:
from importlib import resources
[ ]:
dbFilename="Example8"
dbFile = resources.files("PT3S").joinpath("Examples", f"{dbFilename}.db3")
[4]:
m=dxAndMxHelperFcts.readDxAndMx(dbFile=dbFile)
INFO    ; Dx.__init__: dbFile (abspath): c:\users\aUserName\3s\pt3s\Examples\Example8.db3 exists readable ...
INFO    ; Dx.__init__:  SYSTEMKONFIG ID 3 not defined. Value(ID=3) is supposed to define the Model which is used in QGIS. Now QGISmodelXk is undefined ...
INFO    ; dxAndMxHelperFcts.readDxAndMx: ..\Examples\Example8-dx.pkl exists and is overwritten...
INFO    ; dxAndMxHelperFcts.readDxAndMx:  QGISmodelXk not defined. Now the MX of 1st Model in VIEW_MODELLE is used ...
INFO    ; Mx.setResultsToMxsFile: Mxs: ..\Examples\WDExample8\B1\V0\BZ1\M-1-0-1.1.MXS reading ...
INFO    ; dxAndMxHelperFcts.readDxAndMx: ..\Examples\Example8-mx-_Examples_WDExample8_B1_V0_BZ1_M_1_0_1_1_MX1.pkl exists and is overwritten...
INFO    ; dxWithMx.__init__: Example8: processing dx and mx ...
INFO    ; dxAndMxHelperFcts.readDxAndMx: ..\Examples\Example8-m.pkl exists and is overwritten...

Generate corresponding pp model

[5]:
#!pip install pandapipes
[6]:
import pandapipes
net = pandapipes.create_empty_network(fluid="water")

junctions

[7]:
# create junctions
js={}
for idx,row in m.V3_KNOT.iterrows():
    j=pandapipes.create_junction(net
                       ,pn_bar=row['PH']
                       ,tfluid_k=273.15+row['T']
                       ,height_m=row['ZKOR']
                       ,name=f"{row['NAME']}~{row['tk']}"
    )
    js[row['tk']]=j
[8]:
net.junction
[8]:
name pn_bar tfluid_k height_m in_service type
0 j1~5545156887373324999 10.000000 363.15000 0.0 True junction
1 j2~4658286599152640406 9.578555 362.81214 0.0 True junction

pipes

[9]:
# create pipes
ps={}
for idx,row in m.V3_ROHR.iterrows():
     p=pandapipes.create_pipe_from_parameters(net
                                  ,from_junction=js[row['fkKI']]
                                  ,to_junction=js[row['fkKK']]
                                  ,length_km=row['L']/1000.
                                  ,diameter_m=row['DI']/1000.
                                  ,k_mm=row['RAU']
                                  ,name=f"{row['NAME_i']}~{row['NAME_k']}~{row['tk']}"
     )
     ps[row['tk']]=p

[10]:
net.pipe
[10]:
name from_junction to_junction std_type length_km diameter_m k_mm loss_coefficient u_w_per_m2k text_k qext_w sections in_service type
0 j1~j2~5436899515124385631 0 1 None 1.0 0.2 0.25 0.0 0.0 NaN 0.0 1 True pipe

sources (ext. grids)

[11]:
# sources (ext. grids)
for idx,row in m.V3_KNOT.iterrows():
    match row['KTYP']:
        case 'PKON':
            pandapipes.create_ext_grid(net
                              ,junction=js[row['tk']]
                              ,p_bar=row['PH']
                              ,t_k=273.15+row['T']
                              ,name=f"Src: {row['NAME']}~{row['tk']}"
            )
        case _:
            continue
[12]:
net.ext_grid
[12]:
name junction p_bar t_k in_service type
0 Src: j1~5545156887373324999 0 10.0 363.15 True pt

sinks

[13]:
# sinks
for idx,row in m.V3_KNOT.iterrows():
    match row['KTYP']:
        case 'QKON':
            pandapipes.create_sink(net
                         ,junction=js[row['tk']]
                         ,mdot_kg_per_s=-row['M']
                         ,name=f"Snk: {row['NAME']}~{row['tk']}"
            )

        case _:
            continue
[14]:
net.sink
[14]:
name junction mdot_kg_per_s scaling in_service type
0 Snk: j2~4658286599152640406 1 27.777779 1.0 True sink

calculate pp model

[15]:
pandapipes.pipeflow(net
            ,friction_model='colebrook'
            #,mode='sequential'
            )

examine pp result

junctions

[16]:
net.res_junction
[16]:
p_bar t_k
0 10.0000 363.15000
1 9.5709 362.81214

pipes

[17]:
net.res_pipe
[17]:
v_mean_m_per_s p_from_bar p_to_bar t_from_k t_to_k t_outlet_k mdot_from_kg_per_s mdot_to_kg_per_s vdot_m3_per_s reynolds lambda
0 0.915959 10.0 9.5709 363.15 362.81214 362.81214 27.777779 -27.777779 0.028776 561271.686993 0.021193

sources (ext. grids)

[18]:
net.res_ext_grid
[18]:
mdot_kg_per_s
0 -27.777779

sinks

[19]:
net.res_sink
[19]:
mdot_kg_per_s
0 27.777779

compare results

mapping

[20]:
m.V3_KNOT['ppID']=m.V3_KNOT.apply(lambda row: js[row['tk']],axis=1)
[21]:
m.V3_ROHR['ppID']=m.V3_ROHR.apply(lambda row: ps[row['tk']],axis=1)
[22]:
import pandas as pd
dfCmpJunctions=pd.merge(m.V3_KNOT,net.res_junction,left_on='ppID',right_index=True)
dfCmpPipes=pd.merge(m.V3_ROHR,net.res_pipe,left_on='ppID',right_index=True)

dfCmpJunctions['t_C']=dfCmpJunctions['t_k']-273.15
dfCmpPipes['t_from_C']=dfCmpPipes['t_from_k']-273.15
dfCmpPipes['t_to_C']=dfCmpPipes['t_to_k']-273.15
[23]:
dfCmpPipes
[23]:
pk fkDE rk tk fkKI fkKK fkDTRO_ROWD fkLTGR fkSTRASSE L LZU RAU JLAMBS LAMBDA0 ZEIN ZAUS ZUML ASOLL INDSCHALL BAUJAHR HAL fkCONT fk2LROHR BESCHREIBUNG GEOMWKB DELETED SELECT1 IDREFERENZ KENNUNG IPLANUNG KVR pk_BZ fkDE_BZ fk QSVB IRTRENN LECKSTATUS LECKSTART LECKEND LECKORT LECKMENGE IMPTNZ ZVLIMPTNZ KANTENZV GEOM GRAF MId MText Basis Variante BZ Geaendert Erstellt pk_VMBZ fkBASIS fkVARIANTE fkBZ MZ MT pk_CONT fkDE_CONT rk_CONT tk_CONT ID_CONT NAME_CONT IDPARENT_CONT rkPARENT_CONT LFDNR_CONT GRAF_CONT FONT_CONT GEOM_CONT DELETED_CONT SELECT1_CONT IDREFERENZ_CONT NAME_DTRO DN DI DA S KT PN Am2 Vm3 NAME_LTGR NAME_STRASSE tk_i NAME_i tk_k NAME_k mx2NofPts dL mx2Idx (STAT, ROHR~*~*~*~A, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DTTR, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DWVERL, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DWVERLABS, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~IAKTIV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~IRTRENN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~JV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~LAMBDA, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~MAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PDAMPF, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PHR, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PMIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~QMAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~VAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~VOLDA, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~WVL, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~ZAUS, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~ZEIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) ('STAT', 'KNOT~*~*~*~PH', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~H', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~T', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~RHO', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~PH', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~H', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~T', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~RHO', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k QMAVAbs VAVAbs PHRAbs JVAbs MAV LAMBDA ppID v_mean_m_per_s p_from_bar p_to_bar t_from_k t_to_k t_outlet_k mdot_from_kg_per_s mdot_to_kg_per_s vdot_m3_per_s reynolds lambda t_from_C t_to_C
0 5436899515124385631 4982567935033599504 5436899515124385631 5436899515124385631 5545156887373324999 4658286599152640406 5456839515335324031 5515842498618683031 -1 1000.0 None 0.25 1.0 0.025 None None None 1000.0 None None None 5060822126933396627 -1 Template Element for single Pipe Creation None None None 3S5201225267441779810 NaN 1.0 NaN 4741144811589278980 4804028781596645401 5436899515124385631 None None None None None None None None None None b'\x01\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00... b'\x00\x00\x80?\x00\x00\x00\x00\x01\x00\x00\x0... M-1-0-1 B1 V0 BZ1 2025-05-09 13:17:45 2025-04-08 11:45:59 5703508123076770847 4982567935033599504 5151772185690695097 4804028781596645401 1 1 5060822126933396627 4982567935033599504 5060822126933396627 5060822126933396627 1001.0 M-1-0-1 1001.0 5060822126933396627 None None None b'\x00\x00\x80?\x01\x00\x00\x00\x01\x00\x00\x0... 0.0 0.0 None STDROHR xxx 200.0 0.0 0.0 0.494 0.0 0.031416 31.415927 STDROHR None 5545156887373324999 j1 4658286599152640406 j2 11 100.0 0 0.0 0.308801 39.43655 39.43655 0.0 0.0 0.414041 0.021201 27.777779 0.696674 0.414041 10.578555 100.0 0.899538 -3.333333e+32 0.0 0.0 0.0 10.0 10.0 90.0 965.200012 9.578555 9.578555 89.66214 965.571655 100.0 0.899538 0.414041 0.414041 27.777779 0.021201 0 0.915959 10.0 9.5709 363.15 362.81214 362.81214 27.777779 -27.777779 0.028776 561271.686993 0.021193 90.0 89.66214
[ ]:

comparison

[24]:
dfCmpJunctions
[24]:
pk fkDE rk tk NAME KTYP XKOR YKOR ZKOR QM_EIN LFAKT fkPZON fkFSTF fkUTMP fkFQPS fkCONT fk2LKNOT BESCHREIBUNG GEOMWKB DELETED SELECT1 IDREFERENZ KENNUNG IPLANUNG KVR DRAKONZ pk_BZ fkDE_BZ fk fkPVAR fkQVAR fkLFKT PH_EIN TM TE PH_MIN GRAF MId MText Basis Variante BZ Geaendert Erstellt pk_VMBZ fkBASIS fkVARIANTE fkBZ MZ MT pk_CONT fkDE_CONT rk_CONT tk_CONT ID_CONT NAME_CONT IDPARENT_CONT rkPARENT_CONT LFDNR_CONT GRAF_CONT FONT_CONT GEOM_CONT DELETED_CONT SELECT1_CONT IDREFERENZ_CONT pk_VKNO fkDE_VKNO rk_VKNO fkKNOT_VKNO fkCONT_VKNO SHOWNAME_VKNO POSNAME_VKNO POINTINSERTX_VKNO POINTINSERTY_VKNO SYMBOLFACT_VKNO DISPLAYMODE_VKNO DELETED_VKNO SELECT1_VKNO MId_VKNO MText_VKNO Basis_VKNO Variante_VKNO BZ_VKNO Geaendert_VKNO Erstellt_VKNO pk_VMBASIS_VKNO fkBASIS_VKNO fkVARIANTE_VKNO fkBZ_VKNO MZ_VKNO MT_VKNO MId_VMVARIANTE_VKNO MText_VMVARIANTE_VKNO Basis_VMVARIANTE_VKNO Variante_VMVARIANTE_VKNO BZ_VMVARIANTE_VKNO Geaendert_VMVARIANTE_VKNO Erstellt_VMVARIANTE_VKNO pk_VMVARIANTE_VKNO fkBASIS_VMVARIANTE_VKNO fkVARIANTE_VMVARIANTE_VKNO fkBZ_VMVARIANTE_VKNO MZ_VMVARIANTE_VKNO MT_VMVARIANTE_VKNO pk_CONT_VKNO fkDE_CONT_VKNO rk_CONT_VKNO tk_CONT_VKNO ID_CONT_VKNO NAME_CONT_VKNO IDPARENT_CONT_VKNO rkPARENT_CONT_VKNO LFDNR_CONT_VKNO GRAF_CONT_VKNO FONT_CONT_VKNO GEOM_CONT_VKNO DELETED_CONT_VKNO SELECT1_CONT_VKNO IDREFERENZ_CONT_VKNO NAME_LFKT NAME_PVAR NAME_PZON NAME_QVAR NAME_UTMP NAME_FSTF NAME_FQPS mx2Idx (STAT, KNOT~*~*~*~BCIND, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~DP, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~DPH, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~FITT_BASTYPE, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~FITT_DP1, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~FITT_DP2, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~FITT_DP3, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~FITT_STATE, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~H, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~IAKTIV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~LFAKTAKT, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~M, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~P, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~PDAMPF, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~PH, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~PHMINMAXDIF, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~PH_EIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~PH_MIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~QM, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~RHO, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~T, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~TTR, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, KNOT~*~*~*~VOLD, 2025-04-08 09:45:59, 2025-04-08 09:45:59) PH QM dPH T M ppID p_bar t_k t_C
3 5545156887373324999 4982567935033599504 5545156887373324999 5545156887373324999 j1 PKON 300.000012 649.999976 0.0 NaN 1.0 -1 5297658028320820931 5154968777807259962 -1 5060822126933396627 -1 Template Element for single Node Creation None None None 3S5671171592228004325 NaN 1.0 NaN None 5473573628395650757 4804028781596645401 5545156887373324999 -1 -1 -1 10.0 None 90.0 None b'\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00... M-1-0-1 B1 V0 BZ1 2025-05-09 13:17:45 2025-04-08 11:45:59 5703508123076770847 4982567935033599504 5151772185690695097 4804028781596645401 1 1 5060822126933396627 4982567935033599504 5060822126933396627 5060822126933396627 1001.0 M-1-0-1 1001.0 5060822126933396627 None None None b'\x00\x00\x80?\x01\x00\x00\x00\x01\x00\x00\x0... 0.0 0.0 None NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN None None None None Standard Standard None NaN 24.0 -3.333333e+32 -3.333333e+32 -333333333.0 -3.333333e+32 -3.333333e+32 -3.333333e+32 -333333333.0 10.000000 0.0 1.0 27.777779 11.000000 0.701100 10.000000 0.0 10.000000 0.0 100.0 965.200012 90.00000 0.000000 0.0 10.000000 100.0 None 90.00000 27.777779 0 10.0000 363.15000 90.00000
4 4658286599152640406 4982567935033599504 4658286599152640406 4658286599152640406 j2 QKON 449.999917 499.999869 0.0 -100.0 1.0 -1 5297658028320820931 5154968777807259962 -1 5060822126933396627 -1 Template Element for single Node Creation None None None 3S5671171592228004325 NaN 1.0 NaN None 4927625957676832607 4804028781596645401 4658286599152640406 -1 -1 -1 NaN None NaN None b'\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00... M-1-0-1 B1 V0 BZ1 2025-05-09 13:17:45 2025-04-08 11:45:59 5703508123076770847 4982567935033599504 5151772185690695097 4804028781596645401 1 1 5060822126933396627 4982567935033599504 5060822126933396627 5060822126933396627 1001.0 M-1-0-1 1001.0 5060822126933396627 None None None b'\x00\x00\x80?\x01\x00\x00\x00\x01\x00\x00\x0... 0.0 0.0 None NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN None None None None Standard Standard None NaN 21.0 -3.333333e+32 -3.333333e+32 -333333333.0 -3.333333e+32 -3.333333e+32 -3.333333e+32 -333333333.0 9.578555 0.0 1.0 -27.777779 10.578555 0.692248 9.578555 0.0 9.578555 0.0 -100.0 965.571655 89.66214 0.308801 0.0 9.578555 -100.0 None 89.66214 -27.777779 1 9.5709 362.81214 89.66214
[25]:
dfCmpPipes
[25]:
pk fkDE rk tk fkKI fkKK fkDTRO_ROWD fkLTGR fkSTRASSE L LZU RAU JLAMBS LAMBDA0 ZEIN ZAUS ZUML ASOLL INDSCHALL BAUJAHR HAL fkCONT fk2LROHR BESCHREIBUNG GEOMWKB DELETED SELECT1 IDREFERENZ KENNUNG IPLANUNG KVR pk_BZ fkDE_BZ fk QSVB IRTRENN LECKSTATUS LECKSTART LECKEND LECKORT LECKMENGE IMPTNZ ZVLIMPTNZ KANTENZV GEOM GRAF MId MText Basis Variante BZ Geaendert Erstellt pk_VMBZ fkBASIS fkVARIANTE fkBZ MZ MT pk_CONT fkDE_CONT rk_CONT tk_CONT ID_CONT NAME_CONT IDPARENT_CONT rkPARENT_CONT LFDNR_CONT GRAF_CONT FONT_CONT GEOM_CONT DELETED_CONT SELECT1_CONT IDREFERENZ_CONT NAME_DTRO DN DI DA S KT PN Am2 Vm3 NAME_LTGR NAME_STRASSE tk_i NAME_i tk_k NAME_k mx2NofPts dL mx2Idx (STAT, ROHR~*~*~*~A, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DTTR, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DWVERL, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~DWVERLABS, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~IAKTIV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~IRTRENN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~JV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~LAMBDA, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~MAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PDAMPF, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PHR, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~PMIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~QMAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~VAV, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~VOLDA, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~WVL, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~ZAUS, 2025-04-08 09:45:59, 2025-04-08 09:45:59) (STAT, ROHR~*~*~*~ZEIN, 2025-04-08 09:45:59, 2025-04-08 09:45:59) ('STAT', 'KNOT~*~*~*~PH', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~H', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~T', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~RHO', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_i ('STAT', 'KNOT~*~*~*~PH', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~H', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~T', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k ('STAT', 'KNOT~*~*~*~RHO', Timestamp('2025-04-08 09:45:59'), Timestamp('2025-04-08 09:45:59'))_k QMAVAbs VAVAbs PHRAbs JVAbs MAV LAMBDA ppID v_mean_m_per_s p_from_bar p_to_bar t_from_k t_to_k t_outlet_k mdot_from_kg_per_s mdot_to_kg_per_s vdot_m3_per_s reynolds lambda t_from_C t_to_C
0 5436899515124385631 4982567935033599504 5436899515124385631 5436899515124385631 5545156887373324999 4658286599152640406 5456839515335324031 5515842498618683031 -1 1000.0 None 0.25 1.0 0.025 None None None 1000.0 None None None 5060822126933396627 -1 Template Element for single Pipe Creation None None None 3S5201225267441779810 NaN 1.0 NaN 4741144811589278980 4804028781596645401 5436899515124385631 None None None None None None None None None None b'\x01\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00... b'\x00\x00\x80?\x00\x00\x00\x00\x01\x00\x00\x0... M-1-0-1 B1 V0 BZ1 2025-05-09 13:17:45 2025-04-08 11:45:59 5703508123076770847 4982567935033599504 5151772185690695097 4804028781596645401 1 1 5060822126933396627 4982567935033599504 5060822126933396627 5060822126933396627 1001.0 M-1-0-1 1001.0 5060822126933396627 None None None b'\x00\x00\x80?\x01\x00\x00\x00\x01\x00\x00\x0... 0.0 0.0 None STDROHR xxx 200.0 0.0 0.0 0.494 0.0 0.031416 31.415927 STDROHR None 5545156887373324999 j1 4658286599152640406 j2 11 100.0 0 0.0 0.308801 39.43655 39.43655 0.0 0.0 0.414041 0.021201 27.777779 0.696674 0.414041 10.578555 100.0 0.899538 -3.333333e+32 0.0 0.0 0.0 10.0 10.0 90.0 965.200012 9.578555 9.578555 89.66214 965.571655 100.0 0.899538 0.414041 0.414041 27.777779 0.021201 0 0.915959 10.0 9.5709 363.15 362.81214 362.81214 27.777779 -27.777779 0.028776 561271.686993 0.021193 90.0 89.66214
[26]:
import math

def fCmp2(row
         ,col1
         ,col2
         ,col2Offset=0.
         ,dAbsMax=0.01 # max. tol. Abw.
         ,dProzMax=0.1 # max. tol. Abw. in %
    ):

    #print(row)
    #print(dAbsMax)
    d=row[col1]-(row[col2]+col2Offset)
    dAbs=math.fabs(d)


    dProz=dAbs/row[col1]*100


    l = ['color: red' if dProz > dProzMax or dAbs > dAbsMax else 'color: green' for _ in row]
    return ['',l[1]]

def stylerJunctions(styler):
    styler.set_caption("SIR 3S vs. pp: Junctions")
    styler.format(
    {
        'PH': '{:,.3f}',
        'p_bar': '{:,.3f}',
        'T': '{:,.2f}',
        't_k': '{:,.2f}',
        't_C': '{:,.2f}',
    },
    na_rep='-',
    precision=0
    )


    styler.apply(fCmp2,axis=1,subset=['PH','p_bar'],col1='PH',col2='p_bar',dAbsMax=0.01)

    styler.apply(fCmp2,axis=1,subset=['T','t_k'],col1='T',col2='t_k',dAbsMax=0.01,col2Offset=-273.15)

    return styler
[27]:
dfCmpJunctions[['NAME','PH','p_bar','T','t_k','t_C']].style.pipe(stylerJunctions)
[27]:
SIR 3S vs. pp: Junctions
  NAME PH p_bar T t_k t_C
3 j1 10.000 10.000 90.00 363.15 90.00
4 j2 9.579 9.571 89.66 362.81 89.66
[28]:

def stylerPipes(styler): styler.set_caption("SIR 3S vs. pp: Pipes") styler.format( { 'QMAVAbs': '{:,.2f}', 'mdot_from_kg_per_s': '{:,.2f}', 'MAV': '{:,.2f}', 'LAMBDA': '{:,.5f}', 'lambda': '{:,.5f}', }, na_rep='-', precision=0 ) styler.apply(fCmp2,axis=1,subset=['LAMBDA','lambda'],col1='LAMBDA',col2='lambda',dAbsMax=0.00001) styler.apply(fCmp2,axis=1,subset=['MAV','mdot_from_kg_per_s'],col1='MAV',col2='mdot_from_kg_per_s',dAbsMax=0.01) return styler
[29]:
dfCmpPipes[['NAME_i','NAME_k','QMAVAbs','MAV', 'mdot_from_kg_per_s','LAMBDA','lambda','reynolds']].style.pipe(stylerPipes)
[29]:
SIR 3S vs. pp: Pipes
  NAME_i NAME_k QMAVAbs MAV mdot_from_kg_per_s LAMBDA lambda reynolds
0 j1 j2 100.00 27.78 27.78 0.02120 0.02119 561272

example for determining roughness

[30]:
def fDetRau(net=net, pSoll=9.4, dk=1):

    pIst=net.res_junction.loc[1,'p_bar']
    dp=pSoll-pIst

    if math.fabs(dp) <= 0.001:
        print(f"pIst={pIst:.3f} dp={dp:.3f} k={net.pipe.loc[0,'k_mm']:.4f} (dk={dk:.4f})")
        return(pIst,net.pipe.loc[0,'k_mm'])

    dpVStart=math.copysign(1,dp)
    dpV=dpVStart

    while dpV == dpVStart:

        # Rauheit veraendern
        if dp > 0:
            dkAdd=-dk
        else:
            dkAdd=dk

        net.pipe.loc[0,'k_mm']=net.pipe.loc[0,'k_mm']+dkAdd

        # rechnen
        pandapipes.pipeflow(net
                ,friction_model='colebrook'
                #,mode='sequential'
                )

        pIst=net.res_junction.loc[1,'p_bar']
        dp=pSoll-pIst

        dpV=math.copysign(1,dp)

    fDetRau(net=net, pSoll=9.4, dk=dk/2)

[31]:
fDetRau()
pIst=9.400 dp=0.000 k=0.9062 (dk=0.0078)

Example using pnh

installation

[32]:
!pip install -U pnh
Requirement already satisfied: pnh in c:\users\wolters\appdata\local\anaconda3\lib\site-packages (0.0.8)
[33]:
try:
    from pnh.utils.gen_model_from_nx import pp
except Exception as e:
    from utils.gen_model_from_nx import pp
[34]:
try:
    import pnh.utils.gen_model_from_nx as gen_model_from_nx
except Exception as e:
    import utils.gen_model_from_nx as gen_model_from_nx
[35]:
import importlib
[36]:
#importlib.reload(gen_model_from_nx)
# should be \\AppData\\Local\\anaconda3\\Lib\\site-packages...
[37]:
m.G
[37]:
<networkx.classes.graph.Graph at 0x24f2f9fb0d0>

generating pp model

[38]:
m.G.nodes['j1'].update({'extPressure':m.G.nodes['j1']['PH']})
[39]:
m.G.nodes['j2'].update({'extFlow':m.G.nodes['j2']['M']})
[40]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='DI'
       ,k='RAU'
)
[41]:
pandapipes.pipeflow(ppn,friction_model='colebrook')

generation pp model with heat transfer

[42]:
m.G['j1']['j2'].update({'alpha':0.494,'Ta':273.15+10.})
[43]:
m.G.nodes['j1'].update({'inletTemperature':273.15+90.})
[44]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='DI'
       ,k='RAU'
)
[45]:
pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional'
                    ,tol_p=1.e-5,tol_res=1.e-4
)

compare results

[46]:
#                                                                    from gen_model_from_nx.pp
m.V3_KNOT['ppID']=m.V3_KNOT.apply(lambda row: m.G.nodes[row['NAME']]['ID'],axis=1)
#                                                                                    from gen_model_from_nx.pp
m.V3_ROHR['ppID']=m.V3_ROHR.apply(lambda row: m.G.edges[row['NAME_i'],row['NAME_k']]['ID'],axis=1)
[47]:
dfCmpJunctions=pd.merge(m.V3_KNOT,ppn.res_junction,left_on='ppID',right_index=True)
dfCmpPipes=pd.merge(m.V3_ROHR,ppn.res_pipe,left_on='ppID',right_index=True)

dfCmpJunctions['t_C']=dfCmpJunctions['t_k']-273.15
dfCmpPipes['t_from_C']=dfCmpPipes['t_from_k']-273.15
dfCmpPipes['t_to_C']=dfCmpPipes['t_to_k']-273.15
[48]:
dfCmpJunctions[['NAME','PH','p_bar','T','t_k','t_C']].style.pipe(stylerJunctions)
[48]:
SIR 3S vs. pp: Junctions
  NAME PH p_bar T t_k t_C
3 j1 10.000 10.000 90.00 363.15 90.00
4 j2 9.579 9.571 89.66 362.81 89.66
[49]:
dfCmpPipes[['NAME_i','NAME_k','QMAVAbs','MAV', 'mdot_from_kg_per_s','LAMBDA','lambda','reynolds']].style.pipe(stylerPipes)
[49]:
SIR 3S vs. pp: Pipes
  NAME_i NAME_k QMAVAbs MAV mdot_from_kg_per_s LAMBDA lambda reynolds
0 j1 j2 100.00 27.78 27.78 0.02120 0.02119 561273

experiment: set D to SIR 3S’ VAV

\[\overline{D} = \sqrt{\frac{4}{\pi} \, \frac{m}{\rho} \, \frac{1}{\overline{v}}}\]
[50]:
v_=m.V3_ROHR['VAVAbs'].iloc[0]
[51]:
v_
[51]:
0.8995376825332642
[52]:
D_=math.sqrt(4/math.pi*1/v_*math.fabs(m.G.nodes['j2']['M'])/(m.G.edges['j1','j2']['RHO_i']))*1000
[53]:
D_
[53]:
201.82988634654708
[54]:
m.G.edges['j1','j2']['D_']=D_
[55]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='D_'
       ,k='RAU'
)
[56]:
pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional')
[57]:
dfCmpJunctions=pd.merge(m.V3_KNOT,ppn.res_junction,left_on='ppID',right_index=True)
dfCmpPipes=pd.merge(m.V3_ROHR,ppn.res_pipe,left_on='ppID',right_index=True)

dfCmpJunctions['t_C']=dfCmpJunctions['t_k']-273.15
dfCmpPipes['t_from_C']=dfCmpPipes['t_from_k']-273.15
dfCmpPipes['t_to_C']=dfCmpPipes['t_to_k']-273.15
[58]:
dfCmpJunctions[['NAME','PH','p_bar','T','t_k','t_C']].style.pipe(stylerJunctions)
[58]:
SIR 3S vs. pp: Junctions
  NAME PH p_bar T t_k t_C
3 j1 10.000 10.000 90.00 363.15 90.00
4 j2 9.579 9.591 89.66 362.81 89.66
[59]:
dfCmpPipes[['NAME_i','NAME_k','QMAVAbs','MAV', 'mdot_from_kg_per_s','LAMBDA','lambda','reynolds']].style.pipe(stylerPipes)
[59]:
SIR 3S vs. pp: Pipes
  NAME_i NAME_k QMAVAbs MAV mdot_from_kg_per_s LAMBDA lambda reynolds
0 j1 j2 100.00 27.78 27.78 0.02120 0.02115 556184

determining roughness due to required friction pressure loss

[60]:
try:
    from pnh.utils.calc_k_from_dp import pp as ppk
except Exception as e:
    from utils.calc_k_from_dp import pp as ppk

1-pipe, 2-nodes network

[61]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='DI'
       ,k='RAU'
)

calculate with pp

[62]:
pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional')
[63]:
dfCmpJunctions=pd.merge(m.V3_KNOT,ppn.res_junction,left_on='ppID',right_index=True)
dfCmpPipes=pd.merge(m.V3_ROHR,ppn.res_pipe,left_on='ppID',right_index=True)

dfCmpJunctions['t_C']=dfCmpJunctions['t_k']-273.15
dfCmpPipes['t_from_C']=dfCmpPipes['t_from_k']-273.15
dfCmpPipes['t_to_C']=dfCmpPipes['t_to_k']-273.15
[64]:
dfCmpJunctions[['NAME','PH','p_bar','T','t_k','t_C']].style.pipe(stylerJunctions)
[64]:
SIR 3S vs. pp: Junctions
  NAME PH p_bar T t_k t_C
3 j1 10.000 10.000 90.00 363.15 90.00
4 j2 9.579 9.571 89.66 362.81 89.66
[65]:
dfCmpPipes[['NAME_i','NAME_k','QMAVAbs','MAV', 'mdot_from_kg_per_s','LAMBDA','lambda','reynolds']].style.pipe(stylerPipes)
[65]:
SIR 3S vs. pp: Pipes
  NAME_i NAME_k QMAVAbs MAV mdot_from_kg_per_s LAMBDA lambda reynolds
0 j1 j2 100.00 27.78 27.78 0.02120 0.02119 561273

required friction loss

[66]:
m.G.edges['j1','j2'].update({'dpFL_SP':0.7})

calculate roughness

[67]:
ppk(m.G,ppn)
m.G.edges['j1','j2']['k_MV']

[67]:
1.5

control: set roughness to calculated roughness

[68]:
m.G.edges['j1','j2'].update({'RAU_':m.G.edges['j1','j2']['k_MV']})
[69]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='DI'
       ,k='RAU_'
)
[70]:
pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional')
[71]:
ppn.res_junction
[71]:
p_bar t_k
0 10.000000 363.150000
1 9.300053 362.812397

required friction loss lower

[72]:
m.G.edges['j1','j2'].update({'dpFL_SP':0.5})
ppk(m.G,ppn)
m.G.edges['j1','j2']['k_MV']
[72]:
0.4688125000000001
[73]:
m.G.edges['j1','j2'].update({'dpFL_SP':0.1})
ppk(m.G,ppn)
m.G.edges['j1','j2']['k_MV']
[73]:
0.001
[74]:
ppk(m.G,ppn,k_min=0.002)
m.G.edges['j1','j2']['k_MV']
[74]:
0.002
[75]:
m.G.edges['j1','j2'].update({'RAU_':m.G.edges['j1','j2']['k_MV']})
[76]:
ppn=pp(m.G
       ,fluid='water'
       ,TNet=273.15+m.G.nodes['j1']['T']
       ,pNet=m.G.nodes['j1']['PH']
       ,z='ZKOR'
       ,diameter='DI'
       ,k='RAU_'
)
[77]:
pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional')
[78]:
ppn.res_junction
[78]:
p_bar t_k
0 10.000000 363.150000
1 9.735941 362.812397
[ ]:

determining SIR 3S’s roughness due to required friction pressure loss

[79]:
import shutil
import xml.etree.ElementTree as ET
import subprocess
import re
import sys
import networkx

logging.getLogger('PT3S').setLevel(logging.ERROR)

try:
    from PT3S import Mx
except:
    import Mx

def sir3sk(
    # 2-node, 1-pipe SIR 3S Model
    dbFile=dbFile
    # pipe-length in m
   ,L=1000.
    # DN in mm
   ,DI=200.
   ,DA=None
   ,KT=None  # W/(mK)
   # geodetic heights
   ,zi=None ,zk=None
   # inlet pressure in bar (== model unit); node i: PKON expected
   ,pi=None

   # inlet temperature in °C
   ,Ti=90.
   # outer temperature in °C
   ,Ta=10. # not set in SIR 3S Model; should be SIR 3S Model outer temperature

   # flow in model unit; node k: QKON expected
   ,mk=None
   # dp due to friction loss in bar
   ,dp_SP=.5
   ,dp_ER=0.001
   ,dkSir3sStart=.01 # dk start iteration step for k calculation in SIR 3S in mm
   ,k_min=0.001 # min. allowed k in mm
):
    """
    Calculates k to achieve dp_SP

    Returns: k in mm
    """

    logStr=f"{sys._getframe().f_code.co_name}:"

    # read the model
    m=dxAndMxHelperFcts.readDxAndMx(dbFile=dbFile
    ,maxRecords=-1
    ,forceSir3sRead=True
    )

    SirCalcExe=r"C:\3S\Sir3s\SirCalc-90-14-02-12_Potsdam.fix1_x64\SirCalc.exe"
    pOpenAr=[SirCalcExe
       ,'/rstnSpezial'
       ,'/InteraktRgMax1000'
       ,'/InteraktThMax1000'
       ,m.SirCalcXmlFile]

    # read the model's Xml
    tree = ET.parse(m.SirCalcXmlFile) # ElementTree
    root = tree.getroot()  # Element

    # set parameter #######################################

    pathStr = f"./ROHR[@fkKI!='-1']"
    pipeEl=root.findall(pathStr)[0]

    pathStr = f"./DTRO_ROWD[@pk='{pipeEl.get('fkDTRO_ROWD')}']"
    DNEl=root.findall(pathStr)[0]

    pathStr = f"./KNOT[@pk='{pipeEl.get('fkKI')}']"
    nodeKiEl=root.findall(pathStr)[0]
    pathStr = f"./KNOT_BZ[@fk='{nodeKiEl.get('pk')}']"
    nodeKiBzEl=root.findall(pathStr)[0]

    pathStr = f"./KNOT[@pk='{pipeEl.get('fkKK')}']"
    nodeKkEl=root.findall(pathStr)[0]
    pathStr = f"./KNOT_BZ[@fk='{nodeKkEl.get('pk')}']"
    nodeKkBzEl=root.findall(pathStr)[0]

    # pipe
    if L!=None:
        logger.debug(f"set L to {L}")
        pipeEl.set('L',str(L))
    if DI!=None:
        logger.debug(f"set DI to {DI}")
        DNEl.set('DI',str(DI))
    if DA!=None:
        logger.debug(f"set DA to {DA}")
        DNEl.set('DA',str(DA))
    if KT!=None:
        logger.debug(f"set KT to {KT}")
        DNEl.set('KT',str(KT))

    # nodes z
    if zi != None:
        logger.debug(f"set zi to {zi}")
        nodeKiEl.set('ZKOR',str(zi))
    if zk != None:
        logger.debug(f"set zk to {zk}")
        nodeKkEl.set('ZKOR',str(zk))

    # nodes BC
    if pi != None:
        logger.debug(f"set pi to {pi}")
        nodeKiBzEl.set('PH_EIN',str(pi))
    if Ti != None:
        logger.debug(f"set TE to {Ti}")
        nodeKiBzEl.set('TE',str(Ti))
    if mk != None:
        logger.debug(f"set mk to {mk}")
        nodeKkBzEl.set('QM_EIN',str(mk))
        nodeKkEl.set('QM_EIN',str(mk)) #!

    dz=float(nodeKiEl.get('ZKOR'))-float(nodeKkEl.get('ZKOR'))

    # write
    tree.write(m.SirCalcXmlFile)

    # calculate
    with subprocess.Popen(pOpenAr) as process:
        process.wait()
        logger.debug(f'Command {process.args} exited with {process.returncode}.')

    # read result
    mx=Mx.Mx(m.mx.mx1File)
    mx.df.rename(columns={col:col.replace(Mx.reSir3sIDSep+mo.group('OBJTYPE_PK'),'') for col,mo in [(col,re.search(Mx.reSir3sIDcompiled,col)) for col in mx.df.columns.to_list() if re.search(Mx.reSir3sIDcompiled,col) != None]},inplace=True)

    # result-Channels
    piCh=f"KNOT~{nodeKiEl.get('NAME')}~~PH"
    pkCh=f"KNOT~{nodeKkEl.get('NAME')}~~PH"
    dpCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~PHR"
    rhoiCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~RHOI"
    rhokCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~RHOK"
    mkCh=f"KNOT~{nodeKkEl.get('NAME')}~~QM"
    mkrawCh=f"KNOT~{nodeKkEl.get('NAME')}~~M"

    # determine start-k with pp
    # create network
    nxg=networkx.Graph()
    nxg.add_nodes_from([(1,{'extPressure':mx.df[piCh].iloc[0]}),(2,{'extFlow':mx.df[mkrawCh].iloc[0]})])
    nxg.add_edges_from([(1, 2,{'L':L,'D':DI,'k':float(pipeEl.get('RAU'))})])

    if KT!=None:
        logger.debug(f"set alpha to KT:{KT}")
        nxg.edges[1,2].update({'alpha':KT})
    else:
        logger.debug(f"set alpha to:{float(DNEl.get('KT'))}")
        nxg.edges[1,2].update({'alpha':float(DNEl.get('KT'))})

    if Ta!=None:
        logger.debug(f"set Ta to {Ta}")
        nxg.edges[1,2].update({'Ta':Ta+273.15})

    nxg.nodes[1].update({'inletTemperature':Ti+273.15})

    ppn=pp(nxg)
    # calc network
    pandapipes.pipeflow(ppn,friction_model='colebrook',mode='bidirectional')
    # friction loss setpoint
    nxg.edges[1,2].update({'dpFL_SP':dp_SP})
    # calc k
    ppk(nxg,ppn)

    logger.debug(f"{logStr} k_pp: {nxg.edges[1,2]['k_MV']}")

    # set k
    pipeEl.set('RAU',str(nxg.edges[1,2]['k_MV']))
    # write again
    tree.write(m.SirCalcXmlFile)
    # calculate again
    with subprocess.Popen(pOpenAr) as process:
        process.wait()
        logger.debug(f'Command {process.args} exited with {process.returncode}.')

    def sir3s_calc_roughness(
            dk=dkSir3sStart
           ,depth=0
    ):

        logStr=f"{sys._getframe().f_code.co_name}:"

        logger.debug(f"{logStr} Start. depth: {depth}")

        # read result
        mx=Mx.Mx(m.mx.mx1File)
        mx.df.rename(columns={col:col.replace(Mx.reSir3sIDSep+mo.group('OBJTYPE_PK'),'') for col,mo in [(col,re.search(Mx.reSir3sIDcompiled,col)) for col in mx.df.columns.to_list() if re.search(Mx.reSir3sIDcompiled,col) != None]},inplace=True)

        # result-Channels
        pathStr = f"./ROHR[@fkKI!='-1']"
        pipeEl=root.findall(pathStr)[0]

        pathStr = f"./KNOT[@pk='{pipeEl.get('fkKI')}']"
        nodeKiEl=root.findall(pathStr)[0]

        pathStr = f"./KNOT[@pk='{pipeEl.get('fkKK')}']"
        nodeKkEl=root.findall(pathStr)[0]

        # result-Channels
        piCh=f"KNOT~{nodeKiEl.get('NAME')}~~PH"
        pkCh=f"KNOT~{nodeKkEl.get('NAME')}~~PH"
        dpCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~PHR"
        rhoiCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~RHOI"
        rhokCh=f"ROHR~{nodeKiEl.get('NAME')}~{nodeKkEl.get('NAME')}~RHOK"
        mkCh=f"KNOT~{nodeKkEl.get('NAME')}~~QM"

        # calculate deviation
        dp=mx.df[piCh].iloc[0]-mx.df[pkCh].iloc[0]#mx.df[dpCh].iloc[0]

        rho=.5*(mx.df[rhoiCh].iloc[0]+mx.df[rhokCh].iloc[0])
        dp_DZ=dz*rho*9.81*1.e-5
        dp_PV=dp+dp_DZ

        dp_DV=dp_SP-dp_PV

        if math.fabs(dp_DV) <= dp_ER:

                logger.debug(f"{logStr} Convergence: dpFL_DV: {dp_DV:+.4f} dp_ER: {dp_ER:+.4f} k: {float(pipeEl.get('RAU')):.4f} (dk={dk:.4f})")
                logger.debug(f"{logStr}                dp_SP: {dp_SP:+.4f} dp_PV: {dp_PV:+.4f}")
                logger.debug(f"{logStr}                pFrom: {mx.df[piCh].iloc[0]:7.4f}     pTo: {mx.df[pkCh].iloc[0]:7.4f}")
                logger.debug(f"{logStr}                 flow: {mx.df[mkCh].iloc[0]:7.4f}")
                logger.debug(f"{logStr} Done.")
                return float(pipeEl.get('RAU'))

        elif depth==0:

                logger.debug(f"{logStr} Start:       dpFL_DV: {dp_DV:+.4f} dp_ER: {dp_ER:+.4f} k: {float(pipeEl.get('RAU')):.4f} (dk={dk:.4f})")
                logger.debug(f"{logStr}                dp_SP: {dp_SP:+.4f} dp_PV: {dp_PV:+.4f}")
                logger.debug(f"{logStr}                pFrom: {mx.df[piCh].iloc[0]:7.4f}     pTo: {mx.df[pkCh].iloc[0]:7.4f}")
                logger.debug(f"{logStr}                 flow: {mx.df[mkCh].iloc[0]:7.4f}")

        dp_DVVStart=math.copysign(1,dp_DV)
        dp_DVV=dp_DVVStart

        # with the same k-value change dk until the sign of the deviation changes
        while dp_DVV==dp_DVVStart and float(pipeEl.get('RAU'))>k_min:

            # adjust roughness in the right direction
            if dp_DVV > 0:
                # increase roughness
                dkAdd=dk
            else:
                # reduce roughness
                dkAdd=-dk
            k_new=float(pipeEl.get('RAU'))+dkAdd
            if k_new < k_min:
                logger.debug(f"{logStr} k_new: {k_new} < k_min: {k_min}: k_new==k_min ...")
                # k + dk = k_min
                dk = math.fabs(k_min - float(pipeEl.get('RAU')))
                dkAdd=-dk
                k_new=float(pipeEl.get('RAU'))+dkAdd

            pipeEl.set('RAU',str(k_new))

            # write
            tree.write(m.SirCalcXmlFile)
            # calculate
            with subprocess.Popen(pOpenAr) as process:
                process.wait()
                logger.debug(f'Command {process.args} exited with {process.returncode}.')
            # read
            mx=Mx.Mx(m.mx.mx1File)
            mx.df.rename(columns={col:col.replace(Mx.reSir3sIDSep+mo.group('OBJTYPE_PK'),'') for col,mo in [(col,re.search(Mx.reSir3sIDcompiled,col)) for col in mx.df.columns.to_list() if re.search(Mx.reSir3sIDcompiled,col) != None]},inplace=True)

            # calculate deviation
            dp=mx.df[piCh].iloc[0]-mx.df[pkCh].iloc[0]#mx.df[dpCh].iloc[0]

            rho=.5*(mx.df[rhoiCh].iloc[0]+mx.df[rhokCh].iloc[0])
            dp_DZ=dz*rho*9.81*1.e-5
            dp_PV=dp+dp_DZ

            dp_DV=dp_SP-dp_PV

            logger.debug(f"{logStr} Iteration:   dp_DV: {dp_DV:+.4f} dp_ER: {dp_ER:+.4f} k: {float(pipeEl.get('RAU')):.4f} (dkAdd={dkAdd:+.4f})")
            dp_DVV=math.copysign(1,dp_DV)

        if dp_DVV!=dp_DVVStart and float(pipeEl.get('RAU'))>k_min:
            # the sign of the deviation changed above k _min; continue with k-value change dk/2 ...
            k=sir3s_calc_roughness(
                dk=dk/2
               ,depth=depth+1
            )
        elif dp_DVV!=dp_DVVStart and float(pipeEl.get('RAU'))<=k_min:
            logger.debug(f"{logStr} the sign of the deviation changed @k_min; continue with k-value change dk/2 ...")
            k=sir3s_calc_roughness(
                dk=dk/2
               ,depth=depth+1
            )
        else:
            logger.debug(f"{logStr} the sign of the deviation changed not; k<=k_min; stay with k_min ...")
            k=float(pipeEl.get('RAU'))

        return k

    return sir3s_calc_roughness(dk=dkSir3sStart)



[80]:
sir3sk()
[80]:
0.49875
[81]:
def f():
    """
    >>> k=sir3sk(dbFile=os.path.join(os.path.dirname(os.path.abspath(dxAndMxHelperFcts.__file__)),'Examples\\Example8.db3'))
    >>> round(k,1)
    0.5
    >>> k=sir3sk(dbFile=os.path.join(os.path.dirname(os.path.abspath(dxAndMxHelperFcts.__file__)),'Examples\\Example8.db3'),L=1100,pi=11,mk=-110,dp_SP=.6,DI=185,Ti=91)
    >>> round(k,2)
    0.04
    """
    pass
[82]:
import doctest
doctest.testmod()
[82]:
TestResults(failed=0, attempted=4)