pvlib 0.11.1__py3-none-any.whl → 0.11.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. pvlib/_deprecation.py +73 -0
  2. pvlib/atmosphere.py +79 -0
  3. pvlib/clearsky.py +35 -22
  4. pvlib/data/pvgis_tmy_test.csv +8761 -0
  5. pvlib/data/tmy_45.000_8.000_2005_2023.csv +8789 -0
  6. pvlib/data/tmy_45.000_8.000_2005_2023.epw +8768 -0
  7. pvlib/data/tmy_45.000_8.000_2005_2023.json +1 -0
  8. pvlib/data/tmy_45.000_8.000_2005_2023.txt +8761 -0
  9. pvlib/data/tmy_45.000_8.000_userhorizon.json +1 -1
  10. pvlib/iam.py +4 -4
  11. pvlib/iotools/midc.py +1 -1
  12. pvlib/iotools/pvgis.py +0 -10
  13. pvlib/irradiance.py +98 -55
  14. pvlib/ivtools/sdm.py +75 -52
  15. pvlib/pvsystem.py +132 -84
  16. pvlib/solarposition.py +46 -30
  17. pvlib/spa.py +4 -2
  18. pvlib/spectrum/irradiance.py +2 -1
  19. pvlib/spectrum/spectrl2.py +2 -1
  20. pvlib/temperature.py +49 -3
  21. pvlib/tests/iotools/test_pvgis.py +9 -9
  22. pvlib/tests/ivtools/test_sdm.py +23 -1
  23. pvlib/tests/test__deprecation.py +97 -0
  24. pvlib/tests/test_atmosphere.py +147 -0
  25. pvlib/tests/test_clearsky.py +7 -1
  26. pvlib/tests/test_conftest.py +0 -44
  27. pvlib/tests/test_irradiance.py +56 -10
  28. pvlib/tests/test_pvsystem.py +17 -1
  29. pvlib/tests/test_solarposition.py +33 -0
  30. pvlib/tests/test_spa.py +29 -0
  31. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/METADATA +11 -10
  32. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/RECORD +36 -37
  33. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/WHEEL +1 -1
  34. pvlib/data/aod550_tcwv_20121101_test.nc +0 -0
  35. pvlib/data/pvgis_tmy_test.dat +0 -8761
  36. pvlib/data/tmy_45.000_8.000_2005_2020.csv +0 -8789
  37. pvlib/data/tmy_45.000_8.000_2005_2020.epw +0 -8768
  38. pvlib/data/tmy_45.000_8.000_2005_2020.json +0 -1
  39. pvlib/data/tmy_45.000_8.000_2005_2020.txt +0 -8761
  40. pvlib/data/variables_style_rules.csv +0 -56
  41. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/AUTHORS.md +0 -0
  42. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/LICENSE +0 -0
  43. {pvlib-0.11.1.dist-info → pvlib-0.11.2.dist-info}/top_level.txt +0 -0
pvlib/iam.py CHANGED
@@ -269,8 +269,8 @@ def martin_ruiz(aoi, a_r=0.16):
269
269
 
270
270
  which is presented as :math:`AL(\alpha) = 1 - IAM` in equation 4 of [1]_,
271
271
  with :math:`\alpha` representing the angle of incidence AOI. Thus IAM = 1
272
- at AOI = 0, and IAM = 0 at AOI = 90. This equation is only valid for
273
- -90 <= aoi <= 90, therefore `iam` is constrained to 0.0 outside this
272
+ at AOI = 0°, and IAM = 0 at AOI = 90°. This equation is only valid for
273
+ <= aoi <= 90°, therefore `iam` is constrained to 0.0 outside this
274
274
  interval.
275
275
 
276
276
  References
@@ -891,8 +891,8 @@ def schlick_diffuse(surface_tilt):
891
891
  implements only the integrated Schlick approximation.
892
892
 
893
893
  Note also that the output of this function (which is an exact integration)
894
- can be compared with the output of :py:func:`marion_diffuse` which numerically
895
- integrates the Schlick approximation:
894
+ can be compared with the output of :py:func:`marion_diffuse` which
895
+ numerically integrates the Schlick approximation:
896
896
 
897
897
  .. code::
898
898
 
pvlib/iotools/midc.py CHANGED
@@ -193,7 +193,7 @@ def read_midc(filename, variable_map={}, raw_data=False, **kwargs):
193
193
 
194
194
  See the MIDC_VARIABLE_MAP for collection of mappings by site.
