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 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 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 save_scaled_jacobian(filename, mesh, sd=-1): sj = get_scaled_jacobian(mesh, sd=sd) fec = mfem.L2_FECollection(0, mesh.Dimension()) fes = mfem.FiniteElementSpace(mesh, fec) vec = mfem.Vector(sj) gf = mfem.GridFunction(fes, vec.GetData()) gf.Save(filename)
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')
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]] quad_e = [[3, 2, 1, 0], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [4, 5, 6, 7]] 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) # Set the space for the high-order mesh nodes. fec = mfem.H1_FECollection(order, mesh.Dimension()) nodal_fes = mfem.FiniteElementSpace(mesh, fec, mesh.SpaceDimension()) mesh.SetNodalFESpace(nodal_fes) def SnapNodes(mesh): nodes = mesh.GetNodes() node = mfem.Vector(mesh.SpaceDimension()) for i in np.arange(nodes.FESpace().GetNDofs()): for d in np.arange(mesh.SpaceDimension()): node[d] = nodes[nodes.FESpace().DofToVDof(i, d)] node /= node.Norml2() for d in range(mesh.SpaceDimension()): nodes[nodes.FESpace().DofToVDof(i, d)] = node[d]
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 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)
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 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
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