1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.ode;
24
25 import java.lang.reflect.Array;
26
27 import org.hipparchus.CalculusFieldElement;
28 import org.hipparchus.Field;
29 import org.hipparchus.analysis.solvers.BracketedRealFieldUnivariateSolver;
30 import org.hipparchus.analysis.solvers.FieldBracketingNthOrderBrentSolver;
31 import org.hipparchus.ode.events.Action;
32 import org.hipparchus.ode.events.FieldAdaptableInterval;
33 import org.hipparchus.ode.events.FieldODEEventDetector;
34 import org.hipparchus.ode.events.FieldODEEventHandler;
35 import org.hipparchus.util.FastMath;
36 import org.hipparchus.util.MathArrays;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class TestFieldProblem4<T extends CalculusFieldElement<T>>
55 extends TestFieldProblemAbstract<T> {
56
57 private static final double OFFSET = 1.2;
58
59
60 private T a;
61
62
63
64
65 public TestFieldProblem4(Field<T> field) {
66 super(convert(field, 0.0),
67 createY0(field),
68 convert(field, 15),
69 convert(field, 1.0, 0.0));
70 a = convert(field, OFFSET);
71 }
72
73 private static <T extends CalculusFieldElement<T>> T[] createY0(final Field<T> field) {
74 final T a = convert(field, OFFSET);
75 T[] y0 = MathArrays.buildArray(field, 2);
76 y0[0] = a.sin();
77 y0[1] = a.cos();
78 return y0;
79 }
80
81 @Override
82 public FieldODEEventDetector<T>[] getEventDetectors(final double maxCheck, final T threshold, final int maxIter) {
83 @SuppressWarnings("unchecked")
84 FieldODEEventDetector<T>[] handlers =
85 (FieldODEEventDetector<T>[]) Array.newInstance(FieldODEEventDetector.class, 2);
86 handlers[0] = new Bounce<>(maxCheck, threshold, maxIter);
87 handlers[1] = new Stop<>(maxCheck, threshold, maxIter);
88 return handlers;
89 }
90
91
92
93
94
95 @Override
96 public T[] getTheoreticalEventsTimes() {
97 T[] array = MathArrays.buildArray(getField(), 5);
98 array[0] = a.negate().add(1 * FastMath.PI);
99 array[1] = a.negate().add(2 * FastMath.PI);
100 array[2] = a.negate().add(3 * FastMath.PI);
101 array[3] = a.negate().add(4 * FastMath.PI);
102 array[4] = convert(a.getField(), 120.0);
103 return array;
104 }
105
106 @Override
107 public T[] doComputeDerivatives(T t, T[] y) {
108 final T[] yDot = MathArrays.buildArray(getField(), getDimension());
109 yDot[0] = y[1];
110 yDot[1] = y[0].negate();
111 return yDot;
112 }
113
114 @Override
115 public T[] computeTheoreticalState(T t) {
116 T sin = t.add(a).sin();
117 T cos = t.add(a).cos();
118 final T[] y = MathArrays.buildArray(getField(), getDimension());
119 y[0] = sin.abs();
120 y[1] = (sin.getReal() >= 0) ? cos : cos.negate();
121 return y;
122 }
123
124 private static abstract class BaseDetector<T extends CalculusFieldElement<T>>
125 implements FieldODEEventDetector<T>, FieldODEEventHandler<T> {
126
127 final double maxCheck;
128 final int maxIter;
129 final BracketedRealFieldUnivariateSolver<T> solver;
130
131 protected BaseDetector(final double maxCheck, final T threshold, final int maxIter) {
132 this.maxCheck = maxCheck;
133 this.maxIter = maxIter;
134 this.solver = new FieldBracketingNthOrderBrentSolver<>(threshold.getField().getZero(),
135 threshold,
136 threshold.getField().getZero(),
137 5);
138 }
139
140 public FieldAdaptableInterval<T> getMaxCheckInterval() {
141 return s -> maxCheck;
142 }
143
144 public int getMaxIterationCount() {
145 return maxIter;
146 }
147
148 public BracketedRealFieldUnivariateSolver<T> getSolver() {
149 return solver;
150 }
151
152 public FieldODEEventHandler<T> getHandler() {
153 return this;
154 }
155
156 }
157
158 private static class Bounce<T extends CalculusFieldElement<T>> extends BaseDetector<T> {
159
160 private int sign;
161
162 public Bounce(final double maxCheck, final T threshold, final int maxIter) {
163 super(maxCheck, threshold, maxIter);
164 sign = +1;
165 }
166
167 public void init(FieldODEStateAndDerivative<T> state0, T t) {
168 }
169
170 public T g(FieldODEStateAndDerivative<T> state) {
171 return state.getPrimaryState()[0].multiply(sign);
172 }
173
174 public Action eventOccurred(FieldODEStateAndDerivative<T> state,
175 FieldODEEventDetector<T> detector,
176 boolean increasing) {
177
178 sign = -sign;
179 return Action.RESET_STATE;
180 }
181
182 public FieldODEState<T> resetState(FieldODEEventDetector<T> detector,
183 FieldODEStateAndDerivative<T> state) {
184 T[] y = state.getPrimaryState();
185 y[0] = y[0].negate();
186 y[1] = y[1].negate();
187 return new FieldODEState<T>(state.getTime(), y);
188 }
189
190 }
191
192 private static class Stop<T extends CalculusFieldElement<T>> extends BaseDetector<T> {
193
194 public Stop(final double maxCheck, final T threshold, final int maxIter) {
195 super(maxCheck, threshold, maxIter);
196 }
197
198 public void init(FieldODEStateAndDerivative<T> state0, T t) {
199 }
200
201 public T g(FieldODEStateAndDerivative<T> state) {
202 return state.getTime().subtract(12.0);
203 }
204
205 public Action eventOccurred(FieldODEStateAndDerivative<T> state,
206 FieldODEEventDetector<T> detector,
207 boolean increasing) {
208 return Action.STOP;
209 }
210
211 public FieldODEState<T> resetState(FieldODEEventDetector<T> detector,
212 FieldODEStateAndDerivative<T> state) {
213 return state;
214 }
215
216 }
217
218 }