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])
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)
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)
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)