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_MAX_CHECK = 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 ODEEventDetector.super.init(s0, t); 81 forward = t >= s0.getTime(); 82 } 83 84 /** {@inheritDoc} */ 85 @Override 86 public AdaptableInterval getMaxCheckInterval() { 87 return maxCheck; 88 } 89 90 /** {@inheritDoc} */ 91 @Override 92 public int getMaxIterationCount() { 93 return maxIter; 94 } 95 96 /** {@inheritDoc} */ 97 @Override 98 public BracketedUnivariateSolver<UnivariateFunction> getSolver() { 99 return solver; 100 } 101 102 /** 103 * Setup the maximum checking interval. 104 * <p> 105 * This will override a maximum checking interval if it has been configured previously. 106 * </p> 107 * @param newMaxCheck maximum checking interval 108 * @return a new detector with updated configuration (the instance is not changed) 109 */ 110 public T withMaxCheck(final double newMaxCheck) { 111 return withMaxCheck(AdaptableInterval.of(newMaxCheck)); 112 } 113 114 /** 115 * Setup the maximum checking interval. 116 * <p> 117 * This will override a maximum checking interval if it has been configured previously. 118 * </p> 119 * @param newMaxCheck maximum checking interval 120 * @return a new detector with updated configuration (the instance is not changed) 121 * @since 3.0 122 */ 123 public T withMaxCheck(final AdaptableInterval newMaxCheck) { 124 return create(newMaxCheck, getMaxIterationCount(), getSolver(), getHandler()); 125 } 126 127 /** 128 * Setup the maximum number of iterations in the event time search. 129 * <p> 130 * This will override a number of iterations if it has been configured previously. 131 * </p> 132 * @param newMaxIter maximum number of iterations in the event time search 133 * @return a new detector with updated configuration (the instance is not changed) 134 */ 135 public T withMaxIter(final int newMaxIter) { 136 return create(getMaxCheckInterval(), newMaxIter, getSolver(), getHandler()); 137 } 138 139 /** 140 * Setup the convergence threshold. 141 * <p> 142 * This is equivalent to call {@code withSolver(new BracketingNthOrderBrentSolver(0, 143 * newThreshold, 0, 5))}, so it will override a solver if one has been configured previously. 144 * </p> 145 * @param newThreshold convergence threshold 146 * @return a new detector with updated configuration (the instance is not changed) 147 * @see #withSolver(BracketedUnivariateSolver) 148 */ 149 public T withThreshold(final double newThreshold) { 150 return withSolver(new BracketingNthOrderBrentSolver(0, newThreshold, 0, 5)); 151 } 152 153 /** 154 * Setup the root-finding algorithm to use to detect state events. 155 * <p> 156 * This will override a solver if it has been configured previously. 157 * </p> 158 * @param newSolver root-finding algorithm to use to detect state events 159 * @return a new detector with updated configuration (the instance is not changed) 160 * @see #withThreshold(double) 161 */ 162 public T withSolver(final BracketedUnivariateSolver<UnivariateFunction> newSolver) { 163 return create(getMaxCheckInterval(), getMaxIterationCount(), newSolver, getHandler()); 164 } 165 166 /** 167 * Setup the event handler to call at event occurrences. 168 * <p> 169 * This will override a handler if it has been configured previously. 170 * </p> 171 * @param newHandler event handler to call at event occurrences 172 * @return a new detector with updated configuration (the instance is not changed) 173 */ 174 public T withHandler(final ODEEventHandler newHandler) { 175 return create(getMaxCheckInterval(), getMaxIterationCount(), getSolver(), newHandler); 176 } 177 178 /** {@inheritDoc} */ 179 @Override 180 public ODEEventHandler getHandler() { 181 return handler; 182 } 183 184 /** Build a new instance. 185 * @param newMaxCheck maximum checking interval 186 * @param newmaxIter maximum number of iterations in the event time search 187 * @param newSolver root-finding algorithm to use to detect state events 188 * @param newHandler event handler to call at event occurrences 189 * @return a new instance of the appropriate sub-type 190 */ 191 protected abstract T create(AdaptableInterval newMaxCheck, int newmaxIter, 192 BracketedUnivariateSolver<UnivariateFunction> newSolver, 193 ODEEventHandler newHandler); 194 195 /** Check if the current propagation is forward or backward. 196 * @return true if the current propagation is forward 197 */ 198 public boolean isForward() { 199 return forward; 200 } 201 202 }