Exemple #1
0
        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);
        }
Exemple #2
0
        /// <summary>
        /// Calculate node factors that are used to modify the amplitude of each tidal constituent
        /// </summary>
        /// <param name="epochStartYear">The epoch start year</param>
        /// <param name="epochStartJulianDay">The epoch start day</param>
        /// <param name="halfEpochLengthInHours">One half of epoch length in hours</param>
        private void CalculateNodeFactors(int epochStartYear, int epochStartJulianDay, int halfEpochLengthInHours)
        {
            CelestialLongitudes middleOfEpochLongitudes = new CelestialLongitudes(epochStartYear, epochStartJulianDay, halfEpochLengthInHours);

            ///CalculateCelestialLongitudes(epochStartYear, epochStartJulianDay, halfEpochLengthInHours);
            double N     = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.LongitudeOfMoonsNode);
            double I     = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_I);
            double NU    = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_v);
            double XI    = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_e);
            double P     = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.LongitudeOfLunarPerigee);
            double PC    = MathFuncs.DegreesToRadians(middleOfEpochLongitudes.Schureman_P);
            double SINI  = Math.Sin(I);
            double SINI2 = Math.Sin(I / 2.0);
            double SIN2I = Math.Sin(2.0 * I);
            double COSI2 = Math.Cos(I / 2.0);
            double TANI2 = Math.Tan(I / 2.0);

            // Equations are from Schureman pp 25-45
            double EQ197 = Math.Sqrt(2.310 + 1.435 * Math.Cos(2.0 * PC));
            double EQ213 = Math.Sqrt(1.0 - 12.0 * TANI2 * TANI2 * Math.Cos(2.0 * PC) + 36.0 * TANI2 * TANI2 * TANI2 * TANI2);
            double EQ73  = (2.0 / 3.0 - SINI * SINI) / 0.5021;
            double EQ74  = SINI * SINI / 0.1578;
            double EQ75  = SINI * COSI2 * COSI2 / 0.37988;
            double EQ76  = Math.Sin(2.0 * I) / 0.7214;
            double EQ77  = SINI * SINI2 * SINI2 / 0.0164;
            double EQ78  = (COSI2 * COSI2 * COSI2 * COSI2) / 0.91544;
            double EQ149 = COSI2 * COSI2 * COSI2 * COSI2 * COSI2 * COSI2 / 0.8758;
            double EQ207 = EQ75 * EQ197;
            double EQ215 = EQ78 * EQ213;
            double EQ227 = Math.Sqrt(0.8965 * SIN2I * SIN2I + 0.6001 * SIN2I * Math.Cos(NU) + 0.1006);
            double EQ235 = 0.001 + Math.Sqrt(19.0444 * SINI * SINI * SINI * SINI + 2.7702 * SINI * SINI * Math.Cos(2.0 * NU) + 0.0981);

            // Node factor calculations from Schureman p 25
            this.Constituents[Constants.M2].NodeFactor      = EQ78;
            this.Constituents[Constants.S2].NodeFactor      = 1.0;
            this.Constituents[Constants.N2].NodeFactor      = EQ78;
            this.Constituents[Constants.K1].NodeFactor      = EQ227;
            this.Constituents[Constants.M4].NodeFactor      = EQ78 * EQ78;
            this.Constituents[Constants.O1].NodeFactor      = EQ75;
            this.Constituents[Constants.M6].NodeFactor      = EQ78 * EQ78 * EQ78;
            this.Constituents[Constants.MK3].NodeFactor     = EQ78 * EQ227;
            this.Constituents[Constants.S4].NodeFactor      = 1.0;
            this.Constituents[Constants.MN4].NodeFactor     = EQ78 * EQ78;
            this.Constituents[Constants.NU2].NodeFactor     = EQ78;
            this.Constituents[Constants.S6].NodeFactor      = 1.0;
            this.Constituents[Constants.MU2].NodeFactor     = EQ78;
            this.Constituents[Constants._2N2].NodeFactor    = EQ78;
            this.Constituents[Constants.OO1].NodeFactor     = EQ77;
            this.Constituents[Constants.LAMBDA2].NodeFactor = EQ78;
            this.Constituents[Constants.S1].NodeFactor      = 1.0;
            // equation 207 not working.
            //this.Constituents[Constants.M1].NodeFactor = EQ207;
            this.Constituents[Constants.M1].NodeFactor    = 1.0;
            this.Constituents[Constants.J1].NodeFactor    = EQ76;
            this.Constituents[Constants.MM].NodeFactor    = EQ73;
            this.Constituents[Constants.SSA].NodeFactor   = 1.0;
            this.Constituents[Constants.SA].NodeFactor    = 1.0;
            this.Constituents[Constants.MSF].NodeFactor   = EQ78;
            this.Constituents[Constants.MF].NodeFactor    = EQ74;
            this.Constituents[Constants.RHO1].NodeFactor  = EQ75;
            this.Constituents[Constants.Q1].NodeFactor    = EQ75;
            this.Constituents[Constants.T2].NodeFactor    = 1.0;
            this.Constituents[Constants.R2].NodeFactor    = 1.0;
            this.Constituents[Constants._2Q1].NodeFactor  = EQ75;
            this.Constituents[Constants.P1].NodeFactor    = 1.0;
            this.Constituents[Constants._2SM2].NodeFactor = EQ78;
            this.Constituents[Constants.M3].NodeFactor    = EQ149;
            // equation 215 is not working.
            //this.Constituents[Constants.L2].NodeFactor = EQ215;
            this.Constituents[Constants.L2].NodeFactor    = 1.0;
            this.Constituents[Constants._2MK3].NodeFactor = EQ78 * EQ78 * EQ227;
            this.Constituents[Constants.K2].NodeFactor    = EQ235;
            this.Constituents[Constants.M8].NodeFactor    = EQ78 * EQ78 * EQ78 * EQ78;
            this.Constituents[Constants.MS4].NodeFactor   = EQ78;
        }
Exemple #3
0
        /// <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);
            }
        }
 /// <summary>
 /// this is the derivative of the RateOfChange function, it returns the acceleration of the tide
 /// Same units (probably feet or meters) per hour per hour as the amplitude
 /// </summary>
 /// <param name="hours">hours since epoch start</param>
 /// <returns>the acceleration of the tide</returns>
 public double AccelerationOfChange(double hours)
 {
     return(-1 * Amplitude * NodeFactor * (Math.PI / 180) * Speed * (Math.PI / 180) * Speed * Math.Cos(MathFuncs.DegreesToRadians(Speed * hours + EquilibriumPhase - Phase)));
 }
 /// <summary>
 /// Calculate the height of this constituent.  Same units (probably feet or meters) as the amplitude
 /// </summary>
 /// <param name="h">the number of hours since the start of the epoch that the equilibrium phases are based on.</param>
 /// <returns>the height of this harmonic constituent</returns>
 public double Height(double hours)
 {
     return(Amplitude * NodeFactor * Math.Cos(MathFuncs.DegreesToRadians(Speed * hours + EquilibriumPhase - Phase)));
 }