View Javadoc
1   /*
2    * Licensed to the Hipparchus project 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 Hipparchus project 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    *      https://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  
18  package org.hipparchus.ode;
19  
20  import org.hipparchus.Field;
21  import org.hipparchus.analysis.solvers.BracketedRealFieldUnivariateSolver;
22  import org.hipparchus.analysis.solvers.FieldBracketingNthOrderBrentSolver;
23  import org.hipparchus.ode.events.Action;
24  import org.hipparchus.ode.events.FieldAdaptableInterval;
25  import org.hipparchus.ode.events.FieldODEEventDetector;
26  import org.hipparchus.ode.events.FieldODEEventHandler;
27  import org.hipparchus.ode.nonstiff.EulerFieldIntegrator;
28  import org.hipparchus.ode.sampling.FieldODEStateInterpolator;
29  import org.hipparchus.ode.sampling.FieldODEStepHandler;
30  import org.hipparchus.util.Binary64;
31  import org.hipparchus.util.Binary64Field;
32  import org.hipparchus.util.MathArrays;
33  import org.junit.jupiter.api.Test;
34  
35  import static org.junit.jupiter.api.Assertions.assertEquals;
36  import static org.junit.jupiter.api.Assertions.assertTrue;
37  
38  class AbstractFieldIntegratorTest {
39  
40      @Test
41      void testIntegrateWithResetDerivativesAndEventDetector() {
42          // GIVEN
43          final Field<Binary64> field = Binary64Field.getInstance();
44          final Binary64 finalTime = new Binary64(1.);
45          final EulerFieldIntegrator<Binary64> integrator = new EulerFieldIntegrator<>(field, finalTime);
46          final TestDetector detector = new TestDetector(0.5, Action.RESET_DERIVATIVES);
47          integrator.addEventDetector(detector);
48          final TestFieldProblem1<Binary64> testProblem = new TestFieldProblem1<>(field);
49          final FieldODEState<Binary64> initialState = new FieldODEState<>(Binary64.ZERO, MathArrays.buildArray(field, 2));
50          // WHEN
51          integrator.integrate(testProblem, initialState, finalTime);
52          // THEN
53          assertTrue(detector.resetted);
54      }
55  
56      @Test
57      void testUpdateStepIsCalledOncePerStepWhileHandleStepIsCalledAtEachEvent() {
58          // GIVEN
59          final Field<Binary64> field = Binary64Field.getInstance();
60          final Binary64 finalTime = new Binary64(3.);
61          final EulerFieldIntegrator<Binary64> integrator = new EulerFieldIntegrator<>(field, finalTime);
62          integrator.addStepHandler(new UpdateStepTestHandler());
63          integrator.addEventDetector(new TestDetector(0.5, Action.CONTINUE));
64          integrator.addEventDetector(new TestDetector(0.6, Action.CONTINUE));
65          final TestFieldProblem1<Binary64> testProblem = new TestFieldProblem1<>(field);
66          final FieldODEState<Binary64> initialState = new FieldODEState<>(Binary64.ZERO, MathArrays.buildArray(field, 2));
67          // WHEN
68          integrator.integrate(testProblem, initialState, finalTime);
69          // THEN
70          assertEquals(1, ((UpdateStepTestHandler) integrator.getStepHandlers().get(0)).getUpdateStepCounter());
71          assertEquals(3, ((UpdateStepTestHandler) integrator.getStepHandlers().get(0)).getHandlerStepCounter());
72      }
73  
74      private static class TestDetector implements FieldODEEventDetector<Binary64> {
75  
76          boolean resetted = false;
77          double rootTime;
78          Action action;
79  
80          public TestDetector(double rootTime, Action action) {
81              this.rootTime = rootTime;
82              this.action = action;
83          }
84  
85          @Override
86          public void reset(FieldODEStateAndDerivative<Binary64> intermediateState, Binary64 finalTime) {
87              FieldODEEventDetector.super.reset(intermediateState, finalTime);
88              resetted = true;
89          }
90  
91          @Override
92          public FieldAdaptableInterval<Binary64> getMaxCheckInterval() {
93              return FieldAdaptableInterval.of(1);
94          }
95  
96          @Override
97          public int getMaxIterationCount() {
98              return 10;
99          }
100 
101         @Override
102         public BracketedRealFieldUnivariateSolver<Binary64> getSolver() {
103             return new FieldBracketingNthOrderBrentSolver<>(new Binary64(1e-14), new Binary64(1e-6), new Binary64(1e-15), 5);
104         }
105 
106         @Override
107         public FieldODEEventHandler<Binary64> getHandler() {
108             return (state, detector, increasing) -> action;
109         }
110 
111         @Override
112         public Binary64 g(FieldODEStateAndDerivative<Binary64> state) {
113             return state.getTime().subtract(rootTime);
114         }
115     }
116 
117     private static class UpdateStepTestHandler implements FieldODEStepHandler<Binary64> {
118 
119         private int handlerStepCounter = 0;
120         private int updateStepCounter = 0;
121 
122         @Override
123         public void handleStep(FieldODEStateInterpolator<Binary64> interpolator) {
124             handlerStepCounter++;
125         }
126 
127         @Override
128         public void updateOnStep(FieldODEStateInterpolator<Binary64> interpolator) {
129             updateStepCounter++;
130         }
131 
132         public int getHandlerStepCounter() {
133             return handlerStepCounter;
134         }
135 
136         public int getUpdateStepCounter() {
137             return updateStepCounter;
138         }
139     }
140 
141 }