From a36a8db75390071660faf1eaeedb5bcbed62be21 Mon Sep 17 00:00:00 2001 From: Lucas Tan Date: Tue, 1 Apr 2025 09:56:45 +0800 Subject: [PATCH] pivot modelling method to using pvlib shading_fraction1d --- Utilities/Processes.py | 1 + Utilities/Shading.py | 73 +++++++++--------------------------------- 2 files changed, 17 insertions(+), 57 deletions(-) diff --git a/Utilities/Processes.py b/Utilities/Processes.py index 80ce0c2..e98b66c 100644 --- a/Utilities/Processes.py +++ b/Utilities/Processes.py @@ -1,4 +1,5 @@ import numpy as np +from ladybug_geometry.geometry3d import Point3D, Vector3D def calculate_no_of_panels(system_size, panel_peak_power): diff --git a/Utilities/Shading.py b/Utilities/Shading.py index 656fe4b..ee82e76 100644 --- a/Utilities/Shading.py +++ b/Utilities/Shading.py @@ -2,6 +2,7 @@ import numpy as np import pandas as pd import logging import math +from tqdm import tqdm from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D from ladybug_geometry.geometry3d.plane import Plane @@ -9,7 +10,9 @@ from ladybug_geometry.geometry3d.polyface import Polyface3D import pvlib -from Utilities.Processes import calculate_no_of_panels +from Utilities.Processes import ( + calculate_no_of_panels, +) logger = logging.getLogger(__name__) @@ -98,7 +101,8 @@ def create_panels(coordinates, c): # Here, we assume the width runs in the positive X-direction. x_axis = Vector3D(1, 0, 0) # points north - panels = [] + 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"]) @@ -109,12 +113,17 @@ def create_panels(coordinates, c): # Create the panel geometry panel = Polyface3D.from_box( width=panel_width, - depth=panel_length, - height=panel_thickness, + depth=panel_thickness, + height=panel_length, base_plane=panel_plane, ) - panels.append(panel) + 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 @@ -159,57 +168,7 @@ def calculate_sun_vector(solar_zenith, 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) + z = math.sin(zenith_rad) * math.sin(azimuth_rad) + y = 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