示例#1
0
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