Beispiel #1
0
def test_faoi_fn_from_pvlib():
    """Check that faoi function creator produces correct results"""
    module_example = 'Canadian_Solar_CS5P_220M___2009_'
    faoi_fn = faoi_fn_from_pvlib_sandia(module_example)

    # Make sure the convention to measure angles from 0 to 180 deg works
    np.testing.assert_allclose(faoi_fn([10, 20, 50]), faoi_fn([170, 160, 130]))
    # Check some value consistency
    np.testing.assert_allclose(faoi_fn([10, 20, 50, 90]),
                               [0.597472, 0.856388, 1., 1.])
    # Check values outside of acceptable range: should be zero
    np.testing.assert_allclose(faoi_fn([-10, 190]), [0., 0.])
Beispiel #2
0
def test_rho_from_faoi_fn(pvmodule_canadian):
    """Check that can correctly calculate rho from faoi function"""
    faoi_fn = faoi_fn_from_pvlib_sandia(pvmodule_canadian)
    n_points = 300
    # use same faoi fn for front and back
    aoi_methods = AOIMethods(faoi_fn, faoi_fn, n_integral_sections=n_points)

    # Should be identical for front and back
    rho_out = aoi_methods.rho_from_faoi_fn(True)
    np.testing.assert_allclose(rho_out, 0.02900688, atol=0, rtol=1e-6)
    rho_out = aoi_methods.rho_from_faoi_fn(False)
    np.testing.assert_allclose(rho_out, 0.02900688, atol=0, rtol=1e-6)
Beispiel #3
0
def test_create_engine_with_rho_init(params, pvmodule_canadian):
    """Check that can create PV engine with rho initialization
    from faoi functions"""
    # Create inputs
    pvarray = OrderedPVArray.init_from_dict(params)
    irradiance = HybridPerezOrdered(rho_front=None, rho_back=None)
    faoi_fn = faoi_fn_from_pvlib_sandia(pvmodule_canadian)
    vfcalculator = VFCalculator(faoi_fn_front=faoi_fn, faoi_fn_back=faoi_fn)
    # Create engine
    engine = PVEngine.with_rho_initialization(pvarray, vfcalculator,
                                              irradiance)
    # Check that rho values are the ones calculated
    np.testing.assert_allclose(engine.irradiance.rho_front, 0.02900688)
    np.testing.assert_allclose(engine.irradiance.rho_back, 0.02900688)
Beispiel #4
0
def test_engine_w_faoi_fn_in_irradiance_vfcalcs(params, pvmodule_canadian):
    """Run PV engine calcs with faoi functions for AOI losses"""

    # Irradiance inputs
    timestamps = dt.datetime(2019, 6, 11, 11)
    DNI = 1000.
    DHI = 100.

    pvarray = OrderedPVArray.init_from_dict(params)
    # create faoi function
    faoi_fn = faoi_fn_from_pvlib_sandia(pvmodule_canadian)
    # create vf_calculator with faoi function
    vfcalculator = VFCalculator(faoi_fn_front=faoi_fn, faoi_fn_back=faoi_fn)
    # create irradiance model with faoi function
    irradiance_model = HybridPerezOrdered(faoi_fn_front=faoi_fn,
                                          faoi_fn_back=faoi_fn)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model,
                   vf_calculator=vfcalculator)

    # Make sure aoi methods are available
    assert eng.vf_calculator.vf_aoi_methods is not None

    # Fit engine
    eng.fit(timestamps, DNI, DHI,
            params['solar_zenith'],
            params['solar_azimuth'],
            params['surface_tilt'],
            params['surface_azimuth'],
            params['rho_ground'])

    # Run timestep
    pvarray = eng.run_full_mode(fn_build_report=lambda pvarray: pvarray)
    # Checks
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[0].front.get_param_weighted('qinc'),
        1110.1164773159298)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[1].front.get_param_weighted('qinc'), 1110.595903991)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[2].front.get_param_weighted('qinc'), 1112.37717553)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[1].back.get_param_weighted('qinc'),
        116.49050349491208)
    # Check absorbed irradiance: calculated using faoi functions
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[2].front.get_param_weighted('qabs'),
        [1109.1180884])
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[1].back.get_param_weighted('qabs'),
        [114.2143503])
