Skip to content

Commit c4305a5

Browse files
committed
upgraded to Cartan v0.3.3
1 parent b67eed0 commit c4305a5

File tree

3 files changed

+69
-48
lines changed

3 files changed

+69
-48
lines changed

.appveyor.yml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ environment:
33
- julia_version: 1
44
- julia_version: 1.6
55
- julia_version: 1.10
6+
- julia_version: 1.11
67
- julia_version: nightly
78

89
platform:

Project.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Adapode"
22
uuid = "0750cfb5-909a-49d7-927e-29b6595444bf"
33
authors = ["Michael Reed"]
4-
version = "0.3"
4+
version = "0.3.1"
55

66
[deps]
77
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
@@ -13,7 +13,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1313
[compat]
1414
julia = "1"
1515
Requires = "1"
16-
Grassmann = "0.8,0.9"
16+
Grassmann = "0.8"
1717
Cartan = "0.3"
1818

1919
[extras]

src/Adapode.jl

+66-46
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Grassmann: value, vector, valuetype, tangent, list
2323
import Grassmann: Values, Variables, FixedVector
2424
import Grassmann: Scalar, GradedVector, Bivector, Trivector
2525
import Base: @pure
26+
import Cartan: resize, resize_lastdim!, extract, assign!
2627

2728
export Values, odesolve, odesolve2
2829
export initmesh, pdegrad
@@ -47,7 +48,7 @@ mutable struct TimeStep{T}
4748
e::T
4849
i::Int
4950
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))
5152
checkstep!(new{typeof(h)}(h,hmin,hmax,emin,emax,(emin+emax)/2,1,0))
5253
end
5354
end
@@ -77,66 +78,73 @@ function explicit(x,h,c,fx,i)
7778
weights(h*c,fx[shift(Val(m),Val(l),i+(m-l))])
7879
end
7980
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
8283
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)
8489
fx = f[t.i]
8590
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
8792
end
8893

8994
@pure butcher(::Val{N},::Val{A}=Val(false)) where {N,A} = A ? CBA[N] : CB[N]
9095
@pure blength(n::Val{N},a::Val{A}=Val(false)) where {N,A} = Val(length(butcher(n,a))-A)
9196
function butcher(x::Section{B,F},f,h,v::Val{N}=Val(4),a::Val{A}=Val(false)) where {N,A,B,F}
9297
b = butcher(v,a)
9398
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))
96102
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)))
98104
end
99105
return fx
100106
end
101107
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))
103111

104112
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))
106114
explicit(x,t.h,PC ? CAM[k] : CAB[k],fx,t.s)
107115
end # more accurate compared with CAB[k] methods
108116
function predictcorrect(x,f,fx,t,k::Val{m}=Val(4)) where m
109117
iszero(t.s) && initsteps!(x,f,fx,t)
110-
@inbounds xti = x[t.i]
118+
xti = extract(x,t.i)
111119
xi,tn = fiber(xti),point(xti)+t.h
112120
xn = multistep!(xti,f,fx,t,k)
113121
t.s = (t.s%(m+1))+1; t.i += 1
114122
xn = multistep!(tn(xi+xn),f,fx,t,k,Val(true))
115123
return xi + xn
116124
end
117125
function predictcorrect(x,f,fx,t,::Val{1})
118-
@inbounds xti = x[t.i]
126+
xti = extract(x,t.i)
119127
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)))))
121129
end
122130

123131
initsteps(x0,t,tmax,m) = initsteps(init(x0),t,tmax,m)
124132
initsteps(x0,t,tmax,f,m,B) = initsteps(init(x0),t,tmax,f,m,B)
125133
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
128136
t = m (0,1,3) ? (tmin:t.h:tmax) : Vector{typeof(t.h)}(undef,n)
129137
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)
133141
end
134142
function initsteps(x0::Section,t,tmax,f,m,B::Val{o}=Val(4)) where o
135143
initsteps(x0,t,tmax,m), Variables{o+1,fibertype(x0)}(undef)
136144
end
137145

138146
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))
140148
@inbounds explicit(x,t.h,PC ? CAM[k] : CAB[k-1],fx,t.s)
141149
end
142150
function predictcorrect2(x,f,fx,t,k::Val{m}=Val(4)) where m
@@ -152,7 +160,7 @@ end
152160
function predictcorrect2(x,f,fx,t,::Val{1})
153161
@inbounds xti = x[t.i]
154162
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))
156164
end
157165

158166
initsteps2(x0,t,tmax,f,m,B) = initsteps2(init(x0),t,tmax,f,m,B)
@@ -162,46 +170,46 @@ end
162170

