Example #1
0
 def test_solar_elevation_raises_exception_hour(self):
     """Test an exception is raised if latitudes out of range"""
     utc_hour = -10.0
     msg = 'Hour must be between 0 and 24.0'
     with self.assertRaisesRegex(ValueError, msg):
         calc_solar_elevation(self.latitudes, self.longitudes,
                              self.day_of_year, utc_hour)
Example #2
0
 def test_solar_elevation_raises_exception_lat(self):
     """Test an exception is raised if latitudes out of range"""
     latitudes = np.array([-150.0, 50.0, 50.0])
     msg = 'Latitudes must be between -90.0 and 90.0'
     with self.assertRaisesRegex(ValueError, msg):
         calc_solar_elevation(latitudes, self.longitudes, self.day_of_year,
                              self.utc_hour)
Example #3
0
 def test_solar_elevation_raises_exception_day_of_year(self):
     """Test an exception is raised if latitudes out of range"""
     day_of_year = 367
     msg = 'Day of the year must be between 0 and 365'
     with self.assertRaisesRegex(ValueError, msg):
         calc_solar_elevation(self.latitudes, self.longitudes, day_of_year,
                              self.utc_hour)
Example #4
0
 def test_sine_solar_elevation(self):
     """Test the solar elevation with return_sine equal true."""
     expected_results = [-0.00803911, 0.11810263, 0.02403892, -0.11757863]
     for i, hour in enumerate([8.0, 9.0, 16.0, 17.0]):
         result = calc_solar_elevation(50.0, 0.0, 10, hour, return_sine=True)
         self.assertIsInstance(result, float)
         self.assertAlmostEqual(result, expected_results[i])
Example #5
0
 def test_basic_solar_elevation_array(self):
     """Test the solar elevation for an array of lats and lons."""
     expected_array = np.array([-3.1423043, -0.46061176, 2.09728301])
     result = calc_solar_elevation(self.latitudes, self.longitudes,
                                   self.day_of_year, self.utc_hour)
     self.assertIsInstance(result, np.ndarray)
     self.assertArrayAlmostEqual(result, expected_array)
Example #6
0
 def test_basic_solar_elevation_array_360(self):
     """Test the solar elevation for lons > 180."""
     longitudes = np.array([355.0, 0.0, 5.0])
     expected_array = np.array([-3.1423043, -0.46061176, 2.09728301])
     result = calc_solar_elevation(self.latitudes, longitudes,
                                   self.day_of_year, self.utc_hour)
     self.assertIsInstance(result, np.ndarray)
     self.assertArrayAlmostEqual(result, expected_array)
Example #7
0
 def test_basic_solar_elevation(self):
     """Test the solar elevation for a single point over several hours."""
     expected_results = [-0.460611756793, 6.78261282655,
                         1.37746106416, -6.75237871867]
     for i, hour in enumerate([8.0, 9.0, 16.0, 17.0]):
         result = calc_solar_elevation(50.0, 0.0, 10, hour)
         self.assertIsInstance(result, float)
         self.assertAlmostEqual(result, expected_results[i])
def test__calc_clearsky_ineichen_grid_properties(target_grid):
    """Test irradiance values vary over grid as expected."""
    lats, lons = get_grid_y_x_values(target_grid)

    zenith_angle = 90.0 - calc_solar_elevation(lats, lons, day_of_year=0, utc_hour=12)
    result = GenerateClearskySolarRadiation()._calc_clearsky_ineichen(
        zenith_angle=zenith_angle, day_of_year=0, surface_altitude=0, linke_turbidity=3
    )
    # For constant surface_altitude, check that max irradiance occurs for minimum zenith_angle
    assert np.unravel_index(
        np.argmax(result, axis=None), result.shape
    ) == np.unravel_index(np.argmin(zenith_angle, axis=None), zenith_angle.shape)
    # For constant surface_altitude, check that larger irradiance value at adjacent sites,
    # occurs for the location with the smaller zenith angle.
    assert np.all(
        (result[:, 1:] - result[:, :-1] > 0)
        == (zenith_angle[:, 1:] - zenith_angle[:, :-1] < 0)
    )
    assert np.all(
        (result[1:, :] - result[:-1, :] > 0)
        == (zenith_angle[1:, :] - zenith_angle[:-1, :] < 0)
    )
    def calc_sin_phi(dtval: datetime, lats: ndarray, lons: ndarray) -> ndarray:
        """
        Calculate sin of solar elevation

        Args:
            dtval:
                Date and time.
            lats:
                Array 2d of latitudes for each point
            lons:
                Array 2d of longitudes for each point

        Returns:
            Array of sine of solar elevation at each point
        """
        day_of_year = (dtval - datetime(dtval.year, 1, 1)).days
        utc_hour = (dtval.hour * 60.0 + dtval.minute) / 60.0
        sin_phi = calc_solar_elevation(lats,
                                       lons,
                                       day_of_year,
                                       utc_hour,
                                       return_sine=True)
        return sin_phi
Example #10
0
    def _calc_clearsky_solar_radiation_data(
        self,
        target_grid: Cube,
        irradiance_times: List[datetime],
        surface_altitude: ndarray,
        linke_turbidity: ndarray,
        temporal_spacing: int,
    ) -> ndarray:
        """Evaluate the gridded clearsky solar radiation data over the specified period,
        calculated on the same spatial grid points as target_grid.

        Args:
            target_grid:
                Cube containing the target spatial grid on which to evaluate irradiance.
            irradiance_times:
                Datetimes at which to evaluate the irradiance data.
            surface_altitude:
                Surface altitude data, specified in metres.
            linke_turbidity:
                Linke turbidity data.
            temporal_spacing:
                The time stepping, specified in mins, used in the integration of solar
                irradiance to produce the accumulated solar radiation.

        Returns:
            Gridded irradiance values evaluated over the specified times.
        """
        if lat_lon_determine(target_grid) is not None:
            lats, lons = transform_grid_to_lat_lon(target_grid)
        else:
            lats, lons = get_grid_y_x_values(target_grid)
        irradiance_data = np.zeros(
            shape=(
                len(irradiance_times),
                target_grid.coord(axis="Y").shape[0],
                target_grid.coord(axis="X").shape[0],
            ),
            dtype=np.float32,
        )

        for time_index, time_step in enumerate(irradiance_times):

            day_of_year = get_day_of_year(time_step)
            utc_hour = get_hour_of_day(time_step)

            zenith_angle = 90.0 - calc_solar_elevation(lats, lons, day_of_year,
                                                       utc_hour)

            irradiance_data[time_index, :, :] = self._calc_clearsky_ineichen(
                zenith_angle,
                day_of_year,
                surface_altitude=surface_altitude,
                linke_turbidity=linke_turbidity,
            )

        # integrate the irradiance data along the time dimension to get the
        # accumulated solar irradiance.
        solar_radiation_data = np.trapz(irradiance_data,
                                        dx=SECONDS_IN_MINUTE *
                                        temporal_spacing,
                                        axis=0)

        return solar_radiation_data