diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index 4070ed56c3..5909db3a7a 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -202,6 +202,7 @@ Functions relevant for the single diode model. :toctree: generated/ pvsystem.calcparams_desoto + pvsystem.calcparams_pvsyst pvsystem.i_from_v pvsystem.singlediode pvsystem.v_from_i diff --git a/docs/sphinx/source/whatsnew/v0.6.0.rst b/docs/sphinx/source/whatsnew/v0.6.0.rst index 2f205edf04..1fc8c0a241 100644 --- a/docs/sphinx/source/whatsnew/v0.6.0.rst +++ b/docs/sphinx/source/whatsnew/v0.6.0.rst @@ -13,6 +13,7 @@ Enhancements * Add sea surface albedo in irradiance.py (:issue:`458`) * Implement first_solar_spectral_loss in modelchain.py (:issue:`359`) * Clarify arguments Egref and dEgdT for calcparams_desoto (:issue:`462`) +* Add pvsystem.calcparams_pvsyst to compute values for the single diode equation using the PVsyst v6 model (:issue:'470') Bug fixes diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 96ac7d3d90..9d3bea858b 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -302,11 +302,40 @@ def calcparams_desoto(self, effective_irradiance, temp_cell, **kwargs): """ kwargs = _build_kwargs(['a_ref', 'I_L_ref', 'I_o_ref', 'R_sh_ref', - 'R_s', 'alpha_sc', 'EgRef', 'dEgdT'], + 'R_s', 'alpha_sc', 'EgRef', 'dEgdT', + 'irrad_ref', 'temp_ref'], self.module_parameters) - + return calcparams_desoto(effective_irradiance, temp_cell, **kwargs) + def calcparams_pvsyst(self, effective_irradiance, temp_cell): + """ + Use the :py:func:`calcparams_pvsyst` function, the input + parameters and ``self.module_parameters`` to calculate the + module currents and resistances. + + Parameters + ---------- + 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. + + Returns + ------- + See pvsystem.calcparams_pvsyst for details + """ + + kwargs = _build_kwargs(['gamma_ref', 'mu_gamma', 'I_L_ref', 'I_o_ref', + 'R_sh_ref', 'R_sh_0', 'R_sh_exp', + 'R_s', 'alpha_sc', 'EgRef', + 'irrad_ref', 'temp_ref', + 'cells_in_series'], + self.module_parameters) + + return calcparams_pvsyst(effective_irradiance, temp_cell, **kwargs) + def sapm(self, effective_irradiance, temp_cell, **kwargs): """ Use the :py:func:`sapm` function, the input parameters, @@ -462,7 +491,7 @@ def first_solar_spectral_loss(self, pw, airmass_absolute): coefficients = None return atmosphere.first_solar_spectral_correction(pw, - airmass_absolute, + airmass_absolute, module_type, coefficients) @@ -946,12 +975,12 @@ def physicaliam(aoi, n=1.526, K=4., L=0.002): def calcparams_desoto(effective_irradiance, temp_cell, - alpha_sc, a_ref, I_L_ref, I_o_ref, R_sh_ref, R_s, + 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): ''' - Calculates five parameter values for the single diode equation at - effective irradiance and cell temperature using the De Soto et al. + 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. @@ -968,34 +997,34 @@ def calcparams_desoto(effective_irradiance, temp_cell, module in units of A/C. a_ref : float - The product of the usual diode ideality factor (n, unitless), + 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 units of eV. - 1.121 eV for crystalline silicon. EgRef must be >0. For parameters + 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 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 + 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. @@ -1011,28 +1040,21 @@ def calcparams_desoto(effective_irradiance, temp_cell, Tuple of the following results: photocurrent : numeric - Light-generated current in amperes at irradiance=S and - cell temperature=Tcell. + Light-generated current in amperes saturation_current : numeric - Diode saturation curent in amperes at irradiance - S and cell temperature Tcell. + Diode saturation curent in amperes resistance_series : float - Series resistance in ohms at irradiance S and cell temperature - Tcell. + Series resistance in ohms resistance_shunt : numeric - Shunt resistance in ohms at irradiance S and cell temperature - Tcell. + Shunt resistance in ohms nNsVth : numeric - Modified diode ideality factor at irradiance S and cell - temperature Tcell. Note that in source [1] nNsVth = a (equation - 2). nNsVth is the product of the usual diode ideality factor - (n), the number of series-connected cells in the module (Ns), - and the thermal voltage of a cell in the module (Vth) at a cell - temperature of Tcell. + 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. References ---------- @@ -1051,8 +1073,6 @@ def calcparams_desoto(effective_irradiance, temp_cell, See Also -------- - sapm - sapm_celltemp singlediode retrieve_sam @@ -1143,7 +1163,7 @@ def calcparams_desoto(effective_irradiance, temp_cell, # Boltzmann constant in eV/K k = 8.617332478e-05 - + # reference temperature Tref_K = temp_ref + 273.15 Tcell_K = temp_cell + 273.15 @@ -1152,9 +1172,9 @@ def calcparams_desoto(effective_irradiance, temp_cell, nNsVth = a_ref * (Tcell_K / Tref_K) - # 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) * + # 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)) @@ -1164,7 +1184,7 @@ def calcparams_desoto(effective_irradiance, temp_cell, # 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., + # 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 @@ -1172,6 +1192,143 @@ def calcparams_desoto(effective_irradiance, temp_cell, return IL, I0, Rs, Rsh, nNsVth +def calcparams_pvsyst(effective_irradiance, temp_cell, + alpha_sc, gamma_ref, mu_gamma, + I_L_ref, I_o_ref, + R_sh_ref, R_sh_0, R_s, + cells_in_series, + R_sh_exp=5.5, + EgRef=1.121, + irrad_ref=1000, temp_ref=25): + ''' + Calculates five parameter values for the single diode equation at + effective irradiance and cell temperature using the PVsyst v6 + model described in [1,2,3]. The five values returned by calcparams_pvsyst + can be used by singlediode to calculate an IV curve. + + Parameters + ---------- + 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_sc : float + The short-circuit current temperature coefficient of the + module in units of A/C. + + gamma_ref : float + The diode ideality factor + + mu_gamma : float + The temperature coefficient for the diode ideality factor, 1/K + + 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_sh_0 : float + The shunt resistance at zero irradiance conditions, in ohms. + + R_s : float + The series resistance at reference conditions, in ohms. + + cells_in_series : integer + The number of cells connected in series. + + R_sh_exp : float + The exponent in the equation for shunt resistance, unitless. Defaults + to 5.5. + + EgRef : float + The energy bandgap at reference temperature in units of eV. + 1.121 eV for crystalline silicon. EgRef must be >0. + + irrad_ref : float (optional, default=1000) + Reference irradiance in W/m^2. + + temp_ref : float (optional, default=25) + Reference cell temperature in C. + + Returns + ------- + Tuple of the following results: + + photocurrent : numeric + Light-generated current in amperes + + saturation_current : numeric + Diode saturation current in amperes + + resistance_series : float + Series resistance in ohms + + resistance_shunt : numeric + Shunt resistance in ohms + + nNsVth : numeric + 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. + + 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 modelling, Presentation at the 2nd PV + Performance Modeling Workshop, Santa Clara, CA, May 2013 + + [3] A. Mermoud, T. Lejeune, Performance Assessment of a Simulation Model + for PV modules of any available technology, 25th European Photovoltaic + Solar Energy Conference, Valencia, Spain, Sept. 2010 + + See Also + -------- + calcparams_desoto + singlediode + + ''' + + # Boltzmann constant in J/K + k = 1.38064852e-23 + + # elementary charge in coulomb + q = 1.6021766e-19 + + # reference temperature + Tref_K = temp_ref + 273.15 + Tcell_K = temp_cell + 273.15 + + gamma = gamma_ref + mu_gamma * (Tcell_K - Tref_K) + nNsVth = gamma * k / q * cells_in_series * Tcell_K + + 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((q * EgRef) / (k * gamma) * (1 / Tref_K - 1 / Tcell_K))) + + Rsh_tmp = (R_sh_ref - R_sh_0 * np.exp(-R_sh_exp)) / (1.0 - np.exp(-R_sh_exp)) + Rsh_base = np.maximum(0.0, Rsh_tmp) + + Rsh = Rsh_base + (R_sh_0 - Rsh_base) * \ + np.exp(-R_sh_exp * effective_irradiance / irrad_ref) + + Rs = R_s + + return IL, I0, Rs, Rsh, nNsVth + + def retrieve_sam(name=None, path=None): ''' Retrieve latest module and inverter info from a local file or the diff --git a/pvlib/test/test_pvsystem.py b/pvlib/test/test_pvsystem.py index 289b0f6577..6931543824 100644 --- a/pvlib/test/test_pvsystem.py +++ b/pvlib/test/test_pvsystem.py @@ -174,6 +174,23 @@ def cec_module_params(sam_data): return module_parameters +@pytest.fixture() +def pvsyst_module_params(): + module_parameters = {} + module_parameters['gamma_ref'] = 1.05 + module_parameters['mu_gamma'] = 0.001 + module_parameters['I_L_ref'] = 6.0 + module_parameters['I_o_ref'] = 5e-9 + module_parameters['EgRef'] = 1.121 + module_parameters['R_sh_ref'] = 300 + module_parameters['R_sh_0'] = 1000 + module_parameters['R_s'] = 0.5 + module_parameters['R_sh_exp'] = 5.5 + module_parameters['cells_in_series'] = 60 + module_parameters['alpha_sc'] = 0.001 + return module_parameters + + def test_sapm(sapm_module_params): times = pd.DatetimeIndex(start='2015-01-01', periods=5, freq='12H') @@ -386,6 +403,35 @@ def test_calcparams_desoto(cec_module_params): assert_allclose(nNsVth, 0.473) +def test_calcparams_pvsyst(pvsyst_module_params): + times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') + effective_irradiance = pd.Series([0.0, 800.0], index=times) + temp_cell = pd.Series([25, 50], index=times) + + IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_pvsyst( + effective_irradiance, + temp_cell, + alpha_sc=pvsyst_module_params['alpha_sc'], + gamma_ref=pvsyst_module_params['gamma_ref'], + mu_gamma=pvsyst_module_params['mu_gamma'], + I_L_ref=pvsyst_module_params['I_L_ref'], + I_o_ref=pvsyst_module_params['I_o_ref'], + R_sh_ref=pvsyst_module_params['R_sh_ref'], + R_sh_0=pvsyst_module_params['R_sh_0'], + R_s=pvsyst_module_params['R_s'], + cells_in_series=pvsyst_module_params['cells_in_series'], + EgRef=pvsyst_module_params['EgRef']) + + assert_series_equal(np.round(IL, 3), pd.Series([0.0, 4.8200], index=times)) + assert_series_equal(np.round(I0, 3), + pd.Series([0.0, 1.47e-7], index=times)) + assert_allclose(Rs, 0.500) + assert_series_equal(np.round(Rsh, 3), + pd.Series([1000.0, 305.757], index=times)) + assert_series_equal(np.round(nNsVth, 4), + pd.Series([1.6186, 1.7961], index=times)) + + def test_PVSystem_calcparams_desoto(cec_module_params, mocker): mocker.spy(pvsystem, 'calcparams_desoto') module_parameters = cec_module_params.copy() @@ -414,6 +460,36 @@ def test_PVSystem_calcparams_desoto(cec_module_params, mocker): assert_allclose(nNsVth, 0.5, atol=0.1) +def test_PVSystem_calcparams_pvsyst(pvsyst_module_params, mocker): + mocker.spy(pvsystem, 'calcparams_pvsyst') + module_parameters = pvsyst_module_params.copy() + system = pvsystem.PVSystem(module_parameters=module_parameters) + effective_irradiance = np.array([0, 800]) + temp_cell = np.array([25, 50]) + IL, I0, Rs, Rsh, nNsVth = system.calcparams_pvsyst(effective_irradiance, + temp_cell) + pvsystem.calcparams_pvsyst.assert_called_once_with( + effective_irradiance, + temp_cell, + alpha_sc=pvsyst_module_params['alpha_sc'], + gamma_ref=pvsyst_module_params['gamma_ref'], + mu_gamma=pvsyst_module_params['mu_gamma'], + I_L_ref=pvsyst_module_params['I_L_ref'], + I_o_ref=pvsyst_module_params['I_o_ref'], + R_sh_ref=pvsyst_module_params['R_sh_ref'], + R_sh_0=pvsyst_module_params['R_sh_0'], + R_s=pvsyst_module_params['R_s'], + cells_in_series=pvsyst_module_params['cells_in_series'], + EgRef=pvsyst_module_params['EgRef'], + R_sh_exp=pvsyst_module_params['R_sh_exp']) + + assert_allclose(IL, np.array([0.0, 4.8200]), atol=1) + assert_allclose(I0, np.array([0.0, 1.47e-7]), atol=1.0e-5) + assert_allclose(Rs, 0.5, atol=0.1) + assert_allclose(Rsh, np.array([1000, 305.757]), atol=50) + assert_allclose(nNsVth, np.array([1.6186, 1.7961]), atol=0.1) + + @pytest.fixture(params=[ { # Can handle all python scalar inputs 'Rsh': 20.,