mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-20 18:18:31 +00:00
added sparse assembly
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
# This file is a part of JuliaFEM. License is MIT: https://github.com/ovainola/JuliaFEM/blob/master/README.md
|
||||
module elasticity_solver
|
||||
|
||||
using Logging
|
||||
@Logging.configure(level=DEBUG)
|
||||
|
||||
VERSION < v"0.4-" && using Docile
|
||||
|
||||
export solve_elasticity_interface!
|
||||
@@ -69,6 +72,85 @@ function calc_local_matrices!(X, u, R, Kt, N, dNdξ, λ_, μ_, ipoints, iweights
|
||||
end
|
||||
|
||||
|
||||
@doc """
|
||||
Assemble global stiffness matrix to I,J,V ready for sparse format
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ke : local matrix
|
||||
eldofs_ : Array
|
||||
degrees of freedom
|
||||
I,J,V : Arrays for sparse matrix
|
||||
|
||||
Notes
|
||||
-----
|
||||
eldofs can also be node ids for convenience. In that case dimension
|
||||
is calculated and eldofs are "extended" to problem dimension.
|
||||
""" ->
|
||||
function assemble!(ke, eldofs_, I, J, V)
|
||||
n, m = size(ke)
|
||||
dim = round(Int, n/length(eldofs_))
|
||||
@debug("problem dim = ", dim)
|
||||
if dim == 1
|
||||
eldofs = eldofs_
|
||||
else
|
||||
eldofs = Int64[]
|
||||
for i in eldofs_
|
||||
for d in 1:dim
|
||||
push!(eldofs, dim*(i-1)+d)
|
||||
end
|
||||
end
|
||||
@debug("old eldofs", eldofs_)
|
||||
@debug("new eldofs", eldofs)
|
||||
end
|
||||
for i in 1:n
|
||||
for j in 1:m
|
||||
push!(I, eldofs[i])
|
||||
push!(J, eldofs[j])
|
||||
push!(V, ke[i,j])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@doc """
|
||||
Assemble global RHS to I,V ready for sparse format
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fe : local vector
|
||||
eldofs_ : Array
|
||||
degrees of freedom
|
||||
I,V : Arrays for sparse matrix
|
||||
|
||||
Notes
|
||||
-----
|
||||
eldofs can also be node ids for convenience. In that case dimension
|
||||
is calculated and eldofs are "extended" to problem dimension.
|
||||
""" ->
|
||||
function assemble!(fe, eldofs_, I, V)
|
||||
n = length(fe)
|
||||
dim = round(Int, n/length(eldofs_))
|
||||
if dim == 1
|
||||
eldofs = eldofs_
|
||||
else
|
||||
eldofs = Int64[]
|
||||
for i in eldofs_
|
||||
for d in 1:dim
|
||||
push!(eldofs, dim*(i-1)+d)
|
||||
end
|
||||
end
|
||||
@debug("old eldofs", eldofs_)
|
||||
@debug("new eldofs", eldofs)
|
||||
end
|
||||
|
||||
for i in 1:n
|
||||
push!(I, eldofs[i])
|
||||
push!(V, fe[i])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@doc """
|
||||
Solve one increment of elasticity problem
|
||||
""" ->
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using JuliaFEM.elasticity_solver
|
||||
|
||||
using FactCheck
|
||||
using Logging
|
||||
@Logging.configure(level=DEBUG)
|
||||
|
||||
|
||||
using JuliaFEM.elasticity_solver: solve_elasticity_increment!
|
||||
facts("test solve elasticity increment") do
|
||||
|
||||
X = [0 0; 10 0; 10 1; 0 1]'
|
||||
elmap = [1; 2; 3; 4]
|
||||
nodalloads = [0 0; 0 0; 0 -2; 0 0]'
|
||||
@@ -41,8 +41,8 @@ facts("test solve elasticity increment") do
|
||||
iweights = [1 1 1 1]
|
||||
|
||||
for i=1:10
|
||||
JuliaFEM.elasticity_solver.solve_elasticity_increment!(
|
||||
X, u, du, R, Kt,elmap, nodalloads, dirichletbc, la, mu, N, dNdξ, ipoints, iweights)
|
||||
solve_elasticity_increment!(X, u, du, R, Kt,elmap, nodalloads, dirichletbc,
|
||||
la, mu, N, dNdξ, ipoints, iweights)
|
||||
@debug("increment:\n",du)
|
||||
u += du
|
||||
if norm(du) < 1.0e-9
|
||||
@@ -52,3 +52,70 @@ facts("test solve elasticity increment") do
|
||||
@debug("solution\n",u)
|
||||
@fact u[2, 3] => roughly(-2.222244754401764) # Tested against Elmer solution
|
||||
end
|
||||
|
||||
|
||||
using JuliaFEM.elasticity_solver: assemble!
|
||||
|
||||
facts("test assembly of global matrix for 1 dim/node case") do
|
||||
I = Int64[]
|
||||
J = Int64[]
|
||||
V = Float64[]
|
||||
ke = [3 1; 1 1]
|
||||
eldofs = [1, 2]
|
||||
assemble!(ke, eldofs, I, J, V)
|
||||
ke = [4 2; 2 3]
|
||||
eldofs = [2, 4]
|
||||
assemble!(ke, eldofs, I, J, V)
|
||||
S = full(sparse(I, J, V))
|
||||
@fact S => [3.0 1.0 0.0 0.0
|
||||
1.0 5.0 0.0 2.0
|
||||
0.0 0.0 0.0 0.0
|
||||
0.0 2.0 0.0 3.0]
|
||||
end
|
||||
|
||||
facts("test assembly of global vector for 1 dim/node case") do
|
||||
I = Int64[]
|
||||
V = Float64[]
|
||||
fe = [1;2]
|
||||
eldofs = [1, 2]
|
||||
assemble!(fe, eldofs, I, V)
|
||||
fe = [3;1]
|
||||
eldofs = [2, 4]
|
||||
assemble!(fe, eldofs, I, V)
|
||||
S = full(sparsevec(I, V))
|
||||
@fact S => [1.0 5.0 0.0 1.0]'
|
||||
end
|
||||
|
||||
facts("test assembly of global matrix for 2 dim/node case") do
|
||||
# provide "convienence" function, if given only nodal connectivity
|
||||
# automatically find out dimension and "extend" matrix to full
|
||||
I = Int64[]
|
||||
J = Int64[]
|
||||
V = Float64[]
|
||||
ke = reshape(1:16, 4, 4)
|
||||
eldofs = [1, 2]
|
||||
assemble!(ke, eldofs, I, J, V)
|
||||
eldofs = [2, 3]
|
||||
assemble!(2*ke, eldofs, I, J, V)
|
||||
expected = zeros(6, 6)
|
||||
expected[1:4,1:4] += ke
|
||||
expected[3:6,3:6] += 2*ke
|
||||
S = full(sparse(I, J, V))
|
||||
@fact S => expected
|
||||
end
|
||||
|
||||
facts("test assembly of global vector for 2 dim/node case") do
|
||||
# provide "convienence" function, if given only nodal connectivity
|
||||
# automatically find out dimension and "extend" matrix to full
|
||||
I = Int64[]
|
||||
J = Int64[]
|
||||
V = Float64[]
|
||||
fe = [1, 2, 3, 4]
|
||||
eldofs = [1, 2]
|
||||
assemble!(fe, eldofs, I, V)
|
||||
eldofs = [2, 3]
|
||||
assemble!(2*fe, eldofs, I, V)
|
||||
S = full(sparsevec(I, V))
|
||||
expected = [1.0 2.0 5.0 8.0 6.0 8.0]'
|
||||
@fact S => expected
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user