diff --git a/hub/catalog_factories/data_models/usages/thermal_control.py b/hub/catalog_factories/data_models/usages/thermal_control.py index 1060e7fa..113f4190 100644 --- a/hub/catalog_factories/data_models/usages/thermal_control.py +++ b/hub/catalog_factories/data_models/usages/thermal_control.py @@ -19,7 +19,7 @@ class ThermalControl: heating_set_point_schedules, cooling_set_point_schedules): #todo: eliminate negative value - deltaTsetpoint=-1 + deltaTsetpoint=0 self._mean_heating_set_point = mean_heating_set_point self._heating_set_back = heating_set_back self._mean_cooling_set_point = mean_cooling_set_point diff --git a/hub/city_model_structure/building_demand/thermal_zone.py b/hub/city_model_structure/building_demand/thermal_zone.py index 65b40b29..8c8cb13c 100644 --- a/hub/city_model_structure/building_demand/thermal_zone.py +++ b/hub/city_model_structure/building_demand/thermal_zone.py @@ -603,7 +603,8 @@ class ThermalZone: _mean_peak_flow = 0 _mean_service_temperature = 0 for usage in self.usages: - _mean_peak_density_load += usage.percentage * usage.domestic_hot_water.density + # todo: change hardcoded density DHW + _mean_peak_density_load += usage.percentage * 1 #usage.domestic_hot_water.density _mean_peak_flow += usage.percentage * usage.domestic_hot_water.peak_flow _mean_service_temperature += usage.percentage * usage.domestic_hot_water.service_temperature self._domestic_hot_water.density = _mean_peak_density_load @@ -630,6 +631,7 @@ class ThermalZone: schedule.values = new_values _schedules.append(schedule) self._domestic_hot_water.schedules = _schedules + return self._domestic_hot_water @property diff --git a/hub/exports/building_energy/idf.py b/hub/exports/building_energy/idf.py index 38ea197a..64a04050 100644 --- a/hub/exports/building_energy/idf.py +++ b/hub/exports/building_energy/idf.py @@ -23,6 +23,7 @@ class Idf: _LIGHTS = 'LIGHTS' _APPLIANCES = 'OTHEREQUIPMENT' _PEOPLE = 'PEOPLE' + _DHW = 'WATERUSE:EQUIPMENT' _THERMOSTAT = 'HVACTEMPLATE:THERMOSTAT' _IDEAL_LOAD_AIR_SYSTEM = 'HVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM' _SURFACE = 'BUILDINGSURFACE:DETAILED' @@ -247,6 +248,28 @@ class Idf: return return self._add_standard_compact_hourly_schedule(usage, schedule_type, new_schedules) + def _add_servicetemp_schedules(self, thermal_zone): + #todo: clean Domestic Hot Water + _schedule = Schedule() + _schedule.type = cte.DOMESTIC_HOT_WATER + _schedule.data_type = cte.TEMPERATURE + _schedule.time_step = cte.HOUR + _schedule.time_range = cte.DAY + #_schedule.day_types = copy.deepcopy(hvac_availability_schedule.day_types) + _servicetemp_values = [] + for schedule_value in thermal_zone._domestic_hot_water.schedules: + if schedule_value == 0: + _servicetemp_values.append(60) + else: + _servicetemp_values.append(60) + _schedule.values = _servicetemp_values + _servicetemp_values.append(_schedule) + for schedule in self._idf.idfobjects[self._HOURLY_SCHEDULE]: + if schedule.Name == f'DHW_temp schedules {thermal_zone.usage_name}': + return + return self._add_standard_compact_hourly_schedule(thermal_zone.usage_name, 'DHW_temp', _servicetemp_values) + + def _add_construction(self, thermal_boundary): for construction in self._idf.idfobjects[self._CONSTRUCTION]: if thermal_boundary.parent_surface.vegetation is not None: @@ -371,8 +394,6 @@ class Idf: method = 'Watts/Area' factor_size = thermal_zone.total_floor_area / thermal_zone.footprint_area watts_per_zone_floor_area = thermal_zone.appliances.density*factor_size - print(thermal_zone.appliances.density) - print(watts_per_zone_floor_area) subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#InteriorEquipment' # _object = self._idf.newidfobject(self._APPLIANCES) # print(vars(_object)) @@ -404,7 +425,23 @@ class Idf: Design_Flow_Rate_Calculation_Method='AirChanges/Hour', Air_Changes_per_Hour=thermal_zone.infiltration_rate_system_off*factorreduct ) - + def _add_DHW(self, thermal_zone, zone_name): + fuel_type = 'Electricity' + method = 'Watts/Area' + factor_size = thermal_zone.total_floor_area / thermal_zone.footprint_area + peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow*factor_size + #_object = self._idf.newidfobject(self._DHW) + #print(vars(_object)) + self._idf.newidfobject(self._DHW, + Name=f'{zone_name}_DHW', + Zone_or_ZoneList_Name=zone_name, + Schedule_Name=f'DHW {thermal_zone.usage_name}', + Peak_flow_rate=peak_flow_rate, + Flow_Rate_Fraction_Schedule_Name=f'DHW_prof {thermal_zone.usage_name}', + Target_Temperature_Schedule_Name=f'DHW_temp {thermal_zone.usage_name}', + Cold_Water_Supply_Temperature_Schedule_Name=f'CW_temp {thermal_zone.usage_name}', + EndUse_Subcategory=f'DHW {thermal_zone.usage_name}' + ) def _rename_building(self, city_name): name = str(str(city_name.encode("utf-8"))) for building in self._idf.idfobjects[self._BUILDING]: @@ -453,6 +490,9 @@ class Idf: self._add_schedules(usage, 'Cooling thermostat', thermal_zone.thermal_control.cooling_set_point_schedules) self._add_schedules(usage, 'Lighting', thermal_zone.lighting.schedules) self._add_schedules(usage, 'Appliance', thermal_zone.appliances.schedules) + self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules) + self._add_servicetemp_schedules(thermal_zone) + self._add_schedules(usage, 'CW_temp', building.cold_water_temperature.hour) self._add_people_activity_level_schedules(thermal_zone) @@ -462,6 +502,7 @@ class Idf: self._add_occupancy(thermal_zone, building.name) self._add_lighting(thermal_zone, building.name) self._add_appliances(thermal_zone, building.name) + self._add_DHW(thermal_zone, building.name) if self._export_type == "Surfaces": if building.name in self._target_buildings or building.name in self._adjacent_buildings: diff --git a/hub/exports/building_energy/idf_files/Minimal.idf b/hub/exports/building_energy/idf_files/Minimal.idf index 4152f476..f720b702 100644 --- a/hub/exports/building_energy/idf_files/Minimal.idf +++ b/hub/exports/building_energy/idf_files/Minimal.idf @@ -148,7 +148,6 @@ OutputControl:Table:Style, CommaAndHTML,JtoKWH; - Output:Meter,Electricity:Facility,monthly; Output:Meter,DISTRICTHEATING:Facility,monthly; Output:Meter,DISTRICTCOOLING:Facility,monthly; Output:Meter,InteriorEquipment:Electricity,monthly; diff --git a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py index 8f0800ee..6b07179a 100644 --- a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py +++ b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py @@ -123,9 +123,9 @@ class InselMonthlyEnergyBalance(Insel): for ig in usage.internal_gains: total_internal_gain += ig.average_internal_gain * (ig.convective_fraction + ig.radiative_fraction) parameters.append(f'{total_internal_gain} % BP(12) #2 Internal gains of zone {i + 1}') - parameters.append(f'{usage.thermal_control.mean_heating_set_point+1} % BP(13) #3 Heating setpoint temperature ' + parameters.append(f'{usage.thermal_control.mean_heating_set_point} % BP(13) #3 Heating setpoint temperature ' f'zone {i + 1} (degree Celsius)') - parameters.append(f'{usage.thermal_control.heating_set_back+1} % BP(14) #4 Heating setback temperature ' + parameters.append(f'{usage.thermal_control.heating_set_back} % BP(14) #4 Heating setback temperature ' f'zone {i + 1} (degree Celsius)') parameters.append(f'{usage.thermal_control.mean_cooling_set_point+4} % BP(15) #5 Cooling setpoint temperature ' f'zone {i + 1} (degree Celsius)') @@ -153,8 +153,8 @@ class InselMonthlyEnergyBalance(Insel): for day_type in schedule.day_types: infiltration += infiltration_day * cte.DAYS_A_YEAR[day_type] / 365 ventilation += ventilation_day * cte.DAYS_A_YEAR[day_type] / 365 - - ventilation_infiltration = ventilation + infiltration + #todo: eliminate hardcoded coefficient to ventilationinf + ventilation_infiltration = (ventilation + infiltration)*0.5 parameters.append(f'{ventilation_infiltration} % BP(18) #8 Minimum air change rate zone {i + 1} (ACH)') parameters.append(f'{len(thermal_zone.thermal_boundaries)} % Number of surfaces = BP(11+8z) \n'