lamb.Assign(1.0) lamb[0] = 50. lambda_c = mfem.PWConstCoefficient(lamb) mu = mfem.Vector(mesh.attributes.Max()) mu.Assign(1.0); mu[0] = 50.0 mu_c = mfem.PWConstCoefficient(mu) # 8. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system. In this example, the linear form b(.) consists # only of the terms responsible for imposing weakly the Dirichlet # boundary conditions, over the attributes marked in 'dir_bdr'. The # values for the Dirichlet boundary condition are taken from the # VectorFunctionCoefficient 'x_init' which in turn is based on the # function 'InitDisplacement'. b = mfem.LinearForm(fespace) print('r.h.s ...') integrator = mfem.DGElasticityDirichletLFIntegrator(init_x, lambda_c, mu_c, alpha, kappa) b.AddBdrFaceIntegrator(integrator , dir_bdr) b.Assemble() # 9. Set up the bilinear form a(.,.) on the DG finite element space # corresponding to the linear elasticity integrator with coefficients # lambda and mu as defined above. The additional interior face integrator # ensures the weak continuity of the displacement field. The additional # boundary face integrator works together with the boundary integrator # added to the linear form b(.) to impose weakly the Dirichlet boundary # conditions. a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.ElasticityIntegrator(lambda_c, mu_c))
# interior faces. velocity = velocity_coeff(dim) inflow = inflow_coeff() u0 = u0_coeff() m = mfem.BilinearForm(fes) m.AddDomainIntegrator(mfem.MassIntegrator()) k = mfem.BilinearForm(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.LinearForm(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() # 7. Define the initial conditions, save the corresponding grid function to # a file u = mfem.GridFunction(fes) u.ProjectCoefficient(u0)
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)
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) mVarf.AddDomainIntegrator(mfem.VectorFEMassIntegrator(k)) mVarf.Assemble()
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. 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()