Exemple #1
0
def test_pvengine_float_inputs_perez(params):
    """Test that PV engine works for float inputs"""

    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'],
                                   DNI)

    # Run timestep
    pvarray = eng.run_full_mode_timestep(0)
    # Checks
    assert isinstance(pvarray, OrderedPVArray)
    np.testing.assert_almost_equal(
        pvarray.pvrows[0].front.get_param_weighted('qinc'), 1110.1164773159298)
    np.testing.assert_almost_equal(
        pvarray.pvrows[1].front.get_param_weighted('qinc'), 1110.595903991)
    np.testing.assert_almost_equal(
        pvarray.pvrows[2].front.get_param_weighted('qinc'), 1112.37717553)
    np.testing.assert_almost_equal(
        pvarray.pvrows[1].back.get_param_weighted('qinc'), 116.49050349491208)
Exemple #2
0
def test_pvengine_ts_inputs_perez(params_serial, df_inputs_serial_calculation,
                                  fn_report_example):
    """Test that PV engine works for timeseries inputs"""

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs_serial_calculation)
    albedo = params_serial['rho_ground']

    # Create engine
    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params_serial, param_names=irradiance_model.params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

    # Fit engine
    eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth, surface_tilt,
            surface_azimuth, albedo)

    # Run all timesteps
    report = eng.run_full_mode(fn_build_report=fn_report_example)

    # Check values
    np.testing.assert_array_almost_equal(report['qinc_front'],
                                         [1066.272392, 1065.979824])
    np.testing.assert_array_almost_equal(report['qinc_back'],
                                         [135.897106, 136.01297])
    np.testing.assert_array_almost_equal(report['iso_front'],
                                         [42.816637, 42.780206])
    np.testing.assert_array_almost_equal(report['iso_back'],
                                         [1.727308, 1.726535])
    np.testing.assert_array_almost_equal(report['qabs_back'],
                                         report['qinc_back'] * 0.97)
Exemple #3
0
def test_fast_pvengine_float_inputs_perez(params):
    """Test that PV engine works for float inputs"""

    # Prepare some engine inputs
    irradiance_model = HybridPerezOrdered()
    fast_mode_pvrow_index = 1

    # Create engine object
    eng = PVEngine(params,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_pvrow'], DNI)

    # Run timestep
    pvarray = eng.run_timestep(0)
    # Checks
    assert isinstance(pvarray, OrderedPVArray)
    np.testing.assert_almost_equal(
        pvarray.pvrows[1].back.get_param_weighted('qinc'), 123.7087347744459)
Exemple #4
0
def test_pvengine_float_inputs_iso(params):
    """Test that PV engine works for float inputs"""

    irradiance_model = IsotropicOrdered()
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'],
                                   DNI)

    # Run timestep
    pvarray = eng.run_full_mode(fn_build_report=lambda pvarray: pvarray)
    # Checks
    assert isinstance(pvarray, OrderedPVArray)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[0].front.get_param_weighted('qinc'), 1099.22245374)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[1].front.get_param_weighted('qinc'), 1099.6948573)
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[2].front.get_param_weighted('qinc'), 1102.76149246)
    # Check absorbed
    np.testing.assert_almost_equal(
        pvarray.ts_pvrows[1].front.get_param_weighted('qabs'),
        1099.6948573 * 0.99)
Exemple #5
0
def test_fast_mode_8760(params, df_inputs_clearsky_8760):
    """Test fast mode with 1 PV row to make sure that is consistent
    after the vectorization update: should get exact same values
    """
    # Get MET data
    df_inputs = df_inputs_clearsky_8760
    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
    # Run simulation for only 1 PV row
    params.update({'n_pvrows': 1})

    # Run engine
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray)
    eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth, surface_tilt,
            surface_azimuth, params['rho_ground'])
    qinc = eng.run_fast_mode(
        fn_build_report=lambda pvarray:
        (pvarray.ts_pvrows[0].back.get_param_weighted('qinc')),
        pvrow_index=0)

    # Check than annual energy on back is consistent
    np.testing.assert_allclose(np.nansum(qinc) / 1e3, 342.848005)
