Example #1
0
    def residual(self, dt, coords, du):
        """Assemble the element residual force

        Parameters
        ----------
        dt : float
            Time step

        coords : array_like
            Nodal coordinates
            coords[i, a] -> ith coord of ath node

        materialprops : array_like
            Material properties passed on to constitutive procedures

        du : array_like
            Displacement increment vector
            du[i, a] -> ath component of displacement increment at ith node

        Returns
        -------
        rel : array_like
            Element residual

        """
        # output array
        rel = np.zeros((self.ndof * self.nnodes))

        # Set up integration points and weights
        xilist = self.gauss_coords
        w = self.gauss_weights

        # Loop over the integration points
        nnodes, ndof, ncoord = self.nnodes, self.ndof, self.ncoord

        for intpt in range(self.ngauss):

            # Compute shape functions and derivatives wrt local coords
            xi = xilist[intpt]
            N = self.calc_shape(xi)
            dNdxi = self.calc_shape_deriv(xi)

            # Compute the Jacobian matrix J = dNdxi.x
            dxdxi = np.dot(dNdxi, coords)
            dtm = float(np.linalg.det(dxdxi))

            # Convert shape function derivatives to derivatives wrt global coords
            dxidx = np.linalg.inv(dxdxi)
            dNdx = np.dot(dxidx, dNdxi)

            # Compute the element residual
            sig = self.data[1, intpt, STRESS:STRESS+NSYMM]
            if not ro.ENABLE_WEAVE:
                for a in range(nnodes):
                    for i in range(ndof):
                        row = ndof * a + i
                        for j in range(ncoord):
                            I = reduce_map(i, j, 3)
                            rel[row] += sig[I] * dNdx[j, a] * w[intpt] * dtm;

            else:
                code = """
                    int row, I;
                    for (int a=0; a < nnodes; ++a) {
                      for (int i=0; i < ndof; ++i) {
                        row = ndof * a + i;
                        for (int j=0; j < ncoord; ++j) {
                          I = reduce_map_C(i, j, 3);
                          rel(row) += sig(I) * dNdx(j, a) * w(intpt) * dtm;
                          }
                        }
                      }
                    """
                inline(code, ["nnodes", "ndof", "ncoord", "rel",
                              "dNdx", "dtm", "w", "sig", "intpt"],
                       support_code=reduce_map_C,
                       type_converters=converters.blitz)

            continue # intpt

        return rel
Example #2
0
    def add_to_kel(self, kel, dNdx, D, w, dtm, mode=0):
        """Put the stiffness at the quadrature point in to the element
        stiffness.

        Parameters
        ----------
        kel : array_like
            Current element stiffness

        dNdx : array_like
            Shape functions

        D : array_like
            Material stiffness at Gauss point.  Stored as 3x3 or 2x2 matrix

        w : float
            Gauss integration weight

        dtm : float
            Jacobian

        mode : int
            Mode flag
            mode == 0 -> Assemble stiffness regularly, subtracting off some
                         deviatoric contributions if reduced integration is
                         used
            mode == 1 -> Add bulk contribution back to the element
        Returns
        -------
        None

        Notes
        -----
        kel is changed in place

        """
        # use only two space since there are so many loops
        nnodes, ndof, ncoord = self.nnodes, self.ndof, self.ncoord
        reducedint = 0 if not self.reducedint else 1

        if not ro.ENABLE_WEAVE:
            for A in range(nnodes):
                for i in range(ndof):
                    for j in range(ncoord):
                        for k in range(ncoord):
                            for l in range(ndof):
                                for B in range(nnodes):
                                    rw = A * ndof + j
                                    cl = B * ndof + k
                                    I = reduce_map(i, j, ncoord)
                                    L = reduce_map(k, l, ncoord)
                                    JJ = reduce_map(j, j, ncoord)
                                    if mode == 0:
                                        kAB = dNdx[i, A] * D[I, L] * dNdx[l, B]
                                        kR = 0.
                                        if reducedint == 1:
                                            kR = -dNdx[i, A] * D[JJ, L] * dNdx[l, B]

                                    else:
                                       # Adding back in some deviatoric contribution
                                       kAB = 0.
                                       kR = dNdx[i, A] * D[JJ, L] * dNdx[l, B]

                                    # add the contribution to the stiffness
                                    kC = (kAB + kR / ncoord) * w * dtm
                                    kel[rw, cl] = kel[rw, cl] + kC

        else:
            code = """
              int rw, cl, I, L, JJ;
              double kAB, kR;
              for (int A=0; A < nnodes; ++A) {
                for (int i=0; i < ndof; ++i) {
                  for (int j=0; j < ncoord; ++j) {
                    for (int k=0; k < ncoord; ++k) {
                      for (int l=0; l < ndof; ++l) {
                        for (int B=0; B < nnodes; ++B) {
                          rw = A * ndof + j;
                          cl = B * ndof + k;
                          I = reduce_map_C(i, j, ncoord);
                          L = reduce_map_C(k, l, ncoord);
                          JJ = reduce_map_C(j, j, ncoord);
                          if (mode == 0) {
                            kAB = dNdx(i, A) * D(I, L) * dNdx(l, B);
                            kR = 0.;
                            if (reducedint == 1) {
                              kR = -dNdx(i, A) * D(JJ, L) * dNdx(l, B);
                              }
                            }
                          else {
                            // Adding back in some deviatoric contribution
                            kAB = 0.;
                            kR = dNdx(i, A) * D(JJ, L) * dNdx(l, B);
                            }
                          // add the contribution to the stiffness
                          kel(rw, cl) = kel(rw, cl) + (kAB + kR / ncoord) * w * dtm;
                          }
                        }
                      }
                    }
                  }
                }
              """
            inline(code, ["nnodes", "ndof", "ncoord", "mode", "kel",
                          "D", "dNdx", "dtm", "w", "reducedint"],
                   support_code=reduce_map_C, type_converters=converters.blitz)

        return
Example #3
0
    def stiffness(self, dt, d, stress, xtra):
        """Compute the material stiffness tensor

        Parameters
        ----------
        dt : float
            time step

        d : array_like
            Deformation rate

        stress : array_like
            Stress at beginning of step

        xtra : float
            Extra variables

        Returns
        -------
        C : array_like
            The material stiffness

        Notes
        -----
        Currently coded either for plane strain or general 3D. Note that in
        this procedure `stress' is the current estimate for stress at the end
        of the increment S_n+1

        """
        dstrain = d * dt
        eplas = xtra[0]
        E = self._params[self.Ei]
        nu = self._params[self.Nui]
        K = E / (3. * (1. - 2. * nu))
        G = 3. * K * E / (9. * K - E)
        e0 = self._params[self.E0i]
        n = self._params[self.Ni]
        m = self._params[self.Mi]

        devol = trace(dstrain)
        p = trace(stress)

        S = dev(stress)
        se = np.sqrt(1.5 * np.sum(S * S))

        # tjfulle: fix model
        dep = 0.

        if se * dep > 0:
            beta = 1. / (1. + 1.5 * E * dep / ((1. + nu) * se))
            gamma = beta * (1.5 * E / ((1 + nu) * se)
                            + (1 / (n * (e0 + eplas + dep)) + 1. / (m * dep)))
            factor = 1.5 * 1.5 * E * (dep - 1. / gamma) / ((1. + nu) * se ** 3)
        else:
            beta = 1.
            factor = 0.

        C = np.zeros((6, 6))
        for i in range(3):
            for j in range(3):
                for k in range(3):
                    for l in range(3):
                        ik = reduce_map((i, k), 3)
                        jl = reduce_map((j, l), 3)
                        jk = reduce_map((j, k), 3)
                        il = reduce_map((i, l), 3)
                        ij = reduce_map((i, j), 3)
                        kl = reduce_map((k, l), 3)
                        w = ((I6[ik] * I6[jl] + I6[jk] * I6[il]) / 2.,
                             -I6[ij] * I6[kl] / 3.,
                             factor * S[ij] * S[kl])
                        c = (beta  *  E / (1 + nu) * (w[0] + w[1] + w[2]),
                             K * I6[ij] * I6[kl])
                        C[ij, kl] = c[0] + c[1]
                        continue
                    continue
                continue
            continue

        return C
