diff --git a/notebooks/2015-06-25-elasticity-solver-example.ipynb b/notebooks/2015-06-25-elasticity-solver-example.ipynb index e509b7b..b1b8047 100644 --- a/notebooks/2015-06-25-elasticity-solver-example.ipynb +++ b/notebooks/2015-06-25-elasticity-solver-example.ipynb @@ -4,14 +4,178 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Elasticity solver examples\n", + "# Solving elasticity problems using JuliaFEM\n", "\n", - "Author(s): Jukka Aho " + "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." + ] + }, + { + "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", - "execution_count": 1, + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Logger(root,DEBUG,Pipe(open, 0 bytes waiting),root)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "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", + "*Design principle 5*: we use 4 space indentation like in Python.\n", + "\n", + "First we write some elementary functions to calculate stiffness matrix. Our development direction is \"bottom-up\" to interface." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "calc_local_matrices! (generic function with 1 method)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "Calculate local tangent stiffness matrix and residual force vector\n", + "R = T - F for elasticity problem.\n", + "\n", + "Parameters\n", + "----------\n", + "X : Element coordinates\n", + "u : Displacement field\n", + "R : Residual force vector\n", + "K : Tangent stiffness matrix\n", + "basis : Basis functions\n", + "dbasis : Derivative of basis functions\n", + "lambda : Material parameter\n", + "mu : Material parameter\n", + "ipoints : integration points\n", + "iweights : integration weights\n", + "\n", + "Returns\n", + "-------\n", + "None\n", + "\n", + "Notes\n", + "-----\n", + "If material parameters are given in list, they are interpolated to gauss\n", + "points using shape functions.\n", + "\n", + "Examples\n", + "--------\n", + "\n", + "\"\"\"\n", + "function calc_local_matrices!(X, u, R, K, basis, dbasis, lambda_, mu_, ipoints, iweights)\n", + " dim, nnodes = size(X)\n", + " I = eye(dim)\n", + " R[:,:] = 0.0\n", + " K[:,:] = 0.0\n", + "\n", + " dF = zeros(dim, dim)\n", + "\n", + " for m = 1:length(iweights)\n", + " w = iweights[m]\n", + " xi = ipoints[m, :]\n", + " # calculate material parameters\n", + " lambda = typeof(lambda_) == Float64 ? lambda_ : dot(lambda_, basis(xi))\n", + " mu = typeof(mu_) == Float64 ? mu_ : dot(mu_, basis(xi))\n", + " Jt = X*dbasis(xi)\n", + " detJ = det(Jt)\n", + " dbasisdX = dbasis(xi)*inv(Jt)\n", + "\n", + " gradu = u*dbasisdX\n", + " F = I + gradu # Deformation gradient\n", + " E = 1/2*(gradu' + gradu + gradu'*gradu) # Green-Lagrange strain tensor\n", + " S = lambda*trace(E)*I + 2*mu*E # PK2 stress tensor\n", + " P = F*S # PK1 stress tensor\n", + "\n", + " R[:,:] += w*P*dbasisdX'*detJ\n", + "\n", + " for p = 1:nnodes\n", + " for i = 1:dim\n", + " dF[:,:] = 0.0\n", + " dF[i,:] = dbasisdX[p,:]\n", + " dE = 1/2*(F'*dF + dF'*F)\n", + " dS = lambda*trace(dE)*I + 2*mu*dE\n", + " dP = dF*S + F*dS\n", + " for q = 1:nnodes\n", + " for j = 1:dim\n", + " K[dim*(p-1)+i,dim*(q-1)+j] += w*(dP[j,:]*dbasisdX[q,:]')[1]*detJ\n", + " end\n", + " end\n", + " end\n", + " end\n", + "\n", + " end\n", + "end" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Design principle 6*: we test our code. We use FactCheck in testing." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "using FactCheck" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "metadata": { "collapsed": false }, @@ -20,65 +184,161 @@ "name": "stdout", "output_type": "stream", "text": [ - "Docile: upgrading cache to 0.0.2.\n" + "test solve one element model\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "\n", - "WARNING: deprecated syntax \"{a=>b, ...}\" at /Users/jukka/.julia/v0.4/JuliaFEM/src/abaqus_reader.jl:11.\n", - "Use \"Dict{Any,Any}(a=>b, ...)\" instead.\n", - "\n", - "WARNING: deprecated syntax \"{a=>b, ...}\" at /Users/jukka/.julia/v0.4/JuliaFEM/src/abaqus_reader.jl:32.\n", - "Use \"Dict{Any,Any}(a=>b, ...)\" instead.\n", - "Warning: requiring \"JuliaFEM\" did not define a corresponding module.\n", - "Warning: requiring \"JuliaFEM\" did not define a corresponding module.\n", - "Warning: requiring \"JuliaFEM\" did not define a corresponding module.\n" + "28-Jul 22:15:35:DEBUG:root:Converged in 6 iterations.\n", + "28-Jul 22:15:35:DEBUG:root:solution vector: \n", + " [0.0 -0.39914506095474317 -0.07228582695592449 0.0\n", + " 0.0 -2.1779892317073504 -2.222244754401764 0.0]\n", + "28-Jul 22:15:35:DEBUG:root:norm of u: 3.1292483947150043\n", + "28-Jul 22:15:35:DEBUG:root:Converged in 6 iterations.\n", + "28-Jul 22:15:35:DEBUG:root:solution vector: \n", + " [0.0 0.7433248532717793 1.0485210147234858 0.0\n", + " 0.0 -2.085766534304891 -1.9606633242166027 0.0]\n", + "28-Jul 22:15:35:DEBUG:root:norm of u: 3.129248394715006\n" ] }, { "data": { "text/plain": [ - "Logger(root,DEBUG,Pipe(open, 0 bytes waiting),root)" + "delayed_handler (generic function with 4 methods)" ] }, - "execution_count": 1, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# These are internal module functions and not intended to use like this.\n", - "using JuliaFEM.elasticity_solver\n", - "using JuliaFEM.xdmf\n", - "using JuliaFEM.abaqus_reader\n", - "using Logging\n", - "Logging.configure(level=DEBUG)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "using LightXML" + "facts(\"test solve one element model\") do\n", + " X = [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]'\n", + " F = [0 0; 0 0; 0 -2; 0 0]'\n", + "\n", + " # Material properties\n", + " E = 90\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", + "\n", + " u = zeros(2, 4)\n", + " du = zeros(2, 4)\n", + " R = zeros(2, 4)\n", + " K = zeros(8, 8)\n", + "\n", + " basis(xi) = [\n", + " (1-xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1+xi[2])/4\n", + " (1-xi[1])*(1+xi[2])/4]\n", + "\n", + " dbasis(xi) = [-(1-xi[2])/4.0 -(1-xi[1])/4.0\n", + " (1-xi[2])/4.0 -(1+xi[1])/4.0\n", + " (1+xi[2])/4.0 (1+xi[1])/4.0\n", + " -(1+xi[2])/4.0 (1-xi[1])/4.0]\n", + "\n", + " ipoints = 1/sqrt(3)*[-1 -1; 1 -1; 1 1; -1 1]\n", + " iweights = [1, 1, 1, 1]\n", + " free_dofs = [3, 4, 5, 6]\n", + "\n", + " for i=1:10\n", + " calc_local_matrices!(X, u, R, K, basis, dbasis, la, mu, ipoints, iweights)\n", + " du[free_dofs] = K[free_dofs, free_dofs] \\ -(R - F)[free_dofs]\n", + " u += du\n", + " 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", + " Logging.debug(\"solution vector: \\n $u\")\n", + " @fact u[2, 3] => roughly(-2.222244754401764)\n", + " norm1 = norm(u)\n", + " Logging.debug(\"norm of u: $(norm(u))\")\n", + "\n", + " # We rotate model a bit and make sure that L2 norm is same\n", + " phi = 30/180*pi\n", + " rmat = [\n", + " cos(phi) -sin(phi)\n", + " sin(phi) cos(phi)]\n", + " X = rmat*X\n", + " F = rmat*F\n", + " u = zeros(2, 4)\n", + " for i=1:10\n", + " calc_local_matrices!(X, u, R, K, basis, dbasis, la, mu, ipoints, iweights)\n", + " du[free_dofs] = K[free_dofs, free_dofs] \\ -(R - F)[free_dofs]\n", + " u += du\n", + " if norm(du) < 1.0e-9\n", + " Logging.debug(\"Converged in $i iterations.\")\n", + " break\n", + " end\n", + " end\n", + " Logging.debug(\"solution vector: \\n $u\")\n", + " Logging.debug(\"norm of u: $(norm(u))\")\n", + " @fact norm(u) => roughly(norm1) \n", + "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## 2d beam with linear elements" + "One element solutions are not particularly interesting so next step is to create function that assembles global matrix from local matrices." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 facts verified.\n" + ] + } + ], + "source": [ + "type Node\n", + " id :: Int\n", + " coordinates :: Array{Float64, 1}\n", + "end\n", + "\n", + "type Element\n", + " id :: Int\n", + " nodes :: Array{Node, 1}\n", + " attributes :: Dict{ASCIIString, Any}\n", + "end\n", + "\n", + "type FunctionSpace\n", + " family :: String\n", + " order :: Int\n", + "end\n", + "\n", + "type IntegrationScheme\n", + " points :: Array{Float64, 2}\n", + " weights :: Array{Float64, 1}\n", + "end\n", + "\n", + "type IJVMatrix\n", + " I :: Array{Int64, 1}\n", + " J :: Array{Int64, 1}\n", + " V :: Array{Float64, 1}\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": 105, "metadata": { "collapsed": false }, @@ -86,16 +346,131 @@ { "data": { "text/plain": [ - "Array{Float64,2}" + "Element2(1,[Node2(1,[1.0,2.0,3.0])],Dict(\"Young's modulus\"=>2.1e11,\"Poisson's ration\"=>0.3),\"Lagrange(1,2)\",\"FPG4\")" ] }, - "execution_count": 4, + "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "typeof(Float64[1 2; 2 3])" + "function get_shape_functions(fs::FunctionSpace)\n", + " if (fs.family == \"Lagrange\") & (fs.order == 1)\n", + " basis(xi) = [\n", + " (1-xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1+xi[2])/4\n", + " (1-xi[1])*(1+xi[2])/4]\n", + " dbasis(xi) = [-(1-xi[2])/4.0 -(1-xi[1])/4.0\n", + " (1-xi[2])/4.0 -(1+xi[1])/4.0\n", + " (1+xi[2])/4.0 (1+xi[1])/4.0\n", + " -(1+xi[2])/4.0 (1-xi[1])/4.0]\n", + " return basis, dbasis\n", + " end\n", + " throw(\"Unknown function space\")\n", + "end\n", + "\n", + "function get_integration_scheme(is::IntegrationScheme)\n", + " if is.\n", + "end\n", + "\n", + "function assemble!(IJV::IJVMatrix, element::Element, gdofs, fs::FunctionSpace, is::IntegrationScheme)\n", + " nnodes = length(element.nodes)\n", + " ndim = length(elements.nodes[1].coordinates)\n", + "\n", + " # Material properties\n", + " E = element.attributes[\"Young\"]\n", + " nu = element.attributes[\"Poisson\"]\n", + " mu = E/(2*(1+nu))\n", + " la = E*nu/((1+nu)*(1-2*nu))\n", + " la = 2*la*mu/(la + 2*mu)\n", + "\n", + " R = zeros(ndim, nnodes)\n", + " K = zeros(ndim*nnodes, ndim*nnodes)\n", + "\n", + " basis, dbasis = get_shape_functions(fs)\n", + "\n", + " calc_local_matrices!(X, u, R, K, basis, dbasis, la, mu, ipoints, iweights)\n", + "\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "IntegrationScheme(4x2 Array{Float64,2}:\n", + " -0.57735 -0.57735\n", + " 0.57735 -0.57735\n", + " 0.57735 0.57735\n", + " -0.57735 0.57735,[1.0,1.0,1.0,1.0])" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "is = IntegrationScheme(1/sqrt(3)*[-1 -1; 1 -1; 1 1; -1 1], [1, 1, 1, 1])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Node2(2,[3.0,2.0,3.0])" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "e2 = Element2(2, [n1], Dict(\"Young's modulus\" => 90.0e9, \"Poisson's ration\" => 0.3), \"Lagrange(1,2)\", \"FPG4\")\n", + "e2.nodes[1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "n1 = new_node()\n", + "set_node_id(n1, 1)\n", + "set_node_coords(n1, [0.0, 0.0])\n", + "\n", + "n2 = new_node()\n", + "set_node_id(n2, 2)\n", + "set_node_coords(n2, [10.0, 0.0])\n", + "\n", + "n3 = new_node()\n", + "set_node_id(n3, 3)\n", + "set_node_coords(n3, [10.0, 1.0])\n", + "\n", + "n4 = new_node()\n", + "set_node_id(n4, 4)\n", + "set_node_coords(n4, [0.0, 1.0])\n", + "\n", + "nodes = [n1, n2, n3, n4]\n", + "add_nodes(m, \"NALL\", nodes)" ] }, { @@ -126,125 +501,11 @@ } ], "source": [ - "\"\"\"\n", - "#### Parameters\n", - "X : Array{Float64, 2}\n", - " \n", - "\"\"\"\n", - "function solve_elasticity_increment!(X, u, du, elmap, nodalloads,\n", - " dirichletbc, lambda, mu, N, dNdchi, ipoints,\n", - " iweights)\n", - " if length(size(elmap)) == 1\n", - " # quick hack for just one element\n", - " elmap = elmap''\n", - " end\n", - " nelnodes, nelements = size(elmap)\n", - " dim, nnodes = size(u)\n", - " dofs = dim*nelnodes\n", - "\n", - " Imat = Int64[]\n", - " Jmat = Int64[]\n", - " Vmat = Float64[]\n", - " Ivec = Int64[]\n", - " Vvec = Float64[]\n", - "\n", - " # FIXME: different number of nodes/element\n", - " R = zeros(dim, nelnodes)\n", - " Kt = zeros(dofs, dofs)\n", - "\n", - " # this can be parallelized\n", - " for i in 1:nelements\n", - " eldofs = elmap[:,i]\n", - " calc_local_matrices!(X[:, eldofs], u[:, eldofs], R, Kt, N, dNdchi,\n", - " lambda[eldofs], mu[eldofs], ipoints, iweights)\n", - " assemble!(Kt, eldofs, Imat, Jmat, Vmat)\n", - " assemble!(R, eldofs, Ivec, Vvec)\n", - " end\n", - "\n", - " # add additional neumann boundary conditions to force vector\n", - " for (i, nodal_load) in enumerate(nodalloads)\n", - " if nodal_load == 0\n", - " continue\n", - " end\n", - " push!(Ivec, i)\n", - " push!(Vvec, -nodal_load)\n", - " end\n", - "\n", - " # Create sparse matrix and vector\n", - " A = sparse(Imat, Jmat, Vmat)\n", - " b = sparsevec(Ivec, Vvec)\n", - "\n", - " # Remove dirichlet boundary conditions\n", - " free_dofs = find(isnan(dirichletbc))\n", - " #Imat, Jmat, Vmat = eliminate_boundary_conditions(dirichletbc, Imat, Jmat, Vmat)\n", - " b = b[free_dofs]\n", - " A = A[free_dofs, free_dofs]\n", - "\n", - " # solution\n", - " du[free_dofs] = lufact(A) \\ -full(b)\n", - "end\n", - "\n", - "function one_elem_fixture()\n", - " X = [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]'\n", - " elmap = [1; 2; 3; 4]\n", - " nodalloads = [0 0; 0 0; 0 -2; 0 0]'\n", - " dirichletbc = [0 0; NaN NaN; NaN NaN; 0 0]'\n", - "\n", - " E = 90\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", - "\n", - " la = la*ones(1, 4)\n", - " mu = mu*ones(1, 4)\n", - " u = zeros(2, 4)\n", - " du = zeros(2, 4)\n", - "\n", - " N(xi) = [\n", - " (1-xi[1])*(1-xi[2])/4\n", - " (1+xi[1])*(1-xi[2])/4\n", - " (1+xi[1])*(1+xi[2])/4\n", - " (1-xi[1])*(1+xi[2])/4\n", - " ]\n", - "\n", - " dNdξ(ξ) = [-(1-ξ[2])/4.0 -(1-ξ[1])/4.0\n", - " (1-ξ[2])/4.0 -(1+ξ[1])/4.0\n", - " (1+ξ[2])/4.0 (1+ξ[1])/4.0\n", - " -(1+ξ[2])/4.0 (1-ξ[1])/4.0]\n", - "\n", - " ipoints = 1/sqrt(3)*[-1 -1; 1 -1; 1 1; -1 1]\n", - " iweights = [1 1 1 1]\n", - "\n", - " return (X, u, du, elmap, nodalloads, dirichletbc,\n", - " la, mu, N, dNdξ, ipoints, iweights)\n", - "end\n", - "\n", "#(X, u, du, elmap, nodalloads, dirichletbc,\n", "# la, mu, N, dNdξ, ipoints, iweights) = one_elem_fixture()\n", "function solve_one_element()\n", "\n", - " m = new_model()\n", - "\n", " # create nodes separately ...\n", - " n1 = new_node()\n", - " set_node_id(n1, 1)\n", - " set_node_coords(n1, [0.0, 0.0])\n", - "\n", - " n2 = new_node()\n", - " set_node_id(n2, 2)\n", - " set_node_coords(n2, [10.0, 0.0])\n", - " \n", - " n3 = new_node()\n", - " set_node_id(n3, 3)\n", - " set_node_coords(n3, [10.0, 1.0])\n", - "\n", - " n4 = new_node()\n", - " set_node_id(n4, 4)\n", - " set_node_coords(n4, [0.0, 1.0])\n", - "\n", - " nodes = [n1, n2, n3, n4]\n", - " add_nodes(m, \"NALL\", nodes)\n", "\n", " # .. or create somewhat simpler syntax\n", " # nodes = Dict(1 => [0.0, 0.0], 2 => [10.0, 0.0], 3 => [10.0, 1.0], 4 => [0.0, 1.0])\n", @@ -356,6 +617,109 @@ "u" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "\"\"\"\n", + "#### Parameters\n", + "X : Array{Float64, 2}\n", + " \n", + "\"\"\"\n", + "function solve_elasticity_increment!(X, u, du, elmap, nodalloads,\n", + " dirichletbc, lambda, mu, N, dNdchi, ipoints,\n", + " iweights)\n", + " if length(size(elmap)) == 1\n", + " # quick hack for just one element\n", + " elmap = elmap''\n", + " end\n", + " nelnodes, nelements = size(elmap)\n", + " dim, nnodes = size(u)\n", + " dofs = dim*nelnodes\n", + "\n", + " Imat = Int64[]\n", + " Jmat = Int64[]\n", + " Vmat = Float64[]\n", + " Ivec = Int64[]\n", + " Vvec = Float64[]\n", + "\n", + " # FIXME: different number of nodes/element\n", + " R = zeros(dim, nelnodes)\n", + " Kt = zeros(dofs, dofs)\n", + "\n", + " # this can be parallelized\n", + " for i in 1:nelements\n", + " eldofs = elmap[:,i]\n", + " calc_local_matrices!(X[:, eldofs], u[:, eldofs], R, Kt, N, dNdchi,\n", + " lambda[eldofs], mu[eldofs], ipoints, iweights)\n", + " assemble!(Kt, eldofs, Imat, Jmat, Vmat)\n", + " assemble!(R, eldofs, Ivec, Vvec)\n", + " end\n", + "\n", + " # add additional neumann boundary conditions to force vector\n", + " for (i, nodal_load) in enumerate(nodalloads)\n", + " if nodal_load == 0\n", + " continue\n", + " end\n", + " push!(Ivec, i)\n", + " push!(Vvec, -nodal_load)\n", + " end\n", + "\n", + " # Create sparse matrix and vector\n", + " A = sparse(Imat, Jmat, Vmat)\n", + " b = sparsevec(Ivec, Vvec)\n", + "\n", + " # Remove dirichlet boundary conditions\n", + " free_dofs = find(isnan(dirichletbc))\n", + " #Imat, Jmat, Vmat = eliminate_boundary_conditions(dirichletbc, Imat, Jmat, Vmat)\n", + " b = b[free_dofs]\n", + " A = A[free_dofs, free_dofs]\n", + "\n", + " # solution\n", + " du[free_dofs] = lufact(A) \\ -full(b)\n", + "end\n", + "\n", + "function one_elem_fixture()\n", + " X = [0.0 0.0; 10.0 0.0; 10.0 1.0; 0.0 1.0]'\n", + " elmap = [1; 2; 3; 4]\n", + " nodalloads = [0 0; 0 0; 0 -2; 0 0]'\n", + " dirichletbc = [0 0; NaN NaN; NaN NaN; 0 0]'\n", + "\n", + " E = 90\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", + "\n", + " la = la*ones(1, 4)\n", + " mu = mu*ones(1, 4)\n", + " u = zeros(2, 4)\n", + " du = zeros(2, 4)\n", + "\n", + " N(xi) = [\n", + " (1-xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1-xi[2])/4\n", + " (1+xi[1])*(1+xi[2])/4\n", + " (1-xi[1])*(1+xi[2])/4\n", + " ]\n", + "\n", + " dNdξ(ξ) = [-(1-ξ[2])/4.0 -(1-ξ[1])/4.0\n", + " (1-ξ[2])/4.0 -(1+ξ[1])/4.0\n", + " (1+ξ[2])/4.0 (1+ξ[1])/4.0\n", + " -(1+ξ[2])/4.0 (1-ξ[1])/4.0]\n", + "\n", + " ipoints = 1/sqrt(3)*[-1 -1; 1 -1; 1 1; -1 1]\n", + " iweights = [1 1 1 1]\n", + "\n", + " return (X, u, du, elmap, nodalloads, dirichletbc,\n", + " la, mu, N, dNdξ, ipoints, iweights)\n", + "end" + ] + }, { "cell_type": "code", "execution_count": 3, @@ -456,9 +820,7 @@ "outputs": [ { "data": { - "image/png": [ - "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" - ], + "image/png": "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", "text/plain": [ "PyObject " ]