/// <summary> /// Evaluate the gravity at an arbitrary point above (or below) the ellipsoid. /// </summary> /// <param name="lat">the geographic latitude (degrees).</param> /// <param name="h">the height above the ellipsoid (meters).</param> /// <returns> /// <list type="bullet"> /// <item><i>U</i>, the corresponding normal potential (m^2 s^−2).</item> /// <item><i>gammay</i>, the northerly component of the acceleration (m s^−2).</item> /// <item><i>gammaz</i>, the upward component of the acceleration (m s−^2); this is usually negative.</item> /// </list> /// </returns> /// <remarks> /// Due to the axial symmetry of the ellipsoid, the result is independent of the value of the longitude and the easterly /// component of the acceleration vanishes, <i>gammax</i> = 0. The function includes the effects of the earth's rotation. /// When <i>h</i> = 0, this function gives <i>gammay</i> = 0 and the returned value matches that of /// <see cref="SurfaceGravity(double)"/>. /// </remarks> public (double U, double gammay, double gammaz) Gravity(double lat, double h) { Span <double> M = stackalloc double[Geocentric.dim2_]; var(X, Y, Z) = _earth.IntForward(lat, 0, h, M); var(Ures, gammaX, gammaY, gammaZ) = U(X, Y, Z); // gammax = M[0] * gammaX + M[3] * gammaY + M[6] * gammaZ; var gammay = M[1] * gammaX + M[4] * gammaY + M[7] * gammaZ; var gammaz = M[2] * gammaX + M[5] * gammaY + M[8] * gammaZ; return(Ures, gammay, gammaz); }
private (double x, double y, double z) IntForward(double lat, double lon, double h, Span <double> M) { var(xc, yc, zc) = _earth.IntForward(lat, lon, h, M); xc -= _x0; yc -= _y0; zc -= _z0; var x = _r.Span[0] * xc + _r.Span[3] * yc + _r.Span[6] * zc; var y = _r.Span[1] * xc + _r.Span[4] * yc + _r.Span[7] * zc; var z = _r.Span[2] * xc + _r.Span[5] * yc + _r.Span[8] * zc; if (M != default) { MatrixMultiply(M); } return(x, y, z); }
private (double Bx, double By, double Bz) Field(double t, double lat, double lon, double h, bool diffp, out double Bxt, out double Byt, out double Bzt) { Bxt = Byt = Bzt = default; Span <double> M = stackalloc double[Geocentric.dim2_]; var(X, Y, Z) = _earth.IntForward(lat, lon, h, M); // Components in geocentric basis // initial values to suppress warning var(BX, BY, BZ) = FieldGeocentric(t, X, Y, Z, out var BXt, out var BYt, out var BZt); if (diffp) { Geocentric.Unrotate(M, BXt, BYt, BZt, out Bxt, out Byt, out Bzt); } Geocentric.Unrotate(M, BX, BY, BZ, out var Bx, out var By, out var Bz); return(Bx, By, Bz); }