示例#1
0
def test_shadows_coords_left_right_of_cut_point():
    """Test that coords left and right of cut point are created correctly"""
    # Ground inputs
    shadow_coords = np.array(
        [[[[0], [0]], [[2], [0]]], [[[3], [0]], [[5], [0]]]], dtype=float)
    overlap = [False]

    # --- Create timeseries ground
    cut_point = TsPointCoords([2.5], [0])
    ts_ground = TsGround.from_ordered_shadows_coords(
        shadow_coords, flag_overlap=overlap, cut_point_coords=[cut_point])

    # Get left and right shadows
    shadows_left = ts_ground.shadow_coords_left_of_cut_point(0)
    shadows_right = ts_ground.shadow_coords_right_of_cut_point(0)

    # Reformat for testing
    shadows_left = [shadow.as_array for shadow in shadows_left]
    shadows_right = [shadow.as_array for shadow in shadows_right]

    expected_shadows_left = [
        shadow_coords[0], [cut_point.as_array, cut_point.as_array]
    ]
    expected_shadows_right = [[cut_point.as_array, cut_point.as_array],
                              shadow_coords[1]]

    # Test that correct
    np.testing.assert_allclose(shadows_left, expected_shadows_left)
    np.testing.assert_allclose(shadows_right, expected_shadows_right)

    # --- Case where pv rows are flat, cut point are inf
    cut_point = TsPointCoords([np.inf], [0])
    ts_ground = TsGround.from_ordered_shadows_coords(
        shadow_coords, flag_overlap=overlap, cut_point_coords=[cut_point])

    # Get right shadows
    shadows_right = ts_ground.shadow_coords_right_of_cut_point(0)

    # Test that correct
    maxi = MAX_X_GROUND
    expected_shadows_right = np.array([[[[maxi], [0.]], [[maxi], [0.]]],
                                       [[[maxi], [0.]], [[maxi], [0.]]]])
    shadows_right = [shadow.as_array for shadow in shadows_right]
    np.testing.assert_allclose(shadows_right, expected_shadows_right)

    # --- Case where pv rows are flat, cut point are - inf
    cut_point = TsPointCoords([-np.inf], [0])
    ts_ground = TsGround.from_ordered_shadows_coords(
        shadow_coords, flag_overlap=overlap, cut_point_coords=[cut_point])

    # Get left shadows
    shadows_left = ts_ground.shadow_coords_left_of_cut_point(0)

    # Test that correct
    mini = MIN_X_GROUND
    expected_shadows_left = np.array([[[[mini], [0.]], [[mini], [0.]]],
                                      [[[mini], [0.]], [[mini], [0.]]]])
    shadows_left = [shadow.as_array for shadow in shadows_left]
    np.testing.assert_allclose(shadows_left, expected_shadows_left)
示例#2
0
def test_ts_ground_overlap():

    shadow_coords = np.array([[[[0, 0], [0, 0]], [[2, 1], [0, 0]]],
                              [[[1, 2], [0, 0]], [[5, 5], [0, 0]]]])
    overlap = [True, False]

    # Test without overlap
    ts_ground = TsGround.from_ordered_shadows_coords(shadow_coords)
    np.testing.assert_allclose(ts_ground.shadow_elements[0].b2.x, [2, 1])

    # Test with overlap
    ts_ground = TsGround.from_ordered_shadows_coords(shadow_coords,
                                                     flag_overlap=overlap)
    np.testing.assert_allclose(ts_ground.shadow_elements[0].b2.x, [1, 1])
示例#3
0
    def fit(self, solar_zenith, solar_azimuth, surface_tilt, surface_azimuth):
        """Fit the ordered PV array to the list of solar and surface angles.
        All intermediate PV array results necessary to build the geometries
        will be calculated here using vectorization as much as possible.

        Intemediate results include: PV row coordinates for all timestamps,
        ground element coordinates for all timestamps, cases of direct
        shading, ...

        Parameters
        ----------
        solar_zenith : array-like or float
            Solar zenith angles [deg]
        solar_azimuth : array-like or float
            Solar azimuth angles [deg]
        surface_tilt : array-like or float
            Surface tilt angles, from 0 to 180 [deg]
        surface_azimuth : array-like or float
            Surface azimuth angles [deg]
        """

        self.n_states = len(solar_zenith)
        # Calculate rotation angles
        rotation_vec = _get_rotation_from_tilt_azimuth(surface_azimuth,
                                                       self.axis_azimuth,
                                                       surface_tilt)
        # Save rotation vector
        self.rotation_vec = rotation_vec

        # Calculate the solar 2D vectors for all timestamps
        self.solar_2d_vectors = _get_solar_2d_vectors(solar_zenith,
                                                      solar_azimuth,
                                                      self.axis_azimuth)
        # Calculate the angle made by 2D sun vector and x-axis
        alpha_vec = np.arctan2(self.solar_2d_vectors[1],
                               self.solar_2d_vectors[0])

        # Calculate the coordinates of all PV rows for all timestamps
        self._calculate_pvrow_elements_coords(alpha_vec, rotation_vec)

        # Calculate ground elements coordinates for all timestamps
        self.ts_ground = TsGround.from_ts_pvrows_and_angles(
            self.ts_pvrows,
            alpha_vec,
            rotation_vec,
            y_ground=self.y_ground,
            flag_overlap=self.has_direct_shading,
            param_names=self.param_names)

        # Save surface rotation angles
        self.rotation_vec = rotation_vec

        # Index all timeseries surfaces
        self._index_all_ts_surfaces()
