public CelestialLongitudes(int year, int julianDay, int hours) { double doubleHour = hours; int leapDaysSince1901 = ((year - 1901) / 4); //number of leap days between 1901 and Jan 1 of year double yearsSince1900 = year - 1900; //number of years since 1900 double additionalDays = julianDay + leapDaysSince1901 - 1; // julian Day + leap days. this.LongitudeOfMoonsNode = 259.1560564 - 19.328185764 * yearsSince1900 - .0529539336 * additionalDays - .0022064139 * doubleHour; this.LongitudeOfMoonsNode = MathFuncs.Angle(LongitudeOfMoonsNode); this.LongitudeOfLunarPerigee = 334.3837214 + 40.66246584 * yearsSince1900 + .111404016 * additionalDays + .004641834 * doubleHour; this.LongitudeOfLunarPerigee = MathFuncs.Angle(this.LongitudeOfLunarPerigee); this.LongitudeOfSun = 280.1895014 - .238724988 * yearsSince1900 + .9856473288 * additionalDays + .0410686387 * doubleHour; this.LongitudeOfSun = MathFuncs.Angle(LongitudeOfSun); this.LongitudeOfSolarPerigee = 281.2208569 + .01717836 * yearsSince1900 + .000047064 * additionalDays + .000001961 * doubleHour; this.LongitudeOfSolarPerigee = MathFuncs.Angle(LongitudeOfSolarPerigee); this.LongitudeOfMoon = 277.0256206 + 129.38482032 * yearsSince1900 + 13.176396768 * additionalDays + .549016532 * doubleHour; this.LongitudeOfMoon = MathFuncs.Angle(LongitudeOfMoon); // the following calculations are based on the Manual Of Harmonic Analysis and Prediction of Tides by Paul Schureman // I, from Schureman p156 first equation. Values for each degree of longitude of Moon's node given in Schureman table 6. double N = MathFuncs.DegreesToRadians(LongitudeOfMoonsNode); double IRadians = Math.Acos(.9136949 - .0356926 * Math.Cos(N)); this.Schureman_I = MathFuncs.Angle(MathFuncs.RadiansToDegrees(IRadians)); // little V, Schureman p156. Values for each degree of longitude of Moon's node given in Schureman table 6. double vRadians = Math.Asin(.0897056 * Math.Sin(N) / Math.Sin(IRadians)); this.Schureman_v = MathFuncs.RadiansToDegrees(vRadians); //v // epsilon, Schureman p 156, third equation. Values for each degree of longitude of Moon's node given in Schureman table 6. double epsilonRadians = N - 2.0 * Math.Atan(.64412 * Math.Tan(N / 2.0)) - vRadians; this.Schureman_e = MathFuncs.RadiansToDegrees(epsilonRadians); // used for node factor calculations double NUP = Math.Atan(Math.Sin(vRadians) / (Math.Cos(vRadians) + .334766 / Math.Sin(2.0 * IRadians))); this.DNUP = MathFuncs.RadiansToDegrees(NUP); // used for node factor calculations double NUP2 = Math.Atan(Math.Sin(2.0 * vRadians) / (Math.Cos(2.0 * vRadians) + .0726184 / (Math.Sin(IRadians) * Math.Sin(IRadians)))) / 2.0; this.DNUP2 = MathFuncs.RadiansToDegrees(NUP2); // P is the mean longitude of the lunar perigee reckoned from the lunar intersection. // Equation 191, Schureman p 41 this.Schureman_P = MathFuncs.Angle(this.LongitudeOfLunarPerigee - this.Schureman_e); }
/// <summary> /// Calculate the phases of all constituents of the theoretical equilibrium tide, for the start of the epoch /// </summary> /// <param name="epochStartYear">Year of epoch start</param> /// <param name="epochStartJulianDay">day of epoch start</param> /// <param name="epochStartHour">hour of epoch start</param> /// <param name="halfEpochLengthInHours">One half of epoch length in hours</param> private void CalculateEquilibriumPhases(int epochStartYear, int epochStartJulianDay, int epochStartHour, int halfEpochLengthInHours) { // get celestial longitudes for start of the epoch CelestialLongitudes startOfEpochLongitudes = new CelestialLongitudes(epochStartYear, epochStartJulianDay, epochStartHour); double S = startOfEpochLongitudes.LongitudeOfMoon; double P = startOfEpochLongitudes.LongitudeOfLunarPerigee; double H = startOfEpochLongitudes.LongitudeOfSun; double P1 = startOfEpochLongitudes.LongitudeOfSolarPerigee; double T = MathFuncs.Angle(180.0 + epochStartHour * (360.0 / 24.0)); // hour angle of mean sun at place of observation // get values based on longitude of moon's node, these are calculated from the middle of the epoch. CelestialLongitudes middleOfEpochLongitudes = new CelestialLongitudes(epochStartYear, epochStartJulianDay, halfEpochLengthInHours); double NU = middleOfEpochLongitudes.Schureman_v; //v double XI = middleOfEpochLongitudes.Schureman_e; //e double NUP = middleOfEpochLongitudes.DNUP; double NUP2 = middleOfEpochLongitudes.DNUP2; // now fill in the equilibrium phases of the Harmonic Constituents. // equations from The Manual of Harmonic analysis and Prediction of Tides by Paul Schureman page 22. this.Constituents[Constants.M2].EquilibriumPhase = MathFuncs.Angle(2.0 * (T - S + H) + 2.0 * (XI - NU)); this.Constituents[Constants.S2].EquilibriumPhase = MathFuncs.Angle(2.0 * T); this.Constituents[Constants.N2].EquilibriumPhase = MathFuncs.Angle(2.0 * (T + H) - 3.0 * S + P + 2.0 * (XI - NU)); this.Constituents[Constants.K1].EquilibriumPhase = MathFuncs.Angle(T + H - 90.0 - NUP); this.Constituents[Constants.M4].EquilibriumPhase = MathFuncs.Angle(4.0 * (T - S + H) + 4.0 * (XI - NU)); this.Constituents[Constants.O1].EquilibriumPhase = MathFuncs.Angle(T - 2.0 * S + H + 90.0 + 2.0 * XI - NU); this.Constituents[Constants.M6].EquilibriumPhase = MathFuncs.Angle(6.0 * (T - S + H) + 6.0 * (XI - NU)); this.Constituents[Constants.MK3].EquilibriumPhase = MathFuncs.Angle(3.0 * (T + H) - 2.0 * S - 90.0 + 2.0 * (XI - NU) - NUP); this.Constituents[Constants.S4].EquilibriumPhase = MathFuncs.Angle(4.0 * T); this.Constituents[Constants.MN4].EquilibriumPhase = MathFuncs.Angle(4.0 * (T + H) - 5.0 * S + P + 4.0 * (XI - NU)); this.Constituents[Constants.NU2].EquilibriumPhase = 2.0 * T - 3.0 * S + 4.0 * H - P + 2.0 * (XI - NU); this.Constituents[Constants.S6].EquilibriumPhase = 6.0 * T; this.Constituents[Constants.MU2].EquilibriumPhase = 2.0 * (T + 2.0 * (H - S)) + 2.0 * (XI - NU); this.Constituents[Constants._2N2].EquilibriumPhase = 2.0 * (T - 2.0 * S + H + P) + 2.0 * (XI - NU); this.Constituents[Constants.OO1].EquilibriumPhase = T + 2.0 * S + H - 90.0 - 2.0 * XI - NU; this.Constituents[Constants.LAMBDA2].EquilibriumPhase = 2.0 * T - S + P + 180.0 + 2.0 * (XI - NU); this.Constituents[Constants.S1].EquilibriumPhase = T; double I = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_I); double PC = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_P); double TOP = (5.0 * Math.Cos(I) - 1.0) * Math.Sin(PC); double BOTTOM = (7.0 * Math.Cos(I) + 1.0) * Math.Cos(PC); double Q = MathFuncs.Arctan(TOP, BOTTOM, 1); this.Constituents[Constants.M1].EquilibriumPhase = T - S + H - 90.0 + XI - NU + Q; this.Constituents[Constants.J1].EquilibriumPhase = T + S + H - P - 90.0 - NU; this.Constituents[Constants.MM].EquilibriumPhase = S - P; this.Constituents[Constants.SSA].EquilibriumPhase = 2.0 * H; this.Constituents[Constants.SA].EquilibriumPhase = H; this.Constituents[Constants.MSF].EquilibriumPhase = 2.0 * (S - H); this.Constituents[Constants.MF].EquilibriumPhase = 2.0 * S - 2.0 * XI; this.Constituents[Constants.RHO1].EquilibriumPhase = T + 3.0 * (H - S) - P + 90.0 + 2.0 * XI - NU; this.Constituents[Constants.Q1].EquilibriumPhase = T - 3.0 * S + H + P + 90.0 + 2.0 * XI - NU; this.Constituents[Constants.T2].EquilibriumPhase = 2.0 * T - H + P1; this.Constituents[Constants.R2].EquilibriumPhase = 2.0 * T + H - P1 + 180.0; this.Constituents[Constants._2Q1].EquilibriumPhase = T - 4.0 * S + H + 2.0 * P + 90.0 + 2.0 * XI - NU; this.Constituents[Constants.P1].EquilibriumPhase = T - H + 90.0; this.Constituents[Constants._2SM2].EquilibriumPhase = 2.0 * (T + S - H) + 2.0 * (NU - XI); this.Constituents[Constants.M3].EquilibriumPhase = 3.0 * (T - S + H) + 3.0 * (XI - NU); double R = Math.Sin(2.0 * PC) / ((1.0 / 6.0) * (1.0 / Math.Tan(0.5 * I)) * (1.0 / Math.Tan(0.5 * I)) - Math.Cos(2.0 * PC)); R = MathFuncs.RadiansToDegrees(Math.Atan(R)); this.Constituents[Constants.L2].EquilibriumPhase = 2.0 * (T + H) - S - P + 180.0 + 2.0 * (XI - NU) - R; this.Constituents[Constants._2MK3].EquilibriumPhase = 3.0 * (T + H) - 4.0 * S + 90.0 + 4.0 * (XI - NU) + NUP; this.Constituents[Constants.K2].EquilibriumPhase = 2.0 * (T + H) - 2.0 * NUP2; this.Constituents[Constants.M8].EquilibriumPhase = 8.0 * (T - S + H) + 8.0 * (XI - NU); this.Constituents[Constants.MS4].EquilibriumPhase = 2.0 * (2.0 * T - S + H) + 2.0 * (XI - NU); for (int index = 0; index < Constants.ConstitutentArraySize; index++) { this.Constituents[index].EquilibriumPhase = MathFuncs.Angle(this.Constituents[index].EquilibriumPhase); } }