Skip to content

Commit af06f67

Browse files
Use Symmetric Covariant Axis2Tensor
wip
1 parent 161d952 commit af06f67

File tree

5 files changed

+96
-21
lines changed

5 files changed

+96
-21
lines changed

src/Geometry/Geometry.jl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,65 @@ export Contravariant1Vector,
2323
Contravariant123Vector
2424

2525

26+
"""
27+
SimpleSymmetric
28+
29+
A simple Symmetric matrix. `LinearAlgebra.Symmetric` has a field
30+
`uplo::Char`, which results in a failed `check_basetype(T, S)`.
31+
"""
32+
struct SimpleSymmetric{T, S <: AbstractMatrix{<:T}} <: AbstractMatrix{T}
33+
data::S
34+
function SimpleSymmetric{T, S}(data) where {T, S <: AbstractMatrix{<:T}}
35+
new{T, S}(data)
36+
end
37+
end
38+
SimpleSymmetric(A) = cc_symmetric_type(typeof(A))(A)
39+
40+
LinearAlgebra.transpose(A::SimpleSymmetric) = A
41+
42+
"""
43+
cc_symmetric_type(T::Type)
44+
45+
The type of the object returned by `symmetric(::T, ::Symbol)`. For matrices, this is an
46+
appropriately typed `Symmetric`, for `Number`s, it is the original type. If `symmetric` is
47+
implemented for a custom type, so should be `cc_symmetric_type`, and vice versa.
48+
"""
49+
cc_symmetric_type(::Type{T}) where {S, T <: AbstractMatrix{S}} =
50+
SimpleSymmetric{
51+
Union{S, Base.promote_op(transpose, S), cc_symmetric_type(S)},
52+
T,
53+
}
54+
cc_symmetric_type(::Type{T}) where {S <: Number, T <: AbstractMatrix{S}} =
55+
SimpleSymmetric{S, T}
56+
cc_symmetric_type(
57+
::Type{T},
58+
) where {S <: AbstractMatrix, T <: AbstractMatrix{S}} =
59+
SimpleSymmetric{AbstractMatrix, T}
60+
cc_symmetric_type(::Type{T}) where {T <: Number} = T
61+
62+
Base.@propagate_inbounds function Base.getindex(
63+
A::SimpleSymmetric,
64+
i::Integer,
65+
j::Integer,
66+
)
67+
@boundscheck checkbounds(A, i, j)
68+
@inbounds if i == j
69+
data_ij = A.data[i, j]
70+
if data_ij isa AbstractMatrix
71+
return SimpleSymmetric(data_ij)::cc_symmetric_type(eltype(A.data))
72+
elseif data_ij isa Number
73+
return data_ij::cc_symmetric_type(eltype(A.data))
74+
end
75+
elseif (i < j)
76+
return A.data[i, j]
77+
else
78+
return LinearAlgebra.transpose(A.data[j, i])
79+
end
80+
end
81+
82+
Base.@propagate_inbounds Base.getindex(A::SimpleSymmetric, i::Integer) =
83+
A.data[i]
84+
2685

2786
include("coordinates.jl")
2887
include("axistensors.jl")

src/Geometry/axistensors.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ struct AxisTensor{
136136
T,
137137
N,
138138
A <: NTuple{N, AbstractAxis},
139-
S <: StaticArray{<:Tuple, T, N},
139+
S <: Union{
140+
SimpleSymmetric{T, <:StaticArray{<:Tuple, T, N}},
141+
StaticArray{<:Tuple, T, N},
142+
},
140143
} <: AbstractArray{T, N}
141144
axes::A
142145
components::S
@@ -147,7 +150,10 @@ AxisTensor(
147150
components::S,
148151
) where {
149152
A <: Tuple{Vararg{AbstractAxis}},
150-
S <: StaticArray{<:Tuple, T, N},
153+
S <: Union{
154+
SimpleSymmetric{T, <:StaticArray{<:Tuple, T, N}},
155+
StaticArray{<:Tuple, T, N},
156+
},
151157
} where {T, N} = AxisTensor{T, N, A, S}(axes, components)
152158

153159
AxisTensor(axes::Tuple{Vararg{AbstractAxis}}, components) =

src/Geometry/localgeometry.jl

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import LinearAlgebra
2+
import .Geometry: SimpleSymmetric
3+
4+
import InteractiveUtils
15

