Source code for fe.beam2d

#
##
##  SPDX-FileCopyrightText: © 2007-2024 Benedict Verhegghe <bverheg@gmail.com>
##  SPDX-License-Identifier: GPL-3.0-or-later
##
##  This file is part of pyFormex 3.5  (Thu Feb  8 19:11:13 CET 2024)
##  pyFormex is a tool for generating, manipulating and transforming 3D
##  geometrical models by sequences of mathematical operations.
##  Home page: https://pyformex.org
##  Project page: https://savannah.nongnu.org/projects/pyformex/
##  Development: https://gitlab.com/bverheg/pyformex
##  Distributed under the GNU General Public License version 3 or later.
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""beam2d: A 2d beam finite element

"""
import numpy as np

class Beam2d:

    @staticmethod
    def mass(rho, A, l):
        l = float(l)
        l2 = l*l
        M = np.array([
            [ 156  , 22*l ,  54  , -13*l  ],   # noqa: 201,203
            [  22*l,  4*l2,  13*l,  -3*l2 ],   # noqa: 201,203
            [  54  , 13*l , 156  , -22*l  ],   # noqa: 201,203
            [ -13*l, -3*l2, -22*l,   4*l2 ]])  # noqa: 201,203
        M *= rho * A * l / 420
        return M

    @staticmethod
    def stiff(E, I, l):
        l = float(l)
        EIl = E*I/l
        b4 = 2 * EIl
        b3 = 2 * b4
        b2 = 3 * b4 / l
        b1 = 2 * b2 / l
        K = np.array([
            [  b1,  b2, -b1,  b2 ],    # noqa: 201,203
            [  b2,  b3, -b2,  b4 ],    # noqa: 201,203
            [ -b1, -b2,  b1, -b2 ],    # noqa: 201,203
            [  b2,  b4, -b2,  b3 ]])   # noqa: 201,203
        return K

# units are N, m, kg, s

class steel():
    E = 210.e9

class IPE100():
    rho = 8.26    # kg/m
    A = 1032.e-6
    I = 171.e-12


[docs]def cantilever_frequencies(rho, A, l, E, I): """First 6 eigenfrequencies of cantilever beam These are high precision results from analytical formulas. """ c = np.sqrt(E*I/(rho*A)) / (l*l) coeffs = np.array([ 1.875104069, 4.694091133, 7.854757438, 10.99554073, 14.13716839, 17.27875953]) return c * coeffs**2 / 2 / np.pi
[docs]def assemble(Ke, Me, ne): """Assemble beam of ne identical elements Ke, Me""" n = 2*(ne+1) K = np.zeros((n, n)) M = np.zeros((n, n)) for ie in range(ne): i = 2*ie K[i:i+4, i:i+4] += Ke M[i:i+4, i:i+4] += Me return K, M
[docs]def createBeam(lt, nel, addbc=True): """Create stiffness and mass matrices of a simple beam. lt: length of the beam (m) nel: number of element to use along the beam length addbc: if True, add cantilever boundary conditions """ # element length l = lt / nel # create element stiffness and mass matrix Ke = Beam2d.stiff(steel.E, IPE100.I, l) Me = Beam2d.mass(IPE100.rho, IPE100.A, l) # assemble the global stiffness and mass matrix K, M = assemble(Ke, Me, nel) if addbc: # Impose cantilever boundary conditions # This is done by adding a very stiff translational # and rotational spring to the first node: VERY_STIFF = 1.e4 K[0, 0] *= (1.+VERY_STIFF) K[1, 1] *= (1.+VERY_STIFF) return K, M
# End