From fb3a3de581012268e68239118de85258049e7bc3 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 08:41:03 -0700 Subject: [PATCH 1/6] implement inverter.pvwatts_multi --- docs/sphinx/source/api.rst | 1 + docs/sphinx/source/whatsnew/v0.8.1.rst | 4 +-- pvlib/inverter.py | 40 ++++++++++++++++++++++++-- pvlib/tests/test_inverter.py | 19 ++++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index 1306ed79d1..7db1b09034 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -295,6 +295,7 @@ Inverter models (DC to AC conversion) inverter.sandia_multi inverter.adr inverter.pvwatts + inverter.pvwatts_multi Functions for fitting inverter models diff --git a/docs/sphinx/source/whatsnew/v0.8.1.rst b/docs/sphinx/source/whatsnew/v0.8.1.rst index abd816424b..7e7e243a1c 100644 --- a/docs/sphinx/source/whatsnew/v0.8.1.rst +++ b/docs/sphinx/source/whatsnew/v0.8.1.rst @@ -17,8 +17,8 @@ Enhancements option to :py:class:`~pvlib.modelchain.ModelChain`. (:pull:`1042`) (:issue:`1073`) * Added :py:func:`pvlib.temperature.ross` for cell temperature modeling using only NOCT. (:pull:`1045`) -* Added :py:func:`pvlib.inverter.sandia_multi` for modeling inverters with - multiple MPPTs (:issue:`457`, :pull:`1085`) +* Added :py:func:`pvlib.inverter.sandia_multi` and :py:func:`pvlib.inverter.pvwatts_multi` + for modeling inverters with multiple MPPTs (:issue:`457`, :pull:`1085`, :pull:`1103`) * Added optional ``attributes`` parameter to :py:func:`pvlib.iotools.get_psm3` and added the option of fetching 5- and 15-minute PSM3 data. (:pull:`1086`) * Added :py:func:`pvlib.irradiance.campbell_norman` for estimating DNI, DHI and GHI diff --git a/pvlib/inverter.py b/pvlib/inverter.py index 90a94a51ec..28f8e15699 100644 --- a/pvlib/inverter.py +++ b/pvlib/inverter.py @@ -328,7 +328,7 @@ def adr(v_dc, p_dc, inverter, vtol=0.10): def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): r""" - Implements NREL's PVWatts inverter model. + Extends NREL's PVWatts inverter model for multiple MPP inputs. The PVWatts inverter model [1]_ calculates inverter efficiency :math:`\eta` as a function of input DC power @@ -348,8 +348,9 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): Parameters ---------- - pdc: numeric - DC power. Same unit as ``pdc0``. + p_dc : tuple, list or array of numeric + DC power on each MPPT input of the inverter. If type is array, must + be 2d with axis 0 being the MPPT inputs. Same unit as ``pdc0``. pdc0: numeric DC input limit of the inverter. Same unit as ``pdc``. eta_inv_nom: numeric, default 0.96 @@ -396,6 +397,39 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): return power_ac +def pvwatts_multi(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): + r""" + Extends NREL's PVWatts inverter model for multiple MPP inputs. + + DC input power is summed over MPP inputs to obtain the DC power + input to the PVWatts inverter model. See :py:func:`pvlib.inverter.pvwatts` + for details. + + Parameters + ---------- + p_dc : tuple, list or array of numeric + DC power on each MPPT input of the inverter. If type is array, must + be 2d with axis 0 being the MPPT inputs. Same unit as ``pdc0``. + pdc0: numeric + DC input limit of the inverter. Same unit as ``pdc``. + eta_inv_nom: numeric, default 0.96 + Nominal inverter efficiency. [unitless] + eta_inv_ref: numeric, default 0.9637 + Reference inverter efficiency. PVWatts defines it to be 0.9637 + and is included here for flexibility. [unitless] + + Returns + ------- + power_ac: numeric + AC power. Same unit as ``pdc0``. + + See also + -------- + pvlib.inverter.pvwatts + """ + return pvwatts(sum(pdc), pdc0, eta_inv_nom, eta_inv_ref) + + def fit_sandia(ac_power, dc_power, dc_voltage, dc_voltage_level, p_ac_0, p_nt): r''' Determine parameters for the Sandia inverter model. diff --git a/pvlib/tests/test_inverter.py b/pvlib/tests/test_inverter.py index 7ea2b8dda3..46ecb7a3a0 100644 --- a/pvlib/tests/test_inverter.py +++ b/pvlib/tests/test_inverter.py @@ -171,6 +171,25 @@ def test_pvwatts_series(): assert_series_equal(expected, out) +def test_pvwatts_multi(): + pdc = np.array([np.nan, 0, 50, 100]) / 2 + pdc0 = 100 + expected = np.array([np.nan, 0., 47.608436, 95.]) + out = inverter.pvwatts_multi((pdc, pdc), pdc0, 0.95) + assert_allclose(expected, out) + # with 2D array + pdc_2d = np.array([pdc, pdc]).T + out = inverter.pvwatts_multi((pdc_2d, pdc_2d), pdc0, 0.95) + assert_allclose(expected, out) + # with Series + pdc = pd.Series(pdc) + out = inverter.pvwatts_multi((pdc, pdc), pdc0, 0.95) + assert_series_equal(expected, out) + # with list instead of tuple + out = inverter.pvwatts_multi([pdc, pdc], pdc0, 0.95) + assert_series_equal(expected, out) + + INVERTER_TEST_MEAS = DATA_DIR / 'inverter_fit_snl_meas.csv' INVERTER_TEST_SIM = DATA_DIR / 'inverter_fit_snl_sim.csv' From ac2bd9764c8fbb96aacf924573d5ebdcbd92a20e Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 08:55:31 -0700 Subject: [PATCH 2/6] fix text, formatting --- pvlib/tests/test_inverter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/tests/test_inverter.py b/pvlib/tests/test_inverter.py index 46ecb7a3a0..0262576c1e 100644 --- a/pvlib/tests/test_inverter.py +++ b/pvlib/tests/test_inverter.py @@ -179,7 +179,7 @@ def test_pvwatts_multi(): assert_allclose(expected, out) # with 2D array pdc_2d = np.array([pdc, pdc]).T - out = inverter.pvwatts_multi((pdc_2d, pdc_2d), pdc0, 0.95) + out = inverter.pvwatts_multi(pdc_2d, pdc0, 0.95) assert_allclose(expected, out) # with Series pdc = pd.Series(pdc) @@ -188,7 +188,7 @@ def test_pvwatts_multi(): # with list instead of tuple out = inverter.pvwatts_multi([pdc, pdc], pdc0, 0.95) assert_series_equal(expected, out) - + INVERTER_TEST_MEAS = DATA_DIR / 'inverter_fit_snl_meas.csv' INVERTER_TEST_SIM = DATA_DIR / 'inverter_fit_snl_sim.csv' From 1648f09fb10da740f51b973af2c86ef5474df9c3 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 08:58:23 -0700 Subject: [PATCH 3/6] fix docstring --- pvlib/inverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/inverter.py b/pvlib/inverter.py index 28f8e15699..5e84361710 100644 --- a/pvlib/inverter.py +++ b/pvlib/inverter.py @@ -328,7 +328,7 @@ def adr(v_dc, p_dc, inverter, vtol=0.10): def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): r""" - Extends NREL's PVWatts inverter model for multiple MPP inputs. + NREL's PVWatts inverter model. The PVWatts inverter model [1]_ calculates inverter efficiency :math:`\eta` as a function of input DC power From 9c923099ecd336f06b466c16be8eead27d2111d2 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 09:12:50 -0700 Subject: [PATCH 4/6] remove mistaken .T --- pvlib/tests/test_inverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/tests/test_inverter.py b/pvlib/tests/test_inverter.py index 0262576c1e..af241ef220 100644 --- a/pvlib/tests/test_inverter.py +++ b/pvlib/tests/test_inverter.py @@ -178,7 +178,7 @@ def test_pvwatts_multi(): out = inverter.pvwatts_multi((pdc, pdc), pdc0, 0.95) assert_allclose(expected, out) # with 2D array - pdc_2d = np.array([pdc, pdc]).T + pdc_2d = np.array([pdc, pdc]) out = inverter.pvwatts_multi(pdc_2d, pdc0, 0.95) assert_allclose(expected, out) # with Series From 97da62a4a79fb5100b634d2979fda4b9adbe738c Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 10:10:33 -0700 Subject: [PATCH 5/6] review --- docs/sphinx/source/whatsnew/v0.8.1.rst | 2 +- pvlib/inverter.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.8.1.rst b/docs/sphinx/source/whatsnew/v0.8.1.rst index 7e7e243a1c..c5fd0540fe 100644 --- a/docs/sphinx/source/whatsnew/v0.8.1.rst +++ b/docs/sphinx/source/whatsnew/v0.8.1.rst @@ -18,7 +18,7 @@ Enhancements * Added :py:func:`pvlib.temperature.ross` for cell temperature modeling using only NOCT. (:pull:`1045`) * Added :py:func:`pvlib.inverter.sandia_multi` and :py:func:`pvlib.inverter.pvwatts_multi` - for modeling inverters with multiple MPPTs (:issue:`457`, :pull:`1085`, :pull:`1103`) + for modeling inverters with multiple MPPTs (:issue:`457`, :pull:`1085`, :pull:`1106`) * Added optional ``attributes`` parameter to :py:func:`pvlib.iotools.get_psm3` and added the option of fetching 5- and 15-minute PSM3 data. (:pull:`1086`) * Added :py:func:`pvlib.irradiance.campbell_norman` for estimating DNI, DHI and GHI diff --git a/pvlib/inverter.py b/pvlib/inverter.py index 5e84361710..d603a79fa9 100644 --- a/pvlib/inverter.py +++ b/pvlib/inverter.py @@ -348,9 +348,8 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): Parameters ---------- - p_dc : tuple, list or array of numeric - DC power on each MPPT input of the inverter. If type is array, must - be 2d with axis 0 being the MPPT inputs. Same unit as ``pdc0``. + p_dc : numeric + DC power. Same unit as ``pdc0``. pdc0: numeric DC input limit of the inverter. Same unit as ``pdc``. eta_inv_nom: numeric, default 0.96 @@ -372,6 +371,10 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): :py:func:`pvlib.pvsystem.pvwatts_dc` refers to the DC power of the modules at reference conditions. + See Also + -------- + pvlib.inverter.pvwatts_multi + References ---------- .. [1] A. P. Dobos, "PVWatts Version 5 Manual," @@ -399,7 +402,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): def pvwatts_multi(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): r""" - Extends NREL's PVWatts inverter model for multiple MPP inputs. + Extend NREL's PVWatts inverter model for multiple MPP inputs. DC input power is summed over MPP inputs to obtain the DC power input to the PVWatts inverter model. See :py:func:`pvlib.inverter.pvwatts` @@ -423,7 +426,7 @@ def pvwatts_multi(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): power_ac: numeric AC power. Same unit as ``pdc0``. - See also + See Also -------- pvlib.inverter.pvwatts """ From 0c55e50f0675119e2b10a8e9e210017ad26e2911 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Fri, 11 Dec 2020 10:30:53 -0700 Subject: [PATCH 6/6] pdc not p_dc in docstring --- pvlib/inverter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/inverter.py b/pvlib/inverter.py index d603a79fa9..3c2fca9123 100644 --- a/pvlib/inverter.py +++ b/pvlib/inverter.py @@ -348,7 +348,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): Parameters ---------- - p_dc : numeric + pdc : numeric DC power. Same unit as ``pdc0``. pdc0: numeric DC input limit of the inverter. Same unit as ``pdc``. @@ -410,7 +410,7 @@ def pvwatts_multi(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637): Parameters ---------- - p_dc : tuple, list or array of numeric + pdc : tuple, list or array of numeric DC power on each MPPT input of the inverter. If type is array, must be 2d with axis 0 being the MPPT inputs. Same unit as ``pdc0``. pdc0: numeric