Skip to content

Commit 2bdea49

Browse files
committed
remake expected test output, add kwargs
1 parent 11ce601 commit 2bdea49

2 files changed

Lines changed: 100 additions & 77 deletions

File tree

pvlib/ivtools/convert.py

Lines changed: 79 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,6 @@
1919
CONSTANTS = {'E0': 1000.0, 'T0': 25.0, 'k': constants.k, 'q': constants.e}
2020

2121

22-
IEC61853_plus = pd.DataFrame(
23-
columns=['effective_irradiance', 'temp_cell'],
24-
data=np.array(
25-
[[100, 100, 100, 100, 200, 200, 200, 200, 400, 400, 400, 400,
26-
600, 600, 600, 600, 800, 800, 800, 800, 1000, 1000, 1000, 1000,
27-
1100, 1100, 1100, 1100],
28-
[15, 25, 50, 75, 15, 25, 50, 75, 15, 25, 50, 75, 15, 25, 50, 75,
29-
15, 25, 50, 75, 15, 25, 50, 75, 15, 25, 50, 75]]).T,
30-
dtype=np.float64)
31-
32-
3322
IEC61853 = pd.DataFrame(
3423
columns=['effective_irradiance', 'temp_cell'],
3524
data=np.array(
@@ -88,8 +77,10 @@ def _pvsyst_objfun(pvs_mod, cec_ivs, ee, tc, cs):
8877
return mean_abs_diff
8978

9079

91-
def convert_cec_pvsyst(cec_model, cells_in_series, method='Nelder-Mead',
92-
options=None):
80+
81+
def convert_cec_pvsyst(cec_model, cells_in_series, initial=None,
82+
method='Nelder-Mead',
83+
bounds=None, options=None):
9384
r"""
9485
Convert a set of CEC model parameters to an equivalent set of PVsyst model
9586
parameters.
@@ -106,16 +97,21 @@ def convert_cec_pvsyst(cec_model, cells_in_series, method='Nelder-Mead',
10697
'R_sh_ref', 'R_s', 'Adjust'
10798
cell_in_series : int
10899
Number of cells in series.
100+
initial : ndarray, optional
101+
Initial guess for CEC model parameters. See Notes for parameter order.
109102
method : str, default 'Nelder-Mead'
110103
Method for scipy.optimize.minimize.
104+
bounds : sequence or Bounds, optional
105+
Initial guess for CEC model parameters. See Notes for parameter order.
106+
See documentation for scipy.optimize.minimize for details.
111107
options : dict, optional
112108
Solver options passed to scipy.optimize.minimize.
113109
114110
Returns
115111
-------
116112
dict with the following elements:
117113
alpha_sc : float
118-
Short-circuit current temperature coefficient [A/C] .
114+
Short-circuit current temperature coefficient [A/C].
119115
I_L_ref : float
120116
The light-generated current (or photocurrent) at reference
121117
conditions [A].
@@ -159,6 +155,27 @@ def convert_cec_pvsyst(cec_model, cells_in_series, method='Nelder-Mead',
159155
.. [2] "IEC 61853-3 Photovoltaic (PV) module performance testing and energy
160156
rating - Part 3: Energy rating of PV modules". IEC, Geneva, 2018.
161157
"""
158+
if initial is None:
159+
# initial guess at PVsyst parameters
160+
# Order in list is alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref,
161+
# Rsh_mult = R_sh_0 / R_sh_ref, R_sh_ref, R_s
162+
gamma_ref = cec_model['a_ref'] / (cells_in_series * 0.025)
163+
initial = [cec_model['alpha_sc'], gamma_ref, 0.001,
164+
cec_model['I_L_ref'], cec_model['I_o_ref'],
165+
12, 1000, cec_model['R_s']]
166+
167+
if bounds is None:
168+
# bounds for PVsyst parameters
169+
b_alpha = (-1, 1)
170+
b_gamma = (1, 2)
171+
b_mu = (-1, 1)
172+
b_IL = (1e-12, 100)
173+
b_Io = (1e-24, 0.1)
174+
b_Rmult = (1, 20)
175+
b_Rsh = (100, 1e6)
176+
b_Rs = (1e-12, 10)
177+
bounds = [b_alpha, b_gamma, b_mu, b_IL, b_Io, b_Rmult, b_Rsh, b_Rs]
178+
162179
if options is None:
163180
options = {'maxiter': 5000, 'maxfev': 5000, 'xatol': 0.001}
164181

@@ -169,23 +186,6 @@ def convert_cec_pvsyst(cec_model, cells_in_series, method='Nelder-Mead',
169186
**cec_model)
170187
cec_ivs = singlediode(*cec_params)
171188

172-
# initial guess at PVsyst parameters
173-
# Order in list is alpha_sc, gamma_ref, mu_gamma, I_L_ref, I_o_ref,
174-
# Rsh_mult = R_sh_0 / R_sh_ref, R_sh_ref, R_s
175-
initial = [0, 1.2, 0.001, cec_model['I_L_ref'], cec_model['I_o_ref'],
176-
12, 1000, cec_model['R_s']]
177-
178-
# bounds for PVsyst parameters
179-
b_alpha = (-1, 1)
180-
b_gamma = (1, 2)
181-
b_mu = (-1, 1)
182-
b_IL = (1e-12, 100)
183-
b_Io = (1e-24, 0.1)
184-
b_Rmult = (1, 20)
185-
b_Rsh = (100, 1e6)
186-
b_Rs = (1e-12, 10)
187-
bounds = [b_alpha, b_gamma, b_mu, b_IL, b_Io, b_Rmult, b_Rsh, b_Rs]
188-
189189
# optimization to find PVsyst parameters
190190
result = optimize.minimize(
191191
_pvsyst_objfun, initial,
@@ -242,7 +242,9 @@ def _cec_objfun(cec_mod, pvs_ivs, ee, tc, alpha_sc):
242242
return mean_diff
243243

244244

245-
def convert_pvsyst_cec(pvsyst_model, method='Nelder-Mead', options=None):
245+
def convert_pvsyst_cec(pvsyst_model, initial=None, method='Nelder-Mead',
246+
bounds=None, options=None,
247+
EgRef=1.121, dEgdT=-0.0002677):
246248
r"""
247249
Convert a set of PVsyst model parameters to an equivalent set of CEC model
248250
parameters.
@@ -258,14 +260,31 @@ def convert_pvsyst_cec(pvsyst_model, method='Nelder-Mead', options=None):
258260
Must include keys: 'alpha_sc', 'I_L_ref', 'I_o_ref', 'EgRef', 'R_s',
259261
'R_sh_ref', 'R_sh_0', 'R_sh_exp', 'gamma_ref', 'mu_gamma',
260262
'cells_in_series'
261-
method : str, default 'Nelder-Mead'
263+
initial : ndarray, optional
264+
Initial guess for CEC model parameters. See Notes for parameter order.
265+
method : str or callable, default 'Nelder-Mead'
262266
Method for scipy.optimize.minimize.
267+
bounds : sequence or Bounds, optional
268+
Initial guess for CEC model parameters. See Notes for parameter order.
269+
See documentation for scipy.optimize.minimize for details.
263270
options : dict, optional
264271
Solver options passed to scipy.optimize.minimize.
272+
EgRef : float, default 1.121
273+
The energy bandgap at reference temperature [eV].
274+
1.121 eV for crystalline silicon. EgRef=1.121 is implicit for all
275+
cell types in the SAM CEC module database, and is imposed by the
276+
CEC parameter estimation algorithm in SAM.
277+
dEgdT : float, default -0.0002677
278+
The temperature dependence of the energy bandgap at reference
279+
conditions [1/K]. dEgdT=-0.0002677 is implicit for all cell
280+
types in the SAM CEC module database, and is imposed by the
281+
CEC parameter estimation algorithm in SAM.
265282
266283
Returns
267284
-------
268285
dict with the following elements:
286+
alpha_sc : float
287+
The input short-circuit current temperature coefficient [A/C].
269288
I_L_ref : float
270289
The light-generated current (or photocurrent) at reference
271290
conditions [A].
@@ -284,16 +303,21 @@ def convert_pvsyst_cec(pvsyst_model, method='Nelder-Mead', options=None):
284303
The adjustment to the temperature coefficient for short circuit
285304
current, in percent.
286305
EgRef : float
287-
The energy bandgap at reference temperature [eV].
306+
The input energy bandgap at reference temperature [eV].
288307
dEgdT : float
289-
The temperature dependence of the energy bandgap at reference
308+
The input temperature dependence of the energy bandgap at reference
290309
conditions [1/K].
291310
292311
Notes
293312
-----
294313
Reference conditions are irradiance of 1000 W/m⁻² and cell temperature of
295314
25 °C.
296315
316+
Notes
317+
-----
318+
The order of the parameters in the initial guess and bounds:
319+
[I_L_ref, I_o_ref, a_ref, R_sh_ref, R_s, Adjust]
320+
297321
See Also
298322
--------
299323
pvlib.ivtools.convert.convert_cec_pvsyst
@@ -307,6 +331,25 @@ def convert_pvsyst_cec(pvsyst_model, method='Nelder-Mead', options=None):
307331
.. [2] "IEC 61853-3 Photovoltaic (PV) module performance testing and energy
308332
rating - Part 3: Energy rating of PV modules". IEC, Geneva, 2018.
309333
"""
334+
# initial guess
335+
# order must match arguments of _cec_objfun
336+
# order : [I_L_ref, I_o_ref, a_ref, R_sh_ref, R_s, alpha_sc, Adjust]
337+
338+
if initial is None:
339+
nNsVth = pvsyst_model['gamma_ref'] * pvsyst_model['cells_in_series'] \
340+
* 0.025
341+
initial = [pvsyst_model['I_L_ref'], pvsyst_model['I_o_ref'],
342+
nNsVth, pvsyst_model['R_sh_ref'], pvsyst_model['R_s'], 0]
343+
344+
if bounds is None:
345+
# bounds for CEC parameters
346+
b_IL = (1e-12, 100)
347+
b_Io = (1e-24, 0.1)
348+
b_aref = (1e-12, 1000)
349+
b_Rsh = (100, 1e6)
350+
b_Rs = (1e-12, 10)
351+
b_Adjust = (-100, 100)
352+
bounds = [b_IL, b_Io, b_aref, b_Rsh, b_Rs, b_Adjust]
310353

311354
if options is None:
312355
options = {'maxiter': 5000, 'maxfev': 5000, 'xatol': 0.001}
@@ -318,33 +361,11 @@ def convert_pvsyst_cec(pvsyst_model, method='Nelder-Mead', options=None):
318361
**pvsyst_model)
319362
pvsyst_ivs = singlediode(*pvs_params)
320363

321-
# set EgRef and dEgdT to CEC defaults
322-
EgRef = 1.121
323-
dEgdT = -0.0002677
324-
325-
# initial guess
326-
# order must match _pvsyst_objfun
327-
# order : [I_L_ref, I_o_ref, a_ref, R_sh_ref, R_s, alpha_sc, Adjust]
328-
nNsVth = pvsyst_model['gamma_ref'] * pvsyst_model['cells_in_series'] \
329-
* 0.025
330-
initial = [pvsyst_model['I_L_ref'], pvsyst_model['I_o_ref'],
331-
nNsVth, pvsyst_model['R_sh_ref'], pvsyst_model['R_s'],
332-
0]
333-
334-
# bounds for PVsyst parameters
335-
b_IL = (1e-12, 100)
336-
b_Io = (1e-24, 0.1)
337-
b_aref = (1e-12, 1000)
338-
b_Rsh = (100, 1e6)
339-
b_Rs = (1e-12, 10)
340-
b_Adjust = (-100, 100)
341-
bounds = [b_IL, b_Io, b_aref, b_Rsh, b_Rs, b_Adjust]
342-
343364
result = optimize.minimize(
344365
_cec_objfun, initial,
345366
args=(pvsyst_ivs, IEC61853['effective_irradiance'],
346367
IEC61853['temp_cell'], pvsyst_model['alpha_sc']),
347-
method='Nelder-Mead',
368+
method=method,
348369
bounds=bounds,
349370
options=options)
350371

tests/ivtools/test_convert.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,24 @@ def test_convert_cec_pvsyst():
66
cells_in_series = 66
77
trina660_cec = {'I_L_ref': 18.4759, 'I_o_ref': 5.31e-12,
88
'EgRef': 1.121, 'dEgdT': -0.0002677,
9-
'R_s': 0.159916, 'R_sh_ref': 113.991, 'a_ref': 1.59068,
9+
'R_s': 0.159916, 'R_sh_ref': 113.991, 'a_ref': 1.8,
1010
'Adjust': 6.42247, 'alpha_sc': 0.00629}
1111
trina660_pvsyst_est = convert.convert_cec_pvsyst(trina660_cec,
1212
cells_in_series)
13-
pvsyst_expected = {'alpha_sc': 0.007478218748188788,
14-
'I_L_ref': 18.227679597516214,
15-
'I_o_ref': 2.7418999402908e-11,
16-
'EgRef': 1.121,
17-
'R_s': 0.16331908293164496,
18-
'R_sh_ref': 5267.928954454954,
19-
'R_sh_0': 60171.206687871425,
20-
'R_sh_exp': 5.5,
21-
'gamma_ref': 1.0,
22-
'mu_gamma': -6.349173477135307e-05,
23-
'cells_in_series': 66}
13+
pvsyst_expected = {'alpha_sc': 0.0096671,
14+
'I_L_ref': 18.19305,
15+
'I_o_ref': 6.94494e-12,
16+
'EgRef': 1.121,
17+
'R_s': 0.16318,
18+
'R_sh_ref': 1000.947,
19+
'R_sh_0': 8593.35,
20+
'R_sh_exp': 5.5,
21+
'gamma_ref': 1.0724,
22+
'mu_gamma': -0.00074595,
23+
'cells_in_series': 66}
2424

2525
assert np.all([np.isclose(trina660_pvsyst_est[k], pvsyst_expected[k],
26-
rtol=1e-3)
26+
rtol=1e-4, atol=0.)
2727
for k in pvsyst_expected])
2828

2929

@@ -34,15 +34,17 @@ def test_convert_pvsyst_cec():
3434
'R_sh_exp': 5.5, 'gamma_ref': 1.002, 'mu_gamma': 1e-3,
3535
'cells_in_series': 66}
3636
trina660_cec_est = convert.convert_pvsyst_cec(trina660_pvsyst)
37+
3738
cec_expected = {'alpha_sc': 0.0074,
38-
'I_L_ref': 18.05154226834071,
39-
'I_o_ref': 2.6863417875143392e-14,
39+
'I_L_ref': 18.09421,
40+
'I_o_ref': 2.46522e-14,
4041
'EgRef': 1.121,
4142
'dEgdT': -0.0002677,
42-
'R_s': 0.09436341848926795,
43-
'a_ref': 1.2954800250731866,
44-
'Adjust': 0.0011675969492410047}
43+
'R_s': 0.098563,
44+
'R_sh_ref': 268.508,
45+
'a_ref': 1.2934,
46+
'Adjust': 0.0065145}
4547

4648
assert np.all([np.isclose(trina660_cec_est[k], cec_expected[k],
47-
rtol=1e-3)
49+
rtol=1e-4, atol=0.)
4850
for k in cec_expected])

0 commit comments

Comments
 (0)