mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-25 19:36:58 +00:00
Bug/mortar discretization (#88)
* new mortar segmentation tests which are failing * test_problems_mortar_3d.jl: first test (Tet4) pass * solvers.jl: diagonal of A is now properly filled, if that option is used. Another option is to remove zero rows from matrix system, which is on by default * problems_mortar.jl: added new function diagnose_interface to calculate quantities from interface hopefully revealing bugs in calculation * problems_mortar_3d.jl: added docstring for check_orientation! and removed flooding debug messages not helping to debug anything * solvers.jl: Another way to solve Ax = b * Refactored code to make implementation of Tri6 assemble! easier * Patch test with linear Tet4 elements and quadratic Tet10 elements pass When using quadratic elements, in polygon clipping algorithm element is divided to linear sub-elements as proposed in [Puso2008]. Interpolation of Lagrange multiplier space is done using quadratic shape functions. References ---------- [Puso2008] Puso, Michael A., T. A. Laursen, and Jerome Solberg. "A segment-to-segment mortar contact method for quadratic elements and large deformations." Computer Methods in Applied Mechanics and Engineering 197.6 (2008): 555-566. * increased coverage by adding diagnose_interface * test using dual basis, failing for unknown reason * Fixed dual basis construction for Mortar/Tet4 The coefficient matrix Ae for one particular slave element e is the result performing numerical integration on *all* integration cells associated with this element [Popp2013]. Ae cannot be calculated "cell-wise" like it was done before. Now patch test will pass also using `interface.properties.dual_basis = true` option. Partially integrated slave elements are supported as well. References ---------- [Popp2013] Popp, Alexander, et al. "Improved robustness and consistency of 3D contact algorithms based on a dual mortar approach." Computer Methods in Applied Mechanics and Engineering 264 (2013): 67-80. * Minor modifications to preprocess.jl - removed two functions which are unimplemented (but maybe planned in future) - added function create_node_set_from_element_set!, which can be used, like name suggests, to create a node set from nodes belonging to some set of elements. * solvers.jl: now prints a list of overconstrained nodes which can be easily copy-pasted to problem.assembly.removed_dofs list to solver overconstrained situation manually * Increase code coverage Added a new test which tests dual basis 3d mortar + adjust option when using Tet4 in elasticity problem. * Tet10 + Dual basis still failing, others are working * mortar 3d low level tests * linear surface element projection tests pass * Introduced basis transform constant alpha Tet10 + dual basis patch test still failing, but single element low level routine tests gives expected results with alpha=0.2 * added new integration rule FPG12 for triangular elements * added drop_tolerance option to remove very small values from constraint matrices * Introduced a basis transform matrix T Constructing bi-orthogonal basis for quadratic surfaces is ill-conditioned. By doing a basis transform N' = N*T for slave side displacement vector it's possible to construct a bi-orthogonal basis in a same way than with linear elements. Setting alpha=0.2 ensures that quadratic basis functions are strictly positive in practical cases. * fix 3d clipping test routine, accepts only 3d vertices * dropped number of integration poitns from 12 to 7 in quadratic mortar surfaces intrestingly gives more accurate results, maybe something numerical error in FPG12 integration rule..? * added two displacement patch tests + output writing for all cases * %s/Int64/Int/g * Changed test data location * Fine tuning of logging levels
This commit is contained in:
committed by
Tero Frondelius
parent
a5c093c1d6
commit
f275ce3767
@@ -1,10 +1,11 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
using JuliaFEM
|
||||
using JuliaFEM: get_polygon_clip, calculate_polygon_area
|
||||
using JuliaFEM.Testing
|
||||
|
||||
@testset "polygon clip case 1" begin
|
||||
@testset "polygon clipping" begin
|
||||
|
||||
S = Vector[
|
||||
[0.375, 0.0, 0.5],
|
||||
[0.6, 0.0, 0.5],
|
||||
@@ -15,17 +16,9 @@ using JuliaFEM.Testing
|
||||
[0.375, 0.25, 0.5]]
|
||||
n0 = [0.0, 0.0, 1.0]
|
||||
P = get_polygon_clip(S, M, n0)
|
||||
P_expected = Vector{Float64}[
|
||||
[0.500, 0.0, 0.5],
|
||||
[0.375, 0.0, 0.5],
|
||||
[0.4375, 0.125, 0.5]]
|
||||
@test length(P) == length(P_expected)
|
||||
for (Pi, Pj) in zip(P, P_expected)
|
||||
@test isapprox(Pi, Pj)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "polygon clip case 2" begin
|
||||
@test length(P) == 3
|
||||
@test isapprox(calculate_polygon_area(P), 1/128)
|
||||
|
||||
S = Vector[
|
||||
[0.25, 0.0, 0.5],
|
||||
[0.75, 0.0, 0.5],
|
||||
@@ -37,5 +30,13 @@ end
|
||||
n0 = [0.0, 0.0, 1.0]
|
||||
P = get_polygon_clip(S, M, n0)
|
||||
@test length(P) == 3
|
||||
end
|
||||
@test isapprox(calculate_polygon_area(P), 1/48)
|
||||
|
||||
# visually inspected
|
||||
Xs = Vector[[0.0, 0.0, 0.5], [1.0, 0.0, 0.5], [0.0, 1.0, 0.5]]
|
||||
Xm = Vector[[-0.25, 0.50, 0.5], [0.50, -0.25, 0.5], [0.75,0.75, 0.5]]
|
||||
P_ = Vector[[0.65,0.35,0.0], [0.5625,0.0,0.0], [0.25,0.0,0.0],
|
||||
[0.0,0.25,0.0], [0.0,0.5625,0.0], [0.35,0.65,0.0]]
|
||||
P = get_polygon_clip(Xs, Xm, [0.0, 0.0, 1.0])
|
||||
@test length(P) == length(P_)
|
||||
end
|
||||
|
||||
+428
-11
@@ -7,32 +7,40 @@ using JuliaFEM.Postprocess
|
||||
using JuliaFEM.Testing
|
||||
using JuliaFEM.Abaqus: create_surface_elements
|
||||
|
||||
@testset "test that interface transfers constant field without error" begin
|
||||
meshfile = Pkg.dir("JuliaFEM") * "/test/testdata/block_3d.med"
|
||||
mesh = aster_read_mesh(meshfile)
|
||||
### temperature patch tests, sl tet4, dl tet4, sl tet10, dl tet 10
|
||||
|
||||
upper = Problem(Heat, "upper", 1)
|
||||
tet4_meshfile = "test_problems_mortar_3d/tet4.inp"
|
||||
tet10_meshfile = "test_problems_mortar_3d/tet10.inp"
|
||||
|
||||
@testset "patch test temperature + abaqus inp + tet4" begin
|
||||
mesh = abaqus_read_mesh(tet4_meshfile)
|
||||
|
||||
upper = Problem(Heat, "UPPER", 1)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "temperature thermal conductivity", 1.0)
|
||||
lower = Problem(Heat, "lower", 1)
|
||||
|
||||
lower = Problem(Heat, "LOWER", 1)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "temperature thermal conductivity", 1.0)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "upper boundary", 1, "temperature")
|
||||
bc_upper.elements = create_elements(mesh, "UPPER_TOP")
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 1, "temperature")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "temperature 1", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "lower boundary", 1, "temperature")
|
||||
bc_lower.elements = create_elements(mesh, "LOWER_BOTTOM")
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 1, "temperature")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "temperature 1", 1.0)
|
||||
|
||||
interface = Problem(Mortar, "interface between upper and lower block", 1, "temperature")
|
||||
interface_slave_elements = create_elements(mesh, "LOWER_TOP")
|
||||
interface_master_elements = create_elements(mesh, "UPPER_BOTTOM")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_master_elements; interface_slave_elements]
|
||||
|
||||
JuliaFEM.diagnose_interface(interface, 0.0)
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, interface)
|
||||
solver.xdmf = Xdmf("sl_lin_temp_results")
|
||||
|
||||
solver()
|
||||
|
||||
node_ids, temperature = get_nodal_vector(interface.elements, "temperature", 0.0)
|
||||
@@ -42,4 +50,413 @@ using JuliaFEM.Abaqus: create_surface_elements
|
||||
info("minT = $minT, maxT = $maxT")
|
||||
@test isapprox(minT, 0.5)
|
||||
@test isapprox(maxT, 0.5)
|
||||
|
||||
#=
|
||||
initialize!(solver)
|
||||
assemble!(solver)
|
||||
M, K, Kg, f, fg = get_field_assembly(solver)
|
||||
Kb, C1, C2, D, fb, g = get_boundary_assembly(solver)
|
||||
K = K + Kg + Kb
|
||||
f = f + fg + fb
|
||||
K = 1/2*(K + K')
|
||||
M = 1/2*(M + M')
|
||||
=#
|
||||
|
||||
end
|
||||
|
||||
@testset "patch test temperature + abaqus inp + tet4 + dual basis + adjust" begin
|
||||
mesh = abaqus_read_mesh(tet4_meshfile)
|
||||
|
||||
upper = Problem(Heat, "UPPER", 1)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "temperature thermal conductivity", 1.0)
|
||||
|
||||
lower = Problem(Heat, "LOWER", 1)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "temperature thermal conductivity", 1.0)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 1, "temperature")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "temperature 1", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 1, "temperature")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "temperature 1", 1.0)
|
||||
|
||||
interface = Problem(Mortar, "interface between upper and lower block", 1, "temperature")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_master_elements; interface_slave_elements]
|
||||
interface.properties.dual_basis = true
|
||||
#interface.properties.adjust = true
|
||||
|
||||
JuliaFEM.diagnose_interface(interface, 0.0)
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, interface)
|
||||
solver.xdmf = Xdmf("dl_lin_temp_results")
|
||||
|
||||
solver()
|
||||
|
||||
node_ids, temperature = get_nodal_vector(interface.elements, "temperature", 0.0)
|
||||
T = [t[1] for t in temperature]
|
||||
minT = minimum(T)
|
||||
maxT = maximum(T)
|
||||
info("minT = $minT, maxT = $maxT")
|
||||
@test isapprox(minT, 0.5)
|
||||
@test isapprox(maxT, 0.5)
|
||||
|
||||
end
|
||||
|
||||
@testset "patch test temperature + abaqus inp + tet10, quadratic surface elements" begin
|
||||
mesh = abaqus_read_mesh(tet10_meshfile)
|
||||
|
||||
upper = Problem(Heat, "UPPER", 1)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "temperature thermal conductivity", 1.0)
|
||||
|
||||
lower = Problem(Heat, "LOWER", 1)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "temperature thermal conductivity", 1.0)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 1, "temperature")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "temperature 1", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 1, "temperature")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "temperature 1", 1.0)
|
||||
|
||||
interface = Problem(Mortar, "interface between upper and lower block", 1, "temperature")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_master_elements; interface_slave_elements]
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.alpha = 0.0
|
||||
# JuliaFEM.diagnose_interface(interface, 0.0)
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, interface)
|
||||
solver.xdmf = Xdmf("sl_quad_temp_results")
|
||||
solver()
|
||||
|
||||
node_ids, temperature = get_nodal_vector(interface.elements, "temperature", 0.0)
|
||||
T = [t[1] for t in temperature]
|
||||
|
||||
minT = minimum(T)
|
||||
maxT = maximum(T)
|
||||
stdT = std(T)
|
||||
info("minT = $minT, maxT = $maxT, stdT = $stdT")
|
||||
@test maxT - minT < 1.0e-10
|
||||
@test isapprox(stdT, 0.0; atol=1.0e-10)
|
||||
|
||||
end
|
||||
|
||||
@testset "patch test temperature + abaqus inp + tet10 + quadratic surface elements + dual basis + alpha=0.2" begin
|
||||
mesh = abaqus_read_mesh(tet10_meshfile)
|
||||
|
||||
upper = Problem(Heat, "UPPER", 1)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "temperature thermal conductivity", 1.0)
|
||||
|
||||
lower = Problem(Heat, "LOWER", 1)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "temperature thermal conductivity", 1.0)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 1, "temperature")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "temperature 1", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 1, "temperature")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "temperature 1", 1.0)
|
||||
|
||||
interface = Problem(Mortar, "interface between upper and lower block", 1, "temperature")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_master_elements; interface_slave_elements]
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.dual_basis = true
|
||||
interface.properties.alpha = 0.2
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, interface)
|
||||
solver.xdmf = Xdmf("dl_quad_temp_results")
|
||||
solver()
|
||||
|
||||
node_ids, temperature = get_nodal_vector(interface.elements, "temperature", 0.0)
|
||||
#node_ids, temperature = get_nodal_vector(interface_slave_elements, "temperature", 0.0)
|
||||
#=
|
||||
for (j, (nid, T)) in enumerate(zip(node_ids, temperature))
|
||||
info("$j: $nid -> $(T[1])")
|
||||
j == 10 && break
|
||||
end
|
||||
=#
|
||||
T = [t[1] for t in temperature]
|
||||
minT = minimum(T)
|
||||
maxT = maximum(T)
|
||||
stdT = std(T)
|
||||
info("minT = $minT, maxT = $maxT, stdT = $stdT")
|
||||
@test maxT - minT < 1.0e-10
|
||||
@test isapprox(stdT, 0.0; atol=1.0e-10)
|
||||
end
|
||||
|
||||
### displacement patch tests, sl tet4, dl tet4, sl tet10, dl tet 10
|
||||
|
||||
@testset "patch test displacement + abaqus inp + tet4 + adjust" begin
|
||||
|
||||
mesh = abaqus_read_mesh(tet4_meshfile)
|
||||
# modify mesh a bit, find all nodes in elements in element set UPPER and put 0.2 to X3 to test adjust
|
||||
JuliaFEM.Preprocess.create_node_set_from_element_set!(mesh, :UPPER)
|
||||
for nid in mesh.node_sets[:UPPER]
|
||||
mesh.nodes[nid][3] += 0.2
|
||||
end
|
||||
|
||||
upper = Problem(Elasticity, "UPPER", 3)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "youngs modulus", 288.0)
|
||||
update!(upper, "poissons ratio", 1/3)
|
||||
|
||||
lower = Problem(Elasticity, "LOWER", 3)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "youngs modulus", 288.0)
|
||||
update!(lower, "poissons ratio", 1/3)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 3, "displacement")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "displacement 3", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 3, "displacement")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "displacement 3", 0.0)
|
||||
|
||||
bc_sym13 = Problem(Dirichlet, "SYM13", 3, "displacement")
|
||||
bc_sym13.elements = [create_surface_elements(mesh, "LOWER_SYM13"); create_surface_elements(mesh, "UPPER_SYM13")]
|
||||
update!(bc_sym13, "displacement 2", 0.0)
|
||||
|
||||
bc_sym23 = Problem(Dirichlet, "SYM23", 3, "displacement")
|
||||
bc_sym23.elements = [create_surface_elements(mesh, "LOWER_SYM23"); create_surface_elements(mesh, "UPPER_SYM23")]
|
||||
update!(bc_sym23, "displacement 1", 0.0)
|
||||
|
||||
interface = Problem(Mortar, "LOWER_TO_UPPER", 3, "displacement")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_slave_elements; interface_master_elements]
|
||||
|
||||
append!(interface.assembly.removed_dofs, [1316, 1319, 1358, 1387, 1388, 1492, 1597, 1627])
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.adjust = true
|
||||
interface.properties.dual_basis = false
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, bc_sym13, bc_sym23, interface)
|
||||
solver.xdmf = Xdmf("sl_lin_disp_results")
|
||||
solver()
|
||||
|
||||
node_ids, displacement = get_nodal_vector(interface.elements, "displacement", 0.0)
|
||||
node_ids, geometry = get_nodal_vector(interface.elements, "geometry", 0.0)
|
||||
u3 = [u[3] for u in displacement]
|
||||
maxabsu3 = maximum(abs(u3))
|
||||
stdabsu3 = std(abs(u3))
|
||||
info("tet10 block: max(abs(u3)) = $maxabsu3, std(abs(u3)) = $stdabsu3")
|
||||
@test isapprox(stdabsu3, 0.0; atol=1.0e-10)
|
||||
end
|
||||
|
||||
@testset "patch test displacement + abaqus inp + tet4 + adjust + dual basis" begin
|
||||
|
||||
mesh = abaqus_read_mesh(tet4_meshfile)
|
||||
# modify mesh a bit, find all nodes in elements in element set UPPER and put 0.2 to X3 to test adjust
|
||||
JuliaFEM.Preprocess.create_node_set_from_element_set!(mesh, :UPPER)
|
||||
for nid in mesh.node_sets[:UPPER]
|
||||
mesh.nodes[nid][3] += 0.2
|
||||
end
|
||||
|
||||
upper = Problem(Elasticity, "UPPER", 3)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "youngs modulus", 288.0)
|
||||
update!(upper, "poissons ratio", 1/3)
|
||||
|
||||
lower = Problem(Elasticity, "LOWER", 3)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "youngs modulus", 288.0)
|
||||
update!(lower, "poissons ratio", 1/3)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 3, "displacement")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "displacement 3", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 3, "displacement")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "displacement 3", 0.0)
|
||||
|
||||
bc_sym13 = Problem(Dirichlet, "SYM13", 3, "displacement")
|
||||
bc_sym13.elements = [create_surface_elements(mesh, "LOWER_SYM13"); create_surface_elements(mesh, "UPPER_SYM13")]
|
||||
update!(bc_sym13, "displacement 2", 0.0)
|
||||
|
||||
bc_sym23 = Problem(Dirichlet, "SYM23", 3, "displacement")
|
||||
bc_sym23.elements = [create_surface_elements(mesh, "LOWER_SYM23"); create_surface_elements(mesh, "UPPER_SYM23")]
|
||||
update!(bc_sym23, "displacement 1", 0.0)
|
||||
|
||||
interface = Problem(Mortar, "LOWER_TO_UPPER", 3, "displacement")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_slave_elements; interface_master_elements]
|
||||
|
||||
append!(interface.assembly.removed_dofs, [1316, 1319, 1358, 1387, 1388, 1492, 1597, 1627])
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.adjust = true
|
||||
interface.properties.dual_basis = true
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, bc_sym13, bc_sym23, interface)
|
||||
solver.xdmf = Xdmf("dl_lin_disp_results")
|
||||
solver()
|
||||
|
||||
node_ids, displacement = get_nodal_vector(interface.elements, "displacement", 0.0)
|
||||
node_ids, geometry = get_nodal_vector(interface.elements, "geometry", 0.0)
|
||||
u3 = [u[3] for u in displacement]
|
||||
maxabsu3 = maximum(abs(u3))
|
||||
stdabsu3 = std(abs(u3))
|
||||
info("tet10 block: max(abs(u3)) = $maxabsu3, std(abs(u3)) = $stdabsu3")
|
||||
@test isapprox(stdabsu3, 0.0; atol=1.0e-10)
|
||||
end
|
||||
|
||||
@testset "patch test displacement + abaqus inp + tet10 + adjust" begin
|
||||
|
||||
mesh = abaqus_read_mesh(tet10_meshfile)
|
||||
# modify mesh a bit, find all nodes in elements in element set UPPER and put 0.2 to X3 to test adjust
|
||||
JuliaFEM.Preprocess.create_node_set_from_element_set!(mesh, :UPPER)
|
||||
for nid in mesh.node_sets[:UPPER]
|
||||
mesh.nodes[nid][3] += 0.2
|
||||
end
|
||||
|
||||
upper = Problem(Elasticity, "UPPER", 3)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "youngs modulus", 288.0)
|
||||
update!(upper, "poissons ratio", 1/3)
|
||||
|
||||
lower = Problem(Elasticity, "LOWER", 3)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "youngs modulus", 288.0)
|
||||
update!(lower, "poissons ratio", 1/3)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 3, "displacement")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "displacement 3", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 3, "displacement")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "displacement 3", 0.0)
|
||||
|
||||
bc_sym13 = Problem(Dirichlet, "SYM13", 3, "displacement")
|
||||
bc_sym13.elements = [create_surface_elements(mesh, "LOWER_SYM13"); create_surface_elements(mesh, "UPPER_SYM13")]
|
||||
update!(bc_sym13, "displacement 2", 0.0)
|
||||
|
||||
bc_sym23 = Problem(Dirichlet, "SYM23", 3, "displacement")
|
||||
bc_sym23.elements = [create_surface_elements(mesh, "LOWER_SYM23"); create_surface_elements(mesh, "UPPER_SYM23")]
|
||||
update!(bc_sym23, "displacement 1", 0.0)
|
||||
|
||||
interface = Problem(Mortar, "LOWER_TO_UPPER", 3, "displacement")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_slave_elements; interface_master_elements]
|
||||
|
||||
removed_dofs = [1316, 1319, 1325, 1358, 1361, 1387, 1388, 1391, 1492, 1597, 1600, 1627, 1630, 1657]
|
||||
append!(interface.assembly.removed_dofs, removed_dofs)
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.adjust = true
|
||||
interface.properties.dual_basis = false
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, bc_sym13, bc_sym23, interface)
|
||||
solver.xdmf = Xdmf("sl_quad_disp_results")
|
||||
solver()
|
||||
|
||||
node_ids, displacement = get_nodal_vector(interface.elements, "displacement", 0.0)
|
||||
node_ids, geometry = get_nodal_vector(interface.elements, "geometry", 0.0)
|
||||
u3 = [u[3] for u in displacement]
|
||||
maxabsu3 = maximum(abs(u3))
|
||||
stdabsu3 = std(abs(u3))
|
||||
info("tet10 block: max(abs(u3)) = $maxabsu3, std(abs(u3)) = $stdabsu3")
|
||||
@test isapprox(stdabsu3, 0.0; atol=1.0e-6)
|
||||
end
|
||||
|
||||
|
||||
@testset "patch test displacement + abaqus inp + tet10 + adjust + dual basis + alpha=0.2" begin
|
||||
|
||||
mesh = abaqus_read_mesh(tet10_meshfile)
|
||||
# modify mesh a bit, find all nodes in elements in element set UPPER and put 0.2 to X3 to test adjust
|
||||
JuliaFEM.Preprocess.create_node_set_from_element_set!(mesh, :UPPER)
|
||||
for nid in mesh.node_sets[:UPPER]
|
||||
mesh.nodes[nid][3] += 0.2
|
||||
end
|
||||
|
||||
upper = Problem(Elasticity, "UPPER", 3)
|
||||
upper.elements = create_elements(mesh, "UPPER")
|
||||
update!(upper, "youngs modulus", 288.0)
|
||||
update!(upper, "poissons ratio", 1/3)
|
||||
|
||||
lower = Problem(Elasticity, "LOWER", 3)
|
||||
lower.elements = create_elements(mesh, "LOWER")
|
||||
update!(lower, "youngs modulus", 288.0)
|
||||
update!(lower, "poissons ratio", 1/3)
|
||||
|
||||
bc_upper = Problem(Dirichlet, "UPPER_TOP", 3, "displacement")
|
||||
bc_upper.elements = create_surface_elements(mesh, "UPPER_TOP")
|
||||
update!(bc_upper, "displacement 3", 0.0)
|
||||
|
||||
bc_lower = Problem(Dirichlet, "LOWER_BOTTOM", 3, "displacement")
|
||||
bc_lower.elements = create_surface_elements(mesh, "LOWER_BOTTOM")
|
||||
update!(bc_lower, "displacement 3", 0.0)
|
||||
|
||||
bc_sym13 = Problem(Dirichlet, "SYM13", 3, "displacement")
|
||||
bc_sym13.elements = [create_surface_elements(mesh, "LOWER_SYM13"); create_surface_elements(mesh, "UPPER_SYM13")]
|
||||
update!(bc_sym13, "displacement 2", 0.0)
|
||||
|
||||
bc_sym23 = Problem(Dirichlet, "SYM23", 3, "displacement")
|
||||
bc_sym23.elements = [create_surface_elements(mesh, "LOWER_SYM23"); create_surface_elements(mesh, "UPPER_SYM23")]
|
||||
update!(bc_sym23, "displacement 1", 0.0)
|
||||
|
||||
interface = Problem(Mortar, "LOWER_TO_UPPER", 3, "displacement")
|
||||
interface_slave_elements = create_surface_elements(mesh, "LOWER_TO_UPPER")
|
||||
interface_master_elements = create_surface_elements(mesh, "UPPER_TO_LOWER")
|
||||
update!(interface_slave_elements, "master elements", interface_master_elements)
|
||||
interface.elements = [interface_slave_elements; interface_master_elements]
|
||||
|
||||
removed_dofs = [1316, 1319, 1325, 1358, 1361, 1387, 1388, 1391, 1492, 1597, 1600, 1627, 1630, 1657]
|
||||
append!(interface.assembly.removed_dofs, removed_dofs)
|
||||
|
||||
interface.properties.linear_surface_elements = false
|
||||
interface.properties.split_quadratic_slave_elements = false
|
||||
interface.properties.split_quadratic_master_elements = false
|
||||
interface.properties.adjust = true
|
||||
interface.properties.dual_basis = true
|
||||
interface.properties.alpha = 0.2
|
||||
|
||||
solver = LinearSolver(upper, lower, bc_upper, bc_lower, bc_sym13, bc_sym23, interface)
|
||||
solver.xdmf = Xdmf("dl_quad_disp_results")
|
||||
solver()
|
||||
|
||||
node_ids, displacement = get_nodal_vector(interface.elements, "displacement", 0.0)
|
||||
node_ids, geometry = get_nodal_vector(interface.elements, "geometry", 0.0)
|
||||
u3 = [u[3] for u in displacement]
|
||||
maxabsu3 = maximum(abs(u3))
|
||||
stdabsu3 = std(abs(u3))
|
||||
info("tet10 block: max(abs(u3)) = $maxabsu3, std(abs(u3)) = $stdabsu3")
|
||||
@test isapprox(stdabsu3, 0.0; atol=1.0e-6)
|
||||
end
|
||||
|
||||
|
||||
Executable → Regular
@@ -0,0 +1,589 @@
|
||||
**NSET COUNT = 116
|
||||
*NODE
|
||||
127, 1.00000, 0.00000, 0.75000
|
||||
128, 1.00000, 0.00000, 1.00000
|
||||
129, 0.75000, 0.00000, 1.00000
|
||||
133, 0.75000, 0.00000, 0.75000
|
||||
136, 1.00000, 0.00000, 0.50000
|
||||
139, 0.75000, 0.00000, 0.50000
|
||||
142, 0.50000, 0.00000, 1.00000
|
||||
145, 0.50000, 0.00000, 0.75000
|
||||
149, 0.50000, 0.00000, 0.50000
|
||||
152, 0.25000, 0.00000, 1.00000
|
||||
155, 0.25000, 0.00000, 0.75000
|
||||
159, 0.25000, 0.00000, 0.50000
|
||||
162, 0.00000, 0.00000, 1.00000
|
||||
165, 0.00000, 0.00000, 0.75000
|
||||
169, 0.00000, 0.00000, 0.50000
|
||||
172, 0.75000, 1.00000, 1.00000
|
||||
173, 1.00000, 1.00000, 1.00000
|
||||
174, 1.00000, 1.00000, 0.75000
|
||||
178, 0.75000, 1.00000, 0.75000
|
||||
181, 1.00000, 1.00000, 0.50000
|
||||
184, 0.75000, 1.00000, 0.50000
|
||||
187, 0.50000, 1.00000, 1.00000
|
||||
190, 0.50000, 1.00000, 0.75000
|
||||
194, 0.50000, 1.00000, 0.50000
|
||||
197, 0.25000, 1.00000, 1.00000
|
||||
200, 0.25000, 1.00000, 0.75000
|
||||
204, 0.25000, 1.00000, 0.50000
|
||||
207, 0.00000, 1.00000, 1.00000
|
||||
210, 0.00000, 1.00000, 0.75000
|
||||
214, 0.00000, 1.00000, 0.50000
|
||||
217, 1.00000, 0.75000, 1.00000
|
||||
220, 1.00000, 0.75000, 0.75000
|
||||
224, 1.00000, 0.75000, 0.50000
|
||||
227, 1.00000, 0.50000, 1.00000
|
||||
230, 1.00000, 0.50000, 0.75000
|
||||
234, 1.00000, 0.50000, 0.50000
|
||||
237, 1.00000, 0.25000, 1.00000
|
||||
240, 1.00000, 0.25000, 0.75000
|
||||
244, 1.00000, 0.25000, 0.50000
|
||||
252, 0.00000, 0.75000, 1.00000
|
||||
255, 0.00000, 0.75000, 0.75000
|
||||
259, 0.00000, 0.75000, 0.50000
|
||||
262, 0.00000, 0.50000, 1.00000
|
||||
265, 0.00000, 0.50000, 0.75000
|
||||
269, 0.00000, 0.50000, 0.50000
|
||||
272, 0.00000, 0.25000, 1.00000
|
||||
275, 0.00000, 0.25000, 0.75000
|
||||
279, 0.00000, 0.25000, 0.50000
|
||||
288, 0.75000, 0.75000, 1.00000
|
||||
292, 0.50000, 0.75000, 1.00000
|
||||
296, 0.25000, 0.75000, 1.00000
|
||||
302, 0.75000, 0.50000, 1.00000
|
||||
306, 0.50000, 0.50000, 1.00000
|
||||
310, 0.25000, 0.50000, 1.00000
|
||||
316, 0.75000, 0.25000, 1.00000
|
||||
320, 0.50000, 0.25000, 1.00000
|
||||
324, 0.25000, 0.25000, 1.00000
|
||||
337, 0.75000, 0.75000, 0.50000
|
||||
341, 0.50000, 0.75000, 0.50000
|
||||
345, 0.25000, 0.75000, 0.50000
|
||||
351, 0.75000, 0.50000, 0.50000
|
||||
355, 0.50000, 0.50000, 0.50000
|
||||
359, 0.25000, 0.50000, 0.50000
|
||||
365, 0.75000, 0.25000, 0.50000
|
||||
369, 0.50000, 0.25000, 0.50000
|
||||
373, 0.25000, 0.25000, 0.50000
|
||||
438, 1.00000, 0.00000, 0.25000
|
||||
439, 1.00000, 0.00000, 0.50000
|
||||
440, 0.66667, 0.00000, 0.50000
|
||||
444, 0.66667, 0.00000, 0.25000
|
||||
447, 1.00000, 0.00000, 0.00000
|
||||
450, 0.66667, 0.00000, 0.00000
|
||||
453, 0.33333, 0.00000, 0.50000
|
||||
456, 0.33333, 0.00000, 0.25000
|
||||
460, 0.33333, 0.00000, 0.00000
|
||||
463, 0.00000, 0.00000, 0.50000
|
||||
466, 0.00000, 0.00000, 0.25000
|
||||
470, 0.00000, 0.00000, 0.00000
|
||||
473, 0.66667, 1.00000, 0.50000
|
||||
474, 1.00000, 1.00000, 0.50000
|
||||
475, 1.00000, 1.00000, 0.25000
|
||||
479, 0.66667, 1.00000, 0.25000
|
||||
482, 1.00000, 1.00000, 0.00000
|
||||
485, 0.66667, 1.00000, 0.00000
|
||||
488, 0.33333, 1.00000, 0.50000
|
||||
491, 0.33333, 1.00000, 0.25000
|
||||
495, 0.33333, 1.00000, 0.00000
|
||||
498, 0.00000, 1.00000, 0.50000
|
||||
501, 0.00000, 1.00000, 0.25000
|
||||
505, 0.00000, 1.00000, 0.00000
|
||||
508, 1.00000, 0.66667, 0.50000
|
||||
511, 1.00000, 0.66667, 0.25000
|
||||
515, 1.00000, 0.66667, 0.00000
|
||||
518, 1.00000, 0.33333, 0.50000
|
||||
521, 1.00000, 0.33333, 0.25000
|
||||
525, 1.00000, 0.33333, 0.00000
|
||||
533, 0.00000, 0.66667, 0.50000
|
||||
536, 0.00000, 0.66667, 0.25000
|
||||
540, 0.00000, 0.66667, 0.00000
|
||||
543, 0.00000, 0.33333, 0.50000
|
||||
546, 0.00000, 0.33333, 0.25000
|
||||
550, 0.00000, 0.33333, 0.00000
|
||||
559, 0.66667, 0.66667, 0.50000
|
||||
563, 0.33333, 0.66667, 0.50000
|
||||
569, 0.66667, 0.33333, 0.50000
|
||||
573, 0.33333, 0.33333, 0.50000
|
||||
584, 0.66667, 0.66667, 0.00000
|
||||
588, 0.33333, 0.66667, 0.00000
|
||||
594, 0.66667, 0.33333, 0.00000
|
||||
598, 0.33333, 0.33333, 0.00000
|
||||
608, 0.66006, 0.47128, 0.70078
|
||||
609, 0.19762, 0.64074, 0.81889
|
||||
610, 0.65771, 0.82813, 0.74829
|
||||
611, 0.59993, 0.15953, 0.76106
|
||||
612, 0.40915, 0.16311, 0.74937
|
||||
613, 0.50000, 0.50000, 0.25000
|
||||
**
|
||||
**ELSET COUNT = 172
|
||||
**HWCOLOR COMP 54 0
|
||||
*ELEMENT, TYPE=C3D4, ELSET=UPPER
|
||||
570, 252, 262, 255, 609
|
||||
571, 252, 310, 262, 609
|
||||
572, 252, 296, 310, 609
|
||||
573, 200, 252, 255, 609
|
||||
574, 296, 306, 310, 609
|
||||
575, 262, 310, 265, 609
|
||||
576, 259, 265, 269, 359
|
||||
577, 184, 337, 220, 610
|
||||
578, 259, 345, 265, 359
|
||||
579, 288, 608, 292, 610
|
||||
580, 187, 288, 292, 610
|
||||
581, 172, 288, 187, 610
|
||||
582, 178, 172, 187, 610
|
||||
583, 178, 220, 172, 610
|
||||
584, 172, 220, 288, 610
|
||||
585, 230, 240, 237, 316
|
||||
586, 178, 184, 220, 610
|
||||
587, 178, 190, 184, 610
|
||||
588, 178, 187, 190, 610
|
||||
589, 187, 292, 190, 610
|
||||
590, 190, 292, 609, 610
|
||||
591, 190, 609, 341, 610
|
||||
592, 190, 341, 194, 610
|
||||
593, 184, 190, 194, 610
|
||||
594, 184, 194, 337, 610
|
||||
595, 194, 341, 337, 610
|
||||
596, 337, 341, 608, 610
|
||||
597, 230, 337, 608, 610
|
||||
598, 230, 608, 288, 610
|
||||
599, 220, 230, 288, 610
|
||||
600, 220, 337, 230, 610
|
||||
601, 341, 609, 608, 610
|
||||
602, 292, 608, 609, 610
|
||||
603, 306, 316, 320, 611
|
||||
604, 306, 608, 316, 611
|
||||
605, 365, 608, 369, 611
|
||||
606, 240, 608, 365, 611
|
||||
607, 240, 316, 608, 611
|
||||
608, 240, 133, 316, 611
|
||||
609, 240, 365, 133, 611
|
||||
610, 365, 139, 133, 611
|
||||
611, 365, 369, 139, 611
|
||||
612, 369, 149, 139, 611
|
||||
613, 149, 145, 611, 612
|
||||
614, 240, 127, 128, 316
|
||||
615, 320, 129, 142, 611
|
||||
616, 316, 129, 320, 611
|
||||
617, 316, 133, 129, 611
|
||||
618, 129, 133, 142, 611
|
||||
619, 142, 133, 145, 611
|
||||
620, 139, 145, 133, 611
|
||||
621, 139, 149, 145, 611
|
||||
622, 310, 320, 324, 612
|
||||
623, 306, 320, 310, 612
|
||||
624, 306, 611, 320, 612
|
||||
625, 306, 608, 611, 612
|
||||
626, 306, 609, 608, 612
|
||||
627, 306, 310, 609, 612
|
||||
628, 265, 609, 310, 612
|
||||
629, 265, 310, 324, 612
|
||||
630, 265, 324, 275, 612
|
||||
631, 265, 275, 373, 612
|
||||
632, 265, 373, 359, 612
|
||||
633, 265, 359, 609, 612
|
||||
634, 355, 609, 359, 612
|
||||
635, 355, 608, 609, 612
|
||||
636, 355, 369, 608, 612
|
||||
637, 369, 611, 608, 612
|
||||
638, 214, 255, 259, 345
|
||||
639, 142, 611, 145, 612
|
||||
640, 320, 611, 142, 612
|
||||
641, 320, 142, 324, 612
|
||||
642, 324, 142, 152, 612
|
||||
643, 324, 152, 155, 612
|
||||
644, 275, 324, 155, 612
|
||||
645, 275, 155, 373, 612
|
||||
646, 373, 155, 159, 612
|
||||
647, 373, 159, 149, 612
|
||||
648, 369, 373, 149, 612
|
||||
649, 359, 373, 369, 612
|
||||
650, 355, 359, 369, 612
|
||||
651, 369, 149, 611, 612
|
||||
652, 149, 155, 145, 612
|
||||
653, 149, 159, 155, 612
|
||||
654, 152, 145, 155, 612
|
||||
655, 142, 145, 152, 612
|
||||
656, 237, 240, 128, 316
|
||||
657, 244, 136, 127, 365
|
||||
658, 240, 365, 127, 133
|
||||
659, 240, 351, 244, 365
|
||||
660, 220, 224, 230, 337
|
||||
661, 227, 288, 230, 302
|
||||
662, 200, 207, 252, 296
|
||||
663, 240, 127, 316, 133
|
||||
664, 230, 337, 234, 351
|
||||
665, 275, 162, 165, 155
|
||||
666, 172, 220, 217, 288
|
||||
667, 200, 252, 210, 255
|
||||
668, 190, 292, 197, 296
|
||||
669, 230, 234, 240, 351
|
||||
670, 204, 210, 214, 345
|
||||
671, 210, 255, 214, 345
|
||||
672, 275, 165, 373, 155
|
||||
673, 172, 174, 217, 220
|
||||
674, 200, 204, 341, 345
|
||||
675, 240, 244, 127, 365
|
||||
676, 220, 230, 227, 288
|
||||
677, 272, 275, 324, 155
|
||||
678, 272, 152, 162, 155
|
||||
679, 200, 255, 210, 345
|
||||
680, 190, 200, 194, 341
|
||||
681, 197, 207, 200, 296
|
||||
682, 190, 197, 200, 296
|
||||
683, 279, 165, 169, 159
|
||||
684, 200, 207, 210, 252
|
||||
685, 224, 234, 230, 337
|
||||
686, 187, 197, 190, 292
|
||||
687, 275, 165, 279, 373
|
||||
688, 265, 275, 269, 373
|
||||
689, 272, 324, 152, 155
|
||||
690, 262, 265, 310, 324
|
||||
691, 265, 272, 275, 324
|
||||
692, 184, 224, 220, 337
|
||||
693, 272, 162, 275, 155
|
||||
694, 262, 272, 265, 324
|
||||
695, 178, 174, 172, 220
|
||||
696, 136, 365, 139, 133
|
||||
697, 227, 230, 237, 302
|
||||
698, 178, 184, 181, 220
|
||||
699, 172, 174, 173, 217
|
||||
700, 194, 200, 204, 341
|
||||
701, 234, 244, 240, 351
|
||||
702, 200, 210, 204, 345
|
||||
703, 230, 237, 302, 316
|
||||
704, 128, 316, 127, 129
|
||||
705, 217, 220, 227, 288
|
||||
706, 127, 365, 136, 133
|
||||
707, 265, 269, 359, 373
|
||||
708, 279, 373, 165, 159
|
||||
709, 165, 159, 373, 155
|
||||
710, 269, 275, 279, 373
|
||||
711, 127, 129, 316, 133
|
||||
712, 181, 220, 184, 224
|
||||
713, 178, 181, 174, 220
|
||||
714, 292, 302, 306, 608
|
||||
715, 288, 302, 292, 608
|
||||
716, 230, 302, 288, 608
|
||||
717, 230, 316, 302, 608
|
||||
718, 230, 240, 316, 608
|
||||
719, 230, 351, 240, 608
|
||||
720, 230, 337, 351, 608
|
||||
721, 302, 316, 306, 608
|
||||
722, 240, 351, 365, 608
|
||||
723, 351, 355, 365, 608
|
||||
724, 341, 355, 351, 608
|
||||
725, 337, 341, 351, 608
|
||||
726, 355, 369, 365, 608
|
||||
727, 341, 355, 608, 609
|
||||
728, 292, 608, 306, 609
|
||||
729, 292, 306, 296, 609
|
||||
730, 190, 292, 296, 609
|
||||
731, 190, 200, 341, 609
|
||||
732, 190, 296, 200, 609
|
||||
733, 200, 296, 252, 609
|
||||
734, 200, 255, 345, 609
|
||||
735, 200, 345, 341, 609
|
||||
736, 341, 345, 355, 609
|
||||
737, 345, 359, 355, 609
|
||||
738, 265, 359, 345, 609
|
||||
739, 255, 265, 345, 609
|
||||
740, 255, 265, 259, 345
|
||||
741, 255, 262, 265, 609
|
||||
**
|
||||
**ELSET COUNT = 92
|
||||
**HWCOLOR COMP 1 0
|
||||
*ELEMENT, TYPE=C3D4, ELSET=LOWER
|
||||
742, 456, 460, 466, 598
|
||||
743, 444, 450, 456, 598
|
||||
744, 444, 525, 447, 594
|
||||
745, 536, 540, 588, 598
|
||||
746, 453, 456, 463, 543
|
||||
747, 533, 543, 536, 573
|
||||
748, 444, 456, 453, 573
|
||||
749, 466, 550, 546, 598
|
||||
750, 536, 543, 546, 573
|
||||
751, 491, 536, 495, 588
|
||||
752, 438, 447, 444, 525
|
||||
753, 444, 594, 450, 598
|
||||
754, 444, 521, 525, 594
|
||||
755, 438, 444, 440, 521
|
||||
756, 540, 546, 550, 598
|
||||
757, 453, 456, 543, 573
|
||||
758, 488, 491, 559, 563
|
||||
759, 505, 536, 540, 588
|
||||
760, 440, 444, 453, 573
|
||||
761, 491, 495, 584, 588
|
||||
762, 444, 447, 450, 594
|
||||
763, 485, 491, 495, 584
|
||||
764, 440, 569, 444, 573
|
||||
765, 495, 501, 505, 536
|
||||
766, 473, 479, 511, 559
|
||||
767, 438, 440, 439, 521
|
||||
768, 491, 533, 536, 563
|
||||
769, 444, 569, 521, 594
|
||||
770, 473, 479, 475, 511
|
||||
771, 491, 498, 501, 533
|
||||
772, 495, 536, 505, 588
|
||||
773, 438, 444, 521, 525
|
||||
774, 473, 511, 508, 559
|
||||
775, 440, 521, 444, 569
|
||||
776, 511, 515, 521, 584
|
||||
777, 491, 498, 533, 563
|
||||
778, 515, 525, 521, 584
|
||||
779, 460, 550, 466, 598
|
||||
780, 439, 521, 440, 569
|
||||
781, 456, 463, 543, 546
|
||||
782, 479, 482, 511, 515
|
||||
783, 533, 536, 563, 573
|
||||
784, 479, 515, 511, 584
|
||||
785, 450, 460, 456, 598
|
||||
786, 521, 569, 559, 594
|
||||
787, 559, 594, 569, 613
|
||||
788, 559, 584, 594, 613
|
||||
789, 521, 559, 584, 594
|
||||
790, 536, 546, 540, 598
|
||||
791, 511, 521, 559, 584
|
||||
792, 479, 559, 491, 584
|
||||
793, 491, 559, 563, 584
|
||||
794, 511, 521, 518, 559
|
||||
795, 491, 584, 563, 588
|
||||
796, 563, 588, 584, 613
|
||||
797, 559, 563, 584, 613
|
||||
798, 559, 569, 563, 613
|
||||
799, 563, 569, 573, 613
|
||||
800, 536, 563, 573, 588
|
||||
801, 563, 573, 588, 613
|
||||
802, 573, 598, 588, 613
|
||||
803, 491, 501, 495, 536
|
||||
804, 536, 573, 546, 598
|
||||
805, 536, 588, 573, 598
|
||||
806, 588, 598, 594, 613
|
||||
807, 584, 588, 594, 613
|
||||
808, 444, 569, 594, 598
|
||||
809, 521, 584, 525, 594
|
||||
810, 444, 573, 569, 598
|
||||
811, 569, 598, 573, 613
|
||||
812, 569, 594, 598, 613
|
||||
813, 444, 456, 573, 598
|
||||
814, 439, 518, 521, 569
|
||||
815, 456, 546, 543, 573
|
||||
816, 479, 485, 482, 515
|
||||
817, 508, 511, 518, 559
|
||||
818, 456, 546, 573, 598
|
||||
819, 488, 498, 491, 563
|
||||
820, 479, 485, 515, 584
|
||||
821, 491, 563, 536, 588
|
||||
822, 473, 488, 479, 559
|
||||
823, 479, 491, 485, 584
|
||||
824, 491, 533, 501, 536
|
||||
825, 479, 511, 559, 584
|
||||
826, 479, 488, 491, 559
|
||||
827, 475, 479, 482, 511
|
||||
828, 518, 559, 521, 569
|
||||
829, 473, 475, 508, 511
|
||||
830, 473, 475, 474, 508
|
||||
831, 460, 470, 466, 550
|
||||
832, 456, 466, 463, 546
|
||||
833, 456, 466, 546, 598
|
||||
**
|
||||
**ELSET COUNT = 18
|
||||
*SURFACE,TYPE=ELEMENT,NAME=LOWER_TO_UPPER
|
||||
799,S1
|
||||
798,S1
|
||||
764,S2
|
||||
814,S2
|
||||
747,S2
|
||||
828,S2
|
||||
819,S2
|
||||
822,S2
|
||||
777,S3
|
||||
746,S4
|
||||
757,S4
|
||||
760,S4
|
||||
780,S4
|
||||
783,S4
|
||||
817,S4
|
||||
758,S4
|
||||
774,S4
|
||||
830,S4
|
||||
**
|
||||
**ELSET COUNT = 18
|
||||
*SURFACE,TYPE=ELEMENT,NAME=LOWER_BOTTOM
|
||||
806,S1
|
||||
807,S1
|
||||
831,S2
|
||||
779,S2
|
||||
785,S2
|
||||
778,S2
|
||||
753,S3
|
||||
762,S3
|
||||
744,S3
|
||||
745,S3
|
||||
809,S3
|
||||
761,S3
|
||||
820,S3
|
||||
816,S3
|
||||
756,S4
|
||||
759,S4
|
||||
772,S4
|
||||
763,S4
|
||||
**
|
||||
**ELSET COUNT = 12
|
||||
*SURFACE,TYPE=ELEMENT,NAME=LOWER_SYM13
|
||||
831,S1
|
||||
742,S1
|
||||
832,S1
|
||||
746,S1
|
||||
785,S1
|
||||
743,S1
|
||||
748,S1
|
||||
760,S1
|
||||
762,S1
|
||||
752,S1
|
||||
755,S1
|
||||
767,S1
|
||||
**
|
||||
**ELSET COUNT = 12
|
||||
*SURFACE,TYPE=ELEMENT,NAME=LOWER_SYM23
|
||||
749,S1
|
||||
756,S1
|
||||
790,S1
|
||||
750,S1
|
||||
747,S1
|
||||
759,S1
|
||||
831,S3
|
||||
832,S3
|
||||
781,S3
|
||||
765,S3
|
||||
824,S3
|
||||
771,S3
|
||||
**
|
||||
**ELSET COUNT = 32
|
||||
*SURFACE,TYPE=ELEMENT,NAME=UPPER_TOP
|
||||
678,S1
|
||||
689,S1
|
||||
642,S1
|
||||
641,S1
|
||||
615,S1
|
||||
616,S1
|
||||
622,S1
|
||||
623,S1
|
||||
603,S1
|
||||
721,S1
|
||||
571,S1
|
||||
572,S1
|
||||
574,S1
|
||||
729,S1
|
||||
714,S1
|
||||
715,S1
|
||||
580,S1
|
||||
581,S1
|
||||
704,S2
|
||||
694,S2
|
||||
661,S2
|
||||
681,S2
|
||||
686,S2
|
||||
703,S3
|
||||
662,S3
|
||||
668,S3
|
||||
656,S4
|
||||
690,S4
|
||||
697,S4
|
||||
705,S4
|
||||
666,S4
|
||||
699,S4
|
||||
**
|
||||
**ELSET COUNT = 32
|
||||
*SURFACE,TYPE=ELEMENT,NAME=UPPER_TO_LOWER
|
||||
647,S1
|
||||
648,S1
|
||||
612,S1
|
||||
611,S1
|
||||
696,S1
|
||||
649,S1
|
||||
650,S1
|
||||
726,S1
|
||||
723,S1
|
||||
737,S1
|
||||
736,S1
|
||||
724,S1
|
||||
725,S1
|
||||
595,S1
|
||||
594,S1
|
||||
708,S2
|
||||
657,S2
|
||||
701,S2
|
||||
578,S2
|
||||
685,S2
|
||||
692,S2
|
||||
707,S3
|
||||
659,S3
|
||||
664,S3
|
||||
674,S3
|
||||
683,S4
|
||||
710,S4
|
||||
576,S4
|
||||
638,S4
|
||||
670,S4
|
||||
700,S4
|
||||
712,S4
|
||||
**
|
||||
**ELSET COUNT = 16
|
||||
*SURFACE,TYPE=ELEMENT,NAME=UPPER_SYM13
|
||||
653,S1
|
||||
652,S1
|
||||
654,S1
|
||||
655,S1
|
||||
621,S1
|
||||
620,S1
|
||||
619,S1
|
||||
618,S1
|
||||
709,S2
|
||||
711,S2
|
||||
683,S3
|
||||
665,S3
|
||||
678,S3
|
||||
696,S4
|
||||
706,S4
|
||||
704,S4
|
||||
**
|
||||
**ELSET COUNT = 16
|
||||
*SURFACE,TYPE=ELEMENT,NAME=UPPER_SYM23
|
||||
683,S1
|
||||
687,S1
|
||||
665,S1
|
||||
693,S1
|
||||
710,S1
|
||||
688,S1
|
||||
691,S1
|
||||
694,S1
|
||||
576,S1
|
||||
740,S1
|
||||
741,S1
|
||||
570,S1
|
||||
638,S1
|
||||
671,S1
|
||||
667,S3
|
||||
684,S3
|
||||
**
|
||||
**Property Definitions
|
||||
**
|
||||
*SOLID SECTION, ELSET=UPPER, MATERIAL=Def_Material
|
||||
*SOLID SECTION, ELSET=LOWER, MATERIAL=Def_Material
|
||||
**
|
||||
**Material Definitions
|
||||
**
|
||||
**Material:Def_Material
|
||||
*MATERIAL,NAME=Def_Material
|
||||
*ELASTIC,TYPE=ISO
|
||||
2.08000e+005,3.00000e-001
|
||||
*DENSITY
|
||||
7.80000e-009,
|
||||
*SPECIFIC HEAT
|
||||
5.00000e-001
|
||||
*CONDUCTIVITY
|
||||
4.98100e-002
|
||||
**
|
||||
@@ -0,0 +1,196 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
using JuliaFEM
|
||||
using JuliaFEM.Preprocess
|
||||
using JuliaFEM.Postprocess
|
||||
using JuliaFEM.Testing
|
||||
using JuliaFEM.Abaqus: create_surface_elements
|
||||
|
||||
@testset "forget to add elements to problem" begin
|
||||
X = Dict(
|
||||
1 => [0.0, 0.0, 0.0],
|
||||
2 => [1.0, 0.0, 0.0],
|
||||
3 => [0.0, 1.0, 0.0],
|
||||
4 => [-0.25, 0.50, 0.00],
|
||||
5 => [0.50, -0.25, 0.00],
|
||||
6 => [0.75, 0.75, 0.00])
|
||||
s = Element(Tri3, [1, 2, 3])
|
||||
m = Element(Tri3, [4, 5, 6])
|
||||
update!([s, m], "geometry", X)
|
||||
update!(s, "master elements", [m])
|
||||
p = Problem(Mortar, "two elements", 1, "temperature")
|
||||
initialize!(p)
|
||||
assemble!(p)
|
||||
@test true
|
||||
end
|
||||
|
||||
""" Calculate mortar projection matrix P = D^-1*M from mortar assembly. """
|
||||
function calculate_mortar_projection_matrix(problem::Problem{Mortar}, ndim::Int)
|
||||
|
||||
C1 = sparse(problem.assembly.C1, ndim, ndim)
|
||||
C2 = sparse(problem.assembly.C2, ndim, ndim)
|
||||
|
||||
@assert nnz(sparse(problem.assembly.K)) == 0
|
||||
@assert nnz(sparse(problem.assembly.D)) == 0
|
||||
@assert nnz(sparse(problem.assembly.Kg)) == 0
|
||||
@assert nnz(sparse(problem.assembly.fg)) == 0
|
||||
@assert nnz(sparse(problem.assembly.f)) == 0
|
||||
@assert nnz(sparse(problem.assembly.g)) == 0
|
||||
|
||||
@assert C1 == C2
|
||||
#@assert problem.properties.dual_basis == true
|
||||
@assert problem.properties.adjust == false
|
||||
|
||||
S = get_nonzero_rows(C2)
|
||||
M = setdiff(get_nonzero_columns(C2), S)
|
||||
|
||||
# Construct matrix P = D^-1*M
|
||||
D_ = C2[S,S]
|
||||
M_ = -C2[S,M]
|
||||
|
||||
#=
|
||||
P = nothing
|
||||
if !isdiag(D_)
|
||||
warn("D is not diagonal, is dual basis used? This might take a long time.")
|
||||
P = ldltfact(1/2*(D_ + D_')) \ M_
|
||||
else
|
||||
P = D_ \ M_
|
||||
end
|
||||
=#
|
||||
|
||||
P = lufact(D_) \ full(M_)
|
||||
|
||||
return S, M, P
|
||||
end
|
||||
|
||||
@testset "two linear element clipping, calculation of projection matrix P for standard and dual basis" begin
|
||||
X = Dict(
|
||||
1 => [0.0, 0.0, 0.0],
|
||||
2 => [1.0, 0.0, 0.0],
|
||||
3 => [0.0, 1.0, 0.0],
|
||||
4 => [-0.25, 0.50, 0.00],
|
||||
5 => [0.50, -0.25, 0.00],
|
||||
6 => [0.75, 0.75, 0.00])
|
||||
s = Element(Tri3, [1, 2, 3])
|
||||
m = Element(Tri3, [4, 5, 6])
|
||||
update!([s, m], "geometry", X)
|
||||
update!(s, "master elements", [m])
|
||||
p = Problem(Mortar, "two elements", 1, "temperature")
|
||||
p.properties.dual_basis = false
|
||||
p.elements = [s; m]
|
||||
initialize!(p)
|
||||
assemble!(p)
|
||||
C1 = sparse(p.assembly.C1)
|
||||
C2 = sparse(p.assembly.C2)
|
||||
D = sparse(p.assembly.D)
|
||||
@test length(D) == 0
|
||||
@test C1 == C2
|
||||
S, M, P = calculate_mortar_projection_matrix(p, 6)
|
||||
@test S == [1, 2, 3]
|
||||
@test M == [4, 5, 6]
|
||||
# visually inspected to be ok result
|
||||
P_expected = 1/15*[9 9 -3; -7 13 9; 13 -7 9]
|
||||
@test isapprox(P, P_expected)
|
||||
um = [7.5, 15.0, 22.5]
|
||||
@test isapprox(P*um, [9.0, 23.0, 13.0])
|
||||
|
||||
empty!(p.assembly)
|
||||
p.properties.dual_basis = true
|
||||
assemble!(p)
|
||||
C1 = sparse(p.assembly.C1)
|
||||
C2 = sparse(p.assembly.C2)
|
||||
D = sparse(p.assembly.D)
|
||||
@test length(D) == 0
|
||||
@test C1 == C2
|
||||
S, M, P = calculate_mortar_projection_matrix(p, 6)
|
||||
@test S == [1, 2, 3]
|
||||
@test M == [4, 5, 6]
|
||||
@test isapprox(P, P_expected)
|
||||
um = [7.5, 15.0, 22.5]
|
||||
@test isapprox(P*um, [9.0, 23.0, 13.0])
|
||||
end
|
||||
|
||||
|
||||
@testset "two quadratic element clipping, calculation of projection matrix P for standard basis" begin
|
||||
X = Dict(
|
||||
1 => [0.0, 0.0, 0.0],
|
||||
2 => [1.0, 0.0, 0.0],
|
||||
3 => [0.0, 1.0, 0.0],
|
||||
7 => [-0.25, 0.50, 0.00],
|
||||
8 => [0.50, -0.25, 0.00],
|
||||
9 => [0.75, 0.75, 0.00])
|
||||
# middle nodes
|
||||
X[4] = 1/2*(X[1] + X[2])
|
||||
X[5] = 1/2*(X[2] + X[3])
|
||||
X[6] = 1/2*(X[3] + X[1])
|
||||
X[10] = 1/2*(X[7] + X[8])
|
||||
X[11] = 1/2*(X[8] + X[9])
|
||||
X[12] = 1/2*(X[9] + X[7])
|
||||
s = Element(Tri6, [1, 2, 3, 4, 5, 6])
|
||||
m = Element(Tri6, [7, 8, 9, 10, 11, 12])
|
||||
update!([s, m], "geometry", X)
|
||||
update!(s, "master elements", [m])
|
||||
p = Problem(Mortar, "two elements", 1, "temperature")
|
||||
p.properties.dual_basis = false
|
||||
p.properties.alpha = 0.2
|
||||
p.elements = [s; m]
|
||||
initialize!(p)
|
||||
assemble!(p)
|
||||
C1 = sparse(p.assembly.C1)
|
||||
C2 = sparse(p.assembly.C2)
|
||||
D = sparse(p.assembly.D)
|
||||
@test length(D) == 0
|
||||
@test C1 == C2
|
||||
S, M, P = calculate_mortar_projection_matrix(p, 12)
|
||||
@test S == [1, 2, 3, 4, 5, 6]
|
||||
@test M == [7, 8, 9, 10, 11, 12]
|
||||
println(full(P))
|
||||
# visually inspected to be ok result
|
||||
P_expected = 1/675*[81 81 189 972 -324 -324; 609 429 81 -1092 1404 -756; 429 609 81 -1092 -756 1404; -39 231 -81 132 396 36; -81 -81 81 108 324 324; 231 -39 -81 132 36 396]
|
||||
@test isapprox(P, P_expected)
|
||||
um = 15/2*[1, 2, 3]
|
||||
um = [um[1], um[2], um[3], 0.5*(um[1]+um[2]), 0.5*(um[2]+um[3]), 0.5*(um[3]+um[1])]
|
||||
us = P*um
|
||||
@test isapprox(us, [9.0, 23.0, 13.0, 16.0, 18.0, 11.0])
|
||||
end
|
||||
|
||||
@testset "two quadratic element clipping, calculation of projection matrix P for dual lagrange basis" begin
|
||||
X = Dict(
|
||||
1 => [0.0, 0.0, 0.0],
|
||||
2 => [1.0, 0.0, 0.0],
|
||||
3 => [0.0, 1.0, 0.0],
|
||||
7 => [-0.25, 0.50, 0.00],
|
||||
8 => [0.50, -0.25, 0.00],
|
||||
9 => [0.75, 0.75, 0.00])
|
||||
# middle nodes
|
||||
X[4] = 1/2*(X[1] + X[2])
|
||||
X[5] = 1/2*(X[2] + X[3])
|
||||
X[6] = 1/2*(X[3] + X[1])
|
||||
X[10] = 1/2*(X[7] + X[8])
|
||||
X[11] = 1/2*(X[8] + X[9])
|
||||
X[12] = 1/2*(X[9] + X[7])
|
||||
s = Element(Tri6, [1, 2, 3, 4, 5, 6])
|
||||
m = Element(Tri6, [7, 8, 9, 10, 11, 12])
|
||||
update!([s, m], "geometry", X)
|
||||
update!(s, "master elements", [m])
|
||||
p = Problem(Mortar, "two elements", 1, "temperature")
|
||||
p.properties.dual_basis = true
|
||||
p.properties.alpha = 0.2
|
||||
p.elements = [s; m]
|
||||
initialize!(p)
|
||||
assemble!(p)
|
||||
C1 = sparse(p.assembly.C1)
|
||||
C2 = sparse(p.assembly.C2)
|
||||
D = sparse(p.assembly.D)
|
||||
@test length(D) == 0
|
||||
@test C1 == C2
|
||||
S, M, P = calculate_mortar_projection_matrix(p, 12)
|
||||
P_expected = 1/675*[81 81 189 972 -324 -324; 609 429 81 -1092 1404 -756; 429 609 81 -1092 -756 1404; -39 231 -81 132 396 36; -81 -81 81 108 324 324; 231 -39 -81 132 36 396]
|
||||
@test isapprox(P, P_expected)
|
||||
um = 15/2*[1, 2, 3]
|
||||
um = [um[1], um[2], um[3], 0.5*(um[1]+um[2]), 0.5*(um[2]+um[3]), 0.5*(um[3]+um[1])]
|
||||
us = P*um
|
||||
@test isapprox(us, [9.0, 23.0, 13.0, 16.0, 18.0, 11.0])
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user