def test_3d(self):
        prm = c.Parameters(c.Constraint.FULL)
        mesh = df.UnitCubeMesh(5, 5, 5)

        u_bc = 42.0
        problem = c.MechanicsProblem(mesh, prm, law(prm))
        bcs = []
        bcs.append(df.DirichletBC(problem.Vd.sub(0), 0, boundary.plane_at(0)))
        bcs.append(
            df.DirichletBC(problem.Vd.sub(0), u_bc, boundary.plane_at(1)))
        bcs.append(
            df.DirichletBC(problem.Vd.sub(1), 0, boundary.plane_at(0, "y")))
        bcs.append(
            df.DirichletBC(problem.Vd.sub(2), 0, boundary.plane_at(0, "z")))
        problem.set_bcs(bcs)

        u = problem.solve()

        xs = np.linspace(0, 1, 5)
        for x in xs:
            for y in xs:
                for z in xs:
                    u_fem = u((x, y, z))
                    # print(u_fem)
                    u_correct = (x * u_bc, -y * u_bc * prm.nu,
                                 -z * u_bc * prm.nu)
                    self.assertAlmostEqual(u_fem[0], u_correct[0])
                    self.assertAlmostEqual(u_fem[1], u_correct[1])
                    self.assertAlmostEqual(u_fem[2], u_correct[2])
Example #2
0
    def test_plane_at(self):
        b = boundary.plane_at(0, "Y")
        self.assertTrue(b.inside([0, 0], True))
        self.assertTrue(b.inside([42, 0, 42], True))
        self.assertFalse(b.inside([0, 1], True))
        self.assertFalse(b.inside([0, 0], False))

        with self.assertRaises(Exception):
            b.inside([0], True)
    def test_1d(self):
        prm = c.Parameters(c.Constraint.UNIAXIAL_STRAIN)
        mesh = df.UnitIntervalMesh(10)

        u_bc = 42.0
        problem = c.MechanicsProblem(mesh, prm, law(prm))
        bcs = []
        bcs.append(df.DirichletBC(problem.Vd, [0], boundary.plane_at(0)))
        bcs.append(df.DirichletBC(problem.Vd, [u_bc], boundary.plane_at(1)))
        problem.set_bcs(bcs)

        u = problem.solve()

        xs = np.linspace(0, 1, 5)
        for x in xs:
            u_fem = u((x))
            u_correct = x * u_bc
            self.assertAlmostEqual(u_fem, u_correct)
Example #4
0
    def test_plate(self):
        L, radius = 4.0, 1.0

        prm = c.Parameters(c.Constraint.PLANE_STRESS)

        plate_with_hole = PlateWithHoleSolution(L=L, E=prm.E, nu=prm.nu, radius=radius)
        mesh = plate_with_hole.build_mesh(resolution=50)

        n = FacetNormal(mesh)
        stress = StressSolution(plate_with_hole, degree=2)
        traction = dot(stress, n)
  
        problem = c.MechanicsProblem(mesh, prm, c.LinearElastic(prm.E, prm.nu, prm.constraint))
        bc0 = DirichletBC(problem.Vd.sub(0), 0.0, boundary.plane_at(0, "x"))
        bc1 = DirichletBC(problem.Vd.sub(1), 0.0, boundary.plane_at(0, "y"))
        problem.set_bcs([bc0, bc1])
        problem.add_force_term(dot(TestFunction(problem.Vd), traction)*ds)
        u = problem.solve() 
        
        disp = DisplacementSolution(plate_with_hole, degree=2)
        error = errornorm(disp, u)
        self.assertLess(error, 1.e-6)
Example #5
0
    def test_uniaxial(self):
        prm = c.Parameters(c.Constraint.UNIAXIAL_STRESS)
        prm.deg_d = 1
        prm.alpha = 0.999
        prm.gf = 0.01
        k0 = 2.0e-4
        prm.ft = k0 * prm.E
        law = law_from_prm(prm)

        mesh = df.UnitIntervalMesh(1)
        problem = c.MechanicsProblem(mesh, prm, law)

        bc0 = df.DirichletBC(problem.Vd, [0], boundary.plane_at(0))
        bc_expr = df.Expression(["u"], u=0, degree=0)
        bc1 = df.DirichletBC(problem.Vd, bc_expr, boundary.plane_at(1))

        problem.set_bcs([bc0, bc1])

        ld = c.helper.LoadDisplacementCurve(bc1)

        # ld.show()

        solver = df.NewtonSolver()
        solver.parameters["linear_solver"] = "mumps"
        solver.parameters["maximum_iterations"] = 10
        solver.parameters["error_on_nonconvergence"] = False

        u_max = 100 * k0
        for u in np.linspace(0, u_max, 101):
            bc_expr.u = u
            converged = solver.solve(problem, problem.u.vector())
            assert converged
            problem.update()
            ld(u, df.assemble(problem.R))

        GF = np.trapz(ld.load, ld.disp)
        self.assertAlmostEqual(GF,
                               0.5 * k0**2 * prm.E + prm.gf,
                               delta=prm.gf / 100)
    def test_plane_strain(self):
        prm = c.Parameters(c.Constraint.PLANE_STRAIN)
        mesh = df.UnitSquareMesh(10, 10)

        u_bc = 42.0
        problem = c.MechanicsProblem(mesh, prm, law(prm))
        bcs = []
        bcs.append(df.DirichletBC(problem.Vd.sub(0), 0, boundary.plane_at(0)))
        bcs.append(
            df.DirichletBC(problem.Vd.sub(0), u_bc, boundary.plane_at(1)))
        bcs.append(
            df.DirichletBC(problem.Vd.sub(1), 0, boundary.plane_at(0, "y")))
        problem.set_bcs(bcs)

        u = problem.solve()

        xs = np.linspace(0, 1, 5)
        for x in xs:
            for y in xs:
                u_fem = u((x, y))
                u_correct = (x * u_bc, -y * u_bc * (prm.nu) / (1 - prm.nu))
                self.assertAlmostEqual(u_fem[0], u_correct[0])
                self.assertAlmostEqual(u_fem[1], u_correct[1])
    def test_bending(self):
        # return
        LX = 6.0
        LY = 0.5
        LZ = 0.5

        mesh_resolution = 6.0

        def loading(t):
            level = 4 * LZ
            N = 1.5
            return level * np.sin(N * t * 2 * np.pi)

        # show_loading(loading)  # if you really insist on it :P

        prm = c.Parameters(c.Constraint.PLANE_STRESS)
        prm.E = 1000.0
        prm.Et = prm.E / 100.0
        prm.sig0 = 12.0
        prm.H = 15.0 * prm.E * prm.Et / (prm.E - prm.Et)
        prm.nu = 0.3
        prm.deg_d = 3
        prm.deg_q = 4
        law = None  # for now, plays no role.

        mesh = df.RectangleMesh(
            df.Point(0, 0),
            df.Point(LX, LY),
            int(LX * mesh_resolution),
            int(LY * mesh_resolution),
        )

        yf = Yield_VM(prm.sig0, prm.constraint, H=prm.H)
        ri = c.RateIndependentHistory()
        # mat = PlasticConsitutivePerfect(prm.E, prm.nu, prm.constraint, yf=yf)
        mat = PlasticConsitutiveRateIndependentHistory(prm.E,
                                                       prm.nu,
                                                       prm.constraint,
                                                       yf=yf,
                                                       ri=ri)
        plasticity = Plasticity(mat)

        problem = c.MechanicsProblem(mesh, prm, law=law, iploop=plasticity)

        left = boundary.plane_at(0.0)
        right_top = boundary.point_at((LX, LY))
        bc_expr = df.Expression("u", degree=0, u=0)

        bcs = []
        bcs.append(
            df.DirichletBC(problem.Vd.sub(1),
                           bc_expr,
                           right_top,
                           method="pointwise"))
        bcs.append(df.DirichletBC(problem.Vd, (0, 0), left))
        problem.set_bcs(bcs)

        linear_solver = df.LUSolver("mumps")
        solver = df.NewtonSolver(df.MPI.comm_world, linear_solver,
                                 df.PETScFactory.instance())
        solver.parameters["linear_solver"] = "mumps"
        solver.parameters["maximum_iterations"] = 10
        solver.parameters["error_on_nonconvergence"] = False

        def solve(t, dt):
            print(t, dt)
            bc_expr.u = loading(t)
            return solver.solve(problem, problem.u.vector())

        ld = c.helper.LoadDisplacementCurve(bcs[0])
        ld.show()

        if not ld.is_root:
            set_log_level(LogLevel.ERROR)

        fff = df.XDMFFile("output.xdmf")
        fff.parameters["functions_share_mesh"] = True
        fff.parameters["flush_output"] = True

        def pp(t):
            problem.update()

            # this fixes XDMF time stamps
            import locale

            locale.setlocale(locale.LC_NUMERIC, "en_US.UTF-8")
            fff.write(problem.u, t)

            ld(t, df.assemble(problem.R))

        TimeStepper(solve, pp, problem.u).dt_max(0.02).adaptive(1.0, dt=0.01)
