pythonpvlib

Axis Tilt limitations using PVLIB in Python


Going through the documentation, I was trying to determine whether my South-angled Axis Tilt should be positive or negative.

The primary documentation doesn't cover it, and the NREL publication isn't very clear (see page #2 of this document).

In the source code of tracking.single_axis, we get some additional notes:

# In [1] coordinates, axis_tilt is a rotation about the x-axis.
# For a system with array azimuth (y-axis) oriented south,
# the x-axis is oriented west, and a positive axis_tilt is a
# counterclockwise rotation, i.e, lifting the north edge of the panel.
# Thus, in [1] coordinate system, in the northern hemisphere a positive
# axis_tilt indicates a rotation toward the equator,
# whereas in the southern hemisphere rotation toward the equator is
# indicated by axis_tilt<0.  Here, the input axis_tilt is
# always positive and is a rotation toward the equator.

Updated tracking.single_axis link.

Question: Does PVLIB for Python not support an axis tilt that faces away from the equator? With the natural sloping that can occur for solar sites, you would think this could support small negative values. Am I understanding this correctly?

In Testing, we see that values are very similar (<1% from eachother) for negative and positive values (EX: -5 and 5). The Irradiance also increases for both positive and negative values. I would expect negative values - pointing further away from the sun - to reduce POA irradiance.

Example Code: A location in Madison, WI at the end of October with Axis Tilt settings between -5 and 5.

import pvlib
import pandas as pd
import plotly.express as px

# SITE DETAILS - Madison, WI
lat=43
lon=-89
tz='US/Central'
alt=100

# TRACKER DETAILS
row_spacing = 5
mod_length = 2
axis_tilt = 0  # Not used in this case
azimuth = 180
tracker_angle = 60
backtrack = False

# # FILENAME FOR POA DATA
# _filename = 'clearsky_poa.csv'

# LIST OF AXIS TILT VALUES TO USE
axis_tilt_values = [-5, -2.5, -1, 0, 1, 2.5, 5]

# Create PVLIB location object
location = pvlib.location.Location(lat, lon, tz, alt)
# Create dt index
times = pd.date_range('2023-10-30', '2023-10-31', freq='5T', tz=tz)
# Get solar position & clearsky
solar_position = location.get_solarposition(times=times)
clearsky = location.get_clearsky(times=times)

def basic_plot(df, title=""):
    fig = px.line(df, title=title)
    fig.update_layout(hovermode='x', modebar_add=['hoverclosest', 'hovercompare'])
    fig.update_traces(hovertemplate=None)
    return fig

# ## TESTING MULTIPLE AXIS TILT SETTINGS ###########
# Create Dataframe of different POAs for various axis_tilt angles
poa_list = []
for i in axis_tilt_values:
    gcr = mod_length / row_spacing
    # Create tracker mount object
    tracker_mount = pvlib.pvsystem.SingleAxisTrackerMount(i, azimuth, tracker_angle, backtrack, gcr)
    # Calc tilt data
    tilt_df = tracker_mount.get_orientation(solar_azimuth=solar_position.azimuth,
                                            solar_zenith=solar_position.apparent_zenith)
    # Create Array object
    array = pvlib.pvsystem.Array(tracker_mount)
    # Calc POA
    poa = array.get_irradiance(solar_zenith=solar_position.zenith,
                               solar_azimuth=solar_position.azimuth,
                               dni=clearsky.dni, ghi=clearsky.ghi, dhi=clearsky.dhi)
    poa_list.append(poa.poa_global.rename(f'{str(i)}'))

axis_tilt_variations = pd.concat(poa_list, axis='columns')
# axis_tilt_variations.to_csv(_filename)

fig = basic_plot(axis_tilt_variations, title='Utilizing different Axis Tilt settings')
fig.show()

UPDATE
Thanks to Kevin for the clarification. What helps me think about axis_azimuth and axis_tilt, is that: azimuth should be measured in degrees East of North, and should 'point' downhill.

So a North/South row could be 0 or 180 for a perflectly horizontal row (an axis_tilt of 0). However if there is a slope, you need to choose the degree between 0 and 360 that points downhill.

For a row that is sloped 1 degree, slightly North, I would choose 0 for axis_azimuth and 1 for axis_tilt.

For a row that is sloped 1 degree, slightly South, I would choose 180 for axis_azimuth and 1 for axis_tilt.


Solution

  • Does PVLIB for Python not support an axis tilt that faces away from the equator?

    It certainly supports axes tilted away from the equator. The pvlib convention is that axis_tilt goes from 0 to 90 and the direction of the tilt is defined by axis_azimuth. To represent an axis tilted away from the equator (in the northern hemisphere), set axis_tilt to some positive number and axis_azimuth to zero.

    By the way, you might want to be careful about what version of the documentation and code you are reading. The URLs in the question link to pages for v0.9.0 (a little old) and v0.4.3 (very old).