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