1import LinearAlgebra: det 2 3""" 4 CeedDim(dim) 5 6The singleton object of type `CeedDim{dim}`, used for dispatch to linear algebra operations 7specialized for small matrices (1, 2, or 3 dimensions). 8""" 9struct CeedDim{dim} end 10@inline CeedDim(dim) = CeedDim{Int(dim)}() 11 12""" 13 det(J, ::CeedDim{dim}) 14 15Specialized determinant calculations for matrices of size 1, 2, or 3. 16""" 17@inline det(J, ::CeedDim{1}) = @inbounds J[1] 18@inline det(J, ::CeedDim{2}) = @inbounds J[1]*J[4] - J[3]*J[2] 19#! format: off 20@inline det(J, ::CeedDim{3}) = @inbounds ( 21 J[1]*(J[5]*J[9] - J[6]*J[8]) - 22 J[2]*(J[4]*J[9] - J[6]*J[7]) + 23 J[3]*(J[4]*J[8] - J[5]*J[7]) 24) 25#! format: on 26 27""" 28 setvoigt(J::StaticArray{Tuple{D,D},T,2}) 29 setvoigt(J, ::CeedDim{dim}) 30 31Given a symmetric matrix `J`, return a `SVector` that encodes `J` using the [Voigt 32convention](https://en.wikipedia.org/wiki/Voigt_notation). 33 34The size of the symmetric matrix `J` must be known statically, either specified using 35[`CeedDim`](@ref) or `StaticArray`. 36""" 37@inline setvoigt(J::StaticArray{Tuple{D,D}}) where {D} = setvoigt(J, CeedDim(D)) 38@inline setvoigt(J, ::CeedDim{1}) = @inbounds @SVector [J[1]] 39@inline setvoigt(J, ::CeedDim{2}) = @inbounds @SVector [J[1], J[4], J[2]] 40@inline setvoigt(J, ::CeedDim{3}) = @inbounds @SVector [J[1], J[5], J[9], J[6], J[3], J[2]] 41 42@inline function setvoigt!(V, J, ::CeedDim{1}) 43 @inbounds V[1] = J[1] 44end 45 46@inline function setvoigt!(V, J, ::CeedDim{2}) 47 @inbounds begin 48 V[1] = J[1] 49 V[2] = J[4] 50 V[3] = J[2] 51 end 52end 53 54@inline function setvoigt!(V, J, ::CeedDim{3}) 55 @inbounds begin 56 V[1] = J[1] 57 V[2] = J[5] 58 V[3] = J[9] 59 V[4] = J[6] 60 V[5] = J[3] 61 V[6] = J[2] 62 end 63end 64 65""" 66 getvoigt(V, ::CeedDim{dim}) 67 68Given a vector `V` that encodes a symmetric matrix using the [Voigt 69convention](https://en.wikipedia.org/wiki/Voigt_notation), return the corresponding 70`SMatrix`. 71""" 72@inline getvoigt(V, ::CeedDim{1}) = @inbounds @SMatrix [V[1]] 73@inline getvoigt(V, ::CeedDim{2}) = @inbounds @SMatrix [V[1] V[3]; V[3] V[2]] 74@inline getvoigt(V, ::CeedDim{3}) = @inbounds @SMatrix [ 75 V[1] V[6] V[5] 76 V[6] V[2] V[4] 77 V[5] V[4] V[3] 78] 79@inline getvoigt(V::StaticArray{Tuple{1}}) = getvoigt(V, CeedDim(1)) 80@inline getvoigt(V::StaticArray{Tuple{3}}) = getvoigt(V, CeedDim(2)) 81@inline getvoigt(V::StaticArray{Tuple{6}}) = getvoigt(V, CeedDim(3)) 82 83@inline function getvoigt!(J, V, ::CeedDim{1}) 84 @inbounds J[1, 1] = V[1] 85end 86 87@inline function getvoigt!(J, V, ::CeedDim{2}) 88 @inbounds begin 89 #! format: off 90 J[1,1] = V[1] ; J[1,2] = V[3] 91 J[2,1] = V[3] ; J[2,2] = V[2] 92 #! format: on 93 end 94end 95 96@inline function getvoigt!(J, V, ::CeedDim{3}) 97 @inbounds begin 98 #! format: off 99 J[1,1] = V[1] ; J[1,2] = V[6] ; J[1,3] = V[5] 100 J[2,1] = V[6] ; J[2,2] = V[2] ; J[2,3] = V[4] 101 J[3,1] = V[5] ; J[3,2] = V[4] ; J[3,3] = V[3] 102 #! format: on 103 end 104end 105 106function tmp_view(obj, view_fn) 107 str = mktemp() do fname, f 108 cf = Libc.FILE(f) 109 er = view_fn(obj, cf.ptr) 110 ccall(:fflush, Cint, (Ptr{Cvoid},), cf) 111 seek(f, 0) 112 read(f, String) 113 end 114 chomp(str) 115end 116 117function ceed_show(io::IO, obj, view_fn) 118 print(io, tmp_view(obj[], view_fn)) 119end 120