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