def test_tangent(self): shape = [2, 3] Eps = np.random.random(shape + [2, 2]) Eps = tensor.A4_ddot_B2(tensor.Array2d(shape).I4s, Eps) mat = GMat.Elastic2d(np.random.random(shape), np.random.random(shape)) mat.Eps = Eps self.assertTrue(np.allclose(tensor.A4_ddot_B2(mat.C, mat.Eps), mat.Sig))
def test_Elastic(self): shape = [2, 3] K = np.random.random(shape) G = np.random.random(shape) mat = GMat.Elastic2d(K, G) gamma = np.random.random(shape) epsm = np.random.random(shape) mat.Eps[..., 0, 0] = epsm mat.Eps[..., 1, 1] = epsm mat.Eps[..., 0, 1] = gamma mat.Eps[..., 1, 0] = gamma mat.refresh() Sig = np.empty(shape + [2, 2]) Sig[..., 0, 0] = K * epsm Sig[..., 1, 1] = K * epsm Sig[..., 0, 1] = G * gamma Sig[..., 1, 0] = G * gamma self.assertTrue(np.allclose(GMat.Epsd(mat.Eps), gamma)) self.assertTrue(np.allclose(GMat.Sigd(mat.Sig), 2 * G * gamma)) self.assertTrue(np.allclose(mat.Sig, Sig)) self.assertTrue(np.allclose(tensor.A4_ddot_B2(mat.C, mat.Eps), Sig)) self.assertTrue(np.allclose(mat.energy, K * epsm**2 + G * gamma**2)) self.assertTrue(np.allclose(mat.K, K)) self.assertTrue(np.allclose(mat.G, G))
def ComputePerturbation(sigma_star_test, trigger, mat, quad, vector, K, Solver): fext = np.zeros(vector.shape_nodevec()) disp = np.zeros(vector.shape_nodevec()) # pre-stress Sigstar = np.zeros(quad.shape_qtensor(2)) for q in range(quad.nip): Sigstar[trigger, q, :, :] = sigma_star_test Sigstar[trigger, q, :, :] = sigma_star_test # strain, stress, tangent Eps = np.zeros(quad.shape_qtensor(2)) 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.Eps = Eps return gtens.Deviatoric(Eps[trigger, 0]), disp, np.copy(mat.Eps), np.copy(mat.Sig)
def ComputeEnergy(P, S, Eps, Sig, dV, Eps_s, Sig_s, Eps_p, Sig_p): dE = np.empty(P.size) for i, (p, s) in enumerate(zip(P.ravel(), S.ravel())): dE[i] = np.sum(gtens.A2_ddot_B2(Sig + p * Sig_p + s * Sig_s, p * Eps_p + s * Eps_s) * dV) return dE.reshape(P.shape)
G = np.random.random(n) mat["Elastic1d"] = {"mat": GMat.Elastic1d(K, G), "is": iden == 2} data["/elastic/I"] = I data["/elastic/idx"] = idx data["/elastic/K"] = K data["/elastic/G"] = G data["/elastic/epsy"] = epsy for m in mat: mat[m]["is_tensor2"] = np.zeros(shape + [2, 2], bool) mat[m]["is_tensor4"] = np.zeros(shape + [2, 2, 2, 2], bool) mat[m]["is_tensor2"] += (mat[m]["is"]).reshape(shape + [1, 1]) mat[m]["is_tensor4"] += (mat[m]["is"]).reshape(shape + [1, 1, 1, 1]) I4s = tensor.Array2d(shape).I4s for i in range(20): GradU = 200 * np.random.random(shape + [2, 2]) data[f"/random/{i:d}/GradU"] = GradU Eps = tensor.A4_ddot_B2(I4s, GradU) for m in mat: mat[m]["mat"].Eps = Eps[mat[m]["is_tensor2"]].reshape(-1, 2, 2) Sig[mat[m]["is_tensor2"]] = mat[m]["mat"].Sig.reshape(-1) C[mat[m]["is_tensor4"]] = mat[m]["mat"].C.reshape(-1) if m == "Elastic1d": continue index[mat[m]["is"]] = mat[m]["mat"].i
# 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) # -------------------------------- # Explore different configurations # -------------------------------- dV = quad.dV() sig = np.zeros((201, 201)) eps = np.zeros(sig.shape) energy = np.zeros(sig.shape) P = np.linspace(-3, 3, sig.shape[0]) S = np.linspace(-3, 3, sig.shape[1]) E0 = np.average(0.5 * gtens.A2_ddot_B2(Sig, Eps), weights=dV) * np.sum(dV) for i, p in enumerate(P): for j, s in enumerate(S): Eps_n = Eps + s * Eps_s + p * Eps_p Sig_n = Sig + s * Sig_s + p * Sig_p sig[i, j] = GMat.Sigd(Sig_n[trigger, 0]) eps[i, j] = GMat.Epsd(Eps_n[trigger, 0]) energy[i, j] = ( np.average(0.5 * gtens.A2_ddot_B2(Sig_n, Eps_n), weights=dV) * np.sum(dV) - E0) # Plot phase diagram - stress
def test_basic(self): # ------------------------ # initialise configuration # ------------------------ # mesh # ---- # define mesh mesh = GooseFEM.Mesh.Quad4.FineLayer(21, 21) # mesh dimensions nelem = mesh.nelem mesh.nne mesh.ndim # 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)) # material definition mat = GMat.Elastic2d(10 * np.ones([nelem, quad.nip]), np.ones([nelem, quad.nip])) # solve # ----- # strain, stress, tangent ue = vector.AsElement(disp) mat.Eps = quad.SymGradN_vector(ue) # stiffness matrix Ke = quad.Int_gradN_dot_tensor4_dot_gradNT_dV(mat.C) K.assemble(Ke) # residual force fe = quad.Int_gradN_dot_tensor2_dV(mat.Sig) fint = vector.AssembleNode(fe) fext = vector.Copy_p(fint, fext) fres = fext - fint # set fixed displacements disp[nodesTop, 0] = +5.0 disp[nodesTop, 1] = np.sin(np.linspace(0, 2.0 * np.pi, len(nodesTop)) - np.pi) disp[nodesBot, 1] = np.cos(np.linspace(0, 2.0 * np.pi, len(nodesBot)) - np.pi) # solve disp = Solver.Solve(K, fres, disp) # compute new state ue = vector.AsElement(disp) Eps = quad.SymGradN_vector(ue) mat.Eps = Eps Sig = np.copy(mat.Sig) # ---------------------- # Effect of perturbation # ---------------------- epsy = np.cumsum(np.ones(50 * plastic.size).reshape(plastic.size, -1), axis=0) sys = model.System( coor=coor, conn=conn, dofs=dofs, iip=iip, elastic_elem=elastic, elastic_K=10 * FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), elastic_G=FrictionQPotFEM.moduli_toquad(np.ones(elastic.size)), plastic_elem=plastic, plastic_K=10 * FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_G=FrictionQPotFEM.moduli_toquad(np.ones(plastic.size)), plastic_epsy=FrictionQPotFEM.epsy_initelastic_toquad(epsy), dt=1, rho=1, alpha=1, eta=0, ) modelTrigger = model.LocalTriggerFineLayerFull(sys) modelTrigger.setState(Eps, Sig, 0.5 * np.ones((len(plastic), 4)), 100) Barrier = [] for itrigger, trigger in enumerate(plastic): Sigstar_s = np.array([[0.0, +1.0], [+1.0, 0.0]]) Sigstar_p = np.array([[+1.0, 0.0], [0.0, -1.0]]) Epsstar_s, u_s, Eps_s, Sig_s = ComputePerturbation( Sigstar_s, trigger, mat, quad, vector, K, Solver) Epsstar_p, u_p, Eps_p, Sig_p = ComputePerturbation( Sigstar_p, trigger, mat, quad, vector, K, Solver) self.assertTrue(np.allclose(u_s, modelTrigger.u_s(itrigger))) self.assertTrue(np.allclose(u_p, modelTrigger.u_p(itrigger))) self.assertTrue(np.allclose(Eps_s, modelTrigger.Eps_s(itrigger))) self.assertTrue(np.allclose(Eps_p, modelTrigger.Eps_p(itrigger))) self.assertTrue(np.allclose(Sig_s, modelTrigger.Sig_s(itrigger))) self.assertTrue(np.allclose(Sig_p, modelTrigger.Sig_p(itrigger))) # Current state for triggered element Epsd = gtens.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, plastic[itrigger]) # Plot perturbed configuration smin = Sy.ravel()[np.argmin(Ey)] pmin = Py.ravel()[np.argmin(Ey)] Barrier += [np.min(Ey)] delta_u = pmin * u_p + smin * u_s self.assertTrue( np.allclose(delta_u, modelTrigger.delta_u(itrigger, 0))) Barrier = np.array(Barrier) self.assertTrue(np.allclose(Barrier, modelTrigger.barriers()[:, 0]))