@@ -6,7 +6,15 @@ will automatically define `getindex` and `setindex!` appropriately. An immutable
6
6
`FieldArray` will be as performant as an `SArray` of similar length and element type,
7
7
while a mutable `FieldArray` will behave similarly to an `MArray`.
8
8
9
- For example:
9
+ Note that you must define the fields of any `FieldArray` subtype in column major order. If you
10
+ want to use an alternative ordering you will need to pay special attention in providing your
11
+ own definitions of `getindex`, `setindex!` and tuple conversion.
12
+
13
+ If you define a `FieldArray` which is parametric on the element type you should
14
+ consider defining `similar_type` as in the `FieldVector` example.
15
+
16
+
17
+ # Example
10
18
11
19
struct Stiffness <: FieldArray{Tuple{2,2,2,2}, Float64, 4}
12
20
xxxx::Float64
@@ -26,10 +34,6 @@ For example:
26
34
xyyy::Float64
27
35
yyyy::Float64
28
36
end
29
-
30
- Note that you must define the fields of any `FieldArray` subtype in column major order. If you
31
- want to use an alternative ordering you will need to pay special attention in providing your
32
- own definitions of `getindex`, `setindex!` and tuple conversion.
33
37
"""
34
38
abstract type FieldArray{N, T, D} <: StaticArray{N, T, D} end
35
39
@@ -41,7 +45,13 @@ will automatically define `getindex` and `setindex!` appropriately. An immutable
41
45
`FieldMatrix` will be as performant as an `SMatrix` of similar length and element type,
42
46
while a mutable `FieldMatrix` will behave similarly to an `MMatrix`.
43
47
44
- For example:
48
+ Note that the fields of any subtype of `FieldMatrix` must be defined in column
49
+ major order unless you are willing to implement your own `getindex`.
50
+
51
+ If you define a `FieldMatrix` which is parametric on the element type you
52
+ should consider defining `similar_type` as in the `FieldVector` example.
53
+
54
+ # Example
45
55
46
56
struct Stress <: FieldMatrix{3, 3, Float64}
47
57
xx::Float64
@@ -67,13 +77,12 @@ For example:
67
77
2.0 5.0 8.0
68
78
3.0 6.0 9.0
69
79
70
-
71
80
will give you the transpose of what the multi-argument formatting suggests. For clarity,
72
81
you may consider using the alternative
73
82
74
- sigma = Stress(@SArray [1.0 2.0 3.0;
75
- 4.0 5.0 6.0;
76
- 7.0 8.0 9.0])
83
+ sigma = Stress(SA [1.0 2.0 3.0;
84
+ 4.0 5.0 6.0;
85
+ 7.0 8.0 9.0])
77
86
"""
78
87
abstract type FieldMatrix{N1, N2, T} <: FieldArray{Tuple{N1, N2}, T, 2} end
79
88
@@ -85,13 +94,19 @@ will automatically define `getindex` and `setindex!` appropriately. An immutable
85
94
`FieldVector` will be as performant as an `SVector` of similar length and element type,
86
95
while a mutable `FieldVector` will behave similarly to an `MVector`.
87
96
88
- For example:
97
+ If you define a `FieldVector` which is parametric on the element type you
98
+ should consider defining `similar_type` to preserve your array type through
99
+ array operations as in the example below.
100
+
101
+ # Example
89
102
90
- struct Point3D <: FieldVector{3, Float64 }
91
- x::Float64
92
- y::Float64
93
- z::Float64
103
+ struct Vec3D{T} <: FieldVector{3, T }
104
+ x::T
105
+ y::T
106
+ z::T
94
107
end
108
+
109
+ StaticArrays.similar_type(::Type{<:Vec3D}, ::Type{T}, s::Size{(3,)}) where {T} = Vec3D{T}
95
110
"""
96
111
abstract type FieldVector{N, T} <: FieldArray{Tuple{N}, T, 1} end
97
112
109
124
Base. cconvert (:: Type{<:Ptr} , a:: FieldArray ) = Base. RefValue (a)
110
125
Base. unsafe_convert (:: Type{Ptr{T}} , m:: Base.RefValue{FA} ) where {N,T,D,FA<: FieldArray{N,T,D} } =
111
126
Ptr {T} (Base. unsafe_convert (Ptr{FA}, m))
127
+
128
+ # We can automatically preserve FieldArrays in array operations which do not
129
+ # change their eltype or Size. This should cover all non-parametric FieldArray,
130
+ # but for those which are parametric on the eltype the user will still need to
131
+ # overload similar_type themselves.
132
+ similar_type (:: Type{A} , :: Type{T} , S:: Size ) where {N, T, A<: FieldArray{N, T} } =
133
+ _fieldarray_similar_type (A, T, S, Size (A))
134
+
135
+ # Extra layer of dispatch to match NewSize and OldSize
136
+ _fieldarray_similar_type (A, T, NewSize:: S , OldSize:: S ) where {S} = A
137
+ _fieldarray_similar_type (A, T, NewSize, OldSize) =
138
+ default_similar_type (T, NewSize, length_val (NewSize))
0 commit comments