Source code for prereise.gather.demanddata.bldg_electrification.ff2elec_profile_generator_htg

import os

import numpy as np
import pandas as pd

from prereise.gather.demanddata.bldg_electrification import const


[docs]def calculate_cop(temp_c, model): cop_base, cr_base = _calculate_cop_base_cr_base(temp_c, model) eaux = [max(0.75 - i, 0) for i in cr_base] sumlist = [ (cr_base[i] + eaux[i]) / (cr_base[i] / cop_base[i] + eaux[i]) if cr_base[i] != 0 else 1 for i in range(len(cr_base)) ] cop = [1 if cr_base[i] == 0 else max(sumlist[i], 1) for i in range(len(cr_base))] return cop
def _calculate_cop_base_cr_base(temp_c, model): temp_k = [i + 273.15 for i in temp_c] cop_base = [0] * len(temp_c) cr_base = [0] * len(temp_c) model_params = const.hp_param.set_index("model").loc[model] T1_K = model_params.loc["T1_K"] # noqa: N806 COP1 = model_params.loc["COP1"] # noqa: N806 T2_K = model_params.loc["T2_K"] # noqa: N806 COP2 = model_params.loc["COP2"] # noqa: N806 T3_K = model_params.loc["T3_K"] # noqa: N806 COP3 = model_params.loc["COP3"] # noqa: N806 CR3 = model_params.loc["CR3"] # noqa: N806 a = model_params.loc["a"] b = model_params.loc["b"] c = model_params.loc["c"] for i, temp in enumerate(temp_k): if temp + b > 0: cr_base[i] = a * np.log(temp + b) + c if temp > T2_K: cop_base[i] = ((COP1 - COP2) / (T1_K - T2_K)) * temp + ( COP2 * T1_K - COP1 * T2_K ) / (T1_K - T2_K) if T3_K < temp <= T2_K: cop_base[i] = ((COP2 - COP3) / (T2_K - T3_K)) * temp + ( COP3 * T2_K - COP2 * T3_K ) / (T2_K - T3_K) if temp <= T3_K: cop_base[i] = (cr_base[i] / CR3) * COP3 return cop_base, cr_base
[docs]def htg_to_cop(temp_c, model): if model == "futurehp": cop = calculate_cop(temp_c, model) adv_cop = calculate_cop(temp_c, "advperfhp") cop_final = [max(cop[i], adv_cop[i]) for i in range(len(cop))] return cop_final else: return calculate_cop(temp_c, model)
[docs]def generate_htg_profiles( yr_temps=const.base_year, states=None, bldg_class="res", hp_model="advperfhp", output_folder="Profiles", ): """Generate and write profiles on dist. Create time series for electricity loads from converting fossil fuel heating to electric heat pumps. :param int yr_temps: year for temperature, defaults to ``const.base_year``. :param list states: list of states to loop through, defaults to None, in which case ``const.state_list`` is used. :param str bldg_class: type of building. :param str hp_model: type of heat pump. :param str output_folder: location to store profiles (will be created if necessary). :raises TypeError: if ``yr_temps`` is not an int. if ``bldg_class`` and ``hp_model`` are not str. :raises ValueError: if ``yr_temps`` is not one of the available temperature data year if ``bldg_class`` is not 'res' or 'com' if ``hp_model`` is not 'advperfhp', 'midperfhp' or 'futurehp' """ if not isinstance(yr_temps, int): raise TypeError("yr_temps must be an int") if states is None: states = const.state_list if not isinstance(bldg_class, str): raise TypeError("bldg_class must be a str") if not isinstance(hp_model, str): raise TypeError("hp_model must be a str") if yr_temps not in const.yr_temps_all: raise ValueError( "yr_temps must be among available temperature years: " "{const.yr_temps_first}-{const.yr_temps_last}" ) if bldg_class not in ["res", "com"]: raise ValueError( "bldg_class must be one of: \n", "res: residential \n", "com: commercial" ) if hp_model not in ["advperfhp", "midperfhp", "futurehp"]: raise ValueError( "hp_model must be one of: \n", "midperfhp: mid-performance cold climate heat pump \n", "advperfhp: advanced performance cold climate heat pump \n", "futurehp: future performance heat pump", ) os.makedirs(output_folder, exist_ok=True) # parse user data temp_ref_it = const.temp_ref[bldg_class] dir_path = os.path.dirname(os.path.abspath(__file__)) puma_slopes = pd.read_csv( os.path.join(dir_path, "data", f"puma_slopes_ff_{bldg_class}.csv"), index_col="puma", ) # Loop through states to create profile outputs for state in states: # Load and subset relevant data for the state puma_data_it = const.puma_data.query("state == @state") puma_slopes_it = puma_slopes.query("state == @state") temps_pumas_it = pd.read_csv( f"https://besciences.blob.core.windows.net/datasets/bldg_el/pumas/{yr_temps}/temps/temps_pumas_{state}_{yr_temps}.csv" ) # Compute electric HP loads from fossil fuel conversion elec_htg_ff2hp_puma_mw_it_ref_temp = temps_pumas_it.applymap( lambda x: max(temp_ref_it - x, 0) ) elec_htg_ff2hp_puma_mw_it_func = temps_pumas_it.apply( lambda x: np.reciprocal(htg_to_cop(x, hp_model)) ) elec_htg_ff2hp_puma_mw_it = elec_htg_ff2hp_puma_mw_it_ref_temp.multiply( elec_htg_ff2hp_puma_mw_it_func ) pumalist = ( puma_slopes_it[f"htg_slope_{bldg_class}_mmbtu_m2_degC"] * puma_data_it[f"{bldg_class}_area_{const.base_year}_m2"] * puma_data_it[f"frac_ff_sh_{bldg_class}_{const.base_year}"] * (const.conv_mmbtu_to_kwh * const.conv_kw_to_mw) * const.eff_htg_ff_base ) elec_htg_ff2hp_puma_mw_it *= pumalist # Export profile file as CSV elec_htg_ff2hp_puma_mw_it.to_csv( os.path.join( os.path.dirname(__file__), "Profiles", f"elec_htg_ff2hp_{bldg_class}_{state}_{yr_temps}_{hp_model}_mw.csv", ), index=False, )