def calc_thermal_loads(building_name, bpr, weather_data, usage_schedules, date, gv, locator, use_stochastic_occupancy, use_dynamic_infiltration_calculation, resolution_outputs, loads_output, massflows_output, temperatures_output, format_output, region): """ Calculate thermal loads of a single building with mechanical or natural ventilation. Calculation procedure follows the methodology of ISO 13790 The structure of ``usage_schedules`` is: .. code-block:: python :emphasize-lines: 2,4 { 'list_uses': ['ADMIN', 'GYM', ...], 'schedules': [ ([...], [...], [...], [...]), (), (), () ] } * each element of the 'list_uses' entry represents a building occupancy type. * each element of the 'schedules' entry represents the schedules for a building occupancy type. * the schedules for a building occupancy type are a 4-tuple (occupancy, electricity, domestic hot water, probability of use), with each element of the 4-tuple being a list of hourly values (8760 values). Side effect include a number of files in two folders: * ``scenario/outputs/data/demand`` * ``${Name}.csv`` for each building * temporary folder (as returned by ``tempfile.gettempdir()``) * ``${Name}T.csv`` for each building daren-thomas: as far as I can tell, these are the only side-effects. :param building_name: name of building :type building_name: str :param bpr: a collection of building properties for the building used for thermal loads calculation :type bpr: BuildingPropertiesRow :param weather_data: data from the .epw weather file. Each row represents an hour of the year. The columns are: ``drybulb_C``, ``relhum_percent``, and ``windspd_ms`` :type weather_data: pandas.DataFrame :param usage_schedules: dict containing schedules and function names of buildings. :type usage_schedules: dict :param date: the dates (hours) of the year (8760) :type date: pandas.tseries.index.DatetimeIndex :param gv: global variables / context :type gv: GlobalVariables :param locator: :param use_dynamic_infiltration_calculation: :returns: This function does not return anything :rtype: NoneType """ schedules, tsd = initialize_inputs(bpr, usage_schedules, weather_data, use_stochastic_occupancy) # CALCULATE ELECTRICITY LOADS tsd = electrical_loads.calc_Eal_Epro(tsd, bpr, schedules) # CALCULATE REFRIGERATION LOADS if refrigeration_loads.has_refrigeration_load(bpr): tsd = refrigeration_loads.calc_Qcre_sys(bpr, tsd, schedules) tsd = refrigeration_loads.calc_Qref(locator, bpr, tsd, region) else: tsd['DC_cre'] = tsd['Qcre_sys'] = tsd['Qcre'] = np.zeros(8760) tsd['mcpcre_sys'] = tsd['Tcre_sys_re'] = tsd[ 'Tcre_sys_sup'] = np.zeros(8760) tsd['E_cre'] = np.zeros(8760) if np.isclose(bpr.rc_model['Af'], 0.0): # if building does not have conditioned area #UPDATE ALL VALUES TO 0 tsd = update_timestep_data_no_conditioned_area(tsd) else: #CALCULATE PROCESS HEATING tsd['Qhpro_sys'][:] = schedules['Qhpro'] * bpr.internal_loads[ 'Qhpro_Wm2'] # in kWh # CALCULATE DATA CENTER LOADS if datacenter_loads.has_data_load(bpr): tsd = datacenter_loads.calc_Edata(bpr, tsd, schedules) # end-use electricity tsd = datacenter_loads.calc_Qcdata_sys( tsd) # system need for cooling tsd = datacenter_loads.calc_Qcdataf( locator, bpr, tsd, region) # final need for cooling else: tsd['DC_cdata'] = tsd['Qcdata_sys'] = tsd['Qcdata'] = np.zeros( 8760) tsd['mcpcdata_sys'] = tsd['Tcdata_sys_re'] = tsd[ 'Tcdata_sys_sup'] = np.zeros(8760) tsd['Edata'] = tsd['E_cdata'] = np.zeros(8760) #CALCULATE HEATING AND COOLING DEMAND tsd = calc_Qhs_Qcs( bpr, date, tsd, use_dynamic_infiltration_calculation, region) #end-use demand latent and sensible + ventilation tsd = sensible_loads.calc_Qhs_Qcs_loss(bpr, tsd) # losses tsd = sensible_loads.calc_Qhs_sys_Qcs_sys(tsd) # system (incl. losses) tsd = sensible_loads.calc_temperatures_emission_systems( bpr, tsd) # calculate temperatures tsd = electrical_loads.calc_Eauxf_ve( tsd) #calc auxiliary loads ventilation tsd = electrical_loads.calc_Eaux_Qhs_Qcs( tsd, bpr) #calc auxiliary loads heating and cooling #SOME TRICKS FOR THE GRAPHS - see where to put this. tsd = latent_loads.calc_latent_gains_from_people(tsd, bpr) tsd['Qcs_lat_sys'] = abs(tsd['Qcs_lat_sys']) tsd['DC_cs'] = abs(tsd['DC_cs']) tsd['Qcs_sys'] = abs(tsd['Qcs_sys']) tsd = calc_Qcs_sys(bpr, tsd) # final : including fuels and renewables tsd = calc_Qhs_sys(bpr, tsd) # final : including fuels and renewables #CALCULATE HOT WATER LOADS if hotwater_loads.has_hot_water_technical_system(bpr): tsd = electrical_loads.calc_Eaux_fw(tsd, bpr, schedules) tsd = hotwater_loads.calc_Qww(bpr, tsd, schedules) # end-use tsd = hotwater_loads.calc_Qww_sys(bpr, tsd, gv) # system (incl. losses) tsd = electrical_loads.calc_Eaux_ww(tsd, bpr) #calc auxiliary loads tsd = hotwater_loads.calc_Qwwf(bpr, tsd) #final else: tsd = electrical_loads.calc_Eaux_fw(tsd, bpr, schedules) tsd['Qww'] = tsd['DH_ww'] = tsd['Qww_sys'] = np.zeros(8760) tsd['mcpww_sys'] = tsd['Tww_sys_re'] = tsd[ 'Tww_sys_sup'] = np.zeros(8760) tsd['Eaux_ww'] = tsd['SOLAR_ww'] = np.zeros(8760) tsd['NG_ww'] = tsd['COAL_ww'] = tsd['OIL_ww'] = tsd[ 'WOOD_ww'] = np.zeros(8760) tsd['E_ww'] = np.zeros(8760) # CALCULATE SUM OF HEATING AND COOLING LOADS tsd = calc_QH_sys_QC_sys(tsd) # aggregated cooling and heating loads #CALCULATE ELECTRICITY LOADS PART 2/2 AUXILIARY LOADS + ENERGY GENERATION tsd = electrical_loads.calc_Eaux(tsd) # auxiliary totals tsd = electrical_loads.calc_E_sys(tsd) # system (incl. losses) tsd = electrical_loads.calc_Ef(bpr, tsd) # final (incl. self. generated) #WRITE SOLAR RESULTS write_results(bpr, building_name, date, format_output, gv, loads_output, locator, massflows_output, resolution_outputs, temperatures_output, tsd) return
def calc_thermal_loads(building_name, bpr, weather_data, date_range, locator, use_dynamic_infiltration_calculation, resolution_outputs, loads_output, massflows_output, temperatures_output, config, debug): """ Calculate thermal loads of a single building with mechanical or natural ventilation. Calculation procedure follows the methodology of ISO 13790 The structure of ``usage_schedules`` is: .. code-block:: python :emphasize-lines: 2,4 { 'list_uses': ['ADMIN', 'GYM', ...], 'schedules': [ ([...], [...], [...], [...]), (), (), () ] } * each element of the 'list_uses' entry represents a building occupancy type. * each element of the 'schedules' entry represents the schedules for a building occupancy type. * the schedules for a building occupancy type are a 4-tuple (occupancy, electricity, domestic hot water, probability of use), with each element of the 4-tuple being a list of hourly values (HOURS_IN_YEAR values). Side effect include a number of files in two folders: * ``scenario/outputs/data/demand`` * ``${Name}.csv`` for each building * temporary folder (as returned by ``tempfile.gettempdir()``) * ``${Name}T.csv`` for each building daren-thomas: as far as I can tell, these are the only side-effects. :param building_name: name of building :type building_name: str :param bpr: a collection of building properties for the building used for thermal loads calculation :type bpr: BuildingPropertiesRow :param weather_data: data from the .epw weather file. Each row represents an hour of the year. The columns are: ``drybulb_C``, ``relhum_percent``, and ``windspd_ms`` :type weather_data: pandas.DataFrame :param locator: :param use_dynamic_infiltration_calculation: :returns: This function does not return anything :rtype: NoneType """ schedules, tsd = initialize_inputs(bpr, weather_data, locator) # CALCULATE ELECTRICITY LOADS tsd = electrical_loads.calc_Eal_Epro(tsd, schedules) # CALCULATE REFRIGERATION LOADS if refrigeration_loads.has_refrigeration_load(bpr): tsd = refrigeration_loads.calc_Qcre_sys(bpr, tsd, schedules) tsd = refrigeration_loads.calc_Qref(locator, bpr, tsd) else: tsd['DC_cre'] = tsd['Qcre_sys'] = tsd['Qcre'] = np.zeros(HOURS_IN_YEAR) tsd['mcpcre_sys'] = tsd['Tcre_sys_re'] = tsd[ 'Tcre_sys_sup'] = np.zeros(HOURS_IN_YEAR) tsd['E_cre'] = np.zeros(HOURS_IN_YEAR) if np.isclose(bpr.rc_model['Af'], 0.0): # if building does not have conditioned area tsd['T_int'] = tsd['T_ext'] tsd['x_int'] = np.vectorize(convert_rh_to_moisture_content)( tsd['rh_ext'], tsd['T_int']) print("building () does not have an air-conditioned area".format( bpr.name)) else: # CALCULATE PROCESS HEATING tsd['Qhpro_sys'] = schedules['Qhpro_W'] # in Wh # CALCULATE PROCESS COOLING tsd['Qcpro_sys'] = schedules['Qcpro_W'] # in Wh # CALCULATE DATA CENTER LOADS if datacenter_loads.has_data_load(bpr): tsd = datacenter_loads.calc_Edata(tsd, schedules) # end-use electricity tsd = datacenter_loads.calc_Qcdata_sys( bpr, tsd) # system need for cooling tsd = datacenter_loads.calc_Qcdataf(locator, bpr, tsd) # final need for cooling else: tsd['DC_cdata'] = tsd['Qcdata_sys'] = tsd['Qcdata'] = np.zeros( HOURS_IN_YEAR) tsd['mcpcdata_sys'] = tsd['Tcdata_sys_re'] = tsd[ 'Tcdata_sys_sup'] = np.zeros(HOURS_IN_YEAR) tsd['Edata'] = tsd['E_cdata'] = np.zeros(HOURS_IN_YEAR) # CALCULATE SPACE CONDITIONING DEMANDS tsd = latent_loads.calc_Qgain_lat(tsd, schedules) tsd = calc_set_points( bpr, date_range, tsd, building_name, config, locator, schedules) # calculate the setpoints for every hour tsd = calc_Qhs_Qcs( bpr, tsd, use_dynamic_infiltration_calculation ) # end-use demand latent and sensible + ventilation tsd = sensible_loads.calc_Qhs_Qcs_loss(bpr, tsd) # losses tsd = sensible_loads.calc_Qhs_sys_Qcs_sys(tsd) # system (incl. losses) tsd = sensible_loads.calc_temperatures_emission_systems( bpr, tsd) # calculate temperatures tsd = electrical_loads.calc_Eauxf_ve( tsd) # calc auxiliary loads ventilation tsd = electrical_loads.calc_Eaux_Qhs_Qcs( tsd, bpr) # calc auxiliary loads heating and cooling tsd = calc_Qcs_sys(bpr, tsd) # final : including fuels and renewables tsd = calc_Qhs_sys(bpr, tsd) # final : including fuels and renewables # Positive loads tsd['Qcs_lat_sys'] = abs(tsd['Qcs_lat_sys']) tsd['DC_cs'] = abs(tsd['DC_cs']) tsd['Qcs_sys'] = abs(tsd['Qcs_sys']) tsd['Qcre_sys'] = abs( tsd['Qcre_sys'] ) # inverting sign of cooling loads for reporting and graphs tsd['Qcdata_sys'] = abs( tsd['Qcdata_sys'] ) # inverting sign of cooling loads for reporting and graphs # CALCULATE HOT WATER LOADS if hotwater_loads.has_hot_water_technical_system(bpr): tsd = electrical_loads.calc_Eaux_fw(tsd, bpr, schedules) tsd = hotwater_loads.calc_Qww(bpr, tsd, schedules) # end-use tsd = hotwater_loads.calc_Qww_sys(bpr, tsd) # system (incl. losses) tsd = electrical_loads.calc_Eaux_ww(tsd, bpr) # calc auxiliary loads tsd = hotwater_loads.calc_Qwwf(bpr, tsd) # final else: tsd = electrical_loads.calc_Eaux_fw(tsd, bpr, schedules) tsd['Qww'] = tsd['DH_ww'] = tsd['Qww_sys'] = np.zeros(HOURS_IN_YEAR) tsd['mcpww_sys'] = tsd['Tww_sys_re'] = tsd['Tww_sys_sup'] = np.zeros( HOURS_IN_YEAR) tsd['Eaux_ww'] = tsd['SOLAR_ww'] = np.zeros(HOURS_IN_YEAR) tsd['NG_ww'] = tsd['COAL_ww'] = tsd['OIL_ww'] = tsd[ 'WOOD_ww'] = np.zeros(HOURS_IN_YEAR) tsd['E_ww'] = np.zeros(HOURS_IN_YEAR) # CALCULATE SUM OF HEATING AND COOLING LOADS tsd = calc_QH_sys_QC_sys(tsd) # aggregated cooling and heating loads # CALCULATE ELECTRICITY LOADS PART 2/2 AUXILIARY LOADS + ENERGY GENERATION tsd = electrical_loads.calc_Eaux(tsd) # auxiliary totals tsd = electrical_loads.calc_E_sys(tsd) # system (incl. losses) tsd = electrical_loads.calc_Ef(bpr, tsd) # final (incl. self. generated) # WRITE SOLAR RESULTS write_results(bpr, building_name, date_range, loads_output, locator, massflows_output, resolution_outputs, temperatures_output, tsd, debug) return