Example #1
0
def test_luminance_in_timeseries_calc(df_perez_luminance,
                                      mock_array_timeseries_calculate):
    """
    Test that the calculation of luminance -- first step in using the vf model
    with Perez -- is functional
    """
    df_inputs_clearday = pd.read_csv(FILE_PATH)
    df_inputs_clearday = df_inputs_clearday.set_index('datetime', drop=True)
    df_inputs_clearday.index = (pd.DatetimeIndex(
        df_inputs_clearday.index).tz_localize('UTC').tz_convert(
            'Etc/GMT+7').tz_localize(None))

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs_clearday)
    _, df_outputs = calculate_radiosities_serially_perez(
        (None, timestamps, solar_zenith, solar_azimuth, surface_tilt,
         surface_azimuth, dni, dhi))

    col_order = df_outputs.columns
    tol = 1e-8
    np.testing.assert_allclose(df_outputs.values,
                               df_perez_luminance[col_order].values,
                               atol=0,
                               rtol=tol)
def test_serial_calculation(pvarray_parameters_serial_calc,
                            df_inputs_serial_calculation):
    """
    Make sure that the calculations using the Perez model stay consistent for
    all the modeled surfaces. Also testing that there is no unexpected NaN.
    """

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs_serial_calculation)

    # Run calculation in 1 process only
    df_registries, _ = calculate_radiosities_serially_perez(
        (pvarray_parameters_serial_calc, timestamps, solar_zenith,
         solar_azimuth, surface_tilt, surface_azimuth, dni, dhi))

    # Format df_registries to get outputs
    df_outputs = get_average_pvrow_outputs(df_registries,
                                           include_shading=False)

    # Did the outputs remain consistent?
    test_results = values_are_consistent(df_outputs)
    for result in test_results:
        assert result['passed'], ("test failed for %s" %
                                  result['irradiance_term'])
def test_calculate_radiosities_parallel_perez():
    """
    Check that the parallel calculation using Perez diffuse model is able to
    run. The consistency is not tested here, because it is already tested for
    the serial calculation (which it relies on)
    """
    # Inputs to the calculations
    filename = "file_test_multiprocessing_inputs.csv"
    subset_idx = 100
    arguments = {
        'n_pvrows': 2,
        'pvrow_height': 3.,
        'pvrow_width': 1.,
        'array_azimuth': 270.,
        'array_tilt': -20.,
        'gcr': 0.3,
        'solar_zenith': 20.,
        'solar_azimuth': 90.,
        'rho_ground': 0.2,
        'rho_front_pvrow': 0.01,
        'rho_back_pvrow': 0.03
    }
    # Import inputs
    df_inputs_simulation = pd.read_csv(os.path.join(TEST_DATA, filename),
                                       index_col=0)
    df_inputs_simulation.index = pd.DatetimeIndex(df_inputs_simulation.index)
    # Reduce number of inputs
    df_inputs_simulation = df_inputs_simulation.iloc[:subset_idx, :]
    # Select number of processes
    n_processes = None
    # Break up inputs
    (timestamps, array_tilt, array_azimuth, solar_zenith, solar_azimuth, dni,
     dhi) = breakup_df_inputs(df_inputs_simulation)
    # Run calculation
    results = calculate_radiosities_parallel_perez(arguments,
                                                   timestamps,
                                                   array_tilt,
                                                   array_azimuth,
                                                   solar_zenith,
                                                   solar_azimuth,
                                                   dni,
                                                   dhi,
                                                   n_processes=n_processes)
