|
| 1 | +""" |
| 2 | +Fast simulation using the ADR efficiency model starting from PVsyst parameters |
| 3 | +============================================================================== |
| 4 | +
|
| 5 | +Would you like to increase simulation speed by a factor of 4000+? |
| 6 | +
|
| 7 | +Simulation using single-diode models can be slow because the maximum |
| 8 | +power point is usually found by an iterative search. |
| 9 | +In this example we use the PVsyst single diode model to generate |
| 10 | +a matrix of efficiency values, then determine the ADR model |
| 11 | +parameters to approximate the behavior of the PVsyst model. |
| 12 | +This way both PVsyst and ADR models can simulate the same PV module type. |
| 13 | +
|
| 14 | +To compare simulation speed, we run them using ``timeit``. |
| 15 | +
|
| 16 | +Author: Anton Driesse |
| 17 | +""" |
| 18 | + |
| 19 | +import numpy as np |
| 20 | +import matplotlib.pyplot as plt |
| 21 | + |
| 22 | +from pvlib.pvsystem import calcparams_pvsyst, max_power_point |
| 23 | +from pvlib.pvarray import fit_pvefficiency_adr, pvefficiency_adr |
| 24 | + |
| 25 | +from timeit import timeit |
| 26 | + |
| 27 | +# %% The text on this line is not displayed |
| 28 | +# |
| 29 | +# Generate a matrix of power values |
| 30 | +# |
| 31 | + |
| 32 | +pvsyst_params = {'alpha_sc': 0.0015, |
| 33 | + 'gamma_ref': 1.20585, |
| 34 | + 'mu_gamma': -9.41066e-05, |
| 35 | + 'I_L_ref': 5.9301, |
| 36 | + 'I_o_ref': 2.9691e-10, |
| 37 | + 'R_sh_ref': 1144, |
| 38 | + 'R_sh_0': 3850, |
| 39 | + 'R_s': 0.6, |
| 40 | + 'cells_in_series': 96, |
| 41 | + 'R_sh_exp': 5.5, |
| 42 | + 'EgRef': 1.12, |
| 43 | + } |
| 44 | + |
| 45 | +G_REF = 1000 |
| 46 | +T_REF = 25 |
| 47 | + |
| 48 | +params_stc = calcparams_pvsyst(G_REF, T_REF, **pvsyst_params) |
| 49 | +mpp_stc = max_power_point(*params_stc) |
| 50 | + |
| 51 | +P_REF = mpp_stc['p_mp'] |
| 52 | + |
| 53 | +g, t = np.meshgrid(np.linspace(100, 1100, 11), |
| 54 | + np.linspace(0, 75, 4)) |
| 55 | + |
| 56 | +adjusted_params = calcparams_pvsyst(g, t, **pvsyst_params) |
| 57 | +mpp = max_power_point(*adjusted_params) |
| 58 | +p_mp = mpp['p_mp'] |
| 59 | + |
| 60 | +print('irradiance') |
| 61 | +print(g[:1].round(0)) |
| 62 | + |
| 63 | +print('maximum power') |
| 64 | +print(p_mp.round(1)) |
| 65 | + |
| 66 | +# %% |
| 67 | +# |
| 68 | +# Convert power matrix to efficiency and fit the ADR model to all the points |
| 69 | +# |
| 70 | + |
| 71 | +eta_rel_pvs = (p_mp / P_REF) / (g / G_REF) |
| 72 | + |
| 73 | +adr_params = fit_pvefficiency_adr(g, t, eta_rel_pvs, dict_output=True) |
| 74 | + |
| 75 | +for k, v in adr_params.items(): |
| 76 | + print('%-5s = %8.5f' % (k, v)) |
| 77 | + |
| 78 | +# %% |
| 79 | +# |
| 80 | +# Compare the ADR model output to the PVsyst model output |
| 81 | +# |
| 82 | + |
| 83 | +eta_rel_adr = pvefficiency_adr(g, t, **adr_params) |
| 84 | +mbe = np.mean(eta_rel_adr - eta_rel_pvs) |
| 85 | +rmse = np.sqrt(np.mean(np.square(eta_rel_adr - eta_rel_pvs))) |
| 86 | + |
| 87 | +plt.figure() |
| 88 | +plt.plot(g.flat, eta_rel_pvs.flat, 'oc', ms=8) |
| 89 | +plt.plot(g.flat, eta_rel_adr.flat, '.k') |
| 90 | +plt.grid(alpha=0.5) |
| 91 | +plt.xlim(0, 1200) |
| 92 | +plt.ylim(0.7, 1.1) |
| 93 | + |
| 94 | +plt.xlabel('Irradiance [W/m²]') |
| 95 | +plt.ylabel('Relative efficiency [-]') |
| 96 | +plt.legend(['PVsyst model output', 'ADR model fit'], loc='lower right') |
| 97 | +plt.title('Differences: mean %.5f, RMS %.5f' % (mbe, rmse)) |
| 98 | +plt.show() |
| 99 | + |
| 100 | +# %% |
| 101 | +# |
| 102 | +# Generate some random irradiance and temperature data |
| 103 | +# |
| 104 | + |
| 105 | +g = np.random.uniform(0, 1200, 8760) |
| 106 | +t = np.random.uniform(20, 80, 8760) |
| 107 | + |
| 108 | + |
| 109 | +def run_adr(): |
| 110 | + eta_rel = pvefficiency_adr(g, t, **adr_params) |
| 111 | + p_adr = P_REF * eta_rel * (g / G_REF) |
| 112 | + return p_adr |
| 113 | + |
| 114 | + |
| 115 | +def run_pvsyst(): |
| 116 | + adjusted_params = calcparams_pvsyst(g, t, **pvsyst_params) |
| 117 | + mpp = max_power_point(*adjusted_params) |
| 118 | + p_pvs = mpp['p_mp'] |
| 119 | + return p_pvs |
| 120 | + |
| 121 | + |
| 122 | +elapsed_adr = timeit('run_adr()', number=1, globals=globals()) |
| 123 | +elapsed_pvs = timeit('run_pvsyst()', number=1, globals=globals()) |
| 124 | + |
| 125 | +print('Elapsed time for the PVsyst model: %9.6f s' % elapsed_pvs) |
| 126 | +print('Elapsed time for the ADR model: %9.6f s' % elapsed_adr) |
| 127 | +print('ADR acceleration ratio: %9.0f x' % (elapsed_pvs/elapsed_adr)) |
| 128 | + |
| 129 | +# %% |
| 130 | +# |
| 131 | +# That's fast, but is it accurate? |
| 132 | +# Run them again to compare the simulated power values |
| 133 | +# |
| 134 | + |
| 135 | +p_pvs = run_pvsyst() |
| 136 | +p_adr = run_adr() |
| 137 | + |
| 138 | +mbe = np.mean(p_adr - p_pvs) |
| 139 | +rmse = np.sqrt(np.mean(np.square(p_adr - p_pvs))) |
| 140 | + |
| 141 | +# sphinx_gallery_thumbnail_number = 2 |
| 142 | +plt.figure() |
| 143 | +pc = plt.scatter(p_pvs, p_adr-p_pvs, c=t, cmap='jet') |
| 144 | +plt.colorbar() |
| 145 | +pc.set_alpha(0.25) |
| 146 | +plt.ylim(-1.4, 1.4) |
| 147 | +plt.grid(alpha=0.5) |
| 148 | + |
| 149 | +plt.xlabel('Power calculated using the PVsyst model [W]') |
| 150 | +plt.ylabel('ADR model power - PVsyst model power [W]') |
| 151 | +plt.title('Differences: mean %.2f W, RMS %.2f W' % (mbe, rmse)) |
| 152 | +plt.show() |
| 153 | + |
| 154 | +# %% |
| 155 | +# |
| 156 | +# There are some small systematic differences between the original |
| 157 | +# PVsyst model output and the ADR fit. But these differences are |
| 158 | +# much smaller than the typical uncertainty in measured output |
| 159 | +# of modules of this type. The PVsyst model and the parameters |
| 160 | +# we started with are of course also only approximations of the |
| 161 | +# true module behavior. |
| 162 | +# |
| 163 | + |
| 164 | +# %% |
| 165 | +# |
| 166 | +# References |
| 167 | +# ---------- |
| 168 | +# .. [1] A. Driesse and J. S. Stein, "From IEC 61853 power measurements |
| 169 | +# to PV system simulations", Sandia Report No. SAND2020-3877, 2020. |
| 170 | +# :doi:`10.2172/1615179` |
| 171 | +# |
| 172 | +# .. [2] A. Driesse, M. Theristis and J. S. Stein, "A New Photovoltaic Module |
| 173 | +# Efficiency Model for Energy Prediction and Rating," in IEEE Journal |
| 174 | +# of Photovoltaics, vol. 11, no. 2, pp. 527-534, March 2021. |
| 175 | +# :doi:`10.1109/JPHOTOV.2020.3045677` |
| 176 | +# |
0 commit comments