@@ -40,348 +40,7 @@ const StaticVector{N, T} = StaticArray{Tuple{N}, T, 1}
40
40
const StaticMatrix{N, M, T} = StaticArray{Tuple{N, M}, T, 2 }
41
41
const StaticVecOrMat{T} = Union{StaticVector{<: Any , T}, StaticMatrix{<: Any , <: Any , T}}
42
42
43
- # The ::Tuple variants exist to make sure that anything that calls with a tuple
44
- # instead of a Tuple gets through to the constructor, so the user gets a nice
45
- # error message
46
- Base. @pure tuple_length (T:: Type{<:Tuple} ) = length (T. parameters)
47
- Base. @pure tuple_length (T:: Tuple ) = length (T)
48
- Base. @pure tuple_prod (T:: Type{<:Tuple} ) = length (T. parameters) == 0 ? 1 : * (T. parameters... )
49
- Base. @pure tuple_prod (T:: Tuple ) = prod (T)
50
- Base. @pure tuple_minimum (T:: Type{<:Tuple} ) = length (T. parameters) == 0 ? 0 : minimum (tuple (T. parameters... ))
51
- Base. @pure tuple_minimum (T:: Tuple ) = minimum (T)
52
-
53
- """
54
- size_to_tuple(::Type{S}) where S<:Tuple
55
-
56
- Converts a size given by `Tuple{N, M, ...}` into a tuple `(N, M, ...)`.
57
- """
58
- Base. @pure function size_to_tuple (:: Type{S} ) where S<: Tuple
59
- return tuple (S. parameters... )
60
- end
61
-
62
- # Something doesn't match up type wise
63
- @generated function check_array_parameters (:: Type{Size} , :: Type{T} , :: Type{Val{N}} , :: Type{Val{L}} ) where {Size,T,N,L}
64
- if ! all (x-> isa (x, Int), Size. parameters)
65
- return :(throw (ArgumentError (" Static Array parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`)." )))
66
- end
67
-
68
- if L != tuple_prod (Size) || L < 0 || tuple_minimum (Size) < 0 || tuple_length (Size) != N
69
- return :(throw (ArgumentError (" Size mismatch in Static Array parameters. Got size $Size , dimension $N and length $L ." )))
70
- end
71
-
72
- return nothing
73
- end
74
-
75
- # Cast any Tuple to an TupleN{T}
76
- @generated function convert_ntuple (:: Type{T} , d:: NTuple{N,Any} ) where {N,T}
77
- exprs = ntuple (i -> :(convert (T, d[$ i])), Val (N))
78
- return quote
79
- Base. @_inline_meta
80
- $ (Expr (:tuple , exprs... ))
81
- end
82
- end
83
-
84
-
85
- """
86
- SArray{S, T, N, L}(x::NTuple{L})
87
- SArray{S, T, N, L}(x1, x2, x3, ...)
88
-
89
- Construct a statically-sized array `SArray`. Since this type is immutable, the data must be
90
- provided upon construction and cannot be mutated later. The `S` parameter is a Tuple-type
91
- specifying the dimensions, or size, of the array - such as `Tuple{3,4,5}` for a 3×4×5-sized
92
- array. The `N` parameter is the dimension of the array; the `L` parameter is the `length`
93
- of the array and is always equal to `prod(S)`. Constructors may drop the `L`, `N` and `T`
94
- parameters if they are inferrable from the input (e.g. `L` is always inferrable from `S`).
95
-
96
- SArray{S}(a::Array)
97
-
98
- Construct a statically-sized array of dimensions `S` (expressed as a `Tuple{...}`) using
99
- the data from `a`. The `S` parameter is mandatory since the size of `a` is unknown to the
100
- compiler (the element type may optionally also be specified).
101
- """
102
- struct SArray{S <: Tuple , T, N, L} <: StaticArray{S, T, N}
103
- data:: NTuple{L,T}
104
-
105
- function SArray {S, T, N, L} (x:: NTuple{L,T} ) where {S<: Tuple , T, N, L}
106
- check_array_parameters (S, T, Val{N}, Val{L})
107
- new {S, T, N, L} (x)
108
- end
109
-
110
- function SArray {S, T, N, L} (x:: NTuple{L,Any} ) where {S<: Tuple , T, N, L}
111
- check_array_parameters (S, T, Val{N}, Val{L})
112
- new {S, T, N, L} (convert_ntuple (T, x))
113
- end
114
- end
115
-
116
- @inline SArray {S,T,N} (x:: Tuple ) where {S<: Tuple ,T,N} = SArray {S,T,N,tuple_prod(S)} (x)
117
-
118
- """
119
- SVector{S, T}(x::NTuple{S, T})
120
- SVector{S, T}(x1, x2, x3, ...)
121
-
122
- Construct a statically-sized vector `SVector`. Since this type is immutable,
123
- the data must be provided upon construction and cannot be mutated later.
124
- Constructors may drop the `T` and `S` parameters if they are inferrable from the
125
- input (e.g. `SVector(1,2,3)` constructs an `SVector{3, Int}`).
126
-
127
- SVector{S}(vec::Vector)
128
-
129
- Construct a statically-sized vector of length `S` using the data from `vec`.
130
- The parameter `S` is mandatory since the length of `vec` is unknown to the
131
- compiler (the element type may optionally also be specified).
132
- """
133
- const SVector{S, T} = SArray{Tuple{S}, T, 1 , S}
134
-
135
- """
136
- SMatrix{S1, S2, T, L}(x::NTuple{L, T})
137
- SMatrix{S1, S2, T, L}(x1, x2, x3, ...)
138
-
139
- Construct a statically-sized matrix `SMatrix`. Since this type is immutable,
140
- the data must be provided upon construction and cannot be mutated later. The
141
- `L` parameter is the `length` of the array and is always equal to `S1 * S2`.
142
- Constructors may drop the `L`, `T` and even `S2` parameters if they are inferrable
143
- from the input (e.g. `L` is always inferrable from `S1` and `S2`).
144
-
145
- SMatrix{S1, S2}(mat::Matrix)
146
-
147
- Construct a statically-sized matrix of dimensions `S1 × S2` using the data from
148
- `mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is
149
- unknown to the compiler (the element type may optionally also be specified).
150
- """
151
- const SMatrix{S1, S2, T, L} = SArray{Tuple{S1, S2}, T, 2 , L}
152
-
153
- # MArray
154
-
155
- """
156
- MArray{S, T, N, L}(undef)
157
- MArray{S, T, N, L}(x::NTuple{L})
158
- MArray{S, T, N, L}(x1, x2, x3, ...)
159
-
160
-
161
- Construct a statically-sized, mutable array `MArray`. The data may optionally be
162
- provided upon construction and can be mutated later. The `S` parameter is a Tuple-type
163
- specifying the dimensions, or size, of the array - such as `Tuple{3,4,5}` for a 3×4×5-sized
164
- array. The `N` parameter is the dimension of the array; the `L` parameter is the `length`
165
- of the array and is always equal to `prod(S)`. Constructors may drop the `L`, `N` and `T`
166
- parameters if they are inferrable from the input (e.g. `L` is always inferrable from `S`).
167
-
168
- MArray{S}(a::Array)
169
-
170
- Construct a statically-sized, mutable array of dimensions `S` (expressed as a `Tuple{...}`)
171
- using the data from `a`. The `S` parameter is mandatory since the size of `a` is unknown to
172
- the compiler (the element type may optionally also be specified).
173
- """
174
- mutable struct MArray{S <: Tuple , T, N, L} <: StaticArray{S, T, N}
175
- data:: NTuple{L,T}
176
-
177
- function MArray {S,T,N,L} (x:: NTuple{L,T} ) where {S<: Tuple ,T,N,L}
178
- check_array_parameters (S, T, Val{N}, Val{L})
179
- new {S,T,N,L} (x)
180
- end
181
-
182
- function MArray {S,T,N,L} (x:: NTuple{L,Any} ) where {S<: Tuple ,T,N,L}
183
- check_array_parameters (S, T, Val{N}, Val{L})
184
- new {S,T,N,L} (convert_ntuple (T, x))
185
- end
186
-
187
- function MArray {S,T,N,L} (:: UndefInitializer ) where {S<: Tuple ,T,N,L}
188
- check_array_parameters (S, T, Val{N}, Val{L})
189
- new {S,T,N,L} ()
190
- end
191
- end
192
-
193
- @inline MArray {S,T,N} (x:: Tuple ) where {S<: Tuple ,T,N} = MArray {S,T,N,tuple_prod(S)} (x)
194
-
195
- """
196
- MVector{S,T}(undef)
197
- MVector{S,T}(x::NTuple{S, T})
198
- MVector{S,T}(x1, x2, x3, ...)
199
-
200
- Construct a statically-sized, mutable vector `MVector`. Data may optionally be
201
- provided upon construction, and can be mutated later. Constructors may drop the
202
- `T` and `S` parameters if they are inferrable from the input (e.g.
203
- `MVector(1,2,3)` constructs an `MVector{3, Int}`).
204
-
205
- MVector{S}(vec::Vector)
206
-
207
- Construct a statically-sized, mutable vector of length `S` using the data from
208
- `vec`. The parameter `S` is mandatory since the length of `vec` is unknown to the
209
- compiler (the element type may optionally also be specified).
210
- """
211
- const MVector{S, T} = MArray{Tuple{S}, T, 1 , S}
212
-
213
- """
214
- MMatrix{S1, S2, T, L}(undef)
215
- MMatrix{S1, S2, T, L}(x::NTuple{L, T})
216
- MMatrix{S1, S2, T, L}(x1, x2, x3, ...)
217
-
218
- Construct a statically-sized, mutable matrix `MMatrix`. The data may optionally
219
- be provided upon construction and can be mutated later. The `L` parameter is the
220
- `length` of the array and is always equal to `S1 * S2`. Constructors may drop
221
- the `L`, `T` and even `S2` parameters if they are inferrable from the input
222
- (e.g. `L` is always inferrable from `S1` and `S2`).
223
-
224
- MMatrix{S1, S2}(mat::Matrix)
225
-
226
- Construct a statically-sized, mutable matrix of dimensions `S1 × S2` using the data from
227
- `mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is
228
- unknown to the compiler (the element type may optionally also be specified).
229
- """
230
- const MMatrix{S1, S2, T, L} = MArray{Tuple{S1, S2}, T, 2 , L}
231
-
232
-
233
- # SizedArray
234
-
235
- require_one_based_indexing (A... ) = ! Base. has_offset_axes (A... ) ||
236
- throw (ArgumentError (" offset arrays are not supported but got an array with index other than 1" ))
237
-
238
- """
239
- SizedArray{Tuple{dims...}}(array)
240
-
241
- Wraps an `AbstractArray` with a static size, so to take advantage of the (faster)
242
- methods defined by the static array package. The size is checked once upon
243
- construction to determine if the number of elements (`length`) match, but the
244
- array may be reshaped.
245
-
246
- The aliases `SizedVector{N}` and `SizedMatrix{N,M}` are provided as more
247
- convenient names for one and two dimensional `SizedArray`s. For example, to
248
- wrap a 2x3 array `a` in a `SizedArray`, use `SizedMatrix{2,3}(a)`.
249
- """
250
- struct SizedArray{S<: Tuple ,T,N,M,TData<: AbstractArray{T,M} } <: StaticArray{S,T,N}
251
- data:: TData
252
-
253
- function SizedArray {S,T,N,M,TData} (a:: TData ) where {S<: Tuple ,T,N,M,TData<: AbstractArray{T,M} }
254
- require_one_based_indexing (a)
255
- if size (a) != size_to_tuple (S) && size (a) != (tuple_prod (S),)
256
- throw (DimensionMismatch (" Dimensions $(size (a)) don't match static size $S " ))
257
- end
258
- return new {S,T,N,M,TData} (a)
259
- end
260
-
261
- function SizedArray {S,T,N,1,TData} (:: UndefInitializer ) where {S<: Tuple ,T,N,TData<: AbstractArray{T,1} }
262
- return new {S,T,N,1,TData} (TData (undef, tuple_prod (S)))
263
- end
264
- function SizedArray {S,T,N,N,TData} (:: UndefInitializer ) where {S<: Tuple ,T,N,TData<: AbstractArray{T,N} }
265
- return new {S,T,N,N,TData} (TData (undef, size_to_tuple (S)... ))
266
- end
267
- end
268
-
269
- const SizedVector{S,T} = SizedArray{Tuple{S},T,1 ,1 }
270
-
271
- const SizedMatrix{S1,S2,T} = SizedArray{Tuple{S1,S2},T,2 }
272
-
273
- # FieldArray
274
-
275
- """
276
- abstract FieldArray{N, T, D} <: StaticArray{N, T, D}
277
-
278
- Inheriting from this type will make it easy to create your own rank-D tensor types. A `FieldArray`
279
- will automatically define `getindex` and `setindex!` appropriately. An immutable
280
- `FieldArray` will be as performant as an `SArray` of similar length and element type,
281
- while a mutable `FieldArray` will behave similarly to an `MArray`.
282
-
283
- Note that you must define the fields of any `FieldArray` subtype in column major order. If you
284
- want to use an alternative ordering you will need to pay special attention in providing your
285
- own definitions of `getindex`, `setindex!` and tuple conversion.
286
-
287
- If you define a `FieldArray` which is parametric on the element type you should
288
- consider defining `similar_type` as in the `FieldVector` example.
289
-
290
-
291
- # Example
292
-
293
- struct Stiffness <: FieldArray{Tuple{2,2,2,2}, Float64, 4}
294
- xxxx::Float64
295
- yxxx::Float64
296
- xyxx::Float64
297
- yyxx::Float64
298
- xxyx::Float64
299
- yxyx::Float64
300
- xyyx::Float64
301
- yyyx::Float64
302
- xxxy::Float64
303
- yxxy::Float64
304
- xyxy::Float64
305
- yyxy::Float64
306
- xxyy::Float64
307
- yxyy::Float64
308
- xyyy::Float64
309
- yyyy::Float64
310
- end
311
- """
312
- abstract type FieldArray{N, T, D} <: StaticArray{N, T, D} end
313
-
314
- """
315
- abstract FieldMatrix{N1, N2, T} <: FieldArray{Tuple{N1, N2}, 2}
316
-
317
- Inheriting from this type will make it easy to create your own rank-two tensor types. A `FieldMatrix`
318
- will automatically define `getindex` and `setindex!` appropriately. An immutable
319
- `FieldMatrix` will be as performant as an `SMatrix` of similar length and element type,
320
- while a mutable `FieldMatrix` will behave similarly to an `MMatrix`.
321
-
322
- Note that the fields of any subtype of `FieldMatrix` must be defined in column
323
- major order unless you are willing to implement your own `getindex`.
324
-
325
- If you define a `FieldMatrix` which is parametric on the element type you
326
- should consider defining `similar_type` as in the `FieldVector` example.
327
-
328
- # Example
329
-
330
- struct Stress <: FieldMatrix{3, 3, Float64}
331
- xx::Float64
332
- yx::Float64
333
- zx::Float64
334
- xy::Float64
335
- yy::Float64
336
- zy::Float64
337
- xz::Float64
338
- yz::Float64
339
- zz::Float64
340
- end
341
-
342
- Note that the fields of any subtype of `FieldMatrix` must be defined in column major order.
343
- This means that formatting of constructors for literal `FieldMatrix` can be confusing. For example
344
-
345
- sigma = Stress(1.0, 2.0, 3.0,
346
- 4.0, 5.0, 6.0,
347
- 7.0, 8.0, 9.0)
348
-
349
- 3×3 Stress:
350
- 1.0 4.0 7.0
351
- 2.0 5.0 8.0
352
- 3.0 6.0 9.0
353
-
354
- will give you the transpose of what the multi-argument formatting suggests. For clarity,
355
- you may consider using the alternative
356
-
357
- sigma = Stress(SA[1.0 2.0 3.0;
358
- 4.0 5.0 6.0;
359
- 7.0 8.0 9.0])
360
- """
361
- abstract type FieldMatrix{N1, N2, T} <: FieldArray{Tuple{N1, N2}, T, 2} end
362
-
363
- """
364
- abstract FieldVector{N, T} <: FieldArray{Tuple{N}, 1}
365
-
366
- Inheriting from this type will make it easy to create your own vector types. A `FieldVector`
367
- will automatically define `getindex` and `setindex!` appropriately. An immutable
368
- `FieldVector` will be as performant as an `SVector` of similar length and element type,
369
- while a mutable `FieldVector` will behave similarly to an `MVector`.
370
-
371
- If you define a `FieldVector` which is parametric on the element type you
372
- should consider defining `similar_type` to preserve your array type through
373
- array operations as in the example below.
374
-
375
- # Example
376
-
377
- struct Vec3D{T} <: FieldVector{3, T}
378
- x::T
379
- y::T
380
- z::T
381
- end
382
-
383
- StaticArrays.similar_type(::Type{<:Vec3D}, ::Type{T}, s::Size{(3,)}) where {T} = Vec3D{T}
384
- """
385
- abstract type FieldVector{N, T} <: FieldArray{Tuple{N}, T, 1} end
43
+ include (" staticarrays.jl" )
44
+ include (" utils.jl" )
386
45
387
46
end # module
0 commit comments