def test_back_surface_luminance():
    """
    The model didn't calculate cases when the sun would hit the back surface
    because the perez model would return 0 circumsolar (not calculated for
    back surface). Fix was implemented, and this should check for it.
    """
    pvarray_parameters = {
        'surface_azimuth': 90,
        'surface_tilt': 0.0,
        'gcr': 0.3,
        'n_pvrows': 3,
        'Pvrow_height': 1.5,
        'pvrow_width': 1.0,
        'rho_back_pvrow': 0.03,
        'rho_front_pvrow': 0.01,
        'rho_ground': 0.2,
        'solar_azimuth': 90.0,
        'solar_zenith': 20.0
    }

    input_filename = 'file_test_back_surface_luminance.csv'

    df_inputs = pd.read_csv(os.path.join(TEST_DATA, input_filename),
                            index_col=0)
    df_inputs.index = pd.DatetimeIndex(df_inputs.index).tz_localize(
        'UTC').tz_convert('US/Arizona')

    # Break up inputs
    (timestamps, tracker_theta, surface_azimuth,
     solar_zenith, solar_azimuth, dni, dhi) = breakup_df_inputs(df_inputs)

    args = (pvarray_parameters, timestamps, solar_zenith, solar_azimuth,
            tracker_theta, surface_azimuth, dni, dhi)
    df_registries, _ = calculate_radiosities_serially_perez(args)

    df_outputs = get_average_pvrow_outputs(df_registries)

    vf_ipoa_front = df_outputs.loc[:, IDX_SLICE[1, 'front', 'qinc']]
    vf_ipoa_back = df_outputs.loc[:, IDX_SLICE[1, 'back', 'qinc']]

    assert isinstance(vf_ipoa_front[0], float)
    assert isinstance(vf_ipoa_back[0], float)
def test_serial_circumsolar_shading_calculation():
    """
    Calculate and save results from front surface circumsolar shading on
    pvrows. Test that it functions with the given data.
    """

    # Choose a PV array configuration and pass the arguments necessary for
    # the calculation to be triggered:
    # eg 'calculate_front_circ_horizon_shading'
    arguments = {
        'array_azimuth': 90.0,
        'array_tilt': 20.0,
        'cut': [(1, 5, 'front')],
        'gcr': 0.3,
        'n_pvrows': 2,
        'pvrow_height': 1.5,
        'pvrow_width': 1.,
        'rho_ground': 0.2,
        'rho_pvrow_back': 0.03,
        'rho_pvrow_front': 0.01,
        'solar_azimuth': 90.0,
        'solar_zenith': 30.0,
        'circumsolar_angle': 50.,
        'horizon_band_angle': 6.5,
        'calculate_front_circ_horizon_shading': True,
        'circumsolar_model': 'gaussian'
    }
    # Load inputs for the serial calculation
    test_file = os.path.join(
        TEST_DATA, 'file_test_serial_circumsolar_shading_calculation.csv')
    df_inputs = pd.read_csv(test_file, index_col=0)
    df_inputs.index = pd.DatetimeIndex(df_inputs.index)
    (timestamps, array_tilt, array_azimuth,
     solar_zenith, solar_azimuth, dni, dhi) = breakup_df_inputs(df_inputs)

    # Run the calculation for functional testing
    df_registries, df_inputs_perez = (
        calculate_radiosities_serially_perez((arguments, timestamps, array_tilt,
                                              array_azimuth, solar_zenith,
                                              solar_azimuth, dni, dhi))
    )