def test_tensile_meso():

    mesh = df.Mesh()
    mvc = df.MeshValueCollection("size_t", mesh, 1)
    LX, LY = 80.0, 80.0  # magic!

    mesh_file = Path(__file__).parent / "mesh.xdmf"
    with df.XDMFFile(str(mesh_file)) as f:
        f.read(mesh)
        f.read(mvc, "gmsh:physical")

    subdomains = df.MeshFunction("size_t", mesh, mvc)

    if not TEST:
        import matplotlib.pyplot as plt
        df.plot(subdomains)
        plt.show()

    mat_l = 2.0
    Q = c.Q

    s = GDMSpaces(mesh, c.Constraint.PLANE_STRAIN, subdomains)
    s.create()
    R = df.inner(s.eps(s.d_), s.q[Q.SIGMA]) * s.dxm(1)
    dR = df.inner(s.eps(s.dd), s.q[Q.DSIGMA_DEPS] * s.eps(s.d_)) * s.dxm(1)

    R += s.e_ * (s.e - s.q[Q.EEQ]) * s.dxm(1)
    R += df.dot(df.grad(s.e_), mat_l**2 * df.grad(s.e)) * s.dxm(1)

    dR += s.de * df.dot(s.q[Q.DSIGMA_DE], s.eps(s.d_)) * s.dxm(1)
    dR += df.inner(s.eps(s.dd), -s.q[Q.DEEQ] * s.e_) * s.dxm(1)
    dR += s.de * s.e_ * s.dxm(1)
    dR += df.dot(df.grad(s.de), mat_l**2 * df.grad(s.e_)) * s.dxm(1)

    R += df.inner(s.eps(s.d_), s.q[Q.SIGMA]) * s.dxm(2)
    dR += df.inner(s.eps(s.dd), s.q[Q.DSIGMA_DEPS] * s.eps(s.d_)) * s.dxm(2)
    dR += s.de * s.e_ * s.dxm(2)

    R += df.inner(s.eps(s.d_), s.q[Q.SIGMA]) * s.dxm(3)
    dR += df.inner(s.eps(s.dd), s.q[Q.DSIGMA_DEPS] * s.eps(s.d_)) * s.dxm(3)
    dR += s.de * s.e_ * s.dxm(3)

    VQF, VQV, VQT = c.helper.spaces(s.mesh, s.deg_q, c.q_dim(s.constraint))
    calculate_eps = c.helper.LocalProjector(s.eps(s.d), VQV, s.dxm)
    calculate_e = c.helper.LocalProjector(s.e, VQF, s.dxm(1))

    F = 0.75  # interface reduction
    t = 0.5  # interface thickness
    lawAggreg = c.LinearElastic(2 * 26738, 0.18, s.constraint)
    lawInterf = c.LocalDamage(
        26738,
        0.18,
        s.constraint,
        c.DamageLawExponential(k0=F * 3.4 / 26738.0,
                               alpha=0.99,
                               beta=3.4 / 26738.0 / (0.12 * F / t)),
        c.ModMisesEeq(k=10, nu=0.18, constraint=s.constraint),
    )
    lawMatrix = c.GradientDamage(
        26738.0,
        0.18,
        s.constraint,
        c.DamageLawExponential(k0=3.4 / 26738.0,
                               alpha=0.99,
                               beta=3.4 / 26738.0 / 0.0216),
        c.ModMisesEeq(k=10, nu=0.18, constraint=s.constraint),
    )
    loop = c.IpLoop()
    loop.add_law(lawMatrix, np.where(s.ip_flags == 1)[0])
    loop.add_law(lawAggreg, np.where(s.ip_flags == 2)[0])
    loop.add_law(lawInterf, np.where(s.ip_flags == 3)[0])
    loop.resize(s.n)

    bot = boundary.plane_at(0, "y")
    top = boundary.plane_at(LY, "y")
    bc_expr = df.Expression("u", degree=0, u=0)
    bcs = []
    bcs.append(df.DirichletBC(s.Vd.sub(1), bc_expr, top))
    bcs.append(df.DirichletBC(s.Vd.sub(1), 0.0, bot))
    bcs.append(
        df.DirichletBC(s.Vd.sub(0),
                       0.0,
                       boundary.point_at((0, 0)),
                       method="pointwise"))

    # return

    assembler = df.SystemAssembler(dR, R, bcs)

    class SolveMe(df.NonlinearProblem):
        def F(self, b, x):
            calculate_eps(s.q_in[Q.EPS])
            calculate_e(s.q_in[Q.E])
            loop.evaluate(s.q_in[Q.EPS].vector().get_local(),
                          s.q_in[Q.E].vector().get_local())

            # ... and write the calculated values into their quadrature spaces.
            c.helper.set_q(s.q[Q.SIGMA], loop.get(c.Q.SIGMA))
            c.helper.set_q(s.q[Q.DSIGMA_DEPS], loop.get(c.Q.DSIGMA_DEPS))
            c.helper.set_q(s.q[Q.DEEQ], loop.get(c.Q.DEEQ))
            c.helper.set_q(s.q[Q.DSIGMA_DE], loop.get(c.Q.DSIGMA_DE))
            c.helper.set_q(s.q[Q.EEQ], loop.get(c.Q.EEQ))

            assembler.assemble(b, x)

        def J(self, A, x):
            assembler.assemble(A)

    linear_solver = df.LUSolver("mumps")
    solver = df.NewtonSolver(df.MPI.comm_world, linear_solver,
                             df.PETScFactory.instance())
    solver.parameters["linear_solver"] = "mumps"
    solver.parameters["maximum_iterations"] = 10
    solver.parameters["error_on_nonconvergence"] = False

    problem = SolveMe()

    def solve(t, dt):
        print(t, dt)
        bc_expr.u = 0.1 * t
        # try:
        return solver.solve(problem, s.u.vector())
        # except:
        # return -1, False

    ld = c.helper.LoadDisplacementCurve(bcs[0])
    if not TEST:
        ld.show()
    if not ld.is_root:
        df.set_log_level(df.LogLevel.ERROR)

    fff = df.XDMFFile("output.xdmf")
    fff.parameters["functions_share_mesh"] = True
    fff.parameters["flush_output"] = True

    plot_space = df.FunctionSpace(s.mesh, "DG", 0)
    k = df.Function(plot_space, name="kappa")

    def pp(t):
        calculate_eps(s.q_in[Q.EPS])
        calculate_e(s.q_in[Q.E])
        loop.update(s.q_in[Q.EPS].vector().get_local(),
                    s.q_in[Q.E].vector().get_local())

        # this fixes XDMF time stamps
        import locale

        locale.setlocale(locale.LC_NUMERIC, "en_US.UTF-8")
        d, e = s.u.split(0)
        d.rename("disp", "disp")
        e.rename("e", "e")

        all_kappa = lawInterf.kappa() + lawMatrix.kappa()
        k.vector().set_local(all_kappa[::s.nq])

        fff.write(d, t)
        fff.write(e, t)
        fff.write(k, t)

        ld(t, df.assemble(R))

    t_end = 1.
    if TEST:
        t_end = 0.02
    TimeStepper(solve, pp, s.u).adaptive(t_end, dt=0.02)