# conditions, applying conforming constraints for non-conforming AMR, # static condensation, etc. if (static_cond): a.EnableStaticCondensation() a.Assemble(); A = mfem.SparseMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B); ## Here, original version calls hegith, which is not ## defined in the header...!? print("Size of linear system: " + str(A.Size())) # 10. Solve M = mfem.GSSmoother(A) mfem.PCG(A, M, B, X, 1, 500, 1e-12, 0.0); # 11. Recover the solution as a finite element grid function. a.RecoverFEMSolution(X, b, x); # 12. Compute and print the L^2 norm of the error. print("|| E_h - E ||_{L^2} = " + str(x.ComputeL2Error(E))) mesh.PrintToFile('refined.mesh', 8) x.SaveToFile('sol.gf', 8)
A = mfem.SparseMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B); print('...done') A.PrintInfo(sys.stdout) # 11. Define a simple symmetric Gauss-Seidel preconditioner and use it to # solve the system Ax=b with PCG for the symmetric formulation, or GMRES # for the non-symmetric. M = mfem.GSSmoother(A) rtol = 1e-6 if (alpha == -1.0): mfem.PCG(A, M, B, X, 3, 5000, rtol*rtol, 0.0) else: mfem.GMRES(A, M, B, X, 3, 5000, 50, rtol*rtol, 0.0) # 12. Recover the solution as a finite element grid function 'x'. a.RecoverFEMSolution(X, b, x) # 13. Use the DG solution space as the mesh nodal space. This allows us to # save the displaced mesh as a curved DG mesh. mesh.SetNodalFESpace(fespace) reference_nodes = mfem.Vector() if (visualization): reference_nodes.Assign(mesh.GetNodes()) # 14. Save the displaced mesh and minus the solution (which gives the # backward displacements to the reference mesh). This output can be # viewed later using GLVis: "glvis -m displaced.mesh -g sol.gf".
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)
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() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) ## Here, original version calls hegith, which is not ## defined in the header...!? print("Size of linear system: " + str(A.Size())) # 10. Solve M = mfem.GSSmoother(A) mfem.PCG(A, M, B, X, 1, 10000, 1e-20, 0.0) # 11. Recover the solution as a finite element grid function. a.RecoverFEMSolution(X, b, x) print("|| F_h - F ||_{L^2} = " + str(x.ComputeL2Error(F))) mesh.PrintToFile('refined.mesh', 8) x.SaveToFile('sol.gf', 8)
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 14. Create the linear system: eliminate boundary conditions, constrain # hanging nodes and possibly apply other transformations. The system # will be solved for true (unconstrained) DOFs only. A = mfem.OperatorPtr() B = mfem.Vector() X = mfem.Vector() copy_interior = 1 a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior) # 15. Define a simple symmetric Gauss-Seidel preconditioner and use it to # solve the linear system with PCG. AA = mfem.OperatorHandle2SparseMatrix(A) M = mfem.GSSmoother(AA) mfem.PCG(AA, M, B, X, 3, 200, 1e-12, 0.0) # 16. After solving the linear system, reconstruct the solution as a # finite element GridFunction. Constrained nodes are interpolated # from true DOFs (it may therefore happen that x.Size() >= X.Size()). a.RecoverFEMSolution(X, b, x) if (cdofs > max_dofs): print("Reached the maximum number of dofs. Stop.") break # 18. Call the refiner to modify the mesh. The refiner calls the error # estimator to obtain element errors, then it selects elements to be # refined and finally it modifies the mesh. The Stop() method can be # used to determine if a stopping criterion was met. refiner.Apply(mesh) if (refiner.Stop()): print("Stopping criterion satisfied. Stop.")
b.Assemble() # 15. Project the exact solution to the essential boundary DOFs. x.ProjectBdrCoefficient(bdr, ess_bdr) # 16. Create and solve the linear system. ess_tdof_list = intArray() fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) A = mfem.OperatorPtr() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) AA = mfem.OperatorHandle2SparseMatrix(A) M = mfem.GSSmoother(AA) mfem.PCG(AA, M, B, X, 0, 500, 1e-12, 0.0) # 17. Extract the local solution on each processor. a.RecoverFEMSolution(X, b, x) # 18. Send the solution by socket to a GLVis server if visualization: sout.precision(8) sout.send_solution(mesh, x) # 19. Apply the refiner on the mesh. The refiner calls the error # estimator to obtain element errors, then it selects elements to # be refined and finally it modifies the mesh. The Stop() method # determines if all elements satisfy the local threshold. refiner.Apply(mesh) if refiner.Stop(): break
x.Assign(0.0) # 7. Set up the bilinear form a(.,.) on the finite element space # corresponding to the Laplacian operator -Delta, by adding the Diffusion # domain integrator and the interior and boundary DG face integrators. # Note that boundary conditions are imposed weakly in the form, so there # is no need for dof elimination. After assembly and finalizing we # extract the corresponding sparse matrix A. a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) a.AddInteriorFaceIntegrator(mfem.DGDiffusionIntegrator(one, sigma, kappa)) a.AddBdrFaceIntegrator(mfem.DGDiffusionIntegrator(one, sigma, kappa)) a.Assemble() a.Finalize() A = a.SpMat() # 8. Define a simple symmetric Gauss-Seidel preconditioner and use it to # solve the system Ax=b with PCG in the symmetric case, and GMRES in the # non-symmetric one. M = mfem.GSSmoother(A) if (sigma == -1.0): mfem.PCG(A, M, b, x, 1, 500, 1e-12, 0.0) else: mfem.GMRES(A, M, b, x, 1, 500, 10, 1e-12, 0.0) # 9. Save the refined mesh and the solution. This output can be viewed later # using GLVis: "glvis -m refined.mesh -g sol.gf". mesh.PrintToFile('refined.mesh', 8) x.SaveToFile('sol.gf', 8)
print('matrix...') static_cond = False if (static_cond): a.EnableStaticCondensation() a.Assemble() A = mfem.SparseMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) print('...done') ## Here, original version calls hegith, which is not ## defined in the header...!? print("Size of linear system: " + str(A.Size())) # 10. Solve M = mfem.GSSmoother(A) mfem.PCG(A, M, B, X, 1, 500, 1e-8, 0.0) # 11. Recover the solution as a finite element grid function. a.RecoverFEMSolution(X, b, x) # 13. For non-NURBS meshes, make the mesh curved based on the finite element # space. This means that we define the mesh elements through a fespace # based transformation of the reference element. This allows us to save # the displaced mesh as a curved mesh when using high-order finite # element displacement field. We assume that the initial mesh (read from # the file) is not higher order curved mesh compared to the chosen FE # space. if not mesh.NURBSext: mesh.SetNodalFESpace(fespace) # 14. Save the displaced mesh and the inverted solution (which gives the
Shatinv.SetPrintLevel(-1) Shatinv.SetRelTol(prec_rtol) Shatinv.SetMaxIter(prec_maxit) # Disable 'iterative_mode' when using CGSolver (or any IterativeSolver) as # a preconditioner: S0inv.iterative_mode = False Shatinv.iterative_mode = False P = mfem.BlockDiagonalPreconditioner(offsets) P.SetDiagonalBlock(0, S0inv) P.SetDiagonalBlock(1, Shatinv) # 10. Solve the normal equation system using the PCG iterative solver. # Check the weighted norm of residual for the DPG least square problem. # Wrap the primal variable in a GridFunction for visualization purposes. mfem.PCG(A, P, b, x, 1, 200, 1e-12, 0.0) LSres = mfem.Vector(s_test) B.Mult(x, LSres) LSres -= F res = sqrt(matSinv.InnerProduct(LSres, LSres)) print("|| B0*x0 + Bhat*xhat - F ||_{S^-1} = " + str(res)) x0 = mfem.GridFunction() x0.MakeRef(x0_space, x.GetBlock(x0_var), 0); # 11. 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) x0.Save('sol.gf', 8)