pvlib 0.9.4a1__py3-none-any.whl → 0.10.0__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 (86) hide show
  1. pvlib/__init__.py +3 -2
  2. pvlib/atmosphere.py +23 -173
  3. pvlib/bifacial/infinite_sheds.py +88 -277
  4. pvlib/bifacial/utils.py +270 -28
  5. pvlib/data/adr-library-cec-inverters-2019-03-05.csv +5009 -0
  6. pvlib/data/precise_iv_curves1.json +10251 -0
  7. pvlib/data/precise_iv_curves2.json +10251 -0
  8. pvlib/data/precise_iv_curves_parameter_sets1.csv +33 -0
  9. pvlib/data/precise_iv_curves_parameter_sets2.csv +33 -0
  10. pvlib/data/test_psm3_2017.csv +17521 -17521
  11. pvlib/data/test_psm3_2019_5min.csv +288 -288
  12. pvlib/data/test_read_psm3.csv +17522 -17522
  13. pvlib/data/test_read_pvgis_horizon.csv +49 -0
  14. pvlib/data/variables_style_rules.csv +3 -0
  15. pvlib/iam.py +207 -51
  16. pvlib/inverter.py +6 -1
  17. pvlib/iotools/__init__.py +7 -2
  18. pvlib/iotools/acis.py +516 -0
  19. pvlib/iotools/midc.py +4 -4
  20. pvlib/iotools/psm3.py +59 -42
  21. pvlib/iotools/pvgis.py +84 -28
  22. pvlib/iotools/sodapro.py +8 -6
  23. pvlib/iotools/srml.py +121 -18
  24. pvlib/iotools/surfrad.py +2 -2
  25. pvlib/iotools/tmy.py +146 -102
  26. pvlib/irradiance.py +270 -15
  27. pvlib/ivtools/sde.py +14 -20
  28. pvlib/ivtools/sdm.py +31 -20
  29. pvlib/ivtools/utils.py +127 -6
  30. pvlib/location.py +3 -2
  31. pvlib/modelchain.py +67 -70
  32. pvlib/pvarray.py +225 -0
  33. pvlib/pvsystem.py +169 -539
  34. pvlib/shading.py +43 -2
  35. pvlib/singlediode.py +216 -66
  36. pvlib/snow.py +36 -15
  37. pvlib/soiling.py +3 -3
  38. pvlib/spa.py +327 -368
  39. pvlib/spectrum/__init__.py +8 -2
  40. pvlib/spectrum/mismatch.py +335 -0
  41. pvlib/temperature.py +124 -13
  42. pvlib/tests/bifacial/test_infinite_sheds.py +44 -106
  43. pvlib/tests/bifacial/test_utils.py +102 -5
  44. pvlib/tests/conftest.py +0 -31
  45. pvlib/tests/iotools/test_acis.py +213 -0
  46. pvlib/tests/iotools/test_midc.py +6 -6
  47. pvlib/tests/iotools/test_psm3.py +7 -5
  48. pvlib/tests/iotools/test_pvgis.py +21 -14
  49. pvlib/tests/iotools/test_sodapro.py +1 -1
  50. pvlib/tests/iotools/test_srml.py +71 -6
  51. pvlib/tests/iotools/test_tmy.py +43 -8
  52. pvlib/tests/ivtools/test_sde.py +19 -17
  53. pvlib/tests/ivtools/test_sdm.py +9 -4
  54. pvlib/tests/ivtools/test_utils.py +96 -1
  55. pvlib/tests/test_atmosphere.py +8 -64
  56. pvlib/tests/test_clearsky.py +0 -1
  57. pvlib/tests/test_iam.py +74 -1
  58. pvlib/tests/test_irradiance.py +56 -2
  59. pvlib/tests/test_location.py +1 -1
  60. pvlib/tests/test_modelchain.py +33 -76
  61. pvlib/tests/test_pvarray.py +46 -0
  62. pvlib/tests/test_pvsystem.py +366 -201
  63. pvlib/tests/test_shading.py +35 -0
  64. pvlib/tests/test_singlediode.py +306 -29
  65. pvlib/tests/test_snow.py +84 -1
  66. pvlib/tests/test_soiling.py +8 -7
  67. pvlib/tests/test_solarposition.py +7 -7
  68. pvlib/tests/test_spa.py +6 -7
  69. pvlib/tests/test_spectrum.py +145 -1
  70. pvlib/tests/test_temperature.py +29 -11
  71. pvlib/tests/test_tools.py +41 -0
  72. pvlib/tests/test_tracking.py +0 -149
  73. pvlib/tools.py +49 -25
  74. pvlib/tracking.py +1 -269
  75. pvlib-0.10.0.dist-info/AUTHORS.md +35 -0
  76. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/LICENSE +5 -2
  77. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/METADATA +3 -13
  78. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/RECORD +80 -75
  79. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/WHEEL +1 -1
  80. pvlib/data/adr-library-2013-10-01.csv +0 -1762
  81. pvlib/forecast.py +0 -1211
  82. pvlib/iotools/ecmwf_macc.py +0 -312
  83. pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
  84. pvlib/tests/test_forecast.py +0 -228
  85. pvlib-0.9.4a1.dist-info/AUTHORS.md +0 -32
  86. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
pvlib/pvsystem.py CHANGED
@@ -10,16 +10,18 @@ import itertools
10
10
  import os
11
11
  from urllib.request import urlopen
12
12
  import numpy as np
13
+ from scipy import constants
13
14
  import pandas as pd
14
15
  from dataclasses import dataclass
15
16
  from abc import ABC, abstractmethod
16
17
  from typing import Optional
17
18
 
18
- from pvlib._deprecation import deprecated
19
+ from pvlib._deprecation import deprecated, warn_deprecated
19
20
 
20
21
  from pvlib import (atmosphere, iam, inverter, irradiance,
21
- singlediode as _singlediode, temperature)
22
+ singlediode as _singlediode, spectrum, temperature)
22
23
  from pvlib.tools import _build_kwargs, _build_args
24
+ import pvlib.tools as tools
23
25
 
24
26
 
25
27
  # a dict of required parameter names for each DC power model
@@ -67,37 +69,6 @@ def _unwrap_single_value(func):
67
69
  return f
68
70
 
69
71
 