163171
function initsteps!(x,f,fx,t,B=Val(4))
164172
m = length(fx)-2
165-
@inbounds xi = x[t.i]
173+
xi = extract(x,t.i)
166174
for j 1:m
167-
@inbounds fx[j] = f(xi)
175+
@inbounds fx[j] = localfiber(f(xi))
168176
xi = (point(xi)+t.h) explicit(xi,f,t.h,B)
169-
x[t.i+j] = xi
177+
assign!(x,t.i+j,xi)
170178
end
171179
t.s = 1+m
172180
t.i += m
173181
end
174182

175183
function explicit!(x,f,t,B=Val(5))
176184
resize!(x,t.i,10000)
177-
@inbounds xti = x[t.i]
185+
xti = extract(x,t.i)
178186
xi = fiber(xti)
179187
fx,b = butcher(xti,f,t.h,B,Val(true)),butcher(B,Val(true))
180188
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))
182190
@inbounds t.e = maximum(abs.(t.h*value(b[end]fx)))
183191
end
184192

185193
function predictcorrect!(x,f,fx,t,B::Val{m}=Val(4)) where m
186194
resize!(x,t.i+m,10000)
187195
iszero(t.s) && initsteps!(x,f,fx,t)
188-
@inbounds xti = x[t.i]
196+
xti = extract(x,t.i)
189197
xi,tn = fiber(xti),point(xti)+t.h
190198
p = xi + multistep!(xti,f,fx,t,B)
191199
t.s = (t.s%(m+1))+1
192200
c = xi + multistep!(tnp,f,fx,t,B,Val(true))
193201
t.i += 1
194-
@inbounds x[t.i] = tn c
202+
assign!(x,t.i,tn c)
195203
t.e = maximum(abs.(value(c-p)./value(c)))
196204
end
197205
function predictcorrect!(x,f,fx,t,::Val{1})
198-
@inbounds xti = x[t.i]
206+
xti = extract(x,t.i)
199207
xi,tn = fiber(xti),point(xti)+t.h
200-
p = xi + t.h*f(xti)
201-
c = xi + t.h*f(tnp)
208+
p = xi + t.h*localfiber(f(xti))
209+
c = xi + t.h*localfiber(f(tnp))
202210
t.i += 1
203211
resize!(x,t.i,10000)
204-
@inbounds x[t.i] = tn c
212+
assign!(x,t.i,tn c)
205213
t.e = maximum(abs.(value(c-p)./value(c)))
206214
end
207215

@@ -213,13 +221,13 @@ function odesolve(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
213221
t = TimeStep(2.0^-tol)
214222
if m == 0 # Improved Euler, Heun's Method
215223
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))
218226
end
219227
elseif m == 1 # Singlestep
220228
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))
223231
end
224232
elseif m == 2 # Adaptive Singlestep
225233
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
228236
end
229237
elseif m == 3 # Multistep
230238
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))
233241
end
234242
else # Adaptive Multistep
235243
x,fx = initsteps(x0,t,tmax,f,M,B)
236244
while timeloop!(x,t,tmax,B) # o+1 fix??
237245
predictcorrect!(x,f,fx,t,B)
238246
end
239247
end
240-
return x
248+
return resize(x)
241249
end
242250

243251
#integrange
@@ -249,7 +257,7 @@ function odesolve2(f,x0,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where
249257
if m == 1 # Singlestep
250258
x = initsteps(x0,t,tmax,M)
251259
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))
253261
end
254262
elseif m == 2 # Adaptive Singlestep
255263
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
259267
elseif m == 3 # Multistep
260268
x,fx = initsteps2(x0,t,tmax,f,M,B)
261269
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))
263271
end
264272
else # Adaptive Multistep
265273
x,fx = initsteps(x0,t,tmax,f,M,B) # o+1 fix?
266274
while timeloop!(x,t,tmax,B)
267275
predictcorrect!(x,f,fx,t,B)
268276
end
269277
end
270-
return x
278+
return resize(x)
271279
end
272280

273281
function integrate(f::TensorField,x,tmax=2π,tol=15,M::Val{m}=Val(1),B::Val{o}=Val(4)) where {m,o}
274282
x0,t = init(x),TimeStep(2.0^-tol)
275283
if m == 0 # Improved Euler, Heun's Method
276284
x = initsteps(x0,t,tmax,M)
277285
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))
279287
end
280288
elseif m == 3 # Multistep
281289
x,fx = initsteps(x0,t,tmax,f,M,B)
282290
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))
284292
end
285293
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)
287307
end
288308

289309
function timeloop!(x,t,tmax,::Val{m}=Val(1)) where m
@@ -307,8 +327,8 @@ end
307327

308328
time(x) = x[1]
309329

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)
312332

313333
show_progress(x,t,b) = t.i%75000 == 11 && println(point(x[t.i])," out of ",b)
314334

0 commit comments

Comments
 (0)