From 52a40f76a4c9197a47c99a9aa611eb975eac00d8 Mon Sep 17 00:00:00 2001 From: RDaxini <143435106+RDaxini@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:59:51 +0100 Subject: [PATCH 1/3] create update __init__.py, mismatch.py, test_spectrum --- pvlib/spectrum/__init__.py | 1 + pvlib/spectrum/mismatch.py | 125 +++++++++++++++++++++++++++++++++++ pvlib/tests/test_spectrum.py | 37 +++++++++++ 3 files changed, 163 insertions(+) diff --git a/pvlib/spectrum/__init__.py b/pvlib/spectrum/__init__.py index b95f221066..ee84b3b659 100644 --- a/pvlib/spectrum/__init__.py +++ b/pvlib/spectrum/__init__.py @@ -9,6 +9,7 @@ spectral_factor_sapm, spectral_factor_pvspec, spectral_factor_jrc, + spectral_factor_daxini, sr_to_qe, qe_to_sr ) diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index 197c226231..579430c739 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -836,6 +836,131 @@ def spectral_factor_pvspec(airmass_absolute, clearsky_index, return mismatch +def spectral_factor_daxini(ape, band_depth, module_type=None, + coefficients=None): + r""" + Estimate a technology-specific spectral mismatch modifier from the average + photon energy (APE) and the depth of a water absorption band using the + Daxini model. + + Parameters + ---------- + ape : numeric + Average photon energy (APE, :math:`\varphi`) [eV] + + band_depth : numeric + Depth of a spectral band, :math:`\varepsilon` [:math:`Wm^-2`] + + module_type : str, optional. The default is None. + One of the following PV technology strings from [1]_: + + * ``asi-t`` - anyonymous triple junction amorphous Si + * ``'cdte'`` - anyonymous CdTe module. + * ``'multisi'`` - anyonymous multicrystalline Si module. + + coefficients : array-ike, optional + User-defined coefficients, if not using one of the default coefficient + sets via the ``module_type`` parameter. The default is None. + + 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. + + Notes + ----- + The Daxini model parameterises the spectral mismatch factor, :math:`M`, as + a function of the average photon energy, :math:`\varphi`, and the depth of + a water absorption band, :math:`\varepsilon`, as follows: + + .. math:: + + M = a_0 + a_1\varphi + a_2\varepsilon + a_3\varphi^2 + a_4\varepsilon^2 + + a_5\varphi\varepsilon, + + where :math:`a_{0-5}` are module-specific coefficients. In [1]_, + :math:`\varphi` is calculated between the limits of 350nm to 1050nm. + While several atmopsheric windows and water absorption bands within the + spectral irradiance range 350nm-1050nm are tested as candidates for + :math:`\varepsilon`, ultimately the 650nm-670nm is recommended for the PV + devices analysed in the study. It should be noted that "depth" here refers + to the area beneath the spectral irradiance curve within the specified + wavelength limits, which in this case are 650nm-670nm. Therefore, + :math:`\varepsilon` is calculated by integrating the spectral irradiance, + with respect to wavelength, between 650nm-670nm. The purpose of this second + index, used in conjunction with the APE, is to distinguish between + different spectra that have the same or similar APE values, which reduces + the reliability of an single-variable APE spectral mismatch estimation + function. + + The model is developed and validated using one year of outdoor + meteorological, PV, and spectral irradiance data measured at the National + Renewable Energy Laboratory in Golden, Colorado, USA. The data used are + publicly available and can be found at [2]_ and [3]_. The primary + publications associated with these data releases are [4]_, and [5] and + [6]_, respectively. + + References + ---------- + .. [1] Daxini, R., et al., 2023 "Modelling the spectral influence on + photovoltaic device performance using the average photon energy and + the depth of a water absorption band for improved forecasting." + Energy 284: 129046. + :doi:`10.1016/j.energy.2023.129046` + .. [2] Measurement and Instrumentation Data Center (MIDC) + :doi:`10.5439/1052221 + .. [3] Data for Validating Models for PV Module Performance + :doi:`10.21948/1811521` + .. [4] Stoffel, T., and Andreas, A. NREL Solar Radiation Research + laboratory (SRRL): Baseline measurement system (BMS); Golden, + Colorado (data). No. NREL/DA-5500-56488. National Renewable Energy + Laboratory.(NREL), Golden, CO (United States), 1981. + :doi:`10.5439/1052221` + .. [5] Marion, B., et al. Data for validating models for PV module + performance. EMN-DURMAT (EMN-DuraMAT); National Renewable Energy + Laboratory (NREL), Golden, CO (United States), 2021. + :doi:`10.21948/1811521` + .. [6] Marion, B., et al. User's manual for data for validating models for + PV module performance. No. NREL/TP-5200-61610. National Renewable + Energy Laboratory (NREL), Golden, CO (United States), 2014. + :doi:`10.2172/1130632` + """ + + _coefficients = {} + _coefficients['multisi'] = (-0.3998, 1.101, 0.03366, -0.1837, + 1.493e-4, -0.02046) + _coefficients['cdte'] = (-0.5313, 0.7208, 0.02232, 0.05321, + 1.629e-4, -0.01445) + _coefficients['asi-t'] = (-21.94, 22.62, -0.01393, -5.521, + 1.7341e-4, 0.003860) + + 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 ' + + ", ".join(_coefficients.keys())) + else: + raise ValueError('Cannot resolve input, must supply only one of ' + + 'module_type and coefficients. module_type can be ' + + 'one of' ", ".join(_coefficients.keys())) + + coeff = coefficients + e = band_depth + + mismatch = ( + coeff[0] + coeff[1]*ape + coeff[2]*e + coeff[3]*ape**2 + + coeff[4]*e**2 + coeff[5]*ape*e + ) + + return mismatch + + def spectral_factor_jrc(airmass, clearsky_index, module_type=None, coefficients=None): r""" diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index 969fb819b8..b1c4cc4cfb 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -474,6 +474,43 @@ def test_spectral_factor_jrc_supplied_ambiguous(): coefficients=None) +@pytest.mark.parametrize("module_type,expected", [ + ('multisi', pd.Series([0.98897, 1.000677, 1.00829])), + ('cdte', pd.Series([0.94950, 0.98647, 1.04016])), + ('asi-t', pd.Series([0.92752, 1.02894, 1.13527])), +]) +def test_spectral_factor_daxini_series(module_type, expected): + apes = pd.Series([1.82, 1.87, 1.95]) + bands = pd.Series([2, 4, 8]) + out = spectrum.spectral_factor_daxini(apes, bands, + module_type=module_type) + assert isinstance(out, pd.Series) + assert np.allclose(expected, out, atol=1e-5) + + +def test_spectral_factor_daxini_supplied(): + # use the cdte coeffs + coeffs = (-0.5313, 0.7208, 0.02232, 0.05321, 1.629e-4, -0.01445) + out = spectrum.spectral_factor_daxini(1.87, 4, coefficients=coeffs) + expected = 0.98647 + assert_allclose(out, expected, atol=1e-5) + + +def test_spectral_factor_daxini_supplied_redundant(): + # Error when specifying both module_type and coefficients + coeffs = (-0.5313, 0.7208, 0.02232, 0.05321, 1.629e-4, -0.01445) + with pytest.raises(ValueError, match='supply only one of'): + spectrum.spectral_factor_daxini(1.87, 4, module_type='cdte', + coefficients=coeffs) + + +def test_spectral_factor_daxini_supplied_ambiguous(): + # Error when specifying neither module_type nor coefficients + with pytest.raises(ValueError, match='No valid input provided'): + spectrum.spectral_factor_daxini(1.87, 4, module_type=None, + coefficients=None) + + @pytest.fixture def sr_and_eqe_fixture(): # Just some arbitrary data for testing the conversion functions From 46ad8e4a6add6586d2a30799f4ae1d22187e1d84 Mon Sep 17 00:00:00 2001 From: RDaxini <143435106+RDaxini@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:25:31 +0100 Subject: [PATCH 2/3] Update spectrum.rst --- .../source/reference/effects_on_pv_system_output/spectrum.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst index 15fd1d09b8..896eb7bb7f 100644 --- a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst +++ b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst @@ -16,5 +16,6 @@ Spectrum spectrum.spectral_factor_sapm spectrum.spectral_factor_pvspec spectrum.spectral_factor_jrc + spectrum.spectral_factor_daxini spectrum.sr_to_qe spectrum.qe_to_sr From b949635a70977de3be7fcfe5c78b1c78c92c6d1b Mon Sep 17 00:00:00 2001 From: RDaxini <143435106+RDaxini@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:41:43 +0100 Subject: [PATCH 3/3] docstring revisions --- pvlib/spectrum/mismatch.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index 579430c739..e6e99e8212 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -849,16 +849,18 @@ def spectral_factor_daxini(ape, band_depth, module_type=None, Average photon energy (APE, :math:`\varphi`) [eV] band_depth : numeric - Depth of a spectral band, :math:`\varepsilon` [:math:`Wm^-2`] + Depth of a spectral band, :math:`\varepsilon` [Wm:math:`^{-2}`] - module_type : str, optional. The default is None. + module_type : str, optional One of the following PV technology strings from [1]_: - * ``asi-t`` - anyonymous triple junction amorphous Si + * ``asi-t`` - anyonymous triple junction amorphous Si module * ``'cdte'`` - anyonymous CdTe module. - * ``'multisi'`` - anyonymous multicrystalline Si module. + * ``'multisi'`` - anyonymous multicrystalline Si module + + The default is None. - coefficients : array-ike, optional + coefficients : array-like, optional User-defined coefficients, if not using one of the default coefficient sets via the ``module_type`` parameter. The default is None. @@ -884,23 +886,22 @@ def spectral_factor_daxini(ape, band_depth, module_type=None, where :math:`a_{0-5}` are module-specific coefficients. In [1]_, :math:`\varphi` is calculated between the limits of 350nm to 1050nm. While several atmopsheric windows and water absorption bands within the - spectral irradiance range 350nm-1050nm are tested as candidates for + spectral irradiance range 350nm-1050nm were tested as candidates for :math:`\varepsilon`, ultimately the 650nm-670nm is recommended for the PV devices analysed in the study. It should be noted that "depth" here refers to the area beneath the spectral irradiance curve within the specified wavelength limits, which in this case are 650nm-670nm. Therefore, :math:`\varepsilon` is calculated by integrating the spectral irradiance, with respect to wavelength, between 650nm-670nm. The purpose of this second - index, used in conjunction with the APE, is to distinguish between - different spectra that have the same or similar APE values, which reduces - the reliability of an single-variable APE spectral mismatch estimation - function. + index is to distinguish between different spectra that have the same or + similar APE values, the occurance of which reduces the reliability of a + single-variable APE spectral mismatch estimation function. The model is developed and validated using one year of outdoor meteorological, PV, and spectral irradiance data measured at the National Renewable Energy Laboratory in Golden, Colorado, USA. The data used are publicly available and can be found at [2]_ and [3]_. The primary - publications associated with these data releases are [4]_, and [5] and + publications associated with these data releases are [4]_, and [5]_ and [6]_, respectively. References @@ -911,7 +912,7 @@ def spectral_factor_daxini(ape, band_depth, module_type=None, Energy 284: 129046. :doi:`10.1016/j.energy.2023.129046` .. [2] Measurement and Instrumentation Data Center (MIDC) - :doi:`10.5439/1052221 + :doi:`10.5439/1052221` .. [3] Data for Validating Models for PV Module Performance :doi:`10.21948/1811521` .. [4] Stoffel, T., and Andreas, A. NREL Solar Radiation Research