@@ -39,6 +39,51 @@ export ProductSpace, RealRegion, Interval, Rectangle, Hyperrectangle, ⧺, ⊕
39
39
include (" constants.jl" )
40
40
include (" element.jl" )
41
41
42
+ abstract type AbstractIntegrator end
43
+ abstract type StepIntegrator <: AbstractIntegrator end
44
+ abstract type AdaptiveIntegrator <: AbstractIntegrator end
45
+
46
+ struct EulerHeunIntegrator <: StepIntegrator
47
+ tol:: Float64
48
+ end
49
+
50
+ struct ExplicitIntegrator{o} <: StepIntegrator
51
+ tol:: Float64
52
+ end
53
+
54
+ struct ExplicitAdaptor{o} <: AdaptiveIntegrator
55
+ tol:: Float64
56
+ end
57
+
58
+ struct MultistepIntegrator{o} <: StepIntegrator
59
+ tol:: Float64
60
+ end
61
+
62
+ struct MultistepAdaptor{o} <: AdaptiveIntegrator
63
+ tol:: Float64
64
+ end
65
+
66
+ AbstractIntegrator (tol= 15 ,int:: AbstractIntegrator = ExplicitIntegrator{4 }) = int (tol)
67
+ AbstractIntegrator (tol,m,o= 4 ) = AbstractIntegrator (tol,Val (m),Val (o))
68
+ function AbstractIntegrator (tol,M:: Val{m} ,B:: Val{o} = Val (4 )) where {m,o}
69
+ int = if m == 0
70
+ EulerHeunIntegrator (tol)
71
+ elseif m == 1
72
+ ExplicitIntegrator {o} (tol)
73
+ elseif m == 2
74
+ ExplicitAdaptor {o} (tol)
75
+ elseif m == 3
76
+ MultistepIntegrator {o} (tol)
77
+ elseif m == 4
78
+ MultistepAdaptor {o} (tol)
79
+ end
80
+ end
81
+
82
+ EulerHeunIntegrator (tol:: Int ) = EulerHeunIntegrator (2.0 ^- tol)
83
+ for fun ∈ (:ExplicitIntegrator ,:ExplicitAdaptor ,:MultistepIntegrator ,:MultistepAdaptor )
84
+ @eval $ fun {o} (tol:: Int ) where o = $ fun {o} (2.0 ^- tol)
85
+ end
86
+
42
87
mutable struct TimeStep{T}
43
88
h:: T
44
89
hmin:: T
@@ -52,6 +97,8 @@ mutable struct TimeStep{T}
52
97
checkstep! (new {typeof(h)} (h,hmin,hmax,emin,emax,(emin+ emax)/ 2 ,1 ,0 ))
53
98
end
54
99
end
100
+ TimeStep (I:: AbstractIntegrator ) = TimeStep (I. tol)
101
+
55
102
function checkstep! (t)
56
103
abs (t. h) < t. hmin && (t. h = copysign (t. hmin,t. h))
57
104
abs (t. h) > t. hmax && (t. h = copysign (t. hmax,t. h))
@@ -133,9 +180,9 @@ initsteps(x0,t,tmax,f,m,B) = initsteps(init(x0),t,tmax,f,m,B)
133
180
function initsteps (x0:: Section ,t,tmax,:: Val{m} ) where m
134
181
tmin,f0 = base (x0),fiber (x0)
135
182
n = Int (round ((tmax- tmin)/ t. h))+ 1
136
- t = m ∈ ( 0 , 1 , 3 ) ? (tmin: t. h: tmax) : Vector {typeof(t.h)} (undef,n)
137
- m ∉ ( 0 , 1 , 3 ) && (t[1 ] = tmin)
138
- x = Array {fibertype(fibertype(x0)),ndims(f0)+1} (undef,size (f0)... ,m ∈ ( 0 , 1 , 3 ) ? length (t) : n)
183
+ t = m ? (tmin: t. h: tmax) : Vector {typeof(t.h)} (undef,n)
184
+ ( ! m ) && (t[1 ] = tmin)
185
+ x = Array {fibertype(fibertype(x0)),ndims(f0)+1} (undef,size (f0)... ,m ? length (t) : n)
139
186
assign! (x,1 ,fiber (f0))
140
187
return TensorField (ndims (f0) > 0 ? base (f0)× t : t,x)
141
188
end
@@ -216,77 +263,99 @@ end
216
263
init (x0) = 0.0 ↦ x0
217
264
init (x0:: Section ) = x0
218
265
219
- odesolve (f,x0,tmax,tol,m,o) = odesolve (f,x0,tmax,tol,Val (m),Val (o))
266
+ struct InitialCondition{F,X}
267
+ f:: F
268
+ x0:: X
269
+ tmax:: Float64
270
+ end
271
+
272
+ InitialCondition (f,x0) = InitialCondition (f,x0,2 π)
273
+
274
+ struct InitialValueSetup{F,X,I<: AbstractIntegrator }
275
+ ic:: InitialCondition{F,X}
276
+ i:: I
277
+ end
278
+
279
+ InitialValueSetup (f,x0,tmax,tol,m,o= 4 ) = InitialValueSetup (f,x0,tmax,tol,Val (m),Val (o))
280
+ function InitialValueSetup (f,x0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
281
+ InitialValueSetup (InitialCondition (f,x0,tmax),AbstractIntegrator (tol,M,B))
282
+ end
283
+
284
+ odesolve (ode:: InitialValueSetup ) = odesolve (ode. ic,ode. i)
285
+ odesolve (f,x0,tmax,tol,m,o= 4 ) = odesolve (f,x0,tmax,tol,Val (m),Val (o))
220
286
function odesolve (f,x0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
221
- t = TimeStep (2.0 ^- tol)
222
- if m == 0 # Improved Euler, Heun's Method
223
- x = initsteps (x0,t,tmax,M)
224
- for i ∈ 2 : size (x)[end ]
225
- assign! (x,i,heun (extract (x,i- 1 ),f,t. h))
226
- end
227
- elseif m == 1 # Singlestep
228
- x = initsteps (x0,t,tmax,M)
229
- for i ∈ 2 : size (x)[end ]
230
- assign! (x,i,explicit (extract (x,i- 1 ),f,t. h,B))
231
- end
232
- elseif m == 2 # Adaptive Singlestep
233
- x = initsteps (x0,t,tmax,M)
234
- while timeloop! (x,t,tmax)
235
- explicit! (x,f,t,B)
236
- end
237
- elseif m == 3 # Multistep
238
- x,fx = initsteps (x0,t,tmax,f,M,B)
239
- for i ∈ o+ 1 : size (x)[end ] # o+1 changed to o
240
- assign! (x,i,predictcorrect (x,f,fx,t,B))
241
- end
242
- else # Adaptive Multistep
243
- x,fx = initsteps (x0,t,tmax,f,M,B)
244
- while timeloop! (x,t,tmax,B) # o+1 fix??
245
- predictcorrect! (x,f,fx,t,B)
246
- end
287
+ odesolve (InitialCondition (f,x0,tmax),AbstractIntegrator (tol,M,B))
288
+ end
289
+ function odesolve (ic:: InitialCondition ,I:: EulerHeunIntegrator )
290
+ t = TimeStep (I)
291
+ x = initsteps (ic. x0,t,ic. tmax,Val (true ))
292
+ for i ∈ 2 : size (x)[end ]
293
+ assign! (x,i,heun (extract (x,i- 1 ),ic. f,t. h))
294
+ end
295
+ return x
296
+ end
297
+ function odesolve (ic:: InitialCondition ,I:: ExplicitIntegrator{o} ) where o
298
+ t,B = TimeStep (I),Val (o)
299
+ x = initsteps (ic. x0,t,ic. tmax,Val (true ))
300
+ for i ∈ 2 : size (x)[end ]
301
+ assign! (x,i,explicit (extract (x,i- 1 ),ic. f,t. h,B))
302
+ end
303
+ return x
304
+ end
305
+ function odesolve (ic:: InitialCondition ,I:: ExplicitAdaptor{o} ) where o
306
+ t,B = TimeStep (I),Val (o)
307
+ x = initsteps (ic. x0,t,ic. tmax,Val (false ))
308
+ while timeloop! (x,t,ic. tmax)
309
+ explicit! (x,ic. f,t,B)
310
+ end
311
+ return resize (x)
312
+ end
313
+ function odesolve (ic:: InitialCondition ,I:: MultistepIntegrator{o} ) where o
314
+ t,B = TimeStep (I),Val (o)
315
+ x,fx = initsteps (ic. x0,t,ic. tmax,ic. f,Val (true ),B)
316
+ for i ∈ o+ 1 : size (x)[end ] # o+1 changed to o
317
+ assign! (x,i,predictcorrect (x,ic. f,fx,t,B))
318
+ end
319
+ return x
320
+ end
321
+ function odesolve (ic:: InitialCondition ,I:: MultistepAdaptor{o} ) where o
322
+ t,B = TimeStep (I),Val (o)
323
+ x,fx = initsteps (ic. x0,t,ic. tmax,ic. f,Val (false ),B)
324
+ while timeloop! (x,t,ic. tmax,B) # o+1 fix??
325
+ predictcorrect! (x,ic. f,fx,t,B)
247
326
end
248
327
return resize (x)
249
328
end
250
329
251
330
# integrange
252
331
# integadapt
253
332
254
- odesolve2 (f,x0,tmax,tol,m,o) = odesolve2 (f,x0,tmax,tol,Val (m),Val (o))
333
+ odesolve2 (ode:: InitialValueSetup ) = odesolve2 (ode. ic,ode. i)
334
+ odesolve2 (f,x0,tmax,tol,m,o= 4 ) = odesolve2 (f,x0,tmax,tol,Val (m),Val (o))
255
335
function odesolve2 (f,x0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
256
- t = TimeStep (2.0 ^- tol)
257
- if m == 1 # Singlestep
258
- x = initsteps (x0,t,tmax,M)
259
- for i ∈ 2 : length (x)
260
- assign! (x,i,explicit (extract (x,i- 1 ),f,t. h,B))
261
- end
262
- elseif m == 2 # Adaptive Singlestep
263
- x = initsteps (x0,t,tmax,M)
264
- while timeloop! (x,t,tmax)
265
- explicit! (x,f,t,B)
266
- end
267
- elseif m == 3 # Multistep
268
- x,fx = initsteps2 (x0,t,tmax,f,M,B)
269
- for i ∈ (isone (o) ? 2 : o): length (x) # o+1 changed to o
270
- assign! (x,i,predictcorrect2 (x,f,fx,t,B))
271
- end
272
- else # Adaptive Multistep
273
- x,fx = initsteps (x0,t,tmax,f,M,B) # o+1 fix?
274
- while timeloop! (x,t,tmax,B)
275
- predictcorrect! (x,f,fx,t,B)
276
- end
336
+ odesolve2 (InitialCondition (f,x0,tmax),AbstractIntegrator (tol,M,B))
337
+ end
338
+ odesolve2 (ic:: InitialCondition ,I:: ExplicitIntegrator ) = odesolve (ic,I)
339
+ odesolve2 (ic:: InitialCondition ,I:: ExplicitAdaptor ) = odesolve (ic,I)
340
+ odesolve2 (ic:: InitialCondition ,I:: MultistepAdaptor ) = odesolve (ic,I)
341
+ function odesolve2 (ic:: InitialCondition ,I:: MultistepIntegrator{o} ) where o
342
+ t,B = TimeStep (I),Val (o)
343
+ x,fx = initsteps2 (ic. x0,t,ic. tmax,ic. f,Val (true ),B)
344
+ for i ∈ (isone (o) ? 2 : o): size (x)[end ] # o+1 changed to o
345
+ assign! (x,i,predictcorrect2 (x,ic. f,fx,t,B))
277
346
end
278
- return resize (x)
347
+ return x
279
348
end
280
349
281
350
function integrate (f:: TensorField ,x,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
282
351
x0,t = init (x),TimeStep (2.0 ^- tol)
283
352
if m == 0 # Improved Euler, Heun's Method
284
- x = initsteps (x0,t,tmax,M )
353
+ x = initsteps (x0,t,tmax,Val ( true ) )
285
354
for i ∈ 2 : length (x)
286
355
assign! (x,i,heun (extract (x,i- 1 ),f,t. h))
287
356
end
288
357
elseif m == 3 # Multistep
289
- x,fx = initsteps (x0,t,tmax,f,M ,B)
358
+ x,fx = initsteps (x0,t,tmax,f,Val ( true ) ,B)
290
359
for i ∈ o+ 1 : length (x)
291
360
assign! (x,i,predictcorrect (x,f,fx,t,B))
292
361
end
296
365
297
366
export geosolve
298
367
299
- geosolve (Γ,x0,v0,tmax,tol,m,o) = geosolve (Γ,x0,v0,tmax,tol,Val (m),Val (o))
368
+ geosolve (ode:: InitialValueSetup ) = getindex .(odesolve (ode),1 )
369
+ geosolve (ic:: InitialCondition ,i:: AbstractIntegrator ) = getindex .(odesolve (ic,i),1 )
370
+ geosolve (Γ,x0,v0,tmax,tol,m,o= 4 ) = geosolve (Γ,x0,v0,tmax,tol,Val (m),Val (o))
300
371
function geosolve (Γ,x0,v0,tmax= 2 π,tol= 15 ,M:: Val{m} = Val (1 ),B:: Val{o} = Val (4 )) where {m,o}
301
372
getindex .(odesolve (geodesic (Γ),Chain (x0,v0),tmax,tol,M,B),1 )
302
373
end
0 commit comments