# Matrix assembly

Hi,
I am trying to understand this equation and implementing it in julia.

where sigma is second order tensor assuming dimension n1n1. and Nd is shape function matric for scalar value so dimension is 1n2. How this multiplication can be done? I think it would be a third order tensor and if it is right how can I assemble that matric in Julia. I tried to find some examples on that but I couldnt.
Thank you

I assembled before matrices in trial and test spaces with same dimensions. but now i have 2 different dimensions

\bar d is likely a vector of size n2. I can’t make sense of that expression otherwise.

Then the meaning is rather clear: I’ll write it for you with more indices and summation over repeated indices is implied (I also call N_d just N so it’s clearer what the indices are):

\frac{\partial\sigma_{i,j}}{\partial \bar d_k} = -2(1- N_l \bar d_l) \sigma_{i,j} N_k

This object indeed has 3 indices and is thus a 3-tensor.

I am not sure what you mean with “implementing it in Julia” but Julia supports multi-dimensional arrays out of the box. So you could use just a 3 dimensional array to store all the values.

thank you! perfect explanation. so what is the dimension of this 3rd order tensor? n1n1n2?
also for coding part i used gridap FE package like below

function dσfun(ε, ε_in,s_in)
σ_elas = C_mat⊙ε
if tr(ε_in) >= 0
dσ = (2 * s_in)*σ_elas
elseif  tr(ε_in) < 0
dσ = (2 * s_in)*P_dev ⊙ σ_elas
end
return  dσ
end
function MatrixdAs(pth,uh,sh;fem_params)
dAs_Disp(u,pth,uh,sh,s) =  ((p->Em(p))∘pth) * ((dσfun∘(ε(u), ε(uh), sh)) * s)
dAs_mat = assemble_matrix(fem_params.V0_Disp, fem_params.U_PF) do u,s
∫(dAs_Disp(u,pth,uh,sh,s))fem_params.dΩ
end
return dAs_mat
end


but it can not assemble that matrix and getting this error

MethodError: no method matching Float64(::SymTensorValue{2, Float64, 3})
Closest candidates are:
(::Type{T})(::T) where T<:Number at boot.jl:772
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
(::Type{T})(::Base.TwicePrecision) where T<:Number at twiceprecision.jl:266
...

Stacktrace:
[1] convert(#unused#::Type{Float64}, x::SymTensorValue{2, Float64, 3})
@ Base .\number.jl:7
[2] setindex!(A::Vector{Float64}, x::SymTensorValue{2, Float64, 3}, i1::Int64)
@ Base .\array.jl:966
[3] add_entry!(#unused#::typeof(+), a::Gridap.Algebra.InserterCSC{Float64, Int64}, v::SymTensorValue{2, Float64, 3}, i::Int32, j::Int32)
@ Gridap.Algebra C:\Users\marya\.julia\packages\Gridap\971dU\src\Algebra\SparseMatrixCSC.jl:132
@ C:\Users\marya\.julia\packages\Gridap\971dU\src\Algebra\AlgebraInterfaces.jl:149 [inlined]
@ C:\Users\marya\.julia\packages\Gridap\971dU\src\Algebra\AlgebraInterfaces.jl:127 [inlined]
[6] evaluate!(cache::Nothing, k::Gridap.Arrays.AddEntriesMap{typeof(+)}, A::Gridap.Algebra.InserterCSC{Float64, Int64}, v::Matrix{SymTensorValue{2, Float64, 3}}, i::Vector{Int32}, j::Vector{Int32})
@ Gridap.Arrays C:\Users\marya\.julia\packages\Gridap\971dU\src\Arrays\AlgebraMaps.jl:47
@ Gridap.FESpaces C:\Users\marya\.julia\packages\Gridap\971dU\src\FESpaces\SparseMatrixAssemblers.jl:261
[8] numeric_loop_matrix!(A::Gridap.Algebra.InserterCSC{Float64, Int64}, a::Gridap.FESpaces.GenericSparseMatrixAssembler, matdata::Tuple{Vector{Any}, Vector{Any}, Vector{Any}})
@ Gridap.FESpaces C:\Users\marya\.julia\packages\Gridap\971dU\src\FESpaces\SparseMatrixAssemblers.jl:248
[9] assemble_matrix(a::Gridap.FESpaces.GenericSparseMatrixAssembler, matdata::Tuple{Vector{Any}, Vector{Any}, Vector{Any}})
@ Gridap.FESpaces C:\Users\marya\.julia\packages\Gridap\971dU\src\FESpaces\SparseMatrixAssemblers.jl:107
[10] assemble_matrix(f::var"#79#82"{NamedTuple{(:V0_Disp, :U_PF, :V0_PF, :Q, :P, :Qf, :Pf, :np, :Ω, :dΩ, :n_Γ_Load, :dΓ_Load), Tuple{Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{VectorValue{2, Int32}}}, TrialFESpace{Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{Int32}}}, Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{Int32}}, Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Nothing}, TrialFESpace{Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Nothing}}, Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{Int32}}, TrialFESpace{Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{Int32}}}, Int64, BodyFittedTriangulation{2, 2, UnstructuredDiscreteModel{2, 2, Float64, Oriented}, UnstructuredGrid{2, 2, Float64, Oriented, Nothing}, Gridap.Arrays.IdentityVector{Int64}}, Gridap.CellData.GenericMeasure, GenericCellField{ReferenceDomain}, Gridap.CellData.GenericMeasure}}, Gridap.CellData.OperationCellField{ReferenceDomain}, Gridap.FESpaces.SingleFieldFEFunction{GenericCellField{ReferenceDomain}}, Gridap.FESpaces.SingleFieldFEFunction{GenericCellField{ReferenceDomain}}, var"#dAs_Disp#80"}, a::Gridap.FESpaces.GenericSparseMatrixAssembler, U::Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{VectorValue{2, Int32}}}, V::TrialFESpace{Gridap.FESpaces.UnconstrainedFESpace{Vector{Float64}, Gridap.FESpaces.NodeToDofGlue{Int32}}})
@ Gridap.FESpaces C:\Users\marya\.julia\packages\Gridap\971dU\src\FESpaces\Assemblers.jl:285
[11] assemble_matrix
@ C:\Users\marya\.julia\packages\Gridap\971dU\src\FESpaces\Assemblers.jl:342 [inlined]
[12] #MatrixdAs#77
@ .\In[48]:9 [inlined]
[13] top-level scope
@ In[48]:14


You can choose how you want to arrange the dimensions. Choose whatever will be practical in the following code.

I am sorry, but I am not familiar with this package. So someone else needs to chime in and comment on that

thank you the indices notation helps a lot