use of org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics in project Orekit by CS-SI.
the class CachedNormalizedSphericalHarmonicsProviderTest method testInterpolation.
@Test
public void testInterpolation() throws OrekitException {
// setup
// generate points on grid with date as the origin
cache.onDate(date);
// sample at step/2
AbsoluteDate sampleDate = date.shiftedBy(step / 2.0);
// expected values
NormalizedSphericalHarmonics expected = raw.onDate(sampleDate);
// action
NormalizedSphericalHarmonics actual = cache.onDate(sampleDate);
// verify
double tol = Precision.EPSILON;
for (int n = 0; n < raw.getMaxDegree(); n++) {
for (int m = 0; m < n; m++) {
Assert.assertEquals(expected.getNormalizedCnm(n, m), actual.getNormalizedCnm(n, m), tol);
Assert.assertEquals(expected.getNormalizedSnm(n, m), actual.getNormalizedSnm(n, m), tol);
}
}
}
use of org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics in project Orekit by CS-SI.
the class EGMFormatReaderTest method testReadNormalized.
@Test
public void testReadNormalized() throws OrekitException {
Utils.setDataRoot("potential");
GravityFieldFactory.addPotentialCoefficientsReader(new EGMFormatReader("egm96_to5.ascii", true));
NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(5, 5);
NormalizedSphericalHarmonics harmonics = provider.onDate(AbsoluteDate.FUTURE_INFINITY);
Assert.assertEquals(TideSystem.TIDE_FREE, provider.getTideSystem());
Assert.assertEquals(0.957254173792E-06, harmonics.getNormalizedCnm(3, 0), 1.0e-15);
Assert.assertEquals(0.174971983203E-06, harmonics.getNormalizedCnm(5, 5), 1.0e-15);
Assert.assertEquals(0.0, harmonics.getNormalizedSnm(4, 0), 1.0e-15);
Assert.assertEquals(0.308853169333E-06, harmonics.getNormalizedSnm(4, 4), 1.0e-15);
Assert.assertEquals(-0.295301647654E-06, harmonics.getNormalizedCnm(5, 4), 1.0e-15);
Assert.assertNull(provider.getReferenceDate());
Assert.assertEquals(0, provider.getOffset(AbsoluteDate.J2000_EPOCH), Precision.SAFE_MIN);
Assert.assertEquals(0, provider.getOffset(AbsoluteDate.MODIFIED_JULIAN_EPOCH), Precision.SAFE_MIN);
}
use of org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics in project Orekit by CS-SI.
the class GRGSFormatReaderTest method testRegular05cNormalized.
@Test
public void testRegular05cNormalized() throws OrekitException {
GravityFieldFactory.addPotentialCoefficientsReader(new GRGSFormatReader("grim5_C1.dat", true));
NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(5, 5);
Assert.assertEquals(TideSystem.UNKNOWN, provider.getTideSystem());
AbsoluteDate refDate = new AbsoluteDate("1997-01-01T12:00:00", TimeScalesFactory.getTT());
Assert.assertEquals(refDate, provider.getReferenceDate());
AbsoluteDate date = new AbsoluteDate("2011-05-01T01:02:03", TimeScalesFactory.getTT());
Assert.assertEquals(date.durationFrom(refDate), provider.getOffset(date), Precision.SAFE_MIN);
double offset = date.durationFrom(refDate);
double offsetYear = offset / Constants.JULIAN_YEAR;
NormalizedSphericalHarmonics harmonics = provider.onDate(date);
Assert.assertEquals(0.95857491635129E-06 + offsetYear * 0.28175700027753E-11, harmonics.getNormalizedCnm(3, 0), 1.0e-15);
Assert.assertEquals(0.17481512311600E-06, harmonics.getNormalizedCnm(5, 5), 1.0e-15);
Assert.assertEquals(0.0, harmonics.getNormalizedSnm(4, 0), 1.0e-15);
Assert.assertEquals(0.30882755318300E-06, harmonics.getNormalizedSnm(4, 4), 1.0e-15);
Assert.assertEquals(0.3986004415E+15, provider.getMu(), 0);
Assert.assertEquals(0.6378136460E+07, provider.getAe(), 0);
}
use of org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics in project Orekit by CS-SI.
the class ICGEMFormatReaderTest method testRegular05cNormalized.
@Test
public void testRegular05cNormalized() throws OrekitException {
Utils.setDataRoot("potential");
GravityFieldFactory.addPotentialCoefficientsReader(new ICGEMFormatReader("g007_eigen_05c_coef", false));
NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(5, 5);
Assert.assertEquals(TideSystem.TIDE_FREE, provider.getTideSystem());
AbsoluteDate refDate = new AbsoluteDate("2004-10-01T12:00:00", TimeScalesFactory.getTT());
Assert.assertEquals(refDate, provider.getReferenceDate());
AbsoluteDate date = new AbsoluteDate("2013-01-08T10:46:53", TimeScalesFactory.getTT());
NormalizedSphericalHarmonics harmonics = provider.onDate(date);
Assert.assertEquals(date.durationFrom(refDate), provider.getOffset(date), Precision.SAFE_MIN);
double offset = date.durationFrom(refDate);
double offsetYear = offset / Constants.JULIAN_YEAR;
Assert.assertEquals(0.957212879862e-06 + offsetYear * 0.490000000000e-11, harmonics.getNormalizedCnm(3, 0), 1.0e-15);
Assert.assertEquals(0.174804558032e-06, harmonics.getNormalizedCnm(5, 5), 1.0e-15);
Assert.assertEquals(0.0, harmonics.getNormalizedSnm(4, 0), 1.0e-15);
Assert.assertEquals(0.308816581016e-06, harmonics.getNormalizedSnm(4, 4), 1.0e-15);
Assert.assertEquals(0.3986004415E+15, provider.getMu(), 1.0e-20);
Assert.assertEquals(0.6378136460E+07, provider.getAe(), 1.0e-20);
}
use of org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics in project Orekit by CS-SI.
the class HolmesFeatherstoneAttractionModel method gradientHessian.
/**
* Compute both the gradient and the hessian of the non-central part of the gravity field.
* @param date current date
* @param position position at which gravity field is desired in body frame
* @param mu central attraction coefficient to use
* @return gradient and hessian of the non-central part of the gravity field
* @exception OrekitException if position cannot be converted to central body frame
*/
private GradientHessian gradientHessian(final AbsoluteDate date, final Vector3D position, final double mu) throws OrekitException {
final int degree = provider.getMaxDegree();
final int order = provider.getMaxOrder();
final NormalizedSphericalHarmonics harmonics = provider.onDate(date);
// allocate the columns for recursion
double[] pnm0Plus2 = new double[degree + 1];
double[] pnm0Plus1 = new double[degree + 1];
double[] pnm0 = new double[degree + 1];
double[] pnm1Plus1 = new double[degree + 1];
double[] pnm1 = new double[degree + 1];
final double[] pnm2 = new double[degree + 1];
// compute polar coordinates
final double x = position.getX();
final double y = position.getY();
final double z = position.getZ();
final double x2 = x * x;
final double y2 = y * y;
final double z2 = z * z;
final double r2 = x2 + y2 + z2;
final double r = FastMath.sqrt(r2);
final double rho2 = x2 + y2;
final double rho = FastMath.sqrt(rho2);
// cos(theta), where theta is the polar angle
final double t = z / r;
// sin(theta), where theta is the polar angle
final double u = rho / r;
final double tOu = z / rho;
// compute distance powers
final double[] aOrN = createDistancePowersArray(provider.getAe() / r);
// compute longitude cosines/sines
final double[][] cosSinLambda = createCosSinArrays(position.getX() / rho, position.getY() / rho);
// outer summation over order
int index = 0;
double value = 0;
final double[] gradient = new double[3];
final double[][] hessian = new double[3][3];
for (int m = degree; m >= 0; --m) {
// compute tesseral terms
index = computeTesseral(m, degree, index, t, u, tOu, pnm0Plus2, pnm0Plus1, pnm1Plus1, pnm0, pnm1, pnm2);
if (m <= order) {
// compute contribution of current order to field (equation 5 of the paper)
// inner summation over degree, for fixed order
double sumDegreeS = 0;
double sumDegreeC = 0;
double dSumDegreeSdR = 0;
double dSumDegreeCdR = 0;
double dSumDegreeSdTheta = 0;
double dSumDegreeCdTheta = 0;
double d2SumDegreeSdRdR = 0;
double d2SumDegreeSdRdTheta = 0;
double d2SumDegreeSdThetadTheta = 0;
double d2SumDegreeCdRdR = 0;
double d2SumDegreeCdRdTheta = 0;
double d2SumDegreeCdThetadTheta = 0;
for (int n = FastMath.max(2, m); n <= degree; ++n) {
final double qSnm = aOrN[n] * harmonics.getNormalizedSnm(n, m);
final double qCnm = aOrN[n] * harmonics.getNormalizedCnm(n, m);
final double nOr = n / r;
final double nnP1Or2 = nOr * (n + 1) / r;
final double s0 = pnm0[n] * qSnm;
final double c0 = pnm0[n] * qCnm;
final double s1 = pnm1[n] * qSnm;
final double c1 = pnm1[n] * qCnm;
final double s2 = pnm2[n] * qSnm;
final double c2 = pnm2[n] * qCnm;
sumDegreeS += s0;
sumDegreeC += c0;
dSumDegreeSdR -= nOr * s0;
dSumDegreeCdR -= nOr * c0;
dSumDegreeSdTheta += s1;
dSumDegreeCdTheta += c1;
d2SumDegreeSdRdR += nnP1Or2 * s0;
d2SumDegreeSdRdTheta -= nOr * s1;
d2SumDegreeSdThetadTheta += s2;
d2SumDegreeCdRdR += nnP1Or2 * c0;
d2SumDegreeCdRdTheta -= nOr * c1;
d2SumDegreeCdThetadTheta += c2;
}
// contribution to outer summation over order
final double sML = cosSinLambda[1][m];
final double cML = cosSinLambda[0][m];
value = value * u + sML * sumDegreeS + cML * sumDegreeC;
gradient[0] = gradient[0] * u + sML * dSumDegreeSdR + cML * dSumDegreeCdR;
gradient[1] = gradient[1] * u + m * (cML * sumDegreeS - sML * sumDegreeC);
gradient[2] = gradient[2] * u + sML * dSumDegreeSdTheta + cML * dSumDegreeCdTheta;
hessian[0][0] = hessian[0][0] * u + sML * d2SumDegreeSdRdR + cML * d2SumDegreeCdRdR;
hessian[1][0] = hessian[1][0] * u + m * (cML * dSumDegreeSdR - sML * dSumDegreeCdR);
hessian[2][0] = hessian[2][0] * u + sML * d2SumDegreeSdRdTheta + cML * d2SumDegreeCdRdTheta;
hessian[1][1] = hessian[1][1] * u - m * m * (sML * sumDegreeS + cML * sumDegreeC);
hessian[2][1] = hessian[2][1] * u + m * (cML * dSumDegreeSdTheta - sML * dSumDegreeCdTheta);
hessian[2][2] = hessian[2][2] * u + sML * d2SumDegreeSdThetadTheta + cML * d2SumDegreeCdThetadTheta;
}
// rotate the recursion arrays
final double[] tmp0 = pnm0Plus2;
pnm0Plus2 = pnm0Plus1;
pnm0Plus1 = pnm0;
pnm0 = tmp0;
final double[] tmp1 = pnm1Plus1;
pnm1Plus1 = pnm1;
pnm1 = tmp1;
}
// scale back
value = FastMath.scalb(value, SCALING);
for (int i = 0; i < 3; ++i) {
gradient[i] = FastMath.scalb(gradient[i], SCALING);
for (int j = 0; j <= i; ++j) {
hessian[i][j] = FastMath.scalb(hessian[i][j], SCALING);
}
}
// apply the global mu/r factor
final double muOr = mu / r;
value *= muOr;
gradient[0] = muOr * gradient[0] - value / r;
gradient[1] *= muOr;
gradient[2] *= muOr;
hessian[0][0] = muOr * hessian[0][0] - 2 * gradient[0] / r;
hessian[1][0] = muOr * hessian[1][0] - gradient[1] / r;
hessian[2][0] = muOr * hessian[2][0] - gradient[2] / r;
hessian[1][1] *= muOr;
hessian[2][1] *= muOr;
hessian[2][2] *= muOr;
// convert gradient and Hessian from spherical to Cartesian
final SphericalCoordinates sc = new SphericalCoordinates(position);
return new GradientHessian(sc.toCartesianGradient(gradient), sc.toCartesianHessian(hessian, gradient));
}
Aggregations