def writeOutTriangulation(tri, filebase="mesh", nbase=0, verbose=0): """ collect necessary steps to write out files for triangle data structures """ failed = False if tri == None: failed = True return failed if not nbase in [0, 1]: print 'must have vertex base numbering = 0 or 1, got nbase= ', nbase failed = True return failed #end nodes = triangulate.getPoints(tri) patts = triangulate.getPointAttributes(tri) pmarks = triangulate.getPointMarkers(tri) if verbose > 0: print 'writing node file' printNodeFile(nodes, filebase, patts, pmarks, nbase=nbase) elems = triangulate.getTriangles(tri) eatts = triangulate.getTriangleAttributes(tri) if verbose > 0: print 'writing elements file' printElemFile(elems, filebase, eatts, nbase=nbase) segms = triangulate.getSegments(tri) segmmks = triangulate.getSegmentMarkers(tri) holes = triangulate.getHoles(tri) regions = triangulate.getRegions(tri) if verbose > 0: print 'writing poly file' printPolyFile(nodes, segms, filebase, patts, pmarks, segmmks, holes, regions, nbase=nbase) edges = triangulate.getEdges(tri) edgemks = triangulate.getEdgeMarkers(tri) if verbose > 0: print 'writing edges file' printEdgeFile(edges, filebase, edgemks, nbase=nbase) neigs = triangulate.getNeighbors(tri) if verbose > 0: print 'writing neighbors file' printNeighborFile(neigs, filebase, nbase=nbase) return failed
def writeOutTriangulation(tri,filebase="mesh",nbase=0,verbose=0): """ collect necessary steps to write out files for triangle data structures """ failed = False if tri == None: failed = True return failed if not nbase in [0,1]: print 'must have vertex base numbering = 0 or 1, got nbase= ',nbase failed = True return failed #end nodes = triangulate.getPoints(tri) patts = triangulate.getPointAttributes(tri) pmarks= triangulate.getPointMarkers(tri) if verbose > 0: print 'writing node file' printNodeFile(nodes,filebase,patts,pmarks,nbase=nbase) elems = triangulate.getTriangles(tri) eatts = triangulate.getTriangleAttributes(tri) if verbose > 0: print 'writing elements file' printElemFile(elems,filebase,eatts,nbase=nbase) segms = triangulate.getSegments(tri) segmmks= triangulate.getSegmentMarkers(tri) holes = triangulate.getHoles(tri) regions= triangulate.getRegions(tri) if verbose > 0: print 'writing poly file' printPolyFile(nodes,segms,filebase,patts,pmarks, segmmks,holes,regions,nbase=nbase) edges = triangulate.getEdges(tri) edgemks= triangulate.getEdgeMarkers(tri) if verbose > 0: print 'writing edges file' printEdgeFile(edges,filebase,edgemks,nbase=nbase) neigs = triangulate.getNeighbors(tri) if verbose > 0: print 'writing neighbors file' printNeighborFile(neigs,filebase,nbase=nbase) return failed
def convertToAdhPyUtilMesh(self, verbose=0): """ Generate a representation in the format expected by adhPyUtil. Need to make sure the triangle mesh has generated nodes elements (triangles) edges neighbors First set the _global arrays for nodes elements """ import MeshTools triInfo = triangulate.getInfo(self.trirep[0]) if verbose > 1: print 'generating adhPyUtilMesh:' print self.infoFormat % triInfo #end if #create basic adhPyUtil mesh meshout = MeshTools.Mesh() #get basic information to make sure I can proceed #with current mesh representation nNodes_global = triInfo[0] nElems_global = triInfo[2] nNodes_elem = triInfo[3] nEdges_global = triInfo[8] spaceDim = 2 assert (nNodes_global > 0 and nElems_global > 0 and nNodes_elem >= 3 and nEdges_global > 0) #subtract off base since adhPyMesh wants base 0 more or less nbase = self.nbase #should also check? base zero, #get the minimum array information ##nodes nodeArray = triangulate.getPoints(self.trirep[0]) meshout.nNodes_global = nNodes_global meshout.nodeArray = Numeric.zeros((meshout.nNodes_global, 3), Numeric.Float) for nN in range(nNodes_global): meshout.nodeArray[nN, :spaceDim] = nodeArray[nN, :spaceDim] - nbase ##elements elemArray = triangulate.getTriangles(self.trirep[0]) #ignore higher order nodes for adhPyUtil mesh meshout.nNodes_element = spaceDim + 1 meshout.nElements_global = nElems_global #just copy over first 3 nodes meshout.elementNodesArray = Numeric.zeros( (nElems_global, spaceDim + 1), Numeric.Int) for eN in range(nElems_global): meshout.elementNodesArray[eN, :] = elemArray[eN, :spaceDim + 1] - nbase #end eN ##adhPyMesh keeps elements per node nodeElementsDict = {} for eN in range(nElems_global): for nN_element in range(spaceDim + 1): nN = meshout.elementNodesArray[eN, nN_element] if nodeElementsDict.has_key(nN): nodeElementsDict[nN].append(eN) else: nodeElementsDict[nN] = [eN] #end if #end for nN_element #end eN meshout.max_nElements_node = max( len(nodeElementsDict[nN]) for nN in range(meshout.nNodes_global)) meshout.nElements_node = Numeric.zeros((meshout.nNodes_global, ), Numeric.Int) meshout.nodeElementsArray = Numeric.zeros( (meshout.nNodes_global, meshout.max_nElements_node), Numeric.Int) for nN, elementList in nodeElementsDict.iteritems(): meshout.nElements_node[nN] = len(elementList) for eN_element, eN in enumerate(elementList): meshout.nodeElementsArray[nN, eN_element] = eN #end eN_element #end nN ##now build the element <--> element boundary arrays meshout.nElementBoundaries_element = spaceDim + 1 #make sure Triangle keeps all edges and not just boundary ones meshout.nElementBoundaries_global = nEdges_global #maps element, local edge number to global edge number meshout.elementBoundariesArray = Numeric.zeros( (nElems_global, spaceDim + 1), Numeric.Int) #maps edge to global element on left and right (out of domain is 0) meshout.elementBoundaryElementsArray = Numeric.ones( (meshout.nElementBoundaries_global, 2), Numeric.Int) meshout.elementBoundaryElementsArray *= -1 #maps global edge to its local number on the neighboring elements meshout.elementBoundaryLocalElementBoundariesArray = Numeric.zeros( (meshout.nElementBoundaries_global, 2), Numeric.Int) #several options for edge to "left" and "right" element neighbor, #could number each neighbor according to which one #has a given edge first in the current numbering #could try to make element 0 be the one that has same orientation of edge elementBoundaryElementsCardArray = Numeric.zeros( (meshout.nElementBoundaries_global, ), Numeric.Int) #CardArray in Mesh #I have to generate the element-->global edge number mapping manually edgeArray = triangulate.getEdges(self.trirep[0]) edgeDict = {} for edgeN in range(nEdges_global): n0 = edgeArray[edgeN, 0] - nbase n1 = edgeArray[edgeN, 1] - nbase edgeDict[(n0, n1)] = edgeN #global edge number #end for for eN in range(nElems_global): locNodes = elemArray[eN, :spaceDim + 1] - nbase #global node numbers edgeOrientedSame = [False, False, False] #edge I is across from node I #0 e0 = (locNodes[1], locNodes[2]) e0rev = (locNodes[2], locNodes[1]) e0_global = None if edgeDict.has_key(e0): e0_global = edgeDict[e0] #same orientation edgeOrientedSame[0] = True elif edgeDict.has_key(e0rev): #opposite orientation e0_global = edgeDict[ e0rev] #could make negative to denote orientation #end if assert (not e0_global == None) #1 e1 = (locNodes[2], locNodes[0]) e1rev = (locNodes[0], locNodes[2]) e1_global = None if edgeDict.has_key(e1): e1_global = edgeDict[e1] #same orientation edgeOrientedSame[1] = True elif edgeDict.has_key(e1rev): #opposite orientation e1_global = edgeDict[ e1rev] #could make negative to denote orientation #end if assert (not e1_global == None) #2 e2 = (locNodes[0], locNodes[1]) e2rev = (locNodes[1], locNodes[0]) e2_global = None if edgeDict.has_key(e2): e2_global = edgeDict[e2] #same orientation edgeOrientedSame[2] = True elif edgeDict.has_key(e2rev): #opposite orientation e2_global = edgeDict[ e2rev] #could make negative to denote orientation #end if assert (not e2_global == None) eI_global = Numeric.array([e0_global, e1_global, e2_global], Numeric.Int) meshout.elementBoundariesArray[eN, :] = eI_global for eI in eI_global: #edge --> element mappings elementBoundaryElementsCardArray[eI] += 1 #end eI for eiloc in range(meshout.nElementBoundaries_element): eI = eI_global[eiloc] #first visited labelling elneig = elementBoundaryElementsCardArray[eI] - 1 #elneig = 0 #same orientation #if not edgeOrientedSame[eiloc] #elneig = 1 #opposite ##endif meshout.elementBoundaryElementsArray[eI, elneig] = eN meshout.elementBoundaryLocalElementBoundariesArray[ eI, elneig] = eiloc #end eiloc #end eN #perform some sanity checks for edgeN in range(nEdges_global): assert (elementBoundaryElementsCardArray[edgeN] in [1, 2]) eN0 = meshout.elementBoundaryElementsArray[edgeN, 0] eN1 = meshout.elementBoundaryElementsArray[edgeN, 1] assert (0 <= eN0 and eN0 < meshout.nElements_global) if elementBoundaryElementsCardArray[edgeN] == 1: assert (eN1 == -1) else: assert (0 <= eN1 and eN1 < meshout.nElements_global) #end if #end sanity check on edges #now take care of boundary edges #interior elements counted twice sumCard = Numeric.sum(elementBoundaryElementsCardArray) nExtBnd = 2 * meshout.nElementBoundaries_global - sumCard nIntBnd = meshout.nElementBoundaries_global - nExtBnd meshout.nExteriorElementBoundaries_global = nExtBnd meshout.nInteriorElementBoundaries_global = nIntBnd #global edge numbers on exterior boundary meshout.exteriorElementBoundariesArray = Numeric.zeros((nExtBnd, ), Numeric.Int) meshout.interiorElementBoundariesArray = Numeric.zeros((nIntBnd, ), Numeric.Int) #enumerate interior and exterior interiorI = 0 exteriorI = 0 for ebN in range(meshout.nElementBoundaries_global): if elementBoundaryElementsCardArray[ebN] == 1: meshout.exteriorElementBoundariesArray[exteriorI] = ebN exteriorI += 1 else: meshout.interiorElementBoundariesArray[interiorI] = ebN interiorI += 1 #end if on card #end ebN #now track which nodes are on the boundary #maps edge --> its nodes #this is just the edgelist in triangle meshout.elementBoundaryNodesArray = Numeric.zeros( (nEdges_global, spaceDim), Numeric.Int) for edgeN in range(nEdges_global): meshout.elementBoundaryNodesArray[ edgeN, :spaceDim] = edgeArray[edgeN, :spaceDim] - nbase #end edgeN #2d so edgeList is same as elementBoundaryNodesArray meshout.edgeNodesArray = Numeric.zeros((nEdges_global, spaceDim), Numeric.Int) for edgeN in range(nEdges_global): meshout.edgeNodesArray[ edgeN, :spaceDim] = edgeArray[edgeN, :spaceDim] - nbase #end edgeN #now tell mesh that it doesn't have the list interface meshout.hasListInterface = False #compute diameters array manually meshout.elementDiametersArray = Numeric.zeros( (meshout.nElements_global, ), Numeric.Float) import math for eN in range(meshout.nElements_global): elen = Numeric.zeros((meshout.nElementBoundaries_element, ), Numeric.Float) for eloc in range(meshout.nElementBoundaries_element): eg = meshout.elementBoundariesArray[eN, eloc] #glocal edge number n0, n1 = meshout.elementBoundaryNodesArray[ eg, 0:2] #global node numbers number de = meshout.nodeArray[n0, :] - meshout.nodeArray[n1, :] elen[eloc] = math.sqrt(de[0]**2 + de[1]**2) #end eloc meshout.elementDiametersArray[eN] = max(elen) #end eN meshout.hasGeometricInfo = True return meshout
def convertToAdhPyUtilMesh(self,verbose=0): """ Generate a representation in the format expected by adhPyUtil. Need to make sure the triangle mesh has generated nodes elements (triangles) edges neighbors First set the _global arrays for nodes elements """ import MeshTools triInfo = triangulate.getInfo(self.trirep[0]) if verbose > 1: print 'generating adhPyUtilMesh:' print self.infoFormat % triInfo #end if #create basic adhPyUtil mesh meshout = MeshTools.Mesh() #get basic information to make sure I can proceed #with current mesh representation nNodes_global = triInfo[0]; nElems_global = triInfo[2]; nNodes_elem = triInfo[3]; nEdges_global = triInfo[8]; spaceDim = 2 assert(nNodes_global > 0 and nElems_global > 0 and nNodes_elem >= 3 and nEdges_global > 0) #subtract off base since adhPyMesh wants base 0 more or less nbase = self.nbase #should also check? base zero, #get the minimum array information ##nodes nodeArray = triangulate.getPoints(self.trirep[0]) meshout.nNodes_global = nNodes_global meshout.nodeArray = Numeric.zeros((meshout.nNodes_global,3), Numeric.Float) for nN in range(nNodes_global): meshout.nodeArray[nN,:spaceDim] = nodeArray[nN,:spaceDim]-nbase ##elements elemArray = triangulate.getTriangles(self.trirep[0]) #ignore higher order nodes for adhPyUtil mesh meshout.nNodes_element = spaceDim+1 meshout.nElements_global = nElems_global #just copy over first 3 nodes meshout.elementNodesArray = Numeric.zeros((nElems_global,spaceDim+1), Numeric.Int) for eN in range(nElems_global): meshout.elementNodesArray[eN,:] = elemArray[eN,:spaceDim+1]-nbase #end eN ##adhPyMesh keeps elements per node nodeElementsDict={} for eN in range(nElems_global): for nN_element in range(spaceDim+1): nN = meshout.elementNodesArray[eN,nN_element] if nodeElementsDict.has_key(nN): nodeElementsDict[nN].append(eN) else: nodeElementsDict[nN] = [eN] #end if #end for nN_element #end eN meshout.max_nElements_node = max(len(nodeElementsDict[nN]) for nN in range(meshout.nNodes_global)) meshout.nElements_node = Numeric.zeros((meshout.nNodes_global,),Numeric.Int) meshout.nodeElementsArray = Numeric.zeros((meshout.nNodes_global, meshout.max_nElements_node), Numeric.Int) for nN,elementList in nodeElementsDict.iteritems(): meshout.nElements_node[nN] = len(elementList) for eN_element,eN in enumerate(elementList): meshout.nodeElementsArray[nN,eN_element]=eN #end eN_element #end nN ##now build the element <--> element boundary arrays meshout.nElementBoundaries_element = spaceDim+1 #make sure Triangle keeps all edges and not just boundary ones meshout.nElementBoundaries_global = nEdges_global #maps element, local edge number to global edge number meshout.elementBoundariesArray = Numeric.zeros((nElems_global,spaceDim+1), Numeric.Int) #maps edge to global element on left and right (out of domain is 0) meshout.elementBoundaryElementsArray=Numeric.ones( (meshout.nElementBoundaries_global,2),Numeric.Int) meshout.elementBoundaryElementsArray*=-1 #maps global edge to its local number on the neighboring elements meshout.elementBoundaryLocalElementBoundariesArray=Numeric.zeros( (meshout.nElementBoundaries_global,2),Numeric.Int) #several options for edge to "left" and "right" element neighbor, #could number each neighbor according to which one #has a given edge first in the current numbering #could try to make element 0 be the one that has same orientation of edge elementBoundaryElementsCardArray = Numeric.zeros((meshout.nElementBoundaries_global,), Numeric.Int) #CardArray in Mesh #I have to generate the element-->global edge number mapping manually edgeArray = triangulate.getEdges(self.trirep[0]) edgeDict = {} for edgeN in range(nEdges_global): n0 = edgeArray[edgeN,0]-nbase; n1 = edgeArray[edgeN,1]-nbase edgeDict[(n0,n1)] = edgeN #global edge number #end for for eN in range(nElems_global): locNodes = elemArray[eN,:spaceDim+1]-nbase #global node numbers edgeOrientedSame = [False,False,False] #edge I is across from node I #0 e0 = (locNodes[1],locNodes[2]); e0rev = (locNodes[2],locNodes[1]) e0_global = None if edgeDict.has_key(e0): e0_global = edgeDict[e0] #same orientation edgeOrientedSame[0] = True elif edgeDict.has_key(e0rev): #opposite orientation e0_global = edgeDict[e0rev] #could make negative to denote orientation #end if assert(not e0_global == None) #1 e1 = (locNodes[2],locNodes[0]); e1rev = (locNodes[0],locNodes[2]) e1_global = None if edgeDict.has_key(e1): e1_global = edgeDict[e1] #same orientation edgeOrientedSame[1] = True elif edgeDict.has_key(e1rev): #opposite orientation e1_global = edgeDict[e1rev] #could make negative to denote orientation #end if assert(not e1_global == None) #2 e2 = (locNodes[0],locNodes[1]); e2rev = (locNodes[1],locNodes[0]) e2_global = None if edgeDict.has_key(e2): e2_global = edgeDict[e2] #same orientation edgeOrientedSame[2] = True elif edgeDict.has_key(e2rev): #opposite orientation e2_global = edgeDict[e2rev] #could make negative to denote orientation #end if assert(not e2_global == None) eI_global = Numeric.array([e0_global,e1_global,e2_global], Numeric.Int) meshout.elementBoundariesArray[eN,:] = eI_global for eI in eI_global: #edge --> element mappings elementBoundaryElementsCardArray[eI] += 1 #end eI for eiloc in range(meshout.nElementBoundaries_element): eI = eI_global[eiloc] #first visited labelling elneig = elementBoundaryElementsCardArray[eI]-1 #elneig = 0 #same orientation #if not edgeOrientedSame[eiloc] #elneig = 1 #opposite ##endif meshout.elementBoundaryElementsArray[eI,elneig]=eN meshout.elementBoundaryLocalElementBoundariesArray[eI,elneig]=eiloc #end eiloc #end eN #perform some sanity checks for edgeN in range(nEdges_global): assert(elementBoundaryElementsCardArray[edgeN] in [1,2]) eN0 = meshout.elementBoundaryElementsArray[edgeN,0] eN1 = meshout.elementBoundaryElementsArray[edgeN,1] assert(0 <= eN0 and eN0 < meshout.nElements_global) if elementBoundaryElementsCardArray[edgeN] == 1: assert(eN1 == -1) else: assert(0 <= eN1 and eN1 < meshout.nElements_global) #end if #end sanity check on edges #now take care of boundary edges #interior elements counted twice sumCard = Numeric.sum(elementBoundaryElementsCardArray) nExtBnd = 2*meshout.nElementBoundaries_global-sumCard nIntBnd = meshout.nElementBoundaries_global-nExtBnd meshout.nExteriorElementBoundaries_global=nExtBnd meshout.nInteriorElementBoundaries_global=nIntBnd #global edge numbers on exterior boundary meshout.exteriorElementBoundariesArray=Numeric.zeros((nExtBnd,),Numeric.Int) meshout.interiorElementBoundariesArray=Numeric.zeros((nIntBnd,),Numeric.Int) #enumerate interior and exterior interiorI = 0 exteriorI = 0 for ebN in range(meshout.nElementBoundaries_global): if elementBoundaryElementsCardArray[ebN] == 1: meshout.exteriorElementBoundariesArray[exteriorI]=ebN exteriorI+= 1 else: meshout.interiorElementBoundariesArray[interiorI]=ebN interiorI+= 1 #end if on card #end ebN #now track which nodes are on the boundary #maps edge --> its nodes #this is just the edgelist in triangle meshout.elementBoundaryNodesArray = Numeric.zeros((nEdges_global,spaceDim), Numeric.Int) for edgeN in range(nEdges_global): meshout.elementBoundaryNodesArray[edgeN,:spaceDim]=edgeArray[edgeN,:spaceDim]-nbase #end edgeN #2d so edgeList is same as elementBoundaryNodesArray meshout.edgeNodesArray = Numeric.zeros((nEdges_global,spaceDim), Numeric.Int) for edgeN in range(nEdges_global): meshout.edgeNodesArray[edgeN,:spaceDim]=edgeArray[edgeN,:spaceDim]-nbase #end edgeN #now tell mesh that it doesn't have the list interface meshout.hasListInterface=False #compute diameters array manually meshout.elementDiametersArray=Numeric.zeros((meshout.nElements_global,), Numeric.Float) import math for eN in range(meshout.nElements_global): elen = Numeric.zeros((meshout.nElementBoundaries_element,), Numeric.Float) for eloc in range(meshout.nElementBoundaries_element): eg = meshout.elementBoundariesArray[eN,eloc] #glocal edge number n0,n1 = meshout.elementBoundaryNodesArray[eg,0:2] #global node numbers number de = meshout.nodeArray[n0,:]-meshout.nodeArray[n1,:] elen[eloc] = math.sqrt(de[0]**2 + de[1]**2) #end eloc meshout.elementDiametersArray[eN]=max(elen) #end eN meshout.hasGeometricInfo=True return meshout