Exemple #6
0
def test_fast_mode_loop_like(params):
    """Test value of older and decomissioned loop like fast mode"""

    # Prepare some engine inputs
    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params, param_names=irradiance_model.params)
    fast_mode_pvrow_index = 1

    # Create engine object
    eng = PVEngine(pvarray,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'],
                                   DNI)

    # Run timestep
    pvarray = _fast_mode_with_loop(eng.pvarray, eng.irradiance,
                                   eng.vf_calculator, fast_mode_pvrow_index, 0)
    # Checks
    assert isinstance(pvarray, OrderedPVArray)
    np.testing.assert_almost_equal(
        pvarray.pvrows[1].back.get_param_weighted('qinc'), 119.0505580124769)
Exemple #7
0
def test_vf_matrix_subset_calculation(params):
    """Check that the vf matrix subset is calculated correctly"""
    # Run in fast mode
    irradiance_model = HybridPerezOrdered()
    fast_mode_pvrow_index = 1
    eng = PVEngine(params,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index)
    timestamps = dt.datetime(2019, 6, 11, 11)
    DNI = 1000.
    DHI = 100.
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    pvarray_fast = eng.run_timestep(0)
    vf_mat_fast = pvarray_fast.vf_matrix

    # Run in full mode
    irradiance_model = HybridPerezOrdered()
    eng = PVEngine(params, irradiance_model=irradiance_model)
    timestamps = dt.datetime(2019, 6, 11, 11)
    DNI = 1000.
    DHI = 100.
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    pvarray_full = eng.run_timestep(0)
    vf_mat_full = pvarray_full.vf_matrix

    index_of_back_side_surface = 13
    np.testing.assert_array_almost_equal(
        vf_mat_fast, vf_mat_full[[index_of_back_side_surface], :])
Exemple #8
0
def test_check_direct_shading_continuity():
    """Make sure the calculation is correct when direct shading happens.
    - before v1.3.0, there's a discontinuity (big jump) in prediction
    when direct shading happens. The values are the same as >=v1.3.0 for
    no direct shading, but they are different with direct shading.
    - starting at v1.3.0, the values are more continuous (no big change) when
    going from no direct shading to direct shading, which means it's
    most certainly a better implementation.

    The issue before v1.3.0 could be due to the fact that shadows are merged,
    and there might be a piece of geometry lost there, but not entirely sure.
    Since it's still relatively small, will not dig further.

    Here, we're testing the outputs at 2 timestamps, right before and
    right after direct shading, when varying only solar zenith.
    """

    # Prepare inputs
    n = 2
    inputs = {
        'solar_zenith': [81.275, 81.276],  # right at the limit of direct shadg
        'solar_azimuth': [295.9557133] * n,
        'surface_tilt': [15.18714669] * n,
        'surface_azimuth': [270.] * n,
        'dni': [1000.] * n,
        'dhi': [100.] * n,
        'albedo': [0.2] * n,
        'times': [dt.datetime(2014, 6, 25, 3)] * n}
    # Array parameters
    params = {'n_pvrows': 3,
              'axis_azimuth': 0.0,
              'pvrow_height': 1.5,
              'pvrow_width': 2.5,
              'gcr': 0.4}

    # Create engine and fit to inputs
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray)
    eng.fit(np.array(inputs['times']),
            np.array(inputs['dni']),
            np.array(inputs['dhi']),
            np.array(inputs['solar_zenith']),
            np.array(inputs['solar_azimuth']),
            np.array(inputs['surface_tilt']),
            np.array(inputs['surface_azimuth']),
            np.array(inputs['albedo']))

    # Check there we are indeed right at the limit of direct shading
    np.testing.assert_array_equal(pvarray.has_direct_shading, [False, True])

    # Run simulation and get output
    pvarray = eng.run_full_mode(fn_build_report=lambda pvarray: pvarray)
    out = pvarray.ts_pvrows[1].back.get_param_weighted('qinc')

    # Check expected outputs: before v1.3.0, expected output is
    # [20.4971271991293, 21.389095477613356], which shows discontinuity
    expected_out = [20.497127, 20.50229]
    np.testing.assert_allclose(out, expected_out)
