1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.hipparchus.ode.nonstiff;
19
20 import org.hipparchus.exception.MathIllegalArgumentException;
21 import org.hipparchus.exception.MathIllegalStateException;
22 import org.hipparchus.linear.Array2DRowRealMatrix;
23 import org.hipparchus.linear.RealMatrix;
24 import org.hipparchus.ode.EquationsMapper;
25 import org.hipparchus.ode.ExpandableODE;
26 import org.hipparchus.ode.LocalizedODEFormats;
27 import org.hipparchus.ode.MultistepIntegrator;
28 import org.hipparchus.ode.ODEState;
29 import org.hipparchus.ode.ODEStateAndDerivative;
30
31
32
33
34
35 public abstract class AdamsIntegrator extends MultistepIntegrator {
36
37
38 private final AdamsNordsieckTransformer transformer;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public AdamsIntegrator(final String name, final int nSteps, final int order,
56 final double minStep, final double maxStep,
57 final double scalAbsoluteTolerance,
58 final double scalRelativeTolerance)
59 throws MathIllegalArgumentException {
60 super(name, nSteps, order, minStep, maxStep,
61 scalAbsoluteTolerance, scalRelativeTolerance);
62 transformer = AdamsNordsieckTransformer.getInstance(nSteps);
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public AdamsIntegrator(final String name, final int nSteps, final int order,
81 final double minStep, final double maxStep,
82 final double[] vecAbsoluteTolerance,
83 final double[] vecRelativeTolerance)
84 throws IllegalArgumentException {
85 super(name, nSteps, order, minStep, maxStep,
86 vecAbsoluteTolerance, vecRelativeTolerance);
87 transformer = AdamsNordsieckTransformer.getInstance(nSteps);
88 }
89
90
91 @Override
92 public ODEStateAndDerivative integrate(final ExpandableODE equations,
93 final ODEState initialState,
94 final double finalTime)
95 throws MathIllegalArgumentException, MathIllegalStateException {
96
97 sanityChecks(initialState, finalTime);
98 setStepStart(initIntegration(equations, initialState, finalTime));
99 final boolean forward = finalTime > initialState.getTime();
100
101
102 start(equations, getStepStart(), finalTime);
103
104
105 ODEStateAndDerivative stepEnd =
106 AdamsStateInterpolator.taylor(equations.getMapper(), getStepStart(),
107 getStepStart().getTime() + getStepSize(),
108 getStepSize(), scaled, nordsieck);
109
110
111 setIsLastStep(false);
112 final double[] y = getStepStart().getCompleteState();
113 do {
114
115 double[] predictedY = null;
116 final double[] predictedScaled = new double[y.length];
117 Array2DRowRealMatrix predictedNordsieck = null;
118 double error = 10;
119 while (error >= 1.0) {
120
121
122 predictedY = stepEnd.getCompleteState();
123
124
125 final double[] yDot = computeDerivatives(stepEnd.getTime(), predictedY);
126
127
128 for (int j = 0; j < predictedScaled.length; ++j) {
129 predictedScaled[j] = getStepSize() * yDot[j];
130 }
131 predictedNordsieck = updateHighOrderDerivativesPhase1(nordsieck);
132 updateHighOrderDerivativesPhase2(scaled, predictedScaled, predictedNordsieck);
133
134
135 error = errorEstimation(y, stepEnd.getTime(), predictedY, predictedScaled, predictedNordsieck);
136 if (Double.isNaN(error)) {
137 throw new MathIllegalStateException(LocalizedODEFormats.NAN_APPEARING_DURING_INTEGRATION,
138 stepEnd.getTime());
139 }
140
141 if (error >= 1.0) {
142
143 final double factor = computeStepGrowShrinkFactor(error);
144 rescale(getStepSizeHelper().filterStep(getStepSize() * factor, forward, false));
145 stepEnd = AdamsStateInterpolator.taylor(equations.getMapper(), getStepStart(),
146 getStepStart().getTime() + getStepSize(),
147 getStepSize(),
148 scaled,
149 nordsieck);
150
151 }
152 }
153
154 final AdamsStateInterpolator interpolator =
155 finalizeStep(getStepSize(), predictedY, predictedScaled, predictedNordsieck,
156 forward, getStepStart(), stepEnd, equations.getMapper());
157
158
159 setStepStart(acceptStep(interpolator, finalTime));
160 scaled = interpolator.getScaled();
161 nordsieck = interpolator.getNordsieck();
162
163 if (!isLastStep()) {
164
165 if (resetOccurred()) {
166
167
168
169 start(equations, getStepStart(), finalTime);
170
171 final double nextT = getStepStart().getTime() + getStepSize();
172 final boolean nextIsLast = forward ?
173 (nextT >= finalTime) :
174 (nextT <= finalTime);
175 final double hNew = nextIsLast ? finalTime - getStepStart().getTime() : getStepSize();
176
177 rescale(hNew);
178 System.arraycopy(getStepStart().getCompleteState(), 0, y, 0, y.length);
179
180 } else {
181
182
183 final double factor = computeStepGrowShrinkFactor(error);
184 final double scaledH = getStepSize() * factor;
185 final double nextT = getStepStart().getTime() + scaledH;
186 final boolean nextIsLast = forward ?
187 (nextT >= finalTime) :
188 (nextT <= finalTime);
189 double hNew = getStepSizeHelper().filterStep(scaledH, forward, nextIsLast);
190
191 final double filteredNextT = getStepStart().getTime() + hNew;
192 final boolean filteredNextIsLast = forward ? (filteredNextT >= finalTime) : (filteredNextT <= finalTime);
193 if (filteredNextIsLast) {
194 hNew = finalTime - getStepStart().getTime();
195 }
196
197 rescale(hNew);
198 System.arraycopy(predictedY, 0, y, 0, y.length);
199
200 }
201
202 stepEnd = AdamsStateInterpolator.taylor(equations.getMapper(), getStepStart(), getStepStart().getTime() + getStepSize(),
203 getStepSize(), scaled, nordsieck);
204
205 }
206
207 } while (!isLastStep());
208
209 final ODEStateAndDerivative finalState = getStepStart();
210 setStepStart(null);
211 setStepSize(Double.NaN);
212 return finalState;
213
214 }
215
216
217 @Override
218 protected Array2DRowRealMatrix initializeHighOrderDerivatives(final double h, final double[] t,
219 final double[][] y,
220 final double[][] yDot) {
221 return transformer.initializeHighOrderDerivatives(h, t, y, yDot);
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235 public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) {
236 return transformer.updateHighOrderDerivativesPhase1(highOrder);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 public void updateHighOrderDerivativesPhase2(final double[] start,
253 final double[] end,
254 final Array2DRowRealMatrix highOrder) {
255 transformer.updateHighOrderDerivativesPhase2(start, end, highOrder);
256 }
257
258
259
260
261
262
263
264
265
266
267 protected abstract double errorEstimation(double[] previousState, double predictedTime,
268 double[] predictedState, double[] predictedScaled,
269 RealMatrix predictedNordsieck);
270
271
272
273
274
275
276
277
278
279
280
281
282
283 protected abstract AdamsStateInterpolator finalizeStep(double stepSize, double[] predictedState,
284 double[] predictedScaled, Array2DRowRealMatrix predictedNordsieck,
285 boolean isForward,
286 ODEStateAndDerivative globalPreviousState,
287 ODEStateAndDerivative globalCurrentState,
288 EquationsMapper equationsMapper);
289
290 }