View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.ode.events;
18  
19  import org.apache.commons.math4.legacy.ode.FirstOrderDifferentialEquations;
20  import org.apache.commons.math4.legacy.ode.FirstOrderIntegrator;
21  import org.apache.commons.math4.legacy.ode.nonstiff.DormandPrince853Integrator;
22  import org.junit.Assert;
23  import org.junit.Test;
24  
25  /**
26   * Check events are detected correctly when the event times are close.
27   *
28   * @author Evan Ward
29   */
30  public class CloseEventsTest {
31  
32      @Test
33      public void testCloseEvents() {
34          // setup
35          double e = 1e-15;
36          FirstOrderIntegrator integrator =
37                  new DormandPrince853Integrator(e, 100.0, 1e-7, 1e-7);
38  
39          TimeDetector detector1 = new TimeDetector(5);
40          integrator.addEventHandler(detector1, 10, 1, 100);
41          TimeDetector detector2 = new TimeDetector(5.5);
42          integrator.addEventHandler(detector2, 10, 1, 100);
43  
44          // action
45          integrator.integrate(new Equation(), 0, new double[2], 20, new double[2]);
46  
47          // verify
48          Assert.assertEquals(5, detector1.getActualT(), 0.0);
49          Assert.assertEquals(5.5, detector2.getActualT(), 0.0);
50      }
51  
52      @Test
53      public void testSimultaneousEvents() {
54          // setup
55          double e = 1e-15;
56          FirstOrderIntegrator integrator =
57                  new DormandPrince853Integrator(e, 100.0, 1e-7, 1e-7);
58  
59          TimeDetector detector1 = new TimeDetector(5);
60          integrator.addEventHandler(detector1, 10, 1, 100);
61          TimeDetector detector2 = new TimeDetector(5);
62          integrator.addEventHandler(detector2, 10, 1, 100);
63  
64          // action
65          integrator.integrate(new Equation(), 0, new double[2], 20, new double[2]);
66  
67          // verify
68          Assert.assertEquals(5, detector1.getActualT(), 0.0);
69          Assert.assertEquals(5, detector2.getActualT(), 0.0);
70      }
71  
72  
73      /** Trigger an event at a particular time. */
74      private static final class TimeDetector implements EventHandler {
75  
76          /** time of the event to trigger. */
77          private final double eventT;
78  
79          /** time the event was actually triggered. */
80          private double actualT;
81  
82          /**
83           * Create a new detector.
84           *
85           * @param eventT the time to trigger an event.
86           */
87          TimeDetector(double eventT) {
88              this.eventT = eventT;
89          }
90  
91          /** Get the actual time the event occurred. */
92          public double getActualT() {
93              return actualT;
94          }
95  
96          @Override
97          public void init(double t0, double[] y0, double t) {
98          }
99  
100         @Override
101         public double g(double t, double[] y) {
102             return t - eventT;
103         }
104 
105         @Override
106         public Action eventOccurred(double t, double[] y, boolean increasing) {
107             this.actualT = t;
108             return Action.CONTINUE;
109         }
110 
111         @Override
112         public void resetState(double t, double[] y) {
113         }
114     }
115 
116     /** Some basic equations to integrate. */
117     public static class Equation implements FirstOrderDifferentialEquations {
118 
119         @Override
120         public int getDimension() {
121             return 2;
122         }
123 
124         @Override
125         public void computeDerivatives(double t, double[] y, double[] yDot) {
126             yDot[0] = 1.0;
127             yDot[1] = 2.0;
128         }
129     }
130 }