Exemple #9
0
def run_pvfactors_simulation(data: DataFrame,
                             pvarray_params: dict) -> OrderedPVArray:
    "Fit and run simulation"
    pvarray = OrderedPVArray.init_from_dict(pvarray_params)
    engine = PVEngine(pvarray)
    pvarray = engine.fit(data.index, data.dni, data.dhi, data.zenith,
                         data.azimuth, data.surface_tilt, data.surface_azimuth,
                         data.albedo)
    fn_build_report = lambda pvarray: pvarray
    return engine.run_full_mode(fn_build_report)
Exemple #10
0
def test_pvengine_float_inputs_perez_transparency_spacing_fast(params):
    """Test that module transparency and spacing are having the
    expected effect to calculated PV back side irradiance"""

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

    # --- with 0 transparency and spacing
    # Create models
    irr_params = {'module_transparency': 0.,
                  'module_spacing_ratio': 0.}
    irradiance_model = HybridPerezOrdered(**irr_params)
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

    # Fit engine
    eng.fit(timestamps, DNI, DHI,
            params['solar_zenith'],
            params['solar_azimuth'],
            params['surface_tilt'],
            params['surface_azimuth'],
            params['rho_ground'])
    # Run timestep
    def fn_report(pvarray): return (pvarray.ts_pvrows[1]
                                    .back.get_param_weighted('qinc'))
    no_spacing_transparency_back_qinc = \
        eng.run_fast_mode(fn_build_report=fn_report, pvrow_index=1)

    # --- with non-0 transparency and spacing
    # Create models
    irr_params = {'module_transparency': 0.1,
                  'module_spacing_ratio': 0.1}
    irradiance_model = HybridPerezOrdered(**irr_params)
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

    # Fit engine
    eng.fit(timestamps, DNI, DHI,
            params['solar_zenith'],
            params['solar_azimuth'],
            params['surface_tilt'],
            params['surface_azimuth'],
            params['rho_ground'])
    # Run timestep
    w_spacing_transparency_back_qinc = \
        eng.run_fast_mode(fn_build_report=fn_report, pvrow_index=1)
    # Checks
    expected_back_qinc = 134.7143531  # higher than when params are 0
    np.testing.assert_almost_equal(
        w_spacing_transparency_back_qinc, expected_back_qinc)
    assert no_spacing_transparency_back_qinc < w_spacing_transparency_back_qinc
Exemple #11
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])
Exemple #12
0
def test_run_fast_mode_compare_to_loop_like(params):
    """Test that PV engine works for timeseries fast mode and float inputs.

    Check the left pv row back side (no obstruction, since rotation < 0)
    This should be exactly the same calculated value as in loop-like fast mode
    because ground is not infinite for back of left pv row"""

    # Prepare some engine inputs
    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params, param_names=irradiance_model.params)
    fast_mode_pvrow_index = 1
    # Irradiance inputs
    timestamps = dt.datetime(2019, 6, 11, 11)
    DNI = 1000.
    DHI = 100.

    # Create engine object
    eng = PVEngine(pvarray,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index)
    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])

    # Run baseline calculation
    pvrow_idx = 0
    time_idx = 0
    pvarray_loop = _fast_mode_with_loop(eng.pvarray, eng.irradiance,
                                        eng.vf_calculator, pvrow_idx, time_idx)
    # Expected should be: 138.10421248631152
    qinc_expected = pvarray_loop.pvrows[0].back.get_param_weighted('qinc')
    # Run timeseries calculation
    qinc = eng.run_fast_mode(
        fn_build_report=lambda pvarray:
        (pvarray.ts_pvrows[0].back.get_param_weighted('qinc')),
        pvrow_index=0)
    # Check results: value taken from loop-like fast mode
    np.testing.assert_allclose(qinc, qinc_expected)
