exs_bar2_l

Purpose:

Analysis of a plane truss.

Description:

Consider a plane truss, loaded by a single force \(P=0.5\) MN.

_images/exs4_1.svg

The corresponding finite element model consists of ten elements and twelve degrees of freedom.

_images/exs4_2.svg

Material properties:

  • Cross-sectional area: \(A=25.0 \times 10^{-4}\)

  • Young’s modulus: \(E=2.10 \times 10^{5}\) MPa

Example:

The computation is initialized by importing CALFEM and NumPy. The element topology matrix contains only the degrees of freedom for each element:

import numpy as np
import calfem.core as cfc
import calfem.utils as cfu

edof = np.array([
    [1, 2, 5, 6],
    [3, 4, 7, 8],
    [5, 6, 9, 10],
    [7, 8, 11, 12],
    [7, 8, 5, 6],
    [11, 12, 9, 10],
    [3, 4, 5, 6],
    [7, 8, 9, 10],
    [1, 2, 7, 8],
    [5, 6, 11, 12],
])

The global stiffness matrix K and load vector f are initialized. The load \(P=0.5\) MN is divided into x and y components:

K = np.zeros([12, 12])
f = np.zeros([12, 1])
f[10] = 0.5e6 * np.sin(np.pi / 6)
f[11] = -0.5e6 * np.cos(np.pi / 6)

The material and geometric properties are defined, along with element coordinate matrices:

A = 25.0e-4
E = 2.1e11
ep = [E, A]

ex = np.array([
    [0.0, 2.0],
    [0.0, 2.0],
    [2.0, 4.0],
    [2.0, 4.0],
    [2.0, 2.0],
    [4.0, 4.0],
    [0.0, 2.0],
    [2.0, 4.0],
    [0.0, 2.0],
    [2.0, 4.0],
])

ey = np.array([
    [2.0, 2.0],
    [0.0, 0.0],
    [2.0, 2.0],
    [0.0, 0.0],
    [0.0, 2.0],
    [0.0, 2.0],
    [0.0, 2.0],
    [0.0, 2.0],
    [2.0, 0.0],
    [2.0, 0.0],
])

The element stiffness matrices are computed and assembled in a loop:

for elx, ely, eltopo in zip(ex, ey, edof):
    Ke = cfc.bar2e(elx, ely, ep)
    cfc.assem(eltopo, K, Ke)

The system of equations is solved by specifying boundary conditions and using solveq():

bc_dofs = np.array([1, 2, 3, 4])
bc_vals = np.array([0.0, 0.0, 0.0, 0.0])
a, r = cfc.solveq(K, f, bc_dofs, bc_vals)

cfu.disp_h2("Displacements a:")
cfu.disp_array(a, tablefmt='plain')

cfu.disp_h2("Reaction forces r:")
cfu.disp_array(r, tablefmt='plain')

The displacement at the point of loading is \(-1.7 \times 10^{-3}\) m in the x-direction and \(-11.3 \times 10^{-3}\) m in the y-direction. At the upper support the horizontal force is \(-0.866\) MN and the vertical \(0.240\) MN. At the lower support the forces are \(0.616\) MN and \(0.193\) MN, respectively.

Normal forces are evaluated from element displacements. These are obtained from the global displacements using extract_ed() and the forces are calculated using bar2s():

ed = cfc.extract_ed(edof, a)
N = np.zeros([edof.shape[0]])

cfu.disp_h2("Element forces:")

i = 0
for elx, ely, eld in zip(ex, ey, ed):
    es = cfc.bar2s(elx, ely, ep, eld)
    N[i] = es[0][0]
    print("N%d = %g" % (i + 1, N[i]))
    i += 1

The largest normal force \(N=0.626\) MN is obtained in element 1 and is equivalent to a normal stress \(\sigma=250\) MPa.

To reduce the quantity of input data, the element coordinate matrices ex and ey can alternatively be created from a global coordinate matrix coord and a global topology matrix dof using coord_extract():

coord = np.array([
    [0, 2],
    [0, 0],
    [2, 2],
    [2, 0],
    [4, 2],
    [4, 0]
])

dof = np.array([
    [1, 2],
    [3, 4],
    [5, 6],
    [7, 8],
    [9, 10],
    [11, 12]
])

ex, ey = cfc.coord_extract(edof, coord, dof, 2)