1   /* Copyright 2022-2025 Romain Serra
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 org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.orekit.propagation.FieldSpacecraftState;
22  import org.orekit.propagation.events.intervals.FieldAdaptableInterval;
23  
24  /**
25   * Class containing parameters for event detection.
26   *
27   * @author Romain Serra.
28   * @since 12.2
29   * @see EventDetectionSettings
30   * @see FieldEventDetector
31   */
32  public class FieldEventDetectionSettings <T extends CalculusFieldElement<T>> {
33  
34      /** Default maximum checking interval (s). */
35      public static final double DEFAULT_MAX_CHECK = EventDetectionSettings.DEFAULT_MAX_CHECK;
36  
37      /** Default convergence threshold (s). */
38      public static final double DEFAULT_THRESHOLD = EventDetectionSettings.DEFAULT_THRESHOLD;
39  
40      /** Default maximum number of iterations in the event time search. */
41      public static final int DEFAULT_MAX_ITER = EventDetectionSettings.DEFAULT_MAX_ITER;
42  
43      /** Adaptable interval for maximum time without event evaluation. */
44      private final FieldAdaptableInterval<T> maxCheckInterval;
45  
46      /** Detection threshold (s). */
47      private final T threshold;
48  
49      /** Maximum iteration number when detecting event. */
50      private final int maxIterationCount;
51  
52      /**
53       * Constructor.
54       *
55       * @param maxCheckInterval  adaptable interval
56       * @param threshold         detection threshold on time
57       * @param maxIterationCount maximum iteration number
58       */
59      public FieldEventDetectionSettings(final FieldAdaptableInterval<T> maxCheckInterval, final T threshold,
60                                         final int maxIterationCount) {
61          this.maxCheckInterval = maxCheckInterval;
62          this.maxIterationCount = maxIterationCount;
63          this.threshold = threshold;
64      }
65  
66      /**
67       * Constructor with maximum check as double.
68       *
69       * @param maxCheck          constant maximum check for adaptable interval
70       * @param threshold         detection threshold on time
71       * @param maxIterationCount maximum iteration number
72       */
73      public FieldEventDetectionSettings(final double maxCheck, final T threshold, final int maxIterationCount) {
74          this(FieldAdaptableInterval.of(maxCheck), threshold, maxIterationCount);
75      }
76  
77      /**
78       * Constructor from non-Field settings.
79       *
80       * @param field field
81       * @param eventDetectionSettings non-Field detection settings
82       */
83      public FieldEventDetectionSettings(final Field<T> field, final EventDetectionSettings eventDetectionSettings) {
84          this(FieldAdaptableInterval.of(eventDetectionSettings.getMaxCheckInterval()),
85              field.getZero().newInstance(eventDetectionSettings.getThreshold()), eventDetectionSettings.getMaxIterationCount());
86      }
87  
88      /**
89       * Getter for adaptable interval.
90       * @return adaptable interval
91       */
92      public FieldAdaptableInterval<T> getMaxCheckInterval() {
93          return maxCheckInterval;
94      }
95  
96      /**
97       * Getter for threshold.
98       * @return threshold
99       */
100     public T getThreshold() {
101         return threshold;
102     }
103 
104     /**
105      * Getter for max iter.
106      * @return max iter
107      */
108     public int getMaxIterationCount() {
109         return maxIterationCount;
110     }
111 
112     /**
113      * Builds a new instance with a new max. check interval.
114      * @param newMaxCheckInterval new max. check.
115      * @return new object
116      * @since 13.0
117      */
118     public FieldEventDetectionSettings<T> withMaxCheckInterval(final FieldAdaptableInterval<T> newMaxCheckInterval) {
119         return new FieldEventDetectionSettings<>(newMaxCheckInterval, threshold, maxIterationCount);
120     }
121 
122     /**
123      * Builds a new instance with a new threshold value.
124      * @param newThreshold detection threshold in seconds
125      * @return new object
126      * @since 13.0
127      */
128     public FieldEventDetectionSettings<T> withThreshold(final T newThreshold) {
129         return new FieldEventDetectionSettings<>(maxCheckInterval, newThreshold, maxIterationCount);
130     }
131 
132     /**
133      * Builds a new instance with a new max. iteration count.
134      * @param newMaxIterationCount new max iteration count.
135      * @return new object
136      * @since 13.0
137      */
138     public FieldEventDetectionSettings<T> withMaxIter(final int newMaxIterationCount) {
139         return new FieldEventDetectionSettings<>(maxCheckInterval, threshold, newMaxIterationCount);
140     }
141 
142     /**
143      * Returns default settings for event detections.
144      * @param <T> field type
145      * @param field field
146      * @return default settings
147      * @since 13.0
148      */
149     public static <T extends CalculusFieldElement<T>> FieldEventDetectionSettings<T> getDefaultEventDetectionSettings(final Field<T> field) {
150         return new FieldEventDetectionSettings<>(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK),
151                 field.getZero().newInstance(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER);
152     }
153 
154     /**
155      * Create a non-Field equivalent object.
156      * @return event detection settings
157      */
158     public EventDetectionSettings toEventDetectionSettings() {
159         return new EventDetectionSettings((state, isForward) -> getMaxCheckInterval().currentInterval(new FieldSpacecraftState<>(getThreshold().getField(), state), isForward),
160                 getThreshold().getReal(), getMaxIterationCount());
161     }
162 }