Beispiel #1
0
def test_run_parallel_engine_with_ghi(params_serial, df_inputs_clearsky_8760):
    """Test that ghi is correctly passed to models.
    Notes:
    - ghi is not used in full modes, so it will not affect the full mode results
    - so use fast mode instead
    """
    df_inputs = df_inputs_clearsky_8760.iloc[:24, :]

    # Get MET data
    timestamps = df_inputs.index
    dni = df_inputs.dni.values
    dhi = df_inputs.dhi.values
    ghi = 500. * np.ones_like(dni)
    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
    fast_mode_pvrow_index = 1
    n_processes = 2

    # Report with no ghi
    report_no_ghi = run_parallel_engine(
        TestFastReportBuilder,
        params_serial,
        timestamps,
        dni,
        dhi,
        solar_zenith,
        solar_azimuth,
        surface_tilt,
        surface_azimuth,
        params_serial['rho_ground'],
        n_processes=n_processes,
        fast_mode_pvrow_index=fast_mode_pvrow_index)

    np.testing.assert_almost_equal(np.nansum(report_no_ghi['qinc_back']),
                                   548.0011865481954)

    # Report with ghi
    report_w_ghi = run_parallel_engine(
        TestFastReportBuilder,
        params_serial,
        timestamps,
        dni,
        dhi,
        solar_zenith,
        solar_azimuth,
        surface_tilt,
        surface_azimuth,
        params_serial['rho_ground'],
        n_processes=n_processes,
        fast_mode_pvrow_index=fast_mode_pvrow_index,
        ghi=ghi)

    np.testing.assert_almost_equal(np.nansum(report_w_ghi['qinc_back']),
                                   771.8440422696128)
Beispiel #2
0
def test_run_parallel_engine_with_irradiance_params(params_serial,
                                                    df_inputs_clearsky_8760):
    """Test that irradiance model params are passed correctly in parallel
    simulations"""
    df_inputs = df_inputs_clearsky_8760.iloc[:24, :]
    n = df_inputs.shape[0]

    # 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
    n_processes = 2

    irradiance_params = {'horizon_band_angle': 6.5}
    report_no_params = run_parallel_engine(
        ExampleReportBuilder,
        params_serial,
        timestamps,
        dni,
        dhi,
        solar_zenith,
        solar_azimuth,
        surface_tilt,
        surface_azimuth,
        params_serial['rho_ground'],
        n_processes=n_processes,
        irradiance_model_params=irradiance_params)

    np.testing.assert_almost_equal(np.nansum(report_no_params['qinc_back']),
                                   541.7115807694377)

    # The incident irradiance should be higher with larger horizon band
    irradiance_params = {'horizon_band_angle': 15.}
    report_w_params = run_parallel_engine(
        ExampleReportBuilder,
        params_serial,
        timestamps,
        dni,
        dhi,
        solar_zenith,
        solar_azimuth,
        surface_tilt,
        surface_azimuth,
        params_serial['rho_ground'],
        n_processes=n_processes,
        irradiance_model_params=irradiance_params)

    np.testing.assert_almost_equal(np.nansum(report_w_params['qinc_back']),
                                   554.5333279555168)
