Commit 55f9f314 authored by Dmitry Yu. Naumov's avatar Dmitry Yu. Naumov
Browse files

Merge branch 'BHE_PNW' into 'master'

Add an closed loop network model for BHE array benchmark and update the BHE array tutorial accordingly

See merge request ogs/ogs!3091
parents b9133771 087b4fe4
......@@ -3,6 +3,9 @@
<mesh>3bhes_1U.vtu</mesh>
<geometry>3bhes_1U.gml</geometry>
<python_script>bcs_tespy.py</python_script>
<!-- use the following for closed loop network model
<python_script>bcs_tespy_closedloop.py</python_script>
-->
<processes>
<process>
<name>HeatTransportBHE</name>
......
###
# Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
# Distributed under a Modified BSD License.
# See accompanying file LICENSE.txt or
# http://www.opengeosys.org/project/license
###
import sys
print(sys.version)
import os
import numpy as np
from pandas import read_csv
import OpenGeoSys
from tespy.networks import load_network
# User setting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# parameters
# refrigerant density
rho_f = 992.92 # kg/m3
# switch for special boundary conditions
# switch of the function for manually specified dynamic flowrate
switch_dyn_frate = 'off' # 'on','off'
# switch of the function for manually specified dynamic thermal demand
switch_dyn_demand = 'on' # 'on','off'
if switch_dyn_demand == 'on':
#give the consumer name defined by user in the network model
consumer_name = 'consumer'
# network status setting
def network_status(t):
nw_status = 'on'
# month for closed network
timerange_nw_off_month = [] # No month for closed network
# t-1 to avoid the calculation problem at special time point,
# e.g. t = 2592000.
t_trans = int((t - 1) / 86400 / 30) + 1
t_trans_month = t_trans
if t_trans_month > 12:
t_trans_month = t_trans - 12 * (int(t_trans / 12))
if t_trans_month in timerange_nw_off_month:
nw_status = 'off'
return nw_status
# dynamic consumer thermal load
def consumer_demand(t): # dynamic thermal demand from consumer
# time conversion
t_trans = int((t - 1) / 86400 / 30) + 1
if t_trans > 12:
t_trans = t_trans - 12 * (int(t_trans / 12))
# thermal demand in each month (assumed specific heat extraction rate*
# length of BHE* number of BHE)
month_demand = [
-25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3,
-25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3, -25 * 50 * 3,
-25 * 50 * 3, -25 * 50 * 3
]
return month_demand[t_trans - 1]
# dynamic hydraulic flow rate at the network inlet
def dyn_frate(t):
# time conversion
t_trans = int((t - 1) / 86400 / 30) + 1
if t_trans > 12:
t_trans = t_trans - 12 * (int(t_trans / 12))
# flow rate in kg / s time curve in month
month_frate = []
return month_frate[t_trans - 1]
# End User setting+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# create network dataframe
def create_dataframe():
# return dataframe
df_nw = read_csv('./pre/bhe_network.csv',
delimiter=';',
index_col=[0],
dtype={'data_index': str})
return (df_nw)
# TESPy calculation process
def get_tespy_results(t):
# bhe network boundary conditions re parametrization
# if network exist dynamic flowrate
if switch_dyn_frate == 'on':
cur_frate = dyn_frate(t)
localVars['inlet_name'].set_attr(m=cur_frate)
# if network exist dynamic thermal demand
if switch_dyn_demand == 'on':
# consumer thermal load:
cur_month_demand = consumer_demand(t)
nw.components[consumer_name].set_attr(Q=cur_month_demand)
# T_out re parametrization:
for i in range(n_BHE):
localVars['outlet_BHE' + str(i + 1)].set_attr(T=df.loc[data_index[i],
'Tout_val'])
# solving network
nw.solve(mode='design')
# get Tin_val and flow rate
for i in range(n_BHE):
# get Tin_val
df.loc[df.index[i],
'Tin_val'] = localVars['inlet_BHE' +
str(i + 1)].get_attr('T').val
# get flowrate
df.loc[df.index[i],
'flowrate'] = localVars['inlet_BHE' +
str(i + 1)].get_attr('m').val / rho_f
return df['Tin_val'].tolist(), df['flowrate'].tolist()
# OGS setting
# Dirichlet BCs
class BC(OpenGeoSys.BHENetwork):
def initializeDataContainer(self):
# initialize network and get data from the network
nw.solve(mode='design')
get_tespy_results(0)
# convert dataframe to column list
t = 0 # 'initial time'
data_col_1 = df['Tin_val'].tolist() # 'Tin_val'
data_col_2 = df['Tout_val'].tolist() # 'Tout_val'
data_col_3 = df['Tout_node_id'].astype(int).tolist() # 'Tout_node_id'
data_col_4 = df['flowrate'].tolist() # 'BHE flow rate'
return (t, data_col_1, data_col_2, data_col_3, data_col_4)
def tespySolver(self, t, Tin_val, Tout_val):
# network status:
nw_status = network_status(t)
# if network closed:
if nw_status == 'off':
df.loc[:,'flowrate'] = 0
cur_flowrate = df['flowrate'].tolist()
return (True, True, Tout_val, cur_flowrate)
else:
# read Tout_val to dataframe
for i in range(n_BHE):
df.loc[df.index[i], 'Tout_val'] = Tout_val[i]
# TESPy solver
cur_Tin_val, cur_flowrate = get_tespy_results(t)
# check norm if network achieves the converge
if_success = False
pre_Tin_val = Tin_val
norm_dx = np.linalg.norm(
abs(np.asarray(pre_Tin_val) - np.asarray(cur_Tin_val)))
norm_x = np.linalg.norm(np.asarray(cur_Tin_val))
if norm_dx/norm_x < 1e-6:
if_success = True
# return to OGS
return (True, if_success, cur_Tin_val, cur_flowrate)
# main
# initialize the tespy model of the bhe network
# load path of network model:
# loading the TESPy model
project_dir = os.getcwd()
print("Project dir is: ", project_dir)
nw = load_network('./pre/tespy_nw_closedloop')
# set if print the network iteration info
nw.set_attr(iterinfo=False)
# create bhe dataframe of the network system from bhe_network.csv
df = create_dataframe()
n_BHE = np.size(df.iloc[:, 0])
# create local variables of the components label and connections label in
# network
localVars = locals()
data_index = df.index.tolist()
for i in range(n_BHE):
for c in nw.conns.index:
# bhe inlet and outlet conns
if c.target.label == data_index[i]: # inlet conns of bhe
localVars['inlet_BHE' + str(i + 1)] = c
if c.source.label == data_index[i]: # outlet conns of bhe
localVars['outlet_BHE' + str(i + 1)] = c
# time depended flowrate
if switch_dyn_frate == 'on':
# import the name of inlet connection from the network csv file
inlet_name = read_csv('./pre/tespy_nw/connections.csv',
delimiter=';',
index_col=[0]).iloc[0,0]
for c in nw.conns.index:
# bhe inflow conns
if c.source.label == inlet_name: # inlet conns of bhe
localVars['inlet_name'] = c
# instantiate BC objects referenced in OpenGeoSys
bc_bhe = BC()
###
# Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
# Distributed under a Modified BSD License.
# See accompanying file LICENSE.txt or
# http://www.opengeosys.org/project/license
###
# Execute this file to generate TESPy network csv files
from tespy.networks import network
from tespy.connections import connection, ref
from tespy.components import source, sink, pump, splitter, merge, heat_exchanger_simple, cycle_closer
from tespy.tools import char_line, dc_cc
import numpy as np
# %% network
btes = network(fluids=['water'], T_unit='K', p_unit='bar', h_unit='kJ / kg')
# %% components
fc = cycle_closer('cycle closer')
pu = pump('pump')
sp = splitter('splitter', num_out=3)
# bhe:
bhe1 = heat_exchanger_simple('BHE1')
bhe2 = heat_exchanger_simple('BHE2')
bhe3 = heat_exchanger_simple('BHE3')
mg = merge('merge', num_in=3)
cons = heat_exchanger_simple('consumer')
## components paramerization
# pump
# flow_char
# provide volumetric flow in m^3 / s
x = np.array([
0.00, 0.00001952885971862, 0.00390577194372, 0.005858657915586,
0.007811543887448, 0.00976442985931, 0.011717315831173, 0.013670201803035,
0.015623087774897, 0.017575973746759, 0.019528859718621, 0.021481745690483,
0.023434631662345, 0.025387517634207, 0.027340403606069, 0.029293289577931,
0.031246175549793, 0.033199061521655, 0.035151947493517, 0.037104833465379,
0.039057719437241, 0.041010605409104, 0.042963491380966, 0.044916377352828,
0.04686926332469, 0.048822149296552, 0.050775035268414, 0.052727921240276,
0.054680807212138, 0.056633693184
])
# provide head in Pa
y = np.array([
0.47782539, 0.47725723, 0.47555274, 0.47271192, 0.46873478, 0.46362130,
0.45737151, 0.44998538, 0.44146293, 0.43180416, 0.4220905, 0.40907762,
0.39600986, 0.38180578, 0.36646537, 0.34998863, 0.33237557, 0.31362618,
0.29374046, 0.27271841, 0.25056004, 0.22726535, 0.20283432, 0.17726697,
0.15056329, 0.12272329, 0.09374696, 0.06363430, 0.03238531, 0.00000000
]) * 1e5
char = char_line(x=x, y=y)
pu.set_attr(flow_char=dc_cc(func=char, is_set=True))
pu.set_attr(eta_s=0.90)
# bhes
bhe1.set_attr(D=0.013665, L=100, ks=0.00001)
bhe2.set_attr(D=0.013665, L=100, ks=0.00001)
bhe3.set_attr(D=0.013665, L=100, ks=0.00001)
# consumer
cons.set_attr(pr=1)
# consumer heat demand
cons.set_attr(Q=-3000) # W
# %% connections
fc_pu = connection(fc, 'out1', pu, 'in1')
pu_sp = connection(pu, 'out1', sp, 'in1')
sp_bhe1 = connection(sp, 'out1', bhe1, 'in1')
sp_bhe2 = connection(sp, 'out2', bhe2, 'in1')
sp_bhe3 = connection(sp, 'out3', bhe3, 'in1')
bhe1_mg = connection(bhe1, 'out1', mg, 'in1')
bhe2_mg = connection(bhe2, 'out1', mg, 'in2')
bhe3_mg = connection(bhe3, 'out1', mg, 'in3')
mg_cons = connection(mg, 'out1', cons, 'in1')
cons_fc = connection(cons, 'out1', fc, 'in1')
btes.add_conns(fc_pu, pu_sp, sp_bhe1, sp_bhe2, sp_bhe3, bhe1_mg, bhe2_mg,
bhe3_mg, mg_cons, cons_fc)
## connection parametrization
# system inlet
fc_pu.set_attr(p=2, fluid={'water': 1})
# for BHEs:
# Tout:
bhe1_mg.set_attr(T=303.15)
bhe2_mg.set_attr(T=303.15)
bhe3_mg.set_attr(T=303.15)
# %% solve
btes.solve('design')
#btes.print_results()
# %% save to csv:
btes.save('tespy_nw_closedloop')
id;type;x;y;extrapolate
0x000001E60A48F7B8;char_line;[0.071, 0.282, 0.635, 0.776, 0.917, 1.0, 1.128, 1.27, 1.41, 1.763, 2.115, 2.5];[0.25, 0.547, 0.9, 0.965, 0.995, 1.0, 0.99, 0.959, 0.911, 0.737, 0.519, 0.25];False
0x000001E60A4385F8;char_line;[0.0, 1.952885971862e-05, 0.00390577194372, 0.005858657915586, 0.007811543887448, 0.00976442985931, 0.011717315831173, 0.013670201803035, 0.015623087774897, 0.017575973746759, 0.019528859718621, 0.021481745690483, 0.023434631662345, 0.025387517634207, 0.027340403606069, 0.029293289577931, 0.031246175549793, 0.033199061521655, 0.035151947493517, 0.037104833465379, 0.039057719437241, 0.041010605409104, 0.042963491380966, 0.044916377352828, 0.04686926332469, 0.048822149296552, 0.050775035268414, 0.052727921240276, 0.054680807212138, 0.056633693184];[47782.539000000004, 47725.723, 47555.274, 47271.192, 46873.478, 46362.130000000005, 45737.151, 44998.538, 44146.293, 43180.416, 42209.049999999996, 40907.761999999995, 39600.986, 38180.578, 36646.537000000004, 34998.863000000005, 33237.557, 31362.618, 29374.046, 27271.841000000004, 25056.003999999997, 22726.535, 20283.432, 17726.697, 15056.329, 12272.329, 9374.696, 6363.43, 3238.531, 0.0];False
0x000001E60A48F7F0;char_line;[0.0, 0.01084, 0.03655, 0.07779, 0.13389, 0.20417, 0.28796, 0.38458, 0.49337, 0.61364, 0.74473, 0.88595, 1.0, 1.19613, 1.36374, 1.53879, 1.72061, 1.90854, 2.10189, 2.29999, 2.50217, 2.70776, 2.91608, 3.0];[0.01, 0.09598, 0.18995, 0.28191, 0.37185, 0.45974, 0.54557, 0.62932, 0.71098, 0.79053, 0.86796, 0.94324, 1.0, 1.0873, 1.15605, 1.22259, 1.28691, 1.34898, 1.40879, 1.46633, 1.52157, 1.5745, 1.62511, 1.645];False
0x000001E60A48F828;char_line;[0.0, 0.01084, 0.03655, 0.07779, 0.13389, 0.20417, 0.28796, 0.38458, 0.49337, 0.61364, 0.74473, 0.88595, 1.0, 1.19613, 1.36374, 1.53879, 1.72061, 1.90854, 2.10189, 2.29999, 2.50217, 2.70776, 2.91608, 3.0];[0.01, 0.09598, 0.18995, 0.28191, 0.37185, 0.45974, 0.54557, 0.62932, 0.71098, 0.79053, 0.86796, 0.94324, 1.0, 1.0873, 1.15605, 1.22259, 1.28691, 1.34898, 1.40879, 1.46633, 1.52157, 1.5745, 1.62511, 1.645];False
0x000001E60A48F860;char_line;[0.0, 0.01084, 0.03655, 0.07779, 0.13389, 0.20417, 0.28796, 0.38458, 0.49337, 0.61364, 0.74473, 0.88595, 1.0, 1.19613, 1.36374, 1.53879, 1.72061, 1.90854, 2.10189, 2.29999, 2.50217, 2.70776, 2.91608, 3.0];[0.01, 0.09598, 0.18995, 0.28191, 0.37185, 0.45974, 0.54557, 0.62932, 0.71098, 0.79053, 0.86796, 0.94324, 1.0, 1.0873, 1.15605, 1.22259, 1.28691, 1.34898, 1.40879, 1.46633, 1.52157, 1.5745, 1.62511, 1.645];False
0x000001E60A48F898;char_line;[0.0, 0.01084, 0.03655, 0.07779, 0.13389, 0.20417, 0.28796, 0.38458, 0.49337, 0.61364, 0.74473, 0.88595, 1.0, 1.19613, 1.36374, 1.53879, 1.72061, 1.90854, 2.10189, 2.29999, 2.50217, 2.70776, 2.91608, 3.0];[0.01, 0.09598, 0.18995, 0.28191, 0.37185, 0.45974, 0.54557, 0.62932, 0.71098, 0.79053, 0.86796, 0.94324, 1.0, 1.0873, 1.15605, 1.22259, 1.28691, 1.34898, 1.40879, 1.46633, 1.52157, 1.5745, 1.62511, 1.645];False
label;cp;busses;bus_param;bus_P_ref;bus_char;bus_base;design;offdesign;design_path;local_design;local_offdesign;mass_deviation;mass_deviation_set;mass_deviation_var;fluid_deviation;fluid_deviation_set;fluid_deviation_var
cycle closer;cycle_closer;[];[];[];[];[];[];[];nan;False;False;0.0;False;False;0.0;False;False
label;cp;busses;bus_param;bus_P_ref;bus_char;bus_base;design;offdesign;design_path;local_design;local_offdesign;Q;Q_set;Q_var;pr;pr_set;pr_var;zeta;zeta_set;zeta_var;D;D_set;D_var;L;L_set;L_var;ks;ks_set;ks_var;kA;kA_set;kA_var;kA_char;kA_char_set;kA_char_param;Tamb;Tamb_set;SQ1;SQ1_set;SQ2;SQ2_set;Sirr;Sirr_set;hydro_group;kA_group;kA_char_group
BHE1;heat_exchanger_simple;[];[];[];[];[];[];[];nan;False;False;994.9530187301509;False;False;0.8073825335612752;False;False;6516132508.011579;False;False;0.013665;True;False;100;True;False;1e-05;True;False;1;False;False;0x000001E60A48F7F0;False;m;nan;False;3.310817133292918;False;nan;False;nan;False;default;default;default
BHE2;heat_exchanger_simple;[];[];[];[];[];[];[];nan;False;False;994.9530187301509;False;False;0.8073825335612752;False;False;6516132508.011579;False;False;0.013665;True;False;100;True;False;1e-05;True;False;1;False;False;0x000001E60A48F828;False;m;nan;False;3.310817133292918;False;nan;False;nan;False;default;default;default
BHE3;heat_exchanger_simple;[];[];[];[];[];[];[];nan;False;False;994.9530187301509;False;False;0.8073825335612752;False;False;6516132508.011579;False;False;0.013665;True;False;100;True;False;1e-05;True;False;1;False;False;0x000001E60A48F860;False;m;nan;False;3.310817133292918;False;nan;False;nan;False;default;default;default
consumer;heat_exchanger_simple;[];[];[];[];[];[];[];nan;False;False;-2999.9999999999973;True;False;1.0;True;False;0.0;False;False;1.0;False;False;1;False;False;0.0001;False;False;1;False;False;0x000001E60A48F898;False;m;nan;False;-9.937487813070446;False;nan;False;nan;False;default;default;default
label;cp;busses;bus_param;bus_P_ref;bus_char;bus_base;design;offdesign;design_path;local_design;local_offdesign;num_in;num_in_set
merge;merge;[];[];[];[];[];[];[];nan;False;False;3;True
label;cp;busses;bus_param;bus_P_ref;bus_char;bus_base;design;offdesign;design_path;local_design;local_offdesign;P;P_set;P_var;eta_s;eta_s_set;eta_s_var;eta_s_char;eta_s_char_set;eta_s_char_param;pr;pr_set;pr_var;flow_char;flow_char_set;flow_char_param;Sirr;Sirr_set
pump;pump;[];[];[];[];[];[];[];nan;False;False;15.140943809536056;False;False;0.8999999993360919;True;False;0x000001E60A48F7B8;False;nan;1.2385702667967196;False;False;0x000001E60A4385F8;True;nan;0.005036413191689607;False
label;cp;busses;bus_param;bus_P_ref;bus_char;bus_base;design;offdesign;design_path;local_design;local_offdesign;num_out;num_out_set
splitter;splitter;[];[];[];[];[];[];[];nan;False;False;3;True
id;source;source_id;target;target_id;design;offdesign;design_path;local_design;local_offdesign;label;m;m_unit;m_unit_set;m0;m_set;m_ref;m_ref_f;m_ref_d;m_ref_set;p;p_unit;p_unit_set;p0;p_set;p_ref;p_ref_f;p_ref_d;p_ref_set;h;h_unit;h_unit_set;h0;h_set;h_ref;h_ref_f;h_ref_d;h_ref_set;T;T_unit;T_unit_set;T0;T_set;T_ref;T_ref_f;T_ref_d;T_ref_set;x;x_unit;x_unit_set;x0;x_set;x_ref;x_ref_f;x_ref_d;x_ref_set;v;v_unit;v_unit_set;v0;v_set;v_ref;v_ref_f;v_ref_d;v_ref_set;Td_bp;Td_bp_unit;Td_bp_unit_set;Td_bp0;Td_bp_set;Td_bp_ref;Td_bp_ref_f;Td_bp_ref_d;Td_bp_ref_set;state;state_set;water;water0;water_set;balance
0x000001E60A438668;cycle closer;out1;pump;in1;[];[];nan;False;False;cycle closer:out1_pump:in1;0.2845767455781414;kg / s;False;0.2845767455781414;False;nan;nan;nan;False;2.0;bar;False;2.0;True;nan;nan;nan;False;115.37052818256211;kJ / kg;False;115.37052818256211;False;nan;nan;nan;False;300.62789867906355;K;False;300.62789867906355;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;0.00028559706952047386;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;True;False
0x000001E60A438B70;pump;out1;splitter;in1;[];[];nan;False;False;pump:out1_splitter:in1;0.2845767455781414;kg / s;False;0.2845767455781414;False;nan;nan;nan;False;2.477140533593439;bar;False;2.477140533593439;False;nan;nan;nan;False;115.42373331630829;kJ / kg;False;115.42373331630829;False;nan;nan;nan;False;300.6301383476882;K;False;300.6301383476882;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;0.0002855911202866885;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A43E0B8;splitter;out1;BHE1;in1;[];[];nan;False;False;splitter:out1_BHE1:in1;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.477140533593439;bar;False;2.477140533593439;False;nan;nan;nan;False;115.4237333163083;kJ / kg;False;115.4237333163083;False;nan;nan;nan;False;300.6301383476882;K;False;300.6301383476882;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.519704009556283e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A43E5C0;splitter;out2;BHE2;in1;[];[];nan;False;False;splitter:out2_BHE2:in1;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.477140533593439;bar;False;2.477140533593439;False;nan;nan;nan;False;115.4237333163083;kJ / kg;False;115.4237333163083;False;nan;nan;nan;False;300.6301383476882;K;False;300.6301383476882;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.519704009556283e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A43EAC8;splitter;out3;BHE3;in1;[];[];nan;False;False;splitter:out3_BHE3:in1;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.477140533593439;bar;False;2.477140533593439;False;nan;nan;nan;False;115.4237333163083;kJ / kg;False;115.4237333163083;False;nan;nan;nan;False;300.6301383476882;K;False;300.6301383476882;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.519704009556283e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A43EFD0;BHE1;out1;merge;in1;[];[];nan;False;False;BHE1:out1_merge:in1;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.0;bar;False;2.0;False;nan;nan;nan;False;125.91249988831495;kJ / kg;False;125.91249988831495;False;nan;nan;nan;False;303.14999999999844;K;False;303.14999999999844;True;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.526919836383884e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A454518;BHE2;out1;merge;in2;[];[];nan;False;False;BHE2:out1_merge:in2;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.0;bar;False;2.0;False;nan;nan;nan;False;125.91249988831495;kJ / kg;False;125.91249988831495;False;nan;nan;nan;False;303.14999999999844;K;False;303.14999999999844;True;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.526919836383884e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A454A20;BHE3;out1;merge;in3;[];[];nan;False;False;BHE3:out1_merge:in3;0.09485891519271379;kg / s;False;0.09485891519271379;False;nan;nan;nan;False;2.0;bar;False;2.0;False;nan;nan;nan;False;125.91249988831495;kJ / kg;False;125.91249988831495;False;nan;nan;nan;False;303.14999999999844;K;False;303.14999999999844;True;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;9.526919836383884e-05;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A454F28;merge;out1;consumer;in1;[];[];nan;False;False;merge:out1_consumer:in1;0.2845767455781414;kg / s;False;0.2845767455781414;False;nan;nan;nan;False;2.0;bar;False;2.0;False;nan;nan;nan;False;125.91249988831494;kJ / kg;False;125.91249988831494;False;nan;nan;nan;False;303.14999999999844;K;False;303.14999999999844;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;0.00028580759509151655;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
0x000001E60A459470;consumer;out1;cycle closer;in1;[];[];nan;False;False;consumer:out1_cycle closer:in1;0.2845767455781414;kg / s;False;0.2845767455781414;False;nan;nan;nan;False;2.0;bar;False;2.0;False;nan;nan;nan;False;115.37052818256208;kJ / kg;False;115.37052818256208;False;nan;nan;nan;False;300.62789867906355;K;False;300.62789867906355;False;nan;nan;nan;False;-1.0;-;False;nan;False;nan;nan;nan;False;0.00028559706952047386;m3 / s;False;nan;False;nan;nan;nan;False;nan;K;False;nan;False;nan;nan;nan;False;nan;False;1;1;False;False
{
"m_unit": "kg / s",
"m_range": [
-1000000000000.0,
1000000000000.0
],
"p_unit": "bar",
"p_range": [
0.002,
300.0
],
"h_unit": "kJ / kg",
"h_range": [
1.0,
7000.0
],
"T_unit": "K",
"x_unit": "-",
"v_unit": "m3 / s",
"s_unit": "J / kgK",
"fluids": {
"water": "HEOS"
}
}
\ No newline at end of file
......@@ -58,22 +58,37 @@ The detailed input parameters can be found in the 3bhes\_1U.prj file, they are a
### TESPy
A one-way pipeline network system was constructed in TESPy to be coupled with the OGS model.
The TESPy software developed by Francesco Witte is capable of simulating coupled thermal-hydraulic status of a network, which is composed of pre-defined components including pipes, heat exchangers, and different types of turbo machinery.
Here, the TESPy software developed by Francesco Witte is employed to simulate the coupled thermal-hydraulic status of a pipe network, which is composed of pre-defined components including pipes, heat exchangers, and different types of turbo machinery.
Interested readers may refer to the online documentation of TESPy for the detailed introduction of the software.
The TESPy version 0.3.2 is used in this benchmark.
Figure 1 illustrates the basic configuration of the entire network.
Two different pipe network setup were constructed for this benchmakr.
* A one-way pipe network (see Figure 1a)
In this setup, the refrigerant flow rate in the network is pre-defined by the user.
After being lifted by the pump, the refrigerant inflow will be divided into 3 branches by the splitter and then flow into each BHEs.
Because of the pipe network configuration, the inflow temperature on each BHE will be the same.
Because of this configuration, the inflow temperature on each BHE will be the same.
The refrigerant flowing out of the BHEs array will be firstly mixed at the merging point and then extracted for the heat extraction through the heat pump.
After that, the refrigerant will flow out from the network.
For the boundary condition, a constant thermal load of 3750 $W$ is imposed on the heat pump for the entire simulation period, which means an average specific heat extraction rate on each BHE with 25 $W/m$.
The fluid enthalpy value at the splitter point is set to be equal to the sink point enthalpy, such that means all the consumed heat on the heat pump is supplied by the BHEs array.
For the boundary condition, a constant thermal load of 3750 $W$ is imposed on the heat pump for the entire simulation period. which means an average specific heat extraction rate on each BHE with 25 $W/m$.
The fluid enthalpy value at the splitter point is set to be equal to the sink point enthalpy, that means all the consumed heat on the heat pump is supplied by the BHEs array.
The total simulation time is 6 months.
{{< img src="../3D_3BHEs_array_figures/BHE_network.png" width="200">}}
Figure 1: Pipeline network model in TESPy
Figure 1a: One-way pipeline network model
* A closed-loop pipe network (see Figure 1b)
The setup for a closed-loop network model is illustrated in Figure 1b.
Compared to the configuration in the one-way network, the refrigerant in the closed loop network is circulating through the entire system.
In this case, the flow rate will be automatically adjusted by the water pump in each time step, as its pressure head is directly linked to the flow rate. Subsequently, the flow rate is determined by the pressure losses in the BHE array.
{{< img src="../3D_3BHEs_array_figures/BHE_network_closedloop.png" width="200">}}
Figure 1b: Closed-loop pipeline network model
## Results
......@@ -84,6 +99,14 @@ This imbalance leads to a lower outflow temperature from the BHE \#2, which is s
Compared to the decrease of the heat extraction rate on the centre BHE \#2, the rates on the other two BHEs located at the out sides was gradually increasing.
It indicates that the heat extraction rate is shifting from the centre BHE towards the outer BHEs over the heating season.
In comparision to the one-way setup, the closed-loop network shows a slightly different behaviour.
The evolution of inflow refrigerant temperature and flow rate entering the BHE array is shown in Figure 5.
With the decreasing of the working fluid temperature over the time, the system flow rate dereases gradually.
Figure 6 depicts the thermal load shifting phenomenon with the closed-loop model.
Except for the thermal shifiting behavior among the BHEs, the averaged heat extraction rate of all BHEs (black line) increases slightly over the time.
This is due to the fact that additional energy is required to compensate the hydraulic loss of the pipe.
{{< img src="../3D_3BHEs_array_figures/Soil_temperature.png" width="200">}}
Figure 2: Evolution of the soil temperature located at the 1 m distance away from each BHE
......@@ -96,6 +119,14 @@ Figure 3: Evolution of the inflow and outflow refrigerant temperature of each BH
Figure 4: Evolution of the heat extraction rate of each BHE
{{< img src="../3D_3BHEs_array_figures/Inflow_temperature_and_flow_rate.png" width="200">}}
Figure 5: Evolution of the inflow refrigerant temperature and flow rate entering the BHE array
{{< img src="../3D_3BHEs_array_figures/Heat_extraction_rate_closedloop.png" width="200">}}
Figure 6: Evolution of the heat extraction rate of each BHE with close loop network model
## References
[1] Diersch, H. J., Bauer, D., Heidemann, W., Rühaak, W., & Schätzl, P. (2011). Finite element modeling of borehole heat exchanger systems: Part 1. Fundamentals. Computers & Geosciences, 37(8), 1122-1135.
......
......@@ -192,25 +192,32 @@ BHE3;3;283.15;283.15;0;0
### < PipeNetwork feature interface >
The python script `bcs_tespy.py` is the data exchange interface for running the PipeNetwork feature. It contains the main procedure of data exchange during the simulation. In the script a network status controller function `network_status`, a system dynamic thermal load function `consumer_demand` and a system dynamic inlet flow rate function `dyn_frate` are optionally required to be pre-defined by the user. The function `network_status` receives the current time step information from OGS and determine if the network is required to be shut off. When the switch for dynamic thermal load `switch_dyn_demand` and dynamic flow rate `switch_dyn_frate` are set to be `off`, the constant thermal load on the heat pump and the system inlet flow rate which was defined in the TESPy model will be used throughout the simulation. When the switchs are set to be `on`, a user defined system thermal load curve and inlet flow rate curve could be specified according to the current time step from OGS.
The python script `bcs_tespy.py` is the data exchange interface for running the PipeNetwork feature.
It contains the main procedure of data exchange during the simulation.
In the script a network status controller function `network_status`, a system dynamic thermal load function `consumer_demand` and a system dynamic inlet flow rate function `dyn_frate` are optionally required to be pre-defined by the user.
The function `network_status` receives the current time step information from OGS and determines if the network is required to be shut off.
When the switch for dynamic thermal load `switch_dyn_demand` and dynamic flow rate `switch_dyn_frate` are `off`, the thermal and hydraulic boundary conditions, which were defined in the pre-constructed TESPy model, will be used throughout the simulation.
When the switches are `on`, a user defined system thermal load curve and inlet flow rate curve can be specified according to the current time step from OGS.
```bash
# User setting +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# User setting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# parameters
# refrigerant parameters
refrig_density = 992.92 # kg/m3
# refrigerant density
rho_f = 992.92 # kg/m3
# switch for special boundary conditions
# 'on','off', switch of the function for dynamic thermal demand from consumer
switch_dyn_demand = 'on'
# 'on','off', switch of the function for dynamic flowrate in BHE
switch_dyn_frate = 'off'
# switch of the function for manually specified dynamic flowrate
switch_dyn_frate = 'off' # 'on','off'
# switch of the function for manually specified dynamic thermal demand
switch_dyn_demand = 'on' # 'on','off'
if switch_dyn_demand == 'on':
#give the consumer name defined by user in the network model
consumer_name = 'consumer'
# network status setting
def network_status(t):
nw_status = 'on'
# month for closed network
timerange_nw_off_month = [-9999] # No month for closed network
timerange_nw_off_month = [] # No month for closed network
# t-1 to avoid the calculation problem at special time point,
# e.g. t = 2592000.
t_trans = int((t - 1) / 86400 / 30) + 1
......@@ -226,6 +233,8 @@ def network_status(t):
def consumer_demand(t): # dynamic thermal demand from consumer
# time conversion
t_trans = int((t - 1) / 86400 / 30) + 1
if t_trans > 12:
t_trans = t_trans - 12 * (int(t_trans / 12))
# thermal demand in each month (assumed specific heat extraction rate*
# length of BHE* number of BHE)
month_demand = [
......@@ -236,14 +245,17 @@ def consumer_demand(t): # dynamic thermal demand from consumer
return month_demand[t_trans - 1]
# dynamic hydraulic flow rate
def dyn_frate(t): # dynamic flowrate in BHE
# dynamic hydraulic flow rate at the network inlet
def dyn_frate(t):
# time conversion
t_trans = int((t - 1) / 86400 / 30) + 1
if t_trans > 12:
t_trans = t_trans - 12 * (int(t_trans / 12))
# flow rate in kg / s time curve in month
month_frate = [-9999]
month_frate = []
return month_frate[t_trans - 1]
# End User setting+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment