def ComputePerturbation(sigma_star_test, trigger, mat, quad, vector, K, Solver): fext = vector.AllocateNodevec(0.0) disp = vector.AllocateNodevec(0.0) # pre-stress Sigstar = quad.AllocateQtensor(2, 0.0) for q in range(nip): Sigstar[trigger, q, :, :] = sigma_star_test Sigstar[trigger, q, :, :] = sigma_star_test # strain, stress, tangent Eps = quad.AllocateQtensor(2, 0.0) Sig = -Sigstar # residual force fe = quad.Int_gradN_dot_tensor2_dV(Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # solve disp = Solver.Solve(K, fres, disp) # post-process # ------------ ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) mat.setStrain(Eps) Sig = mat.Stress() return GMat.Deviatoric(Eps[trigger, 0]), disp, Eps, Sig
quad, vector, K, Solver) # Check with perturbation that is rolled periodically iconfig = int(itrigger % nconfig) roll = int((itrigger - itrigger % nconfig) / nconfig) elemmap = config[iconfig]["elemmap"][roll] nodemap = config[iconfig]["nodemap"][roll] assert np.allclose(config[iconfig]["Eps_s"][elemmap, :], Eps_s) assert np.allclose(config[iconfig]["Eps_p"][elemmap, :], Eps_p) assert np.allclose(config[iconfig]["Sig_s"][elemmap, :], Sig_s) assert np.allclose(config[iconfig]["Sig_p"][elemmap, :], Sig_p) assert np.allclose(config[iconfig]["u_s"][nodemap, :], u_s) assert np.allclose(config[iconfig]["u_p"][nodemap, :], u_p) # Current state for triggered element Epsd = GMat.Deviatoric(Eps[trigger, 0]) gamma = Epsd[0, 1] E = Epsd[0, 0] # Find which (s, p) lie on the yield surface, # and to which energy change those perturbations lead Py, Sy = GetYieldSurface(E, gamma, Epsstar_p[0, 0], Epsstar_s[0, 1]) Ey = ComputeEnergy(Py, Sy, Eps, Sig, quad.dV(), Eps_s, Sig_s, Eps_p, Sig_p) # Plot perturbed configuration smin = Sy.ravel()[np.argmin(Ey)] pmin = Py.ravel()[np.argmin(Ey)] Barrier += [np.min(Ey)] u = disp + pmin * u_p + smin * u_s
def ComputePerturbation(sigma_star_test): # mesh # ---- # define mesh mesh = GooseFEM.Mesh.Quad4.FineLayer(13, 13) # mesh dimensions nelem = mesh.nelem() # mesh definitions coor = mesh.coor() conn = mesh.conn() dofs = mesh.dofs() # node sets nodesLft = mesh.nodesLeftOpenEdge() nodesRgt = mesh.nodesRightOpenEdge() nodesTop = mesh.nodesTopEdge() nodesBot = mesh.nodesBottomEdge() # element sets plastic = mesh.elementsMiddleLayer() elastic = np.setdiff1d(np.arange(nelem), plastic) # periodicity and fixed displacements DOFs # ---------------------------------------- dofs[nodesRgt, :] = dofs[nodesLft, :] dofs = GooseFEM.Mesh.renumber(dofs) iip = np.concatenate( (dofs[nodesBot, 0], dofs[nodesBot, 1], dofs[nodesTop, 0], dofs[nodesTop, 1])) # simulation variables # -------------------- # vector definition vector = GooseFEM.VectorPartitioned(conn, dofs, iip) # allocate system matrix K = GooseFEM.MatrixPartitioned(conn, dofs, iip) Solver = GooseFEM.MatrixPartitionedSolver() # nodal quantities disp = np.zeros(coor.shape) fint = np.zeros(coor.shape) fext = np.zeros(coor.shape) fres = np.zeros(coor.shape) # element/material definition # --------------------------- # element definition quad = GooseFEM.Element.Quad4.Quadrature(vector.AsElement(coor)) nip = quad.nip() # material definition mat = GMat.Array2d([nelem, nip]) iden = np.zeros(mat.shape(), dtype="int") iden[elastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) iden = np.zeros(mat.shape(), dtype="int") iden[plastic, :] = 1 mat.setElastic(iden, 10.0, 1.0) # solve # ----- # strain ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) # pre-stress trigger = plastic[int(len(plastic) / 2.0)] Sigstar = quad.AllocateQtensor(2, 0.0) for q in range(nip): Sigstar[trigger, q, :, :] = sigma_star_test Sigstar[trigger, q, :, :] = sigma_star_test # stress & tangent mat.setStrain(Eps) Sig = mat.Stress() - Sigstar C = mat.Tangent() # stiffness matrix Ke = quad.Int_gradN_dot_tensor4_dot_gradNT_dV(C) K.assemble(Ke) # residual force fe = quad.Int_gradN_dot_tensor2_dV(Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # solve disp = Solver.Solve(K, fres, disp) # post-process # ------------ ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) return ( GMat.Deviatoric(Eps[trigger, 0]), trigger, disp, coor, conn, vector, quad, mat, )