70
- def _check_deprecated_passthrough(func):
71
- """
72
- Decorator to warn or error when getting and setting the "pass-through"
73
- PVSystem properties that have been moved to Array. Emits a warning for
74
- PVSystems with only one Array and raises an error for PVSystems with
75
- more than one Array.
76
- """
77
-
78
- @functools.wraps(func)
79
- def wrapper(self, *args, **kwargs):
80
- pvsystem_attr = func.__name__
81
- class_name = self.__class__.__name__ # PVSystem or SingleAxisTracker
82
- overrides = { # some Array attrs aren't the same as PVSystem
83
- 'strings_per_inverter': 'strings',
84
- }
85
- array_attr = overrides.get(pvsystem_attr, pvsystem_attr)
86
- alternative = f'{class_name}.arrays[i].{array_attr}'
87
-
88
- if len(self.arrays) > 1:
89
- raise AttributeError(
90
- f'{class_name}.{pvsystem_attr} not supported for multi-array '
91
- f'systems. Set {array_attr} for each Array in '
92
- f'{class_name}.arrays instead.')
93
-
94
- wrapped = deprecated('0.9', alternative=alternative, removal='0.10',
95
- name=f"{class_name}.{pvsystem_attr}")(func)
96
- return wrapped(self, *args, **kwargs)
97
-
98
- return wrapper
99
-
100
-
101
72
  # not sure if this belongs in the pvsystem module.
102
73
  # maybe something more like core.py? It may eventually grow to
103
74
  # import a lot more functionality from other modules.
@@ -217,7 +188,6 @@ class PVSystem:
217
188
  See also
218
189
  --------
219
190
  pvlib.location.Location
220
- pvlib.tracking.SingleAxisTracker
221
191
  """
222
192
 
223
193
  def __init__(self,
@@ -635,44 +605,11 @@ class PVSystem:
635
605
  in zip(self.arrays, effective_irradiance, temp_cell)
636
606
  )
637
607
 
638
- @deprecated('0.9', alternative='PVSystem.get_cell_temperature',
639
- removal='0.10.0')
640
- def sapm_celltemp(self, poa_global, temp_air, wind_speed):
641
- """Uses :py:func:`pvlib.temperature.sapm_cell` to calculate cell
642
- temperatures.
643
-
644
- Parameters
645
- ----------
646
- poa_global : numeric or tuple of numeric
647
- Total incident irradiance in W/m^2.
648
-
649
- temp_air : numeric or tuple of numeric
650
- Ambient dry bulb temperature in degrees C.
651
-
652
- wind_speed : numeric or tuple of numeric
653
- Wind speed in m/s at a height of 10 meters.
654
-
655
- Returns
656
- -------
657
- numeric or tuple of numeric
658
- values in degrees C.
659
-
660
- Notes
661
- -----
662
- The `temp_air` and `wind_speed` parameters may be passed as tuples
663
- to provide different values for each Array in the system. If not
664
- passed as a tuple then the same value is used for input to each Array.
665
- If passed as a tuple the length must be the same as the number of
666
- Arrays.
667
- """
668
- return self.get_cell_temperature(poa_global, temp_air, wind_speed,
669
- model='sapm')
670
-
671
608
  @_unwrap_single_value
672
609
  def sapm_spectral_loss(self, airmass_absolute):
673
610
  """
674
- Use the :py:func:`sapm_spectral_loss` function, the input
675
- parameters, and ``self.module_parameters`` to calculate F1.
611
+ Use the :py:func:`pvlib.spectrum.spectral_factor_sapm` function,
612
+ the input parameters, and ``self.module_parameters`` to calculate F1.
676
613
 
677
614
  Parameters
678
615
  ----------
@@ -685,7 +622,8 @@ class PVSystem:
685
622
  The SAPM spectral loss coefficient.
