-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Clarify Egref and dEgdT values, changes calcparams_desoto api #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bf5e3cf
5d5afde
beadc8d
767a466
fcc7fd5
20d9722
e03c304
674fdc7
d883a3b
a906ce6
a371544
6197d99
b7114ec
b3508c3
c3fc630
aa45275
43b912c
aafde7c
bdb212a
ee7c217
869b09a
8d8fc14
558d10e
97d9477
8ca98b6
88584a4
a5c3b2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -279,16 +279,16 @@ def physicaliam(self, aoi): | |
|
||
return physicaliam(aoi, **kwargs) | ||
|
||
def calcparams_desoto(self, poa_global, temp_cell, **kwargs): | ||
def calcparams_desoto(self, effective_irradiance, temp_cell, **kwargs): | ||
""" | ||
Use the :py:func:`calcparams_desoto` function, the input | ||
parameters and ``self.module_parameters`` to calculate the | ||
module currents and resistances. | ||
|
||
Parameters | ||
---------- | ||
poa_global : float or Series | ||
The irradiance (in W/m^2) absorbed by the module. | ||
effective_irradiance : numeric | ||
The irradiance (W/m2) that is converted to photocurrent. | ||
|
||
temp_cell : float or Series | ||
The average cell temperature of cells within a module in C. | ||
|
@@ -300,11 +300,12 @@ def calcparams_desoto(self, poa_global, temp_cell, **kwargs): | |
------- | ||
See pvsystem.calcparams_desoto for details | ||
""" | ||
return calcparams_desoto(poa_global, temp_cell, | ||
self.module_parameters['alpha_sc'], | ||
self.module_parameters, | ||
self.module_parameters['EgRef'], | ||
self.module_parameters['dEgdT'], **kwargs) | ||
|
||
kwargs = _build_kwargs(['a_ref', 'I_L_ref', 'I_o_ref', 'R_sh_ref', | ||
'R_s', 'alpha_sc', 'EgRef', 'dEgdT'], | ||
self.module_parameters) | ||
|
||
return calcparams_desoto(effective_irradiance, temp_cell, **kwargs) | ||
|
||
def sapm(self, effective_irradiance, temp_cell, **kwargs): | ||
""" | ||
|
@@ -944,75 +945,60 @@ def physicaliam(aoi, n=1.526, K=4., L=0.002): | |
return iam | ||
|
||
|
||
def calcparams_desoto(poa_global, temp_cell, alpha_isc, module_parameters, | ||
EgRef, dEgdT, M=1, irrad_ref=1000, temp_ref=25): | ||
def calcparams_desoto(effective_irradiance, temp_cell, | ||
alpha_sc, a_ref, I_L_ref, I_o_ref, R_sh_ref, R_s, | ||
EgRef=1.121, dEgdT=-0.0002677, | ||
irrad_ref=1000, temp_ref=25): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the desoto model is more naturally parameterized in terms of total irradiance at the POA. I propose that Also, calling this "effective irradiance" might be confused with the G_{eff} appearing in the DeSoto's master's thesis, which appears to have a different definition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thunderfish24 here we have a conflict between adhering to the published reference (input would be absorbed irradiance, after reflections and soiling losses but without an adjustment from broadband to effective irradiance) and consistency within pvlib-python. SAPM (and PVsyst, when it is implemented #470) accept effective irradiance as input. I would prefer to see Desoto (and CEC, when it is implemented #463) use the same input quantity, with function signature and inline comments documenting the change from literature. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the standpoint of being able to implement and compare different models easily from the same time-dependent input data (say, global irradiance from pyranometer, albedo, ambient dry bulb temperature, and wind speed), I think having a consistent API would be preferable over complete fidelity to the original model formulation (and documenting the modifications in the code sounds acceptable). It sounds like the definition of "effective irradiance" that you are talking about here is the last one here with SF=1. Can you confirm? I also realize that my thoughts are muddy on POA irradiance. In particular, the above-mentioned irradiance ratio at the POA doesn't seem to include any of the losses that give DeSoto's S or M factors (or an SF for that matter). It sounds like we plan on moving those factors into a separate function (or functions)? Computation graphs might be helpful here for the various models taking inputs to outputs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SAPM documentation strikes again. The explanation of effective irradiance in SAPM is rather opaque and is the question we are asked most frequently. A better explanation would be:
From our attempts to bring order and consistency to PV modeling we arrived at this perspective:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the further detailed explanation @cwhanse, which is making better sense to me now. I need a bit more time to think about the "swapping" of this effective irradiance into DeSoto, but it seems reasonable. Also, it looks like the SAPM's effective irradiance does not try to treat the various angles of incidence of diffuse reflectance on the POA (which seems like a challenging prospect anyhow, and there is an f_D factor). Note that the "effective irradiance" F in my definition here does not include a temperature correction to Isc0. This is not an approximation, but falls out of the derivation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One can derive an alternative auxiliary equation for the photocurrent I_L at operating conditions in the Desoto model by setting V=0 in the SDM and rearranging:
where some of these other parameters are also computed at operating conditions (e.g., I_D). One can then use equation (1) in the SAPM as the model for I_sc at operating conditions (possibly also with a SF) to compute F at operating conditions :). I humbly request that we implement this auxiliary equation for I_L for the SDM in terms of F, which then would then allow us to use either the SAPM or a matched (or unmatched) PV reference device measurement for the determination of the control variable F. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thunderfish24 I could see your request being part of a new function calcparams_(name here). That would be consistent with the API: calcparams_xxxxx returns the 5 values for the single diode equation at irradiance and temperature, etc. My concerns are 1) a source of model parameters (the module-specific constants used by calcparams_xxxxx and 2) ensuring that users understand the input F. Most use cases start with measured broadband irradiance, although pvlib doesn't force the user to consider the instrument behind the measurement. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. K. I am happy to implement this after I work out a usage example with the SAPM I_sc in more detail. It seems to me that if someone is already using measured broadband irradiance as a starting point with SAPM, then that workflow should readily adapt to this implementation of SDM with existing calibration parameters (with only a translation of I_L0 to I_sc0, I think). I also have to first wrap up #426. (I have most of the documentation done there except for some function parameter descriptions and two more tests that I really should write.) |
||
''' | ||
Applies the temperature and irradiance corrections to inputs for | ||
singlediode. | ||
|
||
Applies the temperature and irradiance corrections to the IL, I0, | ||
Rs, Rsh, and a parameters at reference conditions (IL_ref, I0_ref, | ||
etc.) according to the De Soto et. al description given in [1]. The | ||
results of this correction procedure may be used in a single diode | ||
model to determine IV curves at irradiance = S, cell temperature = | ||
Tcell. | ||
Calculates five parameter values for the single diode equation at | ||
effective irradiance and cell temperature using the De Soto et al. | ||
model described in [1]. The five values returned by calcparams_desoto | ||
can be used by singlediode to calculate an IV curve. | ||
|
||
Parameters | ||
---------- | ||
poa_global : numeric | ||
The irradiance (in W/m^2) absorbed by the module. | ||
effective_irradiance : numeric | ||
The irradiance (W/m2) that is converted to photocurrent. | ||
|
||
temp_cell : numeric | ||
The average cell temperature of cells within a module in C. | ||
|
||
alpha_isc : float | ||
alpha_sc : float | ||
The short-circuit current temperature coefficient of the | ||
module in units of 1/C. | ||
|
||
module_parameters : dict | ||
Parameters describing PV module performance at reference | ||
conditions according to DeSoto's paper. Parameters may be | ||
generated or found by lookup. For ease of use, | ||
retrieve_sam can automatically generate a dict based on the | ||
most recent SAM CEC module | ||
database. The module_parameters dict must contain the | ||
following 5 fields: | ||
|
||
* a_ref - modified diode ideality factor parameter at | ||
reference conditions (units of eV), a_ref can be calculated | ||
from the usual diode ideality factor (n), | ||
number of cells in series (Ns), | ||
and cell temperature (Tcell) per equation (2) in [1]. | ||
* I_L_ref - Light-generated current (or photocurrent) | ||
in amperes at reference conditions. This value is referred to | ||
as Iph in some literature. | ||
* I_o_ref - diode reverse saturation current in amperes, | ||
under reference conditions. | ||
* R_sh_ref - shunt resistance under reference conditions (ohms). | ||
* R_s - series resistance under reference conditions (ohms). | ||
module in units of A/C. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C could be confused with Coulombs. Perhaps degC is preferable. (This is also an issue in temp_cell above.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the unit is clear in the context of the docstring. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Amps/Coulomb = 1/second There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to leave the temperature unit on the temperature coefficients as C, because that's the unit used in IEC standards and datasheets. I agree with @wholmgren about being clear in context. |
||
|
||
a_ref : float | ||
The product of the usual diode ideality factor (n, unitless), | ||
number of cells in series (Ns), and cell thermal voltage at reference | ||
conditions, in units of V. | ||
|
||
I_L_ref : float | ||
The light-generated current (or photocurrent) at reference conditions, | ||
in amperes. | ||
|
||
I_o_ref : float | ||
The dark or diode reverse saturation current at reference conditions, | ||
in amperes. | ||
|
||
R_sh_ref : float | ||
The shunt resistance at reference conditions, in ohms. | ||
|
||
R_s : float | ||
The series resistance at reference conditions, in ohms. | ||
|
||
EgRef : float | ||
The energy bandgap at reference temperature (in eV). | ||
1.121 eV for silicon. EgRef must be >0. | ||
The energy bandgap at reference temperature in units of eV. | ||
1.121 eV for crystalline silicon. EgRef must be >0. For parameters | ||
from the SAM CEC module database, EgRef=1.121 is implicit for all | ||
cell types in the parameter estimation algorithm used by NREL. | ||
|
||
dEgdT : float | ||
The temperature dependence of the energy bandgap at SRC (in | ||
1/C). May be either a scalar value (e.g. -0.0002677 as in [1]) | ||
or a DataFrame of dEgdT values corresponding to each input | ||
condition (this may be useful if dEgdT is a function of | ||
temperature). | ||
|
||
M : numeric (optional, default=1) | ||
An optional airmass modifier, if omitted, M is given a value of | ||
1, which assumes absolute (pressure corrected) airmass = 1.5. In | ||
this code, M is equal to M/Mref as described in [1] (i.e. Mref | ||
is assumed to be 1). Source [1] suggests that an appropriate | ||
value for M as a function absolute airmass (AMa) may be: | ||
|
||
>>> M = np.polyval([-0.000126, 0.002816, -0.024459, 0.086257, 0.918093], | ||
... AMa) # doctest: +SKIP | ||
|
||
M may be a Series. | ||
The temperature dependence of the energy bandgap at reference | ||
conditions in units of 1/K. May be either a scalar value | ||
(e.g. -0.0002677 as in [1]) or a DataFrame (this may be useful if | ||
dEgdT is a modeled as a function of temperature). For parameters from | ||
the SAM CEC module database, dEgdT=-0.0002677 is implicit for all cell | ||
types in the parameter estimation algorithm used by NREL. | ||
|
||
irrad_ref : float (optional, default=1000) | ||
Reference irradiance in W/m^2. | ||
|
@@ -1090,7 +1076,7 @@ def calcparams_desoto(poa_global, temp_cell, alpha_isc, module_parameters, | |
and modifying the reference parameters (for irradiance, temperature, | ||
and airmass) per DeSoto's equations. | ||
|
||
Silicon (Si): | ||
Crystalline Silicon (Si): | ||
* EgRef = 1.121 | ||
* dEgdT = -0.0002677 | ||
|
||
|
@@ -1134,26 +1120,54 @@ def calcparams_desoto(poa_global, temp_cell, alpha_isc, module_parameters, | |
Source: [4] | ||
''' | ||
|
||
M = np.maximum(M, 0) | ||
a_ref = module_parameters['a_ref'] | ||
IL_ref = module_parameters['I_L_ref'] | ||
I0_ref = module_parameters['I_o_ref'] | ||
Rsh_ref = module_parameters['R_sh_ref'] | ||
Rs_ref = module_parameters['R_s'] | ||
|
||
# test for use of function pre-v0.6.0 API change | ||
if isinstance(a_ref, dict) or \ | ||
(isinstance(a_ref, pd.Series) and ('a_ref' in a_ref.keys())): | ||
import warnings | ||
warnings.warn('module_parameters detected as fourth positional' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Recommend using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
+ ' argument of calcparams_desoto. calcparams_desoto' | ||
+ ' will require one argument for each module model' | ||
+ ' parameter in v0.7.0 and later', DeprecationWarning) | ||
try: | ||
module_parameters = a_ref | ||
a_ref = module_parameters['a_ref'] | ||
I_L_ref = module_parameters['I_L_ref'] | ||
I_o_ref = module_parameters['I_o_ref'] | ||
R_sh_ref = module_parameters['R_sh_ref'] | ||
R_s = module_parameters['R_s'] | ||
except Exception as e: | ||
raise e('Module parameters could not be extracted from fourth' | ||
+ ' positional argument of calcparams_desoto. Check that' | ||
+ ' parameters are from the CEC database and/or update' | ||
+ ' your code for the new API for calcparams_desoto') | ||
|
||
# Boltzmann constant in eV/K | ||
k = 8.617332478e-05 | ||
|
||
# reference temperature | ||
Tref_K = temp_ref + 273.15 | ||
Tcell_K = temp_cell + 273.15 | ||
|
||
E_g = EgRef * (1 + dEgdT*(Tcell_K - Tref_K)) | ||
|
||
nNsVth = a_ref * (Tcell_K / Tref_K) | ||
|
||
IL = (poa_global/irrad_ref) * M * (IL_ref + alpha_isc * (Tcell_K - Tref_K)) | ||
I0 = (I0_ref * ((Tcell_K / Tref_K) ** 3) * | ||
# In the equation for IL, the single factor effective_irradiance is | ||
# used, in place of the product S*M in [1]. effective_irradiance is | ||
# equivalent to the product of S (irradiance reaching a module's cells) * | ||
# M (spectral adjustment factor) as described in [1]. | ||
IL = effective_irradiance / irrad_ref * \ | ||
(I_L_ref + alpha_sc * (Tcell_K - Tref_K)) | ||
I0 = (I_o_ref * ((Tcell_K / Tref_K) ** 3) * | ||
(np.exp(EgRef / (k*(Tref_K)) - (E_g / (k*(Tcell_K)))))) | ||
Rsh = Rsh_ref * (irrad_ref / poa_global) | ||
Rs = Rs_ref | ||
# Note that the equation for Rsh differs from [1]. In [1] Rsh is given as | ||
# Rsh = Rsh_ref * (S_ref / S) where S is broadband irradiance reaching | ||
# the module's cells. If desired this model behavior can be duplicated | ||
# by applying reflection and soiling losses to broadband plane of array | ||
# irradiance and not applying a spectral loss modifier, i.e., | ||
# spectral_modifier = 1.0. | ||
Rsh = R_sh_ref * (irrad_ref / effective_irradiance) | ||
Rs = R_s | ||
|
||
return IL, I0, Rs, Rsh, nNsVth | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will repeat my preference for spelling out most of these arguments in the function signature as in i_from_v. It would require adding some mapping function within
PVSystem.calcparams_desoto
but I think that's worth it for more descriptive argument names. The descriptive parameter names could be reassigned to the short names to keep the equations more readable.The abbreviated names are still an improvement to the existing API, so I do not object to moving forward as is after some consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your preference but I'd like to defer it to a pull request with a larger scope. The short argument names, e.g.,
alpha_sc
,R_sh_ref
,R_s
(notice the discrepancy) are inherited from the column headings in the SAM database file. We read the column headings from the SAM file, do some character replacement, then use the reformatted names as keys.Using long names in
calcparams_desoto
would ripple to edits topvsystem.retrieve_sam
, where the long names would be assigned as keys, in order to maintain the functionality of_build_kwargs
. I considered doing this but decided it was outside the scope of #462, the issue motivating this pull request.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The R_s instead of R_s_ref in SAM has always puzzled me.