def get_date_strings(days_to_plot, daystep): """Calculate date and position for range input of yeardays """ major_ticks_days = [] major_ticks_labels = [] cnt = 0 cnt_daystep = 1 for day in days_to_plot: str_date = str(date_prop.yearday_to_date(2015, day)) str_date_short = str_date[5:] yearhour = cnt * 24 if daystep == cnt_daystep: # Label major_ticks_labels.append(str_date_short) # Position major_ticks_days.append(yearhour) cnt_daystep = 1 cnt += 1 else: cnt_daystep += 1 cnt += 1 return major_ticks_days, major_ticks_labels
def test_yearday_to_date(): """Testing """ in_year = 2015 in_month = 6 in_day = 13 in_yearday = 163 expected = date(2015, in_month, in_day) # call function out_value = date_prop.yearday_to_date(in_year, in_yearday) assert out_value == expected
def get_date_strings(days_to_plot, daystep): """Calculate date and position for range input of yeardays Arguments --------- days_to_plot : list List with yeardays to plot daystep : int Intervall of days to assign label Return ------- ticks_position : list Hourly ticks position major_ticks_labels : list Ticks labels """ ticks_position, ticks_labels = [], [] cnt = 0 cnt_daystep = 1 for day in days_to_plot: str_date = str(date_prop.yearday_to_date(2015, day)) str_date_short = str_date[5:] # Because 0 posit in hour list is 01:00, substract minus one hour yearhour = (cnt * 24) - 1 if daystep == cnt_daystep: ticks_labels.append(str_date_short) ticks_position.append(yearhour) cnt_daystep = 1 cnt += 1 else: cnt_daystep += 1 cnt += 1 return ticks_position, ticks_labels
def plot_radar_plots_average_peak_day(scenario_data, fueltype_to_model, fueltypes, year_to_plot, fig_name, base_yr=2015): """Compare averaged dh profile overall regions for peak day for future year and base year MAYBE: SO FAR ONLY FOR ONE SCENARIO """ fueltype_int = fueltypes[fueltype_to_model] # ---------------- # Create base year peak load profile # Aggregate load profiles of all regions # ----------------- peak_winter_individ_radars_to_plot_dh = [] trough_summer_individ_radars_to_plot_dh = [] load_factor_fueltype_y_cy = [] results_txt = [] for scenario_cnt, scenario in enumerate(scenario_data): print("-------Scenario: '{}' '{}'".format(scenario, fueltype_to_model)) # ------------------------ # Future year load profile # ------------------------ all_regs_fueltypes_yh_by = np.sum( scenario_data[scenario]['ed_fueltype_regs_yh'][base_yr], axis=1) all_regs_fueltypes_yh_cy = np.sum( scenario_data[scenario]['ed_fueltype_regs_yh'][year_to_plot], axis=1) # --------------------------- # Calculate load factors # --------------------------- peak_day_nr_by, by_max_h = enduse_func.get_peak_day_single_fueltype( all_regs_fueltypes_yh_by[fueltype_int]) test_peak_day_by = enduse_func.get_peak_day_all_fueltypes( all_regs_fueltypes_yh_by) peak_day_nr_cy, cy_max_h = enduse_func.get_peak_day_single_fueltype( all_regs_fueltypes_yh_cy[fueltype_int]) test_peak_day_cy = enduse_func.get_peak_day_all_fueltypes( all_regs_fueltypes_yh_cy) #peak_day_nr_cy = 32 _ = all_regs_fueltypes_yh_cy[fueltype_int].reshape(365, 24) print(_[peak_day_nr_cy]) print(np.max(_[peak_day_nr_cy])) print(cy_max_h) print("-----{} {}".format(scenario, peak_day_nr_cy)) print(_[peak_day_nr_cy]) print("EGON") # Minimum trough day trough_day_nr_by, by_max_h_trough = enduse_func.get_trough_day_single_fueltype( all_regs_fueltypes_yh_by[fueltype_int]) trough_day_nr_cy, cy_max_h_trough = enduse_func.get_trough_day_single_fueltype( all_regs_fueltypes_yh_cy[fueltype_int]) scen_load_factor_fueltype_y_by = load_factors.calc_lf_y( all_regs_fueltypes_yh_by) load_factor_fueltype_y_by = round( scen_load_factor_fueltype_y_by[fueltype_int], fueltype_int) scen_load_factor_fueltype_y_cy = load_factors.calc_lf_y( all_regs_fueltypes_yh_cy) load_factor_fueltype_y_cy.append( round(scen_load_factor_fueltype_y_cy[fueltype_int], fueltype_int)) # Add info on peak days #by2: {} results_txt.append( "p_day: {} by1: {} cy1: {}: cy2: {} trough_by: {} trough_cy: {}". format( peak_day_nr_cy, date_prop.yearday_to_date(2015, peak_day_nr_by), date_prop.yearday_to_date(2015, peak_day_nr_cy), #date_prop.yearday_to_date(2015, test_peak_day_by), date_prop.yearday_to_date(2015, test_peak_day_cy), date_prop.yearday_to_date(2015, trough_day_nr_by), date_prop.yearday_to_date(2015, trough_day_nr_cy))) # ------------------------ # Restult calculations # ------------------------ # Calculate share or space and water heating of total electrictiy demand in 2050 enduses_to_agg = [ 'rs_space_heating', 'rs_water_heating', 'ss_space_heating', 'ss_water_heating', 'is_space_heating' ] aggregated_enduse_fueltype_cy = np.zeros((8760)) aggregated_enduse_fueltype_by = np.zeros((8760)) for enduse in scenario_data[scenario]['results_enduse_every_year'][ year_to_plot].keys(): if enduse in enduses_to_agg: aggregated_enduse_fueltype_by += scenario_data[scenario][ 'results_enduse_every_year'][2015][enduse][fueltype_int] aggregated_enduse_fueltype_cy += scenario_data[scenario][ 'results_enduse_every_year'][year_to_plot][enduse][ fueltype_int] aggregated_enduse_fueltype_by_8760 = aggregated_enduse_fueltype_by.reshape( 365, 24) aggregated_enduse_fueltype_cy_8760 = aggregated_enduse_fueltype_cy.reshape( 365, 24) # Total demand of selected enduses selected_enduses_peak_by = round( np.max(aggregated_enduse_fueltype_by_8760[peak_day_nr_by]), 1) selected_enduses_peak_cy = round( np.max(aggregated_enduse_fueltype_cy_8760[peak_day_nr_cy]), 1) selected_enduses_min_by = round( np.max(aggregated_enduse_fueltype_by_8760[trough_day_nr_by]), 1) selected_enduses_min_cy = round( np.max(aggregated_enduse_fueltype_cy_8760[trough_day_nr_cy]), 1) # Calculate change in peak all_regs_fueltypes_yh_by = all_regs_fueltypes_yh_by.reshape( all_regs_fueltypes_yh_by.shape[0], 365, 24) all_regs_fueltypes_yh_cy = all_regs_fueltypes_yh_cy.reshape( all_regs_fueltypes_yh_cy.shape[0], 365, 24) diff_max_h = round(((100 / by_max_h) * cy_max_h) - 100, 1) txt = "peak_h_by: {} peak_h_cy: {} winter_heating_by: {} winter_heating_cy: {} trough_by: {} trough_cy: {} summer_heating_by: {} summer_heating_cy: {} {}".format( round(by_max_h, 1), round(cy_max_h, 1), selected_enduses_peak_by, selected_enduses_peak_cy, round(by_max_h_trough, 1), round(cy_max_h_trough, 1), selected_enduses_min_by, selected_enduses_min_cy, scenario) results_txt.append(txt) results_txt.append("----------") #results_txt.append("trough:day: " + str(all_regs_fueltypes_yh_by[fueltype_int][trough_day_nr_by])) print("Calculation of diff in peak: {} {} {} {}".format( scenario, round(diff_max_h, 1), round(by_max_h, 1), round(cy_max_h, 1))) # ---------------------------------- # Plot dh for peak day for base year # ---------------------------------- if scenario_cnt == 0: peak_winter_individ_radars_to_plot_dh.append( list(all_regs_fueltypes_yh_by[fueltype_int][peak_day_nr_by])) trough_summer_individ_radars_to_plot_dh.append( list(all_regs_fueltypes_yh_by[fueltype_int][trough_day_nr_cy])) else: pass # Add current year maximum winter peak day peak_winter_individ_radars_to_plot_dh.append( list(all_regs_fueltypes_yh_cy[fueltype_int][peak_day_nr_cy])) # Add current year minimum summer trough day trough_summer_individ_radars_to_plot_dh.append( list(all_regs_fueltypes_yh_cy[fueltype_int][trough_day_nr_cy])) # -------------------------- # Save model results to txt # -------------------------- name_spider_plot_peak = os.path.join( fig_name, "spider_scenarios_{}.pdf".format(fueltype_to_model)) write_data.write_list_to_txt( os.path.join(fig_name, name_spider_plot_peak[:-3] + "txt"), results_txt) name_spider_plot_trough = os.path.join( fig_name, "spider_scenarios_min_summer{}.pdf".format(fueltype_to_model)) write_data.write_list_to_txt( os.path.join(fig_name, name_spider_plot_trough[:-3] + "txt"), results_txt) # -------------------------- # Plot figure # -------------------------- # PEAK WINTER DAY PLOTS plot_radar_plot_multiple_lines(peak_winter_individ_radars_to_plot_dh, name_spider_plot_peak, plot_steps=50, scenario_names=list(scenario_data.keys()), plotshow=False, lf_y_by=[], lf_y_cy=[], list_diff_max_h=results_txt) # TROUGH Summer DAY PLOTS plot_radar_plot_multiple_lines(trough_summer_individ_radars_to_plot_dh, name_spider_plot_trough, plot_steps=50, scenario_names=list(scenario_data.keys()), plotshow=False, lf_y_by=[], lf_y_cy=[], list_diff_max_h=results_txt)
def __init__(self, lookup_enduses=None, lookup_sector_enduses=None, base_yr=None, weather_by=None, simulation_end_yr=None, curr_yr=None, sim_yrs=None, paths=None, enduses=None, sectors=None, reg_nrs=None): """Constructor """ self.lookup_enduses = lookup_enduses self.lookup_sector_enduses = lookup_sector_enduses self.submodels_names = lookup_tables.basic_lookups()['submodels_names'] self.nr_of_submodels = len(self.submodels_names) self.fueltypes = lookup_tables.basic_lookups()['fueltypes'] self.fueltypes_nr = lookup_tables.basic_lookups()['fueltypes_nr'] self.base_yr = base_yr self.weather_by = weather_by self.reg_nrs = reg_nrs self.simulation_end_yr = simulation_end_yr self.curr_yr = curr_yr self.sim_yrs = sim_yrs # ============================================================ # Spatially modelled variables # # If spatial explicit diffusion is modelled, all parameters # or technologies having a spatial explicit diffusion need # to be defined. # ============================================================ self.spatial_explicit_diffusion = 0 #0: False, 1: True # Define all variables which are affected by regional diffusion self.spatially_modelled_vars = [] # ['smart_meter_p'] # Define technologies which are affected by spatial explicit diffusion self.techs_affected_spatial_f = ['heat_pumps_electricity'] # Max penetration speed self.speed_con_max = 1 #1.5 # 1: uniform distribution >1: regional differences # ============================================================ # Model calibration factors # ============================================================ # # These calibration factors are used to match the modelled # electrictiy demand better with the validation data. # # Weekend effects are used to distribut energy demands # between working and weekend days. With help of these # factors, the demand on weekends and holidays can be # be lowered compared to working days. # This factor can be applied either directly to an enduse # or to the hdd or cdd calculations (to correct cooling # or heating demand) # # f_ss_cooling_weekend : float # Weekend effect for cooling enduses # f_ss_weekend : float # WWeekend effect for service submodel enduses # f_is_weekend : float # Weekend effect for industry submodel enduses # f_mixed_floorarea : float # Share of floor_area which is assigned to either # residential or non_residential floor area # ------------------------------------------------------------ self.f_ss_cooling_weekend = 0.45 # Temporal calibration factor self.f_ss_weekend = 0.8 # Temporal calibration factor self.f_is_weekend = 0.45 # Temporal calibration factor # ============================================================ # Modelled day related factors # ============================================================ # model_yeardays_date : dict # Contains for the base year for each days # the information wheter this is a working or holiday # ------------------------------------------------------------ self.model_yeardays = list(range(365)) # Calculate dates self.model_yeardays_date = [] for yearday in self.model_yeardays: self.model_yeardays_date.append( date_prop.yearday_to_date(base_yr, yearday)) # ============================================================ # Dwelling stock related assumptions # ============================================================ # # Assumptions to generate a virtual dwelling stock # # assump_diff_floorarea_pp : float # Change in floor area per person (%, 1=100%) # assump_diff_floorarea_pp_yr_until_changed : int # Year until this change in floor area happens # dwtype_distr_by : dict # Housing Stock Distribution by Type # Source: UK Housing Energy Fact File, Table 4c # dwtype_distr_fy : dict # welling type distribution end year # Source: UK Housing Energy Fact File, Table 4c # dwtype_floorarea_by : dict # Floor area per dwelling type (Annex Table 3.1) # Source: UK Housing Energy Fact File, Table 4c # dwtype_floorarea_fy : dict # Floor area per dwelling type # Source: UK Housing Energy Fact File, Table 4c # dwtype_age_distr : dict # Floor area per dwelling type # Source: Housing Energy Fact Sheet) # yr_until_changed : int # Year until change is realised # # https://www.gov.uk/government/statistics/english-housing-survey-2014-to-2015-housing-stock-report # ------------------------------------------------------------ yr_until_changed_all_things = 2050 self.dwtype_distr_by = { 'semi_detached': 0.26, 'terraced': 0.283, 'flat': 0.203, 'detached': 0.166, 'bungalow': 0.088 } self.dwtype_distr_fy = { 'yr_until_changed': yr_until_changed_all_things, 'semi_detached': 0.26, 'terraced': 0.283, 'flat': 0.203, 'detached': 0.166, 'bungalow': 0.088 } self.dwtype_floorarea_by = { 'semi_detached': 96, 'terraced': 82.5, 'flat': 61, 'detached': 147, 'bungalow': 77 } self.dwtype_floorarea_fy = { 'yr_until_changed': yr_until_changed_all_things, 'semi_detached': 96, 'terraced': 82.5, 'flat': 61, 'detached': 147, 'bungalow': 77 } # (Average builing age within age class, fraction) # The newest category of 2015 is added to implement change in refurbishing rate # For the base year, this is set to zero (if e.g. with future scenario set to 5%, then # proportionally to base year distribution number of houses are refurbished) self.dwtype_age_distr = { 2015: { '1918': 0.21, '1941': 0.36, '1977.5': 0.3, '1996.5': 0.08, '2002': 0.05 } } # ============================================================ # Scenario drivers # ============================================================ # # For every enduse the relevant factors which affect enduse # consumption can be added in a list. # # Note: If e.g. floorarea and population are added, the # effects will be overestimates (i.e. no multi- # collinearity are considered). # # scenario_drivers : dict # Scenario drivers per enduse # ------------------------------------------------------------ self.scenario_drivers = { # --Residential 'rs_space_heating': ['floorarea', 'hlc'], # Do not use HDD or pop because otherweise double count 'rs_water_heating': ['population'], 'rs_lighting': ['population', 'floorarea'], 'rs_cooking': ['population'], 'rs_cold': ['population'], 'rs_wet': ['population'], 'rs_consumer_electronics': ['population', 'gva'], 'rs_home_computing': ['population'], # --Service 'ss_space_heating': ['floorarea'], 'ss_water_heating': ['population'], 'ss_lighting': ['floorarea'], 'ss_catering': ['population'], 'ss_ICT_equipment': ['population'], 'ss_cooling_humidification': ['floorarea', 'population'], 'ss_fans': ['floorarea', 'population'], 'ss_small_power': ['population'], 'ss_cooled_storage': ['population'], 'ss_other_gas': ['population'], 'ss_other_electricity': ['population'], # Industry 'is_high_temp_process': ['gva'], 'is_low_temp_process': ['gva'], 'is_drying_separation': ['gva'], 'is_motors': ['gva'], 'is_compressed_air': ['gva'], 'is_lighting': ['gva'], 'is_space_heating': ['gva'], 'is_other': ['gva'], 'is_refrigeration': ['gva'] } # ============================================================ # Cooling related assumptions # ============================================================ # assump_cooling_floorarea : int # The percentage of cooled floor space in the base year # # Literature # ---------- # Abela, A. et al. (2016). Study on Energy Use by Air # Conditioning. Bre, (June), 31. Retrieved from # https://www.bre.co.uk/filelibrary/pdf/projects/aircon-energy-use/StudyOnEnergyUseByAirConditioningFinalReport.pdf # ------------------------------------------------------------ # See Abela et al. (2016) & Carbon Trust. (2012). Air conditioning. Maximising comfort, minimising energy consumption self.cooled_ss_floorarea_by = 0.35 # ============================================================ # Smart meter related base year assumptions # ============================================================ # smart_meter_p_by : int # The percentage of households with smart meters in by # ------------------------------------------------------------ self.smart_meter_assump = {} # Currently in 2017 8.6 mio smart meter installed of 27.2 mio households --> 31.6% # https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/671930/Smart_Meters_2017_update.pdf) # In 2015, 5.8 % percent of all househods had one: https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/533060/2016_Q1_Smart_Meters_Report.pdf self.smart_meter_assump['smart_meter_p_by'] = 0.05 # Long term smart meter induced general savings, purley as # a result of having a smart meter (e.g. 0.03 --> 3% savings) # DECC 2015: Smart Metering Early Learning Project: Synthesis report # https://www.gov.uk/government/publications/smart-metering-early-learning-project-and-small-scale-behaviour-trials # Reasonable assumption is between 0.03 and 0.01 (DECC 2015) self.smart_meter_assump['savings_smart_meter'] = { # Residential 'rs_cold': 0.03, 'rs_cooking': 0.03, 'rs_lighting': 0.03, 'rs_wet': 0.03, 'rs_consumer_electronics': 0.03, 'rs_home_computing': 0.03, 'rs_space_heating': 0.03, 'rs_water_heating': 0.03, # Service 'ss_space_heating': 0.03, 'ss_water_heating': 0.03, 'ss_cooling_humidification': 0.03, 'ss_fans': 0.03, 'ss_lighting': 0.03, 'ss_catering': 0.03, 'ss_small_power': 0.03, 'ss_ICT_equipment': 0.03, 'ss_cooled_storage': 0.03, 'ss_other_gas': 0.03, 'ss_other_electricity': 0.03, # Industry submodule 'is_high_temp_process': 0, 'is_low_temp_process': 0, 'is_drying_separation': 0, 'is_motors': 0, 'is_compressed_air': 0, 'is_lighting': 0, 'is_space_heating': 0, 'is_other': 0, 'is_refrigeration': 0 } # ============================================================ # Base temperature assumptions # ============================================================ # # Parameters related to smart metering # # rs_t_heating : int # Residential submodel base temp of heating of base year # rs_t_cooling_by : int # Residential submodel base temp of cooling of base year # ... # # Note # ---- # Because demand for cooling cannot directly be linked to # calculated cdd, the paramters 'ss_t_base_cooling' is used # as a calibration factor. By artifiallcy lowering this # parameter, the energy demand assignement over the days # in a year is improved. # ------------------------------------------------------------ t_bases = { 'rs_t_heating': 15.5, 'ss_t_heating': 15.5, 'ss_t_cooling': 5, 'is_t_heating': 15.5 } self.t_bases = DummyClass(t_bases) # ============================================================ # Enduses lists affed by hdd/cdd # ============================================================ # # These lists show for which enduses temperature related # calculations are performed. # # enduse_space_heating : list # All enduses for which hdd are used for yd calculations # ss_enduse_space_cooling : list # All service submodel enduses for which cdd are used for # yd calculations # ------------------------------------------------------------ self.enduse_space_heating = [ 'rs_space_heating', 'ss_space_heating', 'is_space_heating' ] self.ss_enduse_space_cooling = ['ss_cooling_humidification'] # ============================================================ # Industry related # # High temperature processing (high_temp_ process) dominates # energy consumption in the iron and steel # # ---- Steel production - Enduse: is_high_temp_process, Sector: basic_metals # With industry service switch, the future shares of 'is_temp_high_process' # in sector 'basic_metals' can be set for 'basic_oxygen_furnace', # 'electric_arc_furnace', and 'SNG_furnace' can be specified # # ---- Cement production - Enduse: is_high_temp_process, Sector: non_metallic_mineral_products # Dry kilns, semidry kilns can be set # ============================================================ # Share of cold rolling in steel manufacturing self.p_cold_rolling_steel_by = 0.2 # Estimated based on https://aceroplatea.es/docs/EuropeanSteelFigures_2015.pdf self.eff_cold_rolling_process = 1.8 # 80% more efficient than hot rolling Fruehan et al. (2002) self.eff_hot_rolling_process = 1.0 # 100% assumed efficiency # ============================================================ # Assumption related to heat pump technologies # ============================================================ # # Assumptions related to technologies # # gshp_fraction : list # Fraction of installed gshp_fraction heat pumps in base year # ASHP = 1 - gshp_fraction # ------------------------------------------------------------ self.gshp_fraction = 0.1 # Load defined technologies self.technologies, self.tech_list = read_data.read_technologies( paths['path_technologies']) self.installed_heat_pump_by = tech_related.generate_ashp_gshp_split( self.gshp_fraction) # Add heat pumps to technologies self.technologies, self.tech_list[ 'heating_non_const'], self.heat_pumps = tech_related.generate_heat_pump_from_split( self.technologies, self.installed_heat_pump_by, self.fueltypes) # ============================================================ # Fuel Stock Definition # Provide for every fueltype of an enduse the share of fuel # which is used by technologies in the base year # ============================================================$ fuel_tech_p_by = fuel_shares.assign_by_fuel_tech_p( enduses, sectors, self.fueltypes, self.fueltypes_nr) # ======================================== # Get technologies of an enduse and sector # ======================================== self.specified_tech_enduse_by = helpers.get_def_techs(fuel_tech_p_by) _specified_tech_enduse_by = helpers.add_undef_techs( self.heat_pumps, self.specified_tech_enduse_by, self.enduse_space_heating) self.specified_tech_enduse_by = _specified_tech_enduse_by # ======================================== # General other info # ======================================== self.seasons = date_prop.get_season(year_to_model=base_yr) self.model_yeardays_daytype, self.yeardays_month, self.yeardays_month_days = date_prop.get_yeardays_daytype( year_to_model=base_yr) # ======================================== # Helper functions # ======================================== self.fuel_tech_p_by, self.specified_tech_enduse_by, self.technologies = tech_related.insert_placholder_techs( self.technologies, fuel_tech_p_by, self.specified_tech_enduse_by) # ======================================== # Calculations with assumptions # ======================================== self.cdd_weekend_cfactors = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_ss_cooling_weekend) self.ss_weekend_f = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_ss_weekend) self.is_weekend_f = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_is_weekend) # ======================================== # Testing # ======================================== testing_functions.testing_fuel_tech_shares(self.fuel_tech_p_by) testing_functions.testing_tech_defined(self.technologies, self.specified_tech_enduse_by)
def compare_peak(name_fig, path_result, real_elec_2015_peak, modelled_peak_dh, peak_day): """Compare peak electricity day with calculated peak energy demand Arguments --------- name_fig : str Name of figure local_paths : dict Paths real_elec_2015_peak : array Real data of peak day modelled_peak_dh : array Modelled peak day """ logging.debug("...compare elec peak results") real_elec_peak = np.copy(real_elec_2015_peak) # ------------------------------- # Compare values # ------------------------------- fig = plt.figure(figsize=basic_plot_functions.cm2inch(8, 8)) # smooth line x_smoothed, y_modelled_peak_dh_smoothed = basic_plot_functions.smooth_data( range(24), modelled_peak_dh, num=500) plt.plot(x_smoothed, y_modelled_peak_dh_smoothed, color='blue', linestyle='--', linewidth=0.5, label='model') x_smoothed, real_elec_peak_smoothed = basic_plot_functions.smooth_data( range(24), real_elec_peak, num=500) plt.plot(x_smoothed, real_elec_peak_smoothed, color='black', linestyle='-', linewidth=0.5, label='validation') #raise Exception # Calculate hourly differences in % diff_p_h = np.round((100 / real_elec_peak) * modelled_peak_dh, 1) # Calculate maximum difference max_h_real = np.max(real_elec_peak) max_h_modelled = np.max(modelled_peak_dh) max_h_diff = round((100 / max_h_real) * max_h_modelled, 2) max_h_diff_gwh = round((abs(100 - max_h_diff) / 100) * max_h_real, 2) # Y-axis ticks plt.xlim(0, 23) plt.yticks(range(0, 60, 10)) # because position 0 in list is 01:00, the labelling starts with 1 plt.xticks([0, 5, 11, 17, 23], [1, 6, 12, 18, 24]) #ticks, labels plt.legend(frameon=False) # Labelling date_yearday = date_prop.yearday_to_date(2015, peak_day) plt.title("peak comparison {}".format(date_yearday)) plt.xlabel("h (max {} ({} GWH)".format(max_h_diff, max_h_diff_gwh)) plt.ylabel("uk electrictiy use [GW]") plt.text( 5, #position 5, #position diff_p_h, fontdict={ 'family': 'arial', 'color': 'black', 'weight': 'normal', 'size': 4 }) # Tight layout plt.tight_layout() plt.margins(x=0) # Save fig plt.savefig(os.path.join(path_result, name_fig)) plt.close()
def __init__(self, base_yr=None, curr_yr=None, simulated_yrs=None, paths=None, enduses=None, sectors=None, fueltypes=None, fueltypes_nr=None): yr_until_changed_all_things = 2050 # Simulation parameters self.base_yr = base_yr self.curr_yr = curr_yr self.simulated_yrs = simulated_yrs # ============================================================ # Spatially modelled variables # ============================================================ # Define all variables which are affected by regional diffusion self.spatially_modelled_vars = ['smart_meter_improvement_p'] # Define technologies which are affected by spatial explicit diffusion self.techs_affected_spatial_f = ['heat_pumps_electricity'] # ============================================================ # Model calibration factors # ============================================================ # # These calibration factors are used to match the modelled # electrictiy demand better with the validation data. # # Weekend effects are used to distribut energy demands # between working and weekend days. With help of these # factors, the demand on weekends and holidays can be # be lowered compared to working days. # This factor can be applied either directly to an enduse # or to the hdd or cdd calculations (to correct cooling # or heating demand) # # f_ss_cooling_weekend : float # Weekend effect for cooling enduses # f_ss_weekend : float # WWeekend effect for service submodel enduses # f_is_weekend : float # Weekend effect for industry submodel enduses # f_mixed_floorarea : float # Share of floor_area which is assigned to either # residential or non_residential floor area # ------------------------------------------------------------ # Temporal calibration factors self.f_ss_cooling_weekend = 0.45 # 0.55 self.f_ss_weekend = 0.75 # 0.7 self.f_is_weekend = 0.45 # 0.4 # Spatial calibration factor self.f_mixed_floorarea = 0.5 # 0.5 # ============================================================ # Modelled day related factors # ============================================================ # # model_yeardays_nrs : int # Number of modelled yeardays (default=365) # model_yearhours_nrs : int # Number of modelled yearhours (default=8760) # model_yeardays_date : dict # Contains for the base year for each days # the information wheter this is a working or holiday # ------------------------------------------------------------ self.model_yeardays = list(range(365)) # Calculate dates self.model_yeardays_date = [] for yearday in self.model_yeardays: self.model_yeardays_date.append( date_prop.yearday_to_date(base_yr, yearday)) self.model_yeardays_nrs = len(self.model_yeardays) self.model_yearhours_nrs = len(self.model_yeardays) * 24 # ============================================================ # Dwelling stock related assumptions # ============================================================ # # Assumptions to generate a virtual dwelling stock # # assump_diff_floorarea_pp : float # Change in floor area per person (%, 1=100%) # assump_diff_floorarea_pp_yr_until_changed : int # Year until this change in floor area happens # dwtype_distr_by : dict # Housing Stock Distribution by Type # Source: UK Housing Energy Fact File, Table 4c # dwtype_distr_fy : dict # welling type distribution end year # Source: UK Housing Energy Fact File, Table 4c # dwtype_floorarea_by : dict # Floor area per dwelling type (Annex Table 3.1) # Source: UK Housing Energy Fact File, Table 4c # dwtype_floorarea_fy : dict # Floor area per dwelling type # Source: UK Housing Energy Fact File, Table 4c # dwtype_age_distr : dict # Floor area per dwelling type # Source: Housing Energy Fact Sheet) # yr_until_changed : int # Year until change is realised # # https://www.gov.uk/government/statistics/english-housing-survey-2014-to-2015-housing-stock-report # ------------------------------------------------------------ self.assump_diff_floorarea_pp = 1.0 self.assump_diff_floorarea_pp_yr_until_changed = yr_until_changed_all_things self.dwtype_distr_by = { 'semi_detached': 0.26, 'terraced': 0.283, 'flat': 0.203, 'detached': 0.166, 'bungalow': 0.088 } self.dwtype_distr_fy = { 'yr_until_changed': yr_until_changed_all_things, 'semi_detached': 0.26, 'terraced': 0.283, 'flat': 0.203, 'detached': 0.166, 'bungalow': 0.088 } self.dwtype_floorarea_by = { 'semi_detached': 96, 'terraced': 82.5, 'flat': 61, 'detached': 147, 'bungalow': 77 } self.dwtype_floorarea_fy = { 'yr_until_changed': yr_until_changed_all_things, 'semi_detached': 96, 'terraced': 82.5, 'flat': 61, 'detached': 147, 'bungalow': 77 } # (Average builing age within age class, fraction) # The newest category of 2015 is added to implement change in refurbishing rate # For the base year, this is set to zero (if e.g. with future scenario set to 5%, then # proportionally to base year distribution number of houses are refurbished) self.dwtype_age_distr = { 2015: { '1918': 0.21, '1941': 0.36, '1977.5': 0.3, '1996.5': 0.08, '2002': 0.05 } } # ============================================================ # Scenario drivers # ============================================================ # # For every enduse the relevant factors which affect enduse # consumption can be added in a list. # # Note: If e.g. floorarea and population are added, the # effects will be overestimates (i.e. no multi- # collinearity are considered). # # scenario_drivers : dict # Scenario drivers per enduse # ------------------------------------------------------------ self.scenario_drivers = {} # --Residential SubModel self.scenario_drivers['rs_submodule'] = { 'rs_space_heating': ['floorarea', 'hlc'], # Do not use HDD or pop because otherweise double count 'rs_water_heating': ['population'], 'rs_lighting': ['population', 'floorarea'], 'rs_cooking': ['population'], 'rs_cold': ['population'], 'rs_wet': ['population'], 'rs_consumer_electronics': ['population' ], #GVA TODO. As soon as GVA is avaiable, drive it with GVA 'rs_home_computing': ['population'] } #GVA # --Service Submodel (Table 5.5a) self.scenario_drivers['ss_submodule'] = { 'ss_space_heating': ['floorarea'], 'ss_water_heating': ['population'], 'ss_lighting': ['floorarea'], 'ss_catering': ['population'], 'ss_ICT_equipment': ['population'], 'ss_cooling_humidification': ['floorarea', 'population'], 'ss_fans': ['floorarea', 'population'], 'ss_small_power': ['population'], 'ss_cooled_storage': ['population'], 'ss_other_gas': ['population'], 'ss_other_electricity': ['population'] } # --Industry Submodel self.scenario_drivers['is_submodule'] = { 'is_high_temp_process': ['gva'], 'is_low_temp_process': ['gva'], 'is_drying_separation': ['gva'], 'is_motors': ['gva'], 'is_compressed_air': ['gva'], 'is_lighting': ['gva'], 'is_space_heating': ['gva'], 'is_other': ['gva'], 'is_refrigeration': ['gva'] } # ============================================================ # Cooling related assumptions # ============================================================ # # Parameters related to cooling enduses are defined here. # # assump_cooling_floorarea : int # The percentage of cooled floor space in the base year # # Literature # ---------- # Abela, A. et al. (2016). Study on Energy Use by Air # Conditioning. Bre, (June), 31. Retrieved from # https://www.bre.co.uk/filelibrary/pdf/projects/aircon-energy-use # /StudyOnEnergyUseByAirConditioningFinalReport.pdf # ------------------------------------------------------------ # See Abela et al. (2016) # Carbon Trust. (2012). Air conditioning. Maximising comfort, minimising energy consumption self.cooled_ss_floorarea_by = 0.35 # ============================================================ # Smart meter related base year assumptions # ============================================================ # # Parameters related to smart metering # # smart_meter_p_by : int # The percentage of households with smart meters in by # smart_meter_diff_params : dict # Sigmoid diffusion parameter of smater meters # ------------------------------------------------------------ self.smart_meter_assump = {} self.smart_meter_assump['smart_meter_p_by'] = 0.1 self.smart_meter_assump['smart_meter_diff_params'] = { 'sig_midpoint': 0, 'sig_steepness': 1 } # ============================================================ # Base temperature assumptions # ============================================================ # # Parameters related to smart metering # # rs_t_heating_by : int # Residential submodel base temp of heating of base year # rs_t_cooling_by : int # Residential submodel base temp of cooling of base year # base_temp_diff_params : dict # Sigmoid temperature diffusion parameters # ... # # Note # ---- # Because demand for cooling cannot directly be linked to # calculated cdd, the paramters 'ss_t_cooling_by' is used # as a calibration factor. By artifiallcy lowering this # parameter, the energy demand assignement over the days # in a year is improved. # ------------------------------------------------------------ t_bases = {} t_bases['rs_t_heating_by'] = 15.5 # #t_bases['rs_t_cooling_by'] = Not implemented t_bases['ss_t_heating_by'] = 15.5 # t_bases['ss_t_cooling_by'] = 5 # Orig: 5 t_bases['is_t_heating_by'] = 15.5 # #self.t_bases['is_t_cooling_by'] = Not implemented self.t_bases = DummyClass(t_bases) self.base_temp_diff_params = { 'sig_midpoint': 0, 'sig_steepness': 1, 'yr_until_changed': yr_until_changed_all_things } # ============================================================ # Enduses lists affed by hdd/cdd # ============================================================ # # These lists show for which enduses temperature related # calculations are performed. # # enduse_space_heating : list # All enduses for which hdd are used for yd calculations # enduse_rs_space_cooling : list # All residential enduses for which cdd are used for # yd calculations # ss_enduse_space_cooling : list # All service submodel enduses for which cdd are used for # yd calculations # ------------------------------------------------------------ self.enduse_space_heating = [ 'rs_space_heating', 'ss_space_heating', 'is_space_heating' ] self.enduse_rs_space_cooling = [] self.ss_enduse_space_cooling = ['ss_cooling_humidification'] # ============================================================ # Industry submodel related parameters # ============================================================ # # Assumptions related to industrial enduses # # Overal changes in industry related enduse can be changed # in 'enduse_overall_change_enduses' # # ------------------------------------------------------------ # -------------------------------------------- # heating # -------------------------------------------- # --> No scenario drivers but driven by switches # -------------------------------------------- # lighting # # No individual technologies are defined. Only # overall efficiency increase can be implemented #-------------------------------------------- # -------------------------------------------- # high_temp_ process # # High temperature processing dominates energy consumption in the iron and steel, # non-ferrous metal, bricks, cement, glass and potteries industries. This includes # - coke ovens # - blast furnaces and other furnaces # - kilns and # - glass tanks. # High consumption in Chemicals, Non_metallic mineral products, paper, food_production # Fuel use ratio - electric arc furnace over blast furnace steel making in cement sector # BAT - iron & steel - continous/Ingot casting Sectoral share - continuous % # -------------------------------------------- # Share of cold rolling in steel manufacturing # ***************** self.p_cold_rolling_steel_by = 0.2 # Estimated based on https://aceroplatea.es/docs/EuropeanSteelFigures_2015.pdf self.eff_cold_rolling_process = 1.8 # 80% more efficient than hot rolling Fruehan et al. (2002) self.eff_hot_rolling_process = 1.0 # 100% assumed efficiency # Steel production - Enduse: is_high_temp_process, Sector: basic_metals # ***************** # With industry service switch, the future shares # in 'basic_oxygen_furnace', 'electric_arc_furnace', and 'SNG_furnace' # can be specified #scrap-based production: electric arc furnace #direct reduction process: natrual gas based, electric arc furnace #BF-BOF (blast furnace - basix oxgen furnace) # Example service switch: # is_high_temp_process,SNG_furnace,1.0,2050,basic_metals # Cement production - Enduse: is_high_temp_process, Sector: non_metallic_mineral_products # ***************** # technologies: Dry kilns, semidry kilns # CHEMICALs - Enduse: is_high_temp_process, Sector: CHEMICALS # ***************** # technologies: Dry & wet kilns # ---------------- # Efficiency of motors # ---------------- #is_motors_eff_change = 0 # ---------------- # Efficiency of others # ---------------- #is_others_eff_change = 0 # ---------------- # Efficiency of others # ---------------- #is_refrigeration_eff_change = 0 # ---------------- # Efficiency of is_compressed_air # ---------------- #is_compressed_air_eff_change = # ---------------- # Efficiency of is_drying_separation # ---------------- #is_drying_separation_eff_change = # ---------------- # Efficiency of is_low_temp_process # ---------------- #is_low_temp_process_eff_change = # ============================================================ # Assumption related to heat pump technologies # ============================================================ # # Assumptions related to technologies # # gshp_fraction : list # Fraction of installed gshp_fraction heat pumps in base year # ASHP = 1 - gshp_fraction # ------------------------------------------------------------ self.gshp_fraction = 0.1 self.technologies, self.tech_list = read_data.read_technologies( paths['path_technologies'], fueltypes) self.installed_heat_pump_by = tech_related.generate_ashp_gshp_split( self.gshp_fraction) # Add heat pumps to technologies self.technologies, self.tech_list[ 'heating_non_const'], self.heat_pumps = tech_related.generate_heat_pump_from_split( self.technologies, self.installed_heat_pump_by, fueltypes) # Collect all heating technologies # TODO: MAYBE ADD IN TECH DOC ANOTHER LIST SPECIFYING ALL HEATING TECHs self.heating_technologies = get_all_heating_techs(self.tech_list) # ============================================================ # Enduse diffusion paramters # ============================================================ # # Assumptions related to general diffusion # # This parameters are used to specify e.g. diffusion of # an enduse which is not specified by technologies # or the diffusion of a policy of changing a parameter # over time. # ------------------------------------------------------------ self.enduse_overall_change = {} self.enduse_overall_change['other_enduse_mode_info'] = { 'diff_method': 'linear', 'sigmoid': { 'sig_midpoint': 0, 'sig_steepness': 1 } } # ============================================================ # Fuel Stock Definition # Provide for every fueltype of an enduse # the share of fuel which is used by technologies for thebase year # ============================================================ self.rs_fuel_tech_p_by, self.ss_fuel_tech_p_by, self.is_fuel_tech_p_by = assumptions_fuel_shares.assign_by_fuel_tech_p( enduses, sectors, fueltypes, fueltypes_nr) # ======================================== # Get technologies of an enduse # ======================================== self.rs_specified_tech_enduse_by = helpers.get_def_techs( self.rs_fuel_tech_p_by, sector_crit=False) self.ss_specified_tech_enduse_by = helpers.get_def_techs( self.ss_fuel_tech_p_by, sector_crit=True) self.is_specified_tech_enduse_by = helpers.get_def_techs( self.is_fuel_tech_p_by, sector_crit=True) rs_specified_tech_enduse_by_new = helpers.add_undef_techs( self.heat_pumps, self.rs_specified_tech_enduse_by, 'rs_space_heating') self.rs_specified_tech_enduse_by = rs_specified_tech_enduse_by_new ss_specified_tech_enduse_by_new = helpers.add_undef_techs( self.heat_pumps, self.ss_specified_tech_enduse_by, 'ss_space_heating') self.ss_specified_tech_enduse_by = ss_specified_tech_enduse_by_new is_specified_tech_enduse_by_new = helpers.add_undef_techs( self.heat_pumps, self.is_specified_tech_enduse_by, 'is_space_heating') self.is_specified_tech_enduse_by = is_specified_tech_enduse_by_new # ============================================================ # Read in switches # ============================================================ # Read in scenaric fuel switches self.rs_fuel_switches = read_data.read_fuel_switches( paths['rs_path_fuel_switches'], enduses, fueltypes, self.technologies) self.ss_fuel_switches = read_data.read_fuel_switches( paths['ss_path_fuel_switches'], enduses, fueltypes, self.technologies) self.is_fuel_switches = read_data.read_fuel_switches( paths['is_path_fuel_switches'], enduses, fueltypes, self.technologies) # Read in scenaric service switches self.rs_service_switches = read_data.service_switch( paths['rs_path_service_switch'], self.technologies) self.ss_service_switches = read_data.service_switch( paths['ss_path_service_switch'], self.technologies) self.is_service_switches = read_data.service_switch( paths['is_path_industry_switch'], self.technologies) # Read in scenaric capacity switches self.rs_capacity_switches = read_data.read_capacity_switch( paths['rs_path_capacity_installation']) self.ss_capacity_switches = read_data.read_capacity_switch( paths['ss_path_capacity_installation']) self.is_capacity_switches = read_data.read_capacity_switch( paths['is_path_capacity_installation']) # Testing self.crit_switch_happening = testing_functions.switch_testing( fuel_switches=[ self.rs_fuel_switches, self.ss_fuel_switches, self.is_fuel_switches ], service_switches=[ self.rs_service_switches, self.ss_service_switches, self.is_service_switches ], capacity_switches=[ self.rs_capacity_switches, self.ss_capacity_switches, self.is_capacity_switches ]) # ======================================== # General other assumptions # ======================================== self.seasons = date_prop.get_season(year_to_model=base_yr) self.model_yeardays_daytype, self.yeardays_month, self.yeardays_month_days = date_prop.get_model_yeardays_daytype( year_to_model=base_yr) # ======================================== # Helper functions # ======================================== self.rs_fuel_tech_p_by, self.rs_specified_tech_enduse_by, self.technologies = tech_related.insert_placholder_techs( self.technologies, self.rs_fuel_tech_p_by, self.rs_specified_tech_enduse_by, sector_crit=False) self.ss_fuel_tech_p_by, self.ss_specified_tech_enduse_by, self.technologies = tech_related.insert_placholder_techs( self.technologies, self.ss_fuel_tech_p_by, self.ss_specified_tech_enduse_by, sector_crit=True) self.is_fuel_tech_p_by, self.is_specified_tech_enduse_by, self.technologies = tech_related.insert_placholder_techs( self.technologies, self.is_fuel_tech_p_by, self.is_specified_tech_enduse_by, sector_crit=True) # ======================================== # Calculations with assumptions # ======================================== self.cdd_weekend_cfactors = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_ss_cooling_weekend) self.ss_weekend_f = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_ss_weekend) self.is_weekend_f = hdd_cdd.calc_weekend_corr_f( self.model_yeardays_daytype, self.f_is_weekend) # ======================================== # Testing # ======================================== testing_functions.testing_fuel_tech_shares(self.rs_fuel_tech_p_by) for enduse in self.ss_fuel_tech_p_by: testing_functions.testing_fuel_tech_shares( self.ss_fuel_tech_p_by[enduse]) for enduse in self.is_fuel_tech_p_by: testing_functions.testing_fuel_tech_shares( self.is_fuel_tech_p_by[enduse]) testing_functions.testing_tech_defined( self.technologies, self.rs_specified_tech_enduse_by) testing_functions.testing_tech_defined( self.technologies, self.ss_specified_tech_enduse_by) testing_functions.testing_tech_defined( self.technologies, self.is_specified_tech_enduse_by)