Exemplo n.º 1
0
        public static int ValidateInputs(ref SPAData spa)
        {
            if ((spa.Year < -2000) || (spa.Year > 6000)) return 1;
            if ((spa.Month < 1) || (spa.Month > 12)) return 2;
            if ((spa.Day < 1) || (spa.Day > 31)) return 3;
            if ((spa.Hour < 0) || (spa.Hour > 24)) return 4;
            if ((spa.Minute < 0) || (spa.Minute > 59)) return 5;
            if ((spa.Second < 0) || (spa.Second >= 60)) return 6;
            if ((spa.Pressure < 0) || (spa.Pressure > 5000)) return 12;
            if ((spa.Temperature <= -273) || (spa.Temperature > 6000)) return 13;
            if ((spa.DeltaUt1 <= -1) || (spa.DeltaUt1 >= 1)) return 17;
            if ((spa.Hour == 24) && (spa.Minute > 0)) return 5;
            if ((spa.Hour == 24) && (spa.Second > 0)) return 6;

            if (Math.Abs(spa.DeltaT) > 8000) return 7;
            if (Math.Abs(spa.Timezone) > 18) return 8;
            if (Math.Abs(spa.Longitude) > 180) return 9;
            if (Math.Abs(spa.Latitude) > 90) return 10;
            if (Math.Abs(spa.AtmosRefract) > 5) return 16;
            if (spa.Elevation < -6500000) return 11;

            if ((spa.Function == CalculationMode.SPA_ZA_INC) || (spa.Function == CalculationMode.SPA_ALL))
            {
                if (Math.Abs(spa.Slope) > 360) return 14;
                if (Math.Abs(spa.AzmRotation) > 360) return 15;
            }

            return 0;
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            var timer = new Stopwatch();

            timer.Start();
            var     dic  = new Dictionary <DateTime, Data>();
            SPAData data = new SPAData
            {
                Year         = 2020,
                Month        = 1,
                Day          = 1,
                Hour         = 1,
                Minute       = 0,
                Second       = 0,
                DeltaUt1     = 0,
                DeltaT       = 0,
                Timezone     = 2,
                Latitude     = 54.5421,
                Longitude    = 23.57262,
                Elevation    = 76,
                Pressure     = 993,
                Temperature  = 20,
                Slope        = 0,
                AzmRotation  = 0,
                AtmosRefract = 0.5667,
            };

            var endTime = new DateTime(2021, 1, 1, 1, 1, 1);

            for (var time = new DateTime(2020, 1, 1, 1, 1, 1); time < endTime; time = time.AddMinutes(1.0))
            {
                data.Month  = time.Month;
                data.Day    = time.Day;
                data.Hour   = time.Hour;
                data.Minute = time.Minute;
                SPACalculate(ref data);
                dic.Add(time, new Data {
                    Azimuth = data.Azimuth, Zenith = data.Zenith
                });
            }
            timer.Stop();
        }
Exemplo n.º 3
0
        public static int SPACalculate(ref SPAData spa)
        {
            var result = ValidateInputs(ref spa);

            if (result == 0)
            {
                spa.Jd = JulianDay(spa.Year, spa.Month, spa.Day, spa.Hour,
                    spa.Minute, spa.Second, spa.DeltaUt1, spa.Timezone);

                CalculateGeocentricSunRightAscensionAndDeclination(ref spa);

                spa.H = ObserverHourAngle(spa.Nu, spa.Longitude, spa.Alpha);
                spa.Xi = SunEquatorialHorizontalParallax(spa.R);

                RightAscensionParallaxAndTopocentricDec(spa.Latitude, spa.Elevation, spa.Xi,
                    spa.H, spa.Delta, ref spa.DelAlpha, ref spa.DeltaPrime);

                spa.AlphaPrime = TopocentricRightAscension(spa.Alpha, spa.DelAlpha);
                spa.HPrime = TopocentricLocalHourAngle(spa.H, spa.DelAlpha);

                spa.E0 = TopocentricElevationAngle(spa.Latitude, spa.DeltaPrime, spa.HPrime);
                spa.DelE = AtmosphericRefractionCorrection(spa.Pressure, spa.Temperature,
                    spa.AtmosRefract, spa.E0);
                spa.E = TopocentricElevationAngleCorrected(spa.E0, spa.DelE);

                spa.Zenith = TopocentricZenithAngle(spa.E);
                spa.AzimuthAstro = TopocentricAzimuthAngleAstro(spa.HPrime, spa.Latitude,
                    spa.DeltaPrime);
                spa.Azimuth = TopocentricAzimuthAngle(spa.AzimuthAstro);

                if ((spa.Function == CalculationMode.SPA_ZA_INC) || (spa.Function == CalculationMode.SPA_ALL))
                    spa.Incidence = SurfaceIncidenceAngle(spa.Zenith, spa.AzimuthAstro,
                        spa.AzmRotation, spa.Slope);

                if ((spa.Function == CalculationMode.SPA_ZA_RTS) || (spa.Function == CalculationMode.SPA_ALL))
                    CalculateEOTAndSunRiseTransitSet(ref spa);
            }

            return result;
        }