195
195
  For a full list of pvlib variable names see the
196
- :ref:`variables_style_rules`.
196
+ :ref:`nomenclature`.
197
197
 
198
198
  Be sure to check the units for the variables you will use on the
199
199
  `MIDC site <https://midcdmz.nrel.gov/>`_.
pvlib/iotools/pvgis.py CHANGED
@@ -467,16 +467,6 @@ def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
467
467
  metadata : list or dict
468
468
  file metadata, ``None`` for basic
469
469
 
470
- Note
471
- ----
472
- The PVGIS website uses 10 years of data to generate the TMY, whereas the
473
- API accessed by this function defaults to using all available years. This
474
- means that the TMY returned by this function may not be identical to the
475
- one generated by the website. To replicate the website requests, specify
476
- the corresponding 10 year period using ``startyear`` and ``endyear``.
477
- Specifying ``endyear`` also avoids the TMY changing when new data becomes
478
- available.
479
-
480
470
  Raises
481
471
  ------
482
472
  requests.HTTPError
pvlib/irradiance.py CHANGED
@@ -16,7 +16,7 @@ from scipy.optimize import bisect
16
16
  from pvlib import atmosphere, solarposition, tools
17
17
  import pvlib # used to avoid dni name collision in complete_irradiance
18
18
 
19
- from pvlib._deprecation import pvlibDeprecationWarning
19
+ from pvlib._deprecation import pvlibDeprecationWarning, renamed_kwarg_warning
20
20
  import warnings
21
21
 
22
22
 
@@ -244,7 +244,7 @@ def beam_component(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
244
244
  solar_azimuth : numeric
245
245
  Solar azimuth angle.
246
246
  dni : numeric
247
- Direct Normal Irradiance
247
+ Direct normal irradiance, see :term:`dni`. [Wm⁻²]
248
248
 
249
249
  Returns
250
250
  -------
@@ -734,16 +734,14 @@ def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
734
734
  The Hay and Davies model determines the diffuse irradiance from
735
735
  the sky (ground reflected irradiance is not included in this
736
736
  algorithm) on a tilted surface using the surface tilt angle, surface
737
- azimuth angle, diffuse horizontal irradiance, direct normal
738
- irradiance, extraterrestrial irradiance, sun zenith angle, and sun
739
- azimuth angle.
737
+ azimuth angle, diffuse horizontal irradiance, direct normal irradiance,
738
+ extraterrestrial irradiance, sun zenith angle, and sun azimuth angle.
740
739
 
741
740
  Parameters
742
741
  ----------
743
742
  surface_tilt : numeric
744
- Surface tilt angles in decimal degrees. The tilt angle is
745
- defined as degrees from horizontal (e.g. surface facing up = 0,
746
- surface facing horizon = 90)
743
+ Panel tilt from the horizontal, in decimal degrees, see
744
+ :term:`surface_tilt`.
747
745
 
748
746
  surface_azimuth : numeric
749
747
  Surface azimuth angles in decimal degrees. The azimuth
@@ -754,7 +752,7 @@ def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
754
752
  Diffuse horizontal irradiance. [Wm⁻²]
755
753
 
756
754
  dni : numeric
757
- Direct normal irradiance. [Wm⁻²]
755
+ Direct normal irradiance, see :term:`dni`. [Wm⁻²]
758
756
 
759
757
  dni_extra : numeric
760
758
  Extraterrestrial normal irradiance. [Wm⁻²]
@@ -871,19 +869,14 @@ def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
871
869
  def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
872
870
  solar_zenith, solar_azimuth):
