Skip to content

ADR PV efficiency model from pvpltools-python #1572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
befa65e
Start with a copy of the code from adriesse/pvpltools-python.
adriesse Oct 14, 2022
0f3cfaa
Merge branch 'pvlib:main' into eta
adriesse Nov 16, 2022
411974c
Reduce scope of this PR to the ADR model.
adriesse Nov 22, 2022
527523b
Handle array-like inputs on all arguments.
adriesse Nov 22, 2022
ba8e14e
Substantial doc string edits.
adriesse Nov 22, 2022
3c9f05f
Rewrite fitting function, add tests and much more.
adriesse Nov 23, 2022
704cd78
Stickler
adriesse Nov 23, 2022
dd0ac02
Change rtol in tests.
adriesse Nov 23, 2022
3a0a39d
Stickler
adriesse Nov 23, 2022
29eb67d
First attempt at making an example for the gallery.
adriesse Nov 23, 2022
0027c95
Stickler in example; adjust numeric values in tests.
adriesse Nov 23, 2022
2a799d5
More experimenting with examples for th gallery. (Not for review yet.)
adriesse Nov 24, 2022
abe8456
Spruce up the examples some more and tweak the test tolerance again.
adriesse Nov 24, 2022
118e8b8
Making examples is actually pretty easy and fun.
adriesse Nov 24, 2022
5a9b7aa
Add a pair of utility functions.
adriesse Nov 24, 2022
227629d
Add a pair of utility functions.
adriesse Nov 24, 2022
f49ae85
Merge branch 'eta' of https://github.com/adriesse/pvlib-python into eta
adriesse Nov 24, 2022
75989d8
Minor rename
adriesse Nov 24, 2022
ee5be03
Simplify examples somewhat.
adriesse Nov 25, 2022
816e7d7
Undo utility functions.
adriesse Nov 25, 2022
b4304ae
More simplification.
adriesse Nov 25, 2022
172e5b1
Add new functions to the API reference under "PV Modeling/Other" (for…
adriesse Nov 25, 2022
8a3dae3
Rewrite simulation example and a few other little things.
adriesse Nov 27, 2022
9d0bf5c
Rewrite simulation example with tmy3 data and a few other little things.
adriesse Nov 27, 2022
447638f
Merge branch 'eta' of https://github.com/adriesse/pvlib-python into eta
adriesse Nov 27, 2022
c0807a9
csv -> CSV
adriesse Nov 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/examples/adr-pv-module-efficiency/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ADR Model for PV Module Efficiency
----------------------------------

110 changes: 110 additions & 0 deletions docs/examples/adr-pv-module-efficiency/plot_fit_to_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
Obtaining ADR model parameters from IEC 61853 matrix measurements
=================================================================

There's a fitting function provided in pvlib to do exactly that.

(WORK IN PROGRESS)

Since PV module efficiency varies with irradiance and temperature
what better way to train a model than using efficiency measurement
over a broad range of temperature and irradiance levels?
The standard IEC 61853-1 defines a standard matrix of conditions
for such measurements and this example shows how the ADR model
parameters can be determined with just a few lines of code using
functions in pvlib-python.

"""

from io import StringIO
import pandas as pd
import matplotlib.pyplot as plt

from pvlib.pvefficiency import adr, fit_pvefficiency_adr

# %% The text on this line is not displayed
#
# Here are some matrix measurements:
#

iec61853data = '''
irradiance temperature p_mp
0 100 15.0 30.159
1 200 15.0 63.057
2 400 15.0 129.849
3 600 15.0 197.744
4 800 15.0 264.825
5 1000 15.0 330.862
6 100 25.0 29.250
7 200 25.0 61.137
8 400 25.0 126.445
9 600 25.0 192.278
10 800 25.0 257.561
11 1000 25.0 322.305
12 1100 25.0 354.174
13 100 50.0 26.854
14 200 50.0 56.698
15 400 50.0 117.062
16 600 50.0 177.959
17 800 50.0 238.626
18 1000 50.0 298.954
19 1100 50.0 328.413
20 100 75.0 24.074
21 200 75.0 51.103
22 400 75.0 106.546
23 600 75.0 162.966
24 800 75.0 218.585
25 1000 75.0 273.651
26 1100 75.0 301.013
'''
df = pd.read_csv(StringIO(iec61853data), delim_whitespace=True)

# %%
#
# Now calculate the normalized or relative efficiency values
# and use the fitting function to determine the parameters.
# The parameters (shown below) can now be used to
# simulate the module operating in a PV system.
#

P_REF = 322.305 # (W) STC value from the table above
G_REF = 1000. # (W/m2)

df['eta_rel'] = (df['p_mp'] / P_REF) / (df['irradiance'] / G_REF)

adr_params = fit_pvefficiency_adr(df['irradiance'], df['temperature'],
df['eta_rel'])

for k, v in adr_params.items():
print('%-5s = %7.4f' % (k, v))

# %%
#
# Compare the model output to the original measurements.
# The chart below shows minor differences but due to their random nature
# they are most likely evidence of the limitations of measurement accuracy.
#

eta_rel_adr = adr(df['irradiance'], df['temperature'], **adr_params)

plt.figure()
plt.plot(df['irradiance'], df['eta_rel'], 'oc', ms=8)
plt.plot(df['irradiance'], eta_rel_adr, '.k')
plt.legend(['Lab measurements', 'ADR model fit'])
plt.xlabel('Irradiance [W/m²]')
plt.ylabel('Relative efficiency [-]')
plt.grid(alpha=0.5)
plt.show()

# %%
#
# References
# ----------
# .. [1] A. Driesse and J. S. Stein, "From IEC 61853 power measurements
# to PV system simulations", Sandia Report No. SAND2020-3877, 2020.
#
# .. [2] A. Driesse, M. Theristis and J. S. Stein, "A New Photovoltaic Module
# Efficiency Model for Energy Prediction and Rating," in IEEE Journal
# of Photovoltaics, vol. 11, no. 2, pp. 527-534, March 2021,
# doi: 10.1109/JPHOTOV.2020.3045677.
#
152 changes: 152 additions & 0 deletions docs/examples/adr-pv-module-efficiency/plot_simulate_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"""
Simulating PV systems using the ADR module efficiency model
===========================================================

Time series processing with the ADR model is fast and ... efficient!

This example reads a TMY3 weather file, and runs a basic simulation
on a fixed latitude-tilt system.
Efficiency is independent of system size, so adjusting the system
capacity is just a matter of setting the desired value, e.g. P_STC = 5000.

"""

import os
import pandas as pd
import matplotlib.pyplot as plt

import pvlib
from pvlib import iotools, location, pvefficiency
from pvlib.irradiance import aoi, get_total_irradiance

# %%
#
# Read a TMY3 file containing weather data and select needed columns
#

PVLIB_DIR = pvlib.__path__[0]
DATA_FILE = os.path.join(PVLIB_DIR, 'data', '723170TYA.CSV')

tmy, metadata = iotools.read_tmy3(DATA_FILE, coerce_year=1990)

df = pd.DataFrame({'ghi': tmy['GHI'], 'dhi': tmy['DHI'],
'dni': tmy['DNI'], 'dni_extra': tmy['ETRN'],
'temp_air': tmy['DryBulb'], 'wind_speed': tmy['Wspd'],
})

# %%
#
# Shift timestamps to middle of hour and then calculate sun positions
#

df.index = df.index - pd.Timedelta(minutes=30)

loc = location.Location.from_tmy(metadata)
solpos = loc.get_solarposition(df.index)

# %%
#
# Determine total irradiance on a fixed-tilt array
#

TILT = metadata['latitude']
ORIENT = 180

df['aoi'] = aoi(TILT, ORIENT, solpos.apparent_zenith, solpos.azimuth)

total_irrad = get_total_irradiance(TILT, ORIENT,
solpos.apparent_zenith, solpos.azimuth,
df.dni, df.ghi, df.dhi, df.dni_extra)

df['poa_global'] = total_irrad.poa_global

# %%
#
# Estimate the expected operating temperature of the PV modules
#

df['temp_pv'] = pvlib.temperature.faiman(df.poa_global, df.temp_air,
df.wind_speed)

# %%
#
# Now we're ready to calculate PV array DC output power based
# on POA irradiance and PV module operating temperature.
# Among the models available in pvlib-python to do this are:
# - PVWatts
# - SAPM
# - single-diode model variations
# - and now also the ADR PV efficiency model
#
# Simulation is done in two steps:
# - first calculate efficiency using the ADR model,
# - then convert (scale up) efficiency to power.
#

# Borrow the ADR model parameters from the other example:

adr_params = {'k_a': 0.99879,
'k_d': -5.85188,
'tc_d': 0.01939,
'k_rs': 0.06962,
'k_rsh': 0.21036
}

df['eta_rel'] = pvefficiency.adr(df['poa_global'], df['temp_pv'], **adr_params)

# Set the desired array size:
P_STC = 5000. # (W)
# and the irradiance level needed to achieve this output (
G_STC = 1000. # (W/m2)

df['p_mp'] = P_STC * df['eta_rel'] * (df['poa_global'] / G_STC)

# %%
#
# Show how power and efficiency vary with both irradiance and temperature
#

plt.figure()
pc = plt.scatter(df['poa_global'], df['eta_rel'], c=df['temp_pv'], cmap='jet')
plt.colorbar(label='Temperature [C]', ax=plt.gca())
pc.set_alpha(0.25)
plt.grid(alpha=0.5)
plt.ylim(0.48)
plt.xlabel('Irradiance [W/m²]')
plt.ylabel('Relative efficiency [-]')
plt.show()

plt.figure()
pc = plt.scatter(df['poa_global'], df['p_mp'], c=df['temp_pv'], cmap='jet')
plt.colorbar(label='Temperature [C]', ax=plt.gca())
pc.set_alpha(0.25)
plt.grid(alpha=0.5)
plt.xlabel('Irradiance [W/m²]')
plt.ylabel('Array power [W]')
plt.show()

# %%
#
# One day:
#

DEMO_DAY = '1990-08-05'

plt.figure()
plt.plot(df['p_mp'][DEMO_DAY])
plt.xticks(rotation=30)
plt.ylabel('Power [W]')
plt.show()

# %%
#
# References
# ----------
# .. [1] A. Driesse and J. S. Stein, "From IEC 61853 power measurements
# to PV system simulations", Sandia Report No. SAND2020-3877, 2020.
#
# .. [2] A. Driesse, M. Theristis and J. S. Stein, "A New Photovoltaic Module
# Efficiency Model for Energy Prediction and Rating," in IEEE Journal
# of Photovoltaics, vol. 11, no. 2, pp. 527-534, March 2021,
# doi: 10.1109/JPHOTOV.2020.3045677.
#
2 changes: 2 additions & 0 deletions docs/sphinx/source/reference/pv_modeling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,5 @@ Other

pvsystem.retrieve_sam
pvsystem.scale_voltage_current_power
pvefficiency.adr
pvefficiency.fit_pvefficiency_adr
Loading