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
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
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
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
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
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