From 05f54087e7bca678f6735bfdc8f4a202d4bbece7 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:03:14 -0500 Subject: [PATCH 01/18] add marion's adjustment --- pvlib/pvsystem.py | 54 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 2b703f3a52..14c96ff6bf 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2878,14 +2878,36 @@ def scale_voltage_current_power(data, voltage=1, current=1): @renamed_kwarg_warning( "0.13.0", "g_poa_effective", "effective_irradiance") -def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25.): +def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., + k=0.0, capped_adjustment=False): r""" - Implements NREL's PVWatts DC power model. The PVWatts DC model [1]_ is: + Implements NREL's PVWatts (Version 5) DC power model. The PVWatts Version + 5 DC model [1]_ is: .. math:: P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref})) + This model has also been referred to as the power temperature coefficient + model. + + This function accepts an optional irradiance adjustment factor, `k`, based + on based on [2]_. This applies a piece-wise adjustment to power based on + irradiance, where `k` is the reduction in actual power at 200 W/m^2 + relative to ideal power calculated linearly from standard test conditions, + normalized to nameplate power at standard test conditions. + + .. math:: + + k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} + + For example, a 500 W module that produces 95 W at 200 W/m^2 (a 5% relative + reduction in efficiency) would have a value of `k` = 0.01. + + This adjustment increases relative efficiency for irradiance above 1000 + W/m^2, which may not be desired. An optional input, `capped_adjustment`, + modifies the adjustment from [2]_ to only apply below 1000 W/m^2. + Note that ``pdc0`` is also used as a symbol in :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC power of the modules at reference conditions. ``pdc0`` in @@ -2909,6 +2931,11 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25.): temp_ref: numeric, default 25.0 Cell reference temperature. PVWatts defines it to be 25 C and is included here for flexibility. [C] + k: numeric, default 0.005 + Irradiance correction factor, defined in [2]_. [unitless] + modified_marion: Boolean, default False + Optional modification to [2]_, where no adjustment is applied above + 1000 W/m^2. Returns ------- @@ -2920,11 +2947,34 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25.): .. [1] A. P. Dobos, "PVWatts Version 5 Manual" http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf (2014). + .. [2] B. Marion, "Comparison of Predictive Models for + Photovoltaic Module Performance," + https://doi.org/10.1109/PVSC.2008.4922586, + https://docs.nrel.gov/docs/fy08osti/42511.pdf + (2008). """ # noqa: E501 pdc = (effective_irradiance * 0.001 * pdc0 * (1 + gamma_pdc * (temp_cell - temp_ref))) + # apply Marion's correction if k is anything but zero + if k != 0: + err_1 = (k * (1 - (1 - effective_irradiance / 200)**4) / + (effective_irradiance / 1000)) + err_2 = (k * (1000 - effective_irradiance) / (1000 - 200)) + + pdc_marion = np.where(effective_irradiance <= 200, + pdc * (1 - err_1), + pdc * (1 - err_2)) + + # "cap" Marion's correction at 1000 W/m^2 + if capped_adjustment is True: + pdc_marion = np.where(effective_irradiance >= 1000, + pdc, + pdc_marion) + + pdc = pdc_marion + return pdc From 6d7ae12f6e0e3d352017dc2f3ca271519460f4d6 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:52:45 -0500 Subject: [PATCH 02/18] linting --- pvlib/pvsystem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 14c96ff6bf..c3b241339c 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2907,7 +2907,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., This adjustment increases relative efficiency for irradiance above 1000 W/m^2, which may not be desired. An optional input, `capped_adjustment`, modifies the adjustment from [2]_ to only apply below 1000 W/m^2. - + Note that ``pdc0`` is also used as a symbol in :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC power of the modules at reference conditions. ``pdc0`` in @@ -2948,7 +2948,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf (2014). .. [2] B. Marion, "Comparison of Predictive Models for - Photovoltaic Module Performance," + Photovoltaic Module Performance," https://doi.org/10.1109/PVSC.2008.4922586, https://docs.nrel.gov/docs/fy08osti/42511.pdf (2008). From 40328c836840880ecd4e8c4239044c907459cbdc Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:56:39 -0500 Subject: [PATCH 03/18] Update pvlib/pvsystem.py Co-authored-by: Cliff Hansen --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index c3b241339c..14018f4fe3 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2933,7 +2933,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., is included here for flexibility. [C] k: numeric, default 0.005 Irradiance correction factor, defined in [2]_. [unitless] - modified_marion: Boolean, default False + cap_adjustment: Boolean, default False Optional modification to [2]_, where no adjustment is applied above 1000 W/m^2. From a9dfb281277210f3f23733c455c314893c8a4eb3 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:56:49 -0500 Subject: [PATCH 04/18] Update pvlib/pvsystem.py Co-authored-by: Cliff Hansen --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 14018f4fe3..5ce37bcdad 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2931,7 +2931,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., temp_ref: numeric, default 25.0 Cell reference temperature. PVWatts defines it to be 25 C and is included here for flexibility. [C] - k: numeric, default 0.005 + k: numeric, optional Irradiance correction factor, defined in [2]_. [unitless] cap_adjustment: Boolean, default False Optional modification to [2]_, where no adjustment is applied above From 551e722632ae28519ccbc56df27affb14c6f707f Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:57:18 -0500 Subject: [PATCH 05/18] Update pvlib/pvsystem.py Co-authored-by: Cliff Hansen --- pvlib/pvsystem.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 5ce37bcdad..5379776e3a 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2934,8 +2934,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., k: numeric, optional Irradiance correction factor, defined in [2]_. [unitless] cap_adjustment: Boolean, default False - Optional modification to [2]_, where no adjustment is applied above - 1000 W/m^2. + If True, apply the optional adjustment at and below 1000 W/m^2. Returns ------- From 73e80d3fccf1d7f36a7cdec0ce5dd818b7a41854 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:57:25 -0500 Subject: [PATCH 06/18] Update pvlib/pvsystem.py Co-authored-by: Cliff Hansen --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 5379776e3a..1e54ea2c33 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2957,7 +2957,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., (1 + gamma_pdc * (temp_cell - temp_ref))) # apply Marion's correction if k is anything but zero - if k != 0: + if k is not None: err_1 = (k * (1 - (1 - effective_irradiance / 200)**4) / (effective_irradiance / 1000)) err_2 = (k * (1000 - effective_irradiance) / (1000 - 200)) From f25b42634b4d1dd3cc6efcc35ec9e14593ff46c2 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:57:53 -0500 Subject: [PATCH 07/18] Update pvlib/pvsystem.py Co-authored-by: Cliff Hansen --- pvlib/pvsystem.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 1e54ea2c33..9f75b7cb22 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2894,8 +2894,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., This function accepts an optional irradiance adjustment factor, `k`, based on based on [2]_. This applies a piece-wise adjustment to power based on irradiance, where `k` is the reduction in actual power at 200 W/m^2 - relative to ideal power calculated linearly from standard test conditions, - normalized to nameplate power at standard test conditions. + relative to power calculated at 200 W/m^2 as 0.2*`pdc0`. .. math:: From 380bb5895cee96bc34d4318093f95dd6010a9c13 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:01:27 -0500 Subject: [PATCH 08/18] more suggested changes --- pvlib/pvsystem.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 9f75b7cb22..064b75fdaf 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2879,7 +2879,7 @@ def scale_voltage_current_power(data, voltage=1, current=1): @renamed_kwarg_warning( "0.13.0", "g_poa_effective", "effective_irradiance") def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., - k=0.0, capped_adjustment=False): + k=None, cap_adjustment=False): r""" Implements NREL's PVWatts (Version 5) DC power model. The PVWatts Version 5 DC model [1]_ is: @@ -2892,17 +2892,16 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., model. This function accepts an optional irradiance adjustment factor, `k`, based - on based on [2]_. This applies a piece-wise adjustment to power based on - irradiance, where `k` is the reduction in actual power at 200 W/m^2 - relative to power calculated at 200 W/m^2 as 0.2*`pdc0`. + on [2]_. This applies a piece-wise adjustment to power based on irradiance, + where `k` is the reduction in actual power at 200 W/m^2 relative to power + calculated at 200 W/m^2 as 0.2*`pdc0`. For example, a 500 W module that + produces 95 W at 200 W/m^2 (a 5% relative reduction in efficiency) would + have a value of `k` = 0.01. .. math:: k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} - For example, a 500 W module that produces 95 W at 200 W/m^2 (a 5% relative - reduction in efficiency) would have a value of `k` = 0.01. - This adjustment increases relative efficiency for irradiance above 1000 W/m^2, which may not be desired. An optional input, `capped_adjustment`, modifies the adjustment from [2]_ to only apply below 1000 W/m^2. @@ -2966,7 +2965,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., pdc * (1 - err_2)) # "cap" Marion's correction at 1000 W/m^2 - if capped_adjustment is True: + if cap_adjustment is True: pdc_marion = np.where(effective_irradiance >= 1000, pdc, pdc_marion) From 5d31dfd0a2708d7d85a4c53b958c100c9142340f Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:41:41 -0500 Subject: [PATCH 09/18] Update pvlib/pvsystem.py doi sphinx Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 064b75fdaf..8d5755dd14 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2946,7 +2946,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., (2014). .. [2] B. Marion, "Comparison of Predictive Models for Photovoltaic Module Performance," - https://doi.org/10.1109/PVSC.2008.4922586, + :doi:`10.1109/PVSC.2008.4922586`, https://docs.nrel.gov/docs/fy08osti/42511.pdf (2008). """ # noqa: E501 From ad146b508b122d41ed7d252e5166d3a28e342999 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:42:13 -0500 Subject: [PATCH 10/18] Update pvlib/pvsystem.py Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 8d5755dd14..be003e8d54 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2893,7 +2893,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., This function accepts an optional irradiance adjustment factor, `k`, based on [2]_. This applies a piece-wise adjustment to power based on irradiance, - where `k` is the reduction in actual power at 200 W/m^2 relative to power + where `k` is the reduction in actual power at 200 Wm⁻² relative to power calculated at 200 W/m^2 as 0.2*`pdc0`. For example, a 500 W module that produces 95 W at 200 W/m^2 (a 5% relative reduction in efficiency) would have a value of `k` = 0.01. From 69ce5e743507cc00cb7d090f42a9ec91f4c72449 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:42:26 -0500 Subject: [PATCH 11/18] Update pvlib/pvsystem.py Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- pvlib/pvsystem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index be003e8d54..211ac2d5b2 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2903,8 +2903,8 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} This adjustment increases relative efficiency for irradiance above 1000 - W/m^2, which may not be desired. An optional input, `capped_adjustment`, - modifies the adjustment from [2]_ to only apply below 1000 W/m^2. + Wm⁻², which may not be desired. An optional input, `capped_adjustment`, + modifies the adjustment from [2]_ to only apply below 1000 Wm⁻². Note that ``pdc0`` is also used as a symbol in :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC From dc58507188ef4df9c1b4a6f4e28dd88bfea7538b Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:54:17 -0500 Subject: [PATCH 12/18] cleaning up docs --- pvlib/pvsystem.py | 63 +++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 211ac2d5b2..bb9a8b903e 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2881,36 +2881,7 @@ def scale_voltage_current_power(data, voltage=1, current=1): def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., k=None, cap_adjustment=False): r""" - Implements NREL's PVWatts (Version 5) DC power model. The PVWatts Version - 5 DC model [1]_ is: - - .. math:: - - P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref})) - - This model has also been referred to as the power temperature coefficient - model. - - This function accepts an optional irradiance adjustment factor, `k`, based - on [2]_. This applies a piece-wise adjustment to power based on irradiance, - where `k` is the reduction in actual power at 200 Wm⁻² relative to power - calculated at 200 W/m^2 as 0.2*`pdc0`. For example, a 500 W module that - produces 95 W at 200 W/m^2 (a 5% relative reduction in efficiency) would - have a value of `k` = 0.01. - - .. math:: - - k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} - - This adjustment increases relative efficiency for irradiance above 1000 - Wm⁻², which may not be desired. An optional input, `capped_adjustment`, - modifies the adjustment from [2]_ to only apply below 1000 Wm⁻². - - Note that ``pdc0`` is also used as a symbol in - :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC - power of the modules at reference conditions. ``pdc0`` in - :py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of - the inverter. + Implement NREL's PVWatts (Version 5) DC power model. Parameters ---------- @@ -2939,6 +2910,38 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., pdc: numeric DC power. [W] + Notes + ----- + The PVWatts Version 5 DC model [1]_ is: + + .. math:: + + P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref})) + + This model has also been referred to as the power temperature coefficient + model. + + This function accepts an optional irradiance adjustment factor, `k`, based + on [2]_. This applies a piece-wise adjustment to power based on irradiance, + where `k` is the reduction in actual power at 200 Wm⁻² relative to power + calculated at 200 Wm-2 as 0.2*`pdc0`. For example, a 500 W module that + produces 95 W at 200 Wm-2 (a 5% relative reduction in efficiency) would + have a value of `k` = 0.01. + + .. math:: + + k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} + + This adjustment increases relative efficiency for irradiance above 1000 + Wm⁻², which may not be desired. An optional input, `capped_adjustment`, + modifies the adjustment from [2]_ to only apply below 1000 Wm⁻². + + Note that ``pdc0`` is also used as a symbol in + :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC + power of the modules at reference conditions. ``pdc0`` in + :py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of + the inverter. + References ---------- .. [1] A. P. Dobos, "PVWatts Version 5 Manual" From 0d8b0b5f2b1e54b44f8b8cead089779a8a37bdbe Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:00:01 -0600 Subject: [PATCH 13/18] Update pvlib/pvsystem.py Co-authored-by: Will Holmgren --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index bb9a8b903e..610519eea4 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2968,7 +2968,7 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., pdc * (1 - err_2)) # "cap" Marion's correction at 1000 W/m^2 - if cap_adjustment is True: + if cap_adjustment: pdc_marion = np.where(effective_irradiance >= 1000, pdc, pdc_marion) From 90b7c54e7b5c7ce6b3671971a15fde0ffd5e6c9a Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 19:58:24 -0500 Subject: [PATCH 14/18] prevent negative power --- pvlib/pvsystem.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index bb9a8b903e..57b48d644d 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2901,7 +2901,8 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., Cell reference temperature. PVWatts defines it to be 25 C and is included here for flexibility. [C] k: numeric, optional - Irradiance correction factor, defined in [2]_. [unitless] + Irradiance correction factor, defined in [2]_. Typically positive. + [unitless] cap_adjustment: Boolean, default False If True, apply the optional adjustment at and below 1000 W/m^2. @@ -2973,6 +2974,10 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., pdc, pdc_marion) + # large k values can result in negative power at low irradiance, so + # set negative power to zero + pdc_marion[pdc_marion < 0] = 0 + pdc = pdc_marion return pdc From 4488e3ce497523f47c9796fe9a55b44ba81d5635 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 20:04:15 -0500 Subject: [PATCH 15/18] fix typo in error eqn --- pvlib/pvsystem.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index a85861dfa0..2fb02cfd48 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2960,9 +2960,8 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., # apply Marion's correction if k is anything but zero if k is not None: - err_1 = (k * (1 - (1 - effective_irradiance / 200)**4) / - (effective_irradiance / 1000)) - err_2 = (k * (1000 - effective_irradiance) / (1000 - 200)) + err_1 = k * (1 - (1 - effective_irradiance / 200)**4) + err_2 = k * (1000 - effective_irradiance) / (1000 - 200) pdc_marion = np.where(effective_irradiance <= 200, pdc * (1 - err_1), From 250af5a1df3287e3be97fee67581466b1827a0e7 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Wed, 8 Oct 2025 21:15:26 -0500 Subject: [PATCH 16/18] fix the right typo this time... --- pvlib/pvsystem.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 2fb02cfd48..f8ba6a37e1 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2960,8 +2960,10 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., # apply Marion's correction if k is anything but zero if k is not None: - err_1 = k * (1 - (1 - effective_irradiance / 200)**4) - err_2 = k * (1000 - effective_irradiance) / (1000 - 200) + err_1 = (k * (1 - (1 - effective_irradiance / 200)**4) / + (effective_irradiance / 1000)) + err_2 = (k * (1000 - effective_irradiance) / (1000 - 200) / + (effective_irradiance / 1000)) pdc_marion = np.where(effective_irradiance <= 200, pdc * (1 - err_1), From bd16ac2648dfe504bc3aec6233a8e82bef8edfe7 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Thu, 9 Oct 2025 16:07:23 -0500 Subject: [PATCH 17/18] reorder err eqns --- pvlib/pvsystem.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index f8ba6a37e1..04ecbf182c 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2960,14 +2960,12 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., # apply Marion's correction if k is anything but zero if k is not None: - err_1 = (k * (1 - (1 - effective_irradiance / 200)**4) / - (effective_irradiance / 1000)) - err_2 = (k * (1000 - effective_irradiance) / (1000 - 200) / - (effective_irradiance / 1000)) + err_1 = k * (1 - (1 - effective_irradiance / 200)**4) + err_2 = k * (1000 - effective_irradiance) / (1000 - 200) pdc_marion = np.where(effective_irradiance <= 200, - pdc * (1 - err_1), - pdc * (1 - err_2)) + pdc - (pdc0 * err_1), + pdc - (pdc0 * err_2)) # "cap" Marion's correction at 1000 W/m^2 if cap_adjustment: From f3041c21c6817c4ee3c111e9216c27d6d744b642 Mon Sep 17 00:00:00 2001 From: Will Hobbs <45701090+williamhobbs@users.noreply.github.com> Date: Thu, 9 Oct 2025 17:08:17 -0500 Subject: [PATCH 18/18] add more detail on `cap_adjustment` --- pvlib/pvsystem.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 04ecbf182c..f07d698379 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2933,9 +2933,12 @@ def pvwatts_dc(effective_irradiance, temp_cell, pdc0, gamma_pdc, temp_ref=25., k=\frac{0.2P_{dc0}-P_{200}}{P_{dc0}} - This adjustment increases relative efficiency for irradiance above 1000 - Wm⁻², which may not be desired. An optional input, `capped_adjustment`, - modifies the adjustment from [2]_ to only apply below 1000 Wm⁻². + For positive `k` values, and `k` is typically positive, this adjustment + increases relative efficiency when irradiance is above 1000 Wm⁻². This may + not be desired, as modules with nonlinear irradiance response often have + peak efficiency near 1000 Wm⁻², and it is either flat or declining at + higher irradiance. An optional parameter, `cap_adjustment`, can address + this by modifying the adjustment from [2]_ to only apply below 1000 Wm⁻². Note that ``pdc0`` is also used as a symbol in :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC