Beispiel #1
0
class BAR2(ContinuumElement):
    """2-node, isoparametric element

    Notes
    -----
    Node and element face numbering

            0-------1
               [0]

    """
    ndi = 1
    nshr = 0
    name = "BAR2"
    num_node = 2
    num_coord = 1
    num_dof_per_node = 1
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord, self.num_node)
        args = (self.num_coord-1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
Beispiel #2
0
class TRIE3(ContinuumElement):
    """Element function for linear CST element defined in [1]

    Notes
    -----
    Node and element face numbering


            2
            |\
       [2]  |  \  [1]
            |    \
            0-----1
              [0]

    References
    ----------
    1. Taylor & Hughes (1981), p.49

    """
    ndi = 3
    nshr = 1
    name = "TRIE3"
    num_node = 3
    num_coord = 2
    num_dof_per_node = 2
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

    @staticmethod
    def b_matrix(shg, shgbar=None, **kwargs):
        """Assemble and return the B matrix"""
        B = zeros((4, 6))
        B[0, 0::2] = shg[0, :]
        B[1, 1::2] = shg[1, :]
        B[3, 0::2] = shg[1, :]
        B[3, 1::2] = shg[0, :]
        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords,
                                cls.thickness)
Beispiel #3
0
class QE4FI(ContinuumElement):
    """4-node, isoparametric, plane strain element.  Full integration

    Notes
    -----
    Node and element face numbering

               [2]
            3-------2
            |       |
       [3]  |       | [1]
            |       |
            0-------1
               [0]

    """
    ndi = 3
    nshr = 1
    name = "QE4FI"
    num_node = 4
    num_coord = 2
    num_dof_per_node = 2
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

    def b_matrix(self, shg, shgbar=None, **kwargs):
        """Assemble and return the B matrix"""
        B = zeros(
            (self.ndi + self.nshr, self.num_node * self.num_dof_per_node))
        B[0, 0::2] = shg[0, :]
        B[1, 1::2] = shg[1, :]
        B[3, 0::2] = shg[1, :]
        B[3, 1::2] = shg[0, :]
        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords,
                                cls.thickness)
Beispiel #4
0
class TET4(ContinuumElement):
    """Trilinear tet element"""
    ndi = 3
    nshr = 3
    name = "TET4"
    num_node = 4
    num_coord = 3
    num_dof_per_node = 3
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

    @staticmethod
    def b_matrix(shg, shgbar=None, **kwargs):
        B = zeros((6, 12))
        B[0, 0::3] = shg[0, :]
        B[1, 1::3] = shg[1, :]
        B[2, 2::3] = shg[2, :]

        B[3, 0::3] = shg[1, :]
        B[3, 1::3] = shg[0, :]

        B[4, 1::3] = shg[2, :]
        B[4, 2::3] = shg[1, :]

        B[5, 0::3] = shg[2, :]
        B[5, 2::3] = shg[0, :]

        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords)
Beispiel #5
0
class HEX8RI(ContinuumElement):
    """Trilinear hex element

    Notes
    -----
    Integration points in parentheses

          7---------------6
         /|(7)        (6)/|
        / |             / |
       /  |            /  |
      /   |           /   |
     / (4)|       (5)/    |
    4---------------5     |
    |     |         |     |
    |     3---------|-----2
    |    / (3)      | (2)/
    |   /           |   /
    |  /            |  /
    | /             | /
    |/ (0)       (1)|/
    0---------------1

    """
    ndi = 3
    nshr = 3
    name = "HEX8RI"
    num_node = 8
    num_coord = 3
    num_dof_per_node = 3
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord,
                                                 self.num_node,
                                                 reduced=True)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)

    def b_matrix(self, shg, shgbar=None, **kwargs):
        B = zeros((6, 24))
        B[0, 0::3] = shg[0, :]
        B[1, 1::3] = shg[1, :]
        B[2, 2::3] = shg[2, :]

        B[3, 0::3] = shg[1, :]
        B[3, 1::3] = shg[0, :]

        B[4, 1::3] = shg[2, :]
        B[4, 2::3] = shg[1, :]

        B[5, 0::3] = shg[2, :]
        B[5, 2::3] = shg[0, :]

        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords)
Beispiel #6
0
class QE8FI(ContinuumElement):
    """8-node, isoparametric, plane strain element

    Notes
    -----
    Node and element face numbering

               [2]
            3---6---2
            |       |
       [3]  7       5 [1]
            |       |
            0---4---1
               [0]

    """
    ndi = 3
    nshr = 1
    name = "QE8FI"
    num_node = 8
    num_coord = 2
    num_dof_per_node = 2
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord, self.num_node)
        args = (self.num_coord-1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

    def b_matrix(self, shg, shgbar=None, **kwargs):
        """Assemble and return the B matrix"""
        B = zeros((self.ndi+self.nshr, self.num_node * self.num_dof_per_node))
        B[0, 0::2] = shg[0, :]
        B[1, 1::2] = shg[1, :]
        B[3, 0::2] = shg[1, :]
        B[3, 1::2] = shg[0, :]

        if shgbar is None:
            return B

        # mean dilatational formulation
        for a in range(self.num_node):
            i = 2 * a
            j = i + 1

            bb1 = (shgbar[0, a] - shg[0, a]) / 2.
            bb2 = (shgbar[1, a] - shg[1, a]) / 2.

            B[0, i:i+2] += [bb1, bb2]
            B[1, i:i+2] += [bb1, bb2]

        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node,
                                coords, thickness=cls.thickness)
Beispiel #7
0
class QE4SRI(ContinuumElementSRI):
    """4-node, isoparametric, plane strain element

    Notes
    -----
    Node and element face numbering

               [2]
            3-------2
            |       |
       [3]  |       | [1]
            |       |
            0-------1
               [0]

    """
    ndi = 3
    nshr = 1
    name = "QE4SRI"
    num_node = 4
    num_coord = 2
    num_dof_per_node = 2
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

        self.sri_e = QE4RI(**{"hourglass stiffness": 0.})

    @staticmethod
    def iso_contrib(c, num_coord, nshr):
        # modify base function to have zeros in rows/columns associated with
        # plane strain
        I = array([1 for i in range(2)] + [0 for i in range(2)])
        a = dot(I, c) / num_coord
        return outer(a, I)

    def b_matrix(self, shg, shgbar=None, **kwargs):
        """Assemble and return the B matrix"""
        B = zeros(
            (self.ndi + self.nshr, self.num_node * self.num_dof_per_node))
        B[0, 0::2] = shg[0, :]
        B[1, 1::2] = shg[1, :]
        B[3, 0::2] = shg[1, :]
        B[3, 1::2] = shg[0, :]

        if shgbar is None:
            return B

        # mean dilatational formulation
        for a in range(self.num_node):
            i = 2 * a
            j = i + 1

            bb1 = (shgbar[0, a] - shg[0, a]) / 2.
            bb2 = (shgbar[1, a] - shg[1, a]) / 2.

            B[0, i:i + 2] += [bb1, bb2]
            B[1, i:i + 2] += [bb1, bb2]

        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords,
                                cls.thickness)
Beispiel #8
0
class QE4IM(ContinuumElementI):
    """4-node, isoparametric, plane strain element, incompatible modes

    Notes
    -----
    Node and element face numbering

               [2]
            3-------2
            |       |
       [3]  |       | [1]
            |       |
            0-------1
               [0]

    """
    ndi = 3
    nshr = 1
    name = "QE4IM"
    num_node = 4
    num_coord = 2
    num_dof_per_node = 2
    num_incompat_modes = 2
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord, self.num_node)
        args = (self.num_coord-1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)
        self.thickness = 1.

    def b_matrix(self, shg, shgbar=None, lcoords=None, coords=None, det=None,
                 disp=0, **kwargs):
        """Assemble and return the B matrix"""
        B = zeros((self.ndi+self.nshr, self.num_node * self.num_dof_per_node))
        B[0, 0::2] = shg[0, :]
        B[1, 1::2] = shg[1, :]
        B[3, 0::2] = shg[1, :]
        B[3, 1::2] = shg[0, :]

        if not disp:
            return B

        # Algorithm in
        # The Finite Element Method: Its Basis and Fundamentals
        # By Olek C Zienkiewicz, Robert L Taylor, J.Z. Zhu
        # Jacobian at element centroid
        dNdxi = self.shape.grad([0., 0.])
        dxdxi = dot(dNdxi, coords)
        J0 = inv(dxdxi)
        dt0 = determinant(dxdxi)

        xi, eta = lcoords
        dNdxi = array([[-2. * xi, 0.], [0., -2. * eta]])
        dNdx = dt0 / det * dot(J0, dNdxi)

        G1 = array([[dNdx[0, 0],  0],
                    [0,  dNdx[0, 1]],
                    [0, 0],
                    [dNdx[0, 1], dNdx[0, 0]]])

        G2 = array([[dNdx[1, 0],  0],
                    [0,  dNdx[1, 1]],
                    [0,  0],
                    [dNdx[1, 1], dNdx[1, 0]]])
        G = concatenate((G1, G2), axis=1)
        return B, G

        # Algorithm in Taylor's original paper and
        # The Finite Element Method: Linear Static and Dynamic
        # Finite Element Analysis
        # By Thomas J. R. Hughe
        xi = self.gauss_coords
        n = self.num_gauss
        dxdxi = asum([coords[i, 0] * xi[i, 0] for i in range(n)])
        dxdeta = asum([coords[i, 0] * xi[i, 1] for i in range(n)])
        dydxi = asum([coords[i, 1] * xi[i, 0] for i in range(n)])
        dydeta = asum([coords[i, 1] * xi[i, 1] for i in range(n)])

        xi, eta = lcoords
        G1 = array([[-xi * dydeta, 0],
                    [0, xi * dxdeta],
                    [0, 0],
                    [xi * dxdeta, -xi * dydeta]])
        G2 = array([[-eta * dydxi, 0.],
                    [0, eta * dxdxi],
                    [0, 0],
                    [eta * dxdxi, -eta * dydxi]])
        G = 2. / det * concatenate((G1, G2), axis=1)
        return B, G

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords, cls.thickness)
Beispiel #9
0
class HEX8SRI(ContinuumElementSRI):
    """Trilinear hex element

    Notes
    -----
    Integration points in parentheses

          7---------------6
         /|(7)        (6)/|
        / |             / |
       /  |            /  |
      /   |           /   |
     / (4)|       (5)/    |
    4---------------5     |
    |     |         |     |
    |     3---------|-----2
    |    / (3)      | (2)/
    |   /           |   /
    |  /            |  /
    | /             | /
    |/ (0)       (1)|/
    0---------------1

    """
    ndi = 3
    nshr = 3
    name = "HEX8SRI"
    num_node = 8
    num_coord = 3
    num_dof_per_node = 3
    type = geom.get_elem_type(num_coord, num_node)
    cp = geom.elem_center_coord(num_coord, num_node)
    xp = geom.elem_corner_coord(num_coord, num_node)

    def __init__(self):

        # integration scheme for this element
        self.integration = IntegrationProperties(self.num_coord, self.num_node)
        self.shape = ShapefunctionPrototype(self.num_coord, self.num_node)

        # element boundary properties
        self.num_face_nodes = geom.num_face_nodes(self.num_coord,
                                                  self.num_node)
        args = (self.num_coord - 1, self.num_face_nodes)
        self.bndry = ShapefunctionPrototype(*args)
        self.bndry.integration = IntegrationProperties(*args)

        self.sri_e = HEX8RI(**{"hourglass stiffness": 0.})

    @staticmethod
    def iso_contrib(c):
        I = array([1 for i in range(3)] + [0 for i in range(3)])
        a = dot(I, c) / num_coord
        return outer(a, I)

    def b_matrix(self, shg, shgbar=None, **kwargs):
        B = zeros((6, 24))
        B[0, 0::3] = shg[0, :]
        B[1, 1::3] = shg[1, :]
        B[2, 2::3] = shg[2, :]

        B[3, 0::3] = shg[1, :]
        B[3, 1::3] = shg[0, :]

        B[4, 1::3] = shg[2, :]
        B[4, 2::3] = shg[1, :]

        B[5, 0::3] = shg[2, :]
        B[5, 2::3] = shg[0, :]

        return B

    @classmethod
    def volume(cls, coords):
        return geom.elem_volume(cls.num_coord, cls.num_node, coords)