def bilin_mortar(u, v, w): # jumps ju, jv = jump(w, dot(u, w.n), dot(v, w.n)) mu = .5 * dot(w.n, mul(C(sym_grad(u)), w.n)) mv = .5 * dot(w.n, mul(C(sym_grad(v)), w.n)) return ((1. / (alpha * w.h) * ju * jv - mu * jv - mv * ju) * (np.abs(w.x[1]) <= limit))
def bilin_mortar(u, v, w): ju = (-1.)**j * dot(u, w.n) jv = (-1.)**i * dot(v, w.n) nxn = prod(w.n, w.n) mu = .5 * ddot(nxn, C(sym_grad(u))) mv = .5 * ddot(nxn, C(sym_grad(v))) return ((1. / (alpha * w.h) * ju * jv - mu * jv - mv * ju) * (np.abs(w.x[1]) <= limit))
def __init__(self, state_n, state_np1, solver_options, set_strain=None): """ Setup solver Parameters: state_n previous state state_np1 current state solver_options various 'how to solve' parameters Additional parameters: set_strain set the zz strain to this value, if given """ self.state_n = state_n self.state_np1 = state_np1 self.options = solver_options self.set_strain = set_strain self.ebcs = [] self.edofs = [] self.evalues = [] # Initialize the guess self.setup_guess() # The operators! if self.ndim == 1: # 1D axisymmetric is different than 2D/3D cartesian self.internal = LinearForm( lambda v, w: ( v.grad[0][0] * w["radial"] - v.value[0] * w["radial"] / w.x[0] + v.value[0] * w["hoop"] / w.x[0] ) ) self.jac = BilinearForm( lambda u, v, w: v.grad[0][0] * w["Crr"] * u.grad[0][0] + v.grad[0][0] * w["Crt"] * u.value[0] / w.x[0] - v.value[0] * (w["Crr"] * u.grad[0][0] + w["Crt"] * u.value[0] / w.x[0]) / w.x[0] + v.value[0] * (w["Ctr"] * u.grad[0][0] + w["Ctt"] * u.value[0] / w.x[0]) / w.x[0] ) else: self.internal = LinearForm( lambda v, w: helpers.ddot(helpers.sym_grad(v), w["stress"]) ) self.jac = BilinearForm( lambda u, v, w: helpers.ddot( helpers.sym_grad(v), helpers.ddot(w["C"], helpers.sym_grad(u)) ) ) self.external = LinearForm( lambda v, w: helpers.dot((-1.0) * w["pressure"] * w.n, v) )
def calculate_strain(self, D): """ Calculate the strain based on the current displacements Parameters: D displacements to use """ U = self.state_np1.basis.interpolate(D) E = np.zeros((3, 3) + U[0][0].shape) E[:self.ndim, :self.ndim] = helpers.sym_grad(U) if self.ndim == 1: # Cast needed b/c they don't have a divide operator! E[1, 1] = np.array(U) / np.array( self.state_np1.basis.interpolate( self.state_np1.mesh.p.flatten())) return E
def proj(v, _): return ddot(C(sym_grad(x)), v)
def proj_cauchy(u, v, w): return C(sym_grad(u))[itr, jtr] * v
def lin_mortar(v, w): jv = (-1.)**i * dot(v, w.n) mv = .5 * ddot(prod(w.n, w.n), C(sym_grad(v))) return ((1. / (alpha * w.h) * gap(w.x) * jv - gap(w.x) * mv) * (np.abs(w.x[1]) <= limit))
def weakform(u, v, w): return ddot(C(sym_grad(u)), sym_grad(v))
D = gb.get_dofs("left") y = gb.zeros() I = gb.complement_dofs(D) L, x = solve(*condense(K, M, I=I), solver=solver_eigen_scipy_sym(k=6, sigma=0.0)) y = x[:, 4] # calculate stress sgb = gb.with_element(ElementVector(e)) C = linear_stress(lam, mu) yi = gb.interpolate(y) sigma = sgb.project(C(sym_grad(yi))) def visualize(): from skfem.visuals.matplotlib import plot, draw M = MeshQuad(np.array(m.p + .5 * y[gb.nodal_dofs]), m.t) ax = draw(M) return plot(M, sigma[sgb.nodal_dofs[0]], ax=ax, colorbar='$\sigma_{xx}$', shading='gouraud') if __name__ == "__main__": visualize().show()