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
Exemple #2
0
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()
Exemple #3
0
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))
Exemple #4
0
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())
Exemple #5
0
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
Exemple #7
0
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)
Exemple #8
0
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")
Exemple #9
0
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)
Exemple #10
0
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
Exemple #11
0
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
Exemple #12
0
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)
Exemple #13
0
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
Exemple #14
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)
Exemple #15
0
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")
Exemple #16
0
    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)
Exemple #17
0
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())
Exemple #18
0
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
Exemple #19
0
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
Exemple #22
0
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