def test_calcparams_desoto(): cecmodule = sam_data['cecmod'].Example_Module pvsystem.calcparams_desoto(S=irrad_data.GHI, temp_cell=25, alpha_isc=cecmodule['Alpha_sc'], module_parameters=cecmodule, EgRef=1.121, dEgdT=-0.0002677)
def test_calcparams_desoto(): cecmodule = sam_data["cecmod"].Example_Module pvsystem.calcparams_desoto( irrad_data["ghi"], temp_cell=25, alpha_isc=cecmodule["alpha_sc"], module_parameters=cecmodule, EgRef=1.121, dEgdT=-0.0002677, )
def test_brentq_spr_e20_327(): """test pvsystem.singlediode with Brent method on SPR-E20-327""" spr_e20_327 = CECMOD.SunPower_SPR_E20_327 x = pvsystem.calcparams_desoto( effective_irradiance=POA, temp_cell=TCELL, alpha_sc=spr_e20_327.alpha_sc, a_ref=spr_e20_327.a_ref, I_L_ref=spr_e20_327.I_L_ref, I_o_ref=spr_e20_327.I_o_ref, R_sh_ref=spr_e20_327.R_sh_ref, R_s=spr_e20_327.R_s, EgRef=1.121, dEgdT=-0.0002677) il, io, rs, rsh, nnsvt = x pvs = pvsystem.singlediode(*x, method='lambertw') out = pvsystem.singlediode(*x, method='brentq') isc, voc, imp, vmp, pmp, ix, ixx = out.values() assert np.isclose(pvs['i_sc'], isc) assert np.isclose(pvs['v_oc'], voc) # the singlediode method doesn't actually get the MPP correct pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw') pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw') assert np.isclose(pvs_imp, imp) assert np.isclose(pvs_vmp, vmp) assert np.isclose(pvs['p_mp'], pmp) assert np.isclose(pvs['i_x'], ix) pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il, method='lambertw') assert np.isclose(pvs_ixx, ixx) return isc, voc, imp, vmp, pmp, pvs
def test_singlediode_series_ivcurve(cec_module_params): times = pd.DatetimeIndex(start='2015-06-01', periods=3, freq='6H') poa_data = pd.Series([0, 400, 800], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( poa_data, temp_cell=25, alpha_isc=cec_module_params['alpha_sc'], module_parameters=cec_module_params, EgRef=1.121, dEgdT=-0.0002677) out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3) expected = OrderedDict([('i_sc', array([ nan, 3.01054475, 6.00675648])), ('v_oc', array([ nan, 9.96886962, 10.29530483])), ('i_mp', array([ nan, 2.65191983, 5.28594672])), ('v_mp', array([ nan, 8.33392491, 8.4159707 ])), ('p_mp', array([ nan, 22.10090078, 44.48637274])), ('i_x', array([ nan, 2.88414114, 5.74622046])), ('i_xx', array([ nan, 2.04340914, 3.90007956])), ('v', array([[ nan, nan, nan], [ 0. , 4.98443481, 9.96886962], [ 0. , 5.14765242, 10.29530483]])), ('i', array([[ nan, nan, nan], [ 3.01079860e+00, 2.88414114e+00, 3.10862447e-14], [ 6.00726296e+00, 5.74622046e+00, 0.00000000e+00]]))]) for k, v in out.items(): assert_allclose(expected[k], v, atol=1e-2)
def test_newton_fs_495(): """test pvsystem.singlediode with Newton method on FS495""" fs_495 = CECMOD.First_Solar_FS_495 x = pvsystem.calcparams_desoto( effective_irradiance=POA, temp_cell=TCELL, alpha_sc=fs_495.alpha_sc, a_ref=fs_495.a_ref, I_L_ref=fs_495.I_L_ref, I_o_ref=fs_495.I_o_ref, R_sh_ref=fs_495.R_sh_ref, R_s=fs_495.R_s, EgRef=1.475, dEgdT=-0.0003) il, io, rs, rsh, nnsvt = x x += (101, ) pvs = pvsystem.singlediode(*x, method='lambertw') out = pvsystem.singlediode(*x, method='newton') isc, voc, imp, vmp, pmp, ix, ixx, i, v = out.values() assert np.isclose(pvs['i_sc'], isc) assert np.isclose(pvs['v_oc'], voc) # the singlediode method doesn't actually get the MPP correct pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw') pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw') assert np.isclose(pvs_imp, imp) assert np.isclose(pvs_vmp, vmp) assert np.isclose(pvs['p_mp'], pmp) assert np.isclose(pvs['i_x'], ix) pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il, method='lambertw') assert np.isclose(pvs_ixx, ixx) return isc, voc, imp, vmp, pmp, i, v, pvs
def test_singlediode(): cecmodule = sam_data['cecmod'].Example_Module IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(S=irrad_data.GHI, temp_cell=25, alpha_isc=cecmodule['Alpha_sc'], module_parameters=cecmodule, EgRef=1.121, dEgdT=-0.0002677) pvsystem.singlediode(module=cecmodule, IL=IL, I0=I0, Rs=Rs, Rsh=Rsh, nNsVth=nNsVth)
def test_singlediode_series(): cecmodule = sam_data['cecmod'].Example_Module IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( irrad_data['ghi'], temp_cell=25, alpha_isc=cecmodule['alpha_sc'], module_parameters=cecmodule, EgRef=1.121, dEgdT=-0.0002677) out = pvsystem.singlediode(cecmodule, IL, I0, Rs, Rsh, nNsVth) assert isinstance(out, pd.DataFrame)
def test_singlediode_series(cec_module_params): times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') poa_data = pd.Series([0, 800], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( poa_data, temp_cell=25, alpha_isc=cec_module_params['alpha_sc'], module_parameters=cec_module_params, EgRef=1.121, dEgdT=-0.0002677) out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth) assert isinstance(out, pd.DataFrame)
def test_calcparams_desoto(cec_module_params): times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') poa_data = pd.Series([0, 800], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( poa_data, temp_cell=25, alpha_isc=cec_module_params['alpha_sc'], module_parameters=cec_module_params, EgRef=1.121, dEgdT=-0.0002677) assert_series_equal(np.round(IL, 3), pd.Series([0.0, 6.036], index=times)) assert_allclose(I0, 1.943e-9) assert_allclose(Rs, 0.094) assert_series_equal(np.round(Rsh, 3), pd.Series([np.inf, 19.65], index=times)) assert_allclose(nNsVth, 0.473)
def test_calcparams_desoto(): module = 'Example_Module' module_parameters = sam_data['cecmod'][module] times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H') poa_data = pd.Series([0, 800], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( poa_data, temp_cell=25, alpha_isc=module_parameters['alpha_sc'], module_parameters=module_parameters, EgRef=1.121, dEgdT=-0.0002677) assert_series_equal(np.round(IL, 3), pd.Series([0.0, 6.036], index=times)) assert_almost_equals(I0, 1.943e-9) assert_almost_equals(Rs, 0.094) assert_series_equal(np.round(Rsh, 3), pd.Series([np.inf, 19.65], index=times)) assert_almost_equals(nNsVth, 0.473)
def prepare_data(): print('preparing single diode data from clear sky ghi...') # adjust values to change length of test data times = pd.DatetimeIndex(start='20180101', end='20190101', freq='1min', tz='America/Phoenix') location = pvlib.location.Location(32.2, -110.9, altitude=710) cs = location.get_clearsky(times) poa_data = cs['ghi'] cec_modules = pvsystem.retrieve_sam('cecmod') cec_module_params = cec_modules['Example_Module'] IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( poa_data, temp_cell=25, alpha_isc=cec_module_params['alpha_sc'], module_parameters=cec_module_params, EgRef=1.121, dEgdT=-0.0002677) return IL, I0, Rs, Rsh, nNsVth
def _add_single_diode_iv_curve(sys_df, sys_params): """Add IV curve generated by single diode model. Args: sys_df (pd.DataFrame): time-series data that must contain 'g_poa' and 'temp_air' parameters sys_params (dict): organized like so: {'mod': pvlib.pvsystem.retrieve_same(...).SYSTEM_NAME, 'n_mod': int} Returns: pd.DataFrame with new columns (voltage_array_single_diode and current_array_single_diode) """ new_df = [] if 'temp_cell' not in sys_df.keys(): sys_df = _add_cell_module_temp(sys_df, sys_params['celltemp_model']) for i in range(len(sys_df)): ser = sys_df.iloc[i] # final two args are the band gap (assumed Si) and temperature dependence of bandgap at SRC il, i0, rs, rsh, nnsvth = pvsystem.calcparams_desoto( ser['g_poa'], ser['temp_cell'], sys_params['mod']['alpha_sc'], sys_params['mod'], 1.121, -0.0002677) params = pvsystem.singlediode(il, i0, rs, rsh, nnsvth, ivcurve_pnts=250) new_df.append({ 'voltage_array_single_diode': params['v'] * sys_params['n_mod'], 'current_array_single_diode': params['i'] }) new_df = pd.DataFrame(new_df, index=sys_df.index) sys_df['voltage_array_single_diode'] = new_df['voltage_array_single_diode'] sys_df['current_array_single_diode'] = new_df['current_array_single_diode'] return sys_df.copy()
def simulate_full_curve(parameters, Geff, Tcell, ivcurve_pnts=1000): """ Use De Soto and Bishop to simulate a full IV curve with both forward and reverse bias regions. """ # adjust the reference parameters according to the operating # conditions using the De Soto model: sde_args = pvsystem.calcparams_desoto( Geff, Tcell, alpha_sc=parameters['alpha_sc'], a_ref=parameters['a_ref'], I_L_ref=parameters['I_L_ref'], I_o_ref=parameters['I_o_ref'], R_sh_ref=parameters['R_sh_ref'], R_s=parameters['R_s'], ) # sde_args has values: # (photocurrent, saturation_current, resistance_series, # resistance_shunt, nNsVth) # Use Bishop's method to calculate points on the IV curve with V ranging # from the reverse breakdown voltage to open circuit kwargs = { 'breakdown_factor': parameters['breakdown_factor'], 'breakdown_exp': parameters['breakdown_exp'], 'breakdown_voltage': parameters['breakdown_voltage'], } v_oc = singlediode.bishop88_v_from_i(0.0, *sde_args, **kwargs) # ideally would use some intelligent log-spacing to concentrate points # around the forward- and reverse-bias knees, but this is good enough: vd = np.linspace(0.99 * kwargs['breakdown_voltage'], v_oc, ivcurve_pnts) ivcurve_i, ivcurve_v, _ = singlediode.bishop88(vd, *sde_args, **kwargs) return pd.DataFrame({ 'i': ivcurve_i, 'v': ivcurve_v, })
def test_calcparams_desoto(cec_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, 25], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( effective_irradiance, temp_cell, alpha_sc=cec_module_params['alpha_sc'], a_ref=cec_module_params['a_ref'], I_L_ref=cec_module_params['I_L_ref'], I_o_ref=cec_module_params['I_o_ref'], R_sh_ref=cec_module_params['R_sh_ref'], R_s=cec_module_params['R_s'], EgRef=1.121, dEgdT=-0.0002677) assert_series_equal(np.round(IL, 3), pd.Series([0.0, 6.036], index=times)) # changed value in GH 444 for 2017-6-5 module file assert_allclose(I0, 1.94e-9) assert_allclose(Rs, 0.094) assert_series_equal(np.round(Rsh, 3), pd.Series([np.inf, 19.65], index=times)) assert_allclose(nNsVth, 0.473)
def singlediode_i_from_v( voltage, effective_irradiance, temperature_cell, resistance_shunt_ref, resistance_series_ref, diode_factor, cells_in_series, alpha_isc, photocurrent_ref, saturation_current_ref, Eg_ref=1.121, dEgdT=-0.0002677, reference_irradiance=1000, reference_temperature=25, method='newton', verbose=False, ): kB = 1.381e-23 q = 1.602e-19 iph, io, rs, rsh, nNsVth = calcparams_desoto( effective_irradiance, temperature_cell, alpha_sc=alpha_isc, a_ref=diode_factor * cells_in_series * kB / q * (273.15 + reference_temperature), I_L_ref=photocurrent_ref, I_o_ref=saturation_current_ref, R_sh_ref=resistance_shunt_ref, R_s=resistance_series_ref, EgRef=Eg_ref, dEgdT=dEgdT, ) current = _lambertw_i_from_v(rsh, rs, nNsVth, voltage, io, iph) return current
TEST_DATA = 'bishop88_numerical_precision.csv' DATA_PATH = DATA_DIR / TEST_DATA POA = 888 TCELL = 55 # module parameters from CEC module SunPower SPR-E20-327 SPR_E20_327 = { 'alpha_sc': 0.004522, 'a_ref': 2.6868, 'I_L_ref': 6.468, 'I_o_ref': 1.88e-10, 'R_s': 0.37, 'R_sh_ref': 298.13, } # apply temp/irrad desoto corrections ARGS = pvsystem.calcparams_desoto( effective_irradiance=POA, temp_cell=TCELL, EgRef=1.121, dEgdT=-0.0002677, **SPR_E20_327, ) IL, I0, RS, RSH, NNSVTH = ARGS IVCURVE_NPTS = 100 try: from sympy import symbols, exp as sy_exp except ImportError as exc: LOGGER.exception(exc) symbols = NotImplemented sy_exp = NotImplemented def generate_numerical_precision(): # pragma: no cover """ Generate expected data with infinite numerical precision using SymPy.
logging.basicConfig() LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) TEST_DATA = 'bishop88_numerical_precision.csv' TEST_PATH = os.path.dirname(os.path.abspath(__file__)) PVLIB_PATH = os.path.dirname(TEST_PATH) DATA_PATH = os.path.join(PVLIB_PATH, 'data', TEST_DATA) POA = 888 TCELL = 55 CECMOD = pvsystem.retrieve_sam('cecmod') # get module from cecmod and apply temp/irrad desoto corrections SPR_E20_327 = CECMOD.SunPower_SPR_E20_327 ARGS = pvsystem.calcparams_desoto( effective_irradiance=POA, temp_cell=TCELL, alpha_sc=SPR_E20_327.alpha_sc, a_ref=SPR_E20_327.a_ref, I_L_ref=SPR_E20_327.I_L_ref, I_o_ref=SPR_E20_327.I_o_ref, R_sh_ref=SPR_E20_327.R_sh_ref, R_s=SPR_E20_327.R_s, EgRef=1.121, dEgdT=-0.0002677 ) IL, I0, RS, RSH, NNSVTH = ARGS IVCURVE_NPTS = 100 try: from sympy import symbols, exp as sy_exp except ImportError as exc: LOGGER.exception(exc) symbols = NotImplemented sy_exp = NotImplemented def generate_numerical_precision():
def generateMatrix(module_params_stc={}, file_input_data=None, col_names=['G', 'T'], EgRef=1.121, dEgdT=-0.000126): ''' Generates the 61853-1 matrix based on IV diode modelling and the module reference parameters. Parameters ---------- file input_data: CSV file It is the data given in a csv file format having two columns 1: Irradiance and 2 temperature. Col_names : A list of strings This defines the column names as appeared in the CSV file module_params_stc : default None If None then example parameters are provided for this The module parameters at STC (standard testing conditions) a_ref : Diode modified ideality factor Calculated by n*Ns*k*T_ref/q: n diode ideality factor, Ns number of cells in series, k boltzmann constant, T_ref temperature at STC, q electron charge. IL_ref : Light (photo-)current I0_ref : Diode saturation current Rsh_ref : Shunt resistance (parallel) Rs_ref : Series resistance alpha_sc : Temperature coefficient for short circuit current (needed for translation to other conditions) V_oc_ref : open circuit voltage at STC In this module the following conditions are taken into account conditions : The G-T matrix of 61853 -1. G (irradiance),T(temperature) data taken from a csv file. Be careful of the data, they should have titled columns as 'G','T' if none is given then the following matrix is used for 22 conditions of G,T: G\T| 15 25 50 75 ------------------------- 1100 | - x x x 1000 | x x x x 800 | x x x x 600 | x x x x 400 | x x x - 200 | x x - - 100 | x x - - EgRef: float in eV The bandgap of the material at reference conditions dEgdT: float gradient of Eg with temperature Returns ------ matrixdf: A Pandas dataframe with 3 columns of irradiance, module temperature and maximum power ''' AMref = 1 k = 1.38E-23 q = 1.602E-19 if not module_params_stc: # for a 60 cell module P_ref = 230 W module_params_stc['I_L_ref'] = 8.44 module_params_stc['I_o_ref'] = 1.04E-09 module_params_stc['R_sh_ref'] = 319 module_params_stc['R_s'] = 0.367 module_params_stc['a_ref'] = 1.05 * 60 * 298.0 * k / q #n*Ns*k*T_ref/q module_params_stc['V_oc_ref'] = 36.9 module_params_stc['alpha_sc'] = 0.005 alpha_isc = module_params_stc['alpha_sc'] if file_input_data is None: print('Generating default matrix ...') G = [100, 200, 400, 600, 800, 1000, 1100] T = [15, 25, 50, 75] # 61853 -1 matrix 22 conditions conditions = [(G[0], T[0]), (G[0], T[1]), (G[1], T[0]), (G[1], T[1]), (G[2], T[0]), (G[2], T[1]), (G[2], T[2]), (G[3], T[0]), (G[3], T[1]), (G[3], T[2]), (G[3], T[3]), (G[4], T[0]), (G[4], T[1]), (G[4], T[2]), (G[4], T[3]), (G[5], T[0]), (G[5], T[1]), (G[5], T[2]), (G[5], T[3]), (G[6], T[1]), (G[6], T[2]), (G[6], T[3])] df = pd.DataFrame(conditions, columns=['G', 'T']) G = df['G'] T = df['T'] else: # write the given data frame as list of tuples print('Make sure the format is as requested...') df = pd.read_csv(file_input_data, index_col=None) G = df[col_names[0]] T = df[col_names[1]] module_params_list = pvsystem.calcparams_desoto(G, T, alpha_isc, module_params_stc, EgRef, dEgdT, AMref) module_params = { 'I_L': module_params_list[0], 'I_o': module_params_list[1], 'R_s': module_params_list[2], 'R_sh': module_params_list[3], 'nNsVth': module_params_list[4] } dfparams = pvsystem.singlediode(module_params_stc, module_params['I_L'], module_params['I_o'], module_params['R_s'], module_params['R_sh'], module_params['nNsVth']) pmax = dfparams['p_mp'] imp = dfparams['i_mp'] vmp = dfparams['v_mp'] #print(dfparams['v_mp']) matrixdf = pd.DataFrame({'G (W/m2)': G, 'T(oC)': T, 'P(W)': pmax}) print(matrixdf) return matrixdf
LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) TEST_DATA = 'bishop88_numerical_precision.csv' TEST_PATH = os.path.dirname(os.path.abspath(__file__)) PVLIB_PATH = os.path.dirname(TEST_PATH) DATA_PATH = os.path.join(PVLIB_PATH, 'data', TEST_DATA) POA = 888 TCELL = 55 CECMOD = pvsystem.retrieve_sam('cecmod') # get module from cecmod and apply temp/irrad desoto corrections SPR_E20_327 = CECMOD.SunPower_SPR_E20_327 ARGS = pvsystem.calcparams_desoto(effective_irradiance=POA, temp_cell=TCELL, alpha_sc=SPR_E20_327.alpha_sc, a_ref=SPR_E20_327.a_ref, I_L_ref=SPR_E20_327.I_L_ref, I_o_ref=SPR_E20_327.I_o_ref, R_sh_ref=SPR_E20_327.R_sh_ref, R_s=SPR_E20_327.R_s, EgRef=1.121, dEgdT=-0.0002677) IL, I0, RS, RSH, NNSVTH = ARGS IVCURVE_NPTS = 100 try: from sympy import symbols, exp as sy_exp except ImportError as exc: LOGGER.exception(exc) symbols = NotImplemented sy_exp = NotImplemented
'PTC': 200.1, 'Technology': 'Mono-c-Si', } cases = [(1000, 55), (800, 55), (600, 55), (400, 25), (400, 40), (400, 55)] conditions = pd.DataFrame(cases, columns=['Geff', 'Tcell']) # adjust the reference parameters according to the operating # conditions using the De Soto model: IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( conditions['Geff'], conditions['Tcell'], alpha_sc=parameters['alpha_sc'], a_ref=parameters['a_ref'], I_L_ref=parameters['I_L_ref'], I_o_ref=parameters['I_o_ref'], R_sh_ref=parameters['R_sh_ref'], R_s=parameters['R_s'], EgRef=1.121, dEgdT=-0.0002677) # plug the parameters into the SDE and solve for IV curves: curve_info = pvsystem.singlediode(photocurrent=IL, saturation_current=I0, resistance_series=Rs, resistance_shunt=Rsh, nNsVth=nNsVth, ivcurve_pnts=100, method='lambertw')
def test_singlediode_series_ivcurve(cec_module_params): times = pd.date_range(start='2015-06-01', periods=3, freq='6H') effective_irradiance = pd.Series([0.0, 400.0, 800.0], index=times) IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto( effective_irradiance, temp_cell=25, alpha_sc=cec_module_params['alpha_sc'], a_ref=cec_module_params['a_ref'], I_L_ref=cec_module_params['I_L_ref'], I_o_ref=cec_module_params['I_o_ref'], R_sh_ref=cec_module_params['R_sh_ref'], R_s=cec_module_params['R_s'], EgRef=1.121, dEgdT=-0.0002677) out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3, method='lambertw') expected = OrderedDict([ ('i_sc', array([0., 3.01054475, 6.00675648])), ('v_oc', array([0., 9.96886962, 10.29530483])), ('i_mp', array([0., 2.65191983, 5.28594672])), ('v_mp', array([0., 8.33392491, 8.4159707])), ('p_mp', array([0., 22.10090078, 44.48637274])), ('i_x', array([0., 2.88414114, 5.74622046])), ('i_xx', array([0., 2.04340914, 3.90007956])), ('v', array([[0., 0., 0.], [0., 4.98443481, 9.96886962], [0., 5.14765242, 10.29530483]])), ('i', array([[0., 0., 0.], [3.01079860e+00, 2.88414114e+00, 3.10862447e-14], [6.00726296e+00, 5.74622046e+00, 0.00000000e+00]])) ]) for k, v in out.items(): assert_allclose(v, expected[k], atol=1e-2) out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3) expected['i_mp'] = pvsystem.i_from_v(Rsh, Rs, nNsVth, out['v_mp'], I0, IL, method='lambertw') expected['v_mp'] = pvsystem.v_from_i(Rsh, Rs, nNsVth, out['i_mp'], I0, IL, method='lambertw') expected['i'] = pvsystem.i_from_v(Rsh, Rs, nNsVth, out['v'].T, I0, IL, method='lambertw').T expected['v'] = pvsystem.v_from_i(Rsh, Rs, nNsVth, out['i'].T, I0, IL, method='lambertw').T for k, v in out.items(): assert_allclose(v, expected[k], atol=1e-2)
def _add_single_diode_params(sys_df, sys_params, extracted_params=True): """Compute expected IV parameters using single-diode equation. Single-diode parameters will be added to the self.df_dict dataframes using the following columns: isc_single_diode, voc_single_diode, ipmax_single_diode, vpmax_single_diode, pmax_single_diode, ix_single_diode, ixx_single_diode The measured values will also be normalized by single-diode parameters and stored in columns with names: isc_norm_single_diode, voc_norm_single_diode, ipmax_norm_single_diode, vpmax_norm_single_diode, pmax_norm_single_diode, ix_norm_single_diode, ixx_norm_single_diode Args: sys_df (pd.DataFrame): time-series data that must contain IV curves sys_params (dict): parameters needed for single-diode calculation from PVLIB; organized as follows: {'mod': pvlib.pvsystem.retrieve_same(...).SYSTEM_NAME, 'n_mod': int} Returns: pd.DataFrame with additional columns added """ diode_params = [] if 'temp_cell' not in sys_df.keys(): sys_df = _add_cell_module_temp(sys_df, sys_params['celltemp_model']) for i in range(len(sys_df)): ser = sys_df.iloc[i] # final two args are the band gap (assumed Si) and temperature dependence of bandgap at SRC il, i0, rs, rsh, nnsvth = pvsystem.calcparams_desoto( ser['g_poa'], ser['temp_cell'], sys_params['mod']['alpha_sc'], sys_params['mod'], 1.121, -0.0002677) params = pvsystem.singlediode(il, i0, rs, rsh, nnsvth) diode_params.append({ 'isc_single_diode': params['i_sc'], 'voc_single_diode': params['v_oc'] * sys_params['n_mod'], 'ipmax_single_diode': params['i_mp'], 'vpmax_single_diode': params['v_mp'] * sys_params['n_mod'], 'pmax_single_diode': params['p_mp'] * sys_params['n_mod'], 'ix_single_diode': params['i_x'], 'ixx_single_diode': params['i_xx'] }) param_df = pd.DataFrame(diode_params, index=sys_df.index) for key in param_df: sys_df[key] = param_df[key] if extracted_params: try: sys_df['isc_norm_single_diode'] = sys_df['isc_extracted'] / sys_df[ 'isc_single_diode'] sys_df['voc_norm_single_diode'] = sys_df['voc_extracted'] / sys_df[ 'voc_single_diode'] sys_df['ipmax_norm_single_diode'] = sys_df[ 'ipmax_extracted'] / sys_df['ipmax_single_diode'] sys_df['vpmax_norm_single_diode'] = sys_df[ 'vpmax_extracted'] / sys_df['vpmax_single_diode'] sys_df['pmax_norm_single_diode'] = sys_df[ 'pmax_extracted'] / sys_df['pmax_single_diode'] sys_df['ix_norm_single_diode'] = sys_df['ix_extracted'] / sys_df[ 'ix_single_diode'] sys_df['ixx_norm_single_diode'] = sys_df['ixx_extracted'] / sys_df[ 'ixx_single_diode'] except KeyError: raise KeyError( 'Call param_extraction() if extracted_params = True.') else: sys_df['isc_norm_single_diode'] = sys_df['isc'] / sys_df[ 'isc_single_diode'] sys_df['voc_norm_single_diode'] = sys_df['voc'] / sys_df[ 'voc_single_diode'] sys_df['ipmax_norm_single_diode'] = sys_df['ipmax'] / sys_df[ 'ipmax_single_diode'] sys_df['vpmax_norm_single_diode'] = sys_df['vpmax'] / sys_df[ 'vpmax_single_diode'] sys_df['pmax_norm_single_diode'] = sys_df['pmax'] / sys_df[ 'pmax_single_diode'] # data doesn't usually contain ix, ixx try: sys_df['ix_norm_single_diode'] = sys_df['ix'] / sys_df[ 'ix_single_diode'] except KeyError: pass try: sys_df['ixx_norm_single_diode'] = sys_df['ixx'] / sys_df[ 'ixx_single_diode'] except KeyError: pass return sys_df.copy()
def singlediode_v_from_i( current, effective_irradiance, temperature_cell, resistance_shunt_ref, resistance_series_ref, diode_factor, cells_in_series, alpha_isc, photocurrent_ref, saturation_current_ref, Eg_ref=1.121, dEgdT=-0.0002677, reference_irradiance=1000, reference_temperature=25, method='newton', verbose=False, ): """ Calculate voltage at a particular point on the IV curve. Parameters ---------- current effective_irradiance temperature_cell resistance_shunt_ref resistance_series_ref diode_factor cells_in_series alpha_isc photocurrent_ref saturation_current_ref Eg_ref dEgdT reference_irradiance reference_temperature method verbose Returns ------- """ kB = 1.381e-23 q = 1.602e-19 iph, io, rs, rsh, nNsVth = calcparams_desoto( effective_irradiance, temperature_cell, alpha_sc=alpha_isc, a_ref=diode_factor * cells_in_series * kB / q * ( 273.15 + reference_temperature), I_L_ref=photocurrent_ref, I_o_ref=saturation_current_ref, R_sh_ref=resistance_shunt_ref, R_s=resistance_series_ref, EgRef=Eg_ref, dEgdT=dEgdT, ) voltage = _lambertw_v_from_i(rsh, rs, nNsVth, current, io, iph) return voltage