@@ -23,6 +23,7 @@ import Grassmann: value, vector, valuetype, tangent, list
23
23
import Grassmann: Values, Variables, FixedVector
24
24
import Grassmann: Scalar, GradedVector, Bivector, Trivector
25
25
import Base: @pure
26
+ import Cartan: resize, resize_lastdim!, extract, assign!
26
27
27
28
export Values, odesolve, odesolve2
28
29
export initmesh, pdegrad
@@ -47,7 +48,7 @@ mutable struct TimeStep{T}
47
48
e:: T
48
49
i:: Int
49
50
s:: Int
50
- function TimeStep (h,hmin= 1e-16 ,hmax= 1e-4 ,emin= 10 ^ (log2 (h)- 3 ),emax= 10 ^ log2 (h))
51
+ function TimeStep (h,hmin= 1e-16 ,hmax= h > 1e-4 ? h : 1e-4 ,emin= 10 ^ (log2 (h)- 3 ),emax= 10 ^ log2 (h))
51
52
checkstep! (new {typeof(h)} (h,hmin,hmax,emin,emax,(emin+ emax)/ 2 ,1 ,0 ))
52
53
end
53
54
end
@@ -77,66 +78,73 @@ function explicit(x,h,c,fx,i)
77
78
weights (h* c,fx[shift (Val (m),Val (l),i+ (m- l))])
78
79
end
79
80
function heun (x,f:: Function ,h)
80
- hfx = h* f (x)
81
- fiber (x)+ (hfx+ h* f ((point (x)+ h)↦ (fiber (x)+ hfx)))/ 2
81
+ hfx = h* localfiber ( f (x) )
82
+ fiber (x)+ (hfx+ h* fiber ( f ((point (x)+ h)↦ (fiber (x)+ hfx) )))/ 2
82
83
end
83
- function heun (x,f:: TensorField ,t)
84
+ function heun (x,f:: TensorField ,h)
85
+ hfx = h* localfiber (f (x))
86
+ fiber (x)+ (hfx+ h* localfiber (f ((point (x)+ h)↦ (fiber (x)+ hfx))))/ 2
87
+ end
88
+ function heun2 (x,f:: TensorField ,t)
84
89
fx = f[t. i]
85
90
hfx = t. h* fx
86
- fiber (x)+ (hfx+ t. h* f (point (fx)↦ (fiber (x)+ hfx)))/ 2
91
+ fiber (x)+ (hfx+ t. h* localfiber ( f (point (fx)↦ (fiber (x)+ hfx) )))/ 2
87
92
end
88
93
89
94
@pure butcher (:: Val{N} ,:: Val{A} = Val (false )) where {N,A} = A ? CBA[N] : CB[N]
90
95
@pure blength (n:: Val{N} ,a:: Val{A} = Val (false )) where {N,A} = Val (length (butcher (n,a))- A)
91
96
function butcher (x:: Section{B,F} ,f,h,v:: Val{N} = Val (4 ),a:: Val{A} = Val (false )) where {N,A,B,F}
92
97
b = butcher (v,a)
93
98
n = length (b)- A
94
- fx = F<: Vector ? FixedVector {n,F} (undef) : Variables {n,F} (undef)
95
- @inbounds fx[1 ] = f (x)
99
+ # switch to isbits(F)
100
+ fx = F<: AbstractVector ? FixedVector {n,F} (undef) : Variables {n,F} (undef)
101
+ @inbounds fx[1 ] = localfiber (f (x))
96
102
for k ∈ 2 : n
97
- @inbounds fx[k] = f ((point (x)+ h* sum (b[k- 1 ]))↦ explicit (x,h,b[k- 1 ],fx))
103
+ @inbounds fx[k] = localfiber ( f ((point (x)+ h* sum (b[k- 1 ]))↦ explicit (x,h,b[k- 1 ],fx) ))
98
104
end
99
105
return fx
100
106
end
101
107
explicit (x,f:: Function ,h,b:: Val = Val (4 )) = explicit (x,h,butcher (b)[end ],butcher (x,f,h,b))
102
- explicit (x,f:: Function ,h,:: Val{1} ) = fiber (x)+ h* f (x)
108
+ explicit (x,f:: Function ,h,:: Val{1} ) = fiber (x)+ h* localfiber (f (x))
109
+ explicit (x,f:: TensorField ,h,b:: Val = Val (4 )) = explicit (x,h,butcher (b)[end ],butcher (x,f,h,b))
110
+ explicit (x,f:: TensorField ,h,:: Val{1} ) = fiber (x)+ h* localfiber (f (x))
103
111
104
112
function multistep! (x,f,fx,t,:: Val{k} = Val (4 ),:: Val{PC} = Val (false )) where {k,PC}
105
- fx[t. s] = f (x)
113
+ fx[t. s] = localfiber ( f (x) )
106
114
explicit (x,t. h,PC ? CAM[k] : CAB[k],fx,t. s)
107
115
end # more accurate compared with CAB[k] methods
108
116
function predictcorrect (x,f,fx,t,k:: Val{m} = Val (4 )) where m
109
117
iszero (t. s) && initsteps! (x,f,fx,t)
110
- @inbounds xti = x[ t. i]
118
+ xti = extract (x, t. i)
111
119
xi,tn = fiber (xti),point (xti)+ t. h
112
120
xn = multistep! (xti,f,fx,t,k)
113
121
t. s = (t. s% (m+ 1 ))+ 1 ; t. i += 1
114
122
xn = multistep! (tn↦ (xi+ xn),f,fx,t,k,Val (true ))
115
123
return xi + xn
116
124
end
117
125
function predictcorrect (x,f,fx,t,:: Val{1} )
118
- @inbounds xti = x[ t. i]
126
+ xti = extract (x, t. i)
119
127
t. i += 1
120
- fiber (xti)+ t. h* f ((point (xti)+ t. h)↦ (fiber (xti)+ t. h* f (xti)))
128
+ fiber (xti)+ t. h* localfiber ( f ((point (xti)+ t. h)↦ (fiber (xti)+ t. h* localfiber ( f (xti)) )))
121
129
end
122
130
123
131
initsteps (x0,t,tmax,m) = initsteps (init (x0),t,tmax,m)
124
132
initsteps (x0,t,tmax,f,m,B) = initsteps (init (x0),t,tmax,f,m,B)
125
133
function initsteps (x0:: Section ,t,tmax,:: Val{m} ) where m
126
- tmin = base (x0)
127
- n = Int (round ((tmax- tmin)* 2 ^- log2 ( t. h) ))+ 1
134
+ tmin,f0 = base (x0), fiber (x0)
135
+ n = Int (round ((tmax- tmin)/ t. h))+ 1
128
136
t = m ∈ (0 ,1 ,3 ) ? (tmin: t. h: tmax) : Vector {typeof(t.h)} (undef,n)
129
137
m ∉ (0 ,1 ,3 ) && (t[1 ] = tmin)
130
- x = Vector {fibertype(x0)} (undef,m ∈ (0 ,1 ,3 ) ? length (t) : n)
131
- x[ 1 ] = fiber (x0 )
132
- return TensorField (t,x)
138
+ x = Array {fibertype(fibertype( x0)),ndims(f0)+1 } (undef, size (f0) ... ,m ∈ (0 ,1 ,3 ) ? length (t) : n)
139
+ assign! (x, 1 , fiber (f0) )
140
+ return TensorField (ndims (f0) > 0 ? base (f0) × t : t,x)
133
141
end
134
142
function initsteps (x0:: Section ,t,tmax,f,m,B:: Val{o} = Val (4 )) where o
135
143
initsteps (x0,t,tmax,m), Variables {o+1,fibertype(x0)} (undef)
136
144
end
137
145
138
146
function multistep2! (x,f,fx,t,:: Val{k} = Val (4 ),:: Val{PC} = Val (false )) where {k,PC}
139
- @inbounds fx[t. s] = f (x)
147
+ @inbounds fx[t. s] = localfiber ( f (x) )
140
148
@inbounds explicit (x,t. h,PC ? CAM[k] : CAB[k- 1 ],fx,t. s)
141
149
end
142
150
function predictcorrect2 (x,f,fx,t,k:: Val{m} = Val (4 )) where m
152
160
function predictcorrect2 (x,f,fx,t,:: Val{1} )
153
161
@inbounds xti = x[t. i]
154
162
t. i += 1
155
- fiber (xti)+ t. h* f ((point (xti)+ t. h)↦ xti)
163
+ fiber (xti)+ t. h* localfiber ( f ((point (xti)+ t. h)↦ xti) )
156
164
end
157
165
158
166
initsteps2 (x0,t,tmax,f,m,B) = initsteps2 (init (x0),t,tmax,f,m,B)
@@ -162,46 +170,46 @@ end
162
170
163
171
function initsteps! (x,f,fx,t,B= Val (4 ))
164
172
m = length (fx)- 2
165
- @inbounds xi = x[ t. i]
173
+ xi = extract (x, t. i)
166
174
for j ∈ 1 : m
167
- @inbounds fx[j] = f (xi)
175
+ @inbounds fx[j] = localfiber ( f (xi) )
168
176
xi = (point (xi)+ t. h) ↦ explicit (xi,f,t. h,B)
169
- x[ t. i+ j] = xi
177
+ assign! (x, t. i+ j,xi)
170
178
end
171
179
t. s = 1 + m
172
180
t. i += m
173
181
end
174
182
175
183
function explicit! (x,f,t,B= Val (5 ))
176
184
resize! (x,t. i,10000 )
177
- @inbounds xti = x[ t. i]
185
+ xti = extract (x, t. i)
178
186
xi = fiber (xti)
179
187
fx,b = butcher (xti,f,t. h,B,Val (true )),butcher (B,Val (true ))
180
188
t. i += 1
181
- @inbounds x[ t. i] = (point (xti)+ t. h) ↦ explicit (xti,t. h,b[end - 1 ],fx)
189
+ assign! (x, t. i, (point (xti)+ t. h) ↦ explicit (xti,t. h,b[end - 1 ],fx) )
182
190
@inbounds t. e = maximum (abs .(t. h* value (b[end ]⋅ fx)))
183
191
end
184
192
185
193
function predictcorrect! (x,f,fx,t,B:: Val{m} = Val (4 )) where m
186
194
resize! (x,t. i+ m,10000 )
187
195
iszero (t. s) && initsteps! (x,f,fx,t)
188
- @inbounds xti = x[ t. i]
196
+ xti = extract (x, t. i)
189
197
xi,tn = fiber (xti),point (xti)+ t. h
190
198
p = xi + multistep! (xti,f,fx,t,B)
191
199
t. s = (t. s% (m+ 1 ))+ 1
192
200
c = xi + multistep! (tn↦ p,f,fx,t,B,Val (true ))
193
201
t. i += 1
194
- @inbounds x[ t. i] = tn ↦ c
202
+ assign! (x, t. i, tn ↦ c)
195
203
t. e = maximum (abs .(value (c- p)./ value (c)))
196
204
end
197
205
function predictcorrect! (x,f,fx,t,:: Val{1} )
198
- @inbounds xti = x[ t. i]
206
+ xti = extract (x, t. i)
199
207
xi,tn = fiber (xti),point (xti)+ t. h
200
- p = xi + t. h* f (xti)
201
- c = xi + t. h* f (tn↦ p)
208
+ p = xi + t. h* localfiber ( f (xti) )
209
+ c = xi + t. h* localfiber ( f (tn↦ p) )
202
210
t. i += 1
203
211
resize! (x,t. i,10000 )
204
- @inbounds x[ t. i] = tn ↦ c
212
+ assign! (x, t. i, tn ↦ c)
205
213
t. e = maximum (abs .(value (c- p)./ value (c)))
206
214
end
207
215
@@ -213,13 +221,13 @@ function odesolve(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
213
221
t = TimeStep (2.0 ^- tol)
214
222
if m == 0 # Improved Euler, Heun's Method
215
223
x = initsteps (x0,t,tmax,M)
216
- for i ∈ 2 : length (x)
217
- @inbounds x[i] = heun (x[ i- 1 ] ,f,t. h)
224
+ for i ∈ 2 : size (x)[ end ]
225
+ assign! (x,i, heun (extract (x, i- 1 ) ,f,t. h) )
218
226
end
219
227
elseif m == 1 # Singlestep
220
228
x = initsteps (x0,t,tmax,M)
221
- for i ∈ 2 : length (x)
222
- @inbounds x[i] = explicit (x[ i- 1 ] ,f,t. h,B)
229
+ for i ∈ 2 : size (x)[ end ]
230
+ assign! (x,i, explicit (extract (x, i- 1 ) ,f,t. h,B) )
223
231
end
224
232
elseif m == 2 # Adaptive Singlestep
225
233
x = initsteps (x0,t,tmax,M)
@@ -228,16 +236,16 @@ function odesolve(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
228
236
end
229
237
elseif m == 3 # Multistep
230
238
x,fx = initsteps (x0,t,tmax,f,M,B)
231
- for i ∈ o+ 1 : length (x) # o+1 changed to o
232
- @inbounds x[i] = predictcorrect (x,f,fx,t,B)
239
+ for i ∈ o+ 1 : size (x)[ end ] # o+1 changed to o
240
+ assign! (x,i, predictcorrect (x,f,fx,t,B) )
233
241
end
234
242
else # Adaptive Multistep
235
243
x,fx = initsteps (x0,t,tmax,f,M,B)
236
244
while timeloop! (x,t,tmax,B) # o+1 fix??
237
245
predictcorrect! (x,f,fx,t,B)
238
246
end
239
247
end
240
- return x
248
+ return resize (x)
241
249
end
242
250
243
251
# integrange
@@ -249,7 +257,7 @@ function odesolve2(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
249
257
if m == 1 # Singlestep
250
258
x = initsteps (x0,t,tmax,M)
251
259
for i ∈ 2 : length (x)
252
- @inbounds x[i] = explicit (x[ i- 1 ] ,f,t. h,B)
260
+ assign! (x,i, explicit (extract (x, i- 1 ) ,f,t. h,B) )
253
261
end
254
262
elseif m == 2 # Adaptive Singlestep
255
263
x = initsteps (x0,t,tmax,M)
@@ -259,31 +267,43 @@ function odesolve2(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
259
267
elseif m == 3 # Multistep
260
268
x,fx = initsteps2 (x0,t,tmax,f,M,B)
261
269
for i ∈ (isone (o) ? 2 : o): length (x) # o+1 changed to o
262
- @inbounds x[i] = predictcorrect2 (x,f,fx,t,B)
270
+ assign! (x,i, predictcorrect2 (x,f,fx,t,B) )
263
271
end
264
272
else # Adaptive Multistep
265
273
x,fx = initsteps (x0,t,tmax,f,M,B) # o+1 fix?
266
274
while timeloop! (x,t,tmax,B)
267
275
predictcorrect! (x,f,fx,t,B)
268
276
end
269
277
end
270
- return x
278
+ return resize (x)
271
279
end
272
280
273
281
function integrate (f:: TensorField ,x,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
274
282
x0,t = init (x),TimeStep (2.0 ^- tol)
275
283
if m == 0 # Improved Euler, Heun's Method
276
284
x = initsteps (x0,t,tmax,M)
277
285
for i ∈ 2 : length (x)
278
- @inbounds x[i] = heun (x[ i- 1 ] ,f,t. h)
286
+ assign! (x,i, heun (extract (x, i- 1 ) ,f,t. h) )
279
287
end
280
288
elseif m == 3 # Multistep
281
289
x,fx = initsteps (x0,t,tmax,f,M,B)
282
290
for i ∈ o+ 1 : length (x)
283
- @inbounds x[i] = predictcorrect (x,f,fx,t,B)
291
+ assign! (x,i, predictcorrect (x,f,fx,t,B) )
284
292
end
285
293
end
286
- return x
294
+ return resize (x)
295
+ end
296
+
297
+ export geosolve, geosolve2
298
+
299
+ geosolve (Γ,x0,v0,tmax,tol,m,o) = geosolve (Γ,x0,v0,tmax,tol,Val (m),Val (o))
300
+ function geosolve (Γ,x0,v0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
301
+ getindex .(odesolve (x-> geodesicsystem (x[1 ],Γ),Chain (x0,v0),tmax,tol,M,B),1 )
302
+ end
303
+
304
+ geosolve2 (Γ,g,x0,v0,tmax,tol,m,o) = geosolve2 (Γ,g,x0,v0,tmax,tol,Val (m),Val (o))
305
+ function geosolve2 (Γ,g,x0,v0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
306
+ getindex .(odesolve (x-> geodesicsystem (x[1 ],Γ,g),Chain (x0,v0),tmax,tol,M,B),1 )
287
307
end
288
308
289
309
function timeloop! (x,t,tmax,:: Val{m} = Val (1 )) where m
307
327
308
328
time (x) = x[1 ]
309
329
310
- Base. resize! (x,i,h) = length (x)< i+ 1 && resize ! (x,i+ h)
311
- truncate! (x,i) = length (x)> i+ 1 && resize ! (x,i)
330
+ Base. resize! (x,i,h) = length (x)< i+ 1 && resize_lastdim ! (x,i+ h)
331
+ truncate! (x,i) = length (x)> i+ 1 && resize_lastdim ! (x,i)
312
332
313
333
show_progress (x,t,b) = t. i% 75000 == 11 && println (point (x[t. i])," out of " ,b)
314
334
0 commit comments