Пример #1
0
def test_slope_aware_backtracking():
    """
    Test validation data set from https://www.nrel.gov/docs/fy20osti/76626.pdf
    """
    index = pd.date_range('2019-01-01T08:00', '2019-01-01T17:00', freq='h')
    index = index.tz_localize('Etc/GMT+5')
    expected_data = pd.DataFrame(index=index,
                                 data=[
                                     (2.404287, 122.79177, -84.440, -10.899),
                                     (11.263058, 133.288729, -72.604, -25.747),
                                     (18.733558, 145.285552, -59.861, -59.861),
                                     (24.109076, 158.939435, -45.578, -45.578),
                                     (26.810735, 173.931802, -28.764, -28.764),
                                     (26.482495, 189.371536, -8.475, -8.475),
                                     (23.170447, 204.13681, 15.120, 15.120),
                                     (17.296785, 217.446538, 39.562, 39.562),
                                     (9.461862, 229.102218, 61.587, 32.339),
                                     (0.524817, 239.330401, 79.530, 5.490),
                                 ],
                                 columns=[
                                     'ApparentElevation', 'SolarAzimuth',
                                     'TrueTracking', 'Backtracking'
                                 ])
    expected_axis_tilt = 9.666
    expected_slope_angle = -2.576
    slope_azimuth, slope_tilt = 180.0, 10.0
    axis_azimuth = 195.0
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth, slope_tilt,
                                        axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt, rtol=1e-3, atol=1e-3)
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt,
                      expected_slope_angle,
                      rtol=1e-3,
                      atol=1e-3)
    sat = tracking.singleaxis(90.0 - expected_data['ApparentElevation'],
                              expected_data['SolarAzimuth'],
                              axis_tilt,
                              axis_azimuth,
                              max_angle=90.0,
                              backtrack=True,
                              gcr=0.5,
                              cross_axis_tilt=cross_axis_tilt)
    assert_series_equal(sat['tracker_theta'],
                        expected_data['Backtracking'].rename('tracker_theta'),
                        check_less_precise=True)
    truetracking = tracking.singleaxis(90.0 -
                                       expected_data['ApparentElevation'],
                                       expected_data['SolarAzimuth'],
                                       axis_tilt,
                                       axis_azimuth,
                                       max_angle=90.0,
                                       backtrack=False,
                                       gcr=0.5,
                                       cross_axis_tilt=cross_axis_tilt)
    assert_series_equal(truetracking['tracker_theta'],
                        expected_data['TrueTracking'].rename('tracker_theta'),
                        check_less_precise=True)
