use pvfactors for bifacial modelling
This commit is contained in:
		
							parent
							
								
									cc7a1eb993
								
							
						
					
					
						commit
						e9d426e6ec
					
				| @ -27,7 +27,11 @@ def optimise_vertical_panel_pitch(c): | ||||
|     # perform minimization | ||||
|     initial_pitch = c["array"]["spacing"] | ||||
|     result = minimize( | ||||
|         objective, initial_pitch, bounds=[(0, 20)], tol=1e-8, options={"eps": 1} | ||||
|         objective, | ||||
|         initial_pitch, | ||||
|         bounds=[(c["panel"]["dimensions"]["length"], 20)], | ||||
|         tol=1e-8, | ||||
|         options={"eps": 1}, | ||||
|     ) | ||||
|     optimal_pitch = result.x[0] | ||||
|     c["array"]["spacing"] = optimal_pitch | ||||
|  | ||||
| @ -2,6 +2,7 @@ import numpy as np | ||||
| import pandas as pd | ||||
| import logging | ||||
| import math | ||||
| import matplotlib.pyplot as pl | ||||
| 
 | ||||
| import pvlib | ||||
| from pvlib.bifacial.pvfactors import pvfactors_timeseries | ||||
| @ -154,22 +155,15 @@ def calculate_energy_production_vertical(c): | ||||
|     shading_row_rotation = 90 | ||||
|     surface_azimuth = 90  # east facing | ||||
|     axis_tilt = 0 | ||||
|     axis_azimuth = 0 | ||||
|     axis_azimuth = 180 | ||||
| 
 | ||||
|     ground_coverage = ( | ||||
|         no_of_panels | ||||
|         * c["panel"]["dimensions"]["width"] | ||||
|         * c["panel"]["dimensions"]["thickness"] | ||||
|     ) | ||||
|     land_area = ( | ||||
|         c["environment"]["roof"]["dimensions"]["width"] | ||||
|         * c["environment"]["roof"]["dimensions"]["length"] | ||||
|     ) | ||||
|     gcr = ground_coverage / land_area | ||||
|     gcr = np.divide(c["panel"]["dimensions"]["length"], pitch) | ||||
|     gcr = min(1, gcr) | ||||
|     logger.info(f"Ground coverage ratio: {gcr}") | ||||
| 
 | ||||
|     # use pvfactors bifacial modelling package | ||||
|     for row in range(no_of_rows): | ||||
|     POA_data = pd.Series(dtype=object) | ||||
|     for row in range(0, 3): | ||||
|         result = pvfactors_timeseries( | ||||
|             solar_zenith=solar_positions["apparent_zenith"], | ||||
|             solar_azimuth=solar_positions["azimuth"], | ||||
| @ -183,55 +177,39 @@ def calculate_energy_production_vertical(c): | ||||
|             pvrow_height=c["panel"]["dimensions"]["length"], | ||||
|             pvrow_width=c["panel"]["dimensions"]["width"] * no_of_panels_in_row, | ||||
|             albedo=0.2, | ||||
|             n_pvrows=no_of_rows, | ||||
|             n_pvrows=3, | ||||
|             index_observed_pvrow=row, | ||||
|         ) | ||||
|         # set negative values to 0 | ||||
|         poa_front = result[2].clip(lower=0) | ||||
|         poa_rear = result[3].clip(lower=0) | ||||
|         poa_global = poa_front + poa_rear * c["panel"]["bifaciality"] | ||||
|         POA_data.at[row] = poa_global | ||||
| 
 | ||||
|     # calculate irradiance on plane of array | ||||
|     poa_front = pvlib.irradiance.get_total_irradiance( | ||||
|         surface_tilt=90, | ||||
|         surface_azimuth=90, | ||||
|         solar_zenith=morning_projected_solar_zenith, | ||||
|         solar_azimuth=solar_positions["azimuth"], | ||||
|         dni=clearsky_data["dni"], | ||||
|         ghi=clearsky_data["ghi"], | ||||
|         dhi=clearsky_data["dhi"], | ||||
|         surface_type="urban", | ||||
|     ) | ||||
|     # drop rows with poa_global NaN values | ||||
|     poa_front = poa_front.dropna(subset=["poa_global"]) | ||||
| 
 | ||||
