# imports # standard from numbers import Real from math import inf, isclose # local, external # local, internal # topupopt from src.topupopt.data.dhn.network import PipeTrenchOptions, ExistingPipeTrench from src.topupopt.data.dhn.network import PipeTrenchInvestments from src.topupopt.data.finance.invest import Investment # topupheat from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase import topupheat.pipes.trenches as trenches from topupheat.common.fluids import FluidDatabase # ***************************************************************************** # ***************************************************************************** class TestDistrictHeatingNetwork: # TODO: method to check the validity of arcs def test_existing_pipe_trench(self): # fluid data waterdata_file = "tests/data/incropera2006_saturated_water.csv" phase = FluidDatabase.fluid_LIQUID fluid_db = FluidDatabase(fluid="fluid", phase=phase, source=waterdata_file) singlepipedata_files = ["tests/data/isoplus_singlepipes_s1.csv"] pipedb = StandardisedPipeDatabase(source=singlepipedata_files) pipe = StandardisedPipe( pipe_tuple=pipedb.pipe_tuples[0], # e_eff=pipe_e_eff, # sp=pipe_specific_price, db=pipedb, ) # network details supply_temperature = 85 + 273.15 return_temperature = 45 + 273.15 pressure = 1e5 # trench pipe_distance = 0.52 # m pipe_depth = 0.66 # m # environmental outdoor_temperature = 6 + 273.15 # K h_gs = inf # 14.6 # W/m2K soil_k = 1.5 # W/mK # more information max_specific_pressure_loss = 100 # Pa/m mytrench = trenches.SupplyReturnPipeTrench( pipe_center_depth=pipe_depth, pipe_center_distance=pipe_distance, fluid_db=fluid_db, phase=phase, pressure=pressure, supply_temperature=supply_temperature, return_temperature=return_temperature, max_specific_pressure_loss=max_specific_pressure_loss, supply_pipe=pipe, ) # PipeTrenchOptions myarcs = ExistingPipeTrench( option_selected=0, trench=mytrench, name="hellotrench", length=20 ) # add static loss scenario myarcs.set_static_losses( scenario_key="scenario0", ground_thermal_conductivity=soil_k, ground_air_heat_transfer_coefficient=h_gs, time_interval_duration=3600, temperature_surroundings=outdoor_temperature, ) # add another static loss scenario myarcs.set_static_losses( scenario_key="scenario1", ground_thermal_conductivity=soil_k + 1, ground_air_heat_transfer_coefficient=h_gs + 1, time_interval_duration=3600 + 100, temperature_surroundings=outdoor_temperature + 1, ) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # test arcs n = myarcs.number_options() assert myarcs.has_been_selected() assert len(myarcs.capacity) == n assert len(myarcs.minimum_cost) == n assert isinstance(myarcs.specific_capacity_cost, Real) assert type(myarcs.efficiency) == type(None) assert type(myarcs.efficiency_reverse) == type(None) assert type(myarcs.static_loss) == dict assert len(myarcs.static_loss) != 0 for (h, q, k), sl in myarcs.static_loss.items(): assert isinstance(sl, Real) assert sl >= 0 # redefine the capacity capacity = tuple(myarcs.capacity) myarcs.set_capacity(max_specific_pressure_loss=max_specific_pressure_loss + 100) assert len(capacity) == len(myarcs.capacity) for _c1, _c2 in zip(capacity, myarcs.capacity): assert _c1 != _c2 # redefine the minimum costs min_cost = tuple(myarcs.minimum_cost) myarcs.set_minimum_cost(minimum_cost=[_mc + 1 for _mc in min_cost]) assert len(min_cost) == len(myarcs.minimum_cost) for _mc1, _mc2 in zip(min_cost, myarcs.minimum_cost): assert _mc1 + 1 == _mc2 # ********************************************************************* # ************************************************************************* # ************************************************************************* def test_creating_single_arcs(self): # fluid data waterdata_file = "tests/data/incropera2006_saturated_water.csv" phase = FluidDatabase.fluid_LIQUID fluid_db = FluidDatabase(fluid="fluid", phase=phase, source=waterdata_file) singlepipedata_files = ["tests/data/isoplus_singlepipes_s1.csv"] pipedb = StandardisedPipeDatabase(source=singlepipedata_files) pipe = StandardisedPipe( pipe_tuple=pipedb.pipe_tuples[0], # e_eff=pipe_e_eff, # sp=pipe_specific_price, db=pipedb, ) # network details supply_temperature = 85 + 273.15 return_temperature = 45 + 273.15 pressure = 1e5 # trench pipe_distance = 0.52 # m pipe_depth = 0.66 # m # environmental outdoor_temperature = 6 + 273.15 # K h_gs = inf # 14.6 # W/m2K soil_k = 1.5 # W/mK # more information max_specific_pressure_loss = 100 # Pa/m mytrench = trenches.SupplyReturnPipeTrench( pipe_center_depth=pipe_depth, pipe_center_distance=pipe_distance, fluid_db=fluid_db, phase=phase, pressure=pressure, supply_temperature=supply_temperature, return_temperature=return_temperature, max_specific_pressure_loss=max_specific_pressure_loss, supply_pipe=pipe, ) # PipeTrenchOptions myarcs = PipeTrenchOptions(trench=mytrench, name="hellotrench", length=50) # add static loss scenario myarcs.set_static_losses( scenario_key="scenario0", ground_thermal_conductivity=soil_k, ground_air_heat_transfer_coefficient=h_gs, time_interval_duration=3600, temperature_surroundings=outdoor_temperature, ) # add another static loss scenario myarcs.set_static_losses( scenario_key="scenario1", ground_thermal_conductivity=soil_k + 1, ground_air_heat_transfer_coefficient=h_gs + 1, time_interval_duration=3600 + 100, temperature_surroundings=outdoor_temperature + 1, ) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # test arcs n = myarcs.number_options() assert not myarcs.has_been_selected() assert len(myarcs.capacity) == n assert len(myarcs.minimum_cost) == n assert isinstance(myarcs.specific_capacity_cost, Real) assert type(myarcs.efficiency) == type(None) assert type(myarcs.efficiency_reverse) == type(None) assert type(myarcs.static_loss) == dict assert len(myarcs.static_loss) != 0 for (h, q, k), sl in myarcs.static_loss.items(): assert isinstance(sl, Real) assert sl >= 0 # redefine the capacity capacity = tuple(myarcs.capacity) myarcs.set_capacity(max_specific_pressure_loss=max_specific_pressure_loss + 100) assert len(capacity) == len(myarcs.capacity) for _c1, _c2 in zip(capacity, myarcs.capacity): assert _c1 != _c2 # redefine the minimum costs min_cost = tuple(myarcs.minimum_cost) myarcs.set_minimum_cost(minimum_cost=[_mc + 1 for _mc in min_cost]) assert len(min_cost) == len(myarcs.minimum_cost) for _mc1, _mc2 in zip(min_cost, myarcs.minimum_cost): assert _mc1 + 1 == _mc2 # ********************************************************************* # create arcs object with multiple static loss values as a first case # PipeTrenchOptions myarcs = PipeTrenchOptions(trench=mytrench, name="hellotrench", length=50) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # ************************************************************************* # ************************************************************************* def test_creating_single_arcs_investment(self): # fluid data waterdata_file = "tests/data/incropera2006_saturated_water.csv" phase = FluidDatabase.fluid_LIQUID fluid_db = FluidDatabase(fluid="fluid", phase=phase, source=waterdata_file) singlepipedata_files = ["tests/data/isoplus_singlepipes_s1.csv"] pipedb = StandardisedPipeDatabase(source=singlepipedata_files) pipe = StandardisedPipe( pipe_tuple=pipedb.pipe_tuples[0], # e_eff=pipe_e_eff, # sp=pipe_specific_price, db=pipedb, ) # network details supply_temperature = 85 + 273.15 return_temperature = 45 + 273.15 pressure = 1e5 # trench pipe_distance = 0.52 # m pipe_depth = 0.66 # m # environmental outdoor_temperature = 6 + 273.15 # K h_gs = inf # 14.6 # W/m2K soil_k = 1.5 # W/mK # more information max_specific_pressure_loss = 100 # Pa/m mytrench = trenches.SupplyReturnPipeTrench( pipe_center_depth=pipe_depth, pipe_center_distance=pipe_distance, fluid_db=fluid_db, phase=phase, pressure=pressure, supply_temperature=supply_temperature, return_temperature=return_temperature, max_specific_pressure_loss=max_specific_pressure_loss, supply_pipe=pipe, ) # investments number_periods = 20 discount_rate = 0.035 discount_rates = tuple([discount_rate for p in range(number_periods)]) inv = Investment(discount_rates=discount_rates) # PipeTrenchOptions myarcs = PipeTrenchInvestments( trench=mytrench, name="hellotrench", length=50, investments=(inv,), ) # add static loss scenario myarcs.set_static_losses( scenario_key="scenario0", ground_thermal_conductivity=soil_k, ground_air_heat_transfer_coefficient=h_gs, time_interval_duration=3600, temperature_surroundings=outdoor_temperature, ) # add another static loss scenario myarcs.set_static_losses( scenario_key="scenario1", ground_thermal_conductivity=soil_k + 1, ground_air_heat_transfer_coefficient=h_gs + 1, time_interval_duration=3600 + 100, temperature_surroundings=outdoor_temperature + 1, ) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # test arcs n = myarcs.number_options() assert not myarcs.has_been_selected() assert len(myarcs.capacity) == n assert len(myarcs.minimum_cost) == n assert isinstance(myarcs.specific_capacity_cost, Real) assert type(myarcs.efficiency) == type(None) assert type(myarcs.efficiency_reverse) == type(None) assert type(myarcs.static_loss) == dict assert len(myarcs.static_loss) != 0 for (h, q, k), sl in myarcs.static_loss.items(): assert isinstance(sl, Real) assert sl >= 0 # redefine the capacity capacity = tuple(myarcs.capacity) myarcs.set_capacity(max_specific_pressure_loss=max_specific_pressure_loss + 100) assert len(capacity) == len(myarcs.capacity) for _c1, _c2 in zip(capacity, myarcs.capacity): assert _c1 != _c2 # redefine the minimum costs min_cost = tuple(myarcs.minimum_cost) myarcs.set_minimum_cost(minimum_cost=[_mc + 1 for _mc in min_cost]) assert len(min_cost) == len(myarcs.minimum_cost) for _mc1, _mc2 in zip(min_cost, myarcs.minimum_cost): assert _mc1 + 1 == _mc2 # ********************************************************************* # create arcs object with multiple static loss values as a first case # PipeTrenchOptions myarcs = PipeTrenchOptions(trench=mytrench, name="hellotrench", length=50) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # ************************************************************************* # ************************************************************************* def test_creating_multiple_arcs(self): # fluid data waterdata_file = "tests/data/incropera2006_saturated_water.csv" phase = FluidDatabase.fluid_LIQUID fluid_db = FluidDatabase(fluid="fluid", phase=phase, source=waterdata_file) singlepipedata_files = ["tests/data/isoplus_singlepipes_s1.csv"] pipedb = StandardisedPipeDatabase(source=singlepipedata_files) pipe = StandardisedPipe( pipe_tuple=pipedb.pipe_tuples[0], # e_eff=pipe_e_eff, # sp=pipe_specific_price, db=pipedb, ) # network details supply_temperature = 85 + 273.15 return_temperature = 45 + 273.15 pressure = 1e5 # trench pipe_distance = 0.52 # m pipe_depth = 0.66 # m # environmental outdoor_temperature = 6 + 273.15 # K h_gs = inf # 14.6 # W/m2K soil_k = 1.5 # W/mK # more information max_specific_pressure_loss = 100 # Pa/m number_options = 2 mytrench = trenches.SupplyReturnPipeTrench( pipe_center_depth=[pipe_depth for i in range(number_options)], pipe_center_distance=[pipe_distance for i in range(number_options)], fluid_db=fluid_db, phase=phase, pressure=[pressure for i in range(number_options)], supply_temperature=[supply_temperature for i in range(number_options)], return_temperature=[return_temperature for i in range(number_options)], max_specific_pressure_loss=[ max_specific_pressure_loss for i in range(number_options) ], supply_pipe=[pipe for i in range(number_options)], ) # PipeTrenchOptions myarcs = PipeTrenchOptions(trench=mytrench, name="hellotrench", length=50) # add static loss scenario myarcs.set_static_losses( scenario_key="scenario0", ground_thermal_conductivity=soil_k, ground_air_heat_transfer_coefficient=h_gs, time_interval_duration=3600, temperature_surroundings=outdoor_temperature, ) # add another static loss scenario myarcs.set_static_losses( scenario_key="scenario1", ground_thermal_conductivity=soil_k + 1, ground_air_heat_transfer_coefficient=h_gs + 1, time_interval_duration=3600 + 100, temperature_surroundings=outdoor_temperature + 1, ) # add static loss scenario number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # test arcs assert number_options == myarcs.number_options() assert len(myarcs.capacity) == number_options assert len(myarcs.minimum_cost) == number_options assert isinstance(myarcs.specific_capacity_cost, Real) assert type(myarcs.efficiency) == type(None) assert type(myarcs.efficiency_reverse) == type(None) assert type(myarcs.static_loss) == dict assert len(myarcs.static_loss) != 0 for (h, q, k), sl in myarcs.static_loss.items(): assert isinstance(sl, Real) assert sl >= 0 # redefine the capacity capacity = tuple(myarcs.capacity) myarcs.set_capacity( max_specific_pressure_loss=[ max_specific_pressure_loss + 100 for i in range(number_options) ] ) assert len(capacity) == len(myarcs.capacity) for _c1, _c2 in zip(capacity, myarcs.capacity): assert _c1 != _c2 # redefine the minimum costs min_cost = tuple(myarcs.minimum_cost) myarcs.set_minimum_cost(minimum_cost=[_mc + 1 for _mc in min_cost]) assert len(min_cost) == len(myarcs.minimum_cost) for _mc1, _mc2 in zip(min_cost, myarcs.minimum_cost): assert _mc1 + 1 == _mc2 # try redefining the capacity with a single input (non-list, non-tuple) error_raised = False try: myarcs.set_capacity( max_specific_pressure_loss=max_specific_pressure_loss + 100 ) except TypeError: # vector mode and only one max specific pressure loss value was provided error_raised = True assert error_raised # ********************************************************************* # PipeTrenchOptions myarcs = PipeTrenchOptions(trench=mytrench, name="hellotrench", length=50) number_steps = 3 myarcs.set_static_losses( scenario_key="scenario2", ground_thermal_conductivity=[soil_k for i in range(number_steps)], ground_air_heat_transfer_coefficient=[h_gs for i in range(number_steps)], time_interval_duration=[3600 for i in range(number_steps)], temperature_surroundings=[outdoor_temperature for i in range(number_steps)], ) # ************************************************************************* # ************************************************************************* # ***************************************************************************** # ***************************************************************************** # # test pipe trench objects # def example_pipe_trench_objects(fluid_db, # single_pipe_db, # twin_pipe_db): # #************************************************************************** # #************************************************************************** # # water pipes # list_single_pipe_tuples = [pipe_tuple # for pipe_tuple in single_pipe_db.pipe_tuples] # list_twin_pipe_tuples = [pipe_tuple # for pipe_tuple in twin_pipe_db.pipe_tuples] # list_single_pipes = [ # StandardisedPipe(pipe_tuple=pipe_tuple, # db=single_pipe_db) # for i, pipe_tuple in enumerate(list_single_pipe_tuples) # ] # list_twin_pipes = [ # StandardisedTwinPipe(pipe_tuple=pipe_tuple, # db=twin_pipe_db) # for i, pipe_tuple in enumerate(list_twin_pipe_tuples) # ] # #************************************************************************** # # what does it do? # # >> Creates a distric heating trench object with multiple options # # seed number # seed_number = 249 # rand.seed(seed_number) # # number of intervals # number_intervals = 3 # time_interval_duration = [rand.random() for k in range(number_intervals)] # # network # dhn_supply_temperature = 100+273.15 # K # dhn_return_temperature = 60+273.15 # K # dhn_max_specific_pressure_loss = 100 # Pa # # trench # trench_pipe_depth = 3 # trench_pipe_distance = 2 # # trench_ground_thermal_conductivity = 1.8 # 0.9-2.7 # trench_ground_surface_temperature = [ # 7.8+273.15 for i in range(number_intervals)] # K # trench_ground_air_heat_transfer_coefficient = 14.6 # W/m2 # # pipe details # pipe_length = 1000 # pipe_relative_roughness = 1e-3 # #************************************************************************** # #************************************************************************** # # single pipe trenches # trench_tech = trenches.SupplyReturnPipeTrenchWithIdenticalPipes( # pipes=list_single_pipes, # fluid_database=fluid_db, # ground_thermal_conductivity=trench_ground_thermal_conductivity, # ground_air_heat_transfer_coefficient=trench_ground_air_heat_transfer_coefficient, # pipe_center_depth=trench_pipe_depth, # pipe_center_distance=trench_pipe_distance, # supply_temperature=dhn_supply_temperature, # return_temperature=dhn_return_temperature, # max_specific_pressure_loss=dhn_max_specific_pressure_loss, # time_interval_duration=time_interval_duration, # surroundings_temperature=trench_ground_surface_temperature) # # single pipe, no external cost, no offset # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=None, # validate=True) # original_min_cost = tuple(pipe_trench_obj.minimum_cost) # # single pipe, no external cost, offset # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=tuple( # rand.random() # for pipe in list_single_pipes # ), # validate=True) # for orig_cost, new_cost in zip(original_min_cost, # pipe_trench_obj.minimum_cost): # assert orig_cost <= new_cost # # single pipe, external cost, no offset # external_cost = tuple(0.2+min_cost for min_cost in original_min_cost) # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=external_cost, # minimum_cost_offset=None, # validate=True) # assert external_cost == pipe_trench_obj.minimum_cost # # single pipe, external cost, offset # error_raised = False # try: # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=original_min_cost, # minimum_cost_offset=external_cost, # validate=True) # except TypeError: # error_raised = True # assert error_raised # # use list as minimum cost offset # error_raised = False # try: # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=list( # rand.random() # for pipe in list_single_pipes # ), # validate=True) # except TypeError: # error_raised = True # assert error_raised # #************************************************************************** # #************************************************************************** # # twin pipe trenches # trench_tech = trenches.SupplyReturnPipeTrenchWithIdenticalPipes( # pipes=list_twin_pipes, # fluid_database=fluid_db, # ground_thermal_conductivity=trench_ground_thermal_conductivity, # ground_air_heat_transfer_coefficient=trench_ground_air_heat_transfer_coefficient, # pipe_center_depth=trench_pipe_depth, # pipe_center_distance=trench_pipe_distance, # supply_temperature=dhn_supply_temperature, # return_temperature=dhn_return_temperature, # max_specific_pressure_loss=dhn_max_specific_pressure_loss, # time_interval_duration=time_interval_duration, # surroundings_temperature=trench_ground_surface_temperature) # # single pipe, no external cost, no offset # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=None, # validate=True) # original_min_cost = tuple(pipe_trench_obj.minimum_cost) # # single pipe, no external cost, offset # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=tuple( # rand.random() # for pipe in list_twin_pipes # ), # validate=True) # for orig_cost, new_cost in zip(original_min_cost, # pipe_trench_obj.minimum_cost): # assert orig_cost <= new_cost # # single pipe, external cost, no offset # external_cost = tuple(0.2+min_cost for min_cost in original_min_cost) # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=external_cost, # minimum_cost_offset=None, # validate=True) # assert external_cost == pipe_trench_obj.minimum_cost # # single pipe, external cost, offset # error_raised = False # try: # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=original_min_cost, # minimum_cost_offset=external_cost, # validate=True) # except TypeError: # error_raised = True # assert error_raised # # use list as minimum cost offset # error_raised = False # try: # pipe_trench_obj = PipeTrench(name='hello', # trenches={0: trench_tech}, # length=pipe_length, # use_proportional_losses=True, # use_static_losses=True, # minimum_cost=None, # minimum_cost_offset=list( # rand.random() # for pipe in list_twin_pipes # ), # validate=True) # except TypeError: # error_raised = True # assert error_raised # #************************************************************************** # #************************************************************************** # #****************************************************************************** # #******************************************************************************