Merge branch 'main' into feature/lifecycle_emission_calculation

This commit is contained in:
Guille Gutierrez 2024-10-28 05:45:34 +01:00
commit a9262b42e7
210 changed files with 4965 additions and 1273 deletions

View File

@ -22,6 +22,7 @@ class EilatCatalog(Catalog):
""" """
Eilat catalog class Eilat catalog class
""" """
def __init__(self, path): def __init__(self, path):
_path_archetypes = Path(path / 'eilat_archetypes.json').resolve() _path_archetypes = Path(path / 'eilat_archetypes.json').resolve()
_path_constructions = (path / 'eilat_constructions.json').resolve() _path_constructions = (path / 'eilat_constructions.json').resolve()
@ -121,8 +122,10 @@ class EilatCatalog(Catalog):
construction_period = archetype['period_of_construction'] construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height'] average_storey_height = archetype['average_storey_height']
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges'] extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS infiltration_rate_for_ventilation_system_off = archetype[
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS 'infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype[
'infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
archetype_constructions = [] archetype_constructions = []
for archetype_construction in archetype['constructions']: for archetype_construction in archetype['constructions']:
@ -160,7 +163,9 @@ class EilatCatalog(Catalog):
extra_loses_due_to_thermal_bridges, extra_loses_due_to_thermal_bridges,
None, None,
infiltration_rate_for_ventilation_system_off, infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on)) infiltration_rate_for_ventilation_system_on,
0,
0))
return _catalog_archetypes return _catalog_archetypes
def names(self, category=None): def names(self, category=None):

View File

@ -128,6 +128,12 @@ class NrcanCatalog(Catalog):
infiltration_rate_for_ventilation_system_on = ( infiltration_rate_for_ventilation_system_on = (
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
) )
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
)
archetype_constructions = [] archetype_constructions = []
for archetype_construction in archetype['constructions']: for archetype_construction in archetype['constructions']:
@ -153,7 +159,6 @@ class NrcanCatalog(Catalog):
_window) _window)
archetype_constructions.append(_construction) archetype_constructions.append(_construction)
break break
_catalog_archetypes.append(Archetype(archetype_id, _catalog_archetypes.append(Archetype(archetype_id,
name, name,
function, function,
@ -165,7 +170,10 @@ class NrcanCatalog(Catalog):
extra_loses_due_to_thermal_bridges, extra_loses_due_to_thermal_bridges,
None, None,
infiltration_rate_for_ventilation_system_off, infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on)) infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on
))
return _catalog_archetypes return _catalog_archetypes
def names(self, category=None): def names(self, category=None):

View File

@ -162,7 +162,9 @@ class NrelCatalog(Catalog):
extra_loses_due_to_thermal_bridges, extra_loses_due_to_thermal_bridges,
indirect_heated_ratio, indirect_heated_ratio,
infiltration_rate_for_ventilation_system_off, infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on)) infiltration_rate_for_ventilation_system_on,
0,
0))
return _catalog_archetypes return _catalog_archetypes
def names(self, category=None): def names(self, category=None):

View File