Example #4
0
    def stiffness(self, dt, d, stress, xtra):
        """Compute the material stiffness tensor

        Parameters
        ----------
        dt : float
            time step

        d : array_like
            Deformation rate

        stress : array_like
            Stress at beginning of step

        xtra : float
            Extra variables

        Returns
        -------
        C : array_like
            The material stiffness

        Notes
        -----
        Currently coded either for plane strain or general 3D. Note that in
        this procedure `stress' is the current estimate for stress at the end
        of the increment S_n+1

        """
        dstrain = d * dt
        eplas = xtra[0]
        E = self._params[self.Ei]
        nu = self._params[self.Nui]
        K = E / (3. * (1. - 2. * nu))
        G = 3. * K * E / (9. * K - E)
        e0 = self._params[self.E0i]
        n = self._params[self.Ni]
        m = self._params[self.Mi]

        devol = trace(dstrain)
        p = trace(stress)

        S = dev(stress)
        se = np.sqrt(1.5 * np.sum(S * S))

        # tjfulle: fix model
        dep = 0.

        if se * dep > 0:
            beta = 1. / (1. + 1.5 * E * dep / ((1. + nu) * se))
            gamma = beta * (1.5 * E / ((1 + nu) * se) +
                            (1 / (n * (e0 + eplas + dep)) + 1. / (m * dep)))
            factor = 1.5 * 1.5 * E * (dep - 1. / gamma) / ((1. + nu) * se**3)
        else:
            beta = 1.
            factor = 0.

        C = np.zeros((6, 6))
        for i in range(3):
            for j in range(3):
                for k in range(3):
                    for l in range(3):
                        ik = reduce_map((i, k), 3)
                        jl = reduce_map((j, l), 3)
                        jk = reduce_map((j, k), 3)
                        il = reduce_map((i, l), 3)
                        ij = reduce_map((i, j), 3)
                        kl = reduce_map((k, l), 3)
                        w = ((I6[ik] * I6[jl] + I6[jk] * I6[il]) / 2.,
                             -I6[ij] * I6[kl] / 3., factor * S[ij] * S[kl])
                        c = (beta * E / (1 + nu) * (w[0] + w[1] + w[2]),
                             K * I6[ij] * I6[kl])
                        C[ij, kl] = c[0] + c[1]
                        continue
                    continue
                continue
            continue

        return C
Example #5
0
    def residual(self, dt, coords, du):
        """Assemble the element residual force

        Parameters
        ----------
        dt : float
            Time step

        coords : array_like
            Nodal coordinates
            coords[i, a] -> ith coord of ath node

        materialprops : array_like
            Material properties passed on to constitutive procedures

        du : array_like
            Displacement increment vector
            du[i, a] -> ath component of displacement increment at ith node

        Returns
        -------
        rel : array_like
            Element residual

        """
        # output array
        rel = np.zeros((self.ndof * self.nnodes))

        # Set up integration points and weights
        xilist = self.gauss_coords
        w = self.gauss_weights

        # Loop over the integration points
        nnodes, ndof, ncoord = self.nnodes, self.ndof, self.ncoord

        for intpt in range(self.ngauss):

            # Compute shape functions and derivatives wrt local coords
            xi = xilist[intpt]
            N = self.calc_shape(xi)
            dNdxi = self.calc_shape_deriv(xi)

            # Compute the Jacobian matrix J = dNdxi.x
            dxdxi = np.dot(dNdxi, coords)
            dtm = float(np.linalg.det(dxdxi))

            # Convert shape function derivatives to derivatives wrt global coords
            dxidx = np.linalg.inv(dxdxi)
            dNdx = np.dot(dxidx, dNdxi)

            # Compute the element residual
            sig = self.data[1, intpt, STRESS:STRESS + NSYMM]
            if not ro.ENABLE_WEAVE:
                for a in range(nnodes):
                    for i in range(ndof):
                        row = ndof * a + i
                        for j in range(ncoord):
                            I = reduce_map(i, j, 3)
                            rel[row] += sig[I] * dNdx[j, a] * w[intpt] * dtm

            else:
                code = """
                    int row, I;
                    for (int a=0; a < nnodes; ++a) {
                      for (int i=0; i < ndof; ++i) {
                        row = ndof * a + i;
                        for (int j=0; j < ncoord; ++j) {
                          I = reduce_map_C(i, j, 3);
                          rel(row) += sig(I) * dNdx(j, a) * w(intpt) * dtm;
                          }
                        }
                      }
                    """
                inline(code, [
                    "nnodes", "ndof", "ncoord", "rel", "dNdx", "dtm", "w",
                    "sig", "intpt"
                ],
                       support_code=reduce_map_C,
                       type_converters=converters.blitz)

            continue  # intpt

        return rel
