def get_cell_temp(forecast_data, poa_irrad): # Calculate pv cell temperature ambient_temperature = forecast_data['temp_air'] wnd_spd = forecast_data['wind_speed'] thermal_params = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer'] pvtemp = temperature.sapm_cell(poa_irrad['poa_global'], ambient_temperature, wnd_spd, **thermal_params) return pvtemp
def test_sapm_ndarray(sapm_default): temps = np.array([0, 10, 5]) irrads = np.array([0, 500, 0]) winds = np.array([10, 5, 0]) cell_temps = temperature.sapm_cell(irrads, temps, winds, sapm_default['a'], sapm_default['b'], sapm_default['deltaT']) module_temps = temperature.sapm_module(irrads, temps, winds, sapm_default['a'], sapm_default['b']) expected_cell = np.array([0., 23.06066166, 5.]) expected_module = np.array([0., 21.56066166, 5.]) assert_allclose(expected_cell, cell_temps, 3) assert_allclose(expected_module, module_temps, 3)
def test_sapm_series(sapm_default): times = pd.date_range(start='2015-01-01', end='2015-01-02', freq='12H') temps = pd.Series([0, 10, 5], index=times) irrads = pd.Series([0, 500, 0], index=times) winds = pd.Series([10, 5, 0], index=times) cell_temps = temperature.sapm_cell(irrads, temps, winds, sapm_default['a'], sapm_default['b'], sapm_default['deltaT']) module_temps = temperature.sapm_module(irrads, temps, winds, sapm_default['a'], sapm_default['b']) expected_cell = pd.Series([0., 23.06066166, 5.], index=times) expected_module = pd.Series([0., 21.56066166, 5.], index=times) assert_series_equal(expected_cell, cell_temps) assert_series_equal(expected_module, module_temps)
def power_pvwatts(request, clearsky_july, solarposition_july): pdc0 = 100 pdc0_inverter = 110 tilt = 30 azimuth = 180 pdc0_marker = request.node.get_closest_marker("pdc0_inverter") if pdc0_marker is not None: pdc0_inverter = pdc0_marker.args[0] poa = irradiance.get_total_irradiance( tilt, azimuth, solarposition_july['zenith'], solarposition_july['azimuth'], **clearsky_july ) cell_temp = temperature.sapm_cell( poa['poa_global'], 25, 0, **TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass'] ) dc = pvsystem.pvwatts_dc(poa['poa_global'], cell_temp, pdc0, -0.004) return inverter.pvwatts(dc, pdc0_inverter)
def test_sapm_cell(sapm_default): default = temperature.sapm_cell(900, 20, 5, sapm_default['a'], sapm_default['b'], sapm_default['deltaT']) assert_allclose(default, 43.509, 3)
# Simulate some noise on the measured poa irradiance. poa_noise_level = 0.02 df['poa_meas'] = df['poa_actual'] * (1 + poa_noise_level * (np.random.random(df['ghi'].shape) - 0.5)) # estimate module/cell temperature df['temperature_module_actual'] = sapm_module(poa_global=df['poa_actual'], temp_air=df['temperature_air'], wind_speed=df['wind_speed'], a=-3.56, b=-0.075) df['temperature_cell_actual'] = sapm_cell(poa_global=df['poa_actual'], temp_air=df['temperature_air'], wind_speed=df['wind_speed'], a=-3.56, b=-0.075, deltaT=3) # "measured" module temperature has noise. temperature_noise_level = 2 df['temperature_module_meas'] = df['temperature_module_actual'] + ( np.random.random(df['ghi'].shape) - 0.5) * temperature_noise_level q = 1.60218e-19 # Elementary charge in units of coulombs kb = 1.38066e-23 # Boltzmann's constant in units of J/K # time vector in years t_years = (df.index - df.index[0]).days / 365
def basic_chain(times, latitude, longitude, module_parameters, temperature_model_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. See pvsystem.sapm for details. temperature_model_parameters : None, dict or Series. Temperature model parameters as defined by the SAPM. See temperature.sapm_cell for details. inverter_parameters : None, dict or Series Inverter parameters as defined by the CEC. See pvsystem.snlinverter for details. 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') 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} cell_temperature = temperature.sapm_cell( total_irrad['poa_global'], weather['temp_air'], weather['wind_speed'], temperature_model_parameters['a'], temperature_model_parameters['b'], temperature_model_parameters['deltaT']) effective_irradiance = pvsystem.sapm_effective_irradiance( total_irrad['poa_direct'], total_irrad['poa_diffuse'], airmass, aoi, module_parameters) dc = pvsystem.sapm(effective_irradiance, cell_temperature, module_parameters) ac = pvsystem.snlinverter(dc['v_mp'], dc['p_mp'], inverter_parameters) return dc, ac
def performance_ratio_nrel(poa_global, temp_air, wind_speed, pac, pdc0, a=-3.56, b=-0.075, deltaT=3, gamma_pdc=-0.00433): r""" Calculate NREL Performance Ratio. See equation [5] in Weather-Corrected Performance Ratio [1]_ for details on the weighted method for Tref. Parameters ---------- poa_global : numeric Total incident irradiance [W/m^2]. temp_air : numeric Ambient dry bulb temperature [C]. wind_speed : numeric Wind speed at a height of 10 meters [m/s]. pac : float AC power [kW]. pdc0 : float Power of the modules at 1000 W/m2 and cell reference temperature [kW]. a : float Parameter :math:`a` in SAPM model [unitless]. b : float Parameter :math:`b` in in SAPM model [s/m]. deltaT : float Parameter :math:`\Delta T` in SAPM model [C]. gamma_pdc : float The temperature coefficient in units of 1/C. Typically -0.002 to -0.005 per degree C [1/C]. Returns ------- performance_ratio: float Performance Ratio of data. References ---------- .. [1] Dierauf et al. "Weather-Corrected Performance Ratio". NREL, 2013. https://www.nrel.gov/docs/fy13osti/57991.pdf """ cell_temperature = sapm_cell(poa_global, temp_air, wind_speed, a, b, deltaT) tcell_poa_global = poa_global * cell_temperature tref = tcell_poa_global.sum() / poa_global.sum() pdc = pvwatts_dc(poa_global, cell_temperature, pdc0, gamma_pdc, temp_ref=tref) performance_ratio = pac.sum() / pdc.sum() return performance_ratio