예제 #1
0
 public SphericalHarmonicsPanel()
 {
     InitializeComponent();
     try
     {
         m_sh0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT);
         m_sh1 = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.FULL);
         m_sh2 = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.FULL);
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     m_classComboBox.SelectedIndex = 0;
 }
예제 #2
0
 public SphericalHarmonicsPanel()
 {
     InitializeComponent();
     try
     {
         m_sh0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT);
         m_sh1 = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.FULL);
         m_sh2 = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.FULL);
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     m_classComboBox.SelectedIndex = 0;
 }
 static void Main(string[] args)
 {
     try {
         int N = 3, N1 = 2;                  // The maximum degrees
         double[] ca = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
         double[] sa = {6, 5, 4, 3, 2, 1}; // sine coefficients
         double[] cb = {1, 2, 3, 4, 5, 6};
         double[] sb = {3, 2, 1};
         double a = 1;
         SphericalHarmonic1 h = new SphericalHarmonic1(ca, sa, N, cb, sb, N1, a, SphericalHarmonic1.Normalization.SCHMIDT);
         double tau = 0.1, x = 2, y = 3, z = 1;
         double v, vx, vy, vz;
         v = h.HarmonicSum(tau, x, y, z, out vx, out vy, out vz);
         Console.WriteLine(String.Format("{0} {1} {2} {3}", v, vx, vy, vz));
     }
     catch (GeographicErr e) {
         Console.WriteLine(String.Format("Caught exception: {0}", e.Message));
     }
 }
예제 #4
0
 static void Main(string[] args)
 {
     try {
         int                N = 3, N1 = 2;                          // The maximum degrees
         double[]           ca = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; // cosine coefficients
         double[]           sa = { 6, 5, 4, 3, 2, 1 };              // sine coefficients
         double[]           cb = { 1, 2, 3, 4, 5, 6 };
         double[]           sb = { 3, 2, 1 };
         double             a = 1;
         SphericalHarmonic1 h = new SphericalHarmonic1(ca, sa, N, cb, sb, N1, a, SphericalHarmonic1.Normalization.SCHMIDT);
         double             tau = 0.1, x = 2, y = 3, z = 1;
         double             v, vx, vy, vz;
         v = h.HarmonicSum(tau, x, y, z, out vx, out vy, out vz);
         Console.WriteLine(String.Format("{0} {1} {2} {3}", v, vx, vy, vz));
     }
     catch (GeographicErr e) {
         Console.WriteLine(String.Format("Caught exception: {0}", e.Message));
     }
 }
예제 #5
0
 private void OnValidate(object sender, EventArgs e)
 {
     try
     {
         const double      DEG_TO_RAD = 3.1415926535897932384626433832795 / 180.0;
         double            gradx, grady, gradz;
         SphericalHarmonic s0 = new SphericalHarmonic(C, S, N, N - 1, 0, a, SphericalHarmonic.Normalization.SCHMIDT);
         s0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT);
         double sum  = s0.HarmonicSum(1.0, 2.0, 3.0);
         double test = s0.HarmonicSum(1.0, 2.0, 3.0, out gradx, out grady, out grady);
         if (sum != test)
         {
             throw new Exception("Error in SphericalHarmonic.HarmonicSum");
         }
         SphericalCoefficients sc = s0.Coefficients();
         CircularEngine        ce = s0.Circle(1.0, 0.5, true);
         sum  = ce.LongitudeSum(60.0);
         test = ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD));
         if (sum != test)
         {
             throw new Exception("Error in CircularEngine.LongitudeSum 1");
         }
         test = ce.LongitudeSum(60.0, out gradx, out grady, out gradz);
         if (sum != test)
         {
             throw new Exception("Error in CircularEngine.LongitudeSum 2");
         }
         ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD), out gradx, out grady, out gradz);
         if (sum != test)
         {
             throw new Exception("Error in CircularEngine.LongitudeSum 3");
         }
         SphericalHarmonic1 s1 = new SphericalHarmonic1(C, S, N, N - 1, 1, C1, S1, N1, N1 - 1, 0, a, SphericalHarmonic1.Normalization.SCHMIDT);
         s1   = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.SCHMIDT);
         sum  = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0);
         test = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0, out gradx, out grady, out gradz);
         if (sum != test)
         {
             throw new Exception("Error in SphericalHarmonic1.HarmonicSum 3");
         }
         ce = s1.Circle(0.95, 1.0, 0.5, true);
         sc = s1.Coefficients();
         sc = s1.Coefficients1();
         SphericalHarmonic2 s2 = new SphericalHarmonic2(C, S, N, N - 1, 2, C1, S1, N1, N1 - 1, 1,
                                                        C2, S2, N2, N2 - 1, 0, a, SphericalHarmonic2.Normalization.SCHMIDT);
         s2   = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.SCHMIDT);
         sum  = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0);
         test = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0, out gradx, out grady, out gradz);
         if (sum != test)
         {
             throw new Exception("Error in SphericalHarmonic2.HarmonicSum 3");
         }
         ce = s2.Circle(0.95, 0.8, 1.0, 0.5, true);
         sc = s2.Coefficients();
         sc = s2.Coefficients1();
         sc = s2.Coefficients2();
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
         return;
     }
     MessageBox.Show("No errors found", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
 }
