Example #1
0
        ///////////////////////////////////////////////////////////////////////////////////////////
        // Calculate all SPA parameters and put into structure
        // Note: All inputs values (listed in header file) must already be in structure
        ///////////////////////////////////////////////////////////////////////////////////////////

        #region Calculate all SPA parameters and put into structure

        public int spa_calculate(ref SpaData spa)
        {
            int result;

            result = validate_inputs(ref spa);

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

                calculate_geocentric_sun_right_ascension_and_declination(ref spa);

                spa.H  = observer_hour_angle(spa.Nu, spa.Longitude, spa.Alpha);
                spa.Xi = sun_equatorial_horizontal_parallax(spa.R);

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

                spa.AlphaPrime = topocentric_sun_right_ascension(spa.Alpha, spa.DelAlpha);
                spa.HPrime     = topocentric_local_hour_angle(spa.H, spa.DelAlpha);

                spa.E0   = topocentric_elevation_angle(spa.Latitude, spa.DeltaPrime, spa.HPrime);
                spa.DelE = atmospheric_refraction_correction(spa.Pressure, spa.Temperature,
                                                             spa.AtmosRefract, spa.E0);
                spa.E = topocentric_elevation_angle_corrected(spa.E0, spa.DelE);

                spa.Zenith     = topocentric_zenith_angle(spa.E);
                spa.Azimuth180 = topocentric_azimuth_angle_neg180_180(spa.HPrime, spa.Latitude,
                                                                      spa.DeltaPrime);
                spa.Azimuth = topocentric_azimuth_angle_zero_360(spa.Azimuth180);

                if ((spa.Function == (int)SpaSelect.SpaZaInc) || (spa.Function == (int)SpaSelect.SpaAll))
                {
                    spa.Incidence = surface_incidence_angle(spa.Zenith, spa.Azimuth180,
                                                            spa.AzmRotation, spa.Slope);
                }

                if ((spa.Function == (int)SpaSelect.SpaZaRts) || (spa.Function == (int)SpaSelect.SpaAll))
                {
                    calculate_eot_and_sun_rise_transit_set(ref spa);
                }
            }

            return(result);
        }
Example #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////
        // Calculate required SPA parameters to get the right ascension (alpha) and declination (delta)
        // Note: JD must be already calculated and in structure
        ////////////////////////////////////////////////////////////////////////////////////////////////

        #region SPA

        public void calculate_geocentric_sun_right_ascension_and_declination(ref SpaData spa)
        {
            double[] x = new double[(int)TermX.TermXCount];

            spa.Jc = julian_century(spa.Jd);

            spa.Jde = julian_ephemeris_day(spa.Jd, spa.DeltaT);
            spa.Jce = julian_ephemeris_century(spa.Jde);
            spa.Jme = julian_ephemeris_millennium(spa.Jce);

            spa.L = earth_heliocentric_longitude(spa.Jme);
            spa.B = earth_heliocentric_latitude(spa.Jme);
            spa.R = earth_radius_vector(spa.Jme);

            spa.Theta = geocentric_longitude(spa.L);
            spa.Beta  = geocentric_latitude(spa.B);

            x[(int)TermX.TermX0] = spa.X0 = mean_elongation_moon_sun(spa.Jce);
            x[(int)TermX.TermX1] = spa.X1 = mean_anomaly_sun(spa.Jce);
            x[(int)TermX.TermX2] = spa.X2 = mean_anomaly_moon(spa.Jce);
            x[(int)TermX.TermX3] = spa.X3 = argument_latitude_moon(spa.Jce);
            x[(int)TermX.TermX4] = spa.X4 = ascending_longitude_moon(spa.Jce);

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

            spa.Epsilon0 = ecliptic_mean_obliquity(spa.Jme);
            spa.Epsilon  = ecliptic_true_obliquity(spa.DelEpsilon, spa.Epsilon0);

            spa.DelTau = aberration_correction(spa.R);
            spa.Lamda  = apparent_sun_longitude(spa.Theta, spa.DelPsi, spa.DelTau);
            spa.Nu0    = greenwich_mean_sidereal_time(spa.Jd, spa.Jc);
            spa.Nu     = greenwich_sidereal_time(spa.Nu0, spa.DelPsi, spa.Epsilon);

            spa.Alpha = geocentric_sun_right_ascension(spa.Lamda, spa.Epsilon, spa.Beta);
            spa.Delta = geocentric_sun_declination(spa.Beta, spa.Epsilon, spa.Lamda);
        }
