sanity checking shading results

This commit is contained in:
Lucas Tan 2025-04-03 19:47:16 +08:00
parent 05186bd77f
commit 2f8f0ab9e9
6 changed files with 40 additions and 16 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
Solar Calculations
Solar Zenith: Angle between the position of the sun and vertical
Solar Azimuth: Horizontal angle with respect to north of the Sun's position
Shadow Length Formula: Height of object / tan(solar_zenith)

View File

@ -16,6 +16,7 @@ def optimise_vertical_panel_pitch(c):
Returns:
float: The negative of the energy production from vertical panels.
"""
pitch += c["panel"]["dimensions"]["thickness"]
c["array"]["spacing"] = pitch
logging.info(f"Optimizing with pitch: {pitch}m")
vertical_energy, _ = calculate_energy_production_vertical(c)

View File

@ -16,3 +16,13 @@ def calculate_no_of_panels(system_size, panel_peak_power):
no_of_panels = np.ceil(system_size / panel_peak_power_kWp)
return no_of_panels
def calculate_required_system_size(c):
c["array"]["system_size"] = (
c["array"]["peak_power_demand"]
* c["array"]["DC_AC_ratio"]
* c["array"]["performance_ratio"]
)
return c

View File

@ -5,9 +5,7 @@ import math
import pvlib
from Utilities.Processes import (
calculate_no_of_panels,
)
from Utilities.Processes import calculate_no_of_panels, calculate_required_system_size
logger = logging.getLogger(__name__)
@ -23,7 +21,6 @@ def get_location(c):
def define_grid_layout(c, panel_tilt):
# get number of panels required
no_of_panels = calculate_no_of_panels(
c["array"]["system_size"], c["panel"]["peak_power"]
)
@ -52,7 +49,7 @@ def define_grid_layout(c, panel_tilt):
max_number_of_rows = np.floor(
(
c["environment"]["roof"]["dimensions"]["length"]
- (2 * c["array"]["edge_setback"] + c["panel"]["dimensions"]["length"])
- (2 * c["array"]["edge_setback"])
)
/ pitch
)
@ -129,6 +126,7 @@ def get_solar_data(c):
def calculate_energy_production_vertical(c):
c = calculate_required_system_size(c)
panel_coordinates, no_of_panels = define_grid_layout(c, panel_tilt=90)
solar_positions, clearsky_data = get_solar_data(c)
@ -230,6 +228,9 @@ def calculate_energy_production_vertical(c):
def calculate_energy_production_horizontal(c):
c["array"]["system_size"] = (
c["array"]["system_size"] * c["array"]["horizontal_max_capacity"]
)
panel_coordinates, no_of_panels = define_grid_layout(c, panel_tilt=0)
solar_positions, clearsky_data = get_solar_data(c)

View File

@ -1,9 +1,12 @@
array:
system_size: 900 # in kWp
spacing: 21.8 # spacing between adjacent panel rows in m
peak_power_demand: 900 # in kWac
DC_AC_ratio: 1.2 # ratio of DC to AC power
spacing: 0.4 # spacing between adjacent panel rows in m
edge_setback: 1.8 # distance from the edge of the roof to the array
roof_slope: 0
slope: 0 # degrees from horizontal (+ve means shaded row is higher than the row in front)
horizontal_max_capacity: 0.75 # scale down due to peak power demand limit of NOVA
performance_ratio: 0.9 # ratio of actual energy output to the theoretical maximum
simulation_date_time:
start: 2025-03-30 00:00 # start date and time in ISO 8601 format
@ -13,9 +16,9 @@ environment:
roof:
dimensions:
# dimensions all in m
length: 100
width: 125
albedo: 0.8 # % of light reflected from the surface
length: 50
width: 40
albedo: 0.2 # % of light reflected from the surface
tilt: 0 # degrees from horizontal
location:
latitude: 3.1186108758412945

15
main.py
View File

@ -36,29 +36,32 @@ optimal_pitch, vertical_energy, no_of_panels_vertical = optimise_vertical_panel_
logger.info("Energy production for vertical panels calculated successfully.")
logger.debug(f"Vertical Energy Production: {vertical_energy.sum()}")
logger.debug("Number of panels: %d", no_of_panels_vertical)
logger.debug(f"System size: {no_of_panels_vertical * c['panel']['peak_power']/1e3} kWp")
horizontal_energy, no_of_panels_horizontal = calculate_energy_production_horizontal(c)
logger.info("Energy production for horizontal panels calculated successfully.")
logger.debug(f"Horizontal Energy Production: {horizontal_energy.sum()}")
logger.debug("Number of panels: %d", no_of_panels_horizontal)
logger.debug(
f"System size: {no_of_panels_horizontal * c['panel']['peak_power']/1e3} kWp"
)
NOVA_scaledown = 0.75
horizontal_energy_scaled = horizontal_energy * NOVA_scaledown
logger.info("Energy production for horizontal panels scaled down to NOVA requirement.")
logger.info(
f"Energy production for horizontal panels: {np.round(horizontal_energy_scaled.sum(),0)} kWh"
f"Energy production for horizontal panels: {np.round(horizontal_energy.sum(),0)} kWh"
)
logger.info(f"No. of panels for horizontal orientation: {int(no_of_panels_horizontal)}")
logger.info(
f"Energy production for vertical panels: {np.round(vertical_energy.sum(),0)} kWh"
)
logger.info(f"No. of panels for vertical orientation: {int(no_of_panels_vertical)}")
# overlay horizontal and vertical energy production
pl.figure(figsize=(10, 6))
pl.plot(
horizontal_energy_scaled.index,
horizontal_energy_scaled.values,
horizontal_energy.index,
horizontal_energy.values,
label="Horizontal Panels",
)
pl.plot(vertical_energy.index, vertical_energy.values, label="Vertical Panels")