Note
Go to the end to download the full example code or to run this example in your browser via Binder.
Astronomic Constants Calculation#
This notebook verifies the calculations of key coefficients found in Paul Schureman’s “Manual of Harmonic Analysis and Prediction of Tides” (Special Publication No. 98, 1940 Edition). The Python script provided has been used to recompute these values based on the astronomical constants and formulas detailed in the manual.
import dataclasses
import math
def dms_to_deg(degrees: float, minutes: float, seconds: float) -> float:
"""Converts degrees, minutes, and seconds to decimal degrees.
Args:
degrees (float): The degrees value.
minutes (float): The minutes value.
seconds (float): The seconds value.
Returns:
float: The decimal degrees value.
"""
return degrees + minutes / 60 + seconds / 3600
def round_to_4_decimal(value: float, enabled: bool = True) -> float:
"""Rounds a float to 4 decimal places.
Args:
value (float): The value to round.
enabled (bool): Whether to round the value.
Returns:
float: The rounded value.
"""
return round(value, 4) if enabled else value
@dataclasses.dataclass
class AstronomicConstants:
"""Astronomic constants used in the Manual Of Harmonic Analysis and
Prediction of Tides.
"""
#: Inclination of moon's orbit to plane of ecliptic
i: float
#: Obliquity of ecliptic
w: float
#: Eccentricity of earth's orbit
e1: float
#: Eccentricity of moon's orbit
e: float
#: Solar factor
s: float
def __str__(self) -> str:
return (
'Astronomic Constants:\n'
f' Inclination (i): {round_to_4_decimal(self.i)} rad\n'
f' Obliquity (w): {round_to_4_decimal(self.w)} rad\n'
" Eccentricity of Earth's orbit (e1): "
f'{round_to_4_decimal(self.e1)}\n'
" Eccentricity of Moon's orbit (e): "
f'{round_to_4_decimal(self.e)}\n'
f' Solar factor (s): {round_to_4_decimal(self.s)}'
)
def schureman_values() -> AstronomicConstants:
"""Returns the Schureman's values as written in the book."""
return AstronomicConstants(
i=math.radians(5.145),
w=math.radians(23.452),
e1=0.016_75,
e=0.054_90,
s=0.4602,
)
def schureman_recomputed_values() -> AstronomicConstants:
"""Returns the Schureman's values recomputed with the given values written
in the book.
"""
# Distance of the center of the earth to the center of the moon
# (in miles)
# R = 239_000
# Mass (of sun/mass) of earth (S/E)
SE = 331_954
# Mass of moon/mass of earth (M/E)
ME = 0.012_27
# Solar parallax
c1: float = math.radians(dms_to_deg(0, 0, 8.80))
# Lunar equatorial parallax
c: float = math.radians(dms_to_deg(0, 57, 2.70))
# Mean earth radius in miles
mean_earth_radius = 3_958.9
# Equatorial radius of earth in miles
earth_equatorial_radius = 3_963.37
# Mean solar parallax in respect to mean radius
ac1 = (mean_earth_radius / earth_equatorial_radius) * c1
# Mean lunar parallax in respect to mean radius
ac = (mean_earth_radius / earth_equatorial_radius) * c
# Solar coefficient U1 (SE) * ac1^3
u1: float = SE * ac1**3
# Basic factor U (ME) * ac^3
u: float = ME * ac**3
return AstronomicConstants(
i=math.radians(dms_to_deg(5, 8, 43.3546)),
w=math.radians(dms_to_deg(23, 27, 8.26)),
e1=0.016_75,
e=0.054_90,
s=u1 / u,
)
def updated_astronomic_constants() -> AstronomicConstants:
"""Provides updated astronomic constants based on IERS Conventions (2010).
The "solar factor" (s) is the ratio of the tide-generating forces of the
Sun and Moon, calculated as: s = (M_sun / M_moon) * (a_moon / a_sun)^3
This is equivalent to (S/E) / (M/E) * (a_moon / AU)^3.
References
----------
Petit, G. & Luzum, B. (eds.), *IERS Conventions (2010)*, IERS Technical
Note No. 36, Verlag des Bundesamts für Kartographie und Geodäsie,
Frankfurt am Main, 2010. ISBN 3-89888-989-6.
https://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html
Luzum, B., Capitaine, N., Fienga, A., et al. "The IAU 2009 system of
astronomical constants: the report of the IAU working group on
numerical standards for Fundamental Astronomy",
*Celestial Mechanics and Dynamical Astronomy*, 110, 293-304 (2011).
https://doi.org/10.1007/s10569-011-9352-4
IAU 2012 Resolution B2 (re-definition of the astronomical unit),
XXVIII General Assembly, Beijing.
https://www.iau.org/static/resolutions/IAU2012_English.pdf
Capitaine, N., Wallace, P. T. & Chapront, J., "Expressions for IAU 2000
precession quantities", *A&A* 412, 567-586 (2003).
https://doi.org/10.1051/0004-6361:20031539
Chapront-Touzé, M. & Chapront, J., "The lunar ephemeris ELP 2000",
*A&A* 124, 50-62 (1983).
"""
# Mass of Sun / Mass of Earth (S/E) — μ in IERS 2010 Table 1.1.
# Derived from the heliocentric (GM_sun) and geocentric (GM_earth)
# gravitational constants: GM_sun / GM_earth.
# Source: IERS Conventions (2010), Table 1.1; IAU 2009 system
# (Luzum et al. 2011).
SE = 332946.0487
# Mass of Moon / Mass of Earth (M/E).
# Source: IERS Conventions (2010), Table 1.1; IAU 2009 system
# (Luzum et al. 2011).
ME = 0.0123000371
# Semi-major axis of the lunar orbit (a_moon) in meters.
# Source: IERS Conventions (2010), Ch. 5 / JPL DE ephemerides; equivalent
# to the value used to derive Schureman's lunar equatorial parallax.
a_moon = 384399e3
# Astronomical Unit (AU) in meters — exact by definition.
# Source: IAU 2012 Resolution B2 (Beijing); adopted by IERS.
AU = 149597870700.0
# The ratio of tide-generating forces (Solar Factor 's')
# s = (SE / ME) * (a_moon / AU)**3
s = (SE / ME) * (a_moon / AU) ** 3
return AstronomicConstants(
# Inclination of the mean lunar orbit to the mean ecliptic (I).
# Source: ELP2000 (Chapront-Touzé & Chapront 1983); IERS
# Conventions (2010), Ch. 5. 5°08'43.4″ ≈ 5.14539°.
i=math.radians(dms_to_deg(5, 8, 43.4)),
# Obliquity of the ecliptic at J2000.0 (ε).
# Source: IAU 2006 precession (Capitaine, Wallace & Chapront 2003);
# IERS Conventions (2010), eq. 5.39.
w=math.radians(dms_to_deg(23, 26, 21.406)),
# Eccentricity of the Earth's mean orbit at J2000.0.
# Source: VSOP87 / IAU 2006 (Simon et al. 1994, A&A 282, 663);
# IERS Conventions (2010), Ch. 5.
e1=0.016708634,
# Eccentricity of the Moon's mean orbit.
# Source: ELP2000 (Chapront-Touzé & Chapront 1983); IERS
# Conventions (2010), Ch. 5.
e=0.0549006,
# The calculated solar factor.
s=s,
)
Note on the parallaxes used by Schureman#
Schureman uses the solar (8.80″) and lunar equatorial (0°57’02.70″) parallaxes directly. With the modern IERS 2010 / IAU 2012 lengths (a_E = 6378136.6 m, AU = 149597870700 m, a_moon = 384399 km) these become:
- π_sun = arcsin(a_E / AU) ≈ 8.794143″
(Luzum et al. 2011, IAU 2009 system)
- π_moon = arcsin(a_E / a_moon) ≈ 3422.6″ ≈ 0°57’02.6″
(IERS Conventions 2010 / JPL DE ephemerides)
Astronomical Constants Used#
The following astronomic constants, as defined by Schureman, are used for the calculations. The values are converted to radians for use in Python’s trigonometric functions.
const = schureman_values()
print(const)
Astronomic Constants:
Inclination (i): 0.0898 rad
Obliquity (w): 0.4093 rad
Eccentricity of Earth's orbit (e1): 0.0168
Eccentricity of Moon's orbit (e): 0.0549
Solar factor (s): 0.4602
Calculation Checks#
Below, each formula from the manual is presented, followed by the result from the Python script and a comparison with Schureman’s published value.
Formulae 65 & 73 (P. 24, 25)#
This formula calculates the mean value of the obliquity factor for the lunar long-period constituent \(Mm\)
f65 = 0.5021 (Schureman: 0.5021)
Formulae 66 & 74 (P. 24, 25)#
This calculates the mean obliquity factor for the lunar long-period constituent \(Mf\).
f66 = 0.1578 (Schureman: 0.1578)
Formulae 67 & 75 (P. 25)#
This calculates the mean obliquity factor for the lunar diurnal constituent \(O_1\).
f67 = 0.3800 (Schureman: 0.3800)
Formulae 68 & 76 (P. 25)#
This calculates the mean obliquity factor for the lunar diurnal constituent \(J_1\).
f68 = 0.7214 (Schureman: 0.7214)
Formulae 69 & 77 (P. 25)#
This calculates the mean obliquity factor for the lunar diurnal constituent \(OO_1\).
f69 = 0.0164 (Schureman: 0.0164)
Formulae 70 & 78 (P. 25)#
This calculates the mean obliquity factor for the principal lunar semidiurnal constituent \(M_2\).
f70 = 0.9154 (Schureman: 0.9154)
Formulae 71 & 79 (P. 25)#
This calculates a mean obliquity factor used for several semidiurnal constituents.
f71 = 0.1565 (Schureman: 0.1565)
Formulae 141 & 137 (P. 35, 36)#
This calculates a mean obliquity factor for certain long-period constituents derived from the 4th power of the moon’s parallax.
(where \(\overline{I} = \omega\))
f141 = 0.3192 (Schureman: 0.3192)
Formulae 144 & 138 (P. 35, 36)#
This calculates a mean obliquity factor for certain diurnal constituents (like \(M_1\)) derived from the 4th power of the moon’s parallax.
f144 = 0.5873 (Schureman: 0.5873)
Formulae 146 & 139 (P. 35, 36)#
This calculates a mean obliquity factor for certain semidiurnal constituents derived from the 4th power of the moon’s parallax.
(where \(\overline{I} = \omega\))
f146 = 0.3658 (Schureman: 0.3658)
Formulae 147 & 139 (P. 35, 36)#
This calculates another mean obliquity factor for semidiurnal constituents.
f147 = 0.1114 (Schureman: 0.1114)
Formula 149 (P. 36)#
This formula provides the node factor for the terdiurnal constituent \(M_3\).
f149 = 0.8758 (Schureman: 0.8758)
Formula 197 (P. 41)#
This formula calculates the components for the amplitude factor \(1/Q_a\) of the \(M_1\) tide.
(where \(I = \omega\))
This simplifies to:
Formulae 207 (P. 43)#
f197_1 = round_to_4_decimal(
(1 / 4) + (9 / 4) * (math.cos(const.w) ** 2 / math.cos(0.5 * const.w) ** 4)
)
f197_2 = round_to_4_decimal(
(3 / 2) * (math.cos(const.w) / math.cos(0.5 * const.w) ** 2)
)
print(f'f197_1 = {f197_1:.3f} (Schureman: 2.310)')
print(f'f197_2 = {f197_2:.3f} (Schureman: 1.435)')
f197_1 = 2.310 (Schureman: 2.310)
f197_2 = 1.435 (Schureman: 1.435)
Formulae 216-219 (P. 45)#
These formulas compute the coefficients for the terms that combine to form the lunisolar constituents \(K_1\) and \(K_2\).
f216 = round_to_4_decimal(1 / 2 + 3 / 4 * const.e**2)
f217 = round_to_4_decimal(
(1 / 2 + 3 / 4 * const.e1**2) * const.s * math.sin(2 * const.w)
)
f218 = round_to_4_decimal(1 / 2 + 3 / 4 * const.e**2)
f219 = round_to_4_decimal(
(1 / 2 + 3 / 4 * const.e1**2) * const.s * math.sin(const.w) ** 2
)
print(f'f216 = {f216:.4f} (Schureman: 0.5023)')
print(f'f217 = {f217:.4f} (Schureman: 0.1681)')
print(f'f218 = {f218:.4f} (Schureman: 0.5023)')
print(f'f219 = {f219:.4f} (Schureman: 0.0365)')
f216 = 0.5023 (Schureman: 0.5023)
f217 = 0.1681 (Schureman: 0.1681)
f218 = 0.5023 (Schureman: 0.5023)
f219 = 0.0365 (Schureman: 0.0365)
Formulae 224 (P. 45)#
This provides the ratio of the solar coefficient to the lunar coefficient for the K1 tide.
where \(A = 0.5023 \sin(2I)\) and \(B = 0.1681\).
f224 = 0.3347 (Schureman: 0.3347)
Formula 226 (P. 45)#
This calculates the mean value of the \(K_1\) coefficient.
f226 = 0.5305 (Schureman: 0.5305)
Formula 227 (P. 45)#
This gives the components for the node factor \(f(K_1)\).
where \(A\) and \(B\) are the coefficients for \(term A_{22}\) and \(term B_{22}\)
\(A^2=0.2523\)
\(2AB=0.1689\)
\(B^2=0.0283\)
\(A^2/0.5305=0.8665\)
\(2AB/0.5305=0.6001\)
\(B^2/0.5305=0.1006\)
denominator = f226**2
f227_1 = round_to_4_decimal(f216**2) / denominator
f227_2 = round_to_4_decimal(f216 * f217 * 2) / denominator
f227_3 = round_to_4_decimal(f217**2) / denominator
print(f'{f227_1:.4f} (Schureman: 0.8665)')
print(f'{f227_2:.4f} (Schureman: 0.6001)')
print(f'{f227_3:.4f} (Schureman: 0.1006)')
0.8965 (Schureman: 0.8665)
0.6001 (Schureman: 0.6001)
0.1006 (Schureman: 0.1006)
Formulae 232 (P. 45)#
This provides the ratio of the solar coefficient to the lunar coefficient for the K2 tide.
where \(A = 0.5023 \sin(2I)\) and \(B = 0.0365\).
f232 = 0.0727 (Schureman: 0.0727)
Formula 234 (P. 46)#
This calculates the mean value of the \(K_2\) coefficient.
f234 = 0.1151 (Schureman: 0.1151)
Formula 235 (P. 46)#
This gives the components for the node factor \(f(K_2)\).
where \(A\) and \(B\) are the coefficients for \(term A_{47}\) and \(term B_{47}\)
\(A^2=0.2523\)
\(2AB=0.0367\)
\(B^2=0.0013\)
\(A^2/0.1151=19.0444\)
\(2AB/0.1151=2.7702\)
\(B^2/0.1151=0.0981\)
denominator = f234**2
f235_1 = round_to_4_decimal(f218**2) / denominator
f235_2 = round_to_4_decimal(f218 * f219 * 2) / denominator
f235_3 = round_to_4_decimal(f219**2) / denominator
print(f'{f235_1:.4f} (Schureman: 19.0444)')
print(f'{f235_2:.4f} (Schureman: 2.7702)')
print(f'{f235_3:.4f} (Schureman: 0.0981)')
19.0444 (Schureman: 19.0444)
2.7702 (Schureman: 2.7702)
0.0981 (Schureman: 0.0981)
Formulae from Page 156#
These formulas from the “Explanation of Tables” section are fundamental for calculating the values of I, \(\nu\), and \(\xi\).
cos_i_cos_w = math.cos(const.i) * math.cos(const.w)
sin_i_sin_w = math.sin(const.i) * math.sin(const.w)
print(f'cos(i) * cos(ω) = {cos_i_cos_w:.5f} (Schureman: 0.91370)')
print(f'sin(i) * sin(ω) = {sin_i_sin_w:.5f} (Schureman: 0.03569)')
cos(i) * cos(ω) = 0.91370 (Schureman: 0.91370)
sin(i) * sin(ω) = 0.03569 (Schureman: 0.03569)
numerator = math.cos(0.5 * (const.w - const.i))
denominator = math.cos(0.5 * (const.w + const.i))
tan_coeff_1 = numerator / denominator
print(f'{tan_coeff_1:.5f} (Schureman: 1.01883)')
1.01883 (Schureman: 1.01883)
numerator = math.sin(0.5 * (const.w - const.i))
denominator = math.sin(0.5 * (const.w + const.i))
tan_coeff_2 = numerator / denominator
print(f'{tan_coeff_2:.5f} (Schureman: 0.64412)')
0.64412 (Schureman: 0.64412)
Total running time of the script: (0 minutes 0.008 seconds)