-
-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathPMAB3Solver.class.st
More file actions
135 lines (113 loc) · 4.25 KB
/
PMAB3Solver.class.st
File metadata and controls
135 lines (113 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"
We can't use AB3 method until we have three old solution values. A AB3 method is explicit. We found starting point with Midpoint Method (RK2) and the next point with AB2 method.
"
Class {
#name : #PMAB3Solver,
#superclass : #PMAB2Solver,
#category : #'Math-ODE'
}
{ #category : #'as yet unclassified' }
PMAB3Solver class >> secondStepperClass [
^ PMAB2Stepper
]
{ #category : #'as yet unclassified' }
PMAB3Solver class >> stepperClass [
^ PMAB3Stepper
]
{ #category : #'as yet unclassified' }
PMAB3Solver >> lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime [
"catch partial or full step at end"
(lastTime equalsTo: endTime )
ifFalse:
[state := stepper
lastStep: state
prevState: prevState
prevPrevState: prevPrevState
prevPrevTime: lastTime-(2*dt)
stepSize: endTime - lastTime
deltaT: dt.
self announceState: state time: endTime].
^ state
]
{ #category : #'as yet unclassified' }
PMAB3Solver >> mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime [
|previousState previousPrevState |
previousState := prevState.
previousPrevState:=prevPrevState.
"don't go to end time to avoid overrunning"
(initialTime to: endTime - (3*self dt) by: self dt) do:
[:time | | tempState1 tempState2|
tempState1 := state.
tempState2:=previousState.
state := stepper
doStep: state
prevState: previousState
prevPrevState: previousPrevState
prevPrevTime: time
stepSize: self dt.
previousPrevState:=tempState2.
previousState := tempState1.
"announce step results"
self announceState: state time: time + self dt.
lastTime := time + (3*self dt)].
^ { previousPrevState. previousState}
]
{ #category : #'as yet unclassified' }
PMAB3Solver >> secondStepPrevState: prevState startTime: t [
state := stepper doStep: state prevState: prevState time: t stepSize: self dt.
self announceState: state time: t + self dt.
lastTime := t + self dt.
^ state
]
{ #category : #'as yet unclassified' }
PMAB3Solver >> secondStepperClass [
^ self class secondStepperClass
]
{ #category : #'as yet unclassified' }
PMAB3Solver >> solve: aSystem startState: initialState startTime: initialTime endTime: endTime [
|prevState prevPrevState statesPair |
self system: aSystem.
self stepper: ((self firstStepperClass) onSystem: self system).
state := initialState.
lastTime:=initialTime.
"announce initial conditions"
self announceState: state time: initialTime.
(lastTime+dt > endTime and: lastTime < endTime)
ifTrue:[
state :=self lastStepState: state endTime: endTime].
lastTime+dt<= endTime
ifTrue:[
prevState:= initialState.
state := self firstStepStartTime: initialTime.
"announce first step"
self announceState: state time:lastTime.
(lastTime+dt > endTime and: lastTime < endTime)
ifTrue:[
self stepper: ((self secondStepperClass) onSystem: self system).
state :=self lastStepPrevState: prevState endTime: endTime].
lastTime+dt<= endTime
ifTrue:[
prevPrevState := prevState.
prevState := state.
self stepper: ((self secondStepperClass) onSystem: self system).
state := self secondStepPrevState: prevPrevState startTime: lastTime.
"announce second step"
self announceState: state time: lastTime.
(lastTime+dt > endTime and: lastTime < endTime)
ifTrue:[
self stepper: ((self stepperClass) onSystem: self system).
state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime].
lastTime+dt<= endTime
ifTrue:[
self stepper: ((self stepperClass) onSystem: self system).
"step until the end"
statesPair := self mainStepsPrevState: prevState prevPrevState: prevPrevState startTime: initialTime endTime: endTime.
prevPrevState:=statesPair first.
prevState:= statesPair second.
"sanity check"
self assert: [(lastTime between: initialTime and: endTime)
or: [lastTime between: endTime and: initialTime]].
"take another step if needed"
state := self lastStepPrevState: prevState prevPrevState: prevPrevState endTime: endTime]]].
^ state
]