def apply_essential(self, engine, gf, kfes, real=False, **kwargs): mesh = engine.get_mesh(mm=self) ibdr = mesh.bdr_attributes.ToList() bdr_attr = [0] * mesh.bdr_attributes.Max() for idx in self._sel_index: bdr_attr[idx - 1] = 1 if kfes == 0: coeff1 = mfem.VectorArrayCoefficient(3) coeff1.Set(0, mfem.ConstantCoefficient(0.0)) coeff1.Set(1, mfem.ConstantCoefficient(0.0)) coeff1.Set(2, mfem.ConstantCoefficient(0.0)) gf.ProjectBdrCoefficientTangent(coeff1, mfem.intArray(bdr_attr))
def __init__(self, spaces, ess_bdr, block_offsets, rel_tol, abs_tol, iter, mu): # Array<Vector *> -> tuple super(RubberOperator, self).__init__(spaces[0].TrueVSize() + spaces[1].TrueVSize()) rhs = (None, None) self.spaces = spaces self.mu = mfem.ConstantCoefficient(mu) self.block_offsets = block_offsets Hform = mfem.ParBlockNonlinearForm(spaces) Hform.AddDomainIntegrator( mfem.IncompressibleNeoHookeanIntegrator(self.mu)) Hform.SetEssentialBC(ess_bdr, rhs) self.Hform = Hform a = mfem.ParBilinearForm(self.spaces[1]) one = mfem.ConstantCoefficient(1.0) mass = mfem.OperatorHandle(mfem.Operator.Hypre_ParCSR) a.AddDomainIntegrator(mfem.MassIntegrator(one)) a.Assemble() a.Finalize() a.ParallelAssemble(mass) mass.SetOperatorOwner(False) pressure_mass = mass.Ptr() self.j_prec = JacobianPreconditioner(spaces, pressure_mass, block_offsets) j_gmres = mfem.GMRESSolver(MPI.COMM_WORLD) 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(MPI.COMM_WORLD) # 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
def assemble(self, *args, **kwargs): ''' integral() integral('boundary', [1,3]) # selection type and selection ''' engine = self._engine() self.process_kwargs(engine, kwargs) if len(args)>0: self._sel_mode = args[0] if len(args)>1: self._sel = args[1] lf1 = engine.new_lf(self._fes1()) one = mfem.ConstantCoefficient(1.0) coff = self.restrict_coeff(one, self._fes1()) if self._sel_mode == 'domain': intg = mfem.DomainLFIntegrator(coff) elif self._sel_mode == 'boundary': intg = mfem.BoundaryLFIntegrator(coff) else: assert False, "Selection Type must be either domain or boundary" lf1.AddDomainIntegrator(intg) lf1.Assemble() from mfem.common.chypre import LF2PyVec, PyVec2PyMat, MfemVec2PyVec v1 = MfemVec2PyVec(engine.b2B(lf1), None) v1 = PyVec2PyMat(v1) if not self._transpose: v1 = v1.transpose() return v1
def run_test(): #meshfile = expanduser(join(mfem_path, 'data', 'semi_circle.mesh')) meshfile = "../data/amr-quad.mesh" mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() sdim = mesh.SpaceDimension() fec = mfem.H1_FECollection(1, dim) fespace = mfem.FiniteElementSpace(mesh, fec, 1) print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) c = mfem.ConstantCoefficient(1.0) gf = mfem.GridFunction(fespace) gf.ProjectCoefficient(c) print("write mesh to STDOUT") mesh.Print(mfem.STDOUT) print("creat VTK file to file") mesh.PrintVTK('mesh.vtk', 1) print("creat VTK to STDOUT") mesh.PrintVTK(mfem.STDOUT, 1) print("save GridFunction to file") gf.Save('out_test_gridfunc.gf') gf.SaveVTK(mfem.wFILE('out_test_gridfunc1.vtk'), 'data', 1) print("save GridFunction to file in VTK format") gf.SaveVTK('out_test_gridfunc2.vtk', 'data', 1) print("Gridfunction to STDOUT") gf.Save(mfem.STDOUT) o = io.StringIO() count = gf.Save(o) count2 = gf.SaveVTK(o, 'data', 1) print("length of data ", count, count2) print('result: ', o.getvalue())
def updMassMatMS(self, elmLst, elmCompDiagMassMat, rho=1.0): self.M = mfem.ParBilinearForm(self.fespace) self.ro = mfem.ConstantCoefficient(rho) self.M.AddDomainIntegrator(mfem.VectorMassIntegrator(self.ro)) print("in updateMass") self.M.Assemble(0, elmLst, elmCompDiagMassMat, True, True) self.M.EliminateEssentialBC(self.vess_bdr) self.M.Finalize(0) self.Mmat = self.M.ParallelAssemble() self.M_solver.SetOperator(self.Mmat)
def apply_essential(self, engine, gf, real = False, kfes = 0): if kfes > 1: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) else: dprint1("Apply Ess.(imag)" + str(self._sel_index)) Erphiz = self.vt.make_value_or_expression(self) mesh = engine.get_mesh(mm = self) ibdr = mesh.bdr_attributes.ToList() bdr_attr = [0]*mesh.bdr_attributes.Max() for idx in self._sel_index: bdr_attr[idx-1] = 1 if kfes == 0: coeff1 = mfem.VectorArrayCoefficient(2) coeff1.Set(0, mfem.ConstantCoefficient(0.0)) coeff1.Set(1, mfem.ConstantCoefficient(0.0)) gf.ProjectBdrCoefficientTangent(coeff1, mfem.intArray(bdr_attr)) elif kfes == 1: coeff1 = mfem.ConstantCoefficient(0.0) gf.ProjectBdrCoefficient(coeff1, mfem.intArray(bdr_attr))
def run_test(): #meshfile =expanduser(join(mfem_path, 'data', 'beam-tri.mesh')) meshfile = expanduser(join(mfem_path, 'data', 'semi_circle.mesh')) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() sdim = mesh.SpaceDimension() fec = mfem.H1_FECollection(1, dim) fespace = mfem.FiniteElementSpace(mesh, fec, 1) print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) c = mfem.ConstantCoefficient(1.0) gf = mfem.GridFunction(fespace) gf.ProjectCoefficient(c) gf.Save('out_test_gridfunc.gf')
def apply_essential(self, engine, gf, real=False, kfes=0): if kfes > 0: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) else: dprint1("Apply Ess.(imag)" + str(self._sel_index)) mesh = engine.get_mesh(mm=self) ibdr = mesh.bdr_attributes.ToList() bdr_attr = [0] * mesh.bdr_attributes.Max() for idx in self._sel_index: bdr_attr[idx - 1] = 1 coeff1 = mfem.ConstantCoefficient(0.0) gf.ProjectBdrCoefficient(coeff1, mfem.intArray(bdr_attr))
def apply_essential(self, engine, gf, real = False, kfes = 0): if kfes == 0: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) coeff = mfem.ConstantCoefficient(float(self.psi0)) else: return #dprint1("Apply Ess.(imag)" + str(self._sel_index)) #coeff = mfem.ConstantCoefficient(complex(self.psi0).imag) coeff = self.restrict_coeff(coeff, engine) mesh = engine.get_mesh(mm = self) ibdr = mesh.bdr_attributes.ToList() bdr_attr = [0]*mesh.bdr_attributes.Max() ess_bdr = self.get_essential_idx(1) dprint1("Essential boundaries", ess_bdr) for idx in ess_bdr: bdr_attr[idx-1] = 1 gf.ProjectBdrCoefficient(coeff, mfem.intArray(bdr_attr))
def run_test(): #meshfile = expanduser(join(mfem_path, 'data', 'semi_circle.mesh')) meshfile = "../data/amr-quad.mesh" mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() sdim = mesh.SpaceDimension() fec = mfem.H1_FECollection(1, dim) fespace = mfem.FiniteElementSpace(mesh, fec, 1) print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) c = mfem.ConstantCoefficient(1.0) gf = mfem.GridFunction(fespace) gf.ProjectCoefficient(c) odata = gf.GetDataArray().copy() gf.Save("out_test_gz.gf") gf2 = mfem.GridFunction(mesh, "out_test_gz.gf") odata2 = gf2.GetDataArray().copy() check(odata, odata2, "text file does not agree with original") gf.Save("out_test_gz.gz") gf2.Assign(0.0) gf2 = mfem.GridFunction(mesh, "out_test_gz.gz") odata2 = gf2.GetDataArray().copy() check(odata, odata2, ".gz file does not agree with original") gf.Print("out_test_gz.dat") gf2.Assign(0.0) gf2.Load("out_test_gz.dat", gf.Size()) odata2 = gf2.GetDataArray().copy() check(odata, odata2, ".dat file does not agree with original") gf.Print("out_test_gz.dat.gz") gf2.Assign(0.0) gf2.Load("out_test_gz.dat.gz", gf.Size()) odata2 = gf2.GetDataArray().copy() check(odata, odata2, ".dat file does not agree with original (gz)") import gzip import io gf.Print("out_test_gz.dat2.gz") with gzip.open("out_test_gz.dat2.gz", 'rt') as f: sio = io.StringIO(f.read()) gf3 = mfem.GridFunction(fespace) gf3.Load(sio, gf.Size()) odata3 = gf3.GetDataArray().copy() check(odata, odata3, ".dat file does not agree with original(gz-io)") c = mfem.ConstantCoefficient(2.0) gf.ProjectCoefficient(c) odata = gf.GetDataArray().copy() o = io.StringIO() gf.Print(o) gf2.Load(o, gf.Size()) odata2 = gf2.GetDataArray().copy() check(odata, odata2, "StringIO does not agree with original") print("GridFunction .gf, .gz .dat and StringIO agree with original") mesh2 = mfem.Mesh() mesh.Print("out_test_gz.mesh") mesh2.Load("out_test_gz.mesh") check_mesh(mesh, mesh2, ".mesh does not agree with original") mesh2 = mfem.Mesh() mesh.Print("out_test_gz.mesh.gz") mesh2.Load("out_test_gz.mesh.gz") check_mesh(mesh, mesh2, ".mesh.gz does not agree with original") mesh3 = mfem.Mesh() mesh.PrintGZ("out_test_gz3.mesh") mesh3.Load("out_test_gz3.mesh") check_mesh(mesh, mesh3, ".mesh (w/o .gz exntension) does not agree with original") o = io.StringIO() mesh2 = mfem.Mesh() mesh.Print(o) mesh2.Load(o) check_mesh(mesh, mesh2, ".mesh.gz does not agree with original") print("Mesh .mesh, .mesh.gz and StringIO agree with original") print("PASSED")
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)
ess_tdof_list = mfem.intArray() ess_bdr.Assign(0) ess_bdr[0] = 1 fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 9. Set up the parallel 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 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] * pmesh.bdr_attributes.Max()) pull_force[1] = -1.0e-2 f.Set(dim - 1, mfem.PWConstCoefficient(pull_force)) b = mfem.ParLinearForm(fespace) b.AddBoundaryIntegrator(mfem.VectorBoundaryLFIntegrator(f)) print('r.h.s. ...') b.Assemble() # 10. Define the solution vector x as a parallel 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)
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_test(): print("Test complex_operator module") Nvert = 6 Nelem = 8 Nbelem = 2 mesh = mfem.Mesh(2, Nvert, Nelem, 2, 3) tri_v = [[1., 0., 0.], [0., 1., 0.], [-1., 0., 0.], [0., -1., 0.], [0., 0., 1.], [0., 0., -1.]] tri_e = [[0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4], [1, 0, 5], [2, 1, 5], [3, 2, 5], [0, 3, 5]] tri_l = [[1, 4], [1, 2]] for j in range(Nvert): mesh.AddVertex(tri_v[j]) for j in range(Nelem): mesh.AddTriangle(tri_e[j], 1) for j in range(Nbelem): mesh.AddBdrSegment(tri_l[j], 1) mesh.FinalizeTriMesh(1, 1, True) dim = mesh.Dimension() order = 1 fec = mfem.H1_FECollection(order, dim) if use_parallel: mesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) fes = mfem.ParFiniteElementSpace(mesh, fec) a1 = mfem.ParBilinearForm(fes) a2 = mfem.ParBilinearForm(fes) else: fes = mfem.FiniteElementSpace(mesh, fec) a1 = mfem.BilinearForm(fes) a2 = mfem.BilinearForm(fes) one = mfem.ConstantCoefficient(1.0) a1.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) a1.Assemble() a1.Finalize() a2.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) a2.Assemble() a2.Finalize() if use_parallel: M1 = a1.ParallelAssemble() M2 = a2.ParallelAssemble() M1.Print('M1') width = fes.GetTrueVSize() #X = mfem.HypreParVector(fes) #Y = mfem.HypreParVector(fes) #X.SetSize(fes.TrueVSize()) #Y.SetSize(fes.TrueVSize()) #from mfem.common.parcsr_extra import ToScipyCoo #MM1 = ToScipyCoo(M1) #print(MM1.toarray()) #print(MM1.dot(np.ones(6))) else: M1 = a1.SpMat() M2 = a2.SpMat() M1.Print('M1') width = fes.GetVSize() #X = mfem.Vector() #Y = mfem.Vector() #X.SetSize(M1.Width()) #Y.SetSize(M1.Height()) #from mfem.common.sparse_utils import sparsemat_to_scipycsr #MM1 = sparsemat_to_scipycsr(M1, np.float) #print(MM1.toarray()) #print(MM1.dot(np.ones(6))) #X.Assign(0.0) #X[0] = 1.0 #M1.Mult(X, Y) #print(Y.GetDataArray()) Mc = mfem.ComplexOperator(M1, M2, hermitan=True) offsets = mfem.intArray([0, width, width]) offsets.PartialSum() x = mfem.BlockVector(offsets) y = mfem.BlockVector(offsets) x.GetBlock(0).Assign(0) if myid == 0: x.GetBlock(0)[0] = 1.0 x.GetBlock(1).Assign(0) if myid == 0: x.GetBlock(1)[0] = 1.0 Mc.Mult(x, y) print("x", x.GetDataArray()) print("y", y.GetDataArray()) if myid == 0: x.GetBlock(1)[0] = -1.0 x.Print() Mc.Mult(x, y) print("x", x.GetDataArray()) print("y", y.GetDataArray())
# 9. 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. x = mfem.ParGridFunction(fespace) E = E_exact() x.ProjectCoefficient(E) # 10. 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.ParBilinearForm(fespace) a.AddDomainIntegrator(mfem.CurlCurlIntegrator(muinv)) a.AddDomainIntegrator(mfem.VectorFEMassIntegrator(sigma)) # 11. 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.HypreParMatrix() B = mfem.Vector() X = mfem.Vector()
def ex19_main(args): ser_ref_levels = args.refine_serial par_ref_levels = args.refine_parallel 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 if myid == 0: parser.print_options(args) meshfile = expanduser(join(path, 'data', args.mesh)) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() for lev in range(ser_ref_levels): mesh.UniformRefinement() pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh for lev in range(par_ref_levels): pmesh.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.ParFiniteElementSpace(pmesh, quad_coll, dim, mfem.Ordering.byVDIM) W_space = mfem.ParFiniteElementSpace(pmesh, lin_coll) spaces = [R_space, W_space] glob_R_size = R_space.GlobalTrueVSize() glob_W_size = W_space.GlobalTrueVSize() # 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] if myid == 0: print("***********************************************************") print("dim(u) = " + str(glob_R_size)) print("dim(p) = " + str(glob_W_size)) print("dim(u+p) = " + str(glob_R_size + glob_W_size)) print("***********************************************************") block_offsets = intArray([0, R_space.TrueVSize(), W_space.TrueVSize()]) 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.ParGridFunction(R_space) x_ref = mfem.ParGridFunction(R_space) x_def = mfem.ParGridFunction(R_space) p_gf = mfem.ParGridFunction(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) # 12. Set up the block solution vectors x_gf.GetTrueDofs(xp.GetBlock(0)) p_gf.GetTrueDofs(xp.GetBlock(1)) # 13. Initialize the incompressible neo-Hookean operator oper = RubberOperator(spaces, ess_bdr, block_offsets, newton_rel_tol, newton_abs_tol, newton_iter, mu) # 14. Solve the Newton system oper.Solve(xp) # 15. Distribute the shared degrees of freedom x_gf.Distribute(xp.GetBlock(0)) p_gf.Distribute(xp.GetBlock(1)) # 16. Compute the final deformation mfem.subtract_vector(x_gf, x_ref, x_def) # 17. Visualize the results if requested if (visualization): vis_u = mfem.socketstream("localhost", 19916) visualize(vis_u, pmesh, x_gf, x_def, "Deformation", True) MPI.COMM_WORLD.Barrier() vis_p = mfem.socketstream("localhost", 19916) visualize(vis_p, pmesh, 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 = pmesh.SwapNodes(nodes, owns_nodes) smyid = '.' + '{:0>6d}'.format(myid) pmesh.PrintToFile('deformed.mesh' + smyid, 8) p_gf.SaveToFile('pressure.sol' + smyid, 8) x_def.SaveToFile("deformation.sol" + smyid, 8)
def __init__(self, fespace, lmbda=1., mu=1., rho=1., visc=0.0, vess_tdof_list=None, vess_bdr=None, xess_tdof_list=None, xess_bdr=None, v_gfBdr=None, x_gfBdr=None, deform=None, velo=None, vx=None): mfem.PyTimeDependentOperator.__init__(self, 2 * fespace.GetTrueVSize(), 0.0) self.lmbda = lmbda self.mu = mu self.viscosity = visc self.deform = deform self.velo = velo self.x_gfBdr = x_gfBdr self.v_gfBdr = v_gfBdr self.vx = vx self.z = mfem.Vector(self.Height() / 2) self.z.Assign(0.0) self.w = mfem.Vector(self.Height() / 2) self.w.Assign(0.0) self.tmpVec = mfem.Vector(self.Height() / 2) self.tmpVec.Assign(0.0) self.fespace = fespace self.xess_bdr = xess_bdr self.vess_bdr = vess_bdr self.xess_tdof_list = xess_tdof_list self.vess_tdof_list = vess_tdof_list # setting up linear form cv = mfem.Vector(3) cv.Assign(0.0) #self.zero_coef = mfem.ConstantCoefficient(0.0) self.zero_coef = mfem.VectorConstantCoefficient(cv) self.bx = mfem.LinearForm(self.fespace) self.bx.AddDomainIntegrator( mfem.VectorBoundaryLFIntegrator(self.zero_coef)) self.bx.Assemble() self.bv = mfem.LinearForm(self.fespace) self.bv.AddDomainIntegrator( mfem.VectorBoundaryLFIntegrator(self.zero_coef)) self.bv.Assemble() self.Bx = mfem.Vector() self.Bv = mfem.Vector() # setting up bilinear forms self.M = mfem.ParBilinearForm(self.fespace) self.K = mfem.ParBilinearForm(self.fespace) self.S = mfem.ParBilinearForm(self.fespace) self.ro = mfem.ConstantCoefficient(rho) self.M.AddDomainIntegrator(mfem.VectorMassIntegrator(self.ro)) self.M.Assemble(0) self.M.EliminateEssentialBC(self.vess_bdr) self.M.Finalize(0) self.Mmat = self.M.ParallelAssemble() self.M_solver = mfem.CGSolver(self.fespace.GetComm()) self.M_solver.iterative_mode = False self.M_solver.SetRelTol(1e-8) self.M_solver.SetAbsTol(0.0) self.M_solver.SetMaxIter(30) self.M_solver.SetPrintLevel(0) self.M_prec = mfem.HypreSmoother() self.M_prec.SetType(mfem.HypreSmoother.Jacobi) self.M_solver.SetPreconditioner(self.M_prec) self.M_solver.SetOperator(self.Mmat) lambVec = mfem.Vector(self.fespace.GetMesh().attributes.Max()) print('Number of volume attributes : ' + str(self.fespace.GetMesh().attributes.Max())) lambVec.Assign(lmbda) lambVec[0] = lambVec[1] * 1.0 lambda_func = mfem.PWConstCoefficient(lambVec) muVec = mfem.Vector(self.fespace.GetMesh().attributes.Max()) muVec.Assign(mu) muVec[0] = muVec[1] * 1.0 mu_func = mfem.PWConstCoefficient(muVec) self.K.AddDomainIntegrator( mfem.ElasticityIntegrator(lambda_func, mu_func)) self.K.Assemble(0) # to set essential BC to zero value uncomment #self.K.EliminateEssentialBC(self.xess_bdr) #self.K.Finalize(0) #self.Kmat = self.K.ParallelAssemble() # to set essential BC to non-zero uncomment self.Kmat = mfem.HypreParMatrix() visc_coeff = mfem.ConstantCoefficient(visc) self.S.AddDomainIntegrator(mfem.VectorDiffusionIntegrator(visc_coeff)) self.S.Assemble(0) #self.S.EliminateEssentialBC(self.vess_bdr) #self.S.Finalize(0) #self.Smat = self.S.ParallelAssemble() self.Smat = mfem.HypreParMatrix() # VX solver for implicit time-stepping self.VX_solver = mfem.CGSolver(self.fespace.GetComm()) self.VX_solver.iterative_mode = False self.VX_solver.SetRelTol(1e-8) self.VX_solver.SetAbsTol(0.0) self.VX_solver.SetMaxIter(30) self.VX_solver.SetPrintLevel(0) self.VX_prec = mfem.HypreSmoother() self.VX_prec.SetType(mfem.HypreSmoother.Jacobi) self.VX_solver.SetPreconditioner(self.VX_prec) # setting up operators empty_tdof_list = intArray() self.S.FormLinearSystem(empty_tdof_list, self.v_gfBdr, self.bv, self.Smat, self.vx.GetBlock(0), self.Bv, 1) self.K.FormLinearSystem(empty_tdof_list, self.x_gfBdr, self.bx, self.Kmat, self.vx.GetBlock(1), self.Bx, 1)
def __init__(self, fespace, ess_bdr, visc, mu, K): mfem.PyTimeDependentOperator.__init__(self, 2 * fespace.TrueVSize(), 0.0) rel_tol = 1e-8 skip_zero_entries = 0 ref_density = 1.0 self.ess_tdof_list = intArray() self.z = mfem.Vector(self.Height() // 2) self.fespace = fespace self.viscosity = visc self.newton_solver = mfem.NewtonSolver(fespace.GetComm()) M = mfem.ParBilinearForm(fespace) S = mfem.ParBilinearForm(fespace) H = mfem.ParNonlinearForm(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) self.Mmat = M.ParallelAssemble() fespace.GetEssentialTrueDofs(ess_bdr, self.ess_tdof_list) self.Mmat.EliminateRowsCols(self.ess_tdof_list) M_solver = mfem.CGSolver(fespace.GetComm()) M_prec = mfem.HypreSmoother() M_solver.iterative_mode = False M_solver.SetRelTol(rel_tol) M_solver.SetAbsTol(0.0) M_solver.SetMaxIter(30) M_solver.SetPrintLevel(0) M_prec.SetType(mfem.HypreSmoother.Jacobi) M_solver.SetPreconditioner(M_prec) M_solver.SetOperator(self.Mmat) self.M_solver = M_solver self.M_prec = M_prec model = mfem.NeoHookeanModel(mu, K) H.AddDomainIntegrator(mfem.HyperelasticNLFIntegrator(model)) H.SetEssentialTrueDofs(self.ess_tdof_list) 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.reduced_oper = ReducedSystemOperator(M, S, H, self.ess_tdof_list) J_hypreSmoother = mfem.HypreSmoother() J_hypreSmoother.SetType(mfem.HypreSmoother.l1Jacobi) J_hypreSmoother.SetPositiveDiagonal(True) J_prec = J_hypreSmoother J_minres = mfem.MINRESSolver(fespace.GetComm()) 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(fespace.GetComm()) newton_solver.iterative_mode = False newton_solver.SetSolver(self.J_solver) newton_solver.SetOperator(self.reduced_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
b.Assemble() # 9. Define the solution vector x as a parallel finite element grid function # corresponding to fespace. Initialize x by projecting the exact # solution. Note that only values from the boundary faces will be used # when eliminating the non-homogeneous boundary condition to modify the # r.h.s. vector b. x = mfem.ParGridFunction(fespace) F = E_exact(sdim) x.ProjectCoefficient(F) # 10. Set up the parallel bilinear form corresponding to the H(div) # diffusion operator grad alpha div + beta I, by adding the div-div and # the mass domain integrators. alpha = mfem.ConstantCoefficient(1.0) beta = mfem.ConstantCoefficient(1.0) a = mfem.ParBilinearForm(fespace) a.AddDomainIntegrator(mfem.DivDivIntegrator(alpha)) a.AddDomainIntegrator(mfem.VectorFEMassIntegrator(beta)) # 11. Assemble the parallel bilinear form and the corresponding linear # system, applying any necessary transformations such as: parallel # assembly, eliminating boundary conditions, applying conforming # constraints for non-conforming AMR, static condensation, # hybridization, etc. if (static_cond): a.EnableStaticCondensation() elif (hybridization): hfec = mfem.DG_Interface_FECollection(order - 1, dim) hfes = mfem.ParFiniteElementSpace(mesh, hfec) a.EnableHybridization(hfes, mfem.NormalTraceJumpIntegrator(),
del mesh for x in range(par_ref_levels): pmesh.UniformRefinement() # 6. Define a parallel finite element space on the parallel mesh. Here we # use discontinuous finite elements of the specified order >= 0. fec = mfem.DG_FECollection(order, dim) fespace = mfem.ParFiniteElementSpace(pmesh, fec) glob_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of unknowns: ' + str(glob_size)) # 7. Set up the parallel linear form b(.) which corresponds to the # right-hand side of the FEM linear system. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) zero = mfem.ConstantCoefficient(0.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.AddBdrFaceIntegrator(mfem.DGDirichletLFIntegrator(zero, one, sigma, kappa)) b.Assemble() # 8. Define the solution vector x as a parallel finite element grid function # corresponding to fespace. Initialize x with initial guess of zero. x = mfem.ParGridFunction(fespace) x.Assign(0.0) # 9. 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 serial and parallel assembly we
ess_bdr.Assign(0); ess_bdr[0] = 1 fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) print("here") # 9. Set up the parallel 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 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. print dim f = mfem.VectorArrayCoefficient(dim) c1 = mfem.ConstantCoefficient(0.0); c2 = mfem.ConstantCoefficient(0.0); c3 = mfem.ConstantCoefficient(0.0); #for i in range(dim-1): f.Set(0, c1) f.Set(1, c2) print [0]*pmesh.bdr_attributes.Max() pull_force = mfem.Vector([0]*pmesh.bdr_attributes.Max()) pull_force[1] = -1.0e-2; pull_force.Print() c3 = mfem.PWConstCoefficient(pull_force) f.Set(dim-1, c3) b = mfem.ParLinearForm(fespace) '''
del mesh ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) # 6. 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.ParFiniteElementSpace(pmesh, fec) # 7. As in Example 1p, 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 inner loop. a = mfem.ParBilinearForm(fespace) b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) bdr = BdrCoefficient() rhs = RhsCoefficient() integ = mfem.DiffusionIntegrator(one) a.AddDomainIntegrator(integ) b.AddDomainIntegrator(mfem.DomainLFIntegrator(rhs)) # 8. The solution vector x and the associated finite element grid function # will be maintained over the AMR iterations. x = mfem.ParGridFunction(fespace) # 9. Connect to GLVis. if visualization: sout = mfem.socketstream("localhost", 19916) sout.precision(8)
def do_integration(expr, solvars, phys, mesh, kind, attrs, order, num): from petram.helper.variables import (Variable, var_g, NativeCoefficientGenBase, CoefficientVariable) from petram.phys.coefficient import SCoeff st = parser.expr(expr) code= st.compile('<string>') names = code.co_names g = {} #print solvars.keys() for key in phys._global_ns.keys(): g[key] = phys._global_ns[key] for key in solvars.keys(): g[key] = solvars[key] l = var_g.copy() ind_vars = ','.join(phys.get_independent_variables()) if kind == 'Domain': size = max(max(mesh.attributes.ToList()), max(attrs)) else: size = max(max(mesh.bdr_attributes.ToList()), max(attrs)) arr = [0]*(size) for k in attrs: arr[k-1] = 1 flag = mfem.intArray(arr) s = SCoeff(expr, ind_vars, l, g, return_complex=False) ## note L2 does not work for boundary....:D if kind == 'Domain': fec = mfem.L2_FECollection(order, mesh.Dimension()) else: fec = mfem.H1_FECollection(order, mesh.Dimension()) fes = mfem.FiniteElementSpace(mesh, fec) one = mfem.ConstantCoefficient(1) gf = mfem.GridFunction(fes) gf.Assign(0.0) if kind == 'Domain': gf.ProjectCoefficient(mfem.RestrictedCoefficient(s, flag)) else: gf.ProjectBdrCoefficient(mfem.RestrictedCoefficient(s, flag), flag) b = mfem.LinearForm(fes) one = mfem.ConstantCoefficient(1) if kind == 'Domain': itg = mfem.DomainLFIntegrator(one) b.AddDomainIntegrator(itg) else: itg = mfem.BoundaryLFIntegrator(one) b.AddBoundaryIntegrator(itg) b.Assemble() from petram.engine import SerialEngine en = SerialEngine() ans = mfem.InnerProduct(en.x2X(gf), en.b2B(b)) if not np.isfinite(ans): print("not finite", ans, arr) print(size, mesh.bdr_attributes.ToList()) from mfem.common.chypre import LF2PyVec, PyVec2PyMat, Array2PyVec, IdentityPyMat #print(list(gf.GetDataArray())) print(len(gf.GetDataArray()), np.sum(gf.GetDataArray())) print(np.sum(list(b.GetDataArray()))) return ans