Skip to content
Snippets Groups Projects
Commit b1dc662a authored by Pedro L. Magalhães's avatar Pedro L. Magalhães
Browse files

Fixed examples. Simplified heat transfer rate methods need clarification.

parent d7158950
Branches
No related tags found
1 merge request!1Revised tests for simplified heat transfer methods in the trench test section....
...@@ -4,26 +4,35 @@ ...@@ -4,26 +4,35 @@
# TIP: this script requires the data found in the hyhetra-pipedata and hyhetra- # TIP: this script requires the data found in the hyhetra-pipedata and hyhetra-
# -fluiddata repositories # -fluiddata repositories
pipedata_files = ['pipes/isoplus_single_disconti_s1.csv'] # pipedata_files = ['pipes/isoplus_single_disconti_s1.csv']
pipedata_files = [
'pipes/enerpipe_caldopex_single.csv',
'pipes/enerpipe_caldopex_twin.csv',
'pipes/isoplus_single_disconti_s1.csv',
'pipes/isoplus_single_disconti_s2.csv',
'pipes/isoplus_single_disconti_s3.csv',
'pipes/isoplus_twin_disconti_s1.csv',
'pipes/isoplus_twin_disconti_s2.csv',
'pipes/isoplus_twin_disconti_s3.csv',
]
fluiddata_file = 'fluids/incropera2006_saturated_water.csv' fluiddata_file = 'fluids/incropera2006_saturated_water.csv'
# other files # other files
file_best2018 = 'papers/Best2018_design_flow_speeds.csv' file_best2018 = 'papers/Best2018_design_flow_speeds.csv'
file_sven2013 = 'papers/Sven2013_design_flow_speeds.csv' file_sven2013 = 'papers/Sven2013_design_flow_speeds.csv'
file_nussbaumer2016 = 'papers/Nussbaumer2016_design_flow_speeds.csv' file_nussbaumer2016 = 'papers/Nussbaumer2016_design_flow_speeds.csv'
file_euroheat2021 = 'papers/EuroHeat2021_design_flow_speeds.csv' file_euroheat2021 = 'papers/EuroHeat2021_design_flow_speeds.csv'
# import libraries # import libraries
import math
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# topupheat # topupheat
import topupheat.pipes.fic as fic import topupheat.pipes.fic as fic
import topupheat.pipes.trenches as _tre
from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase
from topupheat.pipes.twin import StandardisedTwinPipe
from topupheat.pipes.trenches import TwinPipeTrench
import topupheat.pipes.utils as utils import topupheat.pipes.utils as utils
from topupheat.common import formulas as core from topupheat.common import formulas as core
...@@ -71,21 +80,21 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'), ...@@ -71,21 +80,21 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'),
(50, 1, 'isoplus', 'DRE-50-STD'), (50, 1, 'isoplus', 'DRE-50-STD'),
(65, 1, 'isoplus', 'DRE-65-STD'), (65, 1, 'isoplus', 'DRE-65-STD'),
(80, 1, 'isoplus', 'DRE-80-STD'), (80, 1, 'isoplus', 'DRE-80-STD'),
(100, 1, 'isoplus', 'DRE-100-ST'), (100, 1, 'isoplus', 'DRE-100-STD'),
(125, 1, 'isoplus', 'DRE-125-ST'), (125, 1, 'isoplus', 'DRE-125-STD'),
(150, 1, 'isoplus', 'DRE-150-ST'), (150, 1, 'isoplus', 'DRE-150-STD'),
(200, 1, 'isoplus', 'DRE-200-ST'), (200, 1, 'isoplus', 'DRE-200-STD'),
(250, 1, 'isoplus', 'DRE-250-ST'), (250, 1, 'isoplus', 'DRE-250-STD'),
(300, 1, 'isoplus', 'DRE-300-ST'), (300, 1, 'isoplus', 'DRE-300-STD'),
(350, 1, 'isoplus', 'DRE-350-ST'), (350, 1, 'isoplus', 'DRE-350-STD'),
(400, 1, 'isoplus', 'DRE-400-ST'), (400, 1, 'isoplus', 'DRE-400-STD'),
(450, 1, 'isoplus', 'DRE-450-ST'), (450, 1, 'isoplus', 'DRE-450-STD'),
(500, 1, 'isoplus', 'DRE-500-ST'), (500, 1, 'isoplus', 'DRE-500-STD'),
(600, 1, 'isoplus', 'DRE-600-ST'), (600, 1, 'isoplus', 'DRE-600-STD'),
(700, 1, 'isoplus', 'DRE-700-ST'), (700, 1, 'isoplus', 'DRE-700-STD'),
(800, 1, 'isoplus', 'DRE-800-ST'), (800, 1, 'isoplus', 'DRE-800-STD'),
(900, 1, 'isoplus', 'DRE-900-ST'), (900, 1, 'isoplus', 'DRE-900-STD'),
(1000, 1, 'isoplus', 'DRE-1000-S')] (1000, 1, 'isoplus', 'DRE-1000-STD')]
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
...@@ -95,12 +104,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'), ...@@ -95,12 +104,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'),
#****************************************************************************** #******************************************************************************
# pipe data # pipe data
pipedb = StandardisedPipeDatabase(source=pipedata_files) pipedb = StandardisedPipeDatabase(source=pipedata_files)
# water data # water data
fluiddb = fic.FluidDatabase(fluid='water', phase='l', source=fluiddata_file)
waterdb = fic.FluidDatabase(fluid='water', phase='l', source=fluiddata_file)
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
...@@ -111,19 +118,19 @@ dh_flow = fic.Fluid( ...@@ -111,19 +118,19 @@ dh_flow = fic.Fluid(
phase='l', phase='l',
temperature=dh_flow_temperature, temperature=dh_flow_temperature,
pressure=1e5, pressure=1e5,
db=waterdb) db=fluiddb)
dh_return = fic.Fluid( dh_return = fic.Fluid(
phase='l', phase='l',
temperature=dh_return_temperature, temperature=dh_return_temperature,
pressure=1e5, pressure=1e5,
db=waterdb) db=fluiddb)
fluid_bulk = fic.Fluid( fluid_bulk = fic.Fluid(
phase='l', phase='l',
temperature=temperature_fluid_bulk, temperature=temperature_fluid_bulk,
pressure=1e5, pressure=1e5,
db=waterdb) db=fluiddb)
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
...@@ -542,6 +549,7 @@ for i, max_specific_pressure_loss in enumerate(list_max_specific_pressure_loss): ...@@ -542,6 +549,7 @@ for i, max_specific_pressure_loss in enumerate(list_max_specific_pressure_loss):
ax.plot(list_pipe_diameters, ax.plot(list_pipe_diameters,
[spl for spl in dict_specific_pressure_loss[ [spl for spl in dict_specific_pressure_loss[
(max_specific_pressure_loss,list_pipe_roughness[i])]], (max_specific_pressure_loss,list_pipe_roughness[i])]],
list_linestyle_our[i],
label='MSP='+str(max_specific_pressure_loss)+' Pa/m') label='MSP='+str(max_specific_pressure_loss)+' Pa/m')
# ax.plot(data_best2018['x']*1e3, # ax.plot(data_best2018['x']*1e3,
...@@ -570,7 +578,201 @@ plt.show() ...@@ -570,7 +578,201 @@ plt.show()
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
#******************************************************************************
#****************************************************************************** # ISOPLUS validation
#******************************************************************************
#****************************************************************************** # @ 30K
\ No newline at end of file
isoplus_twin_mlfs = {
21.7: [0.5, 1.1], # 20
27.3: [0.5, 1.1], # 25
36.0: [0.6, 1.2], # 32
41.9: [0.6, 1.2], # 40
53.9: [0.7, 1.4], # 50
69.7: [0.7, 1.4], # 65
82.5: [0.8, 1.6], # 80
107.1: [0.8, 1.6], # 100
132.5: [1.0, 1.8], # 125
160.3: [1.2, 2.1], # 150
210.1: [1.4, 2.4], # 200
}
# volumetric flow rate m3/hour
isoplus_twin_vfr = {
21.7: [0.703, 1.547], # 20
27.3: [1.148, 2.526], # 25
36.0: [2.348, 4.695], # 32
41.9: [3.151, 6.303], # 40
53.9: [5.879, 11.757], # 50
69.7: [9.781, 19.563], # 65
82.5: [15.395, 30.791], # 80
107.1: [25.945, 51.891], # 100
132.5: [49.639, 89.350], # 125
160.3: [87.185, 152.573], # 150
210.1: [174.732, 299.541], # 200
}
# capacity in kW
isoplus_twin_capacity = {
21.7: [25, 54], # 20
27.3: [40, 88], # 25
36.0: [82, 164], # 32
41.9: [110, 220], # 40
53.9: [205, 410], # 50
69.7: [341, 683], # 65
82.5: [537, 1074], # 80
107.1: [905, 1811], # 100
132.5: [1732, 3118], # 125
160.3: [3042, 5324], # 150
210.1: [6097, 10451], # 200
}
# *****************************************************************************
# *****************************************************************************
# specifications
# district heating details
# dh_flow_temperature = 273.15+115 # K # leads to problems in friction factor calculation
# dh_return_temperature = 273.15+85 # K # leads to problems in friction factor calculation
dh_flow_temperature = 273.15+70 # K
dh_return_temperature = 273.15+40 # K
# temperature fluid bulk
temperature_fluid_bulk = 0.5*(dh_return_temperature+dh_flow_temperature)
# ground temperature
ground_temperature = 273.15+10 # K
# pipe absolute/effective roughness
pipe_e_eff = 0.01/1000 # m
# pipe length
pipe_length = 1000
# pipe depth
pipe_depth = 0.8
# soil thermal conductivity
soil_k = 1 #0.5
# pipe distance
pipe_distance = 0.1 # plus diameter
ground_air_heat_transfer_coefficient = math.inf
# single pipe method
# single_pipe_trench_config = (_tre.SHT_METHOD_DIRECT, _tre.TRGTPT_KRISCHER1936)
# single_pipe_trench_config = (_tre.SHT_METHOD_SYM_ASYM, _tre.TRGTPT_MULTIPOLE_ZERO_ORDER)
# single_pipe_trench_config = (_tre.SHT_METHOD_SYM_ASYM, _tre.TRGTPT_MULTIPOLE_FIRST_ORDER)
# single_pipe_trench_config = (_tre.SHT_METHOD_DIRECT, _tre.TRGTPT_MULTIPOLE_ZERO_ORDER)
single_pipe_trench_config = (_tre.SHT_METHOD_DIRECT, _tre.TRGTPT_MULTIPOLE_FIRST_ORDER)
# twin pipe method
# twin_pipe_trench_config = (_tre.SHT_METHOD_SYM_ASYM, _tre.TRGTPT_MULTIPOLE_ZERO_ORDER)
# twin_pipe_trench_config = (_tre.SHT_METHOD_SYM_ASYM, _tre.TRGTPT_MULTIPOLE_FIRST_ORDER)
twin_pipe_trench_config = (_tre.SHT_METHOD_SYM_ASYM, _tre.TRGTPT_TWO_MODEL_APPROX)
# *****************************************************************************
# *****************************************************************************
pipe_tuples = [
(20, 1, 'isoplus', 'DRD-20-STD'),
(25, 1, 'isoplus', 'DRD-25-STD'),
(32, 1, 'isoplus', 'DRD-32-STD'),
(40, 1, 'isoplus', 'DRD-40-STD'),
(50, 1, 'isoplus', 'DRD-50-STD'),
(65, 1, 'isoplus', 'DRD-65-STD'),
(80, 1, 'isoplus', 'DRD-80-STD'),
(100, 1, 'isoplus', 'DRD-100-STD'),
(125, 1, 'isoplus', 'DRD-125-STD'),
(150, 1, 'isoplus', 'DRD-150-STD'),
(200, 1, 'isoplus', 'DRD-200-STD'),
]
list_twin_pipes = [
StandardisedTwinPipe(
pipe_tuple=pipe_tuple,
e_eff=pipe_e_eff, # override pipe absolute roughness
length=pipe_length, # override the pipe length
db=pipedb)
for pipe_tuple in pipe_tuples
]
# *****************************************************************************
# *****************************************************************************
twin_trench = TwinPipeTrench(
pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_twin_pipes],
fluid_db=fluiddb,
phase=fluiddb.fluid_LIQUID,
pressure=[1e5 for i in range(len(list_twin_pipes))],
supply_temperature=[dh_flow_temperature for i in range(len(list_twin_pipes))],
return_temperature=[dh_return_temperature for i in range(len(list_twin_pipes))],
max_specific_pressure_loss=[100 for i in range(len(list_twin_pipes))],
supply_pipe=list_twin_pipes
)
twin_trench2 = TwinPipeTrench(
pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_twin_pipes],
fluid_db=fluiddb,
phase=fluiddb.fluid_LIQUID,
pressure=[1e5 for i in range(len(list_twin_pipes))],
supply_temperature=[dh_flow_temperature for i in range(len(list_twin_pipes))],
return_temperature=[dh_return_temperature for i in range(len(list_twin_pipes))],
max_specific_pressure_loss=[200 for i in range(len(list_twin_pipes))],
supply_pipe=list_twin_pipes
)
# pipe capacity vs flow rate
fig, ax = plt.subplots()
# datasheet
level_label_datasheet = ['low speed', 'high speed']
level_linestyle_datasheet = ['rd-','bd-']
for level in range(2):
ax.semilogy([d for d in isoplus_twin_capacity.keys()],
[_cap[level] for d, _cap in isoplus_twin_capacity.items()],
level_linestyle_datasheet[level],
label=level_label_datasheet[level])
# model
level_label_model = ['low speed (model)', 'high speed (model)']
level_linestyle_model = ['ro--','bo--']
fluid_density = twin_trench.supply_fluid[0].mass_density #1000 # Kg/m3
for level in range(2):
# convert vfr to m3/s
m = [_v[level]*fluid_density/3600 for k, _v in isoplus_twin_vfr.items()]
trans_cap = []
for i, _m in enumerate(m):
_cap = twin_trench.heat_transfer_rate(mass_flow_rate=_m)
trans_cap.append(_cap[i]/1e3)
ax.semilogy([pipe.d_int*1e3 for pipe in twin_trench.supply_pipe],
trans_cap,
level_linestyle_model[level],
markersize=15,
markerfacecolor='none',
label=level_label_model[level])
# rated capacity @ 100 Pa/m
cap = [_cap/1e3 for _cap in twin_trench.rated_heat_capacity()]
ax.semilogy([pipe.d_int*1e3 for pipe in twin_trench.supply_pipe],
cap,
'k--',
label=str(twin_trench.max_specific_pressure_loss[0])+' Pa/m (model)')
# rated capacity @ 200 Pa/m
cap2 = [_cap/1e3 for _cap in twin_trench2.rated_heat_capacity()]
ax.semilogy([pipe.d_int*1e3 for pipe in twin_trench2.supply_pipe],
cap2,
'k-',
label=str(twin_trench2.max_specific_pressure_loss[0])+' Pa/m (model)')
ax.set(xlabel='Pipe internal diameter [mm]',
ylabel='Transmittable Capacity [kW]')
ax.legend()
ax.grid()
ax.set(xlim=(10, 220),ylim=(0, 12e3))
# fig.savefig("test.png")
plt.show()
...@@ -26,10 +26,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'), ...@@ -26,10 +26,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'),
(50, 1, 'isoplus', 'DRE-50-STD'), (50, 1, 'isoplus', 'DRE-50-STD'),
(65, 1, 'isoplus', 'DRE-65-STD'), (65, 1, 'isoplus', 'DRE-65-STD'),
(80, 1, 'isoplus', 'DRE-80-STD'), (80, 1, 'isoplus', 'DRE-80-STD'),
(100, 1, 'isoplus', 'DRE-100-ST'), (100, 1, 'isoplus', 'DRE-100-STD'),
(125, 1, 'isoplus', 'DRE-125-ST'), (125, 1, 'isoplus', 'DRE-125-STD'),
(150, 1, 'isoplus', 'DRE-150-ST'), (150, 1, 'isoplus', 'DRE-150-STD'),
(200, 1, 'isoplus', 'DRE-200-ST')] (200, 1, 'isoplus', 'DRE-200-STD')]
# relative pipe roughness # relative pipe roughness
......
...@@ -38,10 +38,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'), ...@@ -38,10 +38,10 @@ list_pipe_tuples = [(20, 1, 'isoplus', 'DRE-20-STD'),
(50, 1, 'isoplus', 'DRE-50-STD'), (50, 1, 'isoplus', 'DRE-50-STD'),
(65, 1, 'isoplus', 'DRE-65-STD'), (65, 1, 'isoplus', 'DRE-65-STD'),
(80, 1, 'isoplus', 'DRE-80-STD'), (80, 1, 'isoplus', 'DRE-80-STD'),
(100, 1, 'isoplus', 'DRE-100-ST'), (100, 1, 'isoplus', 'DRE-100-STD'),
(125, 1, 'isoplus', 'DRE-125-ST'), (125, 1, 'isoplus', 'DRE-125-STD'),
(150, 1, 'isoplus', 'DRE-150-ST'), (150, 1, 'isoplus', 'DRE-150-STD'),
(200, 1, 'isoplus', 'DRE-200-ST')] (200, 1, 'isoplus', 'DRE-200-STD')]
# relative pipe roughness # relative pipe roughness
......
...@@ -10,6 +10,7 @@ from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase ...@@ -10,6 +10,7 @@ from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase
from topupheat.pipes.twin import StandardisedTwinPipe from topupheat.pipes.twin import StandardisedTwinPipe
from topupheat.pipes.trenches import SupplyReturnPipeTrench, TwinPipeTrench from topupheat.pipes.trenches import SupplyReturnPipeTrench, TwinPipeTrench
import topupheat.pipes.trenches as _tre import topupheat.pipes.trenches as _tre
from topupheat.pipes.utils import minimum_assembling_distance_isoplus
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
...@@ -26,65 +27,6 @@ pipedata_files = [ ...@@ -26,65 +27,6 @@ pipedata_files = [
'pipes/isoplus_twin_disconti_s3.csv', 'pipes/isoplus_twin_disconti_s3.csv',
] ]
def minimum_assembling_distance(pipe_outer_diameter: float):
if pipe_outer_diameter <= 0.065:
return 0.100
elif pipe_outer_diameter <= 0.075:
return 0.100
elif pipe_outer_diameter <= 0.090:
return 0.100
elif pipe_outer_diameter <= 0.110:
return 0.150
elif pipe_outer_diameter <= 0.125:
return 0.150
elif pipe_outer_diameter <= 0.140:
return 0.150
elif pipe_outer_diameter <= 0.160:
return 0.200
elif pipe_outer_diameter <= 0.180:
return 0.200
elif pipe_outer_diameter <= 0.200:
return 0.200
elif pipe_outer_diameter <= 0.225:
return 0.200
elif pipe_outer_diameter <= 0.250:
return 0.200
elif pipe_outer_diameter <= 0.280:
return 0.300
elif pipe_outer_diameter <= 0.315:
return 0.300
elif pipe_outer_diameter <= 0.355:
return 0.300
elif pipe_outer_diameter <= 0.400:
return 0.400
elif pipe_outer_diameter <= 0.450:
return 0.400
elif pipe_outer_diameter <= 0.500:
return 0.400
elif pipe_outer_diameter <= 0.560:
return 0.500
elif pipe_outer_diameter <= 0.630:
return 0.500
elif pipe_outer_diameter <= 0.670:
return 0.600
elif pipe_outer_diameter <= 0.710:
return 0.600
elif pipe_outer_diameter <= 0.800:
return 0.700
elif pipe_outer_diameter <= 0.900:
return 0.700
elif pipe_outer_diameter <= 1.000:
return 0.800
elif pipe_outer_diameter <= 1.100:
return 0.800
elif pipe_outer_diameter <= 1.200:
return 0.900
elif pipe_outer_diameter <= 1.300:
return 0.900
else:
raise NotImplementedError
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
...@@ -94,8 +36,10 @@ def minimum_assembling_distance(pipe_outer_diameter: float): ...@@ -94,8 +36,10 @@ def minimum_assembling_distance(pipe_outer_diameter: float):
list_max_specific_pressure_loss = [80] # Pa/m list_max_specific_pressure_loss = [80] # Pa/m
# district heating details # district heating details
dh_flow_temperature = 273.15+115 # K # dh_flow_temperature = 273.15+115 # K # leads to problems in friction factor calculation
dh_return_temperature = 273.15+85 # K # dh_return_temperature = 273.15+85 # K # leads to problems in friction factor calculation
dh_flow_temperature = 273.15+70 # K
dh_return_temperature = 273.15+40 # K
# temperature fluid bulk # temperature fluid bulk
temperature_fluid_bulk = 0.5*(dh_return_temperature+dh_flow_temperature) temperature_fluid_bulk = 0.5*(dh_return_temperature+dh_flow_temperature)
...@@ -112,7 +56,7 @@ pipe_length = 1000 ...@@ -112,7 +56,7 @@ pipe_length = 1000
# pipe depth # pipe depth
pipe_depth = 0.8 pipe_depth = 0.8
# pipe soil # soil thermal conductivity
soil_k = 1 #0.5 soil_k = 1 #0.5
# pipe distance # pipe distance
...@@ -399,8 +343,7 @@ u_pipes = { ...@@ -399,8 +343,7 @@ u_pipes = {
(150, 3, 'isoplus', 'DRD-150-TWIRE'): 0.2379 (150, 3, 'isoplus', 'DRD-150-TWIRE'): 0.2379
} }
# pipe speeds # pipe mass flow in tones per hour
m_pipes = { # 60-80 Pa m_pipes = { # 60-80 Pa
21.7: [0.4, 0.5], # 20 21.7: [0.4, 0.5], # 20
27.3: [0.8, 1.0], 27.3: [0.8, 1.0],
...@@ -632,7 +575,7 @@ for max_specific_pressure_loss in list_max_specific_pressure_loss: ...@@ -632,7 +575,7 @@ for max_specific_pressure_loss in list_max_specific_pressure_loss:
single_trench = SupplyReturnPipeTrench( single_trench = SupplyReturnPipeTrench(
pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_single_pipes], pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_single_pipes],
# pipe_center_distance=[pipe_distance+pipe.d_cas for pipe in list_single_pipes], # minimum_assembling_distance # pipe_center_distance=[pipe_distance+pipe.d_cas for pipe in list_single_pipes], # minimum_assembling_distance
pipe_center_distance=[minimum_assembling_distance(pipe.d_cas)+pipe.d_cas for pipe in list_single_pipes], pipe_center_distance=[minimum_assembling_distance_isoplus(pipe.d_cas)+pipe.d_cas for pipe in list_single_pipes],
fluid_db=fluiddb, fluid_db=fluiddb,
phase=fluiddb.fluid_LIQUID, phase=fluiddb.fluid_LIQUID,
pressure=[1e5 for i in range(len(list_single_pipes))], pressure=[1e5 for i in range(len(list_single_pipes))],
...@@ -753,29 +696,25 @@ twin_pipe_tuples_per_tech = { ...@@ -753,29 +696,25 @@ twin_pipe_tuples_per_tech = {
for max_specific_pressure_loss in list_max_specific_pressure_loss: for max_specific_pressure_loss in list_max_specific_pressure_loss:
# single pipe # single pipe
for tech_index, _single_pipe_tuples in single_pipe_tuples_per_tech.items(): for tech_index, _single_pipe_tuples in single_pipe_tuples_per_tech.items():
_indices = [list_single_pipe_tuples.index(pipe_tuple) for pipe_tuple in _single_pipe_tuples] _indices = [list_single_pipe_tuples.index(pipe_tuple) for pipe_tuple in _single_pipe_tuples]
ax.semilogy( ax.semilogy(
[1000*list_single_pipes[index].d_int for index in _indices], [1000*list_single_pipes[index].d_int for index in _indices],
[2*u_pipes[pipe_tuple]*(temperature_fluid_bulk-ground_temperature) [2*u_pipes[pipe_tuple]*(temperature_fluid_bulk-ground_temperature)
for pipe_tuple in _single_pipe_tuples], for pipe_tuple in _single_pipe_tuples],
style_category_single_official[tech_index], style_category_single_official[tech_index],
markersize=10, markersize=10,
label='isoplus, 2x single, tech '+str(model_string_ids[tech_index][1:])+' (datasheet)' label='isoplus, 2x single, '+str(model_string_ids[tech_index][1:])+' series (datasheet)'
) )
# twin pipe # twin pipe
for tech_index, _twin_pipe_tuples in twin_pipe_tuples_per_tech.items(): for tech_index, _twin_pipe_tuples in twin_pipe_tuples_per_tech.items():
_indices = [list_twin_pipe_tuples.index(pipe_tuple) for pipe_tuple in _twin_pipe_tuples] _indices = [list_twin_pipe_tuples.index(pipe_tuple) for pipe_tuple in _twin_pipe_tuples]
ax.semilogy( ax.semilogy(
[1000*list_twin_pipes[index].d_int for index in _indices], [1000*list_twin_pipes[index].d_int for index in _indices],
[u_pipes[pipe_tuple]*(temperature_fluid_bulk-ground_temperature) [u_pipes[pipe_tuple]*(temperature_fluid_bulk-ground_temperature)
for pipe_tuple in _twin_pipe_tuples], for pipe_tuple in _twin_pipe_tuples],
style_category_twin_official[tech_index], style_category_twin_official[tech_index],
markersize=10, markersize=10,
label='isoplus, 1x twin, tech '+str(model_string_ids[tech_index][1:])+' (datasheet)' label='isoplus, 1x twin, '+str(model_string_ids[tech_index][1:])+' series (datasheet)'
) )
# model, single # model, single
...@@ -797,26 +736,12 @@ for tech_index, _twin_pipe_tuples in twin_pipe_tuples_per_tech.items(): ...@@ -797,26 +736,12 @@ for tech_index, _twin_pipe_tuples in twin_pipe_tuples_per_tech.items():
markersize=10, markersize=10,
label='isoplus, 1x twin (model)') label='isoplus, 1x twin (model)')
# ax.plot([1000*pipe.d_int for pipe in list_single_pipes],
# [dict_single_heat_transfer_rate[max_specific_pressure_loss][i]
# for i, pipe_tuple in enumerate(list_single_pipe_tuples)],
# 'gx',
# markersize=10,
# label='isoplus, 2x single (model)')
# ax.plot([1000*pipe.d_int for pipe in list_twin_pipes],
# [dict_twin_heat_transfer_rate[max_specific_pressure_loss][i]
# for i, pipe_tuple in enumerate(list_twin_pipe_tuples)],
# 'k^',
# markersize=10,
# label='isoplus, 1x twin (model)')
ax.set(xlabel='Nominal diameter (DN)', ax.set(xlabel='Nominal diameter (DN)',
ylabel='Specific heat losses [W/m]', ylabel='Specific heat losses [W/m]',
title='Specific heat losses as a function of pipe diameter') title='Specific heat losses as a function of pipe diameter')
ax.grid() ax.set(xlim=(0, 1000),ylim=(5, 100))
ax.grid(which='both')
ax.legend() ax.legend()
# fig.savefig("test.png") # fig.savefig("test.png")
...@@ -830,7 +755,7 @@ plt.show() ...@@ -830,7 +755,7 @@ plt.show()
fig, ax = plt.subplots() fig, ax = plt.subplots()
fig.set_size_inches(15,10) fig.set_size_inches(15,10)
cpdt = 4187*30*(3600/1000)/1000 # m in tons per hour; cpdt has to be in J/Kg cpdt = 4187*(dh_flow_temperature-dh_return_temperature)*(1000/3600)/1000 # m in tons per hour; cpdt has to be in J/Kg
max_specific_pressure_loss = 80 max_specific_pressure_loss = 80
...@@ -871,6 +796,10 @@ for max_specific_pressure_loss in list_max_specific_pressure_loss: ...@@ -871,6 +796,10 @@ for max_specific_pressure_loss in list_max_specific_pressure_loss:
label='isoplus, 2x single (model)') label='isoplus, 2x single (model)')
break break
# [dict_single_trench[max_specific_pressure_loss].nmls_supply
# for pipe_tuple in _single_pipe_tuples]
# ax.semilogy([1000*pipe.d_int for pipe in list_twin_pipes], # ax.semilogy([1000*pipe.d_int for pipe in list_twin_pipes],
# [dict_twin_capacity[max_specific_pressure_loss][i]/1e3 # [dict_twin_capacity[max_specific_pressure_loss][i]/1e3
# for i, pipe_tuple in enumerate(list_twin_pipe_tuples)], # for i, pipe_tuple in enumerate(list_twin_pipe_tuples)],
......
...@@ -569,7 +569,6 @@ class SupplyReturnPipeSystem: ...@@ -569,7 +569,6 @@ class SupplyReturnPipeSystem:
unit_conversion_factor: float = 1.0 unit_conversion_factor: float = 1.0
): ):
# length >> options
# specific_heat_transfer_coefficient >> options # specific_heat_transfer_coefficient >> options
# temperature_surroundings >> temporal # temperature_surroundings >> temporal
# determine if the inputs are for temporal vector/normal mode # determine if the inputs are for temporal vector/normal mode
...@@ -585,7 +584,8 @@ class SupplyReturnPipeSystem: ...@@ -585,7 +584,8 @@ class SupplyReturnPipeSystem:
if ((not self.vector_mode and if ((not self.vector_mode and
not isinstance(specific_heat_transfer_coefficient, Real)) or not isinstance(specific_heat_transfer_coefficient, Real)) or
(self.vector_mode and (self.vector_mode and
len(self.supply_temperature) < 1 len(self.supply_temperature) < 1 or
len(specific_heat_transfer_coefficient) != self.number_options()
) )
): ):
raise TypeError('Inconsistent inputs.') raise TypeError('Inconsistent inputs.')
...@@ -646,7 +646,7 @@ class SupplyReturnPipeSystem: ...@@ -646,7 +646,7 @@ class SupplyReturnPipeSystem:
return out return out
# ************************************************************************* # *************************************************************************
# TODO: reconsider the implementation in vector mode
def simplified_heat_transfer_surroundings( def simplified_heat_transfer_surroundings(
self, self,
length: float or list, length: float or list,
...@@ -655,6 +655,40 @@ class SupplyReturnPipeSystem: ...@@ -655,6 +655,40 @@ class SupplyReturnPipeSystem:
time_interval_duration: float or list, time_interval_duration: float or list,
unit_conversion_factor: float = 1.0 unit_conversion_factor: float = 1.0
): ):
"""
Calculates the heat transfer with the surroundings using a constant
specific heat transfer coefficient.
Parameters
----------
length : float or list
The length of each segment.
specific_heat_transfer_coefficient : float or list
The heat transfer coefficient per unit length.
temperature_surroundings : float or list
The temperature of the surroundings.
time_interval_duration : float or list
The duration of each time step under consideration.
unit_conversion_factor : float, optional
A factor to adjust the final units. The default is 1.0.
Raises
------
TypeError
This error is raised if the combination of inputs is incompatible.
Returns
-------
out : float, list or list of lists
The heat transfer rate based on the inputs. If single inputs are
provided and a single option is under consideration, then a float
is returned. If there are multiple options and single inputs are
provided, then a list with one heat transfer rate per option is
returned. If there are multiple options and multiple inputs, then
a list of lists is returned: one list with one list per option,
each of which with one heat transfer rate per input.
"""
# length >> options # length >> options
# specific_heat_transfer_coefficient >> options # specific_heat_transfer_coefficient >> options
...@@ -669,7 +703,7 @@ class SupplyReturnPipeSystem: ...@@ -669,7 +703,7 @@ class SupplyReturnPipeSystem:
type(time_interval_duration) == tuple)): type(time_interval_duration) == tuple)):
temporal_vector_mode = True temporal_vector_mode = True
else: else:
raise ValueError('Incompatible inputs.') raise TypeError('Incompatible inputs.')
# confirm inputs are consistent with vector/normal mode # confirm inputs are consistent with vector/normal mode
if ((not self.vector_mode and if ((not self.vector_mode and
...@@ -678,7 +712,8 @@ class SupplyReturnPipeSystem: ...@@ -678,7 +712,8 @@ class SupplyReturnPipeSystem:
(self.vector_mode and (self.vector_mode and
(type(length) != list and (type(length) != list and
type(length) != tuple or type(length) != tuple or
len(length) != len(self.supply_temperature)) len(length) != self.number_options() or
len(specific_heat_transfer_coefficient) != len(length))
) )
): ):
raise TypeError('Inconsistent inputs.') raise TypeError('Inconsistent inputs.')
......
import math
import numpy as np import numpy as np
# from numbers import Real # from numbers import Real
from src.topupheat.common.fluids import FluidDatabase, Fluid from src.topupheat.common.fluids import FluidDatabase, Fluid
...@@ -9,6 +9,7 @@ from src.topupheat.pipes.twin import SymmetricalTwinPipe, StandardisedTwinPipe ...@@ -9,6 +9,7 @@ from src.topupheat.pipes.twin import SymmetricalTwinPipe, StandardisedTwinPipe
from math import isclose, inf, ceil from math import isclose, inf, ceil
from src.topupheat.common.factors import shape_factor_buried_horizontal_isothermal_cylinder from src.topupheat.common.factors import shape_factor_buried_horizontal_isothermal_cylinder
from src.topupheat.common.factors import thermal_resistance_from_shape_factor from src.topupheat.common.factors import thermal_resistance_from_shape_factor
from topupheat.pipes.utils import minimum_assembling_distance_isoplus
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
...@@ -2705,8 +2706,169 @@ class TestPipeTrench: ...@@ -2705,8 +2706,169 @@ class TestPipeTrench:
# assert type(trench.printable_description()) == str # assert type(trench.printable_description()) == str
# TODO: test the simplified specific heat transfer method using trench objects # *************************************************************************
# *************************************************************************
def test_simplified_heat_transfer_twin_pipes(self):
# maximum specific pressure drop
max_specific_pressure_loss = 80 # Pa/m
# district heating details
dh_flow_temperature = 273.15+70 # K
dh_return_temperature = 273.15+40 # K
# ground temperature
ground_temperature = 273.15+10 # K
# pipe absolute/effective roughness
pipe_e_eff = 0.01/1000 # m
# pipe length
pipe_length = 1000
# pipe depth
pipe_depth = 0.8
# pipe data
pipedata_files = [
'tests/data/isoplus_twin_disconti_s1.csv',
# 'tests/data/isoplus_twin_disconti_s2.csv',
# 'tests/data/isoplus_twin_disconti_s3.csv',
]
# pipe data
pipedb = StandardisedPipeDatabase(source=pipedata_files)
# fluid data
fluiddata_file = 'tests/data/incropera2006_saturated_water.csv'
fluiddb = fic.FluidDatabase(fluid='water', phase='l', source=fluiddata_file)
# *****************************************************************************
# *****************************************************************************
# pipe tuples
list_pipe_tuples = [
pipe_tuple
for pipe_tuple in pipedb.pipe_tuples
]
# pipe objects
list_pipes = [
StandardisedTwinPipe(
pipe_tuple=pipe_tuple,
e_eff=pipe_e_eff, # override pipe absolute roughness
length=pipe_length, # override the pipe length
db=pipedb)
for pipe_tuple in list_pipe_tuples
]
# single pipe trench
single_trench = trenches.TwinPipeTrench(
pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_pipes],
fluid_db=fluiddb,
phase=fluiddb.fluid_LIQUID,
pressure=[1e5 for i in range(len(list_pipes))],
supply_temperature=[dh_flow_temperature for i in range(len(list_pipes))],
return_temperature=[dh_return_temperature for i in range(len(list_pipes))],
max_specific_pressure_loss=[max_specific_pressure_loss for i in range(len(list_pipes))],
supply_pipe=list_pipes
)
assert single_trench.vector_mode
assert single_trench.number_options() == len(list_pipes)
# one u per option
u = [i+1 for i in range(len(list_pipe_tuples))]
q = single_trench.simplified_specific_heat_transfer_surroundings(
specific_heat_transfer_coefficient=u,
temperature_surroundings=ground_temperature,
)
for i, q_i in enumerate(q):
assert math.isclose(
q_i,
u[i]*(dh_flow_temperature/2+dh_return_temperature/2-ground_temperature),
abs_tol=1e-3
)
# TODO: multiple time intervals
# *************************************************************************
# *************************************************************************
def test_simplified_heat_transfer_two_single_pipes(self):
# maximum specific pressure drop
max_specific_pressure_loss = 80 # Pa/m
# district heating details
dh_flow_temperature = 273.15+70 # K
dh_return_temperature = 273.15+40 # K
# ground temperature
ground_temperature = 273.15+10 # K
# pipe absolute/effective roughness
pipe_e_eff = 0.01/1000 # m
# pipe length
pipe_length = 1000
# pipe depth
pipe_depth = 0.8
# pipe data
pipedata_files = [
'tests/data/isoplus_single_disconti_s1.csv',
# 'tests/data/isoplus_single_disconti_s2.csv',
# 'tests/data/isoplus_single_disconti_s3.csv',
]
# pipe data
pipedb = StandardisedPipeDatabase(source=pipedata_files)
# fluid data
fluiddata_file = 'tests/data/incropera2006_saturated_water.csv'
fluiddb = fic.FluidDatabase(fluid='water', phase='l', source=fluiddata_file)
# pipe tuples
list_pipe_tuples = [
pipe_tuple
for pipe_tuple in pipedb.pipe_tuples
]
# pipe objects
list_pipes = [
StandardisedPipe(
pipe_tuple=pipe_tuple,
e_eff=pipe_e_eff, # override pipe absolute roughness
length=pipe_length, # override the pipe length
db=pipedb)
for pipe_tuple in list_pipe_tuples
]
# single pipe trench
single_trench = trenches.SupplyReturnPipeTrench(
pipe_center_depth=[pipe_depth+pipe.d_cas/2 for pipe in list_pipes],
pipe_center_distance=[minimum_assembling_distance_isoplus(pipe.d_cas)+pipe.d_cas for pipe in list_pipes],
fluid_db=fluiddb,
phase=fluiddb.fluid_LIQUID,
pressure=[1e5 for i in range(len(list_pipes))],
supply_temperature=[dh_flow_temperature for i in range(len(list_pipes))],
return_temperature=[dh_return_temperature for i in range(len(list_pipes))],
max_specific_pressure_loss=[max_specific_pressure_loss for i in range(len(list_pipes))],
supply_pipe=list_pipes
)
assert single_trench.vector_mode
# one u per option
u = [i+1 for i in range(len(list_pipe_tuples))]
q = single_trench.simplified_specific_heat_transfer_surroundings(
specific_heat_transfer_coefficient=u,
temperature_surroundings=ground_temperature,
)
for i, q_i in enumerate(q):
assert math.isclose(
q_i,
u[i]*(dh_flow_temperature/2+dh_return_temperature/2-ground_temperature),
abs_tol=1e-3
)
# *************************************************************************
# ************************************************************************* # *************************************************************************
def test_different_single_pipes(self): def test_different_single_pipes(self):
...@@ -2852,98 +3014,6 @@ class TestPipeTrench: ...@@ -2852,98 +3014,6 @@ class TestPipeTrench:
# ************************************************************************* # *************************************************************************
# ************************************************************************* # *************************************************************************
# TODO: try to do this
# def test_u_coefficient_formula_bohm2005_twin(self):
# # *********************************************************************
# # trench
# pipe_distance = 0.0251+0.0889 # m
# pipe_depth = 1.28 # m
# h_gs = 14.6 # W/m2K
# ground_temperature = 8+273.15 # K
# soil_k = 1.5 # W/mK
# supply_temperature = 80+273.15
# return_temperature = 40+273.15
# #**************************************************************************
# # pipes
# twin_pipe = SymmetricalTwinPipe(
# length=1000,
# k=60,
# e_eff=1e-5,
# d_int=0.0889-2*0.0032,
# d_ext=0.0889,
# d_ins=0.2483,
# d_cas=0.2483+2*0.0036,
# k_ins=0.0265,
# k_cas=0.43,
# pipe_center_distance=pipe_distance)
# #**************************************************************************
# u11_true = 0.2517 # W/mK
# u22_true = 0.2534 # W/mK
# u12_true = 0.0784 # W/mK
# q_total_true = 18.08 # W/m
# list_abs_tol_u11 = [1e-9, 1e-9, 1e-9]
# list_abs_tol_u12 = [1e-9, 1e-9, 1e-9]
# # calculations
# list_ground_resistance_models = [
# trenches.TRGTPT_TWO_MODEL_APPROX,
# trenches.TRGTPT_MULTIPOLE_ZERO_ORDER,
# trenches.TRGTPT_MULTIPOLE_FIRST_ORDER
# ]
# for i, model in enumerate(list_ground_resistance_models):
# (rsym,
# rasym) = trenches.ThermalResistanceBuriedTwinPipesWallenten(
# twin_pipe,
# soil_k,
# pipe_depth,
# pipe_distance,
# h_gs,
# model=model)
# (u1122,
# u12) = trenches.HeatTransferCoefficientsFromSymmetricalAsymmetricalResistances(
# rsym, rasym)
# print('hey')
# print(u1122)
# print(u12)
# assert isclose(
# u1122,
# u11_true,
# abs_tol=list_abs_tol_u11[i]
# )
# assert isclose(
# u12,
# u12_true,
# abs_tol=list_abs_tol_u12[i]
# )
# # *********************************************************************
# *************************************************************************
def test_district_cooling(self): def test_district_cooling(self):
# load pipe data # load pipe data
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment