AbstractODEDetector.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.analysis.UnivariateFunction;
  19. import org.hipparchus.analysis.solvers.BracketedUnivariateSolver;
  20. import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
  21. import org.hipparchus.ode.ODEStateAndDerivative;

  22. /** Base class for #@link {@link ODEEventDetector}.
  23.  * @param <T> type of the detector
  24.  * @since 3.0
  25.  */
  26. public abstract class AbstractODEDetector<T extends AbstractODEDetector<T>> implements ODEEventDetector {

  27.     /** Default maximum checking interval (s). */
  28.     public static final double DEFAULT_MAX_CHECK = 600;

  29.     /** Default convergence threshold (s). */
  30.     public static final double DEFAULT_THRESHOLD = 1.e-6;

  31.     /** Default maximum number of iterations in the event time search. */
  32.     public static final int DEFAULT_MAX_ITER = 100;

  33.     /** Max check interval. */
  34.     private final AdaptableInterval maxCheck;

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

  37.     /** Root-finding algorithm to use to detect state events. */
  38.     private final BracketedUnivariateSolver<UnivariateFunction> solver;

  39.     /** Default handler for event overrides. */
  40.     private final ODEEventHandler handler;

  41.     /** Propagation direction. */
  42.     private boolean forward;

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

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

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public AdaptableInterval getMaxCheckInterval() {
  73.         return maxCheck;
  74.     }

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

  80.     /** {@inheritDoc} */
  81.     @Override
  82.     public BracketedUnivariateSolver<UnivariateFunction> getSolver() {
  83.         return solver;
  84.     }

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

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

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

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

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

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

  155.     /** {@inheritDoc} */
  156.     @Override
  157.     public ODEEventHandler getHandler() {
  158.         return handler;
  159.     }

  160.     /** Build a new instance.
  161.      * @param newMaxCheck maximum checking interval
  162.      * @param newmaxIter maximum number of iterations in the event time search
  163.      * @param newSolver root-finding algorithm to use to detect state events
  164.      * @param newHandler event handler to call at event occurrences
  165.      * @return a new instance of the appropriate sub-type
  166.      */
  167.     protected abstract T create(AdaptableInterval newMaxCheck, int newmaxIter,
  168.                                 BracketedUnivariateSolver<UnivariateFunction> newSolver,
  169.                                 ODEEventHandler newHandler);

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

  176. }