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)
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
def run(order = 1, static_cond = False, meshfile = def_meshfile, visualization = False): mesh = mfem.Mesh(meshfile, 1,1) dim = mesh.Dimension() ref_levels = int(np.floor(np.log(10000./mesh.GetNE())/np.log(2.)/dim)) for x in range(ref_levels): mesh.UniformRefinement(); mesh.ReorientTetMesh(); pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh par_ref_levels = 2 for l in range(par_ref_levels): pmesh.UniformRefinement(); if order > 0: fec = mfem.H1_FECollection(order, dim) elif mesh.GetNodes(): fec = mesh.GetNodes().OwnFEC() prinr( "Using isoparametric FEs: " + str(fec.Name())); else: order = 1 fec = mfem.H1_FECollection(order, dim) fespace =mfem.ParFiniteElementSpace(pmesh, fec) fe_size = fespace.GlobalTrueVSize() if (myid == 0): print('Number of finite element unknowns: '+ str(fe_size)) ess_tdof_list = mfem.intArray() if pmesh.bdr_attributes.Size()>0: ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # the basis functions in the finite element fespace. b = mfem.ParLinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble(); x = mfem.ParGridFunction(fespace); x.Assign(0.0) a = mfem.ParBilinearForm(fespace); a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) if static_cond: a.EnableStaticCondensation() a.Assemble(); A = mfem.HypreParMatrix() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) if (myid == 0): print("Size of linear system: " + str(x.Size())) print("Size of linear system: " + str(A.GetGlobalNumRows())) amg = mfem.HypreBoomerAMG(A) pcg = mfem.HyprePCG(A) pcg.SetTol(1e-12) pcg.SetMaxIter(200) pcg.SetPrintLevel(2) pcg.SetPreconditioner(amg) pcg.Mult(B, X); a.RecoverFEMSolution(X, b, x) smyid = '{:0>6d}'.format(myid) mesh_name = "mesh."+smyid sol_name = "sol."+smyid pmesh.PrintToFile(mesh_name, 8) x.SaveToFile(sol_name, 8)
def ex19_main(args): ser_ref_levels = args.refine_serial par_ref_levels = args.refine_parallel order = args.order visualization = args.visualization mu = args.shear_modulus newton_rel_tol = args.relative_tolerance newton_abs_tol = args.absolute_tolerance newton_iter = args.newton_iterations if myid == 0: parser.print_options(args) meshfile = expanduser(join(path, 'data', args.mesh)) mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() for lev in range(ser_ref_levels): mesh.UniformRefinement() pmesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) del mesh for lev in range(par_ref_levels): pmesh.UniformRefinement() # 4. Define the shear modulus for the incompressible Neo-Hookean material c_mu = mfem.ConstantCoefficient(mu) # 5. Define the finite element spaces for displacement and pressure # (Taylor-Hood elements). By default, the displacement (u/x) is a second # order vector field, while the pressure (p) is a linear scalar function. quad_coll = mfem.H1_FECollection(order, dim) lin_coll = mfem.H1_FECollection(order - 1, dim) R_space = mfem.ParFiniteElementSpace(pmesh, quad_coll, dim, mfem.Ordering.byVDIM) W_space = mfem.ParFiniteElementSpace(pmesh, lin_coll) spaces = [R_space, W_space] glob_R_size = R_space.GlobalTrueVSize() glob_W_size = W_space.GlobalTrueVSize() # 6. Define the Dirichlet conditions (set to boundary attribute 1 and 2) ess_bdr_u = mfem.intArray(R_space.GetMesh().bdr_attributes.Max()) ess_bdr_p = mfem.intArray(W_space.GetMesh().bdr_attributes.Max()) ess_bdr_u.Assign(0) ess_bdr_u[0] = 1 ess_bdr_u[1] = 1 ess_bdr_p.Assign(0) ess_bdr = [ess_bdr_u, ess_bdr_p] if myid == 0: print("***********************************************************") print("dim(u) = " + str(glob_R_size)) print("dim(p) = " + str(glob_W_size)) print("dim(u+p) = " + str(glob_R_size + glob_W_size)) print("***********************************************************") block_offsets = intArray([0, R_space.TrueVSize(), W_space.TrueVSize()]) block_offsets.PartialSum() xp = mfem.BlockVector(block_offsets) # 9. Define grid functions for the current configuration, reference # configuration, final deformation, and pressure x_gf = mfem.ParGridFunction(R_space) x_ref = mfem.ParGridFunction(R_space) x_def = mfem.ParGridFunction(R_space) p_gf = mfem.ParGridFunction(W_space) #x_gf.MakeRef(R_space, xp.GetBlock(0), 0) #p_gf.MakeRef(W_space, xp.GetBlock(1), 0) deform = InitialDeformation(dim) refconfig = ReferenceConfiguration(dim) x_gf.ProjectCoefficient(deform) x_ref.ProjectCoefficient(refconfig) p_gf.Assign(0.0) # 12. Set up the block solution vectors x_gf.GetTrueDofs(xp.GetBlock(0)) p_gf.GetTrueDofs(xp.GetBlock(1)) # 13. Initialize the incompressible neo-Hookean operator oper = RubberOperator(spaces, ess_bdr, block_offsets, newton_rel_tol, newton_abs_tol, newton_iter, mu) # 14. Solve the Newton system oper.Solve(xp) # 15. Distribute the shared degrees of freedom x_gf.Distribute(xp.GetBlock(0)) p_gf.Distribute(xp.GetBlock(1)) # 16. Compute the final deformation mfem.subtract_vector(x_gf, x_ref, x_def) # 17. Visualize the results if requested if (visualization): vis_u = mfem.socketstream("localhost", 19916) visualize(vis_u, pmesh, x_gf, x_def, "Deformation", True) MPI.COMM_WORLD.Barrier() vis_p = mfem.socketstream("localhost", 19916) visualize(vis_p, pmesh, x_gf, p_gf, "Deformation", True) # 14. Save the displaced mesh, the final deformation, and the pressure nodes = x_gf owns_nodes = 0 nodes, owns_nodes = pmesh.SwapNodes(nodes, owns_nodes) smyid = '.' + '{:0>6d}'.format(myid) pmesh.PrintToFile('deformed.mesh' + smyid, 8) p_gf.SaveToFile('pressure.sol' + smyid, 8) x_def.SaveToFile("deformation.sol" + smyid, 8)
def volume(mesh, in_attr, filename='', precision=8): ''' make a new mesh which contains only spedified attributes. note: 1) boundary elements are also copied and bdr_attributes are maintained 2) in parallel, new mesh must be geometrically continuous. this routine does not check it mesh must have sdim == 3: in_attr : domain attribute filename : an option to save the file return new volume mesh ''' in_attr = np.atleast_1d(in_attr) sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim != 3: assert False, "sdim must be three for volume mesh" if dim != 3: assert False, "sdim must be three for volume mesh" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, 'dom') v2s = mesh.extended_connectivity['vol2surf'] in_battr = np.unique(np.hstack([v2s[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_battr = np.unique(allgather_vector(in_battr)) bidx, battrs, bivert, nbverts, bbase = _collect_data(in_battr, mesh, 'bdr') iface = np.array([mesh.GetBdrElementEdgeIndex(i) for i in bidx], dtype=int) # note u is sorted unique u, indices = np.unique(np.hstack((ivert, bivert)), return_inverse=True) kbelem = np.array([True] * len(bidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, bivert = _gather_shared_vertex(mesh, u, shared_info, ivert, bivert) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) bivert = allgather_vector(bivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, bivert]), return_inverse=True) # # take care of shared boundary (face) # # 2018.11.28 # skip_adding is on. This basically skip shared_element # processing. Check em3d_TEwg7 if you need to remov this. # kbelem, battrs, nbverts, bbase, bivert = (_gather_shared_element( mesh, 'face', shared_info, iface, kbelem, battrs, nbverts, bbase, bivert, skip_adding=True)) #indices0 = np.array([np.where(u == biv)[0][0] for biv in ivert]) #bindices0 = np.array([np.where(u == biv)[0][0] for biv in bivert]) iv, ivi = np.unique(ivert, return_inverse=True) tmp = np.where(np.in1d(u, ivert, assume_unique=True))[0] indices = tmp[ivi] iv, ivi = np.unique(bivert, return_inverse=True) tmp = np.where(np.in1d(u, bivert, assume_unique=True))[0] bindices = tmp[ivi] #print('check', np.sum(np.abs(indices - indices0))) Nvert = len(vtx) Nelem = len(attrs) Nbelem = np.sum(kbelem) #len(battrs) if myid == 0: print("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(3, Nvert, Nelem, Nbelem, sdim) #omesh = mfem.Mesh(3, Nvert, Nelem, 0, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, bindices, nbverts, battrs, bbase, kbelem) omesh.FinalizeTopology() omesh.Finalize(refine=True, fix_orientation=True) if hasNodal: odim = omesh.Dimension() fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal GetXDofs = Nodal.GetElementDofs GetNX = Nodal.GetNE dGetXDofs = dNodal.GetElementDofs dGetNX = dNodal.GetNE DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) if isParMesh(mesh): omesh = mfem.ParMesh(comm, omesh) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh
def surface(mesh, in_attr, filename='', precision=8): ''' mesh must be if sdim == 3: a domain of 2D mesh a boundary of 3D mesh if sdim == 2: a domain in 2D mesh in_attr : eihter filename : an option to save the file return new surface mesh ''' sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim == 3 and dim == 3: mode = 'bdr', 'edge' elif sdim == 3 and dim == 2: mode = 'dom', 'bdr' elif sdim == 2 and dim == 2: mode = 'dom', 'bdr' else: assert False, "unsupported mdoe" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, mode[0]) s2l = mesh.extended_connectivity['surf2line'] in_eattr = np.unique(np.hstack([s2l[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_eattr = np.unique(allgather_vector(in_eattr)) eidx, eattrs, eivert, neverts, ebase = _collect_data( in_eattr, mesh, mode[1]) u, indices = np.unique(np.hstack((ivert, eivert)), return_inverse=True) keelem = np.array([True] * len(eidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, eivert = _gather_shared_vertex(mesh, u, shared_info, ivert, eivert) Nvert = len(u) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) eivert = allgather_vector(eivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, eivert]), return_inverse=True) # # take care of shared boundary (edge) # keelem, eattrs, neverts, ebase, eivert = (_gather_shared_element( mesh, 'edge', shared_info, eidx, keelem, eattrs, neverts, ebase, eivert, skip_adding=True)) #indices = np.array([np.where(u == biv)[0][0] for biv in ivert]) #eindices = np.array([np.where(u == biv)[0][0] for biv in eivert]) iv, ivi = np.unique(ivert, return_inverse=True) tmp = np.where(np.in1d(u, ivert, assume_unique=True))[0] indices = tmp[ivi] iv, ivi = np.unique(eivert, return_inverse=True) tmp = np.where(np.in1d(u, eivert, assume_unique=True))[0] eindices = tmp[ivi] Nvert = len(vtx) Nelem = len(attrs) Nbelem = len(eattrs) if myid == 0: print("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(2, Nvert, Nelem, Nbelem, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, eindices, neverts, eattrs, ebase, keelem) omesh.FinalizeTopology() omesh.Finalize(refine=True, fix_orientation=True) if hasNodal: odim = omesh.Dimension() print("odim, dim, sdim", odim, " ", dim, " ", sdim) fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal if sdim == 3: if dim == 3: GetXDofs = Nodal.GetBdrElementDofs GetNX = Nodal.GetNBE elif dim == 2: GetXDofs = Nodal.GetElementDofs GetNX = Nodal.GetNE else: assert False, "not supported ndim 1" if odim == 3: dGetXDofs = dNodal.GetBdrElementDofs dGetNX = dNodal.GetNBE elif odim == 2: dGetXDofs = dNodal.GetElementDofs dGetNX = dNodal.GetNE else: assert False, "not supported ndim (3->1)" elif sdim == 2: GetNX = Nodal.GetNE dGetNX = dNodal.GetNE GetXDofs = Nodal.GetElementDofs dGetXDofs = dNodal.GetElementDofs DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) if isParMesh(mesh): omesh = mfem.ParMesh(comm, omesh) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh
def initialize(self, inMeshObj=None, inMeshFile=None): # 2. Problem initialization self.parser = ArgParser(description='Based on MFEM Ex16p') self.parser.add_argument('-m', '--mesh', default='beam-tet.mesh', action='store', type=str, help='Mesh file to use.') self.parser.add_argument('-rs', '--refine-serial', action='store', default=1, type=int, help="Number of times to refine the mesh \ uniformly in serial") self.parser.add_argument('-rp', '--refine-parallel', action='store', default=0, type=int, help="Number of times to refine the mesh \ uniformly in parallel") self.parser.add_argument('-o', '--order', action='store', default=1, type=int, help="Finite element order (polynomial \ degree)") self.parser.add_argument( '-s', '--ode-solver', action='store', default=3, type=int, help='\n'.join([ "ODE solver: 1 - Backward Euler, 2 - SDIRK2, \ 3 - SDIRK3", "\t\t 11 - Forward Euler, \ 12 - RK2, 13 - RK3 SSP, 14 - RK4." ])) self.parser.add_argument('-t', '--t-final', action='store', default=20., type=float, help="Final time; start time is 0.") self.parser.add_argument("-dt", "--time-step", action='store', default=5e-3, type=float, help="Time step.") self.parser.add_argument("-v", "--viscosity", action='store', default=0.00, type=float, help="Viscosity coefficient.") self.parser.add_argument('-L', '--lmbda', action='store', default=1.e0, type=float, help='Lambda of Hooks law') self.parser.add_argument('-mu', '--shear-modulus', action='store', default=1.e0, type=float, help='Shear modulus for Hooks law') self.parser.add_argument('-rho', '--density', action='store', default=1.0, type=float, help='mass density') self.parser.add_argument('-vis', '--visualization', action='store_true', help='Enable GLVis visualization') self.parser.add_argument('-vs', '--visualization-steps', action='store', default=25, type=int, help="Visualize every n-th timestep.") args = self.parser.parse_args() self.ser_ref_levels = args.refine_serial self.par_ref_levels = args.refine_parallel self.order = args.order self.dt = args.time_step self.visc = args.viscosity self.t_final = args.t_final self.lmbda = args.lmbda self.mu = args.shear_modulus self.rho = args.density self.visualization = args.visualization self.ti = 1 self.vis_steps = args.visualization_steps self.ode_solver_type = args.ode_solver self.t = 0.0 self.last_step = False if self.myId == 0: self.parser.print_options(args) # 3. Reading mesh if inMeshObj is None: self.meshFile = inMeshFile if self.meshFile is None: self.meshFile = args.mesh self.mesh = mfem.Mesh(self.meshFile, 1, 1) else: self.mesh = inMeshObj self.dim = self.mesh.Dimension() print("Mesh dimension: %d" % self.dim) print("Number of vertices in the mesh: %d " % self.mesh.GetNV()) print("Number of elements in the mesh: %d " % self.mesh.GetNE()) # 4. Define the ODE solver used for time integration. # Several implicit singly diagonal implicit # Runge-Kutta (SDIRK) methods, as well as # explicit Runge-Kutta methods are available. if self.ode_solver_type == 1: self.ode_solver = BackwardEulerSolver() elif self.ode_solver_type == 2: self.ode_solver = mfem.SDIRK23Solver(2) elif self.ode_solver_type == 3: self.ode_solver = mfem.SDIRK33Solver() elif self.ode_solver_type == 11: self.ode_solver = ForwardEulerSolver() elif self.ode_solver_type == 12: self.ode_solver = mfem.RK2Solver(0.5) elif self.ode_solver_type == 13: self.ode_solver = mfem.RK3SSPSolver() elif self.ode_solver_type == 14: self.ode_solver = mfem.RK4Solver() elif self.ode_solver_type == 22: self.ode_solver = mfem.ImplicitMidpointSolver() elif self.ode_solver_type == 23: self.ode_solver = mfem.SDIRK23Solver() elif self.ode_solver_type == 24: self.ode_solver = mfem.SDIRK34Solver() else: print("Unknown ODE solver type: " + str(self.ode_solver_type)) exit # 5. Refine the mesh in serial to increase the # resolution. In this example we do # 'ser_ref_levels' of uniform refinement, where # 'ser_ref_levels' is a command-line parameter. for lev in range(self.ser_ref_levels): self.mesh.UniformRefinement() # 6. Define a parallel mesh by a partitioning of # the serial mesh. Refine this mesh further # in parallel to increase the resolution. Once the # parallel mesh is defined, the serial mesh can # be deleted. self.pmesh = mfem.ParMesh(MPI.COMM_WORLD, self.mesh) for lev in range(self.par_ref_levels): self.pmesh.UniformRefinement() # 7. Define the vector finite element space # representing the current and the # initial temperature, u_ref. self.fe_coll = mfem.H1_FECollection(self.order, self.dim) self.fespace = mfem.ParFiniteElementSpace(self.pmesh, self.fe_coll, self.dim) self.fe_size = self.fespace.GlobalTrueVSize() if self.myId == 0: print("FE Number of unknowns: " + str(self.fe_size)) true_size = self.fespace.TrueVSize() self.true_offset = mfem.intArray(3) self.true_offset[0] = 0 self.true_offset[1] = true_size self.true_offset[2] = 2 * true_size self.vx = mfem.BlockVector(self.true_offset) self.v_gf = mfem.ParGridFunction(self.fespace) self.v_gfbnd = mfem.ParGridFunction(self.fespace) self.x_gf = mfem.ParGridFunction(self.fespace) self.x_gfbnd = mfem.ParGridFunction(self.fespace) self.x_ref = mfem.ParGridFunction(self.fespace) self.pmesh.GetNodes(self.x_ref) # 8. Set the initial conditions for u. #self.velo = InitialVelocity(self.dim) self.velo = velBCs(self.dim) #self.deform = InitialDeformation(self.dim) self.deform = defBCs(self.dim) self.v_gf.ProjectCoefficient(self.velo) self.v_gfbnd.ProjectCoefficient(self.velo) self.x_gf.ProjectCoefficient(self.deform) self.x_gfbnd.ProjectCoefficient(self.deform) #self.v_gf.GetTrueDofs(self.vx.GetBlock(0)); #self.x_gf.GetTrueDofs(self.vx.GetBlock(1)); # setup boundary-conditions self.xess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.xess_bdr.Assign(0) self.xess_bdr[0] = 1 self.xess_bdr[1] = 1 self.xess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.xess_bdr, self.xess_tdof_list) #print('True x essential BCs are') #self.xess_tdof_list.Print() self.vess_bdr = mfem.intArray( self.fespace.GetMesh().bdr_attributes.Max()) self.vess_bdr.Assign(0) self.vess_bdr[0] = 1 self.vess_bdr[1] = 1 self.vess_tdof_list = intArray() self.fespace.GetEssentialTrueDofs(self.vess_bdr, self.vess_tdof_list) #print('True v essential BCs are') #self.vess_tdof_list.Print() # 9. Initialize the stiffness operator self.oper = StiffnessOperator(self.fespace, self.lmbda, self.mu, self.rho, self.visc, self.vess_tdof_list, self.vess_bdr, self.xess_tdof_list, self.xess_bdr, self.v_gfbnd, self.x_gfbnd, self.deform, self.velo, self.vx) # 10. Setting up file output self.smyid = '{:0>2d}'.format(self.myId) # initializing ode solver self.ode_solver.Init(self.oper)
def run_test(): print("Test complex_operator module") Nvert = 6 Nelem = 8 Nbelem = 2 mesh = mfem.Mesh(2, Nvert, Nelem, 2, 3) tri_v = [[1., 0., 0.], [0., 1., 0.], [-1., 0., 0.], [0., -1., 0.], [0., 0., 1.], [0., 0., -1.]] tri_e = [[0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4], [1, 0, 5], [2, 1, 5], [3, 2, 5], [0, 3, 5]] tri_l = [[1, 4], [1, 2]] for j in range(Nvert): mesh.AddVertex(tri_v[j]) for j in range(Nelem): mesh.AddTriangle(tri_e[j], 1) for j in range(Nbelem): mesh.AddBdrSegment(tri_l[j], 1) mesh.FinalizeTriMesh(1, 1, True) dim = mesh.Dimension() order = 1 fec = mfem.H1_FECollection(order, dim) if use_parallel: mesh = mfem.ParMesh(MPI.COMM_WORLD, mesh) fes = mfem.ParFiniteElementSpace(mesh, fec) a1 = mfem.ParBilinearForm(fes) a2 = mfem.ParBilinearForm(fes) else: fes = mfem.FiniteElementSpace(mesh, fec) a1 = mfem.BilinearForm(fes) a2 = mfem.BilinearForm(fes) one = mfem.ConstantCoefficient(1.0) a1.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) a1.Assemble() a1.Finalize() a2.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) a2.Assemble() a2.Finalize() if use_parallel: M1 = a1.ParallelAssemble() M2 = a2.ParallelAssemble() M1.Print('M1') width = fes.GetTrueVSize() #X = mfem.HypreParVector(fes) #Y = mfem.HypreParVector(fes) #X.SetSize(fes.TrueVSize()) #Y.SetSize(fes.TrueVSize()) #from mfem.common.parcsr_extra import ToScipyCoo #MM1 = ToScipyCoo(M1) #print(MM1.toarray()) #print(MM1.dot(np.ones(6))) else: M1 = a1.SpMat() M2 = a2.SpMat() M1.Print('M1') width = fes.GetVSize() #X = mfem.Vector() #Y = mfem.Vector() #X.SetSize(M1.Width()) #Y.SetSize(M1.Height()) #from mfem.common.sparse_utils import sparsemat_to_scipycsr #MM1 = sparsemat_to_scipycsr(M1, np.float) #print(MM1.toarray()) #print(MM1.dot(np.ones(6))) #X.Assign(0.0) #X[0] = 1.0 #M1.Mult(X, Y) #print(Y.GetDataArray()) Mc = mfem.ComplexOperator(M1, M2, hermitan=True) offsets = mfem.intArray([0, width, width]) offsets.PartialSum() x = mfem.BlockVector(offsets) y = mfem.BlockVector(offsets) x.GetBlock(0).Assign(0) if myid == 0: x.GetBlock(0)[0] = 1.0 x.GetBlock(1).Assign(0) if myid == 0: x.GetBlock(1)[0] = 1.0 Mc.Mult(x, y) print("x", x.GetDataArray()) print("y", y.GetDataArray()) if myid == 0: x.GetBlock(1)[0] = -1.0 x.Print() Mc.Mult(x, y) print("x", x.GetDataArray()) print("y", y.GetDataArray())
def edge(mesh, in_attr, filename='', precision=8): ''' make a new mesh which contains only spedified edges. in_attr : eihter filename : an option to save the file return new surface mesh ''' sdim = mesh.SpaceDimension() dim = mesh.Dimension() Nodal = mesh.GetNodalFESpace() hasNodal = (Nodal is not None) if sdim == 3 and dim == 3: mode = 'edge', 'vertex' elif sdim == 3 and dim == 2: mode = 'bdr', 'vertex' elif sdim == 2 and dim == 2: mode = 'bdr', 'vertex' elif sdim == 2 and dim == 1: mode = 'dom', 'vertex' else: assert False, "unsupported mdoe" idx, attrs, ivert, nverts, base = _collect_data(in_attr, mesh, mode[0]) l2v = mesh.extended_connectivity['line2vert'] in_eattr = np.unique(np.hstack([l2v[k] for k in in_attr])).astype(int, copy=False) if isParMesh(mesh): in_eattr = np.unique(allgather_vector(in_eattr)) eidx, eattrs, eivert, neverts, ebase = _collect_data( in_eattr, mesh, mode[1]) u, indices = np.unique(np.hstack((ivert, eivert)), return_inverse=True) keelem = np.array([True] * len(eidx), dtype=bool) u_own = u if isParMesh(mesh): shared_info = distribute_shared_entity(mesh) u_own, ivert, eivert = _gather_shared_vertex(mesh, u, shared_info, ivert, eivert) Nvert = len(u) if len(u_own) > 0: vtx = np.vstack([mesh.GetVertexArray(i) for i in u_own]) else: vtx = np.array([]).reshape((-1, sdim)) if isParMesh(mesh): # # distribute vertex/element data # base = allgather_vector(base) nverts = allgather_vector(nverts) attrs = allgather_vector(attrs) ivert = allgather_vector(ivert) eivert = allgather_vector(eivert) vtx = allgather_vector(vtx.flatten()).reshape(-1, sdim) u, indices = np.unique(np.hstack([ivert, eivert]), return_inverse=True) # # take care of shared boundary (edge) # keelem, eattrs, neverts, ebase, eivert = (_gather_shared_element( mesh, 'vertex', shared_info, eidx, keelem, eattrs, neverts, ebase, eivert)) indices = np.array([np.where(u == biv)[0][0] for biv in ivert]) eindices = np.array([np.where(u == biv)[0][0] for biv in eivert]) Nvert = len(vtx) Nelem = len(attrs) Nbelem = len(eattrs) dprint1("NV, NBE, NE: " + ",".join([str(x) for x in (Nvert, Nbelem, Nelem)])) omesh = mfem.Mesh(1, Nvert, Nelem, Nbelem, sdim) _fill_mesh_elements(omesh, vtx, indices, nverts, attrs, base) _fill_mesh_bdr_elements(omesh, vtx, eindices, neverts, eattrs, ebase, keelem) omesh.FinalizeTopology() if hasNodal: odim = omesh.Dimension() dprint1("odim, dim, sdim", odim, " ", dim, " ", sdim) fec = Nodal.FEColl() dNodal = mfem.FiniteElementSpace(omesh, fec, sdim) omesh.SetNodalFESpace(dNodal) omesh._nodal = dNodal GetXDofs = Nodal.GetElementDofs if dim == 3: GetXDofs = Nodal.GetEdgeDofs elif dim == 2: GetXDofs = Nodal.GetBdrElementDofs elif dim == 1: GetXDofs = Nodal.GetElementDofs dGetXDofs = dNodal.GetElementDofs DofToVDof = Nodal.DofToVDof dDofToVDof = dNodal.DofToVDof #nicePrint(dGetNX(),',', GetNX()) nodes = mesh.GetNodes() node_ptx1 = nodes.GetDataArray() onodes = omesh.GetNodes() node_ptx2 = onodes.GetDataArray() #nicePrint(len(idx), idx) if len(idx) > 0: dof1_idx = np.hstack([[DofToVDof(i, d) for d in range(sdim)] for j in idx for i in GetXDofs(j)]) data = node_ptx1[dof1_idx] else: dof1_idx = np.array([]) data = np.array([]) if isParMesh(mesh): data = allgather_vector(data) if isParMesh(mesh): idx = allgather_vector(idx) #nicePrint(len(data), ',', len(idx)) dof2_idx = np.hstack([[dDofToVDof(i, d) for d in range(sdim)] for j in range(len(idx)) for i in dGetXDofs(j)]) node_ptx2[dof2_idx] = data #nicePrint(len(dof2_idx)) # this should be after setting HO nodals... omesh.Finalize(refine=True, fix_orientation=True) if isParMesh(mesh): if omesh.GetNE() < nprc * 3: parts = omesh.GeneratePartitioning(1, 1) else: parts = None omesh = mfem.ParMesh(comm, omesh, parts) if filename != '': if isParMesh(mesh): smyid = '{:0>6d}'.format(myid) filename = filename + '.' + smyid omesh.PrintToFile(filename, precision) return omesh