Exemple #13
0
def test_run_fast_and_full_modes_sequentially(params, fn_report_example):
    """Make sure that can run fast and full modes one after the other
    without making the engine crash"""

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

    # Prepare some engine inputs
    pvarray = OrderedPVArray.init_from_dict(params)
    fast_mode_pvrow_index = 1
    fast_mode_segment_index = 0

    # Create engine object
    eng = PVEngine(pvarray,
                   fast_mode_pvrow_index=fast_mode_pvrow_index,
                   fast_mode_segment_index=fast_mode_segment_index)
    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])

    # Run fast mode
    def fn_report(pvarray):
        return (pvarray.ts_pvrows[1].back.get_param_weighted('qinc'))

    qinc_fast = eng.run_fast_mode(fn_build_report=fn_report)
    # Run full mode
    report = eng.run_full_mode(fn_build_report=fn_report_example)

    np.testing.assert_allclose(qinc_fast, 119.095285)
    np.testing.assert_allclose(report['qinc_back'], 116.49050349491)
def pv_engine_run(data, pvarray_parameters, parallel=0):
    if parallel > 0:
        report = run_parallel_engine(MyReportBuilder,
                                     pvarray_parameters,
                                     data.index,
                                     data.dni,
                                     data.dhi,
                                     data.zenith,
                                     data.azimuth,
                                     data.surface_tilt,
                                     data.surface_azimuth,
                                     data.albedo,
                                     n_processes=6)
    else:
        rb = MyReportBuilder()
        engine = PVEngine(pvarray_parameters)
        engine.fit(data.index, data.dni, data.dhi, data.zenith, data.azimuth,
                   data.surface_tilt, data.surface_azimuth, data.albedo)
        report = engine.run_all_timesteps(rb.build)

    df_report = pd.DataFrame(report, index=data.index).fillna(0)
    return df_report
Exemple #15
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)
Exemple #16
0
def test_engine_variable_albedo(params, df_inputs_clearsky_8760):
    """Run PV engine calcs with variable albedo"""
    n_points = 100  # limiting because circleci is taking very long

    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(params)
    eng = PVEngine(pvarray, irradiance_model=irradiance_model)

    # Manage timeseries inputs
    df_inputs = df_inputs_clearsky_8760[:n_points]

    # Get MET data
    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
    albedo = np.linspace(0.01, 1, num=n_points)

    # Fit engine
    eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth, surface_tilt,
            surface_azimuth, albedo)

    # Run timestep
    pvarray = eng.run_full_mode(fn_build_report=lambda pvarray: pvarray)
    # Check the bifacial gain values
    pvrow = pvarray.ts_pvrows[1]
    bfg = (np.nansum(pvrow.back.get_param_weighted('qinc')) /
           np.nansum(pvrow.front.get_param_weighted('qinc'))) * 100.
    bfg_after_aoi = (np.nansum(pvrow.back.get_param_weighted('qabs')) /
                     np.nansum(pvrow.front.get_param_weighted('qabs'))) * 100.
    expected_bfg = 14.973198
    expected_bfg_after_aoi = 14.670709
    np.testing.assert_allclose(bfg, expected_bfg)
    np.testing.assert_allclose(bfg_after_aoi, expected_bfg_after_aoi)