Beispiel #5
0
def test_ts_aoi_methods(pvmodule_canadian):
    """Checks
    - can create aoi methods correctly
    - vf_aoi_integrand matrix makes sense and stays consistent
    - vf_aoi values stay consistent"""
    n_timestamps = 6  # using 5 timestamps
    n_points = 6  # using only 6 sections for the integral from 0 to 180 deg
    faoi_fn = faoi_fn_from_pvlib_sandia(pvmodule_canadian)
    # use same faoi fn for front and back
    aoi_methods = AOIMethods(faoi_fn, faoi_fn, n_integral_sections=n_points)
    aoi_methods.fit(n_timestamps)
    # Check that function was passed correctly
    assert callable(aoi_methods.faoi_fn_front)
    assert callable(aoi_methods.faoi_fn_back)
    assert aoi_methods.aoi_angles_low.shape == (n_timestamps, n_points)
    assert aoi_methods.aoi_angles_high.shape == (n_timestamps, n_points)
    assert aoi_methods.integrand_front.shape == (n_timestamps, n_points)
    assert aoi_methods.integrand_back.shape == (n_timestamps, n_points)

    # Create some dummy angle values
    low_angles = np.array([0., 2., 108., 72., 179., 0.])
    high_angles = np.array([31., 30., 144., 144., 180., 180.])

    # Check that integrand is calculated correctly
    faoi_integrand = aoi_methods._calculate_vfaoi_integrand(
        low_angles, high_angles)
    expected_integrand = \
        [[0.05056557, 0.18255583, 0., 0., 0., 0.],
         [0.05056557, 0., 0., 0., 0., 0.],
         [0., 0., 0., 0.25, 0.18255583, 0.],
         [0., 0., 0.25, 0.25, 0.18255583, 0.],
         [0., 0., 0., 0., 0., 0.05056557],
         [0.05056557, 0.18255583, 0.25, 0.25, 0.18255583, 0.05056557]]
    np.testing.assert_allclose(faoi_integrand, expected_integrand)

    # Check that faoi values calculated correctly
    vf_aoi = aoi_methods._calculate_vf_aoi_wedge_level(low_angles, high_angles)
    expected_vf_aoi = [
        0.2331214, 0.05056557, 0.43255583, 0.68255583, 0.05056557, 0.96624281
    ]
    np.testing.assert_allclose(vf_aoi, expected_vf_aoi)
Beispiel #6
0
 def faoi(*args, **kwargs):
     fn = faoi_fn_from_pvlib_sandia('Canadian_Solar_CS5P_220M___2009_')
     return fn(*args, **kwargs)
