def test_pvsyst_recombination_loss(method, poa, temp_cell, expected, tol): """test PVSst recombination loss""" pvsyst_fs_495 = get_pvsyst_fs_495() # first evaluate PVSyst model with thin-film recombination loss current # at reference conditions x = pvsystem.calcparams_pvsyst( effective_irradiance=poa, temp_cell=temp_cell, alpha_sc=pvsyst_fs_495['alpha_sc'], gamma_ref=pvsyst_fs_495['gamma_ref'], mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'], I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'], R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'], R_s=pvsyst_fs_495['R_s'], cells_in_series=pvsyst_fs_495['cells_in_series'], EgRef=pvsyst_fs_495['EgRef'] ) il_pvsyst, io_pvsyst, rs_pvsyst, rsh_pvsyst, nnsvt_pvsyst = x voc_est_pvsyst = estimate_voc(photocurrent=il_pvsyst, saturation_current=io_pvsyst, nNsVth=nnsvt_pvsyst) vd_pvsyst = np.linspace(0, voc_est_pvsyst, 1000) pvsyst = bishop88( diode_voltage=vd_pvsyst, photocurrent=il_pvsyst, saturation_current=io_pvsyst, resistance_series=rs_pvsyst, resistance_shunt=rsh_pvsyst, nNsVth=nnsvt_pvsyst, d2mutau=pvsyst_fs_495['d2mutau'], NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series'] ) # test max power assert np.isclose(max(pvsyst[2]), expected['pmp'], *tol) # test short circuit current isc_pvsyst = np.interp(0, pvsyst[1], pvsyst[0]) assert np.isclose(isc_pvsyst, expected['isc'], *tol) # test open circuit voltage voc_pvsyst = np.interp(0, pvsyst[0][::-1], pvsyst[1][::-1]) assert np.isclose(voc_pvsyst, expected['voc'], *tol) # repeat tests as above with specialized bishop88 functions y = dict(d2mutau=pvsyst_fs_495['d2mutau'], NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series']) mpp_88 = bishop88_mpp(*x, **y, method=method) assert np.isclose(mpp_88[2], expected['pmp'], *tol) isc_88 = bishop88_i_from_v(0, *x, **y, method=method) assert np.isclose(isc_88, expected['isc'], *tol) voc_88 = bishop88_v_from_i(0, *x, **y, method=method) assert np.isclose(voc_88, expected['voc'], *tol) ioc_88 = bishop88_i_from_v(voc_88, *x, **y, method=method) assert np.isclose(ioc_88, 0.0, *tol) vsc_88 = bishop88_v_from_i(isc_88, *x, **y, method=method) assert np.isclose(vsc_88, 0.0, *tol)
def test_numerical_precision(): """ Test that there are no numerical errors due to floating point arithmetic. """ expected = pd.read_csv(DATA_PATH) vdtest = np.linspace(0, estimate_voc(IL, I0, NNSVTH), IVCURVE_NPTS) results = bishop88(vdtest, *ARGS, gradients=True) assert np.allclose(expected['i'], results[0]) assert np.allclose(expected['v'], results[1]) assert np.allclose(expected['p'], results[2]) assert np.allclose(expected['grad_i'], results[3]) assert np.allclose(expected['grad_v'], results[4]) assert np.allclose(expected['grad'], results[5]) assert np.allclose(expected['grad_p'], results[6]) assert np.allclose(expected['grad2p'], results[7])
def generate_numerical_precision(): # pragma: no cover """ Generate expected data with infinite numerical precision using SymPy. :return: dataframe of expected values """ if symbols is NotImplemented: LOGGER.critical("SymPy is required to generate expected data.") raise ImportError("could not import sympy") il, io, rs, rsh, nnsvt, vd = symbols('il, io, rs, rsh, nnsvt, vd') a = sy_exp(vd / nnsvt) b = 1.0 / rsh i = il - io * (a - 1.0) - vd * b v = vd - i * rs c = io * a / nnsvt grad_i = - c - b # di/dvd grad_v = 1.0 - grad_i * rs # dv/dvd # dp/dv = d(iv)/dv = v * di/dv + i grad = grad_i / grad_v # di/dv p = i * v grad_p = v * grad + i # dp/dv grad2i = -c / nnsvt grad2v = -grad2i * rs grad2p = ( grad_v * grad + v * (grad2i/grad_v - grad_i*grad2v/grad_v**2) + grad_i ) # generate exact values data = dict(zip((il, io, rs, rsh, nnsvt), ARGS)) vdtest = np.linspace(0, estimate_voc(IL, I0, NNSVTH), IVCURVE_NPTS) expected = [] for test in vdtest: data[vd] = test test_data = { 'i': np.float64(i.evalf(subs=data)), 'v': np.float64(v.evalf(subs=data)), 'p': np.float64(p.evalf(subs=data)), 'grad_i': np.float64(grad_i.evalf(subs=data)), 'grad_v': np.float64(grad_v.evalf(subs=data)), 'grad': np.float64(grad.evalf(subs=data)), 'grad_p': np.float64(grad_p.evalf(subs=data)), 'grad2p': np.float64(grad2p.evalf(subs=data)) } LOGGER.debug(test_data) expected.append(test_data) return pd.DataFrame(expected, index=vdtest)
def generate_numerical_precision(): """ Generate expected data with infinite numerical precision using SymPy. :return: dataframe of expected values """ if symbols is NotImplemented: LOGGER.critical("SymPy is required to generate expected data.") raise ImportError("could not import sympy") il, io, rs, rsh, nnsvt, vd = symbols('il, io, rs, rsh, nnsvt, vd') a = sy_exp(vd / nnsvt) b = 1.0 / rsh i = il - io * (a - 1.0) - vd * b v = vd - i * rs c = io * a / nnsvt grad_i = - c - b # di/dvd grad_v = 1.0 - grad_i * rs # dv/dvd # dp/dv = d(iv)/dv = v * di/dv + i grad = grad_i / grad_v # di/dv p = i * v grad_p = v * grad + i # dp/dv grad2i = -c / nnsvt grad2v = -grad2i * rs grad2p = ( grad_v * grad + v * (grad2i/grad_v - grad_i*grad2v/grad_v**2) + grad_i ) # generate exact values data = dict(zip((il, io, rs, rsh, nnsvt), ARGS)) vdtest = np.linspace(0, estimate_voc(IL, I0, NNSVTH), IVCURVE_NPTS) expected = [] for test in vdtest: data[vd] = test test_data = { 'i': np.float64(i.evalf(subs=data)), 'v': np.float64(v.evalf(subs=data)), 'p': np.float64(p.evalf(subs=data)), 'grad_i': np.float64(grad_i.evalf(subs=data)), 'grad_v': np.float64(grad_v.evalf(subs=data)), 'grad': np.float64(grad.evalf(subs=data)), 'grad_p': np.float64(grad_p.evalf(subs=data)), 'grad2p': np.float64(grad2p.evalf(subs=data)) } LOGGER.debug(test_data) expected.append(test_data) return pd.DataFrame(expected, index=vdtest)
def test_pvsyst_recombination_loss(poa, temp_cell, expected, tol): """test PVSst recombination loss""" pvsyst_fs_495 = get_pvsyst_fs_495() # first evaluate PVSyst model with thin-film recombination loss current # at reference conditions x = pvsystem.calcparams_pvsyst( effective_irradiance=poa, temp_cell=temp_cell, alpha_sc=pvsyst_fs_495['alpha_sc'], gamma_ref=pvsyst_fs_495['gamma_ref'], mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'], I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'], R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'], R_s=pvsyst_fs_495['R_s'], cells_in_series=pvsyst_fs_495['cells_in_series'], EgRef=pvsyst_fs_495['EgRef'] ) il_pvsyst, io_pvsyst, rs_pvsyst, rsh_pvsyst, nnsvt_pvsyst = x voc_est_pvsyst = estimate_voc(photocurrent=il_pvsyst, saturation_current=io_pvsyst, nNsVth=nnsvt_pvsyst) vd_pvsyst = np.linspace(0, voc_est_pvsyst, 1000) pvsyst = bishop88( diode_voltage=vd_pvsyst, photocurrent=il_pvsyst, saturation_current=io_pvsyst, resistance_series=rs_pvsyst, resistance_shunt=rsh_pvsyst, nNsVth=nnsvt_pvsyst, d2mutau=pvsyst_fs_495['d2mutau'], NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series'] ) # test max power assert np.isclose(max(pvsyst[2]), expected['pmp'], *tol) # test short circuit current isc_pvsyst = np.interp(0, pvsyst[1], pvsyst[0]) assert np.isclose(isc_pvsyst, expected['isc'], *tol) # test open circuit current voc_pvsyst = np.interp(0, pvsyst[0][::-1], pvsyst[1][::-1]) assert np.isclose(voc_pvsyst, expected['voc'], *tol)
def test_pvsyst_recombination_loss(pvsyst_fs_495, poa, temp_cell, expected, tol): """test PVSst recombination loss""" # first evaluate PVSyst model with thin-film recombination loss current # at reference conditions x = pvsystem.calcparams_pvsyst( effective_irradiance=poa, temp_cell=temp_cell, alpha_sc=pvsyst_fs_495['alpha_sc'], gamma_ref=pvsyst_fs_495['gamma_ref'], mu_gamma=pvsyst_fs_495['mu_gamma'], I_L_ref=pvsyst_fs_495['I_L_ref'], I_o_ref=pvsyst_fs_495['I_o_ref'], R_sh_ref=pvsyst_fs_495['R_sh_ref'], R_sh_0=pvsyst_fs_495['R_sh_0'], R_sh_exp=pvsyst_fs_495['R_sh_exp'], R_s=pvsyst_fs_495['R_s'], cells_in_series=pvsyst_fs_495['cells_in_series'], EgRef=pvsyst_fs_495['EgRef'] ) il_pvsyst, io_pvsyst, rs_pvsyst, rsh_pvsyst, nnsvt_pvsyst = x voc_est_pvsyst = estimate_voc(photocurrent=il_pvsyst, saturation_current=io_pvsyst, nNsVth=nnsvt_pvsyst) vd_pvsyst = np.linspace(0, voc_est_pvsyst, 1000) pvsyst = bishop88( diode_voltage=vd_pvsyst, photocurrent=il_pvsyst, saturation_current=io_pvsyst, resistance_series=rs_pvsyst, resistance_shunt=rsh_pvsyst, nNsVth=nnsvt_pvsyst, d2mutau=pvsyst_fs_495['d2mutau'], NsVbi=VOLTAGE_BUILTIN*pvsyst_fs_495['cells_in_series'] ) # test max power assert np.isclose(max(pvsyst[2]), expected['pmp'], *tol) # test short circuit current isc_pvsyst = np.interp(0, pvsyst[1], pvsyst[0]) assert np.isclose(isc_pvsyst, expected['isc'], *tol) # test open circuit current voc_pvsyst = np.interp(0, pvsyst[0][::-1], pvsyst[1][::-1]) assert np.isclose(voc_pvsyst, expected['voc'], *tol)