Skip to content
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

Add PVSPEC spectral correction factor model #2072

Merged
merged 79 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
b006adb
Create test_pelland.py
RDaxini May 28, 2024
a5563e6
new spectral factor
RDaxini May 28, 2024
82d2892
Update __init__.py
RDaxini May 31, 2024
cb8a17a
Update mismatch.py
RDaxini May 31, 2024
fa555a7
Delete test_pelland.py
RDaxini May 31, 2024
6656fee
Update mismatch.py
RDaxini May 31, 2024
56c4628
Update mismatch.py
RDaxini May 31, 2024
acc3998
Update test_spectrum.py
RDaxini May 31, 2024
11b38bd
Update test_spectrum.py
RDaxini May 31, 2024
d36d3b0
correct function name
RDaxini May 31, 2024
486ff98
Update pvlib/spectrum/mismatch.py
RDaxini Jun 4, 2024
28e9339
Update pvlib/spectrum/mismatch.py
RDaxini Jun 4, 2024
b642d05
Update pvlib/spectrum/mismatch.py
RDaxini Jun 4, 2024
e430b27
Update pvlib/tests/test_spectrum.py
RDaxini Jun 4, 2024
83c1683
Update pvlib/spectrum/mismatch.py
RDaxini Jun 4, 2024
6812f51
Update spectrum.rst
RDaxini Jun 4, 2024
200aaed
Merge branch 'main' of https://github.com/RDaxini/pvlib-python
RDaxini Jun 4, 2024
b1ec78f
Update mismatch.py
RDaxini Jun 4, 2024
358a532
Update mismatch.py
RDaxini Jun 4, 2024
67299e3
Update mismatch.py
RDaxini Jun 6, 2024
d5c9725
Update mismatch.py
RDaxini Jun 7, 2024
0df61ed
Update mismatch.py
RDaxini Jun 7, 2024
0d41306
Update mismatch.py
RDaxini Jun 7, 2024
24e05b8
Update mismatch.py
RDaxini Jun 7, 2024
7b4f15d
Update mismatch.py
RDaxini Jun 7, 2024
3bd0b75
Update pvlib/spectrum/mismatch.py
RDaxini Jun 7, 2024
f0706de
Update pvlib/spectrum/mismatch.py
RDaxini Jun 7, 2024
6919364
Update pvlib/spectrum/mismatch.py
RDaxini Jun 7, 2024
ed13838
Update mismatch.py
RDaxini Jun 7, 2024
639fc75
Merge branch 'main' of https://github.com/RDaxini/pvlib-python
RDaxini Jun 7, 2024
7c50791
Update test_spectrum.py
RDaxini Jun 7, 2024
e7c032b
Update test_spectrum.py
RDaxini Jun 7, 2024
a7f9909
Update mismatch.py
RDaxini Jun 7, 2024
4616dc2
Update pvlib/spectrum/mismatch.py
RDaxini Jun 8, 2024
bd84537
Update mismatch.py
RDaxini Jun 8, 2024
f773ba7
Merge branch 'main' of https://github.com/RDaxini/pvlib-python
RDaxini Jun 8, 2024
b6a827b
Update mismatch.py
RDaxini Jun 8, 2024
3df83c3
Update pvlib/spectrum/mismatch.py
RDaxini Jun 8, 2024
f468db8
Update pvlib/tests/test_spectrum.py
RDaxini Jun 8, 2024
43727b7
Update pvlib/tests/test_spectrum.py
RDaxini Jun 8, 2024
9071dba
Merge branch 'main' of https://github.com/RDaxini/pvlib-python
RDaxini Jun 8, 2024
8e53d56
Update mismatch.py
RDaxini Jun 8, 2024
da1780f
Update pvlib/tests/test_spectrum.py
RDaxini Jun 8, 2024
15e328c
name change
RDaxini Jun 8, 2024
8925730
Update test_spectrum.py
RDaxini Jun 8, 2024
cc4a3d1
Update pvlib/spectrum/mismatch.py
RDaxini Jun 8, 2024
3d5eab6
Update test_spectrum.py
RDaxini Jun 8, 2024
f845adb
Merge branch 'main' of https://github.com/RDaxini/pvlib-python
RDaxini Jun 8, 2024
70f86c3
Update mismatch.py
RDaxini Jun 8, 2024
332fed5
Update test_spectrum.py
RDaxini Jun 8, 2024
974e098
Update test_spectrum.py
RDaxini Jun 8, 2024
cc05445
Update test_spectrum.py
RDaxini Jun 8, 2024
b36116d
Update test_spectrum.py
RDaxini Jun 8, 2024
c09e8b8
Update test_spectrum.py
RDaxini Jun 9, 2024
bd133ef
Update mismatch.py
RDaxini Jun 9, 2024
1a7416c
Update test_spectrum.py
RDaxini Jun 10, 2024
35b1411
Update pvlib/spectrum/mismatch.py
RDaxini Jun 11, 2024
b0385a1
Update mismatch.py
RDaxini Jun 11, 2024
e30694b
Update pvlib/spectrum/mismatch.py
RDaxini Jun 11, 2024
bcf8abc
Update mismatch.py
RDaxini Jun 11, 2024
ba7c34b
Update mismatch.py
RDaxini Jun 11, 2024
0f1bce0
Update mismatch.py
RDaxini Jun 11, 2024
7701d85
Update pvlib/spectrum/mismatch.py
RDaxini Jun 11, 2024
d5f0979
Update pvlib/spectrum/mismatch.py
RDaxini Jun 11, 2024
887faee
Update pvlib/spectrum/mismatch.py
RDaxini Jun 11, 2024
3c478d5
Update mismatch.py
RDaxini Jun 11, 2024
6203ca6
Merge remote-tracking branch 'upstream/main'
RDaxini Jun 11, 2024
9a4510c
Update mismatch.py
RDaxini Jun 11, 2024
8aeb8b5
Update mismatch.py
RDaxini Jun 11, 2024
7ba41ba
Update mismatch.py
RDaxini Jun 11, 2024
604e911
Update pvlib/spectrum/mismatch.py
RDaxini Jun 12, 2024
8897411
Update pvlib/spectrum/mismatch.py
RDaxini Jun 12, 2024
413cc04
Update pvlib/spectrum/mismatch.py
RDaxini Jun 12, 2024
4605d06
Update mismatch.py
RDaxini Jun 12, 2024
a772a94
test for output type
RDaxini Jun 13, 2024
55d34ed
Update mismatch.py
RDaxini Jun 13, 2024
38469cf
Update pvlib/tests/test_spectrum.py
RDaxini Jun 13, 2024
294eb8e
Update v0.11.0.rst
RDaxini Jun 14, 2024
bc37d49
Update docs/sphinx/source/whatsnew/v0.11.0.rst
RDaxini Jun 14, 2024
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
1 change: 1 addition & 0 deletions pvlib/spectrum/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
spectral_factor_caballero,
spectral_factor_firstsolar,
spectral_factor_sapm,
spectral_factor_pelland
)
125 changes: 125 additions & 0 deletions pvlib/spectrum/mismatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,3 +571,128 @@
)
modifier = f_AM + f_AOD + f_PW # Eq 5
return modifier

