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; }
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)); } }
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)); } }
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); }
/// <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"/> < 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); }
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); }