import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from importlib import reload
import solar
reload(solar)
<module 'solar' from '/home/flo/documents/fhv/LV_programming_NES/Programmiertechniken/08_files/solar.py'>
In [1]:
In [2]:
tau | declination | h | alpha | iswr_clearsky | |
---|---|---|---|---|---|
datetime | |||||
2023-01-01 00:00:00 | -180.0 | -22.930544 | -65.518144 | NaN | 0.0 |
2023-01-01 01:00:00 | -165.0 | -22.930544 | -62.729858 | 211.348308 | 0.0 |
2023-01-01 02:00:00 | -150.0 | -22.930544 | -55.750441 | 234.906273 | 0.0 |
2023-01-01 03:00:00 | -135.0 | -22.930544 | -46.681349 | 251.665818 | 0.0 |
2023-01-01 04:00:00 | -120.0 | -22.930544 | -36.760543 | 264.601524 | 0.0 |
... | ... | ... | ... | ... | ... |
2023-12-30 20:00:00 | 120.0 | -23.085911 | -36.866391 | 95.256414 | 0.0 |
2023-12-30 21:00:00 | 135.0 | -23.085911 | -46.792577 | 108.175901 | 0.0 |
2023-12-30 22:00:00 | 150.0 | -23.085911 | -55.874482 | 124.927227 | 0.0 |
2023-12-30 23:00:00 | 165.0 | -23.085911 | -62.873366 | 148.521437 | 0.0 |
2023-12-31 00:00:00 | -180.0 | -23.011637 | -65.599237 | NaN | 0.0 |
8737 rows × 5 columns
A grid search involves systematically searching through a predefined set of parameters to find the best parameter configuration for a specific question or model.
We aim to determine how the azimuth and incline of a PV module impact its energy production. Once again, we can utilize our existing solar
module to address this question under idealized conditions and simplified assumptions.
We will perform the grid search by calling a function that does all the computations for us. In the following, I define that function and within the function body I have left you an opportunity for exercise. This task is not essential to continue with the remaining tasks. Do not get hung up here. Tip: Use the method pd.Series.diff()
and the timedelta method .dt.total_seconds()
to compute the time sampling in hours. If the time sampling is not equal between all time steps, raise an error.
In [3]:
def comp_energy_produced(iswr0, beta, pvazimuth, elevangle, azimuth, datetime = None, efficiency=0.2, area=1):
"""
Calculate the energy produced by a PV module based on solar irradiance data.
Parameters
----------
iswr0 (pandas.Series): Solar irradiance data onto horizontal surface.
beta (float): Incline angle of the PV module (in degrees).
pvazimuth (float): Azimuth angle of the PV module (in degrees, 0 in the south).
elevangle (array-like): Elevation angle of the sun (in degrees).
azimuth (array-like): Azimuth angle of the sun (in degrees, 0 in the south).
datetime (pandas.Series or None, optional): Timestamps associated with the irradiance data. If None,
the function assumes regular time intervals based on the index of 'iswr0'.
efficiency (float, optional): Efficiency of the photovoltaic system (default is 0.2).
area (float, optional): Area of the PV module (default is 1).
Returns
-------
float: Total energy produced by the photovoltaic system (in Wh).
If 'datetime' is not provided, the function assumes regular time intervals based on the index of 'iswr0'.
The function raises a ValueError if the time intervals are irregular.
"""
if datetime is None:
datetime = iswr0.index.to_series()
# Retrieve unique time sampling dt in (hours)
delta = datetime.diff()
dt = delta.dt.total_seconds()/3600
dt = dt[dt.notna()].unique()
if (len(dt) > 1):
raise ValueError("Irregular time sampling is not allowed")
# Calculate iswr onto inclined PV module
iswr_beta = solar.comp_irradiance_incline(iswr0,
solar.comp_cos_incidenceangle(elevangle, azimuth, beta, pvazimuth),
elevangle)
# Calculate generated power and energy
power = iswr_beta * area * efficiency
energy = power.sum() * dt
return energy[0]
Finally, you can perform the grid search:
In [4]:
In [14]:
In [19]:
In [26]:
f, ax = plt.subplots(figsize=(12, 5))
cf = ax.contourf(alpha_pv, beta_pv, Z, levels=30, cmap='Reds', extend='both')
cbar = f.colorbar(cf)
ax.scatter(APV[np.unravel_index(i_max, APV.shape)], BPV[np.unravel_index(i_max, APV.shape)], color='black')
cbar.set_label("Percentage of maximum (%)")
ax.set_ylabel(r"PV incline ($^\circ$)")
ax.set_xlabel(r"PV azimuth ($^\circ$): W <----> E")
ax.set_title("Annual energy production under idealized conditions in Dornbirn, 2023")
# plt.savefig("contourplot.png")
Text(0.5, 1.0, 'Annual energy production under idealized conditions in Dornbirn, 2023')