Exemple #17
0
def test_run_fast_mode_segments(params):
    """Test that PV engine works for timeseries fast mode and float inputs.
    Value is very close to loop-like fast mode"""

    # Discretize middle PV row's back side
    params.update({'cut': {1: {'back': 5}}})

    # Prepare some engine inputs
    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params, param_names=irradiance_model.params)
    fast_mode_pvrow_index = 1
    fast_mode_segment_index = 2

    # Create engine object
    eng = PVEngine(pvarray,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index,
                   fast_mode_segment_index=fast_mode_segment_index)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI, params['solar_zenith'],
            params['solar_azimuth'], params['surface_tilt'],
            params['surface_azimuth'], params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'],
                                   DNI)

    # Define report function to grab irradiance from PV row segment
    def fn_report(pvarray):
        return (pvarray.ts_pvrows[1].back.list_segments[2].get_param_weighted(
            'qinc'))

    # Expected value for middle segment
    qinc_expected = 116.572594
    # Run fast mode for specific segment
    qinc_segment = eng.run_fast_mode(fn_build_report=fn_report)
    # Check results
    np.testing.assert_allclose(qinc_segment, qinc_expected)

    # Without providing segment index: the value should be the same as above
    eng.fast_mode_segment_index = None
    qinc_segment = eng.run_fast_mode(fn_build_report=fn_report)
    # Check results
    np.testing.assert_allclose(qinc_segment, qinc_expected)
Exemple #18
0
def test_run_fast_mode_back_shading(params):
    """Test that PV engine works for timeseries fast mode and float inputs,
    and when there's large direct shading on the back surface.
    Value is very close to loop-style fast mode"""

    params.update({
        'gcr': 0.6,
        'surface_azimuth': 270,
        'surface_tilt': 120,
        'solar_zenith': 70.
    })
    # Prepare some engine inputs
    irradiance_model = HybridPerezOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params, param_names=irradiance_model.params)
    fast_mode_pvrow_index = 1
    fast_mode_segment_index = 0

    # Create engine object
    eng = PVEngine(pvarray,
                   irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index,
                   fast_mode_segment_index=fast_mode_segment_index)

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

    # Expected values
    expected_qinc = 683.537153

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

    def fn_report(pvarray):
        return (pvarray.ts_pvrows[1].back.get_param_weighted('qinc'))

    # By providing segment index
    qinc = eng.run_fast_mode(fn_build_report=fn_report)
    # Check results
    np.testing.assert_allclose(qinc, expected_qinc)

    # Without providing segment index
    eng.fast_mode_segment_index = None
    qinc = eng.run_fast_mode(fn_build_report=fn_report)
    # Check results
    np.testing.assert_allclose(qinc, expected_qinc)
Exemple #19
0
def test_run_fast_mode_isotropic(params):
    """Test that PV engine works for timeseries fast mode and float inputs,
    and using the isotropic irradiance model"""

    # Prepare some engine inputs
    irradiance_model = IsotropicOrdered()
    pvarray = OrderedPVArray.init_from_dict(
        params, param_names=irradiance_model.params)
    fast_mode_pvrow_index = 1
    fast_mode_segment_index = 0

    # Create engine object
    eng = PVEngine(pvarray, irradiance_model=irradiance_model,
                   fast_mode_pvrow_index=fast_mode_pvrow_index,
                   fast_mode_segment_index=fast_mode_segment_index)

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

    # Fit engine
    eng.fit(timestamps, DNI, DHI,
            params['solar_zenith'], params['solar_azimuth'],
            params['surface_tilt'], params['surface_azimuth'],
            params['rho_ground'])
    # Checks
    np.testing.assert_almost_equal(eng.irradiance.direct['front_illum_pvrow'],
                                   DNI)

    # Expected value
    qinc_expected = 122.73453

    # Run fast mode
    qinc = eng.run_fast_mode(
        fn_build_report=lambda pvarray: (pvarray.ts_pvrows[1]
                                         .back.get_param_weighted('qinc')))
    # Check results
    np.testing.assert_allclose(qinc, qinc_expected)

    # Without providing segment index
    eng.fast_mode_segment_index = None
    qinc = eng.run_fast_mode(
        fn_build_report=lambda pvarray: (pvarray.ts_pvrows[1]
                                         .back.get_param_weighted('qinc')))
    # Check results
    np.testing.assert_allclose(qinc, qinc_expected)