def spectral_factor_pelland(airmass_absolute, clearness_index,

Check failure on line 575 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E302 expected 2 blank lines, found 1
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
module_type = None, coefficients = None,

Check failure on line 576 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals

Check failure on line 576 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals

Check failure on line 576 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals

Check failure on line 576 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals
min_airmass_absolute = 0.58,

Check failure on line 577 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals

Check failure on line 577 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals
max_airmass_absolute = 10):

Check failure on line 578 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals

Check failure on line 578 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

E251 unexpected spaces around keyword / parameter equals
r"""
Estimate a technology-specific spectral mismatch modifier from
airmass and clearness index using the Pelland model, which takes the
following form:

Check failure on line 583 in pvlib/spectrum/mismatch.py

View workflow job for this annotation

GitHub Actions / flake8-linter

W293 blank line contains whitespace
.. math::

M = a_1*kc**(a_2)*ama**(a_3),
RDaxini marked this conversation as resolved.
Show resolved Hide resolved

where M is the spectral mismatch factor, and a_1, a_2, a_3 are
module-specific coefficients.

The motivtion for this model is to include the effect of cloud cover on the
spectrum, and thus spectral mismatch. Another motivation is to develop a
simple parameterisation compared with existing models. Model coefficients
are derived using spectral irradiance and other meteorological data from
eight locations. These coefficients for seven modules, available here via
the ``module_type`` parameter, as well as more details on the model, can be
found in Ref. [1]_
RDaxini marked this conversation as resolved.
Show resolved Hide resolved

Parameters
----------
airmass_absolute : numeric
absolute (pressure-adjusted) airmass. [unitless]
RDaxini marked this conversation as resolved.
Show resolved Hide resolved

clearness_index: numeric
clearness index. [unitless]

module_type : str, optional
One of the following PV technology strings from [1]_:

* ``'fs4-1'`` - First Solar series 4-1 and earlier CdTe module.
* ``'fs4-2'`` - First Solar 4-2 and earlier CdTe module.
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
* ``'monosi'``, - anonymous sc-si module.
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
* ``'multisi'``, - anonymous mc-si- module.
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
* ``'cigs'`` - anonymous copper indium gallium selenide module.
* ``'asi'`` - anonymous amorphous silicon module.

coefficients : array-like, optional
user-defined coefficients, if not using one of the default coefficient
sets via the ``module_type`` parameter.

Returns
-------
mismatch: numeric
spectral mismatch factor (unitless) which is multiplied
with broadband irradiance reaching a module's cells to estimate
effective irradiance, i.e., the irradiance that is converted to
electrical current.

References
----------
.. [1] Pelland, S., Beswick, C., Thevenard, D., Côté, A., Pai, A. and
Poissant, Y., 2020, June. Development and testing of the PVSPEC model of
photovoltaic spectral mismatch factor. In 2020 47th IEEE Photovoltaic
Specialists Conference (PVSC) (pp. 1258-1264). IEEE.
:doi:`https://doi.org/10.1109/PVSC45281.2020.9300932`
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
"""
# =============================================================================
# --- Screen Input Data ---
# =============================================================================
#kc
kc = np.atleast_1d(clearness_index)
kc = kc.astype('float64')
if np.min(kc) < 0:
raise ValueError('Clearness index cannot be negative')
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
if np.max(kc) > 1:
raise ValueError('Clearness index cannot be >1')
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
#ama
if np.max(airmass_absolute) > max_airmass_absolute:
warn('Exceptionally high air mass: ' +
'values greater than 'f'{max_airmass_absolute} in dataset')
# Warn user about exceptionally low ama data
if np.min(airmass_absolute) < min_airmass_absolute:
airmass_absolute = np.maximum(airmass_absolute, min_airmass_absolute )
warn('Exceptionally low air mass: ' +
'model not intended for extra-terrestrial use')
# =============================================================================
# --- Default coefficients ---
# =============================================================================
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
#Empirical coefficients from [1]_
_coefficients = {}
_coefficients['multisi'] = (
0.9847, -0.05237, 0.03034)
_coefficients['monosi'] = (
0.9845, -0.05169, 0.03034)
_coefficients['fs-2'] = (
1.002, -0.07108, 0.02465)
_coefficients['fs-4'] = (
0.9981, -0.05776, 0.02336)
_coefficients['cigs'] = (
0.9791, -0.03904, 0.03096)
_coefficients['asi'] = (
1.051, -0.1033, 0.009838)
_coefficients['polysi'] = _coefficients['multisi']
_coefficients['xsi'] = _coefficients['monosi']
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
# =============================================================================
# --- Check arguments ---
# =============================================================================
if module_type is not None and coefficients is None:
coefficients = _coefficients[module_type.lower()]
elif module_type is None and coefficients is not None:
pass
elif module_type is None and coefficients is None:
raise ValueError('No valid input provided, both module_type and ' +
'coefficients are None. module_type can be one of ' +
'poly-Si, monosi, fs-2, fs-4, cigs, or asi')
else:
raise ValueError('Cannot resolve input, must supply only one of ' +
'module_type and coefficients. module_type can be ' +
'one of poly-Si, monosi, fs-2, fs-4, cigs, or asi')
# =============================================================================
# --- Specral mismatch calculation ---
# =============================================================================
coeff = coefficients
ama = airmass_absolute
kc = clearness_index
mismatch = coeff[0]*kc**(coeff[1])*ama**(coeff[2])

