@Test
  public void testPropagationTypesHyperbolic() throws OrekitException, ParseException, IOException {

    SpacecraftState state =
        new SpacecraftState(
            new KeplerianOrbit(
                -10000000.0,
                2.5,
                0.3,
                0,
                0,
                0.0,
                PositionAngle.TRUE,
                FramesFactory.getEME2000(),
                initDate,
                mu));

    ForceModel gravityField =
        new HolmesFeatherstoneAttractionModel(
            FramesFactory.getITRF(IERSConventions.IERS_2010, true),
            GravityFieldFactory.getNormalizedProvider(5, 5));
    propagator.addForceModel(gravityField);

    // Propagation of the initial at t + dt
    final PVCoordinates pv = state.getPVCoordinates();
    final double dP = 0.001;
    final double dV =
        state.getMu() * dP / (pv.getPosition().getNormSq() * pv.getVelocity().getNorm());

    final PVCoordinates pvcM = propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.MEAN);
    final PVCoordinates pvkM = propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.MEAN);

    final PVCoordinates pvcE =
        propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.ECCENTRIC);
    final PVCoordinates pvkE =
        propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.ECCENTRIC);

    final PVCoordinates pvcT = propagateInType(state, dP, OrbitType.CARTESIAN, PositionAngle.TRUE);
    final PVCoordinates pvkT = propagateInType(state, dP, OrbitType.KEPLERIAN, PositionAngle.TRUE);

    Assert.assertEquals(0, pvcM.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3);
    Assert.assertEquals(0, pvcM.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4);
    Assert.assertEquals(0, pvkM.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.2);
    Assert.assertEquals(0, pvkM.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.3);

    Assert.assertEquals(0, pvcE.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3);
    Assert.assertEquals(0, pvcE.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4);
    Assert.assertEquals(0, pvkE.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.009);
    Assert.assertEquals(0, pvkE.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.006);

    Assert.assertEquals(0, pvcT.getPosition().subtract(pvkT.getPosition()).getNorm() / dP, 0.3);
    Assert.assertEquals(0, pvcT.getVelocity().subtract(pvkT.getVelocity()).getNorm() / dV, 0.4);
  }
  @Test
  public void testPropagationTypesElliptical() throws OrekitException, ParseException, IOException {

    NormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getNormalizedProvider(5, 5);
    ForceModel gravityField =
        new HolmesFeatherstoneAttractionModel(
            FramesFactory.getITRF(IERSConventions.IERS_2010, true), provider);
    Orbit initialOrbit =
        new KeplerianOrbit(
            8000000.0,
            0.01,
            0.1,
            0.7,
            0,
            1.2,
            PositionAngle.TRUE,
            FramesFactory.getEME2000(),
            AbsoluteDate.J2000_EPOCH,
            provider.getMu());

    double dt = 900;
    double dP = 0.001;
    for (OrbitType orbitType : OrbitType.values()) {
      for (PositionAngle angleType : PositionAngle.values()) {

        // compute state Jacobian using PartialDerivatives
        NumericalPropagator propagator =
            setUpPropagator(initialOrbit, dP, orbitType, angleType, gravityField);
        PartialDerivativesEquations partials =
            new PartialDerivativesEquations("partials", propagator);
        final SpacecraftState initialState =
            partials.setInitialJacobians(new SpacecraftState(initialOrbit), 6, 0);
        propagator.setInitialState(initialState);
        final JacobiansMapper mapper = partials.getMapper();
        PickUpHandler pickUp = new PickUpHandler(mapper, null);
        propagator.setMasterMode(pickUp);
        propagator.propagate(initialState.getDate().shiftedBy(dt));
        double[][] dYdY0 = pickUp.getdYdY0();

        // compute reference state Jacobian using finite differences
        double[][] dYdY0Ref = new double[6][6];
        AbstractIntegratedPropagator propagator2 =
            setUpPropagator(initialOrbit, dP, orbitType, angleType, gravityField);
        double[] steps = NumericalPropagator.tolerances(1000000 * dP, initialOrbit, orbitType)[0];
        for (int i = 0; i < 6; ++i) {
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, -4 * steps[i], i));
          SpacecraftState sM4h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, -3 * steps[i], i));
          SpacecraftState sM3h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, -2 * steps[i], i));
          SpacecraftState sM2h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, -1 * steps[i], i));
          SpacecraftState sM1h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, 1 * steps[i], i));
          SpacecraftState sP1h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, 2 * steps[i], i));
          SpacecraftState sP2h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, 3 * steps[i], i));
          SpacecraftState sP3h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          propagator2.resetInitialState(
              shiftState(initialState, orbitType, angleType, 4 * steps[i], i));
          SpacecraftState sP4h = propagator2.propagate(initialState.getDate().shiftedBy(dt));
          fillJacobianColumn(
              dYdY0Ref, i, orbitType, angleType, steps[i], sM4h, sM3h, sM2h, sM1h, sP1h, sP2h, sP3h,
              sP4h);
        }

        for (int i = 0; i < 6; ++i) {
          for (int j = 0; j < 6; ++j) {
            double error = FastMath.abs((dYdY0[i][j] - dYdY0Ref[i][j]) / dYdY0Ref[i][j]);
            Assert.assertEquals(0, error, 6.0e-2);
          }
        }
      }
    }
  }
  @Test
  public void testPropagationTypesElliptical() throws OrekitException, ParseException, IOException {

    ForceModel gravityField =
        new HolmesFeatherstoneAttractionModel(
            FramesFactory.getITRF(IERSConventions.IERS_2010, true),
            GravityFieldFactory.getNormalizedProvider(5, 5));
    propagator.addForceModel(gravityField);

    // Propagation of the initial at t + dt
    final PVCoordinates pv = initialState.getPVCoordinates();
    final double dP = 0.001;
    final double dV =
        initialState.getMu() * dP / (pv.getPosition().getNormSq() * pv.getVelocity().getNorm());

    final PVCoordinates pvcM =
        propagateInType(initialState, dP, OrbitType.CARTESIAN, PositionAngle.MEAN);
    final PVCoordinates pviM =
        propagateInType(initialState, dP, OrbitType.CIRCULAR, PositionAngle.MEAN);
    final PVCoordinates pveM =
        propagateInType(initialState, dP, OrbitType.EQUINOCTIAL, PositionAngle.MEAN);
    final PVCoordinates pvkM =
        propagateInType(initialState, dP, OrbitType.KEPLERIAN, PositionAngle.MEAN);

    final PVCoordinates pvcE =
        propagateInType(initialState, dP, OrbitType.CARTESIAN, PositionAngle.ECCENTRIC);
    final PVCoordinates pviE =
        propagateInType(initialState, dP, OrbitType.CIRCULAR, PositionAngle.ECCENTRIC);
    final PVCoordinates pveE =
        propagateInType(initialState, dP, OrbitType.EQUINOCTIAL, PositionAngle.ECCENTRIC);
    final PVCoordinates pvkE =
        propagateInType(initialState, dP, OrbitType.KEPLERIAN, PositionAngle.ECCENTRIC);

    final PVCoordinates pvcT =
        propagateInType(initialState, dP, OrbitType.CARTESIAN, PositionAngle.TRUE);
    final PVCoordinates pviT =
        propagateInType(initialState, dP, OrbitType.CIRCULAR, PositionAngle.TRUE);
    final PVCoordinates pveT =
        propagateInType(initialState, dP, OrbitType.EQUINOCTIAL, PositionAngle.TRUE);
    final PVCoordinates pvkT =
        propagateInType(initialState, dP, OrbitType.KEPLERIAN, PositionAngle.TRUE);

    Assert.assertEquals(0, pvcM.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 3.0);
    Assert.assertEquals(0, pvcM.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 2.0);
    Assert.assertEquals(0, pviM.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.6);
    Assert.assertEquals(0, pviM.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.4);
    Assert.assertEquals(0, pvkM.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.5);
    Assert.assertEquals(0, pvkM.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.3);
    Assert.assertEquals(0, pveM.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.2);
    Assert.assertEquals(0, pveM.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.2);

    Assert.assertEquals(0, pvcE.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 3.0);
    Assert.assertEquals(0, pvcE.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 2.0);
    Assert.assertEquals(0, pviE.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.03);
    Assert.assertEquals(0, pviE.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.04);
    Assert.assertEquals(0, pvkE.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.4);
    Assert.assertEquals(0, pvkE.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.3);
    Assert.assertEquals(0, pveE.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.2);
    Assert.assertEquals(0, pveE.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.07);

    Assert.assertEquals(0, pvcT.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 3.0);
    Assert.assertEquals(0, pvcT.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 2.0);
    Assert.assertEquals(0, pviT.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.3);
    Assert.assertEquals(0, pviT.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.2);
    Assert.assertEquals(0, pvkT.getPosition().subtract(pveT.getPosition()).getNorm() / dP, 0.4);
    Assert.assertEquals(0, pvkT.getVelocity().subtract(pveT.getVelocity()).getNorm() / dV, 0.2);
  }