wip shading modelling
This commit is contained in:
		
							parent
							
								
									a36a8db753
								
							
						
					
					
						commit
						0a4d980f4f
					
				| @ -4,10 +4,6 @@ import logging | |||||||
| import math | import math | ||||||
| from tqdm import tqdm | 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 | import pvlib | ||||||
| 
 | 
 | ||||||
| from Utilities.Processes import ( | from Utilities.Processes import ( | ||||||
| @ -23,6 +19,19 @@ def define_grid_layout(c): | |||||||
|         c["array"]["system_size"], c["panel"]["peak_power"] |         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 |     # get maximum number of panels based on spacing and dimensions | ||||||
|     max__panels_per_row = np.floor( |     max__panels_per_row = np.floor( | ||||||
|         ( |         ( | ||||||
| @ -36,7 +45,7 @@ def define_grid_layout(c): | |||||||
|             c["environment"]["roof"]["dimensions"]["length"] |             c["environment"]["roof"]["dimensions"]["length"] | ||||||
|             - 2 * c["array"]["edge_setback"] |             - 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 |     max_no_of_panels = max__panels_per_row * max_number_of_rows | ||||||
|     logger.info( |     logger.info( | ||||||
| @ -82,50 +91,7 @@ def define_grid_layout(c): | |||||||
|             "z": z, |             "z": z, | ||||||
|         } |         } | ||||||
|     ) |     ) | ||||||
|     return coordinates |     return coordinates, no_of_panels | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 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 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_solar_data(c): | def get_solar_data(c): | ||||||
| @ -152,23 +118,11 @@ def get_solar_data(c): | |||||||
|     return solar_positions |     return solar_positions | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def calculate_sun_vector(solar_zenith, solar_azimuth): | def calculate_shading(c, coordinates, solar_positions): | ||||||
|     """ |     # calculate shading row by row | ||||||
|     Calculate the sun vector from solar zenith and azimuth angles. |     logger.info("Calculating shading for each row of panels") | ||||||
|     Args: |     row_coordinates = np.unique(coordinates["y"]) | ||||||
|         solar_zenith (float): Solar zenith angle in degrees. |     for row in row_coordinates: | ||||||
|         solar_azimuth (float): Solar azimuth angle in degrees. |         # get number of panels in row for width of row | ||||||
| 
 |         panels_in_row = coordinates[coordinates["y"] == row].shape[0] | ||||||
|     Returns: |         row_width = panels_in_row * c["panel"]["dimensions"]["width"] | ||||||
|         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) |  | ||||||
|  | |||||||
| @ -1,7 +1,10 @@ | |||||||
| array: | array: | ||||||
|   system_size: 500 # in kWp |   system_size: 100 # in kWp | ||||||
|   spacing: 1 # spacing between adjacent panel rows in m |   spacing: 1.5 # spacing between adjacent panel rows in m | ||||||
|   edge_setback: 1.8 # distance from the edge of the roof to the array |   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: | simulation_date_time: | ||||||
|   start: 2025-03-30 00:00 # start date and time in ISO 8601 format |   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 yaml | ||||||
| import logging | import logging | ||||||
| from Utilities.Shading import calculate_shading_fraction | from Utilities.Shading import define_grid_layout | ||||||
| 
 | 
 | ||||||
| logging.basicConfig( | logging.basicConfig( | ||||||
|     level=logging.INFO, |     level=logging.INFO, | ||||||
| @ -24,6 +24,7 @@ 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}") | ||||||
| 
 | 
 | ||||||
| calculate_shading_fraction(c) | shading = define_grid_layout(c) | ||||||
|  | logger.info("Shading calculation completed successfully.") | ||||||
| 
 | 
 | ||||||
| # %% | # %% | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user