def __init__(self, vertexCoords, faceVertexIDs, cellFaceIDs): """faceVertexIds and cellFacesIds must be padded with minus ones.""" self.vertexCoords = vertexCoords self.faceVertexIDs = MA.masked_values(faceVertexIDs, -1) self.cellFaceIDs = MA.masked_values(cellFaceIDs, -1) _CommonMesh.__init__(self)
def _calcTopology(self): self.dim = self.vertexCoords.shape[0] if not hasattr(self, "numberOfFaces"): self.numberOfFaces = self.faceVertexIDs.shape[-1] if not hasattr(self, "numberOfCells"): self.numberOfCells = self.cellFaceIDs.shape[-1] if not hasattr(self, "globalNumberOfCells"): self.globalNumberOfCells = self.numberOfCells if not hasattr(self, "globalNumberOfFaces"): self.globalNumberOfFaces = self.numberOfFaces self._calcFaceCellIDs() _CommonMesh._calcTopology(self)
def _connectFaces(self, faces0, faces1): """ Merge faces on the same mesh. This is used to create periodic meshes. The first list of faces, `faces1`, will be the faces that are used to add to the matrix diagonals. The faces in `faces2` will not be used. They aren't deleted but their adjacent cells are made to point at `faces1`. The list `faces2` are not altered, they still remain as members of exterior faces. >>> from fipy.meshes.numMesh.grid2D import Grid2D >>> mesh = Grid2D(nx = 2, ny = 2, dx = 1., dy = 1.) >>> from fipy.tools import parallel >>> print parallel.procID != 0 or (mesh._getCellFaceIDs() == [[0, 1, 2, 3], ... [7, 8, 10, 11], ... [2, 3, 4, 5], ... [6, 7, 9, 10]]).flatten().all() True >>> mesh._connectFaces(numerix.nonzero(mesh.getFacesLeft()), numerix.nonzero(mesh.getFacesRight())) >>> print parallel.procID != 0 or (mesh._getCellFaceIDs() == [[0, 1, 2, 3], ... [7, 6, 10, 9], ... [2, 3, 4, 5], ... [6, 7, 9, 10]]).flatten().all() True """ ## check for errors ## check that faces are members of exterior faces from fipy.variables.faceVariable import FaceVariable faces = FaceVariable(mesh=self, value=False) faces[faces0] = True faces[faces1] = True assert (faces | self.getExteriorFaces() == self.getExteriorFaces()).all() ## following assert checks number of faces are equal, normals are opposite and areas are the same assert numerix.alltrue(numerix.take(self.areaProjections, faces0, axis=1) == numerix.take(-self.areaProjections, faces1, axis=1)) ## extract the adjacent cells for both sets of faces faceCellIDs0 = self.faceCellIDs[0] faceCellIDs1 = self.faceCellIDs[1] ## set the new adjacent cells for `faces0` MA.put(faceCellIDs1, faces0, MA.take(faceCellIDs0, faces0)) MA.put(faceCellIDs0, faces0, MA.take(faceCellIDs0, faces1)) self.faceCellIDs[0] = faceCellIDs0 self.faceCellIDs[1] = faceCellIDs1 ## extract the face to cell distances for both sets of faces faceToCellDistances0 = self.faceToCellDistances[0] faceToCellDistances1 = self.faceToCellDistances[1] ## set the new faceToCellDistances for `faces0` MA.put(faceToCellDistances1, faces0, MA.take(faceToCellDistances0, faces0)) MA.put(faceToCellDistances0, faces0, MA.take(faceToCellDistances0, faces1)) self.faceToCellDistances[0] = faceToCellDistances0 self.faceToCellDistances[1] = faceToCellDistances1 ## calculate new cell distances and add them to faces0 numerix.put(self.cellDistances, faces0, MA.take(faceToCellDistances0 + faceToCellDistances1, faces0)) ## change the direction of the face normals for faces0 for dim in range(self.getDim()): faceNormals = self.faceNormals[dim].copy() numerix.put(faceNormals, faces0, MA.take(faceNormals, faces1)) self.faceNormals[dim] = faceNormals ## Cells that are adjacent to faces1 are changed to point at faces0 ## get the cells adjacent to faces1 faceCellIDs = MA.take(self.faceCellIDs[0], faces1) ## get all the adjacent faces for those particular cells cellFaceIDs = numerix.take(self.cellFaceIDs, faceCellIDs, axis=1) for i in range(cellFaceIDs.shape[0]): ## if the faces is a member of faces1 then change the face to point at ## faces0 cellFaceIDs[i] = MA.where(cellFaceIDs[i] == faces1, faces0, cellFaceIDs[i]) ## add those faces back to the main self.cellFaceIDs tmp = self.cellFaceIDs[i] numerix.put(tmp, faceCellIDs, cellFaceIDs[i]) self.cellFaceIDs[i] = tmp ## calculate new topology _CommonMesh._calcTopology(self) ## calculate new geometry self._calcFaceToCellDistanceRatio() self._calcCellToCellDistances() self._calcScaledGeometry() self._calcFaceAspectRatios()
def _calcGeometry(self): self._calcFaceCenters() _CommonMesh._calcGeometry(self) self._calcCellNormals()