def __init__(self, site: SiteInfo, system_capacity_kw: float, detailed_not_simple: bool = False): """ :param system_capacity_kw: :param detailed_not_simple: Detailed model uses Pvsamv1, simple uses PVWatts """ self.detailed_not_simple: bool = detailed_not_simple if not detailed_not_simple: system_model = Pvwatts.default("PVWattsSingleOwner") financial_model = Singleowner.from_existing( system_model, "PVWattsSingleOwner") else: system_model = Pvsam.default("FlatPlatePVSingleOwner") financial_model = Singleowner.from_existing( system_model, "FlatPlatePVSingleOwner") super().__init__("SolarPlant", site, system_model, financial_model) self.system_model.SolarResource.solar_resource_data = self.site.solar_resource.data self.system_capacity_kw: float = system_capacity_kw
def test_reopt_sizing_pvsam(solar_resource): import PySAM.Utilityrate5 as ur sys = pvsam.default("FlatPlatePVCommercial") fin = ur.from_existing(sys, "FlatPlatePVCommercial") bt = stbt.from_existing(sys, "GenericBatteryCommercial") sys.SolarResource.solar_resource_file = solar_resource bt.Load.crit_load = [0] * 8760 post = sys.Reopt_size_battery_post() assert('Scenario' in post['reopt_post']) assert(post['reopt_post']['Scenario']['Site']['latitude'] == pytest.approx(33.6, 0.1))
def run_generator(self): self.tech = 'pv' #used for system costs self.generator = pv.default('FlatPlatePVSingleOwner') self.generator.SolarResource.solar_resource_file = self.resource_file self._size_system() self.generator.SystemDesign.assign({ k: v for k, v in self.system_config['SystemDesign'].items() if k in list(self.generator.SystemDesign.export().keys()) }) self.generator.SystemDesign.system_capacity = self.fitted_capacity self.generator.SystemDesign.subarray1_backtrack - 0 self.generator.Lifetime.analysis_period = self.cambium.analysis_period #get analysis period from cambium, which accounts for retirement year self.generator.Lifetime.system_use_lifetime_output = 1 self.generator.Lifetime.dc_degradation = [config.DEGRADATION * 100] self.generator.execute()
def gcr_func(x, y): # set up base a = Pvsamv1.default("FlatPlatePVSingleowner") a.SolarResource.solar_resource_file = "../sam/deploy/solar_resource/tucson_az_32.116521_-110.933042_psmv3_60_tmy.csv" b = Singleowner.default("FlatPlatePVSingleowner") # set up shading a.Shading.subarray1_shade_mode = 1 a.Layout.subarray1_nmodx = 12 a.Layout.subarray1_nmody = 2 a.SystemDesign.subarray1_gcr = float(x) land_area = a.CECPerformanceModelWithModuleDatabase.cec_area * ( a.SystemDesign.subarray1_nstrings * a.SystemDesign.subarray1_modules_per_string) / x * 0.0002471 a.execute() # total_installed_cost = total_direct_cost + permitting_total + engr_total + grid_total + landprep_total + sales_tax_total + land_total b.SystemCosts.total_installed_cost += y * land_area * 1000 b.SystemOutput.gen = a.Outputs.gen b.execute() return b.Outputs.analysis_period_irr
def __init__(self, site: SiteInfo, pv_config: dict, detailed_not_simple: bool = False): """ :param pv_config: dict, with keys ('system_capacity_kw', 'layout_params') where 'layout_params' is of the SolarGridParameters type :param detailed_not_simple: Detailed model uses Pvsamv1, simple uses PVWatts """ if 'system_capacity_kw' not in pv_config.keys(): raise ValueError self._detailed_not_simple: bool = detailed_not_simple if not detailed_not_simple: system_model = Pvwatts.default("PVWattsSingleOwner") financial_model = Singleowner.from_existing(system_model, "PVWattsSingleOwner") else: system_model = Pvsam.default("FlatPlatePVSingleOwner") financial_model = Singleowner.from_existing(system_model, "FlatPlatePVSingleOwner") super().__init__("SolarPlant", site, system_model, financial_model) self._system_model.SolarResource.solar_resource_data = self.site.solar_resource.data self.dc_degradation = [0] params: Optional[PVGridParameters] = None if 'layout_params' in pv_config.keys(): params: PVGridParameters = pv_config['layout_params'] self._layout = PVLayout(site, system_model, params) self._dispatch: PvDispatch = None self.system_capacity_kw: float = pv_config['system_capacity_kw']
def create_model(ac_size=None, modules=None, inverters=None, racking_options=None, gcrs=None, azimuths=None, dcac_ratios=None, string_length=None): #create the new model model = pv.new() #define the module parameters to assign #weather file solar_resource = { 'solar_resource_file': r'C:\Users\jmarsnik\SAM Downloaded Weather Files\centralia_il_38.526099_-89.133204_psmv3_60_tmy.csv', 'albedo': [0.2 for c in range(0, 12)], 'use_wf_albedo': 1 } #module model definition module_model = { #0 for simple efficiency 'module_model': 0 } #inverter model definition inverter_model = { 'inverter_model': 0, 'inv_num_mppt': 1, 'mppt_hi_inverter': 1425, 'mppt_low_inverter': 850 } #now do our grid loop and update the module and inverter databases and build the system design/shading i = 0 model_dict = {} for module in modules: for inverter in inverters: for racking_option in racking_options: for gcr in gcrs: for azimuth in azimuths: for dcac_ratio in dcac_ratios: #to determine the number of strings, we need the dc to ac ratio, string length and module size string_size = string_length * module['size'] #module definition: module_specs = module['specs'] #inverter specifications: inverter_specs = inverter['specs'] inverter_ac_output = inverter_specs['inv_snl_paco'] #the amount of dc we can put on the inverter given the dcac_ratio inverter_dc_input = inverter_ac_output * dcac_ratio inv_num_strings = round(inverter_dc_input / string_size) #system design (takes in gcr, dcac, azimuth, etc.) inverter_count = round(ac_size / inverter_ac_output) total_strings = inv_num_strings * inverter_count system_design = define_system_design( inverter_count, azimuth, gcr, string_length, inverter_model['inv_num_mppt'], total_strings, ac_size) shading = define_shading() layout = define_layout(module_specs['spe_area']) losses = define_losses() adjustment_factors = define_adjustment_factors() #assign all of the model parameters, execute and get output model.SolarResource.assign(solar_resource) model.Module.assign(module_model) model.Inverter.assign(inverter_model) model.InverterCECDatabase.assign(inverter_specs) model.SimpleEfficiencyModuleModel.assign( module_specs) model.SystemDesign.assign(system_design) model.Shading.assign(shading) model.Losses.assign(losses) model.Layout.assign(layout) model.AdjustmentFactors.assign(adjustment_factors) model.execute() output = model.Outputs.export() model_name = f"{module['name']}_{inverter['name']}_{racking_option}_{gcr}_{azimuth}_{dcac_ratio}" model_energy = output['annual_energy'] model_dict[model_name] = model_energy print(f"{i} : {model_name} : {model_energy}") i += 1 max_energy_model = max(model_dict, key=model_dict.get) return max_energy_model
Most recently tested against PySAM 2.2 @author: brtietz """ import PySAM.Battery as battery_model import PySAM.Pvsamv1 as pvsam from PySAM.PySSC import * weather_file = sys.argv[1] # .csv weather file with tmy format analysis_period = 1 # years days_in_year = 365 # Create the detailed residential pv model using PySAM's defaults system_model = pvsam.default("FlatPlatePVResidential") # Create the battery model based on the PV defaults battery = battery_model.from_existing(system_model, "GenericBatteryResidential") # Default model does not include a weather file, so set that based on the command line path system_model.SolarResource.solar_resource_file = weather_file # 24 hours of dispatch data, duplicated for each day. Would need to extend daily_dispatch for subhourly lifetime_dispatch = [] daily_dispatch = [ 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -1, 0, 0, 0, 0, 2, 4, 2, 2, 0, 0, 0 ] # kW, negative is charging # Extend daily lists for entire analysis period for i in range(0, days_in_year * analysis_period):
#single owner model import PySAM.Pvsamv1 as pv model = pv.new() #weather file solar_resource = { 'solar_resource_file': r'C:\Users\jmarsnik\SAM Downloaded Weather Files\centralia_il_38.526099_-89.133204_psmv3_60_tmy.csv', 'albedo': [0.2 for c in range(0, 12)], 'use_wf_albedo': 1 } #module model module = {'module_model': 0} #simple efficiency module model simple_eff_module_model = { 'spe_a': -3.56, 'spe_area': 1.94236, 'spe_b': -0.075, 'spe_bifacial_ground_clearance_height': 0, 'spe_bifacial_transmission_factor': 0, 'spe_bifaciality': 0, 'spe_dT': 3, 'spe_eff0': 16.99, 'spe_eff1': 16.99, 'spe_eff2': 16.99, 'spe_eff3': 16.99, 'spe_eff4': 16.99, 'spe_fd': 0,