예제 #6
0
        /// <summary>
        /// Construct a gravity model.
        /// </summary>
        /// <param name="name">the name of the model.</param>
        /// <param name="path">directory for data file.</param>
        /// <param name="Nmax">if non-negative, truncate the degree of the model this value.</param>
        /// <param name="Mmax">if non-negative, truncate the order of the model this value.</param>
        /// <remarks>
        /// A filename is formed by appending ".egm" (World Gravity Model) to the <paramref name="name"/>.
        /// If <paramref name="path"/> is specified (and is non-empty), then the file is loaded from directory, <paramref name="path"/>.
        /// Otherwise the <paramref name="path"/> is given by <see cref="DefaultGravityPath"/>.
        /// <para>
        /// This file contains the metadata which specifies the properties of the model.
        /// The coefficients for the spherical harmonic sums are obtained from a file obtained by appending ".cof"
        /// to metadata file (so the filename ends in ".egm.cof").
        /// </para>
        /// <para>
        /// If <paramref name="Nmax"/> ≥ 0 and <paramref name="Mmax"/> &lt; 0, then <paramref name="Mmax"/> is set to <paramref name="Nmax"/>.
        /// After the model is loaded, the maximum degree and order of the model can be found by the <see cref="Degree"/> and <see cref="Order"/> methods.
        /// </para>
        /// </remarks>
        public GravityModel(string name, string path = "", int Nmax = -1, int Mmax = -1)
        {
            _name        = name;
            _dir         = path;
            _description = "NONE";
            _amodel      = double.NaN;
            _GMmodel     = double.NaN;
            _zeta0       = 0;
            _corrmult    = 1;
            _nmx         = -1;
            _mmx         = -1;
            _norm        = Normalization.Full;

            if (string.IsNullOrWhiteSpace(path))
            {
                _dir = DefaultGravityPath;
            }
            bool truncate = Nmax >= 0 || Mmax >= 0;

            if (truncate)
            {
                if (Nmax >= 0 && Mmax < 0)
                {
                    Mmax = Nmax;
                }
                if (Nmax < 0)
                {
                    Nmax = int.MaxValue;
                }
                if (Mmax < 0)
                {
                    Mmax = int.MaxValue;
                }
            }
            ReadMetadata(_name, ref _filename, ref _name, ref _description, ref _date, ref _amodel, ref _GMmodel,
                         ref _zeta0, ref _corrmult, ref _norm, ref _id, ref _earth);

            double[] _Cx, _Sx;
            string   coeff = _filename + ".cof";

            using (var coeffstr = File.OpenRead(coeff))
            {
                Span <byte> id = stackalloc byte[idlength_];
                if (coeffstr.Read(id) != idlength_)
                {
                    throw new GeographicException("No header in " + coeff);
                }
                if (MemoryMarshal.Cast <char, byte>(_id.AsSpan()).SequenceEqual(id))
                {
                    throw new GeographicException($"ID mismatch: {_id} vs {Encoding.ASCII.GetString(id.ToArray())}");
                }
                int N = 0, M = 0;
                if (truncate)
                {
                    N = Nmax; M = Mmax;
                }

                var scoeff = SphericalEngine.Coeff.FromStream(coeffstr, ref N, ref M, truncate);
                _Cx = new double[scoeff.Cnm.Length];
                _Sx = new double[scoeff.Snm.Length];
                scoeff.Cnm.CopyTo(_Cx);
                scoeff.Snm.CopyTo(_Sx);

                if (!(N >= 0 && M >= 0))
                {
                    throw new GeographicException("Degree and order must be at least 0");
                }
                if (_Cx[0] != 0)
                {
                    throw new GeographicException("The degree 0 term should be zero");
                }

                _Cx[0]         = 1;       // Include the 1/r term in the sum
                _gravitational = new SphericalHarmonic(_Cx, _Sx, N, N, M, _amodel, _norm);
                if (truncate)
                {
                    N = Nmax; M = Mmax;
                }


                scoeff = SphericalEngine.Coeff.FromStream(coeffstr, ref N, ref M, truncate);
                double[] _CC, _CS;
                if (N < 0)
                {
                    N   = M = 0;
                    _CC = new[] { 0d };
                }
                else
                {
                    _CC = new double[scoeff.Cnm.Length];
                    scoeff.Cnm.CopyTo(_CC);
                }

                _CS = new double[scoeff.Snm.Length];
                scoeff.Snm.CopyTo(_CS);

                _CC[0]     += _zeta0 / _corrmult;
                _correction = new SphericalHarmonic(_CC, _CS, N, N, M, 1, _norm);
                var pos = (int)coeffstr.Position;
                coeffstr.Seek(0, SeekOrigin.End);
                if (pos != coeffstr.Position)
                {
                    throw new GeographicException("Extra data in " + coeff);
                }
            }
            int nmx = _gravitational.Coefficients.Nmx;

            _nmx = Max(nmx, _correction.Coefficients.Nmx);
            _mmx = Max(_gravitational.Coefficients.Mmx,
                       _correction.Coefficients.Mmx);
            // Adjust the normalization of the normal potential to match the model.
            var mult  = _earth._GM / _GMmodel;
            var amult = Sq(_earth._a / _amodel);
            // The 0th term in _zonal should be is 1 + _dzonal0.  Instead set it to 1
            // to give exact cancellation with the (0,0) term in the model and account
            // for _dzonal0 separately.
            var _zonal = new List <double> {
                1
            };

            _dzonal0 = (_earth.MassConstant - _GMmodel) / _GMmodel;
            for (int n = 2; n <= nmx; n += 2)
            {
                // Only include as many normal zonal terms as matter.  Figuring the limit
                // in this way works because the coefficients of the normal potential
                // (which is smooth) decay much more rapidly that the corresponding
                // coefficient of the model potential (which is bumpy).  Typically this
                // goes out to n = 18.
                mult *= amult;
                double
                    r = _Cx[n],                                // the model term
                    s = -mult *_earth.Jn(n) / Sqrt(2 * n + 1), // the normal term
                    t = r - s;                                 // the difference

                if (t == r)                                    // the normal term is negligible
                {
                    break;
                }
                _zonal.Add(0);      // index = n - 1; the odd terms are 0
                _zonal.Add(s);
            }
            int nmx1 = _zonal.Count - 1;
            var za   = _zonal.ToArray();

            _disturbing = new SphericalHarmonic1(_Cx, _Sx,
                                                 _gravitational.Coefficients.N,
                                                 nmx, _gravitational.Coefficients.Mmx,
                                                 za,
                                                 za, // This is not accessed!
                                                 nmx1, nmx1, 0,
                                                 _amodel,
                                                 _norm);
        }
