Repository: pvlib/pvlib-python
Pull request #676 (2019-03-19 21:17:11)

fix pvwatts_ac exception and return value when called with pdc=0s
 - [x] Closes  #675 
- [x] I am familiar with the [contributing guidelines](http://pvlib-python.readthedocs.io/en/latest/contributing.html).
 - [x] Fully tested. Added and/or modified tests to ensure correct behavior for all reasonable inputs. Tests (usually) must pass on the TravisCI and Appveyor testing services.
 - [x] Updates entries to `docs/sphinx/source/api.rst` for API changes.
 - [x] Adds description and name entries in the appropriate `docs/sphinx/source/whatsnew` file for all changes.
 - [x] Code quality and style is sufficient. Passes LGTM and SticklerCI checks.
 - [x] New code is fully documented. Includes sphinx/numpydoc compliant docstrings and comments in the code where necessary.
 - [x] Pull request is nearly complete and ready for detailed review.




wholmgren: @mikofski a [stack overflow](https://stackoverflow.com/a/37977222/2802993) user gets the credit, as usual!
wholmgren: @cwhanse go ahead and merge if this looks good to you too.

Patch:
diff --git a/docs/sphinx/source/whatsnew/v0.6.2.rst b/docs/sphinx/source/whatsnew/v0.6.2.rst
index 579ebdc..aff869e 100644
--- a/docs/sphinx/source/whatsnew/v0.6.2.rst
+++ b/docs/sphinx/source/whatsnew/v0.6.2.rst
@@ -24,6 +24,9 @@ Enhancements
 Bug fixes
 ~~~~~~~~~
 * Compatibility with pandas 0.24 deprecations. (:issue:`659`)
+* pvwatts_ac raised ZeroDivisionError when called with scalar pdc=0
+  and a RuntimeWarning for array(0) input. Now correctly returns 0s
+  of the appropriate type. (:issue:`675`)
 
 
 Testing
diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py
index 35e4833..5ee22de 100644
--- a/pvlib/pvsystem.py
+++ b/pvlib/pvsystem.py
@@ -2967,8 +2967,15 @@ def pvwatts_ac(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
     pac0 = eta_inv_nom * pdc0
     zeta = pdc / pdc0
 
+    # arrays to help avoid divide by 0 for scalar and array
+    eta = np.zeros_like(pdc, dtype=float)
+    pdc_neq_0 = ~np.equal(pdc, 0)
+
     # eta < 0 if zeta < 0.006. pac is forced to be >= 0 below. GH 541
-    eta = eta_inv_nom / eta_inv_ref * (-0.0162*zeta - 0.0059/zeta + 0.9858)
+    eta = eta_inv_nom / eta_inv_ref * (
+        - 0.0162*zeta
+        - np.divide(0.0059, zeta, out=eta, where=pdc_neq_0)
+        + 0.9858)
 
     pac = eta * pdc
     pac = np.minimum(pac0, pac)


Test patch:
diff --git a/pvlib/test/test_pvsystem.py b/pvlib/test/test_pvsystem.py
index 3b44652..cd7679f 100644
--- a/pvlib/test/test_pvsystem.py
+++ b/pvlib/test/test_pvsystem.py
@@ -1366,6 +1366,10 @@ def test_pvwatts_ac_scalars():
     expected = 85.58556604752516
     out = pvsystem.pvwatts_ac(90, 100, 0.95)
     assert_allclose(out, expected)
+    # GH 675
+    expected = 0.
+    out = pvsystem.pvwatts_ac(0., 100)
+    assert_allclose(out, expected)
 
 
 def test_pvwatts_ac_possible_negative():
@@ -1378,9 +1382,10 @@ def test_pvwatts_ac_possible_negative():
 
 @needs_numpy_1_10
 def test_pvwatts_ac_arrays():
-    pdc = np.array([[np.nan], [50], [100]])
+    pdc = np.array([[np.nan], [0], [50], [100]])
     pdc0 = 100
     expected = np.array([[nan],
+                         [0.],
                          [47.60843624],
                          [95.]])
     out = pvsystem.pvwatts_ac(pdc, pdc0, 0.95)
@@ -1388,9 +1393,9 @@ def test_pvwatts_ac_arrays():
 
 
 def test_pvwatts_ac_series():
-    pdc = pd.Series([np.nan, 50, 100])
+    pdc = pd.Series([np.nan, 0, 50, 100])
     pdc0 = 100
-    expected = pd.Series(np.array([       nan,  47.608436,  95.      ]))
+    expected = pd.Series(np.array([nan, 0., 47.608436, 95.]))
     out = pvsystem.pvwatts_ac(pdc, pdc0, 0.95)
     assert_series_equal(expected, out)