def test_negativevf_and_flatcasenoon():

    pvarray_parameters = {
        'surface_azimuth': 90,
        'tracker_theta': 0.0,
        'gcr': 0.3,
        'n_pvrows': 3,
        'pvrow_height': 1.5,
        'pvrow_width': 1.0,
        'rho_back_pvrow': 0.03,
        'rho_front_pvrow': 0.01,
        'rho_ground': 0.2,
        'solar_azimuth': 90.0,
        'solar_zenith': 20.0
    }

    input_filename = 'file_test_negativevf_and_flatcasenoon.csv'
    df_inputs = pd.read_csv(os.path.join(TEST_DATA, input_filename),
                            index_col=0)
    df_inputs.index = pd.DatetimeIndex(df_inputs.index).tz_localize(
        'UTC').tz_convert('US/Arizona')

    # Break up inputs
    (timestamps, tracker_theta, surface_azimuth,
     solar_zenith, solar_azimuth, dni, dhi) = breakup_df_inputs(df_inputs)

    args = (pvarray_parameters, timestamps, solar_zenith, solar_azimuth,
            tracker_theta, surface_azimuth, dni, dhi)
    df_registries, _ = calculate_radiosities_serially_perez(args)
    df_outputs = get_average_pvrow_outputs(df_registries)

    vf_ipoa_front = df_outputs.loc[:, IDX_SLICE[1, 'front', 'qinc']]
    vf_ipoa_back = df_outputs.loc[:, IDX_SLICE[1, 'back', 'qinc']]

    # The model should calculate for all daytime points now since we fixed
    # the solar noon case (almost flat but not really), and we allowed
    # negative vf values early and late in the day
    expected_n_calculated_values = 13

    assert np.sum(vf_ipoa_front.notnull()) == expected_n_calculated_values
    assert np.sum(vf_ipoa_back.notnull()) == expected_n_calculated_values
Example #7
0
def test_perez_diffuse_luminance(df_perez_luminance):
    """
    Test that the calculation of luminance -- first step in using the vf model
    with Perez -- is functional
    """
    df_inputs = df_perez_luminance[[
        'surface_tilt', 'surface_azimuth', 'solar_zenith', 'solar_azimuth',
        'dni', 'dhi'
    ]]
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs)
    df_outputs = perez_diffuse_luminance(timestamps, surface_tilt,
                                         surface_azimuth, solar_zenith,
                                         solar_azimuth, dni, dhi)

    col_order = df_outputs.columns
    tol = 1e-8
    np.testing.assert_allclose(df_outputs.values,
                               df_perez_luminance[col_order].values,
                               atol=0,
                               rtol=tol)
def test_serial_calculation_with_skips(
        pvarray_parameters_serial_calc,
        df_inputs_serial_calculation_with_skips):
    """
    Make sure that the calculations using the Perez model stay consistent for
    all the modeled surfaces. Also testing that there is no unexpected NaN.
    """

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs_serial_calculation_with_skips)

    # Run calculation in 1 process only
    df_registries, _ = calculate_radiosities_serially_perez(
        (pvarray_parameters_serial_calc, timestamps, solar_zenith,
         solar_azimuth, surface_tilt, surface_azimuth, dni, dhi))

    list_nan_idx = df_registries.index[df_registries.set_index(
        'timestamps').count(axis=1) == 0]
    # There should be one line with only nan values
    assert len(list_nan_idx) == 1
Example #9
0
def test_perez_diffuse_luminance(df_perez_luminance):
    """
    Test that the calculation of luminance -- first step in using the vf model
    with Perez -- is functional
    """
    df_inputs_clearday = pd.read_csv(FILE_PATH)
    df_inputs_clearday = df_inputs_clearday.set_index('datetime', drop=True)
    df_inputs_clearday.index = (pd.DatetimeIndex(
        df_inputs_clearday.index).tz_localize('UTC').tz_convert(
            'Etc/GMT+7').tz_localize(None))

    # Break up inputs
    (timestamps, array_tilt, array_azimuth, solar_zenith, solar_azimuth, dni,
     dhi) = breakup_df_inputs(df_inputs_clearday)
    df_outputs = perez_diffuse_luminance(timestamps, array_tilt, array_azimuth,
                                         solar_zenith, solar_azimuth, dni, dhi)

    col_order = df_outputs.columns
    tol = 1e-8
    assert np.allclose(df_outputs.values,
                       df_perez_luminance[col_order].values,
                       atol=0,
                       rtol=tol)
