print("dim(W) = " + str(dimW)) print("dim(R+W) = " + str(dimR + dimW)) print("***********************************************************") block_offsets = intArray([0, dimR, dimW]) block_offsets.PartialSum() k = mfem.ConstantCoefficient(1.0) fcoeff = fFunc(dim) fnatcoeff = f_natural() gcoeff = gFunc() ucoeff = uFunc_ex(dim) pcoeff = pFunc_ex() x = mfem.BlockVector(block_offsets) rhs = mfem.BlockVector(block_offsets) fform = mfem.LinearForm() fform.Update(R_space, rhs.GetBlock(0), 0) fform.AddDomainIntegrator(mfem.VectorFEDomainLFIntegrator(fcoeff)) fform.AddBoundaryIntegrator(mfem.VectorFEBoundaryFluxLFIntegrator(fnatcoeff)) fform.Assemble() gform = mfem.LinearForm() gform.Update(W_space, rhs.GetBlock(1), 0) gform.AddDomainIntegrator(mfem.DomainLFIntegrator(gcoeff)) gform.Assemble() mVarf = mfem.BilinearForm(R_space) bVarf = mfem.MixedBilinearForm(R_space, W_space)
def ex19_main(args): ref_levels = args.refine order = args.order visualization = args.visualization mu = args.shear_modulus newton_rel_tol = args.relative_tolerance newton_abs_tol = args.absolute_tolerance newton_iter = args.newton_iterations parser.print_options(args) meshfile = expanduser(join(path, 'data', args.mesh)) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() for lev in range(ref_levels): mesh.UniformRefinement() # 4. Define the shear modulus for the incompressible Neo-Hookean material c_mu = mfem.ConstantCoefficient(mu) # 5. Define the finite element spaces for displacement and pressure # (Taylor-Hood elements). By default, the displacement (u/x) is a second # order vector field, while the pressure (p) is a linear scalar function. quad_coll = mfem.H1_FECollection(order, dim) lin_coll = mfem.H1_FECollection(order - 1, dim) R_space = mfem.FiniteElementSpace(mesh, quad_coll, dim, mfem.Ordering.byVDIM) W_space = mfem.FiniteElementSpace(mesh, lin_coll) spaces = [R_space, W_space] R_size = R_space.GetVSize() W_size = W_space.GetVSize() # 6. Define the Dirichlet conditions (set to boundary attribute 1 and 2) ess_bdr_u = mfem.intArray(R_space.GetMesh().bdr_attributes.Max()) ess_bdr_p = mfem.intArray(W_space.GetMesh().bdr_attributes.Max()) ess_bdr_u.Assign(0) ess_bdr_u[0] = 1 ess_bdr_u[1] = 1 ess_bdr_p.Assign(0) ess_bdr = [ess_bdr_u, ess_bdr_p] print("***********************************************************") print("dim(u) = " + str(R_size)) print("dim(p) = " + str(W_size)) print("dim(u+p) = " + str(R_size + W_size)) print("***********************************************************") block_offsets = intArray([0, R_size, W_size]) block_offsets.PartialSum() xp = mfem.BlockVector(block_offsets) # 9. Define grid functions for the current configuration, reference # configuration, final deformation, and pressure x_gf = mfem.GridFunction(R_space) x_ref = mfem.GridFunction(R_space) x_def = mfem.GridFunction(R_space) p_gf = mfem.GridFunction(W_space) x_gf.MakeRef(R_space, xp.GetBlock(0), 0) p_gf.MakeRef(W_space, xp.GetBlock(1), 0) deform = InitialDeformation(dim) refconfig = ReferenceConfiguration(dim) x_gf.ProjectCoefficient(deform) x_ref.ProjectCoefficient(refconfig) p_gf.Assign(0.0) # 10. Initialize the incompressible neo-Hookean operator oper = RubberOperator(spaces, ess_bdr, block_offsets, newton_rel_tol, newton_abs_tol, newton_iter, mu) # 11. Solve the Newton system oper.Solve(xp) # 12. Compute the final deformation mfem.subtract_vector(x_gf, x_ref, x_def) # 13. Visualize the results if requested if (visualization): vis_u = mfem.socketstream("localhost", 19916) visualize(vis_u, mesh, x_gf, x_def, "Deformation", True) vis_p = mfem.socketstream("localhost", 19916) visualize(vis_p, mesh, x_gf, p_gf, "Deformation", True) # 14. Save the displaced mesh, the final deformation, and the pressure nodes = x_gf owns_nodes = 0 nodes, owns_nodes = mesh.SwapNodes(nodes, owns_nodes) mesh.Print('deformed.mesh', 8) p_gf.Save('pressure.sol', 8) x_def.Save("deformation.sol", 8)
mesh.UniformRefinement() # 5. Define the vector finite element spaces representing the mesh # deformation x, the velocity v, and the initial configuration, x_ref. # Define also the elastic energy density, w, which is in a discontinuous # higher-order space. Since x and v are integrated in time as a system, # we group them together in block vector vx, with offsets given by the # fe_offset array. fec = mfem.H1_FECollection(order, dim) fespace = mfem.FiniteElementSpace(mesh, fec, dim) fe_size = fespace.GetVSize() print("Number of velocity/deformation unknowns: " + str(fe_size)) fe_offset = intArray([0, fe_size, 2 * fe_size]) vx = mfem.BlockVector(fe_offset) x = mfem.GridFunction() v = mfem.GridFunction() v.MakeRef(fespace, vx.GetBlock(0), 0) x.MakeRef(fespace, vx.GetBlock(1), 0) x_ref = mfem.GridFunction(fespace) mesh.GetNodes(x_ref) w_fec = mfem.L2_FECollection(order + 1, dim) w_fespace = mfem.FiniteElementSpace(mesh, w_fec) w = mfem.GridFunction(w_fespace) # 6. Set the initial conditions for v and x, and the boundary conditions on # a beam-like mesh (see description above).
# Finite element space for a mesh-dim vector quantity (momentum) dfes = mfem.FiniteElementSpace(mesh, fec, dim, mfem.Ordering.byNODES) # Finite element space for all variables together (total thermodynamic state) vfes = mfem.FiniteElementSpace(mesh, fec, num_equation, mfem.Ordering.byNODES) assert fes.GetOrdering() == mfem.Ordering.byNODES, "Ordering must be byNODES" print("Number of unknowns: " + str(vfes.GetVSize())) # 6. Define the initial conditions, save the corresponding mesh and grid # functions to a file. This can be opened with GLVis with the -gc option. # The solution u has components {density, x-momentum, y-momentum, energy}. # These are stored contiguously in the BlockVector u_block. offsets = [k * vfes.GetNDofs() for k in range(num_equation + 1)] offsets = mfem.intArray(offsets) u_block = mfem.BlockVector(offsets) mom = mfem.GridFunction(dfes, u_block, offsets[1]) # # Define coefficient using VecotrPyCoefficient and PyCoefficient # A user needs to define EvalValue method # u0 = InitialCondition(num_equation) sol = mfem.GridFunction(vfes, u_block.GetData()) sol.ProjectCoefficient(u0) mesh.PrintToFile("vortex.mesh", 8) for k in range(num_equation): uk = mfem.GridFunction(fes, u_block.GetBlock(k).GetData()) sol_name = "vortex-" + str(k) + "-init.gf" uk.SaveToFile(sol_name, 8)
s0 = x0_space.GetVSize() s1 = xhat_space.GetVSize() s_test = test_space.GetVSize() offsets = mfem.intArray([0, s0, s0+s1]) offsets_test = mfem.intArray([0, s_test]) print('\n'.join(["nNumber of Unknowns", " Trial space, X0 : " + str(s0) + " (order " + str(trial_order) + ")", " Interface space, Xhat : " + str(s1) + " (order " + str(trace_order) + ")", " Test space, Y : " + str(s_test) + " (order " + str(test_order) + ")"])) x = mfem.BlockVector(offsets) b = mfem.BlockVector(offsets) x.Assign(0.0) # 6. Set up the linear form F(.) which corresponds to the right-hand side of # the FEM linear system, which in this case is (f,phi_i) where f=1.0 and # phi_i are the basis functions in the test finite element fespace. one = mfem.ConstantCoefficient(1.0) F = mfem.LinearForm(test_space); F.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) F.Assemble(); # 7. Set up the mixed bilinear form for the primal trial unknowns, B0, # the mixed bilinear form for the interfacial unknowns, Bhat, # the inverse stiffness matrix on the discontinuous test space, Sinv, # and the stiffness matrix on the continuous trial space, S0.