@@ -3,6 +3,7 @@ module StaticArraysCore
3
3
export SArray, SMatrix, SVector
4
4
export MArray, MMatrix, MVector
5
5
export SizedArray, SizedMatrix, SizedVector
6
+ export FieldArray, FieldMatrix, FieldVector
6
7
7
8
"""
8
9
abstract type StaticArray{S, T, N} <: AbstractArray{T, N} end
@@ -269,4 +270,118 @@ const SizedVector{S,T} = SizedArray{Tuple{S},T,1,1}
269
270
270
271
const SizedMatrix{S1,S2,T} = SizedArray{Tuple{S1,S2},T,2 }
271
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
386
+
272
387
end # module
0 commit comments