8000 coefficient estimation method following DeSoto(2006) by tylunel · Pull Request #784 · pvlib/pvlib-python · GitHub
[go: up one dir, main page]

Skip to content

coefficient estimation method following DeSoto(2006) #784

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

Merged
merged 50 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
c5287ea
function getparams_desoto added to pvsystem module. This commit is ju…
tylunel Aug 21, 2019
5a39fea
getparams_desoto moved from pvsystem to singlediode.
tylunel Aug 21, 2019
7b24201
- Modification of getparams_from_specs so as it follows better the pr…
tylunel Aug 22, 2019
c16f1d0
- Bug corrected in DeSoto(2006) procedure
tylunel Aug 22, 2019
e7ef571
- test_getparams_from_specs_desoto() finished
tylunel Aug 23, 2019
cdb2a73
Not sure of all changes brought by this commit because of holidays.
tylunel Sep 9, 2019
0cfe13f
- function '_parse_raw_sam_df' modified. The parser engine is now def…
tylunel Sep 10, 2019
0c27829
- ModelChain attribute 'diode_params' transformed from tuple containi…
tylunel Sep 11, 2019
d8653cd
- singlediode.get_params_from_specs_desoto() output changed. 'a_ref' …
tylunel Sep 12, 2019
bbb4580
read_epw changed. A line has been added to convert the precipitable w…
tylunel Sep 23, 2019
6b8fadf
- read_epw changed. If condition added to make the conversion only in…
tylunel Sep 30, 2019
121cb06
* Pull and Merge done with upstream pvlib/pvlib-python: fork up to date
tylunel Oct 2, 2019
47e1be4
- argument diode_params changed from tuple to pd.DataFrame
tylunel Oct 2, 2019
c1b62c4
- get_params_from_specs_desoto removed from singlediode.py
tylunel Oct 2, 2019
4e62d1a
- function fit_sdm_desoto added. Still need to be formatted
tylunel Oct 2, 2019
747ed48
- change on type of self.diode_params removed. Go check on branch dio…
tylunel Oct 2, 2019
9ea2ed8
- Function 'fit_sdm_desoto' cleaned and variables names named as in '…
tylunel Oct 2, 2019
bd39dbd
- all changes made on other files than ivtools.py removed (cleaning f…
tylunel Oct 2, 2019
ae5c8be
- other differences cleaned
tylunel Oct 2, 2019
2d4f8f3
- renaming of one variable and minor documentation modifications
tylunel Oct 2, 2019
485dae6
- Beginning of writting of test_fit_sdm_desoto. Coverage around 90-95…
tylunel Oct 4, 2019
77d88a2
-minor format changes
tylunel Oct 4, 2019
6fcafc7
- changes made according to feedbacks of markcampanelli
tylunel Oct 4, 2019
2d53d5d
- some cleaning on fit_sdm_desoto to make it more readable
tylunel Oct 4, 2019
fdbf5ec
- minor code cleaning
tylunel Oct 4, 2019
0e1b4b3
- check on importation of scipy removed
tylunel Oct 7, 2019
d2d8c45
- minor cleaning
tylunel Oct 7, 2019
a70debb
- attempt to reach 100% coverage
tylunel Oct 8, 2019
e01f262
- description added in docs/sphinx/source/whatsnew/v0.7.0.rst
tylunel Oct 8, 2019
17f8617
- changes made according to cwhanse review. Except alpha_sc and beta_…
tylunel Oct 10, 2019
e14ad40
- minor correction and adaptation of test
tylunel Oct 10, 2019
32049b0
- sign correction on 3rd equation
tylunel Oct 11, 2019
bfe3994
- changes on units of alpha_sc and beta_voc inputs. Now in A/K and V/…
tylunel Oct 16, 2019
7ff8a96
- other line of test added for better coverage
tylunel Oct 16, 2019
7f08d80
- some changes to try feedbacks of cwhanse and markcampanelli, not fi…
tylunel Oct 17, 2019
27ab961
-OptimizeResult added in output
tylunel Oct 18, 2019
79ef920
- includes all feedbacks made on the 21/10, except moving of pv_fct()…
tylunel Oct 21, 2019
5e9cf8d
- pv_fct moved out of the fit_sdm_desoto function and renamed in _sys…
tylunel Oct 21, 2019
c02e74f
- minor modification: Boltzmann k given in specs to avoid import of s…
tylunel Oct 22, 2019
fa41eb8
- cleaning and minor modifications to docstring
tylunel Oct 22, 2019
753d312
- references added to docstring in _system_of_equations
tylunel Oct 22, 2019
b1b405c
- modification for removing last lint error
tylunel Oct 22, 2019
22d613c
- modification for removing last lint error
tylunel Oct 22, 2019
ae19a68
- modification for removing lint error
tylunel Oct 22, 2019
6913a52
- modif for removing of lint error
tylunel Oct 22, 2019
05051e1
- integration of adriesse suggestions
tylunel Oct 28, 2019
d4772c6
Merge branch 'master' into fit_sdm_desoto
cwhanse Oct 29, 2019
d821494
- adding of tylunel to the list of contributors
tylunel Oct 29, 2019
9d23552
Merge branch 'fit_sdm_desoto' of https://github.com/tylunel/pvlib-pyt…
tylunel Oct 29, 2019
5037da6
- adding of mark requires_scipy
tylunel Oct 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
- Modification of getparams_from_specs so as it follows better the pr…
…ocedure of DeSoto&al(2006).
  • Loading branch information
tylunel committed Aug 22, 2019
commit 7b242018c5e21ca4a99e40289ee38fdc5f391007
171 changes: 0 additions & 171 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,177 +1213,6 @@ def iam_interp(aoi, theta_ref, iam_ref, method='linear', normalize=True):
return iam


def getparams_desoto(I_sc, V_oc, I_mp, V_mp, alpha_sc, N_s, beta_oc=None):
"""
Calculates the five parameters for the single diode equation at
standard irradiance and standard cell temperature using the De Soto et al.
model described in [1]. The six values returned by getparams_desoto
can be used by calcparams_desoto to calculate the values at different
irradiance and cell temperature.

Parameters
----------
I_sc : numeric
Short-circuit current at std conditions in A.

V_oc : numeric
Open-circuit voltage at std conditions in V.

I_mp : numeric
Module current at the maximum-power point at std conditions in A.

V_mp : numeric
Module voltage at the maximum-power point at std conditions in V.

alpha_sc : numeric
The short-circuit current (I_sc) temperature coefficient of the
module in units of %/K. It is converted in A/K for the computing
process.

N_s : numeric
Number of cell in the module.

beta_oc : numeric
The open-circuit voltage (V_oc) temperature coefficient of the
module in units of %/K. It is converted in V/K for the computing
process.

Returns
-------
Dictionnary with the following elements:

photocurrent 'I_L_ref': numeric
Light-generated current in amperes at std conditions.

saturation_current 'I_o_ref': numeric
Diode saturation curent in amperes at std conditions

resistance_series 'R_s': numeric
Series resistance in ohms. Note that '_ref' is not mentionned
in the name because this resistance is not sensible to the
conditions of test.

resistance_shunt 'R_sh_ref': numeric
Shunt resistance in ohms at std conditions.

'a_ref' (= nNsVth): numeric
Diode factor at std conditions.
The product of the usual diode ideality factor (n, unitless),
number of cells in series (Ns), and cell thermal voltage at
specified effective irradiance and cell temperature.

'alpha_sc': numeric
Caution!: Different from the input because of the unit.
The short-circuit current (I_sc) temperature coefficient of the
module in units of A/K.

References
----------
[1] W. De Soto et al., "Improvement and validation of a model for
photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
2006.
"""
# Constants
k = 1.381e-23 # Boltzmann
q = 1.602e-19 # electron charge in J/V
Tref = 25.0 + 273.15
C = 0.0002677
Eg = 1.796e-19

# Conversion from %/K to A/K & V/K
alpha_sc = alpha_sc*I_sc/100
beta_oc = beta_oc*V_oc/100

def pv_fct(x, param):
"""Returns the system of equations used for computing the
single-diode 5 parameters.
To avoid the confusion in names with variables of container function
the '_' of the variables were removed.
"""

Isc = param[0]
Voc = param[1]
Imp = param[2]
Vmp = param[3]
betaoc = param[4]
alphasc = param[5]

# five parameters vector
IL = x[0]
Io = x[1]
a = x[2]
Rsh = x[3]
Rs = x[4]
# five equation vector
y = [0, 0, 0, 0, 0]

Idsc = Io*(np.exp(Isc*Rs/a) - 1.0)
Idoc = Io*(np.exp(Voc/a) - 1.0)
exm = np.exp((Vmp+Imp*Rs)/a)
Idm = Io*(exm - 1.0)
# 1st equation - short-circuit
y[0] = Isc - IL + Idsc + Isc*Rs/Rsh
# 2nd equation - open-circuit ref
y[1] = -IL + Idoc + Voc/Rsh
# 3rd equation - max Imp
y[2] = Imp - IL + Idm + (Vmp+Imp*Rs)/Rsh
# 4th equation - max Imp der
y[3] = Imp - Vmp*(Io*exm/a + 1.0/Rsh)/(1.0+Io*exm*Rs/a+Rs/Rsh)
# 5th equation - open-circuit T2
if betaoc is None: # option 1 - doesn't work yet-DeSoto method
raise NotImplementedError(
'The function getparams_desoto needs beta_oc '
'for computing the five parameters for now. This can be '
'avoided if the code followed the exact same procedure than '
'described in DeSoto&al(2006)'
)
T2 = Tref + 2
a2 = a*T2/Tref
IL2 = IL + alphasc*(T2-Tref)
Eg2 = Eg*(1-C*(T2-Tref))
Io2 = Io*(T2/Tref)**3*np.exp(Eg2/(k*Tref) - Eg2/(k*T2))

def fct_5(Voc2):
return IL2-Io2*(np.exp(Voc2/a2)-1)-Voc2/Rsh
sol5 = scipy.optimize.root(fct_5, xi, args=param, method='lm')
else:
# option 2 - open-circuit T2
T2 = Tref + 2
Voc2 = (T2-Tref)*betaoc + Voc
a2 = a*T2/Tref
IL2 = IL + alphasc*(T2-Tref)
Eg2 = Eg*(1-C*(T2-Tref))
Io2 = Io*(T2/Tref)**3*np.exp(Eg2/(k*Tref) - Eg2/(k*T2))
Idoc2 = Io2*(np.exp(Voc2/a2) - 1.0)
y[4] = -IL2 + Idoc2 + Voc2/Rsh

return y

# initialization of variables for computing convergence
Rsh1 = 100.0
a1 = 1.5*k*Tref*N_s/q
IL1 = I_sc
Io1 = (IL1-V_oc/Rsh1) / (np.exp(V_oc/a1)-1)
Rs1 = (a1*np.log((IL1-I_mp)/Io1+1) - V_mp)/I_mp
# xi : initial values vector
xi = np.array([IL1, Io1, a1, Rsh1, Rs1])
# params of module
param = np.array([I_sc, V_oc, I_mp, V_mp, beta_oc, alpha_sc])
# computing
res = scipy.optimize.root(pv_fct, xi, args=param, method='lm')
sol = res.x

# results
res = {'I_L_ref': sol[0],
'I_o_ref': sol[1],
'a_ref': sol[2],
'R_sh_ref': sol[3],
'R_s': sol[4],
'alpha_sc': alpha_sc
}
return res


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,
Expand Down
136 changes: 58 additions & 78 deletions pvlib/singlediode.py
8EF0
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ def brentq(*a, **kw):
VOLTAGE_BUILTIN = 0.9 # [V]


def getparams_from_specs(I_sc, V_oc, I_mp, V_mp, alpha_sc,
beta_oc=None, N_s=60):
def getparams_from_specs(I_sc, V_oc, I_mp, V_mp, alpha_sc, beta_oc, N_s=60):
"""
Calculates the five parameters for the single diode equation at
standard irradiance and standard cell temperature using the De Soto et al.
Expand Down Expand Up @@ -90,7 +89,7 @@ def getparams_from_specs(I_sc, V_oc, I_mp, V_mp, alpha_sc,
Shunt resistance in ohms at std conditions.

'a_ref' (= nNsVth): numeric
Diode factor at std conditions.
Modified ideality factor at std conditions.
The product of the usual diode ideality factor (n, unitless),
number of cells in series (Ns), and cell thermal voltage at
specified effective irradiance and cell temperature.
Expand All @@ -105,98 +104,79 @@ def getparams_from_specs(I_sc, V_oc, I_mp, V_mp, alpha_sc,
[1] W. De Soto et al., "Improvement and validation of a model for
photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
2006.

[2] John A Duffie ,William A Beckman, "Solar Engineering of Thermal
Processes", Wiley, 2013
"""
# Constants
k = 1.381e-23 # Boltzmann
q = 1.602e-19 # electron charge in J/V
Tref = 25.0 + 273.15
C = 0.0002677
Eg = 1.796e-19
k = 1.381e-23 # Boltzmann constant, in J/K, or 8.617e-5 eV/K
q = 1.602e-19 # electron charge in J/V, or 1 eV
Tref = 25.0 + 273.15 # in K
C = 0.0002677 # valid for silicon
Eg = 1.796e-19 # in J, valid for silicon

# Conversion from %/K to A/K & V/K
alpha_sc = alpha_sc*I_sc/100
beta_oc = beta_oc*V_oc/100

def pv_fct(x, param):
def pv_fct(params, specs):
"""Returns the system of equations used for computing the
single-diode 5 parameters.
To avoid the confusion in names with variables of container function
the '_' of the variables were removed.
To avoid the confusion in names with variables of container
function the '_' of the variables were removed.
"""

Isc = param[0]
Voc = param[1]
Imp = param[2]
Vmp = param[3]
betaoc = param[4]
alphasc = param[5]

# five parameters vector
IL = x[0]
Io = x[1]
a = x[2]
Rsh = x[3]
Rs = x[4]
# six input known variables
Isc = specs[0]
Voc = specs[1]
Imp = specs[2]
Vmp = specs[3]
betaoc = specs[4]
alphasc = specs[5]
# five parameters vector to find
IL = params[0]
Io = params[1]
a = params[2]
Rsh = params[3]
Rs = params[4]
# five equation vector
y = [0, 0, 0, 0, 0]

Idsc = Io*(np.exp(Isc*Rs/a) - 1.0)
Idoc = Io*(np.exp(Voc/a) - 1.0)
exm = np.exp((Vmp+Imp*Rs)/a)
Idm = Io*(exm - 1.0)
# 1st equation - short-circuit
y[0] = Isc - IL + Idsc + Isc*Rs/Rsh
# 2nd equation - open-circuit ref
y[1] = -IL + Idoc + Voc/Rsh
# 3rd equation - max Imp
y[2] = Imp - IL + Idm + (Vmp+Imp*Rs)/Rsh
# 4th equation - max Imp der
y[3] = Imp - Vmp*(Io*exm/a + 1.0/Rsh)/(1.0+Io*exm*Rs/a+Rs/Rsh)
# 5th equation - open-circuit T2
if betaoc is None: # option 1 - doesn't work yet-DeSoto method
raise NotImplementedError(
'The function getparams_desoto needs beta_oc '
'for computing the five parameters for now. This can be '
'avoided if the code followed the exact same procedure than '
'described in DeSoto&al(2006)'
)
T2 = Tref + 2
a2 = a*T2/Tref
IL2 = IL + alphasc*(T2-Tref)
Eg2 = Eg*(1-C*(T2-Tref))
Io2 = Io*(T2/Tref)**3*np.exp(Eg2/(k*Tref) - Eg2/(k*T2))

def fct_5(Voc2):
return IL2-Io2*(np.exp(Voc2/a2)-1)-Voc2/Rsh
sol5 = root(fct_5, xi, args=param, method='lm')
else:
# option 2 - open-circuit T2
T2 = Tref + 2
Voc2 = (T2-Tref)*betaoc + Voc
a2 = a*T2/Tref
IL2 = IL + alphasc*(T2-Tref)
Eg2 = Eg*(1-C*(T2-Tref))
Io2 = Io*(T2/Tref)**3*np.exp(Eg2/(k*Tref) - Eg2/(k*T2))
Idoc2 = Io2*(np.exp(Voc2/a2) - 1.0)
y[4] = -IL2 + Idoc2 + Voc2/Rsh
# 1st equation - short-circuit - eq(3) in [1]
y[0] = Isc - IL + Io*(np.exp(Isc*Rs/a) - 1.0) + Isc*Rs/Rsh
# 2nd equation - open-circuit Tref - eq(4) in [1]
y[1] = -IL + Io*(np.exp(Voc/a) - 1.0) + Voc/Rsh
# 3rd equation - Imp & Vmp - eq(5) in [1]
y[2] = Imp - IL + Io*(np.exp((Vmp+Imp*Rs)/a) - 1.0) + \
(Vmp+Imp*Rs)/Rsh
# 4th equation - Pmp derivated=0 - eq(6) in [1]
y[3] = Imp - Vmp * ((-Io/a)*np.exp((Vmp+Imp*Rs)/a) - 1.0/Rsh) / \
(1.0 + (Io*Rs/a)*np.exp((Vmp+Imp*Rs)/a) + Rs/Rsh)
# 5th equation - open-circuit T2 - eq (4) at temperature T2 in [1]
T2 = Tref + 2
Voc2 = (T2 - Tref)*betaoc + Voc # eq (7) in [1]
a2 = a*T2/Tref # eq (8) in [1]
IL2 = IL + alphasc*(T2-Tref) # eq (11) in [1]
Eg2 = Eg*(1-C*(T2-Tref)) # eq (10) in [1]
Io2 = Io * (T2/Tref)**3 * np.exp(1/k * (Eg/Tref-Eg2/T2)) # eq (9)
y[4] = -IL2 + Io2*(np.exp(Voc2/a2) - 1.0) + Voc2/Rsh # eq (4) at T2

return y

# initialization of variables for computing convergence:
# Values are taken from Duffie & Beckman (2013), p753
Rsh1 = 100.0
a1 = 1.5*k*Tref*N_s/q
IL1 = I_sc
# Io1 = (IL1-V_oc/Rsh1) / (np.exp(V_oc/a1)-1)
Io1 = I_sc * np.exp(-V_oc/a1)
Rs1 = (a1*np.log((IL1-I_mp)/Io1+1) - V_mp)/I_mp
# xi : initial values vector
xi = np.array([IL1, Io1, a1, Rsh1, Rs1])
# params of module
param = np.array([I_sc, V_oc, I_mp, V_mp, beta_oc, alpha_sc])
# initial guesses of variables for computing convergence:
# Values are taken [2], p753
Rsh_i = 100.0
a_i = 1.5*k*Tref*N_s/q
IL_i = I_sc
Io_i = I_sc * np.exp(-V_oc/a_i)
Rs_i = (a_i*np.log((IL_i-I_mp)/Io_i+1) - V_mp)/I_mp
# params_i : initial values vector
params_i = np.array([IL_i, Io_i, a_i, Rsh_i, Rs_i])

# specs of module
specs = np.array([I_sc, V_oc, I_mp, V_mp, beta_oc, alpha_sc])

# computing
res = root(pv_fct, xi, args=param, method='lm')
sol = res.x
sol = root(pv_fct, x0=params_i, args=specs, method='lm').x

# results
res = {'I_L_ref': sol[0],
Expand Down
0