Files
JuliaFEM.jl/notebooks/2015-06-25-elasticity-solver-example.ipynb
T

2000 lines
699 KiB
Plaintext
Raw Normal View History

2015-06-25 00:47:03 +03:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2015-07-28 22:27:41 +03:00
"# Solving elasticity problems using JuliaFEM\n",
2015-06-25 00:47:03 +03:00
"\n",
2015-07-28 22:27:41 +03:00
"Author(s): Jukka Aho\n",
"\n",
"**Abstract**: A workflow to solve typical elasticity problem. This document also tries to give some quidelines how to develop JuliaFEM."
]
},
2015-08-10 23:01:44 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bottom-up design\n",
"\n",
"We go piece by piece starting from something simple and going up to more complicated programming model."
]
},
2015-07-28 22:27:41 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Design principle 1*: we introduce new ideas using Notebooks."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Design principle 2*: we use ``Logging``. Forget ``println``."
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 23,
2015-07-28 22:27:41 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
2015-08-24 01:14:03 +03:00
{
"data": {
"text/plain": [
"Logger(root,DEBUG,Pipe(open, 0 bytes waiting),root)"
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 23,
2015-08-24 01:14:03 +03:00
"metadata": {},
"output_type": "execute_result"
2015-07-28 22:27:41 +03:00
}
],
"source": [
2015-08-27 08:18:20 +03:00
"using ForwardDiff\n",
"using JuliaFEM\n",
2015-08-27 08:18:20 +03:00
"using JuliaFEM: Assembly, Element, Equation, Point1, Quad4, IntegrationPoint\n",
"using JuliaFEM: get_field, set_field, get_element, linearize, integrate, interpolate, get_dbasisdX\n",
2015-07-28 22:27:41 +03:00
"using Logging\n",
"Logging.configure(level=DEBUG)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Design principle 3*: we write docstrings using [numpy style](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt).\n",
"\n",
"*Design principle 4*: we don't use greek characters in code which is implemented to JuliaFEM. In notebooks they are ok.\n",
"\n",
2015-08-24 01:14:03 +03:00
"*Design principle 5*: we use 4 space indentation like in Python."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we construct some type for our element which contains all relevant data. We don't care a much how every element is actually implemented as long as it follows some general rules how the interface is constructed. First we define our element family and it's basis functions, derivatives of them etc. These needs to be defined for each element type only once."
2015-06-25 00:47:03 +03:00
]
},
2015-08-24 01:14:03 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next we define our elements for mechanical problem. Because calculating internal and external energy for several types of elements follow same procedure, we construct whole family of mechanical elements which share common functions."
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 24,
2015-08-24 01:14:03 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"CPS4"
2015-08-24 01:14:03 +03:00
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 24,
2015-08-24 01:14:03 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"abstract Elasticity <: Equation\n",
"\n",
2015-08-24 01:14:03 +03:00
"\"\"\"\n",
"Plane stress formulation for 4-node bilinear element.\n",
2015-08-24 01:14:03 +03:00
"\"\"\"\n",
"type CPS4 <: Elasticity\n",
" element :: Quad4\n",
2015-08-22 20:55:24 +03:00
" integration_points :: Array{IntegrationPoint, 1}\n",
2015-08-24 01:14:03 +03:00
"end\n",
"function CPS4(el::Quad4)\n",
" integration_points = [\n",
" IntegrationPoint(1.0/sqrt(3.0)*[-1, -1], 1.0),\n",
" IntegrationPoint(1.0/sqrt(3.0)*[ 1, -1], 1.0),\n",
" IntegrationPoint(1.0/sqrt(3.0)*[ 1, 1], 1.0),\n",
" IntegrationPoint(1.0/sqrt(3.0)*[-1, 1], 1.0)]\n",
2015-08-27 08:18:20 +03:00
" set_field(el, \"displacement\", zeros(2, 4))\n",
" CPS4(el, integration_points)\n",
2015-08-22 20:55:24 +03:00
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2015-08-24 01:14:03 +03:00
"Here's the actual basic implementation for mechanical elements\n",
"\n",
"Our task is: for given $\\mathbf{u}$ calculate $\\mathbf{R}(\\mathbf{u}) = \\mathbf{T}(\\mathbf{u}) - \\mathbf{F}(\\mathbf{u})$ and it's partial derivative with respect to $\\mathbf{u}$, i.e. $\\partial \\mathbf{R}(\\mathbf{u}) / \\partial \\mathbf{u}$. Because of DRY, we apply this implementation for union of several elements because this works for all 2d and 3d continuum elements."
2015-08-22 20:55:24 +03:00
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 25,
2015-08-22 20:55:24 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"get_lhs (generic function with 2 methods)"
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 25,
2015-08-22 20:55:24 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"Calculate internal nodal forces for continuum element.\n",
"\"\"\"\n",
"function Wint(eq::CPS4)\n",
" el = eq.element\n",
2015-08-24 01:14:03 +03:00
" dNdX(xi) = get_dbasisdX(el, xi)\n",
2015-08-22 20:55:24 +03:00
" # material\n",
" lambda(xi) = interpolate(el, \"lambda\", xi)\n",
" mu(xi) = interpolate(el, \"mu\", xi)\n",
2015-08-19 18:50:43 +03:00
" # kinematics\n",
2015-08-22 20:55:24 +03:00
" Grad(xi, u) = u*dNdX(xi)\n",
" F(xi, u) = I + Grad(xi, u)\n",
" E(xi, u) = 1/2*(Grad(xi, u)' + Grad(xi, u) + Grad(xi, u)'*Grad(xi, u))\n",
2015-08-19 18:50:43 +03:00
" # constitutive equation\n",
2015-08-22 20:55:24 +03:00
" S(xi, u) = lambda(xi)*trace(E(xi, u))*I + 2*mu(xi)*E(xi, u)\n",
" P(xi, u) = F(xi, u)*S(xi, u)\n",
" T(xi, u) = P(xi, u)*dNdX(xi)'\n",
2015-08-27 08:18:20 +03:00
" integrate(eq, (eq, ip) -> T(ip.xi, get_field(get_element(eq), \"displacement\")))\n",
2015-08-22 20:55:24 +03:00
"end\n",
2015-08-19 18:50:43 +03:00
"\n",
"get_rhs(eq::CPS4) = -Wint(eq) # rhs = -R = -(T-F)\n",
2015-08-27 08:18:20 +03:00
"get_lhs(eq::CPS4) = linearize(eq, Wint, \"displacement\")(eq)"
2015-07-28 22:27:41 +03:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That was our geometrically nonlinear elasticity solver. Note how we used automatic differentiation to linearize residual vector.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2015-07-30 00:13:14 +03:00
"*Design principle 6*: we test our code. We use FactCheck for testing."
2015-07-28 22:27:41 +03:00
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 26,
2015-07-28 22:27:41 +03:00
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"using FactCheck"
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 27,
2015-08-22 20:55:24 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
2015-08-27 08:18:20 +03:00
{
"name": "stdout",
"output_type": "stream",
"text": [
"test rhs\n",
"1 fact verified.\n"
]
},
2015-08-22 20:55:24 +03:00
{
"data": {
"text/plain": [
2015-08-27 08:18:20 +03:00
"delayed_handler (generic function with 4 methods)"
2015-08-22 20:55:24 +03:00
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 27,
2015-08-22 20:55:24 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function get_test_equation()\n",
2015-08-22 20:55:24 +03:00
" # set up one linear quadrangle element\n",
" node_ids = [1, 2, 3, 4]\n",
" el = Quad4(node_ids)\n",
" eq = CPS4(el)\n",
2015-08-24 01:14:03 +03:00
"\n",
2015-08-22 20:55:24 +03:00
" E = 90.0\n",
" nu = 0.25\n",
" mu = E/(2*(1+nu))\n",
" la = E*nu/((1+nu)*(1-2*nu))\n",
" la = 2*la*mu/(la + 2*mu)\n",
2015-08-24 01:14:03 +03:00
" X = [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]'\n",
" #set_coordinates(el, X)\n",
" #set_material(el, la, mu)\n",
" set_field(el, \"coordinates\", X)\n",
" set_field(el, \"lambda\", la)\n",
" set_field(el, \"mu\", mu)\n",
" return eq\n",
"end\n",
2015-08-27 08:18:20 +03:00
"facts(\"test rhs\") do\n",
" eq = get_test_equation()\n",
" utest = zeros(2, 4)\n",
" utest[1, 3] = 0.5\n",
" set_field(get_element(eq), \"displacement\", utest)\n",
" rhs = get_rhs(eq)\n",
" #println(rhs)\n",
" @fact rhs[2, 4] --> roughly(-8.4)\n",
"end"
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 28,
2015-06-25 00:47:03 +03:00
"metadata": {
2015-08-11 22:48:35 +03:00
"collapsed": false,
"scrolled": false
2015-06-25 00:47:03 +03:00
},
2015-06-25 23:11:57 +03:00
"outputs": [
2015-07-02 22:21:41 +03:00
{
"name": "stdout",
"output_type": "stream",
"text": [
2015-07-28 22:27:41 +03:00
"test solve one element model\n"
2015-07-02 22:21:41 +03:00
]
},
2015-06-25 23:11:57 +03:00
{
"name": "stderr",
"output_type": "stream",
"text": [
2015-08-27 08:18:20 +03:00
"27-Aug 08:16:52:DEBUG:root:Iteration 1\n",
"27-Aug 08:16:53:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Iteration 2\n",
"27-Aug 08:16:55:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Iteration 3\n",
"27-Aug 08:16:55:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Iteration 4\n",
"27-Aug 08:16:55:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Iteration 5\n",
"27-Aug 08:16:55:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Iteration 6\n",
"27-Aug 08:16:55:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:55:DEBUG:root:Converged in 6 iterations.\n",
"27-Aug 08:16:56:DEBUG:root:solution vector: \n",
" [0.0 -0.3991450609547433 -0.07228582695592461 0.0\n",
2015-07-28 22:27:41 +03:00
" 0.0 -2.1779892317073504 -2.222244754401764 0.0]\n",
2015-08-27 08:18:20 +03:00
"27-Aug 08:16:56:DEBUG:root:norm of u: 3.1292483947150047\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 1\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 2\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 3\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 4\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 5\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Iteration 6\n",
"27-Aug 08:16:56:DEBUG:root:Solving Ax = b\n",
"27-Aug 08:16:56:DEBUG:root:Converged in 6 iterations.\n",
"27-Aug 08:16:56:DEBUG:root:solution vector: \n",
2015-08-24 01:14:03 +03:00
" [0.0 1.2578327758133292 1.5202505368695098 0.0\n",
2015-08-27 08:18:20 +03:00
" 0.0 -1.8223091343697626 -1.6224781337179326 0.0]\n",
"27-Aug 08:16:56:DEBUG:root:norm of u: 3.129248394715004\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2 facts verified.\n"
2015-08-11 22:48:35 +03:00
]
2015-08-27 08:18:20 +03:00
},
{
"data": {
"text/plain": [
"delayed_handler (generic function with 4 methods)"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
2015-06-25 23:11:57 +03:00
}
],
2015-06-25 00:47:03 +03:00
"source": [
"facts(\"test solve one element model\") do\n",
"\n",
" eq = get_test_equation()\n",
" el = get_element(eq)\n",
2015-08-27 08:18:20 +03:00
" #set_field(el, \"displacement\", zeros(2, 4))\n",
" F = [0.0 0.0; 0.0 0.0; 0.0 -2.0; 0.0 0.0]'\n",
"\n",
" du = zeros(2, 4)\n",
2015-07-28 22:27:41 +03:00
"\n",
" free_dofs = [3, 4, 5, 6]\n",
2015-07-28 22:27:41 +03:00
" for i=1:10\n",
2015-08-22 20:55:24 +03:00
" Logging.debug(\"Iteration $i\")\n",
" b = get_rhs(eq)\n",
" A = get_lhs(eq)\n",
2015-08-22 20:55:24 +03:00
" Logging.debug(\"Solving Ax = b\")\n",
" du[free_dofs] = A[free_dofs, free_dofs] \\ (b + F)[free_dofs]\n",
"\n",
" field = get_field(el, \"displacement\") + du\n",
" set_field(el, \"displacement\", field)\n",
2015-07-28 22:27:41 +03:00
" if norm(du) < 1.0e-9\n",
" Logging.debug(\"Converged in $i iterations.\")\n",
" break\n",
" end\n",
" end\n",
"\n",
" # Tested against Elmer solution\n",
" u = get_field(el, \"displacement\")\n",
2015-07-28 22:27:41 +03:00
" Logging.debug(\"solution vector: \\n $u\")\n",
2015-08-11 22:48:35 +03:00
" @fact u[2, 3] --> roughly(-2.222244754401764)\n",
2015-07-28 22:27:41 +03:00
" norm1 = norm(u)\n",
" Logging.debug(\"norm of u: $(norm(u))\")\n",
"\n",
" # We rotate model a bit and make sure that norm remains same\n",
2015-08-24 01:14:03 +03:00
" phi = 45/180*pi\n",
2015-07-28 22:27:41 +03:00
" rmat = [\n",
" cos(phi) -sin(phi)\n",
" sin(phi) cos(phi)]\n",
" set_field(el, \"coordinates\", rmat*get_field(el, \"coordinates\"))\n",
2015-07-28 22:27:41 +03:00
" F = rmat*F\n",
"\n",
" set_field(el, \"displacement\", [0.0 0.0; 0.0 0.0; 0.0 0.0; 0.0 0.0]')\n",
" du = zeros(2, 4)\n",
2015-07-28 22:27:41 +03:00
" for i=1:10\n",
2015-08-22 20:55:24 +03:00
" Logging.debug(\"Iteration $i\")\n",
" A = get_lhs(eq)\n",
" b = get_rhs(eq)\n",
2015-08-22 20:55:24 +03:00
" Logging.debug(\"Solving Ax = b\")\n",
" du[free_dofs] = A[free_dofs, free_dofs] \\ (b + F)[free_dofs]\n",
"\n",
" field = get_field(el, \"displacement\") + du\n",
" set_field(el, \"displacement\", field)\n",
2015-07-28 22:27:41 +03:00
" if norm(du) < 1.0e-9\n",
" Logging.debug(\"Converged in $i iterations.\")\n",
" break\n",
" end\n",
" end\n",
" u = get_field(el, \"displacement\")\n",
2015-07-28 22:27:41 +03:00
" Logging.debug(\"solution vector: \\n $u\")\n",
" Logging.debug(\"norm of u: $(norm(u))\")\n",
2015-08-11 22:48:35 +03:00
" @fact norm(u) --> roughly(norm1) \n",
2015-07-28 22:27:41 +03:00
"end"
]
},
2015-08-22 20:55:24 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assembly procedure is now very general because we always just have to call `get_lhs` and `get_rhs` to get corresponding vectors and matrices from element."
]
},
2015-07-28 22:27:41 +03:00
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 29,
2015-07-28 22:27:41 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-24 01:14:03 +03:00
"assemble_rhs! (generic function with 1 method)"
2015-07-28 22:27:41 +03:00
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 29,
2015-07-28 22:27:41 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-27 08:18:20 +03:00
"function assemble_lhs!(ass::Assembly, eq::Equation)\n",
2015-07-30 00:13:14 +03:00
"\n",
2015-08-27 08:18:20 +03:00
" el::Element = get_element(eq)\n",
" elid = get_field(el, \"id\")\n",
" gdofs = ass.gdofs[elid]\n",
2015-08-22 20:55:24 +03:00
"\n",
2015-08-27 08:18:20 +03:00
" A = get_lhs(eq)\n",
2015-08-22 20:55:24 +03:00
" if !(A == None)\n",
" ii, jj = size(A)\n",
" for i=1:ii\n",
" for j=1:jj\n",
" push!(ass.I, gdofs[i])\n",
" push!(ass.J, gdofs[j])\n",
" push!(ass.A, A[i,j])\n",
" end\n",
" end\n",
" end\n",
2015-08-24 01:14:03 +03:00
"end\n",
"\n",
2015-08-27 08:18:20 +03:00
"function assemble_rhs!(ass::Assembly, eq::Equation)\n",
"\n",
" el::Element = get_element(eq)\n",
" elid = get_field(el, \"id\")\n",
" gdofs = ass.gdofs[elid]\n",
2015-08-24 01:14:03 +03:00
"\n",
2015-08-22 20:55:24 +03:00
" \n",
2015-08-27 08:18:20 +03:00
" b = get_rhs(eq)\n",
2015-08-22 20:55:24 +03:00
" if !(b == None)\n",
" for i=1:length(b)\n",
" push!(ass.i, gdofs[i])\n",
" push!(ass.b, b[i])\n",
2015-07-30 00:13:14 +03:00
" end\n",
" end\n",
"end"
]
},
2015-08-22 20:55:24 +03:00
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 30,
2015-08-22 20:55:24 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-27 08:18:20 +03:00
"get_lhs (generic function with 2 methods)"
2015-08-22 20:55:24 +03:00
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 30,
2015-08-22 20:55:24 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"1-node point force element for plane stress problems.\n",
"\"\"\"\n",
2015-08-27 08:18:20 +03:00
"type CPS1 <: Elasticity\n",
" element :: Point1\n",
" integration_points :: Array{IntegrationPoint, 1}\n",
2015-08-22 20:55:24 +03:00
"end\n",
2015-08-27 08:18:20 +03:00
"function CPS1(el::Point1)\n",
" integration_points = []\n",
" set_field(el, \"displacement\", zeros(2, 1))\n",
" set_field(el, \"displacement nodal load\", zeros(2, 1))\n",
" CPS1(el, integration_points)\n",
2015-08-22 20:55:24 +03:00
"end\n",
2015-08-27 08:18:20 +03:00
"get_rhs(eq::CPS1) = get_field(get_element(eq), \"displacement nodal load\")\n",
"get_lhs(eq::CPS1) = None"
2015-08-22 20:55:24 +03:00
]
},
2015-07-30 00:13:14 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Time to test again. From last test we know that correct solution is\n",
"\n",
" [0.0 -0.39914506095474317 -0.07228582695592449 0.0\n",
2015-08-22 20:55:24 +03:00
" 0.0 -2.1779892317073504 -2.222244754401764 0.0]"
2015-07-28 22:27:41 +03:00
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 31,
2015-07-28 22:27:41 +03:00
"metadata": {
2015-07-30 00:13:14 +03:00
"collapsed": false
2015-07-28 22:27:41 +03:00
},
2015-07-30 00:13:14 +03:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2015-08-27 08:18:20 +03:00
"two element assembly\n"
2015-07-30 00:13:14 +03:00
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
2015-08-27 08:18:20 +03:00
"27-Aug 08:17:00:DEBUG:root:Starting iteration 1\n",
"27-Aug 08:17:00:DEBUG:root:Assembling\n",
"27-Aug 08:17:00:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:00:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 3.0900221367289986\n",
"27-Aug 08:17:01:DEBUG:root:Starting iteration 2\n",
"27-Aug 08:17:01:DEBUG:root:Assembling\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 0.3212131602153472\n",
"27-Aug 08:17:01:DEBUG:root:Starting iteration 3\n",
"27-Aug 08:17:01:DEBUG:root:Assembling\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 0.04043178193999703\n",
"27-Aug 08:17:01:DEBUG:root:Starting iteration 4\n",
"27-Aug 08:17:01:DEBUG:root:Assembling\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 0.0009291101052105739\n",
"27-Aug 08:17:01:DEBUG:root:Starting iteration 5\n",
"27-Aug 08:17:01:DEBUG:root:Assembling\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 1.5638899027804743e-7\n",
"27-Aug 08:17:01:DEBUG:root:Starting iteration 6\n",
"27-Aug 08:17:01:DEBUG:root:Assembling\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 1\n",
"27-Aug 08:17:01:DEBUG:root:Assembling lhs and rhs from equation 2\n",
"27-Aug 08:17:01:DEBUG:root:Solution norm = 1.0464940956129567e-14\n",
"27-Aug 08:17:01:DEBUG:root:Converged in 6 iterations.\n",
"27-Aug 08:17:01:DEBUG:root:Displacement of element = \n",
2015-08-19 18:50:43 +03:00
"[0.0 -0.39914506095474334 -0.0722858269559246 0.0\n",
" 0.0 -2.1779892317073504 -2.222244754401764 0.0]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 fact verified.\n"
2015-07-30 00:13:14 +03:00
]
},
{
"data": {
"text/plain": [
"delayed_handler (generic function with 4 methods)"
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 31,
2015-07-30 00:13:14 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
2015-07-28 22:27:41 +03:00
"source": [
2015-08-27 08:18:20 +03:00
"facts(\"two element assembly\") do\n",
2015-08-22 20:55:24 +03:00
" # set up element 1\n",
2015-08-27 08:18:20 +03:00
" el1 = Quad4([1, 2, 3, 4])\n",
" eq1 = CPS4(el1)\n",
2015-08-22 20:55:24 +03:00
" # assign properties to element, e.g. coordinates, material properties, ...\n",
" E = 90.0\n",
" nu = 0.25\n",
" mu = E/(2*(1+nu))\n",
" la = E*nu/((1+nu)*(1-2*nu))\n",
" la = 2*la*mu/(la + 2*mu)\n",
2015-08-27 08:18:20 +03:00
" set_field(el1, \"coordinates\", [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]')\n",
" set_field(el1, \"lambda\", la)\n",
" set_field(el1, \"mu\", mu)\n",
" set_field(el1, \"id\", 1)\n",
2015-08-22 20:55:24 +03:00
"\n",
" # set up element 2\n",
2015-08-27 08:18:20 +03:00
" el2 = Point1([3])\n",
" eq2 = CPS1(el2) # Create nodal point force element with id 2 for node 3\n",
" set_field(el2, \"displacement nodal load\", [0.0, -2.0])\n",
" set_field(el2, \"id\", 2)\n",
2015-08-22 20:55:24 +03:00
"\n",
" elements = [el1, el2]\n",
2015-08-27 08:18:20 +03:00
" equations = [eq1, eq2]\n",
2015-08-22 20:55:24 +03:00
"\n",
2015-07-30 00:13:14 +03:00
" for i=1:10\n",
" Logging.debug(\"Starting iteration $i\")\n",
" Logging.debug(\"Assembling\")\n",
2015-08-22 20:55:24 +03:00
" ass = Assembly()\n",
2015-08-27 08:18:20 +03:00
" ass.gdofs[get_field(el1, \"id\")] = [1, 2, 3, 4, 5, 6, 7, 8]\n",
" ass.gdofs[get_field(el2, \"id\")] = [5, 6]\n",
2015-08-22 20:55:24 +03:00
"\n",
2015-08-27 08:18:20 +03:00
" for (j, eq) in enumerate(equations)\n",
" Logging.debug(\"Assembling lhs and rhs from equation $j\")\n",
" assemble_lhs!(ass, eq)\n",
" assemble_rhs!(ass, eq)\n",
2015-08-22 20:55:24 +03:00
" end\n",
2015-08-01 20:54:25 +03:00
"\n",
2015-08-22 20:55:24 +03:00
" # (Dirichlet) boundary conditions \"handled\"\n",
2015-08-19 18:50:43 +03:00
" free_dofs = [3, 4, 5, 6]\n",
2015-07-30 00:13:14 +03:00
"\n",
" # solution\n",
2015-08-22 20:55:24 +03:00
" A = sparse(ass.I, ass.J, ass.A)\n",
" b = full(sparsevec(ass.i, ass.b))\n",
2015-08-19 18:50:43 +03:00
" du = zeros(8)\n",
2015-08-22 20:55:24 +03:00
" du[free_dofs] = A[free_dofs, free_dofs] \\ b[free_dofs]\n",
2015-07-28 22:27:41 +03:00
"\n",
2015-07-30 00:13:14 +03:00
" Logging.debug(\"Solution norm = $(norm(du))\")\n",
2015-07-28 22:27:41 +03:00
"\n",
2015-07-30 00:13:14 +03:00
" # update solution back to elements\n",
2015-08-22 20:55:24 +03:00
" for el in elements\n",
2015-08-27 08:18:20 +03:00
" eldu = du[ass.gdofs[get_field(el, \"id\")]]\n",
" #tmp = get_field(el, \"displacement\")\n",
" #set_field(el, \"displacement\", tmp+eldu)\n",
" #update_field(el, eldu)\n",
" el.fields[\"displacement\"][:] += eldu\n",
2015-08-22 20:55:24 +03:00
" end\n",
2015-07-30 00:13:14 +03:00
" if norm(du) < 1.0e-9\n",
" Logging.debug(\"Converged in $i iterations.\")\n",
" break\n",
" end\n",
2015-08-22 20:55:24 +03:00
" end \n",
2015-08-27 08:18:20 +03:00
" disp = get_field(el1, \"displacement\")\n",
2015-07-30 00:13:14 +03:00
" Logging.debug(\"Displacement of element = \\n$disp\")\n",
2015-08-19 18:50:43 +03:00
" @fact norm(disp) --> roughly(3.1292483947150043)\n",
2015-07-30 00:13:14 +03:00
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2015-08-22 20:55:24 +03:00
"Seems to be working. But we still need to handle Dirichlet boundary conditions somewhat more generally. In very general form Dirichlet bc can be expressed as $\\mathbf{B}\\mathbf{u} = \\mathbf{d}$ for variational problem and $\\mathbf{B}\\mathbf{u} \\leq \\mathbf{d}$ for variational inequality problems. In contact mechanics typically nodes are divided to several sets, one with slave nodes (can be eliminated), master nodes, and all other nodes. $\\mathbf{B}$ is usually something $\\mathbf{B}=\\begin{bmatrix}\\mathbf{0} & \\mathbf{D} & -\\mathbf{M}\\end{bmatrix}^\\mathrm{T}$. In normal Dirichlet boundary condition this simplifies to something $\\mathbf{D}\\mathbf{d}_\\mathcal{S} = \\mathbf{0}$, where nodes in set $\\mathcal{S}$ are known to be slave nodes. Finally, contact is nothing more than multi point constraint. Dirichlet boundary conditions can be easily eliminated if $\\mathbf{D}$ is diagonal: $\\mathbf{D}\\mathbf{d}_\\mathcal{S} = \\mathbf{M}\\mathbf{d}_\\mathcal{M} \\Rightarrow \\mathbf{d}_\\mathcal{S} = \\mathbf{D}^{-1}\\mathbf{M}\\mathbf{d}_\\mathcal{M} = \\mathbf{P}\\mathbf{d}_\\mathcal{M}$."
2015-07-02 22:21:41 +03:00
]
},
2015-06-25 00:47:03 +03:00
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 12,
2015-06-25 00:47:03 +03:00
"metadata": {
"collapsed": false
},
2015-08-01 20:54:25 +03:00
"outputs": [],
"source": [
2015-08-24 01:14:03 +03:00
"abstract BoundaryCondition\n",
"abstract DirichletBC <: BoundaryCondition\n",
"\n",
"type MPC <: DirichletBC\n",
2015-08-22 20:55:24 +03:00
" slave_dof :: Int64\n",
" slave_value :: Float64\n",
" master_dofs :: Array{Int64, 1}\n",
" master_values :: Array{Float64, 1}\n",
" constant :: Float64\n",
2015-08-01 20:54:25 +03:00
"end"
]
},
{
"cell_type": "code",
2015-08-27 08:18:20 +03:00
"execution_count": 13,
2015-08-22 20:55:24 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"MPC"
]
},
2015-08-27 08:18:20 +03:00
"execution_count": 13,
2015-08-22 20:55:24 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"Convenient function, to set some dof=0\n",
"\"\"\"\n",
"function MPC(dof)\n",
" MPC(dof, 1.0, Int64[], Float64[], 0.0)\n",
"end"
]
},
2015-08-27 08:18:20 +03:00
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"abstract Problem\n",
"\n",
"type PlaneStressProblem <: Problem\n",
" equations :: Array{Equation, 1}\n",
" boundary_conditions :: Array{BoundaryCondition, 1}\n",
"\n",
"# dofmap :: Dict{Int64, Array{Int64,1}}() # a dict node_id : (dof1, dof2, ...)\n",
"# solver_parameters :: SolverParameters\n",
"end"
]
},
2015-08-22 20:55:24 +03:00
{
"cell_type": "code",
"execution_count": 17,
2015-08-01 20:54:25 +03:00
"metadata": {
2015-08-19 18:50:43 +03:00
"collapsed": false
2015-08-01 20:54:25 +03:00
},
2015-06-25 00:47:03 +03:00
"outputs": [
{
2015-08-11 22:48:35 +03:00
"data": {
"text/plain": [
2015-08-19 18:50:43 +03:00
"create_ldof2gdofmap (generic function with 1 method)"
2015-08-11 22:48:35 +03:00
]
},
"execution_count": 17,
2015-08-11 22:48:35 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"\"\"\n",
"Create local dof to global dof mapping for given elements\n",
"\"\"\"\n",
2015-08-19 18:50:43 +03:00
"function create_ldof2gdofmap(elements, field)\n",
2015-08-11 22:48:35 +03:00
"\n",
2015-08-19 18:50:43 +03:00
" ndofs = size(elements[1].attributes[field], 1)\n",
" \n",
2015-08-11 22:48:35 +03:00
" all_node_ids = Int64[]\n",
" for el in elements\n",
" for nid in el.node_ids\n",
" push!(all_node_ids, nid)\n",
" end\n",
" end\n",
" all_node_ids = unique(all_node_ids)\n",
"\n",
" # Assign global dof for each node\n",
" pdim = 1\n",
" ngdofs = Dict{Int64, Array{Int64,1}}()\n",
" for nid in all_node_ids\n",
" ngdofs[nid] = collect(pdim:pdim+ndofs-1)\n",
" pdim += ndofs\n",
" end\n",
"\n",
" return ngdofs\n",
2015-08-19 18:50:43 +03:00
"end"
]
},
2015-08-24 01:14:03 +03:00
{
"cell_type": "code",
"execution_count": 18,
2015-08-19 18:50:43 +03:00
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"solve one element problem\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"24-Aug 18:34:38:DEBUG:root:Dict(4=>[7,8],2=>[3,4],3=>[5,6],1=>[1,2])\n",
"24-Aug 18:34:38:INFO:root:solve!: dofs per node: 2\n",
"24-Aug 18:34:39:DEBUG:root:Problem size = 8\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 1\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 3.0900221367289444\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 2\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 0.32121316021534796\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 3\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 0.040431781940014504\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 4\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 0.0009291101052065917\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 5\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 1.5638899136781228e-7\n",
"24-Aug 18:34:39:DEBUG:root:Starting iteration 6\n",
"24-Aug 18:34:39:DEBUG:root:Assembling lhs\n",
"24-Aug 18:34:39:DEBUG:root:Assembling rhs\n",
"24-Aug 18:34:39:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"24-Aug 18:34:39:DEBUG:root:Added 4 Lagrange multipliers to model\n",
"24-Aug 18:34:39:DEBUG:root:Solving system of equations. Total size = 12\n",
"24-Aug 18:34:39:DEBUG:root:Solution norm du = 1.0913504694802626e-14\n",
"24-Aug 18:34:39:DEBUG:root:Converged in 6 iterations.\n",
"24-Aug 18:34:39:DEBUG:root:Displacement on upper right = \n",
2015-08-22 20:55:24 +03:00
"[-0.07228582695592467\n",
" -2.222244754401765]\n"
2015-08-19 18:50:43 +03:00
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 fact verified.\n"
]
},
{
"data": {
"text/plain": [
"delayed_handler (generic function with 4 methods)"
]
},
"execution_count": 18,
2015-08-19 18:50:43 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"function solve!(elements, dofmap, dirichlet_bcs; ndofs=2, max_iterations=10)\n",
2015-08-11 22:48:35 +03:00
"\n",
" Logging.info(\"solve!: dofs per node: $ndofs\")\n",
" pdim = length(dofmap)*ndofs\n",
" Logging.debug(\"Problem size = $pdim\")\n",
"\n",
2015-08-22 20:55:24 +03:00
" # Assign global dofs for element ids\n",
2015-08-11 22:48:35 +03:00
" gdofs = Dict{Int64, Array{Int64,1}}()\n",
" for el in elements\n",
" gdofs[el.id] = Int64[]\n",
" for nid in el.node_ids\n",
" for ndof in dofmap[nid]\n",
" push!(gdofs[el.id], ndof)\n",
" end\n",
" end\n",
" end\n",
"\n",
" for iter=1:max_iterations\n",
" Logging.debug(\"Starting iteration $iter\")\n",
2015-08-22 20:55:24 +03:00
" ass = JuliaFEM.Assembly(gdofs)\n",
"\n",
2015-08-24 01:14:03 +03:00
" Logging.debug(\"Assembling lhs\")\n",
2015-08-11 22:48:35 +03:00
" for el in elements\n",
2015-08-24 01:14:03 +03:00
" assemble_lhs!(ass, el)\n",
" end\n",
" Logging.debug(\"Assembling rhs\")\n",
" for el in elements\n",
" assemble_rhs!(ass, el)\n",
2015-08-11 22:48:35 +03:00
" end\n",
"\n",
2015-08-22 20:55:24 +03:00
" i = 0\n",
2015-08-19 18:50:43 +03:00
" Logging.debug(\"Adding Dirichlet boundary conditions using Lagrange multipliers\")\n",
2015-08-22 20:55:24 +03:00
" # Dirichlet boundary conditions (this leads to a saddle point problem)\n",
2015-08-19 18:50:43 +03:00
" for bc in dirichlet_bcs\n",
2015-08-22 20:55:24 +03:00
" i += 1\n",
" #Logging.debug(\"lock dof $(bc.slave_dof), matrix row $(pdim+i)\")\n",
" push!(ass.I, bc.slave_dof)\n",
" push!(ass.J, pdim+i)\n",
" push!(ass.A, bc.slave_value)\n",
" push!(ass.I, pdim+i)\n",
" push!(ass.J, bc.slave_dof)\n",
" push!(ass.A, bc.slave_value)\n",
" push!(ass.i, pdim+i)\n",
" push!(ass.b, bc.constant)\n",
2015-08-11 22:48:35 +03:00
" end\n",
2015-08-19 18:50:43 +03:00
" Logging.debug(\"Added $i Lagrange multipliers to model\")\n",
2015-08-11 22:48:35 +03:00
" Logging.debug(\"Solving system of equations. Total size = $(pdim+i)\")\n",
"\n",
2015-08-22 20:55:24 +03:00
" # solution\n",
" A = sparse(ass.I, ass.J, ass.A)\n",
" b = full(sparsevec(ass.i, ass.b))\n",
" du = A \\ b\n",
2015-08-11 22:48:35 +03:00
"\n",
" solnorm = norm(du[1:pdim])\n",
" Logging.debug(\"Solution norm du = $solnorm\")\n",
"\n",
" # update solution back to elements\n",
" for el in elements\n",
" eldu = du[ass.gdofs[el.id]]\n",
2015-08-22 20:55:24 +03:00
" update_field(el, eldu)\n",
2015-08-11 22:48:35 +03:00
"\n",
" end\n",
" if solnorm < 1.0e-9\n",
" Logging.debug(\"Converged in $iter iterations.\")\n",
" break\n",
" end\n",
" end\n",
"\n",
"end\n",
"\n",
"ENV[\"COLUMNS\"] = 160\n",
"\n",
2015-08-19 18:50:43 +03:00
"facts(\"solve one element problem\") do\n",
2015-08-22 20:55:24 +03:00
"\n",
" # set up element 1\n",
" element_id = 1\n",
" node_ids = [1, 2, 3, 4]\n",
" el1 = CPS4(element_id, node_ids)\n",
" # assign properties to element, e.g. coordinates, material properties, ...\n",
" E = 90.0\n",
" nu = 0.25\n",
" mu = E/(2*(1+nu))\n",
" la = E*nu/((1+nu)*(1-2*nu))\n",
" la = 2*la*mu/(la + 2*mu)\n",
2015-08-24 01:14:03 +03:00
" set_coordinates(el1, [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]')\n",
2015-08-22 20:55:24 +03:00
" set_attribute(el1, \"lambda\", la)\n",
" set_attribute(el1, \"mu\", mu)\n",
"\n",
" # set up element 2\n",
" el2 = CPS1(2, [3]) # Create nodal point force element with id 2 for node 3\n",
" set_attribute(el2, \"displacement nodal load\", [0.0, -2.0])\n",
"\n",
" elements = [el1, el2]\n",
"\n",
2015-08-19 18:50:43 +03:00
" dofmap = create_ldof2gdofmap(elements, \"displacement\")\n",
2015-08-11 22:48:35 +03:00
" Logging.debug(dofmap)\n",
" # Boundary conditions\n",
" # dirichlet bc, set dx=dy=0 on support\n",
2015-08-22 20:55:24 +03:00
" mpc1 = MPC(dofmap[1][1]) # node 1, dx=0\n",
" mpc2 = MPC(dofmap[1][2]) # node 1, dy\n",
" mpc3 = MPC(dofmap[4][1]) # node 4, dx\n",
" mpc4 = MPC(dofmap[4][2]) # node 4, dy\n",
" dbcs = [mpc1, mpc2, mpc3, mpc4]\n",
" #bc2 = BC([dofmap[1][1], dofmap[1][2], dofmap[4][1], dofmap[4][2]], [0.0, 0.0, 0.0, 0.0])\n",
" solve!(elements, dofmap, dbcs; max_iterations=10)\n",
" Logging.debug(\"Displacement on upper right = \\n$(get_field(el2))\")\n",
" disp = get_field(el1)\n",
2015-08-19 18:50:43 +03:00
" @fact norm(disp) --> roughly(3.1292483947150043)\n",
"end\n"
2015-08-11 22:48:35 +03:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2015-08-22 20:55:24 +03:00
"# 3d simulation\n",
2015-08-11 22:48:35 +03:00
"\n",
2015-08-22 20:55:24 +03:00
"We create a new C3D10 element and solve 3d problem."
2015-08-11 22:48:35 +03:00
]
},
{
"cell_type": "code",
2015-08-24 01:14:03 +03:00
"execution_count": 23,
2015-08-11 22:48:35 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
2015-08-24 01:14:03 +03:00
"24-Aug 01:07:34:INFO:root:Registered handlers: Any[\"ELEMENT\",\"NODE\",\"NSET\"]\n",
"24-Aug 01:07:34:DEBUG:root:Found NODE section\n",
"24-Aug 01:07:35:DEBUG:root:Found ELEMENT section\n",
"24-Aug 01:07:35:DEBUG:root:120 elements found\n",
"24-Aug 01:07:35:INFO:root:Creating ELSET Body1\n",
"24-Aug 01:07:35:DEBUG:root:Found NSET section\n",
"24-Aug 01:07:35:DEBUG:root:Creating node set SUPPORT\n",
"24-Aug 01:07:35:DEBUG:root:Found NSET section\n",
"24-Aug 01:07:35:DEBUG:root:Creating node set LOAD\n",
"24-Aug 01:07:35:DEBUG:root:Found NSET section\n",
"24-Aug 01:07:35:DEBUG:root:Creating node set TOP\n"
]
2015-08-19 22:51:44 +03:00
},
{
"data": {
"text/plain": [
"Dict{Any,Any} with 4 entries:\n",
" \"nodes\" => Dict{Any,Any}(288=>[97.5,7.5,10.0],11=>[92.5,2.5,5.0],134=>[45.0,10.0,0.0],158=>[2.5,2.5,0.0],160=>[7.5,7.5,0.0],215=>[60.0,0.0,5.0],29=>[2.5,7…\n",
" \"elements\" => Dict{Any,Any}(68=>[71,144,149,198,51,150,57,43,50,214],2=>[204,199,175,130,207,208,209,3,4,176],89=>[95,78,104,52,127,126,106,60,68,67],11=>[15…\n",
" \"elsets\" => Dict{Any,Any}(\"Body1\"=>[1,2,3,4,5,6,7,8,9,10 … 111,112,113,114,115,116,117,118,119,120])\n",
" \"nsets\" => Dict{Any,Any}(\"LOAD\"=>[82,84,87,179,197,246,249,256,257],\"SUPPORT\"=>[108,109,111,155,162,216,225,281,298],\"TOP\"=>[70,75,76,84,88,90,95,96,98,10…"
]
},
2015-08-24 01:14:03 +03:00
"execution_count": 23,
2015-08-19 22:51:44 +03:00
"metadata": {},
"output_type": "execute_result"
2015-06-25 23:11:57 +03:00
}
],
"source": [
2015-08-11 22:48:35 +03:00
"fid = open(\"../geometry/3d_beam/palkki.inp\")\n",
2015-08-22 20:55:24 +03:00
"model = JuliaFEM.parse_abaqus(fid)\n",
2015-08-11 22:48:35 +03:00
"close(fid)\n",
"model"
2015-06-25 23:11:57 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 20,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
2015-08-24 01:14:03 +03:00
"abstract Tet10 <: CG\n",
"\n",
2015-08-22 20:55:24 +03:00
"\"\"\"\n",
"Stress/displacement elements. 10-node quadratic tetrahedron.\n",
"\"\"\"\n",
2015-08-24 01:14:03 +03:00
"type C3D10 <: Tet10\n",
2015-08-22 20:55:24 +03:00
" id :: Int\n",
" node_ids :: Array{Int, 1}\n",
2015-08-24 01:14:03 +03:00
" coordinates :: Array{Float64, 2}\n",
2015-08-22 20:55:24 +03:00
" integration_points :: Array{IntegrationPoint, 1}\n",
" attributes :: Dict{ASCIIString, Any}\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 21,
2015-08-19 22:51:44 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-22 20:55:24 +03:00
"C3D10"
2015-08-19 22:51:44 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 21,
2015-08-19 22:51:44 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"function C3D10(element_id, node_ids)\n",
"\n",
" # Construct Lagrange basis\n",
" \n",
" P(xi) = [\n",
" 1\n",
" xi[1]\n",
" xi[2]\n",
" xi[3]\n",
" xi[1]^2\n",
" xi[2]^2\n",
" xi[3]^2\n",
" xi[1]*xi[2]\n",
" xi[2]*xi[3]\n",
" xi[3]*xi[1]]\n",
"\n",
" dP(xi) = [\n",
" 0 0 0\n",
" 1 0 0\n",
" 0 1 0\n",
" 0 0 1\n",
" 2*xi[1] 0 0\n",
" 0 2*xi[2] 0\n",
" 0 0 2*xi[3]\n",
" xi[2] xi[1] 0\n",
" 0 xi[3] xi[2]\n",
" xi[3] 0 xi[1]\n",
" ]\n",
"\n",
" X = [\n",
" 0.0 0.0 0.0\n",
" 1.0 0.0 0.0\n",
" 0.0 1.0 0.0\n",
" 0.0 0.0 1.0\n",
" 0.5 0.0 0.0\n",
" 0.5 0.5 0.0\n",
" 0.0 0.5 0.0\n",
" 0.0 0.0 0.5\n",
" 0.5 0.0 0.5\n",
" 0.0 0.5 0.5]\n",
"\n",
" A = zeros(10, 10)\n",
"\n",
" for i=1:10\n",
" A[i,:] = P(X[i,:])\n",
" end\n",
"\n",
" invA = inv(A)\n",
" basis(xi) = invA'*P(xi)\n",
" dbasis(xi) = invA'*dP(xi)\n",
"\n",
" shape_functions = FunctionSpace(basis, dbasis)\n",
"\n",
" a = .585410196624969\n",
" b = .138196601125011\n",
" w = .041666666666667\n",
"\n",
" integration_points = [\n",
" JuliaFEM.IntegrationPoint([a, b, b], w, Dict()),\n",
" JuliaFEM.IntegrationPoint([b, a, b], w, Dict()),\n",
" JuliaFEM.IntegrationPoint([b, b, a], w, Dict()),\n",
" JuliaFEM.IntegrationPoint([b, b, b], w, Dict())]\n",
" \n",
" attributes = Dict(\"displacement\" => zeros(3, 10))\n",
"\n",
" C3D10(element_id, node_ids, shape_functions, integration_points, attributes)\n",
"end"
2015-08-19 22:51:44 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 22,
2015-08-19 22:51:44 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-22 20:55:24 +03:00
"get_lhs (generic function with 4 methods)"
2015-08-19 22:51:44 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 22,
2015-08-19 22:51:44 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"\"\"\"\n",
"1-node point force element for 3d elasticity problem.\n",
"\"\"\"\n",
"type C3D1 <: ContinuumElement\n",
" id :: Int\n",
" node_ids :: Array{Int, 1}\n",
" attributes :: Dict{ASCIIString, Any}\n",
2015-08-19 22:51:44 +03:00
"end\n",
2015-08-22 20:55:24 +03:00
"function C3D1(element_id, node_ids)\n",
" attributes = Dict(\n",
" \"displacement\" => zeros(3, 1),\n",
" \"displacement nodal load\" => zeros(3, 1))\n",
" C3D1(element_id, node_ids, attributes)\n",
"end\n",
"function get_rhs(el::C3D1)\n",
" return el.attributes[\"displacement nodal load\"]\n",
"end\n",
"function get_lhs(el::C3D1)\n",
" return None\n",
"end"
2015-08-19 22:51:44 +03:00
]
},
{
"cell_type": "code",
2015-08-24 01:14:03 +03:00
"execution_count": 40,
2015-06-25 23:11:57 +03:00
"metadata": {
2015-08-11 22:48:35 +03:00
"collapsed": false,
"scrolled": false
2015-06-25 23:11:57 +03:00
},
"outputs": [
{
2015-08-11 22:48:35 +03:00
"name": "stderr",
2015-06-25 23:11:57 +03:00
"output_type": "stream",
"text": [
2015-08-24 01:14:03 +03:00
"22-Aug 21:35:10:DEBUG:root:Creating elements\n",
"22-Aug 21:35:10:DEBUG:root:Creating elements\n",
"22-Aug 21:35:10:INFO:root:solve!: dofs per node: 3\n",
"22-Aug 21:35:10:DEBUG:root:Problem size = 894\n",
"22-Aug 21:35:10:DEBUG:root:Starting iteration 1\n",
"22-Aug 21:35:10:DEBUG:root:Assembling lhs\n",
"22-Aug 21:35:23:DEBUG:root:Assembling rhs\n",
"22-Aug 21:35:23:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:35:23:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:35:23:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:35:23:DEBUG:root:Solution norm du = 550.6462282437674\n",
"22-Aug 21:35:23:DEBUG:root:Starting iteration 2\n",
"22-Aug 21:35:23:DEBUG:root:Assembling lhs\n",
"22-Aug 21:35:36:DEBUG:root:Assembling rhs\n",
"22-Aug 21:35:36:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:35:36:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:35:36:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:35:36:DEBUG:root:Solution norm du = 126.14054730775176\n",
"22-Aug 21:35:36:DEBUG:root:Starting iteration 3\n",
"22-Aug 21:35:36:DEBUG:root:Assembling lhs\n",
"22-Aug 21:35:49:DEBUG:root:Assembling rhs\n",
"22-Aug 21:35:49:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:35:49:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:35:49:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:35:49:DEBUG:root:Solution norm du = 38.949840553368894\n",
"22-Aug 21:35:49:DEBUG:root:Starting iteration 4\n",
"22-Aug 21:35:49:DEBUG:root:Assembling lhs\n",
"22-Aug 21:36:03:DEBUG:root:Assembling rhs\n",
"22-Aug 21:36:04:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:36:04:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:36:04:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:36:04:DEBUG:root:Solution norm du = 15.167069063650652\n",
"22-Aug 21:36:04:DEBUG:root:Starting iteration 5\n",
"22-Aug 21:36:04:DEBUG:root:Assembling lhs\n",
"22-Aug 21:36:17:DEBUG:root:Assembling rhs\n",
"22-Aug 21:36:17:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:36:17:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:36:17:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:36:17:DEBUG:root:Solution norm du = 9.516311534304958\n",
"22-Aug 21:36:17:DEBUG:root:Starting iteration 6\n",
"22-Aug 21:36:17:DEBUG:root:Assembling lhs\n",
"22-Aug 21:36:32:DEBUG:root:Assembling rhs\n",
"22-Aug 21:36:32:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:36:32:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:36:32:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:36:32:DEBUG:root:Solution norm du = 1.6222822043785954\n",
"22-Aug 21:36:32:DEBUG:root:Starting iteration 7\n",
"22-Aug 21:36:32:DEBUG:root:Assembling lhs\n",
"22-Aug 21:36:46:DEBUG:root:Assembling rhs\n",
"22-Aug 21:36:48:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:36:48:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:36:48:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:36:48:DEBUG:root:Solution norm du = 0.09626397754176579\n",
"22-Aug 21:36:48:DEBUG:root:Starting iteration 8\n",
"22-Aug 21:36:48:DEBUG:root:Assembling lhs\n",
"22-Aug 21:37:07:DEBUG:root:Assembling rhs\n",
"22-Aug 21:37:07:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:37:07:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:37:07:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:37:07:DEBUG:root:Solution norm du = 0.00026304537198068307\n",
"22-Aug 21:37:07:DEBUG:root:Starting iteration 9\n",
"22-Aug 21:37:07:DEBUG:root:Assembling lhs\n",
"22-Aug 21:37:22:DEBUG:root:Assembling rhs\n",
"22-Aug 21:37:22:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:37:22:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:37:22:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:37:22:DEBUG:root:Solution norm du = 2.7245126807720425e-9\n",
"22-Aug 21:37:22:DEBUG:root:Starting iteration 10\n",
"22-Aug 21:37:22:DEBUG:root:Assembling lhs\n",
"22-Aug 21:37:35:DEBUG:root:Assembling rhs\n",
"22-Aug 21:37:35:DEBUG:root:Adding Dirichlet boundary conditions using Lagrange multipliers\n",
"22-Aug 21:37:35:DEBUG:root:Added 27 Lagrange multipliers to model\n",
"22-Aug 21:37:35:DEBUG:root:Solving system of equations. Total size = 921\n",
"22-Aug 21:37:35:DEBUG:root:Solution norm du = 1.0919112177573261e-13\n",
"22-Aug 21:37:35:DEBUG:root:Converged in 10 iterations.\n",
"22-Aug 21:37:35:INFO:root:Maximum absolute displacement in y direction: 49.40459927455298\n"
2015-06-25 23:11:57 +03:00
]
}
],
"source": [
2015-08-11 22:48:35 +03:00
"function solve_3d_model()\n",
" Logging.debug(\"Creating elements\")\n",
2015-08-19 22:51:44 +03:00
" elements = JuliaFEM.Element[]\n",
" \n",
2015-08-22 20:55:24 +03:00
" E = 90.0e6\n",
" nu = 0.3\n",
" mu = E/(2*(1+nu))\n",
" la = E*nu/((1+nu)*(1-2*nu))\n",
" la = 2*la*mu/(la + 2*mu)\n",
2015-08-19 22:51:44 +03:00
"\n",
2015-08-22 20:55:24 +03:00
" coordinates = zeros(3, 10)\n",
2015-08-19 22:51:44 +03:00
"\n",
2015-08-22 20:55:24 +03:00
" Logging.debug(\"Creating elements\")\n",
2015-08-11 22:48:35 +03:00
" for (elid, node_ids) in model[\"elements\"]\n",
2015-08-19 22:51:44 +03:00
" coordinates[:,:] = 0.0\n",
2015-08-11 22:48:35 +03:00
" for (i, nid) in enumerate(node_ids)\n",
" coordinates[:,i] = model[\"nodes\"][nid]\n",
" end\n",
2015-08-22 20:55:24 +03:00
" el = C3D10(elid, node_ids)\n",
" set_attribute(el, \"coordinates\", copy(coordinates))\n",
" set_attribute(el, \"lambda\", la)\n",
" set_attribute(el, \"mu\", mu)\n",
2015-08-11 22:48:35 +03:00
" push!(elements, el)\n",
" end\n",
"\n",
" # create \"dofmap\" so that we know how to assemble global stiffness matrix\n",
2015-08-19 22:51:44 +03:00
" dofmap = create_ldof2gdofmap(elements, \"displacement\")\n",
2015-08-11 22:48:35 +03:00
"\n",
" # Boundary conditions\n",
"\n",
2015-08-22 20:55:24 +03:00
" # dirichlet bc, set dx=dy=dz=0 for all nodes in set SUPPORT\n",
" dirichlet_bcs = MPC[]\n",
2015-08-11 22:48:35 +03:00
" for nid in model[\"nsets\"][\"SUPPORT\"]\n",
" for i=1:3\n",
2015-08-22 20:55:24 +03:00
" push!(dirichlet_bcs, MPC(dofmap[nid][i]))\n",
2015-08-11 22:48:35 +03:00
" end\n",
" end\n",
"\n",
2015-08-22 20:55:24 +03:00
" # force boundary condition, put -1500000 to 2nd dof for each node in set LOAD\n",
" elcnt = 100000\n",
" loadvec = [0.0, -1500000.0, 0.0]\n",
2015-08-11 22:48:35 +03:00
" for nid in model[\"nsets\"][\"LOAD\"]\n",
2015-08-22 20:55:24 +03:00
" # set up \"point load element\"\n",
" elcnt += 1\n",
" el = C3D1(elcnt, [nid])\n",
" set_attribute(el, \"displacement nodal load\", loadvec)\n",
" push!(elements, el)\n",
2015-08-11 22:48:35 +03:00
" end\n",
"\n",
" # ndofs = dimension of unknown field in nodes\n",
2015-08-22 20:55:24 +03:00
" solve!(elements, dofmap, dirichlet_bcs; ndofs=3, max_iterations=10)\n",
2015-08-11 22:48:35 +03:00
"\n",
" # Let's pick maximum absolute displacement in y direction\n",
" maxdisp = 0.0\n",
" for el in elements\n",
" eldisp = el.attributes[\"displacement\"]\n",
" eldispy = eldisp[2,:]\n",
" maxeldisp = maximum(abs(eldispy))\n",
" if maxeldisp > maxdisp\n",
" maxdisp = maxeldisp\n",
" end\n",
" end\n",
" Logging.info(\"Maximum absolute displacement in y direction: $maxdisp\")\n",
" return model, elements, dofmap\n",
"end\n",
"\n",
"model, elements, dofmap = solve_3d_model();"
2015-06-25 23:11:57 +03:00
]
},
2015-08-22 20:55:24 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"22.8.2015 13-14 seconds/assembly."
]
},
2015-06-25 23:11:57 +03:00
{
2015-08-11 22:48:35 +03:00
"cell_type": "markdown",
"metadata": {},
2015-06-25 23:11:57 +03:00
"source": [
2015-08-11 22:48:35 +03:00
"## Saving results to file"
2015-06-25 23:11:57 +03:00
]
},
{
2015-06-28 20:27:15 +03:00
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 28,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"<Grid Name=\"Grid\">\n",
" <Time Value=\"0\"/>\n",
"</Grid>\n"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 28,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"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)"
2015-08-11 22:48:35 +03:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Save geometry to xdmf file"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 29,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
2015-08-11 22:48:35 +03:00
"name": "stderr",
"output_type": "stream",
"text": [
2015-08-22 20:55:24 +03:00
"22-Aug 20:53:09:INFO:root:Number of nodes in model: 298\n",
"22-Aug 20:53:09:INFO:root:Number of elements in model: 120\n"
2015-08-11 22:48:35 +03:00
]
2015-06-28 20:27:15 +03:00
}
],
"source": [
2015-08-11 22:48:35 +03:00
"nnodes = length(model[\"nodes\"])\n",
"Logging.info(\"Number of nodes in model: $nnodes\")\n",
"node_ids = Int64[]\n",
"for nid in keys(model[\"nodes\"])\n",
" push!(node_ids, nid)\n",
"end\n",
"sort!(node_ids)\n",
"X = zeros(3, nnodes)\n",
"for (i, nid) in enumerate(node_ids)\n",
" X[:,i] = model[\"nodes\"][nid]\n",
"end\n",
"\n",
"nelements = length(model[\"elements\"])\n",
"Logging.info(\"Number of elements in model: $nelements\")\n",
"elmap = zeros(Int64, 11, nelements)\n",
"elmap[1,:] = 0x0026\n",
"for elid in 1:nelements\n",
" elmap[2:end,elid] = model[\"elements\"][elid]\n",
"end"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 30,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"true"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 30,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"JuliaFEM.xdmf_new_mesh(grid, X, elmap)"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 31,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"10435"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 31,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
2015-06-25 23:11:57 +03:00
"source": [
2015-08-22 20:55:24 +03:00
"JuliaFEM.xdmf_save_model(xdoc, \"/tmp/3d_solid_model.xmf\")"
2015-08-11 22:48:35 +03:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Save nodal data to model"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 32,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"Dict{Any,Any} with 298 entries:\n",
2015-08-22 20:55:24 +03:00
" 288 => [-12.729409015111749,-46.9846345618832,0.009761610393284966]\n",
" 11 => [-14.785829217208345,-42.20176974427358,0.008418234114233902]\n",
" 158 => [-0.09613238427634156,-0.024925865661713818,-0.021152328599486542]\n",
" 215 => [-8.20409899751332,-20.651834887555676,0.003675944651348186]\n",
" 134 => [-0.04746289973766305,-13.917505665457174,0.05113049026250106]\n",
" 160 => [0.24815357717678269,-0.45087760210227873,0.03912838810489934]\n",
" 29 => [0.07844018461547243,-0.0627092438336493,0.004195891729593265]\n",
" 131 => [-0.044388456389576496,-13.917981456773019,-0.0438798882444338]\n",
" 249 => [-18.540806339609137,-46.66700218188106,0.008827411992911762]\n",
" 207 => [-4.7437779792501855,-11.296644899155622,0.02719228049012583]\n",
" 173 => [-6.3308244019029285,-30.052183303569294,0.02087205767261999]\n",
" 289 => [-11.37815163924305,-43.5423942881868,0.006659559839321376]\n",
" 74 => [-1.0030212040099715,-18.13510354497542,0.026360938873556356]\n",
" 201 => [-6.115145748129304,-15.075793071665448,0.0029932630672883753]\n",
" 176 => [-1.9275056779524837,-10.695874800497005,0.002034006619959744]\n",
" 57 => [-4.707634597909023,-20.14315254888759,0.005778013656624454]\n",
" 31 => [-0.017918702135579754,-0.20429459029338543,-0.001244164592902138]\n",
" 285 => [-13.758654101433423,-44.588532062281345,0.009242729767728863]\n",
" 70 => [-0.6491658026068142,-16.68445815172466,-0.03677230855273911]\n",
" 33 => [-0.20319546252824566,-0.1970254554753098,0.020084518618881362]\n",
" 252 => [-1.2461038792304833,-1.632376299729978,0.003005676402356064]\n",
" 114 => [0.6751013334216733,-0.8524740368899743,-0.0743055712746195]\n",
" 165 => [-10.550249918373362,-26.708598943475753,-0.0182375631888076]\n",
" 96 => [-6.477353553877085,-35.67268031983259,-0.004587926489339682]\n",
" 133 => [0.425071475140366,-11.347486228911315,0.003588217409561677]\n",
2015-08-11 22:48:35 +03:00
" ⋮ => ⋮"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 32,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-11 22:48:35 +03:00
"nodaldisp = Dict()\n",
"for el in elements\n",
" for (i, nid) in enumerate(el.node_ids)\n",
" nodaldisp[nid] = el.attributes[\"displacement\"][:, i]\n",
" end\n",
"end\n",
"nodaldisp"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 33,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"3x298 Array{Float64,2}:\n",
2015-08-19 22:51:44 +03:00
" -0.328537 -0.581456 -1.94415 -2.25956 -1.65873 -1.02996 … -0.151833 -0.572535 -0.320967 -1.37494 -0.922318 0.0\n",
" -2.97468 -4.52837 -10.717 -11.9348 -14.9046 -12.2747 -1.683 -4.49601 -2.94077 -8.4008 -6.32738 0.0\n",
" -0.000439894 0.00176042 0.00267874 0.00357279 0.00431665 0.00380978 0.0048871 0.00163786 0.00332861 0.00422365 0.00304404 0.0"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 33,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-11 22:48:35 +03:00
"u = zeros(3, nnodes)\n",
"for (i, nid) in enumerate(node_ids)\n",
" u[:,i] = nodaldisp[nid]\n",
"end\n",
"u"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 34,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-11 22:48:35 +03:00
"true"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 34,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"JuliaFEM.xdmf_new_field(grid, \"Displacement\", \"nodes\", u)"
2015-06-28 20:27:15 +03:00
]
},
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 35,
2015-06-28 20:27:15 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
2015-08-22 20:55:24 +03:00
"28138"
2015-06-28 20:27:15 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 35,
2015-06-28 20:27:15 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-22 20:55:24 +03:00
"JuliaFEM.xdmf_save_model(xdoc, \"/tmp/3d_solid_model.xmf\")"
2015-06-28 20:27:15 +03:00
]
},
2015-08-19 18:50:43 +03:00
{
"cell_type": "code",
2015-08-22 20:55:24 +03:00
"execution_count": 36,
2015-08-19 18:50:43 +03:00
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
2015-08-19 22:51:44 +03:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxIAAAHlCAIAAADurl0UAAAgAElEQVR4XuzdV5xdxZ0v+l+1PPfx+mHmnjlzxoGxh9BKSCAhQIDUyjnn0IqtbuXQvQGDMcZkWglJgHLOOUdQIBiTEQqNseeMPZ7PfblzHua+3XOOd92HWqFWraq11t4dUHf/vp/+SGtV1Vp7SzNo//yvWrWFlBJERERElKYkbQARERERAYxNRERERBkxNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1EREREmTA2EREREWXC2ERERESUCWMTERERUSaMTURERESZMDYRERERZcLYRERERJQJYxMRERFRJoxNRERERJkwNhERERFlwthERERElAljExEREVEmjE1ERERE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
2015-08-19 18:50:43 +03:00
"text/plain": [
2015-08-19 22:51:44 +03:00
"PyObject <IPython.core.display.Image object>"
2015-08-19 18:50:43 +03:00
]
},
2015-08-22 20:55:24 +03:00
"execution_count": 36,
2015-08-19 18:50:43 +03:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2015-08-19 22:51:44 +03:00
"using PyCall\n",
"@pyimport IPython.display as d\n",
"d.Image(\"/tmp/3d_solid_model.png\")"
2015-08-19 18:50:43 +03:00
]
},
2015-08-22 20:55:24 +03:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Another 3d example"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"using JuliaFEM.abaqus_reader\n",
"fid = open(\"../geometry/piston/piston_45510_P1.inp\")\n",
"#fid = open(\"../geometry/piston/piston_8789_P1.inp\")\n",
"model = JuliaFEM.abaqus_reader.parse_abaqus(fid)\n",
"close(fid)\n",
"model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Construct linear Lagrange basis\n",
"P(xi) = [\n",
" 1\n",
" xi[1]\n",
" xi[2]\n",
" xi[3]]\n",
"dP(xi) = [\n",
" 0 0 0\n",
" 1 0 0\n",
" 0 1 0\n",
" 0 0 1]\n",
"X = [\n",
" 0.0 0.0 0.0\n",
" 1.0 0.0 0.0\n",
" 0.0 1.0 0.0\n",
" 0.0 0.0 1.0]\n",
"A = zeros(4, 4)\n",
"for i=1:4\n",
" A[i,:] = P(X[i,:])\n",
"end\n",
"invA = inv(A)\n",
"basis(xi) = invA'*P(xi)\n",
"dbasis(xi) = invA'*dP(xi)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"function solve_3d_model()\n",
" Logging.debug(\"Creating elements\")\n",
" elements = JuliaFEM.Element[]\n",
" coordinates = zeros(3, 4)\n",
"\n",
" integration_points = [\n",
" JuliaFEM.IntegrationPoint([0.25, 0.25, 0.25], 1/6, Dict())\n",
" ]\n",
"\n",
" for (elid, node_ids) in model[\"elements\"]\n",
" coordinates[:,:] = 0.0\n",
" for (i, nid) in enumerate(node_ids)\n",
" coordinates[:,i] = model[\"nodes\"][nid]\n",
" end\n",
"\n",
"\n",
" E = 90.0e6\n",
" nu = 0.3\n",
" mu = E/(2*(1+nu))\n",
" la = E*nu/((1+nu)*(1-2*nu))\n",
" #la = 2*la*mu/(la + 2*mu)\n",
" attributes = Dict()\n",
" el = JuliaFEM.Element(elid, node_ids, basis, dbasis, integration_points, attributes)\n",
" el.attributes[\"coordinates\"] = copy(coordinates)\n",
" el.attributes[\"lambda\"] = la\n",
" el.attributes[\"mu\"] = mu\n",
" el.attributes[\"displacement\"] = zeros(3, 4)\n",
" push!(elements, el)\n",
" end\n",
"\n",
" # create \"dofmap\" so that we know how to assemble global stiffness matrix\n",
" dofmap = create_ldof2gdofmap(elements, \"displacement\")\n",
"\n",
" # Boundary conditions\n",
"\n",
" # dirichlet bc, set dx=dy=dz for all nodes in set SUPPORT\n",
" bc_support = BC(Int64[], Float64[])\n",
" for nid in model[\"nsets\"][\"SUPPORT\"]\n",
" for i=1:3\n",
" push!(bc_support.dofs, dofmap[nid][i])\n",
" push!(bc_support.values, 0.0)\n",
" end\n",
" end\n",
"\n",
" # force boundary condition, put -1 to 2nd dof for each node in set LOAD\n",
" bc_load = BC(Int64[], Float64[])\n",
" for nid in model[\"nsets\"][\"LOAD\"]\n",
" push!(bc_load.dofs, dofmap[nid][3])\n",
" push!(bc_load.values, -1500000.0)\n",
" end\n",
"\n",
" #solve!(elements, [bc1], [bc2]; max_iterations=7)\n",
" neumann_bcs = [bc_load]\n",
" dirichlet_bcs = [bc_support]\n",
" # ndofs = dimension of unknown field in nodes\n",
" solve!(elements, dofmap, neumann_bcs, dirichlet_bcs; ndofs=3, max_iterations=10)\n",
"\n",
" # Let's pick maximum absolute displacement in y direction\n",
" maxdisp = 0.0\n",
" for el in elements\n",
" eldisp = el.attributes[\"displacement\"]\n",
" eldispy = eldisp[2,:]\n",
" maxeldisp = maximum(abs(eldispy))\n",
" if maxeldisp > maxdisp\n",
" maxdisp = maxeldisp\n",
" end\n",
" end\n",
" Logging.info(\"Maximum absolute displacement in y direction: $maxdisp\")\n",
" return model, elements, dofmap\n",
"end\n",
"\n",
"model, elements, dofmap = solve_3d_model();"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"xdoc, xmodel = JuliaFEM.xdmf.xdmf_new_model()\n",
"temporal_collection = JuliaFEM.xdmf.xdmf_new_temporal_collection(xmodel)\n",
"grid = JuliaFEM.xdmf.xdmf_new_grid(temporal_collection; time=0)\n",
"\n",
"nnodes = length(model[\"nodes\"])\n",
"Logging.info(\"Number of nodes in model: $nnodes\")\n",
"node_ids = Int64[]\n",
"for nid in keys(model[\"nodes\"])\n",
" push!(node_ids, nid)\n",
"end\n",
"sort!(node_ids)\n",
"X = zeros(3, nnodes)\n",
"for (i, nid) in enumerate(node_ids)\n",
" X[:,i] = model[\"nodes\"][nid]\n",
"end\n",
"\n",
"nelements = length(model[\"elements\"])\n",
"Logging.info(\"Number of elements in model: $nelements\")\n",
"elmap = zeros(Int64, 5, nelements)\n",
"elmap[1,:] = 0x006 # for tet4\n",
"for (i, elid) in enumerate(keys(model[\"elements\"]))\n",
" elmap[2:end, i] = model[\"elements\"][elid]\n",
"end\n",
"\n",
"xdmf_new_mesh(grid, X, elmap)\n",
"\n",
"nodaldisp = Dict()\n",
"for el in elements\n",
" for (i, nid) in enumerate(el.node_ids)\n",
" nodaldisp[nid] = el.attributes[\"displacement\"][:, i]\n",
" end\n",
"end\n",
"\n",
"u = zeros(3, nnodes)\n",
"for (i, nid) in enumerate(node_ids)\n",
" u[:,i] = nodaldisp[nid]\n",
"end\n",
"\n",
"JuliaFEM.xdmf.xdmf_new_field(grid, \"Displacement\", \"nodes\", u)\n",
"\n",
"JuliaFEM.xdmf.xdmf_save_model(xdoc, \"/tmp/piston.xmf\")\n"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"PyObject <IPython.core.display.Image object>"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"d.Image(\"/tmp/piston.png\")"
]
2015-08-27 08:18:20 +03:00
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"using ForwardDiff"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"f(x::Vector) = sum(sin, x) + prod(tan, x) * sum(sqrt, x);"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Float64,1}:\n",
" 0.903617\n",
" 0.97582 \n",
" 0.36872 \n",
" 0.233261\n",
" 0.213665"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = rand(5)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"2.5477827220775753"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(x)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Float64,1}:\n",
" 0.906762\n",
" 0.860405\n",
" 1.35153 \n",
" 1.59159 \n",
" 1.64713 "
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g = ForwardDiff.gradient(f);\n",
"g(x)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"Function"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(g)"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "LoadError",
"evalue": "LoadError: MethodError: `grad` has no method matching grad(::Function)\nwhile loading In[56], in expression starting on line 1",
"output_type": "error",
"traceback": [
"LoadError: MethodError: `grad` has no method matching grad(::Function)\nwhile loading In[56], in expression starting on line 1",
""
]
}
],
"source": [
"j = ForwardDiff.jacobian(g)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
2015-06-25 00:47:03 +03:00
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 0.4.0-dev",
"language": "julia",
"name": "julia-0.4"
},
"language_info": {
"name": "julia",
"version": "0.4.0"
}
},
"nbformat": 4,
"nbformat_minor": 0
}