873
871
  r'''
874
- Determine diffuse irradiance from the sky on a tilted surface using
875
- Reindl's 1990 model
872
+ Determine the diffuse irradiance from the sky on a tilted surface using
873
+ the Reindl (1990) model.
876
874
 
877
- .. math::
878
-
879
- I_{d} = DHI \left(A R_b + (1 - A) \left(\frac{1 + \cos\beta}{2}\right)
880
- \left(1 + \sqrt{\frac{I_{hb}}{I_h}} \sin^3(\beta/2)\right) \right)
881
-
882
- Reindl's 1990 model determines the diffuse irradiance from the sky
883
- (ground reflected irradiance is not included in this algorithm) on a
884
- tilted surface using the surface tilt angle, surface azimuth angle,
875
+ The Reindl (1990) model [1]_ [2]_ determines the diffuse irradiance from
876
+ the sky on
877
+ a tilted surface using the surface tilt angle, surface azimuth angle,
885
878
  diffuse horizontal irradiance, direct normal irradiance, global
886
- horizontal irradiance, extraterrestrial irradiance, sun zenith
879
+ horizontal irradiance, extraterrestrial normal irradiance, sun zenith
887
880
  angle, and sun azimuth angle.
888
881
 
889
882
  Parameters
@@ -905,7 +898,7 @@ def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
905
898
  direct normal irradiance. [Wm⁻²]
906
899
 
907
900
  ghi: numeric
908
- Global irradiance. [Wm⁻²]
901
+ Global horizontal irradiance. [Wm⁻²]
909
902
 
910
903
  dni_extra : numeric
911
904
  Extraterrestrial normal irradiance. [Wm⁻²]
@@ -925,23 +918,41 @@ def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
925
918
 
926
919
  Notes
927
920
  -----
928
- The poa_sky_diffuse calculation is generated from the Loutzenhiser et al.
929
- (2007) paper, equation 8. Note that I have removed the beam and ground
930
- reflectance portion of the equation and this generates ONLY the diffuse
931
- radiation from the sky and circumsolar, so the form of the equation
932
- varies slightly from equation 8.
921
+ The Reindl (1990) model for the sky diffuse irradiance,
922
+ :math:`I_d`, is as follows:
923
+
924
+ .. math::
925
+
926
+ I_{d} = DHI \left(A \cdot R_b + (1 - A)
927
+ \left(\frac{1 + \cos\beta}{2}\right)
928
+ \left(1 + \sqrt{\frac{BHI}{GHI}} \sin^3(\beta/2)\right) \right).
929
+
930
+ :math:`DHI`, :math:`BHI`, and :math:`GHI` are the diffuse horizontal, beam
931
+ (direct) horizontal and global horizontal irradiances, respectively.
932
+ :math:`A` is the anisotropy index, which is the ratio of the direct normal
933
+ irradiance to the direct extraterrestrial irradiation, :math:`R_b` is the
934
+ projection ratio, which is defined as the ratio of the cosine of the angle
935
+ of incidence (AOI) to the cosine of the zenith angle, and :math:`\beta`
936
+ is the tilt angle of the array.
937
+
938
+ Implementation is based on Loutzenhiser et al.
939
+ (2007) [3]_, Equation 8. The beam and ground reflectance portion of the
940
+ equation have been removed, therefore the model described here generates
941
+ ONLY the diffuse radiation from the sky and circumsolar, so the form of the
942
+ equation varies slightly from Equation 8 in [3]_.
933
943
 
934
944
  References
935
945
  ----------
936
- .. [1] Loutzenhiser P.G. et. al. "Empirical validation of models to
937
- compute solar irradiance on inclined surfaces for building energy
938
- simulation" 2007, Solar Energy vol. 81. pp. 254-267
939
-
940
- .. [2] Reindl, D.T., Beckmann, W.A., Duffie, J.A., 1990a. Diffuse
946
+ .. [1] Reindl, D. T., Beckmann, W. A., Duffie, J. A., 1990a. Diffuse
941
947
  fraction correlations. Solar Energy 45(1), 1-7.
942
-
943
- .. [3] Reindl, D.T., Beckmann, W.A., Duffie, J.A., 1990b. Evaluation of
948
+ :doi:`10.1016/0038-092X(90)90060-P`
949
+ .. [2] Reindl, D. T., Beckmann, W. A., Duffie, J. A., 1990b. Evaluation of
944
950
  hourly tilted surface radiation models. Solar Energy 45(1), 9-17.
951
+ :doi:`10.1016/0038-092X(90)90061-G`
952
+ .. [3] Loutzenhiser P. G. et. al., 2007. Empirical validation of models to
953
+ compute solar irradiance on inclined surfaces for building energy
954
+ simulation. Solar Energy 81(2), 254-267
955
+ :doi:`10.1016/j.solener.2006.03.009`
945
956
  '''
946
957
 
