def surface_weight(refine, gtype): if (refine, gtype) in globals()['weight']: return globals()['weight'][(refine, gtype)] quad_v = [[0, 0], [1, 0], [1, 1], [0, 3]] quad_e = [[0, 1, 2, 3]] tri_v = [[0, 0], [1, 0], [0, 1]] tri_e = [[0, 1, 2,]] seg_v = [[0,], [1, ],] seg_e = [[0, 1,]] if gtype == mfem.Geometry.TRIANGLE: mesh = mfem.Mesh(2, 3, 1, 0, 2) for j in range(3): mesh.AddVertex(tri_v[j]) for j in range(1): mesh.AddTri(tri_e[j], 11) mesh.FinalizeTriMesh(1,1, True) elif gtype == mfem.Geometry.SQUARE: mesh = mfem.Mesh(2, 4, 1, 0, 2) for j in range(4): mesh.AddVertex(quad_v[j]) for j in range(1): mesh.AddQuad(quad_e[j], 11) mesh.FinalizeQuadMesh(1,1, True) elif gtype == mfem.Geometry.SEGMENT: mesh = mfem.Mesh(1, 2, 1, 0, 1) for j in range(2): mesh.AddVertex(seg_v[j]) for j in range(1): seg = mfem.Segment(seg_e[j], j+1) mesh.AddElement(seg) seg.thisown = False mesh.FinalizeTopology() mesh.Finalize(False, False) fec_type = mfem.H1_FECollection fe_coll = fec_type(1, 2) fes = mfem.FiniteElementSpace(mesh, fe_coll, 2) el = fes.GetFE(0) npt = Geom.GetVertices(gtype).GetNPoints() RefG = GR.Refine(gtype, refine) shape = mfem.Vector(el.GetDof()) ir = RefG.RefPts shapes =[] for i in range(ir.GetNPoints()): el.CalcShape(ir.IntPoint(i), shape) shapes.append(shape.GetDataArray().copy()) w = np.vstack(shapes) globals()['weight'][(refine, gtype)] = w return w
def run_test(): meshfile = expanduser(join(mfem_path, 'data', 'beam-tri.mesh')) mesh = mfem.Mesh(meshfile, 1, 1) fec = mfem.H1_FECollection(1, 1) fespace = mfem.FiniteElementSpace(mesh, fec) fespace.Save()
def test_course_to_file_map(): mesh_file = "../data/inline-quad.mesh" device = mfem.Device('cpu') mesh = mfem.Mesh(mesh_file, 1, 1) refinements = mfem.RefinementArray() refinements.Append(mfem.Refinement(0, 0b11)) refinements.Append(mfem.Refinement(1, 0b10)) refinements.Append(mfem.Refinement(2, 0b01)) mesh.GeneralRefinement(refinements) cft = mesh.GetRefinementTransforms() coarse_to_fine = mfem.Table() coarse_to_ref_type = mfem.intArray() ref_type_to_matrix = mfem.Table() ref_type_to_geom = mfem.GeometryTypeArray() cft.GetCoarseToFineMap(mesh, coarse_to_fine, coarse_to_ref_type, ref_type_to_matrix, ref_type_to_geom) print("coarse_to_fine element number mapping:") coarse_to_fine.Print() print("ref_type_to_geom mapping:") for i in range(ref_type_to_geom.Size()): g = ref_type_to_geom[i] print("ref_type: " + str(i) + "=> geom: " + str(g))
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 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 straight_line_mesh(lengths, nsegs, filename='', refine=False, fix_orientation=False, sdim=3, x0=0.0): Nvert = np.sum(nsegs) + 1 Nelem = np.sum(nsegs) Nbdrelem = len(lengths) + 1 mesh = mfem.Mesh(1, Nvert, Nelem, Nbdrelem, sdim) ivert = {} L = np.hstack(([0], np.cumsum(lengths))).astype(float) P = np.hstack(([0], np.cumsum(nsegs))).astype(int) X = [np.linspace(L[i], L[i + 1], n + 1)[1:] for i, n in enumerate(nsegs)] X = np.hstack(([0], np.hstack(X))) A = np.hstack([[i + 1] * n for i, n in enumerate(nsegs)]) for k, i in enumerate(P): ptx = mfem.Point(i) ptx.SetAttribute(k + 1) mesh.AddBdrElement(ptx) ptx.thisown = False for i in range(X.shape[0] - 1): seg = mfem.Segment((i, i + 1), A[i]) mesh.AddElement(seg) seg.thisown = False for i in range(X.shape[0]): pt = [0] * sdim pt[0] = X[i] + x0 mesh.AddVertex(pt) mesh.FinalizeTopology() mesh.Finalize(refine, fix_orientation) if filename != '': mesh.PrintToFile(filename, 8) return mesh
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 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)
def volume(mesh, in_attr, filename='', precision=8): ''' make a new mesh which contains only spedified attributes. note: 1) boundary elements are also copied and bdr_attributes are maintained 2) in parallel, new mesh must be geometrically continuous. this routine does not check it mesh must have sdim == 3: in_attr : domain attribute filename : an option to save the file return new volume mesh ''' in_attr = np.atleast_1d(in_attr) sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim != 3: assert False, "sdim must be three for volume mesh" if dim != 3: assert False, "sdim must be three for volume mesh" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, 'dom') v2s = mesh.extended_connectivity['vol2surf'] in_battr = np.unique(np.hstack([v2s[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_battr = np.unique(allgather_vector(in_battr)) bidx, battrs, bivert, nbverts, bbase = _collect_data(in_battr, mesh, 'bdr') iface = np.array([mesh.GetBdrElementEdgeIndex(i) for i in bidx], dtype=int) # note u is sorted unique u, indices = np.unique(np.hstack((ivert, bivert)), return_inverse=True) kbelem = np.array([True] * len(bidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, bivert = _gather_shared_vertex(mesh, u, shared_info, ivert, bivert) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) bivert = allgather_vector(bivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, bivert]), return_inverse=True) # # take care of shared boundary (face) # # 2018.11.28 # skip_adding is on. This basically skip shared_element # processing. Check em3d_TEwg7 if you need to remov this. # kbelem, battrs, nbverts, bbase, bivert = (_gather_shared_element( mesh, 'face', shared_info, iface, kbelem, battrs, nbverts, bbase, bivert, skip_adding=True)) #indices0 = np.array([np.where(u == biv)[0][0] for biv in ivert]) #bindices0 = np.array([np.where(u == biv)[0][0] for biv in bivert]) iv, ivi = np.unique(ivert, return_inverse=True) tmp = np.where(np.in1d(u, ivert, assume_unique=True))[0] indices = tmp[ivi] iv, ivi = np.unique(bivert, return_inverse=True) tmp = np.where(np.in1d(u, bivert, assume_unique=True))[0] bindices = tmp[ivi] #print('check', np.sum(np.abs(indices - indices0))) Nvert = len(vtx) Nelem = len(attrs) Nbelem = np.sum(kbelem) #len(battrs) if myid == 0: print("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(3, Nvert, Nelem, Nbelem, sdim) #omesh = mfem.Mesh(3, Nvert, Nelem, 0, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, bindices, nbverts, battrs, bbase, kbelem) omesh.FinalizeTopology() omesh.Finalize(refine=True, fix_orientation=True) if hasNodal: odim = omesh.Dimension() fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal GetXDofs = Nodal.GetElementDofs GetNX = Nodal.GetNE dGetXDofs = dNodal.GetElementDofs dGetNX = dNodal.GetNE DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) if isParMesh(mesh): omesh = mfem.ParMesh(comm, omesh) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh
def surface(mesh, in_attr, filename='', precision=8): ''' mesh must be if sdim == 3: a domain of 2D mesh a boundary of 3D mesh if sdim == 2: a domain in 2D mesh in_attr : eihter filename : an option to save the file return new surface mesh ''' sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim == 3 and dim == 3: mode = 'bdr', 'edge' elif sdim == 3 and dim == 2: mode = 'dom', 'bdr' elif sdim == 2 and dim == 2: mode = 'dom', 'bdr' else: assert False, "unsupported mdoe" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, mode[0]) s2l = mesh.extended_connectivity['surf2line'] in_eattr = np.unique(np.hstack([s2l[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_eattr = np.unique(allgather_vector(in_eattr)) eidx, eattrs, eivert, neverts, ebase = _collect_data( in_eattr, mesh, mode[1]) u, indices = np.unique(np.hstack((ivert, eivert)), return_inverse=True) keelem = np.array([True] * len(eidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, eivert = _gather_shared_vertex(mesh, u, shared_info, ivert, eivert) Nvert = len(u) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) eivert = allgather_vector(eivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, eivert]), return_inverse=True) # # take care of shared boundary (edge) # keelem, eattrs, neverts, ebase, eivert = (_gather_shared_element( mesh, 'edge', shared_info, eidx, keelem, eattrs, neverts, ebase, eivert, skip_adding=True)) #indices = np.array([np.where(u == biv)[0][0] for biv in ivert]) #eindices = np.array([np.where(u == biv)[0][0] for biv in eivert]) iv, ivi = np.unique(ivert, return_inverse=True) tmp = np.where(np.in1d(u, ivert, assume_unique=True))[0] indices = tmp[ivi] iv, ivi = np.unique(eivert, return_inverse=True) tmp = np.where(np.in1d(u, eivert, assume_unique=True))[0] eindices = tmp[ivi] Nvert = len(vtx) Nelem = len(attrs) Nbelem = len(eattrs) if myid == 0: print("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(2, Nvert, Nelem, Nbelem, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, eindices, neverts, eattrs, ebase, keelem) omesh.FinalizeTopology() omesh.Finalize(refine=True, fix_orientation=True) if hasNodal: odim = omesh.Dimension() print("odim, dim, sdim", odim, " ", dim, " ", sdim) fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal if sdim == 3: if dim == 3: GetXDofs = Nodal.GetBdrElementDofs GetNX = Nodal.GetNBE elif dim == 2: GetXDofs = Nodal.GetElementDofs GetNX = Nodal.GetNE else: assert False, "not supported ndim 1" if odim == 3: dGetXDofs = dNodal.GetBdrElementDofs dGetNX = dNodal.GetNBE elif odim == 2: dGetXDofs = dNodal.GetElementDofs dGetNX = dNodal.GetNE else: assert False, "not supported ndim (3->1)" elif sdim == 2: GetNX = Nodal.GetNE dGetNX = dNodal.GetNE GetXDofs = Nodal.GetElementDofs dGetXDofs = dNodal.GetElementDofs DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) if isParMesh(mesh): omesh = mfem.ParMesh(comm, omesh) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh
def eval_shape(order = 1, refine = 5, elem_type = 0, fec = 'ND'): if fec == 'ND': fec_type = mfem.ND_FECollection if order < 1: assert False, "ND order is 1 and above" elif fec == 'RT': fec_type = mfem.RT_FECollection elif fec == 'H1': fec_type = mfem.H1_FECollection if order < 1: assert False, "H1 order is 1 and above" elif fec == 'L2': fec_type = mfem.L2_FECollection else: assert False, "unknown basis" if elem_type == 0: Nvert = 3; Nelem = 1; spaceDim = 2 elif elem_type == 1: Nvert = 4; Nelem = 1; spaceDim = 2 mesh = mfem.Mesh(2, Nvert, Nelem, 0, spaceDim) if elem_type == 0: tri_v = [[1., 0.3 ], [0., 1.,], [0, 0]] tri_e = [[0, 1, 2], ] for j in range(Nvert): mesh.AddVertex(tri_v[j]) for j in range(Nelem): mesh.AddTriangle(tri_e[j], j+1) mesh.FinalizeTriMesh(1,1, True) else: quad_v = [[-1, -1.3, ], [+1, -1, ], [+1, +1, ], [-1, +1,]] quad_e = [[0, 1, 2, 3]] for j in range(Nvert): mesh.AddVertex(quad_v[j]) for j in range(Nelem): mesh.AddQuad(quad_e[j], j+1) mesh.FinalizeQuadMesh(1,1, True) #mesh.PrintToFile('plot_basis.mesh', 8) fe_coll = fec_type(order, spaceDim) fespace = mfem.FiniteElementSpace(mesh, fe_coll) x = mfem.GridFunction(fespace) x.Assign(0.0) x[0] = 1.0 idx = 0 geom = mesh.GetElementBaseGeometry(idx) T = mesh.GetElementTransformation(idx) fe = fespace.GetFE(idx) fe_nd = fe.GetDof() ir = fe.GetNodes() npt = ir.GetNPoints() dof = np.vstack([T.Transform(ir.IntPoint(i)) for i in range(npt)]) RefG = mfem.GlobGeometryRefiner.Refine(geom, refine, 1); ir = RefG.RefPts npt = ir.GetNPoints() ptx = np.vstack([T.Transform(ir.IntPoint(i)) for i in range(npt)]) shape = [] if fec == 'ND' or fec == 'RT': mat = mfem.DenseMatrix(fe_nd, spaceDim) shape_func = fe.CalcVShape for i in range(npt): ip = ir.IntPoint(i) T.SetIntPoint(ip) fe.CalcVShape(T, mat) shape.append(mat.GetDataArray().copy()) else: vec = mfem.Vector(fe_nd) for i in range(npt): ip = ir.IntPoint(i) fe.CalcShape(ip, vec) shape.append(vec.GetDataArray().copy()) return dof, ptx, np.stack(shape)
ser_ref_levels = 2 par_ref_levels = 0 order = 3 ode_solver_type = 4 t_final = 10 dt = 0.01 vis_steps = 5 # 3. Read the serial mesh from the given mesh file on all processors. We can # handle geometrically periodic meshes in this code. meshfile = expanduser(join(path, 'data', 'periodic-hexagon.mesh')) if not exists(meshfile): path = dirname(dirname(__file__)) meshfile = expanduser(join(path, 'data', 'periodic-hexagon.mesh')) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() # 4. Define the ODE solver used for time integration. Several explicit # Runge-Kutta methods are available. ode_solver = None if ode_solver_type == 1: ode_solver = mfem.ForwardEulerSolver() elif ode_solver_type == 2: ode_solver = mfem.RK2Solver(1.0) elif ode_solver_type == 3: ode_solver = mfem.RK3SSolver() elif ode_solver_type == 4: ode_solver = mfem.RK4Solver() elif ode_solver_type == 6: ode_solver = mfem.RK6Solver() else: print("Unknown ODE solver type: " + str(ode_solver_type)) exit # 5. Refine the mesh to increase the resolution. In this example we do
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(): #meshfile = expanduser(join(mfem_path, 'data', 'semi_circle.mesh')) mesh = mfem.Mesh(3, 3, 3, "TETRAHEDRON") mesh.ReorientTetMesh() order = 1 dim = mesh.Dimension() sdim = mesh.SpaceDimension() fec1 = mfem.H1_FECollection(order, dim) fespace1 = mfem.FiniteElementSpace(mesh, fec1, 1) fec2 = mfem.ND_FECollection(order, dim) fespace2 = mfem.FiniteElementSpace(mesh, fec2, 1) print("Element order :", order) print('Number of H1 finite element unknowns: ' + str(fespace1.GetTrueVSize())) print('Number of ND finite element unknowns: ' + str(fespace2.GetTrueVSize())) print("Checking scalar") gf = mfem.GridFunction(fespace1) c1 = mfem.NumbaFunction(s_func, sdim).GenerateCoefficient() c2 = s_coeff() gf.Assign(0.0) start = time.time() gf.ProjectCoefficient(c1) end = time.time() data1 = gf.GetDataArray().copy() print("Numba time (scalar)", end - start) gf.Assign(0.0) start = time.time() gf.ProjectCoefficient(c2) end = time.time() data2 = gf.GetDataArray().copy() print("Python time (scalar)", end - start) check(data1, data2, "scalar coefficient does not agree with original") print("Checking vector") gf = mfem.GridFunction(fespace2) c3 = mfem.VectorNumbaFunction(v_func, sdim, dim).GenerateCoefficient() c4 = v_coeff(dim) gf.Assign(0.0) start = time.time() gf.ProjectCoefficient(c3) end = time.time() data1 = gf.GetDataArray().copy() print("Numba time (vector)", end - start) gf.Assign(0.0) start = time.time() gf.ProjectCoefficient(c4) end = time.time() data2 = gf.GetDataArray().copy() print("Python time (vector)", end - start) check(data1, data2, "vector coefficient does not agree with original") print("Checking matrix") a1 = mfem.BilinearForm(fespace2) a2 = mfem.BilinearForm(fespace2) c4 = mfem.MatrixNumbaFunction(m_func, sdim, dim).GenerateCoefficient() c5 = m_coeff(dim) a1.AddDomainIntegrator(mfem.VectorFEMassIntegrator(c4)) a2.AddDomainIntegrator(mfem.VectorFEMassIntegrator(c5)) start = time.time() a1.Assemble() end = time.time() a1.Finalize() M1 = a1.SpMat() print("Numba time (matrix)", end - start) start = time.time() a2.Assemble() end = time.time() a2.Finalize() M2 = a2.SpMat() print("Python time (matrix)", end - start) #from mfem.commmon.sparse_utils import sparsemat_to_scipycsr #csr1 = sparsemat_to_scipycsr(M1, float) #csr2 = sparsemat_to_scipycsr(M2, float) check(M1.GetDataArray(), M2.GetDataArray(), "matrix coefficient does not agree with original") check(M1.GetIArray(), M2.GetIArray(), "matrix coefficient does not agree with original") check(M1.GetJArray(), M2.GetJArray(), "matrix coefficient does not agree with original") print("PASSED")
def initialize(self, inMeshObj=None, inMeshFile=None): # 2. Problem initialization self.parser = ArgParser(description='Based on MFEM Ex16p') self.parser.add_argument('-m', '--mesh', default='beam-tet.mesh', action='store', type=str, help='Mesh file to use.') self.parser.add_argument('-rs', '--refine-serial', action='store', default=1, type=int, help="Number of times to refine the mesh \ uniformly in serial") self.parser.add_argument('-rp', '--refine-parallel', action='store', default=0, type=int, help="Number of times to refine the mesh \ uniformly in parallel") self.parser.add_argument('-o', '--order', action='store', default=1, type=int, help="Finite element order (polynomial \ degree)") self.parser.add_argument( '-s', '--ode-solver', action='store', default=3, type=int, help='\n'.join([ "ODE solver: 1 - Backward Euler, 2 - SDIRK2, \ 3 - SDIRK3", "\t\t 11 - Forward Euler, \ 12 - RK2, 13 - RK3 SSP, 14 - RK4." ])) self.parser.add_argument('-t', '--t-final', action='store', default=20., type=float, help="Final time; start time is 0.") self.parser.add_argument("-dt", "--time-step", action='store', default=5e-3, type=float, help="Time step.") self.parser.add_argument("-v", "--viscosity", action='store', default=0.00, type=float, help="Viscosity coefficient.") self.parser.add_argument('-L', '--lmbda', action='store', default=1.e0, type=float, help='Lambda of Hooks law') self.parser.add_argument('-mu', '--shear-modulus', action='store', default=1.e0, type=float, help='Shear modulus for Hooks law') self.parser.add_argument('-rho', '--density', action='store', default=1.0, type=float, help='mass density') self.parser.add_argument('-vis', '--visualization', action='store_true', help='Enable GLVis visualization') self.parser.add_argument('-vs', '--visualization-steps', action='store', default=25, type=int, help="Visualize every n-th timestep.") args = self.parser.parse_args() self.ser_ref_levels = args.refine_serial self.par_ref_levels = args.refine_parallel self.order = args.order self.dt = args.time_step self.visc = args.viscosity self.t_final = args.t_final self.lmbda = args.lmbda self.mu = args.shear_modulus self.rho = args.density self.visualization = args.visualization self.ti = 1 self.vis_steps = args.visualization_steps self.ode_solver_type = args.ode_solver self.t = 0.0 self.last_step = False if self.myId == 0: self.parser.print_options(args) # 3. Reading mesh if inMeshObj is None: self.meshFile = inMeshFile if self.meshFile is None: self.meshFile = args.mesh self.mesh = mfem.Mesh(self.meshFile, 1, 1) else: self.mesh = inMeshObj self.dim = self.mesh.Dimension() print("Mesh dimension: %d" % self.dim) print("Number of vertices in the mesh: %d " % self.mesh.GetNV()) print("Number of elements in the mesh: %d " % self.mesh.GetNE()) # 4. Define the ODE solver used for time integration. # Several implicit singly diagonal implicit # Runge-Kutta (SDIRK) methods, as well as # explicit Runge-Kutta methods are available. if self.ode_solver_type == 1: self.ode_solver = BackwardEulerSolver() elif self.ode_solver_type == 2: self.ode_solver = mfem.SDIRK23Solver(2) elif self.ode_solver_type == 3: self.ode_solver = mfem.SDIRK33Solver() elif self.ode_solver_type == 11: self.ode_solver = ForwardEulerSolver() elif self.ode_solver_type == 12: self.ode_solver = mfem.RK2Solver(0.5) elif self.ode_solver_type == 13: self.ode_solver = mfem.RK3SSPSolver() elif self.ode_solver_type == 14: self.ode_solver = mfem.RK4Solver() elif self.ode_solver_type == 22: self.ode_solver = mfem.ImplicitMidpointSolver() elif self.ode_solver_type == 23: self.ode_solver = mfem.SDIRK23Solver() elif self.ode_solver_type == 24: self.ode_solver = mfem.SDIRK34Solver() else: print("Unknown ODE solver type: " + str(self.ode_solver_type)) exit # 5. Refine the mesh in serial to increase the # resolution. In this example we do # 'ser_ref_levels' of uniform refinement, where # 'ser_ref_levels' is a command-line parameter. for lev in range(self.ser_ref_levels): self.mesh.UniformRefinement() # 6. Define a parallel mesh by a partitioning of # the serial mesh. Refine this mesh further # in parallel to increase the resolution. Once the # parallel mesh is defined, the serial mesh can # be deleted. self.pmesh = mfem.ParMesh(MPI.COMM_WORLD, self.mesh) for lev in range(self.par_ref_levels): self.pmesh.UniformRefinement() # 7. Define the vector finite element space # representing the current and the # initial temperature, u_ref. self.fe_coll = mfem.H1_FECollection(self.order, self.dim) self.fespace = mfem.ParFiniteElementSpace(self.pmesh, self.fe_coll, self.dim) self.fe_size = self.fespace.GlobalTrueVSize() if self.myId == 0: print("FE Number of unknowns: " + str(self.fe_size)) true_size = self.fespace.TrueVSize() self.true_offset = mfem.intArray(3) self.true_offset[0] = 0 self.true_offset[1] = true_size self.true_offset[2] = 2 * true_size self.vx = mfem.BlockVector(self.true_offset) self.v_gf = mfem.ParGridFunction(self.fespace) self.v_gfbnd = mfem.ParGridFunction(self.fespace) self.x_gf = mfem.ParGridFunction(self.fespace) self.x_gfbnd = mfem.ParGridFunction(self.fespace) self.x_ref = mfem.ParGridFunction(self.fespace) self.pmesh.GetNodes(self.x_ref) # 8. Set the initial conditions for u. #self.velo = InitialVelocity(self.dim) self.velo = velBCs(self.dim) #self.deform = InitialDeformation(self.dim) self.deform = defBCs(self.dim) self.v_gf.ProjectCoefficient(self.velo) self.v_gfbnd.ProjectCoefficient(self.velo) self.x_gf.ProjectCoefficient(self.deform) self.x_gfbnd.ProjectCoefficient(self.deform) #self.v_gf.GetTrueDofs(self.vx.GetBlock(0)); #self.x_gf.GetTrueDofs(self.vx.GetBlock(1)); # setup boundary-conditions self.xess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.xess_bdr.Assign(0) self.xess_bdr[0] = 1 self.xess_bdr[1] = 1 self.xess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.xess_bdr, self.xess_tdof_list) #print('True x essential BCs are') #self.xess_tdof_list.Print() self.vess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.vess_bdr.Assign(0) self.vess_bdr[0] = 1 self.vess_bdr[1] = 1 self.vess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.vess_bdr, self.vess_tdof_list) #print('True v essential BCs are') #self.vess_tdof_list.Print() # 9. Initialize the stiffness operator self.oper = StiffnessOperator(self.fespace, self.lmbda, self.mu, self.rho, self.visc, self.vess_tdof_list, self.vess_bdr, self.xess_tdof_list, self.xess_bdr, self.v_gfbnd, self.x_gfbnd, self.deform, self.velo, self.vx) # 10. Setting up file output self.smyid = '{:0>2d}'.format(self.myId) # initializing ode solver self.ode_solver.Init(self.oper)
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())
def edge(mesh, in_attr, filename='', precision=8): ''' make a new mesh which contains only spedified edges. in_attr : eihter filename : an option to save the file return new surface mesh ''' sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim == 3 and dim == 3: mode = 'edge', 'vertex' elif sdim == 3 and dim == 2: mode = 'bdr', 'vertex' elif sdim == 2 and dim == 2: mode = 'bdr', 'vertex' elif sdim == 2 and dim == 1: mode = 'dom', 'vertex' else: assert False, "unsupported mdoe" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, mode[0]) l2v = mesh.extended_connectivity['line2vert'] in_eattr = np.unique(np.hstack([l2v[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_eattr = np.unique(allgather_vector(in_eattr)) eidx, eattrs, eivert, neverts, ebase = _collect_data( in_eattr, mesh, mode[1]) u, indices = np.unique(np.hstack((ivert, eivert)), return_inverse=True) keelem = np.array([True] * len(eidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, eivert = _gather_shared_vertex(mesh, u, shared_info, ivert, eivert) Nvert = len(u) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) eivert = allgather_vector(eivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, eivert]), return_inverse=True) # # take care of shared boundary (edge) # keelem, eattrs, neverts, ebase, eivert = (_gather_shared_element( mesh, 'vertex', shared_info, eidx, keelem, eattrs, neverts, ebase, eivert)) indices = np.array([np.where(u == biv)[0][0] for biv in ivert]) eindices = np.array([np.where(u == biv)[0][0] for biv in eivert]) Nvert = len(vtx) Nelem = len(attrs) Nbelem = len(eattrs) dprint1("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(1, Nvert, Nelem, Nbelem, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, eindices, neverts, eattrs, ebase, keelem) omesh.FinalizeTopology() if hasNodal: odim = omesh.Dimension() dprint1("odim, dim, sdim", odim, " ", dim, " ", sdim) fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal GetXDofs = Nodal.GetElementDofs if dim == 3: GetXDofs = Nodal.GetEdgeDofs elif dim == 2: GetXDofs = Nodal.GetBdrElementDofs elif dim == 1: GetXDofs = Nodal.GetElementDofs dGetXDofs = dNodal.GetElementDofs DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) # this should be after setting HO nodals... omesh.Finalize(refine=True, fix_orientation=True) if isParMesh(mesh): if omesh.GetNE() < nprc * 3: parts = omesh.GeneratePartitioning(1, 1) else: parts = None omesh = mfem.ParMesh(comm, omesh, parts) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh
elem_type = 1 ref_levels = 2 par_ref_levels = 2 amr = 0 order = 2 always_snap = False if elem_type == 1: Nvert = 8 Nelem = 6 else: Nvert = 6 Nelem = 8 mesh = mfem.Mesh(2, Nvert, Nelem, 0, 3) if elem_type == 0: 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]] for j in range(Nvert): mesh.AddVertex(tri_v[j]) for j in range(Nelem): mesh.AddTriangle(tri_e[j], j + 1) mesh.FinalizeTriMesh(1, 1, True) else: quad_v = [[-1, -1, -1], [+1, -1, -1], [+1, +1, -1], [-1, +1, -1], [-1, -1, +1], [+1, -1, +1], [+1, +1, +1], [-1, +1, +1]]
def hex_box_mesh(xlengths, xnsegs, ylengths, ynsegs, zlengths, znsegs, filename='', refine=False, fix_orientation=False, sdim=3, x0=None): x0 = (0.0, 0.0, 0.0) if x0 is None else x0 Nvert = (np.sum(xnsegs)+1)*(np.sum(ynsegs)+1)*(np.sum(znsegs)+1) Nelem = np.sum(xnsegs)*np.sum(ynsegs)*np.sum(znsegs) Nbdrelem = (np.sum(xnsegs)*np.sum(ynsegs)*(len(zlengths)+1) + np.sum(xnsegs)*np.sum(znsegs)*(len(ylengths)+1) + np.sum(znsegs)*np.sum(ynsegs)*(len(xlengths)+1)) mesh = mfem.Mesh(3, Nvert, Nelem, Nbdrelem, sdim) Lx = np.hstack(([0], np.cumsum(xlengths))) x = [np.linspace(Lx[i], Lx[i+1], n+1)[:-1].astype(float) for i, n in enumerate(xnsegs)]+[np.sum(xlengths)] x = np.hstack(np.array(x)) kx = np.hstack(([0], np.cumsum(xnsegs))) kkx = sum([[i]*n for i,n in enumerate(xnsegs)],[]) Ly = np.hstack(([0], np.cumsum(ylengths))) y = [np.linspace(Ly[i], Ly[i+1], n+1)[:-1].astype(float) for i, n in enumerate(ynsegs)]+[np.sum(ylengths)] y = np.hstack(np.array(y)) ky = np.hstack(([0], np.cumsum(ynsegs))) kky = sum([[i]*n for i,n in enumerate(ynsegs)],[]) Lz = np.hstack(([0], np.cumsum(zlengths))) z = [np.linspace(Lz[i], Lz[i+1], n+1)[:-1].astype(float) for i, n in enumerate(znsegs)]+[np.sum(zlengths)] z = np.hstack(np.array(z)) kz = np.hstack(([0], np.cumsum(znsegs))) kkz = sum([[i]*n for i,n in enumerate(znsegs)],[]) X, Y, Z = np.meshgrid(x, y, z) # y-idx, x-idx, z-idx X = X + x0[0] Y = Y + x0[1] Z = Z + x0[2] IDX = np.arange(len(x)*len(y)*len(z)).reshape(len(y), len(x), len(z)) ax = np.hstack([[i]*n for i, n in enumerate(xnsegs)]) ay = np.hstack([[j]*n for j, n in enumerate(ynsegs)]) az = np.hstack([[j]*n for j, n in enumerate(znsegs)]) AX, AY, AZ = np.meshgrid(ax, ay, az) KDOM = AZ*len(xnsegs)*len(ynsegs) + AY*len(xnsegs) + AX + 1 e_count = 1 for i in range(len(y[:-1])): for j in range(len(x[:-1])): for k in range(len(z[:-1])): elem = [IDX[i, j, k ], IDX[i, j+1, k ], IDX[i+1, j+1, k ], IDX[i+1, j, k ], IDX[i, j,k+1], IDX[i, j+1, k+1], IDX[i+1, j+1, k+1], IDX[i+1, j, k+1]] mesh.AddHex(elem, KDOM[i, j, k]) e_count = e_count + 1 kbdr = 1 b_count = 1 for j in kx: for i in range(len(y[:-1])): for k in range(len(z[:-1])): elem = [IDX[i, j, k], IDX[i+1, j, k], IDX[i+1, j, k+1], IDX[i, j, k+1]] mesh.AddBdrQuad(elem, kbdr+kky[i]*len(znsegs) + kkz[k]) b_count = b_count + 1 kbdr = kbdr + len(ynsegs)*len(znsegs) for i in ky: for k in range(len(z[:-1])): for j in range(len(x[:-1])): elem = [IDX[i, j, k], IDX[i, j+1, k], IDX[i, j+1, k+1], IDX[i, j, k+1]] mesh.AddBdrQuad(elem, kbdr+kkz[k]*len(xnsegs) + kkx[j]) b_count = b_count + 1 kbdr = kbdr + len(xnsegs)*len(znsegs) for k in kz: for j in range(len(x[:-1])): for i in range(len(y[:-1])): elem = [IDX[i, j, k], IDX[i+1, j, k], IDX[i+1, j+1, k], IDX[i, j+1, k]] mesh.AddBdrQuad(elem, kbdr+kkx[j]*len(ynsegs) + kky[i]) b_count = b_count + 1 kbdr = kbdr + len(xnsegs)*len(ynsegs) v_count = 1 for xx, yy, zz in zip(X.flatten(), Y.flatten(), Z.flatten()): ptx = [xx, yy, zz] mesh.AddVertex(ptx) v_count = v_count + 1 #print(e_count, b_count, v_count) #print(Nelem, Nbdrelem, Nvert) mesh.FinalizeTopology() mesh.Finalize(refine, fix_orientation) if filename != '': mesh.PrintToFile(filename, 8) return mesh
def quad_rectangle_mesh(xlengths, xnsegs, ylengths, ynsegs, filename='', refine=False, fix_orientation=False, sdim=3, x0=None): x0 = (0.0, 0.0) if x0 is None else x0 Nvert = (np.sum(xnsegs)+1)*(np.sum(ynsegs)+1) Nelem = np.sum(xnsegs)*np.sum(ynsegs) Nbdrelem = (np.sum(xnsegs)*(len(ylengths)+1) + np.sum(ynsegs)*(len(xlengths)+1)) mesh = mfem.Mesh(2, Nvert, Nelem, Nbdrelem, sdim) Lx = np.hstack(([0], np.cumsum(xlengths))) x = [np.linspace(Lx[i], Lx[i+1], n+1)[:-1].astype(float) for i, n in enumerate(xnsegs)]+[np.sum(xlengths)] x = np.hstack(np.array(x)) kx = np.hstack(([0], np.cumsum(xnsegs))) kkx = sum([[i]*n for i,n in enumerate(xnsegs)],[]) Ly = np.hstack(([0], np.cumsum(ylengths))) y = [np.linspace(Ly[i], Ly[i+1], n+1)[:-1].astype(float) for i, n in enumerate(ynsegs)]+[np.sum(ylengths)] y = np.hstack(np.array(y)) ky = np.hstack(([0], np.cumsum(ynsegs))) kky = sum([[i]*n for i,n in enumerate(ynsegs)],[]) X, Y = np.meshgrid(x, y) X = X + x0[0] Y = Y + x0[1] IDX = np.arange(len(x)*len(y)).reshape(len(y), len(x)) ax = np.hstack([[i]*n for i, n in enumerate(xnsegs)]) ay = np.hstack([[j]*n for j, n in enumerate(ynsegs)]) AX, AY = np.meshgrid(ax, ay) KDOM = AY*len(xnsegs) + AX + 1 e_count = 1 for i in range(len(y[:-1])): for j in range(len(x[:-1])): elem = [IDX[i, j], IDX[i, j+1], IDX[i+1, j+1], IDX[i+1, j]] mesh.AddQuad(elem, KDOM[i, j]) e_count = e_count + 1 kbdr = 1 b_count = 1 for k, j in enumerate(kx): for i in range(len(y[:-1])): elem = [IDX[i, j], IDX[i+1, j]] mesh.AddBdrSegment(elem, kbdr+kky[i]) b_count = b_count + 1 kbdr = kbdr + len(ynsegs) for k, i in enumerate(ky): for j in range(len(x[:-1])): elem = [IDX[i, j], IDX[i, j+1]] mesh.AddBdrSegment(elem, kbdr+kkx[j]) b_count = b_count + 1 kbdr = kbdr + len(xnsegs) v_count = 1 for xx, yy in zip(X.flatten(), Y.flatten()): ptx = [xx, yy, 0.0] mesh.AddVertex(ptx) v_count = v_count + 1 #print(e_count, b_count, v_count) #print(Nelem, Nbdrelem, Nvert) mesh.FinalizeTopology() mesh.Finalize(refine, fix_orientation) if filename != '': mesh.PrintToFile(filename, 8) return mesh
def merge_domain_3d(mesh, domain_list, reorder_dom=True): if not hasattr(mesh, 'extended_connectivity'): from petram.mesh.mesh_utils import get_extended_connectivity get_extended_connectivity(mesh) ec = mesh.extended_connectivity v2s = ec['vol2surf'] s2l = ec['surf2line'] from petram.mesh.mesh_utils import vol2line, line2surf, line2vol v2l = vol2line(v2s, s2l) l2v = line2vol(v2l) l2s = line2surf(s2l) # find surfaces to remove # find edge to remove remove_surf = [] remove_edge = Set() merge_vol = {} for d in domain_list: merge_vol[d] = 0 touched_dom = [] for i, j in combinations(domain_list, 2): iscts = np.intersect1d(v2s[i], v2s[j]) if len(iscts) != 0: touched_dom.append((i, j)) remove_surf.append(iscts) remove_surf = list(np.hstack(remove_surf).astype(int)) for s in remove_surf: for l in s2l[s]: for v in v2l: if l in v2l[v] and not v in domain_list: break else: remove_edge.add(l) for l in s2l[s]: connected_surf = [s for s in l2s[l] if not s in remove_surf] if len(connected_surf) != 2: continue v1 = [ v for v in v2s if not v in domain_list and connected_surf[0] in v2s[v] ] v2 = [ v for v in v2s if not v in domain_list and connected_surf[1] in v2s[v] ] if len(Set(v1 + v2)) == 1: remove_edge.add(l) remove_edge = list(remove_edge) # check merging to one domain if len(touched_dom) == 0: assert False, "domains are not connected" c = list(touched_dom[0]) for i in range(len(touched_dom)): for j in range(i, len(touched_dom)): if touched_dom[j][0] in c and not touched_dom[j][1] in c: c.append(touched_dom[j][1]) if touched_dom[j][1] in c and not touched_dom[j][0] in c: c.append(touched_dom[j][0]) print("touched_domain", c) if len(c) != len(domain_list): assert False, "domains are not connected" # collect faces to merge merge_face0 = [] for k, l in enumerate(remove_edge): for f in merge_face0: if np.intersect1d(list(f), l2s[l]).size != 0: for s in l2s[l]: if not s in remove_surf: f.add(s) break else: sss = [s for s in l2s[l] if not s in remove_surf] merge_face0.append(Set(sss)) print(merge_face0) merge_face = {} for k, ss in enumerate(merge_face0): for s in ss: merge_face[s] = k # mapping of bdr (face) attributes idx = 1 bdrattr_map = {} for s in s2l: if s in remove_surf: continue if not s in merge_face: bdrattr_map[s] = idx idx = idx + 1 for s, k in merge_face.items(): if s in remove_surf: continue bdrattr_map[s] = k + idx # mapping of domaon attributes if reorder_dom: idx = 1 domattr_map = {} for v in v2s: if not v in merge_vol: domattr_map[v] = idx idx = idx + 1 for v, k in merge_vol.items(): domattr_map[v] = k + idx else: domattr_map = {} for v in v2s: if not v in merge_vol: domattr_map[v] = v idx = max(v2s.keys()) + 1 for v, k in merge_vol.tems(): domattr_map[v] = k + idx print("merge_vol", merge_vol) print("merge_surf", merge_face) print("remove_edge", remove_edge) print("remove_surf", remove_surf) print("domattr_map", domattr_map) print("bdrattr_map", bdrattr_map) # check if edge can be removed... NV = mesh.GetNV() NE = mesh.GetNE() NBE = mesh.GetNBE() bdrattr = mesh.GetBdrAttributeArray() domattr = mesh.GetAttributeArray() Nbelem = np.sum([x in bdrattr_map for x in bdrattr]) print("NV, NE, NBE", NV, NE, Nbelem) import sys if 'mfem.par' in sys.modules: import mfem.par as mfem else: import mfem.par as mfem omesh = mfem.Mesh(3, NV, NE, Nbelem, 3) for k in range(NV): v = mesh.GetVertexArray(k) omesh.AddVertex(list(v)) for k in range(NE): iv = mesh.GetElementVertices(k) a = domattr_map[domattr[k]] if len(iv) == 4: omesh.AddTet(list(iv), a) if len(iv) == 8: omesh.AddHex(list(iv), a) for k in range(NBE): iv = mesh.GetBdrElementVertices(k) if not bdrattr[k] in bdrattr_map: continue a = bdrattr_map[bdrattr[k]] if len(iv) == 3: omesh.AddBdrTriangle(list(iv), a) if len(iv) == 4: omesh.AddBdrQuad(list(iv), a) omesh.FinalizeTopology() omesh.Finalize(refine=True, fix_orientation=True) return omesh