Singleaxis with different solar position algorithm

139 views
Skip to first unread message

Nadine Figueiredo

unread,
Sep 7, 2023, 10:29:45 AM9/7/23
to pvlib-python
Hello all,

I am very inexperienced to pvlib and currently working on a project where I have to simulate a pv system with singleaxis tracker, however I would like to perform the analysis considering another algortithm, different from SPA-NREL, which are the 5 solar position methods proposed by Grena. 

According to an article proposed by the author, the codes are available in C++, then for the period that I want to evaluate (feb-2021 to dec-2021) I obtained the hourly angles for azimuth and zenith, as example for GRENA1 attached.

With this CSV file, I wrote the code below. First I read the csv file, then I include the angles in the function tracking.singleaxis to obtain orientation. I am not having any errors, however I am not getting any valid results. 

With this  I am trying to simulate a single axis system with 24 modules and 1 inverter as indicated. Is there anyone who might have a look in the code and help me identify what I am doing wrong?

Thank you all,
-----------------------------------------------
import pvlib
import pandas as pd
from pvlib import location
from pvlib import tracking
from pvlib.bifacial.pvfactors import pvfactors_timeseries
from pvlib import temperature
from pvlib import pvsystem
import matplotlib.pyplot as plt
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
import warnings



# define location
lat, lon = -21.995585, -46.784271
tz = 'America/Sao_Paulo'
site_location = location.Location(lat, lon, tz=tz, name='São J')
altitude = 767

tmy = pd.read_csv("pvlib_soufer_fevtodez.csv", index_col=0)
tmy.index = pd.to_datetime(tmy.index)

# define temp models
temperature_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']

# read calculated angles and orientation in accordance with Grena position
angulos = pd.read_csv('C:/Users/nadine.figueiredo/.spyder-py3/angulosgren1.csv')

gcr = 0.35
max_phi = 60

orientation = tracking.singleaxis(angulos['apparent_zenith'],
                                  angulos['apparent_azimuth'],
                                  max_angle=max_phi,
                                  backtrack=False,
                                  gcr=gcr
                                  )

#procedural modeling - POA

pressure=pvlib.atmosphere.alt2pres(altitude)
dni_extra = pvlib.irradiance.get_extra_radiation(tmy.index)
airmass = pvlib.atmosphere.get_relative_airmass(angulos['apparent_zenith'])
am_abs = pvlib.atmosphere.get_absolute_airmass(airmass, pressure)

aoi = pvlib.irradiance.aoi(
        orientation['surface_tilt'],
        orientation['surface_azimuth'],
        angulos["apparent_zenith"],
        angulos["apparent_azimuth"],
        )

total_irradiance = pvlib.irradiance.get_total_irradiance(
        orientation['surface_tilt'],
        orientation['surface_azimuth'],
        angulos['apparent_zenith'],
        angulos['apparent_azimuth'],
        tmy['dni'],
        tmy['ghi'],
        tmy['dhi'],
        dni_extra=dni_extra,
        model='haydavies')

cell_temperature = pvlib.temperature.sapm_cell(
        total_irradiance['poa_global'],
        tmy["temp_air"],
        tmy["wind_speed"],
        **temperature_parameters,)


# system
sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
cec_inverters = pvlib.pvsystem.retrieve_sam('CECInverter')

module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
inverter = cec_inverters['Fronius_USA__Fronius_Primo_3_8_1_208_240__240V_']

modules_per_string= 24

strings_per_inverter= 1

system = {'module': modules_per_string*module, 'inverter': inverter}

effective_irradiance = pvlib.pvsystem.sapm_effective_irradiance(
total_irradiance['poa_direct'],
        total_irradiance['poa_diffuse'],
        am_abs,
        aoi,
        module,)


dc = pvlib.pvsystem.sapm(effective_irradiance, cell_temperature, module)
ac = pvlib.inverter.sandia(dc['v_mp'], dc['p_mp'], inverter)
annual_energy = ac.sum()
angulosgren1.csv

kevina...@gmail.com

unread,
Sep 7, 2023, 10:40:53 AM9/7/23
to pvlib-python
Hello Nadine,

We cannot run the code ourselves since the "pvlib_soufer_fevtodez.csv" file is not included, but one thing I can see is that the code reads the solar position file in such a way that the returned dataframe does not have a datetime index.  The indexes of all the time series variables must match up for the simulation to proceed correctly, i.e. the solar position dataframe must have the same index as the TMY dataframe.  If you inspect the intermediate calculation results, for example the aoi variable, you might see the effect of the index mismatch.

To fix this problem, do something similar to what you did for reading the TMY file (index_col=0, pd.to_datetime etc).  You may also have to set the timezone for the solar position index.

Kevin

Nadine Figueiredo

unread,
Sep 10, 2023, 1:49:39 PM9/10/23
to pvlib-python
Hi Kevin,

Thank you very much for your feedback. I applied this change to the solar position file to fix this problem, and the problem was solved. 

I am using this tutorial as example to obtain the plane of array (POA), as other parameters to estimate the energy generation: https://pvlib-python.readthedocs.io/en/stable/user_guide/introtutorial.html

However, it seems that its just for one pv module with a micro inverter. In my simulation, I want to perform the analysis considering 24 modules and 1 inverter (models indicated below). 

My doubt now is what is the best way to include them in the system? 


# system
sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
cec_inverters = pvlib.pvsystem.retrieve_sam('CECInverter')

module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
inverter = cec_inverters['Fronius_USA__Fronius_Primo_3_8_1_208_240__240V_']

modules_per_string= 24

strings_per_inverter= 1

system = {'module': module, 'inverter': inverter}


effective_irradiance = pvlib.pvsystem.sapm_effective_irradiance(
total_irradiance['poa_direct'],
        total_irradiance['poa_diffuse'],
        am_abs,
        aoi,
        module,)


dc = pvlib.pvsystem.sapm(effective_irradiance, cell_temperature, module)
ac = pvlib.inverter.sandia(dc['v_mp'], dc['p_mp'], inverter)
annual_energy = ac.sum()

kevina...@gmail.com

unread,
Sep 10, 2023, 6:54:57 PM9/10/23
to pvlib-python
You can use this function to scale the "dc" dataframe according to the number of modules in parallel and series: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.scale_voltage_current_power.html

An alternative approach that doesn't require you to do this "book keeping" yourself is to use PVSystem as described on this page: https://pvlib-python.readthedocs.io/en/stable/user_guide/pvsystem.html

Both approaches are valid; it's just up to your preference.

Kevin
Reply all
Reply to author
Forward
0 new messages