Background
Traditionally I've used NREL SAM tool to estimate solar output. I've been experimenting with PVLIB which is great due to the open nature and flexibility, however I can't seem to reconcile the solar production estimates between PVLIB and NREL SAM.
What I've done
I'm modeling a hypothetical solar farm near Gympie QLD. I've gone to the climate.onebuiling website, and downloaded the zip folder / epw file for "AUS_QLD_Gympie.AP.945660_TMYx.2003-2017". I've then used that weather file in NREL's SAM tool using PVwatts, with the following specs;
- 200,000 KWdc
- Module Type = Standard
- 1.2 DC to AC Ratio
- 96% inverter efficiency
- 1 axis backtracking
- tilt = 26 degrees
- azimuth = 0 degrees
- GCR = 0.4
- losses, shading & curtailment = default
In NREL SAM i get an annual Energy Yield (AC GWh) of 415.96 GWh p.a.
I then took that same epw file and converted it to a csv, keeping just the columns for ghi, dni, dhi, temp_air & wind_speed (Google Drive link to CSV file). I've used this file as an import into PVLIB. I spec'd a PVLIB system the same specs above, with addition of albedo = 0.2 and max angle = 90 degrees (Code Below).
The result I get in PVLIB is 395.61 GWh.
Problem
The results I got are pretty different. PVLIB = ~395 GWh p.a. vs SAM = ~415 GWH p.a. I expected around a 1-2% difference, but not 5%.
Figures are even worse when I compare to a PVLIB system using clearsky.ineichen (adjusted with linke_turbidity) which yields ~475 GWh p.a.
Help Requested
Anyone know why my results are so different? is there anything I can do to narrow the gap?
PVLIB Code
# **********************************************************
# IMPORT LIBRARIES
# **********************************************************
import pandas as pd
from pvlib.pvsystem import PVSystem
from pvlib import clearsky, atmosphere, solarposition, irradiance
from pvlib.location import Location
from pvlib.tracking import SingleAxisTracker
from pvlib.modelchain import ModelChain
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
# **********************************************************
# LOCATION & SOLAR SIZE INPUTS
# **********************************************************
# Lat and Long desired
lat = -26.18
lon = 152.63
# Set Location
tz, altitude, name = 'Australia/Queensland', 10, 'Gympie/QLD'
# Set location details for model
latitude, longitude, = lat, lon
location = Location(latitude, longitude, tz, altitude, name)
# load some module and inverter specifications
module_parameters = {'pdc0': 200000000, 'gamma_pdc': -0.004}
inverter_parameters = {'pdc': 166666666, 'pdc0': 166666666, 'eta_inv_nom': 0.96}
temperature_model_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
# **********************************************************
# ONEBUILDING DATA
# **********************************************************
df = pd.read_csv('weather import.csv')
df['time'] = df['time'].astype('datetime64[ns]')
df.set_index(['time'], inplace=True)
df.index = df.index.tz_localize(tz=tz)
df = df.asfreq(freq='1h')
onebuilding = df
# **********************************************************
# INEICHEN CLEAR SKIES ADJUSTED FOR TURBIDITY
# **********************************************************
# Create PVLib inputs
times = df.index
solpos = solarposition.get_solarposition(times, latitude, longitude)
apparent_zenith = solpos['zenith']
rel_airmass = atmosphere.get_relative_airmass(apparent_zenith)
pressure = atmosphere.alt2pres(altitude)
abs_airmass = atmosphere.get_absolute_airmass(rel_airmass, pressure)
linke_turbidity = clearsky.lookup_linke_turbidity(times, latitude, longitude)
dni_extra = irradiance.get_extra_radiation(times)
ineichen = clearsky.ineichen(apparent_zenith, abs_airmass, linke_turbidity, altitude, dni_extra)
ineichen.to_csv('ineichen.csv')
# **********************************************************
# SELECT WHICH WEATHER DATA TO USE (ineichen v onebuilding)
# **********************************************************
# Select which version we wish to use (onebuilding, ineichen)
selected_irrad = onebuilding
print(selected_irrad)
# Create Weather File
weather = pd.DataFrame(data={'ghi': selected_irrad.ghi, 'dni': selected_irrad.dni,
'dhi': selected_irrad.dhi, 'temp_air': df['temp_air'],
'wind_speed': df['wind_speed']})
# **********************************************************
# CREATE PV SYSTEM AND PV MODEL CHAIN
# **********************************************************
# Define the specs for the PV System (fixed system)
f_system = PVSystem(
surface_tilt=abs(lat),
surface_azimuth=0,
albedo=0.2,
module='pvwatts_dc',
inverter='pvwatts_ac',
module_parameters=module_parameters,
inverter_parameters=inverter_parameters,
racking_model='open_rack_glass_glass',
name='fixed',
temperature_model_parameters=temperature_model_parameters
)
# Define the specs for the PV System (1 axis tracking system)
t_system = SingleAxisTracker(
axis_tilt=0,
axis_azimuth=0,
max_angle=90,
backtrack=True,
module='pvwatts_dc',
inverter='pvwatts_ac',
module_parameters=module_parameters,
inverter_parameters=inverter_parameters,
name='tracking',
gcr=.40,
)
# build model chain
mc = ModelChain(
system=t_system,
location=location,
name='pvwatts',
dc_model='pvwatts',
ac_model='pvwatts',
losses_model='pvwatts',
aoi_model='physical',
spectral_model='no_loss',
temperature_model='sapm')
# run model chain
mc.run_model(weather=weather)
print(mc.ac.sum())