Example #10
0
def test_array_calculate_timeseries():
    """
    Check that the timeseries results of the radiosity calculation using the
    isotropic diffuse sky approach stay consistent
    """
    # Simple sky and array configuration
    df_inputs = pd.DataFrame(
        {
            'solar_zenith': [80., 20., 70.4407256],
            'solar_azimuth': [0., 180., 248.08690811],
            'surface_tilt': [70., 40., 42.4337927],
            'surface_azimuth': [180., 180., 270.],
            'dni': [1e3, 1e3, 1000.],
            'dhi': [1e2, 1e2, 100.]
        },
        index=[0, 1, 2])
    arguments = {
        'n_pvrows': 3,
        'pvrow_height': 1.5,
        'pvrow_width': 1.,
        'gcr': 0.3,
    }

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs)

    # Fill in the missing pieces
    luminance_isotropic = dhi
    luminance_circumsolar = np.zeros(len(timestamps))
    poa_horizon = np.zeros(len(timestamps))
    poa_circumsolar = np.zeros(len(timestamps))

    # Run timeseries calculation
    df_registries = array_timeseries_calculate(arguments, timestamps,
                                               solar_zenith, solar_azimuth,
                                               surface_tilt, surface_azimuth,
                                               dni, luminance_isotropic,
                                               luminance_circumsolar,
                                               poa_horizon, poa_circumsolar)

    # Calculate surface averages for pvrows
    df_outputs = get_average_pvrow_outputs(df_registries,
                                           values=['q0', 'qinc'],
                                           include_shading=False)

    # Check that the outputs are as expected
    expected_outputs_array = np.array(
        [[31.60177482, 6.28906975, 3.58335581],
         [632.03549634, 125.78139505, 71.66711623],
         [2.27843869, 31.55401986, 28.05923971],
         [75.94795617, 1051.80066185, 935.30799022],
         [31.87339866, 6.3776871, 1.81431887],
         [637.46797317, 127.55374206, 36.28637745],
         [2.20476856, 31.21803306, 27.85790853],
         [73.49228524, 1040.60110204, 928.59695092],
         [46.7960208, 7.21518794, 2.16642175],
         [935.92041595, 144.30375888, 43.32843492],
         [2.29986192, 31.16722793, 27.77628919],
         [76.66206408, 1038.90759755, 925.87630648], [True, False, False]],
        dtype=object)
    tol = 1e-8
    np.testing.assert_allclose(expected_outputs_array[:-1, :].astype(float),
                               df_outputs.values.T,
                               atol=tol,
                               rtol=0,
                               equal_nan=True)
Example #11
0
def test_save_all_outputs_calculate_perez():
    """
    Make sure that the serial and parallel calculations are able to save all
    the requested data on discretized segments (instead of averaging them by
    default). Check the consistency of the results.
    """
    # Load timeseries input data
    df_inputs_clearday = pd.read_csv(FILE_PATH)
    df_inputs_clearday = df_inputs_clearday.set_index('datetime', drop=True)
    df_inputs_clearday.index = (pd.DatetimeIndex(
        df_inputs_clearday.index).tz_localize('UTC').tz_convert(
            'Etc/GMT+7').tz_localize(None))
    idx_subset = 10

    # PV array parameters for test
    arguments = {
        'n_pvrows': 3,
        'pvrow_height': 1.5,
        'pvrow_width': 1.,
        'gcr': 0.4,
        'rho_ground': 0.8,
        'rho_back_pvrow': 0.03,
        'rho_front_pvrow': 0.01,
        'cut': [(1, 3, 'front')]
    }

    # Break up inputs
    (timestamps, surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
     dni, dhi) = breakup_df_inputs(df_inputs_clearday.iloc[:idx_subset])

    args = (arguments, timestamps, solar_zenith, solar_azimuth, surface_tilt,
            surface_azimuth, dni, dhi)

    # Run the serial calculation
    df_registries_serial, _ = (calculate_radiosities_serially_perez(args))

    df_registries_parallel, _ = (calculate_radiosities_parallel_perez(*args))

    # Format the outputs
    df_outputs_segments_serial = get_pvrow_segment_outputs(
        df_registries_serial, values=['qinc'], include_shading=False)
    df_outputs_segments_parallel = get_pvrow_segment_outputs(
        df_registries_parallel, values=['qinc'], include_shading=False)

    # Load files with expected outputs
    expected_ipoa_dict_qinc = np.array(
        [[842.54617681, 842.5566707, 842.43690951],
         [839.30179691, 839.30652961, 839.30906023],
         [839.17118956, 839.17513098, 839.17725568],
         [842.24679271, 842.26194393, 842.15463231]])

    # Perform the comparisons
    rtol = 1e-6
    atol = 0
    np.testing.assert_allclose(expected_ipoa_dict_qinc,
                               df_outputs_segments_serial.values,
                               atol=atol,
                               rtol=rtol)
    np.testing.assert_allclose(expected_ipoa_dict_qinc,
                               df_outputs_segments_parallel.values,
                               atol=atol,
                               rtol=rtol)
