wip methods for shading computation
This commit is contained in:
parent
3132d3e568
commit
ccd4afbcd6
@ -1,6 +1,7 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import logging
|
||||
import math
|
||||
|
||||
from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D
|
||||
from ladybug_geometry.geometry3d.plane import Plane
|
||||
@ -86,13 +87,16 @@ def create_panels(coordinates, c):
|
||||
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, 0, 1) # points upward
|
||||
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 east
|
||||
x_axis = Vector3D(1, 0, 0) # points north
|
||||
|
||||
panels = []
|
||||
for index, row in coordinates.iterrows():
|
||||
@ -100,7 +104,7 @@ def create_panels(coordinates, c):
|
||||
panel_origin = Point3D(row["x"], row["y"], row["z"])
|
||||
|
||||
# Create the plane for the panel
|
||||
panel_plane = Plane(origin=panel_origin, y_axis=y_axis, x_axis=x_axis)
|
||||
panel_plane = Plane(o=panel_origin, n=y_axis, x=x_axis)
|
||||
|
||||
# Create the panel geometry
|
||||
panel = Polyface3D.from_box(
|
||||
@ -137,3 +141,75 @@ def get_solar_data(c):
|
||||
solar_positions = pvlib.solarposition.get_solarposition(times, latitude, longitude)
|
||||
|
||||
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)
|
||||
y = math.sin(zenith_rad) * math.sin(azimuth_rad)
|
||||
z = math.cos(zenith_rad)
|
||||
|
||||
return Vector3D(x, y, z)
|
||||
|
||||
|
||||
def compute_array_shading(panels, sun_vector, n_samples=25):
|
||||
"""
|
||||
Given a list of panel geometries (Polyface3D) and the sun vector,
|
||||
compute the shading fraction for each panel and return the overall average shading.
|
||||
|
||||
Parameters:
|
||||
panels: List of Polyface3D objects representing the PV panels.
|
||||
sun_vector: Unit Vector3D in the direction of the sun.
|
||||
n_samples: Number of sample points per panel.
|
||||
|
||||
Returns:
|
||||
Dictionary mapping panel index to its shading fraction, and the overall average.
|
||||
"""
|
||||
shading_results = {}
|
||||
for i, panel in enumerate(panels):
|
||||
# Define obstacles as all other panels in the array
|
||||
obstacles = [pan for j, pan in enumerate(panels) if j != i]
|
||||
shading_frac = calculate_shading_fraction(
|
||||
panel, sun_vector, obstacles, n_samples=n_samples
|
||||
)
|
||||
shading_results[i] = shading_frac
|
||||
# Compute the overall average shading fraction across all panels:
|
||||
overall_avg = np.mean(list(shading_results.values()))
|
||||
return shading_results, overall_avg
|
||||
|
||||
|
||||
def calculate_shading_fraction(c):
|
||||
coordinates = define_grid_layout(c)
|
||||
panels = create_panels(coordinates, c)
|
||||
solar_positions = get_solar_data(c)
|
||||
|
||||
shading_fractions = []
|
||||
for panel in panels:
|
||||
shading_fraction = []
|
||||
for index, row in solar_positions.iterrows():
|
||||
# Get the solar position for the current time step
|
||||
# in a sphere, azimuth is the angle in the x-y plane from the north
|
||||
# and zenith is the angle from the vertical axis
|
||||
solar_zenith = row["apparent_zenith"]
|
||||
solar_azimuth = row["apparent_azimuth"]
|
||||
sun_vector = calculate_sun_vector(solar_zenith, solar_azimuth)
|
||||
|
||||
# Calculate the shading fraction using the panel and solar position
|
||||
shading_fraction.append(panel.shading_fraction(solar_zenith, solar_azimuth))
|
||||
|
||||
shading_fractions.append(shading_fraction)
|
||||
|
||||
return shading_fractions
|
||||
|
4
main.py
4
main.py
@ -1,7 +1,7 @@
|
||||
# %%
|
||||
import yaml
|
||||
import logging
|
||||
from Utilities.Shading import define_grid_layout
|
||||
from Utilities.Shading import calculate_shading_fraction
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
@ -24,6 +24,6 @@ with open(config_path, "r") as file:
|
||||
logger.info("Configuration loaded successfully.")
|
||||
logger.debug(f"Configuration: {c}")
|
||||
|
||||
coordinates = define_grid_layout(c)
|
||||
calculate_shading_fraction(c)
|
||||
|
||||
# %%
|
||||
|
Loading…
x
Reference in New Issue
Block a user