def Append_Solar(glmDict, io_opts, time_opts, location_opts, model_opts): """ glmDict is a feeder already processed by GLD_Feeder, but with no solar yet appended. """ model_opts, config_data, tech_data, use_flags = get_parameters( io_opts, model_opts) glmDict.set_no_reindexing() last_key = len(glmDict) # Append Solar: Call append_solar(feeder_dict, use_flags, config_file, solar_bigbox_array, solar_office_array, solar_stripmall_array, solar_residential_array, last_key) if use_flags['use_solar'] != 0 or use_flags[ 'use_solar_res'] != 0 or use_flags['use_solar_com'] != 0: glmDict = Solar_Technology.Append_Solar(glmDict, use_flags, config_data, tech_data, last_key) # Append recorders glmDict, last_key = AddTapeObjects.add_recorders(glmDict, io_opts, time_opts, last_key, solar_only=True) return (glmDict, last_key)
def Append_Solar(glmDict, io_opts, time_opts, location_opts, model_opts): """ glmDict is a feeder already processed by GLD_Feeder, but with no solar yet appended. """ model_opts, config_data, tech_data, use_flags = get_parameters(io_opts, model_opts) glmDict.set_no_reindexing() last_key = len(glmDict) # Append Solar: Call append_solar(feeder_dict, use_flags, config_file, solar_bigbox_array, solar_office_array, solar_stripmall_array, solar_residential_array, last_key) if use_flags['use_solar'] != 0 or use_flags['use_solar_res'] != 0 or use_flags['use_solar_com'] != 0: glmDict = Solar_Technology.Append_Solar(glmDict, use_flags, config_data, tech_data, last_key) # Append recorders glmDict, last_key = AddTapeObjects.add_recorders(glmDict, io_opts, time_opts, last_key, solar_only = True) return (glmDict, last_key)
def OMFmain( milsoft, feeder_info, scada, case_flag, feeder_config, calibration_config, model_name="Feeder", user_flag_to_calibrate=1, ): if milsoft is None: print("Please input a model to convert!") # error return else: internal_flag_to_calibrate = 0 if feeder_config is None: if feeder_info is None: pass # We'll use defaults. else: # use whatever feeder_info is to write a new feeder_config file that will populate Configuration.py appropriatly. # feeder_config = writeFeederConfig(feeder_info) #TODO: This function is in the future. pass else: pass # We should check that this file is a valid feeder_config file for use inside Configuration.py. This is important if it's coming from the user incase they made change to the file that aren't compatible with our format. if calibration_config is None: if scada is None: pass # Well, we can't do any calibration but we can still pump out a populated model by using defaults. else: internal_flag_to_calibrate = 1 days, SCADA = processSCADA.getValues(scada) else: pass # We'll check that this file is a valid calibration_config file for use inside Configuration.py. This is important if it's coming from the user incase they made change to the file that aren't compatible with our format. # This might be where we can find out if this is the final calibration file or if we're starting mid-calibration. To do this maybe: # a. We could have another input to the script that is a flag indicating "yes, this is calibrated" or "no, this isn't finished yet". # b. We could just run the script using this calbiration_config file and let the script determine whether it's calibrated -- this might take too long though. # c. There could be a flag within the calibration_config file that was set when it was previously determined to be the "best". # Create base .glm dictionary from milsoft model # stdPath, seqPath = milsoft[0], milsoft[1] # outGlm = milToGridlab.convert(stdPath,seqPath) # directory = createFeederDirectory(milsoft) # testing with pre-made dictionary outGLM = milsoft directory = createFeederDirectory(None) # write base .glm to file (save as .txt so that it isn't run when batch file executed) basefile = open(directory + "\\" + model_name + "_base_glm.txt", "w") basefile.write("\\\\ Base feeder model generated by milToGridlab.py.\n") basefile.write(str(outGLM)) basefile.close() if ( internal_flag_to_calibrate == 1 and user_flag_to_calibrate == 1 ): # The user must want to calibrate (user_flag_to_calibrate = 1) and we must have SCADA input (internal_flag_to_calibrate = 1). # Send base .glm dictionary to calibration function final_calib_file, final_dict, last_key = calibrateFeeder.calibrateFeeder( outGLM, days, SCADA, case_flag, feeder_config, calibration_config, directory ) else: # Populate the feeder. print( "Either the user selected not to calibrate this feeder, the SCADA was not input, or this feeder has already been calibrated." ) final_dict, last_key = Milsoft_GridLAB_D_Feeder_Generation.GLD_Feeder( outGLM, case_flag, directory, calibration_config, feeder_config ) # AddTapeObjects # filename = 'test_feeder' if final_dict is not None: # AddTapeObjects.add_recorders(final_dict,None,last_key,None,1,0,filename,None,0,0) dict_with_recorders, last_key = AddTapeObjects.add_recorders( final_dict, case_flag, 0, 1, model_name, last_key ) # TODO: Turn final_dict into a .glm and return it to the user. glmstring = str(dict_with_recorders) if final_calib_file is not None: # calib = re.sub('.txt$','',final_calib_file) m = re.match(r"^Calib_ID(\d*)_Config_ID(\d*)", final_calib_file) if m is not None: calib = m.group() else: calib = "unrecognized" else: calib = "using_default_configuration" file = open(directory + "\\" + model_name + "_" + calib + "_final.glm", "w") file.write(glmstring) file.close() print("Final *.glm file is " + directory + "\\" + model_name + "_" + calib + "_final.glm") print("Calibration file is " + directory + "\\" + final_calib_file) else: pass
def GLD_Feeder(glmDict, io_opts, time_opts, location_opts, model_opts): """ glmDict is a dictionary containing all the objects in WindMIL model represented as equivalent GridLAB-D objects model_opts['tech_flag'] is an integer indicating which technology case to tack on to the GridLAB-D model -1 : Loadshape Case 0 : Base Case 1 : CVR 2 : Automation 3 : FDIR 4 : TOU/CPP w/ tech 5 : TOU/CPP w/o tech 6 : TOU w/ tech 7 : TOU w/o tech 8 : DLC 9 : Thermal Storage 10 : PHEV 11 : Solar Residential 12 : Solar Commercial 13 : Solar Combined io_opts['config_file'] is the name of the file to use for getting feeder information GLD_Feeder returns a dictionary, glmCaseDict, similar to glmDict with additional object dictionaries added according to the model_opts['tech_flag'] selected. """ model_opts, config_data, tech_data, use_flags = get_parameters(io_opts, model_opts) #tmy = 'schedules\\\\SCADA_weather_ISW_gld.csv' tmy = config_data['weather'] #find name of swingbus of static model dictionary swing_bus_name = None nom_volt = None for x in glmDict: if ('bustype' in glmDict[x]) and (glmDict[x]['bustype'] == 'SWING'): swing_bus_name = glmDict[x]['name'] nom_volt = glmDict[x]['nominal_voltage'] # Nominal voltage in V break assert(swing_bus_name is not None) assert(nom_volt is not None) # Create new case dictionary glmCaseDict = feeder.GlmFile() glmCaseDict.set_no_reindexing() last_key = len(glmCaseDict) # Create clock dictionary glmCaseDict[last_key] = {'clock' : '', 'timezone' : '{:s}'.format(config_data['timezone']), 'starttime' : "'{:s}'".format(tech_data['start_date']), 'stoptime' : "'{:s}'".format(tech_data['end_date'])} last_key += 1 # Create dictionaries of preprocessor directives if use_flags['use_homes'] != 0: glmCaseDict[last_key] = {'#include' : '{:s}/appliance_schedules.glm'.format(io_opts['resources_dir'])} last_key += 1 glmCaseDict[last_key] = {'#include' : '{:s}/water_and_setpoint_schedule_v5.glm'.format(io_opts['resources_dir'])} last_key += 1 if use_flags['use_battery'] == 1 or use_flags['use_battery'] == 2: glmCaseDict[last_key] = {'#include' : '{:s}/battery_schedule.glm'.format(io_opts['resources_dir'])} last_key += 1 if use_flags['use_commercial'] == 1: glmCaseDict[last_key] = {'#include' : '{:s}/commercial_schedules.glm'.format(io_opts['resources_dir'])} last_key += 1 if use_flags['use_market'] == 1 or use_flags['use_market'] == 2: glmCaseDict[last_key] = {'#include' : '{:s}/daily_elasticity_schedules.glm'.format(io_opts['resources_dir'])} last_key += 1 if use_flags['use_ts'] == 2 or use_flags['use_ts'] == 4: glmCaseDict[last_key] = {'#include' : '{:s}/thermal_storage_schedule_R{:d}.glm'.format(io_opts['resources_dir'],config_data['region'])} last_key += 1 glmCaseDict[last_key] = {'#define' : 'stylesheet=http://gridlab-d.svn.sourceforge.net/viewvc/gridlab-d/trunk/core/gridlabd-2_0'} last_key += 1 glmCaseDict[last_key] = { '#set' : 'minimum_timestep={}'.format(time_opts['sim_interval'].total_seconds()) } last_key += 1 glmCaseDict[last_key] = {'#set' : 'profiler=1'} last_key += 1 glmCaseDict[last_key] = {'#set' : 'relax_naming_rules=1'} last_key += 1 # Create dictionaries of modules to be used from the model_opts['tech_flag'] glmCaseDict[last_key] = {'module' : 'tape'} last_key += 1 glmCaseDict[last_key] = {'module' : 'climate'} last_key += 1 glmCaseDict[last_key] = {'module' : 'residential', 'implicit_enduses' : 'NONE'} last_key += 1 glmCaseDict[last_key] = {'module' : 'powerflow', 'solver_method' : 'NR', 'NR_iteration_limit' : '50'} last_key += 1 if use_flags['use_solar'] != 0 or use_flags['use_solar_res'] != 0 or use_flags['use_solar_com'] != 0 or use_flags['use_battery'] == 1 or use_flags['use_battery'] == 2: glmCaseDict[last_key] = {'module' : 'generators'} last_key += 1 if use_flags['use_market'] != 0: glmCaseDict[last_key] = {'module' : 'market'} last_key += 1 # Add the class player dictionary to glmCaseDict glmCaseDict[last_key] = {'class' : 'player', 'variable_types' : ['double'], 'variable_names' : ['value']} last_key += 1 if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict[last_key] = {'object' : 'player', 'name' : 'norm_feeder_loadshape', 'property' : 'value', 'file' : '{:s}'.format(config_data['load_shape_norm']), 'loop' : '14600', 'comment' : '// Will loop file for 40 years assuming the file has data for a 24 hour period'} last_key += 1 # Include the objects for the TOU case flags if use_flags['use_market'] != 0: # Add class auction dictionary to glmCaseDict glmCaseDict[last_key] = {'class' : 'auction', 'variable_types' : ['double','double'], 'variable_names' : ['my_avg','my_std']} last_key += 1 # Add CPP player dictionary to glmCaseDict CPP_flag_name = config_data['CPP_flag'] # Strip '.player' from config_data['CPP_flag'] CPP_flag_name.replace('.player','') glmCaseDict[last_key] = {'object' : 'player', 'name' : CPP_flag_name, 'file' : config_data['CPP_flag']} last_key += 1 # Add auction object dictionary to glmCaseDict # Determine which stat to use for my_avg and my_std if use_flags['use_market'] == 1: #TOU temp_avg = config_data['TOU_stats'][0] temp_std = config_data['TOU_stats'][1] elif use_flags['use_market'] == 2 or use_flags['use_market'] == 3: #TOU/CPP temp_avg = config_data['CPP_stats'][0] temp_std = config_data['CPP_stats'][1] glmCaseDict[last_key] = {'object' : 'auction', 'name' : tech_data['market_info'][0], 'period' : "{:.0f}".format(tech_data['market_info'][1]), 'special_mode' : 'BUYERS_ONLY', 'unit' : 'kW', 'my_avg' : temp_avg, 'my_std' : temp_std} parent_key = last_key last_key += 1 # Add player object dictionary for the auction object's clearing price # Determine which file to use for the clear_price if use_flags['use_market'] == 1: #TOU auction_price_file = config_data['TOU_price_player'] elif use_flags['use_market'] == 2 or use_flags['use_market'] == 3: #TOU/CPP auction_price_file = config_data['CPP_price_player'] glmCaseDict[last_key] = {'object' : 'player', 'parent' : glmCaseDict[parent_key]['name'], 'file' : auction_price_file, 'loop' : '10', 'property' : 'current_market.clearing_price'} last_key += 1 else: CPP_flag_name = None; # Add climate dictionaries if '.csv' in tmy: # Climate file is a cvs file. Need to add csv_reader object glmCaseDict[last_key] = {'object' : 'csv_reader', 'name' : 'CsvReader', 'filename' : '"{:s}"'.format(tmy)} last_key += 1 climate_name = tmy.replace('.csv','') elif '.tmy2' in tmy: climate_name = tmy.replace('.tmy2','') glmCaseDict[last_key] = {'object' : 'climate', 'name' : '"{:s}"'.format(climate_name), 'tmyfile' : '"{:s}"'.format(tmy)} if '.tmy2' in tmy: glmCaseDict[last_key]['interpolate'] = 'QUADRATIC' elif '.csv' in tmy: glmCaseDict[last_key]['reader'] = 'CsvReader' last_key += 1 # Add substation transformer transformer_configuration glmCaseDict[last_key] = {'object' : 'transformer_configuration', 'name' : 'trans_config_to_feeder', 'connect_type' : 'WYE_WYE', 'install_type' : 'PADMOUNT', 'primary_voltage' : '{}'.format(config_data['nom_volt']), 'secondary_voltage' : '{:s}'.format(nom_volt), 'power_rating' : '{:.1f} MVA'.format(config_data['feeder_rating']), 'impedance' : '0.00033+0.0022j'} last_key += 1 # Add CVR controller if use_flags['use_vvc'] == 1: # TODO: pull all of these out and put into TechnologyParameters() glmCaseDict[last_key] = {'object' : 'volt_var_control', 'name' : 'volt_var_control', 'control_method' : 'ACTIVE', 'capacitor_delay' : '60.0', 'regulator_delay' : '60.0', 'desired_pf' : '0.99', 'd_max' : '0.8', 'd_min' : '0.1', 'substation_link' : 'substation_transfromer', 'regulator_list' : '"{:s}"'.format(','.join(config_data['regulators'])), # config_data['regulators'] should contain a list of the names of the regulators that use CVR 'maximum_voltage' : '{:.2f}'.format(config_data['voltage_regulation'][2]), 'minimum_voltage' : '{:.2f}'.format(config_data['voltage_regulation'][1]), 'max_vdrop' : '50', 'high_load_deadband' :'{:.2f}'.format(config_data['voltage_regulation'][4]), 'desired_voltages' : '{:.2f}'.format(config_data['voltage_regulation'][0]), 'low_load_deadband' : '{:.2f}'.format(config_data['voltage_regulation'][3])} num_caps = len(config_data['capacitor_outage']) if 'capacitor_outage' in config_data else 0 if num_caps > 0: glmCaseDict[last_key]['capacitor_list'] = '"' for x in range(num_caps): if x < (num_caps - 1): glmCaseDict[last_key]['capacitor_list'] = glmCaseDict[last_key]['capacitor_list'] + '{:s},'.format(config_data['capacitor_outage'][x][0]) else: glmCaseDict[last_key]['capacitor_list'] = glmCaseDict[last_key]['capacitor_list'] + '{:s}"'.format(config_data['capacitor_outage'][x][0]) else: glmCaseDict[last_key]['capacitor_list'] = '""' num_eol = len(config_data['EOL_points']) glmCaseDict[last_key]['voltage_measurements'] = '"' for x in range(num_eol): if x < (num_eol - 1): glmCaseDict[last_key]['voltage_measurements'] = glmCaseDict[last_key]['voltage_measurements'] + '{:s},{:d},'.format(config_data['EOL_points'][x][0],config_data['EOL_points'][x][2]) else: glmCaseDict[last_key]['voltage_measurements'] = glmCaseDict[last_key]['voltage_measurements'] + '{:s},{:d}"'.format(config_data['EOL_points'][x][0],config_data['EOL_points'][x][2]) last_key += 1 # Add substation swing bus and substation transformer dictionaries #TMH - any values that we want to bus.py to measure from the swing bus need to be added here (e.g., 'measured_power' : '0', glmCaseDict[last_key] = {'object' : 'meter', 'name' : 'network_node', 'bustype' : 'SWING', 'nominal_voltage' : '{}'.format(config_data['nom_volt']), 'phases' : 'ABCN', 'measured_power' : '0', 'measured_current_A' : '0', 'measured_current_B' : '0', 'measured_current_C' : '0'} # Add transmission voltage players parent_key = last_key last_key += 1 if config_data["voltage_players"][0] is not None: glmCaseDict[last_key] = {'object' : 'player', 'property' : 'voltage_A', 'parent' : '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop' : '10', 'file' : '{:s}'.format(config_data["voltage_players"][0])} last_key += 1 if config_data["voltage_players"][1] is not None: glmCaseDict[last_key] = {'object' : 'player', 'property' : 'voltage_B', 'parent' : '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop' : '10', 'file' : '{:s}'.format(config_data["voltage_players"][1])} last_key += 1 if config_data["voltage_players"][2] is not None: glmCaseDict[last_key] = {'object' : 'player', 'property' : 'voltage_C', 'parent' : '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop' : '10', 'file' : '{:s}'.format(config_data["voltage_players"][2])} last_key += 1 glmCaseDict[last_key] = {'object' : 'transformer', 'name' : 'substation_transformer', 'from' : 'network_node', 'to' : '{:s}'.format(swing_bus_name), 'phases' : 'ABCN', 'configuration' : 'trans_config_to_feeder'} last_key += 1 # Copy static powerflow model glm dictionary into case dictionary for x in glmDict: # skip clocks, since already added one if 'clock' in glmDict[x]: continue glmCaseDict[last_key] = copy.deepcopy(glmDict[x]) # Remove original swing bus from static model if 'bustype' in glmCaseDict[last_key] and glmCaseDict[last_key]['bustype'] == 'SWING': swing_node = glmCaseDict[last_key]['name'] del glmCaseDict[last_key]['bustype'] glmCaseDict[last_key]['object'] = 'meter' last_key += 1 # Add groupid's to lines and transformers for x in glmCaseDict: if 'object' in glmCaseDict[x]: if re.match("triplex_line.*",glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Triplex_Line' elif re.match("transformer.*",glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Distribution_Trans' elif re.match("overhead_line.*",glmCaseDict[x]['object']) or re.match("underground_line.*",glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Distribution_Line' # Create dictionary that houses the number of commercial 'load' objects where commercial house objects will be tacked on. commercial_dict = {} if use_flags['use_commercial'] == 1: commercial_key = 0 to_remove = [] for x in glmCaseDict: if 'object' in glmCaseDict[x] and re.match("load.*",glmCaseDict[x]['object']): commercial_dict[commercial_key] = {'name' : glmCaseDict[x]['name'], 'parent' : 'None', 'load_classification' : 'None', 'load' : [0,0,0], 'number_of_houses' : [0,0,0], #[phase A, phase B, phase C] 'nom_volt' : glmCaseDict[x]['nominal_voltage'], 'phases' : glmCaseDict[x]['phases']} if 'parent' in glmCaseDict[x]: commercial_dict[commercial_key]['parent'] = glmCaseDict[x]['parent'] if 'load_class' in glmCaseDict[x]: commercial_dict[commercial_key]['load_classification'] = glmCaseDict[x]['load_class'] # Figure out how many houses should be attached to this load object # First determine the total ZIP load for each phase load_A, load_B, load_C = helpers.calculate_load_by_phase(glmCaseDict[x], 'real') commercial_dict[commercial_key]['load'][0] = load_A commercial_dict[commercial_key]['load'][1] = load_B commercial_dict[commercial_key]['load'][2] = load_C # TODO: Bypass this if load rating is known # Determine load_rating total_load = (load_A + load_B + load_C)/1000.0 load_rating, load_rating_index = helpers.get_transformer_size( total_load, config_data['standard_transformer_ratings'], config_data['tranformer_oversize_factor']) commercial_dict[commercial_key]['load_rating'] = load_rating # Deterimine load classification load_class = None if commercial_dict[commercial_key]['load_classification'].isdigit(): load_class = int(commercial_dict[commercial_key]['load_classification']) else: # load_classification is unknown determine from no_houses and transformer size random_class_number = random.random()*100 cum_perc = 0 for i, perc in enumerate([one_load_class[load_rating_index] for one_load_class in config_data['comm_load_class_dists']]): if cum_perc < random_class_number <= cum_perc + perc: load_class = 6 + i break cum_perc += perc assert load_class is not None commercial_dict[commercial_key]['load_classification'] = load_class # print('Replacing {:.0f} kW with buildings of type {}, on a transformer rated at {} kW.'.format( # total_load, # config_data["load_classifications"][load_class], # load_rating)) # Remove load (used to be changed into a node, but then the node was dangling) to_remove.append(x) # if load parented by meter ... meter_key = glmCaseDict.get_parent_key(x,'meter') if meter_key is not None: transformer_key = glmCaseDict.get_connector_by_to_node(meter_key,'transformer') if transformer_key is not None and 'phases' in glmCaseDict[transformer_key]: phases = glmCaseDict[transformer_key]['phases'] m = re.match("(A|B|C|AB|AC|BC|ABC)N",phases) if m is not None: phase = m.group(1) # ... and the structure is what we expect, swap out the transformer for an overhead_line glmCaseDict[transformer_key]['object'] = 'overhead_line' glmCaseDict[transformer_key]['length'] = '50ft' glmCaseDict[transformer_key]['configuration'] = 'line_configuration_comm{:s}'.format(phase) glmCaseDict[transformer_key]['groupid'] = 'Distribution_Line' commercial_key += 1 for x in to_remove: del glmCaseDict[x] # Create dictionary that houses the number of residential 'load' objects where residential house objects will be tacked on. residential_dict = {} if use_flags['use_homes'] == 1: residential_key = 0 to_remove = [] for x in glmCaseDict: if 'object' in glmCaseDict[x] and re.match("triplex_node.*",glmCaseDict[x]['object']): if 'power_1' in glmCaseDict[x] or 'power_12' in glmCaseDict[x]: residential_dict[residential_key] = {'name' : glmCaseDict[x]['name'], 'parent' : 'None', 'load_classification' : 'None', 'number_of_houses' : 0, 'load' : 0, 'large_vs_small' : 0.0, 'phases' : glmCaseDict[x]['phases']} if 'parent' in glmCaseDict[x]: residential_dict[residential_key]['parent'] = glmCaseDict[x]['parent'] if 'load_class' in glmCaseDict[x]: residential_dict[residential_key]['load_classification'] = glmCaseDict[x]['load_class'] # Figure out how many houses should be attached to this load object # First determine the total ZIP load load = helpers.calculate_load(glmCaseDict[x], 'real') c_load = helpers.calculate_load(glmCaseDict[x], 'complex') residential_dict[residential_key]['load'] = load residential_dict[residential_key]['complex_load'] = c_load # Determine load_rating total_load = load/1000 # kW load_rating, load_rating_index = helpers.get_transformer_size( total_load, config_data['standard_transformer_ratings'], config_data['tranformer_oversize_factor']) residential_dict[residential_key]['load_rating'] = load_rating # Deterimine load classification load_class = None if residential_dict[residential_key]['load_classification'].isdigit(): load_class = int(residential_dict[residential_key]['load_classification']) else: # load_classification is unknown. determine from no_houses and transformer size residential_dict[residential_key]['load_classification'] = None random_class_number = random.random()*100 load_class = None cum_perc = 0 for i, perc in enumerate([one_load_class[load_rating_index] for one_load_class in config_data['res_load_class_dists']]): if cum_perc < random_class_number <= cum_perc + perc: load_class = i break cum_perc += perc assert load_class is not None residential_dict[residential_key]['load_classification'] = load_class # print('Replacing {:.0f} kW with houses of type {}, on a transformer rated at {} kW.'.format( # total_load, # config_data["load_classifications"][load_class], # load_rating)) # Remove constant load keys if 'load_class' in glmCaseDict[x]: del glmCaseDict[x]['load_class'] # Must remove load_class as it isn't a published property if 'power_12' in glmCaseDict[x]: del glmCaseDict[x]['power_12'] if 'power_1' in glmCaseDict[x]: del glmCaseDict[x]['power_1'] residential_key += 1 # Calculate some random numbers needed for TOU/CPP and DLC technologies if use_flags['use_market'] != 0: # Initialize psuedo-random seed random.seed(2) if config_data["fix_random_seed"] else random.seed() if len(residential_dict) > 0: # Initialize random number arrays market_penetration_random = [] dlc_rand = [] pool_pump_recovery_random = [] slider_random = [] comm_slider_random = [] dlc_c_rand = [] dlc_c_rand2 = [] # Make a large array so we don't run out if len(residential_dict) > 0: aa = len(residential_dict)*100 # was total_house_number -- just guessing at a big enough maximum number for x in range(aa): market_penetration_random.append(random.random()) dlc_rand.append(random.random()) # Used for dlc randomization # 10 - 25% increase over normal cycle pool_pump_recovery_random.append(0.1 + 0.15*random.random()) # Limit slider randomization to Olypen style slider_random.append(random.normalvariate(0.45,0.2)) if slider_random[x] > tech_data['market_info'][4]: slider_random[x] = tech_data['market_info'][4] if slider_random[x] < 0: slider_random[x] = 0 # Random elasticity values for responsive loads - this is a multiplier # used to randomized individual building responsiveness - very similar # to a lognormal, so we'll use one that has a mean of ~1, max of # ~1.2, and median of ~1.12 sigma = 1.2 mu = 0.7 multiplier = 3.6 xval = [] elasticity_random = [] for x in range(aa): xval.append(random.random()) elasticity_random.append(multiplier * math.exp(-1 / (2 * pow(sigma,2))) * pow((math.log(xval[x]) - mu),2) / (xval[x] * sigma * math.sqrt(2 * math.pi))) if len(commercial_dict) > 0: aa = len(commercial_dict)*15*100 for x in range(aa): # Limit slider randomization to Olypen style comm_slider_random.append(random.normalvariate(0.45,0.2)) if comm_slider_random[x] > tech_data['market_info'][4]: comm_slider_random[x] = tech_data['market_info'][4] if comm_slider_random[x] < 0: comm_slider_random[x] = 0 dlc_c_rand.append(random.random()) dlc_c_rand2.append(random.random()) else: market_penetration_random = None dlc_rand = None pool_pump_recovery_random = None slider_random = None comm_slider_random = None dlc_c_rand = None dlc_c_rand2 = None xval = None elasticity_random = None else: market_penetration_random = None dlc_rand = None pool_pump_recovery_random = None slider_random = None comm_slider_random = None dlc_c_rand = None dlc_c_rand2 = None xval = None elasticity_random = None # Tack on residential loads solar_residential_array = [0,[],[]] if use_flags['use_homes'] != 0: if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict, last_key = AddLoadShapes.add_normalized_residential_ziploads(glmCaseDict, residential_dict, config_data, last_key) else: glmCaseDict, solar_residential_array, ts_residential_array, last_key = ResidentialLoads.append_residential( glmCaseDict, use_flags, config_data, tech_data, residential_dict, last_key, CPP_flag_name, market_penetration_random, dlc_rand, pool_pump_recovery_random, slider_random, xval, elasticity_random, io_opts['dir'], io_opts['resources_dir']) # End addition of residential loads ######################################################################################################################## solar_office_array = [0,[],[]] solar_bigbox_array = [0,[],[]] solar_stripmall_array = [0,[],[]] if use_flags['use_commercial'] != 0: if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict, last_key = AddLoadShapes.add_normalized_commercial_ziploads(glmCaseDict, commercial_dict, config_data, last_key) else: glmCaseDict, solar_office_array, solar_bigbox_array, solar_stripmall_array, ts_office_array, \ ts_bigbox_array, ts_stripmall_array, last_key = CommercialLoads.append_commercial( glmCaseDict, use_flags, config_data, tech_data, last_key, commercial_dict, comm_slider_random, dlc_c_rand, dlc_c_rand2, io_opts['dir'], io_opts['resources_dir']) # Append Solar: Call append_solar(feeder_dict, use_flags, config_file, solar_bigbox_array, solar_office_array, solar_stripmall_array, solar_residential_array, last_key) if use_flags['use_solar'] != 0 or use_flags['use_solar_res'] != 0 or use_flags['use_solar_com'] != 0: glmCaseDict = Solar_Technology.Append_Solar(glmCaseDict, use_flags, config_data, tech_data, last_key) # Append recorders glmCaseDict, last_key = AddTapeObjects.add_recorders(glmCaseDict, io_opts, time_opts, last_key) return (glmCaseDict, last_key)
def GLD_Feeder(glmDict, io_opts, time_opts, location_opts, model_opts): """ glmDict is a dictionary containing all the objects in WindMIL model represented as equivalent GridLAB-D objects model_opts['tech_flag'] is an integer indicating which technology case to tack on to the GridLAB-D model -1 : Loadshape Case 0 : Base Case 1 : CVR 2 : Automation 3 : FDIR 4 : TOU/CPP w/ tech 5 : TOU/CPP w/o tech 6 : TOU w/ tech 7 : TOU w/o tech 8 : DLC 9 : Thermal Storage 10 : PHEV 11 : Solar Residential 12 : Solar Commercial 13 : Solar Combined io_opts['config_file'] is the name of the file to use for getting feeder information GLD_Feeder returns a dictionary, glmCaseDict, similar to glmDict with additional object dictionaries added according to the model_opts['tech_flag'] selected. """ model_opts, config_data, tech_data, use_flags = get_parameters( io_opts, model_opts) #tmy = 'schedules\\\\SCADA_weather_ISW_gld.csv' tmy = config_data['weather'] #find name of swingbus of static model dictionary swing_bus_name = None nom_volt = None for x in glmDict: if ('bustype' in glmDict[x]) and (glmDict[x]['bustype'] == 'SWING'): swing_bus_name = glmDict[x]['name'] nom_volt = glmDict[x]['nominal_voltage'] # Nominal voltage in V break assert (swing_bus_name is not None) assert (nom_volt is not None) # Create new case dictionary glmCaseDict = feeder.GlmFile() glmCaseDict.set_no_reindexing() last_key = len(glmCaseDict) # Create clock dictionary glmCaseDict[last_key] = { 'clock': '', 'timezone': '{:s}'.format(config_data['timezone']), 'starttime': "'{:s}'".format(tech_data['start_date']), 'stoptime': "'{:s}'".format(tech_data['end_date']) } last_key += 1 # Create dictionaries of preprocessor directives if use_flags['use_homes'] != 0: glmCaseDict[last_key] = { '#include': '{:s}/appliance_schedules.glm'.format(io_opts['resources_dir']) } last_key += 1 glmCaseDict[last_key] = { '#include': '{:s}/water_and_setpoint_schedule_v5.glm'.format( io_opts['resources_dir']) } last_key += 1 if use_flags['use_battery'] == 1 or use_flags['use_battery'] == 2: glmCaseDict[last_key] = { '#include': '{:s}/battery_schedule.glm'.format(io_opts['resources_dir']) } last_key += 1 if use_flags['use_commercial'] == 1: glmCaseDict[last_key] = { '#include': '{:s}/commercial_schedules.glm'.format(io_opts['resources_dir']) } last_key += 1 if use_flags['use_market'] == 1 or use_flags['use_market'] == 2: glmCaseDict[last_key] = { '#include': '{:s}/daily_elasticity_schedules.glm'.format( io_opts['resources_dir']) } last_key += 1 if use_flags['use_ts'] == 2 or use_flags['use_ts'] == 4: glmCaseDict[last_key] = { '#include': '{:s}/thermal_storage_schedule_R{:d}.glm'.format( io_opts['resources_dir'], config_data['region']) } last_key += 1 glmCaseDict[last_key] = { '#define': 'stylesheet=http://gridlab-d.svn.sourceforge.net/viewvc/gridlab-d/trunk/core/gridlabd-2_0' } last_key += 1 glmCaseDict[last_key] = { '#set': 'minimum_timestep={}'.format(time_opts['sim_interval'].total_seconds()) } last_key += 1 glmCaseDict[last_key] = {'#set': 'profiler=1'} last_key += 1 glmCaseDict[last_key] = {'#set': 'relax_naming_rules=1'} last_key += 1 # Create dictionaries of modules to be used from the model_opts['tech_flag'] glmCaseDict[last_key] = {'module': 'tape'} last_key += 1 glmCaseDict[last_key] = {'module': 'climate'} last_key += 1 glmCaseDict[last_key] = { 'module': 'residential', 'implicit_enduses': 'NONE' } last_key += 1 glmCaseDict[last_key] = { 'module': 'powerflow', 'solver_method': 'NR', 'NR_iteration_limit': '50' } last_key += 1 if use_flags['use_solar'] != 0 or use_flags[ 'use_solar_res'] != 0 or use_flags[ 'use_solar_com'] != 0 or use_flags[ 'use_battery'] == 1 or use_flags['use_battery'] == 2: glmCaseDict[last_key] = {'module': 'generators'} last_key += 1 if use_flags['use_market'] != 0: glmCaseDict[last_key] = {'module': 'market'} last_key += 1 # Add the class player dictionary to glmCaseDict glmCaseDict[last_key] = { 'class': 'player', 'variable_types': ['double'], 'variable_names': ['value'] } last_key += 1 if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict[last_key] = { 'object': 'player', 'name': 'norm_feeder_loadshape', 'property': 'value', 'file': '{:s}'.format(config_data['load_shape_norm']), 'loop': '14600', 'comment': '// Will loop file for 40 years assuming the file has data for a 24 hour period' } last_key += 1 # Include the objects for the TOU case flags if use_flags['use_market'] != 0: # Add class auction dictionary to glmCaseDict glmCaseDict[last_key] = { 'class': 'auction', 'variable_types': ['double', 'double'], 'variable_names': ['my_avg', 'my_std'] } last_key += 1 # Add CPP player dictionary to glmCaseDict CPP_flag_name = config_data[ 'CPP_flag'] # Strip '.player' from config_data['CPP_flag'] CPP_flag_name.replace('.player', '') glmCaseDict[last_key] = { 'object': 'player', 'name': CPP_flag_name, 'file': config_data['CPP_flag'] } last_key += 1 # Add auction object dictionary to glmCaseDict # Determine which stat to use for my_avg and my_std if use_flags['use_market'] == 1: #TOU temp_avg = config_data['TOU_stats'][0] temp_std = config_data['TOU_stats'][1] elif use_flags['use_market'] == 2 or use_flags[ 'use_market'] == 3: #TOU/CPP temp_avg = config_data['CPP_stats'][0] temp_std = config_data['CPP_stats'][1] glmCaseDict[last_key] = { 'object': 'auction', 'name': tech_data['market_info'][0], 'period': "{:.0f}".format(tech_data['market_info'][1]), 'special_mode': 'BUYERS_ONLY', 'unit': 'kW', 'my_avg': temp_avg, 'my_std': temp_std } parent_key = last_key last_key += 1 # Add player object dictionary for the auction object's clearing price # Determine which file to use for the clear_price if use_flags['use_market'] == 1: #TOU auction_price_file = config_data['TOU_price_player'] elif use_flags['use_market'] == 2 or use_flags[ 'use_market'] == 3: #TOU/CPP auction_price_file = config_data['CPP_price_player'] glmCaseDict[last_key] = { 'object': 'player', 'parent': glmCaseDict[parent_key]['name'], 'file': auction_price_file, 'loop': '10', 'property': 'current_market.clearing_price' } last_key += 1 else: CPP_flag_name = None # Add climate dictionaries if '.csv' in tmy: # Climate file is a cvs file. Need to add csv_reader object glmCaseDict[last_key] = { 'object': 'csv_reader', 'name': 'CsvReader', 'filename': '"{:s}"'.format(tmy) } last_key += 1 climate_name = tmy.replace('.csv', '') elif '.tmy2' in tmy: climate_name = tmy.replace('.tmy2', '') glmCaseDict[last_key] = { 'object': 'climate', 'name': '"{:s}"'.format(climate_name), 'tmyfile': '"{:s}"'.format(tmy) } if '.tmy2' in tmy: glmCaseDict[last_key]['interpolate'] = 'QUADRATIC' elif '.csv' in tmy: glmCaseDict[last_key]['reader'] = 'CsvReader' last_key += 1 # Add substation transformer transformer_configuration glmCaseDict[last_key] = { 'object': 'transformer_configuration', 'name': 'trans_config_to_feeder', 'connect_type': 'WYE_WYE', 'install_type': 'PADMOUNT', 'primary_voltage': '{}'.format(config_data['nom_volt']), 'secondary_voltage': '{:s}'.format(nom_volt), 'power_rating': '{:.1f} MVA'.format(config_data['feeder_rating']), 'impedance': '0.00033+0.0022j' } last_key += 1 # Add CVR controller if use_flags['use_vvc'] == 1: # TODO: pull all of these out and put into TechnologyParameters() glmCaseDict[last_key] = { 'object': 'volt_var_control', 'name': 'volt_var_control', 'control_method': 'ACTIVE', 'capacitor_delay': '60.0', 'regulator_delay': '60.0', 'desired_pf': '0.99', 'd_max': '0.8', 'd_min': '0.1', 'substation_link': 'substation_transfromer', 'regulator_list': '"{:s}"'.format( ','.join(config_data['regulators']) ), # config_data['regulators'] should contain a list of the names of the regulators that use CVR 'maximum_voltage': '{:.2f}'.format(config_data['voltage_regulation'][2]), 'minimum_voltage': '{:.2f}'.format(config_data['voltage_regulation'][1]), 'max_vdrop': '50', 'high_load_deadband': '{:.2f}'.format(config_data['voltage_regulation'][4]), 'desired_voltages': '{:.2f}'.format(config_data['voltage_regulation'][0]), 'low_load_deadband': '{:.2f}'.format(config_data['voltage_regulation'][3]) } num_caps = len(config_data['capacitor_outage'] ) if 'capacitor_outage' in config_data else 0 if num_caps > 0: glmCaseDict[last_key]['capacitor_list'] = '"' for x in range(num_caps): if x < (num_caps - 1): glmCaseDict[last_key]['capacitor_list'] = glmCaseDict[ last_key]['capacitor_list'] + '{:s},'.format( config_data['capacitor_outage'][x][0]) else: glmCaseDict[last_key]['capacitor_list'] = glmCaseDict[ last_key]['capacitor_list'] + '{:s}"'.format( config_data['capacitor_outage'][x][0]) else: glmCaseDict[last_key]['capacitor_list'] = '""' num_eol = len(config_data['EOL_points']) glmCaseDict[last_key]['voltage_measurements'] = '"' for x in range(num_eol): if x < (num_eol - 1): glmCaseDict[last_key]['voltage_measurements'] = glmCaseDict[ last_key]['voltage_measurements'] + '{:s},{:d},'.format( config_data['EOL_points'][x][0], config_data['EOL_points'][x][2]) else: glmCaseDict[last_key]['voltage_measurements'] = glmCaseDict[ last_key]['voltage_measurements'] + '{:s},{:d}"'.format( config_data['EOL_points'][x][0], config_data['EOL_points'][x][2]) last_key += 1 # Add substation swing bus and substation transformer dictionaries #TMH - any values that we want to bus.py to measure from the swing bus need to be added here (e.g., 'measured_power' : '0', glmCaseDict[last_key] = { 'object': 'meter', 'name': 'network_node', 'bustype': 'SWING', 'nominal_voltage': '{}'.format(config_data['nom_volt']), 'phases': 'ABCN', 'measured_power': '0', 'measured_current_A': '0', 'measured_current_B': '0', 'measured_current_C': '0' } # Add transmission voltage players parent_key = last_key last_key += 1 if config_data["voltage_players"][0] is not None: glmCaseDict[last_key] = { 'object': 'player', 'property': 'voltage_A', 'parent': '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop': '10', 'file': '{:s}'.format(config_data["voltage_players"][0]) } last_key += 1 if config_data["voltage_players"][1] is not None: glmCaseDict[last_key] = { 'object': 'player', 'property': 'voltage_B', 'parent': '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop': '10', 'file': '{:s}'.format(config_data["voltage_players"][1]) } last_key += 1 if config_data["voltage_players"][2] is not None: glmCaseDict[last_key] = { 'object': 'player', 'property': 'voltage_C', 'parent': '{:s}'.format(glmCaseDict[parent_key]['name']), 'loop': '10', 'file': '{:s}'.format(config_data["voltage_players"][2]) } last_key += 1 glmCaseDict[last_key] = { 'object': 'transformer', 'name': 'substation_transformer', 'from': 'network_node', 'to': '{:s}'.format(swing_bus_name), 'phases': 'ABCN', 'configuration': 'trans_config_to_feeder' } last_key += 1 # Copy static powerflow model glm dictionary into case dictionary for x in glmDict: # skip clocks, since already added one if 'clock' in glmDict[x]: continue glmCaseDict[last_key] = copy.deepcopy(glmDict[x]) # Remove original swing bus from static model if 'bustype' in glmCaseDict[last_key] and glmCaseDict[last_key][ 'bustype'] == 'SWING': swing_node = glmCaseDict[last_key]['name'] del glmCaseDict[last_key]['bustype'] glmCaseDict[last_key]['object'] = 'meter' last_key += 1 # Add groupid's to lines and transformers for x in glmCaseDict: if 'object' in glmCaseDict[x]: if re.match("triplex_line.*", glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Triplex_Line' elif re.match("transformer.*", glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Distribution_Trans' elif re.match("overhead_line.*", glmCaseDict[x]['object']) or re.match( "underground_line.*", glmCaseDict[x]['object']): glmCaseDict[x]['groupid'] = 'Distribution_Line' # Create dictionary that houses the number of commercial 'load' objects where commercial house objects will be tacked on. commercial_dict = {} if use_flags['use_commercial'] == 1: commercial_key = 0 to_remove = [] for x in glmCaseDict: if 'object' in glmCaseDict[x] and re.match( "load.*", glmCaseDict[x]['object']): commercial_dict[commercial_key] = { 'name': glmCaseDict[x]['name'], 'parent': 'None', 'load_classification': 'None', 'load': [0, 0, 0], 'number_of_houses': [0, 0, 0], #[phase A, phase B, phase C] 'nom_volt': glmCaseDict[x]['nominal_voltage'], 'phases': glmCaseDict[x]['phases'] } if 'parent' in glmCaseDict[x]: commercial_dict[commercial_key]['parent'] = glmCaseDict[x][ 'parent'] if 'load_class' in glmCaseDict[x]: commercial_dict[commercial_key][ 'load_classification'] = glmCaseDict[x]['load_class'] # Figure out how many houses should be attached to this load object # First determine the total ZIP load for each phase load_A, load_B, load_C = helpers.calculate_load_by_phase( glmCaseDict[x], 'real') commercial_dict[commercial_key]['load'][0] = load_A commercial_dict[commercial_key]['load'][1] = load_B commercial_dict[commercial_key]['load'][2] = load_C # TODO: Bypass this if load rating is known # Determine load_rating total_load = (load_A + load_B + load_C) / 1000.0 load_rating, load_rating_index = helpers.get_transformer_size( total_load, config_data['standard_transformer_ratings'], config_data['tranformer_oversize_factor']) commercial_dict[commercial_key]['load_rating'] = load_rating # Deterimine load classification load_class = None if commercial_dict[commercial_key][ 'load_classification'].isdigit(): load_class = int( commercial_dict[commercial_key]['load_classification']) else: # load_classification is unknown determine from no_houses and transformer size random_class_number = random.random() * 100 cum_perc = 0 for i, perc in enumerate([ one_load_class[load_rating_index] for one_load_class in config_data['comm_load_class_dists'] ]): if cum_perc < random_class_number <= cum_perc + perc: load_class = 6 + i break cum_perc += perc assert load_class is not None commercial_dict[commercial_key][ 'load_classification'] = load_class # print('Replacing {:.0f} kW with buildings of type {}, on a transformer rated at {} kW.'.format( # total_load, # config_data["load_classifications"][load_class], # load_rating)) # Remove load (used to be changed into a node, but then the node was dangling) to_remove.append(x) # if load parented by meter ... meter_key = glmCaseDict.get_parent_key(x, 'meter') if meter_key is not None: transformer_key = glmCaseDict.get_connector_by_to_node( meter_key, 'transformer') if transformer_key is not None and 'phases' in glmCaseDict[ transformer_key]: phases = glmCaseDict[transformer_key]['phases'] m = re.match("(A|B|C|AB|AC|BC|ABC)N", phases) if m is not None: phase = m.group(1) # ... and the structure is what we expect, swap out the transformer for an overhead_line glmCaseDict[transformer_key][ 'object'] = 'overhead_line' glmCaseDict[transformer_key]['length'] = '50ft' glmCaseDict[transformer_key][ 'configuration'] = 'line_configuration_comm{:s}'.format( phase) glmCaseDict[transformer_key][ 'groupid'] = 'Distribution_Line' commercial_key += 1 for x in to_remove: del glmCaseDict[x] # Create dictionary that houses the number of residential 'load' objects where residential house objects will be tacked on. residential_dict = {} if use_flags['use_homes'] == 1: residential_key = 0 to_remove = [] for x in glmCaseDict: if 'object' in glmCaseDict[x] and re.match( "triplex_node.*", glmCaseDict[x]['object']): if 'power_1' in glmCaseDict[x] or 'power_12' in glmCaseDict[x]: residential_dict[residential_key] = { 'name': glmCaseDict[x]['name'], 'parent': 'None', 'load_classification': 'None', 'number_of_houses': 0, 'load': 0, 'large_vs_small': 0.0, 'phases': glmCaseDict[x]['phases'] } if 'parent' in glmCaseDict[x]: residential_dict[residential_key][ 'parent'] = glmCaseDict[x]['parent'] if 'load_class' in glmCaseDict[x]: residential_dict[residential_key][ 'load_classification'] = glmCaseDict[x][ 'load_class'] # Figure out how many houses should be attached to this load object # First determine the total ZIP load load = helpers.calculate_load(glmCaseDict[x], 'real') c_load = helpers.calculate_load(glmCaseDict[x], 'complex') residential_dict[residential_key]['load'] = load residential_dict[residential_key]['complex_load'] = c_load # Determine load_rating total_load = load / 1000 # kW load_rating, load_rating_index = helpers.get_transformer_size( total_load, config_data['standard_transformer_ratings'], config_data['tranformer_oversize_factor']) residential_dict[residential_key][ 'load_rating'] = load_rating # Deterimine load classification load_class = None if residential_dict[residential_key][ 'load_classification'].isdigit(): load_class = int(residential_dict[residential_key] ['load_classification']) else: # load_classification is unknown. determine from no_houses and transformer size residential_dict[residential_key][ 'load_classification'] = None random_class_number = random.random() * 100 load_class = None cum_perc = 0 for i, perc in enumerate([ one_load_class[load_rating_index] for one_load_class in config_data['res_load_class_dists'] ]): if cum_perc < random_class_number <= cum_perc + perc: load_class = i break cum_perc += perc assert load_class is not None residential_dict[residential_key][ 'load_classification'] = load_class # print('Replacing {:.0f} kW with houses of type {}, on a transformer rated at {} kW.'.format( # total_load, # config_data["load_classifications"][load_class], # load_rating)) # Remove constant load keys if 'load_class' in glmCaseDict[x]: del glmCaseDict[x][ 'load_class'] # Must remove load_class as it isn't a published property if 'power_12' in glmCaseDict[x]: del glmCaseDict[x]['power_12'] if 'power_1' in glmCaseDict[x]: del glmCaseDict[x]['power_1'] residential_key += 1 # Calculate some random numbers needed for TOU/CPP and DLC technologies if use_flags['use_market'] != 0: # Initialize psuedo-random seed random.seed(2) if config_data["fix_random_seed"] else random.seed() if len(residential_dict) > 0: # Initialize random number arrays market_penetration_random = [] dlc_rand = [] pool_pump_recovery_random = [] slider_random = [] comm_slider_random = [] dlc_c_rand = [] dlc_c_rand2 = [] # Make a large array so we don't run out if len(residential_dict) > 0: aa = len( residential_dict ) * 100 # was total_house_number -- just guessing at a big enough maximum number for x in range(aa): market_penetration_random.append(random.random()) dlc_rand.append( random.random()) # Used for dlc randomization # 10 - 25% increase over normal cycle pool_pump_recovery_random.append(0.1 + 0.15 * random.random()) # Limit slider randomization to Olypen style slider_random.append(random.normalvariate(0.45, 0.2)) if slider_random[x] > tech_data['market_info'][4]: slider_random[x] = tech_data['market_info'][4] if slider_random[x] < 0: slider_random[x] = 0 # Random elasticity values for responsive loads - this is a multiplier # used to randomized individual building responsiveness - very similar # to a lognormal, so we'll use one that has a mean of ~1, max of # ~1.2, and median of ~1.12 sigma = 1.2 mu = 0.7 multiplier = 3.6 xval = [] elasticity_random = [] for x in range(aa): xval.append(random.random()) elasticity_random.append( multiplier * math.exp(-1 / (2 * pow(sigma, 2))) * pow( (math.log(xval[x]) - mu), 2) / (xval[x] * sigma * math.sqrt(2 * math.pi))) if len(commercial_dict) > 0: aa = len(commercial_dict) * 15 * 100 for x in range(aa): # Limit slider randomization to Olypen style comm_slider_random.append(random.normalvariate(0.45, 0.2)) if comm_slider_random[x] > tech_data['market_info'][4]: comm_slider_random[x] = tech_data['market_info'][4] if comm_slider_random[x] < 0: comm_slider_random[x] = 0 dlc_c_rand.append(random.random()) dlc_c_rand2.append(random.random()) else: market_penetration_random = None dlc_rand = None pool_pump_recovery_random = None slider_random = None comm_slider_random = None dlc_c_rand = None dlc_c_rand2 = None xval = None elasticity_random = None else: market_penetration_random = None dlc_rand = None pool_pump_recovery_random = None slider_random = None comm_slider_random = None dlc_c_rand = None dlc_c_rand2 = None xval = None elasticity_random = None # Tack on residential loads solar_residential_array = [0, [], []] if use_flags['use_homes'] != 0: if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict, last_key = AddLoadShapes.add_normalized_residential_ziploads( glmCaseDict, residential_dict, config_data, last_key) else: glmCaseDict, solar_residential_array, ts_residential_array, last_key = ResidentialLoads.append_residential( glmCaseDict, use_flags, config_data, tech_data, residential_dict, last_key, CPP_flag_name, market_penetration_random, dlc_rand, pool_pump_recovery_random, slider_random, xval, elasticity_random, io_opts['dir'], io_opts['resources_dir']) # End addition of residential loads ######################################################################################################################## solar_office_array = [0, [], []] solar_bigbox_array = [0, [], []] solar_stripmall_array = [0, [], []] if use_flags['use_commercial'] != 0: if use_flags['use_normalized_loadshapes'] == 1: glmCaseDict, last_key = AddLoadShapes.add_normalized_commercial_ziploads( glmCaseDict, commercial_dict, config_data, last_key) else: glmCaseDict, solar_office_array, solar_bigbox_array, solar_stripmall_array, ts_office_array, \ ts_bigbox_array, ts_stripmall_array, last_key = CommercialLoads.append_commercial( glmCaseDict, use_flags, config_data, tech_data, last_key, commercial_dict, comm_slider_random, dlc_c_rand, dlc_c_rand2, io_opts['dir'], io_opts['resources_dir']) # Append Solar: Call append_solar(feeder_dict, use_flags, config_file, solar_bigbox_array, solar_office_array, solar_stripmall_array, solar_residential_array, last_key) if use_flags['use_solar'] != 0 or use_flags[ 'use_solar_res'] != 0 or use_flags['use_solar_com'] != 0: glmCaseDict = Solar_Technology.Append_Solar(glmCaseDict, use_flags, config_data, tech_data, last_key) # Append recorders glmCaseDict, last_key = AddTapeObjects.add_recorders( glmCaseDict, io_opts, time_opts, last_key) return (glmCaseDict, last_key)