Files
JuliaFEM.jl/notebooks/2015-06-25-elasticity-solver-example.ipynb
T
2015-11-28 14:06:12 +02:00

542 lines
14 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Solving elasticity problems using JuliaFEM\n",
"\n",
"Author(s): Jukka Aho\n",
"\n",
"**Abstract**: Solving elasticity equations using JuliaFEM.\n",
"\n",
"### Weak form\n",
"\n",
"Given function spaces\n",
"\\begin{align}\n",
"\\boldsymbol{\\mathcal{U}} & =\\left\\{ \\boldsymbol{u}\\in H^{1}\\left(\\Omega\\right)|\\boldsymbol{u}\\left(\\boldsymbol{X},t\\right)=\\hat{\\boldsymbol{u}}\\left(\\boldsymbol{X},t\\right)\\text{ on }\\Gamma_{\\mathrm{u}}\\right\\} ,\\\\\n",
"\\boldsymbol{\\mathcal{V}} & =\\left\\{ \\delta\\boldsymbol{u}\\in H^{1}\\left(\\Omega\\right)|\\delta\\boldsymbol{u}\\left(\\boldsymbol{X}\\right)=0\\text{ on }\\Gamma_{\\mathrm{u}}\\right\\} ,\n",
"\\end{align}\n",
"find $\\boldsymbol{u}\\in\\boldsymbol{\\mathcal{U}}$ such that\n",
"\\begin{equation}\n",
"\\delta\\mathcal{W}:=\\int_{\\Omega_{0}}\\rho_{0}\\ddot{\\boldsymbol{u}}\\cdot\\delta\\boldsymbol{u}\\,\\mathrm{d}V_{0}+\\int_{\\Omega_{0}}\\boldsymbol{S}:\\delta\\boldsymbol{E}\\,\\mathrm{d}V_{0}-\\int_{\\Omega_{0}}\\hat{\\boldsymbol{b}}_{0}\\cdot\\delta\\boldsymbol{u}\\,\\mathrm{d}V_{0}-\\int_{\\Gamma_{\\sigma}}\\hat{\\boldsymbol{t}}_{0}\\cdot\\delta\\boldsymbol{u}\\,\\mathrm{d}A_{0} =0 \\qquad\\forall\\delta\\boldsymbol{u}\\in\\boldsymbol{\\mathcal{V}}\n",
"\\end{equation}\n",
"\n",
"### Some formulas\n",
"\\begin{align}\n",
"J & =\\det\\left(F\\right)\\\\\n",
"I_{c} & =\\mbox{tr}\\left(C\\right)\\\\\n",
"\\mathbf{C} & =\\mathbf{F}^{\\mathrm{T}}\\mathbf{F}\\\\\n",
"\\mathbf{F} & =\\mathbf{I}+\\nabla\\mathbf{u}\\\\\n",
"\\mathbf{E} & =\\frac{1}{2}\\left(\\mathbf{F}^{\\mathrm{T}}\\mathbf{F}-\\mathbf{I}\\right)\n",
"\\end{align}\n",
"\n",
"### Potential energy\n",
"\n",
"\\begin{equation}\n",
"\\underset{u\\in\\boldsymbol{\\mathcal{U}}}{\\min}\\Pi\\left(\\mathbf{u}\\right)\n",
"\\end{equation}\n",
"\\begin{equation}\n",
"\\Pi\\left(\\mathbf{u}\\right)=\\int_{\\Omega}\\psi\\left(\\mathbf{u}\\right)-\\int_{\\Omega}\\hat{\\mathbf{b}}_{0}\\cdot\\mathbf{u}-\\int_{\\Gamma_{\\sigma}}\\hat{\\mathbf{t}}_{0}\\cdot\\mathbf{u}\\,\\mathrm{d}A_{0}\n",
"\\end{equation}\n",
"\n",
"### Material models\n",
"\n",
"https://en.wikipedia.org/wiki/Strain_energy_density_function\n",
"\n",
"Saint-Venant-Kirchhoff model https://en.wikipedia.org/wiki/Hyperelastic_material\n",
"\\begin{equation}\n",
"\\psi\\left(\\mathbf{E}\\right)=\\frac{\\lambda}{2}\\left[\\mbox{tr}\\left(\\mathbf{E}\\right)\\right]^{2}+\\mu\\mbox{tr}\\left(\\mathbf{E}^2\\right)\n",
"\\end{equation}\n",
"\n",
"neo-Hookean material https://en.wikipedia.org/wiki/Neo-Hookean_solid\n",
"\\begin{equation}\n",
"\\psi=\\frac{\\mu}{2}\\left(I_{c}-3\\right)-\\mu\\ln\\left(J\\right)+\\frac{\\lambda}{2}\\ln\\left(J\\right)^{2}\n",
"\\end{equation}"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"using JuliaFEM"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: Registered handlers: Any[\"ELEMENT\",\"NODE\",\"NSET\",\"ELSET\"]\n",
"INFO: Parsing elements\n",
"INFO: 31437 elements found\n",
"INFO: Creating ELSET PISTON\n"
]
},
{
"data": {
"text/plain": [
"Dict{Any,Any} with 3 entries:\n",
" \"nodes\" => Dict{Any,Any}(2843=>[-27.41338,-2.18093,-16.93988],4495=>[-14.0…\n",
" \"elements\" => Dict{Any,Any}(43367=>[4492,4602,4494,6450],35510=>[2796,2798,80…\n",
" \"elsets\" => Dict{Any,Any}(\"BC3\"=>[3975,3976,3977,3978,3979,3980,3981,3982,3…"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: Parsing elements\n",
"INFO: 5894 elements found\n",
"INFO: Creating element set BC1\n",
"INFO: Creating element set BC2\n",
"INFO: Creating element set BC3\n"
]
}
],
"source": [
"model = open(JuliaFEM.parse_abaqus, \"../geometry/piston/piston_8789_P1.inp\")\n",
"model"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"perm = Dict{Int64, Int64}()\n",
"for (i, nid) in enumerate(keys(model[\"nodes\"]))\n",
" perm[nid] = i\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: 37331 elements created.\n"
]
}
],
"source": [
"using JuliaFEM: Element, Tri3, Tet4\n",
"elements = Dict{Int64, Element}()\n",
"for (elid, node_ids) in model[\"elements\"]\n",
" connectivity = Int64[perm[nid] for nid in node_ids]\n",
" coords = Vector{Float64}[model[\"nodes\"][nid] for nid in node_ids]\n",
" if length(coords) == 3\n",
" element = Tri3(connectivity)\n",
" element[\"geometry\"] = coords\n",
" elements[elid] = element\n",
" elseif length(coords) == 4\n",
" element = Tet4(connectivity)\n",
" element[\"geometry\"] = coords\n",
" elements[elid] = element\n",
" else\n",
" warn(\"unknown element dim = $(length(connectivity))\")\n",
" end\n",
"end\n",
"info(\"$(length(elements)) elements created.\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"37331"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"31437+5894"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"using JuliaFEM: ElasticityProblem, DirichletProblem\n",
"\n",
"piston = ElasticityProblem()\n",
"for elid in model[\"elsets\"][\"PISTON\"]\n",
" elements[elid][\"youngs modulus\"] = 210.0e3\n",
" elements[elid][\"poissons ratio\"] = 0.3\n",
" push!(piston, elements[elid])\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"load = Vector{Float64}[[0.0, 0.0, -10.0], [0.0, 0.0, -10.0], [0.0, 0.0, -10.0]]\n",
"for elid in model[\"elsets\"][\"BC1\"]\n",
" elements[elid][\"displacement traction force\"] = load\n",
" push!(piston, elements[elid])\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"encastre = DirichletProblem(\"displacement\", 3)\n",
"for elid in model[\"elsets\"][\"BC2\"]\n",
" elements[elid][\"displacement\"] = 0.0\n",
" push!(encastre, elements[elid])\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"using JuliaFEM: DirectSolver\n",
"solver = DirectSolver()\n",
"push!(solver, piston)\n",
"push!(solver, encastre);"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: # of field problems: 1\n",
"INFO: # of boundary problems: 1\n",
"INFO: Starting iteration 1\n",
"INFO: # of dofs: 26367, # of interface dofs: 1350\n",
"INFO: solved. length of solution vector = 52734\n",
"INFO: timing info for non-linear iteration:\n",
"INFO: boundary assembly : 1.4367611408233643\n",
"INFO: field assembly : 17.380300998687744\n",
"INFO: create sparse matrices : 0.38140082359313965\n",
"INFO: solution of system : 3.159921169281006\n",
"INFO: update element data : 3.3958511352539062\n",
"INFO: non-linear iteration : 25.75425100326538\n",
"INFO: Starting iteration 2\n",
"INFO: # of dofs: 26367, # of interface dofs: 1350\n",
"INFO: solved. length of solution vector = 52734\n",
"INFO: timing info for non-linear iteration:\n",
"INFO: boundary assembly : 0.1028587818145752\n",
"INFO: field assembly : 15.321197032928467\n",
"INFO: create sparse matrices : 0.11679887771606445\n",
"INFO: solution of system : 2.1216089725494385\n",
"INFO: update element data : 3.484022855758667\n",
"INFO: non-linear iteration : 21.146512031555176\n",
"INFO: Starting iteration 3\n",
"INFO: # of dofs: 26367, # of interface dofs: 1350\n",
"INFO: solved. length of solution vector = 52734\n",
"INFO: timing info for non-linear iteration:\n",
"INFO: boundary assembly : 0.09190106391906738\n",
"INFO: field assembly : 14.772294044494629\n",
"INFO: create sparse matrices : 0.12086606025695801\n",
"INFO: solution of system : 2.260561943054199\n",
"INFO: update element data : 3.4714930057525635\n",
"INFO: non-linear iteration : 20.717132806777954\n",
"INFO: Starting iteration 4\n",
"INFO: # of dofs: 26367, # of interface dofs: 1350\n",
"INFO: solved. length of solution vector = 52734\n",
"INFO: timing info for non-linear iteration:\n",
"INFO: boundary assembly : 0.09454894065856934\n",
"INFO: field assembly : 15.800831079483032\n",
"INFO: create sparse matrices : 0.10474300384521484\n",
"INFO: solution of system : 2.3751449584960938\n",
"INFO: update element data : 3.471247911453247\n",
"INFO: non-linear iteration : 21.846541166305542\n",
"INFO: solver finished in 90.86189484596252 seconds.\n"
]
},
{
"data": {
"text/plain": [
"(4,true)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"solver(0.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Saving results to file"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"<Grid Name=\"Grid\">\n",
" <Time Value=\"0\"/>\n",
"</Grid>\n"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xdoc, xmodel = JuliaFEM.xdmf_new_model()\n",
"temporal_collection = JuliaFEM.xdmf_new_temporal_collection(xmodel)\n",
"grid = JuliaFEM.xdmf_new_grid(temporal_collection; time=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Save geometry to xdmf file"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: number of nodes in model: 8789\n",
"INFO: Number of elements in model: 31437\n"
]
}
],
"source": [
"nnodes = length(model[\"nodes\"])\n",
"info(\"number of nodes in model: $nnodes\")\n",
"\n",
"X = zeros(3, nnodes)\n",
"for nid in keys(model[\"nodes\"])\n",
" X[:, perm[nid]] = model[\"nodes\"][nid]\n",
"end\n",
"\n",
"nelements = length(model[\"elsets\"][\"PISTON\"])\n",
"info(\"Number of elements in model: $nelements\")\n",
"elmap = zeros(Int64, 5, nelements)\n",
"#elmap[1,:] = 0x0026\n",
"elmap[1,:] = 0x6\n",
"for (i, elid) in enumerate(model[\"elsets\"][\"PISTON\"])\n",
" elmap[2:end,i] = Int64[perm[nid] for nid in model[\"elements\"][elid]]\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"JuliaFEM.xdmf_new_mesh(grid, X, elmap)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"988949"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"JuliaFEM.xdmf_save_model(xdoc, \"/tmp/piston.xmf\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Save nodal data to model"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(3,8789)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using JuliaFEM: get_connectivity\n",
"\n",
"u = zeros(3, nnodes)\n",
"\n",
"for element in values(elements)\n",
" isa(element, Element{Tet4}) || continue\n",
" connectivity = get_connectivity(element)\n",
" field = element[\"displacement\"](0.0)\n",
" for (i, nid) in enumerate(connectivity)\n",
" u[:, nid] = field[i]\n",
" end\n",
"end\n",
"size(u)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"JuliaFEM.xdmf_new_field(grid, \"Displacement\", \"nodes\", u)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"1573751"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"JuliaFEM.xdmf_save_model(xdoc, \"/tmp/piston.xmf\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 0.4.1",
"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
}