686
623
  """
687
624
  return tuple(
688
- sapm_spectral_loss(airmass_absolute, array.module_parameters)
625
+ spectrum.spectral_factor_sapm(airmass_absolute,
626
+ array.module_parameters)
689
627
  for array in self.arrays
690
628
  )
691
629
 
@@ -728,162 +666,10 @@ class PVSystem:
728
666
  in zip(self.arrays, poa_direct, poa_diffuse, aoi)
729
667
  )
730
668
 
731
- @deprecated('0.9', alternative='PVSystem.get_cell_temperature',
732
- removal='0.10.0')
733
- def pvsyst_celltemp(self, poa_global, temp_air, wind_speed=1.0):
734
- """Uses :py:func:`pvlib.temperature.pvsyst_cell` to calculate cell
735
- temperature.
736
-
737
- Parameters
738
- ----------
739
- poa_global : numeric or tuple of numeric
740
- Total incident irradiance in W/m^2.
741
-
742
- temp_air : numeric or tuple of numeric
743
- Ambient dry bulb temperature in degrees C.
744
-
745
- wind_speed : numeric or tuple of numeric, default 1.0
746
- Wind speed in m/s measured at the same height for which the wind
747
- loss factor was determined. The default value is 1.0, which is
748
- the wind speed at module height used to determine NOCT.
749
-
750
- Returns
751
- -------
752
- numeric or tuple of numeric
753
- values in degrees C.
754
-
755
- Notes
756
- -----
757
- The `temp_air` and `wind_speed` parameters may be passed as tuples
758
- to provide different values for each Array in the system. If not
759
- passed as a tuple then the same value is used for input to each Array.
760
- If passed as a tuple the length must be the same as the number of
761
- Arrays.
762
- """
763
- return self.get_cell_temperature(poa_global, temp_air, wind_speed,
764
- model='pvsyst')
765
-
766
- @deprecated('0.9', alternative='PVSystem.get_cell_temperature',
767
- removal='0.10.0')
768
- def faiman_celltemp(self, poa_global, temp_air, wind_speed=1.0):
769
- """
770
- Use :py:func:`pvlib.temperature.faiman` to calculate cell temperature.
771
-
772
- Parameters
773
- ----------
774
- poa_global : numeric or tuple of numeric
775
- Total incident irradiance [W/m^2].
776
-
777
- temp_air : numeric or tuple of numeric
778
- Ambient dry bulb temperature [C].
779
-
780
- wind_speed : numeric or tuple of numeric, default 1.0
781
- Wind speed in m/s measured at the same height for which the wind
782
- loss factor was determined. The default value 1.0 m/s is the wind
783
- speed at module height used to determine NOCT. [m/s]
784
-
785
- Returns
786
- -------
787
- numeric or tuple of numeric
788
- values in degrees C.
789
-
790
- Notes
791
- -----
792
- The `temp_air` and `wind_speed` parameters may be passed as tuples
793
- to provide different values for each Array in the system. If not
794
- passed as a tuple then the same value is used for input to each Array.
795
- If passed as a tuple the length must be the same as the number of
796
- Arrays.
797
- """
798
- return self.get_cell_temperature(poa_global, temp_air, wind_speed,
799
- model='faiman')
800
-
801
- @deprecated('0.9', alternative='PVSystem.get_cell_temperature',
802
- removal='0.10.0')
803
- def fuentes_celltemp(self, poa_global, temp_air, wind_speed):
804
- """
805
- Use :py:func:`pvlib.temperature.fuentes` to calculate cell temperature.
806
-
807
- Parameters
808
- ----------
809
- poa_global : pandas Series or tuple of Series
810
- Total incident irradiance [W/m^2]
811
-
812
- temp_air : pandas Series or tuple of Series
813
- Ambient dry bulb temperature [C]
814
-
815
- wind_speed : pandas Series or tuple of Series
816
- Wind speed [m/s]
817
-
818
- Returns
819
- -------
820
- temperature_cell : Series or tuple of Series
821
- The modeled cell temperature [C]
822
-
823
- Notes
824
- -----
825
- The Fuentes thermal model uses the module surface tilt for convection
826
- modeling. The SAM implementation of PVWatts hardcodes the surface tilt
827
- value at 30 degrees, ignoring whatever value is used for irradiance
828
- transposition. If you want to match the PVWatts behavior you can
829
- either leave ``surface_tilt`` unspecified to use the PVWatts default
830
- of 30, or specify a ``surface_tilt`` value in the Array's
831
- ``temperature_model_parameters``.
832
-
833
- The `temp_air`, `wind_speed`, and `surface_tilt` parameters may be
834
- passed as tuples
835
- to provide different values for each Array in the system. If not
836
- passed as a tuple then the same value is used for input to each Array.
837
- If passed as a tuple the length must be the same as the number of
838
- Arrays.
839
- """
840
- return self.get_cell_temperature(poa_global, temp_air, wind_speed,
841
- model='fuentes')
842
-
843
- @deprecated('0.9', alternative='PVSystem.get_cell_temperature',
844
- removal='0.10.0')
845
- def noct_sam_celltemp(self, poa_global, temp_air, wind_speed,
846
- effective_irradiance=None):
847
- """
848
- Use :py:func:`pvlib.temperature.noct_sam` to calculate cell
849
- temperature.
850
-
851
- Parameters
852
- ----------
853
- poa_global : numeric or tuple of numeric
854
- Total incident irradiance in W/m^2.
855
-
856
- temp_air : numeric or tuple of numeric
857
- Ambient dry bulb temperature in degrees C.
858
-
859
- wind_speed : numeric or tuple of numeric
860
- Wind speed in m/s at a height of 10 meters.
861
-
862
- effective_irradiance : numeric, tuple of numeric, or None.
863
- The irradiance that is converted to photocurrent. If None,
864
- assumed equal to ``poa_global``. [W/m^2]
865
-
866
- Returns
867
- -------
868
- temperature_cell : numeric or tuple of numeric
869
- The modeled cell temperature [C]
870
-
871
- Notes
872
- -----
873
- The `temp_air` and `wind_speed` parameters may be passed as tuples
874
- to provide different values for each Array in the system. If not
875
- passed as a tuple then the same value is used for input to each Array.
876
- If passed as a tuple the length must be the same as the number of
877
- Arrays.
878
- """
879
- return self.get_cell_temperature(
880
- poa_global, temp_air, wind_speed, model='noct_sam',
881
- effective_irradiance=effective_irradiance)
882
-
883
669
  @_unwrap_single_value
884
670
  def first_solar_spectral_loss(self, pw, airmass_absolute):
885
671
  """
886
- Use :py:func:`pvlib.atmosphere.first_solar_spectral_correction` to
672
+ Use :py:func:`pvlib.spectrum.spectral_factor_firstsolar` to
887
673
  calculate the spectral loss modifier. The model coefficients are
888
674
  specific to the module's cell type, and are determined by searching
889
675
  for one of the following keys in self.module_parameters (in order):
@@ -924,9 +710,8 @@ class PVSystem:
924
710
  module_type = array._infer_cell_type()
925
711
  coefficients = None
926
712
 
927
- return atmosphere.first_solar_spectral_correction(
928
- pw, airmass_absolute,
929
- module_type, coefficients
713
+ return spectrum.spectral_factor_firstsolar(
714
+ pw, airmass_absolute, module_type, coefficients
930
715
  )
931
716
  return tuple(
932
717
  itertools.starmap(_spectral_correction, zip(self.arrays, pw))
@@ -943,14 +728,17 @@ class PVSystem:
943
728
  resistance_series, resistance_shunt, nNsVth,
944
729
  ivcurve_pnts=ivcurve_pnts)
945
730
 
946
- def i_from_v(self, resistance_shunt, resistance_series, nNsVth, voltage,
947
- saturation_current, photocurrent):
731
+ def i_from_v(self, voltage, photocurrent, saturation_current,
732
+ resistance_series, resistance_shunt, nNsVth):
948
733
  """Wrapper around the :py:func:`pvlib.pvsystem.i_from_v` function.
949
734
 
950
- See :py:func:`pvsystem.i_from_v` for details
735
+ See :py:func:`pvlib.pvsystem.i_from_v` for details.
736
+
737
+ .. versionchanged:: 0.10.0
738
+ The function's arguments have been reordered.
951
739
  """
952
- return i_from_v(resistance_shunt, resistance_series, nNsVth, voltage,
953
- saturation_current, photocurrent)
740
+ return i_from_v(voltage, photocurrent, saturation_current,
741
+ resistance_series, resistance_shunt, nNsVth)
954
742
 
955
743
  def get_ac(self, model, p_dc, v_dc=None):
956
744
  r"""Calculates AC power from p_dc using the inverter model indicated
@@ -1023,24 +811,6 @@ class PVSystem:
1023
811
  model + ' is not a valid AC power model.',
1024
812
  ' model must be one of "sandia", "adr" or "pvwatts"')
1025
813
 
1026
- @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10')
1027
- def snlinverter(self, v_dc, p_dc):
1028
- """Uses :py:func:`pvlib.inverter.sandia` to calculate AC power based on
1029
- ``self.inverter_parameters`` and the input voltage and power.
1030
-
1031
- See :py:func:`pvlib.inverter.sandia` for details
1032
- """
1033
- return inverter.sandia(v_dc, p_dc, self.inverter_parameters)
1034
-
1035
- @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10')
1036
- def adrinverter(self, v_dc, p_dc):
1037
- """Uses :py:func:`pvlib.inverter.adr` to calculate AC power based on
1038
- ``self.inverter_parameters`` and the input voltage and power.
1039
-
1040
- See :py:func:`pvlib.inverter.adr` for details
1041
- """
1042
- return inverter.adr(v_dc, p_dc, self.inverter_parameters)
1043
-
1044
814
  @_unwrap_single_value
1045
815
  def scale_voltage_current_power(self, data):
1046
816
  """
@@ -1100,21 +870,6 @@ class PVSystem:
1100
870
  self.losses_parameters)