Example #6
0
    def add_to_kel(self, kel, dNdx, D, w, dtm, mode=0):
        """Put the stiffness at the quadrature point in to the element
        stiffness.

        Parameters
        ----------
        kel : array_like
            Current element stiffness

        dNdx : array_like
            Shape functions

        D : array_like
            Material stiffness at Gauss point.  Stored as 3x3 or 2x2 matrix

        w : float
            Gauss integration weight

        dtm : float
            Jacobian

        mode : int
            Mode flag
            mode == 0 -> Assemble stiffness regularly, subtracting off some
                         deviatoric contributions if reduced integration is
                         used
            mode == 1 -> Add bulk contribution back to the element
        Returns
        -------
        None

        Notes
        -----
        kel is changed in place

        """
        # use only two space since there are so many loops
        nnodes, ndof, ncoord = self.nnodes, self.ndof, self.ncoord
        reducedint = 0 if not self.reducedint else 1

        if not ro.ENABLE_WEAVE:
            for A in range(nnodes):
                for i in range(ndof):
                    for j in range(ncoord):
                        for k in range(ncoord):
                            for l in range(ndof):
                                for B in range(nnodes):
                                    rw = A * ndof + j
                                    cl = B * ndof + k
                                    I = reduce_map(i, j, ncoord)
                                    L = reduce_map(k, l, ncoord)
                                    JJ = reduce_map(j, j, ncoord)
                                    if mode == 0:
                                        kAB = dNdx[i, A] * D[I, L] * dNdx[l, B]
                                        kR = 0.
                                        if reducedint == 1:
                                            kR = -dNdx[i, A] * D[JJ,
                                                                 L] * dNdx[l,
                                                                           B]

                                    else:
                                        # Adding back in some deviatoric contribution
                                        kAB = 0.
                                        kR = dNdx[i, A] * D[JJ, L] * dNdx[l, B]

                                    # add the contribution to the stiffness
                                    kC = (kAB + kR / ncoord) * w * dtm
                                    kel[rw, cl] = kel[rw, cl] + kC

        else:
            code = """
              int rw, cl, I, L, JJ;
              double kAB, kR;
              for (int A=0; A < nnodes; ++A) {
                for (int i=0; i < ndof; ++i) {
                  for (int j=0; j < ncoord; ++j) {
                    for (int k=0; k < ncoord; ++k) {
                      for (int l=0; l < ndof; ++l) {
                        for (int B=0; B < nnodes; ++B) {
                          rw = A * ndof + j;
                          cl = B * ndof + k;
                          I = reduce_map_C(i, j, ncoord);
                          L = reduce_map_C(k, l, ncoord);
                          JJ = reduce_map_C(j, j, ncoord);
                          if (mode == 0) {
                            kAB = dNdx(i, A) * D(I, L) * dNdx(l, B);
                            kR = 0.;
                            if (reducedint == 1) {
                              kR = -dNdx(i, A) * D(JJ, L) * dNdx(l, B);
                              }
                            }
                          else {
                            // Adding back in some deviatoric contribution
                            kAB = 0.;
                            kR = dNdx(i, A) * D(JJ, L) * dNdx(l, B);
                            }
                          // add the contribution to the stiffness
                          kel(rw, cl) = kel(rw, cl) + (kAB + kR / ncoord) * w * dtm;
                          }
                        }
                      }
                    }
                  }
                }
              """
            inline(code, [
                "nnodes", "ndof", "ncoord", "mode", "kel", "D", "dNdx", "dtm",
                "w", "reducedint"
            ],
                   support_code=reduce_map_C,
                   type_converters=converters.blitz)

        return