예제 #1
0
    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))
예제 #2
0
    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))
예제 #3
0
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)
예제 #4
0
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
예제 #6
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)

# --------------------------------
# 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
예제 #7
0
    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]))