# the basis functions in the finite element fespace. class analytic_rhs(mfem.PyCoefficient): def EvalValue(self, x): l2 = np.sum(x**2) return 7. * x[0] * x[1] / l2 class analytic_solution(mfem.PyCoefficient): def EvalValue(self, x): l2 = np.sum(x**2) return x[0] * x[1] / l2 b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) rhs_coef = analytic_rhs() sol_coef = analytic_solution() b.AddDomainIntegrator(mfem.DomainLFIntegrator(rhs_coef)) b.Assemble() # 6. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero. x = mfem.ParGridFunction(fespace) 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 # and Mass domain integrators. a = mfem.ParBilinearForm(fespace)
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) trueX = mfem.BlockVector(block_trueOffsets) trueRhs = mfem.BlockVector(block_trueOffsets) fform = mfem.ParLinearForm() fform.Update(R_space, rhs.GetBlock(0), 0) fform.AddDomainIntegrator(mfem.VectorFEDomainLFIntegrator(fcoeff)) fform.AddBoundaryIntegrator(mfem.VectorFEBoundaryFluxLFIntegrator(fnatcoeff)) fform.Assemble() fform.ParallelAssemble(trueRhs.GetBlock(0)) gform = mfem.ParLinearForm() gform.Update(W_space, rhs.GetBlock(1), 0) gform.AddDomainIntegrator(mfem.DomainLFIntegrator(gcoeff)) gform.Assemble() gform.ParallelAssemble(trueRhs.GetBlock(1)) mVarf = mfem.ParBilinearForm(R_space) bVarf = mfem.ParMixedBilinearForm(R_space, W_space)
def run(order = 1, static_cond = False, meshfile = def_meshfile, visualization = False, use_strumpack = False): mesh = mfem.Mesh(meshfile, 1,1) dim = mesh.Dimension() ref_levels = int(np.floor(np.log(10000./mesh.GetNE())/np.log(2.)/dim)) for x in range(ref_levels): mesh.UniformRefinement(); mesh.ReorientTetMesh(); pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh par_ref_levels = 2 for l in range(par_ref_levels): pmesh.UniformRefinement(); if order > 0: fec = mfem.H1_FECollection(order, dim) elif mesh.GetNodes(): fec = mesh.GetNodes().OwnFEC() print( "Using isoparametric FEs: " + str(fec.Name())); else: order = 1 fec = mfem.H1_FECollection(order, dim) fespace =mfem.ParFiniteElementSpace(pmesh, fec) fe_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of finite element unknowns: '+ str(fe_size)) ess_tdof_list = mfem.intArray() if pmesh.bdr_attributes.Size()>0: ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # the basis functions in the finite element fespace. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble(); x = mfem.ParGridFunction(fespace); x.Assign(0.0) a = mfem.ParBilinearForm(fespace); a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) if static_cond: a.EnableStaticCondensation() a.Assemble(); A = mfem.HypreParMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) if (myid == 0): print("Size of linear system: " + str(x.Size())) print("Size of linear system: " + str(A.GetGlobalNumRows())) if use_strumpack: import mfem.par.strumpack as strmpk Arow = strmpk.STRUMPACKRowLocMatrix(A) args = ["--sp_hss_min_sep_size", "128", "--sp_enable_hss"] strumpack = strmpk.STRUMPACKSolver(args, MPI.COMM_WORLD) strumpack.SetPrintFactorStatistics(True) strumpack.SetPrintSolveStatistics(False) strumpack.SetKrylovSolver(strmpk.KrylovSolver_DIRECT); strumpack.SetReorderingStrategy(strmpk.ReorderingStrategy_METIS) strumpack.SetMC64Job(strmpk.MC64Job_NONE) # strumpack.SetSymmetricPattern(True) strumpack.SetOperator(Arow) strumpack.SetFromCommandLine() strumpack.Mult(B, X); else: amg = mfem.HypreBoomerAMG(A) cg = mfem.CGSolver(MPI.COMM_WORLD) cg.SetRelTol(1e-12) cg.SetMaxIter(200) cg.SetPrintLevel(1) cg.SetPreconditioner(amg) cg.SetOperator(A) cg.Mult(B, X); a.RecoverFEMSolution(X, b, x) smyid = '{:0>6d}'.format(myid) mesh_name = "mesh."+smyid sol_name = "sol."+smyid pmesh.Print(mesh_name, 8) x.Save(sol_name, 8)
def run(order = 1, static_cond = False, meshfile = def_meshfile, visualization = False): mesh = mfem.Mesh(meshfile, 1,1) dim = mesh.Dimension() ref_levels = int(np.floor(np.log(10000./mesh.GetNE())/np.log(2.)/dim)) for x in range(ref_levels): mesh.UniformRefinement(); mesh.ReorientTetMesh(); pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh par_ref_levels = 2 for l in range(par_ref_levels): pmesh.UniformRefinement(); 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.ParFiniteElementSpace(pmesh, fec) fe_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of finite element unknowns: '+ str(fe_size)) ess_tdof_list = mfem.intArray() if pmesh.bdr_attributes.Size()>0: ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # the basis functions in the finite element fespace. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble(); x = mfem.ParGridFunction(fespace); x.Assign(0.0) a = mfem.ParBilinearForm(fespace); a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) if static_cond: a.EnableStaticCondensation() a.Assemble(); A = mfem.HypreParMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) if (myid == 0): print("Size of linear system: " + str(x.Size())) print("Size of linear system: " + str(A.GetGlobalNumRows())) amg = mfem.HypreBoomerAMG(A) pcg = mfem.HyprePCG(A) pcg.SetTol(1e-12) pcg.SetMaxIter(200) pcg.SetPrintLevel(2) pcg.SetPreconditioner(amg) pcg.Mult(B, X); a.RecoverFEMSolution(X, b, x) smyid = '{:0>6d}'.format(myid) mesh_name = "mesh."+smyid sol_name = "sol."+smyid pmesh.PrintToFile(mesh_name, 8) x.SaveToFile(sol_name, 8)
# interior faces. velocity = velocity_coeff(dim) inflow = inflow_coeff() u0 = u0_coeff() m = mfem.ParBilinearForm(fes) m.AddDomainIntegrator(mfem.MassIntegrator()) k = mfem.ParBilinearForm(fes) k.AddDomainIntegrator(mfem.ConvectionIntegrator(velocity, -1.0)) k.AddInteriorFaceIntegrator( mfem.TransposeIntegrator(mfem.DGTraceIntegrator(velocity, 1.0, -0.5))) k.AddBdrFaceIntegrator( mfem.TransposeIntegrator(mfem.DGTraceIntegrator(velocity, 1.0, -0.5))) b = mfem.ParLinearForm(fes) b.AddBdrFaceIntegrator( mfem.BoundaryFlowIntegrator(inflow, velocity, -1.0, -0.5)) m.Assemble() m.Finalize() skip_zeros = 0 k.Assemble(skip_zeros) k.Finalize(skip_zeros) b.Assemble() M = m.ParallelAssemble() K = k.ParallelAssemble() B = b.ParallelAssemble() # 7. Define the initial conditions, save the corresponding grid function to
glob_true_s_test = test_space.GlobalTrueVSize() if myid == 0: print('\n'.join([ "nNumber of Unknowns", " Trial space, X0 : " + str(glob_true_s0) + " (order " + str(trial_order) + ")", " Interface space, Xhat : " + str(glob_true_s1) + " (order " + str(trace_order) + ")", " Test space, Y : " + str(glob_true_s_test) + " (order " + str(test_order) + ")" ])) # 7. 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.ParLinearForm(test_space) F.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) F.Assemble() x0 = mfem.ParGridFunction(x0_space) x0.Assign(0.0) # 8. 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(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) ess_dof = mfem.intArray() x0_space.GetEssentialVDofs(ess_bdr, ess_dof)