Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FieldArray from StaticArrays #7

Merged
merged 2 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "StaticArraysCore"
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
version = "1.0.1"
version = "1.1.0"

[compat]
julia = "1.6"
Expand Down
115 changes: 115 additions & 0 deletions src/StaticArraysCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module StaticArraysCore
export SArray, SMatrix, SVector
export MArray, MMatrix, MVector
export SizedArray, SizedMatrix, SizedVector
export FieldArray, FieldMatrix, FieldVector

"""
abstract type StaticArray{S, T, N} <: AbstractArray{T, N} end
Expand Down Expand Up @@ -269,4 +270,118 @@ const SizedVector{S,T} = SizedArray{Tuple{S},T,1,1}

const SizedMatrix{S1,S2,T} = SizedArray{Tuple{S1,S2},T,2}

# FieldArray

"""
abstract FieldArray{N, T, D} <: StaticArray{N, T, D}

Inheriting from this type will make it easy to create your own rank-D tensor types. A `FieldArray`
will automatically define `getindex` and `setindex!` appropriately. An immutable
`FieldArray` will be as performant as an `SArray` of similar length and element type,
while a mutable `FieldArray` will behave similarly to an `MArray`.

Note that you must define the fields of any `FieldArray` subtype in column major order. If you
want to use an alternative ordering you will need to pay special attention in providing your
own definitions of `getindex`, `setindex!` and tuple conversion.

If you define a `FieldArray` which is parametric on the element type you should
consider defining `similar_type` as in the `FieldVector` example.


# Example

struct Stiffness <: FieldArray{Tuple{2,2,2,2}, Float64, 4}
xxxx::Float64
yxxx::Float64
xyxx::Float64
yyxx::Float64
xxyx::Float64
yxyx::Float64
xyyx::Float64
yyyx::Float64
xxxy::Float64
yxxy::Float64
xyxy::Float64
yyxy::Float64
xxyy::Float64
yxyy::Float64
xyyy::Float64
yyyy::Float64
end
"""
abstract type FieldArray{N, T, D} <: StaticArray{N, T, D} end

"""
abstract FieldMatrix{N1, N2, T} <: FieldArray{Tuple{N1, N2}, 2}

Inheriting from this type will make it easy to create your own rank-two tensor types. A `FieldMatrix`
will automatically define `getindex` and `setindex!` appropriately. An immutable
`FieldMatrix` will be as performant as an `SMatrix` of similar length and element type,
while a mutable `FieldMatrix` will behave similarly to an `MMatrix`.

Note that the fields of any subtype of `FieldMatrix` must be defined in column
major order unless you are willing to implement your own `getindex`.

If you define a `FieldMatrix` which is parametric on the element type you
should consider defining `similar_type` as in the `FieldVector` example.

# Example

struct Stress <: FieldMatrix{3, 3, Float64}
xx::Float64
yx::Float64
zx::Float64
xy::Float64
yy::Float64
zy::Float64
xz::Float64
yz::Float64
zz::Float64
end

Note that the fields of any subtype of `FieldMatrix` must be defined in column major order.
This means that formatting of constructors for literal `FieldMatrix` can be confusing. For example

sigma = Stress(1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0)

3×3 Stress:
1.0 4.0 7.0
2.0 5.0 8.0
3.0 6.0 9.0

will give you the transpose of what the multi-argument formatting suggests. For clarity,
you may consider using the alternative

sigma = Stress(SA[1.0 2.0 3.0;
4.0 5.0 6.0;
7.0 8.0 9.0])
"""
abstract type FieldMatrix{N1, N2, T} <: FieldArray{Tuple{N1, N2}, T, 2} end

"""
abstract FieldVector{N, T} <: FieldArray{Tuple{N}, 1}

Inheriting from this type will make it easy to create your own vector types. A `FieldVector`
will automatically define `getindex` and `setindex!` appropriately. An immutable
`FieldVector` will be as performant as an `SVector` of similar length and element type,
while a mutable `FieldVector` will behave similarly to an `MVector`.

If you define a `FieldVector` which is parametric on the element type you
should consider defining `similar_type` to preserve your array type through
array operations as in the example below.

# Example

struct Vec3D{T} <: FieldVector{3, T}
x::T
y::T
z::T
end

StaticArrays.similar_type(::Type{<:Vec3D}, ::Type{T}, s::Size{(3,)}) where {T} = Vec3D{T}
"""
abstract type FieldVector{N, T} <: FieldArray{Tuple{N}, T, 1} end

end # module