AbstractFieldODEDetector.java

  1. /*
  2.  * Licensed to the Hipparchus project 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 Hipparchus project 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. package org.hipparchus.ode.events;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.analysis.solvers.BracketedRealFieldUnivariateSolver;
  20. import org.hipparchus.analysis.solvers.FieldBracketingNthOrderBrentSolver;
  21. import org.hipparchus.ode.FieldODEStateAndDerivative;

  22. /** Base class for #@link {@link FieldODEEventDetector}.
  23.  * @param <T> type of the detector
  24.  * @param <E> type of the field elements
  25.  * @since 3.0
  26.  */
  27. public abstract class AbstractFieldODEDetector<T extends AbstractFieldODEDetector<T, E>, E extends CalculusFieldElement<E>>
  28.     implements FieldODEEventDetector<E> {

  29.     /** Default maximum checking interval (s). */
  30.     public static final double DEFAULT_MAX_CHECK = AbstractODEDetector.DEFAULT_MAX_CHECK;

  31.     /** Default convergence threshold (s). */
  32.     public static final double DEFAULT_THRESHOLD = AbstractODEDetector.DEFAULT_THRESHOLD;

  33.     /** Default maximum number of iterations in the event time search. */
  34.     public static final int DEFAULT_MAX_ITER = AbstractODEDetector.DEFAULT_MAX_ITER;

  35.     /** Max check interval. */
  36.     private final FieldAdaptableInterval<E> maxCheck;

  37.     /** Maximum number of iterations in the event time search. */
  38.     private final int maxIter;

  39.     /** Root-finding algorithm to use to detect state events. */
  40.     private final BracketedRealFieldUnivariateSolver<E> solver;

  41.     /** Default handler for event overrides. */
  42.     private final FieldODEEventHandler<E> handler;

  43.     /** Propagation direction. */
  44.     private boolean forward;

  45.     /** Build a new instance.
  46.      * @param maxCheck maximum checking interval, must be strictly positive (s)
  47.      * @param maxIter maximum number of iterations in the event time search
  48.      * @param solver root-finding algorithm to use to detect state events
  49.      * @param handler event handler to call at event occurrences
  50.      */
  51.     protected AbstractFieldODEDetector(final FieldAdaptableInterval<E> maxCheck, final int maxIter,
  52.                                        final BracketedRealFieldUnivariateSolver<E> solver,
  53.                                        final FieldODEEventHandler<E> handler) {
  54.         this.maxCheck  = maxCheck;
  55.         this.maxIter   = maxIter;
  56.         this.solver    = solver;
  57.         this.handler   = handler;
  58.         this.forward   = true;
  59.     }

  60.     /**
  61.      * {@inheritDoc}
  62.      *
  63.      * <p> This implementation sets the direction of integration and initializes the event
  64.      * handler. If a subclass overrides this method it should call {@code
  65.      * super.init(s0, t)}.
  66.      */
  67.     @Override
  68.     public void init(final FieldODEStateAndDerivative<E> s0, final E t) {
  69.         FieldODEEventDetector.super.init(s0, t);
  70.         forward = t.subtract(s0.getTime()).getReal() >= 0;
  71.     }

  72.     /** {@inheritDoc} */
  73.     @Override
  74.     public FieldAdaptableInterval<E> getMaxCheckInterval() {
  75.         return maxCheck;
  76.     }

  77.     /** {@inheritDoc} */
  78.     @Override
  79.     public int getMaxIterationCount() {
  80.         return maxIter;
  81.     }

  82.     /** {@inheritDoc} */
  83.     @Override
  84.     public BracketedRealFieldUnivariateSolver<E> getSolver() {
  85.         return solver;
  86.     }

  87.     /**
  88.      * Setup the maximum checking interval.
  89.      * <p>
  90.      * This will override a maximum checking interval if it has been configured previously.
  91.      * </p>
  92.      * @param newMaxCheck maximum checking interval (s)
  93.      * @return a new detector with updated configuration (the instance is not changed)
  94.      */
  95.     public T withMaxCheck(final E newMaxCheck) {
  96.         return withMaxCheck(FieldAdaptableInterval.of(newMaxCheck.getReal()));
  97.     }

  98.     /**
  99.      * Setup the maximum checking interval.
  100.      * <p>
  101.      * This will override a maximum checking interval if it has been configured previously.
  102.      * </p>
  103.      * @param newMaxCheck maximum checking interval (s)
  104.      * @return a new detector with updated configuration (the instance is not changed)
  105.      * @since 3.0
  106.      */
  107.     public T withMaxCheck(final FieldAdaptableInterval<E> newMaxCheck) {
  108.         return create(newMaxCheck, getMaxIterationCount(), getSolver(), getHandler());
  109.     }

  110.     /**
  111.      * Setup the maximum number of iterations in the event time search.
  112.      * <p>
  113.      * This will override a number of iterations if it has been configured previously.
  114.      * </p>
  115.      * @param newMaxIter maximum number of iterations in the event time search
  116.      * @return a new detector with updated configuration (the instance is not changed)
  117.      */
  118.     public T withMaxIter(final int newMaxIter) {
  119.         return create(getMaxCheckInterval(), newMaxIter, getSolver(), getHandler());
  120.     }

  121.     /**
  122.      * Setup the convergence threshold.
  123.      * <p>
  124.      * This is equivalent to call {@code withSolver(new FieldBracketingNthOrderBrentSolver<>(zero,
  125.      * newThreshold, zero, 5)}, so it will override a solver if one has been configured previously.
  126.      * </p>
  127.      * @param newThreshold convergence threshold
  128.      * @return a new detector with updated configuration (the instance is not changed)
  129.      * @see #withSolver(BracketedRealFieldUnivariateSolver)
  130.      */
  131.     public T withThreshold(final E newThreshold) {
  132.         final E zero = newThreshold.getField().getZero();
  133.         return withSolver(new FieldBracketingNthOrderBrentSolver<>(zero, newThreshold, zero, 5));
  134.     }

  135.     /**
  136.      * Setup the root-finding algorithm to use to detect state events.
  137.      * <p>
  138.      * This will override a solver if it has been configured previously.
  139.      * </p>
  140.      * @param newSolver root-finding algorithm to use to detect state events
  141.      * @return a new detector with updated configuration (the instance is not changed)
  142.      * @see #withThreshold(CalculusFieldElement)
  143.      */
  144.     public T withSolver(final BracketedRealFieldUnivariateSolver<E> newSolver) {
  145.         return create(getMaxCheckInterval(), getMaxIterationCount(), newSolver, getHandler());
  146.     }

  147.     /**
  148.      * Setup the event handler to call at event occurrences.
  149.      * <p>
  150.      * This will override a handler if it has been configured previously.
  151.      * </p>
  152.      * @param newHandler event handler to call at event occurrences
  153.      * @return a new detector with updated configuration (the instance is not changed)
  154.      */
  155.     public T withHandler(final FieldODEEventHandler<E> newHandler) {
  156.         return create(getMaxCheckInterval(), getMaxIterationCount(), getSolver(), newHandler);
  157.     }

  158.     /** {@inheritDoc} */
  159.     @Override
  160.     public FieldODEEventHandler<E> getHandler() {
  161.         return handler;
  162.     }

  163.     /** Build a new instance.
  164.      * @param newMaxCheck maximum checking interval
  165.      * @param newMaxIter maximum number of iterations in the event time search
  166.      * @param newSolver root-finding algorithm to use to detect state events
  167.      * @param newHandler event handler to call at event occurrences
  168.      * @return a new instance of the appropriate sub-type
  169.      */
  170.     protected abstract T create(FieldAdaptableInterval<E> newMaxCheck, int newMaxIter,
  171.                                 BracketedRealFieldUnivariateSolver<E> newSolver,
  172.                                 FieldODEEventHandler<E> newHandler);

  173.     /** Check if the current propagation is forward or backward.
  174.      * @return true if the current propagation is forward
  175.      */
  176.     public boolean isForward() {
  177.         return forward;
  178.     }

  179. }