return mismatch
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
53 changes: 53 additions & 0 deletions pvlib/tests/test_spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,56 @@ def test_spectral_factor_caballero_supplied_ambiguous():
with pytest.raises(ValueError):
spectrum.spectral_factor_caballero(1, 1, 1, module_type=None,
coefficients=None)

@pytest.mark.parametrize("module_type,expected", [
('asi', np.array([1.15534029, 1.1123772, 1.08286684])),
('fs-2', np.array([1.0694323, 1.04948777, 1.03556288])),
('fs-4', np.array([1.05234725, 1.037771, 1.0275516])),
('multisi', np.array([1.03310403, 1.02391703, 1.01744833])),
('monosi', np.array([1.03225083, 1.02335353, 1.01708734])),
('cigs', np.array([1.01475834, 1.01143927, 1.00909094])),
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
])
def test_spectral_factor_pelland(module_type, expected):
ams = np.array([1.0, 1.5, 2.0])
kcs = np.array([0.4, 0.6, 0.8])
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
out = spectrum.spectral_factor_pelland(ams, kcs,
module_type=module_type)
assert np.allclose(expected, out, atol=1e-3)
RDaxini marked this conversation as resolved.
Show resolved Hide resolved

def test_spectral_factor_pelland_supplied():
# use the multisi coeffs
coeffs = (
0.9847, -0.05237, 0.03034)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
coeffs = (
0.9847, -0.05237, 0.03034)
coeffs = (0.9847, -0.05237, 0.03034)

