wip shading modelling

This commit is contained in:
Lucas Tan 2025-04-01 17:08:04 +08:00
parent a36a8db753
commit 0a4d980f4f
3 changed files with 31 additions and 73 deletions

View File

@ -4,10 +4,6 @@ import logging
import math
from tqdm import tqdm
from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D
from ladybug_geometry.geometry3d.plane import Plane
from ladybug_geometry.geometry3d.polyface import Polyface3D
import pvlib
from Utilities.Processes import (
@ -23,6 +19,19 @@ def define_grid_layout(c):
c["array"]["system_size"], c["panel"]["peak_power"]
)
# calculate pitch
pitch = c["array"]["spacing"] + c["panel"]["dimensions"]["thickness"]
# calculate minimum pitch if we don't want panel overlap at all
min_pitch = c["panel"]["dimensions"]["length"] * math.cos(
c["array"]["tilt"] / 180 * math.pi
)
if pitch < min_pitch:
logger.warning(
f"Spacing is less than minimum pitch. Setting spacing to {min_pitch}."
)
pitch = min_pitch
logger.info(f"Pitch between panels: {pitch}m")
# get maximum number of panels based on spacing and dimensions
max__panels_per_row = np.floor(
(
@ -36,7 +45,7 @@ def define_grid_layout(c):
c["environment"]["roof"]["dimensions"]["length"]
- 2 * c["array"]["edge_setback"]
)
/ (c["array"]["spacing"] + c["panel"]["dimensions"]["thickness"])
/ pitch
)
max_no_of_panels = max__panels_per_row * max_number_of_rows
logger.info(
@ -82,50 +91,7 @@ def define_grid_layout(c):
"z": z,
}
)
return coordinates
def create_panels(coordinates, c):
panel_width = c["panel"]["dimensions"]["width"]
panel_length = c["panel"]["dimensions"]["length"]
panel_thickness = c["panel"]["dimensions"]["thickness"]
# if viewed from above, and assumming the roof is a rectangle, the
# global origin is at the bottom left corner of the roof
# For a vertical panel:
# - The vertical direction (panel height) is along the Z-axis.
y_axis = Vector3D(0, 1, 0) # points east, therefore front face is east facing
# - The horizontal direction along the panel's width.
# Here, we assume the width runs in the positive X-direction.
x_axis = Vector3D(1, 0, 0) # points north
panel_object = []
base_planes = []
for index, row in coordinates.iterrows():
# Create the bottom-left corner of the panel
panel_origin = Point3D(row["x"], row["y"], row["z"])
# Create the plane for the panel
panel_plane = Plane(o=panel_origin, n=y_axis, x=x_axis)
# Create the panel geometry
panel = Polyface3D.from_box(
width=panel_width,
depth=panel_thickness,
height=panel_length,
base_plane=panel_plane,
)
panel_object.append(panel)
base_planes.append(panel_plane)
panels = pd.DataFrame(columns=["panel", "base_plane"])
panels["panel"] = panel_object
panels["base_plane"] = base_planes
return panels
return coordinates, no_of_panels
def get_solar_data(c):
@ -152,23 +118,11 @@ def get_solar_data(c):
return solar_positions
def calculate_sun_vector(solar_zenith, solar_azimuth):
"""
Calculate the sun vector from solar zenith and azimuth angles.
Args:
solar_zenith (float): Solar zenith angle in degrees.
solar_azimuth (float): Solar azimuth angle in degrees.
Returns:
Vector3D: Sun vector as a 3D vector.
"""
# Convert angles from degrees to radians
zenith_rad = math.radians(solar_zenith)
azimuth_rad = math.radians(solar_azimuth)
# Calculate the sun vector components
x = math.sin(zenith_rad) * math.cos(azimuth_rad)
z = math.sin(zenith_rad) * math.sin(azimuth_rad)
y = math.cos(zenith_rad)
return Vector3D(x, y, z)
def calculate_shading(c, coordinates, solar_positions):
# calculate shading row by row
logger.info("Calculating shading for each row of panels")
row_coordinates = np.unique(coordinates["y"])
for row in row_coordinates:
# get number of panels in row for width of row
panels_in_row = coordinates[coordinates["y"] == row].shape[0]
row_width = panels_in_row * c["panel"]["dimensions"]["width"]

View File

@ -1,7 +1,10 @@
array:
system_size: 500 # in kWp
spacing: 1 # spacing between adjacent panel rows in m
system_size: 100 # in kWp
spacing: 1.5 # spacing between adjacent panel rows in m
edge_setback: 1.8 # distance from the edge of the roof to the array
front_face_azimuth: 90 # 90=east, 180=south, 270=west
tilt: 90
slope: 0 # degrees from horizontal (+ve means shaded row is higher than the row in front)
simulation_date_time:
start: 2025-03-30 00:00 # start date and time in ISO 8601 format

View File

@ -1,7 +1,7 @@
# %%
import yaml
import logging
from Utilities.Shading import calculate_shading_fraction
from Utilities.Shading import define_grid_layout
logging.basicConfig(
level=logging.INFO,
@ -24,6 +24,7 @@ with open(config_path, "r") as file:
logger.info("Configuration loaded successfully.")
logger.debug(f"Configuration: {c}")
calculate_shading_fraction(c)
shading = define_grid_layout(c)
logger.info("Shading calculation completed successfully.")
# %%