Skip to content

Commit

Permalink
Correct hour angle for longitude
Browse files Browse the repository at this point in the history
Previously, hour angle was calculated at longitude 0, which was incorrect.
  • Loading branch information
Halvor Lund committed Jun 3, 2024
1 parent 99b0869 commit b88ba0b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 12 deletions.
5 changes: 5 additions & 0 deletions docs/api/equations/solar_angles.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Solar angles
-------------

.. automodule:: linerate.equations.solar_angles
:members:
2 changes: 1 addition & 1 deletion examples/plot_solar_heating_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# ^^^^^^^^^^^^^^^^^^^^^
time = np.datetime64("2022-06-01T13:00")

omega = solar_angles.compute_hour_angle_relative_to_noon(time)
omega = solar_angles.compute_hour_angle_relative_to_noon(time, 0)
delta = solar_angles.compute_solar_declination(time)

vals_with_range = {
Expand Down
14 changes: 10 additions & 4 deletions linerate/equations/solar_angles.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def _get_minute_of_hour(when: Date) -> Unitless:
return (when.astype(MinuteResolutionType) - when.astype(HourResolutionType)).astype(float)


def compute_hour_angle_relative_to_noon(when: Date) -> Radian:
def compute_hour_angle_relative_to_noon(when: Date, longitude: Degrees) -> Radian:
r"""Compute the hour angle.
Described in the text on p. 18 of :cite:p:`ieee738`. The hour angle is the number of hours
Expand All @@ -35,6 +35,9 @@ def compute_hour_angle_relative_to_noon(when: Date) -> Radian:
which is the same as 15^\circ.
The hour angle is used when calculating the solar altitude.
This function does not take into account the difference between apparent/actual
and mean solar time, which means that the result may be up to 15 minutes from the
correct hour angle.
Parameters
----------
Expand All @@ -46,10 +49,13 @@ def compute_hour_angle_relative_to_noon(when: Date) -> Radian:
Union[float, float64, ndarray[Any, dtype[float64]]]
:math:'\omega~\left[\text{radian}\right]`. The hour angle relative to noon.
"""
hour = _get_hour_of_day(when)
minute = _get_minute_of_hour(when)
utc_hour = _get_hour_of_day(when)
utc_minute = _get_minute_of_hour(when)
pi = np.pi
return (-12 + hour + minute / 60) * (pi / 12) # pi/12 is 15 degrees
# We add longitude/15 since 15 degrees of longitude increases solar hour by 1
return np.mod((-12 + utc_hour + utc_minute / 60 + longitude / 15), 24) * (
pi / 12
) # pi/12 is 15 degrees


def compute_solar_declination(
Expand Down
4 changes: 2 additions & 2 deletions linerate/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def compute_solar_heating(
N_s = self.weather.clearness_ratio
D = self.span.conductor.conductor_diameter

omega = solar_angles.compute_hour_angle_relative_to_noon(self.time)
omega = solar_angles.compute_hour_angle_relative_to_noon(self.time, self.span.longitude)
delta = solar_angles.compute_solar_declination(self.time)
sin_H_s = solar_angles.compute_sin_solar_altitude(phi, delta, omega)
chi = solar_angles.compute_solar_azimuth_variable(phi, delta, omega)
Expand Down Expand Up @@ -491,7 +491,7 @@ def compute_solar_heating(
y = self.span.conductor_altitude # H_e in IEEE
D = self.span.conductor.conductor_diameter # D_0 in IEEE

omega = solar_angles.compute_hour_angle_relative_to_noon(self.time)
omega = solar_angles.compute_hour_angle_relative_to_noon(self.time, self.span.longitude)
delta = solar_angles.compute_solar_declination(self.time)
sin_H_c = solar_angles.compute_sin_solar_altitude(phi, delta, omega)
Q_s = ieee738.solar_heating.compute_total_heat_flux_density(sin_H_c, True)
Expand Down
18 changes: 13 additions & 5 deletions tests/equations/test_solar_angles.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ def test_get_minute_of_hour_with_example():
def test_hour_angle_relative_to_noon_with_example():
when = np.datetime64("2022-06-01T12:00")
omega = 0
assert solar_angles.compute_hour_angle_relative_to_noon(when) == approx(omega)
assert solar_angles.compute_hour_angle_relative_to_noon(when, 0) == approx(omega)


def test_hour_angle_relative_to_noon_norway():
when = np.datetime64("2022-12-01T12:00+01:00")
omega = 0
longitude = 15 # Longitude at timezone +01:00
assert solar_angles.compute_hour_angle_relative_to_noon(when, longitude) == approx(omega)


def test_solar_azimuth_variable_with_example():
Expand Down Expand Up @@ -119,12 +126,13 @@ def test_solar_declination_scales_correctly_with_day_of_year(day):
when=st.datetimes(
min_value=datetime.datetime(2022, 1, 1, 1, 0),
max_value=datetime.datetime(2022, 12, 31, 23, 0),
)
),
longitude=st.floats(min_value=-180, max_value=180),
)
def test_solar_declination_scales_with_dates_and_times(when):
omega = (-12 + when.hour + when.minute / 60) * np.pi / 12
def test_solar_declination_scales_with_dates_and_times(when, longitude):
omega = ((-12 + when.hour + when.minute / 60 + longitude / 15) % 24) * np.pi / 12
when = np.datetime64(when)
assert omega == approx(solar_angles.compute_hour_angle_relative_to_noon(when))
assert omega == approx(solar_angles.compute_hour_angle_relative_to_noon(when, longitude))


def test_solar_declination_with_examples():
Expand Down

0 comments on commit b88ba0b

Please sign in to comment.