26
"""
37
LocalGeometry
@@ -20,7 +24,11 @@ struct LocalGeometry{I, C <: AbstractPoint, FT, S}
2024
"Contravariant metric tensor (inverse of gᵢⱼ), transforms covariant to contravariant vector components"
2125
gⁱʲ::Axis2Tensor{FT, Tuple{ContravariantAxis{I}, ContravariantAxis{I}}, S}
2226
"Covariant metric tensor (gᵢⱼ), transforms contravariant to covariant vector components"
23-
gᵢⱼ::Axis2Tensor{FT, Tuple{CovariantAxis{I}, CovariantAxis{I}}, S}
27+
gᵢⱼ::Axis2Tensor{
28+
FT,
29+
Tuple{CovariantAxis{I}, CovariantAxis{I}},
30+
SimpleSymmetric{FT, S},
31+
}
2432
@inline function LocalGeometry(
2533
coordinates,
2634
J,
@@ -30,20 +38,19 @@ struct LocalGeometry{I, C <: AbstractPoint, FT, S}
3038
∂ξ∂x = inv(∂x∂ξ)
3139
C = typeof(coordinates)
3240
Jinv = inv(J)
33-
return new{I, C, FT, S}(
34-
coordinates,
35-
J,
36-
WJ,
37-
Jinv,
38-
∂x∂ξ,
39-
∂ξ∂x,
40-
∂ξ∂x * ∂ξ∂x',
41-
∂x∂ξ' * ∂x∂ξ,
41+
gᵢⱼ₀ = ∂x∂ξ' * ∂x∂ξ
42+
gⁱʲ = ∂ξ∂x * ∂ξ∂x'
43+
@assert LinearAlgebra.issymmetric(components(gᵢⱼ₀))
44+
@assert LinearAlgebra.issymmetric(components(gⁱʲ))
45+
ˢgᵢⱼ = SimpleSymmetric(components(gᵢⱼ₀))
46+
gᵢⱼ = AxisTensor{FT, 2, typeof(axes(gᵢⱼ₀)), typeof(ˢgᵢⱼ)}(
47+
axes(gᵢⱼ₀),
48+
ˢgᵢⱼ,
4249
)
50+
return new{I, C, FT, S}(coordinates, J, WJ, Jinv, ∂x∂ξ, ∂ξ∂x, gⁱʲ, gᵢⱼ)
4351
end
4452
end
4553

46-
4754
"""
4855
SurfaceGeometry
4956

test/Fields/unit_field.jl

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -708,16 +708,15 @@ end
708708
Geometry.Cartesian123Point(x1, x2, x3),
709709
]
710710
all_components = [
711-
SMatrix{1, 1, FT}(range(1, 1)...),
712-
SMatrix{2, 2, FT}(range(1, 4)...),
713-
SMatrix{3, 3, FT}(range(1, 9)...),
714-
SMatrix{3, 3, FT}(range(1, 9)...),
715-
SMatrix{1, 1, FT}(range(1, 1)...),
716-
SMatrix{2, 2, FT}(range(1, 4)...),
717-
SMatrix{3, 3, FT}(range(1, 9)...),
711+
SMatrix{1, 1}(FT[1]),
712+
SMatrix{2, 2}(FT[1 2; 3 4]),
713+
SMatrix{3, 3}(FT[1 2 10; 4 5 6; 7 8 9]),
714+
SMatrix{3, 3}(FT[1 2 10; 4 5 6; 7 8 9]),
715+
SMatrix{2, 2}(FT[1 2; 3 4]),
716+
SMatrix{3, 3}(FT[1 2 10; 4 5 6; 7 8 9]),
718717
]
719718

720-
expected_dzs = [1.0, 4.0, 9.0, 9.0, 1.0, 4.0, 9.0]
719+
expected_dzs = [1.0, 4.0, 9.0, 9.0, 1.0, 2.0, 9.0]
721720

722721
for (components, coord, expected_dz) in
723722
zip(all_components, coords, expected_dzs)

test/Geometry/axistensor_conversion_benchmarks.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#=
2+
julia --project
3+
using Revise; include(joinpath("test", "Geometry", "axistensor_conversion_benchmarks.jl"))
4+
=#
15
using Test, StaticArrays
26
#! format: off
37
import Random, BenchmarkTools, StatsBase,

0 commit comments

Comments
 (0)