Search code examples
normalsfipy

Fipy calcNormals function


I have a question regarding the calculation of the faceNormals in Fipy: It seems like the normal vector of each face point to the same direction except when the faces are at one of the extremities along the x-, y-, and z-axis of the grid (in which case they point to the opposite direction compared with the other normal vectors). This way, the normals always point toward the interior of a cell. Why is this? Which effect would this have if all the normals were pointing in the same direction (i.e., the last normal would point to the exterior of the mesh). Here is (as way of explanation) the code for the computation of the normals for a 1D non-uniform grid but the principle seems to be the same for 2D- and 3D-grids and meshes:

    def _calcFaceNormals(self):
        faceNormals = numerix.array((numerix.ones(self.numberOfFaces, 'd'),))
        # The left-most face has neighboring cells None and the left-most cell.
        # We must reverse the normal to make fluxes work correctly.
        if self.numberOfFaces > 0:
            faceNormals[..., 0] = -faceNormals[..., 0]
        return faceNormals

For a non-uniform 3D grid, should the normal be pointing toward the center of the cell or simply toward the interior (and have a length of 1)?

The normal of each face is used to compute the advection- and diffusion -flow direction and speed, is this correct?

In this case, the fact that the last normals of a grid point in another direction than the rest would lead to an error in the computation of the flux at the boundaries, would it not?

Thank you for your help!


Solution

  • As the comment in the code says

    # The left-most face has neighboring cells None and the left-most cell.
    # We must reverse the normal to make fluxes work correctly.
    

    FiPy is implemented such that faceNormals always points into the second of the two cells on either side of a face. For the right-most cell in a Grid1D, there is no cell to the right, so the first and second cells are the same and faceNormals points to the left. The same considerations apply for any exterior face.

    It looks like we had intended to distinguish between .faceNormals and ._orientedFaceNormals, but I see no sign that they are ever different.

    Note: Methods start with '_' as a 'weak "internal use" indicator'. These are implementation details and you shouldn't call them. That goes doubly for methods like "._calcSomething()"; these invariably are the workhorse behind a property .something which you should use instead. If you find you need to call these internal methods, let us know so that we can augment our public API.