1101
871
  return pvwatts_losses(**kwargs)
1102
872
 
1103
- @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10')
1104
- def pvwatts_ac(self, pdc):
1105
- """
1106
- Calculates AC power according to the PVWatts model using
1107
- :py:func:`pvlib.inverter.pvwatts`, `self.module_parameters["pdc0"]`,
1108
- and `eta_inv_nom=self.inverter_parameters["eta_inv_nom"]`.
1109
-
1110
- See :py:func:`pvlib.inverter.pvwatts` for details.
1111
- """
1112
- kwargs = _build_kwargs(['eta_inv_nom', 'eta_inv_ref'],
1113
- self.inverter_parameters)
1114
-
1115
- return inverter.pvwatts(pdc, self.inverter_parameters['pdc0'],
1116
- **kwargs)
1117
-
1118
873
  @_unwrap_single_value
1119
874
  def dc_ohms_from_percent(self):
1120
875
  """
@@ -1126,127 +881,6 @@ class PVSystem:
1126
881
 
1127
882
  return tuple(array.dc_ohms_from_percent() for array in self.arrays)
1128
883
 
1129
- @property
1130
- @_unwrap_single_value
1131
- @_check_deprecated_passthrough
1132
- def module_parameters(self):
1133
- return tuple(array.module_parameters for array in self.arrays)
1134
-
1135
- @module_parameters.setter
1136
- @_check_deprecated_passthrough
1137
- def module_parameters(self, value):
1138
- for array in self.arrays:
1139
- array.module_parameters = value
1140
-
1141
- @property
1142
- @_unwrap_single_value
1143
- @_check_deprecated_passthrough
1144
- def module(self):
1145
- return tuple(array.module for array in self.arrays)
1146
-
1147
- @module.setter
1148
- @_check_deprecated_passthrough
1149
- def module(self, value):
1150
- for array in self.arrays:
1151
- array.module = value
1152
-
1153
- @property
1154
- @_unwrap_single_value
1155
- @_check_deprecated_passthrough
1156
- def module_type(self):
1157
- return tuple(array.module_type for array in self.arrays)
1158
-
1159
- @module_type.setter
1160
- @_check_deprecated_passthrough
1161
- def module_type(self, value):
1162
- for array in self.arrays:
1163
- array.module_type = value
1164
-
1165
- @property
1166
- @_unwrap_single_value
1167
- @_check_deprecated_passthrough
1168
- def temperature_model_parameters(self):
1169
- return tuple(array.temperature_model_parameters
1170
- for array in self.arrays)
1171
-
1172
- @temperature_model_parameters.setter
1173
- @_check_deprecated_passthrough
1174
- def temperature_model_parameters(self, value):
1175
- for array in self.arrays:
1176
- array.temperature_model_parameters = value
1177
-
1178
- @property
1179
- @_unwrap_single_value
1180
- @_check_deprecated_passthrough
1181
- def surface_tilt(self):
1182
- return tuple(array.mount.surface_tilt for array in self.arrays)
1183
-
1184
- @surface_tilt.setter
1185
- @_check_deprecated_passthrough
1186
- def surface_tilt(self, value):
1187
- for array in self.arrays:
1188
- array.mount.surface_tilt = value
1189
-
1190
- @property
1191
- @_unwrap_single_value
1192
- @_check_deprecated_passthrough
1193
- def surface_azimuth(self):
1194
- return tuple(array.mount.surface_azimuth for array in self.arrays)
1195
-
1196
- @surface_azimuth.setter
1197
- @_check_deprecated_passthrough
1198
- def surface_azimuth(self, value):
1199
- for array in self.arrays:
1200
- array.mount.surface_azimuth = value
1201
-
1202
- @property
1203
- @_unwrap_single_value
1204
- @_check_deprecated_passthrough
1205
- def albedo(self):
1206
- return tuple(array.albedo for array in self.arrays)
1207
-
1208
- @albedo.setter
1209
- @_check_deprecated_passthrough
1210
- def albedo(self, value):
1211
- for array in self.arrays:
1212
- array.albedo = value
1213
-
1214
- @property
1215
- @_unwrap_single_value
1216
- @_check_deprecated_passthrough
1217
- def racking_model(self):
1218
- return tuple(array.mount.racking_model for array in self.arrays)
1219
-
1220
- @racking_model.setter
1221
- @_check_deprecated_passthrough
1222
- def racking_model(self, value):
1223
- for array in self.arrays:
1224
- array.mount.racking_model = value
1225
-
1226
- @property
1227
- @_unwrap_single_value
1228
- @_check_deprecated_passthrough
1229
- def modules_per_string(self):
1230
- return tuple(array.modules_per_string for array in self.arrays)
1231
-
1232
- @modules_per_string.setter
1233
- @_check_deprecated_passthrough
1234
- def modules_per_string(self, value):
1235
- for array in self.arrays:
1236
- array.modules_per_string = value
1237
-
1238
- @property
1239
- @_unwrap_single_value
1240
- @_check_deprecated_passthrough
1241
- def strings_per_inverter(self):
1242
- return tuple(array.strings for array in self.arrays)
1243
-
1244
- @strings_per_inverter.setter
1245
- @_check_deprecated_passthrough
1246
- def strings_per_inverter(self, value):
1247
- for array in self.arrays:
1248
- array.strings = value
1249
-
1250
884
  @property
1251
885
  def num_arrays(self):
1252
886
  """The number of Arrays in the system."""
@@ -1597,9 +1231,7 @@ class Array:
1597
1231
  func = temperature.pvsyst_cell
1598
1232
  required = tuple()
1599
1233
  optional = {
1600
- # TODO remove 'eta_m' after deprecation of this parameter
1601
- **_build_kwargs(['eta_m', 'module_efficiency',
1602
- 'alpha_absorption'],
1234
+ **_build_kwargs(['module_efficiency', 'alpha_absorption'],
1603
1235
  self.module_parameters),
1604
1236
  **_build_kwargs(['u_c', 'u_v'],
1605
1237
  self.temperature_model_parameters)
@@ -1909,7 +1541,7 @@ def calcparams_desoto(effective_irradiance, temp_cell,
1909
1541
  saturation_current : numeric
1910
1542
  Diode saturation curent in amperes
1911
1543
 
1912
- resistance_series : float
1544
+ resistance_series : numeric
1913
1545
  Series resistance in ohms
1914
1546
 
1915
1547
  resistance_shunt : numeric
@@ -2004,8 +1636,8 @@ def calcparams_desoto(effective_irradiance, temp_cell,
2004
1636
  Source: [4]
2005
1637
  '''
2006
1638
 
2007
- # Boltzmann constant in eV/K
2008
- k = 8.617332478e-05
1639
+ # Boltzmann constant in eV/K, 8.617332478e-05
1640
+ k = constants.value('Boltzmann constant in eV/K')
2009
1641
 
2010
1642
  # reference temperature
2011
1643
  Tref_K = temp_ref + 273.15
@@ -2032,9 +1664,21 @@ def calcparams_desoto(effective_irradiance, temp_cell,
2032
1664
  # use errstate to silence divide by warning
2033
1665
  with np.errstate(divide='ignore'):
2034
1666
  Rsh = R_sh_ref * (irrad_ref / effective_irradiance)
1667
+
2035
1668
  Rs = R_s
2036
1669
 
2037
- return IL, I0, Rs, Rsh, nNsVth
1670
+ numeric_args = (effective_irradiance, temp_cell)
1671
+ out = (IL, I0, Rs, Rsh, nNsVth)
1672
+
1673
+ if all(map(np.isscalar, numeric_args)):
1674
+ return out
1675
+
1676
+ index = tools.get_pandas_index(*numeric_args)
1677
+
1678
+ if index is None:
1679
+ return np.broadcast_arrays(*out)
1680
+
1681
+ return tuple(pd.Series(a, index=index).rename(None) for a in out)
2038
1682
 
2039
1683
 
2040
1684
  def calcparams_cec(effective_irradiance, temp_cell,
@@ -2113,7 +1757,7 @@ def calcparams_cec(effective_irradiance, temp_cell,
2113
1757
  saturation_current : numeric
2114
1758
  Diode saturation curent in amperes
2115
1759
 
2116
- resistance_series : float
1760
+ resistance_series : numeric
2117
1761
  Series resistance in ohms
2118
1762
 
2119
1763
  resistance_shunt : numeric
@@ -2230,7 +1874,7 @@ def calcparams_pvsyst(effective_irradiance, temp_cell,
2230
1874
  saturation_current : numeric
2231
1875
  Diode saturation current in amperes
2232
1876
 
2233
- resistance_series : float
1877
+ resistance_series : numeric
2234
1878
  Series resistance in ohms
2235
1879
 
2236
1880
  resistance_shunt : numeric
@@ -2262,10 +1906,10 @@ def calcparams_pvsyst(effective_irradiance, temp_cell,
2262
1906
  '''
2263
1907
 
2264
1908
  # Boltzmann constant in J/K
2265
- k = 1.38064852e-23
1909
+ k = constants.k
2266
1910
 
2267
1911
  # elementary charge in coulomb
2268
- q = 1.6021766e-19
1912
+ q = constants.e
2269
1913
 
2270
1914
  # reference temperature
2271
1915
  Tref_K = temp_ref + 273.15
@@ -2289,7 +1933,18 @@ def calcparams_pvsyst(effective_irradiance, temp_cell,
2289
1933
 
2290
1934
  Rs = R_s
2291
1935
 
2292
- return IL, I0, Rs, Rsh, nNsVth
1936
+ numeric_args = (effective_irradiance, temp_cell)
1937
+ out = (IL, I0, Rs, Rsh, nNsVth)
1938
+
1939
+ if all(map(np.isscalar, numeric_args)):
1940
+ return out
1941
+
1942
+ index = tools.get_pandas_index(*numeric_args)
1943
+
1944
+ if index is None:
1945
+ return np.broadcast_arrays(*out)
1946
+
1947
+ return tuple(pd.Series(a, index=index).rename(None) for a in out)
2293
1948
 
2294
1949
 
2295
1950
  def retrieve_sam(name=None, path=None):
@@ -2376,7 +2031,8 @@ def retrieve_sam(name=None, path=None):
2376
2031
  csvdata = os.path.join(
2377
2032
  data_path, 'sam-library-sandia-modules-2015-6-30.csv')
2378
2033
  elif name == 'adrinverter':
2379
- csvdata = os.path.join(data_path, 'adr-library-2013-10-01.csv')
2034
+ csvdata = os.path.join(
2035
+ data_path, 'adr-library-cec-inverters-2019-03-05.csv')
2380
2036
  elif name in ['cecinverter', 'sandiainverter']:
2381
2037
  # Allowing either, to provide for old code,
2382
2038
  # while aligning with current expectations
@@ -2537,8 +2193,8 @@ def sapm(effective_irradiance, temp_cell, module):
2537
2193
  temp_ref = 25
2538
2194
  irrad_ref = 1000
2539
2195
 
2540
- q = 1.60218e-19 # Elementary charge in units of coulombs
2541
- kb = 1.38066e-23 # Boltzmann's constant in units of J/K
2196
+ q = constants.e # Elementary charge in units of coulombs
2197
+ kb = constants.k # Boltzmann's constant in units of J/K
2542
2198
 
2543
2199
  # avoid problem with integer input
2544
2200
  Ee = np.array(effective_irradiance, dtype='float64') / irrad_ref
@@ -2597,43 +2253,10 @@ def sapm(effective_irradiance, temp_cell, module):
2597
2253
  return out
2598
2254
 
2599
2255
 
2600
- def sapm_spectral_loss(airmass_absolute, module):
2601
- """
2602
- Calculates the SAPM spectral loss coefficient, F1.
2603
-
2604
- Parameters
2605
- ----------
2606
- airmass_absolute : numeric
2607
- Absolute airmass
2608
-
2609
- module : dict-like
2610
- A dict, Series, or DataFrame defining the SAPM performance
2611
- parameters. See the :py:func:`sapm` notes section for more
2612
- details.
2613
-
2614
- Returns
2615
- -------
2616
- F1 : numeric
2617
- The SAPM spectral loss coefficient.
2618
-
2619
- Notes
2620
- -----
2621
- nan airmass values will result in 0 output.
2622
- """
2623
-
2624
- am_coeff = [module['A4'], module['A3'], module['A2'], module['A1'],
2625
- module['A0']]
2626
-
2627
- spectral_loss = np.polyval(am_coeff, airmass_absolute)
2628
-
2629
- spectral_loss = np.where(np.isnan(spectral_loss), 0, spectral_loss)
2630
-
2631
- spectral_loss = np.maximum(0, spectral_loss)
2632
-
2633
- if isinstance(airmass_absolute, pd.Series):
2634
- spectral_loss = pd.Series(spectral_loss, airmass_absolute.index)
2635
-
2636
- return spectral_loss
2256
+ sapm_spectral_loss = deprecated(
2257
+ since='0.10.0',
2258
+ alternative='pvlib.spectrum.spectral_factor_sapm'
2259
+ )(spectrum.spectral_factor_sapm)
2637
2260
 
2638
2261
 
2639
2262
  def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi,
@@ -2693,11 +2316,11 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi,
2693
2316
  See also
2694
2317
  --------
2695
2318
  pvlib.iam.sapm
2696
- pvlib.pvsystem.sapm_spectral_loss
2319
+ pvlib.spectrum.spectral_factor_sapm
2697
2320
  pvlib.pvsystem.sapm
2698
2321
  """