947
958
  cos_tt = aoi_projection(surface_tilt, surface_azimuth,
@@ -1517,7 +1528,7 @@ def _ghi_from_poa(surface_tilt, surface_azimuth,
1517
1528
  def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
1518
1529
  solar_zenith, solar_azimuth,
1519
1530
  poa_global,
1520
- dni_extra=None, airmass=None, albedo=0.25,
1531
+ dni_extra, airmass=None, albedo=0.25,
1521
1532
  xtol=0.01,
1522
1533
  full_output=False):
1523
1534
  '''
@@ -1538,7 +1549,7 @@ def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
1538
1549
  Solar azimuth angle. [degree]
1539
1550
  poa_global : numeric
1540
1551
  Plane-of-array global irradiance, aka global tilted irradiance. [Wm⁻²]
1541
- dni_extra : numeric, optional
1552
+ dni_extra : numeric
1542
1553
  Extraterrestrial direct normal irradiance. [Wm⁻²]
1543
1554
  airmass : numeric, optional
1544
1555
  Relative airmass (not adjusted for pressure). [unitless]
@@ -1603,7 +1614,12 @@ def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
1603
1614
  return ghi
1604
1615
 
1605
1616
 
1606
- def clearsky_index(ghi, clearsky_ghi, max_clearsky_index=2.0):
1617
+ @renamed_kwarg_warning(
1618
+ since='0.11.2',
1619
+ old_param_name='clearsky_ghi',
1620
+ new_param_name='ghi_clear',
1621
+ removal="0.13.0")
1622
+ def clearsky_index(ghi, ghi_clear, max_clearsky_index=2.0):
1607
1623
  """
1608
1624
  Calculate the clearsky index.
1609
1625
 
@@ -1615,9 +1631,12 @@ def clearsky_index(ghi, clearsky_ghi, max_clearsky_index=2.0):
1615
1631
  ghi : numeric
1616
1632
  Global horizontal irradiance. [Wm⁻²]
1617
1633
 
1618
- clearsky_ghi : numeric
1634
+ ghi_clear : numeric
1619
1635
  Modeled clearsky GHI
1620
1636
 
1637
+ .. versionchanged:: 0.11.2
1638
+ Renamed from ``ghi_clearsky`` to ``ghi_clear``.
1639
+
1621
1640
  max_clearsky_index : numeric, default 2.0
1622
1641
  Maximum value of the clearsky index. The default, 2.0, allows
1623
1642
  for over-irradiance events typically seen in sub-hourly data.
@@ -1627,12 +1646,12 @@ def clearsky_index(ghi, clearsky_ghi, max_clearsky_index=2.0):
1627
1646
  clearsky_index : numeric
1628
1647
  Clearsky index
1629
1648
  """
1630
- clearsky_index = ghi / clearsky_ghi
1649
+ clearsky_index = ghi / ghi_clear
1631
1650
  # set +inf, -inf, and nans to zero
1632
1651
  clearsky_index = np.where(~np.isfinite(clearsky_index), 0,
1633
1652
  clearsky_index)
1634
1653
  # but preserve nans in the input arrays
1635
- input_is_nan = ~np.isfinite(ghi) | ~np.isfinite(clearsky_ghi)
1654
+ input_is_nan = ~np.isfinite(ghi) | ~np.isfinite(ghi_clear)
1636
1655
  clearsky_index = np.where(input_is_nan, np.nan, clearsky_index)
1637
1656
 
1638
1657
  clearsky_index = np.maximum(clearsky_index, 0)
@@ -2140,7 +2159,17 @@ def _dirint_bins(times, kt_prime, zenith, w, delta_kt_prime):
2140
2159
  return kt_prime_bin, zenith_bin, w_bin, delta_kt_prime_bin
2141
2160
 
2142
2161
 
2143
- def dirindex(ghi, ghi_clearsky, dni_clearsky, zenith, times, pressure=101325.,
2162
+ @renamed_kwarg_warning(
2163
+ since='0.11.2',
2164
+ old_param_name='ghi_clearsky',
2165
+ new_param_name='ghi_clear',
2166
+ removal="0.13.0")
2167
+ @renamed_kwarg_warning(
2168
+ since='0.11.2',
2169
+ old_param_name='dni_clearsky',
2170
+ new_param_name='dni_clear',
2171
+ removal="0.13.0")
2172
+ def dirindex(ghi, ghi_clear, dni_clear, zenith, times, pressure=101325.,
2144
2173
  use_delta_kt_prime=True, temp_dew=None, min_cos_zenith=0.065,
2145
2174
  max_zenith=87):
2146
2175
  """
@@ -2148,7 +2177,7 @@ def dirindex(ghi, ghi_clearsky, dni_clearsky, zenith, times, pressure=101325.,
2148
2177
 
2149
2178
  The DIRINDEX model [1]_ modifies the DIRINT model implemented in
2150
2179
  :py:func:`pvlib.irradiance.dirint` by taking into account information
2151
- from a clear sky model. It is recommended that ``ghi_clearsky`` be
2180
+ from a clear sky model. It is recommended that ``ghi_clear`` be
2152
2181
  calculated using the Ineichen clear sky model
2153
2182
  :py:func:`pvlib.clearsky.ineichen` with ``perez_enhancement=True``.
2154
2183
 
@@ -2159,12 +2188,18 @@ def dirindex(ghi, ghi_clearsky, dni_clearsky, zenith, times, pressure=101325.,
2159
2188
  ghi : array-like
2160
2189
  Global horizontal irradiance. [Wm⁻²]
2161
2190
 
2162
- ghi_clearsky : array-like
2191
+ ghi_clear : array-like
2163
2192
  Global horizontal irradiance from clear sky model. [Wm⁻²]
2164
2193
 
2165
- dni_clearsky : array-like
2194
+ .. versionchanged:: 0.11.2
2195
+ Renamed from ``ghi_clearsky`` to ``ghi_clear``.
2196
+
2197
+ dni_clear : array-like
2166
2198
  Direct normal irradiance from clear sky model. [Wm⁻²]
2167
2199
 
2200
+ .. versionchanged:: 0.11.2
2201
+ Renamed from ``dni_clearsky`` to ``dni_clear``.
2202
+
2168
2203
  zenith : array-like
2169
2204
  True (not refraction-corrected) zenith angles in decimal
2170
2205
  degrees. If Z is a vector it must be of the same size as all
@@ -2221,14 +2256,14 @@ def dirindex(ghi, ghi_clearsky, dni_clearsky, zenith, times, pressure=101325.,
2221
2256
  temp_dew=temp_dew, min_cos_zenith=min_cos_zenith,
2222
2257
  max_zenith=max_zenith)
2223
2258
 
2224
- dni_dirint_clearsky = dirint(ghi_clearsky, zenith, times,
2259
+ dni_dirint_clearsky = dirint(ghi_clear, zenith, times,
2225
2260
  pressure=pressure,
2226
2261
  use_delta_kt_prime=use_delta_kt_prime,
2227
2262
  temp_dew=temp_dew,
2228
2263
  min_cos_zenith=min_cos_zenith,
2229
2264
  max_zenith=max_zenith)
2230
2265
 
2231
- dni_dirindex = dni_clearsky * dni_dirint / dni_dirint_clearsky
2266
+ dni_dirindex = dni_clear * dni_dirint / dni_dirint_clearsky
2232
2267
 
2233
2268
  dni_dirindex[dni_dirindex < 0] = 0.
2234
2269
 
@@ -3600,7 +3635,12 @@ def _get_dirint_coeffs():
3600
3635
  return coeffs[1:, 1:, :, :]
3601
3636
 
3602
3637
 
3603
- def dni(ghi, dhi, zenith, clearsky_dni=None, clearsky_tolerance=1.1,
3638
+ @renamed_kwarg_warning(
3639
+ since='0.11.2',
3640
+ old_param_name='clearsky_dni',
3641
+ new_param_name='dni_clear',
3642
+ removal="0.13.0")
3643
+ def dni(ghi, dhi, zenith, dni_clear=None, clearsky_tolerance=1.1,
3604
3644
  zenith_threshold_for_zero_dni=88.0,
3605
3645
  zenith_threshold_for_clearsky_limit=80.0):
3606
3646
  """
@@ -3624,11 +3664,14 @@ def dni(ghi, dhi, zenith, clearsky_dni=None, clearsky_tolerance=1.1,
3624
3664
  True (not refraction-corrected) zenith angles in decimal
3625
3665
  degrees. Angles must be >=0 and <=180.
3626
3666
 
3627
- clearsky_dni : Series, optional
3628
- Clearsky direct normal irradiance.
3667
+ dni_clear : Series, optional
3668
+ Clearsky direct normal irradiance. [Wm⁻²]
3669
+
3670
+ .. versionchanged:: 0.11.2
3671
+ Renamed from ``clearsky_dni`` to ``dni_clear``.
3629
3672
 
3630
3673
  clearsky_tolerance : float, default 1.1
3631
- If 'clearsky_dni' is given this parameter can be used to allow a
3674
+ If ``dni_clear`` is given this parameter can be used to allow a
3632
3675
  tolerance by how much the calculated DNI value can be greater than
3633
3676
  the clearsky value before it is identified as an unreasonable value.
3634
3677
 
@@ -3641,7 +3684,7 @@ def dni(ghi, dhi, zenith, clearsky_dni=None, clearsky_tolerance=1.1,
3641
3684
  'zenith_threshold_for_clearsky_limit' and smaller the
3642
3685
  'zenith_threshold_for_zero_dni' that are greater than the clearsky DNI
3643
3686
  (times allowed tolerance) will be corrected. Only applies if
3644
- 'clearsky_dni' is not None.
3687
+ ``dni_clear`` is not None.
3645
3688
 
3646
3689
  Returns
3647
3690
  -------
@@ -3663,8 +3706,8 @@ def dni(ghi, dhi, zenith, clearsky_dni=None, clearsky_tolerance=1.1,
3663
3706
  # zenith_threshold_for_clearsky_limit and smaller than the
3664
3707
  # upper_cutoff_zenith that are greater than the clearsky DNI (times
3665
3708
  # clearsky_tolerance)
3666
- if clearsky_dni is not None:
3667
- max_dni = clearsky_dni * clearsky_tolerance
3709
+ if dni_clear is not None:
3710
+ max_dni = dni_clear * clearsky_tolerance
3668
3711
  dni[(zenith >= zenith_threshold_for_clearsky_limit) &
3669
3712
  (zenith < zenith_threshold_for_zero_dni) &
3670
3713
  (dni > max_dni)] = max_dni
@@ -3705,8 +3748,8 @@ def complete_irradiance(solar_zenith,
3705
3748
  Pandas series of dni data, with datetime index. Must have the same
3706
3749
  datetime index as ghi, dhi, and zenith series, when available.
3707
3750
  dni_clear : Series, optional
3708
- Pandas series of clearsky dni data. Must have the same datetime index
3709
- as ghi, dhi, dni, and zenith series, when available. See
3751
+ Pandas series of clearsky dni data [Wm⁻²]. Must have the same datetime
3752
+ index as ghi, dhi, dni, and zenith series, when available. See
3710
3753
  :py:func:`dni` for details.
3711
3754
 
3712
3755
  Returns
@@ -3716,7 +3759,7 @@ def complete_irradiance(solar_zenith,
3716
3759
  """
3717
3760
  if ghi is not None and dhi is not None and dni is None:
3718
3761
  dni = pvlib.irradiance.dni(ghi, dhi, solar_zenith,
3719
- clearsky_dni=dni_clear,
3762
+ dni_clear=dni_clear,
3720
3763
  clearsky_tolerance=1.1)
3721
3764
  elif dni is not None and dhi is not None and ghi is None:
3722
3765
  ghi = (dhi + dni * tools.cosd(solar_zenith))
pvlib/ivtools/sdm.py CHANGED
@@ -120,52 +120,55 @@ def fit_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc,
120
120
 
121
121
  def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
122
122
  EgRef=1.121, dEgdT=-0.0002677, temp_ref=25, irrad_ref=1000,
123
- root_kwargs={}):
123
+ init_guess={}, root_kwargs={}):
124
124
  """
125
125
  Calculates the parameters for the De Soto single diode model.
126
126
 
127
- This procedure (described in [1]_) has the advantage of
128
- using common specifications given by manufacturers in the
127
+ This procedure (described in [1]_) fits the De Soto model [2]_ using
128
+ common specifications given by manufacturers in the
129
129
  datasheets of PV modules.
130
130
 
131
- The solution is found using the scipy.optimize.root() function,
132
- with the corresponding default solver method 'hybr'.
133
- No restriction is put on the fit variables, i.e. series
131
+ The solution is found using :py:func:`scipy.optimize.root`,
132
+ with the default solver method 'hybr'.
133
+ No restriction is put on the fit variables, e.g. series
134
134
  or shunt resistance could go negative. Nevertheless, if it happens,
135
- check carefully the inputs and their units; alpha_sc and beta_voc are
136
- often given in %/K in manufacturers datasheets and should be given
137
- in A/K and V/K here.
135
+ check carefully the inputs and their units. For example, ``alpha_sc`` and
136
+ ``beta_voc`` are often given in %/K in manufacturers datasheets but should
137
+ be given in A/K and V/K here.
138
138
 
139
139
  The parameters returned by this function can be used by
140
- :py:func:`pvlib.pvsystem.calcparams_desoto` to calculate the values at
141
- different irradiance and cell temperature.
140
+ :py:func:`pvlib.pvsystem.calcparams_desoto` to calculate single diode
141
+ equation parameters at different irradiance and cell temperature.
142
142
 
143
143
  Parameters
144
144
  ----------
145
145
  v_mp: float
146
- Module voltage at the maximum-power point at reference conditions [V].
146
+ Module voltage at the maximum-power point at reference conditions. [V]
147
147
  i_mp: float
148
- Module current at the maximum-power point at reference conditions [A].
148
+ Module current at the maximum-power point at reference conditions. [A]
149
149
  v_oc: float
150
- Open-circuit voltage at reference conditions [V].
150
+ Open-circuit voltage at reference conditions. [V]
151
151
  i_sc: float
152
- Short-circuit current at reference conditions [A].
152
+ Short-circuit current at reference conditions. [A]
153
153
  alpha_sc: float
154
- The short-circuit current (i_sc) temperature coefficient of the
155
- module [A/K].
154
+ The short-circuit current (``i_sc``) temperature coefficient of the
155
+ module. [A/K]
156
156
  beta_voc: float
157
- The open-circuit voltage (v_oc) temperature coefficient of the
158
- module [V/K].
157
+ The open-circuit voltage (``v_oc``) temperature coefficient of the
158
+ module. [V/K]
159
159
  cells_in_series: integer
160
160
  Number of cell in the module.
161
161
  EgRef: float, default 1.121 eV - value for silicon
162
- Energy of bandgap of semi-conductor used [eV]
162
+ Energy of bandgap of semi-conductor used. [eV]
163
163
  dEgdT: float, default -0.0002677 - value for silicon
164
- Variation of bandgap according to temperature [eV/K]
164
+ Variation of bandgap according to temperature. [1/K]
165
165
  temp_ref: float, default 25
166
- Reference temperature condition [C]
166
+ Reference temperature condition. [C]
167
167
  irrad_ref: float, default 1000
168
- Reference irradiance condition [W/m2]
168
+ Reference irradiance condition. [Wm⁻²]
169
+ init_guess: dict, optional
170
+ Initial values for optimization. Keys can be `'Rsh_0'`, `'a_0'`,
171
+ `'IL_0'`, `'Io_0'`, `'Rs_0'`.
169
172
  root_kwargs : dictionary, optional
170
173
  Dictionary of arguments to pass onto scipy.optimize.root()
171
174
 
@@ -173,13 +176,13 @@ def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
173
176
  -------
174
177
  dict with the following elements:
175
178
  I_L_ref: float
176
- Light-generated current at reference conditions [A]
179
+ Light-generated current at reference conditions. [A]
177
180
  I_o_ref: float
178
- Diode saturation current at reference conditions [A]
181
+ Diode saturation current at reference conditions. [A]
179
182
  R_s: float
180
- Series resistance [ohm]
183
+ Series resistance. [ohm]
181
184
  R_sh_ref: float
182
- Shunt resistance at reference conditions [ohm].
185
+ Shunt resistance at reference conditions. [ohm].
183
186
  a_ref: float
184
187
  Modified ideality factor at reference conditions.
185
188
  The product of the usual diode ideality factor (n, unitless),
@@ -187,15 +190,15 @@ def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
187
190
  specified effective irradiance and cell temperature.
188
191
  alpha_sc: float
189
192
  The short-circuit current (i_sc) temperature coefficient of the
190
- module [A/K].
193
+ module. [A/K]
191
194
  EgRef: float
192
- Energy of bandgap of semi-conductor used [eV]
195
+ Energy of bandgap of semi-conductor used. [eV]
193
196
  dEgdT: float
194
- Variation of bandgap according to temperature [eV/K]
197
+ Variation of bandgap according to temperature. [1/K]
195
198
  irrad_ref: float
196
- Reference irradiance condition [W/m2]
199
+ Reference irradiance condition. [Wm⁻²]
197
200
  temp_ref: float
198
- Reference temperature condition [C]
201
+ Reference temperature condition. [C]
199
202
 
200
203
  scipy.optimize.OptimizeResult
201
204
  Optimization result of scipy.optimize.root().
@@ -203,9 +206,12 @@ def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
203
206
 
204
207
  References
205
208
  ----------
206
- .. [1] W. De Soto et al., "Improvement and validation of a model for
209
+ .. [1] J. A Duffie, W. A Beckman, "Solar Engineering of Thermal Processes",
210
+ 4th ed., Wiley, 2013. :doi:`10.1002/9781118671603`
211
+ .. [2] W. De Soto et al., "Improvement and validation of a model for
207
212
  photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
208
213
  2006. :doi:`10.1016/j.solener.2005.06.010`
214
+
209
215
  """
210
216
 
211
217
  # Constants
@@ -213,14 +219,24 @@ def fit_desoto(v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc, cells_in_series,
213
219
  Tref = temp_ref + 273.15 # [K]
214
220
 
215
221
  # initial guesses of variables for computing convergence:
216
- # Values are taken from [2], p753
217
- Rsh_0 = 100.0
218
- a_0 = 1.5*k*Tref*cells_in_series
219
- IL_0 = i_sc
220
- Io_0 = i_sc * np.exp(-v_oc/a_0)
221
- Rs_0 = (a_0*np.log1p((IL_0-i_mp)/Io_0) - v_mp)/i_mp
222
+ # Default values are taken from [1], p753
223
+ init_guess_keys = ['IL_0', 'Io_0', 'Rs_0', 'Rsh_0', 'a_0'] # order matters
224
+ init = {key: None for key in init_guess_keys}
225
+ init['IL_0'] = i_sc
226
+ init['a_0'] = 1.5*k*Tref*cells_in_series
227
+ init['Io_0'] = i_sc * np.exp(-v_oc/init['a_0'])
228
+ init['Rs_0'] = (init['a_0']*np.log1p((init['IL_0'] - i_mp)/init['Io_0'])
229
+ - v_mp) / i_mp
230
+ init['Rsh_0'] = 100.0
231
+ # overwrite if optional init_guess is provided
232
+ for key in init_guess:
233
+ if key in init_guess_keys:
234
+ init[key] = init_guess[key]
235
+ else:
236
+ raise ValueError(f"'{key}' is not a valid name;"
237
+ f" allowed values are {init_guess_keys}")
222
238
  # params_i : initial values vector
223
- params_i = np.array([IL_0, Io_0, Rs_0, Rsh_0, a_0])
239
+ params_i = np.array([init[k] for k in init_guess_keys])
224
240
 
225
241
  # specs of module
226
242
  specs = (i_sc, v_oc, i_mp, v_mp, beta_voc, alpha_sc, EgRef, dEgdT,
@@ -546,27 +562,34 @@ def fit_desoto_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
546
562
  -------
547
563
  dict
548
564
  I_L_ref : float
549
- light current at STC [A]
565
+ Light current at STC [A]
550
566
  I_o_ref : float
551
- dark current at STC [A]
567
+ Dark current at STC [A]
552
568
  EgRef : float
553
- effective band gap at STC [eV]
569
+ Effective band gap at STC [eV]
554
570
  R_s : float
555
- series resistance at STC [ohm]
571
+ Series resistance at STC [ohm]
556
572
  R_sh_ref : float
557
- shunt resistance at STC [ohm]
573
+ Shunt resistance at STC [ohm]
558
574
  cells_in_series : int
559
- number of cells in series
575
+ Number of cells in series
560
576
  iph : array
561
- light current for each IV curve [A]
577
+ Light current for each IV curve [A]
562
578
  io : array
563
- dark current for each IV curve [A]
579
+ Dark current for each IV curve [A]
564
580
  rs : array
565
- series resistance for each IV curve [ohm]
581
+ Series resistance for each IV curve [ohm]
566
582
  rsh : array
567
- shunt resistance for each IV curve [ohm]
583
+ Shunt resistance for each IV curve [ohm]
584
+ a_ref : float
585
+ The product of the usual diode ideality factor (n, unitless),
586
+ number of cells in series (Ns), and cell thermal voltage at
587
+ reference conditions, in units of V.
588
+ dEgdT : float
589
+ The temperature dependence of the energy bandgap (Eg) at reference
590
+ conditions [1/K].
568
591
  u : array
569
- boolean for each IV curve indicating that the parameter values
592
+ Boolean for each IV curve indicating that the parameter values
570
593
  are deemed reasonable by the private function ``_filter_params``
571
594
 
572
595
  Notes
@@ -855,7 +878,7 @@ def _extract_sdm_params(ee, tc, iph, io, rs, rsh, n, u, specs, const,
855
878
  params['R_sh_exp'] = R_sh_exp
856
879
 
857
880
  elif model == 'desoto':
858
- dEgdT = 0.0002677
881
+ dEgdT = -0.0002677
859
882
  x_for_io = const['q'] / const['k'] * (
860
883
  1. / tok - 1. / tck[u] + dEgdT * (tc[u] - const['T0']) / tck[u])
861
884