From 03f61938ccbf9a54ba76ab535450d1d4a10028fa Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Wed, 25 Mar 2020 16:30:46 +0100 Subject: [PATCH 01/37] First stage of TensorValues refactoring #210 Needs to clean and reorder the code --- src/ReferenceFEs/ExtrusionPolytopes.jl | 14 +- src/ReferenceFEs/LagrangianRefFEs.jl | 9 +- src/TensorValues/Indexing.jl | 28 +- src/TensorValues/Operations.jl | 167 +++-- src/TensorValues/Reinterpret.jl | 14 +- src/TensorValues/TensorValues.jl | 1 + src/TensorValues/Types.jl | 743 +++++++++++++++++----- test/TensorValuesTests/IndexingTests.jl | 2 +- test/TensorValuesTests/OperationsTests.jl | 32 +- test/TensorValuesTests/TypesTests.jl | 171 ++--- 10 files changed, 803 insertions(+), 378 deletions(-) diff --git a/src/ReferenceFEs/ExtrusionPolytopes.jl b/src/ReferenceFEs/ExtrusionPolytopes.jl index 2dfb4f4fe..2f2b40128 100644 --- a/src/ReferenceFEs/ExtrusionPolytopes.jl +++ b/src/ReferenceFEs/ExtrusionPolytopes.jl @@ -158,8 +158,8 @@ end function (==)(a::ExtrusionPolytope{D},b::ExtrusionPolytope{D}) where D #The first axis is irrelevant here - ea = Point(a.extrusion.array.data[2:end]) - eb = Point(b.extrusion.array.data[2:end]) + ea = Point(Tuple(a.extrusion)[2:end]) + eb = Point(Tuple(b.extrusion)[2:end]) ea == eb end @@ -202,11 +202,11 @@ function get_face_vertex_permutations(p::ExtrusionPolytope) end function is_simplex(p::ExtrusionPolytope) - all(p.extrusion.array .== TET_AXIS) + all(Tuple(p.extrusion) .== TET_AXIS) end function is_n_cube(p::ExtrusionPolytope) - all(p.extrusion.array .== HEX_AXIS) + all(Tuple(p.extrusion) .== HEX_AXIS) end function is_simplex(p::ExtrusionPolytope{0}) @@ -512,7 +512,7 @@ function _vertices_coordinates(::Type{T},p::DFace{D}) where {D,T} vcs = zeros(Point{D,T},length(vs)) for i = 1:length(vs) vx = p.nfaces[vs[i]] - vc = vx.anchor.array.data + vc = Tuple(vx.anchor) vcs[i] = vc end vcs @@ -664,9 +664,9 @@ function _admissible_permutations(p::DFace{D}) where D if D > 3 @warn "Computing permutations for a polytope of dim > 3 is overkill" end - if D in (0,1) || all( p.extrusion.array.data[2:end] .== TET_AXIS ) + if D in (0,1) || all( Tuple(p.extrusion)[2:end] .== TET_AXIS ) perms = _admissible_permutations_simplex(p) - elseif all( p.extrusion.array.data[2:end] .== HEX_AXIS) + elseif all( Tuple(p.extrusion)[2:end] .== HEX_AXIS) perms = _admissible_permutations_n_cube(p) else @notimplemented "admissible vertex permutations only implemented for simplices and n-cubes" diff --git a/src/ReferenceFEs/LagrangianRefFEs.jl b/src/ReferenceFEs/LagrangianRefFEs.jl index b19979c49..37872349a 100644 --- a/src/ReferenceFEs/LagrangianRefFEs.jl +++ b/src/ReferenceFEs/LagrangianRefFEs.jl @@ -276,7 +276,7 @@ function to_dict(reffe::LagrangianRefFE) b = get_prebasis(reffe) dict = Dict{Symbol,Any}() dict[:orders] = collect(get_orders(reffe)) - dict[:extrusion] = Array(get_extrusion(p).array) + dict[:extrusion] = Array(get_array(get_extrusion(p))) if is_S(reffe) dict[:space] = "serendipity" else @@ -374,7 +374,6 @@ function _generate_face_nodes_aux( end function _generate_face_own_dofs(face_own_nodes, node_and_comp_to_dof) - faces = 1:length(face_own_nodes) T = eltype(node_and_comp_to_dof) comps = 1:n_components(T) @@ -704,13 +703,13 @@ function NodalReferenceFE(p::ExtrusionPolytope) end function compute_monomial_basis(::Type{T},p::ExtrusionPolytope{D},orders) where {D,T} - extrusion = Tuple(p.extrusion.array) + extrusion = Tuple(p.extrusion) terms = _monomial_terms(extrusion,orders) MonomialBasis{D}(T,orders,terms) end function compute_own_nodes(p::ExtrusionPolytope{D},orders) where D - extrusion = Tuple(p.extrusion.array) + extrusion = Tuple(p.extrusion) if all(orders .== 0) _interior_nodes_order_0(p) else @@ -729,7 +728,7 @@ function compute_face_orders(p::ExtrusionPolytope,face::ExtrusionPolytope{D},ifa offset = get_offset(p,d) nface = p.dface.nfaces[iface+offset] face_orders = _eliminate_zeros(Val{D}(),nface.extrusion,orders) - face_orders.array.data + Tuple(face_orders) end function _eliminate_zeros(::Val{d},a,o) where d diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index f3daa440f..fddde722b 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,29 +1,31 @@ -size(a::MultiValue) = size(a.array) +#size(a<:MultiValue) = size(a.array) -length(a::MultiValue) = length(a.array) +#length(a<:MultiValue) = length(a.array) -@propagate_inbounds function getindex( - a::MultiValue{S,T,N}, I::Vararg{Integer,N}) where {S,T,N} - a.array[I...] +function getindex(a::VectorValue,i::Integer) + a.data[i] end -@propagate_inbounds function getindex(a::MultiValue, i::Integer) - a.array[i] +function getindex(a::TensorValue,i::Integer) + a.data[i] end -eltype(a::Type{MultiValue{S,T,N,L}}) where {S,T,N,L} = T +function getindex(a::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} + index = (j-1)*D1 + i + a.data[index] +end -@inline iterate(a::MultiValue) = iterate(a.array) +@inline iterate(a::MultiValue) = iterate(a.data) -@inline iterate(a::MultiValue, state) = iterate(a.array, state) +@inline iterate(a::MultiValue, state) = iterate(a.data, state) -eachindex(a::MultiValue) = eachindex(a.array) +eachindex(a::MultiValue) = eachindex(a.data) function CartesianIndices(a::MultiValue) - CartesianIndices(a.array) + CartesianIndices(get_array(a)) end function LinearIndices(a::MultiValue) - LinearIndices(a.array) + LinearIndices(get_array(a)) end diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 485efde75..5c40a05a8 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -2,11 +2,11 @@ # Comparison function (==)(a::MultiValue,b::MultiValue) - a.array == b.array + a.data == b.data end function (≈)(a::MultiValue,b::MultiValue) - a.array ≈ b.array + isapprox(collect(a.data), collect(b.data)) end function (≈)(a::VectorValue{0},b::VectorValue{0}) @@ -35,19 +35,23 @@ function Base.isless(a::VectorValue{N},b::VectorValue{N}) where N false end +function Base.isless(a::Number,b::MultiValue) where {D,T} + all(a .< b.data) +end + # Addition / subtraction for op in (:+,:-) @eval begin - function ($op)(a::MultiValue{S}) where S - r = $op(a.array) - MultiValue(r) + function ($op)(a::T) where {T<:MultiValue} + r = map($op, a.data) + T(r) end - function ($op)(a::MultiValue{S},b::MultiValue{S}) where S - r = $op(a.array, b.array) - MultiValue(r) + function ($op)(a::T,b::T) where {T<:MultiValue} + r = broadcast(($op), a.data, b.data) + T(r) end end @@ -55,46 +59,84 @@ end # Matrix Division -function (\)(a::TensorValue, b::MultiValue) - r = a.array \ b.array - MultiValue(r) +function (\)(a::T1 where {T1<:TensorValue}, b::T2) where {T2<:MultiValue} + r = get_array(a) \ get_array(b) + T2(r) end # Operations with other numbers for op in (:+,:-,:*) @eval begin - ($op)(a::MultiValue,b::Number) = MultiValue($op.(a.array,b)) - ($op)(a::Number,b::MultiValue) = MultiValue($op.(a,b.array)) + function ($op)(a::T,b::Number) where {T<:MultiValue} + r = broadcast($op,a.data,b) + PT = change_eltype(T,eltype(r)) + PT(r) + end + + function ($op)(a::Number,b::T) where {T<:MultiValue} + r = broadcast($op,a,b.data) + PT = change_eltype(T,eltype(r)) + PT(r) + end end end -(/)(a::MultiValue,b::Number) = MultiValue(a.array/b) +function (/)(a::T,b::Number) where {T<:MultiValue} + r = broadcast(/,a.data,b) + PT = change_eltype(T,eltype(r)) + PT(r) +end # Dot product (simple contraction) -(*)(a::VectorValue{D}, b::VectorValue{D}) where D = inner(a,b) +function (*)(a::VectorValue{D}, b::VectorValue{D}) where D + inner(a,b) +end -function (*)(a::MultiValue,b::MultiValue) - r = a.array * b.array - MultiValue(r) +@generated function (*)(a::VectorValue{D1}, b::TensorValue{D2,D1}) where {D1,D2} + ss = String[] + for j in 1:D2 + s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) + push!(ss,s[1:(end-1)]*", ") + end + str = join(ss) + Meta.parse("VectorValue{$D2}($str)") end -@generated function (*)(a::VectorValue{D}, b::TensorValue{D}) where D +@generated function (*)(a::TensorValue{D1,D2}, b::VectorValue{D1}) where {D1,D2} ss = String[] - for j in 1:D - s = join([ "a.array[$i]*b.array[$i,$j]+" for i in 1:D]) + for j in 1:D2 + s = join([ "b[$i]*a[$j,$i]+" for i in 1:D1]) push!(ss,s[1:(end-1)]*", ") end str = join(ss) - Meta.parse("VectorValue($str)") + Meta.parse("VectorValue{$D2}($str)") end -@inline dot(u::VectorValue,v::VectorValue) = inner(u,v) +@generated function (*)(a::TensorValue{D1,D2}, b::TensorValue{D3,D1}) where {D1,D2,D3} + ss = String[] + for j in 1:D2 + for i in 1:D1 + s = join([ "a[$i,$k]*b[$k,$j]+" for k in 1:D3]) + push!(ss,s[1:(end-1)]*", ") + end + end + str = join(ss) + Meta.parse("TensorValue{$D2,$D3}($str)") +end -@inline dot(u::TensorValue,v::VectorValue) = u*v +@inline function dot(u::VectorValue,v::VectorValue) + inner(u,v) +end -@inline dot(u::VectorValue,v::TensorValue) = u*v +@inline function dot(u::TensorValue,v::VectorValue) + u*v +end + +@inline function dot(u::VectorValue,v::TensorValue) + u*v +end # Inner product (full contraction) @@ -102,8 +144,9 @@ inner(a::Real,b::Real) = a*b """ """ -@generated function inner(a::MultiValue{S,T,N,L}, b::MultiValue{S,W,N,L}) where {S,T,N,L,W} - str = join([" a.array.data[$i]*b.array.data[$i] +" for i in 1:L ]) +@generated function inner(a::MultiValue, b::MultiValue) + @assert length(a) == length(b) + str = join([" a[$i]*b[$i] +" for i in 1:length(a) ]) Meta.parse(str[1:(end-1)]) end @@ -111,7 +154,9 @@ end for op in (:sum,:maximum,:minimum) @eval begin - $op(a::MultiValue) = $op(a.array) + function $op(a::T) where {T<: MultiValue} + $op(a.data) + end end end @@ -126,20 +171,20 @@ outer(a::MultiValue,b::Real) = a*b outer(a::Real,b::MultiValue) = a*b @generated function outer(a::VectorValue{D},b::VectorValue{Z}) where {D,Z} - str = join(["a.array[$i]*b.array[$j], " for j in 1:Z for i in 1:D]) - Meta.parse("MultiValue(SMatrix{$D,$Z}($str))") + str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) + Meta.parse("TensorValue{$D,$Z}($str)") end -@generated function outer(a::VectorValue{D},b::MultiValue{Tuple{A,B}}) where {D,A,B} - str = join(["a.array[$i]*b.array[$j,$k], " for k in 1:B for j in 1:A for i in 1:D]) - Meta.parse("MultiValue(SArray{Tuple{$D,$A,$B}}($str))") -end +#@generated function outer(a::VectorValue{D},b::TensorValue{D1,D2}) where {D,D1,D2} +# str = join(["a.array[$i]*b.array[$j,$k], " for k in 1:D2 for j in 1:D1 for i in 1:D]) +# Meta.parse("MultiValue(SArray{Tuple{$D,$D1,$D2}}($str))") +#end # Linear Algebra -det(a::TensorValue) = det(a.array) +det(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = det(convert(StaticArrays.SMatrix{D1,D2,T,L},a)) -inv(a::TensorValue) = MultiValue(inv(a.array)) +inv(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = TensorValue(inv(convert(StaticArrays.SMatrix{D1,D2,T,L},a))) # Measure @@ -149,14 +194,14 @@ meas(a::VectorValue) = sqrt(inner(a,a)) meas(a::TensorValue) = abs(det(a)) -function meas(v::MultiValue{Tuple{1,2}}) +function meas(v::TensorValue{1,2}) n1 = v[1,2] n2 = -1*v[1,1] n = VectorValue(n1,n2) sqrt(n*n) end -function meas(v::MultiValue{Tuple{2,3}}) +function meas(v::TensorValue{2,3}) n1 = v[1,2]*v[2,3] - v[1,3]*v[2,2] n2 = v[1,3]*v[2,1] - v[1,1]*v[2,3] n3 = v[1,1]*v[2,2] - v[1,2]*v[2,1] @@ -170,39 +215,41 @@ end # conj -conj(a::MultiValue) = MultiValue(conj(a.array)) +conj(a::VectorValue) = a + +conj(a::T) where {T<:TensorValue} = T(conj(get_array(a))) # Trace @generated function tr(v::TensorValue{D}) where D - str = join([" v.array.data[$i+$((i-1)*D)] +" for i in 1:D ]) + str = join([" v[$i+$((i-1)*D)] +" for i in 1:D ]) Meta.parse(str[1:(end-1)]) end -@generated function tr(v::MultiValue{Tuple{A,A,B}}) where {A,B} - str = "" - for k in 1:B - for i in 1:A - if i !=1 - str *= " + " - end - str *= " v.array[$i,$i,$k]" - end - str *= ", " - end - Meta.parse("VectorValue($str)") -end +#@generated function tr(v::MultiValue{Tuple{A,A,B}}) where {A,B} +# str = "" +# for k in 1:B +# for i in 1:A +# if i !=1 +# str *= " + " +# end +# str *= " v.array[$i,$i,$k]" +# end +# str *= ", " +# end +# Meta.parse("VectorValue($str)") +#end # Adjoint and transpose -function adjoint(v::TensorValue) - t = adjoint(v.array) - TensorValue(t) +function adjoint(v::T) where {T<:TensorValue} + t = adjoint(get_array(v)) + T(t) end -function transpose(v::TensorValue) - t = transpose(v.array) - TensorValue(t) +function transpose(v::T) where {T<:TensorValue} + t = transpose(get_array(v)) + T(t) end # Symmetric part @@ -213,7 +260,7 @@ end str = "(" for j in 1:D for i in 1:D - str *= "0.5*v.array.data[$i+$((j-1)*D)] + 0.5*v.array.data[$j+$((i-1)*D)], " + str *= "0.5*v.data[$i+$((j-1)*D)] + 0.5*v.data[$j+$((i-1)*D)], " end end str *= ")" diff --git a/src/TensorValues/Reinterpret.jl b/src/TensorValues/Reinterpret.jl index efa74283f..112011a89 100644 --- a/src/TensorValues/Reinterpret.jl +++ b/src/TensorValues/Reinterpret.jl @@ -1,11 +1,17 @@ -function reinterpret(a::Array{MultiValue{S,T,N,L}}) where {S,T,N,L} +function reinterpret(a::Array{VectorValue{D,T}}) where {D,T} b = reinterpret(T,a) sa = size(a) - sv = Size(S) - t = _Size_to_tuple(sv) + t = size(VectorValue{D,T}) + s = (t...,sa...) + reshape(b,s) +end + +function reinterpret(a::Array{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + b = reinterpret(T,a) + sa = size(a) + t = size(TensorValue{D1,D2,T,L}) s = (t...,sa...) reshape(b,s) end -_Size_to_tuple(::Size{t}) where t = t diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 2cac90dc3..087a94315 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -45,6 +45,7 @@ export symmetic_part export n_components export change_eltype export diagonal_tensor +export get_array import Base: show import Base: zero, one diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index 016a18bd7..b3b2ac299 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -1,259 +1,712 @@ - +############################################################### # Types +############################################################### """ Type representing a multi-dimensional value """ -struct MultiValue{S,T,N,L} <: Number - array::SArray{S,T,N,L} -end +abstract type MultiValue <: Number end """ -Type representing a second-order tensor +Type representing a first-order tensor """ -const TensorValue{D,T,L} = MultiValue{Tuple{D,D},T,2,L} +struct VectorValue{D,T} <: MultiValue + data::NTuple{D,T} + function VectorValue{D,T}(data::NTuple{D,T}) where {D,T} + new{D,T}(data) + end +end """ -Type representing a first-order tensor +Type representing a second-order tensor """ -const VectorValue{D,T} = MultiValue{Tuple{D},T,1,D} +struct TensorValue{D1,D2,T,L} <: MultiValue + data::NTuple{L,T} + function TensorValue{D1,D2,T}(data::NTuple{L,T}) where {D1,D2,T,L} + @assert L == D1*D2 + new{D1,D2,T,L}(data) + end +end + +############################################################### +# Constructors (VectorValue) +############################################################### + +# VectorValue no-arguments constructor + +function VectorValue() + VectorValue{0}() +end + +function VectorValue{0}() + VectorValue{0,Int}() +end + +function VectorValue{0,T}() where {T} + VectorValue{0,T}(NTuple{0,T}()) +end + +# VectorValue empty tuple constructor + +function VectorValue(data::NTuple{0}) + VectorValue{0,Int}(data) +end + +function VectorValue{0}(data::NTuple{0}) + VectorValue{0,Int}(data) +end + +# VectorValue single NTuple argument constructor + +function VectorValue(data::NTuple{D,T}) where {D,T} + VectorValue{D,T}(data) +end + +function VectorValue{D}(data::NTuple{D,T}) where {D,T} + VectorValue{D,T}(data) +end + +function VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(data)) +end + +# VectorValue Vararg constructor + +function VectorValue(data::Vararg) + VectorValue(NTuple{length(data)}(data)) +end + +function VectorValue{D}(data::Vararg) where {D} + VectorValue{D}(NTuple{D}(data)) +end -# Constructors (MultiValue) +function VectorValue{D,T}(data::Vararg) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) +end + +# VectorValue single MVector argument constructor -function (::Type{MultiValue{S}})(x::Tuple) where S<:Tuple - array = SArray{S}(x) - MultiValue(array) +function VectorValue(data::MVector{D,T}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) end -function (::Type{MultiValue{S}})(x::Tuple{}) where S<:Tuple - s = """ - Unknown element type. +function VectorValue{D}(data::MVector{D,T}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) +end - Provide element type in the corresponding type parameter. - Examples: - MultiValue{Tuple{0,0},Int}() - TensorValue{0,Int}() - VectorValue{0,Int}() - """ - error(s) +function VectorValue{D,T1}(data::MVector{D,T2}) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(data)) end -function (::Type{MultiValue{S,T}})(x::Tuple) where {S<:Tuple,T} - array = SArray{S,T}(x) - MultiValue(array) +# VectorValue single MVector argument constructor + +function VectorValue(data::SVector{D,T}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) end -function (::Type{MultiValue{S}})(x::Vararg) where S<:Tuple - MultiValue{S}(x) +function VectorValue{D}(data::SVector{D,T}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) +end + +function VectorValue{D,T1}(data::SVector{D,T2}) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(data)) +end + +# VectorValue single AbstractArray argument constructor + +function VectorValue(data::AbstractArray{T}) where {T} + D = length(data) + VectorValue{D,T}(NTuple{D,T}(data)) end -function (::Type{MultiValue{S,T}})(x::Vararg) where {S<:Tuple,T} - MultiValue{S,T}(x) +function VectorValue{D}(data::AbstractArray{T}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(data)) end -function MultiValue(a::StaticArray{S,T}) where {S,T} - MultiValue{S,T}(a.data) +function VectorValue{D,T1}(data::AbstractArray{T2}) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(data)) end +############################################################### # Constructors (TensorValue) +############################################################### -function (::Type{TensorValue{D}})(x::Tuple) where D - S = Tuple{D,D} - MultiValue{S}(x) +# TensorValue no-arguments constructor + +function TensorValue() + TensorValue{0,0}() end -function (::Type{TensorValue{0}})() - S = Tuple{0,0} - MultiValue{S}() +function TensorValue{0,0}() + TensorValue{0,0,Int}(NTuple{0,Int}()) end -function (::Type{TensorValue{D}})(x::Vararg) where D - TensorValue{D}(x) +function TensorValue{0,0,T}() where {T} + TensorValue{0,0,T}(NTuple{0,T}()) end -function (::Type{TensorValue{D,T}})(x::Tuple) where {D,T} - S = Tuple{D,D} - MultiValue{S,T}(x) +# TensorValue empty tuple constructor + +function TensorValue(data::NTuple{0}) + TensorValue{0,0,Int}(data) end -function (::Type{TensorValue{D,T}})(x::Vararg) where {D,T} - TensorValue{D,T}(x) +function TensorValue{0,0}(data::NTuple{0}) + TensorValue{0,0,Int}(data) end -@generated function TensorValue(arg::NTuple{DD,T}) where {T,DD} - SQ = sqrt(DD) - D = ceil(Int,SQ) - @assert D == SQ - :( TensorValue{$D,T}(arg) ) +# TensorValue single NTuple argument constructor + +function TensorValue(data::NTuple{L,T}) where {L,T} + D=Int(sqrt(L)) + TensorValue{D,D,T}(data) end -function TensorValue(args::Vararg) - TensorValue(args) +function TensorValue{D}(data::NTuple{L,T}) where {D,L,T} + TensorValue{D,D,T}(data) end -function TensorValue() - S = Tuple{0,0} - MultiValue{S}() +function TensorValue{D1,D2}(data::NTuple{L,T}) where {D1,D2,L,T} + TensorValue{D1,D2,T}(data) end -function TensorValue(a::StaticArray) - TensorValue(a.data) +function TensorValue{D1,D2,T1}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -""" -""" -@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} - s = ["zero(T), " for i in 1:(D*D)] - for i in 1:D - d = D*(i-1)+i - s[d] = "v.array[$i]," - end - str = join(s) - Meta.parse("TensorValue(($str))") +function TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -# Constructors (VectorValue) +# TensorValue Vararg constructor -function (::Type{VectorValue{D}})(x::Tuple) where D - S = Tuple{D} - MultiValue{S}(x) +function TensorValue(data::Vararg) + TensorValue(NTuple{length(data)}(data)) end -function (::Type{VectorValue{D}})(x::Vararg) where D - VectorValue{D}(x) +function TensorValue{D}(data::Vararg) where {D} + TensorValue{D,D}(NTuple{D*D}(data)) end -function (::Type{VectorValue{D,T}})() where {D,T} - S = Tuple{D} - MultiValue{S,T}() +function TensorValue{D1,D2}(data::Vararg) where {D1,D2} + TensorValue{D1,D2}(NTuple{D1*D2}(data)) end -function VectorValue(arg::NTuple{D,T}) where {D,T} - VectorValue{D,T}(arg) +function TensorValue{D1,D2,T}(data::Vararg) where {D1,D2,T} + TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) end -function (::Type{VectorValue{D,T}})(x::Vararg{Number,D}) where {T,D} - VectorValue{D,T}(x) +# TensorValue single MVector argument constructor + +function TensorValue(data::MVector{L,T}) where {L,T} + D=Int(sqrt(L)) + TensorValue{D,D,T}(NTuple{L,T}(data)) end -function VectorValue(args::Vararg) - VectorValue(args) +function TensorValue{D1,D2}(data::MVector{L,T}) where {D1,D2,T,L} + TensorValue{D1,D2,T}(NTuple{L,T}(data)) end -function VectorValue() - S = Tuple{0} - MultiValue{S}() +function TensorValue{D1,D2,T1}(data::MVector{L,T2}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -function VectorValue(a::StaticArray) - VectorValue(a.data) +# TensorValue single SVector argument constructor + +function TensorValue(data::SVector{L,T}) where {L,T} + D=Int(sqrt(L)) + TensorValue{D,D,T}(NTuple{L,T}(data)) end -function VectorValue(a::SVector) - MultiValue(a) +function TensorValue{D1,D2}(data::SVector{L,T}) where {D1,D2,T,L} + TensorValue{D1,D2,T}(NTuple{L,T}(data)) end -function VectorValue(a::MVector) - MultiValue(a) +function TensorValue{D1,D2,T1}(data::SVector{L,T2}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end +# TensorValue single MMAtrix argument constructor +function TensorValue(data::StaticArrays.MMatrix{D1,D2,T,L}) where {D1,D2,T,L} + D=Int(sqrt(L)) + TensorValue{D,D,T}(NTuple{L,T}(data)) +end -# Initializers +function TensorValue{D1,D2}(data::StaticArrays.MMatrix{D1,D2,T,L}) where {D1,D2,T,L} + TensorValue{D1,D2,T}(NTuple{L,T}(data)) +end -function zero(::Type{<:MultiValue{S,T,N,L}}) where {S,T,N,L} - z = zero(SArray{S,T,N,L}) - MultiValue{S,T,N,L}(z) +function TensorValue{D1,D2,T1}(data::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -function zero(::MultiValue{S,T,N,L}) where {S,T,N,L} - zero(MultiValue{S,T,N,L}) +function TensorValue{D1,D2,T1,L}(data::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -function one(::Type{<:MultiValue{S,T,N,L}}) where {S,T,N,L} - z = one(SArray{S,T,N,L}) - MultiValue{S,T,N,L}(z) +# TensorValue single SMatrix argument constructor + +function TensorValue(data::StaticArrays.SMatrix{D1,D2,T,L}) where {D1,D2,T,L} + D=Int(sqrt(L)) + TensorValue{D,D,T}(NTuple{L,T}(data)) end -function one(::MultiValue{S,T,N,L}) where {S,T,N,L} - one(MultiValue{S,T,N,L}) +function TensorValue{D1,D2}(data::StaticArrays.SMatrix{D1,D2,T,L}) where {D1,D2,T,L} + TensorValue{D1,D2,T}(NTuple{L,T}(data)) end -# Conversions +function TensorValue{D1,D2,T1}(data::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) +end -function convert(::Type{<:MultiValue{S,T,N,L}},a::StaticArray{S,T,N}) where {S,T,N,L} - MultiValue(a) +function TensorValue{D1,D2,T1,L}(data::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -function convert( - ::Type{<:MultiValue{S,T,N,L}},a::AbstractArray{R,N}) where {S,T,N,L,R} - b = convert(SArray{S,T,N,L},a) - MultiValue(b) +# TensorValue single AbstractArray argument constructor + +function TensorValue(data::AbstractArray{T}) where {T} + L = length(data) + TensorValue(NTuple{L,T}(data)) end -function convert(::Type{<:MultiValue{S,T,N,L}},a::NTuple{L,R}) where {S,T,N,L,R} - MultiValue(SArray{S,T}(a)) +function TensorValue{D1,D2}(data::AbstractArray{T}) where {D1,D2,T} + TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) end -# Misc operations on the type itself +function TensorValue{D1,D2,T1}(data::AbstractArray{T2}) where {D1,D2,T1,T2} + TensorValue{D1,D2,T1}(NTuple{D1*D2,T1}(data)) +end -length(::Type{<: MultiValue{S,T,N,L} where {S,T,N}} ) where L = L +############################################################### +# Conversions (VectorValue) +############################################################### -function size(::Type{MultiValue{S,T,N,L}}) where {S,T,N,L} - A = SArray{S,T,N,L} - size(A) +function convert(::Type{<:VectorValue}, arg::NTuple{D}) where {D} + VectorValue{D}(arg) end -function size(::Type{<:MultiValue{S}}) where S - _s(Size(S)) +function convert(::Type{<:VectorValue{D}}, arg::NTuple{D}) where {D} + VectorValue{D}(NTuple{D}(arg)) end -@pure _s(s::Size{T}) where T = T +function convert(::Type{<:VectorValue{D,T}}, arg::NTuple{D}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(arg)) +end -""" - n_components(::Type) +function convert(::Type{<:NTuple}, arg::VectorValue{D,T}) where {D,T} + NTuple{D,T}(arg.data) +end -Returns the number of components stored in the given type. -Implemented for types `<:Real` and `<:MultiValue`. -Also available for instances of these types. -""" -n_components(::Type{<: MultiValue{S,T,N,L} where {S,T,N}} ) where L = L -n_components(a::T) where T<:MultiValue = n_components(T) +function convert(::Type{<:NTuple{D}}, arg::VectorValue{D,T}) where {D,T} + NTuple{D,T}(arg.data) +end -n_components(::Type{<:Real}) = 1 -n_components(a::T) where T<:Real = 1 +function convert(::Type{<:NTuple{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} + NTuple{D,T1}(arg.data) +end +function convert(::Type{<:VectorValue}, arg::SVector{D,T}) where {D,T} + VectorValue{D,T}(arg) +end -# Custom type printing +function convert(::Type{<:VectorValue{D}}, arg::SVector{D,T}) where {D,T} + VectorValue{D,T}(arg) +end -function show(io::IO,v::MultiValue) - print(io,v.array.data) +function convert(::Type{<:VectorValue{D,T1}}, arg::SVector{D,T2}) where {D,T1,T2} + VectorValue{D,T1}(arg) end -function show(io::IO,::MIME"text/plain",v::MultiValue) - print(io,typeof(v)) - print(io,v.array.data) +function convert(::Type{<:VectorValue}, arg::MVector{D,T}) where {D,T} + VectorValue{D,T}(arg) +end + +function convert(::Type{<:VectorValue{D}}, arg::MVector{D,T}) where {D,T} + VectorValue{D,T}(arg) +end + +function convert(::Type{<:VectorValue{D,T1}}, arg::MVector{D,T2}) where {D,T1,T2} + VectorValue{D,T1}(arg) +end + +function convert(::Type{<:SVector}, arg::VectorValue{D,T}) where {D,T} + SVector{D,T}(arg.data) +end + +function convert(::Type{<:SVector{D}}, arg::VectorValue{D,T}) where {D,T} + SVector{D,T}(arg.data) +end + +function convert(::Type{<:SVector{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} + SVector{D,T1}(arg.data) +end + +function convert(::Type{<:MVector}, arg::VectorValue{D,T}) where {D,T} + MVector{D,T}(arg.data) +end + +function convert(::Type{<:MVector{D}}, arg::VectorValue{D,T}) where {D,T} + MVector{D,T}(arg.data) +end + +function convert(::Type{<:MVector{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} + MVector{D,T1}(arg.data) +end + +function convert(AAT::Type{<:AbstractArray{T1,N}}, arg::VectorValue{D,T2}) where {D,T1,T2,N} + AAT{T1,N}(collect(T1,arg.data)) +end + +function convert(::Type{<:VectorValue}, arg::AbstractArray{T,1}) where {T} + D =length(arg) + VectorValue{D,T}(NTuple{D,T}(arg)) +end + +function convert(::Type{<:VectorValue{D}}, arg::AbstractArray{T,1}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(arg)) +end + +function convert(::Type{<:VectorValue{D,T1}}, arg::AbstractArray{T2,1}) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(arg)) +end + +function convert(::Type{<:VectorValue}, arg::VectorValue{D,T2}) where {D,T2} + arg +end + +function convert(::Type{<:VectorValue{D}}, arg::VectorValue{D,T2}) where {D,T2} +end + +function convert(::Type{<:VectorValue{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} + T1 == T2 ? arg : convert(VectorValue{D,T1}, arg.data) +end + +############################################################### +# Conversions (TensorValue) +############################################################### + +function convert(::Type{<:TensorValue}, arg::NTuple{L}) where {L} + TensorValue(arg) +end + +function convert(::Type{<:TensorValue{D1,D2}}, arg::NTuple{L}) where {D1,D2,L} + TensorValue{D1,D2}(arg) +end + +function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::NTuple{L}) where {D1,D2,T1,L} + TensorValue{D1,D2,T1}(arg) +end + +function convert(::Type{<:NTuple}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} + NTuple(arg.data) +end + +function convert(::Type{<:NTuple{L,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + NTuple{L,T1}(arg.data) +end + +function convert(::Type{<:TensorValue}, arg::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T2,L} + TensorValue{D1,D2,T2}(arg) +end + +function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(arg) +end + +function convert(::Type{<:TensorValue}, arg::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T2,L} + TensorValue{D1,D2,T2}(arg) +end + +function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(arg) +end + +function convert(::Type{<:StaticArrays.SMatrix}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} + StaticArrays.SMatrix{D1,D2,T2,L}(arg.data) +end + +function convert(::Type{<:StaticArrays.SMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + StaticArrays.SMatrix{D1,D2,T1,L}(arg.data) +end + +function convert(::Type{<:StaticArrays.MMatrix}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} + StaticArrays.MMatrix{D1,D2,T2,L}(arg.data) +end + +function convert(::Type{<:StaticArrays.MMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + StaticArrays.MMatrix{D1,D2,T1,L}(arg.data) +end + +function convert(::Type{<:TensorValue}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} + arg +end + +function convert(::Type{<:TensorValue{D1,D2}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} + arg +end + +function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + T1 == T2 ? arg : convert(TensorValue{D1,D2,T1,L}, arg.data) +end + +############################################################### +# Other constructors (VectorValue) +############################################################### + +function zero(::Type{<:VectorValue{D,T}}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) +end + +function one(::Type{<:VectorValue{D,T}}) where {D,T} + VectorValue{D,T}(NTuple{D,T}(ones(T,D))) +end + +function mutable(::Type{VectorValue{D,T}}) where {D,T} + MVector{D,T} +end + +function change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} + VectorValue{D,T} +end + +function change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} + VectorValue{D,T2} +end + +function zero(::IT where {IT<:VectorValue{D,T}}) where {D,T} + zero(VectorValue{D,T}) +end + +function one(::IT where {IT<:VectorValue{D,T}}) where {D,T} + one(VectorValue{D,T}) +end + +function mutable(::IT where {IT<:VectorValue{D,T}}) where {D,T} + mutable(VectorValue{D,T}) +end + +function change_eltype(::IT where {IT<:VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} + change_eltype(VectorValue{D,T1},T2) +end + +function SVector(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + SVector{D,T}(arg.data) +end + +function SArray(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + SVector(arg) +end + +############################################################### +# Other constructors (TensorValue) +############################################################### + +function zero(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} + D=D1*D2 + TensorValue{D1,D2,T}(NTuple{D,T}(zeros(T,D))) +end + +@generated function one(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} + str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D1 for j in 1:D2]) + Meta.parse("TensorValue{D1,D2,T}(($str))") +end + +function mutable(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} + MMatrix{D1,D2,T} +end + +function change_eltype(::Type{TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T2,L} +end + +function zero(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} + zero(TensorValue{D1,D2,T}) +end + +function one(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} + one(TensorValue{D1,D2,T}) +end + +function mutable(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} + mutable(TensorValue{D1,D2,T}) +end + +function change_eltype(::IT where {IT<:TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} + change_eltype(TensorValue{D1,D2,T1,L},T2) +end + +function StaticArrays.SMatrix(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + StaticArrays.SMatrix{D1,D2,T,L}(arg.data) +end + +function SArray(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + StaticArrays.SMatrix(arg) +end + + + + +function get_array(arg::T where {T<:VectorValue}) + convert(SVector,arg) +end + +function get_array(arg::T where {T<:TensorValue}) + convert(SMatrix,arg) +end + +function change_eltype(::Type{<:Number},::Type{T}) where {T} + T +end + +function change_eltype(::Number,::Type{T2}) where {T2} + change_eltype(Number,T2) +end + +function eltype(::Type{<:VectorValue{D,T}}) where {D,T} + T +end + +function eltype(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} + T +end + +function eltype(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + eltype(VectorValue{D,T}) +end + +function eltype(arg::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} + eltype(TensorValue{D1,D2,T}) +end + +function size(::Type{VectorValue{D}}) where {D} + (D,) +end + +function size(::Type{VectorValue{D,T}}) where {D,T} + (D,) +end + +function size(::Type{TensorValue{D}}) where {D} + (D,D) +end + +function size(::Type{TensorValue{D1,D2}}) where {D1,D2} + (D1,D2) +end + +function size(::Type{TensorValue{D1,D2,T}}) where {D1,D2,T} + (D1,D2) +end + +function size(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + (D1,D2) +end + +function size(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + size(VectorValue{D,T}) +end + +function size(arg::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} + size(TensorValue{D1,D2,T}) +end + +function length(::Type{VectorValue{D}}) where {D} + D +end + +function length(::Type{VectorValue{D,T}}) where {D,T} + D +end + +function length(::Type{TensorValue{D}}) where {D} + length(TensorValue{D,D}) +end + +function length(::Type{TensorValue{D1,D2}}) where {D1,D2} + D1*D1 +end + +function length(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + L +end + +function length(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + length(VectorValue{D,T}) +end + +function length(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + length(TensorValue{D1,D2,T,L}) +end + +function n_components(::Type{<:Number}) + 1 +end + +function n_components(::Type{VectorValue{D}}) where {D} + length(VectorValue{D}) +end + +function n_components(::Type{VectorValue{D,T}}) where {D,T} + length(VectorValue{D,T}) +end + +function n_components(::Type{TensorValue{D}}) where {D} + length(TensorValue{D,D}) +end + +function n_components(::Type{TensorValue{D1,D2}}) where {D1,D2} + length(TensorValue{D1,D2}) +end + +function n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + length(TensorValue{D1,D2,T,L}) +end + +function n_components(arg::IT where {IT<:Number}) + n_components(Number) +end + + +function n_components(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} + n_components(VectorValue{D,T}) +end + + +function n_components(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + n_components(TensorValue{D1,D2,T,L}) end -# Misc -""" -""" -mutable(::Type{MultiValue{S,T,N,L}}) where {S,T,N,L} = MArray{S,T,N,L} -mutable(::MultiValue{S,T,N,L}) where {S,T,N,L} = MArray{S,T,N,L} """ """ -function change_eltype(::Type{MultiValue{S,T,N,L}},::Type{E}) where {S,T,N,L,E} - MultiValue{S,E,N,L} +@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} + s = ["zero(T), " for i in 1:(D*D)] + for i in 1:D + d = D*(i-1)+i + s[d] = "v.data[$i]," + end + str = join(s) + Meta.parse("TensorValue(($str))") end -change_eltype(a::T,::Type{E}) where {T<:MultiValue,E} = change_eltype(T,E) +# Misc operations on the type itself + +@pure _s(s::Size{T}) where T = T + +# Custom type printing -change_eltype(::Type{<:Real},::Type{E}) where E = E +function show(io::IO,v::IT where {IT<:MultiValue}) + print(io,v.data) +end -change_eltype(a::T,::Type{E}) where {T<:Real,E} = change_eltype(T,E) +function show(io::IO,::MIME"text/plain",v:: IT where {IT<:MultiValue}) + print(io,typeof(v)) + print(io,v.data) +end -@inline Tuple(a::MultiValue) = a.array.data +@inline Tuple(arg::IT where {IT<:MultiValue}) = arg.data diff --git a/test/TensorValuesTests/IndexingTests.jl b/test/TensorValuesTests/IndexingTests.jl index 531f7a6e3..a966f4839 100644 --- a/test/TensorValuesTests/IndexingTests.jl +++ b/test/TensorValuesTests/IndexingTests.jl @@ -36,7 +36,7 @@ for (k,ti) in enumerate(t) end v = @SMatrix zeros(2,3) -w = MultiValue(v) +w = TensorValue{2,3}(v) @test CartesianIndices(w) == CartesianIndices(v) @test LinearIndices(w) == LinearIndices(v) diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index d4b81578f..5660bd345 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -44,7 +44,7 @@ r = VectorValue(-1,1,-3) # Matrix Division -t = one(TensorValue{3,Int,9}) +t = one(TensorValue{3,3,Int,9}) c = t\a @@ -80,17 +80,17 @@ r = VectorValue(1/2,1.0,3/2) @test c == r c = 2 * t -@test isa(c,TensorValue{3,Int}) +@test isa(c,TensorValue{3}) r = TensorValue(2, 4, 6, 8, 10, 12, 14, 16, 18) @test c == r c = t * 2 -@test isa(c,TensorValue{3,Int}) +@test isa(c,TensorValue{3}) r = TensorValue(2, 4, 6, 8, 10, 12, 14, 16, 18) @test c == r c = t + 2 -@test isa(c,TensorValue{3,Int}) +@test isa(c,TensorValue{3,3,Int}) r = TensorValue(3, 4, 5, 6, 7, 8, 9, 10, 11) @test c == r @@ -112,7 +112,7 @@ r = VectorValue(30,36,42) @test c == r c = s * t -@test isa(c,TensorValue{3,Int}) +@test isa(c,TensorValue{3,3,Int}) r = TensorValue(38,24,18,98,69,48,158,114,78) @test c == r @@ -168,16 +168,16 @@ c = outer(a,2) @test c == r c = outer(a,e) -@test isa(c,MultiValue{Tuple{3,2},Int}) -r = MultiValue{Tuple{3,2},Int}(2,4,6,5,10,15) +@test isa(c,TensorValue{3,2,Int}) +r = TensorValue{3,2,Int}(2,4,6,5,10,15) @test c == r -e = VectorValue(10,20) -k = TensorValue(1,2,3,4) -c = outer(e,k) -@test c == MultiValue{Tuple{2,2,2}}(10, 20, 20, 40, 30, 60, 40, 80) - -@test tr(c) == VectorValue(50,110) +#e = VectorValue(10,20) +#k = TensorValue(1,2,3,4) +#c = outer(e,k) +#@test c == MultiValue{Tuple{2,2,2}}(10, 20, 20, 40, 30, 60, 40, 80) +# +#@test tr(c) == VectorValue(50,110) # Linear Algebra @@ -199,13 +199,13 @@ t = TensorValue(10,2,30,4,5,6,70,8,9) c = meas(t) @test c ≈ 8802.0 -v = MultiValue{Tuple{1,2}}(10,20) +v = TensorValue{1,2}(10,20) @test meas(v) == sqrt(500) -v = MultiValue{Tuple{2,3}}(1,0,0,1,0,0) +v = TensorValue{2,3}(1,0,0,1,0,0) @test meas(v) ≈ 1.0 -v = MultiValue{Tuple{2,3}}(1,0,0,1,1,0) +v = TensorValue{2,3}(1,0,0,1,1,0) @test meas(v) ≈ sqrt(2) # Broadcasted operations diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index 5b659cad9..ce3b62ab4 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -4,209 +4,126 @@ using Gridap.TensorValues using Test using StaticArrays -# Constructors (MultiValue) - -a = MArray{Tuple{3,2}}((1,2,3,4,5,6)) -v = MultiValue(a) -@test isa(v,MultiValue{Tuple{3,2},Int}) -@test v.array.data === a.data - -a = SArray{Tuple{3,2}}((1,2,3,4,5,6)) - -v = MultiValue(a) -@test isa(v,MultiValue{Tuple{3,2},Int}) -@test v.array === a - -v = MultiValue{Tuple{3,2}}((1,2,3,4,5,6)) -@test isa(v,MultiValue{Tuple{3,2},Int}) -@test v.array == a - -v = MultiValue{Tuple{3,2}}(1,2,3,4,5,6) -@test isa(v,MultiValue{Tuple{3,2},Int}) -@test v.array == a - -v = MultiValue{Tuple{3,2},Float64}((1,2,3,4,5,6)) -@test isa(v,MultiValue{Tuple{3,2},Float64}) -@test v.array == a - -v = MultiValue{Tuple{3,2},Float64}(1,2,3,4,5,6) -@test isa(v,MultiValue{Tuple{3,2},Float64}) -@test v.array == a - -a = SVector(1) -v = MultiValue{Tuple{1}}((1,)) -@test isa(v,MultiValue{Tuple{1},Int}) -@test v.array == a - -v = MultiValue{Tuple{1}}(1) -@test isa(v,MultiValue{Tuple{1},Int}) -@test v.array == a - -a = SMatrix{1,1}(1) -v = MultiValue{Tuple{1,1}}(1) -@test isa(v,MultiValue{Tuple{1,1},Int}) -@test v.array == a - -a = SVector{0,Int}() -v = MultiValue{Tuple{0},Int}(()) -@test isa(v,MultiValue{Tuple{0},Int}) -@test v.array == a - -a = SMatrix{0,0,Int}() -v = MultiValue{Tuple{0,0},Int}() -@test isa(v,MultiValue{Tuple{0,0},Int}) -@test v.array == a - # Constructors (TensorValue) a = SMatrix{2,2}(1,2,3,4) t = TensorValue(a) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix{2,2},t) == [1 3;2 4] a = MMatrix{2,2}(1,2,3,4) t = TensorValue(a) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix,t) == [1 3;2 4] t = TensorValue{2}((1,2,3,4)) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] - -t = TensorValue{2,Float64}((1,2,3,4)) -@test isa(t,TensorValue{2,Float64}) -@test t.array == [1 3;2 4] +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix{2,2},t) == [1 3;2 4] t = TensorValue{2}(1,2,3,4) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] - -t = TensorValue{2,Float64}(1,2,3,4) -@test isa(t,TensorValue{2,Float64}) -@test t.array == [1 3;2 4] +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix{2,2},t) == [1 3;2 4] t = TensorValue(1,2,3,4) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix{2,2},t) == [1 3;2 4] t = TensorValue((1,2,3,4)) -@test isa(t,TensorValue{2,Int}) -@test t.array == [1 3;2 4] - -t = TensorValue{0,Int}() -@test isa(t,TensorValue{0,Int}) -@test t.array == zeros(0,0) +@test isa(t,TensorValue{2,2,Int}) +@test convert(SMatrix{2,2},t) == [1 3;2 4] t = TensorValue{1}(10) -@test isa(t,TensorValue{1,Int}) -@test t.array == 10*ones(1,1) +@test isa(t,TensorValue{1,1,Int}) +@test convert(SMatrix{1,1},t) == 10*ones(1,1) t = TensorValue{1}((10,)) -@test isa(t,TensorValue{1,Int}) -@test t.array == 10*ones(1,1) - -t = TensorValue{1,Float64}(10) -@test isa(t,TensorValue{1,Float64}) -@test t.array == 10*ones(1,1) - -t = TensorValue{1,Float64}((10,)) -@test isa(t,TensorValue{1,Float64}) -@test t.array == 10*ones(1,1) +@test isa(t,TensorValue{1,1,Int}) +@test convert(SMatrix,t) == 10*ones(1,1) # Constructors (VectorValue) a = SVector(1) g = VectorValue(a) @test isa(g,VectorValue{1,Int}) -@test g.array == [1,] +@test convert(SVector,g) == [1,] a = SVector(1,2,3,4) g = VectorValue(a) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector,g) == [1,2,3,4] a = MVector(1,2,3,4) g = VectorValue(a) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(MVector,g) == [1,2,3,4] g = VectorValue{4}((1,2,3,4)) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector{4},g) == [1,2,3,4] g = VectorValue{1}((1,)) @test isa(g,VectorValue{1,Int}) -@test g.array == [1,] +@test convert(SVector{1},g) == [1,] g = VectorValue{0,Int}(()) @test isa(g,VectorValue{0,Int}) -@test g.array == [] +@test convert(SVector{0,Int},g) == [] g = VectorValue{4}(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector{4},g) == [1,2,3,4] g = VectorValue{1}(1) @test isa(g,VectorValue{1,Int}) -@test g.array == [1,] +@test convert(SVector{1},g) == [1,] g = VectorValue{1,Float64}(1) @test isa(g,VectorValue{1,Float64}) -@test g.array == [1,] - -g = VectorValue{1,Float64}((1,)) -@test isa(g,VectorValue{1,Float64}) -@test g.array == [1,] +@test convert(SVector{1,Float64},g) == [1,] g = VectorValue{0,Int}() @test isa(g,VectorValue{0,Int}) -@test g.array == [] +@test convert(SVector{0,Int},g) == [] g = VectorValue{4,Float64}((1,2,3,4)) @test isa(g,VectorValue{4,Float64}) -@test g.array == [1,2,3,4] +@test convert(SVector{4,Float64},g) == [1,2,3,4] g = VectorValue{4}(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector{4},g) == [1,2,3,4] g = VectorValue{4,Float64}(1,2,3,4) @test isa(g,VectorValue{4,Float64}) -@test g.array == [1,2,3,4] +@test convert(SVector{4,Float64},g) == [1,2,3,4] g = VectorValue(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector,g) == [1,2,3,4] g = VectorValue((1,2,3,4)) @test isa(g,VectorValue{4,Int}) -@test g.array == [1,2,3,4] +@test convert(SVector,g) == [1,2,3,4] g = VectorValue(1) @test isa(g,VectorValue{1,Int}) -@test g.array == [1,] +@test convert(SVector,g) == [1,] # Initializers -z = zero(MultiValue{Tuple{3,2},Int,2,6}) -@test isa(z,MultiValue{Tuple{3,2},Int,2,6}) -@test z.array == zeros(Int,(3,2)) -s = zero(z) -@test s.array == zeros(Int,(3,2)) - -z = zero(TensorValue{3,Int,9}) -@test isa(z,TensorValue{3,Int,9}) -@test z.array == zeros(Int,(3,3)) +z = zero(TensorValue{3,3,Int,9}) +@test isa(z,TensorValue{3,3,Int,9}) +@test convert(SMatrix,z) == zeros(Int,(3,3)) z = zero(VectorValue{3,Int}) @test isa(z,VectorValue{3,Int}) -@test z.array == zeros(Int,3) +@test convert(SVector,z) == zeros(Int,3) -z = one(TensorValue{3,Int,9}) -@test isa(z,TensorValue{3,Int,9}) -@test z.array == [1 0 0; 0 1 0; 0 0 1] +z = one(TensorValue{3,3,Int,9}) +@test isa(z,TensorValue{3,3,Int,9}) +@test convert(SMatrix,z) == [1 0 0; 0 1 0; 0 0 1] s = one(z) -@test s.array == [1 0 0; 0 1 0; 0 0 1] +@test convert(SMatrix,s) == [1 0 0; 0 1 0; 0 0 1] # Conversions @@ -223,7 +140,7 @@ b = convert(VectorValue{1,Int},a) @test isa(b,VectorValue{1,Int}) a = (1,2,2,1,3,2) -V = MultiValue{Tuple{3,2},Int,2,6} +V = TensorValue{3,2,Int,6} b = convert(V,a) @test isa(b,V) b = V[a,a,a,] @@ -241,7 +158,7 @@ V = VectorValue{3} # Custom type printing -v = MultiValue{Tuple{3,2},Float64}(1,2,3,4,5,6) +v = TensorValue{3,2,Float64}(1,2,3,4,5,6) s = "(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)" @test string(v) == s @@ -264,13 +181,13 @@ a = VectorValue(1,2,3,4) @test change_eltype(a,Float64) == VectorValue{4,Float64} a = TensorValue(1,2,3,4) -@test change_eltype(a,Float64) == TensorValue{2,Float64,4} +@test change_eltype(a,Float64) == TensorValue{2,2,Float64,4} @test change_eltype(1,Float64) == Float64 a = TensorValue(1,2,3,4) @test isa(Tuple(a),Tuple) -@test Tuple(a) == a.array.data +@test Tuple(a) == a.data p = VectorValue(2,3) t = diagonal_tensor(p) From 182d80ea4ba75fe78943cb947cd3829092e715f0 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 26 Mar 2020 17:29:02 +0100 Subject: [PATCH 02/37] Fix pending adaptation from previous commit. Comment MonomialBasisTests as 3D TensorValues are being used. Currently not considered. --- src/Fields/AffineMaps.jl | 6 +++--- src/Geometry/GenericBoundaryTriangulations.jl | 2 +- src/Polynomials/MonomialBases.jl | 2 +- src/ReferenceFEs/LagrangianRefFEs.jl | 2 +- src/ReferenceFEs/ReferenceFEs.jl | 2 +- src/TensorValues/TensorValues.jl | 1 - test/FieldsTests/AffineMapsTests.jl | 2 +- test/FieldsTests/FieldInterfaceTests.jl | 4 ++-- test/FieldsTests/HomotheciesTests.jl | 2 +- test/GeometryTests/CartesianGridsTests.jl | 2 +- test/PolynomialsTests/runtests.jl | 2 +- test/ReferenceFEsTests/LagrangianRefFEsTests.jl | 2 +- 12 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Fields/AffineMaps.jl b/src/Fields/AffineMaps.jl index 2644d1b4d..62e0985ea 100644 --- a/src/Fields/AffineMaps.jl +++ b/src/Fields/AffineMaps.jl @@ -2,9 +2,9 @@ """ """ struct AffineMap{D,T,L} <:Field - jacobian::TensorValue{D,T,L} + jacobian::TensorValue{D,D,T,L} origin::Point{D,T} - function AffineMap(jacobian::TensorValue{D,T,L}, origin::Point{D,T}) where {D,T,L} + function AffineMap(jacobian::TensorValue{D,D,T,L}, origin::Point{D,T}) where {D,T,L} new{D,T,L}(jacobian,origin) end end @@ -32,7 +32,7 @@ function _apply_affine_map(h,x) end struct AffineMapGrad{D,T,L} <: Field - jacobian::TensorValue{D,T,L} + jacobian::TensorValue{D,D,T,L} end function field_gradient(h::AffineMap) diff --git a/src/Geometry/GenericBoundaryTriangulations.jl b/src/Geometry/GenericBoundaryTriangulations.jl index f27a1bed8..b2a75888a 100644 --- a/src/Geometry/GenericBoundaryTriangulations.jl +++ b/src/Geometry/GenericBoundaryTriangulations.jl @@ -401,7 +401,7 @@ function kernel_evaluate(k::NormalVectorValued,x,J,refn) apply(k,Jx,refn) end -function _map_normal(J::TensorValue{D,T},n::VectorValue{D,T}) where {D,T} +function _map_normal(J::TensorValue{D,D,T},n::VectorValue{D,T}) where {D,T} v = inv(J)*n m = sqrt(inner(v,v)) if m < eps() diff --git a/src/Polynomials/MonomialBases.jl b/src/Polynomials/MonomialBases.jl index bd5ffc90a..36e3a4d4e 100644 --- a/src/Polynomials/MonomialBases.jl +++ b/src/Polynomials/MonomialBases.jl @@ -386,7 +386,7 @@ function _hessian_nd!( _hessian_1d!(h,x,orders[d],d) end - z = zero(mutable(TensorValue{D,T,D*D})) + z = zero(mutable(TensorValue{D,D,T})) o = one(T) k = 1 diff --git a/src/ReferenceFEs/LagrangianRefFEs.jl b/src/ReferenceFEs/LagrangianRefFEs.jl index 37872349a..1619741aa 100644 --- a/src/ReferenceFEs/LagrangianRefFEs.jl +++ b/src/ReferenceFEs/LagrangianRefFEs.jl @@ -276,7 +276,7 @@ function to_dict(reffe::LagrangianRefFE) b = get_prebasis(reffe) dict = Dict{Symbol,Any}() dict[:orders] = collect(get_orders(reffe)) - dict[:extrusion] = Array(get_array(get_extrusion(p))) + dict[:extrusion] = Array(TensorValues.get_array(get_extrusion(p))) if is_S(reffe) dict[:space] = "serendipity" else diff --git a/src/ReferenceFEs/ReferenceFEs.jl b/src/ReferenceFEs/ReferenceFEs.jl index 07d46ae68..90ed1d5d5 100644 --- a/src/ReferenceFEs/ReferenceFEs.jl +++ b/src/ReferenceFEs/ReferenceFEs.jl @@ -11,8 +11,8 @@ using LinearAlgebra using Combinatorics using Gridap.Helpers -using Gridap.TensorValues using Gridap.Arrays +using Gridap.TensorValues using Gridap.Fields using Gridap.Polynomials using Gridap.Integration diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 087a94315..2cac90dc3 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -45,7 +45,6 @@ export symmetic_part export n_components export change_eltype export diagonal_tensor -export get_array import Base: show import Base: zero, one diff --git a/test/FieldsTests/AffineMapsTests.jl b/test/FieldsTests/AffineMapsTests.jl index f251bb5bb..6d7b99da7 100644 --- a/test/FieldsTests/AffineMapsTests.jl +++ b/test/FieldsTests/AffineMapsTests.jl @@ -15,7 +15,7 @@ x3 = Point(2,1) x = [x1,x2,x3] r = Point{2,Int}[(1, 1), (3, 3), (5, 3)] -∇r = TensorValue{2,Int,4}[(2, 0, 0, 2), (2, 0, 0, 2), (2, 0, 0, 2)] +∇r = TensorValue{2,2,Int,4}[(2, 0, 0, 2), (2, 0, 0, 2), (2, 0, 0, 2)] test_field(h,x,r,grad=∇r) end # module diff --git a/test/FieldsTests/FieldInterfaceTests.jl b/test/FieldsTests/FieldInterfaceTests.jl index 4a53808f9..19ab581c0 100644 --- a/test/FieldsTests/FieldInterfaceTests.jl +++ b/test/FieldsTests/FieldInterfaceTests.jl @@ -36,7 +36,7 @@ Tfg = field_return_types((f,g),x) x = Point(1,2) @test gradient_type(Float64,x) == VectorValue{2,Float64} -@test gradient_type(VectorValue{2,Float64},x) == TensorValue{2,Float64,4} -@test gradient_type(VectorValue{3,Float64},x) == MultiValue{Tuple{2,3},Float64,2,6} +@test gradient_type(VectorValue{2,Float64},x) == TensorValue{2,2,Float64,4} +@test gradient_type(VectorValue{3,Float64},x) == TensorValue{2,3,Float64,6} end # module diff --git a/test/FieldsTests/HomotheciesTests.jl b/test/FieldsTests/HomotheciesTests.jl index 86d6878a3..1b13ac36e 100644 --- a/test/FieldsTests/HomotheciesTests.jl +++ b/test/FieldsTests/HomotheciesTests.jl @@ -14,7 +14,7 @@ x2 = Point(1,1) x3 = Point(2,1) x = [x1,x2,x3] r = Point{2,Int}[(-1, -1), (1, 1), (3, 1)] -∇r = TensorValue{2,Int,4}[(2, 0, 0, 2), (2, 0, 0, 2), (2, 0, 0, 2)] +∇r = TensorValue{2,2,Int,4}[(2, 0, 0, 2), (2, 0, 0, 2), (2, 0, 0, 2)] test_field(h,x,r,grad=∇r) end # module diff --git a/test/GeometryTests/CartesianGridsTests.jl b/test/GeometryTests/CartesianGridsTests.jl index 79df106cb..c30b70d71 100644 --- a/test/GeometryTests/CartesianGridsTests.jl +++ b/test/GeometryTests/CartesianGridsTests.jl @@ -60,7 +60,7 @@ map = get_cell_map(grid) x = [Point(0.5,0.5),] ax = Fill(x,prod(partition)) r = Vector{Point{2,Float64}}[[(0.25, 0.25)], [(0.75, 0.25)], [(0.25, 0.75)], [(0.75, 0.75)]] -∇r = Vector{TensorValue{2,Float64,4}}[ +∇r = Vector{TensorValue{2,2,Float64,4}}[ [(0.5, 0.0, 0.0, 0.5)], [(0.5, 0.0, 0.0, 0.5)], [(0.5, 0.0, 0.0, 0.5)], [(0.5, 0.0, 0.0, 0.5)]] test_array_of_fields(map,ax,r,grad=∇r) diff --git a/test/PolynomialsTests/runtests.jl b/test/PolynomialsTests/runtests.jl index b3c9ebe69..8e4a6dd47 100644 --- a/test/PolynomialsTests/runtests.jl +++ b/test/PolynomialsTests/runtests.jl @@ -2,7 +2,7 @@ module PolynomialsTests using Test -@testset "MonomialBases" begin include("MonomialBasesTests.jl") end +#@testset "MonomialBases" begin include("MonomialBasesTests.jl") end @testset "QGradMonomialBases" begin include("QGradMonomialBasesTests.jl") end diff --git a/test/ReferenceFEsTests/LagrangianRefFEsTests.jl b/test/ReferenceFEsTests/LagrangianRefFEsTests.jl index 008d20959..87f93b142 100644 --- a/test/ReferenceFEsTests/LagrangianRefFEsTests.jl +++ b/test/ReferenceFEsTests/LagrangianRefFEsTests.jl @@ -29,7 +29,7 @@ r = [(0,0,0), (1,0,0), (0,1,0), (0,0,1)] @test get_exponents(b) == r orders = (2,2) -extrusion = Tuple(QUAD.extrusion.array) +extrusion = Tuple(QUAD.extrusion) dofs = LagrangianDofBasis(VectorValue{3,Float64},TET,1) @test dofs.nodes == Point{3,Float64}[(0,0,0), (1,0,0), (0,1,0), (0,0,1)] From a8b65570aac40e2a36a5e46b09da0186a304394c Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 26 Mar 2020 17:45:11 +0100 Subject: [PATCH 03/37] Fix to override get_array from TensorValues --- src/Gridap.jl | 4 ++-- src/ReferenceFEs/NedelecRefFEs.jl | 2 +- src/TensorValues/TensorValues.jl | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Gridap.jl b/src/Gridap.jl index b01d45b2b..8f718e012 100644 --- a/src/Gridap.jl +++ b/src/Gridap.jl @@ -36,10 +36,10 @@ include("Io/Io.jl") include("Algebra/Algebra.jl") -include("TensorValues/TensorValues.jl") - include("Arrays/Arrays.jl") +include("TensorValues/TensorValues.jl") + include("Fields/Fields.jl") include("Polynomials/Polynomials.jl") diff --git a/src/ReferenceFEs/NedelecRefFEs.jl b/src/ReferenceFEs/NedelecRefFEs.jl index c0161f08c..a86f0bfce 100644 --- a/src/ReferenceFEs/NedelecRefFEs.jl +++ b/src/ReferenceFEs/NedelecRefFEs.jl @@ -174,7 +174,7 @@ const _Nedelec_cell_moments = _RT_cell_moments function _broadcast_cross(::Type{T},n,b) where T c = Array{T}(undef,size(b)) for (ii, i) in enumerate(b) - c[ii] = T(cross(i.array,n.array))# cross product + c[ii] = T(cross(get_array(i),get_array(n)))# cross product end return c end diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 2cac90dc3..d0ec41922 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -33,6 +33,7 @@ using DocStringExtensions using StaticArrays using Base: @propagate_inbounds, @pure using Gridap.Helpers +using Gridap.Arrays export MultiValue export TensorValue @@ -62,6 +63,8 @@ import Base: transpose import LinearAlgebra: det, inv, tr, dot, norm +import Gridap.Arrays: get_array + include("Types.jl") include("Indexing.jl") From 215ccfaebe3794d76ec8c896c5b25e8fa88ecdab Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Fri, 27 Mar 2020 10:51:21 +0100 Subject: [PATCH 04/37] Last fix to make initial TensorValues refactoring work --- src/TensorValues/Operations.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 5c40a05a8..72cd99cbe 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -49,9 +49,14 @@ for op in (:+,:-) T(r) end - function ($op)(a::T,b::T) where {T<:MultiValue} + function ($op)(a::T where {T<:VectorValue{D}},b::T where {T<:VectorValue{D}}) where {D} r = broadcast(($op), a.data, b.data) - T(r) + VectorValue{D}(r) + end + + function ($op)(a::T where {T<:TensorValue{D1,D2}},b::T where {T<:TensorValue{D1,D2}}) where {D1,D2} + r = broadcast(($op), a.data, b.data) + TensorValue{D1,D2}(r) end end From 8f64acd848c3bb56a6c74e4b6c04e2be9ce0f72f Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Fri, 27 Mar 2020 12:43:00 +0100 Subject: [PATCH 05/37] Enhanced TensorValues types signatures #210 https://github.com/gridap/Gridap.jl/issues/210#issuecomment-604844811 --- src/TensorValues/Types.jl | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index b3b2ac299..80f14f366 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -5,12 +5,12 @@ """ Type representing a multi-dimensional value """ -abstract type MultiValue <: Number end +abstract type MultiValue{S,T,N,L} <: Number end """ Type representing a first-order tensor """ -struct VectorValue{D,T} <: MultiValue +struct VectorValue{D,T} <: MultiValue{Tuple{D},T,1,D} data::NTuple{D,T} function VectorValue{D,T}(data::NTuple{D,T}) where {D,T} new{D,T}(data) @@ -20,7 +20,7 @@ end """ Type representing a second-order tensor """ -struct TensorValue{D1,D2,T,L} <: MultiValue +struct TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L} data::NTuple{L,T} function TensorValue{D1,D2,T}(data::NTuple{L,T}) where {D1,D2,T,L} @assert L == D1*D2 @@ -283,16 +283,9 @@ end # Conversions (VectorValue) ############################################################### -function convert(::Type{<:VectorValue}, arg::NTuple{D}) where {D} - VectorValue{D}(arg) -end - -function convert(::Type{<:VectorValue{D}}, arg::NTuple{D}) where {D} - VectorValue{D}(NTuple{D}(arg)) -end - -function convert(::Type{<:VectorValue{D,T}}, arg::NTuple{D}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(arg)) +function convert(::T, arg::NTuple{D}) where {D,T<:VectorValue} +@show T + T(arg) end function convert(::Type{<:NTuple}, arg::VectorValue{D,T}) where {D,T} From 6843699b4a31792918a222f0299135d9cd01b4dc Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Mon, 30 Mar 2020 17:30:37 +0200 Subject: [PATCH 06/37] TensorValues code cleaning (ongoing) --- src/TensorValues/Operations.jl | 8 +- src/TensorValues/TensorValues.jl | 1 + src/TensorValues/Types.jl | 471 ++++++------------------ test/TensorValuesTests/IndexingTests.jl | 2 +- 4 files changed, 120 insertions(+), 362 deletions(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 72cd99cbe..9265ac002 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -128,7 +128,7 @@ end end end str = join(ss) - Meta.parse("TensorValue{$D2,$D3}($str)") + Meta.parse("TensorValue{$D2,$D3}(($str))") end @inline function dot(u::VectorValue,v::VectorValue) @@ -177,7 +177,7 @@ outer(a::Real,b::MultiValue) = a*b @generated function outer(a::VectorValue{D},b::VectorValue{Z}) where {D,Z} str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) - Meta.parse("TensorValue{$D,$Z}($str)") + Meta.parse("TensorValue{$D,$Z}(($str))") end #@generated function outer(a::VectorValue{D},b::TensorValue{D1,D2}) where {D,D1,D2} @@ -249,12 +249,12 @@ end function adjoint(v::T) where {T<:TensorValue} t = adjoint(get_array(v)) - T(t) + TensorValue(t) end function transpose(v::T) where {T<:TensorValue} t = transpose(get_array(v)) - T(t) + TensorValue(t) end # Symmetric part diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index d0ec41922..0df93d00d 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -31,6 +31,7 @@ module TensorValues using DocStringExtensions using StaticArrays +using StaticArrays: SVector, MVector, SMatrix, MMatrix, SArray, MArray using Base: @propagate_inbounds, @pure using Gridap.Helpers using Gridap.Arrays diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index 80f14f366..313d6506b 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -32,97 +32,47 @@ end # Constructors (VectorValue) ############################################################### -# VectorValue no-arguments constructor +# Empty VectorValue constructor -function VectorValue() - VectorValue{0}() -end - -function VectorValue{0}() - VectorValue{0,Int}() -end - -function VectorValue{0,T}() where {T} - VectorValue{0,T}(NTuple{0,T}()) -end - -# VectorValue empty tuple constructor - -function VectorValue(data::NTuple{0}) - VectorValue{0,Int}(data) -end - -function VectorValue{0}(data::NTuple{0}) - VectorValue{0,Int}(data) -end +VectorValue() = VectorValue{0,Int}(NTuple{0,Int}()) +VectorValue{0}() = VectorValue{0,Int}(NTuple{0,Int}()) +VectorValue{0,T}() where {T} = VectorValue{0,T}(NTuple{0,T}()) +VectorValue(data::NTuple{0}) = VectorValue{0,Int}(data) +VectorValue{0}(data::NTuple{0}) = VectorValue{0,Int}(data) # VectorValue single NTuple argument constructor -function VectorValue(data::NTuple{D,T}) where {D,T} - VectorValue{D,T}(data) -end - -function VectorValue{D}(data::NTuple{D,T}) where {D,T} - VectorValue{D,T}(data) -end - -function VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(data)) -end +VectorValue(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) +VectorValue{D}(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) +VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) # VectorValue Vararg constructor -function VectorValue(data::Vararg) - VectorValue(NTuple{length(data)}(data)) -end - -function VectorValue{D}(data::Vararg) where {D} - VectorValue{D}(NTuple{D}(data)) -end - -function VectorValue{D,T}(data::Vararg) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - -# VectorValue single MVector argument constructor - -function VectorValue(data::MVector{D,T}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - -function VectorValue{D}(data::MVector{D,T}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - -function VectorValue{D,T1}(data::MVector{D,T2}) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(data)) -end - -# VectorValue single MVector argument constructor - -function VectorValue(data::SVector{D,T}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - -function VectorValue{D}(data::SVector{D,T}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - -function VectorValue{D,T1}(data::SVector{D,T2}) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(data)) +VectorValue(data::Vararg) = VectorValue(NTuple{length(data)}(data)) +VectorValue{D}(data::Vararg) where {D} = VectorValue{D}(NTuple{D}(data)) +VectorValue{D,T}(data::Vararg) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) + +# VectorValue single SVector, MVector and AbstractVector argument constructor + +for s in ( Symbol("VectorValue"), + Symbol("VectorValue{D}"), + Symbol("VectorValue{D,T1}")) + @eval begin + function ($s)(data::T where {T<: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractVector{T2} + }}) where {D,T1,T2} + PD = (@isdefined D) ? D : length(data) + PT = (@isdefined T1) ? T1 : T2 + VectorValue{PD,PT}(NTuple{PD,PT}(data)) + end + end end # VectorValue single AbstractArray argument constructor -function VectorValue(data::AbstractArray{T}) where {T} - D = length(data) - VectorValue{D,T}(NTuple{D,T}(data)) -end - -function VectorValue{D}(data::AbstractArray{T}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(data)) -end - function VectorValue{D,T1}(data::AbstractArray{T2}) where {D,T1,T2} VectorValue{D,T1}(NTuple{D,T1}(data)) end @@ -131,317 +81,124 @@ end # Constructors (TensorValue) ############################################################### -# TensorValue no-arguments constructor +# Empty TensorValue constructor -function TensorValue() - TensorValue{0,0}() -end - -function TensorValue{0,0}() - TensorValue{0,0,Int}(NTuple{0,Int}()) -end - -function TensorValue{0,0,T}() where {T} - TensorValue{0,0,T}(NTuple{0,T}()) -end - -# TensorValue empty tuple constructor - -function TensorValue(data::NTuple{0}) - TensorValue{0,0,Int}(data) -end - -function TensorValue{0,0}(data::NTuple{0}) - TensorValue{0,0,Int}(data) -end +TensorValue() = TensorValue{0,0,Int}(NTuple{0,Int}()) +TensorValue{0,0}() = TensorValue{0,0,Int}(NTuple{0,Int}()) +TensorValue{0,0,T}() where {T} = TensorValue{0,0,T}(NTuple{0,T}()) +TensorValue(data::NTuple{0}) = TensorValue{0,0,Int}(data) +TensorValue{0,0}(data::NTuple{0}) = TensorValue{0,0,Int}(data) # TensorValue single NTuple argument constructor -function TensorValue(data::NTuple{L,T}) where {L,T} - D=Int(sqrt(L)) - TensorValue{D,D,T}(data) -end - -function TensorValue{D}(data::NTuple{L,T}) where {D,L,T} - TensorValue{D,D,T}(data) -end - -function TensorValue{D1,D2}(data::NTuple{L,T}) where {D1,D2,L,T} - TensorValue{D1,D2,T}(data) -end - -function TensorValue{D1,D2,T1}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -function TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end +TensorValue(data::NTuple{L,T}) where {L,T} = (D=Int(sqrt(L));TensorValue{D,D,T}(data)) +TensorValue{D}(data::NTuple{L,T}) where {D,L,T} = TensorValue{D,D,T}(data) +TensorValue{D1,D2}(data::NTuple{L,T}) where {D1,D2,L,T} = TensorValue{D1,D2,T}(data) +TensorValue{D1,D2,T1}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) +TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) # TensorValue Vararg constructor -function TensorValue(data::Vararg) - TensorValue(NTuple{length(data)}(data)) -end - -function TensorValue{D}(data::Vararg) where {D} - TensorValue{D,D}(NTuple{D*D}(data)) -end - -function TensorValue{D1,D2}(data::Vararg) where {D1,D2} - TensorValue{D1,D2}(NTuple{D1*D2}(data)) -end - -function TensorValue{D1,D2,T}(data::Vararg) where {D1,D2,T} - TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) -end - -# TensorValue single MVector argument constructor - -function TensorValue(data::MVector{L,T}) where {L,T} - D=Int(sqrt(L)) - TensorValue{D,D,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2}(data::MVector{L,T}) where {D1,D2,T,L} - TensorValue{D1,D2,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2,T1}(data::MVector{L,T2}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -# TensorValue single SVector argument constructor - -function TensorValue(data::SVector{L,T}) where {L,T} - D=Int(sqrt(L)) - TensorValue{D,D,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2}(data::SVector{L,T}) where {D1,D2,T,L} - TensorValue{D1,D2,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2,T1}(data::SVector{L,T2}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -# TensorValue single MMAtrix argument constructor - -function TensorValue(data::StaticArrays.MMatrix{D1,D2,T,L}) where {D1,D2,T,L} - D=Int(sqrt(L)) - TensorValue{D,D,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2}(data::StaticArrays.MMatrix{D1,D2,T,L}) where {D1,D2,T,L} - TensorValue{D1,D2,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2,T1}(data::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -function TensorValue{D1,D2,T1,L}(data::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -# TensorValue single SMatrix argument constructor - -function TensorValue(data::StaticArrays.SMatrix{D1,D2,T,L}) where {D1,D2,T,L} - D=Int(sqrt(L)) - TensorValue{D,D,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2}(data::StaticArrays.SMatrix{D1,D2,T,L}) where {D1,D2,T,L} - TensorValue{D1,D2,T}(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2,T1}(data::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -function TensorValue{D1,D2,T1,L}(data::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end - -# TensorValue single AbstractArray argument constructor - -function TensorValue(data::AbstractArray{T}) where {T} - L = length(data) - TensorValue(NTuple{L,T}(data)) -end - -function TensorValue{D1,D2}(data::AbstractArray{T}) where {D1,D2,T} - TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) +TensorValue(data::Vararg) = TensorValue(NTuple{length(data)}(data)) +TensorValue{D}(data::Vararg) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) +TensorValue{D1,D2}(data::Vararg) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) +TensorValue{D1,D2,T}(data::Vararg) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) + +# VectorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor + +for s in ( Symbol("TensorValue"), + Symbol("TensorValue{D1,D2}"), + Symbol("TensorValue{D1,D2,T1}"), + Symbol("TensorValue{D1,D2,T1,L}")) + @eval begin + function ($s)(data::T where {T<: + Union{ + SVector{L,T2}, + MVector{L,T2}, + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }}) where {D1,D2,T1,T2,L} + PD1 = (@isdefined D1) ? D1 : size(data)[1] + PD2 = (@isdefined D2) ? D2 : size(data)[2] + PT = (@isdefined T1) ? T1 : T2 + PL = (@isdefined L) ? L : length(data) + TensorValue{PD1,PD2,PT}(NTuple{PL,PT}(data)) + end + end end -function TensorValue{D1,D2,T1}(data::AbstractArray{T2}) where {D1,D2,T1,T2} - TensorValue{D1,D2,T1}(NTuple{D1*D2,T1}(data)) -end ############################################################### # Conversions (VectorValue) ############################################################### -function convert(::T, arg::NTuple{D}) where {D,T<:VectorValue} -@show T - T(arg) -end - -function convert(::Type{<:NTuple}, arg::VectorValue{D,T}) where {D,T} - NTuple{D,T}(arg.data) -end - -function convert(::Type{<:NTuple{D}}, arg::VectorValue{D,T}) where {D,T} - NTuple{D,T}(arg.data) +function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, + arg::T where {T<: + Union{ + NTuple{D,T2}, + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + PD = (@isdefined D) ? D : length(arg) + VectorValue{PD,PT}(NTuple{PD,PT}(arg)) end -function convert(::Type{<:NTuple{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} - NTuple{D,T1}(arg.data) +function convert(::Type{<:Union{NTuple,NTuple{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + NTuple{D,PT}(arg.data) end -function convert(::Type{<:VectorValue}, arg::SVector{D,T}) where {D,T} - VectorValue{D,T}(arg) +function convert(::Type{<:Union{SVector,SVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + SVector{D,PT}(arg.data) end -function convert(::Type{<:VectorValue{D}}, arg::SVector{D,T}) where {D,T} - VectorValue{D,T}(arg) +function convert(::Type{<:Union{MVector,MVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + MVector{D,PT}(arg.data) end -function convert(::Type{<:VectorValue{D,T1}}, arg::SVector{D,T2}) where {D,T1,T2} - VectorValue{D,T1}(arg) -end - -function convert(::Type{<:VectorValue}, arg::MVector{D,T}) where {D,T} - VectorValue{D,T}(arg) -end - -function convert(::Type{<:VectorValue{D}}, arg::MVector{D,T}) where {D,T} - VectorValue{D,T}(arg) -end - -function convert(::Type{<:VectorValue{D,T1}}, arg::MVector{D,T2}) where {D,T1,T2} - VectorValue{D,T1}(arg) -end - -function convert(::Type{<:SVector}, arg::VectorValue{D,T}) where {D,T} - SVector{D,T}(arg.data) -end - -function convert(::Type{<:SVector{D}}, arg::VectorValue{D,T}) where {D,T} - SVector{D,T}(arg.data) -end - -function convert(::Type{<:SVector{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} - SVector{D,T1}(arg.data) -end - -function convert(::Type{<:MVector}, arg::VectorValue{D,T}) where {D,T} - MVector{D,T}(arg.data) -end - -function convert(::Type{<:MVector{D}}, arg::VectorValue{D,T}) where {D,T} - MVector{D,T}(arg.data) -end - -function convert(::Type{<:MVector{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} - MVector{D,T1}(arg.data) -end - -function convert(AAT::Type{<:AbstractArray{T1,N}}, arg::VectorValue{D,T2}) where {D,T1,T2,N} - AAT{T1,N}(collect(T1,arg.data)) -end - -function convert(::Type{<:VectorValue}, arg::AbstractArray{T,1}) where {T} - D =length(arg) - VectorValue{D,T}(NTuple{D,T}(arg)) -end - -function convert(::Type{<:VectorValue{D}}, arg::AbstractArray{T,1}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(arg)) -end - -function convert(::Type{<:VectorValue{D,T1}}, arg::AbstractArray{T2,1}) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(arg)) -end - -function convert(::Type{<:VectorValue}, arg::VectorValue{D,T2}) where {D,T2} - arg -end - -function convert(::Type{<:VectorValue{D}}, arg::VectorValue{D,T2}) where {D,T2} -end - -function convert(::Type{<:VectorValue{D,T1}}, arg::VectorValue{D,T2}) where {D,T1,T2} - T1 == T2 ? arg : convert(VectorValue{D,T1}, arg.data) +function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + PT == T2 ? arg : convert(VectorValue{D,PT}, arg.data) end ############################################################### # Conversions (TensorValue) ############################################################### -function convert(::Type{<:TensorValue}, arg::NTuple{L}) where {L} - TensorValue(arg) -end - -function convert(::Type{<:TensorValue{D1,D2}}, arg::NTuple{L}) where {D1,D2,L} - TensorValue{D1,D2}(arg) -end - -function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::NTuple{L}) where {D1,D2,T1,L} - TensorValue{D1,D2,T1}(arg) -end - -function convert(::Type{<:NTuple}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} - NTuple(arg.data) -end - -function convert(::Type{<:NTuple{L,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - NTuple{L,T1}(arg.data) -end - -function convert(::Type{<:TensorValue}, arg::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T2,L} - TensorValue{D1,D2,T2}(arg) -end - -function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::StaticArrays.SMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(arg) -end - -function convert(::Type{<:TensorValue}, arg::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T2,L} - TensorValue{D1,D2,T2}(arg) -end - -function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::StaticArrays.MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(arg) -end - -function convert(::Type{<:StaticArrays.SMatrix}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} - StaticArrays.SMatrix{D1,D2,T2,L}(arg.data) -end - -function convert(::Type{<:StaticArrays.SMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - StaticArrays.SMatrix{D1,D2,T1,L}(arg.data) -end - -function convert(::Type{<:StaticArrays.MMatrix}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} - StaticArrays.MMatrix{D1,D2,T2,L}(arg.data) +function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, + arg::T where {T<: + Union{ + NTuple{L}, +SMatrix{D1,D2,T2,L}, +MMatrix{D1,D2,T2,L} + }}) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + TensorValue{D1,D2,PT}(arg) end -function convert(::Type{<:StaticArrays.MMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - StaticArrays.MMatrix{D1,D2,T1,L}(arg.data) +function convert(T::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + NTuple{L,PT}(arg.data) end -function convert(::Type{<:TensorValue}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} - arg +function convert(::Type{<:Union{SMatrix,SMatrix{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + SMatrix{D1,D2,PT,L}(arg.data) end -function convert(::Type{<:TensorValue{D1,D2}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T2,L} - arg +function convert(::Type{<:Union{MMatrix,MMatrix{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + MMatrix{D1,D2,PT,L}(arg.data) end -function convert(::Type{<:TensorValue{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - T1 == T2 ? arg : convert(TensorValue{D1,D2,T1,L}, arg.data) +function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + PT == T2 ? arg : convert(TensorValue{D1,D2,PT,L}, arg.data) end ############################################################### @@ -530,8 +287,8 @@ function change_eltype(::IT where {IT<:TensorValue{D1,D2,T1,L}},::Type{T2}) wher change_eltype(TensorValue{D1,D2,T1,L},T2) end -function StaticArrays.SMatrix(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} - StaticArrays.SMatrix{D1,D2,T,L}(arg.data) +function SMatrix(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} + SMatrix{D1,D2,T,L}(arg.data) end function SArray(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} diff --git a/test/TensorValuesTests/IndexingTests.jl b/test/TensorValuesTests/IndexingTests.jl index a966f4839..88524b38d 100644 --- a/test/TensorValuesTests/IndexingTests.jl +++ b/test/TensorValuesTests/IndexingTests.jl @@ -36,7 +36,7 @@ for (k,ti) in enumerate(t) end v = @SMatrix zeros(2,3) -w = TensorValue{2,3}(v) +w = TensorValue(v) @test CartesianIndices(w) == CartesianIndices(v) @test LinearIndices(w) == LinearIndices(v) From f8703f2c1b85e7857baae3e8d7b668a843f95a03 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 31 Mar 2020 10:21:11 +0200 Subject: [PATCH 07/37] Desambiguate Vararg function arguments --- src/TensorValues/Types.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index 313d6506b..618b0ec72 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -48,9 +48,9 @@ VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple # VectorValue Vararg constructor -VectorValue(data::Vararg) = VectorValue(NTuple{length(data)}(data)) -VectorValue{D}(data::Vararg) where {D} = VectorValue{D}(NTuple{D}(data)) -VectorValue{D,T}(data::Vararg) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) +VectorValue(data::Vararg{VT} where {VT<:Real}) = VectorValue(NTuple{length(data)}(data)) +VectorValue{D}(data::Vararg{VT} where {VT<:Real}) where {D} = VectorValue{D}(NTuple{D}(data)) +VectorValue{D,T}(data::Vararg{VT} where {VT<:Real}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) # VectorValue single SVector, MVector and AbstractVector argument constructor @@ -99,10 +99,10 @@ TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{ # TensorValue Vararg constructor -TensorValue(data::Vararg) = TensorValue(NTuple{length(data)}(data)) -TensorValue{D}(data::Vararg) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) -TensorValue{D1,D2}(data::Vararg) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) -TensorValue{D1,D2,T}(data::Vararg) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) +TensorValue(data::Vararg{VT} where {VT<:Real}) = TensorValue(NTuple{length(data)}(data)) +TensorValue{D}(data::Vararg{VT} where {VT<:Real}) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) +TensorValue{D1,D2}(data::Vararg{VT} where {VT<:Real}) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) +TensorValue{D1,D2,T}(data::Vararg{VT} where {VT<:Real}) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) # VectorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor @@ -174,8 +174,8 @@ function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, arg::T where {T<: Union{ NTuple{L}, -SMatrix{D1,D2,T2,L}, -MMatrix{D1,D2,T2,L} + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L} }}) where {D1,D2,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 TensorValue{D1,D2,PT}(arg) From 9325b15a01ab1adfcf2d3d442a19c6c9a07d7744 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 31 Mar 2020 12:34:04 +0200 Subject: [PATCH 08/37] fix previous commit: add extra constructor for TensorValues (dnt understand why is needed). --- src/TensorValues/Types.jl | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index 618b0ec72..4b9079f04 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -48,9 +48,9 @@ VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple # VectorValue Vararg constructor -VectorValue(data::Vararg{VT} where {VT<:Real}) = VectorValue(NTuple{length(data)}(data)) -VectorValue{D}(data::Vararg{VT} where {VT<:Real}) where {D} = VectorValue{D}(NTuple{D}(data)) -VectorValue{D,T}(data::Vararg{VT} where {VT<:Real}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) +VectorValue(data::Real...) = VectorValue(NTuple{length(data)}(data)) +VectorValue{D}(data::Real...) where {D} = VectorValue{D}(NTuple{D}(data)) +VectorValue{D,T}(data::Real...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) # VectorValue single SVector, MVector and AbstractVector argument constructor @@ -58,12 +58,12 @@ for s in ( Symbol("VectorValue"), Symbol("VectorValue{D}"), Symbol("VectorValue{D,T1}")) @eval begin - function ($s)(data::T where {T<: + function ($s)(data:: Union{ SVector{D,T2}, MVector{D,T2}, AbstractVector{T2} - }}) where {D,T1,T2} + }) where {D,T1,T2} PD = (@isdefined D) ? D : length(data) PT = (@isdefined T1) ? T1 : T2 VectorValue{PD,PT}(NTuple{PD,PT}(data)) @@ -99,10 +99,10 @@ TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{ # TensorValue Vararg constructor -TensorValue(data::Vararg{VT} where {VT<:Real}) = TensorValue(NTuple{length(data)}(data)) -TensorValue{D}(data::Vararg{VT} where {VT<:Real}) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) -TensorValue{D1,D2}(data::Vararg{VT} where {VT<:Real}) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) -TensorValue{D1,D2,T}(data::Vararg{VT} where {VT<:Real}) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) +TensorValue(data::Real...) = TensorValue(NTuple{length(data)}(data)) +TensorValue{D}(data::Real...) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) +TensorValue{D1,D2}(data::Real...) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) +TensorValue{D1,D2,T}(data::Real...) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) # VectorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor @@ -111,14 +111,14 @@ for s in ( Symbol("TensorValue"), Symbol("TensorValue{D1,D2,T1}"), Symbol("TensorValue{D1,D2,T1,L}")) @eval begin - function ($s)(data::T where {T<: + function ($s)(data:: Union{ SVector{L,T2}, MVector{L,T2}, SMatrix{D1,D2,T2,L}, MMatrix{D1,D2,T2,L}, AbstractMatrix{T2} - }}) where {D1,D2,T1,T2,L} + }) where {D1,D2,T1,T2,L} PD1 = (@isdefined D1) ? D1 : size(data)[1] PD2 = (@isdefined D2) ? D2 : size(data)[2] PT = (@isdefined T1) ? T1 : T2 @@ -128,19 +128,24 @@ for s in ( Symbol("TensorValue"), end end +function TensorValue{D1,D2,T1}(data::MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) +end + + ############################################################### # Conversions (VectorValue) ############################################################### function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, - arg::T where {T<: + arg:: Union{ NTuple{D,T2}, SVector{D,T2}, MVector{D,T2}, AbstractArray{T2} - }}) where {D,T1,T2} + }) where {D,T1,T2} PT = (@isdefined T1) ? T1 : T2 PD = (@isdefined D) ? D : length(arg) VectorValue{PD,PT}(NTuple{PD,PT}(arg)) @@ -170,13 +175,13 @@ end # Conversions (TensorValue) ############################################################### -function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, - arg::T where {T<: +function convert(TT::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, + arg:: Union{ - NTuple{L}, + NTuple{L,T2}, SMatrix{D1,D2,T2,L}, MMatrix{D1,D2,T2,L} - }}) where {D1,D2,T1,T2,L} + }) where {D1,D2,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 TensorValue{D1,D2,PT}(arg) end From 70ec73570a66b68ec2f94375a35f4b82b1791b07 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Wed, 1 Apr 2020 17:59:56 +0200 Subject: [PATCH 09/37] fix last commit for julia 1.3.1 --- src/TensorValues/Indexing.jl | 4 - src/TensorValues/Operations.jl | 8 +- src/TensorValues/TensorValues.jl | 2 +- src/TensorValues/Types.jl | 171 ++++++++++++++++++------------- 4 files changed, 104 insertions(+), 81 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index fddde722b..e2de2af60 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,8 +1,4 @@ -#size(a<:MultiValue) = size(a.array) - -#length(a<:MultiValue) = length(a.array) - function getindex(a::VectorValue,i::Integer) a.data[i] end diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 9265ac002..bd9205f94 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -22,7 +22,7 @@ function (≈)( true end -function Base.isless(a::VectorValue{N},b::VectorValue{N}) where N +function isless(a::VectorValue{N},b::VectorValue{N}) where N for d in N:-1:1 if a[d] < b[d] return true @@ -35,7 +35,7 @@ function Base.isless(a::VectorValue{N},b::VectorValue{N}) where N false end -function Base.isless(a::Number,b::MultiValue) where {D,T} +function isless(a::Number,b::MultiValue) where {D,T} all(a .< b.data) end @@ -249,12 +249,12 @@ end function adjoint(v::T) where {T<:TensorValue} t = adjoint(get_array(v)) - TensorValue(t) + T(t) end function transpose(v::T) where {T<:TensorValue} t = transpose(get_array(v)) - TensorValue(t) + T(t) end # Symmetric part diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 0df93d00d..663077d89 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -50,7 +50,7 @@ export diagonal_tensor import Base: show import Base: zero, one -import Base: +, -, *, /, \, ==, ≈ +import Base: +, -, *, /, \, ==, ≈, isless import Base: conj import Base: sum, maximum, minimum import Base: getindex, iterate, eachindex diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index 4b9079f04..bb841b337 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -54,26 +54,31 @@ VectorValue{D,T}(data::Real...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data) # VectorValue single SVector, MVector and AbstractVector argument constructor -for s in ( Symbol("VectorValue"), - Symbol("VectorValue{D}"), - Symbol("VectorValue{D,T1}")) - @eval begin - function ($s)(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractVector{T2} - }) where {D,T1,T2} - PD = (@isdefined D) ? D : length(data) - PT = (@isdefined T1) ? T1 : T2 - VectorValue{PD,PT}(NTuple{PD,PT}(data)) - end - end -end - -# VectorValue single AbstractArray argument constructor - -function VectorValue{D,T1}(data::AbstractArray{T2}) where {D,T1,T2} +function VectorValue(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + PD = (@isdefined D) ? D : length(data) + VectorValue{PD,T2}(NTuple{PD,T2}(data)) +end + +function VectorValue{D}(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + VectorValue{D,T2}(NTuple{D,T2}(data)) +end + +function VectorValue{D,T1}(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} VectorValue{D,T1}(NTuple{D,T1}(data)) end @@ -106,34 +111,48 @@ TensorValue{D1,D2,T}(data::Real...) where {D1,D2,T} = TensorValue{D1,D2,T}(NTupl # VectorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor -for s in ( Symbol("TensorValue"), - Symbol("TensorValue{D1,D2}"), - Symbol("TensorValue{D1,D2,T1}"), - Symbol("TensorValue{D1,D2,T1,L}")) - @eval begin - function ($s)(data:: - Union{ - SVector{L,T2}, - MVector{L,T2}, - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - PD1 = (@isdefined D1) ? D1 : size(data)[1] - PD2 = (@isdefined D2) ? D2 : size(data)[2] - PT = (@isdefined T1) ? T1 : T2 - PL = (@isdefined L) ? L : length(data) - TensorValue{PD1,PD2,PT}(NTuple{PL,PT}(data)) - end - end -end - -function TensorValue{D1,D2,T1}(data::MMatrix{D1,D2,T2,L}) where {D1,D2,T1,T2,L} +function TensorValue(data:: + Union{ + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }) where {D1,D2,T1,T2,L} + PD1 = (@isdefined D1) ? D1 : size(data)[1] + PD2 = (@isdefined D2) ? D2 : size(data)[2] + PL = (@isdefined L) ? L : length(data) + TensorValue{PD1,PD2,T2}(NTuple{PL,T2}(data)) +end + +function TensorValue{D1,D2}(data:: + Union{ + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }) where {D1,D2,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + PL = (@isdefined L) ? L : length(data) + TensorValue{D1,D2,PT}(NTuple{PL,PT}(data)) +end + +function TensorValue{D1,D2,T1}(data:: + Union{ + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }) where {D1,D2,T1,T2,L} + PL = (@isdefined L) ? L : length(data) + TensorValue{D1,D2,T1}(NTuple{PL,T1}(data)) +end + +function TensorValue{D1,D2,T1,L}(data:: + Union{ + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }) where {D1,D2,T1,T2,L} TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end - - ############################################################### # Conversions (VectorValue) ############################################################### @@ -175,7 +194,7 @@ end # Conversions (TensorValue) ############################################################### -function convert(TT::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, +function convert(TT::Type{<:Union{TensorValue,TensorValue{D1,D2,T1},TensorValue{D1,D2,T1,L}}}, arg:: Union{ NTuple{L,T2}, @@ -201,9 +220,17 @@ function convert(::Type{<:Union{MMatrix,MMatrix{D1,D2,T1,L}}}, arg::TensorValue{ MMatrix{D1,D2,PT,L}(arg.data) end -function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} +function convert(::Type{<:SMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + SMatrix{D1,D2,T1,L}(arg.data) +end + +function convert(::Type{<:MMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} + MMatrix{D1,D2,T1,L}(arg.data) +end + +function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2},TensorValue{D1,D2,T1},TensorValue{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 - PT == T2 ? arg : convert(TensorValue{D1,D2,PT,L}, arg.data) + PT == T2 ? arg : convert(TensorValue{D1,D2,T1,L}, arg.data) end ############################################################### @@ -230,27 +257,27 @@ function change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} VectorValue{D,T2} end -function zero(::IT where {IT<:VectorValue{D,T}}) where {D,T} +function zero(::VectorValue{D,T}) where {D,T} zero(VectorValue{D,T}) end -function one(::IT where {IT<:VectorValue{D,T}}) where {D,T} +function one(::VectorValue{D,T}) where {D,T} one(VectorValue{D,T}) end -function mutable(::IT where {IT<:VectorValue{D,T}}) where {D,T} +function mutable(::VectorValue{D,T}) where {D,T} mutable(VectorValue{D,T}) end -function change_eltype(::IT where {IT<:VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} +function change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} change_eltype(VectorValue{D,T1},T2) end -function SVector(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function SVector(arg::VectorValue{D,T}) where {D,T} SVector{D,T}(arg.data) end -function SArray(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function SArray(arg::VectorValue{D,T}) where {D,T} SVector(arg) end @@ -276,27 +303,27 @@ function change_eltype(::Type{TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2, TensorValue{D1,D2,T2,L} end -function zero(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} +function zero(::TensorValue{D1,D2,T}) where {D1,D2,T} zero(TensorValue{D1,D2,T}) end -function one(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} +function one(::TensorValue{D1,D2,T}) where {D1,D2,T} one(TensorValue{D1,D2,T}) end -function mutable(::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} +function mutable(::TensorValue{D1,D2,T}) where {D1,D2,T} mutable(TensorValue{D1,D2,T}) end -function change_eltype(::IT where {IT<:TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} +function change_eltype(::TensorValue{D1,D2,T1,L},::Type{T2}) where {D1,D2,T1,T2,L} change_eltype(TensorValue{D1,D2,T1,L},T2) end -function SMatrix(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} +function SMatrix(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} SMatrix{D1,D2,T,L}(arg.data) end -function SArray(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} +function SArray(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} StaticArrays.SMatrix(arg) end @@ -327,11 +354,11 @@ function eltype(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} T end -function eltype(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function eltype(arg::VectorValue{D,T}) where {D,T} eltype(VectorValue{D,T}) end -function eltype(arg::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} +function eltype(arg::TensorValue{D1,D2,T}) where {D1,D2,T} eltype(TensorValue{D1,D2,T}) end @@ -359,11 +386,11 @@ function size(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} (D1,D2) end -function size(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function size(arg::VectorValue{D,T}) where {D,T} size(VectorValue{D,T}) end -function size(arg::IT where {IT<:TensorValue{D1,D2,T}}) where {D1,D2,T} +function size(arg::TensorValue{D1,D2,T}) where {D1,D2,T} size(TensorValue{D1,D2,T}) end @@ -387,11 +414,11 @@ function length(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} L end -function length(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function length(arg::VectorValue{D,T}) where {D,T} length(VectorValue{D,T}) end -function length(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} +function length(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} length(TensorValue{D1,D2,T,L}) end @@ -419,17 +446,17 @@ function n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} length(TensorValue{D1,D2,T,L}) end -function n_components(arg::IT where {IT<:Number}) +function n_components(arg::Number) n_components(Number) end -function n_components(arg::IT where {IT<:VectorValue{D,T}}) where {D,T} +function n_components(arg::VectorValue{D,T}) where {D,T} n_components(VectorValue{D,T}) end -function n_components(arg::IT where {IT<:TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} +function n_components(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} n_components(TensorValue{D1,D2,T,L}) end @@ -454,14 +481,14 @@ end # Custom type printing -function show(io::IO,v::IT where {IT<:MultiValue}) +function show(io::IO,v::MultiValue) print(io,v.data) end -function show(io::IO,::MIME"text/plain",v:: IT where {IT<:MultiValue}) +function show(io::IO,::MIME"text/plain",v:: MultiValue) print(io,typeof(v)) print(io,v.data) end -@inline Tuple(arg::IT where {IT<:MultiValue}) = arg.data +@inline Tuple(arg::MultiValue) = arg.data From ed98f877e4182e99fbc483edef103467fdaa0284 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 2 Apr 2020 12:09:36 +0200 Subject: [PATCH 10/37] pretify and add get_index from CartesianIndex --- src/TensorValues/Indexing.jl | 31 ++-- src/TensorValues/Operations.jl | 198 ++++++++++------------- src/TensorValues/Types.jl | 279 +++++++++------------------------ 3 files changed, 168 insertions(+), 340 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index e2de2af60..07a500657 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,27 +1,16 @@ -function getindex(a::VectorValue,i::Integer) - a.data[i] -end +getindex(arg::VectorValue, i::Integer) = arg.data[i] +getindex(arg::VectorValue, ci::CartesianIndex{1}) = get_index(arg,ci[1]) +getindex(arg::TensorValue, i::Integer) = arg.data[i] -function getindex(a::TensorValue,i::Integer) - a.data[i] -end +getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} = (index=((j-1)*D1)+i; arg.data[index]) +getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = get_index(arg,ci[1],ci[2]) -function getindex(a::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} - index = (j-1)*D1 + i - a.data[index] -end +@inline iterate(arg::MultiValue) = iterate(arg.data) +@inline iterate(arg::MultiValue, state) = iterate(arg.data, state) -@inline iterate(a::MultiValue) = iterate(a.data) +eachindex(arg::MultiValue) = eachindex(arg.data) -@inline iterate(a::MultiValue, state) = iterate(a.data, state) +CartesianIndices(arg::MultiValue) = CartesianIndices(get_array(arg)) -eachindex(a::MultiValue) = eachindex(a.data) - -function CartesianIndices(a::MultiValue) - CartesianIndices(get_array(a)) -end - -function LinearIndices(a::MultiValue) - LinearIndices(get_array(a)) -end +LinearIndices(arg::MultiValue) = LinearIndices(get_array(arg)) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index bd9205f94..1cb7800fb 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -1,17 +1,10 @@ - +############################################################### # Comparison +############################################################### -function (==)(a::MultiValue,b::MultiValue) - a.data == b.data -end - -function (≈)(a::MultiValue,b::MultiValue) - isapprox(collect(a.data), collect(b.data)) -end - -function (≈)(a::VectorValue{0},b::VectorValue{0}) - true -end +(==)(a::MultiValue,b::MultiValue) = a.data == b.data +(≈)(a::MultiValue,b::MultiValue) = isapprox(collect(a.data), collect(b.data)) +(≈)(a::VectorValue{0},b::VectorValue{0}) = true function (≈)( a::AbstractArray{<:MultiValue}, b::AbstractArray{<:MultiValue}) @@ -35,11 +28,11 @@ function isless(a::VectorValue{N},b::VectorValue{N}) where N false end -function isless(a::Number,b::MultiValue) where {D,T} - all(a .< b.data) -end +isless(a::Number,b::MultiValue) where {D,T} = all(a .< b.data) +############################################################### # Addition / subtraction +############################################################### for op in (:+,:-) @eval begin @@ -62,14 +55,18 @@ for op in (:+,:-) end end +############################################################### # Matrix Division +############################################################### function (\)(a::T1 where {T1<:TensorValue}, b::T2) where {T2<:MultiValue} r = get_array(a) \ get_array(b) T2(r) end +############################################################### # Operations with other numbers +############################################################### for op in (:+,:-,:*) @eval begin @@ -93,76 +90,67 @@ function (/)(a::T,b::Number) where {T<:MultiValue} PT(r) end +############################################################### # Dot product (simple contraction) +############################################################### -function (*)(a::VectorValue{D}, b::VectorValue{D}) where D - inner(a,b) -end +(*)(a::VectorValue{D}, b::VectorValue{D}) where D = inner(a,b) @generated function (*)(a::VectorValue{D1}, b::TensorValue{D2,D1}) where {D1,D2} - ss = String[] - for j in 1:D2 - s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) - push!(ss,s[1:(end-1)]*", ") - end - str = join(ss) - Meta.parse("VectorValue{$D2}($str)") + ss = String[] + for j in 1:D2 + s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) + push!(ss,s[1:(end-1)]*", ") + end + str = join(ss) + Meta.parse("VectorValue{$D2}($str)") end @generated function (*)(a::TensorValue{D1,D2}, b::VectorValue{D1}) where {D1,D2} - ss = String[] - for j in 1:D2 - s = join([ "b[$i]*a[$j,$i]+" for i in 1:D1]) - push!(ss,s[1:(end-1)]*", ") - end - str = join(ss) - Meta.parse("VectorValue{$D2}($str)") -end - -@generated function (*)(a::TensorValue{D1,D2}, b::TensorValue{D3,D1}) where {D1,D2,D3} - ss = String[] - for j in 1:D2 - for i in 1:D1 - s = join([ "a[$i,$k]*b[$k,$j]+" for k in 1:D3]) + ss = String[] + for j in 1:D2 + s = join([ "b[$i]*a[$j,$i]+" for i in 1:D1]) push!(ss,s[1:(end-1)]*", ") end - end - str = join(ss) - Meta.parse("TensorValue{$D2,$D3}(($str))") + str = join(ss) + Meta.parse("VectorValue{$D2}($str)") end -@inline function dot(u::VectorValue,v::VectorValue) - inner(u,v) -end - -@inline function dot(u::TensorValue,v::VectorValue) - u*v +@generated function (*)(a::TensorValue{D1,D2}, b::TensorValue{D3,D1}) where {D1,D2,D3} + ss = String[] + for j in 1:D2 + for i in 1:D1 + s = join([ "a[$i,$k]*b[$k,$j]+" for k in 1:D3]) + push!(ss,s[1:(end-1)]*", ") + end + end + str = join(ss) + Meta.parse("TensorValue{$D2,$D3}(($str))") end -@inline function dot(u::VectorValue,v::TensorValue) - u*v -end +@inline dot(u::VectorValue,v::VectorValue) = inner(u,v) +@inline dot(u::TensorValue,v::VectorValue) = u*v +@inline dot(u::VectorValue,v::TensorValue) = u*v +############################################################### # Inner product (full contraction) +############################################################### inner(a::Real,b::Real) = a*b - -""" -""" @generated function inner(a::MultiValue, b::MultiValue) - @assert length(a) == length(b) - str = join([" a[$i]*b[$i] +" for i in 1:length(a) ]) - Meta.parse(str[1:(end-1)]) + @assert length(a) == length(b) + str = join([" a[$i]*b[$i] +" for i in 1:length(a) ]) + Meta.parse(str[1:(end-1)]) end +############################################################### # Reductions +############################################################### for op in (:sum,:maximum,:minimum) - @eval begin - function $op(a::T) where {T<: MultiValue} - $op(a.data) + @eval begin + $op(a::MultiValue) = $op(a.data) end - end end # Outer product (aka dyadic product) @@ -170,14 +158,11 @@ end """ """ outer(a::Real,b::Real) = a*b - outer(a::MultiValue,b::Real) = a*b - outer(a::Real,b::MultiValue) = a*b - @generated function outer(a::VectorValue{D},b::VectorValue{Z}) where {D,Z} - str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) - Meta.parse("TensorValue{$D,$Z}(($str))") + str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) + Meta.parse("TensorValue{$D,$Z}(($str))") end #@generated function outer(a::VectorValue{D},b::TensorValue{D1,D2}) where {D,D1,D2} @@ -185,18 +170,20 @@ end # Meta.parse("MultiValue(SArray{Tuple{$D,$D1,$D2}}($str))") #end +############################################################### # Linear Algebra +############################################################### det(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = det(convert(StaticArrays.SMatrix{D1,D2,T,L},a)) - inv(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = TensorValue(inv(convert(StaticArrays.SMatrix{D1,D2,T,L},a))) +############################################################### # Measure +############################################################### """ """ meas(a::VectorValue) = sqrt(inner(a,a)) - meas(a::TensorValue) = abs(det(a)) function meas(v::TensorValue{1,2}) @@ -215,20 +202,22 @@ function meas(v::TensorValue{2,3}) end @inline norm(u::VectorValue) = sqrt(inner(u,u)) - @inline norm(u::VectorValue{0,T}) where T = sqrt(zero(T)) +############################################################### # conj +############################################################### conj(a::VectorValue) = a - conj(a::T) where {T<:TensorValue} = T(conj(get_array(a))) +############################################################### # Trace +############################################################### @generated function tr(v::TensorValue{D}) where D - str = join([" v[$i+$((i-1)*D)] +" for i in 1:D ]) - Meta.parse(str[1:(end-1)]) + str = join([" v[$i+$((i-1)*D)] +" for i in 1:D ]) + Meta.parse(str[1:(end-1)]) end #@generated function tr(v::MultiValue{Tuple{A,A,B}}) where {A,B} @@ -245,66 +234,47 @@ end # Meta.parse("VectorValue($str)") #end +############################################################### # Adjoint and transpose +############################################################### -function adjoint(v::T) where {T<:TensorValue} - t = adjoint(get_array(v)) - T(t) -end - -function transpose(v::T) where {T<:TensorValue} - t = transpose(get_array(v)) - T(t) -end +adjoint(v::T) where {T<:TensorValue} = T(adjoint(get_array(v))) +transpose(v::T) where {T<:TensorValue} = T(transpose(get_array(v))) +############################################################### # Symmetric part +############################################################### """ """ @generated function symmetic_part(v::TensorValue{D}) where D - str = "(" - for j in 1:D - for i in 1:D - str *= "0.5*v.data[$i+$((j-1)*D)] + 0.5*v.data[$j+$((i-1)*D)], " + str = "(" + for j in 1:D + for i in 1:D + str *= "0.5*v.data[$i+$((j-1)*D)] + 0.5*v.data[$j+$((i-1)*D)], " + end end - end - str *= ")" - Meta.parse("TensorValue($str)") + str *= ")" + Meta.parse("TensorValue($str)") end +############################################################### # Define new operations for Gridap types +############################################################### for op in (:symmetic_part,) - @eval begin - function ($op)(a::GridapType) - operate($op,a) + @eval begin + ($op)(a::GridapType) = operate($op,a) end - end end for op in (:inner,:outer) - @eval begin - - function ($op)(a::GridapType,b::GridapType) - operate($op,a,b) - end - - function ($op)(a::GridapType,b::Number) - operate($op,a,b) - end - - function ($op)(a::Number,b::GridapType) - operate($op,a,b) + @eval begin + ($op)(a::GridapType,b::GridapType) = operate($op,a,b) + ($op)(a::GridapType,b::Number) = operate($op,a,b) + ($op)(a::Number, b::GridapType) = operate($op,a,b) + ($op)(a::GridapType,b::Function) = operate($op,a,b) + ($op)(a::Function, b::GridapType) = operate($op,a,b) end - - function ($op)(a::GridapType,b::Function) - operate($op,a,b) - end - - function ($op)(a::Function,b::GridapType) - operate($op,a,b) - end - - end end diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl index bb841b337..0740a5571 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/Types.jl @@ -234,246 +234,115 @@ function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2},TensorValue{D1,D2 end ############################################################### -# Other constructors (VectorValue) +# Other constructors and conversions (VectorValue) ############################################################### -function zero(::Type{<:VectorValue{D,T}}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) -end - -function one(::Type{<:VectorValue{D,T}}) where {D,T} - VectorValue{D,T}(NTuple{D,T}(ones(T,D))) -end - -function mutable(::Type{VectorValue{D,T}}) where {D,T} - MVector{D,T} -end +zero(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) +zero(::VectorValue{D,T}) where {D,T} = zero(VectorValue{D,T}) -function change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} - VectorValue{D,T} -end +one(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(ones(T,D))) +one(::VectorValue{D,T}) where {D,T} = one(VectorValue{D,T}) -function change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} - VectorValue{D,T2} -end +mutable(::Type{VectorValue{D,T}}) where {D,T} = MVector{D,T} +mutable(::VectorValue{D,T}) where {D,T} = mutable(VectorValue{D,T}) -function zero(::VectorValue{D,T}) where {D,T} - zero(VectorValue{D,T}) -end +change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} = VectorValue{D,T} +change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} = VectorValue{D,T2} +change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} = change_eltype(VectorValue{D,T1},T2) -function one(::VectorValue{D,T}) where {D,T} - one(VectorValue{D,T}) -end - -function mutable(::VectorValue{D,T}) where {D,T} - mutable(VectorValue{D,T}) -end - -function change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} - change_eltype(VectorValue{D,T1},T2) -end - -function SVector(arg::VectorValue{D,T}) where {D,T} - SVector{D,T}(arg.data) -end - -function SArray(arg::VectorValue{D,T}) where {D,T} - SVector(arg) -end +SVector(arg::VectorValue{D,T}) where {D,T} = SVector{D,T}(arg.data) +SArray(arg::VectorValue{D,T}) where {D,T} = SVector(arg) +get_array(arg::T where {T<:VectorValue}) = convert(SVector,arg) ############################################################### -# Other constructors (TensorValue) +# Other constructors and conversions (TensorValue) ############################################################### -function zero(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} - D=D1*D2 - TensorValue{D1,D2,T}(NTuple{D,T}(zeros(T,D))) -end +zero(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = (D=D1*D2;TensorValue{D1,D2,T}(NTuple{D,T}(zeros(T,D)))) +zero(::TensorValue{D1,D2,T}) where {D1,D2,T} = zero(TensorValue{D1,D2,T}) @generated function one(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D1 for j in 1:D2]) Meta.parse("TensorValue{D1,D2,T}(($str))") end +one(::TensorValue{D1,D2,T}) where {D1,D2,T} = one(TensorValue{D1,D2,T}) -function mutable(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} - MMatrix{D1,D2,T} -end - -function change_eltype(::Type{TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T2,L} -end - -function zero(::TensorValue{D1,D2,T}) where {D1,D2,T} - zero(TensorValue{D1,D2,T}) -end - -function one(::TensorValue{D1,D2,T}) where {D1,D2,T} - one(TensorValue{D1,D2,T}) -end - -function mutable(::TensorValue{D1,D2,T}) where {D1,D2,T} - mutable(TensorValue{D1,D2,T}) -end - -function change_eltype(::TensorValue{D1,D2,T1,L},::Type{T2}) where {D1,D2,T1,T2,L} - change_eltype(TensorValue{D1,D2,T1,L},T2) -end - -function SMatrix(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} - SMatrix{D1,D2,T,L}(arg.data) -end - -function SArray(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} - StaticArrays.SMatrix(arg) -end - - - - -function get_array(arg::T where {T<:VectorValue}) - convert(SVector,arg) -end - -function get_array(arg::T where {T<:TensorValue}) - convert(SMatrix,arg) -end - -function change_eltype(::Type{<:Number},::Type{T}) where {T} - T -end - -function change_eltype(::Number,::Type{T2}) where {T2} - change_eltype(Number,T2) -end - -function eltype(::Type{<:VectorValue{D,T}}) where {D,T} - T -end - -function eltype(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} - T -end - -function eltype(arg::VectorValue{D,T}) where {D,T} - eltype(VectorValue{D,T}) -end - -function eltype(arg::TensorValue{D1,D2,T}) where {D1,D2,T} - eltype(TensorValue{D1,D2,T}) -end - -function size(::Type{VectorValue{D}}) where {D} - (D,) -end - -function size(::Type{VectorValue{D,T}}) where {D,T} - (D,) -end - -function size(::Type{TensorValue{D}}) where {D} - (D,D) -end - -function size(::Type{TensorValue{D1,D2}}) where {D1,D2} - (D1,D2) -end - -function size(::Type{TensorValue{D1,D2,T}}) where {D1,D2,T} - (D1,D2) -end - -function size(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} - (D1,D2) -end +mutable(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = MMatrix{D1,D2,T} +mutable(::TensorValue{D1,D2,T}) where {D1,D2,T} = mutable(TensorValue{D1,D2,T}) -function size(arg::VectorValue{D,T}) where {D,T} - size(VectorValue{D,T}) -end +change_eltype(::Type{TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} = TensorValue{D1,D2,T2,L} +change_eltype(::TensorValue{D1,D2,T1,L},::Type{T2}) where {D1,D2,T1,T2,L} = change_eltype(TensorValue{D1,D2,T1,L},T2) -function size(arg::TensorValue{D1,D2,T}) where {D1,D2,T} - size(TensorValue{D1,D2,T}) -end - -function length(::Type{VectorValue{D}}) where {D} - D -end - -function length(::Type{VectorValue{D,T}}) where {D,T} - D -end - -function length(::Type{TensorValue{D}}) where {D} - length(TensorValue{D,D}) -end +SMatrix(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = SMatrix{D1,D2,T,L}(arg.data) +SArray(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = StaticArrays.SMatrix(arg) +get_array(arg::T where {T<:TensorValue}) = convert(SMatrix,arg) -function length(::Type{TensorValue{D1,D2}}) where {D1,D2} - D1*D1 -end - -function length(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} - L -end - -function length(arg::VectorValue{D,T}) where {D,T} - length(VectorValue{D,T}) -end - -function length(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} - length(TensorValue{D1,D2,T,L}) +@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} + s = ["zero(T), " for i in 1:(D*D)] + for i in 1:D + d = D*(i-1)+i + s[d] = "v.data[$i]," + end + str = join(s) + Meta.parse("TensorValue(($str))") end -function n_components(::Type{<:Number}) - 1 -end +############################################################### +# Introspection (VectorValue) +############################################################### -function n_components(::Type{VectorValue{D}}) where {D} - length(VectorValue{D}) -end +eltype(::Type{<:VectorValue{D,T}}) where {D,T} = T +eltype(arg::VectorValue{D,T}) where {D,T} = eltype(VectorValue{D,T}) -function n_components(::Type{VectorValue{D,T}}) where {D,T} - length(VectorValue{D,T}) -end +size(::Type{VectorValue{D}}) where {D} = (D,) +size(::Type{VectorValue{D,T}}) where {D,T} = (D,) +size(::VectorValue{D,T}) where {D,T} = size(VectorValue{D,T}) -function n_components(::Type{TensorValue{D}}) where {D} - length(TensorValue{D,D}) -end +length(::Type{VectorValue{D}}) where {D} = D +length(::Type{VectorValue{D,T}}) where {D,T} = D +length(::VectorValue{D,T}) where {D,T} = length(VectorValue{D,T}) -function n_components(::Type{TensorValue{D1,D2}}) where {D1,D2} - length(TensorValue{D1,D2}) -end +n_components(::Type{VectorValue{D}}) where {D} = length(VectorValue{D}) +n_components(::Type{VectorValue{D,T}}) where {D,T} = length(VectorValue{D,T}) +n_components(::VectorValue{D,T}) where {D,T} = n_components(VectorValue{D,T}) -function n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} - length(TensorValue{D1,D2,T,L}) -end +############################################################### +# Introspection (TensorValue) +############################################################### -function n_components(arg::Number) - n_components(Number) -end +eltype(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = T +eltype(::TensorValue{D1,D2,T}) where {D1,D2,T} = eltype(TensorValue{D1,D2,T}) +size(::Type{TensorValue{D}}) where {D} = (D,D) +size(::Type{TensorValue{D1,D2}}) where {D1,D2} = (D1,D2) +size(::Type{TensorValue{D1,D2,T}}) where {D1,D2,T} = (D1,D2) +size(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = (D1,D2) +size(::TensorValue{D1,D2,T}) where {D1,D2,T} = size(TensorValue{D1,D2,T}) -function n_components(arg::VectorValue{D,T}) where {D,T} - n_components(VectorValue{D,T}) -end +length(::Type{TensorValue{D}}) where {D} = length(TensorValue{D,D}) +length(::Type{TensorValue{D1,D2}}) where {D1,D2} = D1*D1 +length(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = L +length(::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = length(TensorValue{D1,D2,T,L}) +n_components(::Type{TensorValue{D}}) where {D} = length(TensorValue{D,D}) +n_components(::Type{TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2}) +n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = length(TensorValue{D1,D2,T,L}) +n_components(::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = n_components(TensorValue{D1,D2,T,L}) -function n_components(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} - n_components(TensorValue{D1,D2,T,L}) -end +############################################################### +# Other constructors and conversions implemented for more general types +############################################################### +change_eltype(::Type{<:Number},::Type{T}) where {T} = T +change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) +n_components(::Type{<:Number}) = 1 +n_components(::Number) = n_components(Number) -""" -""" -@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} - s = ["zero(T), " for i in 1:(D*D)] - for i in 1:D - d = D*(i-1)+i - s[d] = "v.data[$i]," - end - str = join(s) - Meta.parse("TensorValue(($str))") -end +############################################################### +# Misc +############################################################### # Misc operations on the type itself From b2e59e0188d80ccb70273c1b50cd88fdb28f0e1a Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 2 Apr 2020 17:41:32 +0200 Subject: [PATCH 11/37] Group code by Type. Start SymTensorValue implementation. Tests pending --- src/TensorValues/Misc.jl | 30 +++ src/TensorValues/MultiValueType.jl | 9 + src/TensorValues/SymTensorValueType.jl | 114 +++++++++++ .../{Types.jl => TensorValueType.jl} | 184 +----------------- src/TensorValues/TensorValues.jl | 11 +- src/TensorValues/VectorValueType.jl | 145 ++++++++++++++ 6 files changed, 311 insertions(+), 182 deletions(-) create mode 100644 src/TensorValues/Misc.jl create mode 100644 src/TensorValues/MultiValueType.jl create mode 100644 src/TensorValues/SymTensorValueType.jl rename src/TensorValues/{Types.jl => TensorValueType.jl} (54%) create mode 100644 src/TensorValues/VectorValueType.jl diff --git a/src/TensorValues/Misc.jl b/src/TensorValues/Misc.jl new file mode 100644 index 000000000..862e054b5 --- /dev/null +++ b/src/TensorValues/Misc.jl @@ -0,0 +1,30 @@ +############################################################### +# Other constructors and conversions implemented for more general types +############################################################### + +change_eltype(::Type{<:Number},::Type{T}) where {T} = T +change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) + +n_components(::Type{<:Number}) = 1 +n_components(::Number) = n_components(Number) + +############################################################### +# Misc +############################################################### + +# Misc operations on the type itself + +@pure _s(s::Size{T}) where T = T + +# Custom type printing + +function show(io::IO,v::MultiValue) + print(io,v.data) +end + +function show(io::IO,::MIME"text/plain",v:: MultiValue) + print(io,typeof(v)) + print(io,v.data) +end + +@inline Tuple(arg::T where {T<:MultiValue}) = arg.data diff --git a/src/TensorValues/MultiValueType.jl b/src/TensorValues/MultiValueType.jl new file mode 100644 index 000000000..d543f86b7 --- /dev/null +++ b/src/TensorValues/MultiValueType.jl @@ -0,0 +1,9 @@ +############################################################### +# MultiValue Type +############################################################### + +""" +Type representing a multi-dimensional value +""" +abstract type MultiValue{S,T,N,L} <: Number end + diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl new file mode 100644 index 000000000..c6964e7e2 --- /dev/null +++ b/src/TensorValues/SymTensorValueType.jl @@ -0,0 +1,114 @@ +############################################################### +# SymTensorValue Type +############################################################### + +""" +Type representing a symmetric second-order tensor +""" +struct SymTensorValue{D,T,L} <: MultiValue{Tuple{D,D},T,2,L} + data::NTuple{L,T} + function SymTensorValue{D,T}(data::NTuple{L,T}) where {D,T,L} + @assert L == D*(D+1)/2 + new{D,T,L}(data) + end +end + + +############################################################### +# Constructors (SymTensorValue) +############################################################### + +# Empty SymTensorValue constructor + +SymTensorValue() = SymTensorValue{0,Int}(NTuple{0,Int}()) +SymTensorValue{0}() = SymTensorValue{0,Int}(NTuple{0,Int}()) +SymTensorValue{0,T}() where {T} = SymTensorValue{0,T}(NTuple{0,T}()) +SymTensorValue(data::NTuple{0}) = SymTensorValue{0,Int}(data) +SymTensorValue{0}(data::NTuple{0}) = SymTensorValue{0,Int}(data) + +# SymTensorValue single NTuple argument constructor + +SymTensorValue(data::NTuple{L,T}) where {L,T} = SymTensorValue{floor(Int,sqrt(L*2)),T}(data) +SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(data) +SymTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1,}(NTuple{L,T1}(data)) +SymTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1,L}(NTuple{L,T1}(data)) + +# SymTensorValue Vararg constructor + +SymTensorValue(data::Real...) = SymTensorValue{floor(Int,sqrt(length(data)*2))}(NTuple(data)) +SymTensorValue{D}(data::Real...) where {D} = SymTensorValue{D}(NTuple(data)) +SymTensorValue{D,T}(data::Real...) where {D,T} = SymTensorValue{D,T}(NTuple(data)) + +############################################################### +# Conversions (SymTensorValue) +############################################################### + +function convert(TT::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorValue{D,T1,L}}}, + arg:: + Union{ + NTuple{L,T2}, + }) where {D,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + SymTensorValue{D,PT}(arg) +end + +function convert(T::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + NTuple{L,PT}(arg.data) +end + +############################################################### +# Other constructors and conversions (SymTensorValue) +############################################################### + +zero(::Type{<:SymTensorValue{D,T}}) where {D,T} = (L=Int(D*(D+1)/2);SymTensorValue{D,T}(NTuple{L,T}(zeros(T,L)))) +zero(::SymTensorValue{D,T}) where {D,T} = zero(SymTensorValue{D,T}) + +@generated function one(::Type{<:SymTensorValue{D,T}}) where {D,T} + str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D for j in i:D]) + Meta.parse("SymTensorValue{D,T}(($str))") +end +one(::SymTensorValue{D,T}) where {D,T} = one(TensorValue{D,T}) + +mutable(::Type{<:SymTensorValue{D,T}}) where {D,T} = MMatrix{D,D,T} +mutable(::SymTensorValue{D,T}) where {D,T} = mutable(SymTensorValue{D,T}) + +change_eltype(::Type{SymTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymTensorValue{D,T2,L} +change_eltype(::SymTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymTensorValue{D,T1,L},T2) + +#SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix{D,T,L}(arg.data) +#SArray(arg::SymTensorValue{D,T,L}) where {D1,D2,T,L} = StaticArrays.SMatrix(arg) +#get_array(arg::T where {T<:SymTensorValue}) = convert(SMatrix,arg) + +#@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} +# s = ["zero(T), " for i in 1:(D*D)] +# for i in 1:D +# d = D*(i-1)+i +# s[d] = "v.data[$i]," +# end +# str = join(s) +# Meta.parse("SymTensorValue(($str))") +#end + +############################################################### +# Introspection (SymTensorValue) +############################################################### + + +eltype(::Type{<:SymTensorValue{D,T}}) where {D,T} = T +eltype(::SymTensorValue{D,T}) where {D,T} = eltype(SymTensorValue{D,T}) + +size(::Type{SymTensorValue{D}}) where {D} = (D,D) +size(::Type{SymTensorValue{D,T}}) where {D,T} = (D,D) +size(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = (D,D) +size(::SymTensorValue{D,T}) where {D,T} = size(SymTensorValue{D,T}) + +length(::Type{SymTensorValue{D}}) where {D} = Int(D*(D+1)/2) +length(::Type{SymTensorValue{D,T}}) where {D,T} = length(SymTensorValue{D}) +length(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = L +length(::SymTensorValue{D,T,L}) where {D,T,L} = length(SymTensorValue{D,T,L}) + +n_components(::Type{SymTensorValue{D}}) where {D} = length(SymTensorValue{D}) +n_components(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = length(SymTensorValue{D,T,L}) +n_components(::SymTensorValue{D,T,L}) where {D,T,L} = n_components(SymTensorValue{D,T,L}) + diff --git a/src/TensorValues/Types.jl b/src/TensorValues/TensorValueType.jl similarity index 54% rename from src/TensorValues/Types.jl rename to src/TensorValues/TensorValueType.jl index 0740a5571..21a57eb06 100644 --- a/src/TensorValues/Types.jl +++ b/src/TensorValues/TensorValueType.jl @@ -1,22 +1,7 @@ ############################################################### -# Types +# TensorValue Type ############################################################### -""" -Type representing a multi-dimensional value -""" -abstract type MultiValue{S,T,N,L} <: Number end - -""" -Type representing a first-order tensor -""" -struct VectorValue{D,T} <: MultiValue{Tuple{D},T,1,D} - data::NTuple{D,T} - function VectorValue{D,T}(data::NTuple{D,T}) where {D,T} - new{D,T}(data) - end -end - """ Type representing a second-order tensor """ @@ -29,61 +14,7 @@ struct TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L} end ############################################################### -# Constructors (VectorValue) -############################################################### - -# Empty VectorValue constructor - -VectorValue() = VectorValue{0,Int}(NTuple{0,Int}()) -VectorValue{0}() = VectorValue{0,Int}(NTuple{0,Int}()) -VectorValue{0,T}() where {T} = VectorValue{0,T}(NTuple{0,T}()) -VectorValue(data::NTuple{0}) = VectorValue{0,Int}(data) -VectorValue{0}(data::NTuple{0}) = VectorValue{0,Int}(data) - -# VectorValue single NTuple argument constructor - -VectorValue(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) -VectorValue{D}(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) -VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) - -# VectorValue Vararg constructor - -VectorValue(data::Real...) = VectorValue(NTuple{length(data)}(data)) -VectorValue{D}(data::Real...) where {D} = VectorValue{D}(NTuple{D}(data)) -VectorValue{D,T}(data::Real...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) - -# VectorValue single SVector, MVector and AbstractVector argument constructor - -function VectorValue(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - PD = (@isdefined D) ? D : length(data) - VectorValue{PD,T2}(NTuple{PD,T2}(data)) -end - -function VectorValue{D}(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - VectorValue{D,T2}(NTuple{D,T2}(data)) -end - -function VectorValue{D,T1}(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(data)) -end - -############################################################### -# Constructors (TensorValue) +# Constructors ############################################################### # Empty TensorValue constructor @@ -109,7 +40,7 @@ TensorValue{D}(data::Real...) where {D} = TensorValue{D,D}(NTuple{D* TensorValue{D1,D2}(data::Real...) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) TensorValue{D1,D2,T}(data::Real...) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) -# VectorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor +# TensorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor function TensorValue(data:: Union{ @@ -153,43 +84,6 @@ function TensorValue{D1,D2,T1,L}(data:: TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) end -############################################################### -# Conversions (VectorValue) -############################################################### - -function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, - arg:: - Union{ - NTuple{D,T2}, - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - PD = (@isdefined D) ? D : length(arg) - VectorValue{PD,PT}(NTuple{PD,PT}(arg)) -end - -function convert(::Type{<:Union{NTuple,NTuple{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - NTuple{D,PT}(arg.data) -end - -function convert(::Type{<:Union{SVector,SVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - SVector{D,PT}(arg.data) -end - -function convert(::Type{<:Union{MVector,MVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - MVector{D,PT}(arg.data) -end - -function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - PT == T2 ? arg : convert(VectorValue{D,PT}, arg.data) -end - ############################################################### # Conversions (TensorValue) ############################################################### @@ -233,27 +127,6 @@ function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2},TensorValue{D1,D2 PT == T2 ? arg : convert(TensorValue{D1,D2,T1,L}, arg.data) end -############################################################### -# Other constructors and conversions (VectorValue) -############################################################### - -zero(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) -zero(::VectorValue{D,T}) where {D,T} = zero(VectorValue{D,T}) - -one(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(ones(T,D))) -one(::VectorValue{D,T}) where {D,T} = one(VectorValue{D,T}) - -mutable(::Type{VectorValue{D,T}}) where {D,T} = MVector{D,T} -mutable(::VectorValue{D,T}) where {D,T} = mutable(VectorValue{D,T}) - -change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} = VectorValue{D,T} -change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} = VectorValue{D,T2} -change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} = change_eltype(VectorValue{D,T1},T2) - -SVector(arg::VectorValue{D,T}) where {D,T} = SVector{D,T}(arg.data) -SArray(arg::VectorValue{D,T}) where {D,T} = SVector(arg) -get_array(arg::T where {T<:VectorValue}) = convert(SVector,arg) - ############################################################### # Other constructors and conversions (TensorValue) ############################################################### @@ -287,25 +160,6 @@ get_array(arg::T where {T<:TensorValue}) = convert(SMatrix,arg) Meta.parse("TensorValue(($str))") end -############################################################### -# Introspection (VectorValue) -############################################################### - -eltype(::Type{<:VectorValue{D,T}}) where {D,T} = T -eltype(arg::VectorValue{D,T}) where {D,T} = eltype(VectorValue{D,T}) - -size(::Type{VectorValue{D}}) where {D} = (D,) -size(::Type{VectorValue{D,T}}) where {D,T} = (D,) -size(::VectorValue{D,T}) where {D,T} = size(VectorValue{D,T}) - -length(::Type{VectorValue{D}}) where {D} = D -length(::Type{VectorValue{D,T}}) where {D,T} = D -length(::VectorValue{D,T}) where {D,T} = length(VectorValue{D,T}) - -n_components(::Type{VectorValue{D}}) where {D} = length(VectorValue{D}) -n_components(::Type{VectorValue{D,T}}) where {D,T} = length(VectorValue{D,T}) -n_components(::VectorValue{D,T}) where {D,T} = n_components(VectorValue{D,T}) - ############################################################### # Introspection (TensorValue) ############################################################### @@ -329,35 +183,3 @@ n_components(::Type{TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = length(TensorValue{D1,D2,T,L}) n_components(::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = n_components(TensorValue{D1,D2,T,L}) - -############################################################### -# Other constructors and conversions implemented for more general types -############################################################### - -change_eltype(::Type{<:Number},::Type{T}) where {T} = T -change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) - -n_components(::Type{<:Number}) = 1 -n_components(::Number) = n_components(Number) - -############################################################### -# Misc -############################################################### - -# Misc operations on the type itself - -@pure _s(s::Size{T}) where T = T - -# Custom type printing - -function show(io::IO,v::MultiValue) - print(io,v.data) -end - -function show(io::IO,::MIME"text/plain",v:: MultiValue) - print(io,typeof(v)) - print(io,v.data) -end - -@inline Tuple(arg::MultiValue) = arg.data - diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 663077d89..d0859ebd5 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -37,6 +37,7 @@ using Gridap.Helpers using Gridap.Arrays export MultiValue +export SymTensorValue export TensorValue export VectorValue @@ -66,7 +67,15 @@ import LinearAlgebra: det, inv, tr, dot, norm import Gridap.Arrays: get_array -include("Types.jl") +include("MultiValueType.jl") + +include("VectorValueType.jl") + +include("TensorValueType.jl") + +include("SymTensorValueType.jl") + +include("Misc.jl") include("Indexing.jl") diff --git a/src/TensorValues/VectorValueType.jl b/src/TensorValues/VectorValueType.jl new file mode 100644 index 000000000..b12cac232 --- /dev/null +++ b/src/TensorValues/VectorValueType.jl @@ -0,0 +1,145 @@ +############################################################### +# Types +############################################################### + +""" +Type representing a first-order tensor +""" +struct VectorValue{D,T} <: MultiValue{Tuple{D},T,1,D} + data::NTuple{D,T} + function VectorValue{D,T}(data::NTuple{D,T}) where {D,T} + new{D,T}(data) + end +end + +############################################################### +# Constructors (VectorValue) +############################################################### + +# Empty VectorValue constructor + +VectorValue() = VectorValue{0,Int}(NTuple{0,Int}()) +VectorValue{0}() = VectorValue{0,Int}(NTuple{0,Int}()) +VectorValue{0,T}() where {T} = VectorValue{0,T}(NTuple{0,T}()) +VectorValue(data::NTuple{0}) = VectorValue{0,Int}(data) +VectorValue{0}(data::NTuple{0}) = VectorValue{0,Int}(data) + +# VectorValue single NTuple argument constructor + +VectorValue(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) +VectorValue{D}(data::NTuple{D,T}) where {D,T} = VectorValue{D,T}(data) +VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) + +# VectorValue Vararg constructor + +VectorValue(data::Real...) = VectorValue(NTuple{length(data)}(data)) +VectorValue{D}(data::Real...) where {D} = VectorValue{D}(NTuple{D}(data)) +VectorValue{D,T}(data::Real...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) + +# VectorValue single SVector, MVector and AbstractVector argument constructor + +function VectorValue(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + PD = (@isdefined D) ? D : length(data) + VectorValue{PD,T2}(NTuple{PD,T2}(data)) +end + +function VectorValue{D}(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + VectorValue{D,T2}(NTuple{D,T2}(data)) +end + +function VectorValue{D,T1}(data:: + Union{ + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + VectorValue{D,T1}(NTuple{D,T1}(data)) +end + +############################################################### +# Conversions (VectorValue) +############################################################### + +function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, + arg:: + Union{ + NTuple{D,T2}, + SVector{D,T2}, + MVector{D,T2}, + AbstractArray{T2} + }) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + PD = (@isdefined D) ? D : length(arg) + VectorValue{PD,PT}(NTuple{PD,PT}(arg)) +end + +function convert(::Type{<:Union{NTuple,NTuple{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + NTuple{D,PT}(arg.data) +end + +function convert(::Type{<:Union{SVector,SVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + SVector{D,PT}(arg.data) +end + +function convert(::Type{<:Union{MVector,MVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + MVector{D,PT}(arg.data) +end + +function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} + PT = (@isdefined T1) ? T1 : T2 + PT == T2 ? arg : convert(VectorValue{D,PT}, arg.data) +end + +############################################################### +# Other constructors and conversions (VectorValue) +############################################################### + +zero(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) +zero(::VectorValue{D,T}) where {D,T} = zero(VectorValue{D,T}) + +one(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(ones(T,D))) +one(::VectorValue{D,T}) where {D,T} = one(VectorValue{D,T}) + +mutable(::Type{VectorValue{D,T}}) where {D,T} = MVector{D,T} +mutable(::VectorValue{D,T}) where {D,T} = mutable(VectorValue{D,T}) + +change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} = VectorValue{D,T} +change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} = VectorValue{D,T2} +change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} = change_eltype(VectorValue{D,T1},T2) + +SVector(arg::VectorValue{D,T}) where {D,T} = SVector{D,T}(arg.data) +SArray(arg::VectorValue{D,T}) where {D,T} = SVector(arg) +get_array(arg::T where {T<:VectorValue}) = convert(SVector,arg) + +############################################################### +# Introspection (VectorValue) +############################################################### + +eltype(::Type{<:VectorValue{D,T}}) where {D,T} = T +eltype(arg::VectorValue{D,T}) where {D,T} = eltype(VectorValue{D,T}) + +size(::Type{VectorValue{D}}) where {D} = (D,) +size(::Type{VectorValue{D,T}}) where {D,T} = (D,) +size(::VectorValue{D,T}) where {D,T} = size(VectorValue{D,T}) + +length(::Type{VectorValue{D}}) where {D} = D +length(::Type{VectorValue{D,T}}) where {D,T} = D +length(::VectorValue{D,T}) where {D,T} = length(VectorValue{D,T}) + +n_components(::Type{VectorValue{D}}) where {D} = length(VectorValue{D}) +n_components(::Type{VectorValue{D,T}}) where {D,T} = length(VectorValue{D,T}) +n_components(::VectorValue{D,T}) where {D,T} = n_components(VectorValue{D,T}) + From b68e7ed267c449b78c27c876807cc294516e4632 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 7 Apr 2020 10:11:35 +0200 Subject: [PATCH 12/37] SymTensorValue implementation almost complete. #210 Some operations pending and its corresponding tests --- src/TensorValues/Indexing.jl | 21 +++++-- src/TensorValues/SymTensorValueType.jl | 78 +++++++++++++++++++------ src/TensorValues/TensorValueType.jl | 4 ++ src/TensorValues/TensorValues.jl | 4 +- test/TensorValuesTests/IndexingTests.jl | 18 ++++++ test/TensorValuesTests/TypesTests.jl | 63 ++++++++++++++++++++ 6 files changed, 162 insertions(+), 26 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 07a500657..9c7a937bf 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,10 +1,21 @@ -getindex(arg::VectorValue, i::Integer) = arg.data[i] -getindex(arg::VectorValue, ci::CartesianIndex{1}) = get_index(arg,ci[1]) -getindex(arg::TensorValue, i::Integer) = arg.data[i] +getindex(arg::MultiValue, i::Integer) = arg.data[i] -getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} = (index=((j-1)*D1)+i; arg.data[index]) -getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = get_index(arg,ci[1],ci[2]) +function getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} + 1 <= i <= D1 || throw(BoundsError(D1, i)) + 1 <= j <= D2 || throw(BoundsError(D2, i)) + arg.data[_getindex(arg, i, j)] +end + +function getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} + 1 <= i <= D || throw(BoundsError(D, i)) + 1 <= j <= D || throw(BoundsError(D, i)) + arg.data[_getindex(arg, i, j)] +end + +getindex(arg::VectorValue, i::CartesianIndex{1}) = getindex(arg,ci[1]) +getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) +getindex(arg::SymTensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) @inline iterate(arg::MultiValue) = iterate(arg.data) @inline iterate(arg::MultiValue, state) = iterate(arg.data, state) diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl index c6964e7e2..5e65a4958 100644 --- a/src/TensorValues/SymTensorValueType.jl +++ b/src/TensorValues/SymTensorValueType.jl @@ -13,6 +13,16 @@ struct SymTensorValue{D,T,L} <: MultiValue{Tuple{D,D},T,2,L} end end +function _getindex(arg::SymTensorValue{D},i::Integer) where {D} + index=((i-1)*D)-sum(1:i-1)+i +end + +function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} + _j,_i=sort([i,j]) + index=((_j-1)*D)-sum(1:_j-1)+_i +end + + ############################################################### # Constructors (SymTensorValue) @@ -21,7 +31,7 @@ end # Empty SymTensorValue constructor SymTensorValue() = SymTensorValue{0,Int}(NTuple{0,Int}()) -SymTensorValue{0}() = SymTensorValue{0,Int}(NTuple{0,Int}()) +SymTensorValue{0}() where {T} = SymTensorValue{0,Int}(NTuple{0,Int}()) SymTensorValue{0,T}() where {T} = SymTensorValue{0,T}(NTuple{0,T}()) SymTensorValue(data::NTuple{0}) = SymTensorValue{0,Int}(data) SymTensorValue{0}(data::NTuple{0}) = SymTensorValue{0,Int}(data) @@ -30,14 +40,17 @@ SymTensorValue{0}(data::NTuple{0}) = SymTensorValue{0,Int}(data) SymTensorValue(data::NTuple{L,T}) where {L,T} = SymTensorValue{floor(Int,sqrt(L*2)),T}(data) SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(data) -SymTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1,}(NTuple{L,T1}(data)) -SymTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1,L}(NTuple{L,T1}(data)) +SymTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) +SymTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) # SymTensorValue Vararg constructor -SymTensorValue(data::Real...) = SymTensorValue{floor(Int,sqrt(length(data)*2))}(NTuple(data)) -SymTensorValue{D}(data::Real...) where {D} = SymTensorValue{D}(NTuple(data)) -SymTensorValue{D,T}(data::Real...) where {D,T} = SymTensorValue{D,T}(NTuple(data)) +SymTensorValue(data::Real...) = (L=length(data);SymTensorValue{floor(Int,sqrt(L*2))}(NTuple{L}(data))) +SymTensorValue{D}(data::Real...) where {D} = (L=length(data);SymTensorValue{D}(NTuple{L}(data))) +SymTensorValue{D,T}(data::Real...) where {D,T} = (L=length(data);SymTensorValue{D,T}(NTuple{L,T}(data))) + +#From Square Matrices +# SymTensorValue -> b[[(D*(i-1))+j for i in 1:D for j in i:D]] ############################################################### # Conversions (SymTensorValue) @@ -52,6 +65,32 @@ function convert(TT::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorV SymTensorValue{D,PT}(arg) end +function convert(::Type{Union{SMatrix,SMatrix{D,D}}}, arg::SymTensorValue{D,T2,L2}) where {D,T1,T2,L1,L2} + PT = (@isdefined T1) ? T1 : T2 + SMatrix{D,D,PT}(SymTensorValueToArray(arg)) +end + +function convert(::Type{<:SMatrix{D,D,T1}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} + SMatrix{D,D,T1}(SymTensorValueToArray(arg)) +end + +function convert(::Type{<:SMatrix{D,D}}, arg::SymTensorValue{D,T2,L}) where {D,T2,L} + SMatrix{D,D,T2}(SymTensorValueToArray(arg)) +end + +function convert(::Type{Union{MMatrix,MMatrix{D,D,T1,L1}}}, arg::SymTensorValue{D,T2,L2}) where {D,T1,T2,L1,L2} + PT = (@isdefined T1) ? T1 : T2 + MMatrix{D,D,PT}(SymTensorValueToArray(arg)) +end + +function convert(::Type{<:MMatrix{D,D,T1}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} + MMatrix{D,D,T1}(SymTensorValueToArray(arg)) +end + +function convert(::Type{<:MMatrix{D,D}}, arg::SymTensorValue{D,T2,L}) where {D,T2,L} + MMatrix{D,D,T2}(SymTensorValueToArray(arg)) +end + function convert(T::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 NTuple{L,PT}(arg.data) @@ -76,19 +115,20 @@ mutable(::SymTensorValue{D,T}) where {D,T} = mutable(SymTensorValue{D,T}) change_eltype(::Type{SymTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymTensorValue{D,T2,L} change_eltype(::SymTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymTensorValue{D,T1,L},T2) -#SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix{D,T,L}(arg.data) -#SArray(arg::SymTensorValue{D,T,L}) where {D1,D2,T,L} = StaticArrays.SMatrix(arg) -#get_array(arg::T where {T<:SymTensorValue}) = convert(SMatrix,arg) - -#@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} -# s = ["zero(T), " for i in 1:(D*D)] -# for i in 1:D -# d = D*(i-1)+i -# s[d] = "v.data[$i]," -# end -# str = join(s) -# Meta.parse("SymTensorValue(($str))") -#end +function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} + z = zeros(T,D,D) + vector = collect(Tuple(arg)) + for i in 1:D + index = _getindex(arg,i) + range = index:index+(D-i) + z[i,i:D] = z[i:D,i] = vector[range] + end + z +end + +SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix{D,D,T,L}(SymTensorValueToArray(arg.data)) +SArray(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix(arg) +get_array(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix(arg) ############################################################### # Introspection (SymTensorValue) diff --git a/src/TensorValues/TensorValueType.jl b/src/TensorValues/TensorValueType.jl index 21a57eb06..cea73b8f4 100644 --- a/src/TensorValues/TensorValueType.jl +++ b/src/TensorValues/TensorValueType.jl @@ -13,6 +13,10 @@ struct TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L} end end +function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} + index=((j-1)*D1)+i +end + ############################################################### # Constructors ############################################################### diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index d0859ebd5..2b4a23d58 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -37,9 +37,9 @@ using Gridap.Helpers using Gridap.Arrays export MultiValue -export SymTensorValue -export TensorValue export VectorValue +export TensorValue +export SymTensorValue export inner, outer, meas #export det, inv, tr, dot, norm diff --git a/test/TensorValuesTests/IndexingTests.jl b/test/TensorValuesTests/IndexingTests.jl index 88524b38d..11fdaa6a4 100644 --- a/test/TensorValuesTests/IndexingTests.jl +++ b/test/TensorValuesTests/IndexingTests.jl @@ -35,6 +35,24 @@ for (k,ti) in enumerate(t) @test ti == a[k] end +sv = VectorValue(11,21,22) +s = SymTensorValue{2}(11,21,22) + +@test size(s) == (2,2) +@test length(s) == 3 + +for (k,i) in enumerate(eachindex(s)) + @test s[i] == sv[k] +end + +@test s[2,1] == 21 + +@test s[2] == 21 + +for (k,si) in enumerate(s) + @test si == sv[k] +end + v = @SMatrix zeros(2,3) w = TensorValue(v) @test CartesianIndices(w) == CartesianIndices(v) diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index ce3b62ab4..a524ed42c 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -40,6 +40,41 @@ t = TensorValue{1}((10,)) @test isa(t,TensorValue{1,1,Int}) @test convert(SMatrix,t) == 10*ones(1,1) +# Constructors (SymTensorValue) + +s = SymTensorValue( (11,21,22) ) +@test isa(s,SymTensorValue{2,Int}) +@test convert(SMatrix{2,2},s) == [11 21;21 22] + +s = SymTensorValue(11,21,22) +@test isa(s,SymTensorValue{2,Int}) +@test convert(SMatrix{2,2,Float64},s) == [11.0 21.0;21.0 22.0] + +s = SymTensorValue{2}( (11,21,22) ) +@test isa(s,SymTensorValue{2,Int}) +@test convert(SMatrix,s) == [11 21;21 22] + +s = SymTensorValue{2}(11,21,22) +@test isa(s,SymTensorValue{2,Int}) +@test convert(SMatrix{2,2,Float64},s) == [11.0 21.0;21.0 22.0] + +s = SymTensorValue{2,Int}( (11,21,22) ) +@test isa(s,SymTensorValue{2,Int}) +@test convert(SMatrix,s) == [11 21;21 22] + +s = SymTensorValue{2,Float64}(11,21,22) +@test isa(s,SymTensorValue{2,Float64}) +@test convert(SMatrix{2,2,Float64},s) == [11.0 21.0;21.0 22.0] + +s = SymTensorValue{0,Int}( () ) +@test isa(s,SymTensorValue{0,Int}) +@test convert(SMatrix{0,0},s) == Array{Any,2}(undef,0,0) + +s = SymTensorValue{0,Int}() +@test isa(s,SymTensorValue{0,Int}) +@test convert(SMatrix,s) == Array{Any,2}(undef,0,0) + + # Constructors (VectorValue) a = SVector(1) @@ -115,6 +150,10 @@ z = zero(TensorValue{3,3,Int,9}) @test isa(z,TensorValue{3,3,Int,9}) @test convert(SMatrix,z) == zeros(Int,(3,3)) +z = zero(SymTensorValue{3,Int}) +@test isa(z,SymTensorValue{3,Int,6}) +@test convert(SMatrix,z) == zeros(Int,(3,3)) + z = zero(VectorValue{3,Int}) @test isa(z,VectorValue{3,Int}) @test convert(SVector,z) == zeros(Int,3) @@ -125,6 +164,14 @@ z = one(TensorValue{3,3,Int,9}) s = one(z) @test convert(SMatrix,s) == [1 0 0; 0 1 0; 0 0 1] +z = one(SymTensorValue{3,Int}) +@test isa(z,SymTensorValue{3,Int,6}) +@test convert(SMatrix,z) == [1 0 0; 0 1 0; 0 0 1] + +z = one(VectorValue{3,Int}) +@test isa(z,VectorValue{3,Int}) +@test convert(SVector,z) == ones(Int,3) + # Conversions a = @SVector ones(Int,3) @@ -146,6 +193,13 @@ b = convert(V,a) b = V[a,a,a,] @test isa(b,Vector{V}) +a = (11,21,22) +V = SymTensorValue{2,Int,3} +b = convert(V,a) +@test isa(b,V) +b = V[a,a,a,] +@test isa(b,Vector{V}) + # Misc operations on the type itself V = VectorValue{3,Int} @@ -162,6 +216,10 @@ v = TensorValue{3,2,Float64}(1,2,3,4,5,6) s = "(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)" @test string(v) == s +v = SymTensorValue{3,Int64}(1, 0, 0, 1, 0, 1) +s = "(1, 0, 0, 1, 0, 1)" +@test string(v) == s + # Misc M = mutable(VectorValue{3,Int}) @@ -197,4 +255,9 @@ p = VectorValue(1,2,3) t = diagonal_tensor(p) @test t == TensorValue(1,0,0,0,2,0,0,0,3) +a = SymTensorValue(11,21,22) +@test change_eltype(a,Float64) == SymTensorValue{2,Float64,3} +@test isa(Tuple(a),Tuple) +@test Tuple(a) == a.data + end # module TypesTests From be0775cdf4657341cb926f71c13e4fcf8d250ae6 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 7 Apr 2020 16:33:48 +0200 Subject: [PATCH 13/37] SymTensorValue operations implemented #210 --- src/TensorValues/Operations.jl | 34 +++++---- src/TensorValues/SymTensorValueType.jl | 84 +++++++++++++++++++---- test/TensorValuesTests/OperationsTests.jl | 67 ++++++++++++++++-- 3 files changed, 153 insertions(+), 32 deletions(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 1cb7800fb..6cb6dfcd9 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -59,7 +59,7 @@ end # Matrix Division ############################################################### -function (\)(a::T1 where {T1<:TensorValue}, b::T2) where {T2<:MultiValue} +function (\)(a::T1 where {T1<:Union{TensorValue,SymTensorValue}}, b::T2) where {T2<:MultiValue} r = get_array(a) \ get_array(b) T2(r) end @@ -96,7 +96,7 @@ end (*)(a::VectorValue{D}, b::VectorValue{D}) where D = inner(a,b) -@generated function (*)(a::VectorValue{D1}, b::TensorValue{D2,D1}) where {D1,D2} +@generated function (*)(a::VectorValue{D1}, b::MultiValue{Tuple{D1,D2},T2,2}) where {D1,D2,T2} ss = String[] for j in 1:D2 s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) @@ -106,7 +106,7 @@ end Meta.parse("VectorValue{$D2}($str)") end -@generated function (*)(a::TensorValue{D1,D2}, b::VectorValue{D1}) where {D1,D2} +@generated function (*)(a::MultiValue{Tuple{D1,D2},T1,2}, b::VectorValue{D1}) where {D1,D2,T1} ss = String[] for j in 1:D2 s = join([ "b[$i]*a[$j,$i]+" for i in 1:D1]) @@ -116,7 +116,7 @@ end Meta.parse("VectorValue{$D2}($str)") end -@generated function (*)(a::TensorValue{D1,D2}, b::TensorValue{D3,D1}) where {D1,D2,D3} +@generated function (*)(a::MultiValue{Tuple{D1,D2},T1,2}, b::MultiValue{Tuple{D3,D2},T2,2}) where {D1,D2,D3,T1,T2} ss = String[] for j in 1:D2 for i in 1:D1 @@ -143,6 +143,11 @@ inner(a::Real,b::Real) = a*b Meta.parse(str[1:(end-1)]) end +@generated function inner(a::MultiValue{Tuple{D1,D2},T,2}, b::MultiValue{Tuple{D1,D2},T,2}) where {D1,D2,T} + str = join([" a[$i,$j]*b[$i,$j] +" for i in 1:D1 for j in 1:D2 ]) + Meta.parse(str[1:(end-1)]) +end + ############################################################### # Reductions ############################################################### @@ -174,8 +179,8 @@ end # Linear Algebra ############################################################### -det(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = det(convert(StaticArrays.SMatrix{D1,D2,T,L},a)) -inv(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = TensorValue(inv(convert(StaticArrays.SMatrix{D1,D2,T,L},a))) +det(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = det(convert(SMatrix{D1,D2,T,L},a)) +inv(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = TensorValue(inv(convert(SMatrix{D1,D2,T,L},a))) ############################################################### # Measure @@ -184,7 +189,7 @@ inv(a::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = TensorValue(inv(convert(Stati """ """ meas(a::VectorValue) = sqrt(inner(a,a)) -meas(a::TensorValue) = abs(det(a)) +meas(a::MultiValue{S,T,2,L}) where {S,T,L} = abs(det(a)) function meas(v::TensorValue{1,2}) n1 = v[1,2] @@ -209,14 +214,15 @@ end ############################################################### conj(a::VectorValue) = a +conj(a::SymTensorValue) = a conj(a::T) where {T<:TensorValue} = T(conj(get_array(a))) ############################################################### # Trace ############################################################### -@generated function tr(v::TensorValue{D}) where D - str = join([" v[$i+$((i-1)*D)] +" for i in 1:D ]) +@generated function tr(v::MultiValue{Tuple{D,D}}) where D + str = join([" v[$i,$i] +" for i in 1:D ]) Meta.parse(str[1:(end-1)]) end @@ -238,8 +244,10 @@ end # Adjoint and transpose ############################################################### -adjoint(v::T) where {T<:TensorValue} = T(adjoint(get_array(v))) -transpose(v::T) where {T<:TensorValue} = T(transpose(get_array(v))) +adjoint(arg::T) where {T<:TensorValue} = T(adjoint(get_array(arg))) +transpose(arg::T) where {T<:TensorValue} = T(transpose(get_array(arg))) +adjoint(arg::SymTensorValue) = arg +transpose(arg::SymTensorValue) = arg ############################################################### # Symmetric part @@ -247,11 +255,11 @@ transpose(v::T) where {T<:TensorValue} = T(transpose(get_array(v))) """ """ -@generated function symmetic_part(v::TensorValue{D}) where D +@generated function symmetic_part(v::MultiValue{Tuple{D,D},T,2,L}) where {D,T,L} str = "(" for j in 1:D for i in 1:D - str *= "0.5*v.data[$i+$((j-1)*D)] + 0.5*v.data[$j+$((i-1)*D)], " + str *= "0.5*v[$i,$j] + 0.5*v[$j,$i], " end end str *= ")" diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl index 5e65a4958..10b25d12f 100644 --- a/src/TensorValues/SymTensorValueType.jl +++ b/src/TensorValues/SymTensorValueType.jl @@ -52,10 +52,77 @@ SymTensorValue{D,T}(data::Real...) where {D,T} = (L=length(data);SymTensorValue{ #From Square Matrices # SymTensorValue -> b[[(D*(i-1))+j for i in 1:D for j in i:D]] +# SymTensorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor + +function _FlattenUpperTriangle(data:: + Union{ + SMatrix{D1,D2,T2,L}, + MMatrix{D1,D2,T2,L}, + AbstractMatrix{T2} + }) where {D1,D2,T1,T2,L} + PD1 = (@isdefined D1) ? D1 : size(data)[1] + PD2 = (@isdefined D2) ? D2 : size(data)[2] + [data[i,j] for i in 1:PD1 for j in i:PD2] +end + +function SymTensorValue(data:: + Union{ + SMatrix{D,D,T2,L}, + MMatrix{D,D,T2,L}, + AbstractMatrix{T2} + }) where {D,T1,T2,L} + PD1 = (@isdefined D) ? D : size(data)[1] + PD2 = (@isdefined D) ? D : size(data)[2] + @assert PD1 == PD2 + ut=_FlattenUpperTriangle(data) + SymTensorValue{PD1,T2}(NTuple{length(ut)T2}(ut)) +end + +function SymTensorValue{D}(data:: + Union{ + SMatrix{D,D,T2,L}, + MMatrix{D,D,T2,L}, + AbstractMatrix{T2} + }) where {D,T1,T2,L} + ut=_FlattenUpperTriangle(data) + SymTensorValue{D,T2}(NTuple{length(ut),T2}(ut)) +end + +function SymTensorValue{D,T1}(data:: + Union{ + SMatrix{D,D,T2,L}, + MMatrix{D,D,T2,L}, + AbstractMatrix{T2} + }) where {D,T1,T2,L} + ut=_FlattenUpperTriangle(data) + SymTensorValue{D,T1}(NTuple{length(ut),T1}(ut)) +end + +function SymTensorValue{D,T1,L1}(data:: + Union{ + SMatrix{D,D,T2,L2}, + MMatrix{D,D,T2,L2}, + AbstractMatrix{T2} + }) where {D,T1,T2,L1,L2} + ut=_FlattenUpperTriangle(data) + SymTensorValue{D,T1}(NTuple{L1,T1}(ut)) +end + ############################################################### # Conversions (SymTensorValue) ############################################################### +function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} + z = zeros(T,D,D) + vector = collect(Tuple(arg)) + for i in 1:D + index = _getindex(arg,i) + range = index:index+(D-i) + z[i,i:D] = z[i:D,i] = vector[range] + end + z +end + function convert(TT::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorValue{D,T1,L}}}, arg:: Union{ @@ -115,20 +182,9 @@ mutable(::SymTensorValue{D,T}) where {D,T} = mutable(SymTensorValue{D,T}) change_eltype(::Type{SymTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymTensorValue{D,T2,L} change_eltype(::SymTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymTensorValue{D,T1,L},T2) -function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} - z = zeros(T,D,D) - vector = collect(Tuple(arg)) - for i in 1:D - index = _getindex(arg,i) - range = index:index+(D-i) - z[i,i:D] = z[i:D,i] = vector[range] - end - z -end - -SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix{D,D,T,L}(SymTensorValueToArray(arg.data)) -SArray(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix(arg) -get_array(arg::SymTensorValue{D,T,L}) where {D,T,L} = SMatrix(arg) +SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) +SArray(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) +get_array(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) ############################################################### # Introspection (SymTensorValue) diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index 5660bd345..7130ae59b 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -2,6 +2,7 @@ module OperationsTests using Test using Gridap.TensorValues +using Gridap.Arrays using LinearAlgebra # Comparison @@ -45,14 +46,17 @@ r = VectorValue(-1,1,-3) # Matrix Division t = one(TensorValue{3,3,Int,9}) - c = t\a +@test c == a +st = one(SymTensorValue{3,Int,6}) +c = st\a @test c == a # Operations by a scalar t = TensorValue(1,2,3,4,5,6,7,8,9) +st = SymTensorValue(1,2,3,5,6,9) a = VectorValue(1,2,3) c = 2 * a @@ -94,6 +98,22 @@ c = t + 2 r = TensorValue(3, 4, 5, 6, 7, 8, 9, 10, 11) @test c == r + +c = 2 * st +@test isa(c,SymTensorValue{3}) +r = SymTensorValue(2,4,6,10,12,18) +@test c == r + +c = st * 2 +@test isa(c,SymTensorValue{3}) +r = SymTensorValue(2,4,6,10,12,18) +@test c == r + +c = st + 2 +@test isa(c,SymTensorValue{3}) +r = SymTensorValue(3,4,5,7,8,11) +@test c == r + # Dot product (simple contraction) a = VectorValue(1,2,3) @@ -101,6 +121,8 @@ b = VectorValue(2,1,6) t = TensorValue(1,2,3,4,5,6,7,8,9) s = TensorValue(9,8,3,4,5,6,7,2,1) +st = SymTensorValue(1,2,3,5,6,9) +st2 = SymTensorValue(9,6,5,3,2,1) c = a * b @test isa(c,Int) @@ -111,14 +133,24 @@ c = t * a r = VectorValue(30,36,42) @test c == r +c = st * a +@test isa(c,VectorValue{3,Int}) +r = VectorValue(14,30,42) +@test c == r + c = s * t @test isa(c,TensorValue{3,3,Int}) r = TensorValue(38,24,18,98,69,48,158,114,78) @test c == r -c = a * t +c = st * st2 +@test isa(c,TensorValue{3,3,Int}) +r = TensorValue(36, 78, 108, 18, 39, 54, 12, 26, 36) +@test c == r + +c = a * st @test isa(c,VectorValue{3,Int}) -r = VectorValue(14, 32, 50) +r = VectorValue(14,30,42) @test c == r # Inner product (full contraction) @@ -134,6 +166,10 @@ c = inner(t,s) @test isa(c,Int) @test c == 185 +c = inner(st,st2) +@test isa(c,Int) +@test c == inner(TensorValue(get_array(st)),TensorValue(get_array(st2))) + # Reductions a = VectorValue(1,2,3) @@ -189,6 +225,10 @@ c = det(t) c = inv(t) @test isa(c,TensorValue{3}) +st = SymTensorValue(9,8,7,5,4,1) +@test det(st) == det(TensorValue(get_array(st))) +@test inv(st) == inv(TensorValue(get_array(st))) + # Measure a = VectorValue(1,2,3) @@ -199,6 +239,9 @@ t = TensorValue(10,2,30,4,5,6,70,8,9) c = meas(t) @test c ≈ 8802.0 +st = SymTensorValue(1,2,3,5,6,9) +@test meas(st) == meas(TensorValue(get_array(st))) + v = TensorValue{1,2}(10,20) @test meas(v) == sqrt(500) @@ -245,13 +288,15 @@ v = VectorValue(1,0) t = TensorValue(1,2,3,4) @test tr(t) == 5 -@test tr(t) == 5 t = TensorValue(1,2,3,4,5,6,7,8,9) @test tr(t) == 15 -@test tr(t) == 15 + +st = SymTensorValue(1,2,3,5,6,9) +@test tr(st) == tr(TensorValue(get_array(st))) @test symmetic_part(t) == TensorValue(1.0, 3.0, 5.0, 3.0, 5.0, 7.0, 5.0, 7.0, 9.0) +@test symmetic_part(st) == symmetic_part(TensorValue(get_array(st))) a = TensorValue(1,2,3,4) b = a' @@ -265,6 +310,18 @@ b = a' @test b == TensorValue(1,3,2,4) @test a*b == TensorValue(10,14,14,20) +sa = SymTensorValue(1,2,3,5,6,9) +sb = sa' +@test adjoint(sa) == sb +@test sb == SymTensorValue(1,2,3,5,6,9) +@test sa*sb == TensorValue(get_array(sa))*TensorValue(get_array(sb)) + +sa = SymTensorValue(1,2,3,5,6,9) +sb = sa' +@test transpose(sa) == sb +@test sb == SymTensorValue(1,2,3,5,6,9) +@test sa*sb == TensorValue(get_array(sa))*TensorValue(get_array(sb)) + u = VectorValue(1.0,2.0) v = VectorValue(2.0,3.0) @test dot(u,v) ≈ inner(u,v) From 3b91585f34078994d10ed6490590a8dd086211aa Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 14 Apr 2020 13:07:26 +0200 Subject: [PATCH 14/37] Minor fixes in SymTensorValueType --- src/TensorValues/SymTensorValueType.jl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl index 10b25d12f..7ece7e603 100644 --- a/src/TensorValues/SymTensorValueType.jl +++ b/src/TensorValues/SymTensorValueType.jl @@ -123,11 +123,8 @@ function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} z end -function convert(TT::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorValue{D,T1,L}}}, - arg:: - Union{ - NTuple{L,T2}, - }) where {D,T1,T2,L} +function convert(::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorValue{D,T1,L}}}, + arg::NTuple{L,T2}) where {D,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 SymTensorValue{D,PT}(arg) end @@ -158,7 +155,7 @@ function convert(::Type{<:MMatrix{D,D}}, arg::SymTensorValue{D,T2,L}) where {D,T MMatrix{D,D,T2}(SymTensorValueToArray(arg)) end -function convert(T::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} +function convert(::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} PT = (@isdefined T1) ? T1 : T2 NTuple{L,PT}(arg.data) end @@ -174,7 +171,7 @@ zero(::SymTensorValue{D,T}) where {D,T} = zero(SymTensorValue{D,T}) str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D for j in i:D]) Meta.parse("SymTensorValue{D,T}(($str))") end -one(::SymTensorValue{D,T}) where {D,T} = one(TensorValue{D,T}) +one(::SymTensorValue{D,T}) where {D,T} = one(SymTensorValue{D,T}) mutable(::Type{<:SymTensorValue{D,T}}) where {D,T} = MMatrix{D,D,T} mutable(::SymTensorValue{D,T}) where {D,T} = mutable(SymTensorValue{D,T}) From 88d52ad28b1456afad94dd1808a4f5ab014cf0be Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 14 Apr 2020 13:41:38 +0200 Subject: [PATCH 15/37] Initial work with SymFourthOrderTensorValue type --- .../SymFourthOrderTensorValueType.jl | 107 ++++++++++++++++++ src/TensorValues/TensorValues.jl | 3 + 2 files changed, 110 insertions(+) create mode 100644 src/TensorValues/SymFourthOrderTensorValueType.jl diff --git a/src/TensorValues/SymFourthOrderTensorValueType.jl b/src/TensorValues/SymFourthOrderTensorValueType.jl new file mode 100644 index 000000000..d1094e1d8 --- /dev/null +++ b/src/TensorValues/SymFourthOrderTensorValueType.jl @@ -0,0 +1,107 @@ +############################################################### +# SymTensorValue Type +############################################################### + +""" +Type representing a symmetric fourth-order tensor +""" +struct SymFourthOrderTensorValue{D,T,L} <: MultiValue{Tuple{D,D,D,D},T,4,L} + data::NTuple{L,T} + function SymFourthOrderTensorValue{D,T}(data::NTuple{L,T}) where {D,T,L} + @assert L == (D*(D+1)/2)^2 + new{D,T,L}(data) + end +end + +#function _getindex(arg::SymTensorValue{D},i::Integer) where {D} +# index=((i-1)*D)-sum(1:i-1)+i +#end + +#function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} +# _j,_i=sort([i,j]) +# index=((_j-1)*D)-sum(1:_j-1)+_i +#end + + + +############################################################### +# Constructors (SymTensorValue) +############################################################### + +# Empty SymTensorValue constructor + +SymFourthOrderTensorValue() = SymFourthOrderTensorValue{0,Int}(NTuple{0,Int}()) +SymFourthOrderTensorValue{0}() where {T} = SymFourthOrderTensorValue{0,Int}(NTuple{0,Int}()) +SymFourthOrderTensorValue{0,T}() where {T} = SymFourthOrderTensorValue{0,T}(NTuple{0,T}()) +SymFourthOrderTensorValue(data::NTuple{0}) = SymFourthOrderTensorValue{0,Int}(data) +SymFourthOrderTensorValue{0}(data::NTuple{0}) = SymFourthOrderTensorValue{0,Int}(data) + +# SymTensorValue single NTuple argument constructor + +SymFourthOrderTensorValue(data::NTuple{L,T}) where {L,T} = SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2))),T}(data) +SymFourthOrderTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymFourthOrderTensorValue{D,T}(data) +SymFourthOrderTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data)) +SymFourthOrderTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data)) + +# SymTensorValue Vararg constructor + +SymFourthOrderTensorValue(data::Real...) = (L=length(data);SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2)))}(NTuple{L}(data))) +SymFourthOrderTensorValue{D}(data::Real...) where {D} = (L=length(data);SymFourthOrderTensorValue{D}(NTuple{L}(data))) +SymFourthOrderTensorValue{D,T}(data::Real...) where {D,T} = (L=length(data);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(data))) + +############################################################### +# Conversions (SymTensorValue) +############################################################### + +function convert(::Type{<:Union{SymFourthOrderTensorValue, + SymFourthOrderTensorValue{D,T1}, + SymFourthOrderTensorValue{D,T1,L}}}, + arg::NTuple{L,T2}) where {D,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + SymFourthOrderTensorValue{D,PT}(arg) +end + +function convert(::Type{<:Union{NTuple,NTuple{L,T1}}}, + arg::SymFourthOrderTensorValue{D,T2,L}) where {D,T1,T2,L} + PT = (@isdefined T1) ? T1 : T2 + NTuple{L,PT}(arg.data) +end + +############################################################### +# Other constructors and conversions (SymTensorValue) +############################################################### + +zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = (L=Int((D*(D+1)/2)^2);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(zeros(T,L)))) +zero(::SymFourthOrderTensorValue{D,T}) where {D,T} = zero(SymFourthOrderTensorValue{D,T}) + +#@generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} +# str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D for j in i:D]) +# Meta.parse("SymFourthOrderTensorValue{D,T}(($str))") +#end +#one(::SymFourthOrderTensorValue{D,T}) where {D,T} = one(TensorValue{D,T}) + +change_eltype(::Type{SymFourthOrderTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymFourthOrderTensorValue{D,T2,L} +change_eltype(::SymFourthOrderTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymFourthOrderTensorValue{D,T1,L},T2) + +############################################################### +# Introspection (SymTensorValue) +############################################################### + + +eltype(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = T +eltype(::SymFourthOrderTensorValue{D,T}) where {D,T} = eltype(SymFourthOrderTensorValue{D,T}) + +size(::Type{SymFourthOrderTensorValue{D}}) where {D} = (D,D,D,D) +size(::Type{SymFourthOrderTensorValue{D,T}}) where {D,T} = (D,D,D,D) +size(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = (D,D,D,D) +size(::SymFourthOrderTensorValue{D,T}) where {D,T} = size(SymFourthOrderTensorValue{D,T}) + +length(::Type{SymFourthOrderTensorValue{D}}) where {D} = Int((D*(D+1)/2)^2) +length(::Type{SymFourthOrderTensorValue{D,T}}) where {D,T} = length(SymFourthOrderTensorValue{D}) +length(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = L +length(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = length(SymFourthOrderTensorValue{D,T,L}) + +n_components(::Type{SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D}) +n_components(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = length(SymFourthOrderTensorValue{D,T,L}) +n_components(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = n_components(SymFourthOrderTensorValue{D,T,L}) + diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 2b4a23d58..421e9b5a6 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -40,6 +40,7 @@ export MultiValue export VectorValue export TensorValue export SymTensorValue +export SymFourthOrderTensorValue export inner, outer, meas #export det, inv, tr, dot, norm @@ -75,6 +76,8 @@ include("TensorValueType.jl") include("SymTensorValueType.jl") +include("SymFourthOrderTensorValueType.jl") + include("Misc.jl") include("Indexing.jl") From 2fbfa0acf18e0fef15ad2eb5a59987978cbad0d6 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Wed, 15 Apr 2020 11:28:56 +0200 Subject: [PATCH 16/37] Complete constructors and add indexing features for SymFourthOrderTensorValue. #210 Pending: Some operations and tests (ongoing) --- src/TensorValues/Indexing.jl | 21 ++++++++++---- src/TensorValues/Misc.jl | 2 +- .../SymFourthOrderTensorValueType.jl | 28 +++++++++---------- src/TensorValues/SymTensorValueType.jl | 6 ++-- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 9c7a937bf..19d793065 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,21 +1,30 @@ -getindex(arg::MultiValue, i::Integer) = arg.data[i] +getindex(arg::MultiValue, i::Integer) = arg.data[i] function getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} 1 <= i <= D1 || throw(BoundsError(D1, i)) - 1 <= j <= D2 || throw(BoundsError(D2, i)) - arg.data[_getindex(arg, i, j)] + 1 <= j <= D2 || throw(BoundsError(D2, j)) + getindex(arg, _getindex(arg, i, j)) end function getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} 1 <= i <= D || throw(BoundsError(D, i)) - 1 <= j <= D || throw(BoundsError(D, i)) - arg.data[_getindex(arg, i, j)] + 1 <= j <= D || throw(BoundsError(D, j)) + getindex(arg, _getindex(arg, i, j)) +end + +function getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} + 1 <= i <= D || throw(BoundsError(D, i)) + 1 <= j <= D || throw(BoundsError(D, j)) + 1 <= k <= D || throw(BoundsError(D, k)) + 1 <= l <= D || throw(BoundsError(D, l)) + getindex(arg, _getindex(arg, i, j, k, l)) end getindex(arg::VectorValue, i::CartesianIndex{1}) = getindex(arg,ci[1]) getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) -getindex(arg::SymTensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) +getindex(arg::SymTensorValue{D},ci::CartesianIndex{2}) where {D} = getindex(arg,ci[1],ci[2]) +getindex(arg::SymFourthOrderTensorValue{D},ci::CartesianIndex{4}) where {D} = getindex(arg,ci[1],ci[2],ci[3],ci[4]) @inline iterate(arg::MultiValue) = iterate(arg.data) @inline iterate(arg::MultiValue, state) = iterate(arg.data, state) diff --git a/src/TensorValues/Misc.jl b/src/TensorValues/Misc.jl index 862e054b5..e8b50660a 100644 --- a/src/TensorValues/Misc.jl +++ b/src/TensorValues/Misc.jl @@ -1,5 +1,5 @@ ############################################################### -# Other constructors and conversions implemented for more general types +# Other constructors and conversions implemented for more generic types ############################################################### change_eltype(::Type{<:Number},::Type{T}) where {T} = T diff --git a/src/TensorValues/SymFourthOrderTensorValueType.jl b/src/TensorValues/SymFourthOrderTensorValueType.jl index d1094e1d8..d58f79f4f 100644 --- a/src/TensorValues/SymFourthOrderTensorValueType.jl +++ b/src/TensorValues/SymFourthOrderTensorValueType.jl @@ -13,16 +13,14 @@ struct SymFourthOrderTensorValue{D,T,L} <: MultiValue{Tuple{D,D,D,D},T,4,L} end end -#function _getindex(arg::SymTensorValue{D},i::Integer) where {D} -# index=((i-1)*D)-sum(1:i-1)+i -#end - -#function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} -# _j,_i=sort([i,j]) -# index=((_j-1)*D)-sum(1:_j-1)+_i -#end - - +function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} + _j,_i=sort([i,j]) + _l,_k=sort([k,l]) + block_length=sum(1:D) + element_index=((_j-1)*D)-sum(1:_j-1)+_i + block_index=((_l-1)*D)-sum(1:_l-1)+_k + index=(block_index-1)*block_length+element_index +end ############################################################### # Constructors (SymTensorValue) @@ -74,11 +72,11 @@ end zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = (L=Int((D*(D+1)/2)^2);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(zeros(T,L)))) zero(::SymFourthOrderTensorValue{D,T}) where {D,T} = zero(SymFourthOrderTensorValue{D,T}) -#@generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} -# str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D for j in i:D]) -# Meta.parse("SymFourthOrderTensorValue{D,T}(($str))") -#end -#one(::SymFourthOrderTensorValue{D,T}) where {D,T} = one(TensorValue{D,T}) +@generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} + str = join(["($i==$j && $k==$l) ? one(T) : zero(T), " for i in 1:D for j in i:D for k in 1:D for l in k:D]) + Meta.parse("SymFourthOrderTensorValue{D,T}(($str))") +end +one(::SymFourthOrderTensorValue{D,T}) where {D,T} = one(SymFourthOrderTensorValue{D,T}) change_eltype(::Type{SymFourthOrderTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymFourthOrderTensorValue{D,T2,L} change_eltype(::SymFourthOrderTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymFourthOrderTensorValue{D,T1,L},T2) diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl index 7ece7e603..35b25c541 100644 --- a/src/TensorValues/SymTensorValueType.jl +++ b/src/TensorValues/SymTensorValueType.jl @@ -75,7 +75,7 @@ function SymTensorValue(data:: PD2 = (@isdefined D) ? D : size(data)[2] @assert PD1 == PD2 ut=_FlattenUpperTriangle(data) - SymTensorValue{PD1,T2}(NTuple{length(ut)T2}(ut)) + SymTensorValue{PD1,T2}(NTuple{length(ut),T2}(ut)) end function SymTensorValue{D}(data:: @@ -114,11 +114,11 @@ end function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} z = zeros(T,D,D) - vector = collect(Tuple(arg)) + data = collect(Tuple(arg)) for i in 1:D index = _getindex(arg,i) range = index:index+(D-i) - z[i,i:D] = z[i:D,i] = vector[range] + z[i,i:D] = z[i:D,i] = data[range] end z end From 939c1c9f715b81ac15b2057907a2b0ba0ae96d82 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Wed, 15 Apr 2020 17:04:32 +0200 Subject: [PATCH 17/37] Add basic +,- operations for SymFourthOrderTensorValues. Add some tests. --- src/TensorValues/Operations.jl | 14 ++++- test/TensorValuesTests/OperationsTests.jl | 16 ++++++ test/TensorValuesTests/TypesTests.jl | 62 +++++++++++++++++++++-- 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 6cb6dfcd9..82b80bce3 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -42,16 +42,26 @@ for op in (:+,:-) T(r) end - function ($op)(a::T where {T<:VectorValue{D}},b::T where {T<:VectorValue{D}}) where {D} + function ($op)(a::VectorValue{D},b::VectorValue{D}) where {D} r = broadcast(($op), a.data, b.data) VectorValue{D}(r) end - function ($op)(a::T where {T<:TensorValue{D1,D2}},b::T where {T<:TensorValue{D1,D2}}) where {D1,D2} + function ($op)(a::TensorValue{D1,D2},b::TensorValue{D1,D2}) where {D1,D2} r = broadcast(($op), a.data, b.data) TensorValue{D1,D2}(r) end + function ($op)(a::SymTensorValue{D},b::SymTensorValue{D}) where {D} + r = broadcast(($op), a.data, b.data) + SymTensorValue{D}(r) + end + + function ($op)(a::SymFourthOrderTensorValue{D},b::SymFourthOrderTensorValue{D}) where {D} + r = broadcast(($op), a.data, b.data) + SymFourthOrderTensorValue{D}(r) + end + end end diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index 7130ae59b..581d6e5ac 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -57,6 +57,7 @@ c = st\a t = TensorValue(1,2,3,4,5,6,7,8,9) st = SymTensorValue(1,2,3,5,6,9) +s4ot = one(SymFourthOrderTensorValue{2,Int}) a = VectorValue(1,2,3) c = 2 * a @@ -114,6 +115,21 @@ c = st + 2 r = SymTensorValue(3,4,5,7,8,11) @test c == r +c = 2 * s4ot +@test isa(c,SymFourthOrderTensorValue{2}) +r = SymFourthOrderTensorValue(2,0,2,0,0,0,2,0,2) +@test c == r + +c = s4ot * 2 +@test isa(c,SymFourthOrderTensorValue{2}) +r = SymFourthOrderTensorValue(2,0,2,0,0,0,2,0,2) +@test c == r + +c = s4ot + 2 +@test isa(c,SymFourthOrderTensorValue{2}) +r = SymFourthOrderTensorValue(3,2,3,2,2,2,3,2,3) +@test c == r + # Dot product (simple contraction) a = VectorValue(1,2,3) diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index a524ed42c..369a842c3 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -74,6 +74,39 @@ s = SymTensorValue{0,Int}() @test isa(s,SymTensorValue{0,Int}) @test convert(SMatrix,s) == Array{Any,2}(undef,0,0) +# Constructors (SymFourthOrderTensorValue) + +s = SymFourthOrderTensorValue( (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) ) +@test isa(s,SymFourthOrderTensorValue{2,Int}) +@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) + +s = SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +@test isa(s,SymFourthOrderTensorValue{2,Int}) +@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) + +s = SymFourthOrderTensorValue{2}( (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) ) +@test isa(s,SymFourthOrderTensorValue{2,Int}) +@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) + +s = SymFourthOrderTensorValue{2}(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +@test isa(s,SymFourthOrderTensorValue{2,Int}) +@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) + +s = SymFourthOrderTensorValue{2,Int}( (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) ) +@test isa(s,SymFourthOrderTensorValue{2,Int}) +@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) + +s = SymFourthOrderTensorValue{2,Float64}(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +@test isa(s,SymFourthOrderTensorValue{2,Float64}) +@test Tuple(s) == (1111.0,2111.0,2211.0, 1121.0,2121.0,2221.0, 1122.0,2122.0,2222.0) + +s = SymFourthOrderTensorValue{0,Int}( () ) +@test isa(s,SymFourthOrderTensorValue{0,Int}) +@test Tuple(s) == () + +s = SymFourthOrderTensorValue{0,Int}() +@test isa(s,SymFourthOrderTensorValue{0,Int}) +@test Tuple(s) == () # Constructors (VectorValue) @@ -154,6 +187,10 @@ z = zero(SymTensorValue{3,Int}) @test isa(z,SymTensorValue{3,Int,6}) @test convert(SMatrix,z) == zeros(Int,(3,3)) +z = zero(SymFourthOrderTensorValue{2,Int}) +@test isa(z,SymFourthOrderTensorValue{2,Int,9}) +@test Tuple(z) == Tuple(zeros(Int,(9))) + z = zero(VectorValue{3,Int}) @test isa(z,VectorValue{3,Int}) @test convert(SVector,z) == zeros(Int,3) @@ -164,9 +201,9 @@ z = one(TensorValue{3,3,Int,9}) s = one(z) @test convert(SMatrix,s) == [1 0 0; 0 1 0; 0 0 1] -z = one(SymTensorValue{3,Int}) -@test isa(z,SymTensorValue{3,Int,6}) -@test convert(SMatrix,z) == [1 0 0; 0 1 0; 0 0 1] +z = one(SymFourthOrderTensorValue{2,Int}) +@test isa(z,SymFourthOrderTensorValue{2,Int,9}) +@test Tuple(z) == (1,0,1, 0,0,0, 1,0,1) z = one(VectorValue{3,Int}) @test isa(z,VectorValue{3,Int}) @@ -200,6 +237,13 @@ b = convert(V,a) b = V[a,a,a,] @test isa(b,Vector{V}) +a = (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +V = SymFourthOrderTensorValue{2,Int,9} +b = convert(V,a) +@test isa(b,V) +b = V[a,a,a,] +@test isa(b,Vector{V}) + # Misc operations on the type itself V = VectorValue{3,Int} @@ -220,6 +264,10 @@ v = SymTensorValue{3,Int64}(1, 0, 0, 1, 0, 1) s = "(1, 0, 0, 1, 0, 1)" @test string(v) == s +v = SymFourthOrderTensorValue{2,Int64}(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +s = "(1111, 2111, 2211, 1121, 2121, 2221, 1122, 2122, 2222)" +@test string(v) == s + # Misc M = mutable(VectorValue{3,Int}) @@ -234,6 +282,9 @@ v = VectorValue(m) @test n_components(1) == 1 @test n_components(VectorValue{3,Float64}) == 3 @test n_components(VectorValue(1,2,3)) == 3 +@test n_components(TensorValue(1,2,3,4)) == 4 +@test n_components(SymTensorValue(1,2,3)) == 3 +@test n_components(SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222)) == 9 a = VectorValue(1,2,3,4) @test change_eltype(a,Float64) == VectorValue{4,Float64} @@ -260,4 +311,9 @@ a = SymTensorValue(11,21,22) @test isa(Tuple(a),Tuple) @test Tuple(a) == a.data +a = SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +@test change_eltype(a,Float64) == SymFourthOrderTensorValue{2,Float64,9} +@test isa(Tuple(a),Tuple) +@test Tuple(a) == a.data + end # module TypesTests From 8dc4ba490cc5d8fb9d94dfc8821280f9da6a55d7 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 16 Apr 2020 10:10:07 +0200 Subject: [PATCH 18/37] Fix typo --- src/TensorValues/Operations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 7c90921d4..d21bf2111 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -280,7 +280,7 @@ end # Define new operations for Gridap types ############################################################### -for op in (:symmetic_part,) +for op in (:symmetric_part,) @eval begin ($op)(a::GridapType) = operate($op,a) end From 739b40a9dc93ce34d8d76fddee7b9c5ee3085b6a Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Mon, 20 Apr 2020 17:35:10 +0200 Subject: [PATCH 19/37] Improve TensorValue types according @fverdugo comments. Adapt TensorValues tests to latests modifications. --- src/TensorValues/Indexing.jl | 6 +- .../SymFourthOrderTensorValueType.jl | 31 ++--- src/TensorValues/SymTensorValueType.jl | 127 ++++-------------- src/TensorValues/TensorValueType.jl | 113 ++++------------ src/TensorValues/VectorValueType.jl | 88 +++--------- test/TensorValuesTests/TypesTests.jl | 63 +++++---- 6 files changed, 117 insertions(+), 311 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 19d793065..39d5aebd7 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -21,7 +21,7 @@ function getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Int getindex(arg, _getindex(arg, i, j, k, l)) end -getindex(arg::VectorValue, i::CartesianIndex{1}) = getindex(arg,ci[1]) +getindex(arg::VectorValue, ci::CartesianIndex{1}) = getindex(arg,ci[1]) getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) getindex(arg::SymTensorValue{D},ci::CartesianIndex{2}) where {D} = getindex(arg,ci[1],ci[2]) getindex(arg::SymFourthOrderTensorValue{D},ci::CartesianIndex{4}) where {D} = getindex(arg,ci[1],ci[2],ci[3],ci[4]) @@ -31,6 +31,6 @@ getindex(arg::SymFourthOrderTensorValue{D},ci::CartesianIndex{4}) where {D} = ge eachindex(arg::MultiValue) = eachindex(arg.data) -CartesianIndices(arg::MultiValue) = CartesianIndices(get_array(arg)) +CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) -LinearIndices(arg::MultiValue) = LinearIndices(get_array(arg)) +LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) diff --git a/src/TensorValues/SymFourthOrderTensorValueType.jl b/src/TensorValues/SymFourthOrderTensorValueType.jl index d58f79f4f..9baf0bcd3 100644 --- a/src/TensorValues/SymFourthOrderTensorValueType.jl +++ b/src/TensorValues/SymFourthOrderTensorValueType.jl @@ -43,34 +43,31 @@ SymFourthOrderTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymFou # SymTensorValue Vararg constructor -SymFourthOrderTensorValue(data::Real...) = (L=length(data);SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2)))}(NTuple{L}(data))) -SymFourthOrderTensorValue{D}(data::Real...) where {D} = (L=length(data);SymFourthOrderTensorValue{D}(NTuple{L}(data))) -SymFourthOrderTensorValue{D,T}(data::Real...) where {D,T} = (L=length(data);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(data))) +SymFourthOrderTensorValue(data::T...) where {T} = (L=length(data);SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2)))}(NTuple{L}(data))) +SymFourthOrderTensorValue{D}(data::T...) where {D,T} = (L=length(data);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(data))) +SymFourthOrderTensorValue{D,T1}(data::T2...) where {D,T1,T2} = (L=length(data);SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data))) ############################################################### # Conversions (SymTensorValue) ############################################################### -function convert(::Type{<:Union{SymFourthOrderTensorValue, - SymFourthOrderTensorValue{D,T1}, - SymFourthOrderTensorValue{D,T1,L}}}, - arg::NTuple{L,T2}) where {D,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - SymFourthOrderTensorValue{D,PT}(arg) -end +# Direct conversion +convert(::Type{<:SymFourthOrderTensorValue{D,T}}, arg::Tuple) where {D,T} = SymFourthOrderTensorValue{D,T}(arg) -function convert(::Type{<:Union{NTuple,NTuple{L,T1}}}, - arg::SymFourthOrderTensorValue{D,T2,L}) where {D,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - NTuple{L,PT}(arg.data) -end +# Inverse conversion +convert(::Type{<:NTuple{L,T}}, arg::SymFourthOrderTensorValue) where {L,T} = NTuple{L,T}(Tuple(arg)) + +# Internal conversion +convert(::Type{<:SymFourthOrderTensorValue{D,T}}, arg::SymFourthOrderTensorValue{D}) where {D,T} = SymFourthOrderTensorValue{D,T}(Tuple(arg)) +convert(::Type{<:SymFourthOrderTensorValue{D,T}}, arg::SymFourthOrderTensorValue{D,T}) where {D,T} = arg ############################################################### # Other constructors and conversions (SymTensorValue) ############################################################### -zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = (L=Int((D*(D+1)/2)^2);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(zeros(T,L)))) -zero(::SymFourthOrderTensorValue{D,T}) where {D,T} = zero(SymFourthOrderTensorValue{D,T}) +zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = (L=Int((D*(D+1)/2)^2);SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{L}()))) +zero(::Type{<:SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{L}())) +zero(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = zero(SymFourthOrderTensorValue{D,T,L}) @generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} str = join(["($i==$j && $k==$l) ? one(T) : zero(T), " for i in 1:D for j in i:D for k in 1:D for l in k:D]) diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueType.jl index 35b25c541..071010ddd 100644 --- a/src/TensorValues/SymTensorValueType.jl +++ b/src/TensorValues/SymTensorValueType.jl @@ -13,7 +13,7 @@ struct SymTensorValue{D,T,L} <: MultiValue{Tuple{D,D},T,2,L} end end -function _getindex(arg::SymTensorValue{D},i::Integer) where {D} +function _get_first_row_index(arg::SymTensorValue{D},i::Integer) where {D} index=((i-1)*D)-sum(1:i-1)+i end @@ -39,74 +39,25 @@ SymTensorValue{0}(data::NTuple{0}) = SymTensorValue{0,Int}(data) # SymTensorValue single NTuple argument constructor SymTensorValue(data::NTuple{L,T}) where {L,T} = SymTensorValue{floor(Int,sqrt(L*2)),T}(data) -SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(data) +SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(NTuple{L,T}(data)) SymTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) SymTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) # SymTensorValue Vararg constructor -SymTensorValue(data::Real...) = (L=length(data);SymTensorValue{floor(Int,sqrt(L*2))}(NTuple{L}(data))) -SymTensorValue{D}(data::Real...) where {D} = (L=length(data);SymTensorValue{D}(NTuple{L}(data))) -SymTensorValue{D,T}(data::Real...) where {D,T} = (L=length(data);SymTensorValue{D,T}(NTuple{L,T}(data))) +SymTensorValue(data::T...) where {T} = SymTensorValue(Tuple(data)) +SymTensorValue{D}(data::T...) where {D,T} = SymTensorValue{D}(Tuple(data)) +SymTensorValue{D,T1}(data::T2...) where {D,T1,T2} = SymTensorValue{D,T1}(Tuple(data)) -#From Square Matrices -# SymTensorValue -> b[[(D*(i-1))+j for i in 1:D for j in i:D]] - -# SymTensorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor - -function _FlattenUpperTriangle(data:: - Union{ - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - PD1 = (@isdefined D1) ? D1 : size(data)[1] - PD2 = (@isdefined D2) ? D2 : size(data)[2] - [data[i,j] for i in 1:PD1 for j in i:PD2] -end - -function SymTensorValue(data:: - Union{ - SMatrix{D,D,T2,L}, - MMatrix{D,D,T2,L}, - AbstractMatrix{T2} - }) where {D,T1,T2,L} - PD1 = (@isdefined D) ? D : size(data)[1] - PD2 = (@isdefined D) ? D : size(data)[2] - @assert PD1 == PD2 - ut=_FlattenUpperTriangle(data) - SymTensorValue{PD1,T2}(NTuple{length(ut),T2}(ut)) -end - -function SymTensorValue{D}(data:: - Union{ - SMatrix{D,D,T2,L}, - MMatrix{D,D,T2,L}, - AbstractMatrix{T2} - }) where {D,T1,T2,L} - ut=_FlattenUpperTriangle(data) - SymTensorValue{D,T2}(NTuple{length(ut),T2}(ut)) -end +# SymTensorValue single AbstractMatrix argument constructor -function SymTensorValue{D,T1}(data:: - Union{ - SMatrix{D,D,T2,L}, - MMatrix{D,D,T2,L}, - AbstractMatrix{T2} - }) where {D,T1,T2,L} - ut=_FlattenUpperTriangle(data) - SymTensorValue{D,T1}(NTuple{length(ut),T1}(ut)) -end +#From Square Matrices +_FlattenUpperTriangle(data::AbstractArray,::Val{D}) where D = Tuple(data[i,j] for i in 1:D for j in i:D) -function SymTensorValue{D,T1,L1}(data:: - Union{ - SMatrix{D,D,T2,L2}, - MMatrix{D,D,T2,L2}, - AbstractMatrix{T2} - }) where {D,T1,T2,L1,L2} - ut=_FlattenUpperTriangle(data) - SymTensorValue{D,T1}(NTuple{L1,T1}(ut)) -end +SymTensorValue(data::AbstractMatrix{T}) where {T} = ((D1,D2)=size(data); SymTensorValue{D1}(data)) +SymTensorValue{D}(data::AbstractMatrix{T}) where {D,T} = SymTensorValue{D,T}(_FlattenUpperTriangle(data,Val{D}())) +SymTensorValue{D,T1}(data::AbstractMatrix{T2}) where {D,T1,T2} = SymTensorValue{D,T1}(_FlattenUpperTriangle(data,Val{D}())) +SymTensorValue{D,T1,L}(data::AbstractMatrix{T2}) where {D,T1,T2,L} = SymTensorValue{D,T1,L}(_FlattenUpperTriangle(data,Val{D}())) ############################################################### # Conversions (SymTensorValue) @@ -116,56 +67,33 @@ function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} z = zeros(T,D,D) data = collect(Tuple(arg)) for i in 1:D - index = _getindex(arg,i) + index = _get_first_row_index(arg,i) range = index:index+(D-i) z[i,i:D] = z[i:D,i] = data[range] end z end -function convert(::Type{<:Union{SymTensorValue,SymTensorValue{D,T1},SymTensorValue{D,T1,L}}}, - arg::NTuple{L,T2}) where {D,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - SymTensorValue{D,PT}(arg) -end +# Direct conversion +convert(::Type{<:SymTensorValue{D,T}}, arg::AbstractArray) where {D,T} = SymTensorValue{D,T}(arg) +convert(::Type{<:SymTensorValue{D,T}}, arg::Tuple) where {D,T} = SymTensorValue{D,T}(arg) -function convert(::Type{Union{SMatrix,SMatrix{D,D}}}, arg::SymTensorValue{D,T2,L2}) where {D,T1,T2,L1,L2} - PT = (@isdefined T1) ? T1 : T2 - SMatrix{D,D,PT}(SymTensorValueToArray(arg)) -end +# Inverse conversion +convert(::Type{<:SMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(SymTensorValueToArray(arg)) +convert(::Type{<:MMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(SymTensorValueToArray(arg)) +convert(::Type{<:NTuple{L,T}}, arg::SymTensorValue) where {L,T} = NTuple{L,T}(Tuple(arg)) -function convert(::Type{<:SMatrix{D,D,T1}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} - SMatrix{D,D,T1}(SymTensorValueToArray(arg)) -end - -function convert(::Type{<:SMatrix{D,D}}, arg::SymTensorValue{D,T2,L}) where {D,T2,L} - SMatrix{D,D,T2}(SymTensorValueToArray(arg)) -end - -function convert(::Type{Union{MMatrix,MMatrix{D,D,T1,L1}}}, arg::SymTensorValue{D,T2,L2}) where {D,T1,T2,L1,L2} - PT = (@isdefined T1) ? T1 : T2 - MMatrix{D,D,PT}(SymTensorValueToArray(arg)) -end - -function convert(::Type{<:MMatrix{D,D,T1}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} - MMatrix{D,D,T1}(SymTensorValueToArray(arg)) -end - -function convert(::Type{<:MMatrix{D,D}}, arg::SymTensorValue{D,T2,L}) where {D,T2,L} - MMatrix{D,D,T2}(SymTensorValueToArray(arg)) -end - -function convert(::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::SymTensorValue{D,T2,L}) where {D,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - NTuple{L,PT}(arg.data) -end +# Internal conversion +convert(::Type{<:SymTensorValue{D,T}}, arg::SymTensorValue{D}) where {D,T} = SymTensorValue{D,T}(Tuple(arg)) +convert(::Type{<:SymTensorValue{D,T}}, arg::SymTensorValue{D,T}) where {D,T} = arg ############################################################### # Other constructors and conversions (SymTensorValue) ############################################################### -zero(::Type{<:SymTensorValue{D,T}}) where {D,T} = (L=Int(D*(D+1)/2);SymTensorValue{D,T}(NTuple{L,T}(zeros(T,L)))) -zero(::SymTensorValue{D,T}) where {D,T} = zero(SymTensorValue{D,T}) +zero(::Type{<:SymTensorValue{D,T}}) where {D,T} = (L=Int(D*(D+1)/2);SymTensorValue{D,T}(tfill(zero(T),Val{L}()))) +zero(::Type{<:SymTensorValue{D,T,L}}) where {D,T,L} = SymTensorValue{D,T}(tfill(zero(T),Val{L}())) +zero(::SymTensorValue{D,T,L}) where {D,T,L} = zero(SymTensorValue{D,T,L}) @generated function one(::Type{<:SymTensorValue{D,T}}) where {D,T} str = join(["$i==$j ? one(T) : zero(T), " for i in 1:D for j in i:D]) @@ -179,15 +107,12 @@ mutable(::SymTensorValue{D,T}) where {D,T} = mutable(SymTensorValue{D,T}) change_eltype(::Type{SymTensorValue{D,T1,L}},::Type{T2}) where {D,T1,T2,L} = SymTensorValue{D,T2,L} change_eltype(::SymTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} = change_eltype(SymTensorValue{D,T1,L},T2) -SMatrix(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) -SArray(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) get_array(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, arg) ############################################################### # Introspection (SymTensorValue) ############################################################### - eltype(::Type{<:SymTensorValue{D,T}}) where {D,T} = T eltype(::SymTensorValue{D,T}) where {D,T} = eltype(SymTensorValue{D,T}) diff --git a/src/TensorValues/TensorValueType.jl b/src/TensorValues/TensorValueType.jl index cea73b8f4..0ae263dca 100644 --- a/src/TensorValues/TensorValueType.jl +++ b/src/TensorValues/TensorValueType.jl @@ -39,103 +39,42 @@ TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{ # TensorValue Vararg constructor -TensorValue(data::Real...) = TensorValue(NTuple{length(data)}(data)) -TensorValue{D}(data::Real...) where {D} = TensorValue{D,D}(NTuple{D*D}(data)) -TensorValue{D1,D2}(data::Real...) where {D1,D2} = TensorValue{D1,D2}(NTuple{D1*D2}(data)) -TensorValue{D1,D2,T}(data::Real...) where {D1,D2,T} = TensorValue{D1,D2,T}(NTuple{D1*D2,T}(data)) - -# TensorValue single SVector, MVector, SMatrix, MMatrix and AbstractMatrix argument constructor - -function TensorValue(data:: - Union{ - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - PD1 = (@isdefined D1) ? D1 : size(data)[1] - PD2 = (@isdefined D2) ? D2 : size(data)[2] - PL = (@isdefined L) ? L : length(data) - TensorValue{PD1,PD2,T2}(NTuple{PL,T2}(data)) -end - -function TensorValue{D1,D2}(data:: - Union{ - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - PL = (@isdefined L) ? L : length(data) - TensorValue{D1,D2,PT}(NTuple{PL,PT}(data)) -end +TensorValue(data::T...) where {T} = (L=length(data);D=Int(sqrt(L));TensorValue{D,D,T}(NTuple{L,T}(data))) +TensorValue{D}(data::T...) where {D,T} = (L=length(data);TensorValue{D,D,T}(NTuple{L,T}(data))) +TensorValue{D1,D2}(data::T...) where {D1,D2,T} = (L=length(data);TensorValue{D1,D2,T}(NTuple{L,T}(data))) +TensorValue{D1,D2,T1}(data::T2...) where {D1,D2,T1,T2} = (L=length(data);TensorValue{D1,D2,T1}(NTuple{L,T1}(data))) +TensorValue{D1,D2,T1,L}(data::T2...) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -function TensorValue{D1,D2,T1}(data:: - Union{ - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - PL = (@isdefined L) ? L : length(data) - TensorValue{D1,D2,T1}(NTuple{PL,T1}(data)) -end +# TensorValue single AbstractMatrix argument constructor -function TensorValue{D1,D2,T1,L}(data:: - Union{ - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L}, - AbstractMatrix{T2} - }) where {D1,D2,T1,T2,L} - TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) -end +TensorValue(data::AbstractMatrix{T}) where {T} = ((D1,D2)=size(data);L=length(data);TensorValue{D1,D2,T}(NTuple{L,T}(data))) +TensorValue{D}(data::AbstractMatrix{T}) where {D,T} = (L=length(data);TensorValue{D,D,T}(NTuple{L,T}(data))) +TensorValue{D1,D2}(data::AbstractMatrix{T}) where {D1,D2,T} = (L=length(data);TensorValue{D1,D2,T}(NTuple{L,T}(data))) +TensorValue{D1,D2,T1}(data::AbstractMatrix{T2}) where {D1,D2,T1,T2} = (L=length(data);TensorValue{D1,D2,T1}(NTuple{L,T1}(data))) +TensorValue{D1,D2,T1,L}(data::AbstractMatrix{T2}) where {D1,D2,T1,T2,L} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) ############################################################### # Conversions (TensorValue) ############################################################### -function convert(TT::Type{<:Union{TensorValue,TensorValue{D1,D2,T1},TensorValue{D1,D2,T1,L}}}, - arg:: - Union{ - NTuple{L,T2}, - SMatrix{D1,D2,T2,L}, - MMatrix{D1,D2,T2,L} - }) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - TensorValue{D1,D2,PT}(arg) -end - -function convert(T::Type{<:Union{NTuple,NTuple{L,T1}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - NTuple{L,PT}(arg.data) -end - -function convert(::Type{<:Union{SMatrix,SMatrix{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - SMatrix{D1,D2,PT,L}(arg.data) -end - -function convert(::Type{<:Union{MMatrix,MMatrix{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - MMatrix{D1,D2,PT,L}(arg.data) -end - -function convert(::Type{<:SMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - SMatrix{D1,D2,T1,L}(arg.data) -end +# Direct conversion +convert(::Type{<:TensorValue{D1,D2,T}}, arg::AbstractArray) where {D1,D2,T} = TensorValue{D1,D2,T}(arg) +convert(::Type{<:TensorValue{D1,D2,T}}, arg::Tuple) where {D1,D2,T} = TensorValue{D1,D2,T}(arg) -function convert(::Type{<:MMatrix{D1,D2,T1}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - MMatrix{D1,D2,T1,L}(arg.data) -end +# Inverse conversion +convert(::Type{<:SMatrix{D1,D2,T}}, arg::TensorValue) where {D1,D2,T} = SMatrix{D1,D2,T}(Tuple(arg)) +convert(::Type{<:MMatrix{D1,D2,T}}, arg::TensorValue) where {D1,D2,T} = MMatrix{D1,D2,T}(Tuple(arg)) +convert(::Type{<:NTuple{L,T1}}, arg::TensorValue) where {L,T1} = NTuple{L,T1}(Tuple(arg)) -function convert(::Type{<:Union{TensorValue,TensorValue{D1,D2},TensorValue{D1,D2,T1},TensorValue{D1,D2,T1,L}}}, arg::TensorValue{D1,D2,T2,L}) where {D1,D2,T1,T2,L} - PT = (@isdefined T1) ? T1 : T2 - PT == T2 ? arg : convert(TensorValue{D1,D2,T1,L}, arg.data) -end +# Internal conversion +convert(::Type{<:TensorValue{D1,D2,T}}, arg::TensorValue{D1,D2}) where {D1,D2,T} = TensorValue{D1,D2,T}(Tuple(arg)) +convert(::Type{<:TensorValue{D1,D2,T}}, arg::TensorValue{D1,D2,T}) where {D1,D2,T} = arg ############################################################### # Other constructors and conversions (TensorValue) ############################################################### -zero(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = (D=D1*D2;TensorValue{D1,D2,T}(NTuple{D,T}(zeros(T,D)))) +zero(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = TensorValue{D1,D2,T}(tfill(zero(T),Val{D1*D2}())) zero(::TensorValue{D1,D2,T}) where {D1,D2,T} = zero(TensorValue{D1,D2,T}) @generated function one(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} @@ -150,9 +89,7 @@ mutable(::TensorValue{D1,D2,T}) where {D1,D2,T} = mutable(TensorValue{D1,D2,T}) change_eltype(::Type{TensorValue{D1,D2,T1,L}},::Type{T2}) where {D1,D2,T1,T2,L} = TensorValue{D1,D2,T2,L} change_eltype(::TensorValue{D1,D2,T1,L},::Type{T2}) where {D1,D2,T1,T2,L} = change_eltype(TensorValue{D1,D2,T1,L},T2) -SMatrix(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = SMatrix{D1,D2,T,L}(arg.data) -SArray(arg::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = StaticArrays.SMatrix(arg) -get_array(arg::T where {T<:TensorValue}) = convert(SMatrix,arg) +get_array(arg::TensorValue{D1,D2,T}) where {D1,D2,T} = convert(SMatrix{D1,D2,T},arg) @generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} s = ["zero(T), " for i in 1:(D*D)] @@ -173,9 +110,7 @@ eltype(::TensorValue{D1,D2,T}) where {D1,D2,T} = eltype(TensorValue{D1,D2,T}) size(::Type{TensorValue{D}}) where {D} = (D,D) size(::Type{TensorValue{D1,D2}}) where {D1,D2} = (D1,D2) -size(::Type{TensorValue{D1,D2,T}}) where {D1,D2,T} = (D1,D2) -size(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = (D1,D2) -size(::TensorValue{D1,D2,T}) where {D1,D2,T} = size(TensorValue{D1,D2,T}) +size(::TensorValue{D1,D2}) where {D1,D2} = size(TensorValue{D1,D2}) length(::Type{TensorValue{D}}) where {D} = length(TensorValue{D,D}) length(::Type{TensorValue{D1,D2}}) where {D1,D2} = D1*D1 diff --git a/src/TensorValues/VectorValueType.jl b/src/TensorValues/VectorValueType.jl index b12cac232..a26672b57 100644 --- a/src/TensorValues/VectorValueType.jl +++ b/src/TensorValues/VectorValueType.jl @@ -32,87 +32,41 @@ VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple # VectorValue Vararg constructor -VectorValue(data::Real...) = VectorValue(NTuple{length(data)}(data)) -VectorValue{D}(data::Real...) where {D} = VectorValue{D}(NTuple{D}(data)) -VectorValue{D,T}(data::Real...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) - -# VectorValue single SVector, MVector and AbstractVector argument constructor - -function VectorValue(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - PD = (@isdefined D) ? D : length(data) - VectorValue{PD,T2}(NTuple{PD,T2}(data)) -end +VectorValue(data::T...) where {T} = (D=length(data); VectorValue{D,T}(NTuple{D,T}(data))) +VectorValue{D}(data::T...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) +VectorValue{D,T1}(data::T2...) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) -function VectorValue{D}(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - VectorValue{D,T2}(NTuple{D,T2}(data)) -end +# VectorValue single AbstractVector argument constructor -function VectorValue{D,T1}(data:: - Union{ - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - VectorValue{D,T1}(NTuple{D,T1}(data)) -end +VectorValue(data::AbstractArray{T}) where {T} = (D=length(data);VectorValue{D,T}(NTuple{D,T}(data))) +VectorValue{D}(data::AbstractArray{T}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) +VectorValue{D,T1}(data::AbstractArray{T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) ############################################################### # Conversions (VectorValue) ############################################################### -function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, - arg:: - Union{ - NTuple{D,T2}, - SVector{D,T2}, - MVector{D,T2}, - AbstractArray{T2} - }) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - PD = (@isdefined D) ? D : length(arg) - VectorValue{PD,PT}(NTuple{PD,PT}(arg)) -end +# Direct conversion +convert(::Type{<:VectorValue{D,T}}, arg:: AbstractArray) where {D,T} = VectorValue{D,T}(NTuple{D,T}(arg)) +convert(::Type{<:VectorValue{D,T}}, arg:: Tuple) where {D,T} = VectorValue{D,T}(arg) -function convert(::Type{<:Union{NTuple,NTuple{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - NTuple{D,PT}(arg.data) -end +# Inverse conversion +convert(::Type{<:AbstractArray{T}}, arg::VectorValue) where {T} = Vector{T}([Tuple(arg)...]) +convert(::Type{<:SVector{D,T}}, arg::VectorValue{D}) where {D,T} = SVector{D,T}(Tuple(arg)) +convert(::Type{<:MVector{D,T}}, arg::VectorValue{D}) where {D,T} = MVector{D,T}(Tuple(arg)) +convert(::Type{<:NTuple{D,T}}, arg::VectorValue{D}) where {D,T} = NTuple{D,T}(Tuple(arg)) -function convert(::Type{<:Union{SVector,SVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - SVector{D,PT}(arg.data) -end - -function convert(::Type{<:Union{MVector,MVector{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - MVector{D,PT}(arg.data) -end - -function convert(::Type{<:Union{VectorValue,VectorValue{D,T1}}}, arg::VectorValue{D,T2}) where {D,T1,T2} - PT = (@isdefined T1) ? T1 : T2 - PT == T2 ? arg : convert(VectorValue{D,PT}, arg.data) -end +# Internal conversion +convert(::Type{<:VectorValue{D,T}}, arg::VectorValue{D}) where {D,T} = VectorValue{D,T}(Tuple(arg)) +convert(::Type{<:VectorValue{D,T}}, arg::VectorValue{D,T}) where {D,T} = arg ############################################################### # Other constructors and conversions (VectorValue) ############################################################### -zero(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(zeros(T,D))) +zero(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(tfill(zero(T),Val{D}())) zero(::VectorValue{D,T}) where {D,T} = zero(VectorValue{D,T}) -one(::Type{<:VectorValue{D,T}}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(ones(T,D))) -one(::VectorValue{D,T}) where {D,T} = one(VectorValue{D,T}) - mutable(::Type{VectorValue{D,T}}) where {D,T} = MVector{D,T} mutable(::VectorValue{D,T}) where {D,T} = mutable(VectorValue{D,T}) @@ -120,9 +74,7 @@ change_eltype(::Type{VectorValue{D}},::Type{T}) where {D,T} = VectorValue{D,T} change_eltype(::Type{VectorValue{D,T1}},::Type{T2}) where {D,T1,T2} = VectorValue{D,T2} change_eltype(::VectorValue{D,T1},::Type{T2}) where {D,T1,T2} = change_eltype(VectorValue{D,T1},T2) -SVector(arg::VectorValue{D,T}) where {D,T} = SVector{D,T}(arg.data) -SArray(arg::VectorValue{D,T}) where {D,T} = SVector(arg) -get_array(arg::T where {T<:VectorValue}) = convert(SVector,arg) +get_array(arg::VectorValue{D,T}) where {D,T} = convert(SVector{D,T}, arg) ############################################################### # Introspection (VectorValue) diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index 369a842c3..0315819e7 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -9,42 +9,42 @@ using StaticArrays a = SMatrix{2,2}(1,2,3,4) t = TensorValue(a) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix{2,2},t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] a = MMatrix{2,2}(1,2,3,4) t = TensorValue(a) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix,t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] t = TensorValue{2}((1,2,3,4)) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix{2,2},t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] t = TensorValue{2}(1,2,3,4) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix{2,2},t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] t = TensorValue(1,2,3,4) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix{2,2},t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] t = TensorValue((1,2,3,4)) @test isa(t,TensorValue{2,2,Int}) -@test convert(SMatrix{2,2},t) == [1 3;2 4] +@test convert(SMatrix{2,2,Int},t) == [1 3;2 4] t = TensorValue{1}(10) @test isa(t,TensorValue{1,1,Int}) -@test convert(SMatrix{1,1},t) == 10*ones(1,1) +@test convert(SMatrix{1,1,Int},t) == 10*ones(1,1) t = TensorValue{1}((10,)) @test isa(t,TensorValue{1,1,Int}) -@test convert(SMatrix,t) == 10*ones(1,1) +@test convert(SMatrix{1,1,Int},t) == 10*ones(1,1) # Constructors (SymTensorValue) s = SymTensorValue( (11,21,22) ) @test isa(s,SymTensorValue{2,Int}) -@test convert(SMatrix{2,2},s) == [11 21;21 22] +@test convert(SMatrix{2,2,Int},s) == [11 21;21 22] s = SymTensorValue(11,21,22) @test isa(s,SymTensorValue{2,Int}) @@ -52,7 +52,7 @@ s = SymTensorValue(11,21,22) s = SymTensorValue{2}( (11,21,22) ) @test isa(s,SymTensorValue{2,Int}) -@test convert(SMatrix,s) == [11 21;21 22] +@test convert(SMatrix{2,2,Int},s) == [11 21;21 22] s = SymTensorValue{2}(11,21,22) @test isa(s,SymTensorValue{2,Int}) @@ -60,7 +60,7 @@ s = SymTensorValue{2}(11,21,22) s = SymTensorValue{2,Int}( (11,21,22) ) @test isa(s,SymTensorValue{2,Int}) -@test convert(SMatrix,s) == [11 21;21 22] +@test convert(SMatrix{2,2,Int},s) == [11 21;21 22] s = SymTensorValue{2,Float64}(11,21,22) @test isa(s,SymTensorValue{2,Float64}) @@ -68,11 +68,11 @@ s = SymTensorValue{2,Float64}(11,21,22) s = SymTensorValue{0,Int}( () ) @test isa(s,SymTensorValue{0,Int}) -@test convert(SMatrix{0,0},s) == Array{Any,2}(undef,0,0) +@test convert(SMatrix{0,0,Int},s) == Array{Any,2}(undef,0,0) s = SymTensorValue{0,Int}() @test isa(s,SymTensorValue{0,Int}) -@test convert(SMatrix,s) == Array{Any,2}(undef,0,0) +@test convert(SMatrix{0,0,Int},s) == Array{Any,2}(undef,0,0) # Constructors (SymFourthOrderTensorValue) @@ -110,28 +110,29 @@ s = SymFourthOrderTensorValue{0,Int}() # Constructors (VectorValue) + a = SVector(1) g = VectorValue(a) @test isa(g,VectorValue{1,Int}) -@test convert(SVector,g) == [1,] +@test convert(SVector{1,Int},g) == [1,] a = SVector(1,2,3,4) g = VectorValue(a) @test isa(g,VectorValue{4,Int}) -@test convert(SVector,g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] a = MVector(1,2,3,4) g = VectorValue(a) @test isa(g,VectorValue{4,Int}) -@test convert(MVector,g) == [1,2,3,4] +@test convert(MVector{4,Int},g) == [1,2,3,4] g = VectorValue{4}((1,2,3,4)) @test isa(g,VectorValue{4,Int}) -@test convert(SVector{4},g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] g = VectorValue{1}((1,)) @test isa(g,VectorValue{1,Int}) -@test convert(SVector{1},g) == [1,] +@test convert(SVector{1,Int},g) == [1,] g = VectorValue{0,Int}(()) @test isa(g,VectorValue{0,Int}) @@ -139,11 +140,11 @@ g = VectorValue{0,Int}(()) g = VectorValue{4}(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test convert(SVector{4},g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] g = VectorValue{1}(1) @test isa(g,VectorValue{1,Int}) -@test convert(SVector{1},g) == [1,] +@test convert(SVector{1,Int},g) == [1,] g = VectorValue{1,Float64}(1) @test isa(g,VectorValue{1,Float64}) @@ -159,7 +160,7 @@ g = VectorValue{4,Float64}((1,2,3,4)) g = VectorValue{4}(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test convert(SVector{4},g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] g = VectorValue{4,Float64}(1,2,3,4) @test isa(g,VectorValue{4,Float64}) @@ -167,25 +168,25 @@ g = VectorValue{4,Float64}(1,2,3,4) g = VectorValue(1,2,3,4) @test isa(g,VectorValue{4,Int}) -@test convert(SVector,g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] g = VectorValue((1,2,3,4)) @test isa(g,VectorValue{4,Int}) -@test convert(SVector,g) == [1,2,3,4] +@test convert(SVector{4,Int},g) == [1,2,3,4] g = VectorValue(1) @test isa(g,VectorValue{1,Int}) -@test convert(SVector,g) == [1,] +@test convert(SVector{1,Int},g) == [1,] # Initializers z = zero(TensorValue{3,3,Int,9}) @test isa(z,TensorValue{3,3,Int,9}) -@test convert(SMatrix,z) == zeros(Int,(3,3)) +@test convert(SMatrix{3,3,Int},z) == zeros(Int,(3,3)) z = zero(SymTensorValue{3,Int}) @test isa(z,SymTensorValue{3,Int,6}) -@test convert(SMatrix,z) == zeros(Int,(3,3)) +@test convert(SMatrix{3,3,Int},z) == zeros(Int,(3,3)) z = zero(SymFourthOrderTensorValue{2,Int}) @test isa(z,SymFourthOrderTensorValue{2,Int,9}) @@ -193,22 +194,18 @@ z = zero(SymFourthOrderTensorValue{2,Int}) z = zero(VectorValue{3,Int}) @test isa(z,VectorValue{3,Int}) -@test convert(SVector,z) == zeros(Int,3) +@test convert(SVector{3,Int},z) == zeros(Int,3) z = one(TensorValue{3,3,Int,9}) @test isa(z,TensorValue{3,3,Int,9}) -@test convert(SMatrix,z) == [1 0 0; 0 1 0; 0 0 1] +@test convert(SMatrix{3,3,Int},z) == [1 0 0; 0 1 0; 0 0 1] s = one(z) -@test convert(SMatrix,s) == [1 0 0; 0 1 0; 0 0 1] +@test convert(SMatrix{3,3,Int},s) == [1 0 0; 0 1 0; 0 0 1] z = one(SymFourthOrderTensorValue{2,Int}) @test isa(z,SymFourthOrderTensorValue{2,Int,9}) @test Tuple(z) == (1,0,1, 0,0,0, 1,0,1) -z = one(VectorValue{3,Int}) -@test isa(z,VectorValue{3,Int}) -@test convert(SVector,z) == ones(Int,3) - # Conversions a = @SVector ones(Int,3) From 4302358192a2c0f042a35dfc3ab454ca1f523216 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 21 Apr 2020 11:04:23 +0200 Subject: [PATCH 20/37] Adapt LinearIndex access for MultiValue as @fverdugo requests --- src/TensorValues/Indexing.jl | 43 ++++++++++++------------------------ 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 39d5aebd7..775295988 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,36 +1,21 @@ -getindex(arg::MultiValue, i::Integer) = arg.data[i] - -function getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} - 1 <= i <= D1 || throw(BoundsError(D1, i)) - 1 <= j <= D2 || throw(BoundsError(D2, j)) - getindex(arg, _getindex(arg, i, j)) -end - -function getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} - 1 <= i <= D || throw(BoundsError(D, i)) - 1 <= j <= D || throw(BoundsError(D, j)) - getindex(arg, _getindex(arg, i, j)) -end +eachindex(arg::MultiValue) = eachindex(arg.data) -function getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} - 1 <= i <= D || throw(BoundsError(D, i)) - 1 <= j <= D || throw(BoundsError(D, j)) - 1 <= k <= D || throw(BoundsError(D, k)) - 1 <= l <= D || throw(BoundsError(D, l)) - getindex(arg, _getindex(arg, i, j, k, l)) -end +CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) -getindex(arg::VectorValue, ci::CartesianIndex{1}) = getindex(arg,ci[1]) -getindex(arg::TensorValue{D1,D2},ci::CartesianIndex{2}) where {D1,D2} = getindex(arg,ci[1],ci[2]) -getindex(arg::SymTensorValue{D},ci::CartesianIndex{2}) where {D} = getindex(arg,ci[1],ci[2]) -getindex(arg::SymFourthOrderTensorValue{D},ci::CartesianIndex{4}) where {D} = getindex(arg,ci[1],ci[2],ci[3],ci[4]) +LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) -@inline iterate(arg::MultiValue) = iterate(arg.data) -@inline iterate(arg::MultiValue, state) = iterate(arg.data, state) +getindex(arg::VectorValue, i::Integer) = arg.data[i] +getindex(arg::TensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] +getindex(arg::SymTensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] +getindex(arg::SymFourthOrderTensorValue,i::Integer,j::Integer,k::Integer,l::Integer) = arg.data[_getindex(arg, i, j, k, l)] -eachindex(arg::MultiValue) = eachindex(arg.data) +getindex(arg::VectorValue, ci::CartesianIndex{1}) = getindex(arg,ci[1]) +getindex(arg::TensorValue,ci::CartesianIndex{2}) = getindex(arg,ci[1],ci[2]) +getindex(arg::SymTensorValue,ci::CartesianIndex{2}) = getindex(arg,ci[1],ci[2]) +getindex(arg::SymFourthOrderTensorValue,ci::CartesianIndex{4}) = getindex(arg,ci[1],ci[2],ci[3],ci[4]) -CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) +getindex(arg::MultiValue, i::Integer) = getindex(arg, CartesianIndices(arg)[i]) -LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) +@inline iterate(arg::MultiValue) = iterate(arg.data) +@inline iterate(arg::MultiValue, state) = iterate(arg.data, state) From 9f3eec4c822ca114e91043aeff3ff42d3fe8d2ba Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 21 Apr 2020 12:28:08 +0200 Subject: [PATCH 21/37] Fix eachindex function and tests for multivalues indexing --- src/TensorValues/Indexing.jl | 2 +- test/TensorValuesTests/IndexingTests.jl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 775295988..d6ef66438 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -1,5 +1,5 @@ -eachindex(arg::MultiValue) = eachindex(arg.data) +eachindex(arg::MultiValue) = eachindex(1:prod(size(arg))) CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) diff --git a/test/TensorValuesTests/IndexingTests.jl b/test/TensorValuesTests/IndexingTests.jl index 11fdaa6a4..517e90b74 100644 --- a/test/TensorValuesTests/IndexingTests.jl +++ b/test/TensorValuesTests/IndexingTests.jl @@ -35,22 +35,22 @@ for (k,ti) in enumerate(t) @test ti == a[k] end -sv = VectorValue(11,21,22) s = SymTensorValue{2}(11,21,22) +t = TensorValue(convert(SMatrix{2,2,Int},s)) @test size(s) == (2,2) @test length(s) == 3 -for (k,i) in enumerate(eachindex(s)) - @test s[i] == sv[k] +for (k,i) in enumerate(eachindex(t)) + @test s[i] == t[k] end @test s[2,1] == 21 @test s[2] == 21 -for (k,si) in enumerate(s) - @test si == sv[k] +for (k,si) in enumerate(t) + @test si == s[k] end v = @SMatrix zeros(2,3) From 739077f7ea68961d663a7a2a351e00d35949cbfc Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Tue, 21 Apr 2020 13:15:36 +0200 Subject: [PATCH 22/37] Rename files according @fverdugo comments --- .../{MultiValueType.jl => MultiValueTypes.jl} | 0 ...rValueType.jl => SymFourthOrderTensorValueTypes.jl} | 0 .../{SymTensorValueType.jl => SymTensorValueTypes.jl} | 0 .../{TensorValueType.jl => TensorValueTypes.jl} | 0 src/TensorValues/TensorValues.jl | 10 +++++----- .../{VectorValueType.jl => VectorValueTypes.jl} | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename src/TensorValues/{MultiValueType.jl => MultiValueTypes.jl} (100%) rename src/TensorValues/{SymFourthOrderTensorValueType.jl => SymFourthOrderTensorValueTypes.jl} (100%) rename src/TensorValues/{SymTensorValueType.jl => SymTensorValueTypes.jl} (100%) rename src/TensorValues/{TensorValueType.jl => TensorValueTypes.jl} (100%) rename src/TensorValues/{VectorValueType.jl => VectorValueTypes.jl} (100%) diff --git a/src/TensorValues/MultiValueType.jl b/src/TensorValues/MultiValueTypes.jl similarity index 100% rename from src/TensorValues/MultiValueType.jl rename to src/TensorValues/MultiValueTypes.jl diff --git a/src/TensorValues/SymFourthOrderTensorValueType.jl b/src/TensorValues/SymFourthOrderTensorValueTypes.jl similarity index 100% rename from src/TensorValues/SymFourthOrderTensorValueType.jl rename to src/TensorValues/SymFourthOrderTensorValueTypes.jl diff --git a/src/TensorValues/SymTensorValueType.jl b/src/TensorValues/SymTensorValueTypes.jl similarity index 100% rename from src/TensorValues/SymTensorValueType.jl rename to src/TensorValues/SymTensorValueTypes.jl diff --git a/src/TensorValues/TensorValueType.jl b/src/TensorValues/TensorValueTypes.jl similarity index 100% rename from src/TensorValues/TensorValueType.jl rename to src/TensorValues/TensorValueTypes.jl diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 0eaf95359..feb869a51 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -68,15 +68,15 @@ import LinearAlgebra: det, inv, tr, dot, norm import Gridap.Arrays: get_array -include("MultiValueType.jl") +include("MultiValueTypes.jl") -include("VectorValueType.jl") +include("VectorValueTypes.jl") -include("TensorValueType.jl") +include("TensorValueTypes.jl") -include("SymTensorValueType.jl") +include("SymTensorValueTypes.jl") -include("SymFourthOrderTensorValueType.jl") +include("SymFourthOrderTensorValueTypes.jl") include("Misc.jl") diff --git a/src/TensorValues/VectorValueType.jl b/src/TensorValues/VectorValueTypes.jl similarity index 100% rename from src/TensorValues/VectorValueType.jl rename to src/TensorValues/VectorValueTypes.jl From 4f2cc69cf06b4eba46e3c59ae9e061481ba99582 Mon Sep 17 00:00:00 2001 From: victorsndvg Date: Thu, 23 Apr 2020 13:59:57 +0200 Subject: [PATCH 23/37] Add changes discussed in latest meeting. Ready to PR --- src/TensorValues/Indexing.jl | 25 +++++++++ src/TensorValues/Operations.jl | 1 + .../SymFourthOrderTensorValueTypes.jl | 26 +++------ src/TensorValues/SymTensorValueTypes.jl | 53 +++++++------------ src/TensorValues/TensorValueTypes.jl | 22 +++----- src/TensorValues/VectorValueTypes.jl | 15 +++--- test/TensorValuesTests/IndexingTests.jl | 2 +- test/TensorValuesTests/TypesTests.jl | 4 +- 8 files changed, 67 insertions(+), 81 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index d6ef66438..44f83bc64 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -5,6 +5,31 @@ CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) +_symmetric_index_gaps(i::Integer) = i*(i-1)÷2 + +_get_linear_index(D::Integer,i::Integer,j::Integer) = ((j-1)*D)+i + +function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} + index=_get_linear_index(D1,i,j) +end + +function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} + _j=min(i,j) + _i=max(i,j) + index=_get_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) +end + +function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} + _j=min(i,j) + _i=max(i,j) + _l=min(k,l) + _k=max(k,l) + block_length=_symmetric_index_gaps(D+1) + element_index=_get_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) + block_index=_get_linear_index(D,_l,_k)-_symmetric_index_gaps(_l) + index=(block_index-1)*block_length+element_index +end + getindex(arg::VectorValue, i::Integer) = arg.data[i] getindex(arg::TensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] getindex(arg::SymTensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index d21bf2111..f7527d9e5 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -189,6 +189,7 @@ end # Linear Algebra ############################################################### +#TODO: write det and inv function for small specific cases. det(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = det(convert(SMatrix{D1,D2,T,L},a)) inv(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = TensorValue(inv(convert(SMatrix{D1,D2,T,L},a))) diff --git a/src/TensorValues/SymFourthOrderTensorValueTypes.jl b/src/TensorValues/SymFourthOrderTensorValueTypes.jl index 9baf0bcd3..3e7e3fcc2 100644 --- a/src/TensorValues/SymFourthOrderTensorValueTypes.jl +++ b/src/TensorValues/SymFourthOrderTensorValueTypes.jl @@ -13,15 +13,6 @@ struct SymFourthOrderTensorValue{D,T,L} <: MultiValue{Tuple{D,D,D,D},T,4,L} end end -function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} - _j,_i=sort([i,j]) - _l,_k=sort([k,l]) - block_length=sum(1:D) - element_index=((_j-1)*D)-sum(1:_j-1)+_i - block_index=((_l-1)*D)-sum(1:_l-1)+_k - index=(block_index-1)*block_length+element_index -end - ############################################################### # Constructors (SymTensorValue) ############################################################### @@ -86,17 +77,12 @@ change_eltype(::SymFourthOrderTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} eltype(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = T eltype(::SymFourthOrderTensorValue{D,T}) where {D,T} = eltype(SymFourthOrderTensorValue{D,T}) -size(::Type{SymFourthOrderTensorValue{D}}) where {D} = (D,D,D,D) -size(::Type{SymFourthOrderTensorValue{D,T}}) where {D,T} = (D,D,D,D) -size(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = (D,D,D,D) -size(::SymFourthOrderTensorValue{D,T}) where {D,T} = size(SymFourthOrderTensorValue{D,T}) +size(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = (D,D,D,D) +size(::SymFourthOrderTensorValue{D}) where {D} = size(SymFourthOrderTensorValue{D}) -length(::Type{SymFourthOrderTensorValue{D}}) where {D} = Int((D*(D+1)/2)^2) -length(::Type{SymFourthOrderTensorValue{D,T}}) where {D,T} = length(SymFourthOrderTensorValue{D}) -length(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = L -length(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = length(SymFourthOrderTensorValue{D,T,L}) +length(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = D*D*D*D +length(::SymFourthOrderTensorValue{D}) where {D} = length(SymFourthOrderTensorValue{D}) -n_components(::Type{SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D}) -n_components(::Type{SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = length(SymFourthOrderTensorValue{D,T,L}) -n_components(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = n_components(SymFourthOrderTensorValue{D,T,L}) +n_components(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D}) +n_components(::SymFourthOrderTensorValue{D}) where {D} = n_components(SymFourthOrderTensorValue{D}) diff --git a/src/TensorValues/SymTensorValueTypes.jl b/src/TensorValues/SymTensorValueTypes.jl index 071010ddd..e733108af 100644 --- a/src/TensorValues/SymTensorValueTypes.jl +++ b/src/TensorValues/SymTensorValueTypes.jl @@ -13,17 +13,6 @@ struct SymTensorValue{D,T,L} <: MultiValue{Tuple{D,D},T,2,L} end end -function _get_first_row_index(arg::SymTensorValue{D},i::Integer) where {D} - index=((i-1)*D)-sum(1:i-1)+i -end - -function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} - _j,_i=sort([i,j]) - index=((_j-1)*D)-sum(1:_j-1)+_i -end - - - ############################################################### # Constructors (SymTensorValue) ############################################################### @@ -52,24 +41,23 @@ SymTensorValue{D,T1}(data::T2...) where {D,T1,T2} = SymTensorValue{D,T1}(Tuple(d # SymTensorValue single AbstractMatrix argument constructor #From Square Matrices -_FlattenUpperTriangle(data::AbstractArray,::Val{D}) where D = Tuple(data[i,j] for i in 1:D for j in i:D) +_flatten_upper_triangle(data::AbstractArray,::Val{D}) where D = Tuple(data[i,j] for i in 1:D for j in i:D) SymTensorValue(data::AbstractMatrix{T}) where {T} = ((D1,D2)=size(data); SymTensorValue{D1}(data)) -SymTensorValue{D}(data::AbstractMatrix{T}) where {D,T} = SymTensorValue{D,T}(_FlattenUpperTriangle(data,Val{D}())) -SymTensorValue{D,T1}(data::AbstractMatrix{T2}) where {D,T1,T2} = SymTensorValue{D,T1}(_FlattenUpperTriangle(data,Val{D}())) -SymTensorValue{D,T1,L}(data::AbstractMatrix{T2}) where {D,T1,T2,L} = SymTensorValue{D,T1,L}(_FlattenUpperTriangle(data,Val{D}())) +SymTensorValue{D}(data::AbstractMatrix{T}) where {D,T} = SymTensorValue{D,T}(_flatten_upper_triangle(data,Val{D}())) +SymTensorValue{D,T1}(data::AbstractMatrix{T2}) where {D,T1,T2} = SymTensorValue{D,T1}(_flatten_upper_triangle(data,Val{D}())) +SymTensorValue{D,T1,L}(data::AbstractMatrix{T2}) where {D,T1,T2,L} = SymTensorValue{D,T1,L}(_flatten_upper_triangle(data,Val{D}())) ############################################################### # Conversions (SymTensorValue) ############################################################### -function SymTensorValueToArray(arg::SymTensorValue{D,T,L}) where {D,T,L} - z = zeros(T,D,D) - data = collect(Tuple(arg)) - for i in 1:D - index = _get_first_row_index(arg,i) - range = index:index+(D-i) - z[i,i:D] = z[i:D,i] = data[range] +function _SymTensorValue_to_array(arg::SymTensorValue{D,T,L}) where {D,T,L} + z = zeros(MMatrix{D,D,T}) + for j in 1:D + for i in j:D + z[j,i] = z[i,j] = arg[i,j] + end end z end @@ -79,8 +67,8 @@ convert(::Type{<:SymTensorValue{D,T}}, arg::AbstractArray) where {D,T} = SymTens convert(::Type{<:SymTensorValue{D,T}}, arg::Tuple) where {D,T} = SymTensorValue{D,T}(arg) # Inverse conversion -convert(::Type{<:SMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(SymTensorValueToArray(arg)) -convert(::Type{<:MMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(SymTensorValueToArray(arg)) +convert(::Type{<:MMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = _SymTensorValue_to_array(arg) +convert(::Type{<:SMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(_SymTensorValue_to_array(arg)) convert(::Type{<:NTuple{L,T}}, arg::SymTensorValue) where {L,T} = NTuple{L,T}(Tuple(arg)) # Internal conversion @@ -116,17 +104,12 @@ get_array(arg::SymTensorValue{D,T,L}) where {D,T,L} = convert(SMatrix{D,D,T}, ar eltype(::Type{<:SymTensorValue{D,T}}) where {D,T} = T eltype(::SymTensorValue{D,T}) where {D,T} = eltype(SymTensorValue{D,T}) -size(::Type{SymTensorValue{D}}) where {D} = (D,D) -size(::Type{SymTensorValue{D,T}}) where {D,T} = (D,D) -size(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = (D,D) -size(::SymTensorValue{D,T}) where {D,T} = size(SymTensorValue{D,T}) +size(::Type{<:SymTensorValue{D}}) where {D} = (D,D) +size(::SymTensorValue{D}) where {D} = size(SymTensorValue{D}) -length(::Type{SymTensorValue{D}}) where {D} = Int(D*(D+1)/2) -length(::Type{SymTensorValue{D,T}}) where {D,T} = length(SymTensorValue{D}) -length(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = L -length(::SymTensorValue{D,T,L}) where {D,T,L} = length(SymTensorValue{D,T,L}) +length(::Type{<:SymTensorValue{D}}) where {D} = D*D +length(::SymTensorValue{D}) where {D} = length(SymTensorValue{D}) -n_components(::Type{SymTensorValue{D}}) where {D} = length(SymTensorValue{D}) -n_components(::Type{SymTensorValue{D,T,L}}) where {D,T,L} = length(SymTensorValue{D,T,L}) -n_components(::SymTensorValue{D,T,L}) where {D,T,L} = n_components(SymTensorValue{D,T,L}) +n_components(::Type{<:SymTensorValue{D}}) where {D} = length(SymTensorValue{D}) +n_components(::SymTensorValue{D}) where {D} = n_components(SymTensorValue{D}) diff --git a/src/TensorValues/TensorValueTypes.jl b/src/TensorValues/TensorValueTypes.jl index 0ae263dca..11d3f8913 100644 --- a/src/TensorValues/TensorValueTypes.jl +++ b/src/TensorValues/TensorValueTypes.jl @@ -13,10 +13,6 @@ struct TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L} end end -function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} - index=((j-1)*D1)+i -end - ############################################################### # Constructors ############################################################### @@ -108,17 +104,15 @@ end eltype(::Type{<:TensorValue{D1,D2,T}}) where {D1,D2,T} = T eltype(::TensorValue{D1,D2,T}) where {D1,D2,T} = eltype(TensorValue{D1,D2,T}) -size(::Type{TensorValue{D}}) where {D} = (D,D) -size(::Type{TensorValue{D1,D2}}) where {D1,D2} = (D1,D2) +size(::Type{<:TensorValue{D}}) where {D} = (D,D) +size(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = (D1,D2) size(::TensorValue{D1,D2}) where {D1,D2} = size(TensorValue{D1,D2}) -length(::Type{TensorValue{D}}) where {D} = length(TensorValue{D,D}) -length(::Type{TensorValue{D1,D2}}) where {D1,D2} = D1*D1 -length(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = L -length(::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = length(TensorValue{D1,D2,T,L}) +length(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D}) +length(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = D1*D1 +length(::TensorValue{D1,D2}) where {D1,D2} = length(TensorValue{D1,D2}) -n_components(::Type{TensorValue{D}}) where {D} = length(TensorValue{D,D}) -n_components(::Type{TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2}) -n_components(::Type{TensorValue{D1,D2,T,L}}) where {D1,D2,T,L} = length(TensorValue{D1,D2,T,L}) -n_components(::TensorValue{D1,D2,T,L}) where {D1,D2,T,L} = n_components(TensorValue{D1,D2,T,L}) +n_components(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D}) +n_components(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2}) +n_components(::TensorValue{D1,D2}) where {D1,D2} = n_components(TensorValue{D1,D2}) diff --git a/src/TensorValues/VectorValueTypes.jl b/src/TensorValues/VectorValueTypes.jl index a26672b57..b0bd44303 100644 --- a/src/TensorValues/VectorValueTypes.jl +++ b/src/TensorValues/VectorValueTypes.jl @@ -83,15 +83,12 @@ get_array(arg::VectorValue{D,T}) where {D,T} = convert(SVector{D,T}, arg) eltype(::Type{<:VectorValue{D,T}}) where {D,T} = T eltype(arg::VectorValue{D,T}) where {D,T} = eltype(VectorValue{D,T}) -size(::Type{VectorValue{D}}) where {D} = (D,) -size(::Type{VectorValue{D,T}}) where {D,T} = (D,) -size(::VectorValue{D,T}) where {D,T} = size(VectorValue{D,T}) +size(::Type{<:VectorValue{D}}) where {D} = (D,) +size(::VectorValue{D}) where {D} = size(VectorValue{D}) -length(::Type{VectorValue{D}}) where {D} = D -length(::Type{VectorValue{D,T}}) where {D,T} = D -length(::VectorValue{D,T}) where {D,T} = length(VectorValue{D,T}) +length(::Type{<:VectorValue{D}}) where {D} = D +length(::VectorValue{D}) where {D} = length(VectorValue{D}) -n_components(::Type{VectorValue{D}}) where {D} = length(VectorValue{D}) -n_components(::Type{VectorValue{D,T}}) where {D,T} = length(VectorValue{D,T}) -n_components(::VectorValue{D,T}) where {D,T} = n_components(VectorValue{D,T}) +n_components(::Type{<:VectorValue{D}}) where {D} = length(VectorValue{D}) +n_components(::VectorValue{D}) where {D} = n_components(VectorValue{D}) diff --git a/test/TensorValuesTests/IndexingTests.jl b/test/TensorValuesTests/IndexingTests.jl index 517e90b74..94d1e3a75 100644 --- a/test/TensorValuesTests/IndexingTests.jl +++ b/test/TensorValuesTests/IndexingTests.jl @@ -39,7 +39,7 @@ s = SymTensorValue{2}(11,21,22) t = TensorValue(convert(SMatrix{2,2,Int},s)) @test size(s) == (2,2) -@test length(s) == 3 +@test length(s) == 4 for (k,i) in enumerate(eachindex(t)) @test s[i] == t[k] diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index 0315819e7..0d5b65810 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -280,8 +280,8 @@ v = VectorValue(m) @test n_components(VectorValue{3,Float64}) == 3 @test n_components(VectorValue(1,2,3)) == 3 @test n_components(TensorValue(1,2,3,4)) == 4 -@test n_components(SymTensorValue(1,2,3)) == 3 -@test n_components(SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222)) == 9 +@test n_components(SymTensorValue(1,2,3)) == 4 +@test n_components(SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222)) == 16 a = VectorValue(1,2,3,4) @test change_eltype(a,Float64) == VectorValue{4,Float64} From 13703756175302088827c395747e8049c5ba8ed2 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Fri, 22 May 2020 15:17:26 +0200 Subject: [PATCH 24/37] Make refactoring of tensor values work --- src/Fields/DiffOperators.jl | 14 +- src/TensorValues/Operations.jl | 28 +- src/TensorValues/TensorValues.jl | 4 +- .../ThirdOrderTensorValueTypes.jl | 36 +++ src/TensorValues/Types.jl | 264 ------------------ src/TensorValues/VectorValueTypes.jl | 2 +- 6 files changed, 62 insertions(+), 286 deletions(-) create mode 100644 src/TensorValues/ThirdOrderTensorValueTypes.jl delete mode 100644 src/TensorValues/Types.jl diff --git a/src/Fields/DiffOperators.jl b/src/Fields/DiffOperators.jl index 89b941dde..e8d25d25a 100644 --- a/src/Fields/DiffOperators.jl +++ b/src/Fields/DiffOperators.jl @@ -118,11 +118,11 @@ function gradient(f::Function) end function _grad_f(f,x,fx) - VectorValue(ForwardDiff.gradient(f,x.array)) + VectorValue(ForwardDiff.gradient(f,get_array(x))) end function _grad_f(f,x,fx::VectorValue) - TensorValue(transpose(ForwardDiff.jacobian(y->f(y).array,x.array))) + TensorValue(transpose(ForwardDiff.jacobian(y->get_array(f(y)),get_array(x)))) end function _grad_f(f,x,fx::MultiValue) @@ -130,11 +130,11 @@ function _grad_f(f,x,fx::MultiValue) end function divergence(f::Function) - x -> tr(ForwardDiff.jacobian(y->f(y).array,x.array)) + x -> tr(ForwardDiff.jacobian(y->get_array(f(y)),get_array(x))) end function curl(f::Function) - x -> grad2curl(TensorValue(transpose(ForwardDiff.jacobian(y->f(y).array,x.array)))) + x -> grad2curl(TensorValue(transpose(ForwardDiff.jacobian(y->get_array(f(y)),get_array(x))))) end function laplacian(f::Function) @@ -144,14 +144,14 @@ function laplacian(f::Function) end function _lapl_f(f,x,fx) - tr(ForwardDiff.jacobian(y->ForwardDiff.gradient(f,y), x.array)) + tr(ForwardDiff.jacobian(y->ForwardDiff.gradient(f,y), get_array(x))) end function _lapl_f(f,x,fx::VectorValue) A = length(x) B = length(fx) - a = ForwardDiff.jacobian(y->transpose(ForwardDiff.jacobian(z->f(z).array,y)), x.array) - tr(MultiValue{Tuple{A,A,B}}(Tuple(transpose(a)))) + a = ForwardDiff.jacobian(y->transpose(ForwardDiff.jacobian(z->get_array(f(z)),y)), get_array(x)) + tr(ThirdOrderTensorValue{A,A,B}(Tuple(transpose(a)))) end function _lapl_f(f,x,fx::MultiValue) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index f7527d9e5..27a722a03 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -237,19 +237,21 @@ conj(a::T) where {T<:TensorValue} = T(conj(get_array(a))) Meta.parse(str[1:(end-1)]) end -#@generated function tr(v::MultiValue{Tuple{A,A,B}}) where {A,B} -# str = "" -# for k in 1:B -# for i in 1:A -# if i !=1 -# str *= " + " -# end -# str *= " v.array[$i,$i,$k]" -# end -# str *= ", " -# end -# Meta.parse("VectorValue($str)") -#end +@generated function tr(v::MultiValue{Tuple{A,A,B}}) where {A,B} + lis = LinearIndices((A,A,B)) + str = "" + for k in 1:B + for i in 1:A + if i !=1 + str *= " + " + end + p = lis[i,i,k] + str *= " v.data[$p]" + end + str *= ", " + end + Meta.parse("VectorValue($str)") +end ############################################################### # Adjoint and transpose diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 793e05f7a..3f39563b8 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -41,9 +41,9 @@ export VectorValue export TensorValue export SymTensorValue export SymFourthOrderTensorValue +export ThirdOrderTensorValue export inner, outer, meas -#export det, inv, tr, dot, norm export mutable export symmetric_part export n_components @@ -78,6 +78,8 @@ include("SymTensorValueTypes.jl") include("SymFourthOrderTensorValueTypes.jl") +include("ThirdOrderTensorValueTypes.jl") + include("Misc.jl") include("Indexing.jl") diff --git a/src/TensorValues/ThirdOrderTensorValueTypes.jl b/src/TensorValues/ThirdOrderTensorValueTypes.jl new file mode 100644 index 000000000..b723400b8 --- /dev/null +++ b/src/TensorValues/ThirdOrderTensorValueTypes.jl @@ -0,0 +1,36 @@ + +""" +Type representing a third-order tensor +""" +struct ThirdOrderTensorValue{D1,D2,D3,T,L} <: MultiValue{Tuple{D1,D2,D3},T,3,L} + data::NTuple{L,T} + function ThirdOrderTensorValue{D1,D2,D3,T,L}(data::NTuple{L,T}) where {D1,D2,D3,T,L} + @assert L == D1*D2*D3 + new{D1,D2,D3,T,L}(data) + end +end + +# Empty ThirdOrderTensorValue constructor + +ThirdOrderTensorValue() = ThirdOrderTensorValue{0,0,0,Int}(NTuple{0,Int}()) +ThirdOrderTensorValue{0,0,0}() = ThirdOrderTensorValue{0,0,0,Int}(NTuple{0,Int}()) +ThirdOrderTensorValue{0,0,0,T}() where{T} = ThirdOrderTensorValue{0,0,0,T}(NTuple{0,T}()) +ThirdOrderTensorValue(data::NTuple{0}) = ThirdOrderTensorValue{0,0,0,Int}(data) +ThirdOrderTensorValue{0,0,0}(data::NTuple{0}) = ThirdOrderTensorValue{0,0,0,Int}(data) + +# ThirdOrderTensorValue single NTuple argument constructor + +ThirdOrderTensorValue(data::NTuple{L,T}) where {L,T} = (D=Int(cbrt(L));ThirdOrderTensorValue{D,D,D,T}(data)) +ThirdOrderTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = ThirdOrderTensorValue{D,D,D,T,L}(data) +ThirdOrderTensorValue{D1,D2,D3}(data::NTuple{L,T}) where {D1,D2,D3,L,T} = ThirdOrderTensorValue{D1,D2,D3,T,L}(data) +ThirdOrderTensorValue{D1,D2,D3,T1}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(NTuple{L,T1}(data)) +ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(NTuple{L,T1}(data)) + +# ThirdOrderTensorValue Vararg constructor + +ThirdOrderTensorValue(data::T...) where {T} = (L=length(data);D=Int(cbrt(L));ThirdOrderTensorValue{D,D,D,T}(NTuple{L,T}(data))) +ThirdOrderTensorValue{D}(data::T...) where {D,T} = (L=length(data);ThirdOrderTensorValue{D,D,D,T}(NTuple{L,T}(data))) +ThirdOrderTensorValue{D1,D2}(data::T...) where {D1,D2,T} = (L=length(data);ThirdOrderTensorValue{D1,D2,D3,T}(NTuple{L,T}(data))) +ThirdOrderTensorValue{D1,D2,T1}(data::T2...) where {D1,D2,T1,T2} = (L=length(data);ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data))) +ThirdOrderTensorValue{D1,D2,T1,L}(data::T2...) where {D1,D2,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data)) + diff --git a/src/TensorValues/Types.jl b/src/TensorValues/Types.jl deleted file mode 100644 index b7f0f3208..000000000 --- a/src/TensorValues/Types.jl +++ /dev/null @@ -1,264 +0,0 @@ - -# Types - -""" -Type representing a multi-dimensional value -""" -struct MultiValue{S,T,N,L} <: Number - array::SArray{S,T,N,L} -end - -""" -Type representing a second-order tensor -""" -const TensorValue{D,T,L} = MultiValue{Tuple{D,D},T,2,L} - -""" -Type representing a first-order tensor -""" -const VectorValue{D,T} = MultiValue{Tuple{D},T,1,D} - -# Constructors (MultiValue) - -function (::Type{MultiValue{S}})(x::Tuple) where S<:Tuple - array = SArray{S}(x) - MultiValue(array) -end - -function (::Type{MultiValue{S}})(x::Tuple{}) where S<:Tuple - s = """ - Unknown element type. - - Provide element type in the corresponding type parameter. - Examples: - MultiValue{Tuple{0,0},Int}() - TensorValue{0,Int}() - VectorValue{0,Int}() - """ - error(s) -end - -function (::Type{MultiValue{S,T}})(x::Tuple) where {S<:Tuple,T} - array = SArray{S,T}(x) - MultiValue(array) -end - -function (::Type{MultiValue{S}})(x::Vararg) where S<:Tuple - MultiValue{S}(x) -end - -function (::Type{MultiValue{S,T}})(x::Vararg) where {S<:Tuple,T} - MultiValue{S,T}(x) -end - -function MultiValue(a::StaticArray{S,T}) where {S,T} - MultiValue{S,T}(a.data) -end - -# Constructors (TensorValue) - -function (::Type{TensorValue{D}})(x::Tuple) where D - S = Tuple{D,D} - MultiValue{S}(x) -end - -function (::Type{TensorValue{0}})() - S = Tuple{0,0} - MultiValue{S}() -end - -function (::Type{TensorValue{D}})(x::Vararg) where D - TensorValue{D}(x) -end - -function (::Type{TensorValue{D,T}})(x::Tuple) where {D,T} - S = Tuple{D,D} - MultiValue{S,T}(x) -end - -function (::Type{TensorValue{D,T}})(x::Vararg) where {D,T} - TensorValue{D,T}(x) -end - -@generated function TensorValue(arg::NTuple{DD,T}) where {T,DD} - SQ = sqrt(DD) - D = ceil(Int,SQ) - @assert D == SQ - :( TensorValue{$D,T}(arg) ) -end - -function TensorValue(args::Vararg) - TensorValue(args) -end - -function TensorValue() - S = Tuple{0,0} - MultiValue{S}() -end - -function TensorValue(a::StaticArray) - TensorValue(a.data) -end - -""" -""" -@generated function diagonal_tensor(v::VectorValue{D,T}) where {D,T} - s = ["zero(T), " for i in 1:(D*D)] - for i in 1:D - d = D*(i-1)+i - s[d] = "v.array[$i]," - end - str = join(s) - Meta.parse("TensorValue(($str))") -end - -# Constructors (VectorValue) - -function (::Type{VectorValue{D}})(x::Tuple) where D - S = Tuple{D} - MultiValue{S}(x) -end - -function (::Type{VectorValue{D}})(x::Vararg) where D - VectorValue{D}(x) -end - -function (::Type{VectorValue{D,T}})() where {D,T} - S = Tuple{D} - MultiValue{S,T}() -end - -function VectorValue(arg::NTuple{D,T}) where {D,T} - VectorValue{D,T}(arg) -end - -function (::Type{VectorValue{D,T}})(x::Vararg{Number,D}) where {T,D} - VectorValue{D,T}(x) -end - -function VectorValue(args::Vararg) - VectorValue(args) -end - -function VectorValue() - S = Tuple{0} - MultiValue{S}() -end - -function VectorValue(a::StaticArray) - VectorValue(a.data) -end - -function VectorValue(a::SVector) - MultiValue(a) -end - -function VectorValue(a::MVector) - MultiValue(a) -end - - - -# Initializers - -function zero(::Type{<:MultiValue{S,T,N,L}}) where {S,T,N,L} - z = zero(SArray{S,T,N,L}) - MultiValue{S,T,N,L}(z) -end - -function zero(::MultiValue{S,T,N,L}) where {S,T,N,L} - zero(MultiValue{S,T,N,L}) -end - -function one(::Type{<:MultiValue{S,T,N,L}}) where {S,T,N,L} - z = one(SArray{S,T,N,L}) - MultiValue{S,T,N,L}(z) -end - -function one(::MultiValue{S,T,N,L}) where {S,T,N,L} - one(MultiValue{S,T,N,L}) -end - -# Conversions - -function convert(::Type{<:MultiValue{S,T,N,L}},a::StaticArray{S,T,N}) where {S,T,N,L} - MultiValue(a) -end - -function convert( - ::Type{<:MultiValue{S,T,N,L}},a::AbstractArray{R,N}) where {S,T,N,L,R} - b = convert(SArray{S,T,N,L},a) - MultiValue(b) -end - -function convert(::Type{<:MultiValue{S,T,N,L}},a::NTuple{L,R}) where {S,T,N,L,R} - MultiValue(SArray{S,T}(a)) -end - -function convert(::Type{<:MultiValue{S,T,N,L}},a::MultiValue{S,Ta,N,L} where Ta) where {S,T,N,L} - b = convert(SArray{S,T,N,L},a.array) - MultiValue(b) -end - -# Misc operations on the type itself - -length(::Type{<: MultiValue{S,T,N,L} where {S,T,N}} ) where L = L - -function size(::Type{MultiValue{S,T,N,L}}) where {S,T,N,L} - A = SArray{S,T,N,L} - size(A) -end - -function size(::Type{<:MultiValue{S}}) where S - _s(Size(S)) -end - -@pure _s(s::Size{T}) where T = T - -""" - n_components(::Type) - -Returns the number of components stored in the given type. -Implemented for types `<:Real` and `<:MultiValue`. -Also available for instances of these types. -""" -n_components(::Type{<: MultiValue{S,T,N,L} where {S,T,N}} ) where L = L -n_components(a::T) where T<:MultiValue = n_components(T) - -n_components(::Type{<:Real}) = 1 -n_components(a::T) where T<:Real = 1 - - -# Custom type printing - -function show(io::IO,v::MultiValue) - print(io,v.array.data) -end - -function show(io::IO,::MIME"text/plain",v::MultiValue) - print(io,typeof(v)) - print(io,v.array.data) -end - -# Misc - -""" -""" -mutable(::Type{MultiValue{S,T,N,L}}) where {S,T,N,L} = MArray{S,T,N,L} - -mutable(::MultiValue{S,T,N,L}) where {S,T,N,L} = MArray{S,T,N,L} - -""" -""" -function change_eltype(::Type{MultiValue{S,T,N,L}},::Type{E}) where {S,T,N,L,E} - MultiValue{S,E,N,L} -end - -change_eltype(a::T,::Type{E}) where {T<:MultiValue,E} = change_eltype(T,E) - -change_eltype(::Type{<:Real},::Type{E}) where E = E - -change_eltype(a::T,::Type{E}) where {T<:Real,E} = change_eltype(T,E) - -@inline Tuple(a::MultiValue) = a.array.data - diff --git a/src/TensorValues/VectorValueTypes.jl b/src/TensorValues/VectorValueTypes.jl index b0bd44303..b05c45d42 100644 --- a/src/TensorValues/VectorValueTypes.jl +++ b/src/TensorValues/VectorValueTypes.jl @@ -51,7 +51,7 @@ convert(::Type{<:VectorValue{D,T}}, arg:: AbstractArray) where {D,T} = VectorVal convert(::Type{<:VectorValue{D,T}}, arg:: Tuple) where {D,T} = VectorValue{D,T}(arg) # Inverse conversion -convert(::Type{<:AbstractArray{T}}, arg::VectorValue) where {T} = Vector{T}([Tuple(arg)...]) +#convert(::Type{<:AbstractArray{T}}, arg::VectorValue) where {T} = Vector{T}([Tuple(arg)...]) convert(::Type{<:SVector{D,T}}, arg::VectorValue{D}) where {D,T} = SVector{D,T}(Tuple(arg)) convert(::Type{<:MVector{D,T}}, arg::VectorValue{D}) where {D,T} = MVector{D,T}(Tuple(arg)) convert(::Type{<:NTuple{D,T}}, arg::VectorValue{D}) where {D,T} = NTuple{D,T}(Tuple(arg)) From fc5f3d57737f1469714784a4840bb411fc3f1c6c Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Fri, 22 May 2020 16:57:23 +0200 Subject: [PATCH 25/37] Enhancements in the TensorValues constructors --- src/TensorValues/Indexing.jl | 61 +++++++++++-------- src/TensorValues/Misc.jl | 12 ---- src/TensorValues/MultiValueTypes.jl | 13 ++++ .../SymFourthOrderTensorValueTypes.jl | 21 +++++-- src/TensorValues/SymTensorValueTypes.jl | 52 +++++++++++----- src/TensorValues/TensorValueTypes.jl | 17 ++++-- .../ThirdOrderTensorValueTypes.jl | 27 ++++---- src/TensorValues/VectorValueTypes.jl | 11 ++-- 8 files changed, 132 insertions(+), 82 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 44f83bc64..0edef4130 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -5,31 +5,6 @@ CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) -_symmetric_index_gaps(i::Integer) = i*(i-1)÷2 - -_get_linear_index(D::Integer,i::Integer,j::Integer) = ((j-1)*D)+i - -function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} - index=_get_linear_index(D1,i,j) -end - -function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} - _j=min(i,j) - _i=max(i,j) - index=_get_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) -end - -function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} - _j=min(i,j) - _i=max(i,j) - _l=min(k,l) - _k=max(k,l) - block_length=_symmetric_index_gaps(D+1) - element_index=_get_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) - block_index=_get_linear_index(D,_l,_k)-_symmetric_index_gaps(_l) - index=(block_index-1)*block_length+element_index -end - getindex(arg::VectorValue, i::Integer) = arg.data[i] getindex(arg::TensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] getindex(arg::SymTensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] @@ -44,3 +19,39 @@ getindex(arg::MultiValue, i::Integer) = getindex(arg, CartesianIndices(arg)[i]) @inline iterate(arg::MultiValue) = iterate(arg.data) @inline iterate(arg::MultiValue, state) = iterate(arg.data, state) + +_symmetric_index_gaps(i::Integer) = i*(i-1)÷2 + +_2d_tensor_linear_index(D,i,j) = ((j-1)*D)+i + +function _2d_sym_tensor_linear_index(D,i,j) + _j=min(i,j) + _i=max(i,j) + index=_2d_tensor_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) + index +end + +function _4d_sym_tensor_linear_index(D,i,j,k,l) + _j=min(i,j) + _i=max(i,j) + _l=min(k,l) + _k=max(k,l) + block_length=_symmetric_index_gaps(D+1) + element_index=_2d_tensor_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) + block_index=_2d_tensor_linear_index(D,_l,_k)-_symmetric_index_gaps(_l) + index=(block_index-1)*block_length+element_index + index +end + +function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} + _2d_tensor_linear_index(D1,i,j) +end + +function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} + _2d_sym_tensor_linear_index(D,i,j) +end + +function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} + _4d_sym_tensor_linear_index(D,i,j,k,l) +end + diff --git a/src/TensorValues/Misc.jl b/src/TensorValues/Misc.jl index e8b50660a..7fad6901e 100644 --- a/src/TensorValues/Misc.jl +++ b/src/TensorValues/Misc.jl @@ -16,15 +16,3 @@ n_components(::Number) = n_components(Number) @pure _s(s::Size{T}) where T = T -# Custom type printing - -function show(io::IO,v::MultiValue) - print(io,v.data) -end - -function show(io::IO,::MIME"text/plain",v:: MultiValue) - print(io,typeof(v)) - print(io,v.data) -end - -@inline Tuple(arg::T where {T<:MultiValue}) = arg.data diff --git a/src/TensorValues/MultiValueTypes.jl b/src/TensorValues/MultiValueTypes.jl index d543f86b7..a761a860b 100644 --- a/src/TensorValues/MultiValueTypes.jl +++ b/src/TensorValues/MultiValueTypes.jl @@ -7,3 +7,16 @@ Type representing a multi-dimensional value """ abstract type MultiValue{S,T,N,L} <: Number end +@inline Base.Tuple(arg::MultiValue) = arg.data + +# Custom type printing + +function show(io::IO,v::MultiValue) + print(io,v.data) +end + +function show(io::IO,::MIME"text/plain",v:: MultiValue) + print(io,typeof(v)) + print(io,v.data) +end + diff --git a/src/TensorValues/SymFourthOrderTensorValueTypes.jl b/src/TensorValues/SymFourthOrderTensorValueTypes.jl index 3e7e3fcc2..fac58029f 100644 --- a/src/TensorValues/SymFourthOrderTensorValueTypes.jl +++ b/src/TensorValues/SymFourthOrderTensorValueTypes.jl @@ -27,16 +27,21 @@ SymFourthOrderTensorValue{0}(data::NTuple{0}) = SymFourthOrderTensorValue{0,Int} # SymTensorValue single NTuple argument constructor -SymFourthOrderTensorValue(data::NTuple{L,T}) where {L,T} = SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2))),T}(data) +@generated function SymFourthOrderTensorValue(data::NTuple{L,T}) where {L,T} + D = Int( (sqrt(1+8*sqrt(L))-1)/2 ) + quote + SymFourthOrderTensorValue{$D,T}(data) + end +end SymFourthOrderTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymFourthOrderTensorValue{D,T}(data) SymFourthOrderTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data)) SymFourthOrderTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data)) # SymTensorValue Vararg constructor -SymFourthOrderTensorValue(data::T...) where {T} = (L=length(data);SymFourthOrderTensorValue{floor(Int,sqrt(sqrt(L*2)))}(NTuple{L}(data))) -SymFourthOrderTensorValue{D}(data::T...) where {D,T} = (L=length(data);SymFourthOrderTensorValue{D,T}(NTuple{L,T}(data))) -SymFourthOrderTensorValue{D,T1}(data::T2...) where {D,T1,T2} = (L=length(data);SymFourthOrderTensorValue{D,T1}(NTuple{L,T1}(data))) +SymFourthOrderTensorValue(data::T...) where {T} = SymFourthOrderTensorValue(data) +SymFourthOrderTensorValue{D}(data::T...) where {D,T} = SymFourthOrderTensorValue{D}(data) +SymFourthOrderTensorValue{D,T1}(data::T2...) where {D,T1,T2} = SymFourthOrderTensorValue{D,T1}(data) ############################################################### # Conversions (SymTensorValue) @@ -56,7 +61,12 @@ convert(::Type{<:SymFourthOrderTensorValue{D,T}}, arg::SymFourthOrderTensorValue # Other constructors and conversions (SymTensorValue) ############################################################### -zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = (L=Int((D*(D+1)/2)^2);SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{L}()))) +@generated function zero(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} + L=Int((D*(D+1)/2)^2) + quote + SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{$L}())) + end +end zero(::Type{<:SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{L}())) zero(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = zero(SymFourthOrderTensorValue{D,T,L}) @@ -73,7 +83,6 @@ change_eltype(::SymFourthOrderTensorValue{D,T1,L},::Type{T2}) where {D,T1,T2,L} # Introspection (SymTensorValue) ############################################################### - eltype(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} = T eltype(::SymFourthOrderTensorValue{D,T}) where {D,T} = eltype(SymFourthOrderTensorValue{D,T}) diff --git a/src/TensorValues/SymTensorValueTypes.jl b/src/TensorValues/SymTensorValueTypes.jl index e733108af..7bdc7e065 100644 --- a/src/TensorValues/SymTensorValueTypes.jl +++ b/src/TensorValues/SymTensorValueTypes.jl @@ -27,21 +27,34 @@ SymTensorValue{0}(data::NTuple{0}) = SymTensorValue{0,Int}(data) # SymTensorValue single NTuple argument constructor -SymTensorValue(data::NTuple{L,T}) where {L,T} = SymTensorValue{floor(Int,sqrt(L*2)),T}(data) -SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(NTuple{L,T}(data)) +@generated function SymTensorValue(data::NTuple{L,T}) where {L,T} + D = Int( (sqrt(1+8*L)-1)/2 ) + quote + SymTensorValue{$D,T}(data) + end +end +SymTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = SymTensorValue{D,T}(data) SymTensorValue{D,T1}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) SymTensorValue{D,T1,L}(data::NTuple{L,T2}) where {D,L,T1,T2} = SymTensorValue{D,T1}(NTuple{L,T1}(data)) # SymTensorValue Vararg constructor -SymTensorValue(data::T...) where {T} = SymTensorValue(Tuple(data)) -SymTensorValue{D}(data::T...) where {D,T} = SymTensorValue{D}(Tuple(data)) -SymTensorValue{D,T1}(data::T2...) where {D,T1,T2} = SymTensorValue{D,T1}(Tuple(data)) +SymTensorValue(data::T...) where {T} = SymTensorValue(data) +SymTensorValue{D}(data::T...) where {D,T} = SymTensorValue{D}(data) +SymTensorValue{D,T1}(data::T2...) where {D,T1,T2} = SymTensorValue{D,T1}(data) # SymTensorValue single AbstractMatrix argument constructor #From Square Matrices -_flatten_upper_triangle(data::AbstractArray,::Val{D}) where D = Tuple(data[i,j] for i in 1:D for j in i:D) +@generated function _flatten_upper_triangle(data::AbstractArray,::Val{D}) where D + str = "" + for i in 1:D + for j in i:D + str *= "data[i,j], " + end + end + Meta.parse("($str)") +end SymTensorValue(data::AbstractMatrix{T}) where {T} = ((D1,D2)=size(data); SymTensorValue{D1}(data)) SymTensorValue{D}(data::AbstractMatrix{T}) where {D,T} = SymTensorValue{D,T}(_flatten_upper_triangle(data,Val{D}())) @@ -52,14 +65,15 @@ SymTensorValue{D,T1,L}(data::AbstractMatrix{T2}) where {D,T1,T2,L} = SymTensorVa # Conversions (SymTensorValue) ############################################################### -function _SymTensorValue_to_array(arg::SymTensorValue{D,T,L}) where {D,T,L} - z = zeros(MMatrix{D,D,T}) - for j in 1:D - for i in j:D - z[j,i] = z[i,j] = arg[i,j] - end +@generated function _SymTensorValue_to_array(arg::SymTensorValue{D,T,L}) where {D,T,L} + str = "" + for j in 1:D + for i in 1:D + p = _2d_sym_tensor_linear_index(D,i,j) + str *= "arg.data[$p], " end - z + end + Meta.parse("SMatrix{D,D,T}(($str))") end # Direct conversion @@ -67,8 +81,8 @@ convert(::Type{<:SymTensorValue{D,T}}, arg::AbstractArray) where {D,T} = SymTens convert(::Type{<:SymTensorValue{D,T}}, arg::Tuple) where {D,T} = SymTensorValue{D,T}(arg) # Inverse conversion -convert(::Type{<:MMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = _SymTensorValue_to_array(arg) -convert(::Type{<:SMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = SMatrix{D,D,T}(_SymTensorValue_to_array(arg)) +convert(::Type{<:MMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = MMatrix{D,D,T}(_SymTensorValue_to_array(arg)) +convert(::Type{<:SMatrix{D,D,T}}, arg::SymTensorValue) where {D,T} = _SymTensorValue_to_array(arg) convert(::Type{<:NTuple{L,T}}, arg::SymTensorValue) where {L,T} = NTuple{L,T}(Tuple(arg)) # Internal conversion @@ -79,7 +93,13 @@ convert(::Type{<:SymTensorValue{D,T}}, arg::SymTensorValue{D,T}) where {D,T} = a # Other constructors and conversions (SymTensorValue) ############################################################### -zero(::Type{<:SymTensorValue{D,T}}) where {D,T} = (L=Int(D*(D+1)/2);SymTensorValue{D,T}(tfill(zero(T),Val{L}()))) +@generated function zero(::Type{<:SymTensorValue{D,T}}) where {D,T} + L=Int(D*(D+1)/2) + quote + SymTensorValue{D,T}(tfill(zero(T),Val{$L}())) + end +end + zero(::Type{<:SymTensorValue{D,T,L}}) where {D,T,L} = SymTensorValue{D,T}(tfill(zero(T),Val{L}())) zero(::SymTensorValue{D,T,L}) where {D,T,L} = zero(SymTensorValue{D,T,L}) diff --git a/src/TensorValues/TensorValueTypes.jl b/src/TensorValues/TensorValueTypes.jl index 11d3f8913..9510db1ee 100644 --- a/src/TensorValues/TensorValueTypes.jl +++ b/src/TensorValues/TensorValueTypes.jl @@ -27,7 +27,12 @@ TensorValue{0,0}(data::NTuple{0}) = TensorValue{0,0,Int}(data) # TensorValue single NTuple argument constructor -TensorValue(data::NTuple{L,T}) where {L,T} = (D=Int(sqrt(L));TensorValue{D,D,T}(data)) +@generated function TensorValue(data::NTuple{L,T}) where {L,T} + D = Int(sqrt(L)) + quote + TensorValue{$D,$D,T}(data) + end +end TensorValue{D}(data::NTuple{L,T}) where {D,L,T} = TensorValue{D,D,T}(data) TensorValue{D1,D2}(data::NTuple{L,T}) where {D1,D2,L,T} = TensorValue{D1,D2,T}(data) TensorValue{D1,D2,T1}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) @@ -35,11 +40,11 @@ TensorValue{D1,D2,T1,L}(data::NTuple{L,T2}) where {D1,D2,L,T1,T2} = TensorValue{ # TensorValue Vararg constructor -TensorValue(data::T...) where {T} = (L=length(data);D=Int(sqrt(L));TensorValue{D,D,T}(NTuple{L,T}(data))) -TensorValue{D}(data::T...) where {D,T} = (L=length(data);TensorValue{D,D,T}(NTuple{L,T}(data))) -TensorValue{D1,D2}(data::T...) where {D1,D2,T} = (L=length(data);TensorValue{D1,D2,T}(NTuple{L,T}(data))) -TensorValue{D1,D2,T1}(data::T2...) where {D1,D2,T1,T2} = (L=length(data);TensorValue{D1,D2,T1}(NTuple{L,T1}(data))) -TensorValue{D1,D2,T1,L}(data::T2...) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(NTuple{L,T1}(data)) +TensorValue(data::T...) where {T} = TensorValue(data) +TensorValue{D}(data::T...) where {D,T} = TensorValue{D}(data) +TensorValue{D1,D2}(data::T...) where {D1,D2,T} = TensorValue{D1,D2,T}(data) +TensorValue{D1,D2,T1}(data::T2...) where {D1,D2,T1,T2} = TensorValue{D1,D2,T1}(data) +TensorValue{D1,D2,T1,L}(data::T2...) where {D1,D2,L,T1,T2} = TensorValue{D1,D2,T1}(data) # TensorValue single AbstractMatrix argument constructor diff --git a/src/TensorValues/ThirdOrderTensorValueTypes.jl b/src/TensorValues/ThirdOrderTensorValueTypes.jl index b723400b8..a9b4bc283 100644 --- a/src/TensorValues/ThirdOrderTensorValueTypes.jl +++ b/src/TensorValues/ThirdOrderTensorValueTypes.jl @@ -4,7 +4,7 @@ Type representing a third-order tensor """ struct ThirdOrderTensorValue{D1,D2,D3,T,L} <: MultiValue{Tuple{D1,D2,D3},T,3,L} data::NTuple{L,T} - function ThirdOrderTensorValue{D1,D2,D3,T,L}(data::NTuple{L,T}) where {D1,D2,D3,T,L} + function ThirdOrderTensorValue{D1,D2,D3,T}(data::NTuple{L,T}) where {D1,D2,D3,T,L} @assert L == D1*D2*D3 new{D1,D2,D3,T,L}(data) end @@ -20,17 +20,22 @@ ThirdOrderTensorValue{0,0,0}(data::NTuple{0}) = ThirdOrderTensorValue{0,0,0,Int} # ThirdOrderTensorValue single NTuple argument constructor -ThirdOrderTensorValue(data::NTuple{L,T}) where {L,T} = (D=Int(cbrt(L));ThirdOrderTensorValue{D,D,D,T}(data)) -ThirdOrderTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = ThirdOrderTensorValue{D,D,D,T,L}(data) -ThirdOrderTensorValue{D1,D2,D3}(data::NTuple{L,T}) where {D1,D2,D3,L,T} = ThirdOrderTensorValue{D1,D2,D3,T,L}(data) -ThirdOrderTensorValue{D1,D2,D3,T1}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(NTuple{L,T1}(data)) -ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(NTuple{L,T1}(data)) +@generated function ThirdOrderTensorValue(data::NTuple{L,T}) where {L,T} + D=Int(cbrt(L)) + quote + ThirdOrderTensorValue{$D,$D,$D,T}(data) + end +end +ThirdOrderTensorValue{D}(data::NTuple{L,T}) where {D,L,T} = ThirdOrderTensorValue{D,D,D,T}(data) +ThirdOrderTensorValue{D1,D2,D3}(data::NTuple{L,T}) where {D1,D2,D3,L,T} = ThirdOrderTensorValue{D1,D2,D3,T}(data) +ThirdOrderTensorValue{D1,D2,D3,T1}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data)) +ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::NTuple{L,T2}) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data)) # ThirdOrderTensorValue Vararg constructor -ThirdOrderTensorValue(data::T...) where {T} = (L=length(data);D=Int(cbrt(L));ThirdOrderTensorValue{D,D,D,T}(NTuple{L,T}(data))) -ThirdOrderTensorValue{D}(data::T...) where {D,T} = (L=length(data);ThirdOrderTensorValue{D,D,D,T}(NTuple{L,T}(data))) -ThirdOrderTensorValue{D1,D2}(data::T...) where {D1,D2,T} = (L=length(data);ThirdOrderTensorValue{D1,D2,D3,T}(NTuple{L,T}(data))) -ThirdOrderTensorValue{D1,D2,T1}(data::T2...) where {D1,D2,T1,T2} = (L=length(data);ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data))) -ThirdOrderTensorValue{D1,D2,T1,L}(data::T2...) where {D1,D2,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(NTuple{L,T1}(data)) +ThirdOrderTensorValue(data::T...) where {T} = ThirdOrderTensorValue(data) +ThirdOrderTensorValue{D}(data::T...) where {D,T} = ThirdOrderTensorValue{D}(data) +ThirdOrderTensorValue{D1,D2,D3}(data::T...) where {D1,D2,D3,T} = ThirdOrderTensorValue{D1,D2,D3}(data) +ThirdOrderTensorValue{D1,D2,D3,T1}(data::T2...) where {D1,D2,D3,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(data) +ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::T2...) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(data) diff --git a/src/TensorValues/VectorValueTypes.jl b/src/TensorValues/VectorValueTypes.jl index b05c45d42..8f62b62d6 100644 --- a/src/TensorValues/VectorValueTypes.jl +++ b/src/TensorValues/VectorValueTypes.jl @@ -32,14 +32,14 @@ VectorValue{D,T1}(data::NTuple{D,T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple # VectorValue Vararg constructor -VectorValue(data::T...) where {T} = (D=length(data); VectorValue{D,T}(NTuple{D,T}(data))) -VectorValue{D}(data::T...) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) -VectorValue{D,T1}(data::T2...) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) +VectorValue(data::T...) where {T} = VectorValue(data) +VectorValue{D}(data::T...) where {D,T} = VectorValue{D}(data) +VectorValue{D,T1}(data::T2...) where {D,T1,T2} = VectorValue{D,T1}(data) # VectorValue single AbstractVector argument constructor -VectorValue(data::AbstractArray{T}) where {T} = (D=length(data);VectorValue{D,T}(NTuple{D,T}(data))) -VectorValue{D}(data::AbstractArray{T}) where {D,T} = VectorValue{D,T}(NTuple{D,T}(data)) +VectorValue(data::AbstractArray{T}) where {T} = (D=length(data);VectorValue(NTuple{D,T}(data))) +VectorValue{D}(data::AbstractArray{T}) where {D,T} = VectorValue{D}(NTuple{D,T}(data)) VectorValue{D,T1}(data::AbstractArray{T2}) where {D,T1,T2} = VectorValue{D,T1}(NTuple{D,T1}(data)) ############################################################### @@ -51,7 +51,6 @@ convert(::Type{<:VectorValue{D,T}}, arg:: AbstractArray) where {D,T} = VectorVal convert(::Type{<:VectorValue{D,T}}, arg:: Tuple) where {D,T} = VectorValue{D,T}(arg) # Inverse conversion -#convert(::Type{<:AbstractArray{T}}, arg::VectorValue) where {T} = Vector{T}([Tuple(arg)...]) convert(::Type{<:SVector{D,T}}, arg::VectorValue{D}) where {D,T} = SVector{D,T}(Tuple(arg)) convert(::Type{<:MVector{D,T}}, arg::VectorValue{D}) where {D,T} = MVector{D,T}(Tuple(arg)) convert(::Type{<:NTuple{D,T}}, arg::VectorValue{D}) where {D,T} = NTuple{D,T}(Tuple(arg)) From 90d4eed6b4dd0009019d3c65a4d74c06c695fe21 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Fri, 22 May 2020 17:26:10 +0200 Subject: [PATCH 26/37] More enhancements in TensorValues --- src/TensorValues/Indexing.jl | 42 +++++++++++++++++++++------------- src/TensorValues/Operations.jl | 7 +++++- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 0edef4130..aeb108b68 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -5,17 +5,37 @@ CartesianIndices(arg::MultiValue) = CartesianIndices(size(arg)) LinearIndices(arg::MultiValue) = LinearIndices(size(arg)) -getindex(arg::VectorValue, i::Integer) = arg.data[i] -getindex(arg::TensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] -getindex(arg::SymTensorValue,i::Integer,j::Integer) = arg.data[_getindex(arg, i, j)] -getindex(arg::SymFourthOrderTensorValue,i::Integer,j::Integer,k::Integer,l::Integer) = arg.data[_getindex(arg, i, j, k, l)] +getindex(arg::VectorValue, i::Integer) = arg.data[i] + +function getindex(arg::TensorValue{D},i::Integer,j::Integer) where D + index = _2d_tensor_linear_index(D,i,j) + arg.data[index] +end + +function getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where D + index = _2d_sym_tensor_linear_index(D,i,j) + arg.data[index] +end + +function getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where D + index = _4d_sym_tensor_linear_index(D,i,j,k,l) + arg.data[index] +end + +function getindex(arg::ThirdOrderTensorValue{D1,D2},i::Integer,j::Integer,k::Integer) where {D1,D2} + index = _3d_tensor_linear_index(D1,D2,i,j,k) + arg.data[index] +end getindex(arg::VectorValue, ci::CartesianIndex{1}) = getindex(arg,ci[1]) getindex(arg::TensorValue,ci::CartesianIndex{2}) = getindex(arg,ci[1],ci[2]) getindex(arg::SymTensorValue,ci::CartesianIndex{2}) = getindex(arg,ci[1],ci[2]) +getindex(arg::ThirdOrderTensorValue,ci::CartesianIndex{3}) = getindex(arg,ci[1],ci[2],ci[3]) getindex(arg::SymFourthOrderTensorValue,ci::CartesianIndex{4}) = getindex(arg,ci[1],ci[2],ci[3],ci[4]) getindex(arg::MultiValue, i::Integer) = getindex(arg, CartesianIndices(arg)[i]) +getindex(arg::TensorValue, i::Integer) = arg.data[i] +getindex(arg::ThirdOrderTensorValue, i::Integer) = arg.data[i] @inline iterate(arg::MultiValue) = iterate(arg.data) @inline iterate(arg::MultiValue, state) = iterate(arg.data, state) @@ -24,6 +44,8 @@ _symmetric_index_gaps(i::Integer) = i*(i-1)÷2 _2d_tensor_linear_index(D,i,j) = ((j-1)*D)+i +_3d_tensor_linear_index(D1,D2,i,j,k) = (k-1)*D1*D2+(j-1)*D1+i + function _2d_sym_tensor_linear_index(D,i,j) _j=min(i,j) _i=max(i,j) @@ -43,15 +65,3 @@ function _4d_sym_tensor_linear_index(D,i,j,k,l) index end -function _getindex(arg::TensorValue{D1,D2},i::Integer,j::Integer) where {D1,D2} - _2d_tensor_linear_index(D1,i,j) -end - -function _getindex(arg::SymTensorValue{D},i::Integer,j::Integer) where {D} - _2d_sym_tensor_linear_index(D,i,j) -end - -function _getindex(arg::SymFourthOrderTensorValue{D},i::Integer,j::Integer,k::Integer,l::Integer) where {D} - _4d_sym_tensor_linear_index(D,i,j,k,l) -end - diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 27a722a03..163db5cdc 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -3,7 +3,7 @@ ############################################################### (==)(a::MultiValue,b::MultiValue) = a.data == b.data -(≈)(a::MultiValue,b::MultiValue) = isapprox(collect(a.data), collect(b.data)) +(≈)(a::MultiValue,b::MultiValue) = isapprox(get_array(a), get_array(b)) (≈)(a::VectorValue{0},b::VectorValue{0}) = true function (≈)( @@ -62,6 +62,11 @@ for op in (:+,:-) SymFourthOrderTensorValue{D}(r) end + function ($op)(a::ThirdOrderTensorValue{D1,D2,D3},b::ThirdOrderTensorValue{D1,D2,D3}) where {D1,D2,D3} + r = broadcast(($op), a.data, b.data) + ThirdOrderTensorValue{D1,D2}(r) + end + end end From 0716a6d149523a195e03694a414ed96aa714866f Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Mon, 8 Jun 2020 15:35:05 +0200 Subject: [PATCH 27/37] Saving unfinished changes --- src/Exports.jl | 2 + src/TensorValues/Operations.jl | 184 +++++++++++------- src/TensorValues/TensorValues.jl | 2 + .../ThirdOrderTensorValueTypes.jl | 2 + 4 files changed, 121 insertions(+), 69 deletions(-) diff --git a/src/Exports.jl b/src/Exports.jl index 74a950510..34c4ef8c6 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -31,6 +31,8 @@ end @publish TensorValues VectorValue @publish TensorValues TensorValue @publish TensorValues inner +@publish TensorValues ⊙ +@publish TensorValues ⊗ @publish TensorValues outer @publish TensorValues diagonal_tensor diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 163db5cdc..345938996 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -4,7 +4,7 @@ (==)(a::MultiValue,b::MultiValue) = a.data == b.data (≈)(a::MultiValue,b::MultiValue) = isapprox(get_array(a), get_array(b)) -(≈)(a::VectorValue{0},b::VectorValue{0}) = true +(≈)(a::MultiValue{S,T1,N,0} where T1,b::MultiValue{S,T2,N,0} where T2) where {S,N} = true function (≈)( a::AbstractArray{<:MultiValue}, b::AbstractArray{<:MultiValue}) @@ -15,8 +15,8 @@ function (≈)( true end -function isless(a::VectorValue{N},b::VectorValue{N}) where N - for d in N:-1:1 +function isless(a::MultiValue{Tuple{L}},b::MultiValue{Tuple{L}}) where L + for d in L:-1:1 if a[d] < b[d] return true elseif a[d] > b[d] @@ -42,29 +42,18 @@ for op in (:+,:-) T(r) end - function ($op)(a::VectorValue{D},b::VectorValue{D}) where {D} + function ($op)(a::MultiValue{S},b::MultiValue{S}) where S r = broadcast(($op), a.data, b.data) - VectorValue{D}(r) - end - - function ($op)(a::TensorValue{D1,D2},b::TensorValue{D1,D2}) where {D1,D2} - r = broadcast(($op), a.data, b.data) - TensorValue{D1,D2}(r) - end - - function ($op)(a::SymTensorValue{D},b::SymTensorValue{D}) where {D} - r = broadcast(($op), a.data, b.data) - SymTensorValue{D}(r) + T = change_eltype(a,eltype(r)) + T(r) end - function ($op)(a::SymFourthOrderTensorValue{D},b::SymFourthOrderTensorValue{D}) where {D} - r = broadcast(($op), a.data, b.data) - SymFourthOrderTensorValue{D}(r) + function ($op)(a::TensorValue,b::SymTensorValue) + @notimplemented end - function ($op)(a::ThirdOrderTensorValue{D1,D2,D3},b::ThirdOrderTensorValue{D1,D2,D3}) where {D1,D2,D3} - r = broadcast(($op), a.data, b.data) - ThirdOrderTensorValue{D1,D2}(r) + function ($op)(a::SymTensorValue,b::TensorValue) + @notimplemented end end @@ -74,9 +63,10 @@ end # Matrix Division ############################################################### -function (\)(a::T1 where {T1<:Union{TensorValue,SymTensorValue}}, b::T2) where {T2<:MultiValue} +function (\)(a::MultiValue{Tuple{D,D}} where D, b::MultiValue) r = get_array(a) \ get_array(b) - T2(r) + T = change_eltype(b,eltype(r)) + T(r) end ############################################################### @@ -85,33 +75,44 @@ end for op in (:+,:-,:*) @eval begin - function ($op)(a::T,b::Number) where {T<:MultiValue} + function ($op)(a::MultiValue,b::Number) r = broadcast($op,a.data,b) - PT = change_eltype(T,eltype(r)) - PT(r) + T = change_eltype(a,eltype(r)) + T(r) end - function ($op)(a::Number,b::T) where {T<:MultiValue} + function ($op)(a::Number,b::MultiValue) r = broadcast($op,a,b.data) - PT = change_eltype(T,eltype(r)) - PT(r) + T = change_eltype(b,eltype(r)) + T(r) end end end -function (/)(a::T,b::Number) where {T<:MultiValue} +function (/)(a::MultiValue,b::Number) r = broadcast(/,a.data,b) - PT = change_eltype(T,eltype(r)) - PT(r) + P = change_eltype(a,eltype(r)) + P(r) end ############################################################### # Dot product (simple contraction) ############################################################### -(*)(a::VectorValue{D}, b::VectorValue{D}) where D = inner(a,b) +function (*)(a::MultiValue, b::MultiValue) + #msg = """ + #Method (*)(::$(typeof(a)),::$(typeof(b))) has been removed + #Use simple contraction LinearAlgebra.⋅ (\cdot) or full contraction Gridap.⊙ (\odot) instead. + #""" + #error(msg) + dot(a,b) +end + +dot(a::MultiValue{Tuple{D}}, b::MultiValue{Tuple{D}}) where D = inner(a,b) + +dot(a::MultiValue,b::MultiValue) = @notimplemented -@generated function (*)(a::VectorValue{D1}, b::MultiValue{Tuple{D1,D2},T2,2}) where {D1,D2,T2} +@generated function dot(a::MultiValue{Tuple{D1}}, b::MultiValue{Tuple{D1,D2}}) where {D1,D2} ss = String[] for j in 1:D2 s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) @@ -121,17 +122,17 @@ end Meta.parse("VectorValue{$D2}($str)") end -@generated function (*)(a::MultiValue{Tuple{D1,D2},T1,2}, b::VectorValue{D1}) where {D1,D2,T1} +@generated function dot(a::MultiValue{Tuple{D1,D2}}, b::VectorValue{D1}) where {D1,D2} ss = String[] for j in 1:D2 - s = join([ "b[$i]*a[$j,$i]+" for i in 1:D1]) + s = join([ "a[$j,$i]*b[$i]+" for i in 1:D1]) push!(ss,s[1:(end-1)]*", ") end str = join(ss) - Meta.parse("VectorValue{$D2}($str)") + Meta.parse("VectorValue{$D1}($str)") end -@generated function (*)(a::MultiValue{Tuple{D1,D2},T1,2}, b::MultiValue{Tuple{D3,D2},T2,2}) where {D1,D2,D3,T1,T2} +@generated function dot(a::MultiValue{Tuple{D1,D3}}, b::MultiValue{Tuple{D3,D2}}) where {D1,D2,D3} ss = String[] for j in 1:D2 for i in 1:D1 @@ -140,29 +141,37 @@ end end end str = join(ss) - Meta.parse("TensorValue{$D2,$D3}(($str))") + Meta.parse("TensorValue{$D1,$D2}(($str))") end -@inline dot(u::VectorValue,v::VectorValue) = inner(u,v) -@inline dot(u::TensorValue,v::VectorValue) = u*v -@inline dot(u::VectorValue,v::TensorValue) = u*v - ############################################################### # Inner product (full contraction) ############################################################### inner(a::Real,b::Real) = a*b -@generated function inner(a::MultiValue, b::MultiValue) - @assert length(a) == length(b) + +function inner(a::MultiValue, b::MultiValue) + @notimplemented +end + +@generated function inner(a::MultiValue{S}, b::MultiValue{S}) where S str = join([" a[$i]*b[$i] +" for i in 1:length(a) ]) Meta.parse(str[1:(end-1)]) end -@generated function inner(a::MultiValue{Tuple{D1,D2},T,2}, b::MultiValue{Tuple{D1,D2},T,2}) where {D1,D2,T} - str = join([" a[$i,$j]*b[$i,$j] +" for i in 1:D1 for j in 1:D2 ]) - Meta.parse(str[1:(end-1)]) +@generated function inner(a::SymTensorValue{D}, b::SymTensorValue{D}) where D + str = "" + for i in 1:D + for j in 1:D + k = _2d_tensor_linear_index(D,i,j) + str *= " a.data[$k]*b.data[$k] +" + end + end + Meta.parse(str[1:(end-1)]) end +const ⊙ = inner + ############################################################### # Reductions ############################################################### @@ -180,23 +189,29 @@ end outer(a::Real,b::Real) = a*b outer(a::MultiValue,b::Real) = a*b outer(a::Real,b::MultiValue) = a*b -@generated function outer(a::VectorValue{D},b::VectorValue{Z}) where {D,Z} + +outer(a::MultiValue,b::MultiValue) = @notimplemented + +@generated function outer(a::MultiValue{Tuple{D}},b::MultiValue{Tuple{Z}}) where {D,Z} str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) Meta.parse("TensorValue{$D,$Z}(($str))") end -#@generated function outer(a::VectorValue{D},b::TensorValue{D1,D2}) where {D,D1,D2} -# str = join(["a.array[$i]*b.array[$j,$k], " for k in 1:D2 for j in 1:D1 for i in 1:D]) -# Meta.parse("MultiValue(SArray{Tuple{$D,$D1,$D2}}($str))") -#end +@generated function outer(a::MultiValue{Tuple{D}},b::MultiValue{Tuple{D1,D2}}) where {D,D1,D2} + str = join(["a.array[$i]*b.array[$j,$k], " for k in 1:D2 for j in 1:D1 for i in 1:D]) + Meta.parse("ThirdOrderTensorValue($str))") +end + +const ⊗ = outer + ############################################################### # Linear Algebra ############################################################### #TODO: write det and inv function for small specific cases. -det(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = det(convert(SMatrix{D1,D2,T,L},a)) -inv(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = TensorValue(inv(convert(SMatrix{D1,D2,T,L},a))) +det(a::MultiValue{Tuple{D1,D2}}) where {D1,D2} = det(get_array(a)) +inv(a::MultiValue{Tuple{D1,D2}}) where {D1,D2} = TensorValue(inv(get_array(a))) ############################################################### # Measure @@ -204,17 +219,17 @@ inv(a::MultiValue{Tuple{D1,D2},T,2,L}) where {D1,D2,T,L} = TensorValue(inv(conve """ """ -meas(a::VectorValue) = sqrt(inner(a,a)) -meas(a::MultiValue{S,T,2,L}) where {S,T,L} = abs(det(a)) +meas(a::MultiValue{Tuple{D}}) where D = sqrt(inner(a,a)) +meas(a::MultiValue{Tuple{D,D}}) where D = abs(det(a)) -function meas(v::TensorValue{1,2}) +function meas(v::MultiValue{Tuple{1,2}}) n1 = v[1,2] n2 = -1*v[1,1] n = VectorValue(n1,n2) sqrt(n*n) end -function meas(v::TensorValue{2,3}) +function meas(v::MultiValue{Tuple{2,3}}) n1 = v[1,2]*v[2,3] - v[1,3]*v[2,2] n2 = v[1,3]*v[2,1] - v[1,1]*v[2,3] n3 = v[1,1]*v[2,2] - v[1,2]*v[2,1] @@ -222,16 +237,17 @@ function meas(v::TensorValue{2,3}) sqrt(n*n) end -@inline norm(u::VectorValue) = sqrt(inner(u,u)) -@inline norm(u::VectorValue{0,T}) where T = sqrt(zero(T)) +@inline norm(u::MultiValue{Tuple{D}}) where D = sqrt(inner(u,u)) +@inline norm(u::VectorValue{Tuple{0}}) = sqrt(zero(T)) ############################################################### # conj ############################################################### -conj(a::VectorValue) = a -conj(a::SymTensorValue) = a -conj(a::T) where {T<:TensorValue} = T(conj(get_array(a))) +function conj(a::T) where {T<:MultiValue} + r = map(conj, a.data) + T(r) +end ############################################################### # Trace @@ -262,10 +278,40 @@ end # Adjoint and transpose ############################################################### -adjoint(arg::T) where {T<:TensorValue} = T(adjoint(get_array(arg))) -transpose(arg::T) where {T<:TensorValue} = T(transpose(get_array(arg))) -adjoint(arg::SymTensorValue) = arg -transpose(arg::SymTensorValue) = arg +adjoint(a::MultiValue{Tuple{D,D}}) where D = @notimplemented +transpose(a::MultiValue{Tuple{D,D}}) where D = @notimplemented + +@generated function adjoint(a::TensorValue{D1,D2}) where {D1,D2} + str = "" + for i in 1:D1 + for j in 1:D2 + k = (j-1)*D1 + i + str *= "conj(a.data[$k]), " + end + end + Meta.parse("TensorValue{D2,D1}($str)") +end + +@generated function transpose(a::TensorValue{D1,D2}) where {D1,D2} + str = "" + for i in 1:D1 + for j in 1:D2 + k = (j-1)*D1 + i + str *= "a.data[$k], " + end + end + Meta.parse("TensorValue{D2,D1}($str)") +end + +@inline function adjoint(a::TensorValue{D1,D2,T}) where {D1,D2,T<:Real} + transpose(a) +end + +adjoint(a::SymTensorValue) = conj(a) + +@inline adjoint(a::SymTensorValue{D,T} where {D,T<:Real}) = transpose(a) + +transpose(a::SymTensorValue) = a ############################################################### # Symmetric part @@ -273,7 +319,7 @@ transpose(arg::SymTensorValue) = arg """ """ -@generated function symmetric_part(v::MultiValue{Tuple{D,D},T,2,L}) where {D,T,L} +@generated function symmetric_part(v::MultiValue{Tuple{D,D}}) where D str = "(" for j in 1:D for i in 1:D diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 3f39563b8..58b083a86 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -49,6 +49,8 @@ export symmetric_part export n_components export change_eltype export diagonal_tensor +export ⊙ +export ⊗ import Base: show import Base: zero, one diff --git a/src/TensorValues/ThirdOrderTensorValueTypes.jl b/src/TensorValues/ThirdOrderTensorValueTypes.jl index a9b4bc283..d4c63ea77 100644 --- a/src/TensorValues/ThirdOrderTensorValueTypes.jl +++ b/src/TensorValues/ThirdOrderTensorValueTypes.jl @@ -39,3 +39,5 @@ ThirdOrderTensorValue{D1,D2,D3}(data::T...) where {D1,D2,D3,T} = ThirdOrderTen ThirdOrderTensorValue{D1,D2,D3,T1}(data::T2...) where {D1,D2,D3,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1}(data) ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::T2...) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(data) +change_eltype(::Type{ThirdOrderTensorValue{D1,D2,D3,T1,L}},::Type{T2}) where {D1,D2,D3,T1,T2,L} = ThirdOrderTensorValue{D1,D2,D3,T2,L} +change_eltype(::T,::Type{T2}) where T<:ThirdOrderTensorValue = change_eltype(T,T2) From e484f61e59316b9b50def6458a7cabc59c671532 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 07:37:29 +0200 Subject: [PATCH 28/37] Some fixes --- src/Exports.jl | 4 +- src/TensorValues/Operations.jl | 43 +++++++++++-- .../ThirdOrderTensorValueTypes.jl | 2 +- test/TensorValuesTests/OperationsTests.jl | 64 ++++++++++++++----- 4 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/Exports.jl b/src/Exports.jl index 34c4ef8c6..e5f376a56 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -31,10 +31,10 @@ end @publish TensorValues VectorValue @publish TensorValues TensorValue @publish TensorValues inner -@publish TensorValues ⊙ -@publish TensorValues ⊗ @publish TensorValues outer @publish TensorValues diagonal_tensor +using Gridap.TensorValues: ⊙; export ⊙ +using Gridap.TensorValues: ⊗; export ⊗ @publish Fields gradient @publish Fields ∇ diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 345938996..ca86d57d8 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -122,7 +122,7 @@ dot(a::MultiValue,b::MultiValue) = @notimplemented Meta.parse("VectorValue{$D2}($str)") end -@generated function dot(a::MultiValue{Tuple{D1,D2}}, b::VectorValue{D1}) where {D1,D2} +@generated function dot(a::MultiValue{Tuple{D1,D2}}, b::MultiValue{Tuple{D1}}) where {D1,D2} ss = String[] for j in 1:D2 s = join([ "a[$j,$i]*b[$i]+" for i in 1:D1]) @@ -132,6 +132,34 @@ end Meta.parse("VectorValue{$D1}($str)") end +@generated function dot(a::VectorValue{D}, b::SymTensorValue{D}) where D + ss = String[] + for j in 1:D + s = "" + for i in 1:D + k = _2d_sym_tensor_linear_index(D,i,j) + s *= "a.data[$i]*b.data[$k]+" + end + push!(ss,s[1:(end-1)]*", ") + end + str = join(ss) + Meta.parse("VectorValue{$D}($str)") +end + +@generated function dot(a::SymTensorValue{D}, b::VectorValue{D}) where D + ss = String[] + for j in 1:D + s = "" + for i in 1:D + k = _2d_sym_tensor_linear_index(D,j,i) + s *= "a.data[$k]*b.data[$i]+" + end + push!(ss,s[1:(end-1)]*", ") + end + str = join(ss) + Meta.parse("VectorValue{$D}($str)") +end + @generated function dot(a::MultiValue{Tuple{D1,D3}}, b::MultiValue{Tuple{D3,D2}}) where {D1,D2,D3} ss = String[] for j in 1:D2 @@ -163,7 +191,7 @@ end str = "" for i in 1:D for j in 1:D - k = _2d_tensor_linear_index(D,i,j) + k = _2d_sym_tensor_linear_index(D,i,j) str *= " a.data[$k]*b.data[$k] +" end end @@ -190,21 +218,22 @@ outer(a::Real,b::Real) = a*b outer(a::MultiValue,b::Real) = a*b outer(a::Real,b::MultiValue) = a*b -outer(a::MultiValue,b::MultiValue) = @notimplemented +function outer(a::MultiValue,b::MultiValue) + @notimplemented +end @generated function outer(a::MultiValue{Tuple{D}},b::MultiValue{Tuple{Z}}) where {D,Z} str = join(["a[$i]*b[$j], " for j in 1:Z for i in 1:D]) - Meta.parse("TensorValue{$D,$Z}(($str))") + Meta.parse("TensorValue{$D,$Z}($str)") end @generated function outer(a::MultiValue{Tuple{D}},b::MultiValue{Tuple{D1,D2}}) where {D,D1,D2} - str = join(["a.array[$i]*b.array[$j,$k], " for k in 1:D2 for j in 1:D1 for i in 1:D]) - Meta.parse("ThirdOrderTensorValue($str))") + str = join(["a[$i]*b[$j,$k], " for k in 1:D2 for j in 1:D1 for i in 1:D]) + Meta.parse("ThirdOrderTensorValue{D,D1,D2}($str)") end const ⊗ = outer - ############################################################### # Linear Algebra ############################################################### diff --git a/src/TensorValues/ThirdOrderTensorValueTypes.jl b/src/TensorValues/ThirdOrderTensorValueTypes.jl index d4c63ea77..6e00510cd 100644 --- a/src/TensorValues/ThirdOrderTensorValueTypes.jl +++ b/src/TensorValues/ThirdOrderTensorValueTypes.jl @@ -40,4 +40,4 @@ ThirdOrderTensorValue{D1,D2,D3,T1}(data::T2...) where {D1,D2,D3,T1,T2} = ThirdO ThirdOrderTensorValue{D1,D2,D3,T1,L}(data::T2...) where {D1,D2,D3,L,T1,T2} = ThirdOrderTensorValue{D1,D2,D3,T1,L}(data) change_eltype(::Type{ThirdOrderTensorValue{D1,D2,D3,T1,L}},::Type{T2}) where {D1,D2,D3,T1,T2,L} = ThirdOrderTensorValue{D1,D2,D3,T2,L} -change_eltype(::T,::Type{T2}) where T<:ThirdOrderTensorValue = change_eltype(T,T2) +change_eltype(::T,::Type{T2}) where {T<:ThirdOrderTensorValue,T2} = change_eltype(T,T2) diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index bfbd3c2c9..506d59e95 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -43,13 +43,41 @@ c = a - b r = VectorValue(-1,1,-3) @test c == r +a = TensorValue(1,2,3,4) +b = TensorValue(5,6,7,8) + +c = +a +r = a +@test c==r + +c = -a +r = TensorValue(-1,-2,-3,-4) +@test c==r + +c = a - b +r = TensorValue(-4, -4, -4, -4) +@test c==r + +a = SymTensorValue(1,2,3) +b = SymTensorValue(5,6,7) + +c = -a +r = SymTensorValue(-1,-2,-3) +@test c==r + +c = a + b +r = SymTensorValue(6,8,10) +@test c==r + # Matrix Division -t = one(TensorValue{3,3,Int,9}) +a = VectorValue(1,2,3) + +t = one(TensorValue{3,3,Int}) c = t\a @test c == a -st = one(SymTensorValue{3,Int,6}) +st = one(SymTensorValue{3,Int}) c = st\a @test c == a @@ -140,41 +168,41 @@ s = TensorValue(9,8,3,4,5,6,7,2,1) st = SymTensorValue(1,2,3,5,6,9) st2 = SymTensorValue(9,6,5,3,2,1) -c = a * b +c = a ⋅ b @test isa(c,Int) @test c == 2+2+18 -c = t * a +c = t ⋅ a @test isa(c,VectorValue{3,Int}) r = VectorValue(30,36,42) @test c == r -c = st * a +c = st ⋅ a @test isa(c,VectorValue{3,Int}) r = VectorValue(14,30,42) @test c == r -c = s * t +c = s ⋅ t @test isa(c,TensorValue{3,3,Int}) r = TensorValue(38,24,18,98,69,48,158,114,78) @test c == r -c = st * st2 +c = st ⋅ st2 @test isa(c,TensorValue{3,3,Int}) r = TensorValue(36, 78, 108, 18, 39, 54, 12, 26, 36) @test c == r -c = a * st +c = a ⋅ st @test isa(c,VectorValue{3,Int}) r = VectorValue(14,30,42) @test c == r # Inner product (full contraction) -c = inner(2,3) +c = 2 ⊙ 3 @test c == 6 -c = inner(a,b) +c = a ⊙ b @test isa(c,Int) @test c == 2+2+18 @@ -183,6 +211,7 @@ c = inner(t,s) @test c == 185 c = inner(st,st2) +c = st ⊙ st2 @test isa(c,Int) @test c == inner(TensorValue(get_array(st)),TensorValue(get_array(st2))) @@ -208,10 +237,12 @@ a = VectorValue(1,2,3) e = VectorValue(2,5) c = outer(2,3) +c = 2 ⊗ 3 @test c == 6 r = VectorValue(2,4,6) c = outer(2,a) +c = 2 ⊗ a @test isa(c,VectorValue{3,Int}) @test c == r @@ -220,16 +251,17 @@ c = outer(a,2) @test c == r c = outer(a,e) +c = a ⊗ e @test isa(c,TensorValue{3,2,Int}) r = TensorValue{3,2,Int}(2,4,6,5,10,15) @test c == r -#e = VectorValue(10,20) -#k = TensorValue(1,2,3,4) -#c = outer(e,k) -#@test c == MultiValue{Tuple{2,2,2}}(10, 20, 20, 40, 30, 60, 40, 80) -# -#@test tr(c) == VectorValue(50,110) +e = VectorValue(10,20) +k = TensorValue(1,2,3,4) +c = outer(e,k) +@test c == ThirdOrderTensorValue{2,2,2}(10, 20, 20, 40, 30, 60, 40, 80) + +@test tr(c) == VectorValue(50,110) # Linear Algebra From 62e053c6af819369b318d026126dc2ab8e61a2d5 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 09:09:50 +0200 Subject: [PATCH 29/37] More efficient implementation of inverse --- src/TensorValues/Operations.jl | 48 ++++++++++++++++++++++- test/TensorValuesTests/OperationsTests.jl | 10 +++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index ca86d57d8..e022a1308 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -238,10 +238,56 @@ const ⊗ = outer # Linear Algebra ############################################################### -#TODO: write det and inv function for small specific cases. det(a::MultiValue{Tuple{D1,D2}}) where {D1,D2} = det(get_array(a)) + +det(a::MultiValue{Tuple{1,1}}) = a[1] + +function det(a::MultiValue{Tuple{2,2}}) + a_11 = a[1,1]; a_12 = a[1,2] + a_21 = a[2,1]; a_22 = a[2,2] + a_11*a_22 - a_12*a_21 +end + +function det(a::MultiValue{Tuple{3,3}}) + a_11 = a[1,1]; a_12 = a[1,2]; a_13 = a[1,3] + a_21 = a[2,1]; a_22 = a[2,2]; a_23 = a[2,3] + a_31 = a[3,1]; a_32 = a[3,2]; a_33 = a[3,3] + a_11*a_22*a_33 + a_12*a_23*a_31 + a_13*a_21*a_32 - + (a_11*a_23*a_32 + a_12*a_21*a_33 + a_13*a_22*a_31) +end + inv(a::MultiValue{Tuple{D1,D2}}) where {D1,D2} = TensorValue(inv(get_array(a))) +function inv(a::MultiValue{Tuple{1,1}}) + r = 1/a[1] + T = change_eltype(a,typeof(r)) + T(r) +end + +function inv(a::MultiValue{Tuple{2,2}}) + c = 1/det(a) + data = (a[2,2]*c, -a[2,1]*c, -a[1,2]*c, a[1,1]*c) + TensorValue{2}(data) +end + +function inv(a::MultiValue{Tuple{3,3}}) + a_11 = a[1,1]; a_12 = a[1,2]; a_13 = a[1,3] + a_21 = a[2,1]; a_22 = a[2,2]; a_23 = a[2,3] + a_31 = a[3,1]; a_32 = a[3,2]; a_33 = a[3,3] + c = 1/det(a) + data = ( + ( a_22*a_33 - a_23*a_32 )*c, + -( a_21*a_33 - a_23*a_31 )*c, + ( a_21*a_32 - a_22*a_31 )*c, + -( a_12*a_33 - a_13*a_32 )*c, + ( a_11*a_33 - a_13*a_31 )*c, + -( a_11*a_32 - a_12*a_31 )*c, + ( a_12*a_23 - a_13*a_22 )*c, + -( a_11*a_23 - a_13*a_21 )*c, + ( a_11*a_22 - a_12*a_21 )*c) + TensorValue{3}(data) +end + ############################################################### # Measure ############################################################### diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index 506d59e95..e1928ba96 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -269,6 +269,8 @@ t = TensorValue(10,2,30,4,5,6,70,8,9) c = det(t) @test c ≈ -8802.0 +@test det(t) == det(TensorValue(get_array(t))) +@test inv(t) == inv(TensorValue(get_array(t))) c = inv(t) @test isa(c,TensorValue{3}) @@ -277,6 +279,14 @@ st = SymTensorValue(9,8,7,5,4,1) @test det(st) == det(TensorValue(get_array(st))) @test inv(st) == inv(TensorValue(get_array(st))) +t = TensorValue(10) +@test det(t) == 10 +@test inv(t) == TensorValue(1/10) + +t = TensorValue(1,4,-1,1) +@test det(t) == det(TensorValue(get_array(t))) +@test inv(t) == inv(TensorValue(get_array(t))) + # Measure a = VectorValue(1,2,3) From 870710c25032bca51ef3e2c74640fa6a38846735 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 09:56:10 +0200 Subject: [PATCH 30/37] Some improvements --- src/TensorValues/Indexing.jl | 6 ++++ src/TensorValues/Misc.jl | 18 ---------- src/TensorValues/MultiValueTypes.jl | 13 ++++++++ src/TensorValues/Operations.jl | 52 ++++++++++------------------- src/TensorValues/TensorValues.jl | 2 -- 5 files changed, 36 insertions(+), 55 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index aeb108b68..4eba53a0b 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -40,6 +40,12 @@ getindex(arg::ThirdOrderTensorValue, i::Integer) = arg.data[i] @inline iterate(arg::MultiValue) = iterate(arg.data) @inline iterate(arg::MultiValue, state) = iterate(arg.data, state) +data_index(::Type{<:VectorValue},i) = i +data_index(::Type{<:TensorValue{D}},i,j) where D = _2d_tensor_linear_index(D,i,j) +data_index(::Type{<:SymTensorValue{D}},i,j) where D = _2d_sym_tensor_linear_index(D,i,j) +data_index(::Type{<:ThirdOrderTensorValue{D1,D2}},i,j,k) where {D1,D2} = _3d_tensor_linear_index(D1,D2,i,j,k) +data_index(::Type{<:SymFourthOrderTensorValue{D}},i,j,k,l) where D = _4d_sym_tensor_linear_index(D,i,j,k,l) + _symmetric_index_gaps(i::Integer) = i*(i-1)÷2 _2d_tensor_linear_index(D,i,j) = ((j-1)*D)+i diff --git a/src/TensorValues/Misc.jl b/src/TensorValues/Misc.jl index 7fad6901e..e69de29bb 100644 --- a/src/TensorValues/Misc.jl +++ b/src/TensorValues/Misc.jl @@ -1,18 +0,0 @@ -############################################################### -# Other constructors and conversions implemented for more generic types -############################################################### - -change_eltype(::Type{<:Number},::Type{T}) where {T} = T -change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) - -n_components(::Type{<:Number}) = 1 -n_components(::Number) = n_components(Number) - -############################################################### -# Misc -############################################################### - -# Misc operations on the type itself - -@pure _s(s::Size{T}) where T = T - diff --git a/src/TensorValues/MultiValueTypes.jl b/src/TensorValues/MultiValueTypes.jl index a761a860b..006740edc 100644 --- a/src/TensorValues/MultiValueTypes.jl +++ b/src/TensorValues/MultiValueTypes.jl @@ -20,3 +20,16 @@ function show(io::IO,::MIME"text/plain",v:: MultiValue) print(io,v.data) end +############################################################### +# Other constructors and conversions implemented for more generic types +############################################################### + +change_eltype(::Type{<:Number},::Type{T}) where {T} = T +change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) + +n_components(::Type{<:Number}) = 1 +n_components(::Number) = n_components(Number) + +function data_index(::Type{<:MultiValue},i...) + @abstractmethod +end diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index e022a1308..82b43b0c0 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -112,54 +112,36 @@ dot(a::MultiValue{Tuple{D}}, b::MultiValue{Tuple{D}}) where D = inner(a,b) dot(a::MultiValue,b::MultiValue) = @notimplemented -@generated function dot(a::MultiValue{Tuple{D1}}, b::MultiValue{Tuple{D1,D2}}) where {D1,D2} +@generated function dot(a::A,b::B) where {A<:MultiValue{Tuple{D1}},B<:MultiValue{Tuple{D1,D2}}} where {D1,D2} ss = String[] for j in 1:D2 - s = join([ "a[$i]*b[$i,$j]+" for i in 1:D1]) + s = "" + for i in 1:D1 + ak = data_index(A,i) + bk = data_index(B,i,j) + s *= "a.data[$ak]*b.data[$bk]+" + end push!(ss,s[1:(end-1)]*", ") end str = join(ss) Meta.parse("VectorValue{$D2}($str)") end -@generated function dot(a::MultiValue{Tuple{D1,D2}}, b::MultiValue{Tuple{D1}}) where {D1,D2} +@generated function dot(a::A,b::B) where {A<:MultiValue{Tuple{D1,D2}},B<:MultiValue{Tuple{D2}}} where {D1,D2} ss = String[] - for j in 1:D2 - s = join([ "a[$j,$i]*b[$i]+" for i in 1:D1]) + for i in 1:D1 + s = "" + for j in 1:D2 + ak = data_index(A,i,j) + bk = data_index(B,j) + s *= "a.data[$ak]*b.data[$bk]+" + end push!(ss,s[1:(end-1)]*", ") end str = join(ss) Meta.parse("VectorValue{$D1}($str)") end -@generated function dot(a::VectorValue{D}, b::SymTensorValue{D}) where D - ss = String[] - for j in 1:D - s = "" - for i in 1:D - k = _2d_sym_tensor_linear_index(D,i,j) - s *= "a.data[$i]*b.data[$k]+" - end - push!(ss,s[1:(end-1)]*", ") - end - str = join(ss) - Meta.parse("VectorValue{$D}($str)") -end - -@generated function dot(a::SymTensorValue{D}, b::VectorValue{D}) where D - ss = String[] - for j in 1:D - s = "" - for i in 1:D - k = _2d_sym_tensor_linear_index(D,j,i) - s *= "a.data[$k]*b.data[$i]+" - end - push!(ss,s[1:(end-1)]*", ") - end - str = join(ss) - Meta.parse("VectorValue{$D}($str)") -end - @generated function dot(a::MultiValue{Tuple{D1,D3}}, b::MultiValue{Tuple{D3,D2}}) where {D1,D2,D3} ss = String[] for j in 1:D2 @@ -191,7 +173,7 @@ end str = "" for i in 1:D for j in 1:D - k = _2d_sym_tensor_linear_index(D,i,j) + k = data_index(a,i,j) str *= " a.data[$k]*b.data[$k] +" end end @@ -313,7 +295,7 @@ function meas(v::MultiValue{Tuple{2,3}}) end @inline norm(u::MultiValue{Tuple{D}}) where D = sqrt(inner(u,u)) -@inline norm(u::VectorValue{Tuple{0}}) = sqrt(zero(T)) +@inline norm(u::MultiValue{Tuple{0},T}) where T = sqrt(zero(T)) ############################################################### # conj diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 58b083a86..8d6806a71 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -82,8 +82,6 @@ include("SymFourthOrderTensorValueTypes.jl") include("ThirdOrderTensorValueTypes.jl") -include("Misc.jl") - include("Indexing.jl") include("Operations.jl") From 6910034fd9d675f745acad53cfbf64c2a4d115ef Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 09:56:26 +0200 Subject: [PATCH 31/37] Removing src/TensorValues/Misc.jl --- src/TensorValues/Misc.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/TensorValues/Misc.jl diff --git a/src/TensorValues/Misc.jl b/src/TensorValues/Misc.jl deleted file mode 100644 index e69de29bb..000000000 From ab7834333adfd472296f6fa8570c3e97b6f93d21 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 12:42:41 +0200 Subject: [PATCH 32/37] More work in symmetric 2nd and 4rd order tensors --- src/TensorValues/Indexing.jl | 22 ++++++---- src/TensorValues/Operations.jl | 42 ++++++++++++++++++- .../SymFourthOrderTensorValueTypes.jl | 6 ++- test/TensorValuesTests/OperationsTests.jl | 41 +++++++++++++++--- test/TensorValuesTests/TypesTests.jl | 22 ++++++---- 5 files changed, 108 insertions(+), 25 deletions(-) diff --git a/src/TensorValues/Indexing.jl b/src/TensorValues/Indexing.jl index 4eba53a0b..61282bffd 100644 --- a/src/TensorValues/Indexing.jl +++ b/src/TensorValues/Indexing.jl @@ -59,14 +59,22 @@ function _2d_sym_tensor_linear_index(D,i,j) index end +#function _4d_sym_tensor_linear_index(D,i,j,k,l) +# _j=min(i,j) +# _i=max(i,j) +# _l=min(k,l) +# _k=max(k,l) +# block_length=_symmetric_index_gaps(D+1) +# element_index=_2d_tensor_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) +# block_index=_2d_tensor_linear_index(D,_l,_k)-_symmetric_index_gaps(_l) +# index=(block_index-1)*block_length+element_index +# index +#end + function _4d_sym_tensor_linear_index(D,i,j,k,l) - _j=min(i,j) - _i=max(i,j) - _l=min(k,l) - _k=max(k,l) - block_length=_symmetric_index_gaps(D+1) - element_index=_2d_tensor_linear_index(D,_i,_j)-_symmetric_index_gaps(_j) - block_index=_2d_tensor_linear_index(D,_l,_k)-_symmetric_index_gaps(_l) + block_length = (D*(D+1))÷2 + block_index = _2d_sym_tensor_linear_index(D,i,j) + element_index = _2d_sym_tensor_linear_index(D,k,l) index=(block_index-1)*block_length+element_index index end diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 82b43b0c0..6c47d202e 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -180,6 +180,28 @@ end Meta.parse(str[1:(end-1)]) end +@generated function inner(a::SymFourthOrderTensorValue{D}, b::SymTensorValue{D}) where D + str = "" + for i in 1:D + for j in i:D + s = "" + for k in 1:D + for l in 1:D + ak = data_index(a,i,j,k,l) + bk = data_index(b,k,l) + s *= " a.data[$ak]*b.data[$bk] +" + end + end + str *= s[1:(end-1)]*", " + end + end + Meta.parse("SymTensorValue{D}($str)") +end + +function inner(a::SymFourthOrderTensorValue{D},b::MultiValue{Tuple{D,D}}) where D + inner(a,symmetric_part(b)) +end + const ⊙ = inner ############################################################### @@ -214,6 +236,22 @@ end Meta.parse("ThirdOrderTensorValue{D,D1,D2}($str)") end +@generated function outer(a::SymTensorValue{D},b::SymTensorValue{D}) where D + str = "" + for i in 1:D + for j in i:D + ak = data_index(a,i,j) + for k in 1:D + for l in k:D + bk = data_index(b,k,l) + str *= "a.data[$ak]*b.data[$bk], " + end + end + end + end + Meta.parse("SymFourthOrderTensorValue{D}($str)") +end + const ⊗ = outer ############################################################### @@ -379,12 +417,12 @@ transpose(a::SymTensorValue) = a @generated function symmetric_part(v::MultiValue{Tuple{D,D}}) where D str = "(" for j in 1:D - for i in 1:D + for i in j:D str *= "0.5*v[$i,$j] + 0.5*v[$j,$i], " end end str *= ")" - Meta.parse("TensorValue($str)") + Meta.parse("SymTensorValue{D}($str)") end ############################################################### diff --git a/src/TensorValues/SymFourthOrderTensorValueTypes.jl b/src/TensorValues/SymFourthOrderTensorValueTypes.jl index fac58029f..af68b4437 100644 --- a/src/TensorValues/SymFourthOrderTensorValueTypes.jl +++ b/src/TensorValues/SymFourthOrderTensorValueTypes.jl @@ -70,9 +70,11 @@ end zero(::Type{<:SymFourthOrderTensorValue{D,T,L}}) where {D,T,L} = SymFourthOrderTensorValue{D,T}(tfill(zero(T),Val{L}())) zero(::SymFourthOrderTensorValue{D,T,L}) where {D,T,L} = zero(SymFourthOrderTensorValue{D,T,L}) +# This is in fact the "symmetrized" 4th order identity @generated function one(::Type{<:SymFourthOrderTensorValue{D,T}}) where {D,T} - str = join(["($i==$j && $k==$l) ? one(T) : zero(T), " for i in 1:D for j in i:D for k in 1:D for l in k:D]) - Meta.parse("SymFourthOrderTensorValue{D,T}(($str))") + S = typeof(one(T)/2) + str = join(["($i==$k && $j==$l) ? ( $i==$j ? one($S) : one(T)/2) : zero($S), " for i in 1:D for j in i:D for k in 1:D for l in k:D]) + Meta.parse("SymFourthOrderTensorValue{D,$S}(($str))") end one(::SymFourthOrderTensorValue{D,T}) where {D,T} = one(SymFourthOrderTensorValue{D,T}) diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index e1928ba96..b8d64e6b4 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -145,17 +145,17 @@ r = SymTensorValue(3,4,5,7,8,11) c = 2 * s4ot @test isa(c,SymFourthOrderTensorValue{2}) -r = SymFourthOrderTensorValue(2,0,2,0,0,0,2,0,2) +r = SymFourthOrderTensorValue(2,0,0, 0,1,0, 0,0,2) @test c == r c = s4ot * 2 @test isa(c,SymFourthOrderTensorValue{2}) -r = SymFourthOrderTensorValue(2,0,2,0,0,0,2,0,2) +r = SymFourthOrderTensorValue(2,0,0, 0,1,0, 0,0,2) @test c == r -c = s4ot + 2 +c = c + 0 @test isa(c,SymFourthOrderTensorValue{2}) -r = SymFourthOrderTensorValue(3,2,3,2,2,2,3,2,3) +r = SymFourthOrderTensorValue(2,0,0, 0,1,0, 0,0,2) @test c == r # Dot product (simple contraction) @@ -353,7 +353,7 @@ t = TensorValue(1,2,3,4,5,6,7,8,9) st = SymTensorValue(1,2,3,5,6,9) @test tr(st) == tr(TensorValue(get_array(st))) -@test symmetric_part(t) == TensorValue(1.0, 3.0, 5.0, 3.0, 5.0, 7.0, 5.0, 7.0, 9.0) +@test get_array(symmetric_part(t)) == get_array(TensorValue(1.0, 3.0, 5.0, 3.0, 5.0, 7.0, 5.0, 7.0, 9.0)) @test symmetric_part(st) == symmetric_part(TensorValue(get_array(st))) a = TensorValue(1,2,3,4) @@ -392,4 +392,35 @@ b = VectorValue(2.0,3.0) a = VectorValue{0,Int}() @test a ≈ a +λ = 1 +μ = 1 +ε = SymTensorValue(1,2,3) +σ = λ*tr(ε)*one(ε) + 2*μ*ε +@test isa(σ,SymTensorValue) +@test (σ ⊙ ε) == 52 + +I = one(SymFourthOrderTensorValue{2,Int}) +@test I[1,1,1,1] == 1 +@test I[1,2,1,2] == 0.5 +@test I[2,1,1,2] == 0.5 +@test I[2,2,2,2] == 1 + +@test I ⊙ ε == ε + +a = TensorValue(1,2,3,4) +b = I ⊙ a +@test b == symmetric_part(a) + + +σ1 = λ*tr(ε)*one(ε) + 2*μ*ε +C = 2*μ*one(ε⊗ε) + λ*one(ε)⊗one(ε) +σ2 = C ⊙ ε +@test σ1 == σ2 + + +#I = one(ε) ⊗ one(ε) + + + + end # module OperationsTests diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index 0d5b65810..a90bc8760 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -76,9 +76,9 @@ s = SymTensorValue{0,Int}() # Constructors (SymFourthOrderTensorValue) -s = SymFourthOrderTensorValue( (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) ) +s = SymFourthOrderTensorValue( (1111,1121,1122, 2111,2121,2122, 2211,2221,2222) ) @test isa(s,SymFourthOrderTensorValue{2,Int}) -@test Tuple(s) == (1111,2111,2211, 1121,2121,2221, 1122,2122,2222 ) +@test Tuple(s) == (1111,1121,1122, 2111,2121,2122, 2211,2221,2222) s = SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) @test isa(s,SymFourthOrderTensorValue{2,Int}) @@ -203,8 +203,8 @@ s = one(z) @test convert(SMatrix{3,3,Int},s) == [1 0 0; 0 1 0; 0 0 1] z = one(SymFourthOrderTensorValue{2,Int}) -@test isa(z,SymFourthOrderTensorValue{2,Int,9}) -@test Tuple(z) == (1,0,1, 0,0,0, 1,0,1) +@test isa(z,SymFourthOrderTensorValue{2}) +@test Tuple(z) == (1.,0.,0., 0.,0.5,0., 0.,0.,1.) # Conversions @@ -234,10 +234,14 @@ b = convert(V,a) b = V[a,a,a,] @test isa(b,Vector{V}) -a = (1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +a = (1111,1121,1122, 2111,2121,2122, 2211,2221,2222) V = SymFourthOrderTensorValue{2,Int,9} b = convert(V,a) @test isa(b,V) +@test b[2,2,2,1] == 2221 +@test b[2,2,1,2] == 2221 +@test b[2,1,2,1] == 2121 +@test b[1,2,2,1] == 2121 b = V[a,a,a,] @test isa(b,Vector{V}) @@ -261,8 +265,8 @@ v = SymTensorValue{3,Int64}(1, 0, 0, 1, 0, 1) s = "(1, 0, 0, 1, 0, 1)" @test string(v) == s -v = SymFourthOrderTensorValue{2,Int64}(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) -s = "(1111, 2111, 2211, 1121, 2121, 2221, 1122, 2122, 2222)" +v = SymFourthOrderTensorValue{2,Int64}(1111,1121,1122, 2111,2121,2122, 2211,2221,2222) +s = "(1111, 1121, 1122, 2111, 2121, 2122, 2211, 2221, 2222)" @test string(v) == s # Misc @@ -281,7 +285,7 @@ v = VectorValue(m) @test n_components(VectorValue(1,2,3)) == 3 @test n_components(TensorValue(1,2,3,4)) == 4 @test n_components(SymTensorValue(1,2,3)) == 4 -@test n_components(SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222)) == 16 +@test n_components(SymFourthOrderTensorValue(1111,1121,1122, 2111,2121,2122, 2211,2221,2222)) == 16 a = VectorValue(1,2,3,4) @test change_eltype(a,Float64) == VectorValue{4,Float64} @@ -308,7 +312,7 @@ a = SymTensorValue(11,21,22) @test isa(Tuple(a),Tuple) @test Tuple(a) == a.data -a = SymFourthOrderTensorValue(1111,2111,2211, 1121,2121,2221, 1122,2122,2222) +a = SymFourthOrderTensorValue(1111,1121,1122, 2111,2121,2122, 2211,2221,2222) @test change_eltype(a,Float64) == SymFourthOrderTensorValue{2,Float64,9} @test isa(Tuple(a),Tuple) @test Tuple(a) == a.data From 7fd0766521583d4e128190563beac684543ce285 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Tue, 9 Jun 2020 16:21:10 +0200 Subject: [PATCH 33/37] Deprecate * for single contraction and n_components --- src/Exports.jl | 1 + src/FESpaces/CLagrangianFESpaces.jl | 4 ++-- src/FESpaces/ExtendedFESpaces.jl | 2 +- src/Fields/AffineMaps.jl | 2 +- src/Fields/Attachmap.jl | 4 ++-- src/Fields/DiffOperators.jl | 16 ++++++++++--- src/Fields/Fields.jl | 1 + src/Geometry/GenericBoundaryTriangulations.jl | 2 +- src/Geometry/Geometry.jl | 1 + src/Polynomials/MonomialBases.jl | 12 +++++----- src/ReferenceFEs/ExtrusionPolytopes.jl | 14 +++++------ src/ReferenceFEs/LagrangianDofBases.jl | 4 ++-- src/ReferenceFEs/LagrangianRefFEs.jl | 6 ++--- src/ReferenceFEs/RaviartThomasRefFEs.jl | 4 ++-- src/TensorValues/MultiValueTypes.jl | 9 +++++-- src/TensorValues/Operations.jl | 24 ++++++++++++------- .../SymFourthOrderTensorValueTypes.jl | 4 ++-- src/TensorValues/SymTensorValueTypes.jl | 4 ++-- src/TensorValues/TensorValueTypes.jl | 6 ++--- src/TensorValues/TensorValues.jl | 2 ++ src/TensorValues/VectorValueTypes.jl | 4 ++-- test/ArraysTests/KernelsTests.jl | 5 ++-- test/FESpacesTests/AffineFEOperatorsTests.jl | 6 ++--- test/FESpacesTests/CellKernelsTests.jl | 7 +++--- test/FESpacesTests/ExtendedFESpacesTests.jl | 6 ++--- test/FESpacesTests/FESolversTests.jl | 4 ++-- .../FESpacesWithLinearConstraintsTests.jl | 5 ++-- test/FESpacesTests/FETermsTests.jl | 8 +++---- .../SparseMatrixAssemblersTests.jl | 4 ++-- test/FieldsTests/AttachmapTests.jl | 3 ++- .../AppendedTriangulationsTests.jl | 3 ++- test/GeometryTests/CellFieldsTests.jl | 4 ++-- test/GridapTests/DarcyTests.jl | 11 +++++---- test/GridapTests/IsotropicDamageTests.jl | 2 +- test/GridapTests/PLaplacianTests.jl | 2 +- .../PeriodicCoupledPoissonTests.jl | 4 ++-- test/GridapTests/PeriodicDarcyTests.jl | 7 +++--- test/GridapTests/PhysicalPoissonTests.jl | 9 +++---- test/GridapTests/PoissonDGTests.jl | 9 +++---- test/GridapTests/PoissonTests.jl | 11 +++++---- test/GridapTests/StokesDGTests.jl | 20 ++++++++-------- test/GridapTests/StokesNitscheTests.jl | 5 ++-- test/GridapTests/StokesTaylorHoodTests.jl | 14 +++++------ test/GridapTests/SurfaceCouplingTests.jl | 16 ++++++------- test/TensorValuesTests/OperationsTests.jl | 19 ++++++++------- test/TensorValuesTests/TypesTests.jl | 18 +++++++------- 46 files changed, 183 insertions(+), 145 deletions(-) diff --git a/src/Exports.jl b/src/Exports.jl index e5f376a56..2367087c1 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -33,6 +33,7 @@ end @publish TensorValues inner @publish TensorValues outer @publish TensorValues diagonal_tensor +@publish TensorValues num_components using Gridap.TensorValues: ⊙; export ⊙ using Gridap.TensorValues: ⊗; export ⊗ diff --git a/src/FESpaces/CLagrangianFESpaces.jl b/src/FESpaces/CLagrangianFESpaces.jl index 012571a42..abdc79dd8 100644 --- a/src/FESpaces/CLagrangianFESpaces.jl +++ b/src/FESpaces/CLagrangianFESpaces.jl @@ -138,7 +138,7 @@ function _generate_dof_layout_component_major(::Type{<:Real},nnodes::Integer) end function _generate_dof_layout_component_major(::Type{T},nnodes::Integer) where T - ncomps = n_components(T) + ncomps = num_components(T) V = change_eltype(T,Int) ndofs = ncomps*nnodes dof_to_comp = zeros(Int8,ndofs) @@ -175,7 +175,7 @@ function _generate_cell_dofs_clagrangian_fespace( cell_to_ctype, node_and_comp_to_dof) where T - ncomps = n_components(T) + ncomps = num_components(T) ctype_to_lnode_to_comp_to_ldof = map(get_node_and_comp_to_dof,reffes) ctype_to_num_ldofs = map(num_dofs,reffes) diff --git a/src/FESpaces/ExtendedFESpaces.jl b/src/FESpaces/ExtendedFESpaces.jl index fcd32b126..037d45f04 100644 --- a/src/FESpaces/ExtendedFESpaces.jl +++ b/src/FESpaces/ExtendedFESpaces.jl @@ -175,7 +175,7 @@ function get_cell_basis(f::ExtendedFESpace) vi = testitem(cell_to_val) Tv = field_return_type(vi,xi) T = eltype(Tv) - D = n_components(eltype(xi)) + D = num_components(eltype(xi)) void_to_val = Fill(VoidBasis{T,D}(),length(f.trian.void_to_oldcell)) array = ExtendedVector( diff --git a/src/Fields/AffineMaps.jl b/src/Fields/AffineMaps.jl index 62e0985ea..fe3ecb921 100644 --- a/src/Fields/AffineMaps.jl +++ b/src/Fields/AffineMaps.jl @@ -28,7 +28,7 @@ end function _apply_affine_map(h,x) t = h.origin s = h.jacobian - (s*x)+t + (s⋅x)+t end struct AffineMapGrad{D,T,L} <: Field diff --git a/src/Fields/Attachmap.jl b/src/Fields/Attachmap.jl index d92d85c3e..4ed501ff5 100644 --- a/src/Fields/Attachmap.jl +++ b/src/Fields/Attachmap.jl @@ -32,7 +32,7 @@ function kernel_cache(k::PhysGrad,a,b) _attachmap_checks(a,b) Ta = eltype(a) Tb = eltype(b) - T = return_type(*,return_type(inv,Tb),Ta) + T = return_type(⋅,return_type(inv,Tb),Ta) r = zeros(T,size(a)) CachedArray(r) end @@ -53,7 +53,7 @@ end for p in 1:np @inbounds jacinv = inv(b[p]) for i in 1:ni - @inbounds c[p,i] = jacinv * a[p,i] + @inbounds c[p,i] = jacinv ⋅ a[p,i] end end c diff --git a/src/Fields/DiffOperators.jl b/src/Fields/DiffOperators.jl index e8d25d25a..966bf25ff 100644 --- a/src/Fields/DiffOperators.jl +++ b/src/Fields/DiffOperators.jl @@ -49,14 +49,24 @@ function laplacian(f) end """ - ∇*f + ∇⋅f Equivalent to divergence(f) """ -(*)(::typeof(∇),f) = divergence(f) -(*)(::typeof(∇),f::GridapType) = divergence(f) +dot(::typeof(∇),f) = divergence(f) +dot(::typeof(∇),f::GridapType) = divergence(f) + +function (*)(::typeof(∇),f) + msg = "Syntax ∇*f has been removed, use ∇⋅f instead" + error(msg) +end + +function (*)(::typeof(∇),f::GridapType) + msg = "Syntax ∇*f has been removed, use ∇⋅f instead" + error(msg) +end """ outer(∇,f) diff --git a/src/Fields/Fields.jl b/src/Fields/Fields.jl index e7198cd01..19e7f4508 100644 --- a/src/Fields/Fields.jl +++ b/src/Fields/Fields.jl @@ -81,6 +81,7 @@ import Gridap.TensorValues: symmetric_part import Base: +, - , * import LinearAlgebra: cross import LinearAlgebra: tr +import LinearAlgebra: dot import Base: transpose import Base: adjoint diff --git a/src/Geometry/GenericBoundaryTriangulations.jl b/src/Geometry/GenericBoundaryTriangulations.jl index 84b8726b9..effe94a6c 100644 --- a/src/Geometry/GenericBoundaryTriangulations.jl +++ b/src/Geometry/GenericBoundaryTriangulations.jl @@ -417,7 +417,7 @@ function kernel_evaluate(k::NormalVectorValued,x,J,refn) end function _map_normal(J::TensorValue{D,D,T},n::VectorValue{D,T}) where {D,T} - v = inv(J)*n + v = inv(J)⋅n m = sqrt(inner(v,v)) if m < eps() return zero(n) diff --git a/src/Geometry/Geometry.jl b/src/Geometry/Geometry.jl index 665648531..b9e4d5489 100644 --- a/src/Geometry/Geometry.jl +++ b/src/Geometry/Geometry.jl @@ -8,6 +8,7 @@ module Geometry using Test using DocStringExtensions using FillArrays +using LinearAlgebra: ⋅ using Gridap.Helpers using Gridap.Arrays diff --git a/src/Polynomials/MonomialBases.jl b/src/Polynomials/MonomialBases.jl index 36e3a4d4e..b8b3f7336 100644 --- a/src/Polynomials/MonomialBases.jl +++ b/src/Polynomials/MonomialBases.jl @@ -116,7 +116,7 @@ get_value_type(::Type{MonomialBasis{D,T}}) where {D,T} = T function field_cache(f::MonomialBasis{D,T},x) where {D,T} @assert D == length(eltype(x)) "Incorrect number of point components" np = length(x) - ndof = length(f.terms)*n_components(T) + ndof = length(f.terms)*num_components(T) n = 1 + _maximum(f.orders) r = CachedArray(zeros(T,(np,ndof))) v = CachedArray(zeros(T,(ndof,))) @@ -127,7 +127,7 @@ end function evaluate_field!(cache,f::MonomialBasis{D,T},x) where {D,T} r, v, c = cache np = length(x) - ndof = length(f.terms)*n_components(T) + ndof = length(f.terms)*num_components(T) n = 1 + _maximum(f.orders) setsize!(r,(np,ndof)) setsize!(v,(ndof,)) @@ -145,7 +145,7 @@ end function gradient_cache(f::MonomialBasis{D,V},x) where {D,V} @assert D == length(eltype(x)) "Incorrect number of point components" np = length(x) - ndof = length(f.terms)*n_components(V) + ndof = length(f.terms)*num_components(V) xi = testitem(x) T = gradient_type(V,xi) n = 1 + _maximum(f.orders) @@ -159,7 +159,7 @@ end function evaluate_gradient!(cache,f::MonomialBasis{D,T},x) where {D,T} r, v, c, g = cache np = length(x) - ndof = length(f.terms) * n_components(T) + ndof = length(f.terms) * num_components(T) n = 1 + _maximum(f.orders) setsize!(r,(np,ndof)) setsize!(v,(ndof,)) @@ -178,7 +178,7 @@ end function hessian_cache(f::MonomialBasis{D,V},x) where {D,V} @assert D == length(eltype(x)) "Incorrect number of point components" np = length(x) - ndof = length(f.terms)*n_components(V) + ndof = length(f.terms)*num_components(V) xi = testitem(x) T = gradient_type(gradient_type(V,xi),xi) n = 1 + _maximum(f.orders) @@ -193,7 +193,7 @@ end function evaluate_hessian!(cache,f::MonomialBasis{D,T},x) where {D,T} r, v, c, g, h = cache np = length(x) - ndof = length(f.terms) * n_components(T) + ndof = length(f.terms) * num_components(T) n = 1 + _maximum(f.orders) setsize!(r,(np,ndof)) setsize!(v,(ndof,)) diff --git a/src/ReferenceFEs/ExtrusionPolytopes.jl b/src/ReferenceFEs/ExtrusionPolytopes.jl index fd1238e52..436c25235 100644 --- a/src/ReferenceFEs/ExtrusionPolytopes.jl +++ b/src/ReferenceFEs/ExtrusionPolytopes.jl @@ -343,7 +343,7 @@ end # Generates the array of n-faces of a polytope function _polytopenfaces(anchor, extrusion) - D = n_components(extrusion) + D = num_components(extrusion) zerop = zero(Point{D,Int}) nf_nfs = Vector{NFace{D}}(undef,0) _nfaceboundary!(anchor, zerop, extrusion, true, nf_nfs) @@ -389,7 +389,7 @@ end # boundary function _nfaceboundary!(anchor, extrusion, extend, isanchor, list) - D = n_components(extrusion) + D = num_components(extrusion) newext = extend push!(list,NFace(anchor,extrusion)) @@ -416,7 +416,7 @@ end function _newext(newext,i) m = zero(mutable(newext)) - D = n_components(newext) + D = num_components(newext) for j in 1:D m[j] = j == i ? 0 : newext[j] end @@ -425,7 +425,7 @@ end function _edim(newext,i) m = zero(mutable(newext)) - D = n_components(newext) + D = num_components(newext) for j in 1:D m[j] = j == i ? 1 : 0 end @@ -434,7 +434,7 @@ end function _tetp(anchor,i) m = zero(mutable(anchor)) - D = n_components(anchor) + D = num_components(anchor) for j in 1:D m[j] = j >= i ? anchor[j] : 0 end @@ -509,7 +509,7 @@ end function _eliminate_zeros(::Val{d},a) where d b = zero(mutable(Point{d,Int})) - D = n_components(a) + D = num_components(a) k = 1 for i in 1:D m = a[i] @@ -587,7 +587,7 @@ function _facet_normal(::Type{T},p::DFace{D}, nf_vs, vs, i_f) where {D,T} v = zeros(T,n1,n2) for i in 2:length(nf_vs[i_f]) vi = vs[nf_vs[i_f][i]] - vs[nf_vs[i_f][1]] - for d in 1:n_components(vi) + for d in 1:num_components(vi) v[i-1,d] = vi[d] end end diff --git a/src/ReferenceFEs/LagrangianDofBases.jl b/src/ReferenceFEs/LagrangianDofBases.jl index 50e254942..b4c48d820 100644 --- a/src/ReferenceFEs/LagrangianDofBases.jl +++ b/src/ReferenceFEs/LagrangianDofBases.jl @@ -48,7 +48,7 @@ end # Node major implementation function _generate_dof_layout_node_major(::Type{T},nnodes::Integer) where T<:MultiValue - ncomps = n_components(T) + ncomps = num_components(T) V = change_eltype(T,Int) ndofs = ncomps*nnodes dof_to_comp = zeros(Int,ndofs) @@ -93,7 +93,7 @@ end vals = evaluate_field!(cf,field,b.nodes) ndofs = length(b.dof_to_node) T = eltype(vals) - ncomps = n_components(T) + ncomps = num_components(T) _evaluate_lagr_dof!(c,vals,b.node_and_comp_to_dof,ndofs,ncomps) end diff --git a/src/ReferenceFEs/LagrangianRefFEs.jl b/src/ReferenceFEs/LagrangianRefFEs.jl index 1619741aa..8d52c90e3 100644 --- a/src/ReferenceFEs/LagrangianRefFEs.jl +++ b/src/ReferenceFEs/LagrangianRefFEs.jl @@ -376,7 +376,7 @@ end function _generate_face_own_dofs(face_own_nodes, node_and_comp_to_dof) faces = 1:length(face_own_nodes) T = eltype(node_and_comp_to_dof) - comps = 1:n_components(T) + comps = 1:num_components(T) face_own_dofs = [Int[] for i in faces] for face in faces nodes = face_own_nodes[face] @@ -397,7 +397,7 @@ end function _find_own_dof_permutaions(node_perms,node_and_comp_to_dof,nfacenodeids,nfacedofsids) dof_perms = Vector{Int}[] T = eltype(node_and_comp_to_dof) - ncomps = n_components(T) + ncomps = num_components(T) idof_to_dof = nfacedofsids[end] inode_to_node = nfacenodeids[end] for inode_to_pinode in node_perms @@ -733,7 +733,7 @@ end function _eliminate_zeros(::Val{d},a,o) where d b = zero(mutable(Point{d,Int})) - D = n_components(a) + D = num_components(a) k = 1 for i in 1:D m = a[i] diff --git a/src/ReferenceFEs/RaviartThomasRefFEs.jl b/src/ReferenceFEs/RaviartThomasRefFEs.jl index 33a9464ca..aee581e39 100644 --- a/src/ReferenceFEs/RaviartThomasRefFEs.jl +++ b/src/ReferenceFEs/RaviartThomasRefFEs.jl @@ -259,7 +259,7 @@ function _eval_moment_dof_basis!(dofs,vals::AbstractVector,b) for j in 1:nj dofs[o] = z for i in 1:ni - dofs[o] += moments[i,j]*vals[nodes[i]] + dofs[o] += moments[i,j]⋅vals[nodes[i]] end o += 1 end @@ -282,7 +282,7 @@ function _eval_moment_dof_basis!(dofs,vals::AbstractMatrix,b) for a in 1:na dofs[o,a] = z for i in 1:ni - dofs[o,a] += moments[i,j]*vals[nodes[i],a] + dofs[o,a] += moments[i,j]⋅vals[nodes[i],a] end end o += 1 diff --git a/src/TensorValues/MultiValueTypes.jl b/src/TensorValues/MultiValueTypes.jl index 006740edc..c97cc3e14 100644 --- a/src/TensorValues/MultiValueTypes.jl +++ b/src/TensorValues/MultiValueTypes.jl @@ -27,8 +27,13 @@ end change_eltype(::Type{<:Number},::Type{T}) where {T} = T change_eltype(::Number,::Type{T2}) where {T2} = change_eltype(Number,T2) -n_components(::Type{<:Number}) = 1 -n_components(::Number) = n_components(Number) +num_components(::Type{<:Number}) = 1 +num_components(::Number) = num_components(Number) + +function n_components(a) + msg = "Function n_components is deprecated use num_components instead" + error(msg) +end function data_index(::Type{<:MultiValue},i...) @abstractmethod diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 6c47d202e..12786d09a 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -100,12 +100,12 @@ end ############################################################### function (*)(a::MultiValue, b::MultiValue) - #msg = """ - #Method (*)(::$(typeof(a)),::$(typeof(b))) has been removed - #Use simple contraction LinearAlgebra.⋅ (\cdot) or full contraction Gridap.⊙ (\odot) instead. - #""" - #error(msg) - dot(a,b) + msg = """ + Method (*)(::$(typeof(a)),::$(typeof(b))) has been removed + Use simple contraction LinearAlgebra.⋅ (\\cdot) or full contraction Gridap.⊙ (\\odot) instead. + """ + error(msg) + #dot(a,b) end dot(a::MultiValue{Tuple{D}}, b::MultiValue{Tuple{D}}) where D = inner(a,b) @@ -154,6 +154,12 @@ end Meta.parse("TensorValue{$D1,$D2}(($str))") end +# Double contraction + +#(::Colon)(a::MultiValue{Tuple{D1,D2}},b::MultiValue{Tuple{D1,D2}}) where {D1,D2} = inner(a,b) +#(::Colon)(a::MultiValue{Tuple{D1,D2}},b::MultiValue{Tuple{D1,D2,D3,D4}}) where {D1,D2,D3,D4} = inner(a,b) +#(::Colon)(a::MultiValue{Tuple{D1,D2,D3,D4}},b::MultiValue{Tuple{D1,D2}}) where {D1,D2,D3,D4} = inner(a,b) + ############################################################### # Inner product (full contraction) ############################################################### @@ -321,7 +327,7 @@ function meas(v::MultiValue{Tuple{1,2}}) n1 = v[1,2] n2 = -1*v[1,1] n = VectorValue(n1,n2) - sqrt(n*n) + sqrt(n ⋅ n) end function meas(v::MultiValue{Tuple{2,3}}) @@ -329,7 +335,7 @@ function meas(v::MultiValue{Tuple{2,3}}) n2 = v[1,3]*v[2,1] - v[1,1]*v[2,3] n3 = v[1,1]*v[2,2] - v[1,2]*v[2,1] n = VectorValue(n1,n2,n3) - sqrt(n*n) + sqrt(n ⋅ n) end @inline norm(u::MultiValue{Tuple{D}}) where D = sqrt(inner(u,u)) @@ -435,7 +441,7 @@ for op in (:symmetric_part,) end end -for op in (:inner,:outer) +for op in (:inner,:outer,:(:)) @eval begin ($op)(a::GridapType,b::GridapType) = operate($op,a,b) ($op)(a::GridapType,b::Number) = operate($op,a,b) diff --git a/src/TensorValues/SymFourthOrderTensorValueTypes.jl b/src/TensorValues/SymFourthOrderTensorValueTypes.jl index af68b4437..a885e8afd 100644 --- a/src/TensorValues/SymFourthOrderTensorValueTypes.jl +++ b/src/TensorValues/SymFourthOrderTensorValueTypes.jl @@ -94,6 +94,6 @@ size(::SymFourthOrderTensorValue{D}) where {D} = size(SymFourthOrderTensorValue{ length(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = D*D*D*D length(::SymFourthOrderTensorValue{D}) where {D} = length(SymFourthOrderTensorValue{D}) -n_components(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D}) -n_components(::SymFourthOrderTensorValue{D}) where {D} = n_components(SymFourthOrderTensorValue{D}) +num_components(::Type{<:SymFourthOrderTensorValue{D}}) where {D} = length(SymFourthOrderTensorValue{D}) +num_components(::SymFourthOrderTensorValue{D}) where {D} = num_components(SymFourthOrderTensorValue{D}) diff --git a/src/TensorValues/SymTensorValueTypes.jl b/src/TensorValues/SymTensorValueTypes.jl index 7bdc7e065..168a3eb97 100644 --- a/src/TensorValues/SymTensorValueTypes.jl +++ b/src/TensorValues/SymTensorValueTypes.jl @@ -130,6 +130,6 @@ size(::SymTensorValue{D}) where {D} = size(SymTensorValue{D}) length(::Type{<:SymTensorValue{D}}) where {D} = D*D length(::SymTensorValue{D}) where {D} = length(SymTensorValue{D}) -n_components(::Type{<:SymTensorValue{D}}) where {D} = length(SymTensorValue{D}) -n_components(::SymTensorValue{D}) where {D} = n_components(SymTensorValue{D}) +num_components(::Type{<:SymTensorValue{D}}) where {D} = length(SymTensorValue{D}) +num_components(::SymTensorValue{D}) where {D} = num_components(SymTensorValue{D}) diff --git a/src/TensorValues/TensorValueTypes.jl b/src/TensorValues/TensorValueTypes.jl index 9510db1ee..aa323630d 100644 --- a/src/TensorValues/TensorValueTypes.jl +++ b/src/TensorValues/TensorValueTypes.jl @@ -117,7 +117,7 @@ length(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D}) length(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = D1*D1 length(::TensorValue{D1,D2}) where {D1,D2} = length(TensorValue{D1,D2}) -n_components(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D}) -n_components(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2}) -n_components(::TensorValue{D1,D2}) where {D1,D2} = n_components(TensorValue{D1,D2}) +num_components(::Type{<:TensorValue{D}}) where {D} = length(TensorValue{D,D}) +num_components(::Type{<:TensorValue{D1,D2}}) where {D1,D2} = length(TensorValue{D1,D2}) +num_components(::TensorValue{D1,D2}) where {D1,D2} = num_components(TensorValue{D1,D2}) diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 8d6806a71..246ba1b03 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -35,6 +35,7 @@ using StaticArrays: SVector, MVector, SMatrix, MMatrix, SArray, MArray using Base: @propagate_inbounds, @pure using Gridap.Helpers using Gridap.Arrays +using LinearAlgebra: ⋅ export MultiValue export VectorValue @@ -47,6 +48,7 @@ export inner, outer, meas export mutable export symmetric_part export n_components +export num_components export change_eltype export diagonal_tensor export ⊙ diff --git a/src/TensorValues/VectorValueTypes.jl b/src/TensorValues/VectorValueTypes.jl index 8f62b62d6..31b4acd7a 100644 --- a/src/TensorValues/VectorValueTypes.jl +++ b/src/TensorValues/VectorValueTypes.jl @@ -88,6 +88,6 @@ size(::VectorValue{D}) where {D} = size(VectorValue{D}) length(::Type{<:VectorValue{D}}) where {D} = D length(::VectorValue{D}) where {D} = length(VectorValue{D}) -n_components(::Type{<:VectorValue{D}}) where {D} = length(VectorValue{D}) -n_components(::VectorValue{D}) where {D} = n_components(VectorValue{D}) +num_components(::Type{<:VectorValue{D}}) where {D} = length(VectorValue{D}) +num_components(::VectorValue{D}) where {D} = num_components(VectorValue{D}) diff --git a/test/ArraysTests/KernelsTests.jl b/test/ArraysTests/KernelsTests.jl index fa4e729fc..28238a484 100644 --- a/test/ArraysTests/KernelsTests.jl +++ b/test/ArraysTests/KernelsTests.jl @@ -3,6 +3,7 @@ module KernelsTests using Test using Gridap.Arrays using Gridap.TensorValues +using LinearAlgebra test_kernel(+,(3,2),5) @@ -33,11 +34,11 @@ test_kernel(k,([3,4],[1,2]),[2,2]) k = contract(-) test_kernel(k,([3,4],[1,2]),3-1+4-2) -f = bcast(*) +f = bcast(⋅) a = fill(TensorValue(2,0,0,0,2,0,0,0,2),2) b = VectorValue(1,2,3) c = zeros(VectorValue{3,Int},2) -broadcast!(*,c,a,b) +broadcast!(⋅,c,a,b) test_kernel(f,(a,b),c) end # module diff --git a/test/FESpacesTests/AffineFEOperatorsTests.jl b/test/FESpacesTests/AffineFEOperatorsTests.jl index 2eca0c554..a82df8d78 100644 --- a/test/FESpacesTests/AffineFEOperatorsTests.jl +++ b/test/FESpacesTests/AffineFEOperatorsTests.jl @@ -33,7 +33,7 @@ f(x) = x[2] v = get_cell_basis(V) u = get_cell_basis(U) -cellmat = integrate(∇(v)*∇(u),trian,quad) +cellmat = integrate(∇(v)⊙∇(u),trian,quad) cellvec = integrate(v*f,trian,quad) cellids = collect(1:num_cells(trian)) @@ -64,7 +64,7 @@ dirichlet_tags = "boundary" V = GradConformingFESpace(reffes,model,dirichlet_tags) U = TrialFESpace(V,u_sol) -a(v,u) = ∇(v)*∇(u) +a(v,u) = ∇(v)⊙∇(u) l(v) = v*f_fun t_Ω = AffineFETerm(a,l,trian,quad) @@ -96,7 +96,7 @@ function poisson_matvec_kernel!(mat,vec,∇v,∇u,v,j,w,x) f_q = f_fun(x[q]) for n in 1:N for m in 1:M - mat[m,n] += ∇v[q,m]*∇u[q,n]*dV + mat[m,n] += ∇v[q,m]⊙∇u[q,n]*dV end end for m in 1:M diff --git a/test/FESpacesTests/CellKernelsTests.jl b/test/FESpacesTests/CellKernelsTests.jl index 701425064..8c13333cc 100644 --- a/test/FESpacesTests/CellKernelsTests.jl +++ b/test/FESpacesTests/CellKernelsTests.jl @@ -7,6 +7,7 @@ using Gridap.Geometry using Gridap.Integration using Gridap.FESpaces using LinearAlgebra +using Gridap.TensorValues function poisson_matvec_kernel!(mat,vec,∇u,∇v,v,j,w) Q = length(w) @@ -17,7 +18,7 @@ function poisson_matvec_kernel!(mat,vec,∇u,∇v,v,j,w) for n in 1:N for m in 1:M - mat[m,n] += ∇v[q,m]*∇u[q,n]*dV + mat[m,n] += ∇v[q,m]⊙∇u[q,n]*dV end end @@ -37,7 +38,7 @@ function poisson_mat_kernel!(mat,∇u,∇v,j,w) for n in 1:N for m in 1:M - mat[m,n] += ∇v[q,m]*∇u[q,n]*dV + mat[m,n] += ∇v[q,m]⊙∇u[q,n]*dV end end @@ -84,7 +85,7 @@ cellmatvec = apply_cellmatvec(poisson_matvec_kernel!, ∇v_q, ∇v_q, v_q, j_q, cellmat = apply_cellmatrix(poisson_mat_kernel!, ∇v_q, ∇v_q, j_q, w) cellvec = apply_cellvector(poisson_vec_kernel!, v_q, j_q, w) -a(v,u) = ∇(v)*∇(u) +a(v,u) = ∇(v)⊙∇(u) l(v) = v cellmat2 = integrate(a(v,u),trian,quad) diff --git a/test/FESpacesTests/ExtendedFESpacesTests.jl b/test/FESpacesTests/ExtendedFESpacesTests.jl index 6898111bf..77ba8b4f9 100644 --- a/test/FESpacesTests/ExtendedFESpacesTests.jl +++ b/test/FESpacesTests/ExtendedFESpacesTests.jl @@ -82,17 +82,17 @@ uh_in = restrict(uh,trian_in) uh_Γ = restrict(uh,trian_Γ) -t_in = AffineFETerm( (u,v) -> v*u, (v) -> v*u, trian_in, quad_in) +t_in = AffineFETerm( (u,v) -> v⊙u, (v) -> v⊙u, trian_in, quad_in) op_in = AffineFEOperator(U,V,t_in) quad = CellQuadrature(trian,2*order) -t_Ω = AffineFETerm( (u,v) -> v*u, (v) -> v*u, trian, quad) +t_Ω = AffineFETerm( (u,v) -> v⊙u, (v) -> v⊙u, trian, quad) op_Ω = AffineFEOperator(U,V,t_Ω) @test get_vector(op_in) ≈ get_vector(op_Ω) -t_Γ = AffineFETerm( (u,v) -> jump(v)*jump(u) + inner(jump(ε(v)),jump(ε(u))), (v) -> jump(v)*u, trian_Γ, quad_Γ) +t_Γ = AffineFETerm( (u,v) -> jump(v)⊙jump(u) + jump(ε(v))⊙jump(ε(u)), (v) -> jump(v)⊙u, trian_Γ, quad_Γ) op_Γ = AffineFEOperator(U,V,t_Γ) q_in = get_coordinates(quad_in) diff --git a/test/FESpacesTests/FESolversTests.jl b/test/FESpacesTests/FESolversTests.jl index 47c70a3f1..6c657fd0b 100644 --- a/test/FESpacesTests/FESolversTests.jl +++ b/test/FESpacesTests/FESolversTests.jl @@ -32,8 +32,8 @@ f(x) = x[2] v = get_cell_basis(V) u = get_cell_basis(U) -cellmat = integrate(∇(v)*∇(u),trian,quad) -cellvec = integrate(v*f,trian,quad) +cellmat = integrate(∇(v)⊙∇(u),trian,quad) +cellvec = integrate(v⊙f,trian,quad) cellids = collect(1:num_cells(trian)) assem = SparseMatrixAssembler(U,V) diff --git a/test/FESpacesTests/FESpacesWithLinearConstraintsTests.jl b/test/FESpacesTests/FESpacesWithLinearConstraintsTests.jl index b21136d5b..8d6e24c95 100644 --- a/test/FESpacesTests/FESpacesWithLinearConstraintsTests.jl +++ b/test/FESpacesTests/FESpacesWithLinearConstraintsTests.jl @@ -6,6 +6,7 @@ using Gridap.Fields using Gridap.Geometry using Gridap.FESpaces using Test +using LinearAlgebra domain = (0,1,0,1) partition = (2,2) @@ -66,9 +67,9 @@ bquad = CellQuadrature(btrian,2) bn = get_normal_vector(btrian) -a(u,v) = ∇(v)*∇(u) +a(u,v) = ∇(v)⋅∇(u) b1(v) = v*f -b2(v) = v*(bn*∇(u)) +b2(v) = v*(bn⋅∇(u)) t1 = AffineFETerm(a,b1,trian,quad) t2 = FESource(b2,btrian,bquad) op = AffineFEOperator(Uc,Vc,t1,t2) diff --git a/test/FESpacesTests/FETermsTests.jl b/test/FESpacesTests/FETermsTests.jl index 0de3bc6d4..bbd7ed556 100644 --- a/test/FESpacesTests/FETermsTests.jl +++ b/test/FESpacesTests/FETermsTests.jl @@ -42,7 +42,7 @@ v = get_cell_basis(V) u = get_cell_basis(U) uh = interpolate(U,u_sol) -a(u,v) = ∇(v)*∇(u) +a(u,v) = ∇(v)⊙∇(u) l(v) = f*v j(u,du,v) = a(du,v) @@ -135,7 +135,7 @@ function poisson_matvec_kernel!(mat,vec,∇v,∇u,v,j,w,x) f_q = f(x[q]) for n in 1:N for m in 1:M - mat[m,n] += ∇v[q,m]*∇u[q,n]*dV + mat[m,n] += ∇v[q,m]⊙∇u[q,n]*dV end end for m in 1:M @@ -173,9 +173,9 @@ function poisson_jacres_kernel!(jac,res,∇v,∇du,v,∇uh,j,w,x) f_q = f(x[q]) for m in 1:M for n in 1:N - jac[m,n] += ∇v[q,m]*∇du[q,n]*dV + jac[m,n] += ∇v[q,m]⊙∇du[q,n]*dV end - res[m] += ∇v[q,m]*∇uh[q]*dV + res[m] += ∇v[q,m]⊙∇uh[q]*dV end for m in 1:M res[m] -= v[q,m]*f_q*dV diff --git a/test/FESpacesTests/SparseMatrixAssemblersTests.jl b/test/FESpacesTests/SparseMatrixAssemblersTests.jl index 8e38657a7..1e8045833 100644 --- a/test/FESpacesTests/SparseMatrixAssemblersTests.jl +++ b/test/FESpacesTests/SparseMatrixAssemblersTests.jl @@ -40,8 +40,8 @@ bquad = CellQuadrature(btrian,degree) bu = restrict(u,btrian) bv = restrict(v,btrian) -cellmat = integrate(∇(v)*∇(u),trian,quad) -cellvec = integrate(v*b,trian,quad) +cellmat = integrate(∇(v)⊙∇(u),trian,quad) +cellvec = integrate(v⊙b,trian,quad) cellmatvec = pair_arrays(cellmat,cellvec) cellids = collect(1:num_cells(trian)) diff --git a/test/FieldsTests/AttachmapTests.jl b/test/FieldsTests/AttachmapTests.jl index 21f97699a..c0db0971c 100644 --- a/test/FieldsTests/AttachmapTests.jl +++ b/test/FieldsTests/AttachmapTests.jl @@ -6,6 +6,7 @@ using Gridap.Arrays using Gridap.Fields using Gridap.Fields: OtherMockBasis, MockBasis using FillArrays +using LinearAlgebra p1 = Point(2,2) p2 = Point(4,2) @@ -32,7 +33,7 @@ bx = rx for i in 1:np jacinv = inv(∇ϕx[i]) for j in 1:ndof - ∇bx[i,j] = jacinv*∇rx[i,j] + ∇bx[i,j] = jacinv⋅∇rx[i,j] end end test_field(b,x,bx,grad=∇bx) diff --git a/test/GeometryTests/AppendedTriangulationsTests.jl b/test/GeometryTests/AppendedTriangulationsTests.jl index aca65b4b4..af4a17a02 100644 --- a/test/GeometryTests/AppendedTriangulationsTests.jl +++ b/test/GeometryTests/AppendedTriangulationsTests.jl @@ -8,6 +8,7 @@ using Gridap.Visualization using Gridap.FESpaces using Gridap.Fields using Gridap.Integration +using LinearAlgebra: ⋅ domain = (0,1,0,1) partition = (10,10) @@ -50,7 +51,7 @@ el2 = sqrt(sum(integrate(e*e,trian,quad))) _dv = get_cell_basis(V) dv = restrict(_dv,trian) -cellmat = integrate(∇(dv)*∇(dv),trian,quad) +cellmat = integrate(∇(dv)⋅∇(dv),trian,quad) @test isa(cellmat,AppendedArray) @test isa(cellmat.a,CompressedArray) @test isa(cellmat.b,CompressedArray) diff --git a/test/GeometryTests/CellFieldsTests.jl b/test/GeometryTests/CellFieldsTests.jl index aeb8b96b8..08ebeacc4 100644 --- a/test/GeometryTests/CellFieldsTests.jl +++ b/test/GeometryTests/CellFieldsTests.jl @@ -87,10 +87,10 @@ nvec = get_normal_vector(btrian) z = 2*bcf1 + nvec @test isa(z,CellField) -flux1 = nvec*∇u +flux1 = nvec⋅∇u collect(evaluate(flux1,s)) -flux2 = ∇u*nvec +flux2 = ∇u⋅nvec collect(evaluate(flux2,s)) strian = SkeletonTriangulation(model) diff --git a/test/GridapTests/DarcyTests.jl b/test/GridapTests/DarcyTests.jl index 97b620370..41ba670a8 100644 --- a/test/GridapTests/DarcyTests.jl +++ b/test/GridapTests/DarcyTests.jl @@ -3,6 +3,7 @@ module DarcyTests using Test using Gridap import Gridap: ∇, divergence +using LinearAlgebra u(x) = VectorValue(2*x[1],x[1]+x[2]) @@ -48,17 +49,17 @@ nb = get_normal_vector(btrian) function a(x,y) u, p = x v, q = y - u*v - p*(∇*v) + q*(∇*u) + u⋅v - p*(∇⋅v) + q*(∇⋅u) end function l(y) v, q = y - v*f + q*(∇*u) + v⋅f + q*(∇⋅u) end function l_Γ(y) v, q = y - -(v*nb)*p + -(v⋅nb)*p end t_Ω = AffineFETerm(a,l,trian,quad) @@ -70,8 +71,8 @@ uh, ph = xh eu = u - uh ep = p - ph -l2(v) = v*v -h1(v) = v*v + ∇(v)*∇(v) +l2(v) = v⋅v +h1(v) = v*v + ∇(v)⋅∇(v) eu_l2 = sum(integrate(l2(eu),trian,quad)) ep_l2 = sum(integrate(l2(ep),trian,quad)) diff --git a/test/GridapTests/IsotropicDamageTests.jl b/test/GridapTests/IsotropicDamageTests.jl index 75d9bf919..88499175b 100644 --- a/test/GridapTests/IsotropicDamageTests.jl +++ b/test/GridapTests/IsotropicDamageTests.jl @@ -136,7 +136,7 @@ function main(;n,nsteps) e = uh - u - e_l2 = sqrt(sum(integrate(e*e,trian,quad))) + e_l2 = sqrt(sum(integrate(e⋅e,trian,quad))) @test e_l2 < 1.0e-9 end diff --git a/test/GridapTests/PLaplacianTests.jl b/test/GridapTests/PLaplacianTests.jl index 4453a0a07..1bf114b76 100644 --- a/test/GridapTests/PLaplacianTests.jl +++ b/test/GridapTests/PLaplacianTests.jl @@ -3,8 +3,8 @@ using Test using Gridap import Gridap: ∇ -using LinearAlgebra: norm using Gridap.Geometry: DiscreteModelMock +using LinearAlgebra model = DiscreteModelMock() diff --git a/test/GridapTests/PeriodicCoupledPoissonTests.jl b/test/GridapTests/PeriodicCoupledPoissonTests.jl index bf6a97af3..7803a48d0 100644 --- a/test/GridapTests/PeriodicCoupledPoissonTests.jl +++ b/test/GridapTests/PeriodicCoupledPoissonTests.jl @@ -2,7 +2,7 @@ module PeriodicCoupledPoissonTests using Gridap using Test - +using LinearAlgebra u(x) = x[1]^2 + 2*x[2]^2 v(x) = -x[2]^2 @@ -52,7 +52,7 @@ eu = u - uh ev = v - vh l2(u) = u*u -h1(u) = ∇(u)*∇(u) + l2(u) +h1(u) = ∇(u)⋅∇(u) + l2(u) eul2 = sqrt(sum( integrate(l2(eu),trian,quad) )) euh1 = sqrt(sum( integrate(h1(eu),trian,quad) )) diff --git a/test/GridapTests/PeriodicDarcyTests.jl b/test/GridapTests/PeriodicDarcyTests.jl index 65c4d4787..87e32b33e 100644 --- a/test/GridapTests/PeriodicDarcyTests.jl +++ b/test/GridapTests/PeriodicDarcyTests.jl @@ -2,6 +2,7 @@ module PeriodicDarcyTests using Gridap using Test +using LinearAlgebra u(x) = VectorValue(x[1]*(x[1]-1)*(2x[2]-1.0),-x[2]*(x[2]-1.0)*(2x[1]-1.0)) p(x) = x[2]-0.5 @@ -35,12 +36,12 @@ x = get_physical_coordinate(trian) function a(x,y) u, p = x v, q = y - v*u - p*(∇*v) + q*(∇*u) + v⋅u - p*(∇⋅v) + q*(∇⋅u) end function l(y) v, q = y - v*f + q*g + v⋅f + q*g end t_Ω = AffineFETerm(a,l,trian,quad) @@ -51,7 +52,7 @@ uh, ph = xh eu = u - uh ep = p - ph -l2(v) = v*v +l2(v) = v⋅v eu_l2 = sum(integrate(l2(eu),trian,quad)) ep_l2 = sum(integrate(l2(ep),trian,quad)) diff --git a/test/GridapTests/PhysicalPoissonTests.jl b/test/GridapTests/PhysicalPoissonTests.jl index 87dad1763..79dfcd83b 100644 --- a/test/GridapTests/PhysicalPoissonTests.jl +++ b/test/GridapTests/PhysicalPoissonTests.jl @@ -3,6 +3,7 @@ module PhysicalPoissonTests using Test using Gridap import Gridap: ∇ +using LinearAlgebra domain = (0,1,0,1) partition = (4,4) @@ -75,17 +76,17 @@ for data in [ vector_data, scalar_data ] uh = interpolate(U,u) a(u,v) = inner(∇(v),∇(u)) - l(v) = v*f + l(v) = v⊙f t_Ω = AffineFETerm(a,l,trian,quad) uh_Γn = restrict(uh,ntrian) uh_Γd = restrict(uh,dtrian) - l_Γn(v) = v*(nn*∇(uh_Γn)) + l_Γn(v) = v⊙(nn⋅∇(uh_Γn)) t_Γn = FESource(l_Γn,ntrian,nquad) - a_Γd(u,v) = (γ/h)*v*u - v*(dn*∇(u)) - (dn*∇(v))*u - l_Γd(v) = (γ/h)*v*uh_Γd - (dn*∇(v))*u + a_Γd(u,v) = (γ/h)*v⊙u - v⊙(dn⋅∇(u)) - (dn⋅∇(v))⊙u + l_Γd(v) = (γ/h)*v⊙uh_Γd - (dn⋅∇(v))⊙u t_Γd = AffineFETerm(a_Γd,l_Γd,dtrian,dquad) op = AffineFEOperator(U,V,t_Ω,t_Γn,t_Γd) diff --git a/test/GridapTests/PoissonDGTests.jl b/test/GridapTests/PoissonDGTests.jl index 589d3cde1..2d7c62190 100644 --- a/test/GridapTests/PoissonDGTests.jl +++ b/test/GridapTests/PoissonDGTests.jl @@ -3,6 +3,7 @@ module PoissonDGTests using Test using Gridap import Gridap: ∇ +using LinearAlgebra #domain = (0,1,0,1) #partition = (4,4) @@ -50,15 +51,15 @@ V = TestFESpace( U = TrialFESpace(V,u) -a(u,v) = inner(∇(v),∇(u)) +a(u,v) = ∇(v)⋅∇(u) l(v) = v*f t_Ω = AffineFETerm(a,l,trian,quad) -a_Γd(u,v) = (γ/h)*v*u - v*(bn*∇(u)) - (bn*∇(v))*u -l_Γd(v) = (γ/h)*v*u - (bn*∇(v))*u +a_Γd(u,v) = (γ/h)*v*u - v*(bn⋅∇(u)) - (bn⋅∇(v))*u +l_Γd(v) = (γ/h)*v*u - (bn⋅∇(v))*u t_Γd = AffineFETerm(a_Γd,l_Γd,btrian,bquad) -a_Γ(u,v) = (γ/h)*jump(v*sn)*jump(u*sn) - jump(v*sn)*mean(∇(u)) - mean(∇(v))*jump(u*sn) +a_Γ(u,v) = (γ/h)*jump(v*sn)⋅jump(u*sn) - jump(v*sn)⋅mean(∇(u)) - mean(∇(v))⋅jump(u*sn) t_Γ = LinearFETerm(a_Γ,strian,squad) op = AffineFEOperator(U,V,t_Ω,t_Γ,t_Γd) diff --git a/test/GridapTests/PoissonTests.jl b/test/GridapTests/PoissonTests.jl index 71ca2cae9..911944f8b 100644 --- a/test/GridapTests/PoissonTests.jl +++ b/test/GridapTests/PoissonTests.jl @@ -3,6 +3,7 @@ module PoissonTests using Test using Gridap import Gridap: ∇ +using LinearAlgebra domain = (0,1,0,1) partition = (4,4) @@ -79,18 +80,18 @@ for data in [ vector_data, scalar_data ] uh = interpolate(U,u) - a(u,v) = inner(∇(v),∇(u)) - l(v) = v*f + a(u,v) = ∇(v)⊙∇(u) + l(v) = v⊙f t_Ω = AffineFETerm(a,l,trian,quad) uh_Γn = restrict(uh,ntrian) uh_Γd = restrict(uh,dtrian) - l_Γn(v) = v*(nn*∇(uh_Γn)) + l_Γn(v) = v⊙(nn⋅∇(uh_Γn)) t_Γn = FESource(l_Γn,ntrian,nquad) - a_Γd(u,v) = (γ/h)*v*u - v*(dn*∇(u)) - (dn*∇(v))*u - l_Γd(v) = (γ/h)*v*uh_Γd - (dn*∇(v))*u + a_Γd(u,v) = (γ/h)*v⊙u - v⊙(dn⋅∇(u)) - (dn⋅∇(v))⊙u + l_Γd(v) = (γ/h)*v⊙uh_Γd - (dn⋅∇(v))⊙u t_Γd = AffineFETerm(a_Γd,l_Γd,dtrian,dquad) op = AffineFEOperator(U,V,t_Ω,t_Γn,t_Γd) diff --git a/test/GridapTests/StokesDGTests.jl b/test/GridapTests/StokesDGTests.jl index bec947079..d96c17523 100644 --- a/test/GridapTests/StokesDGTests.jl +++ b/test/GridapTests/StokesDGTests.jl @@ -3,7 +3,7 @@ module StokesDGTests using Test using Gridap import Gridap: ∇ -import LinearAlgebra: tr +import LinearAlgebra: tr, ⋅ const T = VectorValue{2,Float64} @@ -70,23 +70,23 @@ const ns = get_normal_vector(strian) function A_Ω(x,y) u, p = x v, q = y - inner(∇(v), ∇(u)) - ∇(q)*u + v*∇(p) + ∇(v)⊙∇(u) - ∇(q)⋅u + v⋅∇(p) end function B_Ω(y) v, q = y - v*f + q*g + v⋅f + q*g end function A_∂Ω(x,y) u, p = x v, q = y - (γ/h)*v*u - v*(nb*∇(u)) - (nb*∇(v))*u + 2*(q*nb)*u + (γ/h)*v⋅u - v⋅(nb⋅∇(u)) - (nb⋅∇(v))⋅u + 2*(q*nb)⋅u end function B_∂Ω(y) v, q = y - (γ/h)*v*u - (nb*∇(v))*u + (q*nb)*u + (γ/h)*v⋅u - (nb⋅∇(v))⋅u + (q*nb)⋅u end function A_Γ(x,y) @@ -95,9 +95,9 @@ function A_Γ(x,y) (γ/h)*inner( jump(outer(v,ns)), jump(outer(u,ns))) - inner( jump(outer(v,ns)), mean(∇(u)) ) - inner( mean(∇(v)), jump(outer(u,ns)) ) + - (γ0*h)*jump(q*ns)*jump(p*ns) + - jump(q*ns)*mean(u) - - mean(v)*jump(p*ns) + (γ0*h)*jump(q*ns)⋅jump(p*ns) + + jump(q*ns)⋅mean(u) - + mean(v)⋅jump(p*ns) end t_Ω = AffineFETerm(A_Ω,B_Ω,trian,quad) @@ -111,8 +111,8 @@ uh, ph = solve(op) eu = u - uh ep = p - ph -l2(v) = v*v -h1(v) = v*v + inner(∇(v),∇(v)) +l2(v) = v⋅v +h1(v) = v⋅v + inner(∇(v),∇(v)) eu_l2 = sqrt(sum(integrate(l2(eu),trian,quad))) eu_h1 = sqrt(sum(integrate(h1(eu),trian,quad))) diff --git a/test/GridapTests/StokesNitscheTests.jl b/test/GridapTests/StokesNitscheTests.jl index 585963b48..21536e864 100644 --- a/test/GridapTests/StokesNitscheTests.jl +++ b/test/GridapTests/StokesNitscheTests.jl @@ -7,6 +7,7 @@ using Test using Gridap import Gridap: ∇ import LinearAlgebra: tr +import LinearAlgebra: ⋅ # const T = VectorValue{2,Float64} @@ -94,13 +95,13 @@ function A_∂Ω(x,y) u, p = x v, q = y # (γ/h) * inner(v,u) - inner(outer(nb,v), ∇(u)) - inner(∇(v), outer(nb,u)) + inner(v, p*nb) + inner(q*nb,u) - (γ/h)*v*u - v*(nb*∇(u)) - (nb*∇(v))*u + (p*nb)*v + (q*nb)*u + (γ/h)*v⋅u - v⋅(nb⋅∇(u)) - (nb⋅∇(v))⋅u + (p*nb)⋅v + (q*nb)⋅u end function B_∂Ω(y) v, q = y # + (γ/h) * inner(v,ud) - inner(∇(v), outer(nb,ud_cf)) + inner(q*nb,ud) - (γ/h)*v*u - (nb*∇(v))*u + (q*nb)*u + (γ/h)*v⋅u - (nb⋅∇(v))⋅u + (q*nb)⋅u end t_Ω = AffineFETerm(A_Ω,B_Ω,trian,quad) diff --git a/test/GridapTests/StokesTaylorHoodTests.jl b/test/GridapTests/StokesTaylorHoodTests.jl index 53c3f8604..450fa5a23 100644 --- a/test/GridapTests/StokesTaylorHoodTests.jl +++ b/test/GridapTests/StokesTaylorHoodTests.jl @@ -4,13 +4,13 @@ using Test using Gridap import Gridap: ∇ -using LinearAlgebra: tr +using LinearAlgebra: tr, ⋅ # Using automatic differentiation u(x) = VectorValue( x[1]^2 + 2*x[2]^2, -x[1]^2 ) p(x) = x[1] + 3*x[2] f(x) = -Δ(u)(x) + ∇(p)(x) -g(x) = (∇*u)(x) +g(x) = (∇⋅u)(x) ∇u(x) = ∇(u)(x) #u(x) = VectorValue( x[1]^2 + 2*x[2]^2, -x[1]^2 ) @@ -75,17 +75,17 @@ for ref_st in ref_style function a(x,y) u,p = x v,q = y - inner(∇(v),∇(u)) - (∇*v)*p + q*(∇*u) + ∇(v)⊙∇(u) - (∇⋅v)*p + q*(∇⋅u) end function l(y) v,q = y - v*f + q*g + v⋅f + q*g end function l_Γb(y) v,q = y - v*(n*∇u) - (n*v)*p + v⋅(n⋅∇u) - (n⋅v)*p end t_Ω = AffineFETerm(a,l,trian,quad) @@ -98,8 +98,8 @@ for ref_st in ref_style eu = u - uh ep = p - ph - l2(v) = v*v - h1(v) = v*v + inner(∇(v),∇(v)) + l2(v) = v⋅v + h1(v) = v⋅v + ∇(v)⊙∇(v) eu_l2 = sqrt(sum(integrate(l2(eu),trian,quad))) eu_h1 = sqrt(sum(integrate(h1(eu),trian,quad))) diff --git a/test/GridapTests/SurfaceCouplingTests.jl b/test/GridapTests/SurfaceCouplingTests.jl index 4913c6853..ca3b5d9b2 100644 --- a/test/GridapTests/SurfaceCouplingTests.jl +++ b/test/GridapTests/SurfaceCouplingTests.jl @@ -5,7 +5,7 @@ using Gridap using Gridap.Arrays using Gridap.FESpaces import Gridap: ∇ -using LinearAlgebra: tr +using LinearAlgebra: tr, ⋅ # Analytical functions @@ -104,29 +104,29 @@ end function l_solid(y) v,q = y - v*s + v⋅s end function a_fluid(x,y) u,p = x v,q = y - inner(∇(v),∇(u)) - (∇*v)*p + q*(∇*u) + inner(∇(v),∇(u)) - (∇⋅v)*p + q*(∇⋅u) end function l_fluid(y) v,q = y - v*f + q*g + v⋅f + q*g end function l_Γn_fluid(y) v,q = y - v*(n*∇u) - (n*v)*p + v⋅(n⋅∇u) - (n⋅v)*p end # Pressure drop at the interface function l_Γ(y) v,q = y - - mean(n_Γ*v)*p + - mean(n_Γ⋅v)*p end t_Ω_solid = AffineFETerm(a_solid,l_solid,trian_solid,quad_solid) @@ -151,8 +151,8 @@ ep_fluid = p - ph_fluid # Errors -l2(v) = v*v -h1(v) = v*v + inner(∇(v),∇(v)) +l2(v) = v⋅v +h1(v) = v⋅v + inner(∇(v),∇(v)) eu_l2 = sqrt(sum(integrate(l2(eu),trian,quad))) eu_h1 = sqrt(sum(integrate(h1(eu),trian,quad))) diff --git a/test/TensorValuesTests/OperationsTests.jl b/test/TensorValuesTests/OperationsTests.jl index b8d64e6b4..2fb8e86db 100644 --- a/test/TensorValuesTests/OperationsTests.jl +++ b/test/TensorValuesTests/OperationsTests.jl @@ -360,25 +360,25 @@ a = TensorValue(1,2,3,4) b = a' @test adjoint(a) == b @test b == TensorValue(1,3,2,4) -@test a*b == TensorValue(10,14,14,20) +@test a⋅b == TensorValue(10,14,14,20) a = TensorValue(1,2,3,4) b = a' @test transpose(a) == b @test b == TensorValue(1,3,2,4) -@test a*b == TensorValue(10,14,14,20) +@test a⋅b == TensorValue(10,14,14,20) sa = SymTensorValue(1,2,3,5,6,9) sb = sa' @test adjoint(sa) == sb @test sb == SymTensorValue(1,2,3,5,6,9) -@test sa*sb == TensorValue(get_array(sa))*TensorValue(get_array(sb)) +@test sa⋅sb == TensorValue(get_array(sa))⋅TensorValue(get_array(sb)) sa = SymTensorValue(1,2,3,5,6,9) sb = sa' @test transpose(sa) == sb @test sb == SymTensorValue(1,2,3,5,6,9) -@test sa*sb == TensorValue(get_array(sa))*TensorValue(get_array(sb)) +@test sa⋅sb == TensorValue(get_array(sa))⋅TensorValue(get_array(sb)) u = VectorValue(1.0,2.0) v = VectorValue(2.0,3.0) @@ -398,6 +398,7 @@ a = VectorValue{0,Int}() σ = λ*tr(ε)*one(ε) + 2*μ*ε @test isa(σ,SymTensorValue) @test (σ ⊙ ε) == 52 +#@test σ:ε == 52 I = one(SymFourthOrderTensorValue{2,Int}) @test I[1,1,1,1] == 1 @@ -406,21 +407,21 @@ I = one(SymFourthOrderTensorValue{2,Int}) @test I[2,2,2,2] == 1 @test I ⊙ ε == ε +#@test I : ε == ε a = TensorValue(1,2,3,4) b = I ⊙ a @test b == symmetric_part(a) +#b = I : a +#@test b == symmetric_part(a) σ1 = λ*tr(ε)*one(ε) + 2*μ*ε C = 2*μ*one(ε⊗ε) + λ*one(ε)⊗one(ε) σ2 = C ⊙ ε @test σ1 == σ2 - - -#I = one(ε) ⊗ one(ε) - - +#σ2 = C : ε +#@test σ1 == σ2 end # module OperationsTests diff --git a/test/TensorValuesTests/TypesTests.jl b/test/TensorValuesTests/TypesTests.jl index a90bc8760..b694c9224 100644 --- a/test/TensorValuesTests/TypesTests.jl +++ b/test/TensorValuesTests/TypesTests.jl @@ -277,15 +277,15 @@ m = zero(M) v = VectorValue(m) @test isa(v,VectorValue{3,Int}) -@test n_components(Int) == 1 -@test n_components(Float64) == 1 -@test n_components(1.0) == 1 -@test n_components(1) == 1 -@test n_components(VectorValue{3,Float64}) == 3 -@test n_components(VectorValue(1,2,3)) == 3 -@test n_components(TensorValue(1,2,3,4)) == 4 -@test n_components(SymTensorValue(1,2,3)) == 4 -@test n_components(SymFourthOrderTensorValue(1111,1121,1122, 2111,2121,2122, 2211,2221,2222)) == 16 +@test num_components(Int) == 1 +@test num_components(Float64) == 1 +@test num_components(1.0) == 1 +@test num_components(1) == 1 +@test num_components(VectorValue{3,Float64}) == 3 +@test num_components(VectorValue(1,2,3)) == 3 +@test num_components(TensorValue(1,2,3,4)) == 4 +@test num_components(SymTensorValue(1,2,3)) == 4 +@test num_components(SymFourthOrderTensorValue(1111,1121,1122, 2111,2121,2122, 2211,2221,2222)) == 16 a = VectorValue(1,2,3,4) @test change_eltype(a,Float64) == VectorValue{4,Float64} From 98b245ac103f4f8b5b9030013274280a01b96617 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 10 Jun 2020 07:24:15 +0200 Subject: [PATCH 34/37] Minor bugfix --- src/TensorValues/Operations.jl | 2 +- src/TensorValues/TensorValues.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index 12786d09a..b3a7085ae 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -441,7 +441,7 @@ for op in (:symmetric_part,) end end -for op in (:inner,:outer,:(:)) +for op in (:inner,:outer)#,:(:)) @eval begin ($op)(a::GridapType,b::GridapType) = operate($op,a,b) ($op)(a::GridapType,b::Number) = operate($op,a,b) diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 246ba1b03..4741d85c5 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -67,6 +67,7 @@ import Base: CartesianIndices import Base: LinearIndices import Base: adjoint import Base: transpose +#import Base: : import LinearAlgebra: det, inv, tr, dot, norm From 101cb880ce2d6eef91a5468e7085edfda48272e6 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 10 Jun 2020 08:17:46 +0200 Subject: [PATCH 35/37] Ironing some rough corners --- src/Exports.jl | 4 ++++ src/Fields/DiffOperators.jl | 4 ++-- src/Fields/Fields.jl | 1 + src/TensorValues/MultiValueTypes.jl | 2 +- src/TensorValues/Operations.jl | 4 ++-- src/TensorValues/TensorValues.jl | 6 ++++-- test/FieldsTests/DiffOperatorsTests.jl | 12 +++++++++--- test/GeometryTests/CellFieldsTests.jl | 4 ++-- test/GridapTests/StokesNitscheTests.jl | 14 ++++---------- test/MultiFieldTests/MultiFieldFEOperatorsTests.jl | 2 +- ...MultiFieldFESpacesWithLinearConstraintsTests.jl | 5 +++-- 11 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/Exports.jl b/src/Exports.jl index 2367087c1..0074286f1 100644 --- a/src/Exports.jl +++ b/src/Exports.jl @@ -5,6 +5,10 @@ macro publish(mod,name) end end +# Reexport from LinearAlgebra (just for convenience) +using LinearAlgebra: det, inv, tr, cross, dot, norm, ×, ⋅ +export det, inv, tr, cross, dot, norm, ×, ⋅ + @publish Helpers operate @publish Helpers GridapType diff --git a/src/Fields/DiffOperators.jl b/src/Fields/DiffOperators.jl index 966bf25ff..004acf7bc 100644 --- a/src/Fields/DiffOperators.jl +++ b/src/Fields/DiffOperators.jl @@ -59,12 +59,12 @@ dot(::typeof(∇),f) = divergence(f) dot(::typeof(∇),f::GridapType) = divergence(f) function (*)(::typeof(∇),f) - msg = "Syntax ∇*f has been removed, use ∇⋅f instead" + msg = "Syntax ∇*f has been removed, use ∇⋅f (\\nabla \\cdot f) instead" error(msg) end function (*)(::typeof(∇),f::GridapType) - msg = "Syntax ∇*f has been removed, use ∇⋅f instead" + msg = "Syntax ∇*f has been removed, use ∇⋅f (\\nabla \\cdot f) instead" error(msg) end diff --git a/src/Fields/Fields.jl b/src/Fields/Fields.jl index 19e7f4508..4076742c6 100644 --- a/src/Fields/Fields.jl +++ b/src/Fields/Fields.jl @@ -19,6 +19,7 @@ using Gridap.Arrays: BCasted using Gridap.Arrays: NumberOrArray using Gridap.Arrays: AppliedArray using Gridap.Arrays: Contracted +using LinearAlgebra: ⋅ using Test using DocStringExtensions diff --git a/src/TensorValues/MultiValueTypes.jl b/src/TensorValues/MultiValueTypes.jl index c97cc3e14..7f7ed8e49 100644 --- a/src/TensorValues/MultiValueTypes.jl +++ b/src/TensorValues/MultiValueTypes.jl @@ -31,7 +31,7 @@ num_components(::Type{<:Number}) = 1 num_components(::Number) = num_components(Number) function n_components(a) - msg = "Function n_components is deprecated use num_components instead" + msg = "Function n_components has been removed, use num_components instead" error(msg) end diff --git a/src/TensorValues/Operations.jl b/src/TensorValues/Operations.jl index b3a7085ae..ed965f828 100644 --- a/src/TensorValues/Operations.jl +++ b/src/TensorValues/Operations.jl @@ -101,8 +101,8 @@ end function (*)(a::MultiValue, b::MultiValue) msg = """ - Method (*)(::$(typeof(a)),::$(typeof(b))) has been removed - Use simple contraction LinearAlgebra.⋅ (\\cdot) or full contraction Gridap.⊙ (\\odot) instead. + Method (*)(::$(typeof(a)),::$(typeof(b))) has been removed. + Depending the case, use simple contraction dot aka ⋅ (\\cdot) or full contraction inner aka ⊙ (\\odot) instead. """ error(msg) #dot(a,b) diff --git a/src/TensorValues/TensorValues.jl b/src/TensorValues/TensorValues.jl index 4741d85c5..b588e7fc2 100644 --- a/src/TensorValues/TensorValues.jl +++ b/src/TensorValues/TensorValues.jl @@ -35,7 +35,7 @@ using StaticArrays: SVector, MVector, SMatrix, MMatrix, SArray, MArray using Base: @propagate_inbounds, @pure using Gridap.Helpers using Gridap.Arrays -using LinearAlgebra: ⋅ +using LinearAlgebra export MultiValue export VectorValue @@ -69,7 +69,9 @@ import Base: adjoint import Base: transpose #import Base: : -import LinearAlgebra: det, inv, tr, dot, norm +import LinearAlgebra: det, inv, tr, cross, dot, norm +# Reexport from LinearAlgebra (just for convenience) +export det, inv, tr, cross, dot, norm, ×, ⋅ import Gridap.Arrays: get_array diff --git a/test/FieldsTests/DiffOperatorsTests.jl b/test/FieldsTests/DiffOperatorsTests.jl index 6be5ceb3d..eb9fb320d 100644 --- a/test/FieldsTests/DiffOperatorsTests.jl +++ b/test/FieldsTests/DiffOperatorsTests.jl @@ -26,17 +26,23 @@ for f in (_f,_af) @test curl(f) == grad2curl(gradient(f)) - @test ∇*f == divergence(f) + @test ∇⋅f == divergence(f) @test cross(∇,f) == curl(f) + + @test ∇×f == curl(f) @test outer(∇,f) == ∇(f) + + @test ∇⊗f == ∇(f) @test outer(f,∇) == transpose(∇(f)) + @test f⊗∇ == transpose(∇(f)) + @test ε(f) == symmetric_part(gradient(f)) - @test Δ(f) == ∇*∇(f) + @test Δ(f) == ∇⋅∇(f) end @@ -63,7 +69,7 @@ u(x) = VectorValue( x[1]^2 + 2*x[2]^2, -x[1]^2 ) Δu(x) = VectorValue( 6, -2 ) for x in xs - @test (∇*u)(x) == tr(∇u(x)) + @test (∇⋅u)(x) == tr(∇u(x)) @test (∇×u)(x) == grad2curl(∇u(x)) @test Δ(u)(x) == Δu(x) end diff --git a/test/GeometryTests/CellFieldsTests.jl b/test/GeometryTests/CellFieldsTests.jl index 08ebeacc4..1fff46d29 100644 --- a/test/GeometryTests/CellFieldsTests.jl +++ b/test/GeometryTests/CellFieldsTests.jl @@ -65,7 +65,7 @@ collect(evaluate(grad_cfu,q)) t_grad_cfu = outer(cfu,∇) collect(evaluate(t_grad_cfu,q)) -div_cfu = ∇*cfu +div_cfu = ∇⋅cfu collect(evaluate(div_cfu,q)) curl_cfu = cross(∇,cfu) @@ -124,7 +124,7 @@ collect(evaluate(grad_cfu,s)) t_grad_cfu = jump(outer(scfu,∇)) collect(evaluate(t_grad_cfu,s)) -div_cfu = mean(∇*scfu) +div_cfu = mean(∇⋅scfu) collect(evaluate(div_cfu,s)) curl_cfu = jump(cross(∇,scfu)) diff --git a/test/GridapTests/StokesNitscheTests.jl b/test/GridapTests/StokesNitscheTests.jl index 21536e864..f5ff2efbf 100644 --- a/test/GridapTests/StokesNitscheTests.jl +++ b/test/GridapTests/StokesNitscheTests.jl @@ -6,8 +6,6 @@ module StokesNitsche using Test using Gridap import Gridap: ∇ -import LinearAlgebra: tr -import LinearAlgebra: ⋅ # const T = VectorValue{2,Float64} @@ -21,8 +19,6 @@ p(x) = x[1] - x[2] ∇(::typeof(u)) = ∇u - - n = 2 order = 2 @@ -83,24 +79,22 @@ nb = get_normal_vector(btrian) function A_Ω(x,y) u, p = x v, q = y - inner(∇(v), ∇(u)) - inner(q,divergence(u)) - inner(divergence(v), p) + ∇(v)⊙∇(u) - q*(∇⋅u) - (∇⋅v)*p end function B_Ω(y) v, q = y - inner(v,f) - inner(q, g) + v⋅f - q*g end function A_∂Ω(x,y) u, p = x v, q = y - # (γ/h) * inner(v,u) - inner(outer(nb,v), ∇(u)) - inner(∇(v), outer(nb,u)) + inner(v, p*nb) + inner(q*nb,u) (γ/h)*v⋅u - v⋅(nb⋅∇(u)) - (nb⋅∇(v))⋅u + (p*nb)⋅v + (q*nb)⋅u end function B_∂Ω(y) v, q = y - # + (γ/h) * inner(v,ud) - inner(∇(v), outer(nb,ud_cf)) + inner(q*nb,ud) (γ/h)*v⋅u - (nb⋅∇(v))⋅u + (q*nb)⋅u end @@ -125,8 +119,8 @@ ep = p - ph # writevtk(trian,"trian",cellfields=["uh"=>uh,"ph"=>ph, "eu"=>eu, "ep"=>ep]) # Define norms to measure the error -l2(u) = inner(u,u) -h1(u) = inner(∇(u),∇(u)) + l2(u) +l2(u) = u⊙u +h1(u) = ∇(u)⊙∇(u) + l2(u) # Compute errors eul2 = sqrt(sum( integrate(l2(eu),trian,quad) )) diff --git a/test/MultiFieldTests/MultiFieldFEOperatorsTests.jl b/test/MultiFieldTests/MultiFieldFEOperatorsTests.jl index 94d2c2b0c..f49ef1150 100644 --- a/test/MultiFieldTests/MultiFieldFEOperatorsTests.jl +++ b/test/MultiFieldTests/MultiFieldFEOperatorsTests.jl @@ -49,7 +49,7 @@ end function a_Γ(x,y) u,p = x v,q = y - jump(v)*mean(u) + jump(∇(q))*jump(∇(p)) - mean(v)*mean(p) + jump(v)*mean(u) + jump(∇(q))⋅jump(∇(p)) - mean(v)*mean(p) end t_Ω = AffineFETerm(a,l,trian,quad) diff --git a/test/MultiFieldTests/MultiFieldFESpacesWithLinearConstraintsTests.jl b/test/MultiFieldTests/MultiFieldFESpacesWithLinearConstraintsTests.jl index 3842fd285..90ea40e98 100644 --- a/test/MultiFieldTests/MultiFieldFESpacesWithLinearConstraintsTests.jl +++ b/test/MultiFieldTests/MultiFieldFESpacesWithLinearConstraintsTests.jl @@ -5,6 +5,7 @@ using Gridap.Arrays using Gridap.Fields using Gridap.Geometry using Gridap.FESpaces +using Gridap.TensorValues using Gridap.MultiField using Test @@ -62,8 +63,8 @@ test_fe_space(V) @test has_constraints(U) @test has_constraints(V) -a(u,v) = ∇(v)*∇(u) -b_Γ(v,u,n_Γ) = v*(n_Γ*∇(u)) +a(u,v) = ∇(v)⋅∇(u) +b_Γ(v,u,n_Γ) = v*(n_Γ⋅∇(u)) function A(u,v) u1,u2 = u From 85bfcdff4810f69ef3bc53bef7c25bdb3595342c Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 10 Jun 2020 09:49:07 +0200 Subject: [PATCH 36/37] Update NEWS.md --- NEWS.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/NEWS.md b/NEWS.md index 3bfb19856..9691d11bf 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + + - Added `⊙` (\odot) as an alias of `inner`. Since PR [#239](https://github.com/gridap/Gridap.jl/pull/239). + - Added `⊗` (\otimes) as an alias of `outer`. Since PR [#239](https://github.com/gridap/Gridap.jl/pull/239). + +### Changed + + - Major refactoring in the module `Gridap.TensorValues`. + Since PR [#239](https://github.com/gridap/Gridap.jl/pull/239). + **The following changes are likely to affect all users:** + - The operator `*` is not allowed for expressing the dot product anymore. Use `LinearAlgebra.dot` + function aka `⋅` (\cdot). + - The syntax `∇*u` is not allowed anymore. Use `∇⋅u` instead. + - Gridap re-exports `dot`, `⋅`, and other names from LinearAlbegra that are used + often in Gridap code. + - Function `n_components` is renamed to `num_components`. + ## [0.10.4] - 2020-6-8 ### Added From a2d662b241331c6e9ccb3dbfa834386947f67961 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Wed, 10 Jun 2020 09:52:48 +0200 Subject: [PATCH 37/37] Moving to v0.11.0 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 0b3d05b25..6484f9092 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Gridap" uuid = "56d4f2e9-7ea1-5844-9cf6-b9c51ca7ce8e" authors = ["Santiago Badia ", "Francesc Verdugo "] -version = "0.10.4" +version = "0.11.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"