2699
2322
 
2700
- F1 = sapm_spectral_loss(airmass_absolute, module)
2323
+ F1 = spectrum.spectral_factor_sapm(airmass_absolute, module)
2701
2324
  F2 = iam.sapm(aoi, module)
2702
2325
 
2703
2326
  Ee = F1 * (poa_direct * F2 + module['FD'] * poa_diffuse)
@@ -2709,7 +2332,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2709
2332
  resistance_shunt, nNsVth, ivcurve_pnts=None,
2710
2333
  method='lambertw'):
2711
2334
  r"""
2712
- Solve the single-diode equation to obtain a photovoltaic IV curve.
2335
+ Solve the single diode equation to obtain a photovoltaic IV curve.
2713
2336
 
2714
2337
  Solves the single diode equation [1]_
2715
2338
 
@@ -2722,11 +2345,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2722
2345
  \frac{V + I R_s}{R_{sh}}
2723
2346
 
2724
2347
  for :math:`I` and :math:`V` when given :math:`I_L, I_0, R_s, R_{sh},` and
2725
- :math:`n N_s V_{th}` which are described later. Returns a DataFrame
2726
- which contains the 5 points on the I-V curve specified in
2727
- [3]_. If all :math:`I_L, I_0, R_s, R_{sh},` and
2728
- :math:`n N_s V_{th}` are scalar, a single curve is returned, if any
2729
- are Series (of the same length), multiple IV curves are calculated.
2348
+ :math:`n N_s V_{th}` which are described later. The five points on the I-V
2349
+ curve specified in [3]_ are returned. If :math:`I_L, I_0, R_s, R_{sh},` and
2350
+ :math:`n N_s V_{th}` are all scalars, a single curve is returned. If any
2351
+ are array-like (of the same length), multiple IV curves are calculated.
2730
2352
 
2731
2353
  The input parameters can be calculated from meteorological data using a
2732
2354
  function for a single diode model, e.g.,
@@ -2764,35 +2386,33 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2764
2386
  Number of points in the desired IV curve. If None or 0, no points on
2765
2387
  the IV curves will be produced.
2766
2388
 
2389
+ .. deprecated:: 0.10.0
2390
+ Use :py:func:`pvlib.pvsystem.v_from_i` and
2391
+ :py:func:`pvlib.pvsystem.i_from_v` instead.
2392
+
2767
2393
  method : str, default 'lambertw'
2768
2394
  Determines the method used to calculate points on the IV curve. The
2769
2395
  options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
2770
2396
 
2771
2397
  Returns
2772
2398
  -------
2773
- OrderedDict or DataFrame
2399
+ dict or pandas.DataFrame
2400
+ The returned dict-like object always contains the keys/columns:
2774
2401
 
2775
- The returned dict-like object always contains the keys/columns:
2402
+ * i_sc - short circuit current in amperes.
2403
+ * v_oc - open circuit voltage in volts.
2404
+ * i_mp - current at maximum power point in amperes.
2405
+ * v_mp - voltage at maximum power point in volts.
2406
+ * p_mp - power at maximum power point in watts.
2407
+ * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2408
+ * i_xx - current, in amperes, at ``v = 0.5*(v_oc+v_mp)``.
2776
2409
 
2777
- * i_sc - short circuit current in amperes.
2778
- * v_oc - open circuit voltage in volts.
2779
- * i_mp - current at maximum power point in amperes.
2780
- * v_mp - voltage at maximum power point in volts.
2781
- * p_mp - power at maximum power point in watts.
2782
- * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2783
- * i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.
2410
+ A dict is returned when the input parameters are scalars or
2411
+ ``ivcurve_pnts > 0``. If ``ivcurve_pnts > 0``, the output dictionary
2412
+ will also include the keys:
2784
2413
 
2785
- If ivcurve_pnts is greater than 0, the output dictionary will also
2786
- include the keys:
2787
-
2788
- * i - IV curve current in amperes.
2789
- * v - IV curve voltage in volts.
2790
-
2791
- The output will be an OrderedDict if photocurrent is a scalar,
2792
- array, or ivcurve_pnts is not None.
2793
-
2794
- The output will be a DataFrame if photocurrent is a Series and
2795
- ivcurve_pnts is None.
2414
+ * i - IV curve current in amperes.
2415
+ * v - IV curve voltage in volts.
2796
2416
 
2797
2417
  See also
2798
2418
  --------
@@ -2839,22 +2459,25 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2839
2459
  photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
2840
2460
  https://doi.org/10.1016/0379-6787(88)90059-2
2841
2461
  """
