Skip to content
Open
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3363ace
Add polo-smm
jesuspolo Jun 25, 2025
ceba758
Apply suggestions from code review
jesuspolo Jun 25, 2025
36c9b43
Update mismatch.py
jesuspolo Jun 25, 2025
eaa90b4
Update mismatch.py
jesuspolo Jun 25, 2025
794ed98
Update mismatch.py
jesuspolo Jun 25, 2025
7926a3d
Update mismatch.py
jesuspolo Jun 25, 2025
988557c
Update mismatch.py
jesuspolo Jul 11, 2025
45e768f
Update mismatch.py
jesuspolo Jul 28, 2025
38e5694
Update pvlib/spectrum/mismatch.py
jesuspolo Jul 28, 2025
c24e013
Update pvlib/spectrum/mismatch.py
jesuspolo Jul 28, 2025
0a00f1b
Changes from code review
AdamRJensen Oct 25, 2025
2a9d0db
Add function to spectrum/__init__.py
AdamRJensen Oct 25, 2025
f296c7b
Update test_mismatch.py
jesuspolo Oct 27, 2025
ce862d8
Update test_mismatch.py
jesuspolo Oct 27, 2025
11336ab
Fix module import in tests
AdamRJensen Oct 27, 2025
e418218
Update test_mismatch.py
jesuspolo Oct 27, 2025
fb0ad0e
Merge branch 'polo-smm' of https://github.com/jesuspolo/pvlib-python …
jesuspolo Oct 27, 2025
450dd37
Fix linter
AdamRJensen Oct 27, 2025
1eb3293
Remove tab character
AdamRJensen Oct 27, 2025
4892e8d
Update test_mismatch.py
jesuspolo Oct 27, 2025
7513f3e
Update test_mismatch.py
jesuspolo Oct 27, 2025
3e4dd56
Update test_mismatch.py
jesuspolo Oct 27, 2025
b9d21ac
fix line legth linter error
AdamRJensen Oct 28, 2025
49c8c91
Update test_mismatch.py
jesuspolo Oct 28, 2025
fa3ff32
Merge branch 'polo-smm' of https://github.com/jesuspolo/pvlib-python …
jesuspolo Oct 28, 2025
31fe508
Update mismatch.py
jesuspolo Oct 29, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions pvlib/spectrum/mismatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,3 +710,86 @@
+ coeff[2] * (airmass - 1.5)
)
return mismatch


def spectral_factor_polo(precipitable_water, airmass_absolute, aod500, aoi,
altitude, module_type=None, coefficients=None,
albedo=0.2):
"""
Estimation of spectral mismatch for BIPV application in vertical facades.
Parameters
----------
precipitable_water : numeric
atmospheric precipitable water. [cm]
airmass_absolute : numeric
absolute (pressure-adjusted) airmass. [unitless]
aod500 : numeric
atmospheric aerosol optical depth at 500 nm. [unitless]
aoi : numeric
angle of incidence. [degrees]
altitude: numeric
altitude over sea level. [m]
module_type : str, optional
One of the following PV technology strings from [1]_:
Copy link
Member

Choose a reason for hiding this comment

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

Are the SR curves used to develop this model open data?

* ``'cdte'`` - anonymous CdTe module.
* ``'monosi'`` - anonymous sc-si module.
* ``'cigs'`` - anonymous copper indium gallium selenide module.
* ``'asi'`` - anonymous amorphous silicon module.
albedo
Copy link
Member

Choose a reason for hiding this comment

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

Can albedo both be a float and an array?

Copy link
Author

Choose a reason for hiding this comment

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

Not sure, I always thought it as a float, since it refers to a total albedo.

Copy link
Member

Choose a reason for hiding this comment

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

I was more wondering if the code allows for albedo being passed in as a time series?

Copy link
Member

Choose a reason for hiding this comment

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

I was more wondering if the code allows for albedo being passed in as a time series?

+1 to making this possible if not already

Ground albedo (default value if 0.2). [unitless]
coefficients : array-like, optional
user-defined coefficients, if not using one of the default coefficient
set via the ``module_type`` parameter.
Returns
-------
modifier: 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] J. Polo and C. Sanz-Saiz, 'Development of spectral mismatch models
for BIPV applications in building façades', Renewable Energy, vol. 245,
p. 122820, Jun. 2025,:doi:`10.1016/j.renene.2025.122820`
"""
if module_type is None and coefficients is None:
raise ValueError('Must provide either `module_type` or `coefficients`')
if module_type is not None and coefficients is not None:
raise ValueError('Only one of `module_type` and `coefficients` should '

Check warning on line 764 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L761-L764

Added lines #L761 - L764 were not covered by tests
'be provided')
am_aoi = pvlib.atmosphere.get_relative_airmass(aoi)
Copy link
Member

Choose a reason for hiding this comment

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

This will produce a nan if aoi > 90.

pressure = pvlib.atmosphere.alt2pres(altitude)
am90 = pvlib.atmosphere.get_absolute_airmass(am_aoi, pressure)
Ram = am90/airmass_absolute
_coefficients = {}
_coefficients = {

Check warning on line 771 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L766-L771

Added lines #L766 - L771 were not covered by tests
'cdte': (-0.0009, 46.80, 49.20, -0.87, 0.00041, 0.053),
'monosi': (0.0027, 10.34, 9.48, 0.307, 0.00077, 0.006),
'cigs': (0.0017, 2.33, 1.30, 0.11, 0.00098, -0.0177),
'asi': (0.0024, 7.32, 7.09, -0.72, -0.0013, 0.089),
}
c = {

Check warning on line 777 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L777

Added line #L777 was not covered by tests
'asi': (0.0056, -0.020, 1.014),
'cigs': (-0.0009, -0.0003, 1),
'cdte': (0.0021, -0.01, 1.01),
'monosi': (0, -0.003, 1.0),
}
if module_type is not None:
coeff = _coefficients[module_type]
c_albedo = c[module_type]

Check warning on line 785 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L783-L785

Added lines #L783 - L785 were not covered by tests
else:
coeff = coefficients
c_albedo = (0.0, 0.0, 1.0) # 0.2 albedo assumed
albedo = 0.2
smm = coeff[0] * Ram + coeff[1] / (coeff[2] + Ram**coeff[3]) \

Check warning on line 790 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L787-L790

Added lines #L787 - L790 were not covered by tests
+ coeff[4] / aod500 + coeff[5]*np.sqrt(precipitable_water)
# Ground albedo correction
g = c_albedo[0] * (albedo/0.2)**2 \

Check warning on line 793 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L793

Added line #L793 was not covered by tests
+ c_albedo[1] * (albedo/0.2) + c_albedo[2]
return g*smm

Check warning on line 795 in pvlib/spectrum/mismatch.py

View check run for this annotation

Codecov / codecov/patch

pvlib/spectrum/mismatch.py#L795

Added line #L795 was not covered by tests
Loading