1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.ode.events;
18
19 import org.hipparchus.analysis.UnivariateFunction;
20 import org.hipparchus.analysis.solvers.BracketedUnivariateSolver;
21 import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
22 import org.hipparchus.ode.ODEIntegrator;
23 import org.hipparchus.ode.ODEState;
24 import org.hipparchus.ode.ODEStateAndDerivative;
25 import org.hipparchus.ode.OrdinaryDifferentialEquation;
26 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
27 import org.hipparchus.util.FastMath;
28 import org.junit.Assert;
29 import org.junit.Test;
30
31
32
33 public class VariableCheckInterval implements OrdinaryDifferentialEquation {
34
35 @Test
36 public void testFixedInterval() {
37 double tZero = 7.0;
38 double width = 0.25;
39 doTest(tZero, width, s -> width / 25, 710);
40 }
41
42 @Test
43 public void testWidthAwareInterval() {
44 double tZero = 7.0;
45 double width = 0.25;
46 doTest(tZero, width,
47 s -> {
48 if (s.getTime() < tZero - 0.5 * width) {
49 return tZero - 0.25 * width - s.getTime();
50 } else if (s.getTime() > tZero + 0.5 * width) {
51 return s.getTime() - (tZero + 0.25 * width);
52 } else {
53 return width / 25;
54 }
55 },
56 21);
57 }
58
59 private void doTest(final double tZero, final double width, final AdaptableInterval checkInterval,
60 final int expectedCalls) {
61 double e = 1e-15;
62 ODEIntegrator integrator = new DormandPrince853Integrator(e, 100.0, 1e-7, 1e-7);
63 Event evt = new Event(checkInterval, e, 999, tZero, width);
64 integrator.addEventDetector(evt);
65 double t = 0.0;
66 double tEnd = 9.75;
67 double[] y = {0.0, 0.0};
68 final ODEStateAndDerivative finalState =
69 integrator.integrate(this, new ODEState(t, y), tEnd);
70 t = finalState.getTime();
71 Assert.assertEquals(tZero, finalState.getTime(), e);
72 Assert.assertEquals(expectedCalls, evt.count);
73 }
74
75
76 public int getDimension() {
77 return 2;
78 }
79
80
81 public double[] computeDerivatives(double t, double[] y) {
82 return new double[] { 1.0, 2.0 };
83 }
84
85
86 private class Event implements ODEEventDetector {
87
88 private final AdaptableInterval maxCheck;
89 private final int maxIter;
90 private final BracketingNthOrderBrentSolver solver;
91 private final double tZero;
92 private final double width;
93 private int count;
94
95
96
97
98
99
100
101
102 public Event(final AdaptableInterval maxCheck, final double threshold, final int maxIter,
103 final double tZero, final double width) {
104 this.maxCheck = maxCheck;
105 this.maxIter = maxIter;
106 this.solver = new BracketingNthOrderBrentSolver(0, threshold, 0, 5);
107 this.tZero = tZero;
108 this.width = width;
109 }
110
111 public AdaptableInterval getMaxCheckInterval() {
112 return maxCheck;
113 }
114
115 public int getMaxIterationCount() {
116 return maxIter;
117 }
118
119 public BracketedUnivariateSolver<UnivariateFunction> getSolver() {
120 return solver;
121 }
122
123 public ODEEventHandler getHandler() {
124 return (state, detector, increasing) -> Action.STOP;
125 }
126
127
128 public double g(final ODEStateAndDerivative s) {
129 ++count;
130 final double t = s.getTime();
131 return FastMath.max(-0.5 * width, FastMath.min(0.5 * width, t - tZero));
132 }
133
134
135 public void init(final ODEStateAndDerivative initialState, final double finalTime) {
136 count = 0;
137 }
138
139 }
140
141 }