2462
+ if ivcurve_pnts:
2463
+ warn_deprecated('0.10.0', name='pvlib.pvsystem.singlediode',
2464
+ alternative=('pvlib.pvsystem.v_from_i and '
2465
+ 'pvlib.pvsystem.i_from_v'),
2466
+ obj_type='parameter ivcurve_pnts',
2467
+ removal='0.11.0')
2468
+ args = (photocurrent, saturation_current, resistance_series,
2469
+ resistance_shunt, nNsVth) # collect args
2842
2470
  # Calculate points on the IV curve using the LambertW solution to the
2843
2471
  # single diode equation
2844
2472
  if method.lower() == 'lambertw':
2845
- out = _singlediode._lambertw(
2846
- photocurrent, saturation_current, resistance_series,
2847
- resistance_shunt, nNsVth, ivcurve_pnts
2848
- )
2849
- i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx = out[:7]
2473
+ out = _singlediode._lambertw(*args, ivcurve_pnts)
2474
+ points = out[:7]
2850
2475
  if ivcurve_pnts:
2851
2476
  ivcurve_i, ivcurve_v = out[7:]
2852
2477
  else:
2853
2478
  # Calculate points on the IV curve using either 'newton' or 'brentq'
2854
2479
  # methods. Voltages are determined by first solving the single diode
