1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.ode.events;
23
24 import org.hipparchus.analysis.UnivariateFunction;
25 import org.hipparchus.analysis.solvers.BracketedUnivariateSolver;
26 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.exception.MathIllegalStateException;
29 import org.hipparchus.ode.ODEIntegrator;
30 import org.hipparchus.ode.ODEState;
31 import org.hipparchus.ode.ODEStateAndDerivative;
32 import org.hipparchus.ode.OrdinaryDifferentialEquation;
33 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
34 import org.junit.jupiter.api.Test;
35
36 import java.util.ArrayList;
37 import java.util.List;
38
39 import static org.junit.jupiter.api.Assertions.assertEquals;
40
41
42
43
44 public class OverlappingEventsTest implements OrdinaryDifferentialEquation {
45
46
47 private static final double[] EVENT_TIMES1 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
48 7.0, 8.0, 9.0};
49
50
51 private static final double[] EVENT_TIMES2 = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0,
52 3.5, 4.0, 4.5, 5.0, 5.5, 6.0,
53 6.5, 7.0, 7.5, 8.0, 8.5, 9.0,
54 9.5};
55
56
57
58
59
60
61 @Test
62 void testOverlappingEvents0()
63 throws MathIllegalArgumentException, MathIllegalStateException {
64 test(0);
65 }
66
67
68
69
70
71
72 @Test
73 void testOverlappingEvents1()
74 throws MathIllegalArgumentException, MathIllegalStateException {
75 test(1);
76 }
77
78
79
80
81
82
83
84 public void test(int eventType)
85 throws MathIllegalArgumentException, MathIllegalStateException {
86 double e = 1e-15;
87 ODEIntegrator integrator = new DormandPrince853Integrator(e, 100.0, 1e-7, 1e-7);
88 ODEEventDetector evt1 = new Event(0.1, e, 999, 0, eventType);
89 ODEEventDetector evt2 = new Event(0.1, e, 999, 1, eventType);
90 integrator.addEventDetector(evt1);
91 integrator.addEventDetector(evt2);
92 double t = 0.0;
93 double tEnd = 9.75;
94 double[] y = {0.0, 0.0};
95 List<Double> events1 = new ArrayList<Double>();
96 List<Double> events2 = new ArrayList<Double>();
97 while (t < tEnd) {
98 final ODEStateAndDerivative finalState =
99 integrator.integrate(this, new ODEState(t, y), tEnd);
100 t = finalState.getTime();
101 y = finalState.getPrimaryState();
102
103 if (y[0] >= 1.0) {
104 y[0] = 0.0;
105 events1.add(t);
106
107 }
108 if (y[1] >= 1.0) {
109 y[1] = 0.0;
110 events2.add(t);
111
112 }
113 }
114 assertEquals(EVENT_TIMES1.length, events1.size());
115 assertEquals(EVENT_TIMES2.length, events2.size());
116 for(int i = 0; i < EVENT_TIMES1.length; i++) {
117 assertEquals(EVENT_TIMES1[i], events1.get(i), 1e-7);
118 }
119 for(int i = 0; i < EVENT_TIMES2.length; i++) {
120 assertEquals(EVENT_TIMES2[i], events2.get(i), 1e-7);
121 }
122
123 }
124
125
126 public int getDimension() {
127 return 2;
128 }
129
130
131 public double[] computeDerivatives(double t, double[] y) {
132 return new double[] { 1.0, 2.0 };
133 }
134
135
136 private class Event implements ODEEventDetector {
137
138 private final AdaptableInterval maxCheck;
139 private final int maxIter;
140 private final BracketingNthOrderBrentSolver solver;
141 private final int idx;
142 private final int eventType;
143
144
145
146
147
148
149
150
151 public Event(final double maxCheck, final double threshold, final int maxIter,
152 final int idx, final int eventType) {
153 this.maxCheck = (s, isForward) -> maxCheck;
154 this.maxIter = maxIter;
155 this.solver = new BracketingNthOrderBrentSolver(0, threshold, 0, 5);
156 this.idx = idx;
157 this.eventType = eventType;
158 }
159
160 public AdaptableInterval getMaxCheckInterval() {
161 return maxCheck;
162 }
163
164 public int getMaxIterationCount() {
165 return maxIter;
166 }
167
168 public BracketedUnivariateSolver<UnivariateFunction> getSolver() {
169 return solver;
170 }
171
172 public ODEEventHandler getHandler() {
173 return (state, detector, increasing) -> Action.STOP;
174 }
175
176
177 public double g(ODEStateAndDerivative s) {
178 return (eventType == 0) ? s.getPrimaryState()[idx] >= 1.0 ? 1.0 : -1.0
179 : s.getPrimaryState()[idx] - 1.0;
180 }
181
182 }
183
184 }