1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Queue;
26
27 import org.hipparchus.CalculusFieldElement;
28 import org.hipparchus.Field;
29 import org.orekit.attitudes.AttitudeProvider;
30 import org.orekit.errors.OrekitException;
31 import org.orekit.errors.OrekitMessages;
32 import org.orekit.frames.Frame;
33 import org.orekit.propagation.sampling.FieldStepHandlerMultiplexer;
34 import org.orekit.time.FieldAbsoluteDate;
35 import org.orekit.utils.FieldArrayDictionary;
36 import org.orekit.utils.FieldTimeSpanMap;
37 import org.orekit.utils.TimeStampedFieldPVCoordinates;
38
39
40
41
42
43
44
45
46
47
48 public abstract class FieldAbstractPropagator<T extends CalculusFieldElement<T>> implements FieldPropagator<T> {
49
50
51 private FieldStepHandlerMultiplexer<T> multiplexer;
52
53
54 private FieldAbsoluteDate<T> startDate;
55
56
57 private AttitudeProvider attitudeProvider;
58
59
60 private final List<FieldAdditionalStateProvider<T>> additionalStateProviders;
61
62
63 private final Map<String, FieldTimeSpanMap<T[], T>> unmanagedStates;
64
65
66 private final Field<T> field;
67
68
69 private FieldSpacecraftState<T> initialState;
70
71
72
73
74 protected FieldAbstractPropagator(final Field<T> field) {
75 this.field = field;
76 multiplexer = new FieldStepHandlerMultiplexer<>();
77 additionalStateProviders = new ArrayList<>();
78 unmanagedStates = new HashMap<>();
79 }
80
81
82
83
84 protected void setStartDate(final FieldAbsoluteDate<T> startDate) {
85 this.startDate = startDate;
86 }
87
88
89
90
91 protected FieldAbsoluteDate<T> getStartDate() {
92 return startDate;
93 }
94
95
96 public AttitudeProvider getAttitudeProvider() {
97 return attitudeProvider;
98 }
99
100
101 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
102 this.attitudeProvider = attitudeProvider;
103 }
104
105
106
107 public Field<T> getField() {
108 return field;
109 }
110
111
112 public FieldSpacecraftState<T> getInitialState() {
113 return initialState;
114 }
115
116
117 public Frame getFrame() {
118 return initialState.getFrame();
119 }
120
121
122 public void resetInitialState(final FieldSpacecraftState<T> state) {
123 initialState = state;
124 setStartDate(state.getDate());
125 }
126
127
128 public FieldStepHandlerMultiplexer<T> getMultiplexer() {
129 return multiplexer;
130 }
131
132
133 public void addAdditionalStateProvider(final FieldAdditionalStateProvider<T> additionalStateProvider) {
134
135
136 if (isAdditionalStateManaged(additionalStateProvider.getName())) {
137
138 throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
139 additionalStateProvider.getName());
140 }
141
142
143 additionalStateProviders.add(additionalStateProvider);
144
145 }
146
147
148 public List<FieldAdditionalStateProvider<T>> getAdditionalStateProviders() {
149 return Collections.unmodifiableList(additionalStateProviders);
150 }
151
152
153
154
155
156
157 protected FieldSpacecraftState<T> updateUnmanagedStates(final FieldSpacecraftState<T> original) {
158
159
160
161 FieldSpacecraftState<T> updated = original;
162
163
164 for (final Map.Entry<String, FieldTimeSpanMap<T[], T>> entry : unmanagedStates.entrySet()) {
165 updated = updated.addAdditionalState(entry.getKey(),
166 entry.getValue().get(original.getDate()));
167 }
168
169 return updated;
170
171 }
172
173
174
175
176
177
178 protected FieldSpacecraftState<T> updateAdditionalStates(final FieldSpacecraftState<T> original) {
179
180
181 FieldSpacecraftState<T> updated = updateUnmanagedStates(original);
182
183
184 final Queue<FieldAdditionalStateProvider<T>> pending = new LinkedList<>(getAdditionalStateProviders());
185
186
187 int yieldCount = 0;
188 while (!pending.isEmpty()) {
189 final FieldAdditionalStateProvider<T> provider = pending.remove();
190 if (provider.yield(updated)) {
191
192
193 pending.add(provider);
194 if (++yieldCount >= pending.size()) {
195
196
197
198 break;
199 }
200 } else {
201
202 updated = updated.addAdditionalState(provider.getName(), provider.getAdditionalState(updated));
203 yieldCount = 0;
204 }
205 }
206
207 return updated;
208
209 }
210
211
212 public boolean isAdditionalStateManaged(final String name) {
213 for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {
214 if (provider.getName().equals(name)) {
215 return true;
216 }
217 }
218 return false;
219 }
220
221
222 public String[] getManagedAdditionalStates() {
223 final String[] managed = new String[additionalStateProviders.size()];
224 for (int i = 0; i < managed.length; ++i) {
225 managed[i] = additionalStateProviders.get(i).getName();
226 }
227 return managed;
228 }
229
230
231 public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> target) {
232 if (startDate == null) {
233 startDate = getInitialState().getDate();
234 }
235 return propagate(startDate, target);
236 }
237
238
239 public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame) {
240 return propagate(date).getPVCoordinates(frame);
241 }
242
243
244
245
246 protected void initializePropagation() {
247
248 unmanagedStates.clear();
249
250 if (initialState != null) {
251
252
253
254 for (final FieldArrayDictionary<T>.Entry initial : initialState.getAdditionalStatesValues().getData()) {
255 if (!isAdditionalStateManaged(initial.getKey())) {
256
257
258 unmanagedStates.put(initial.getKey(),
259 new FieldTimeSpanMap<>(initial.getValue(),
260 initialState.getDate().getField()));
261 }
262 }
263 }
264 }
265
266
267
268
269 protected void stateChanged(final FieldSpacecraftState<T> state) {
270 final FieldAbsoluteDate<T> date = state.getDate();
271 final boolean forward = date.durationFrom(getStartDate()).getReal() >= 0.0;
272 for (final FieldArrayDictionary<T>.Entry changed : state.getAdditionalStatesValues().getData()) {
273 final FieldTimeSpanMap<T[], T> tsm = unmanagedStates.get(changed.getKey());
274 if (tsm != null) {
275
276 if (forward) {
277 tsm.addValidAfter(changed.getValue(), date);
278 } else {
279 tsm.addValidBefore(changed.getValue(), date);
280 }
281 }
282 }
283 }
284
285 }