@ -23,7 +23,10 @@ class Archetype:
extra_loses_due_to_thermal_bridges, extra_loses_due_to_thermal_bridges,
indirect_heated_ratio, indirect_heated_ratio,
infiltration_rate_for_ventilation_system_off, infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on): infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on
):
self._id = archetype_id self._id = archetype_id
self._name = name self._name = name
self._function = function self._function = function
@ -36,6 +39,8 @@ class Archetype:
self._indirect_heated_ratio = indirect_heated_ratio self._indirect_heated_ratio = indirect_heated_ratio
self._infiltration_rate_for_ventilation_system_off = infiltration_rate_for_ventilation_system_off self._infiltration_rate_for_ventilation_system_off = infiltration_rate_for_ventilation_system_off
self._infiltration_rate_for_ventilation_system_on = infiltration_rate_for_ventilation_system_on self._infiltration_rate_for_ventilation_system_on = infiltration_rate_for_ventilation_system_on
self._infiltration_rate_area_for_ventilation_system_off = infiltration_rate_area_for_ventilation_system_off
self._infiltration_rate_area_for_ventilation_system_on = infiltration_rate_area_for_ventilation_system_on
@property @property
def id(self): def id(self):
@ -133,6 +138,22 @@ class Archetype:
""" """
return self._infiltration_rate_for_ventilation_system_on return self._infiltration_rate_for_ventilation_system_on
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get archetype infiltration rate for ventilation system off in m3/sm2
:return: float
"""
return self._infiltration_rate_area_for_ventilation_system_off
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get archetype infiltration rate for ventilation system on in m3/sm2
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
def to_dictionary(self): def to_dictionary(self):
"""Class content to dictionary""" """Class content to dictionary"""
_constructions = [] _constructions = []
@ -149,6 +170,8 @@ class Archetype:
'indirect heated ratio': self.indirect_heated_ratio, 'indirect heated ratio': self.indirect_heated_ratio,
'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off, 'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off,
'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on, 'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on,
'infiltration rate area for ventilation off [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_off,
'infiltration rate area for ventilation on [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_on,
'constructions': _constructions 'constructions': _constructions
} }
} }

View File

@ -25,9 +25,11 @@ class NonPvGenerationSystem(GenerationSystem):
maximum_cooling_supply_temperature=None, minimum_cooling_supply_temperature=None, heat_output_curve=None, maximum_cooling_supply_temperature=None, minimum_cooling_supply_temperature=None, heat_output_curve=None,
heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None, heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None,
cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None, cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None,
distribution_systems=None, energy_storage_systems=None, dual_supply_capability=False): distribution_systems=None, energy_storage_systems=None, domestic_hot_water=False,
super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer, fuel_type=fuel_type, reversible=None, simultaneous_heat_cold=None):
distribution_systems=distribution_systems, energy_storage_systems=energy_storage_systems) super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer,
fuel_type=fuel_type, distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
self._system_type = system_type self._system_type = system_type
self._nominal_heat_output = nominal_heat_output self._nominal_heat_output = nominal_heat_output
self._maximum_heat_output = maximum_heat_output self._maximum_heat_output = maximum_heat_output
@ -53,7 +55,9 @@ class NonPvGenerationSystem(GenerationSystem):
self._cooling_output_curve = cooling_output_curve self._cooling_output_curve = cooling_output_curve
self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve
self._cooling_efficiency_curve = cooling_efficiency_curve self._cooling_efficiency_curve = cooling_efficiency_curve
self._dual_supply_capability = dual_supply_capability self._domestic_hot_water = domestic_hot_water
self._reversible = reversible
self._simultaneous_heat_cold = simultaneous_heat_cold
@property @property
def system_type(self): def system_type(self):
@ -256,12 +260,28 @@ class NonPvGenerationSystem(GenerationSystem):
return self._cooling_efficiency_curve return self._cooling_efficiency_curve
@property @property
def dual_supply_capability(self): def domestic_hot_water(self):
""" """
Get dual supply capability Get the ability to produce domestic hot water
:return: bool :return: bool
""" """
return self._dual_supply_capability return self._domestic_hot_water
@property
def reversibility(self):
"""
Get the ability to produce heating and cooling
:return: bool
"""
return self._reversible
@property
def simultaneous_heat_cold(self):
"""
Get the ability to produce heating and cooling at the same time
:return: bool
"""
return self._simultaneous_heat_cold
def to_dictionary(self): def to_dictionary(self):
"""Class content to dictionary""" """Class content to dictionary"""
@ -269,6 +289,18 @@ class NonPvGenerationSystem(GenerationSystem):
self.distribution_systems] if self.distribution_systems is not None else None self.distribution_systems] if self.distribution_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in _energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None self.energy_storage_systems] if self.energy_storage_systems is not None else None
_heat_output_curve = self.heat_output_curve.to_dictionary() if (
self.heat_output_curve is not None) else None
_heat_fuel_consumption_curve = self.heat_fuel_consumption_curve.to_dictionary() if (
self.heat_fuel_consumption_curve is not None) else None
_heat_efficiency_curve = self.heat_efficiency_curve.to_dictionary() if (
self.heat_efficiency_curve is not None) else None
_cooling_output_curve = self.cooling_output_curve.to_dictionary() if (
self.cooling_output_curve is not None) else None
_cooling_fuel_consumption_curve = self.cooling_fuel_consumption_curve.to_dictionary() if (
self.cooling_fuel_consumption_curve is not None) else None
_cooling_efficiency_curve = self.cooling_efficiency_curve.to_dictionary() if (
self.cooling_efficiency_curve is not None) else None
content = { content = {
'Energy Generation component': 'Energy Generation component':
@ -298,13 +330,15 @@ class NonPvGenerationSystem(GenerationSystem):
'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature, 'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature,
'heat output curve': self.heat_output_curve, 'heat output curve': self.heat_output_curve,
'heat fuel consumption curve': self.heat_fuel_consumption_curve, 'heat fuel consumption curve': self.heat_fuel_consumption_curve,
'heat efficiency curve': self.heat_efficiency_curve, 'heat efficiency curve': _heat_efficiency_curve,
'cooling output curve': self.cooling_output_curve, 'cooling output curve': self.cooling_output_curve,
'cooling fuel consumption curve': self.cooling_fuel_consumption_curve, 'cooling fuel consumption curve': self.cooling_fuel_consumption_curve,
'cooling efficiency curve': self.cooling_efficiency_curve, 'cooling efficiency curve': self.cooling_efficiency_curve,
'distribution systems connected': _distribution_systems, 'distribution systems connected': _distribution_systems,
'storage systems connected': _energy_storage_systems, 'storage systems connected': _energy_storage_systems,
'dual supply capability': self.dual_supply_capability 'domestic hot water production capability': self.domestic_hot_water,
'reversible cycle': self.reversibility,
'simultaneous heat and cooling production': self.simultaneous_heat_cold
} }
} }
return content return content

View File

@ -24,13 +24,13 @@ class PerformanceCurves:
def curve_type(self): def curve_type(self):
""" """
The type of the fit function from the following The type of the fit function from the following
Linear =>>> y = a*x + b Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x) Exponential =>>> y = a*(b**x)
Polynomial =>>> y = a*(x**2) + b*x + c Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b) Power =>>> y = a*(x**b)
Second degree multivariable =>>> y = a*(x**2) + b*x + c*x*z + d*z + e*(z**2) + f Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'polynomial', 'power', 'second degree multivariable'] Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string :return: string
""" """
return self._curve_type return self._curve_type

View File

@ -17,7 +17,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None, def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
nominal_capacity=None, losses_ratio=None, volume=None, height=None, layers=None, nominal_capacity=None, losses_ratio=None, volume=None, height=None, layers=None,
maximum_operating_temperature=None, storage_medium=None): maximum_operating_temperature=None, storage_medium=None, heating_coil_capacity=None):
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio) super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
self._type_energy_stored = type_energy_stored self._type_energy_stored = type_energy_stored
@ -27,6 +27,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
self._layers = layers self._layers = layers
self._maximum_operating_temperature = maximum_operating_temperature self._maximum_operating_temperature = maximum_operating_temperature
self._storage_medium = storage_medium self._storage_medium = storage_medium
self._heating_coil_capacity = heating_coil_capacity
@property @property
def type_energy_stored(self): def type_energy_stored(self):
@ -84,6 +85,14 @@ class ThermalStorageSystem(EnergyStorageSystem):
""" """
return self._storage_medium return self._storage_medium
@property
def heating_coil_capacity(self):
"""
Get heating coil capacity in Watts
:return: [material
"""
return self._heating_coil_capacity
def to_dictionary(self): def to_dictionary(self):
"""Class content to dictionary""" """Class content to dictionary"""
_layers = None _layers = None
@ -110,7 +119,8 @@ class ThermalStorageSystem(EnergyStorageSystem):
'height [m]': self.height, 'height [m]': self.height,
'layers': _layers, 'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature, 'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': self.storage_medium.to_dictionary() 'storage_medium': self.storage_medium.to_dictionary(),
'heating coil capacity [W]': self.heating_coil_capacity
} }
} }
return content return content

View File

@ -87,7 +87,7 @@ class MontrealCustomCatalog(Catalog):
cooling_efficiency=cooling_efficiency, cooling_efficiency=cooling_efficiency,
electricity_efficiency=electricity_efficiency, electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems, energy_storage_systems=storage_systems,
dual_supply_capability=False domestic_hot_water=False
) )
_equipments.append(generation_system) _equipments.append(generation_system)
@ -111,10 +111,7 @@ class MontrealCustomCatalog(Catalog):
distribution_consumption_variable_flow = float( distribution_consumption_variable_flow = float(
equipment['distribution_consumption_variable_flow']['#text']) / 100 equipment['distribution_consumption_variable_flow']['#text']) / 100
emission_equipment = -1 emission_equipment = equipment['dissipation_id']
if 'dissipation_id' in equipment:
emission_equipment = equipment['dissipation_id']
_emission_equipments = None _emission_equipments = None
for equipment_archetype in self._catalog_emission_equipments: for equipment_archetype in self._catalog_emission_equipments:
if int(equipment_archetype.id) == int(emission_equipment): if int(equipment_archetype.id) == int(emission_equipment):

View File

@ -121,13 +121,26 @@ class MontrealFutureSystemCatalogue(Catalog):
parameters = non_pv['cooling_efficiency_curve']['parameters'] parameters = non_pv['cooling_efficiency_curve']['parameters']
coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values()) coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values())
cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients) cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
dual_supply_capability = None dhw = None
if non_pv['dual_supply_capability'] is not None: if non_pv['domestic_hot_water'] is not None:
if non_pv['dual_supply_capability'] == 'True': if non_pv['domestic_hot_water'] == 'True':
dual_supply_capability = True dhw = True
else: else:
dual_supply_capability = False dhw = False
reversible = None
if non_pv['reversible'] is not None:
if non_pv['reversible'] == 'True':
reversible = True
else:
reversible = False
dual_supply = None
if non_pv['simultaneous_heat_cold'] is not None:
if non_pv['simultaneous_heat_cold'] == 'True':
dual_supply = True
else:
dual_supply = False
non_pv_component = NonPvGenerationSystem(system_id=system_id, non_pv_component = NonPvGenerationSystem(system_id=system_id,
name=name, name=name,
system_type=system_type, system_type=system_type,
@ -160,7 +173,9 @@ class MontrealFutureSystemCatalogue(Catalog):
cooling_efficiency_curve=cooling_efficiency_curve, cooling_efficiency_curve=cooling_efficiency_curve,
distribution_systems=distribution_systems, distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems, energy_storage_systems=energy_storage_systems,
dual_supply_capability=dual_supply_capability) domestic_hot_water=dhw,
reversible=reversible,
simultaneous_heat_cold=dual_supply)
generation_components.append(non_pv_component) generation_components.append(non_pv_component)
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][ pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
'pv_generation_component'] 'pv_generation_component']
@ -187,7 +202,6 @@ class MontrealFutureSystemCatalogue(Catalog):
storage_component = pv['energy_storage_systems']['storage_id'] storage_component = pv['energy_storage_systems']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component) storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_systems = storage_systems energy_storage_systems = storage_systems
pv_component = PvGenerationSystem(system_id=system_id, pv_component = PvGenerationSystem(system_id=system_id,
name=name, name=name,
system_type=system_type, system_type=system_type,
@ -284,6 +298,7 @@ class MontrealFutureSystemCatalogue(Catalog):
layers = [insulation_layer, tank_layer] layers = [insulation_layer, tank_layer]
nominal_capacity = tes['nominal_capacity'] nominal_capacity = tes['nominal_capacity']
losses_ratio = tes['losses_ratio'] losses_ratio = tes['losses_ratio']
heating_coil_capacity = tes['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id, storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name, model_name=model_name,
type_energy_stored=type_energy_stored, type_energy_stored=type_energy_stored,
@ -295,7 +310,8 @@ class MontrealFutureSystemCatalogue(Catalog):
height=height, height=height,
layers=layers, layers=layers,
maximum_operating_temperature=maximum_operating_temperature, maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium) storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component) storage_components.append(storage_component)
for template in template_storages: for template in template_storages:
@ -303,7 +319,7 @@ class MontrealFutureSystemCatalogue(Catalog):
storage_type = template['storage_type'] storage_type = template['storage_type']
type_energy_stored = template['type_energy_stored'] type_energy_stored = template['type_energy_stored']
maximum_operating_temperature = template['maximum_operating_temperature'] maximum_operating_temperature = template['maximum_operating_temperature']
height = template['physical_characteristics']['height'] height = float(template['physical_characteristics']['height'])
materials = self._load_materials() materials = self._load_materials()
insulation_material_id = template['insulation']['material_id'] insulation_material_id = template['insulation']['material_id']
insulation_material = self._search_material(materials, insulation_material_id) insulation_material = self._search_material(materials, insulation_material_id)
@ -322,6 +338,7 @@ class MontrealFutureSystemCatalogue(Catalog):
nominal_capacity = template['nominal_capacity'] nominal_capacity = template['nominal_capacity']
losses_ratio = template['losses_ratio'] losses_ratio = template['losses_ratio']
volume = template['physical_characteristics']['volume'] volume = template['physical_characteristics']['volume']
heating_coil_capacity = template['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id, storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name, model_name=model_name,
type_energy_stored=type_energy_stored, type_energy_stored=type_energy_stored,
@ -333,7 +350,8 @@ class MontrealFutureSystemCatalogue(Catalog):
height=height, height=height,
layers=layers, layers=layers,
maximum_operating_temperature=maximum_operating_temperature, maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium) storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component) storage_components.append(storage_component)
return storage_components return storage_components

View File

@ -90,7 +90,9 @@ class Building(CityObject):
self._interior_slabs.append(surface) self._interior_slabs.append(surface)
else: else:
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type) logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
self._heating_consumption_disaggregated = {} self._domestic_hot_water_peak_load = None
self._fuel_consumption_breakdown = {}
self._pv_generation = {}
@property @property
def shell(self) -> Polyhedron: def shell(self) -> Polyhedron:
@ -449,8 +451,8 @@ class Building(CityObject):
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
if monthly_values is None: if monthly_values is None:
return None return None
results[cte.MONTH] = monthly_values results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)] results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
return results return results
@property @property
@ -466,8 +468,24 @@ class Building(CityObject):
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
if monthly_values is None: if monthly_values is None:
return None return None
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values] results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)] results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
return results
@property
def domestic_hot_water_peak_load(self) -> Union[None, dict]:
"""
Get cooling peak load in W
:return: dict{[float]}
"""
results = {}
monthly_values = None
if cte.HOUR in self.domestic_hot_water_heat_demand:
monthly_values = PeakLoads().peak_loads_from_hourly(self.domestic_hot_water_heat_demand[cte.HOUR])
if monthly_values is None:
return None
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
return results return results
@property @property
@ -825,23 +843,6 @@ class Building(CityObject):
self._onsite_electrical_production[_key] = _results self._onsite_electrical_production[_key] = _results
return self._onsite_electrical_production return self._onsite_electrical_production
@property
def heating_consumption_disaggregated(self) -> dict:
"""
Get energy consumed for heating from different fuels in J
return: dict
"""
return self._heating_consumption_disaggregated
@heating_consumption_disaggregated.setter
def heating_consumption_disaggregated(self, value):
"""
Get energy consumed for heating from different fuels in J
return: dict
"""
self._heating_consumption_disaggregated = value
@property @property
def lower_corner(self): def lower_corner(self):
""" """
@ -855,3 +856,60 @@ class Building(CityObject):
Get building upper corner. Get building upper corner.
""" """
return [self._max_x, self._max_y, self._max_z] return [self._max_x, self._max_y, self._max_z]
@property
def energy_consumption_breakdown(self) -> dict:
"""
Get energy consumption of different sectors
return: dict
"""
fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0],
cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0]}}
energy_systems = self.energy_systems
for energy_system in energy_systems:
demand_types = energy_system.demand_types
generation_systems = energy_system.generation_systems
for demand_type in demand_types:
for generation_system in generation_systems:
if generation_system.system_type != cte.PHOTOVOLTAIC:
if generation_system.fuel_type not in fuel_breakdown:
fuel_breakdown[generation_system.fuel_type] = {}
if demand_type in generation_system.energy_consumption:
fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = (
generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0]
storage_systems = generation_system.energy_storage_systems
if storage_systems:
for storage_system in storage_systems:
if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_energy_consumption:
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += storage_system.heating_coil_energy_consumption[cte.YEAR][0]
#TODO: When simulation models of all energy system archetypes are created, this part can be removed
heating_fuels = []
dhw_fuels = []
for energy_system in self.energy_systems:
if cte.HEATING in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
heating_fuels.append(generation_system.fuel_type)
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
dhw_fuels.append(generation_system.fuel_type)
for key in fuel_breakdown:
if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]:
for energy_system in energy_systems:
if cte.COOLING in energy_system.demand_types and cte.COOLING not in fuel_breakdown[key]:
for generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0]
for fuel in heating_fuels:
if cte.HEATING not in fuel_breakdown[fuel]:
for energy_system in energy_systems:
if cte.HEATING in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0]
for fuel in dhw_fuels:
if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[fuel]:
for energy_system in energy_systems:
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0]
self._fuel_consumption_breakdown = fuel_breakdown
return self._fuel_consumption_breakdown

View File

@ -132,6 +132,8 @@ class InternalZone:
_thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas) _thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas)
surface.associated_thermal_boundaries = [_thermal_boundary] surface.associated_thermal_boundaries = [_thermal_boundary]
_thermal_boundaries.append(_thermal_boundary) _thermal_boundaries.append(_thermal_boundary)
if self.thermal_archetype is None:
return None # there are no archetype
_number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height) _number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height)
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys) _thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys)
for thermal_boundary in _thermal_zone.thermal_boundaries: for thermal_boundary in _thermal_zone.thermal_boundaries:

View File

@ -42,10 +42,12 @@ class Surface:
self._short_wave_reflectance = None self._short_wave_reflectance = None
self._long_wave_emittance = None self._long_wave_emittance = None
self._inverse = None self._inverse = None
self._associated_thermal_boundaries = [] self._associated_thermal_boundaries = None
self._vegetation = None self._vegetation = None
self._percentage_shared = None self._percentage_shared = None
self._solar_collectors_area_reduction_factor = None self._solar_collectors_area_reduction_factor = None
self._global_irradiance_tilted = {}
self._installed_solar_collector_area = None
@property @property
def name(self): def name(self):
@ -178,7 +180,7 @@ class Surface:
@property @property
def global_irradiance(self) -> dict: def global_irradiance(self) -> dict:
""" """
Get global irradiance on surface in J/m2 Get global irradiance on surface in W/m2
:return: dict :return: dict
""" """
return self._global_irradiance return self._global_irradiance
@ -186,7 +188,7 @@ class Surface:
@global_irradiance.setter @global_irradiance.setter
def global_irradiance(self, value): def global_irradiance(self, value):
""" """
Set global irradiance on surface in J/m2 Set global irradiance on surface in W/m2
:param value: dict :param value: dict
""" """
self._global_irradiance = value self._global_irradiance = value
@ -384,3 +386,35 @@ class Surface:
:param value: float :param value: float
""" """
self._solar_collectors_area_reduction_factor = value self._solar_collectors_area_reduction_factor = value
@property
def global_irradiance_tilted(self) -> dict:
"""
Get global irradiance on a tilted surface in W/m2
:return: dict
"""
return self._global_irradiance_tilted
@global_irradiance_tilted.setter
def global_irradiance_tilted(self, value):
"""
Set global irradiance on a tilted surface in W/m2
:param value: dict
"""
self._global_irradiance_tilted = value
@property
def installed_solar_collector_area(self):
"""
Get installed solar collector area in m2
:return: dict
"""
return self._installed_solar_collector_area
@installed_solar_collector_area.setter
def installed_solar_collector_area(self, value):
"""
Set installed solar collector area in m2
:return: dict
"""
self._installed_solar_collector_area = value

View File

@ -20,6 +20,8 @@ class ThermalArchetype:
self._indirect_heated_ratio = None self._indirect_heated_ratio = None
self._infiltration_rate_for_ventilation_system_off = None self._infiltration_rate_for_ventilation_system_off = None
self._infiltration_rate_for_ventilation_system_on = None self._infiltration_rate_for_ventilation_system_on = None
self._infiltration_rate_area_for_ventilation_system_off=None
self._infiltration_rate_area_for_ventilation_system_on=None
@property @property
def constructions(self) -> [Construction]: def constructions(self) -> [Construction]:
@ -132,3 +134,35 @@ class ThermalArchetype:
:param value: float :param value: float
""" """
self._infiltration_rate_for_ventilation_system_on = value self._infiltration_rate_for_ventilation_system_on = value
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get infiltration rate for ventilation system off in l/s/m2
:return: float
"""
return self._infiltration_rate_for_ventilation_system_off
@infiltration_rate_area_for_ventilation_system_off.setter
def infiltration_rate_area_for_ventilation_system_off(self, value):
"""
Set infiltration rate for ventilation system off in l/s/m2
:param value: float
"""
self._infiltration_rate_for_ventilation_system_off = value
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get infiltration rate for ventilation system on in l/s/m2
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
@infiltration_rate_area_for_ventilation_system_on.setter
def infiltration_rate_area_for_ventilation_system_on(self, value):
"""
Set infiltration rate for ventilation system on in l/s/m2
:param value: float
"""
self._infiltration_rate_for_ventilation_system_on = value

View File

@ -44,6 +44,8 @@ class ThermalZone:
self._indirectly_heated_area_ratio = None self._indirectly_heated_area_ratio = None
self._infiltration_rate_system_on = None self._infiltration_rate_system_on = None
self._infiltration_rate_system_off = None self._infiltration_rate_system_off = None
self._infiltration_rate_area_system_on = None
self._infiltration_rate_area_system_off = None
self._volume = volume self._volume = volume
self._ordinate_number = None self._ordinate_number = None
self._view_factors_matrix = None self._view_factors_matrix = None
@ -166,6 +168,24 @@ class ThermalZone:
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
return self._infiltration_rate_system_off return self._infiltration_rate_system_off
@property
def infiltration_rate_area_system_on(self):
"""
Get thermal zone infiltration rate system on in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_on
return self._infiltration_rate_area_system_on
@property
def infiltration_rate_area_system_off(self):
"""
Get thermal zone infiltration rate system off in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_off
return self._infiltration_rate_area_system_off
@property @property
def volume(self): def volume(self):
""" """

View File

@ -41,9 +41,10 @@ class CityObject:
self._ground_temperature = {} self._ground_temperature = {}
self._global_horizontal = {} self._global_horizontal = {}
self._diffuse = {} self._diffuse = {}
self._beam = {} self._direct_normal = {}
self._sensors = [] self._sensors = []
self._neighbours = None self._neighbours = None
self._beam = {}
@property @property
def level_of_detail(self) -> LevelOfDetail: def level_of_detail(self) -> LevelOfDetail:
@ -238,20 +239,20 @@ class CityObject:
self._diffuse = value self._diffuse = value
@property @property
def beam(self) -> dict: def direct_normal(self) -> dict:
""" """
Get beam radiation surrounding the city object in J/m2 Get beam radiation surrounding the city object in J/m2
:return: dict{dict{[float]}} :return: dict{dict{[float]}}
""" """
return self._beam return self._direct_normal
@beam.setter @direct_normal.setter
def beam(self, value): def direct_normal(self, value):
""" """
Set beam radiation surrounding the city object in J/m2 Set beam radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}} :param value: dict{dict{[float]}}
""" """
self._beam = value self._direct_normal = value
@property @property
def lower_corner(self): def lower_corner(self):
@ -302,3 +303,19 @@ class CityObject:
Set the list of neighbour_objects and their properties associated to the current city_object Set the list of neighbour_objects and their properties associated to the current city_object
""" """
self._neighbours = value self._neighbours = value
@property
def beam(self) -> dict:
"""
Get beam radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._beam
@beam.setter
def beam(self, value):
"""
Set beam radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._beam = value

