Skip to content

Commit e5c04a3

Browse files
author
Tobin Ford
committed
merge conflicts: apply stash
1 parent bd6c8c9 commit e5c04a3

File tree

2 files changed

+168
-777
lines changed

2 files changed

+168
-777
lines changed

pvdeg/degradation.py

+47-209
Original file line numberDiff line numberDiff line change
@@ -863,70 +863,33 @@ def _gJtoMJ(gJ):
863863
return MJ
864864

865865

866-
# new version of degradation
867866
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]],
872871
Ea: float = 40.0,
873872
n: float = 1.0,
874873
p: float = 0.5,
875874
C2: float = 0.07,
876875
C: float = 1.0,
877-
)-> float:
876+
) -> float:
878877
"""
879878
Compute degredation as double integral of Arrhenius (Activation
880879
Energy, RH, Temperature) and spectral (wavelength, irradiance)
881880
functions over wavelength and time.
882881
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-
887882
Parameters
888883
----------
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]
930893
Ea : float
931894
Arrhenius activation energy. The default is 40. [kJ/mol]
932895
n : float
@@ -945,183 +908,58 @@ def degradation(
945908
-------
946909
degradation : float
947910
Total degredation factor over time and wavelength.
911+
948912
"""
913+
# --- TO DO ---
914+
# unpack input-dataframe
915+
# spectra = df['spectra']
916+
# temp_module = df['temp_module']
917+
# rh_module = df['rh_module']
949918

919+
# Constants
920+
R = 0.0083145 # Gas Constant in [kJ/mol*K]
950921

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
953924

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
976935

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)
989942

990-
R = 0.0083145 # Gas Constant in [kJ/mol*K]
943+
EApR = -Ea / R
944+
C4 = np.exp(EApR / temp_module)
991945

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
1001948

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"]
1005950

1006-
dD = wavelength_integral * time_integrand
1007-
degradation = C * np.sum(dD)
951+
degradation = C * data["dD"].sum(axis=0)
1008952

1009953
return degradation
1010954

1011955

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-
1114956
# change it to take pd.DataFrame? instead of np.ndarray
1115957
@njit
1116958
def vecArrhenius(
1117959
poa_global: np.ndarray, module_temp: np.ndarray, ea: float, x: float, lnr0: float
1118960
) -> float:
1119961
"""
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}}`
1125963
1126964
Parameters
1127965
----------

0 commit comments

Comments
 (0)