Exemplo n.º 4
0
        static void CalculateGeocentricSunRightAscensionAndDeclination(ref SPAData spa)
        {
            double[] x = new double[(int)TERM2.TERM_X_COUNT];

            spa.Jc = JulianCentury(spa.Jd);

            spa.Jde = JulianEphemerisDay(spa.Jd, spa.DeltaT);
            spa.Jce = JulianEphemerisCentury(spa.Jde);
            spa.Jme = JulianEphemerisMillennium(spa.Jce);

            spa.L = EarthHeliocentricLongitude(spa.Jme);
            spa.B = EarthHeliocentricLatitude(spa.Jme);
            spa.R = EarthRadiusVector(spa.Jme);

            spa.Theta = GeocentricLongitude(spa.L);
            spa.Beta = GeocentricLatitude(spa.B);

            x[(int)TERM2.TERM_X0] = spa.X0 = MeanElongationMoonSun(spa.Jce);
            x[(int)TERM2.TERM_X1] = spa.X1 = MeanAnomalySun(spa.Jce);
            x[(int)TERM2.TERM_X2] = spa.X2 = MeanAnomalyMoon(spa.Jce);
            x[(int)TERM2.TERM_X3] = spa.X3 = ArgumentLatitudeMoon(spa.Jce);
            x[(int)TERM2.TERM_X4] = spa.X4 = AscendingLongitudeMoon(spa.Jce);

            NutationLongitudeAndObliquity(spa.Jce, x, ref spa.DelPsi, ref spa.DelEpsilon);

            spa.Epsilon0 = EclipticMeanObliquity(spa.Jme);
            spa.Epsilon = EclipticTrueObliquity(spa.DelEpsilon, spa.Epsilon0);

            spa.DelTau = AberrationCorrection(spa.R);
            spa.Lamda = ApparentSunLongitude(spa.Theta, spa.DelPsi, spa.DelTau);
            spa.Nu0 = GreenwichMeanSiderealTime(spa.Jd, spa.Jc);
            spa.Nu = GreenwichSiderealTime(spa.Nu0, spa.DelPsi, spa.Epsilon);

            spa.Alpha = GeocentricRightAscension(spa.Lamda, spa.Epsilon, spa.Beta);
            spa.Delta = GeocentricDeclination(spa.Beta, spa.Epsilon, spa.Lamda);
        }
Exemplo n.º 5
0
        static void CalculateEOTAndSunRiseTransitSet(ref SPAData spa)
        {
            double[] alpha = new double[(int)TERM4.JD_COUNT], delta = new double[(int)TERM4.JD_COUNT];
            double[] mRts = new double[(int)TERM5.SUN_COUNT],
                nuRts = new double[(int)TERM5.SUN_COUNT],
                hRts = new double[(int)TERM5.SUN_COUNT];
            double[] alphaPrime = new double[(int)TERM5.SUN_COUNT],
                deltaPrime = new double[(int)TERM5.SUN_COUNT],
                hPrime = new double[(int)TERM5.SUN_COUNT];
            double h0Prime = -1 * (SunRadius + spa.AtmosRefract);
            int i;

            SPAData sunRts = spa;

            var m = SunMeanLongitude(spa.Jme);
            spa.Eot = EquationOfTime(m, spa.Alpha, spa.DelPsi, spa.Epsilon);

            sunRts.Hour = sunRts.Minute = 0;
            sunRts.Second = 0;
            sunRts.DeltaUt1 = sunRts.Timezone = 0.0;

            sunRts.Jd = JulianDay(sunRts.Year, sunRts.Month, sunRts.Day, sunRts.Hour,
                sunRts.Minute, sunRts.Second, sunRts.DeltaUt1, sunRts.Timezone);

            CalculateGeocentricSunRightAscensionAndDeclination(ref sunRts);
            var nu = sunRts.Nu;

            sunRts.DeltaT = 0;
            sunRts.Jd--;

            for (i = 0; i < (int)TERM4.JD_COUNT; i++)
            {
                CalculateGeocentricSunRightAscensionAndDeclination(ref sunRts);
                alpha[i] = sunRts.Alpha;
                delta[i] = sunRts.Delta;
                sunRts.Jd++;
            }

            mRts[(int)TERM5.SUN_TRANSIT] = ApproxSunTransitTime(alpha[(int)TERM4.JD_ZERO], spa.Longitude, nu);
            var h0 = SunHourAngleAtRiseSet(spa.Latitude, delta[(int)TERM4.JD_ZERO], h0Prime);

            if (h0 >= 0)
            {
                ApproxSunRiseAndSet(ref mRts, h0);

                for (i = 0; i < (int)TERM5.SUN_COUNT; i++)
                {

                    nuRts[i] = nu + 360.985647 * mRts[i];

                    var n = mRts[i] + spa.DeltaT / 86400.0;
                    alphaPrime[i] = RtsAlphaDeltaPrime(ref alpha, n);
                    deltaPrime[i] = RtsAlphaDeltaPrime(ref delta, n);

                    hPrime[i] = LimitDegrees180pm(nuRts[i] + spa.Longitude - alphaPrime[i]);

                    hRts[i] = RtsSunAltitude(spa.Latitude, deltaPrime[i], hPrime[i]);
                }

                spa.Srha = hPrime[(int)TERM5.SUN_RISE];
                spa.Ssha = hPrime[(int)TERM5.SUN_SET];
                spa.Sta = hRts[(int)TERM5.SUN_TRANSIT];

                spa.Suntransit =
                    DayFracToLocalHr(mRts[(int)TERM5.SUN_TRANSIT] - hPrime[(int)TERM5.SUN_TRANSIT] / 360.0,
                        spa.Timezone);

                spa.Sunrise = DayFracToLocalHr(SunRiseAndSet(ref mRts, ref hRts, ref deltaPrime,
                    spa.Latitude, ref hPrime, h0Prime, (int)TERM5.SUN_RISE), spa.Timezone);

                spa.Sunset = DayFracToLocalHr(SunRiseAndSet(ref mRts, ref hRts, ref deltaPrime,
                    spa.Latitude, ref hPrime, h0Prime, (int)TERM5.SUN_SET), spa.Timezone);

            }
            else spa.Srha = spa.Ssha = spa.Sta = spa.Suntransit = spa.Sunrise = spa.Sunset = -99999;
        }