1   /* Contributed in the public domain.
2    * Licensed to CS Group (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS 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    *   http://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.orekit.propagation.events;
18  
19  import java.util.function.Function;
20  
21  import org.hipparchus.Field;
22  import org.hipparchus.CalculusFieldElement;
23  import org.orekit.propagation.FieldSpacecraftState;
24  import org.orekit.propagation.events.handlers.ContinueOnEvent;
25  import org.orekit.propagation.events.handlers.FieldContinueOnEvent;
26  import org.orekit.propagation.events.handlers.FieldEventHandler;
27  
28  /**
29   * A detector that implements the {@link #g(FieldSpacecraftState)} function using a lambda
30   * that can be set using {@link #withFunction(Function)}.
31   *
32   * <p>For example, to create a simple date detector use:
33   *
34   * <pre>
35   * FieldFunctionalDetector&lt;T&gt; d = new FieldFunctionalDetector&lt;&gt;(field)
36   *     .withGFunction((s) -&gt; s.getDate().durationFrom(triggerDate))
37   *     .withMaxCheck(field.getZero().add(1e10));
38   * </pre>
39   *
40   * @param <T> the type of numbers this detector uses.
41   * @author Evan Ward
42   * @since 10.2
43   */
44  public class FieldFunctionalDetector<T extends CalculusFieldElement<T>>
45          extends FieldAbstractDetector<FieldFunctionalDetector<T>, T> {
46  
47      /** The g function. */
48      private final Function<FieldSpacecraftState<T>, T> function;
49  
50      /**
51       * Create an event detector with the default values. These are {@link
52       * #DEFAULT_MAXCHECK}, {@link #DEFAULT_THRESHOLD}, {@link #DEFAULT_MAX_ITER}, {@link
53       * ContinueOnEvent}, and a g function that is identically unity.
54       *
55       * @param field on which this detector is defined.
56       */
57      public FieldFunctionalDetector(final Field<T> field) {
58          this(FieldAdaptableInterval.of(DEFAULT_MAXCHECK),
59               field.getZero().newInstance(DEFAULT_THRESHOLD),
60               DEFAULT_MAX_ITER,
61               new FieldContinueOnEvent<>(), value -> field.getOne());
62      }
63  
64      /**
65       * Private constructor.
66       *
67       * @param maxCheck  maximum checking interval
68       * @param threshold convergence threshold (s)
69       * @param maxIter   maximum number of iterations in the event time search
70       * @param handler   event handler to call at event occurrences
71       * @param function  the switching function.
72       */
73      protected FieldFunctionalDetector(
74              final FieldAdaptableInterval<T> maxCheck,
75              final T threshold,
76              final int maxIter,
77              final FieldEventHandler<T> handler,
78              final Function<FieldSpacecraftState<T>, T> function) {
79          super(maxCheck, threshold, maxIter, handler);
80          this.function = function;
81      }
82  
83  
84      @Override
85      public T g(final FieldSpacecraftState<T> s) {
86          return function.apply(s);
87      }
88  
89      @Override
90      protected FieldFunctionalDetector<T> create(
91              final FieldAdaptableInterval<T> newMaxCheck,
92              final T newThreshold,
93              final int newMaxIter,
94              final FieldEventHandler<T> newHandler) {
95  
96          return new FieldFunctionalDetector<>(newMaxCheck, newThreshold, newMaxIter,
97                  newHandler, function);
98      }
99  
100     /**
101      * Create a new event detector with a new g function, keeping all other attributes the
102      * same. It is recommended to use {@link #withMaxCheck(FieldAdaptableInterval)} and {@link
103      * #withThreshold(CalculusFieldElement)} to set appropriate values for this g function.
104      *
105      * @param newGFunction the new g function.
106      * @return a new detector with the new g function.
107      */
108     public FieldFunctionalDetector<T> withFunction(
109             final Function<FieldSpacecraftState<T>, T> newGFunction) {
110         return new FieldFunctionalDetector<>(getMaxCheckInterval(), getThreshold(),
111                 getMaxIterationCount(), getHandler(), newGFunction);
112     }
113 
114     /**
115      * Get the switching function.
116      *
117      * @return the function used in {@link #g(FieldSpacecraftState)}.
118      */
119     public Function<FieldSpacecraftState<T>, T> getFunction() {
120         return function;
121     }
122 
123 }