示例#4
0
def test_ts_ground_to_geometry():

    # There should be an overlap
    shadow_coords = np.array([[[[0, 0], [0, 0]], [[2, 1], [0, 0]]],
                              [[[1, 2], [0, 0]], [[5, 5], [0, 0]]]])
    overlap = [True, False]
    cut_point_coords = [TsPointCoords.from_array(np.array([[2, 2], [0, 0]]))]

    # Test with overlap
    ts_ground = TsGround.from_ordered_shadows_coords(
        shadow_coords, flag_overlap=overlap, cut_point_coords=cut_point_coords)

    # Run some checks for index 0
    pvground = ts_ground.at(0,
                            merge_if_flag_overlap=False,
                            with_cut_points=False)
    assert pvground.n_surfaces == 4
    assert pvground.list_segments[0].illum_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.length == 5
    np.testing.assert_allclose(pvground.shaded_length, 5)

    # Run some checks for index 1
    pvground = ts_ground.at(1, with_cut_points=False)
    assert pvground.n_surfaces == 5
    assert pvground.list_segments[0].illum_collection.n_surfaces == 3
    assert pvground.list_segments[0].shaded_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.length == 4
    np.testing.assert_allclose(pvground.shaded_length, 4)

    # Run some checks for index 0, when merging
    pvground = ts_ground.at(0,
                            merge_if_flag_overlap=True,
                            with_cut_points=False)
    assert pvground.n_surfaces == 3
    assert pvground.list_segments[0].illum_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.n_surfaces == 1
    assert pvground.list_segments[0].shaded_collection.length == 5
    np.testing.assert_allclose(pvground.shaded_length, 5)

    # Run some checks for index 0, when merging and with cut points
    pvground = ts_ground.at(0,
                            merge_if_flag_overlap=True,
                            with_cut_points=True)
    assert pvground.n_surfaces == 4
    assert pvground.list_segments[0].illum_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.n_surfaces == 2
    assert pvground.list_segments[0].shaded_collection.length == 5
    np.testing.assert_allclose(pvground.shaded_length, 5)
示例#5
0
def test_ts_ground_from_ts_pvrow():
    """Check that ground geometries are created correctly from ts pvrow"""

    # Create a ts pv row
    xy_center = (0, 2)
    width = 2.
    df_inputs = pd.DataFrame({
        'rotation_vec': [20., -90., 0.],
        'shaded_length_front': [1.3, 0., 1.9],
        'shaded_length_back': [0, 0.3, 0.6]
    })
    cut = {'front': 3, 'back': 4}
    param_names = ['test1', 'test2']

    ts_pvrow = TsPVRow.from_raw_inputs(xy_center,
                                       width,
                                       df_inputs.rotation_vec,
                                       cut,
                                       df_inputs.shaded_length_front,
                                       df_inputs.shaded_length_back,
                                       param_names=param_names)

    # Create ground from it
    alpha_vec = np.deg2rad([80., 90., 70.])
    ts_ground = TsGround.from_ts_pvrows_and_angles([ts_pvrow],
                                                   alpha_vec,
                                                   df_inputs.rotation_vec,
                                                   param_names=param_names)

    assert len(ts_ground.shadow_elements) == 1
    # Check at specific times
    ground_0 = ts_ground.at(0)
    assert ground_0.n_surfaces == 4
    assert ground_0.list_segments[0].shaded_collection.n_surfaces == 1
    ground_1 = ts_ground.at(1)  # vertical, sun above
    assert ground_1.n_surfaces == 2  # only 2 illuminated surfaces
    assert ground_1.list_segments[0].shaded_collection.n_surfaces == 0
    assert ground_1.shaded_length == 0  # no shadow (since shadow length 0ish)
    np.testing.assert_allclose(ground_0.shaded_length, 1.7587704831436)
    np.testing.assert_allclose(ts_ground.at(2).shaded_length, width)  # flat
    # Check that all have surface params
    for surf in ground_0.all_surfaces:
        assert surf.param_names == param_names