@@ -863,70 +863,33 @@ def _gJtoMJ(gJ):
863
863
return MJ
864
864
865
865
866
- # new version of degradation
867
866
def degradation (
868
- spectra_df : pd .DataFrame ,
869
- conditions_df : pd .DataFrame = None ,
870
- temp_module : pd .Series = None ,
871
- rh_module : pd . Series = None ,
867
+ spectra : pd .Series ,
868
+ rh_module : pd .Series ,
869
+ temp_module : pd .Series ,
870
+ wavelengths : Union [ int , np . ndarray [ float ]] ,
872
871
Ea : float = 40.0 ,
873
872
n : float = 1.0 ,
874
873
p : float = 0.5 ,
875
874
C2 : float = 0.07 ,
876
875
C : float = 1.0 ,
877
- )-> float :
876
+ ) -> float :
878
877
"""
879
878
Compute degredation as double integral of Arrhenius (Activation
880
879
Energy, RH, Temperature) and spectral (wavelength, irradiance)
881
880
functions over wavelength and time.
882
881
883
- .. math::
884
-
885
- D = C \\ int_{0}^{t} RH(t)^n \\ cdot e^{\\ frac{-E_a}{RT(t)}} \\ int_{\\ lambda} [e^{-C_2 \\ lambda} \\ cdot G(\\ lambda, t)]^p d\\ lambda dt
886
-
887
882
Parameters
888
883
----------
889
- spectra_df : pd.DataFrame
890
- front or rear irradiance data in dataframe format
891
-
892
- - `data`: Spectral irradiance values for each wavelength [W/m^2 nm].
893
- - `index`: pd.DateTimeIndex
894
- - `columns`: Wavelengths as floats (e.g., 280, 300, etc.).
895
-
896
- Example::
897
-
898
- timestamp 280 300 320 340 360 380 400
899
- 2021-03-09 10:00:00 0.6892 0.4022 0.6726 0.0268 0.3398 0.9432 0.7411
900
- 2021-03-09 11:00:00 0.1558 0.5464 0.6896 0.7828 0.5050 0.9336 0.4652
901
- 2021-03-09 12:00:00 0.2278 0.9057 0.2639 0.0572 0.9906 0.9370 0.1800
902
- 2021-03-09 13:00:00 0.3742 0.0358 0.4052 0.9578 0.1044 0.8917 0.4876
903
-
904
- conditions_df : pd.DataFrame, optional
905
- Environmental conditions including temperature and relative humidity.
906
-
907
- - `index`: pd.DateTimeIndex
908
- - `columns`: (required)
909
- - "temperature" [°C or K]
910
- - "relative_humidity" [%]
911
-
912
- Example::
913
-
914
- timestamp temperature relative_humidity
915
- 2021-03-09 10:00:00 298.0 45.0
916
- 2021-03-09 11:00:00 303.0 50.0
917
- 2021-03-09 12:00:00 310.0 55.0
918
- 2021-03-09 13:00:00 315.0 60.0
919
-
920
- temp_module : pd.Series, optional
921
- Module temperatures [°C]. Required if `conditions_df` is not provided. Time indexed same as spectra_df
922
-
923
- rh_module : pd.Series, optional
924
- Relative humidity values [%]. Required if `conditions_df` is not provided. Time indexed same as spectra_df
925
-
926
- Example::
927
-
928
- 30 = 30%
929
-
884
+ spectra : pd.Series type=Float
885
+ front or rear irradiance at each wavelength in "wavelengths" [W/m^2 nm]
886
+ rh_module : pd.Series type=Float
887
+ module RH, time indexed [%]
888
+ temp_module : pd.Series type=Float
889
+ module temperature, time indexed [C]
890
+ wavelengths : int-array
891
+ integer array (or list) of wavelengths tested w/ uniform delta
892
+ in nanometers [nm]
930
893
Ea : float
931
894
Arrhenius activation energy. The default is 40. [kJ/mol]
932
895
n : float
@@ -945,183 +908,58 @@ def degradation(
945
908
-------
946
909
degradation : float
947
910
Total degredation factor over time and wavelength.
911
+
948
912
"""
913
+ # --- TO DO ---
914
+ # unpack input-dataframe
915
+ # spectra = df['spectra']
916
+ # temp_module = df['temp_module']
917
+ # rh_module = df['rh_module']
949
918
919
+ # Constants
920
+ R = 0.0083145 # Gas Constant in [kJ/mol*K]
950
921
951
- if conditions_df is not None and ( temp_module is not None or rh_module is not None ):
952
- raise ValueError ( "Provide either conditions_df or temp_module and rh_module" )
922
+ wav_bin = list ( np . diff ( wavelengths ))
923
+ wav_bin . append ( wav_bin [ - 1 ]) # Adding a bin for the last wavelength
953
924
954
- if conditions_df is not None :
955
- rh = conditions_df ["relative_humidity" ].values
956
- temps = conditions_df ["temperature" ].values
957
- else :
958
- rh = rh_module .values
959
- temps = temp_module .values
960
-
961
- wavelengths = spectra_df .columns .values .astype (float )
962
- irr = spectra_df .values # irradiance as array
963
-
964
- # call numba compiled function
965
- return deg (
966
- wavelengths = wavelengths ,
967
- irr = irr ,
968
- rh = rh ,
969
- temps = temps ,
970
- Ea = Ea ,
971
- C2 = C2 ,
972
- p = p ,
973
- n = n ,
974
- C = C
975
- )
925
+ # Integral over Wavelength
926
+ try :
927
+ irr = pd .DataFrame (spectra .tolist (), index = spectra .index )
928
+ irr .columns = wavelengths
929
+ except :
930
+ # TODO: Fix this except it works on some cases, veto it by cases
931
+ print ("Removing brackets from spectral irradiance data" )
932
+ # irr = data['spectra'].str.strip('[]').str.split(',', expand=True).astype(float)
933
+ irr = spectra .str .strip ("[]" ).str .split ("," , expand = True ).astype (float )
934
+ irr .columns = wavelengths
976
935
977
- # @njit
978
- def deg (
979
- wavelengths : np .ndarray ,
980
- irr : np .ndarray ,
981
- rh : np .ndarray ,
982
- temps : np .ndarray ,
983
- Ea : float ,
984
- C2 : float ,
985
- p : float ,
986
- n : float ,
987
- C : float
988
- ) -> float :
936
+ sensitivitywavelengths = np .exp (- C2 * wavelengths )
937
+ irr = irr * sensitivitywavelengths
938
+ irr *= np .array (wav_bin )
939
+ irr = irr ** p
940
+ data = pd .DataFrame (index = spectra .index )
941
+ data ["G_integral" ] = irr .sum (axis = 1 )
989
942
990
- R = 0.0083145 # Gas Constant in [kJ/mol*K]
943
+ EApR = - Ea / R
944
+ C4 = np .exp (EApR / temp_module )
991
945
992
- wav_bin = np .diff (wavelengths )
993
- wav_bin = np .append (wav_bin , wav_bin [- 1 ]) # Extend last bin
994
-
995
- # inner integral
996
- # wavelength d lambda
997
- irr_weighted = irr * np .exp (- C2 * wavelengths ) # weight irradiances
998
- irr_weighted *= wav_bin
999
- irr_pow = irr_weighted ** p
1000
- wavelength_integral = np .sum (irr_pow , axis = 1 ) # sum over wavelengths
946
+ RHn = rh_module ** n
947
+ data ["Arr_integrand" ] = C4 * RHn
1001
948
1002
- # outer integral
1003
- # arrhenius integral dt
1004
- time_integrand = (rh ** n ) * np .exp (- Ea / (R * temps ))
949
+ data ["dD" ] = data ["G_integral" ] * data ["Arr_integrand" ]
1005
950
1006
- dD = wavelength_integral * time_integrand
1007
- degradation = C * np .sum (dD )
951
+ degradation = C * data ["dD" ].sum (axis = 0 )
1008
952
1009
953
return degradation
1010
954
1011
955
1012
- # @deprecated("old double integral degradation function will be replaced 'pvdegradation' in an updated version of pvdeg")
1013
- # def degradation(
1014
- # spectra: pd.Series,
1015
- # rh_module: pd.Series,
1016
- # temp_module: pd.Series,
1017
- # wavelengths: Union[int, np.ndarray[float]],
1018
- # Ea: float = 40.0,
1019
- # n: float = 1.0,
1020
- # p: float = 0.5,
1021
- # C2: float = 0.07,
1022
- # C: float = 1.0,
1023
- # ) -> float:
1024
- # """
1025
- # Compute degredation as double integral of Arrhenius (Activation
1026
- # Energy, RH, Temperature) and spectral (wavelength, irradiance)
1027
- # functions over wavelength and time.
1028
-
1029
- # .. math::
1030
-
1031
- # D = C \\int_{0}^{t} RH(t)^n \\cdot e^{\\frac{-E_a}{RT(t)}} \\int_{\\lambda} [e^{-C_2 \\lambda} \\cdot G(\\lambda, t)]^p d\\lambda dt
1032
-
1033
- # Parameters
1034
- # ----------
1035
- # spectra : pd.Series type=Float
1036
- # front or rear irradiance at each wavelength in "wavelengths" [W/m^2 nm]
1037
- # rh_module : pd.Series type=Float
1038
- # module RH, time indexed [%]
1039
- # temp_module : pd.Series type=Float
1040
- # module temperature, time indexed [C]
1041
- # wavelengths : int-array
1042
- # integer array (or list) of wavelengths tested w/ uniform delta
1043
- # in nanometers [nm]
1044
- # Ea : float
1045
- # Arrhenius activation energy. The default is 40. [kJ/mol]
1046
- # n : float
1047
- # Fit paramter for RH sensitivity. The default is 1.
1048
- # p : float
1049
- # Fit parameter for irradiance sensitivity. Typically
1050
- # 0.6 +- 0.22
1051
- # C2 : float
1052
- # Fit parameter for sensitivity to wavelength exponential.
1053
- # Typically 0.07
1054
- # C : float
1055
- # Fit parameter for the Degradation equaiton
1056
- # Typically 1.0
1057
-
1058
- # Returns
1059
- # -------
1060
- # degradation : float
1061
- # Total degredation factor over time and wavelength.
1062
- # """
1063
- # # --- TO DO ---
1064
- # # unpack input-dataframe
1065
- # # spectra = df['spectra']
1066
- # # temp_module = df['temp_module']
1067
- # # rh_module = df['rh_module']
1068
-
1069
- # # Constants
1070
- # R = 0.0083145 # Gas Constant in [kJ/mol*K]
1071
-
1072
- # wav_bin = list(np.diff(wavelengths))
1073
- # wav_bin.append(wav_bin[-1]) # Adding a bin for the last wavelength
1074
-
1075
- # # Integral over Wavelength
1076
- # try:
1077
- # irr = pd.DataFrame(spectra.tolist(), index=spectra.index)
1078
- # irr.columns = wavelengths
1079
- # except:
1080
- # # TODO: Fix this except it works on some cases, veto it by cases
1081
- # print("Removing brackets from spectral irradiance data")
1082
- # # irr = data['spectra'].str.strip('[]').str.split(',', expand=True).astype(float)
1083
- # irr = spectra.str.strip("[]").str.split(",", expand=True).astype(float)
1084
- # irr.columns = wavelengths
1085
-
1086
-
1087
- # # double integral calculation
1088
- # sensitivitywavelengths = np.exp(-C2 * wavelengths)
1089
- # irr = irr * sensitivitywavelengths
1090
- # irr *= np.array(wav_bin)
1091
- # irr = irr**p
1092
- # data = pd.DataFrame(index=spectra.index)
1093
- # data["G_integral"] = irr.sum(axis=1)
1094
-
1095
- # EApR = -Ea / R
1096
- # C4 = np.exp(EApR / temp_module)
1097
-
1098
- # RHn = rh_module**n
1099
-
1100
- # data["Arr_integrand"] = C4 * RHn
1101
-
1102
- # print("arr integral", data["Arr_integrand"])
1103
- # print("wavelength integral", data["G_integral"] )
1104
-
1105
- # data["dD"] = data["G_integral"] * data["Arr_integrand"]
1106
-
1107
- # print(f"delta degradation ", data["dD"])
1108
-
1109
- # degradation = C * data["dD"].sum(axis=0)
1110
-
1111
- # return degradation
1112
-
1113
-
1114
956
# change it to take pd.DataFrame? instead of np.ndarray
1115
957
@njit
1116
958
def vecArrhenius (
1117
959
poa_global : np .ndarray , module_temp : np .ndarray , ea : float , x : float , lnr0 : float
1118
960
) -> float :
1119
961
"""
1120
- Calculate arrhenius degradation using vectorized operations. To eliminate the irradiance term set the irradiance sensitivity to 0.
1121
-
1122
- .. math::
1123
-
1124
- R_D = R_0 \\ cdot I^X \\ cdot e^{\\ frac{-E_a}{kT}}
962
+ Calculates degradation using :math:`R_D = R_0 * I^X * e^{\\ frac{-Ea}{kT}}`
1125
963
1126
964
Parameters
1127
965
----------
0 commit comments