2855
2480
  # equation for the diode voltage V_d then backing out voltage
2856
- args = (photocurrent, saturation_current, resistance_series,
2857
- resistance_shunt, nNsVth) # collect args
2858
2481
  v_oc = _singlediode.bishop88_v_from_i(
2859
2482
  0.0, *args, method=method.lower()
2860
2483
  )
@@ -2870,6 +2493,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2870
2493
  i_xx = _singlediode.bishop88_i_from_v(
2871
2494
  (v_oc + v_mp) / 2.0, *args, method=method.lower()
2872
2495
  )
2496
+ points = i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx
2873
2497
 
2874
2498
  # calculate the IV curve if requested using bishop88
2875
2499
  if ivcurve_pnts:
@@ -2878,22 +2502,23 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2878
2502
  )
2879
2503
  ivcurve_i, ivcurve_v, _ = _singlediode.bishop88(vd, *args)
2880
2504
 
2881
- out = OrderedDict()
2882
- out['i_sc'] = i_sc
2883
- out['v_oc'] = v_oc
2884
- out['i_mp'] = i_mp
2885
- out['v_mp'] = v_mp
2886
- out['p_mp'] = p_mp
2887
- out['i_x'] = i_x
2888
- out['i_xx'] = i_xx
2505
+ columns = ('i_sc', 'v_oc', 'i_mp', 'v_mp', 'p_mp', 'i_x', 'i_xx')
2889
2506
 
2890
- if ivcurve_pnts:
2507
+ if all(map(np.isscalar, args)) or ivcurve_pnts:
2508
+ out = {c: p for c, p in zip(columns, points)}
2509
+
2510
+ if ivcurve_pnts:
2511
+ out.update(i=ivcurve_i, v=ivcurve_v)
2891
2512
 
2892
- out['v'] = ivcurve_v
2893
- out['i'] = ivcurve_i
2513
+ return out
2894
2514
 
2895
- if isinstance(photocurrent, pd.Series) and not ivcurve_pnts:
2896
- out = pd.DataFrame(out, index=photocurrent.index)
2515
+ points = np.atleast_1d(*points) # convert scalars to 1d-arrays
2516
+ points = np.vstack(points).T # collect rows into DataFrame columns
2517
+
2518
+ # save the first available pd.Series index, otherwise set to None
2519
+ index = next((a.index for a in args if isinstance(a, pd.Series)), None)
2520
+
2521
+ out = pd.DataFrame(points, columns=columns, index=index)
2897
2522
 
2898
2523
  return out
2899
2524
 
@@ -2934,7 +2559,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
2934
2559
 
2935
2560
  Returns
2936
2561
  -------
2937
- OrderedDict or pandas.Datafrane
2562
+ OrderedDict or pandas.DataFrame
2938
2563
  ``(i_mp, v_mp, p_mp)``
2939
2564
 
2940
2565
  Notes
