Example #1
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
Example #2
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)
Example #3
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)
Example #4
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)
Example #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)
Example #6
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)
Example #7
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)
Example #8
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