SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
ContinuousState.java
1/*
2 * Class: ContinuousState
3 * Description: Represents the portion of the simulator's state associated
4 with continuous-time simulation.
5 * Environment: Java
6 * Software: SSJ
7 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
8 * Organization: DIRO, Universite de Montreal
9 * @author
10 * @since
11 *
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *
25 */
26package umontreal.ssj.simevents;
27
28import java.util.List;
29import java.util.Collections;
30import java.util.ArrayList;
31
51public class ContinuousState {
52
53 // Integration methods
54 public enum IntegMethod {
55 EULER, // Euler integration method
56 RUNGEKUTTA2, // Runge-Kutta integration method of order 2
57 RUNGEKUTTA4 // Runge-Kutta integration method of order 4
58 }
59
60 private double stepSize; // Integration step size.
61 private IntegMethod integMethod; // Integration method in use.
62 private int order; // Order of the method in use.
63 private double[] A = new double[4];
64 private double[] B = new double[4];
65 private double[] C = new double[4];
66
67 // The event that actually executes integration steps.
68 private StepEvent stepEv = null;
69
70 // Class of event that executes an integration step.
71 private class StepEvent extends Event {
72 public StepEvent(Simulator sim) {
73 super(sim);
74 }
75
76 public void actions() {
77 switch (integMethod) {
78 case EULER:
79 oneStepEuler();
80 break;
81 case RUNGEKUTTA2:
82 oneStepRK();
83 break;
84 case RUNGEKUTTA4:
85 oneStepRK();
86 break;
87 default:
88 throw new IllegalArgumentException("Integration step with undefined method");
89 }
90 this.schedule(stepSize);
91 // if (afterInteg != null) afterInteg.actions();
92 }
93
94 public String toString() {
95 return "Integration step for continuous variable ";
96 }
97 }
98
99 private List<Continuous> list;
100 private Simulator sim;
101
108 protected ContinuousState(Simulator sim) {
109 this.list = new ArrayList<Continuous>();
110 this.sim = sim;
111 assert sim != null;
112 }
113
122 public List<Continuous> getContinuousVariables() {
123 return Collections.unmodifiableList(list);
124 }
125
131 protected void startInteg(Continuous c) {
132 // The following is done only the first time this method is called.
133 if (stepEv == null)
134 stepEv = new StepEvent(sim);
135 c.active = true;
136 // Inserts this in list of active variables.
137 if (list.isEmpty()) {
138 stepEv.schedule(stepSize);
139 } // There was no active variable.
140 list.add(c);
141 }
142
148 protected void stopInteg(Continuous c) {
149 c.active = false;
150 list.remove(c);
151 if (list.isEmpty())
152 stepEv.cancel();
153 }
154
161 return integMethod;
162 }
163
170 public void selectEuler(double h) {
171 integMethod = IntegMethod.EULER;
172 stepSize = h;
173 }
174
181 public void selectRungeKutta2(double h) {
182 integMethod = IntegMethod.RUNGEKUTTA2;
183 stepSize = h;
184 order = 2;
185 A[0] = 1.0;
186 A[1] = 0.0;
187 B[0] = 0.5;
188 B[1] = 0.5;
189 C[0] = 0.0;
190 C[1] = 1.0;
191 }
192
199 public void selectRungeKutta4(double h) {
200 integMethod = IntegMethod.RUNGEKUTTA4;
201 stepSize = h;
202 order = 4;
203 A[0] = 0.5;
204 A[1] = 0.5;
205 A[2] = 1.0;
206 A[3] = 0.0;
207 B[0] = 1.0 / 6.0;
208 B[1] = 1.0 / 3.0;
209 B[2] = 1.0 / 3.0;
210 B[3] = 1.0 / 6.0;
211 C[0] = 0.0;
212 C[1] = 0.5;
213 C[2] = 0.5;
214 C[3] = 1.0;
215 }
216
217 private void oneStepEuler() {
218 Continuous v;
219 double t = sim.time() - stepSize;
220 int current;
221 current = list.size();
222 while (current > 0) {
223 v = list.get(--current);
224 v.phi = v.value + stepSize * v.derivative(t);
225 }
226 current = list.size();
227 while (current > 0) {
228 v = list.get(--current);
229 v.value = v.phi;
230 if (v.ev != null)
231 v.ev.scheduleNext();
232 v.afterEachStep();
233 }
234 }
235
236 private void oneStepRK() {
237 Continuous v;
238 double t = sim.time() - stepSize;
239 int current = list.size();
240 while (current > 0) {
241 v = list.get(--current);
242 v.buffer = v.value;
243 v.sum = 0.0;
244 v.pi = 0.0;
245 }
246 for (int i = 1; i <= order - 1; i++) {
247 current = list.size();
248 while (current > 0) {
249 v = list.get(--current);
250 v.pi = v.derivative(t + stepSize * C[i - 1]);
251 v.sum = v.sum + v.pi * B[i - 1];
252 v.phi = v.buffer + stepSize * v.pi * A[i - 1];
253 }
254 current = list.size();
255 while (current > 0) {
256 v = list.get(--current);
257 v.value = v.phi;
258 }
259 }
260 current = list.size();
261 while (current > 0) {
262 v = list.get(--current);
263 v.pi = v.derivative(t + stepSize * C[order - 1]);
264 v.value = v.buffer + stepSize * (v.sum + v.pi * B[order - 1]);
265 if (v.ev != null)
266 v.ev.scheduleNext();
267 v.afterEachStep();
268 }
269 }
270}
IntegMethod integMethod()
Return an integer that represent the integration method in use.
List< Continuous > getContinuousVariables()
Returns the list of continuous-time variables currently integrated by the simulator.
void stopInteg(Continuous c)
Stops the integration process for Continuous variable.
void selectRungeKutta4(double h)
Selects a Runge-Kutta method of order&#160;4 as the integration method to be used, with step size h.
void selectRungeKutta2(double h)
Selects a Runge-Kutta method of order&#160;2 as the integration method to be used, with step size h.
void startInteg(Continuous c)
Starts the integration process that will change the state of.
void selectEuler(double h)
Selects the Euler method as the integration method, with the integration step size h,...
ContinuousState(Simulator sim)
Creates a new ContinuousState object linked to the given simulator.
Represents a variable in a continuous-time simulation.
void afterEachStep()
This method is executed after each integration step for this Continuous variable.
abstract double derivative(double t)
This method should return the derivative of this variable with respect to time, at time .
This abstract class provides event scheduling tools.
Definition Event.java:53
void scheduleNext()
Schedules this event as the first event in the event list, to be executed at the current time (as the...
Definition Event.java:166
abstract void actions()
This is the method that is executed when this event occurs.
void schedule(double delay)
Schedules this event to happen in delay time units, i.e., at time sim.time() + delay,...
Definition Event.java:153
Represents the executive of a discrete-event simulator.