Finds lunar eclipses and computes their circumstances.
This module is the implementation behind Astro.lunar_eclipse_at_or_after/2
and Astro.lunar_eclipse_before/2, and works in moments (see
Astro.Time.moment/0).
The Earth's shadow
The Earth casts two shadows away from the Sun. The umbra is the cone in which the Sun is wholly hidden by the Earth; the penumbra is the wider cone in which it is partly hidden. At the Moon's distance both are circles centred on the shadow axis, the point opposite the Sun, and a lunar eclipse is the Moon passing through them. It can only happen at a full moon, and only near a node of the Moon's orbit, because otherwise the Moon passes north or south of both circles.
Seen from the centre of the Earth, the radii of the two circles are
penumbra Rp = 1.01 πm + ss + πs
umbra Ru = 1.01 πm − ss + πswhere πm and πs are the Moon's and the Sun's equatorial horizontal
parallaxes, the angles the Earth's equatorial radius subtends at each,
and ss is the Sun's angular semi-diameter. The factor 1.01 is
Danjon's enlargement of the shadows for the Earth's atmosphere, a layer
about 75 km deep that stops sunlight as the solid Earth does,
1 + 1/85 − 1/594, the last term for the Earth's flattening at 45°.
This is the convention of NASA's eclipse catalogues. The older almanac
convention, Chauvenet's, multiplies the radii by 1.02 instead,
penumbra Rp = 1.02 (0.99834 πm + ss + πs)
umbra Ru = 1.02 (0.99834 πm − ss + πs)which makes the umbral magnitude about 0.006 larger and can make an eclipse at the limit total where Danjon's makes it partial.
Greatest eclipse, gamma and magnitude
The Moon's angular distance σ from the shadow axis is least at
greatest eclipse. Gamma is that least distance in equatorial
radii of the Earth, positive when the Moon passes north of the axis.
The penumbral and umbral magnitudes are the fractions of the Moon's
diameter inside each shadow at greatest eclipse,
penumbral magnitude = (Rp + sm − σ) / 2sm
umbral magnitude = (Ru + sm − σ) / 2smwhere sm is the Moon's angular semi-diameter. An eclipse is total
when the umbral magnitude is at least 1, partial when it is between 0
and 1, and penumbral when only the penumbral magnitude is positive.
The contacts
The eclipse begins when the Moon's limb first touches the penumbra
(P1) and ends when it leaves it (P4). A partial or total eclipse has
two more contacts with the umbra, U1 and U4, and a total eclipse two
more, U2 and U3, between which the Moon is wholly inside the umbra.
Each is the instant σ equals a shadow's radius plus or minus sm,
found by bisection either side of greatest eclipse.
The contacts happen at the same instants wherever the Moon is seen;
Astro.Lunar.Eclipse.Local gives the Moon's altitude at each from a
place, and whether the eclipse is seen there.
Positions
The Sun's and the Moon's apparent geocentric positions and distances
are those of Astro.sun_position_at/1 and Astro.moon_position_at/1:
from the JPL ephemeris where the loaded kernel covers the moment, and
from the analytical series elsewhere.
Summary
Types
The kind of lunar eclipse: the Moon passes through the penumbra only, partly into the umbra, or wholly into it.
The convention for enlarging the Earth's shadows: Danjon's, used by NASA's catalogues, or Chauvenet's, the older almanac convention.
A lunar eclipse. Every instant is a UTC DateTime.t/0; the umbral
contacts are nil for an eclipse that does not reach them, and the
Saros series is numbered as NASA numbers it (Astro.Saros).
Functions
Returns the circumstances of the first lunar eclipse whose greatest eclipse is at or after a moment.
Returns the circumstances of the last lunar eclipse whose greatest eclipse is before a moment.
Returns the geometry of the Earth's shadow and the Moon at a moment.
Types
@type eclipse_type() :: :penumbral | :partial | :total
The kind of lunar eclipse: the Moon passes through the penumbra only, partly into the umbra, or wholly into it.
@type shadow() :: :danjon | :chauvenet
The convention for enlarging the Earth's shadows: Danjon's, used by NASA's catalogues, or Chauvenet's, the older almanac convention.
@type t() :: %Astro.Lunar.Eclipse{ gamma: float(), greatest: DateTime.t(), partial_begins: DateTime.t() | nil, partial_ends: DateTime.t() | nil, penumbral_begins: DateTime.t(), penumbral_ends: DateTime.t(), penumbral_magnitude: float(), saros: integer(), total_begins: DateTime.t() | nil, total_ends: DateTime.t() | nil, type: eclipse_type(), umbral_magnitude: float() }
A lunar eclipse. Every instant is a UTC DateTime.t/0; the umbral
contacts are nil for an eclipse that does not reach them, and the
Saros series is numbered as NASA numbers it (Astro.Saros).
Functions
@spec eclipse_at_or_after(Astro.Time.moment(), shadow()) :: {:ok, map()} | {:error, :no_eclipse}
Returns the circumstances of the first lunar eclipse whose greatest eclipse is at or after a moment.
Arguments
tis aAstro.Time.moment/0within 50,000 years of J2000.shadowis the enlargement convention,:danjonor:chauvenet.
Returns
{:ok, circumstances}, a map with the keys oft/0, every instant a moment and every missing contactnil.{:error, :no_eclipse}if none is found within 13 lunations, which does not happen.
Examples
iex> {:ok, eclipse} = Astro.Lunar.Eclipse.eclipse_at_or_after(739_600.0, :danjon)
iex> {eclipse.type, Float.round(eclipse.umbral_magnitude, 3)}
{:total, 1.178}
@spec eclipse_before(Astro.Time.moment(), shadow()) :: {:ok, map()} | {:error, :no_eclipse}
Returns the circumstances of the last lunar eclipse whose greatest eclipse is before a moment.
Arguments
tis aAstro.Time.moment/0within 50,000 years of J2000.shadowis the enlargement convention,:danjonor:chauvenet.
Returns
{:ok, circumstances}, a map with the keys oft/0, every instant a moment and every missing contactnil.{:error, :no_eclipse}if none is found within 13 lunations, which does not happen.
Examples
iex> {:ok, eclipse} = Astro.Lunar.Eclipse.eclipse_before(739_700.0, :danjon)
iex> eclipse.type
:total
@spec geometry(Astro.Time.moment(), shadow()) :: %{ distance: float(), penumbra: float(), umbra: float(), semi_diameter: float(), gamma: float() }
Returns the geometry of the Earth's shadow and the Moon at a moment.
Arguments
tis aAstro.Time.moment/0.shadowis the enlargement convention,:danjonor:chauvenet.
Returns
- A map with these keys, every angle in degrees:
:distance— the Moon's angular distance from the shadow axis,σ.:penumbraand:umbra— the radii of the shadows at the Moon,RpandRu.:semi_diameter— the Moon's angular semi-diameter,sm.:gamma—σin equatorial radii of the Earth at the Moon's distance, positive when the Moon is north of the axis.
Examples
iex> geometry = Astro.Lunar.Eclipse.geometry(739_689.2917, :danjon)
iex> Float.round(geometry.gamma, 3)
0.349