out = spectrum.spectral_factor_pelland(1.5, 0.8, coefficients=coeffs)
expected = 1.00860641
assert_allclose(out, expected, atol=1e-3)
RDaxini marked this conversation as resolved.
Show resolved Hide resolved

def test_spectral_factor_pelland_supplied_redundant():
# Error when specifying both module_type and coefficients
coeffs = (
0.9847, -0.05237, 0.03034)
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
with pytest.raises(ValueError):
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
spectrum.spectral_factor_pelland(1.5, 0.8, module_type='multisi',
coefficients=coeffs)

def test_spectral_factor_pelland_supplied_ambiguous():
# Error when specifying neither module_type nor coefficients
with pytest.raises(ValueError):
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
spectrum.spectral_factor_pelland(1.5, 0.8, module_type=None,
coefficients=None)

def test_spectral_factor_pelland_low_airmass():
with pytest.warns(UserWarning, match='Exceptionally low air mass'):
_ = spectrum.spectral_factor_pelland(0.1, 0.8, 'multisi')

def test_spectral_factor_pelland_high_airmass():
with pytest.warns(UserWarning, match='Exceptionally high air mass'):
_ = spectrum.spectral_factor_pelland(12, 0.8, 'multisi')

def test_spectral_factor_pelland_low_clearnessindex():
with pytest.raises(ValueError, match='Clearness index cannot be negative'):
_ = spectrum.spectral_factor_pelland(1.5, -0.8, 'multisi')

def test_spectral_factor_pelland_high_clearnessindex():
with pytest.raises(ValueError, match='Clearness index cannot be >1'):
_ = spectrum.spectral_factor_pelland(1.5, 1.8, 'multisi')
RDaxini marked this conversation as resolved.
Show resolved Hide resolved
Loading