exs_spring

Purpose:

Show the basic steps in a finite element calculation.

Description:

The general procedure in linear finite element calculations is carried out for a simple structure. The steps are:

  • Define the model

  • Generate element matrices

  • Assemble element matrices into the global system of equations

  • Solve the global system of equations

  • Evaluate element forces

Consider the system of three linear elastic springs, and the corresponding finite element model. The system of springs is fixed in its ends and loaded by a single load \(F=100 N\) and a stiffness \(k=1500 N/m\)

_images/exs1_1.svg
_images/exs1_2.svg
Example:

The computation is initialized by importing CALFEM and NumPy, then defining the topology matrix edof containing 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],                 # element 1 between nodes 1 and 2
    [2, 3],                 # element 2 between nodes 2 and 3
    [2, 3]                  # element 3 between nodes 2 and 3
])

The global stiffness matrix K (3×3) of zeros:

K = np.zeros((3, 3))        # empty global stiffness matrix
f = np.zeros((3, 1))        # empty global load vector

And the load vector f (3×1) with the load \(F=100\) at DOF 2:

f[1] = 100.0                # (N), f[1] corresponds to dof 2

Element stiffness matrices are generated by the function cfc.spring1e. The element property ep for the springs contains the spring stiffnesses \(k\) and \(2k\) respectively, where \(k=1500\):

k = 1500.                   # (N/m)
ep1 = 2.*k                  # spring stiffness, element 1
ep2 = k                     # spring stiffness, element 2
ep3 = 2.*k                  # spring stiffness, element 3
Ke1 = cfc.spring1e(ep1)     # element stiffness matrix, element 1
Ke2 = cfc.spring1e(ep2)     # element stiffness matrix, element 2
Ke3 = cfc.spring1e(ep3)     # element stiffness matrix, element 3

cfu.disp_h2("Ke1")
cfu.disp_array(Ke1, tablefmt='plain')
cfu.disp_h2("Ke2")
cfu.disp_array(Ke2, tablefmt='plain')
cfu.disp_h2("Ke3")
cfu.disp_array(Ke3, tablefmt='plain')

The element stiffness matrices are assembled into the global stiffness matrix K according to the topology:

cfc.assem(edof[0, :], K, Ke1)   # assemble element stiffness matrix 1
cfc.assem(edof[1, :], K, Ke2)   # assemble element stiffness matrix 2
cfc.assem(edof[2, :], K, Ke3)   # assemble element stiffness matrix 3

cfu.disp_h2("Stiffness matrix K (N/m):")
cfu.disp_array(K, tablefmt='plain')

The global system of equations is solved considering the boundary conditions. DOFs 1 and 3 are fixed (value 0):

bc_dofs = np.array([1, 3])       # dofs with prescribed displacment (0)
bc_vals = np.array([0.0, 0.0])   # prescribed displacments

a, r = cfc.solveq(K, f, bc_dofs, bc_vals)

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

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

Element forces are evaluated from the element displacements. These are obtained from the global displacements a using the function cfc.extract_ed and the spring forces are evaluated using the function cfc.spring1s:

ed1 = cfc.extract_ed(edof[0, :], a) # Nodal displacements, element 1
ed2 = cfc.extract_ed(edof[1, :], a) # Nodal displacements, element 2
ed3 = cfc.extract_ed(edof[2, :], a) # Nodal displacements, element 3

es1 = cfc.spring1s(ep1, ed1)        # Element force, element 1
es2 = cfc.spring1s(ep2, ed2)        # Element force, element 2
es3 = cfc.spring1s(ep3, ed3)        # Element force, element 3

cfu.disp_h2("Element forces (N):")
print("N1 = "+str(es1))
print("N2 = "+str(es2))
print("N3 = "+str(es3))