Exemple #1
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 #2
0
    exit

# 5. Refine the mesh to increase the resolution. In this example we do
#    'ref_levels' of uniform refinement, where 'ref_levels' is a
#    command-line parameter. If the mesh is of NURBS type, we convert it to
#    a (piecewise-polynomial) high-order mesh.
for lev in range(ser_ref_levels):
    mesh.UniformRefinement()
    if mesh.NURBSext:
        mesh.SetCurvature(max(order, 1))
    bb_min, bb_max = mesh.GetBoundingBox(max(order, 1))

# 6. Define the 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.
pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh)
for k in range(par_ref_levels):
    pmesh.UniformRefinement()

# 7. Define the discontinuous DG finite element space of the given
#    polynomial order on the refined mesh.
fec = mfem.DG_FECollection(order, dim)
fes = mfem.ParFiniteElementSpace(pmesh, fec)

global_vSize = fes.GlobalTrueVSize()
if myid == 0:
    print("Number of unknowns: " + str(global_vSize))


#
#  Define coefficient using VecotrPyCoefficient and PyCoefficient
Exemple #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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