View File

@ -11,7 +11,8 @@ from abc import ABC
from typing import Union, List from typing import Union, List
from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem
from hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem from hub.city_model_structure.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.city_model_structure.energy_systems.electrical_storage_system import ElectricalStorageSystem
class GenerationSystem(ABC): class GenerationSystem(ABC):
@ -26,6 +27,7 @@ class GenerationSystem(ABC):
self._fuel_type = None self._fuel_type = None
self._distribution_systems = None self._distribution_systems = None
self._energy_storage_systems = None self._energy_storage_systems = None
self._number_of_units = None
@property @property
def system_type(self): def system_type(self):
@ -124,7 +126,7 @@ class GenerationSystem(ABC):
self._distribution_systems = value self._distribution_systems = value
@property @property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]: def energy_storage_systems(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]:
""" """
Get energy storage systems connected to this generation system Get energy storage systems connected to this generation system
:return: [EnergyStorageSystem] :return: [EnergyStorageSystem]
@ -138,3 +140,19 @@ class GenerationSystem(ABC):
:param value: [EnergyStorageSystem] :param value: [EnergyStorageSystem]
""" """
self._energy_storage_systems = value self._energy_storage_systems = value
@property
def number_of_units(self):
"""
Get number of a specific generation unit
:return: int
"""
return self._number_of_units
@number_of_units.setter
def number_of_units(self, value):
"""
Set number of a specific generation unit
:return: int
"""
self._number_of_units = value

Some files were not shown because too many files have changed in this diff Show More