wip methods for shading computation
This commit is contained in:
		
							parent
							
								
									3132d3e568
								
							
						
					
					
						commit
						ccd4afbcd6
					
				| @ -1,6 +1,7 @@ | |||||||
| import numpy as np | import numpy as np | ||||||
| import pandas as pd | import pandas as pd | ||||||
| import logging | import logging | ||||||
|  | import math | ||||||
| 
 | 
 | ||||||
| from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D | from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D | ||||||
| from ladybug_geometry.geometry3d.plane import Plane | from ladybug_geometry.geometry3d.plane import Plane | ||||||
| @ -86,13 +87,16 @@ def create_panels(coordinates, c): | |||||||
|     panel_length = c["panel"]["dimensions"]["length"] |     panel_length = c["panel"]["dimensions"]["length"] | ||||||
|     panel_thickness = c["panel"]["dimensions"]["thickness"] |     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: |     # For a vertical panel: | ||||||
|     # - The vertical direction (panel height) is along the Z-axis. |     # - 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. |     # - The horizontal direction along the panel's width. | ||||||
|     #   Here, we assume the width runs in the positive X-direction. |     #   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 = [] |     panels = [] | ||||||
|     for index, row in coordinates.iterrows(): |     for index, row in coordinates.iterrows(): | ||||||
| @ -100,7 +104,7 @@ def create_panels(coordinates, c): | |||||||
|         panel_origin = Point3D(row["x"], row["y"], row["z"]) |         panel_origin = Point3D(row["x"], row["y"], row["z"]) | ||||||
| 
 | 
 | ||||||
|         # Create the plane for the panel |         # 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 |         # Create the panel geometry | ||||||
|         panel = Polyface3D.from_box( |         panel = Polyface3D.from_box( | ||||||
| @ -137,3 +141,75 @@ def get_solar_data(c): | |||||||
|     solar_positions = pvlib.solarposition.get_solarposition(times, latitude, longitude) |     solar_positions = pvlib.solarposition.get_solarposition(times, latitude, longitude) | ||||||
| 
 | 
 | ||||||
|     return solar_positions |     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 yaml | ||||||
| import logging | import logging | ||||||
| from Utilities.Shading import define_grid_layout | from Utilities.Shading import calculate_shading_fraction | ||||||
| 
 | 
 | ||||||
| logging.basicConfig( | logging.basicConfig( | ||||||
|     level=logging.INFO, |     level=logging.INFO, | ||||||
| @ -24,6 +24,6 @@ with open(config_path, "r") as file: | |||||||
| logger.info("Configuration loaded successfully.") | logger.info("Configuration loaded successfully.") | ||||||
| logger.debug(f"Configuration: {c}") | logger.debug(f"Configuration: {c}") | ||||||
| 
 | 
 | ||||||
| coordinates = define_grid_layout(c) | calculate_shading_fraction(c) | ||||||
| 
 | 
 | ||||||
| # %% | # %% | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user