DormandPrince54FieldStateInterpolator.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.ode.nonstiff.interpolators;

  22. import org.hipparchus.CalculusFieldElement;
  23. import org.hipparchus.Field;
  24. import org.hipparchus.ode.FieldEquationsMapper;
  25. import org.hipparchus.ode.FieldODEStateAndDerivative;
  26. import org.hipparchus.ode.nonstiff.DormandPrince54Integrator;

  27. /**
  28.  * This class represents an interpolator over the last step during an
  29.  * ODE integration for the 5(4) Dormand-Prince integrator.
  30.  *
  31.  * @see DormandPrince54Integrator
  32.  *
  33.  * @param <T> the type of the field elements
  34.  */

  35. public class DormandPrince54FieldStateInterpolator<T extends CalculusFieldElement<T>>
  36.     extends RungeKuttaFieldStateInterpolator<T> {

  37.     /** Last row of the Butcher-array internal weights, element 0. */
  38.     private final T a70;

  39.     // element 1 is zero, so it is neither stored nor used

  40.     /** Last row of the Butcher-array internal weights, element 2. */
  41.     private final T a72;

  42.     /** Last row of the Butcher-array internal weights, element 3. */
  43.     private final T a73;

  44.     /** Last row of the Butcher-array internal weights, element 4. */
  45.     private final T a74;

  46.     /** Last row of the Butcher-array internal weights, element 5. */
  47.     private final T a75;

  48.     /** Shampine (1986) Dense output, element 0. */
  49.     private final T d0;

  50.     // element 1 is zero, so it is neither stored nor used

  51.     /** Shampine (1986) Dense output, element 2. */
  52.     private final T d2;

  53.     /** Shampine (1986) Dense output, element 3. */
  54.     private final T d3;

  55.     /** Shampine (1986) Dense output, element 4. */
  56.     private final T d4;

  57.     /** Shampine (1986) Dense output, element 5. */
  58.     private final T d5;

  59.     /** Shampine (1986) Dense output, element 6. */
  60.     private final T d6;

  61.     /** Simple constructor.
  62.      * @param field field to which the time and state vector elements belong
  63.      * @param forward integration direction indicator
  64.      * @param yDotK slopes at the intermediate points
  65.      * @param globalPreviousState start of the global step
  66.      * @param globalCurrentState end of the global step
  67.      * @param softPreviousState start of the restricted step
  68.      * @param softCurrentState end of the restricted step
  69.      * @param mapper equations mapper for the all equations
  70.      */
  71.     public DormandPrince54FieldStateInterpolator(final Field<T> field, final boolean forward,
  72.                                                  final T[][] yDotK,
  73.                                                  final FieldODEStateAndDerivative<T> globalPreviousState,
  74.                                                  final FieldODEStateAndDerivative<T> globalCurrentState,
  75.                                                  final FieldODEStateAndDerivative<T> softPreviousState,
  76.                                                  final FieldODEStateAndDerivative<T> softCurrentState,
  77.                                                  final FieldEquationsMapper<T> mapper) {
  78.         super(field, forward, yDotK, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState,
  79.                 mapper);
  80.         final T one = field.getOne();
  81.         a70 = one.newInstance(   35.0 /  384.0);
  82.         a72 = one.newInstance(  500.0 / 1113.0);
  83.         a73 = one.newInstance(  125.0 /  192.0);
  84.         a74 = one.newInstance(-2187.0 / 6784.0);
  85.         a75 = one.newInstance(   11.0 /   84.0);
  86.         d0  = one.newInstance(-12715105075.0 /  11282082432.0);
  87.         d2  = one.newInstance( 87487479700.0 /  32700410799.0);
  88.         d3  = one.newInstance(-10690763975.0 /   1880347072.0);
  89.         d4  = one.newInstance(701980252875.0 / 199316789632.0);
  90.         d5  = one.newInstance( -1453857185.0 /    822651844.0);
  91.         d6  = one.newInstance(    69997945.0 /     29380423.0);
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     protected DormandPrince54FieldStateInterpolator<T> create(final Field<T> newField, final boolean newForward, final T[][] newYDotK,
  96.                                                               final FieldODEStateAndDerivative<T> newGlobalPreviousState,
  97.                                                               final FieldODEStateAndDerivative<T> newGlobalCurrentState,
  98.                                                               final FieldODEStateAndDerivative<T> newSoftPreviousState,
  99.                                                               final FieldODEStateAndDerivative<T> newSoftCurrentState,
  100.                                                               final FieldEquationsMapper<T> newMapper) {
  101.         return new DormandPrince54FieldStateInterpolator<>(newField, newForward, newYDotK,
  102.                                                             newGlobalPreviousState, newGlobalCurrentState,
  103.                                                             newSoftPreviousState, newSoftCurrentState,
  104.                                                             newMapper);
  105.     }
  106.     /** {@inheritDoc} */
  107.     @SuppressWarnings("unchecked")
  108.     @Override
  109.     protected FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(final FieldEquationsMapper<T> mapper,
  110.                                                                                    final T time, final T theta,
  111.                                                                                    final T thetaH, final T oneMinusThetaH) {

  112.         // interpolate
  113.         final T one      = time.getField().getOne();
  114.         final T eta      = one.subtract(theta);
  115.         final T twoTheta = theta.multiply(2);
  116.         final T dot2     = one.subtract(twoTheta);
  117.         final T dot3     = theta.multiply(theta.multiply(-3).add(2));
  118.         final T dot4     = twoTheta.multiply(theta.multiply(twoTheta.subtract(3)).add(1));
  119.         final T[] interpolatedState;
  120.         final T[] interpolatedDerivatives;
  121.         if (getGlobalPreviousState() != null && theta.getReal() <= 0.5) {
  122.             final T f1        = thetaH;
  123.             final T f2        = f1.multiply(eta);
  124.             final T f3        = f2.multiply(theta);
  125.             final T f4        = f3.multiply(eta);
  126.             final T coeff0    = f1.multiply(a70).
  127.                                 subtract(f2.multiply(a70.subtract(1))).
  128.                                 add(f3.multiply(a70.multiply(2).subtract(1))).
  129.                                 add(f4.multiply(d0));
  130.             final T coeff1    = time.getField().getZero();
  131.             final T coeff2    = f1.multiply(a72).
  132.                                 subtract(f2.multiply(a72)).
  133.                                 add(f3.multiply(a72.multiply(2))).
  134.                                 add(f4.multiply(d2));
  135.             final T coeff3    = f1.multiply(a73).
  136.                                 subtract(f2.multiply(a73)).
  137.                                 add(f3.multiply(a73.multiply(2))).
  138.                                 add(f4.multiply(d3));
  139.             final T coeff4    = f1.multiply(a74).
  140.                                 subtract(f2.multiply(a74)).
  141.                                 add(f3.multiply(a74.multiply(2))).
  142.                                 add(f4.multiply(d4));
  143.             final T coeff5    = f1.multiply(a75).
  144.                                 subtract(f2.multiply(a75)).
  145.                                 add(f3.multiply(a75.multiply(2))).
  146.                                 add(f4.multiply(d5));
  147.             final T coeff6    = f4.multiply(d6).subtract(f3);
  148.             final T coeffDot0 = a70.
  149.                                 subtract(dot2.multiply(a70.subtract(1))).
  150.                                 add(dot3.multiply(a70.multiply(2).subtract(1))).
  151.                                 add(dot4.multiply(d0));
  152.             final T coeffDot1 = time.getField().getZero();
  153.             final T coeffDot2 = a72.
  154.                                 subtract(dot2.multiply(a72)).
  155.                                 add(dot3.multiply(a72.multiply(2))).
  156.                                 add(dot4.multiply(d2));
  157.             final T coeffDot3 = a73.
  158.                                 subtract(dot2.multiply(a73)).
  159.                                 add(dot3.multiply(a73.multiply(2))).
  160.                                 add(dot4.multiply(d3));
  161.             final T coeffDot4 = a74.
  162.                                 subtract(dot2.multiply(a74)).
  163.                                 add(dot3.multiply(a74.multiply(2))).
  164.                                 add(dot4.multiply(d4));
  165.             final T coeffDot5 = a75.
  166.                                 subtract(dot2.multiply(a75)).
  167.                                 add(dot3.multiply(a75.multiply(2))).
  168.                                 add(dot4.multiply(d5));
  169.             final T coeffDot6 = dot4.multiply(d6).subtract(dot3);
  170.             interpolatedState       = previousStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
  171.                                                                      coeff4, coeff5, coeff6);
  172.             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
  173.                                                                   coeffDot4, coeffDot5, coeffDot6);
  174.         } else {
  175.             final T f1        = oneMinusThetaH.negate();
  176.             final T f2        = oneMinusThetaH.multiply(theta);
  177.             final T f3        = f2.multiply(theta);
  178.             final T f4        = f3.multiply(eta);
  179.             final T coeff0    = f1.multiply(a70).
  180.                                 subtract(f2.multiply(a70.subtract(1))).
  181.                                 add(f3.multiply(a70.multiply(2).subtract(1))).
  182.                                 add(f4.multiply(d0));
  183.             final T coeff1    = time.getField().getZero();
  184.             final T coeff2    = f1.multiply(a72).
  185.                                 subtract(f2.multiply(a72)).
  186.                                 add(f3.multiply(a72.multiply(2))).
  187.                                 add(f4.multiply(d2));
  188.             final T coeff3    = f1.multiply(a73).
  189.                                 subtract(f2.multiply(a73)).
  190.                                 add(f3.multiply(a73.multiply(2))).
  191.                                 add(f4.multiply(d3));
  192.             final T coeff4    = f1.multiply(a74).
  193.                                 subtract(f2.multiply(a74)).
  194.                                 add(f3.multiply(a74.multiply(2))).
  195.                                 add(f4.multiply(d4));
  196.             final T coeff5    = f1.multiply(a75).
  197.                                 subtract(f2.multiply(a75)).
  198.                                 add(f3.multiply(a75.multiply(2))).
  199.                                 add(f4.multiply(d5));
  200.             final T coeff6    = f4.multiply(d6).subtract(f3);
  201.             final T coeffDot0 = a70.
  202.                                 subtract(dot2.multiply(a70.subtract(1))).
  203.                                 add(dot3.multiply(a70.multiply(2).subtract(1))).
  204.                                 add(dot4.multiply(d0));
  205.             final T coeffDot1 = time.getField().getZero();
  206.             final T coeffDot2 = a72.
  207.                                 subtract(dot2.multiply(a72)).
  208.                                 add(dot3.multiply(a72.multiply(2))).
  209.                                 add(dot4.multiply(d2));
  210.             final T coeffDot3 = a73.
  211.                                 subtract(dot2.multiply(a73)).
  212.                                 add(dot3.multiply(a73.multiply(2))).
  213.                                 add(dot4.multiply(d3));
  214.             final T coeffDot4 = a74.
  215.                                 subtract(dot2.multiply(a74)).
  216.                                 add(dot3.multiply(a74.multiply(2))).
  217.                                 add(dot4.multiply(d4));
  218.             final T coeffDot5 = a75.
  219.                                 subtract(dot2.multiply(a75)).
  220.                                 add(dot3.multiply(a75.multiply(2))).
  221.                                 add(dot4.multiply(d5));
  222.             final T coeffDot6 = dot4.multiply(d6).subtract(dot3);
  223.             interpolatedState       = currentStateLinearCombination(coeff0, coeff1, coeff2, coeff3,
  224.                                                                     coeff4, coeff5, coeff6);
  225.             interpolatedDerivatives = derivativeLinearCombination(coeffDot0, coeffDot1, coeffDot2, coeffDot3,
  226.                                                                   coeffDot4, coeffDot5, coeffDot6);
  227.         }
  228.         return mapper.mapStateAndDerivative(time, interpolatedState, interpolatedDerivatives);

  229.     }

  230. }