wip shading modelling
This commit is contained in:
parent
a36a8db753
commit
0a4d980f4f
@ -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"]
|
||||
|
@ -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
|
||||
|
5
main.py
5
main.py
@ -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.")
|
||||
|
||||
# %%
|
||||
|
Loading…
x
Reference in New Issue
Block a user