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 18 package org.hipparchus.ode.events; 19 20 import org.hipparchus.analysis.UnivariateFunction; 21 import org.hipparchus.analysis.solvers.BracketedUnivariateSolver; 22 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver; 23 import org.hipparchus.ode.ODEStateAndDerivative; 24 25 /** Base class for #@link {@link ODEEventDetector}. 26 * @param <T> type of the detector 27 * @since 3.0 28 */ 29 public abstract class AbstractODEDetector<T extends AbstractODEDetector<T>> implements ODEEventDetector { 30 31 /** Default maximum checking interval (s). */ 32 public static final double DEFAULT_MAXCHECK = 600; 33 34 /** Default convergence threshold (s). */ 35 public static final double DEFAULT_THRESHOLD = 1.e-6; 36 37 /** Default maximum number of iterations in the event time search. */ 38 public static final int DEFAULT_MAX_ITER = 100; 39 40 /** Max check interval. */ 41 private final AdaptableInterval maxCheck; 42 43 /** Maximum number of iterations in the event time search. */ 44 private final int maxIter; 45 46 /** Root-finding algorithm to use to detect state events. */ 47 private final BracketedUnivariateSolver<UnivariateFunction> solver; 48 49 /** Default handler for event overrides. */ 50 private final ODEEventHandler handler; 51 52 /** Propagation direction. */ 53 private boolean forward; 54 55 /** Build a new instance. 56 * @param maxCheck maximum checking interval, must be strictly positive (s) 57 * @param maxIter maximum number of iterations in the event time search 58 * @param solver root-finding algorithm to use to detect state events 59 * @param handler event handler to call at event occurrences 60 */ 61 protected AbstractODEDetector(final AdaptableInterval maxCheck, final int maxIter, 62 final BracketedUnivariateSolver<UnivariateFunction> solver, 63 final ODEEventHandler handler) { 64 this.maxCheck = maxCheck; 65 this.maxIter = maxIter; 66 this.solver = solver; 67 this.handler = handler; 68 this.forward = true; 69 } 70 71 /** 72 * {@inheritDoc} 73 * 74 * <p> This implementation sets the direction of integration and initializes the event 75 * handler. If a subclass overrides this method it should call {@code 76 * super.init(s0, t)}. 77 */ 78 @Override 79 public void init(final ODEStateAndDerivative s0, final double t) { 80 forward = t >= s0.getTime(); 81 getHandler().init(s0, t, this); 82 } 83 84 /** {@inheritDoc} */ 85 @Override 86 public abstract double g(ODEStateAndDerivative s); 87 88 /** {@inheritDoc} */ 89 @Override 90 public AdaptableInterval getMaxCheckInterval() { 91 return maxCheck; 92 } 93 94 /** {@inheritDoc} */ 95 @Override 96 public int getMaxIterationCount() { 97 return maxIter; 98 } 99 100 /** {@inheritDoc} */ 101 @Override 102 public BracketedUnivariateSolver<UnivariateFunction> getSolver() { 103 return solver; 104 } 105 106 /** 107 * Setup the maximum checking interval. 108 * <p> 109 * This will override a maximum checking interval if it has been configured previously. 110 * </p> 111 * @param newMaxCheck maximum checking interval 112 * @return a new detector with updated configuration (the instance is not changed) 113 */ 114 public T withMaxCheck(final double newMaxCheck) { 115 return withMaxCheck(s -> newMaxCheck); 116 } 117 118 /** 119 * Setup the maximum checking interval. 120 * <p> 121 * This will override a maximum checking interval if it has been configured previously. 122 * </p> 123 * @param newMaxCheck maximum checking interval 124 * @return a new detector with updated configuration (the instance is not changed) 125 * @since 3.0 126 */ 127 public T withMaxCheck(final AdaptableInterval newMaxCheck) { 128 return create(newMaxCheck, getMaxIterationCount(), getSolver(), getHandler()); 129 } 130 131 /** 132 * Setup the maximum number of iterations in the event time search. 133 * <p> 134 * This will override a number of iterations if it has been configured previously. 135 * </p> 136 * @param newMaxIter maximum number of iterations in the event time search 137 * @return a new detector with updated configuration (the instance is not changed) 138 */ 139 public T withMaxIter(final int newMaxIter) { 140 return create(getMaxCheckInterval(), newMaxIter, getSolver(), getHandler()); 141 } 142 143 /** 144 * Setup the convergence threshold. 145 * <p> 146 * This is equivalent to call {@code withSolver(new BracketingNthOrderBrentSolver(0, 147 * newThreshold, 0, 5))}, so it will override a solver if one has been configured previously. 148 * </p> 149 * @param newThreshold convergence threshold 150 * @return a new detector with updated configuration (the instance is not changed) 151 * @see #withSolver(BracketedUnivariateSolver) 152 */ 153 public T withThreshold(final double newThreshold) { 154 return withSolver(new BracketingNthOrderBrentSolver(0, newThreshold, 0, 5)); 155 } 156 157 /** 158 * Setup the root-finding algorithm to use to detect state events. 159 * <p> 160 * This will override a solver if it has been configured previously. 161 * </p> 162 * @param newSolver root-finding algorithm to use to detect state events 163 * @return a new detector with updated configuration (the instance is not changed) 164 * @see #withThreshold(double) 165 */ 166 public T withSolver(final BracketedUnivariateSolver<UnivariateFunction> newSolver) { 167 return create(getMaxCheckInterval(), getMaxIterationCount(), newSolver, getHandler()); 168 } 169 170 /** 171 * Setup the event handler to call at event occurrences. 172 * <p> 173 * This will override a handler if it has been configured previously. 174 * </p> 175 * @param newHandler event handler to call at event occurrences 176 * @return a new detector with updated configuration (the instance is not changed) 177 */ 178 public T withHandler(final ODEEventHandler newHandler) { 179 return create(getMaxCheckInterval(), getMaxIterationCount(), getSolver(), newHandler); 180 } 181 182 /** {@inheritDoc} */ 183 @Override 184 public ODEEventHandler getHandler() { 185 return handler; 186 } 187 188 /** Build a new instance. 189 * @param newMaxCheck maximum checking interval 190 * @param newmaxIter maximum number of iterations in the event time search 191 * @param newSolver root-finding algorithm to use to detect state events 192 * @param newHandler event handler to call at event occurrences 193 * @return a new instance of the appropriate sub-type 194 */ 195 protected abstract T create(AdaptableInterval newMaxCheck, int newmaxIter, 196 BracketedUnivariateSolver<UnivariateFunction> newSolver, 197 ODEEventHandler newHandler); 198 199 /** Check if the current propagation is forward or backward. 200 * @return true if the current propagation is forward 201 */ 202 public boolean isForward() { 203 return forward; 204 } 205 206 }