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 org.hipparchus.analysis.UnivariateFunction;
26 import org.hipparchus.analysis.solvers.BracketedUnivariateSolver;
27 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
28 import org.hipparchus.ode.events.Action;
29 import org.hipparchus.ode.events.AdaptableInterval;
30 import org.hipparchus.ode.events.ODEEventDetector;
31 import org.hipparchus.ode.events.ODEEventHandler;
32 import org.hipparchus.util.FastMath;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class TestProblem4 extends TestProblemAbstract {
50
51 private static final double OFFSET = 1.2;
52
53
54 private double a;
55
56
57 public TestProblem4() {
58 super(0.0, new double[] { FastMath.sin(OFFSET), FastMath.cos(OFFSET) },
59 15, new double[] { 1.0, 0.0 });
60 a = OFFSET;
61 }
62
63 @Override
64 public ODEEventDetector[] getEventDetectors(final double maxCheck, final double threshold, final int maxIter) {
65 return new ODEEventDetector[] {
66 new Bounce(maxCheck, threshold, maxIter),
67 new Stop(maxCheck, threshold, maxIter)
68 };
69 }
70
71
72
73
74
75 @Override
76 public double[] getTheoreticalEventsTimes() {
77 return new double[] {
78 1 * FastMath.PI - a,
79 2 * FastMath.PI - a,
80 3 * FastMath.PI - a,
81 4 * FastMath.PI - a,
82 12.0
83 };
84 }
85
86 @Override
87 public double[] doComputeDerivatives(double t, double[] y) {
88 return new double[] {
89 y[1], -y[0]
90 };
91 }
92
93 @Override
94 public double[] computeTheoreticalState(double t) {
95 double sin = FastMath.sin(t + a);
96 double cos = FastMath.cos(t + a);
97 return new double[] {
98 FastMath.abs(sin),
99 (sin >= 0) ? cos : -cos
100 };
101 }
102
103 private static abstract class BaseDetector implements ODEEventDetector, ODEEventHandler {
104
105 final double maxCheck;
106 final int maxIter;
107 final BracketedUnivariateSolver<UnivariateFunction> solver;
108
109 protected BaseDetector(final double maxCheck, final double threshold, final int maxIter) {
110 this.maxCheck = maxCheck;
111 this.maxIter = maxIter;
112 this.solver = new BracketingNthOrderBrentSolver(0, threshold, 0, 5);
113 }
114
115 public AdaptableInterval getMaxCheckInterval() {
116 return s -> maxCheck;
117 }
118
119 public int getMaxIterationCount() {
120 return maxIter;
121 }
122
123 public BracketedUnivariateSolver<UnivariateFunction> getSolver() {
124 return solver;
125 }
126
127 public ODEEventHandler getHandler() {
128 return this;
129 }
130
131 }
132
133 private static class Bounce extends BaseDetector {
134
135 private int sign;
136
137 public Bounce(final double maxCheck, final double threshold, final int maxIter) {
138 super(maxCheck, threshold, maxIter);
139 sign = +1;
140 }
141
142 public double g(ODEStateAndDerivative s) {
143 return sign * s.getPrimaryState()[0];
144 }
145
146 public Action eventOccurred(ODEStateAndDerivative s, ODEEventDetector detector, boolean increasing) {
147
148 sign = -sign;
149 return Action.RESET_STATE;
150 }
151
152 public ODEStateAndDerivative resetState(ODEEventDetector detector, ODEStateAndDerivative s) {
153 final double[] y = s.getPrimaryState();
154 final double[] yDot = s.getPrimaryDerivative();
155 y[0] = -y[0];
156 y[1] = -y[1];
157 yDot[0] = -yDot[0];
158 yDot[1] = -yDot[1];
159 return new ODEStateAndDerivative(s.getTime(), y, yDot);
160 }
161
162 }
163
164 private static class Stop extends BaseDetector {
165
166 public Stop(final double maxCheck, final double threshold, final int maxIter) {
167 super(maxCheck, threshold, maxIter);
168 }
169
170 public double g(ODEStateAndDerivative s) {
171 return s.getTime() - 12.0;
172 }
173
174 public Action eventOccurred(ODEStateAndDerivative s, ODEEventDetector detector, boolean increasing) {
175 return Action.STOP;
176 }
177
178 }
179
180 }