mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-29 04:56:15 +00:00
2d tie contact working.
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 2d tie contact\n",
|
||||
"\n",
|
||||
"Author: Jukka Aho\n",
|
||||
"\n",
|
||||
"Abstract: 2d tie contact.\n",
|
||||
"\n",
|
||||
"Model:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Each element is modelled as own \"body\" and they are connected using tie contacts. Segments 5-6 and 9-10 and 6-7 are slave surfaces, so node 6 or 9 is on at least two tie contacts as slave node. Moreover this model has dirichlet boundary $y=0$ at bottom of body 1 and $x=0$ on left. To get the accurate solution one needs to minimize \n",
|
||||
"\\begin{equation}\n",
|
||||
"\\frac{15}{2}u_{1}^{4} + 60 u_{1}^{3} + \\frac{15}{4}u_{1}^{2} u_{2}^{2} + 15 u_{1}^{2} u_{2} + 120 u_{1}^{2} + 15 u_{1} u_{2}^{2} + 60 u_{1} u_{2} + \\frac{15}{2}u_{2}^{4} + 60 u_{2}^{3} + 120 u_{2}^{2} + 50 u_{2}\n",
|
||||
",\n",
|
||||
"\\end{equation}\n",
|
||||
"which gives approximate $u_1 = 0.0634862$ and $u_2 = -0.277183$ for the displacement of upper right corner.\n",
|
||||
"[Wolfram](http://www.wolframalpha.com/input/?i=local+minimum+15*x^4%2F2+%2B+60*x^3+%2B+15*x^2*y^2%2F4+%2B+15*x^2*y+%2B+120*x^2+%2B+15*x*y^2+%2B+60*x*y+%2B+15*y^4%2F2+%2B+60*y^3+%2B+120*y^2+%2B+50*y)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using JuliaFEM\n",
|
||||
"using JuliaFEM: Element, Seg2, Quad4, PlaneStressElasticityProblem, DirichletProblem, MortarProblem, DirectSolver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nodes = Dict{Int64, Vector{Float64}}(\n",
|
||||
" 1 => [0.0, 0.0],\n",
|
||||
" 2 => [2.0, 0.0],\n",
|
||||
" 3 => [2.0, 1.0],\n",
|
||||
" 4 => [0.0, 1.0],\n",
|
||||
" 5 => [0.0, 1.0],\n",
|
||||
" 6 => [1.0, 1.0],\n",
|
||||
" 7 => [1.0, 2.0],\n",
|
||||
" 8 => [0.0, 2.0],\n",
|
||||
" 9 => [1.0, 1.0],\n",
|
||||
" 10 => [2.0, 1.0],\n",
|
||||
" 11 => [2.0, 2.0],\n",
|
||||
" 12 => [1.0, 2.0]);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connectivity = Dict{Int64, Vector{Int64}}(\n",
|
||||
" 1 => [1, 2, 3, 4],\n",
|
||||
" 2 => [5, 6, 7, 8],\n",
|
||||
" 3 => [9, 10, 11, 12]);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"elements = Element[]\n",
|
||||
"for c in values(connectivity)\n",
|
||||
" element = Quad4(c)\n",
|
||||
" element[\"geometry\"] = Vector{Float64}[nodes[i] for i in c]\n",
|
||||
" element[\"youngs modulus\"] = 900.0\n",
|
||||
" element[\"poissons ratio\"] = 0.25\n",
|
||||
" push!(elements, element)\n",
|
||||
"end\n",
|
||||
"length(elements)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Create three bodies, each containing one element."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"body1 = PlaneStressElasticityProblem()\n",
|
||||
"body2 = PlaneStressElasticityProblem()\n",
|
||||
"body3 = PlaneStressElasticityProblem()\n",
|
||||
"push!(body1, elements[1])\n",
|
||||
"push!(body2, elements[2])\n",
|
||||
"push!(body3, elements[3]);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Surface traction to the top of bodies 2 and 3:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"t2 = Seg2([8, 7])\n",
|
||||
"t2[\"geometry\"] = Vector{Float64}[nodes[8], nodes[7]]\n",
|
||||
"t2[\"displacement traction force\"] = Vector{Float64}[[0.0, -100.0], [0.0, -100.0]]\n",
|
||||
"t3 = Seg2([12, 11])\n",
|
||||
"t3[\"geometry\"] = Vector{Float64}[nodes[12], nodes[11]]\n",
|
||||
"t3[\"displacement traction force\"] = Vector{Float64}[[0.0, -100.0], [0.0, -100.0]]\n",
|
||||
"push!(body2, t2)\n",
|
||||
"push!(body3, t3);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Boundary conditions: $x=0$ for left boundary."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dx1 = Seg2([1, 4])\n",
|
||||
"dx1[\"geometry\"] = Vector[nodes[1], nodes[4]]\n",
|
||||
"dx1[\"displacement 1\"] = 0.0\n",
|
||||
"dx2 = Seg2([5, 8])\n",
|
||||
"dx2[\"geometry\"] = Vector[nodes[5], nodes[8]]\n",
|
||||
"dx2[\"displacement 1\"] = 0.0\n",
|
||||
"bc1 = DirichletProblem(\"displacement\", 2)\n",
|
||||
"push!(bc1, dx1)\n",
|
||||
"push!(bc1, dx2);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"$y=0$ for bottom of model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dy1 = Seg2([1, 2])\n",
|
||||
"dy1[\"geometry\"] = Vector[nodes[1], nodes[2]]\n",
|
||||
"dy1[\"displacement 2\"] = 0.0\n",
|
||||
"bc2 = DirichletProblem(\"displacement\", 2)\n",
|
||||
"push!(bc2, dy1);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Mortar boundary conditions: tie contact between body 1 and body 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"rotation_matrix(phi) = [cos(phi) -sin(phi); sin(phi) cos(phi)]\n",
|
||||
"\n",
|
||||
"master1 = Seg2([4, 3])\n",
|
||||
"master1[\"geometry\"] = Vector[nodes[4], nodes[3]]\n",
|
||||
"slave1 = Seg2([5, 6])\n",
|
||||
"slave1[\"geometry\"] = Vector[nodes[5], nodes[6]]\n",
|
||||
"slave1[\"master elements\"] = Element[master1]\n",
|
||||
"slave1[\"nodal ntsys\"] = Matrix[rotation_matrix(-pi/2), rotation_matrix(-pi/2)]\n",
|
||||
"contact1 = MortarProblem(\"displacement\", 2)\n",
|
||||
"push!(contact1, slave1);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Tie contact between body 1 and body 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"slave2 = Seg2([9, 10])\n",
|
||||
"slave2[\"geometry\"] = Vector[nodes[9], nodes[10]]\n",
|
||||
"slave2[\"nodal ntsys\"] = Matrix[rotation_matrix(-pi/2), rotation_matrix(-pi/2)]\n",
|
||||
"slave2[\"master elements\"] = Element[master1]\n",
|
||||
"contact2 = MortarProblem(\"displacement\", 2)\n",
|
||||
"push!(contact2, slave2);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Tie contact between body 2 and body 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"master2 = Seg2([6, 7])\n",
|
||||
"master2[\"geometry\"] = Vector[nodes[6], nodes[7]]\n",
|
||||
"slave3 = Seg2([9, 12])\n",
|
||||
"slave3[\"geometry\"] = Vector[nodes[9], nodes[12]]\n",
|
||||
"slave3[\"nodal ntsys\"] = Matrix[rotation_matrix(0.0), rotation_matrix(0.0)]\n",
|
||||
"slave3[\"master elements\"] = Element[master2]\n",
|
||||
"contact3 = MortarProblem(\"displacement\", 2)\n",
|
||||
"push!(contact3, slave3);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"All defined. Solve it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"solver = DirectSolver()\n",
|
||||
"push!(solver, body1)\n",
|
||||
"push!(solver, body2)\n",
|
||||
"push!(solver, body3)\n",
|
||||
"push!(solver, bc1)\n",
|
||||
"push!(solver, bc2)\n",
|
||||
"push!(solver, contact1)\n",
|
||||
"push!(solver, contact2)\n",
|
||||
"push!(solver, contact3);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO: # of field problems: 3\n",
|
||||
"INFO: # of boundary problems: 5\n",
|
||||
"INFO: Starting iteration 1\n",
|
||||
"INFO: # of dofs: 24, # of interface dofs: 15\n",
|
||||
"INFO: solved. length of solution vector = 48\n",
|
||||
"INFO: Iteration took 9.311098465 seconds\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(5,true)"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO: Starting iteration 2\n",
|
||||
"INFO: # of dofs: 24, # of interface dofs: 15\n",
|
||||
"INFO: solved. length of solution vector = 48\n",
|
||||
"INFO: Iteration took 0.003787437 seconds\n",
|
||||
"INFO: Starting iteration 3\n",
|
||||
"INFO: # of dofs: 24, # of interface dofs: 15\n",
|
||||
"INFO: solved. length of solution vector = 48\n",
|
||||
"INFO: Iteration took 0.020931551 seconds\n",
|
||||
"INFO: Starting iteration 4\n",
|
||||
"INFO: # of dofs: 24, # of interface dofs: 15\n",
|
||||
"INFO: solved. length of solution vector = 48\n",
|
||||
"INFO: Iteration took 0.003763852 seconds\n",
|
||||
"INFO: Starting iteration 5\n",
|
||||
"INFO: # of dofs: 24, # of interface dofs: 15\n",
|
||||
"INFO: solved. length of solution vector = 48\n",
|
||||
"INFO: Iteration took 0.003679408 seconds\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"iterations, converged = call(solver, 0.0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO: displacement at [2.0,2.0] = [0.06348623177789343,-0.27718303785565257]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using JuliaFEM.Test\n",
|
||||
"\n",
|
||||
"@test converged\n",
|
||||
"\n",
|
||||
"X = elements[2](\"geometry\", [1.0, 1.0], 0.0)\n",
|
||||
"u = elements[2](\"displacement\", [1.0, 1.0], 0.0)\n",
|
||||
"info(\"displacement at $X = $u\")\n",
|
||||
"@test isapprox(u, [0.0634862, -0.277183], atol=1.0e-5)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 0.4.0",
|
||||
"language": "julia",
|
||||
"name": "julia-0.4"
|
||||
},
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "0.4.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
Reference in New Issue
Block a user