Exemple #20
0
def test_check_tilt_zero_discontinuity():
    """
    Before version 1.5.2, surface_tilt=0 with certain combinations of
    surface_azimuth and axis_azimuth showed anomolous behavior where
    the irradiance at zero tilt was significantly different from the
    irradiance at very small but nonzero tilts.  Additionally, the
    calculated VF matrix could have values outside [0, 1].  See GH #125
    """
    # expected value calculated for surface_tilt=0.001, so should
    # not be significantly different from result for surface_tilt=0
    rear_qinc_expected = 76.10

    timestamps = np.array([dt.datetime(2019, 6, 1, 10)])
    solar_azimuth = np.array([135])
    solar_zenith = np.array([45])
    dni = np.array([200])
    dhi = np.array([400])
    albedo = np.array([0.2])
    surface_tilt = np.array([0.0])

    # the discontinuity did not occur for all combinations of
    # (surface_azimuth, axis_azimuth), so test all four "primary" pairs:
    for surface_azimuth in [90, 270]:
        surface_azimuth = np.array([surface_azimuth])
        for axis_azimuth in [0, 180]:
            params = dict(n_pvrows=3,
                          axis_azimuth=axis_azimuth,
                          pvrow_height=2,
                          pvrow_width=1,
                          gcr=0.4)

            pvarray = OrderedPVArray.init_from_dict(params)
            eng = PVEngine(pvarray)
            eng.fit(timestamps, dni, dhi, solar_zenith, solar_azimuth,
                    surface_tilt, surface_azimuth, albedo)

            # Run simulation and get output
            eng.run_full_mode()
            out = pvarray.ts_pvrows[1].back.get_param_weighted('qinc')
            assert np.all(pvarray.ts_vf_matrix >= 0)
            assert np.all(pvarray.ts_vf_matrix <= 1)
            assert rear_qinc_expected == pytest.approx(out[0], abs=1e-2)
Exemple #21
0
def pvfactors_engine_run(data, pvarray_parameters, parallel=0, mode='full'):
    """My wrapper function to launch the pvfactors engine in parallel. It is mostly for Windows use.
    In Linux you can directly call run_parallel_engine. It uses MyReportBuilder to generate the output.
    
    Args:
        data (pandas DataFrame): The data to fit the model.
        pvarray_parameters (dict): The pvfactors dict describing the simulation.
        parallel (int, optional): Number of threads to launch. Defaults to 0 (just calls PVEngine.run_all_timesteps)
        mode (str): full or fast depending on the type of back irraadiances. See pvfactors doc.
    
    Returns:
        pandas DataFrame: The results of the simulation, as desired in MyReportBuilder.
    """
    n, row = _get_cut(pvarray_parameters['cut'])
    rb = Report(n, row)
    if parallel > 1:
        report = run_parallel_engine(rb,
                                     pvarray_parameters,
                                     data.index,
                                     data.dni,
                                     data.dhi,
                                     data.zenith,
                                     data.azimuth,
                                     data.surface_tilt,
                                     data.surface_azimuth,
                                     data.albedo,
                                     n_processes=parallel)
    else:
        pvarray = OrderedPVArray.init_from_dict(pvarray_parameters)
        engine = PVEngine(pvarray)
        engine.fit(data.index, data.dni, data.dhi, data.zenith, data.azimuth,
                   data.surface_tilt, data.surface_azimuth, data.albedo,
                   data.ghi)
        if mode == 'full': report = engine.run_full_mode(rb.build)
        else:
            report = engine.run_fast_mode(rb.build,
                                          pvrow_index=0,
                                          segment_index=0)
    df_report = pd.DataFrame(report, index=data.index).fillna(0)
    return df_report