Example #12
0
def test_save_all_outputs_calculate_perez():
    """
    Make sure that the serial and parallel calculations are able to save all
    the requested data on discretized segments (instead of averaging them by
    default). Check the consistency of the results.
    """
    # Load timeseries input data
    df_inputs_clearday = pd.read_csv(FILE_PATH)
    df_inputs_clearday = df_inputs_clearday.set_index('datetime', drop=True)
    df_inputs_clearday.index = (pd.DatetimeIndex(
        df_inputs_clearday.index).tz_localize('UTC').tz_convert(
            'Etc/GMT+7').tz_localize(None))
    idx_subset = 10

    # Adjustment in angles needed: need to keep azimuth constant and change
    # tilt angle only
    df_inputs_clearday.loc[(df_inputs_clearday.solar_azimuth <= 180.),
                           'array_azimuth'] = (
                               df_inputs_clearday.loc[:, 'array_azimuth'][-1])
    df_inputs_clearday.loc[(df_inputs_clearday.solar_azimuth <= 180.),
                           'array_tilt'] *= (-1)

    # PV array parameters for test
    arguments = {
        'n_pvrows': 3,
        'pvrow_height': 1.5,
        'pvrow_width': 1.,
        'gcr': 0.4,
        'rho_ground': 0.8,
        'rho_back_pvrow': 0.03,
        'rho_front_pvrow': 0.01,
        'cut': [(1, 3, 'front')]
    }

    # Break up inputs
    (timestamps, array_tilt, array_azimuth, solar_zenith, solar_azimuth, dni,
     dhi) = breakup_df_inputs(df_inputs_clearday.iloc[:idx_subset])

    args = (arguments, timestamps, solar_zenith, solar_azimuth, array_tilt,
            array_azimuth, dni, dhi)

    # Run the serial calculation
    df_registries_serial, _ = (calculate_radiosities_serially_perez(args))

    df_registries_parallel, _ = (calculate_radiosities_parallel_perez(*args))

    # Format the outputs
    df_outputs_segments_serial = get_pvrow_segment_outputs(
        df_registries_serial, values=['qinc'], include_shading=False)
    df_outputs_segments_parallel = get_pvrow_segment_outputs(
        df_registries_parallel, values=['qinc'], include_shading=False)

    # Load files with expected outputs
    expected_ipoa_dict_qinc = np.array(
        [[842.43691838, 842.54795737, 842.52912932],
         [839.30539601, 839.30285394, 839.29810984],
         [839.17118976, 839.17513111, 839.17725576],
         [842.24681064, 842.26195526, 842.15463995]])

    # Perform the comparisons
    rtol = 1e-7
    atol = 0
    assert np.allclose(expected_ipoa_dict_qinc,
                       df_outputs_segments_serial.values,
                       atol=atol,
                       rtol=rtol)
    assert np.allclose(expected_ipoa_dict_qinc,
                       df_outputs_segments_parallel.values,
                       atol=atol,
                       rtol=rtol)