def SetParameters(self, u): u_alpha_gf = mfem.GridFunction(self.fespace) u_alpha_gf.SetFromTrueDofs(u) for i in range(u_alpha_gf.Size()): u_alpha_gf[i] = self.kappa + self.alpha * u_alpha_gf[i] self.K = mfem.BilinearForm(self.fespace) u_coeff = mfem.GridFunctionCoefficient(u_alpha_gf) self.K.AddDomainIntegrator(mfem.DiffusionIntegrator(u_coeff)) self.K.Assemble() self.K.FormSystemMatrix(self.ess_tdof_list, self.Kmat) self.T = None
# 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.SparseMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) print("Size of linear system: " + str(A.Size())) # 10. Solve M = mfem.GSSmoother(A)
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)
# 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) # 9. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator # that uses the ComputeElementFlux method of the DiffusionIntegrator to # recover a smoothed flux (gradient) that is subtracted from the element
# create finite element function space fec = mfem.H1_FECollection(1, mesh.Dimension()) # H1 order=1 fespace = mfem.FiniteElementSpace(mesh, fec) # ess_tdof_list = mfem.intArray() ess_bdr = mfem.intArray([1] * mesh.bdr_attributes.Size()) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # constant coefficient one = mfem.ConstantCoefficient(1.0) # define Bilinear and Linear operator a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DiffusionIntegrator(sigma(2))) a.Assemble() b = mfem.LinearForm(fespace) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble() # create gridfunction, which is where the solution vector is stored x = mfem.GridFunction(fespace) x.Assign(0.0) # form linear equation (AX=B) 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()))
# 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. ess_bdr = mfem.intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1) B0 = mfem.MixedBilinearForm(x0_space,test_space); B0.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) B0.Assemble() B0.EliminateTrialDofs(ess_bdr, x.GetBlock(x0_var), F) B0.Finalize() Bhat = mfem.MixedBilinearForm(xhat_space,test_space) Bhat.AddTraceFaceIntegrator(mfem.TraceJumpIntegrator()) Bhat.Assemble() Bhat.Finalize() Sinv = mfem.BilinearForm(test_space) Sum = mfem.SumIntegrator() Sum.AddIntegrator(mfem.DiffusionIntegrator(one)) Sum.AddIntegrator(mfem.MassIntegrator(one)) Sinv.AddDomainIntegrator(mfem.InverseIntegrator(Sum)) Sinv.Assemble()