@@ -2946,8 +2571,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
2946
2571
  """
2947
2572
  i_mp, v_mp, p_mp = _singlediode.bishop88_mpp(
2948
2573
  photocurrent, saturation_current, resistance_series,
2949
- resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.Inf,
2950
- method=method.lower()
2574
+ resistance_shunt, nNsVth, d2mutau, NsVbi, method=method.lower()
2951
2575
  )
2952
2576
  if isinstance(photocurrent, pd.Series):
2953
2577
  ivp = {'i_mp': i_mp, 'v_mp': v_mp, 'p_mp': p_mp}
@@ -2960,8 +2584,8 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
2960
2584
  return out
2961
2585
 
2962
2586
 
2963
- def v_from_i(resistance_shunt, resistance_series, nNsVth, current,
2964
- saturation_current, photocurrent, method='lambertw'):
2587
+ def v_from_i(current, photocurrent, saturation_current, resistance_series,
2588
+ resistance_shunt, nNsVth, method='lambertw'):
2965
2589
  '''
2966
2590
  Device voltage at the given device current for the single diode model.
2967
2591
 
@@ -2975,18 +2599,34 @@ def v_from_i(resistance_shunt, resistance_series, nNsVth, current,
2975
2599
  the caller's responsibility to ensure that the arguments are all float64
2976
2600
  and within the proper ranges.
2977
2601
 
2602
+ .. versionchanged:: 0.10.0
2603
+ The function's arguments have been reordered.
2604
+
2978
2605
  Parameters
2979
2606
  ----------
2980
- resistance_shunt : numeric
2981
- Shunt resistance in ohms under desired IV curve conditions.
2982
- Often abbreviated ``Rsh``.
2983
- 0 < resistance_shunt <= numpy.inf
2607
+ current : numeric
2608
+ The current in amperes under desired IV curve conditions.
2609
+
2610
+ photocurrent : numeric
2611
+ Light-generated current (photocurrent) in amperes under desired
2612
+ IV curve conditions. Often abbreviated ``I_L``.
2613
+ 0 <= photocurrent
2614
+
2615
+ saturation_current : numeric
2616
+ Diode saturation current in amperes under desired IV curve
2617
+ conditions. Often abbreviated ``I_0``.
2618
+ 0 < saturation_current
2984
2619
 
2985
2620
  resistance_series : numeric
2986
2621
  Series resistance in ohms under desired IV curve conditions.
2987
2622
  Often abbreviated ``Rs``.
2988
2623
  0 <= resistance_series < numpy.inf
2989
2624
 
2625
+ resistance_shunt : numeric
2626
+ Shunt resistance in ohms under desired IV curve conditions.
2627
+ Often abbreviated ``Rsh``.
2628
+ 0 < resistance_shunt <= numpy.inf
2629
+
2990
2630
  nNsVth : numeric
2991
2631
  The product of three components. 1) The usual diode ideal factor
2992
2632
  (n), 2) the number of cells in series (Ns), and 3) the cell
@@ -2997,19 +2637,6 @@ def v_from_i(resistance_shunt, resistance_series, nNsVth, current,
2997
2637
  q is the charge of an electron (coulombs).
2998
2638
  0 < nNsVth
2999
2639
 
3000
- current : numeric
3001
- The current in amperes under desired IV curve conditions.
3002
-
3003
- saturation_current : numeric
3004
- Diode saturation current in amperes under desired IV curve
3005
- conditions. Often abbreviated ``I_0``.
3006
- 0 < saturation_current
3007
-
3008
- photocurrent : numeric
3009
- Light-generated current (photocurrent) in amperes under desired
3010
- IV curve conditions. Often abbreviated ``I_L``.
3011
- 0 <= photocurrent
3012
-
3013
2640
  method : str
3014
2641
  Method to use: ``'lambertw'``, ``'newton'``, or ``'brentq'``. *Note*:
3015
2642
  ``'brentq'`` is limited to 1st quadrant only.
@@ -3026,8 +2653,8 @@ def v_from_i(resistance_shunt, resistance_series, nNsVth, current,
3026
2653
  '''
3027
2654
  if method.lower() == 'lambertw':
3028
2655
  return _singlediode._lambertw_v_from_i(
3029
- resistance_shunt, resistance_series, nNsVth, current,
3030
- saturation_current, photocurrent
2656
+ current, photocurrent, saturation_current, resistance_series,
2657
+ resistance_shunt, nNsVth
3031
2658
  )
3032
2659
  else:
3033
2660
  # Calculate points on the IV curve using either 'newton' or 'brentq'
@@ -3048,33 +2675,49 @@ def v_from_i(resistance_shunt, resistance_series, nNsVth, current,
3048
2675
  return V
3049
2676
 
3050
2677
 
3051
- def i_from_v(resistance_shunt, resistance_series, nNsVth, voltage,
3052
- saturation_current, photocurrent, method='lambertw'):
2678
+ def i_from_v(voltage, photocurrent, saturation_current, resistance_series,
2679
+ resistance_shunt, nNsVth, method='lambertw'):
3053
2680
  '''
3054
2681
  Device current at the given device voltage for the single diode model.
3055
2682
 
3056
2683
  Uses the single diode model (SDM) as described in, e.g.,
3057
- Jain and Kapoor 2004 [1]_.
2684
+ Jain and Kapoor 2004 [1]_.
3058
2685
  The solution is per Eq 2 of [1] except when resistance_series=0,
3059
- in which case the explict solution for current is used.
2686
+ in which case the explict solution for current is used.
3060
2687
  Ideal device parameters are specified by resistance_shunt=np.inf and
3061
- resistance_series=0.
2688
+ resistance_series=0.
3062
2689
  Inputs to this function can include scalars and pandas.Series, but it is
3063
- the caller's responsibility to ensure that the arguments are all float64
3064
- and within the proper ranges.
2690
+ the caller's responsibility to ensure that the arguments are all float64
2691
+ and within the proper ranges.
2692
+
2693
+ .. versionchanged:: 0.10.0
2694
+ The function's arguments have been reordered.
3065
2695
 
3066
2696
  Parameters
3067
2697
  ----------
3068
- resistance_shunt : numeric
3069
- Shunt resistance in ohms under desired IV curve conditions.
3070
- Often abbreviated ``Rsh``.
3071
- 0 < resistance_shunt <= numpy.inf
2698
+ voltage : numeric
2699
+ The voltage in Volts under desired IV curve conditions.
2700
+
2701
+ photocurrent : numeric
2702
+ Light-generated current (photocurrent) in amperes under desired
2703
+ IV curve conditions. Often abbreviated ``I_L``.
2704
+ 0 <= photocurrent
2705
+
2706
+ saturation_current : numeric
2707
+ Diode saturation current in amperes under desired IV curve
2708
+ conditions. Often abbreviated ``I_0``.
2709
+ 0 < saturation_current
3072
2710
 
3073
2711
  resistance_series : numeric
3074
2712
  Series resistance in ohms under desired IV curve conditions.
3075
2713
  Often abbreviated ``Rs``.
3076
2714
  0 <= resistance_series < numpy.inf
3077
2715
 
2716
+ resistance_shunt : numeric
2717
+ Shunt resistance in ohms under desired IV curve conditions.
2718
+ Often abbreviated ``Rsh``.
2719
+ 0 < resistance_shunt <= numpy.inf
2720
+
3078
2721
  nNsVth : numeric
3079
2722
  The product of three components. 1) The usual diode ideal factor
3080
2723
  (n), 2) the number of cells in series (Ns), and 3) the cell
@@ -3085,19 +2728,6 @@ def i_from_v(resistance_shunt, resistance_series, nNsVth, voltage,
3085
2728
  q is the charge of an electron (coulombs).
3086
2729
  0 < nNsVth
3087
2730
 
3088
- voltage : numeric
3089
- The voltage in Volts under desired IV curve conditions.
3090
-
3091
- saturation_current : numeric
3092
- Diode saturation current in amperes under desired IV curve
3093
- conditions. Often abbreviated ``I_0``.
3094
- 0 < saturation_current
3095
-
3096
- photocurrent : numeric
3097
- Light-generated current (photocurrent) in amperes under desired
3098
- IV curve conditions. Often abbreviated ``I_L``.
3099
- 0 <= photocurrent
3100
-
3101
2731
  method : str
3102
2732
  Method to use: ``'lambertw'``, ``'newton'``, or ``'brentq'``. *Note*:
3103
2733
  ``'brentq'`` is limited to 1st quadrant only.
@@ -3114,8 +2744,8 @@ def i_from_v(resistance_shunt, resistance_series, nNsVth, voltage,
3114
2744
  '''
3115
2745
  if method.lower() == 'lambertw':
3116
2746
  return _singlediode._lambertw_i_from_v(
3117
- resistance_shunt, resistance_series, nNsVth, voltage,
3118
- saturation_current, photocurrent
2747
+ voltage, photocurrent, saturation_current, resistance_series,
2748
+ resistance_shunt, nNsVth
3119
2749
  )
3120
2750
  else:
3121
2751
  # Calculate points on the IV curve using either 'newton' or 'brentq'
@@ -3179,9 +2809,9 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
3179
2809
 
3180
2810
  P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref}))
3181
2811
 
3182
- Note that the pdc0 is also used as a symbol in
3183
- :py:func:`pvlib.inverter.pvwatts`. pdc0 in this function refers to the DC
3184
- power of the modules at reference conditions. pdc0 in
2812
+ Note that ``pdc0`` is also used as a symbol in
2813
+ :py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC
2814
+ power of the modules at reference conditions. ``pdc0`` in
3185
2815
  :py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of
3186
2816
  the inverter.
3187
2817
 
@@ -3206,7 +2836,7 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
3206
2836
  Returns
3207
2837
  -------
3208
2838
  pdc: numeric
3209
- DC power.
2839
+ DC power. [W]
3210
2840
 
3211
2841
  References
3212
2842
  ----------