예제 #7
0
 private void OnValidate(object sender, EventArgs e)
 {
     try
     {
         const double DEG_TO_RAD = 3.1415926535897932384626433832795 / 180.0;
         double gradx, grady, gradz;
         SphericalHarmonic s0 = new SphericalHarmonic(C, S, N, N - 1, 0, a, SphericalHarmonic.Normalization.SCHMIDT);
         s0 = new SphericalHarmonic(C, S, N, a, SphericalHarmonic.Normalization.SCHMIDT);
         double sum = s0.HarmonicSum(1.0, 2.0, 3.0);
         double test = s0.HarmonicSum(1.0, 2.0, 3.0, out gradx, out grady, out grady);
         if (sum != test)
             throw new Exception("Error in SphericalHarmonic.HarmonicSum");
         SphericalCoefficients sc = s0.Coefficients();
         CircularEngine ce = s0.Circle(1.0, 0.5, true);
         sum = ce.LongitudeSum(60.0);
         test = ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD));
         if ( sum != test )
             throw new Exception("Error in CircularEngine.LongitudeSum 1");
         test = ce.LongitudeSum(60.0, out gradx, out grady, out gradz);
         if ( sum != test )
             throw new Exception("Error in CircularEngine.LongitudeSum 2");
         ce.LongitudeSum(Math.Cos(60.0 * DEG_TO_RAD), Math.Sin(60.0 * DEG_TO_RAD), out gradx, out grady, out gradz);
         if (sum != test)
             throw new Exception("Error in CircularEngine.LongitudeSum 3");
         SphericalHarmonic1 s1 = new SphericalHarmonic1(C, S, N, N - 1, 1, C1, S1, N1, N1 - 1, 0, a, SphericalHarmonic1.Normalization.SCHMIDT);
         s1 = new SphericalHarmonic1(C, S, N, C1, S1, N1, a, SphericalHarmonic1.Normalization.SCHMIDT);
         sum = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0);
         test = s1.HarmonicSum(0.95, 1.0, 2.0, 3.0, out gradx, out grady, out gradz);
         if (sum != test)
             throw new Exception("Error in SphericalHarmonic1.HarmonicSum 3");
         ce = s1.Circle(0.95, 1.0, 0.5, true);
         sc = s1.Coefficients();
         sc = s1.Coefficients1();
         SphericalHarmonic2 s2 = new SphericalHarmonic2(C, S, N, N - 1, 2, C1, S1, N1, N1 - 1, 1,
             C2, S2, N2, N2 - 1, 0, a, SphericalHarmonic2.Normalization.SCHMIDT);
         s2 = new SphericalHarmonic2(C, S, N, C1, S1, N1, C2, S2, N2, a, SphericalHarmonic2.Normalization.SCHMIDT);
         sum = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0);
         test = s2.HarmonicSum(0.95, 0.8, 1.0, 2.0, 3.0, out gradx, out grady, out gradz);
         if (sum != test)
             throw new Exception("Error in SphericalHarmonic2.HarmonicSum 3");
         ce = s2.Circle(0.95, 0.8, 1.0, 0.5, true);
         sc = s2.Coefficients();
         sc = s2.Coefficients1();
         sc = s2.Coefficients2();
     }
     catch (Exception xcpt)
     {
         MessageBox.Show(xcpt.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
         return;
     }
     MessageBox.Show("No errors found", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
 }