/// <summary> /// Calculate DeltaT /// </summary> /// <remarks> /// delta t is adjusted to the tidal acceleration that is compatible /// with the ephemeris mode contained in ephemerisMode and with the ephemeris /// files made accessible through swe_set_ephe_path() or swe_set_jplfile(). /// If ephemerisMode is null, then the default tidal acceleration is ussed(i.e. that of DE431). /// </remarks> /// <see cref="calc_deltat"/> /// <returns>DeltaT (ET - UT) in days</returns> public static double Calc(JulianDayNumber julianDay, DeltaTMode deltaTMode, EphemerisMode?ephemerisMode) { var tidalAcceleration = ephemerisMode is null ? TidalAcceleration.Get(JPLDENumber.Default) : TidalAcceleration.Calculate(ephemerisMode.Value, julianDay, JPLDENumber.Auto); if (deltaTMode == DeltaTMode.Stephenson_Etc_2016 && julianDay < JulianDayNumber.J1955) { double deltaT = DeltaTStephensonEtc2016.Calc(julianDay, tidalAcceleration); if (julianDay >= JulianDayNumber.J1952_05_04) { deltaT += (1.0 - (double)(JulianDayNumber.J1955 - julianDay) / 1000.0) * 0.6610218 / 86400.0; } return(deltaT); } if (deltaTMode == DeltaTMode.Espenak_Meeus_2006 && julianDay < J1633) { return(DeltaTEspenakMeeus1620.Calc(julianDay, tidalAcceleration)); } var year = julianDay.GetYear(); // delta t model used in SE 1.72 - 1.76: Stephenson & Morrison 2004; before 1620 if (deltaTMode == DeltaTMode.Stephenson_Morrison_2004 && year < DeltaTTabulated.TabStart) { // before 1600: if (year < DeltaTTabulated.Tab2End) { return(DeltaTStephensonMorrison2004_1600.Calc(julianDay, tidalAcceleration)); } else { // between 1600 and 1620: // linear interpolation between end of table dt2 and start of table dt return(DeltaTTabulated.CalcInterpolated(year, julianDay.GetGregorianYear(), tidalAcceleration)); } } /* delta t model used before SE 1.64: * Stephenson/Morrison 1984 with Borkowski 1988; * before 1620 */ if (deltaTMode == DeltaTMode.Stephenson_Morrison_1984 && year < DeltaTTabulated.TabStart) { double B; double ans; if (year >= 948.0) { /* Stephenson and Morrison, stated domain is 948 to 1600: * 25.5(centuries from 1800)^2 - 1.9159(centuries from 1955)^2 */ B = 0.01 * (year - 2000.0); ans = (23.58 * B + 100.3) * B + 101.6; } else { /* Borkowski, before 948 and between 1600 and 1620 */ B = 0.01 * (year - 2000.0) + 3.75; ans = 35.0 * B * B + 40.0; } return(ans / 86400.0); } /* 1620 - today + a few years (tabend): * Tabulated values of deltaT from Astronomical Almanac * (AA 1997etc., pp. K8-K9) and from IERS * (http://maia.usno.navy.mil/ser7/deltat.data). */ if (year >= DeltaTTabulated.TabStart) { return(DeltaTTabulated.Calc(julianDay, tidalAcceleration, deltaTMode)); } return(0); }
/// <summary> /// The tabulated values of deltaT, in hundredths of a second, /// were taken from The Astronomical Almanac 1997etc., pp.K8-K9. /// Some more recent values are taken from IERS /// http://maia.usno.navy.mil/ser7/deltat.data . /// </summary> /// <remarks> /// Bessel's interpolation formula is implemented to obtain fourth /// order interpolated values at intermediate times. /// The values are adjusted depending on the ephemeris used /// and its inherent value of secular tidal acceleration ndot. /// Note by Dieter Jan. 2017: /// Bessel interpolation assumes equidistant sampling points. However the /// sampling points are not equidistant, because they are for first January of /// every year and years can have either 365 or 366 days.The interpolation uses /// a step width of 365.25 days.As a consequence, in three out of four years /// the interpolation does not reproduce the exact values of the sampling points /// on the days they refer to. /// </remarks> /// <see cref="deltat_aa"/> public static double Calc(JulianDayNumber tjd, double tid_acc, DeltaTMode mode) { double ans, ans2 = 0, ans3; double p, B, B2, Y, dd; double[] d = new double[6]; int i, iy, k; Y = tjd.GetYear(); if (Y <= TabEnd) { // Index into the table. p = Math.Floor(Y); iy = (int)(p - TabStart); /* Zeroth order estimate is value at start of year */ ans = dt[iy]; k = iy + 1; if (k >= TabSize) { goto done; /* No data, can't go on. */ } /* The fraction of tabulation interval */ p = Y - p; /* First order interpolated value */ ans += p * (dt[k] - dt[iy]); if ((iy - 1 < 0) || (iy + 2 >= TabSize)) { goto done; /* can't do second differences */ } /* Make table of first differences */ k = iy - 2; for (i = 0; i < 5; i++) { if ((k < 0) || (k + 1 >= TabSize)) { d[i] = 0; } else { d[i] = dt[k + 1] - dt[k]; } k += 1; } /* Compute second differences */ for (i = 0; i < 4; i++) { d[i] = d[i + 1] - d[i]; } B = 0.25 * p * (p - 1.0); ans += B * (d[1] + d[2]); if (iy + 2 >= TabSize) { goto done; } /* Compute third differences */ for (i = 0; i < 3; i++) { d[i] = d[i + 1] - d[i]; } B = 2.0 * B / 3.0; ans += (p - 0.5) * B * d[1]; if ((iy - 2 < 0) || (iy + 3 > TabSize)) { goto done; } /* Compute fourth differences */ for (i = 0; i < 2; i++) { d[i] = d[i + 1] - d[i]; } B = 0.125 * B * (p + 1.0) * (p - 2.0); ans += B * (d[0] + d[1]); done: ans = TidalAcceleration.AdjustForTidalAcceleration(ans, Y, tid_acc, TidalAccelerationMode.Const26, false); return(ans / 86400.0); } /* today - future: * 3rd degree polynomial based on data given by * Stephenson/Morrison/Hohenkerk 2016 here: * http://astro.ukho.gov.uk/nao/lvm/ */ if (mode == DeltaTMode.Stephenson_Etc_2016) { B = Y - 2000; if (Y < 2500) { ans = B * B * B * 121.0 / 30000000.0 + B * B / 1250.0 + B * 521.0 / 3000.0 + 64.0; /* for slow transition from tablulated data */ B2 = TabEnd - 2000; ans2 = B2 * B2 * B2 * 121.0 / 30000000.0 + B2 * B2 / 1250.0 + B2 * 521.0 / 3000.0 + 64.0; /* we use a parable after 2500 */ } else { B = 0.01 * (Y - 2000); ans = B * B * 32.5 + 42.5; } /* * Formula Stephenson (1997; p. 507), * with modification to avoid jump at end of AA table, * similar to what Meeus 1998 had suggested. * Slow transition within 100 years. */ } else { B = 0.01 * (Y - 1820); ans = -20 + 31 * B * B; /* for slow transition from tablulated data */ B2 = 0.01 * (TabEnd - 1820); ans2 = -20 + 31 * B2 * B2; } /* slow transition from tabulated values to Stephenson formula: */ if (Y <= TabEnd + 100) { ans3 = dt[TabSize - 1]; dd = (ans2 - ans3); ans += dd * (Y - (TabEnd + 100)) * 0.01; } return(ans / 86400.0); }