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.linear.RealMatrix;
28 import org.orekit.attitudes.AttitudeProvider;
29 import org.orekit.errors.OrekitException;
30 import org.orekit.errors.OrekitMessages;
31 import org.orekit.frames.Frame;
32 import org.orekit.propagation.sampling.StepHandlerMultiplexer;
33 import org.orekit.time.AbsoluteDate;
34 import org.orekit.utils.DoubleArrayDictionary;
35 import org.orekit.utils.TimeSpanMap;
36
37
38
39
40
41
42
43
44
45 public abstract class AbstractPropagator implements Propagator {
46
47
48 private final StepHandlerMultiplexer multiplexer;
49
50
51 private AbsoluteDate startDate;
52
53
54 private AttitudeProvider attitudeProvider;
55
56
57 private final List<AdditionalStateProvider> additionalStateProviders;
58
59
60 private final Map<String, TimeSpanMap<double[]>> unmanagedStates;
61
62
63 private SpacecraftState initialState;
64
65
66 private AbstractMatricesHarvester harvester;
67
68
69
70 protected AbstractPropagator() {
71 multiplexer = new StepHandlerMultiplexer();
72 additionalStateProviders = new ArrayList<>();
73 unmanagedStates = new HashMap<>();
74 harvester = null;
75 }
76
77
78
79
80 protected void setStartDate(final AbsoluteDate startDate) {
81 this.startDate = startDate;
82 }
83
84
85
86
87 protected AbsoluteDate getStartDate() {
88 return startDate;
89 }
90
91
92 public AttitudeProvider getAttitudeProvider() {
93 return attitudeProvider;
94 }
95
96
97 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
98 this.attitudeProvider = attitudeProvider;
99 }
100
101
102 public SpacecraftState getInitialState() {
103 return initialState;
104 }
105
106
107 public Frame getFrame() {
108 return initialState.getFrame();
109 }
110
111
112 public void resetInitialState(final SpacecraftState state) {
113 initialState = state;
114 setStartDate(state.getDate());
115 }
116
117
118 public StepHandlerMultiplexer getMultiplexer() {
119 return multiplexer;
120 }
121
122
123 @Override
124 public void addAdditionalStateProvider(final AdditionalStateProvider provider) {
125
126
127 if (isAdditionalStateManaged(provider.getName())) {
128
129 throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
130 provider.getName());
131 }
132
133
134 additionalStateProviders.add(provider);
135
136 }
137
138
139 @Override
140 public List<AdditionalStateProvider> getAdditionalStateProviders() {
141 return Collections.unmodifiableList(additionalStateProviders);
142 }
143
144
145 @Override
146 public MatricesHarvester setupMatricesComputation(final String stmName, final RealMatrix initialStm,
147 final DoubleArrayDictionary initialJacobianColumns) {
148 if (stmName == null) {
149 throw new OrekitException(OrekitMessages.NULL_ARGUMENT, "stmName");
150 }
151 harvester = createHarvester(stmName, initialStm, initialJacobianColumns);
152 return harvester;
153 }
154
155
156
157
158
159
160
161
162
163
164
165 protected AbstractMatricesHarvester createHarvester(final String stmName, final RealMatrix initialStm,
166 final DoubleArrayDictionary initialJacobianColumns) {
167
168 throw new UnsupportedOperationException();
169 }
170
171
172
173
174
175 protected AbstractMatricesHarvester getHarvester() {
176 return harvester;
177 }
178
179
180
181
182
183
184 protected SpacecraftState updateUnmanagedStates(final SpacecraftState original) {
185
186
187
188 SpacecraftState updated = original;
189
190
191 for (final Map.Entry<String, TimeSpanMap<double[]>> entry : unmanagedStates.entrySet()) {
192 updated = updated.addAdditionalState(entry.getKey(),
193 entry.getValue().get(original.getDate()));
194 }
195
196 return updated;
197
198 }
199
200
201
202
203
204
205
206
207 protected SpacecraftState updateAdditionalStates(final SpacecraftState original) {
208
209
210 SpacecraftState updated = updateUnmanagedStates(original);
211
212
213 final Queue<AdditionalStateProvider> pending = new LinkedList<>(getAdditionalStateProviders());
214
215
216 int yieldCount = 0;
217 while (!pending.isEmpty()) {
218 final AdditionalStateProvider provider = pending.remove();
219 if (provider.yields(updated)) {
220
221
222 pending.add(provider);
223 if (++yieldCount >= pending.size()) {
224
225
226
227 break;
228 }
229 } else {
230
231 updated = provider.update(updated);
232 yieldCount = 0;
233 }
234 }
235
236 return updated;
237
238 }
239
240
241
242
243
244
245 protected void initializeAdditionalStates(final AbsoluteDate target) {
246 for (final AdditionalStateProvider provider : additionalStateProviders) {
247 provider.init(initialState, target);
248 }
249 }
250
251
252 public boolean isAdditionalStateManaged(final String name) {
253 for (final AdditionalStateProvider provider : additionalStateProviders) {
254 if (provider.getName().equals(name)) {
255 return true;
256 }
257 }
258 return false;
259 }
260
261
262 public String[] getManagedAdditionalStates() {
263 final String[] managed = new String[additionalStateProviders.size()];
264 for (int i = 0; i < managed.length; ++i) {
265 managed[i] = additionalStateProviders.get(i).getName();
266 }
267 return managed;
268 }
269
270
271 public SpacecraftState propagate(final AbsoluteDate target) {
272 if (startDate == null) {
273 startDate = getInitialState().getDate();
274 }
275 return propagate(startDate, target);
276 }
277
278
279
280
281 protected void initializePropagation() {
282
283 unmanagedStates.clear();
284
285 if (initialState != null) {
286
287
288
289 for (final DoubleArrayDictionary.Entry initial : initialState.getAdditionalStatesValues().getData()) {
290 if (!isAdditionalStateManaged(initial.getKey())) {
291
292
293 unmanagedStates.put(initial.getKey(), new TimeSpanMap<>(initial.getValue()));
294 }
295 }
296 }
297 }
298
299
300
301
302 protected void stateChanged(final SpacecraftState state) {
303 final AbsoluteDate date = state.getDate();
304 final boolean forward = date.durationFrom(getStartDate()) >= 0.0;
305 for (final DoubleArrayDictionary.Entry changed : state.getAdditionalStatesValues().getData()) {
306 final TimeSpanMap<double[]> tsm = unmanagedStates.get(changed.getKey());
307 if (tsm != null) {
308
309 if (forward) {
310 tsm.addValidAfter(changed.getValue(), date, false);
311 } else {
312 tsm.addValidBefore(changed.getValue(), date, false);
313 }
314 }
315 }
316 }
317
318 }