◼ written by Hakan Tanriover 2-D BEAM FORMULATION FROM SECTION 7.2 of "Non-Linear Finite Element Analysis of Solids and Structures" by M.A. Crisfield. Cantilever beam subjected to end moment: Elasticity modulus: elas Crossection area: area Moment of Inertia: Imom Radius of gyration: rg In[1]:= elas = 2; area = 1; Imom = 1; rg = 1; number of nodes: nnodes number of nodes in an element: nelnode number of elements: nelem nodal degrees of freedom: ndof element degrees of freedom: eldof total degrees of freedom: totdof node numbers for elements: elemnodes={left,right} In[2]:= nelem = 10 In[3]:= nnodes = nelem + 1 In[4]:= nelnode = 2 In[5]:= ndof = 3 In[6]:= eldof = ndof * nelnode In[7]:= totdof = ndof * nnodes In[8]:= beamlength = 1 In[9]:= Do[elemnodes[i] = {i, i + 1}, {i, 1, nelem}] initial coordinates of the nodes in the x and z direction: In[10]:= Do[coordx[i] = (i - 1) * (beamlength / nelem) , {i, 1, nnodes}] In[11]:= Do[coordz[i] = 0.0, {i, 1, nnodes}] In[12]:= In[14]:= In[15]:= Do[ncoordx[i] = coordx[i], {i, 1, nnodes}]; Do[ncoordz[i] = coordz[i], {i, 1, nnodes}]; initgeodat = Table[{coordx[i], coordz[i]}, {i, nnodes}] ListPlot[initgeodat, Frame → True, PlotRange → {{-0.25`, 1.25`}, {-0.25`, 0.5`}}, Joined → True, PlotStyle → {Thickness[0.012`], Dashing[{0.02`}]}] number of load steps: nst In[16]:= In[17]:= nst = 40 Do[ "_____step load: df"; 2 largerotbeam_2d.nb df = 4 * Pi / 40; "_____External Force"; Do[exf[i] = 0., {i, 1, totdof}]; exf[totdof] = st * df; exforcevec = Array[exf, totdof]; Print["LOAD STEP:", st]; Do[ "_____tangent stiffness for elements"; Do[ "----node numbers of i and j"; nni = elemnodes[ne][[1]]; nnj = elemnodes[ne][[2]]; "-------length of element"; x21 = coordx[nnj] - coordx[nni]; z21 = coordz[nnj] - coordz[nni]; vecx21 = {x21, z21}; oldlengthel = Sqrt[vecx21.vecx21]; "check for different geometries"; beta0 = ArcSin[z21 / oldlengthel]; "----------let initial values be zero"; If[it ⩵ 1 && st ⩵ 1, u21[ne] = 0; w21[ne] = 0; teta1[ne] = 0.; teta2[ne] = 0.;, u21[ne] = u21[ne] + deltapvec[[nnj * ndof - 2]] - deltapvec[[nni * ndof - 2]]; w21[ne] = w21[ne] + deltapvec[[nnj * ndof - 1]] - deltapvec[[nni * ndof - 1]]; teta1[ne] = teta1[ne] + deltapvec[[nni * ndof]]; teta2[ne] = teta2[ne] + deltapvec[[nnj * ndof]]; ]; d21 = {u21[ne], w21[ne]}; nvecx21 = vecx21 + d21; newlengthel = Sqrt[nvecx21.nvecx21]; cosalpha = vecx21.(vecx21 + d21) / (newlengthel * oldlengthel); sinalpha = (x21 * w21[ne] - z21 * u21[ne]) / (newlengthel * oldlengthel); If[(sinalpha ≥ 0 && cosalpha ≥ 0), largerotbeam_2d.nb alpha = ArcSin[sinalpha]; Goto[alphas]; ]; If[(sinalpha ≤ 0 && cosalpha ≥ 0), alpha = 2 * Pi + ArcSin[sinalpha]; Goto[alphas]; "check!!!"; ]; If[(sinalpha ≥ 0 && cosalpha ≤ 0), alpha = ArcCos[cosalpha]; Goto[alphas]; ]; If[(sinalpha ≤ 0 && cosalpha ≤ 0), alpha = 2 * Pi - ArcCos[cosalpha]; Goto[alphas]; "check!!!"; ]; Label[alphas]; "-------local nodal rotations at node 1 and 2"; tetaloc1 = teta1[ne] - alpha - beta0; tetaloc2 = teta2[ne] - alpha - beta0; "--------Local axial extension:uloc"; uloc = (2 / (newlengthel + oldlengthel)) * ((vecx21 + (d21 / 2)).d21); nx21 = x21 + u21[ne]; nz21 = z21 + w21[ne]; cbeta = nx21 / newlengthel; sbeta = nz21 / newlengthel; r = {-cbeta, -sbeta, 0, cbeta, sbeta, 0}; z = {sbeta, -cbeta, 0, -sbeta, cbeta, 0}; Bmat = {{-cbeta, -sbeta, 0, cbeta, sbeta, 0}, {-sbeta / newlengthel, cbeta / newlengthel, 1, sbeta / newlengthel, -cbeta / newlengthel, 0}, {-sbeta / newlengthel, cbeta / newlengthel, 0, sbeta / newlengthel, -cbeta / newlengthel, 1}}; Cl = (elas * area / oldlengthel) * {{1, 0, 0}, {0, 4 * rg ^2, 2 * rg ^2}, {0, 2 * rg ^2, 4 * rg ^2}}; TBmat = Transpose[Bmat]; "--------First part of tangent stiffness matrix"; 3 4 largerotbeam_2d.nb kt1 = TBmat.Cl.Bmat; "---------Axial force:Nax"; Nax = (elas * area / oldlengthel) * uloc; "--------Moments"; mom1 = (2 * elas * Imom / oldlengthel) * (2 * tetaloc1 + tetaloc2); mom2 = (2 * elas * Imom / oldlengthel) * (tetaloc1 + 2 * tetaloc2); "Local Internal force vector: qiloc"; qiloc = {Nax, mom1, mom2}; "Element Global Internal force vector:qi"; qie[ne] = TBmat.qiloc; "--------z vector as matrix form"; zm = {{sbeta}, {-cbeta}, {0}, {-sbeta}, {cbeta}, {0}}; tzm = Transpose[zm]; "-------second part of stiffness"; ktb1 = (Nax / newlengthel) * (zm.tzm); "--------r vector as matrix"; rm = {{-cbeta}, {-sbeta}, {0}, {cbeta}, {sbeta}, {0}}; trm = Transpose[rm]; "-------last part of stiffness"; ktb23 = ((mom1 + mom2) / newlengthel^2) * (rm.tzm + zm.trm); "------element tangent stiffness matrix"; kte[ne] = kt1 + ktb1 + ktb23; "___________END OF ELEMENT LOOP"; , {ne, 1, nelem}]; "_____Assembling Global tangent stiffness matrix"; largerotbeam_2d.nb Do[kt[i, j] = 0., {i, 1, totdof}, {j, 1, totdof}]; For[e = 1, e ≤ nelem, e++, Do[ kt[i + (e - 1) * ndof, j + (e - 1) * ndof] = kte[e][[i, j]] + kt[i + (e - 1) * ndof, j + (e - 1) * ndof]; , {i, 1, eldof}, {j, 1, eldof}]; ]; "_____Apply BC"; Do[kt[i, i] = 1, {i, 1, 3}]; Do[kt[1, i] = 0., {i, 2, totdof}]; Do[kt[2, i] = 0., {i, 3, totdof}]; Do[kt[3, i] = 0., {i, 4, totdof}]; Do[kt[i, 1] = 0., {i, 2, totdof}]; Do[kt[i, 2] = 0., {i, 3, totdof}]; Do[kt[i, 3] = 0., {i, 4, totdof}]; ktm = Table[kt[i, j], {i, totdof}, {j, totdof}]; iktm = Inverse[ktm]; "_____Assembly of Global Internal Force Vector"; Do[qi[i] = 0., {i, 1, totdof}]; For[e = 1, e ≤ nelem, e++, Do[ qi[i + (e - 1) * ndof] = qie[e][[i]] + qi[i + (e - 1) * ndof] , {i, 1, eldof}]; ]; "_____Internal Force Vector"; "_____apply bc to force vector"; Do[qi[i] = 0., {i, 1, 3}]; qivec = Array[qi, totdof]; "_____Residual vector (qi-qe):qresvec"; qresvec = qivec - exforcevec; "_____Convergence Check"; Normqresvec = Sqrt[qresvec.qresvec]; Normexforcevec = Sqrt[ exforcevec. exforcevec]; 5 6 largerotbeam_2d.nb eps = 1 / 1000; If[Normqresvec < (eps * Normexforcevec), Print["ITERATION:", it, "___", "Normqresvec:", Normqresvec]; Break[]]; "_____Displacement vector:deltapvec"; deltapvec = -iktm.qresvec; "______New coordinates"; Do[ncoordx[i] = ncoordx[i] + deltapvec[[i * ndof - 2]], {i, 1, nnodes}]; Do[ncoordz[i] = ncoordz[i] + deltapvec[[i * ndof - 1]], {i, 1, nnodes}]; Label[end]; , {it, 1, 20}]; geodat[st] = Table[{ncoordx[i], ncoordz[i]}, {i, nnodes}]; , {st, 1, nst}] In[19]:= ListPlot[Array[geodat, nst], Frame → True, PlotRange → {{-0.3, 1.2}, {-0.3, 1.2}}, PlotJoined → True, PlotStyle → {Dashing[{.02}]}, AspectRatio → 1] 1.2 1.0 0.8 0.6 Out[19]= 0.4 0.2 0.0 -0.2 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2