def HighOrderMeshTet_SEMISTABLE(C, mesh, Decimals=10, equally_spaced=False, check_duplicates=True, parallelise=False, nCPU=1, compute_boundary_info=True): from Florence.FunctionSpace import Tet from Florence.QuadratureRules.FeketePointsTet import FeketePointsTet from Florence.MeshGeneration.NodeArrangement import NodeArrangementTet # SWITCH OFF MULTI-PROCESSING FOR SMALLER PROBLEMS WITHOUT GIVING A MESSAGE Parallel = parallelise if (mesh.elements.shape[0] < 500) and (C < 5): Parallel = False nCPU = 1 if not equally_spaced: eps = FeketePointsTet(C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS Neval = np.zeros((4, eps.shape[0]), dtype=np.float64) hpBases = Tet.hpNodal.hpBases for i in range(4, eps.shape[0]): Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], eps[i, 2], Transform=1, EvalOpt=1)[0] else: from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPointsTet eps = EquallySpacedPointsTet(C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS hpBases = Tet.hpNodal.hpBases Neval = np.zeros((4, eps.shape[0]), dtype=np.float64) for i in range(4, eps.shape[0]): Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], eps[i, 2], Transform=1, EvalOpt=1, equally_spaced=True)[0] # THIS IS NECESSARY FOR REMOVING DUPLICATES makezero(Neval, tol=1e-12) nodeperelem = mesh.elements.shape[1] renodeperelem = int((C + 2.) * (C + 3.) * (C + 4.) / 6.) left_over_nodes = renodeperelem - nodeperelem reelements = -1 * np.ones( (mesh.elements.shape[0], renodeperelem), dtype=np.int64) reelements[:, :4] = mesh.elements # TOTAL NUMBER OF (INTERIOR+EDGE+FACE) NODES iesize = np.int64(C * (C - 1) * (C - 2) / 6. + 6. * C + 2 * C * (C - 1)) repoints = np.zeros( (mesh.points.shape[0] + iesize * mesh.elements.shape[0], 3), dtype=np.float64) repoints[:mesh.points.shape[0], :] = mesh.points telements = time() xycoord_higher = [] ParallelTuple1 = [] if Parallel: # GET HIGHER ORDER COORDINATES - PARALLEL ParallelTuple1 = parmap.map(ElementLoopTet, np.arange(0, mesh.elements.shape[0]), mesh.elements, mesh.points, 'tet', eps, Neval, pool=MP.Pool(processes=nCPU)) maxNode = np.max(reelements) for elem in range(0, mesh.elements.shape[0]): # maxNode = np.max(reelements) # BIG BOTTLENECK if Parallel: xycoord_higher = ParallelTuple1[elem] else: xycoord = mesh.points[mesh.elements[elem, :], :] # GET HIGHER ORDER COORDINATES xycoord_higher = GetInteriorNodesCoordinates( xycoord, 'tet', elem, eps, Neval) # EXPAND THE ELEMENT CONNECTIVITY newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes) reelements[elem, 4:] = newElements # INSTEAD COMPUTE maxNode BY INDEXING maxNode = newElements[-1] repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] + (elem + 1) * iesize] = xycoord_higher[4:, :] if Parallel: del ParallelTuple1 telements = time() - telements #-------------------------------------------------------------------------------------- # NOW REMOVE DUPLICATED POINTS tnodes = time() nnode_linear = mesh.points.shape[0] # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR # rounded_repoints = makezero(repoints[nnode_linear:,:].copy()) rounded_repoints = repoints[nnode_linear:, :].copy() makezero(rounded_repoints) rounded_repoints = np.round(rounded_repoints, decimals=Decimals) _, idx_repoints, inv_repoints = unique2d(rounded_repoints, order=False, consider_sort=False, return_index=True, return_inverse=True) # idx_repoints.sort() del rounded_repoints idx_repoints = np.concatenate( (np.arange(nnode_linear), idx_repoints + nnode_linear)) repoints = repoints[idx_repoints, :] unique_reelements, inv_reelements = np.unique(reelements[:, 4:], return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 4) reelements = np.concatenate((mesh.elements, reelements), axis=1) # SANITY CHECK fOR DUPLICATES #---------------------------------------------------------------------# # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO # LINEAR CONNECTIVITY if check_duplicates: last_shape = repoints.shape[0] deci = int(Decimals) - 2 if Decimals < 6: deci = Decimals repoints, idx_repoints, inv_repoints = remove_duplicates_2D( repoints, decimals=deci) unique_reelements, inv_reelements = np.unique(reelements, return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem) if last_shape != repoints.shape[0]: warn( 'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now' ) #---------------------------------------------------------------------# tnodes = time() - tnodes #------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------ if compute_boundary_info: # BUILD FACES NOW tfaces = time() # GET MESH EDGES AND FACES fsize = int((C + 2.) * (C + 3.) / 2.) refaces = np.zeros((mesh.faces.shape[0], fsize), dtype=mesh.faces.dtype) refaces = np.zeros((mesh.faces.shape[0], fsize)) # DO NOT CHANGE THE FACES, BY RECOMPUTING THEM, AS THE LINEAR FACES CAN COME FROM # AN EXTERNAL MESH GENERATOR, WHOSE ORDERING MAY NOT BE THE SAME, SO JUST FIND WHICH # ELEMENTS CONTAIN THESE FACES face_to_elements = mesh.GetElementsWithBoundaryFacesTet() node_arranger = NodeArrangementTet(C)[0] refaces = reelements[face_to_elements[:, 0][:, None], node_arranger[face_to_elements[:, 1], :]].astype( mesh.faces.dtype) tfaces = time() - tfaces #------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------ # BUILD EDGES NOW tedges = time() # BUILD A 2D MESH from Florence import Mesh tmesh = Mesh() tmesh.element_type = "tri" tmesh.elements = refaces tmesh.nelem = tmesh.elements.shape[0] # GET BOUNDARY EDGES reedges = tmesh.GetEdgesTri() del tmesh tedges = time() - tedges #------------------------------------------------------------------------------------------ class nmesh(object): # """Construct pMesh""" points = repoints elements = reelements edges = np.array([[], []]) faces = np.array([[], []]) nnode = repoints.shape[0] nelem = reelements.shape[0] info = 'tet' if compute_boundary_info: nmesh.edges = reedges nmesh.faces = refaces gc.collect() # print '\nHigh order meshing timing:\n\t\tElement loop:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\ # ' seconds'+'\n\t\tEdge loop:\t\t '+str(tedges)+' seconds'+\ # '\n\t\tFace loop:\t\t '+str(tfaces)+' seconds\n' return nmesh
def HighOrderMeshTri_SEMISTABLE(C, mesh, Decimals=10, equally_spaced=False, check_duplicates=True, Parallel=False, nCPU=1, ComputeAll=False): from Florence.FunctionSpace import Tri from Florence.QuadratureRules.FeketePointsTri import FeketePointsTri from Florence.MeshGeneration.NodeArrangement import NodeArrangementTri # SWITCH OFF MULTI-PROCESSING FOR SMALLER PROBLEMS WITHOUT GIVING A MESSAGE if (mesh.elements.shape[0] < 1000) and (C < 8): Parallel = False nCPU = 1 if not equally_spaced: eps = FeketePointsTri(C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS hpBases = Tri.hpNodal.hpBases Neval = np.zeros((3, eps.shape[0]), dtype=np.float64) for i in range(3, eps.shape[0]): Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], 1)[0] else: from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPointsTri eps = EquallySpacedPointsTri(C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS hpBases = Tri.hpNodal.hpBases Neval = np.zeros((3, eps.shape[0]), dtype=np.float64) for i in range(3, eps.shape[0]): Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], Transform=1, EvalOpt=1, equally_spaced=True)[0] # THIS IS NECESSARY FOR REMOVING DUPLICATES makezero(Neval, tol=1e-12) nodeperelem = mesh.elements.shape[1] renodeperelem = int((C + 2.) * (C + 3.) / 2.) left_over_nodes = renodeperelem - nodeperelem reelements = -1 * np.ones( (mesh.elements.shape[0], renodeperelem), dtype=np.int64) reelements[:, :3] = mesh.elements iesize = int(C * (C + 5.) / 2.) repoints = np.zeros( (mesh.points.shape[0] + iesize * mesh.elements.shape[0], mesh.points.shape[1]), dtype=np.float64) # repoints[:mesh.points.shape[0],:]=mesh.points[:,:2] repoints[:mesh.points.shape[0], :] = mesh.points pshape0, pshape1 = mesh.points.shape[0], mesh.points.shape[1] repshape0, repshape1 = repoints.shape[0], repoints.shape[1] telements = time() xycoord_higher = [] ParallelTuple1 = [] if Parallel: # GET HIGHER ORDER COORDINATES - PARALLEL ParallelTuple1 = parmap.map(ElementLoopTri, np.arange(0, mesh.elements.shape[0]), mesh.elements, mesh.points, 'tri', eps, Neval, pool=MP.Pool(processes=nCPU)) # LOOP OVER ELEMENTS maxNode = np.max(reelements) for elem in range(0, mesh.elements.shape[0]): # GET HIGHER ORDER COORDINATES if Parallel: xycoord_higher = ParallelTuple1[elem] else: # xycoord = mesh.points[mesh.elements[elem,:],:] xycoord_higher = GetInteriorNodesCoordinates( mesh.points[mesh.elements[elem, :], :], 'tri', elem, eps, Neval) # EXPAND THE ELEMENT CONNECTIVITY newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes) # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes) reelements[elem, 3:] = newElements maxNode = newElements[-1] repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] + (elem + 1) * iesize] = xycoord_higher[3:, :] telements = time() - telements #-------------------------------------------------------------------------------------- # NOW REMOVE DUPLICATED POINTS tnodes = time() nnode_linear = mesh.points.shape[0] # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR rounded_repoints = repoints[nnode_linear:, :].copy() makezero(rounded_repoints) rounded_repoints = np.round(rounded_repoints, decimals=Decimals) # flattened_repoints = np.ascontiguousarray(rounded_repoints).view(np.dtype((np.void, # rounded_repoints.dtype.itemsize * rounded_repoints.shape[1]))) # _, idx_repoints, inv_repoints = np.unique(flattened_repoints,return_index=True,return_inverse=True) _, idx_repoints, inv_repoints = unique2d(rounded_repoints, order=False, consider_sort=False, return_index=True, return_inverse=True) del rounded_repoints idx_repoints = np.concatenate( (np.arange(nnode_linear), idx_repoints + nnode_linear)) repoints = repoints[idx_repoints, :] unique_reelements, inv_reelements = np.unique(reelements[:, 3:], return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 3) reelements = np.concatenate((mesh.elements, reelements), axis=1) # SANITY CHECK FOR DUPLICATES #---------------------------------------------------------------------# # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO # LINEAR CONNECTIVITY if check_duplicates: last_shape = repoints.shape[0] deci = int(Decimals) - 2 if Decimals < 6: deci = Decimals repoints, idx_repoints, inv_repoints = remove_duplicates_2D( repoints, decimals=deci) unique_reelements, inv_reelements = np.unique(reelements, return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem) if last_shape != repoints.shape[0]: warn( 'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now' ) #---------------------------------------------------------------------# tnodes = time() - tnodes #------------------------------------------------------------------------------------------ # BUILD EDGES NOW #------------------------------------------------------------------------------------------ tedges = time() edge_to_elements = mesh.GetElementsWithBoundaryEdgesTri() node_arranger = NodeArrangementTri(C)[0] reedges = np.zeros((mesh.edges.shape[0], C + 2), dtype=np.int64) # for i in range(mesh.edges.shape[0]): # reedges[i,:] = reelements[edge_to_elements[i,0],node_arranger[edge_to_elements[i,1],:]] reedges = reelements[edge_to_elements[:, 0][:, None], node_arranger[edge_to_elements[:, 1], :]] tedges = time() - tedges #------------------------------------------------------------------------------------------ class nmesh(object): # """Construct pMesh""" points = repoints elements = reelements edges = reedges faces = np.array([[], []]) nnode = repoints.shape[0] nelem = reelements.shape[0] info = 'tri' # print '\npMeshing timing:\n\t\tElement loop 1:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\ # ' seconds'+'\n\t\tElement loop 2:\t '+str(telements_2)+' seconds\n\t\tEdge loop:\t\t '+str(tedges)+' seconds\n' return nmesh
def HighOrderMeshLine(C, mesh, Decimals=10, equally_spaced=False, check_duplicates=True, Parallel=False, nCPU=1): from Florence.FunctionSpace import Line from Florence.QuadratureRules import GaussLobattoPoints1D from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPoints from Florence.MeshGeneration.NodeArrangement import NodeArrangementLine # ARRANGE NODES FOR LINES HERE (DONE ONLY FOR LINES) - IMPORTANT node_aranger = NodeArrangementLine(C) if not equally_spaced: eps = GaussLobattoPoints1D(C).ravel() eps = eps[node_aranger] # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS Neval = np.zeros((2, eps.shape[0]), dtype=np.float64) for i in range(0, eps.shape[0]): Neval[:, i] = Line.LagrangeGaussLobatto(0, eps[i])[0] else: eps = EquallySpacedPoints(2, C).ravel() eps = eps[node_aranger] # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS Neval = np.zeros((2, eps.shape[0]), dtype=np.float64) for i in range(0, eps.shape[0]): Neval[:, i] = Line.Lagrange(0, eps[i])[0] makezero(Neval) nodeperelem = mesh.elements.shape[1] renodeperelem = int(C + 2) left_over_nodes = renodeperelem - nodeperelem reelements = -1 * np.ones( (mesh.elements.shape[0], renodeperelem), dtype=np.int64) reelements[:, :2] = mesh.elements iesize = int(C) repoints = np.zeros( (mesh.points.shape[0] + iesize * mesh.elements.shape[0], mesh.points.shape[1]), dtype=np.float64) repoints[:mesh.points.shape[0], :] = mesh.points #-------------------------------------------------------------------------------------- telements = time() xycoord_higher = [] ParallelTuple1 = [] if Parallel: # GET HIGHER ORDER COORDINATES - PARALLEL ParallelTuple1 = parmap.map(ElementLoopTri, np.arange(0, mesh.elements.shape[0]), mesh.elements, mesh.points, 'line', eps, Neval, pool=MP.Pool(processes=nCPU)) # LOOP OVER ELEMENTS maxNode = np.max(reelements) for elem in range(0, mesh.elements.shape[0]): # GET HIGHER ORDER COORDINATES if Parallel: xycoord_higher = ParallelTuple1[elem] else: xycoord_higher = GetInteriorNodesCoordinates( mesh.points[mesh.elements[elem, :], :], 'line', elem, eps, Neval) # EXPAND THE ELEMENT CONNECTIVITY newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes) # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes) reelements[elem, 2:] = newElements maxNode = newElements[-1] repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] + (elem + 1) * iesize] = xycoord_higher[2:, :] telements = time() - telements #-------------------------------------------------------------------------------------- # NOW REMOVE DUPLICATED POINTS tnodes = time() nnode_linear = mesh.points.shape[0] # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR rounded_repoints = repoints[nnode_linear:, :].copy() makezero(rounded_repoints) rounded_repoints = np.round(rounded_repoints, decimals=Decimals) _, idx_repoints, inv_repoints = unique2d(rounded_repoints, order=False, consider_sort=False, return_index=True, return_inverse=True) del rounded_repoints idx_repoints = np.concatenate( (np.arange(nnode_linear), idx_repoints + nnode_linear)) repoints = repoints[idx_repoints, :] unique_reelements, inv_reelements = np.unique(reelements[:, 2:], return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 2) reelements = np.concatenate((mesh.elements, reelements), axis=1) # SANITY CHECK FOR DUPLICATES #---------------------------------------------------------------------# # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO # LINEAR CONNECTIVITY if check_duplicates: last_shape = repoints.shape[0] deci = int(Decimals) - 2 if Decimals < 6: deci = Decimals repoints, idx_repoints, inv_repoints = remove_duplicates_2D( repoints, decimals=deci) unique_reelements, inv_reelements = np.unique(reelements, return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem) if last_shape != repoints.shape[0]: warn( 'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now' ) #---------------------------------------------------------------------# tnodes = time() - tnodes #------------------------------------------------------------------------------------------ class nmesh(object): points = repoints elements = reelements edges = [] faces = [] nnode = repoints.shape[0] nelem = reelements.shape[0] info = 'line' # MESH CORNERS REMAIN THE SAME FOR ALL POLYNOMIAL DEGREES if isinstance(mesh.corners, np.ndarray): nmesh.corners = mesh.corners return nmesh
def HighOrderMeshQuad(C, mesh, Decimals=10, equally_spaced=False, check_duplicates=True, parallelise=False, nCPU=1, compute_boundary_info=True): from Florence.FunctionSpace import Quad, QuadES from Florence.QuadratureRules import GaussLobattoPointsQuad from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPoints from Florence.MeshGeneration.NodeArrangement import NodeArrangementQuad Parallel = parallelise if not equally_spaced: eps = GaussLobattoPointsQuad(C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS Neval = np.zeros((4, eps.shape[0]), dtype=np.float64) for i in range(0, eps.shape[0]): Neval[:, i] = Quad.LagrangeGaussLobatto(0, eps[i, 0], eps[i, 1], arrange=1)[:, 0] else: eps = EquallySpacedPoints(3, C) # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS Neval = np.zeros((4, eps.shape[0]), dtype=np.float64) for i in range(0, eps.shape[0]): Neval[:, i] = QuadES.Lagrange(0, eps[i, 0], eps[i, 1], arrange=1)[:, 0] makezero(Neval) nodeperelem = mesh.elements.shape[1] renodeperelem = int((C + 2)**2) left_over_nodes = renodeperelem - nodeperelem reelements = -1 * np.ones( (mesh.elements.shape[0], renodeperelem), dtype=np.int64) reelements[:, :4] = mesh.elements iesize = int(4 * C + C**2) repoints = np.zeros( (mesh.points.shape[0] + iesize * mesh.elements.shape[0], mesh.points.shape[1]), dtype=np.float64) repoints[:mesh.points.shape[0], :] = mesh.points #-------------------------------------------------------------------------------------- telements = time() xycoord_higher = [] ParallelTuple1 = [] if Parallel: # GET HIGHER ORDER COORDINATES - PARALLEL ParallelTuple1 = parmap.map(ElementLoopTri, np.arange(0, mesh.elements.shape[0]), mesh.elements, mesh.points, 'quad', eps, Neval, pool=MP.Pool(processes=nCPU)) # LOOP OVER ELEMENTS maxNode = np.max(reelements) for elem in range(0, mesh.elements.shape[0]): # GET HIGHER ORDER COORDINATES if Parallel: xycoord_higher = ParallelTuple1[elem] else: xycoord_higher = GetInteriorNodesCoordinates( mesh.points[mesh.elements[elem, :], :], 'quad', elem, eps, Neval) # EXPAND THE ELEMENT CONNECTIVITY newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes) # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes) reelements[elem, 4:] = newElements maxNode = newElements[-1] repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] + (elem + 1) * iesize] = xycoord_higher[4:, :] telements = time() - telements #-------------------------------------------------------------------------------------- # NOW REMOVE DUPLICATED POINTS tnodes = time() nnode_linear = mesh.points.shape[0] # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR rounded_repoints = repoints[nnode_linear:, :].copy() makezero(rounded_repoints) rounded_repoints = np.round(rounded_repoints, decimals=Decimals) _, idx_repoints, inv_repoints = unique2d(rounded_repoints, order=False, consider_sort=False, return_index=True, return_inverse=True) del rounded_repoints idx_repoints = np.concatenate( (np.arange(nnode_linear), idx_repoints + nnode_linear)) repoints = repoints[idx_repoints, :] unique_reelements, inv_reelements = np.unique(reelements[:, 4:], return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 4) reelements = np.concatenate((mesh.elements, reelements), axis=1) # SANITY CHECK FOR DUPLICATES #---------------------------------------------------------------------# # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO # LINEAR CONNECTIVITY if check_duplicates: last_shape = repoints.shape[0] deci = int(Decimals) - 2 if Decimals < 6: deci = Decimals repoints, idx_repoints, inv_repoints = remove_duplicates_2D( repoints, decimals=deci) unique_reelements, inv_reelements = np.unique(reelements, return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem) if last_shape != repoints.shape[0]: warn( 'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now' ) #---------------------------------------------------------------------# tnodes = time() - tnodes #------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------ reedges = np.array([]) if compute_boundary_info: # BUILD EDGES NOW tedges = time() edge_to_elements = mesh.GetElementsWithBoundaryEdgesQuad() node_arranger = NodeArrangementQuad(C)[0] reedges = np.zeros((mesh.edges.shape[0], C + 2), dtype=np.int64) reedges = reelements[edge_to_elements[:, 0][:, None], node_arranger[edge_to_elements[:, 1], :]] tedges = time() - tedges #------------------------------------------------------------------------------------------ class nmesh(object): points = repoints elements = reelements edges = reedges faces = [] nnode = repoints.shape[0] nelem = reelements.shape[0] info = 'quad' # print('\npMeshing timing:\n\t\tElement loop 1:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\ # ' seconds'+'\n\t\tElement loop 2:\t '+str(telements_2)+' seconds\n\t\tEdge loop:\t\t '+str(tedges)+' seconds\n') return nmesh
maxNode = newElements[-1] repoints[mesh.points.shape[0]+elem*iesize:mesh.points.shape[0]+(elem+1)*iesize] = xycoord_higher[2:,:] telements = time()-telements #-------------------------------------------------------------------------------------- # NOW REMOVE DUPLICATED POINTS tnodes = time() nnode_linear = mesh.points.shape[0] # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR rounded_repoints = repoints[nnode_linear:,:].copy() makezero(rounded_repoints) rounded_repoints = np.round(rounded_repoints,decimals=Decimals) _, idx_repoints, inv_repoints = unique2d(rounded_repoints,order=False, consider_sort=False,return_index=True,return_inverse=True) del rounded_repoints idx_repoints = np.concatenate((np.arange(nnode_linear),idx_repoints+nnode_linear)) repoints = repoints[idx_repoints,:] unique_reelements, inv_reelements = np.unique(reelements[:,2:],return_inverse=True) unique_reelements = unique_reelements[inv_repoints] reelements = unique_reelements[inv_reelements] reelements = reelements.reshape(mesh.elements.shape[0],renodeperelem-2) reelements = np.concatenate((mesh.elements,reelements),axis=1) # SANITY CHECK FOR DUPLICATES #---------------------------------------------------------------------# # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH