def __init__(self, spaces, ess_bdr, block_offsets, rel_tol, abs_tol, iter, mu): # Array<Vector *> -> tuple super(RubberOperator, self).__init__(spaces[0].GetVSize() + spaces[1].GetVSize()) rhs = (None, None) self.spaces = spaces self.mu = mfem.ConstantCoefficient(mu) self.block_offsets = block_offsets Hform = mfem.BlockNonlinearForm(spaces) Hform.AddDomainIntegrator( mfem.IncompressibleNeoHookeanIntegrator(self.mu)) Hform.SetEssentialBC(ess_bdr, rhs) self.Hform = Hform a = mfem.BilinearForm(self.spaces[1]) one = mfem.ConstantCoefficient(1.0) a.AddDomainIntegrator(mfem.MassIntegrator(one)) a.Assemble() a.Finalize() pressure_mass = a.LoseMat() self.j_prec = JacobianPreconditioner(spaces, pressure_mass, block_offsets) j_gmres = mfem.GMRESSolver() j_gmres.iterative_mode = False j_gmres.SetRelTol(1e-12) j_gmres.SetAbsTol(1e-12) j_gmres.SetMaxIter(300) j_gmres.SetPrintLevel(0) j_gmres.SetPreconditioner(self.j_prec) self.j_solver = j_gmres newton_solver = mfem.NewtonSolver() # Set the newton solve parameters newton_solver.iterative_mode = True newton_solver.SetSolver(self.j_solver) newton_solver.SetOperator(self) newton_solver.SetPrintLevel(1) newton_solver.SetRelTol(rel_tol) newton_solver.SetAbsTol(abs_tol) newton_solver.SetMaxIter(iter) self.newton_solver = newton_solver
# 7. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x by projecting the exact # solution. Note that only values from the boundary edges will be used # when eliminating the non-homogeneous boundary condition to modify the # r.h.s. vector b. #from mfem.examples.ex3 import E_exact_cb x = mfem.GridFunction(fespace) E = E_exact() x.ProjectCoefficient(E); # 8. Set up the bilinear form corresponding to the EM diffusion operator # curl muinv curl + sigma I, by adding the curl-curl and the mass domain # integrators. muinv = mfem.ConstantCoefficient(1.0); sigma = mfem.ConstantCoefficient(1.0); a = mfem.BilinearForm(fespace); a.AddDomainIntegrator(mfem.CurlCurlIntegrator(muinv)); a.AddDomainIntegrator(mfem.VectorFEMassIntegrator(sigma)); # 9. Assemble the bilinear form and the corresponding linear system, # applying any necessary transformations such as: eliminating boundary # conditions, applying conforming constraints for non-conforming AMR, # static condensation, etc. if (static_cond): a.EnableStaticCondensation() a.Assemble(); A = mfem.SparseMatrix()
print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) # 5. Determine the list of true (i.e. conforming) essential boundary dofs. # In this example, the boundary conditions are defined by marking all # the boundary attributes from the mesh as essential (Dirichlet) and # converting them to a list of true dofs. ess_tdof_list = mfem.intArray() if mesh.bdr_attributes.Size() > 0: ess_bdr = mfem.intArray([1] * mesh.bdr_attributes.Max()) ess_bdr = mfem.intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) #6. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system, which in this case is (1,phi_i) where phi_i are # the basis functions in the finite element fespace. b = mfem.LinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble() #7. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero, # which satisfies the boundary conditions. x = mfem.GridFunction(fespace) x.Assign(0.0) #8. Set up the bilinear form a(.,.) on the finite element space # corresponding to the Laplacian operator -Delta, by adding the Diffusion # domain integrator. a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) #9. Assemble the bilinear form and the corresponding linear system, # applying any necessary transformations such as: eliminating boundary # conditions, applying conforming constraints for non-conforming AMR,
ess_bdr = intArray(mesh.bdr_attributes.Max()) if set_bc: ess_bdr.Assign(1) else: ess_bdr.Assign(0) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) b = mfem.LinearForm(fespace) f = f_exact() dd = mfem.VectorFEDomainLFIntegrator(f) b.AddDomainIntegrator(dd) b.Assemble() x = mfem.GridFunction(fespace) F = E_exact() x.ProjectCoefficient(F) alpha = mfem.ConstantCoefficient(1.0) beta = mfem.ConstantCoefficient(1.0) a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DivDivIntegrator(alpha)) a.AddDomainIntegrator(mfem.VectorFEMassIntegrator(beta)) if (static_cond): a.EnableStaticCondensation() elif (hybridization): hfec = mfem.DG_Interface_FECollection(order - 1, dim) hfes = mfem.FiniteElementSpace(mesh, hfec) a.EnableHybridization(hfes, mfem.NormalTraceJumpIntegrator(), ess_tdof_list) a.Assemble() A = mfem.SparseMatrix() B = mfem.Vector()
def run(order=1, static_cond=False, meshfile=def_meshfile, visualization=False): mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() # 3. Refine the mesh to increase the resolution. In this example we do # 'ref_levels' of uniform refinement. We choose 'ref_levels' to be the # largest number that gives a final mesh with no more than 50,000 # elements. ref_levels = int(np.floor( np.log(50000. / mesh.GetNE()) / np.log(2.) / dim)) for x in range(ref_levels): mesh.UniformRefinement() #5. Define a finite element space on the mesh. Here we use vector finite # elements, i.e. dim copies of a scalar finite element space. The vector # dimension is specified by the last argument of the FiniteElementSpace # constructor. For NURBS meshes, we use the (degree elevated) NURBS space # associated with the mesh nodes. if order > 0: fec = mfem.H1_FECollection(order, dim) elif mesh.GetNodes(): fec = mesh.GetNodes().OwnFEC() prinr("Using isoparametric FEs: " + str(fec.Name())) else: order = 1 fec = mfem.H1_FECollection(order, dim) fespace = mfem.FiniteElementSpace(mesh, fec) print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) # 5. Determine the list of true (i.e. conforming) essential boundary dofs. # In this example, the boundary conditions are defined by marking all # the boundary attributes from the mesh as essential (Dirichlet) and # converting them to a list of true dofs. ess_tdof_list = mfem.intArray() if mesh.bdr_attributes.Size() > 0: ess_bdr = mfem.intArray([1] * mesh.bdr_attributes.Max()) ess_bdr = mfem.intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) #6. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system, which in this case is (1,phi_i) where phi_i are # the basis functions in the finite element fespace. b = mfem.LinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble() #7. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero, # which satisfies the boundary conditions. x = mfem.GridFunction(fespace) x.Assign(0.0) #8. Set up the bilinear form a(.,.) on the finite element space # corresponding to the Laplacian operator -Delta, by adding the Diffusion # domain integrator. a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) #9. Assemble the bilinear form and the corresponding linear system, # applying any necessary transformations such as: eliminating boundary # conditions, applying conforming constraints for non-conforming AMR, # static condensation, etc. if static_cond: a.EnableStaticCondensation() a.Assemble() A = mfem.OperatorPtr() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) print("Size of linear system: " + str(A.Height())) # 10. Solve AA = mfem.OperatorHandle2SparseMatrix(A) M = mfem.GSSmoother(AA) mfem.PCG(AA, M, B, X, 1, 200, 1e-12, 0.0) # 11. Recover the solution as a finite element grid function. a.RecoverFEMSolution(X, b, x) # 12. Save the refined mesh and the solution. This output can be viewed later # using GLVis: "glvis -m refined.mesh -g sol.gf". mesh.Print('refined.mesh', 8) x.Save('sol.gf', 8) #13. Send the solution by socket to a GLVis server. if (visualization): sol_sock = mfem.socketstream("localhost", 19916) sol_sock.precision(8) sol_sock.send_solution(mesh, x)
for i in range(2): mesh.UniformRefinement() mesh.SetCurvature(2) # 4. Define a finite element space on the mesh. The polynomial order is # one (linear) by default, but this can be changed on the command line. fec = mfem.H1_FECollection(order, dim) fespace = mfem.FiniteElementSpace(mesh, fec) # 5. As in Example 1, we set up bilinear and linear forms corresponding to # the Laplace problem -\Delta u = 1. We don't assemble the discrete # problem yet, this will be done in the main loop. a = mfem.BilinearForm(fespace) b = mfem.LinearForm(fespace) one = mfem.ConstantCoefficient(1.0) zero = mfem.ConstantCoefficient(0.0) integ = mfem.DiffusionIntegrator(one) a.AddDomainIntegrator(integ) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) # 6. The solution vector x and the associated finite element grid function # will be maintained over the AMR iterations. We initialize it to zero. x = mfem.GridFunction(fespace) x.Assign(0.0) # 7. All boundary attributes will be used for essential (Dirichlet) BC. ess_bdr = intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1)
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)
# boundary attribute 1 from the mesh as essential and converting it to a # list of true dofs. ess_tdof_list = intArray() ess_bdr = intArray([1] + [0] * (mesh.bdr_attributes.Max() - 1)) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 7. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system. In this case, b_i equals the boundary integral # of f*phi_i where f represents a "pull down" force on the Neumann part # of the boundary and phi_i are the basis functions in the finite element # fespace. The force is defined by the VectorArrayCoefficient object f, # which is a vector of Coefficient objects. The fact that f is non-zero # on boundary attribute 2 is indicated by the use of piece-wise constants # coefficient for its last component. f = mfem.VectorArrayCoefficient(dim) for i in range(dim - 1): f.Set(i, mfem.ConstantCoefficient(0.0)) pull_force = mfem.Vector([0] * mesh.bdr_attributes.Max()) pull_force[1] = -1.0e-2 f.Set(dim - 1, mfem.PWConstCoefficient(pull_force)) b = mfem.LinearForm(fespace) b.AddBoundaryIntegrator(mfem.VectorBoundaryLFIntegrator(f)) print('r.h.s...') b.Assemble() # 8. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero, # which satisfies the boundary conditions. x = mfem.GridFunction(fespace) x.Assign(0.0) # 9. Set up the bilinear form a(.,.) on the finite element space
def __init__(self, fespace, ess_bdr, visc, mu, K): mfem.PyTimeDependentOperator.__init__(self, 2 * fespace.GetVSize(), 0.0) rel_tol = 1e-8 skip_zero_entries = 0 ref_density = 1.0 self.z = mfem.Vector(self.Height() / 2) self.fespace = fespace self.viscosity = visc M = mfem.BilinearForm(fespace) S = mfem.BilinearForm(fespace) H = mfem.NonlinearForm(fespace) self.M = M self.H = H self.S = S rho = mfem.ConstantCoefficient(ref_density) M.AddDomainIntegrator(mfem.VectorMassIntegrator(rho)) M.Assemble(skip_zero_entries) M.EliminateEssentialBC(ess_bdr) M.Finalize(skip_zero_entries) M_solver = mfem.CGSolver() M_prec = mfem.DSmoother() M_solver.iterative_mode = False M_solver.SetRelTol(rel_tol) M_solver.SetAbsTol(0.0) M_solver.SetMaxIter(30) M_solver.SetPrintLevel(0) M_solver.SetPreconditioner(M_prec) M_solver.SetOperator(M.SpMat()) self.M_solver = M_solver self.M_prec = M_prec model = mfem.NeoHookeanModel(mu, K) H.AddDomainIntegrator(mfem.HyperelasticNLFIntegrator(model)) H.SetEssentialBC(ess_bdr) self.model = model visc_coeff = mfem.ConstantCoefficient(visc) S.AddDomainIntegrator(mfem.VectorDiffusionIntegrator(visc_coeff)) S.Assemble(skip_zero_entries) S.EliminateEssentialBC(ess_bdr) S.Finalize(skip_zero_entries) self.backward_euler_oper = BackwardEulerOperator(M, S, H) J_prec = mfem.DSmoother(1) J_minres = mfem.MINRESSolver() J_minres.SetRelTol(rel_tol) J_minres.SetAbsTol(0.0) J_minres.SetMaxIter(300) J_minres.SetPrintLevel(-1) J_minres.SetPreconditioner(J_prec) self.J_solver = J_minres self.J_prec = J_prec newton_solver = mfem.NewtonSolver() newton_solver.iterative_mode = False newton_solver.SetSolver(self.J_solver) newton_solver.SetOperator(self.backward_euler_oper) newton_solver.SetPrintLevel(1) #print Newton iterations newton_solver.SetRelTol(rel_tol) newton_solver.SetAbsTol(0.0) newton_solver.SetMaxIter(10) self.newton_solver = newton_solver