Example #3
0
        ///////////////////////////////////////////////////////////////////////////////////////////////
        public int validate_inputs(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 > 59))
            {
                return(6);
            }
            if ((spa.Pressure < 0) || (spa.Pressure > 5000))
            {
                return(12);
            }
            if ((spa.Temperature <= -273) || (spa.Temperature > 6000))
            {
                return(13);
            }
            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 == (int)SpaSelect.SpaZaInc) || (spa.Function == (int)SpaSelect.SpaAll))
            {
                if (Math.Abs(spa.Slope) > 360)
                {
                    return(14);
                }
                if (Math.Abs(spa.AzmRotation) > 360)
                {
                    return(15);
                }
            }

            return(0);
        }
Example #4
0
 public Spa()
 {
     spa = new SpaData();
 }
Example #5
0
        ////////////////////////////////////////////////////////////////////////
        // Calculate Equation of Time (EOT) and Sun Rise, Transit, & Set (RTS)
        ////////////////////////////////////////////////////////////////////////

        #region Calculate Equation of Time (EOT) and Sun Rise, Transit, & Set (RTS)

        private void calculate_eot_and_sun_rise_transit_set(ref SpaData spa)
        {
            SpaData sunRts;
            double  nu, m, h0, n;

            double[] alpha      = new double[(int)Julian.JdCount];
            double[] delta      = new double[(int)Julian.JdCount];
            double[] mRts       = new double[(int)SunTerm.SunCount];
            double[] nuRts      = new double[(int)SunTerm.SunCount];
            double[] hRts       = new double[(int)SunTerm.SunCount];
            double[] alphaPrime = new double[(int)SunTerm.SunCount];
            double[] deltaPrime = new double[(int)SunTerm.SunCount];
            double[] hPrime     = new double[(int)SunTerm.SunCount];
            double   h0Prime    = -1 * (SunRadius + spa.AtmosRefract);
            int      i;

            sunRts  = spa;
            m       = sun_mean_longitude(spa.Jme);
            spa.Eot = Eot(m, spa.Alpha, spa.DelPsi, spa.Epsilon);

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

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

            calculate_geocentric_sun_right_ascension_and_declination(ref sunRts);
            nu = sunRts.Nu;

            sunRts.DeltaT = 0;
            sunRts.Jd--;
            for (i = 0; i < (int)Julian.JdCount; i++)
            {
                calculate_geocentric_sun_right_ascension_and_declination(ref sunRts);
                alpha[i] = sunRts.Alpha;
                delta[i] = sunRts.Delta;
                sunRts.Jd++;
            }

            mRts[(int)SunTerm.SunTransit] = approx_sun_transit_time(alpha[(int)Julian.JdZero], spa.Longitude, nu);
            h0 = sun_hour_angle_at_rise_set(spa.Latitude, delta[(int)Julian.JdZero], h0Prime);

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

                for (i = 0; i < (int)SunTerm.SunCount; i++)
                {
                    nuRts[i] = nu + 360.985647 * mRts[i];

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

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

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

                spa.Srha = hPrime[(int)SunTerm.SunRise];
                spa.Ssha = hPrime[(int)SunTerm.SunSet];
                spa.Sta  = hRts[(int)SunTerm.SunTransit];

                spa.Suntransit = dayfrac_to_local_hr(mRts[(int)SunTerm.SunTransit] - hPrime[(int)SunTerm.SunTransit] / 360.0,
                                                     spa.Timezone);

                spa.Sunrise = dayfrac_to_local_hr(sun_rise_and_set(ref mRts, ref hRts, ref deltaPrime,
                                                                   spa.Latitude, ref hPrime, h0Prime, (int)SunTerm.SunRise), spa.Timezone);

                spa.Sunset = dayfrac_to_local_hr(sun_rise_and_set(ref mRts, ref hRts, ref deltaPrime,
                                                                  spa.Latitude, ref hPrime, h0Prime, (int)SunTerm.SunSet), spa.Timezone);
            }
            else
            {
                spa.Srha = spa.Ssha = spa.Sta = spa.Suntransit = spa.Sunrise = spa.Sunset = -99999;
            }
        }