From ebae0aecfe27b484c4f6267017180c143589aba7 Mon Sep 17 00:00:00 2001 From: Lucas Tan Date: Wed, 2 Apr 2025 17:22:59 +0800 Subject: [PATCH] optimiser for pitch --- Utilities/Optimisation.py | 33 +++++++++++++++++++++++++++++++++ Utilities/Optimisers.py | 0 Utilities/Processes.py | 1 - Utilities/Shading.py | 7 +++---- config.yml | 2 +- main.py | 8 +++----- 6 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 Utilities/Optimisation.py delete mode 100644 Utilities/Optimisers.py diff --git a/Utilities/Optimisation.py b/Utilities/Optimisation.py new file mode 100644 index 0000000..e33742b --- /dev/null +++ b/Utilities/Optimisation.py @@ -0,0 +1,33 @@ +from Utilities.Shading import calculate_energy_production_vertical +from scipy.optimize import minimize +import logging + +logger = logging.getLogger(__name__) + + +def optimise_vertical_panel_pitch(c): + def objective(pitch): + """ + Objective function to minimize the energy production from vertical panels. + + Args: + pitch (float): The pitch of the vertical panels in degrees. + + Returns: + float: The negative of the energy production from vertical panels. + """ + c["array"]["spacing"] = pitch + logging.info(f"Optimizing with pitch: {pitch}m") + vertical_energy = calculate_energy_production_vertical(c) + total_energy_yield = vertical_energy.sum() + logger.info(f"Total energy yield for pitch {pitch}m: {total_energy_yield}kWh") + return -total_energy_yield + + # perform minimization + initial_pitch = c["array"]["spacing"] + result = minimize(objective, initial_pitch, bounds=[(0, 90)]) + optimal_pitch = result.x[0] + c["array"]["spacing"] = optimal_pitch + logger.info(f"Optimal pitch found: {optimal_pitch}m") + vetical_energy = calculate_energy_production_vertical(c) + return (optimal_pitch, vetical_energy) diff --git a/Utilities/Optimisers.py b/Utilities/Optimisers.py deleted file mode 100644 index e69de29..0000000 diff --git a/Utilities/Processes.py b/Utilities/Processes.py index e98b66c..80ce0c2 100644 --- a/Utilities/Processes.py +++ b/Utilities/Processes.py @@ -1,5 +1,4 @@ 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 58f99cd..735891a 100644 --- a/Utilities/Shading.py +++ b/Utilities/Shading.py @@ -177,9 +177,8 @@ def calculate_energy_production_vertical(c): afternoon_shaded_fraction = ( afternoon_shaded_fraction * no_of_shaded_rows / no_of_rows ) - logger.info( - f"Shaded fraction calculated for morning and afternoon solar positions." - ) + + logger.info("Shaded fraction calculated for solar positions") # calculate irradiance on plane of array poa_front = pvlib.irradiance.get_total_irradiance( @@ -264,7 +263,7 @@ def calculate_energy_production_horizontal(c): axis_tilt=axis_tilt, ) shaded_fraction = shaded_fraction * no_of_shaded_rows / no_of_rows - logger.info(f"Shaded fraction calculated for solar positions.") + logger.info(f"Shaded fraction calculated for solar positions: {shaded_fraction}") poa = pvlib.irradiance.get_total_irradiance( surface_tilt=0, diff --git a/config.yml b/config.yml index bfc11ed..479bc82 100644 --- a/config.yml +++ b/config.yml @@ -1,5 +1,5 @@ array: - system_size: 400 # in kWp + system_size: 900 # in kWp spacing: 1 # spacing between adjacent panel rows in m edge_setback: 1.8 # distance from the edge of the roof to the array roof_slope: 0 diff --git a/main.py b/main.py index ec7b992..610a860 100644 --- a/main.py +++ b/main.py @@ -3,10 +3,8 @@ import yaml import logging import numpy as np import matplotlib.pyplot as pl -from Utilities.Shading import ( - calculate_energy_production_horizontal, - calculate_energy_production_vertical, -) +from Utilities.Shading import calculate_energy_production_horizontal +from Utilities.Optimisation import optimise_vertical_panel_pitch logging.basicConfig( level=logging.INFO, @@ -30,7 +28,7 @@ logger.info("Configuration loaded successfully.") logger.debug(f"Configuration: {c}") # calculate energy production for horizontal and vertical panels -vertical_energy = calculate_energy_production_vertical(c) +optimal_pitch, vertical_energy = optimise_vertical_panel_pitch(c) logger.info("Energy production for vertical panels calculated successfully.") logger.debug(f"Vertical Energy Production: {vertical_energy.sum()}")