|
| 1 | +using Exodus |
| 2 | +using FiniteElementContainers |
| 3 | +using Tensors |
| 4 | + |
| 5 | +fixed(_, _) = 0. |
| 6 | +displace(_, t) = 1.0 * t |
| 7 | + |
| 8 | +struct Mechanics{Form} <: AbstractPhysics{2, 0, 0} |
| 9 | + formulation::Form |
| 10 | +end |
| 11 | + |
| 12 | +function strain_energy(∇u) |
| 13 | + E = 1.e9 |
| 14 | + ν = 0.25 |
| 15 | + K = E / (3. * (1. - 2. * ν)) |
| 16 | + G = E / (2. * (1. + ν)) |
| 17 | + |
| 18 | + ε = symmetric(∇u) |
| 19 | + ψ = 0.5 * K * tr(ε)^2 + G * dcontract(dev(ε), dev(ε)) |
| 20 | +end |
| 21 | + |
| 22 | +function FiniteElementContainers.residual(physics::Mechanics, cell, u_el, args...) |
| 23 | + (; X_q, N, ∇N_X, JxW) = cell |
| 24 | + |
| 25 | + # kinematics |
| 26 | + ∇u_q = u_el * ∇N_X |
| 27 | + ∇u_q = modify_field_gradients(physics.formulation, ∇u_q) |
| 28 | + # constitutive |
| 29 | + P_q = gradient(strain_energy, ∇u_q) |
| 30 | + # turn into voigt notation |
| 31 | + P_q = extract_stress(physics.formulation, P_q) |
| 32 | + G_q = discrete_gradient(physics.formulation, ∇N_X) |
| 33 | + f_q = G_q * P_q |
| 34 | + return JxW * f_q[:] |
| 35 | + # return f_q |
| 36 | +end |
| 37 | + |
| 38 | +function FiniteElementContainers.stiffness(physics::Mechanics, cell, u_el, args...) |
| 39 | + (; X_q, N, ∇N_X, JxW) = cell |
| 40 | + |
| 41 | + # kinematics |
| 42 | + ∇u_q = u_el * ∇N_X |
| 43 | + ∇u_q = modify_field_gradients(physics.formulation, ∇u_q) |
| 44 | + # constitutive |
| 45 | + K_q = hessian(z -> strain_energy(z), ∇u_q) |
| 46 | + # turn into voigt notation |
| 47 | + K_q = extract_stiffness(physics.formulation, K_q) |
| 48 | + G_q = discrete_gradient(physics.formulation, ∇N_X) |
| 49 | + return JxW * G_q * K_q * G_q' |
| 50 | +end |
| 51 | + |
| 52 | +function mechanics_test() |
| 53 | + mesh = UnstructuredMesh("cube.g") |
| 54 | + V = FunctionSpace(mesh, H1Field, Lagrange) |
| 55 | + physics = (; |
| 56 | + cube=Mechanics(ThreeDimensional()) |
| 57 | + ) |
| 58 | + |
| 59 | + u = VectorFunction(V, :displ) |
| 60 | + asm = SparseMatrixAssembler(H1Field, u) |
| 61 | + |
| 62 | + dbcs = DirichletBC[ |
| 63 | + DirichletBC("displ_x", "ssx-", fixed), |
| 64 | + DirichletBC("displ_y", "ssy-", fixed), |
| 65 | + DirichletBC("displ_z", "ssz-", fixed), |
| 66 | + DirichletBC("displ_z", "ssz+", displace), |
| 67 | + ] |
| 68 | + |
| 69 | + # pre-setup some scratch arrays |
| 70 | + times = TimeStepper(0., 1., 10) |
| 71 | + p = create_parameters(asm, physics; dirichlet_bcs=dbcs, times=times) |
| 72 | + |
| 73 | + solver = NewtonSolver(IterativeLinearSolver(asm, :CgSolver)) |
| 74 | + integrator = QuasiStaticIntegrator(solver) |
| 75 | + pp = PostProcessor(mesh, "cube.e", u) |
| 76 | + |
| 77 | + write_times(pp, 1, p.times.time_current[1]) |
| 78 | + write_field(pp, 1, p.h1_field) |
| 79 | + |
| 80 | + for n in 1:10 |
| 81 | + evolve!(integrator, p) |
| 82 | + write_times(pp, n, p.times.time_current[1]) |
| 83 | + write_field(pp, n, p.h1_field) |
| 84 | + end |
| 85 | + close(pp) |
| 86 | +end |
| 87 | + |
| 88 | +mechanics_test() |
0 commit comments