|     poa_rear = pvlib.irradiance.get_total_irradiance( | ||||
|         surface_tilt=180 - 90, | ||||
|         surface_azimuth=90 + 180, | ||||
|         solar_zenith=afternoon_projected_solar_zenith, | ||||
|         solar_azimuth=solar_positions["azimuth"], | ||||
|         dni=clearsky_data["dni"], | ||||
|         ghi=clearsky_data["ghi"], | ||||
|         dhi=clearsky_data["dhi"], | ||||
|         surface_type="urban", | ||||
|     ) | ||||
|     # drop rows with poa_global NaN values | ||||
|     poa_rear = poa_rear.dropna(subset=["poa_global"]) | ||||
| 
 | ||||
|     effective_front = poa_front["poa_global"] * (1 - morning_shaded_fraction) | ||||
|     effective_rear = ( | ||||
|         poa_rear["poa_global"] | ||||
|         * (1 - afternoon_shaded_fraction) | ||||
|         * c["panel"]["bifaciality"] | ||||
|     ) | ||||
| 
 | ||||
|     total_hourly_irradiance = effective_front + effective_rear | ||||
|     system_size = c["panel"]["peak_power"] * no_of_panels | ||||
|     pdc0 = system_size | ||||
|     total_hourly_irradiance = POA_data.at[0] + POA_data.at[2] + (POA_data.at[1] * 20) | ||||
|     gamma_pdc = c["panel"]["temperature_coefficient"] | ||||
|     temp_cell = c["panel"]["nominal_operating_cell_temperature"] | ||||
|     pdc = pvlib.pvsystem.pvwatts_dc( | ||||
|         pdc0=pdc0, | ||||
|     p_row = no_of_panels_in_row * c["panel"]["peak_power"] | ||||
|     p_middle_rows = (no_of_panels - 2 * no_of_panels_in_row) * c["panel"]["peak_power"] | ||||
|     pdc_first_row = pvlib.pvsystem.pvwatts_dc( | ||||
|         pdc0=p_row, | ||||
|         gamma_pdc=gamma_pdc, | ||||
|         temp_cell=temp_cell, | ||||
|         g_poa_effective=total_hourly_irradiance, | ||||
|         g_poa_effective=POA_data.at[0], | ||||
|     ) | ||||
|     pdc_last_row = pvlib.pvsystem.pvwatts_dc( | ||||
|         pdc0=p_row, | ||||
|         gamma_pdc=gamma_pdc, | ||||
|         temp_cell=temp_cell, | ||||
|         g_poa_effective=POA_data.at[2], | ||||
|     ) | ||||
|     pdc_middle_rows = pvlib.pvsystem.pvwatts_dc( | ||||
|         pdc0=p_middle_rows, | ||||
|         gamma_pdc=gamma_pdc, | ||||
|         temp_cell=temp_cell, | ||||
|         g_poa_effective=POA_data.at[1], | ||||
|     ) | ||||
|     pdc = pdc_first_row + pdc_last_row + pdc_middle_rows | ||||
| 
 | ||||
|     total_hourly_energy = pdc * 15 / 60 / 1e3  # convert to kWh | ||||
| 
 | ||||
| @ -259,7 +237,7 @@ def calculate_energy_production_horizontal(c): | ||||
|     shaded_row_rotation = 0 | ||||
|     shading_row_rotation = 0 | ||||
|     axis_tilt = 0 | ||||
|     axis_azimuth = 90  # south facing | ||||
|     axis_azimuth = 270  # south facing surface | ||||
| 
 | ||||
|     projected_solar_zenith = pvlib.shading.projected_solar_zenith_angle( | ||||
|         solar_zenith=solar_positions["apparent_zenith"], | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user