def test_sapm(): modules = sam_data["sandiamod"] module = modules.Canadian_Solar_CS5P_220M___2009_ sapm = pvsystem.sapm(module, irrad_data["dni"], irrad_data["dhi"], 25, am, aoi) sapm = pvsystem.sapm(module.to_dict(), irrad_data["dni"], irrad_data["dhi"], 25, am, aoi)
def test_sapm(): modules = sam_data['sandiamod'] module_parameters = modules['Canadian_Solar_CS5P_220M___2009_'] times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') irrad_data = pd.DataFrame({'dni':[0,1000], 'ghi':[0,600], 'dhi':[0,100]}, index=times) am = pd.Series([0, 2.25], index=times) aoi = pd.Series([180, 30], index=times) sapm = pvsystem.sapm(module_parameters, irrad_data['dni'], irrad_data['dhi'], 25, am, aoi) expected = pd.DataFrame(np.array( [[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 5.74526799, 5.12194115, 59.67914031, 48.41924255, 248.00051089, 5.61787615, 3.52581308, 1.12848138]]), columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx', 'effective_irradiance'], index=times) assert_frame_equal(sapm, expected) # just make sure it works with a dict input sapm = pvsystem.sapm(module_parameters.to_dict(), irrad_data['dni'], irrad_data['dhi'], 25, am, aoi)
def test_sapm(): modules = sam_data['sandiamod'] module_parameters = modules['Canadian_Solar_CS5P_220M___2009_'] times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') irrad_data = pd.DataFrame( { 'dni': [0, 1000], 'ghi': [0, 600], 'dhi': [0, 100] }, index=times) am = pd.Series([0, 2.25], index=times) aoi = pd.Series([180, 30], index=times) sapm = pvsystem.sapm(module_parameters, irrad_data['dni'], irrad_data['dhi'], 25, am, aoi) expected = pd.DataFrame(np.array([[0., 0., 0., 0., 0., 0., 0., 0.], [ 5.74526799, 5.12194115, 59.67914031, 48.41924255, 248.00051089, 5.61787615, 3.52581308, 1.12848138 ]]), columns=[ 'i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx', 'effective_irradiance' ], index=times) assert_frame_equal(sapm, expected) # just make sure it works with a dict input sapm = pvsystem.sapm(module_parameters.to_dict(), irrad_data['dni'], irrad_data['dhi'], 25, am, aoi)
def test_sapm(): modules = sam_data['sandiamod'] module = modules.Canadian_Solar_CS5P_220M___2009_ sapm = pvsystem.sapm(module, irrad_data.DNI, irrad_data.DHI, 25, am, aoi) sapm = pvsystem.sapm(module.to_dict(), irrad_data.DNI, irrad_data.DHI, 25, am, aoi)
def pvmodule_detail(request, pvmodule_id): pvmod = get_object_or_404(PVModule, pk=pvmodule_id) fieldnames = PVModule._meta.get_fields() pvmod_dict = {k.name: getattr(pvmod, k.name) for k in fieldnames} for k in ['IXO', 'IXXO', 'C4', 'C5', 'C6', 'C7']: if pvmod_dict[k] is None: pvmod_dict[k] = 0. celltemps = np.linspace(0, 100, 5) effirrad, celltemp = np.meshgrid(np.linspace(0.1, 1, 10), celltemps) results = sapm(effirrad, celltemp, pvmod_dict) eff = results['p_mp'] / effirrad / pvmod.Area * 100 / 1000 fig = figure( x_axis_label='effective irradiance, Ee [suns]', y_axis_label='efficiency [%]', title=pvmod.Name, plot_width=800, plot_height=600, sizing_mode='scale_width' ) r = fig.multi_line( effirrad.tolist(), eff.tolist(), color=cmap, line_width=4) legend = Legend(items=[ LegendItem(label='{:d} [C]'.format(int(ct)), renderers=[r], index=n) for n, ct in enumerate(celltemps)]) fig.add_layout(legend) plot_script, plot_div = components(fig) return render( request, 'pvmodule_detail.html', { 'path': request.path, 'pvmod': pvmod, 'plot_script': plot_script, 'plot_div': plot_div, 'pvmod_dict': pvmod_dict})
def test_sapm(sapm_module_params): times = pd.date_range(start='2015-01-01', periods=5, freq='12H') effective_irradiance = pd.Series([-1000, 500, 1100, np.nan, 1000], index=times) temp_cell = pd.Series([10, 25, 50, 25, np.nan], index=times) out = pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params) expected = pd.DataFrame(np.array( [[-5.0608322, -4.65037767, nan, nan, nan, -4.91119927, -4.15367716], [ 2.545575, 2.28773882, 56.86182059, 47.21121608, 108.00693168, 2.48357383, 1.71782772 ], [ 5.65584763, 5.01709903, 54.1943277, 42.51861718, 213.32011294, 5.52987899, 3.48660728 ], [nan, nan, nan, nan, nan, nan, nan], [nan, nan, nan, nan, nan, nan, nan]]), columns=[ 'i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx' ], index=times) assert_frame_equal(out, expected, check_less_precise=4) out = pvsystem.sapm(1000, 25, sapm_module_params) expected = OrderedDict() expected['i_sc'] = 5.09115 expected['i_mp'] = 4.5462909092579995 expected['v_oc'] = 59.260800000000003 expected['v_mp'] = 48.315600000000003 expected['p_mp'] = 219.65677305534581 expected['i_x'] = 4.9759899999999995 expected['i_xx'] = 3.1880204359100004 for k, v in expected.items(): assert_allclose(out[k], v, atol=1e-4) # just make sure it works with Series input pvsystem.sapm(effective_irradiance, temp_cell, pd.Series(sapm_module_params))
def gen_iec_61853_from_sapm(pvmodule): """ Generate an IEC 61853 test from Sandia Array Performance Model (sapm). :param pvmodule: PV module to be tested :type pvmodule: dict Module is a dictionary according to :def:`pvlib.pvsystem.sapm`. """ tc, irr = TEST_MAT return sapm(irr / 1000.0, tc, pvmodule)
def test_sapm(sapm_module_params): times = pd.DatetimeIndex(start='2015-01-01', periods=5, freq='12H') effective_irradiance = pd.Series([-1, 0.5, 1.1, np.nan, 1], index=times) temp_cell = pd.Series([10, 25, 50, 25, np.nan], index=times) out = pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params) expected = pd.DataFrame(np.array( [[ -5.0608322 , -4.65037767, nan, nan, nan, -4.91119927, -4.15367716], [ 2.545575 , 2.28773882, 56.86182059, 47.21121608, 108.00693168, 2.48357383, 1.71782772], [ 5.65584763, 5.01709903, 54.1943277 , 42.51861718, 213.32011294, 5.52987899, 3.48660728], [ nan, nan, nan, nan, nan, nan, nan], [ nan, nan, nan, nan, nan, nan, nan]]), columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'], index=times) assert_frame_equal(out, expected, check_less_precise=4) out = pvsystem.sapm(1, 25, sapm_module_params) expected = OrderedDict() expected['i_sc'] = 5.09115 expected['i_mp'] = 4.5462909092579995 expected['v_oc'] = 59.260800000000003 expected['v_mp'] = 48.315600000000003 expected['p_mp'] = 219.65677305534581 expected['i_x'] = 4.9759899999999995 expected['i_xx'] = 3.1880204359100004 for k, v in expected.items(): assert_allclose(out[k], v, atol=1e-4) # just make sure it works with a dict input pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params.to_dict())
def gen_iec_61853_from_sapm(pvmodule): """ Generate an IEC 61853 test from Sandia Array Performance Model (sapm). :param dict pvmodule: PV module to be tested :returns: a pandas dataframe with columns ``i_mp``, ``v_mp``, ``i_sc``, and ``v_oc`` and rows corresponding to the IEC61853 test conditions Module is a dictionary according to ``pvlib.pvsystem.sapm``. """ tc, irr = TEST_MAT return sapm(irr / 1000.0, tc, pvmodule)
def get_perfect_voltage_for_a_day(start, freq): """This method is used to build a pandas serie with voltage values. This serie has DateTime index and contains a value for every "freq" seconds during 24 hours starting from "start" date. There are several assumptions: 1. Location is Munich 2. A battery is pointing to the south, amount of blocks is 20 3. Sandia Module database is used 4. pvlib library is heavily used :param start: datetime. First timestamp in result series :param freq: str. How often voltage should be sampled :return: voltage : Series """ surface_tilt = _munich_location.latitude surface_azimuth = 180 # pointing south date_range = pd.date_range(start=start, end=start + dt.timedelta( hours=23, minutes=59, seconds=59), freq=freq, tz=_munich_location.tz) clearsky_estimations = _munich_location.get_clearsky(date_range) dni_extra = irradiance.extraradiation(date_range) solar_position = solarposition.get_solarposition( date_range, _munich_location.latitude, _munich_location.longitude) airmass = atmosphere.relativeairmass(solar_position['apparent_zenith']) pressure = atmosphere.alt2pres(_munich_location.altitude) am_abs = atmosphere.absoluteairmass(airmass, pressure) total_irrad = irradiance.total_irrad(surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth'], clearsky_estimations['dni'], clearsky_estimations['ghi'], clearsky_estimations['dhi'], dni_extra=dni_extra, model='haydavies') temps = pvsystem.sapm_celltemp(total_irrad['poa_global'], 0, 15) aoi = irradiance.aoi(surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth']) # add 0.0001 to avoid np.log(0) and warnings about that effective_irradiance = pvsystem.sapm_effective_irradiance( total_irrad['poa_direct'], total_irrad['poa_diffuse'], am_abs, aoi, _sandia_module) + 0.0001 sapm = pvsystem.sapm(effective_irradiance, temps['temp_cell'], _sandia_module) return sapm['p_mp'] * _module_count
def DC_out(solpos, poa_irrad, aoi, pvtemps): ## First calculate airmass airmass = atmosphere.relativeairmass(solpos['apparent_zenith']) ## Get list of modules sandia_modules = pvsystem.retrieve_sam('SandiaMod') ## Choose model (e.g. CS5P_220M___2009) sandia_module = sandia_modules.Canadian_Solar_CS5P_220M___2009_ ## Run SAPM model effective_irradiance = pvsystem.sapm_effective_irradiance( poa_irrad.poa_direct, poa_irrad.poa_diffuse, airmass, aoi, sandia_module) p_dc = pvsystem.sapm(effective_irradiance, pvtemps['temp_cell'], sandia_module) return (p_dc)
def __init__(self, panel=None, forecast_length=7, forecast_model=None): self.forecast_length = forecast_length if panel == None: self.panel = Panel() else: self.panel = panel if forecast_model == None: self.fm = GFS() else: self.fm = forecast_model self.start = pd.Timestamp(datetime.date.today(), tz=self.panel.tz) # today's date self.end = self.start + pd.Timedelta( days=forecast_length) # days from today print( "getting processed data with lat: %s, lng: %s, start:%s, end:%s" % (self.panel.latitude, self.panel.longitude, self.start, self.end)) # get forecast data forecast_data = self.fm.get_processed_data(self.panel.latitude, self.panel.longitude, self.start, self.end) ghi = forecast_data['ghi'] # get solar position time = forecast_data.index a_point = self.fm.location solpos = a_point.get_solarposition(time) # get PV(photovoltaic device) modules sandia_modules = pvsystem.retrieve_sam('SandiaMod') sandia_module = sandia_modules.Canadian_Solar_CS5P_220M___2009_ dni_extra = irradiance.get_extra_radiation( self.fm.time) # extra terrestrial radiation airmass = atmosphere.get_relative_airmass(solpos['apparent_zenith']) # POA: Plane Of Array: an image sensing device consisting of an array # (typically rectangular) of light-sensing pixels at the focal plane of a lens. # https://en.wikipedia.org/wiki/Staring_array # Diffuse sky radiation is solar radiation reaching the Earth's surface after # having been scattered from the direct solar beam by molecules or particulates # in the atmosphere. # https://en.wikipedia.org/wiki/Diffuse_sky_radiation poa_sky_diffuse = irradiance.haydavies(self.panel.surface_tilt, self.panel.surface_azimuth, forecast_data['dhi'], forecast_data['dni'], dni_extra, solpos['apparent_zenith'], solpos['azimuth']) # Diffuse reflection is the reflection of light or other waves or particles # from a surface such that a ray incident on the surface is scattered at many # angles rather than at just one angle as in the case of specular reflection. poa_ground_diffuse = irradiance.get_ground_diffuse( self.panel.surface_tilt, ghi, albedo=self.panel.albedo) # AOI: Angle Of Incidence aoi = irradiance.aoi(self.panel.surface_tilt, self.panel.surface_azimuth, solpos['apparent_zenith'], solpos['azimuth']) # irradiance is the radiant flux (power) received by a surface per unit area # https://en.wikipedia.org/wiki/Irradiance poa_irrad = irradiance.poa_components(aoi, forecast_data['dni'], poa_sky_diffuse, poa_ground_diffuse) temperature = forecast_data['temp_air'] wnd_spd = forecast_data['wind_speed'] # pvtemps: pv temperature pvtemps = pvsystem.sapm_celltemp(poa_irrad['poa_global'], wnd_spd, temperature) # irradiance actually used by PV effective_irradiance = pvsystem.sapm_effective_irradiance( poa_irrad.poa_direct, poa_irrad.poa_diffuse, airmass, aoi, sandia_module) # SAPM: Sandia PV Array Performance Model # https://pvpmc.sandia.gov/modeling-steps/2-dc-module-iv/point-value-models/sandia-pv-array-performance-model/ self.sapm_out = pvsystem.sapm(effective_irradiance, pvtemps['temp_cell'], sandia_module) sapm_inverters = pvsystem.retrieve_sam('sandiainverter') sapm_inverter = sapm_inverters[ 'ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_'] self.ac_power = pvsystem.snlinverter(self.sapm_out.v_mp, self.sapm_out.p_mp, sapm_inverter)
def basic_chain(times, latitude, longitude, module_parameters, inverter_parameters, irradiance=None, weather=None, surface_tilt=None, surface_azimuth=None, orientation_strategy=None, transposition_model='haydavies', solar_position_method='nrel_numpy', airmass_model='kastenyoung1989', altitude=None, pressure=None, **kwargs): """ An experimental function that computes all of the modeling steps necessary for calculating power or energy for a PV system at a given location. Parameters ---------- times : DatetimeIndex Times at which to evaluate the model. latitude : float. Positive is north of the equator. Use decimal degrees notation. longitude : float. Positive is east of the prime meridian. Use decimal degrees notation. module_parameters : None, dict or Series Module parameters as defined by the SAPM. inverter_parameters : None, dict or Series Inverter parameters as defined by the CEC. irradiance : None or DataFrame, default None If None, calculates clear sky data. Columns must be 'dni', 'ghi', 'dhi'. weather : None or DataFrame, default None If None, assumes air temperature is 20 C and wind speed is 0 m/s. Columns must be 'wind_speed', 'temp_air'. surface_tilt : None, float or Series, default None Surface tilt angles in decimal degrees. The tilt angle is defined as degrees from horizontal (e.g. surface facing up = 0, surface facing horizon = 90) surface_azimuth : None, float or Series, default None Surface azimuth angles in decimal degrees. The azimuth convention is defined as degrees east of north (North=0, South=180, East=90, West=270). orientation_strategy : None or str, default None The strategy for aligning the modules. If not None, sets the ``surface_azimuth`` and ``surface_tilt`` properties of the ``system``. Allowed strategies include 'flat', 'south_at_latitude_tilt'. Ignored for SingleAxisTracker systems. transposition_model : str, default 'haydavies' Passed to system.get_irradiance. solar_position_method : str, default 'nrel_numpy' Passed to solarposition.get_solarposition. airmass_model : str, default 'kastenyoung1989' Passed to atmosphere.relativeairmass. altitude : None or float, default None If None, computed from pressure. Assumed to be 0 m if pressure is also None. pressure : None or float, default None If None, computed from altitude. Assumed to be 101325 Pa if altitude is also None. **kwargs Arbitrary keyword arguments. See code for details. Returns ------- output : (dc, ac) Tuple of DC power (with SAPM parameters) (DataFrame) and AC power (Series). """ # use surface_tilt and surface_azimuth if provided, # otherwise set them using the orientation_strategy if surface_tilt is not None and surface_azimuth is not None: pass elif orientation_strategy is not None: surface_tilt, surface_azimuth = \ get_orientation(orientation_strategy, latitude=latitude) else: raise ValueError('orientation_strategy or surface_tilt and ' 'surface_azimuth must be provided') times = times if altitude is None and pressure is None: altitude = 0. pressure = 101325. elif altitude is None: altitude = atmosphere.pres2alt(pressure) elif pressure is None: pressure = atmosphere.alt2pres(altitude) solar_position = solarposition.get_solarposition( times, latitude, longitude, altitude=altitude, pressure=pressure, method=solar_position_method, **kwargs) # possible error with using apparent zenith with some models airmass = atmosphere.get_relative_airmass( solar_position['apparent_zenith'], model=airmass_model) airmass = atmosphere.get_absolute_airmass(airmass, pressure) dni_extra = pvlib.irradiance.get_extra_radiation(solar_position.index) aoi = pvlib.irradiance.aoi(surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth']) if irradiance is None: linke_turbidity = clearsky.lookup_linke_turbidity( solar_position.index, latitude, longitude) irradiance = clearsky.ineichen(solar_position['apparent_zenith'], airmass, linke_turbidity, altitude=altitude, dni_extra=dni_extra) total_irrad = pvlib.irradiance.get_total_irradiance( surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth'], irradiance['dni'], irradiance['ghi'], irradiance['dhi'], model=transposition_model, dni_extra=dni_extra) if weather is None: weather = {'wind_speed': 0, 'temp_air': 20} temps = pvsystem.sapm_celltemp(total_irrad['poa_global'], weather['wind_speed'], weather['temp_air']) effective_irradiance = pvsystem.sapm_effective_irradiance( total_irrad['poa_direct'], total_irrad['poa_diffuse'], airmass, aoi, module_parameters) dc = pvsystem.sapm(effective_irradiance, temps['temp_cell'], module_parameters) ac = pvsystem.snlinverter(dc['v_mp'], dc['p_mp'], inverter_parameters) return dc, ac
def basic_chain(times, latitude, longitude, module_parameters, inverter_parameters, irradiance=None, weather=None, surface_tilt=None, surface_azimuth=None, orientation_strategy=None, transposition_model='haydavies', solar_position_method='nrel_numpy', airmass_model='kastenyoung1989', altitude=None, pressure=None, **kwargs): """ An experimental function that computes all of the modeling steps necessary for calculating power or energy for a PV system at a given location. Parameters ---------- times : DatetimeIndex Times at which to evaluate the model. latitude : float. Positive is north of the equator. Use decimal degrees notation. longitude : float. Positive is east of the prime meridian. Use decimal degrees notation. module_parameters : None, dict or Series Module parameters as defined by the SAPM. inverter_parameters : None, dict or Series Inverter parameters as defined by the CEC. irradiance : None or DataFrame If None, calculates clear sky data. Columns must be 'dni', 'ghi', 'dhi'. weather : None or DataFrame If None, assumes air temperature is 20 C and wind speed is 0 m/s. Columns must be 'wind_speed', 'temp_air'. surface_tilt : float or Series Surface tilt angles in decimal degrees. The tilt angle is defined as degrees from horizontal (e.g. surface facing up = 0, surface facing horizon = 90) surface_azimuth : float or Series Surface azimuth angles in decimal degrees. The azimuth convention is defined as degrees east of north (North=0, South=180, East=90, West=270). orientation_strategy : None or str The strategy for aligning the modules. If not None, sets the ``surface_azimuth`` and ``surface_tilt`` properties of the ``system``. transposition_model : str Passed to system.get_irradiance. solar_position_method : str Passed to location.get_solarposition. airmass_model : str Passed to location.get_airmass. altitude : None or float If None, computed from pressure. Assumed to be 0 m if pressure is also None. pressure : None or float If None, computed from altitude. Assumed to be 101325 Pa if altitude is also None. **kwargs Arbitrary keyword arguments. See code for details. Returns ------- output : (dc, ac) Tuple of DC power (with SAPM parameters) (DataFrame) and AC power (Series). """ # use surface_tilt and surface_azimuth if provided, # otherwise set them using the orientation_strategy if surface_tilt is not None and surface_azimuth is not None: pass elif orientation_strategy is not None: surface_tilt, surface_azimuth = \ get_orientation(orientation_strategy, latitude=latitude) else: raise ValueError('orientation_strategy or surface_tilt and ' + 'surface_azimuth must be provided') times = times if altitude is None and pressure is None: altitude = 0. pressure = 101325. elif altitude is None: altitude = atmosphere.pres2alt(pressure) elif pressure is None: pressure = atmosphere.alt2pres(altitude) solar_position = solarposition.get_solarposition(times, latitude, longitude, altitude=altitude, pressure=pressure, **kwargs) # possible error with using apparent zenith with some models airmass = atmosphere.relativeairmass(solar_position['apparent_zenith'], model=airmass_model) airmass = atmosphere.absoluteairmass(airmass, pressure) dni_extra = pvlib.irradiance.extraradiation(solar_position.index) dni_extra = pd.Series(dni_extra, index=solar_position.index) aoi = pvlib.irradiance.aoi(surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth']) if irradiance is None: irradiance = clearsky.ineichen( solar_position.index, latitude, longitude, zenith_data=solar_position['apparent_zenith'], airmass_data=airmass, altitude=altitude) total_irrad = pvlib.irradiance.total_irrad( surface_tilt, surface_azimuth, solar_position['apparent_zenith'], solar_position['azimuth'], irradiance['dni'], irradiance['ghi'], irradiance['dhi'], model=transposition_model, dni_extra=dni_extra) if weather is None: weather = {'wind_speed': 0, 'temp_air': 20} temps = pvsystem.sapm_celltemp(total_irrad['poa_global'], weather['wind_speed'], weather['temp_air']) dc = pvsystem.sapm(module_parameters, total_irrad['poa_direct'], total_irrad['poa_diffuse'], temps['temp_cell'], airmass, aoi) ac = pvsystem.snlinverter(inverter_parameters, dc['v_mp'], dc['p_mp']) return dc, ac
def forecast_dc_power(poa_irrad, airmass, aoi, pvmodule, pvtemp): # Run the SAPM using the parameters we calculated above. effective_irradiance = pvsystem.sapm_effective_irradiance(poa_irrad.poa_direct, poa_irrad.poa_diffuse, airmass, aoi, pvmodule) sapm_out = pvsystem.sapm(effective_irradiance, pvtemp, pvmodule) return sapm_out
def simulate_power_by_station(station_index, surface_tilt, surface_azimuth, pv_module, tcell_model_parameters, ghi, tamb, wspd, albedo, days, lead_times, air_mass, dni_extra, zenith, apparent_zenith, azimuth): """ This is the worker function for simulating power at a specified location. This function should be used inside of `simulate_power` and direct usage is discouraged. :param station_index: A station index :param ghi: See `simulate_power` :param tamb: See `simulate_power` :param wspd: See `simulate_power` :param albedo: See `simulate_power` :param days: See `simulate_power` :param lead_times: See `simulate_power` :param air_mass: See `simulate_power` :param dni_extra: See `simulate_power` :param zenith: See `simulate_power` :param apparent_zenith: See `simulate_power` :param azimuth: See `simulate_power` :param surface_tilt: See `simulate_power` :param surface_azimuth: See `simulate_power` :param pv_module: A PV module name :param tcell_model_parameters: A cell module name :return: A list with power, cell temperature, and the effective irradiance """ # Sanity check assert 0 <= station_index < ghi.shape[3], 'Invalid station index' # Determine the dimensions num_analogs = ghi.shape[0] num_lead_times = ghi.shape[1] num_days = ghi.shape[2] # Initialization p_mp = np.zeros((num_analogs, num_lead_times, num_days)) tcell = np.zeros((num_analogs, num_lead_times, num_days)) effective_irradiance = np.zeros((num_analogs, num_lead_times, num_days)) pv_module = pvsystem.retrieve_sam("SandiaMod")[pv_module] tcell_model_parameters = temperature.TEMPERATURE_MODEL_PARAMETERS["sapm"][ tcell_model_parameters] for day_index in range(num_days): for lead_time_index in range(num_lead_times): # Determine the current time current_posix = days[day_index] + lead_times[lead_time_index] current_time = pd.Timestamp(current_posix, tz="UTC", unit='s') for analog_index in range(num_analogs): ghi_ = ghi[analog_index, lead_time_index, day_index, station_index] if ghi_ == 0: continue albedo_ = albedo[analog_index, lead_time_index, day_index, station_index] wspd_ = wspd[analog_index, lead_time_index, day_index, station_index] tamb_ = tamb[analog_index, lead_time_index, day_index, station_index] air_mass_ = air_mass[lead_time_index, day_index, station_index] dni_extra_ = dni_extra[lead_time_index, day_index, station_index] zenith_ = zenith[lead_time_index, day_index, station_index] apparent_zenith_ = apparent_zenith[lead_time_index, day_index, station_index] azimuth_ = azimuth[lead_time_index, day_index, station_index] ########################################################################################## # # # Core procedures of simulating power at one location # # # ########################################################################################## # Decompose DNI from GHI dni_dict = irradiance.disc(ghi_, zenith_, current_time) # Calculate POA sky diffuse poa_sky_diffuse = irradiance.haydavies( surface_tilt, surface_azimuth, ghi_, dni_dict["dni"], dni_extra_, apparent_zenith_, azimuth_) # Calculate POA ground diffuse poa_ground_diffuse = irradiance.get_ground_diffuse( surface_tilt, ghi_, albedo_) # Calculate angle of incidence aoi = irradiance.aoi(surface_tilt, surface_azimuth, apparent_zenith_, azimuth_) # Calculate POA total poa_irradiance = irradiance.poa_components( aoi, dni_dict["dni"], poa_sky_diffuse, poa_ground_diffuse) # Calculate cell temperature tcell[analog_index, lead_time_index, day_index] = pvsystem.temperature.sapm_cell( poa_irradiance['poa_global'], tamb_, wspd_, tcell_model_parameters['a'], tcell_model_parameters['b'], tcell_model_parameters["deltaT"]) # Calculate effective irradiance effective_irradiance[ analog_index, lead_time_index, day_index] = pvsystem.sapm_effective_irradiance( poa_irradiance['poa_direct'], poa_irradiance['poa_diffuse'], air_mass_, aoi, pv_module) # Calculate power sapm_out = pvsystem.sapm( effective_irradiance[analog_index, lead_time_index, day_index], tcell[analog_index, lead_time_index, day_index], pv_module) # Save output to numpy p_mp[analog_index, lead_time_index, day_index] = sapm_out["p_mp"] return [p_mp, tcell, effective_irradiance]
forecast_data['dhi'], forecast_data['dni'], dni_extra, solpos['apparent_zenith'], solpos['azimuth']) poa_ground_diffuse = irradiance.get_ground_diffuse(surface_tilt, ghi, albedo=albedo) aoi = irradiance.aoi(surface_tilt, surface_azimuth, solpos['apparent_zenith'], solpos['azimuth']) poa_irrad = irradiance.poa_components(aoi, forecast_data['dni'], poa_sky_diffuse, poa_ground_diffuse) temperature = forecast_data['temp_air'] wnd_spd = forecast_data['wind_speed'] pvtemps = pvsystem.sapm_celltemp(poa_irrad['poa_global'], wnd_spd, temperature) effective_irradiance = pvsystem.sapm_effective_irradiance(poa_irrad.poa_direct, poa_irrad.poa_diffuse, airmass, aoi, sandia_module) sapm_out = pvsystem.sapm(effective_irradiance, pvtemps['temp_cell'], sandia_module) # print(sapm_out.head()) print(sapm_out['p_mp']) plot = "pop" # sapm_out[['p_mp']].plot() # plt.ylabel('DC Power (W)') # plot = plt.savefig('tmp.png') # sapm_inverters = pvsystem.retrieve_sam('sandiainverter') # sapm_inverter = sapm_inverters['ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_'] # p_ac = pvsystem.snlinverter(sapm_out.v_mp, sapm_out.p_mp, sapm_inverter) # # p_ac.plot() # plt.ylabel('AC Power (W)') # plt.ylim(0, None)