Пример #2
0
def test_slope_aware_backtracking():
    """
    Test validation data set from https://www.nrel.gov/docs/fy20osti/76626.pdf
    """
    expected_data = np.array(
        [('2019-01-01T08:00-0500', 2.404287, 122.79177, -84.440, -10.899),
         ('2019-01-01T09:00-0500', 11.263058, 133.288729, -72.604, -25.747),
         ('2019-01-01T10:00-0500', 18.733558, 145.285552, -59.861, -59.861),
         ('2019-01-01T11:00-0500', 24.109076, 158.939435, -45.578, -45.578),
         ('2019-01-01T12:00-0500', 26.810735, 173.931802, -28.764, -28.764),
         ('2019-01-01T13:00-0500', 26.482495, 189.371536, -8.475, -8.475),
         ('2019-01-01T14:00-0500', 23.170447, 204.13681, 15.120, 15.120),
         ('2019-01-01T15:00-0500', 17.296785, 217.446538, 39.562, 39.562),
         ('2019-01-01T16:00-0500', 9.461862, 229.102218, 61.587, 32.339),
         ('2019-01-01T17:00-0500', 0.524817, 239.330401, 79.530, 5.490)],
        dtype=[('Time', '<M8[h]'), ('ApparentElevation', '<f8'),
               ('SolarAzimuth', '<f8'), ('TrueTracking', '<f8'),
               ('Backtracking', '<f8')])
    expected_axis_tilt = 9.666
    expected_slope_angle = -2.576
    slope_azimuth, slope_tilt = 180.0, 10.0
    axis_azimuth = 195.0
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth, slope_tilt,
                                        axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt, rtol=1e-3, atol=1e-3)
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt,
                      expected_slope_angle,
                      rtol=1e-3,
                      atol=1e-3)
    sat = tracking.singleaxis(90.0 - expected_data['ApparentElevation'],
                              expected_data['SolarAzimuth'],
                              axis_tilt,
                              axis_azimuth,
                              max_angle=90.0,
                              backtrack=True,
                              gcr=0.5,
                              cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(sat['tracker_theta'],
                               expected_data['Backtracking'],
                               rtol=1e-3,
                               atol=1e-3)
    truetracking = tracking.singleaxis(90.0 -
                                       expected_data['ApparentElevation'],
                                       expected_data['SolarAzimuth'],
                                       axis_tilt,
                                       axis_azimuth,
                                       max_angle=90.0,
                                       backtrack=False,
                                       gcr=0.5,
                                       cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(truetracking['tracker_theta'],
                               expected_data['TrueTracking'],
                               rtol=1e-3,
                               atol=1e-3)
Пример #3
0
def test_calc_axis_tilt():
    # expected values
    expected_axis_tilt = 2.239  # [degrees]
    expected_side_slope = 9.86649274360294  # [degrees]
    expected = DATA_DIR / 'singleaxis_tracker_wslope.csv'
    expected = pd.read_csv(expected, index_col='timestamp', parse_dates=True)
    # solar positions
    starttime = '2017-01-01T00:30:00-0300'
    stoptime = '2017-12-31T23:59:59-0300'
    lat, lon = -27.597300, -48.549610
    times = pd.DatetimeIndex(pd.date_range(starttime, stoptime, freq='H'))
    solpos = pvlib.solarposition.get_solarposition(times, lat, lon)
    # singleaxis tracker w/slope data
    slope_azimuth, slope_tilt = 77.34, 10.1149
    axis_azimuth = 0.0
    max_angle = 75.0
    # Note: GCR is relative to horizontal distance between rows
    gcr = 0.33292759  # GCR = length / horizontal_pitch = 1.64 / 5 / cos(9.86)
    # calculate tracker axis zenith
    axis_tilt = tracking.calc_axis_tilt(slope_azimuth,
                                        slope_tilt,
                                        axis_azimuth=axis_azimuth)
    assert np.isclose(axis_tilt, expected_axis_tilt)
    # calculate cross-axis tilt and relative rotation
    cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                    axis_azimuth, axis_tilt)
    assert np.isclose(cross_axis_tilt, expected_side_slope)
    sat = tracking.singleaxis(solpos.apparent_zenith,
                              solpos.azimuth,
                              axis_tilt,
                              axis_azimuth,
                              max_angle,
                              backtrack=True,
                              gcr=gcr,
                              cross_axis_tilt=cross_axis_tilt)
    np.testing.assert_allclose(sat['tracker_theta'],
                               expected['tracker_theta'],
                               atol=1e-7)
    np.testing.assert_allclose(sat['aoi'], expected['aoi'], atol=1e-7)
    np.testing.assert_allclose(sat['surface_azimuth'],
                               expected['surface_azimuth'],
                               atol=1e-7)
    np.testing.assert_allclose(sat['surface_tilt'],
                               expected['surface_tilt'],
                               atol=1e-7)
# isn't purely parallel or perpendicular to the axes, the axis tilt and
# cross-axis tilt angles are not immediately obvious. We can use pvlib
# to calculate them for us:

# terrain slopes 10 degrees downward to the south-south-east. note: because
# slope_azimuth is defined in the direction of falling slope, slope_tilt is
# always positive.
slope_azimuth = 155
slope_tilt = 10
axis_azimuth = 180  # tracker axis is still N-S

# calculate the tracker axis tilt, assuming that the axis follows the terrain:
axis_tilt = tracking.calc_axis_tilt(slope_azimuth, slope_tilt, axis_azimuth)

# calculate the cross-axis tilt:
cross_axis_tilt = tracking.calc_cross_axis_tilt(slope_azimuth, slope_tilt,
                                                axis_azimuth, axis_tilt)

print('Axis tilt:', '{:0.01f}°'.format(axis_tilt))
print('Cross-axis tilt:', '{:0.01f}°'.format(cross_axis_tilt))

# %%
# And now we can pass use these values to generate the tracker curve as
# before:

tracker_data = tracking.singleaxis(
    apparent_zenith=solpos['apparent_zenith'],
    apparent_azimuth=solpos['azimuth'],
    axis_tilt=axis_tilt,  # no longer flat because the terrain imparts a tilt
    axis_azimuth=axis_azimuth,
    max_angle=90,
    backtrack=True,