Beispiel #3
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
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
Beispiel #5
0
def pvfactors_timeseries(solar_azimuth,
                         solar_zenith,
                         surface_azimuth,
                         surface_tilt,
                         axis_azimuth,
                         timestamps,
                         dni,
                         dhi,
                         gcr,
                         pvrow_height,
                         pvrow_width,
                         albedo,
                         n_pvrows=3,
                         index_observed_pvrow=1,
                         rho_front_pvrow=0.03,
                         rho_back_pvrow=0.05,
                         horizon_band_angle=15.,
                         run_parallel_calculations=True,
                         n_workers_for_parallel_calcs=2):
    """
    Calculate front and back surface plane-of-array irradiance on
    a fixed tilt or single-axis tracker PV array configuration, and using
    the open-source "pvfactors" package.  pvfactors implements the model
    described in [1]_.
    Please refer to pvfactors online documentation for more details:
    https://sunpower.github.io/pvfactors/

    Parameters
    ----------
    solar_azimuth: numeric
        Sun's azimuth angles using pvlib's azimuth convention (deg)
    solar_zenith: numeric
        Sun's zenith angles (deg)
    surface_azimuth: numeric
        Azimuth angle of the front surface of the PV modules, using pvlib's
        convention (deg)
    surface_tilt: numeric
        Tilt angle of the PV modules, going from 0 to 180 (deg)
    axis_azimuth: float
        Azimuth angle of the rotation axis of the PV modules, using pvlib's
        convention (deg). This is supposed to be fixed for all timestamps.
    timestamps: datetime or DatetimeIndex
        List of simulation timestamps
    dni: numeric
        Direct normal irradiance (W/m2)
    dhi: numeric
        Diffuse horizontal irradiance (W/m2)
    gcr: float
        Ground coverage ratio of the pv array
    pvrow_height: float
        Height of the pv rows, measured at their center (m)
    pvrow_width: float
        Width of the pv rows in the considered 2D plane (m)
    albedo: float
        Ground albedo
    n_pvrows: int, default 3
        Number of PV rows to consider in the PV array
    index_observed_pvrow: int, default 1
        Index of the PV row whose incident irradiance will be returned. Indices
        of PV rows go from 0 to n_pvrows-1.
    rho_front_pvrow: float, default 0.03
        Front surface reflectivity of PV rows
    rho_back_pvrow: float, default 0.05
        Back surface reflectivity of PV rows
    horizon_band_angle: float, default 15
        Elevation angle of the sky dome's diffuse horizon band (deg)
    run_parallel_calculations: bool, default True
        pvfactors is capable of using multiprocessing. Use this flag to decide
        to run calculations in parallel (recommended) or not.
    n_workers_for_parallel_calcs: int, default 2
        Number of workers to use in the case of parallel calculations. The
        '-1' value will lead to using a value equal to the number
        of CPU's on the machine running the model.

    Returns
    -------
    front_poa_irradiance: numeric
        Calculated incident irradiance on the front surface of the PV modules
        (W/m2)
    back_poa_irradiance: numeric
        Calculated incident irradiance on the back surface of the PV modules
        (W/m2)
    df_registries: pandas DataFrame
        DataFrame containing detailed outputs of the simulation; for
        instance the shapely geometries, the irradiance components incident on
        all surfaces of the PV array (for all timestamps), etc.
        In the pvfactors documentation, this is refered to as the "surface
        registry".

    References
    ----------
    .. [1] Anoma, Marc Abou, et al. "View Factor Model and Validation for
        Bifacial PV and Diffuse Shade on Single-Axis Trackers." 44th IEEE
        Photovoltaic Specialist Conference. 2017.
    """

    # Convert pandas Series inputs (and some lists) to numpy arrays
    if isinstance(solar_azimuth, pd.Series):
        solar_azimuth = solar_azimuth.values
    elif isinstance(solar_azimuth, list):
        solar_azimuth = np.array(solar_azimuth)
    if isinstance(solar_zenith, pd.Series):
        solar_zenith = solar_zenith.values
    if isinstance(surface_azimuth, pd.Series):
        surface_azimuth = surface_azimuth.values
    elif isinstance(surface_azimuth, list):
        surface_azimuth = np.array(surface_azimuth)
    if isinstance(surface_tilt, pd.Series):
        surface_tilt = surface_tilt.values
    if isinstance(dni, pd.Series):
        dni = dni.values
    if isinstance(dhi, pd.Series):
        dhi = dhi.values
    if isinstance(solar_azimuth, list):
        solar_azimuth = np.array(solar_azimuth)

    # Import pvfactors functions for timeseries calculations.
    from pvfactors.run import (run_timeseries_engine, run_parallel_engine)

    # Build up pv array configuration parameters
    pvarray_parameters = {
        'n_pvrows': n_pvrows,
        'axis_azimuth': axis_azimuth,
        'pvrow_height': pvrow_height,
        'pvrow_width': pvrow_width,
        'gcr': gcr,
        'rho_front_pvrow': rho_front_pvrow,
        'rho_back_pvrow': rho_back_pvrow,
        'horizon_band_angle': horizon_band_angle
    }

    # Run pvfactors calculations: either in parallel or serially
    if run_parallel_calculations:
        report = run_parallel_engine(PVFactorsReportBuilder,
                                     pvarray_parameters,
                                     timestamps,
                                     dni,
                                     dhi,
                                     solar_zenith,
                                     solar_azimuth,
                                     surface_tilt,
                                     surface_azimuth,
                                     albedo,
                                     n_processes=n_workers_for_parallel_calcs)
    else:
        report = run_timeseries_engine(PVFactorsReportBuilder.build,
                                       pvarray_parameters, timestamps, dni,
                                       dhi, solar_zenith, solar_azimuth,
                                       surface_tilt, surface_azimuth, albedo)

    # Turn report into dataframe
    df_report = pd.DataFrame(report, index=timestamps)

    return df_report.total_inc_front, df_report.total_inc_back
Beispiel #6
0
def test_run_parallel_faoi_fn(params_serial, df_inputs_clearsky_8760):
    """Test that in run_parallel 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

    # create calculator
    report = run_parallel_engine(TestFAOIReportBuilder,
                                 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
    # 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': FaoiClass,
        'faoi_fn_back': FaoiClass,
        'n_aoi_integral_sections': n_sections
    }
    irr_params = {'faoi_fn_front': FaoiClass, 'faoi_fn_back': FaoiClass}

    # create calculator
    report = run_parallel_engine(TestFAOIReportBuilder,
                                 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)
                        type=int,
                        default=4)

    args = parser.parse_args()

    #get args
    n_processes = int(args.jobs)
    tmy_file = args.tmy

    print(f'Args: {n_processes}, {tmy_file}')
    #locate system
    pvarray_parameters = system_def(h_ground=1)
    data = get_data(tmy_file, pvarray_parameters)

    # run simulations in parallel mode
    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=n_processes)

    # make a dataframe out of the report
    df_report = pd.DataFrame(report, index=data.index).dropna()

    df_report.to_csv('pvfactors_output.csv')