Beispiel #7
0
def test_run_timeseries_faoi_fn(params_serial, pvmodule_canadian,
                                df_inputs_clearsky_8760):
    """Test that in run_timeseries function, faoi functions are used
    correctly"""
    # Prepare timeseries inputs
    df_inputs = df_inputs_clearsky_8760.iloc[:24, :]
    timestamps = df_inputs.index
    dni = df_inputs.dni.values
    dhi = df_inputs.dhi.values
    solar_zenith = df_inputs.solar_zenith.values
    solar_azimuth = df_inputs.solar_azimuth.values
    surface_tilt = df_inputs.surface_tilt.values
    surface_azimuth = df_inputs.surface_azimuth.values

    expected_qinc_back = 542.018551
    expected_qinc_front = 5452.858863

    # --- Test without passing vf parameters
    # report function with test in it
    def report_fn_with_tests_no_faoi(pvarray):
        vf_aoi_matrix = pvarray.ts_vf_aoi_matrix
        pvrow = pvarray.ts_pvrows[0]
        list_back_pvrow_idx = [
            ts_surf.index for ts_surf in pvarray.ts_pvrows[0].all_ts_surfaces
        ]
        # Check that sum of vf_aoi is equal to reflectivity values
        # since no faoi_fn used
        np.testing.assert_allclose(
            vf_aoi_matrix[list_back_pvrow_idx, :, 12].sum(axis=1),
            [0.99, 0., 0.97, 0.])

        return {
            'qinc_front': pvrow.front.get_param_weighted('qinc'),
            'qabs_front': pvrow.front.get_param_weighted('qabs'),
            'qinc_back': pvrow.back.get_param_weighted('qinc'),
            'qabs_back': pvrow.back.get_param_weighted('qabs')
        }

    # create calculator
    report = run_timeseries_engine(report_fn_with_tests_no_faoi,
                                   params_serial,
                                   timestamps,
                                   dni,
                                   dhi,
                                   solar_zenith,
                                   solar_azimuth,
                                   surface_tilt,
                                   surface_azimuth,
                                   params_serial['rho_ground'],
                                   vf_calculator_params=None,
                                   irradiance_model_params=None)

    np.testing.assert_allclose(np.nansum(report['qinc_back']),
                               expected_qinc_back)
    np.testing.assert_allclose(np.nansum(report['qabs_back']), 525.757995)
    np.testing.assert_allclose(np.nansum(report['qinc_front']),
                               expected_qinc_front)
    np.testing.assert_allclose(np.nansum(report['qabs_front']), 5398.330275)

    # --- Test when passing vf parameters
    # Prepare vf calc params
    faoi_fn = faoi_fn_from_pvlib_sandia(pvmodule_canadian)
    # the following is a very high number to get agreement in
    # integral sums between back and front surfaces
    n_sections = 10000
    vf_calc_params = {
        'faoi_fn_front': faoi_fn,
        'faoi_fn_back': faoi_fn,
        'n_aoi_integral_sections': n_sections
    }
    irr_params = {'faoi_fn_front': faoi_fn, 'faoi_fn_back': faoi_fn}

    def report_fn_with_tests_w_faoi(pvarray):
        vf_aoi_matrix = pvarray.ts_vf_aoi_matrix
        pvrow = pvarray.ts_pvrows[0]

        list_back_pvrow_idx = [
            ts_surf.index for ts_surf in pvrow.all_ts_surfaces
        ]
        # Check that sum of vf_aoi is consistent
        np.testing.assert_allclose(vf_aoi_matrix[list_back_pvrow_idx, :,
                                                 12].sum(axis=1),
                                   [0.97102, 0., 0.971548, 0.],
                                   atol=0,
                                   rtol=1e-6)

        return {
            'qinc_front': pvrow.front.get_param_weighted('qinc'),
            'qabs_front': pvrow.front.get_param_weighted('qabs'),
            'qinc_back': pvrow.back.get_param_weighted('qinc'),
            'qabs_back': pvrow.back.get_param_weighted('qabs')
        }

    # create calculator
    report = run_timeseries_engine(report_fn_with_tests_w_faoi,
                                   params_serial,
                                   timestamps,
                                   dni,
                                   dhi,
                                   solar_zenith,
                                   solar_azimuth,
                                   surface_tilt,
                                   surface_azimuth,
                                   params_serial['rho_ground'],
                                   vf_calculator_params=vf_calc_params,
                                   irradiance_model_params=irr_params)

    np.testing.assert_allclose(np.nansum(report['qinc_back']),
                               expected_qinc_back)
    np.testing.assert_allclose(np.nansum(report['qabs_back']), 520.892016)
    np.testing.assert_allclose(np.nansum(report['qinc_front']),
                               expected_qinc_front)
    np.testing.assert_allclose(np.nansum(report['qabs_front']), 5347.050682)