def test__fit_sandia_cocontent_fail(): # tests for ValueError exc_text = 'voltage and current should have the same length' with pytest.raises(ValueError, match=exc_text): sde._fit_sandia_cocontent(np.array([0., 1., 2.]), np.array([4., 3.]), 2.) exc_text = 'at least 6 voltage points are required; ~50 are recommended' with pytest.raises(ValueError, match=exc_text): sde._fit_sandia_cocontent(np.array([0., 1., 2., 3., 4.]), np.array([4., 3.9, 3.4, 2., 0.]), 2.)
def test__fit_sandia_cocontent(i, v, nsvth, expected): # test confirms agreement with Matlab code. The returned parameters # are nonsense iph, io, rsh, rs, n = sde._fit_sandia_cocontent(v, i, nsvth) np.testing.assert_allclose(iph, np.array(expected[0]), atol=.0001) np.testing.assert_allclose(io, np.array([expected[1]]), atol=.0001) np.testing.assert_allclose(rs, np.array([expected[2]]), atol=.0001) np.testing.assert_allclose(rsh, np.array([expected[3]]), atol=.0001) np.testing.assert_allclose(n, np.array([expected[4]]), atol=.0001)
def fit_desoto_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3): """ Estimate parameters for the De Soto module performance model. Parameters ---------- ivcurves : dict i : array One array element for each IV curve. The jth element is itself an array of current for jth IV curve (same length as v[j]) [A] v : array One array element for each IV curve. The jth element is itself an array of voltage for jth IV curve (same length as i[j]) [V] ee : array effective irradiance for each IV curve, i.e., POA broadband irradiance adjusted by solar spectrum modifier [W / m^2] tc : array cell temperature for each IV curve [C] i_sc : array short circuit current for each IV curve [A] v_oc : array open circuit voltage for each IV curve [V] i_mp : array current at max power point for each IV curve [A] v_mp : array voltage at max power point for each IV curve [V] specs : dict cells_in_series : int number of cells in series alpha_sc : float temperature coefficient of Isc [A/C] beta_voc : float temperature coefficient of Voc [V/C] const : dict E0 : float effective irradiance at STC, default 1000 [W/m^2] T0 : float cell temperature at STC, default 25 [C] k : float 1.38066E-23 J/K (Boltzmann's constant) q : float 1.60218E-19 Coulomb (elementary charge) maxiter : int, default 5 input that sets the maximum number of iterations for the parameter updating part of the algorithm. eps1: float, default 1e-3 Tolerance for the IV curve fitting. The parameter updating stops when absolute values of the percent change in mean, max and standard deviation of Imp, Vmp and Pmp between iterations are all less than eps1, or when the number of iterations exceeds maxiter. Returns ------- dict I_L_ref : float light current at STC [A] I_o_ref : float dark current at STC [A] EgRef : float effective band gap at STC [eV] R_s : float series resistance at STC [ohm] R_sh_ref : float shunt resistance at STC [ohm] cells_in_series : int number of cells in series iph : array light current for each IV curve [A] io : array dark current for each IV curve [A] rs : array series resistance for each IV curve [ohm] rsh : array shunt resistance for each IV curve [ohm] u : array boolean for each IV curve indicating that the parameter values are deemed reasonable by the private function ``_filter_params`` Notes ----- The De Soto module performance model is described in [1]_. The fitting method is documented in [2]_, [3]_. Ported from PVLib Matlab [4]_. 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. .. [2] C. Hansen, Parameter Estimation for Single Diode Models of Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065 .. [3] C. Hansen, Estimation of Parameters for Single Diode Models using Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013. .. [4] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB """ if const is None: const = {'E0': 1000.0, 'T0': 25.0, 'k': 1.38066e-23, 'q': 1.60218e-19} ee = ivcurves['ee'] tc = ivcurves['tc'] tck = tc + 273.15 isc = ivcurves['i_sc'] voc = ivcurves['v_oc'] imp = ivcurves['i_mp'] vmp = ivcurves['v_mp'] # Cell Thermal Voltage vth = const['k'] / const['q'] * tck n = len(voc) # Initial estimate of Rsh used to obtain the diode factor gamma0 and diode # temperature coefficient mu_gamma. Rsh is estimated using the co-content # integral method. rsh = np.ones(n) for j in range(n): voltage, current = rectify_iv_curve(ivcurves['v'][j], ivcurves['i'][j]) # initial estimate of Rsh, from integral over voltage regression # [5] Step 3a; [6] Step 3a _, _, _, rsh[j], _ = _fit_sandia_cocontent( voltage, current, vth[j] * specs['cells_in_series']) n0 = _fit_desoto_sandia_diode(ee, voc, vth, tc, specs, const) bad_n = np.isnan(n0) or not np.isreal(n0) if bad_n: raise RuntimeError( "Failed to estimate the diode (ideality) factor parameter;" " aborting parameter estimation.") nnsvth = n0 * specs['cells_in_series'] * vth # For each IV curve, sequentially determine initial values for Io, Rs, # and Iph [5] Step 3a; [6] Step 3 iph, io, rs, u = _initial_iv_params(ivcurves, ee, voc, isc, rsh, nnsvth) # Update values for each IV curve to converge at vmp, imp, voc and isc iph, io, rs, rsh, u = _update_iv_params(voc, isc, vmp, imp, ee, iph, io, rs, rsh, nnsvth, u, maxiter, eps1) # get single diode models from converged values for each IV curve desoto = _extract_sdm_params(ee, tc, iph, io, rs, rsh, n0, u, specs, const, model='desoto') # Add parameters estimated in this function desoto['a_ref'] = n0 * specs['cells_in_series'] * const['k'] / \ const['q'] * (const['T0'] + 273.15) desoto['cells_in_series'] = specs['cells_in_series'] return desoto
def fit_pvsyst_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3): """ Estimate parameters for the PVsyst module performance model. Parameters ---------- ivcurves : dict i : array One array element for each IV curve. The jth element is itself an array of current for jth IV curve (same length as v[j]) [A] v : array One array element for each IV curve. The jth element is itself an array of voltage for jth IV curve (same length as i[j]) [V] ee : array effective irradiance for each IV curve, i.e., POA broadband irradiance adjusted by solar spectrum modifier [W / m^2] tc : array cell temperature for each IV curve [C] i_sc : array short circuit current for each IV curve [A] v_oc : array open circuit voltage for each IV curve [V] i_mp : array current at max power point for each IV curve [A] v_mp : array voltage at max power point for each IV curve [V] specs : dict cells_in_series : int number of cells in series alpha_sc : float temperature coefficient of isc [A/C] const : dict E0 : float effective irradiance at STC, default 1000 [W/m^2] T0 : float cell temperature at STC, default 25 [C] k : float 1.38066E-23 J/K (Boltzmann's constant) q : float 1.60218E-19 Coulomb (elementary charge) maxiter : int, default 5 input that sets the maximum number of iterations for the parameter updating part of the algorithm. eps1: float, default 1e-3 Tolerance for the IV curve fitting. The parameter updating stops when absolute values of the percent change in mean, max and standard deviation of Imp, Vmp and Pmp between iterations are all less than eps1, or when the number of iterations exceeds maxiter. Returns ------- dict I_L_ref : float light current at STC [A] I_o_ref : float dark current at STC [A] EgRef : float effective band gap at STC [eV] R_s : float series resistance at STC [ohm] R_sh_ref : float shunt resistance at STC [ohm] R_sh_0 : float shunt resistance at zero irradiance [ohm] R_sh_exp : float exponential factor defining decrease in shunt resistance with increasing effective irradiance gamma_ref : float diode (ideality) factor at STC [unitless] mu_gamma : float temperature coefficient for diode (ideality) factor [1/K] cells_in_series : int number of cells in series iph : array light current for each IV curve [A] io : array dark current for each IV curve [A] rs : array series resistance for each IV curve [ohm] rsh : array shunt resistance for each IV curve [ohm] u : array boolean for each IV curve indicating that the parameter values are deemed reasonable by the private function ``_filter_params`` Notes ----- The PVsyst module performance model is described in [1]_, [2]_, and [3]_. The fitting method is documented in [4]_, [5]_, and [6]_. Ported from PVLib Matlab [7]_. References ---------- .. [1] K. Sauer, T. Roessler, C. W. Hansen, Modeling the Irradiance and Temperature Dependence of Photovoltaic Modules in PVsyst, IEEE Journal of Photovoltaics v5(1), January 2015. .. [2] A. Mermoud, PV Modules modeling, Presentation at the 2nd PV Performance Modeling Workshop, Santa Clara, CA, May 2013 .. [3] A. Mermoud, T. Lejeuene, Performance Assessment of a Simulation Model for PV modules of any available technology, 25th European Photovoltaic Solar Energy Conference, Valencia, Spain, Sept. 2010 .. [4] C. Hansen, Estimating Parameters for the PVsyst Version 6 Photovoltaic Module Performance Model, Sandia National Laboratories Report SAND2015-8598 .. [5] C. Hansen, Parameter Estimation for Single Diode Models of Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065 .. [6] C. Hansen, Estimation of Parameters for Single Diode Models using Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013. .. [7] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB """ if const is None: const = {'E0': 1000.0, 'T0': 25.0, 'k': 1.38066e-23, 'q': 1.60218e-19} ee = ivcurves['ee'] tc = ivcurves['tc'] tck = tc + 273.15 isc = ivcurves['i_sc'] voc = ivcurves['v_oc'] imp = ivcurves['i_mp'] vmp = ivcurves['v_mp'] # Cell Thermal Voltage vth = const['k'] / const['q'] * tck n = len(ivcurves['v_oc']) # Initial estimate of Rsh used to obtain the diode factor gamma0 and diode # temperature coefficient mu_gamma. Rsh is estimated using the co-content # integral method. rsh = np.ones(n) for j in range(n): voltage, current = rectify_iv_curve(ivcurves['v'][j], ivcurves['i'][j]) # initial estimate of Rsh, from integral over voltage regression # [5] Step 3a; [6] Step 3a _, _, _, rsh[j], _ = _fit_sandia_cocontent( voltage, current, vth[j] * specs['cells_in_series']) gamma_ref, mu_gamma = _fit_pvsyst_sandia_gamma(voc, isc, rsh, vth, tck, specs, const) badgamma = np.isnan(gamma_ref) or np.isnan(mu_gamma) \ or not np.isreal(gamma_ref) or not np.isreal(mu_gamma) if badgamma: raise RuntimeError( "Failed to estimate the diode (ideality) factor parameter;" " aborting parameter estimation.") gamma = gamma_ref + mu_gamma * (tc - const['T0']) nnsvth = gamma * (vth * specs['cells_in_series']) # For each IV curve, sequentially determine initial values for Io, Rs, # and Iph [5] Step 3a; [6] Step 3 iph, io, rs, u = _initial_iv_params(ivcurves, ee, voc, isc, rsh, nnsvth) # Update values for each IV curve to converge at vmp, imp, voc and isc iph, io, rs, rsh, u = _update_iv_params(voc, isc, vmp, imp, ee, iph, io, rs, rsh, nnsvth, u, maxiter, eps1) # get single diode models from converged values for each IV curve pvsyst = _extract_sdm_params(ee, tc, iph, io, rs, rsh, gamma, u, specs, const, model='pvsyst') # Add parameters estimated in this function pvsyst['gamma_ref'] = gamma_ref pvsyst['mu_gamma'] = mu_gamma pvsyst['cells_in_series'] = specs['cells_in_series'] return pvsyst