Example #1
0
    def __mul__(self, factor):
        if numerix.shape(factor) is ():
            factor = numerix.resize(factor, (2, 1))

        return UniformGrid2D(dx=self.args['dx'] * numerix.array(factor[0]), nx=self.args['nx'],
                             dy=self.args['dy'] * numerix.array(factor[1]), ny=self.args['ny'],
                             origin=numerix.array(self.args['origin']) * factor, overlap=self.args['overlap'])
Example #2
0
    def _calcValue(self):
        ids = self.mesh.cellFaceIDs
        contributions = numerix.take(self.faceVariable, ids, axis=-1)
        s = (numerix.newaxis, ) * (len(contributions.shape) - 2) + (slice(
            0, None, None), ) + (slice(0, None, None), )

        faceContributions = contributions * self.mesh._cellToFaceOrientations[
            s]  #just changes sign

        temp = faceContributions.copy()
        maskedValues = np.vstack(
            ([not isinstance(xi, float) for xi in temp[0]
              ], [not isinstance(xi, float) for xi in temp[1]
                  ], [not isinstance(xi, float) for xi in temp[2]],
             [not isinstance(xi, float) for xi in temp[3]]))
        faceAreas = np.take(self.mesh._faceAreas, ids)
        faceAreas = MA.masked_where(maskedValues, faceAreas)
        if (len(temp) > 1):

            temp = temp * faceAreas
            temp[2] = numerix.MA.filled(temp[2], temp[0])
            temp[3] = numerix.MA.filled(temp[3], temp[1])

            faceAreas[2] = numerix.MA.filled(faceAreas[2], faceAreas[0])
            faceAreas[3] = numerix.MA.filled(faceAreas[3], faceAreas[1])
            faceAreas[0] = (faceAreas[0] + faceAreas[2])
            faceAreas[1] = (faceAreas[1] + faceAreas[3])

            temp[0] = (temp[0] + temp[2]) / faceAreas[0]
            temp[1] = (temp[1] + temp[3]) / faceAreas[1]
            temp = numerix.vstack(
                (numerix.array(temp[0]), numerix.array(temp[1])))

        return numerix.tensordot(numerix.ones(temp.shape[-2], 'd'), temp,
                                 (0, -2)) / self.mesh.cellVolumes
Example #3
0
    def _buildMatrixPy(self, L, oldArray, b, dt, coeffVectors):
        N = len(oldArray)

        b += numerix.array(oldArray) * numerix.array(coeffVectors['old value']) / dt
        b += numerix.ones([N]) * numerix.array(coeffVectors['b vector'])
        L.addAtDiagonal(numerix.ones([N]) * numerix.array(coeffVectors['new value']) / dt)
        L.addAtDiagonal(numerix.ones([N]) * numerix.array(coeffVectors['diagonal']))
Example #4
0
    def quiver(self, sparsity=None, scale=None):
        var = self.vars[0]
        mesh = var.mesh

        if isinstance(var, FaceVariable):
            N = mesh.numberOfFaces 
            X, Y = mesh.faceCenters

        elif isinstance(var, CellVariable):
            N = mesh.numberOfCells 
            X, Y = mesh.cellCenters
            
        if sparsity is not None and N > sparsity:
            XYrand = numerix.random.random((2, sparsity))
            XYrand = numerix.array([[min(X)], 
                                    [min(Y)]]) + XYrand * numerix.array([[max(X) - min(X)],
                                                                         [max(Y) - min(Y)]])
            self.indices = numerix.nearest(numerix.array([X, Y]), XYrand)
        else:
            self.indices = numerix.arange(N)

        X = numerix.take(X, self.indices)
        Y = numerix.take(Y, self.indices)
        
        U = V = numerix.ones(X.shape, 'l')
        
        if hasattr(self, "_quiver"):
            self._quiver.remove()
        
        self._quiver = self.axes.quiver(X, Y, U, V, scale=scale, pivot='middle')
Example #5
0
    def VTKFaceDataSet(self):
        """Returns a TVTK `DataSet` representing the face centers of this mesh
        """
        try:
            from tvtk.api import tvtk
        except ImportError as e:
            from enthought.tvtk.api import tvtk

        points = self.faceCenters
        points = self._toVTK3D(numerix.array(points))
        ug = tvtk.UnstructuredGrid(points=points)

        num = len(points)
        counts = numerix.array([1] * num)[..., numerix.newaxis]
        cells = numerix.arange(self.numberOfFaces)[..., numerix.newaxis]
        cells = numerix.concatenate((counts, cells), axis=1)
        cell_types = numerix.array([tvtk.Vertex().cell_type]*num)
        cell_array = tvtk.CellArray()
        cell_array.set_cells(num, cells)

        counts = numerix.array([1] * num)
        offset = numerix.cumsum(counts+1)
        if len(offset) > 0:
            offset -= offset[0]
        ug.set_cells(cell_types, offset, cell_array)

        return ug
Example #6
0
 def _createCells(self):
     ## cells = (f1, f2, f3, f4) going anticlockwise.
     ## f1 etc. refer to the faces
     bottomFaces = numerix.arange(0, self.numberOfHorizontalFaces - self.nx)
     topFaces = numerix.arange(self.nx, self.numberOfHorizontalFaces)
     leftFaces = vector.prune(
         numerix.arange(
             self.numberOfHorizontalFaces,
             self.numberOfHorizontalFaces + self.numberOfVerticalFaces),
         self.nx + 1, self.nx)
     rightFaces = vector.prune(
         numerix.arange(
             self.numberOfHorizontalFaces,
             self.numberOfHorizontalFaces + self.numberOfVerticalFaces),
         self.nx + 1, 0)
     lowerLeftDiagonalFaces = numerix.arange(
         self.numberOfHorizontalFaces + self.numberOfVerticalFaces,
         self.numberOfHorizontalFaces + self.numberOfVerticalFaces +
         self.numberOfEachDiagonalFaces)
     lowerRightDiagonalFaces = lowerLeftDiagonalFaces + self.numberOfEachDiagonalFaces
     upperLeftDiagonalFaces = lowerRightDiagonalFaces + self.numberOfEachDiagonalFaces
     upperRightDiagonalFaces = upperLeftDiagonalFaces + self.numberOfEachDiagonalFaces
     ##faces in arrays, now get the cells
     bottomOfBoxCells = numerix.array(
         [bottomFaces, lowerRightDiagonalFaces, lowerLeftDiagonalFaces])
     rightOfBoxCells = numerix.array(
         [rightFaces, upperRightDiagonalFaces, lowerRightDiagonalFaces])
     topOfBoxCells = numerix.array(
         [topFaces, upperLeftDiagonalFaces, upperRightDiagonalFaces])
     leftOfBoxCells = numerix.array(
         [leftFaces, lowerLeftDiagonalFaces, upperLeftDiagonalFaces])
     return numerix.concatenate(
         (rightOfBoxCells, topOfBoxCells, leftOfBoxCells, bottomOfBoxCells),
         axis=1)
Example #7
0
    def _plot(self):

        self.g('set cbrange [' + self._getLimit(('datamin', 'zmin'))  + ':' + self._getLimit(('datamax', 'zmax')) + ']')
        self.g('set view map')
        self.g('set style data pm3d')
        self.g('set pm3d at st solid')
        mesh = self.vars[0].mesh

        if self.vars[0]._variableClass is FaceVariable:
            x, y = mesh.faceCenters
            if isinstance(mesh, Grid2D.__class__):
                nx, ny = mesh.shape
            else:
                N = int(numerix.sqrt(mesh.numberOfCells))
                nx, ny = N, N
        else:
            x, y = mesh.cellCenters
            N = int(numerix.sqrt(mesh.numberOfFaces))
            nx, ny = N, N

        self.g('set dgrid3d %i, %i, 2' % (ny, nx))

        import Gnuplot
        data = Gnuplot.Data(numerix.array(x), numerix.array(y),
                            self.vars[0].value)

        self.g.splot(data)
Example #8
0
    def _explicitBuildMatrixIn(self, oldArray, id1, id2, b, weightedStencilCoeff, mesh, interiorFaces, dt, weight):

        oldArrayId1, oldArrayId2 = self._getOldAdjacentValues(oldArray, id1, id2, dt)
        coeff = numerix.array(self._getGeomCoeff(mesh))
        Nfac = mesh._getNumberOfFaces()

        cell1Diag = numerix.zeros((Nfac,),'d')
        cell1Diag[:] = weight['cell 1 diag']
        cell1OffDiag = numerix.zeros((Nfac,),'d')
        cell1OffDiag[:] = weight['cell 1 offdiag']
        cell2Diag = numerix.zeros((Nfac,),'d')
        cell2Diag[:] = weight['cell 2 diag']
        cell2OffDiag = numerix.zeros((Nfac,),'d')
        cell2OffDiag[:] = weight['cell 2 offdiag']
        
        inline._runInline("""
            long int faceID = faceIDs[i];
            long int cellID1 = id1[i];
            long int cellID2 = id2[i];
            
            b[cellID1] += -coeff[faceID] * (cell1Diag[faceID] * oldArrayId1[i] + cell1OffDiag[faceID] * oldArrayId2[i]);
            b[cellID2] += -coeff[faceID] * (cell2Diag[faceID] * oldArrayId2[i] + cell2OffDiag[faceID] * oldArrayId1[i]);
        """,oldArrayId1 = numerix.array(oldArrayId1),
            oldArrayId2 = numerix.array(oldArrayId2),
            id1 = id1,
            id2 = id2,
            b = b,
            cell1Diag = cell1Diag,
            cell1OffDiag = cell1OffDiag,
            cell2Diag = cell2Diag,
            cell2OffDiag = cell2OffDiag,
            coeff = coeff,
            faceIDs = interiorFaces,
            ni = len(interiorFaces))
Example #9
0
        def _explicitBuildMatrixInline_(self, oldArray, id1, id2, b, coeffMatrix, mesh, interiorFaces, dt, weight):

            oldArrayId1, oldArrayId2 = self._getOldAdjacentValues(oldArray, id1, id2, dt)
            coeff = numerix.array(self._getGeomCoeff(oldArray))
            Nfac = mesh.numberOfFaces

            cell1Diag = numerix.zeros((Nfac,), 'd')
            cell1Diag[:] = weight['cell 1 diag']
            cell1OffDiag = numerix.zeros((Nfac,), 'd')
            cell1OffDiag[:] = weight['cell 1 offdiag']
            cell2Diag = numerix.zeros((Nfac,), 'd')
            cell2Diag[:] = weight['cell 2 diag']
            cell2OffDiag = numerix.zeros((Nfac,), 'd')
            cell2OffDiag[:] = weight['cell 2 offdiag']

            inline._runInline("""
                long int faceID = faceIDs[i];
                long int cellID1 = id1[i];
                long int cellID2 = id2[i];

                b[cellID1] += -coeff[faceID] * (cell1Diag[faceID] * oldArrayId1[i] + cell1OffDiag[faceID] * oldArrayId2[i]);
                b[cellID2] += -coeff[faceID] * (cell2Diag[faceID] * oldArrayId2[i] + cell2OffDiag[faceID] * oldArrayId1[i]);
            """, oldArrayId1 = numerix.array(oldArrayId1),
                oldArrayId2 = numerix.array(oldArrayId2),
                id1 = id1,
                id2 = id2,
                b = b,
                cell1Diag = cell1Diag,
                cell1OffDiag = cell1OffDiag,
                cell2Diag = cell2Diag,
                cell2OffDiag = cell2OffDiag,
                coeff = coeff,
                faceIDs = interiorFaces,
                ni = len(interiorFaces))
Example #10
0
    def VTKCellDataSet(self):
        """Returns a TVTK `DataSet` representing the cells of this mesh
        """
        cvi = self._orderedCellVertexIDs.swapaxes(0, 1)
        from fipy.tools import numerix
        if isinstance(cvi, numerix.ma.masked_array):
            counts = cvi.count(axis=1)[:, None]
            cells = numerix.ma.concatenate((counts, cvi), axis=1).compressed()
        else:
            counts = numerix.array([cvi.shape[1]]*cvi.shape[0])[:, None]
            cells = numerix.concatenate((counts, cvi), axis=1).flatten()

        try:
            from tvtk.api import tvtk
        except ImportError as e:
            from enthought.tvtk.api import tvtk
        num = counts.shape[0]

        cps_type = self._VTKCellType
        cell_types = numerix.array([cps_type]*num)
        cell_array = tvtk.CellArray()
        cell_array.set_cells(num, cells)

        points = self.vertexCoords
        points = self._toVTK3D(points)
        ug = tvtk.UnstructuredGrid(points=points)

        offset = numerix.cumsum(counts[:, 0]+1)
        if len(offset) > 0:
            offset -= offset[0]
        ug.set_cells(cell_types, offset, cell_array)

        return ug
Example #11
0
    def quiver(self, sparsity=None, scale=None):
        var = self.vars[0]
        mesh = var.mesh

        if isinstance(var, FaceVariable):
            N = mesh.numberOfFaces
            X, Y = mesh.faceCenters

        elif isinstance(var, CellVariable):
            N = mesh.numberOfCells
            X, Y = mesh.cellCenters

        if sparsity is not None and N > sparsity:
            XYrand = numerix.random.random((2, sparsity))
            XYrand = numerix.array([
                [min(X)], [min(Y)]
            ]) + XYrand * numerix.array([[max(X) - min(X)], [max(Y) - min(Y)]])
            self.indices = numerix.nearest(numerix.array([X, Y]), XYrand)
        else:
            self.indices = numerix.arange(N)

        X = numerix.take(X, self.indices)
        Y = numerix.take(Y, self.indices)

        U = V = numerix.ones(X.shape, 'l')

        if hasattr(self, "_quiver"):
            self._quiver.remove()

        self._quiver = self.axes.quiver(X,
                                        Y,
                                        U,
                                        V,
                                        scale=scale,
                                        pivot='middle')
Example #12
0
    def _plot(self):

        self.g('set yrange [' + self._getLimit(('datamin', 'ymin', 'zmin')) +
               ':' + self._getLimit(('datamax', 'ymin', 'zmax')) + ']')

        tupleOfGnuplotData = ()

        import Gnuplot
        import re
        m = re.match(r"\d+.\d+", Gnuplot.__version__)
        if m is None or float(m.group(0)) < 1.8:
            raise ImportError("Gnuplot.py version 1.8 or newer is required.")

        for var in self.vars:
            # Python 2.6 made 'with' a keyward (deprecation warnings have been issued since 2.5)
            # this was addressed in Gnuplot.py in r299, in 2007

            if var._variableClass is not FaceVariable:
                X = var.mesh.cellCenters[0]
            else:
                X = var.mesh.faceCenters[0]

            tupleOfGnuplotData += (Gnuplot.Data(numerix.array(X),
                                                numerix.array(var),
                                                title=var.name,
                                                with_='lines'), )

        apply(self.g.plot, tupleOfGnuplotData)
Example #13
0
    def _calcValueInline(self):
        
        NCells = self.mesh.numberOfCells
        ids = self.mesh.cellFaceIDs

        val = self._array.copy()

        inline._runInline("""
        int i;

        for(i = 0; i < numberOfCells; i++)
          {
          int j;
          value[i] = 0.;
          for(j = 0; j < numberOfCellFaces; j++)
            {
              // cellFaceIDs can be masked, which caused subtle and 
              // unreproduceable problems on OS X (who knows why not elsewhere)
              long id = ids[i + j * numberOfCells];
              if (id >= 0) { 
                  value[i] += orientations[i + j * numberOfCells] * faceVariable[id];
              }
            }
            value[i] = value[i] / cellVolume[i];
          }
          """,
                          numberOfCellFaces = self.mesh._maxFacesPerCell,
                          numberOfCells = NCells,
                          faceVariable = self.faceVariable.numericValue,
                          ids = numerix.array(ids),
                          value = val,
                          orientations = numerix.array(self.mesh._cellToFaceOrientations),
                          cellVolume = numerix.array(self.mesh.cellVolumes))
        
        return self._makeValue(value = val)
Example #14
0
    def _calcValue(self):

        Nfaces = self.mesh.numberOfFaces
        M = self.mesh._maxFacesPerCell
        dim = self.mesh.dim
        cellFaceIDs = self.mesh.cellFaceIDs

        faceNormalAreas = self.distanceVar._levelSetNormals * self.mesh._faceAreas

        cellFaceNormalAreas = numerix.array(MA.filled(numerix.take(faceNormalAreas, cellFaceIDs, axis=-1), 0))
        norms = numerix.array(MA.filled(MA.array(self.mesh._cellNormals), 0))

        alpha = numerix.dot(cellFaceNormalAreas, norms)
        alpha = numerix.where(alpha > 0, alpha, 0)

        alphasum = numerix.sum(alpha, axis=0)
        alphasum += (alphasum < 1e-100) * 1.0
        alpha = alpha / alphasum

        phi = numerix.repeat(self.distanceVar[numerix.newaxis, ...], M, axis=0)
        alpha = numerix.where(phi > 0., 0, alpha)

        volumes = numerix.array(self.mesh.cellVolumes)
        alpha = alpha * volumes * norms

        value = numerix.zeros((dim, Nfaces), 'd')

        vector._putAdd(value, cellFaceIDs, alpha, mask=MA.getmask(MA.array(cellFaceIDs)))

##         value = numerix.reshape(value, (dim, Nfaces, dim))

        return -value / self.mesh._faceAreas
Example #15
0
File: grid2D.py Project: regmi/fipy
    def _createFaces(self):
        """
        v1, v2 refer to the vertices.
        Horizontal faces are first
        """
        v1 = numerix.arange(self.numberOfVertices)
        v2 = v1 + 1

        horizontalFaces = vector.prune(numerix.array((v1, v2)), self.numberOfVerticalColumns, self.nx, axis=1)

        v1 = numerix.arange(self.numberOfVertices - self.numberOfVerticalColumns)
        v2 = v1 + self.numberOfVerticalColumns
        verticalFaces =  numerix.array((v1, v2))

        ## The cell normals must point out of the cell.
        ## The left and bottom faces have only one neighboring cell,
        ## in the 2nd neighbor position (there is nothing in the 1st).
        ## 
        ## reverse some of the face orientations to obtain the correct normals

        tmp = horizontalFaces.copy()
        horizontalFaces[0,:self.nx] = tmp[1,:self.nx]
        horizontalFaces[1,:self.nx] = tmp[0,:self.nx]

        self.numberOfHorizontalFaces = horizontalFaces.shape[-1]

        tmp = verticalFaces.copy()
        verticalFaces[0, :] = tmp[1, :]
        verticalFaces[1, :] = tmp[0, :]
        if self.numberOfVerticalColumns > 0:
            verticalFaces[0, ::self.numberOfVerticalColumns] = tmp[0, ::self.numberOfVerticalColumns]
            verticalFaces[1, ::self.numberOfVerticalColumns] = tmp[1,::self.numberOfVerticalColumns]

        return numerix.concatenate((horizontalFaces, verticalFaces), axis=1)
Example #16
0
File: mesh.py Project: regmi/fipy
    def getVTKCellDataSet(self):
        """Returns a TVTK `DataSet` representing the cells of this mesh
        """
        cvi = self._getOrderedCellVertexIDs().swapaxes(0,1)
        from fipy.tools import numerix
        if type(cvi) is numerix.ma.masked_array:
            counts = cvi.count(axis=1)[:,None]
            cells = numerix.ma.concatenate((counts,cvi),axis=1).compressed()
        else:
            counts = numerix.array([cvi.shape[1]]*cvi.shape[0])[:,None]
            cells = numerix.concatenate((counts,cvi),axis=1).flatten()
        
        from enthought.tvtk.api import tvtk
        num = counts.shape[0]

        cps_type = self._getVTKCellType()
        cell_types = numerix.array([cps_type]*num)
        cell_array = tvtk.CellArray()
        cell_array.set_cells(num, cells)

        points = self.getVertexCoords()
        points = self._toVTK3D(points)
        ug = tvtk.UnstructuredGrid(points=points)
        
        offset = numerix.cumsum(counts[:,0]+1)
        if len(offset) > 0:
            offset -= offset[0]
        ug.set_cells(cell_types, offset, cell_array)

        return ug
    def _plot(self):

        self.g('set cbrange [' + self._getLimit(('datamin', 'zmin')) + ':' +
               self._getLimit(('datamax', 'zmax')) + ']')
        self.g('set view map')
        self.g('set style data pm3d')
        self.g('set pm3d at st solid')
        mesh = self.vars[0].mesh

        if self.vars[0]._variableClass is FaceVariable:
            x, y = mesh.faceCenters
            if isinstance(mesh, Grid2D.__class__):
                nx, ny = mesh.shape
            else:
                N = int(numerix.sqrt(mesh.numberOfCells))
                nx, ny = N, N
        else:
            x, y = mesh.cellCenters
            N = int(numerix.sqrt(mesh.numberOfFaces))
            nx, ny = N, N

        self.g('set dgrid3d %i, %i, 2' % (ny, nx))

        import Gnuplot
        data = Gnuplot.Data(numerix.array(x), numerix.array(y),
                            self.vars[0].value)

        self.g.splot(data)
Example #18
0
    def _plot(self):

        self.g('set yrange [' + self._getLimit(('datamin', 'ymin', 'zmin'))  + ':' + self._getLimit(('datamax', 'ymin', 'zmax')) + ']')
        
        tupleOfGnuplotData = ()

        import Gnuplot
        import re
        m = re.match(r"\d+.\d+", Gnuplot.__version__)
        if m is None or float(m.group(0)) < 1.8:
            raise ImportError("Gnuplot.py version 1.8 or newer is required.")
            
        for var in self.vars:
            # Python 2.6 made 'with' a keyward (deprecation warnings have been issued since 2.5)
            # this was addressed in Gnuplot.py in r299, in 2007
            
            if var._variableClass is not FaceVariable:
                X = var.mesh.cellCenters[0]
            else:
                X = var.mesh.faceCenters[0]

            tupleOfGnuplotData += (Gnuplot.Data(numerix.array(X), 
                                                numerix.array(var),
                                                title=var.name,
                                                with_='lines'),)
                              
        apply(self.g.plot, tupleOfGnuplotData)
Example #19
0
    def _levelSetNormals(self):
        """

        Return the face level set normals.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.faceVariable import FaceVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> v = 1 / numerix.sqrt(2)
           >>> answer = FaceVariable(mesh=mesh,
           ...                       value=((0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0),
           ...                              (0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0)))
           >>> print numerix.allclose(distanceVariable._levelSetNormals, answer)
           True
        """

        faceGrad = self.grad.arithmeticFaceValue
        faceGradMag = numerix.array(faceGrad.mag)
        faceGradMag = numerix.where(faceGradMag > 1e-10,
                                    faceGradMag,
                                    1e-10)
        faceGrad = numerix.array(faceGrad)

        ## set faceGrad zero on exteriorFaces
        exteriorFaces = self.mesh.exteriorFaces
        if len(exteriorFaces.value) > 0:
            faceGrad[..., exteriorFaces.value] = 0.
        
        return faceGrad / faceGradMag 
Example #20
0
    def VTKFaceDataSet(self):
        """Returns a TVTK `DataSet` representing the face centers of this mesh
        """
        try:
            from tvtk.api import tvtk
        except ImportError as e:
            from enthought.tvtk.api import tvtk

        points = self.faceCenters
        points = self._toVTK3D(numerix.array(points))
        ug = tvtk.UnstructuredGrid(points=points)

        num = len(points)
        counts = numerix.array([1] * num)[..., numerix.newaxis]
        cells = numerix.arange(self.numberOfFaces)[..., numerix.newaxis]
        cells = numerix.concatenate((counts, cells), axis=1)
        cell_types = numerix.array([tvtk.Vertex().cell_type]*num)
        cell_array = tvtk.CellArray()
        cell_array.set_cells(num, cells)

        counts = numerix.array([1] * num)
        offset = numerix.cumsum(counts+1)
        if len(offset) > 0:
            offset -= offset[0]
        ug.set_cells(cell_types, offset, cell_array)

        return ug
Example #21
0
 def _getArrays(self):
     arrays = []
     
     for var in self.vars:
         arrays.append((numerix.array(var), numerix.array(var.mesh.cellCenters[0])))
         
     return arrays
Example #22
0
 def _getArrays(self):
     arrays = []
     
     for var in self.vars:
         arrays.append((numerix.array(var), numerix.array(var.getMesh().getCellCenters()[0])))
         
     return arrays
Example #23
0
    def _levelSetNormals(self):
        """

        Return the face level set normals.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.faceVariable import FaceVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> v = 1 / numerix.sqrt(2)
           >>> answer = FaceVariable(mesh=mesh,
           ...                       value=((0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0),
           ...                              (0, 0, v, v, 0, 0, 0, v, 0, 0, v, 0)))
           >>> print numerix.allclose(distanceVariable._levelSetNormals, answer)
           True
        """

        faceGrad = self.grad.arithmeticFaceValue
        faceGradMag = numerix.array(faceGrad.mag)
        faceGradMag = numerix.where(faceGradMag > 1e-10, faceGradMag, 1e-10)
        faceGrad = numerix.array(faceGrad)

        ## set faceGrad zero on exteriorFaces
        exteriorFaces = self.mesh.exteriorFaces
        if len(exteriorFaces.value) > 0:
            faceGrad[..., exteriorFaces.value] = 0.

        return faceGrad / faceGradMag
Example #24
0
    def getCellInterfaceAreas(self):
        """
        Returns the length of the interface that crosses the cell

        A simple 1D test:

        >>> from fipy.meshes.grid1D import Grid1D
        >>> mesh = Grid1D(dx = 1., nx = 4)
        >>> distanceVariable = DistanceVariable(mesh = mesh, 
        ...                                     value = (-1.5, -0.5, 0.5, 1.5))
        >>> answer = CellVariable(mesh=mesh, value=(0, 0., 1., 0))
        >>> print numerix.allclose(distanceVariable.getCellInterfaceAreas(), 
        ...                        answer)
        True

        A 2D test case:
        
        >>> from fipy.meshes.grid2D import Grid2D
        >>> from fipy.variables.cellVariable import CellVariable
        >>> mesh = Grid2D(dx = 1., dy = 1., nx = 3, ny = 3)
        >>> distanceVariable = DistanceVariable(mesh = mesh, 
        ...                                     value = (1.5, 0.5, 1.5,
        ...                                              0.5,-0.5, 0.5,
        ...                                              1.5, 0.5, 1.5))
        >>> answer = CellVariable(mesh=mesh,
        ...                       value=(0, 1, 0, 1, 0, 1, 0, 1, 0))
        >>> print numerix.allclose(distanceVariable.getCellInterfaceAreas(), answer)
        True

        Another 2D test case:

        >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
        >>> from fipy.variables.cellVariable import CellVariable
        >>> distanceVariable = DistanceVariable(mesh = mesh, 
        ...                                     value = (-0.5, 0.5, 0.5, 1.5))
        >>> answer = CellVariable(mesh=mesh,
        ...                       value=(0, numerix.sqrt(2) / 4,  numerix.sqrt(2) / 4, 0))
        >>> print numerix.allclose(distanceVariable.getCellInterfaceAreas(), 
        ...                        answer)
        True

        Test to check that the circumfrence of a circle is, in fact, 
        :math:`2\pi r`.
	
        >>> mesh = Grid2D(dx = 0.05, dy = 0.05, nx = 20, ny = 20)
        >>> r = 0.25
        >>> x, y = mesh.getCellCenters()
        >>> rad = numerix.sqrt((x - .5)**2 + (y - .5)**2) - r
        >>> distanceVariable = DistanceVariable(mesh = mesh, value = rad)
        >>> print distanceVariable.getCellInterfaceAreas().sum()
        1.57984690073
        """        
        normals = numerix.array(MA.filled(self._getCellInterfaceNormals(), 0))
        areas = numerix.array(MA.filled(self.mesh._getCellAreaProjections(), 0))
        return CellVariable(mesh=self.mesh, 
                            value=numerix.sum(abs(numerix.dot(normals, areas)), axis=0))
Example #25
0
    def _calcValueInline(self):

        id1, id2 = self.mesh._adjacentCellIDs

        tangents1 = self.mesh._faceTangents1
        tangents2 = self.mesh._faceTangents2

        val = self._array.copy()

        faceNormals = self.mesh._orientedFaceNormals
        if numerix.MA.isMaskedArray(faceNormals):
            faceNormals = faceNormals.filled()

        inline._runIterateElementInline(
            """
            int j;
            double t1grad1, t1grad2, t2grad1, t2grad2, N, N2;
            int ID1 = ITEM(id1, i, NULL);
            int ID2 = ITEM(id2, i, NULL);

            if ITEM(exteriorFaces, i, NULL) {
                 N2 = ITEM(facevar, i, NULL);
            } else {
                 N2 = ITEM(var, ID2, NULL);
            }

            N = (N2 - ITEM(var, ID1, NULL)) / ITEM(dAP, i, NULL);

            t1grad1 = t1grad2 = t2grad1 = t2grad2 = 0.;

            t1grad1 += ITEM(tangents1, i, vec) * ITEM(cellGrad, ID1, vec);
            t1grad2 += ITEM(tangents1, i, vec) * ITEM(cellGrad, ID2, vec);
            t2grad1 += ITEM(tangents2, i, vec) * ITEM(cellGrad, ID1, vec);
            t2grad2 += ITEM(tangents2, i, vec) * ITEM(cellGrad, ID2, vec);

            ITEM(val, i, vec) =  ITEM(normals, i, vec) * N;
            ITEM(val, i, vec) += ITEM(tangents1, i, vec) * (t1grad1 + t1grad2) / 2.;
            ITEM(val, i, vec) += ITEM(tangents2, i, vec) * (t2grad1 + t2grad2) / 2.;
        """,
            tangents1=tangents1,
            tangents2=tangents2,
            cellGrad=self.var.grad.numericValue,
            normals=faceNormals,
            id1=id1,
            id2=id2,
            dAP=numerix.array(self.mesh._cellDistances),
            var=self.var.numericValue,
            facevar=self.var.faceValue.numericValue,
            exteriorFaces=self.mesh.exteriorFaces.numericValue,
            val=val,
            ni=tangents1.shape[1],
            shape=numerix.array(numerix.shape(tangents1)))

        return self._makeValue(value=val)
Example #26
0
def snapshot_var(V, base=False, to_unit=None):
    """
    Utility to express a variable array as its numeric value and corresponding units

    Args:
        V (PhysicalField, Variable, CellVariable, binOp, np.ndarray, int, float): The variable
        base (bool): Whether to express in base units
        to_unit (str): Return array in these units. Ignored if `base = True`

    Returns:
        Tuple of (array, dict(unit=unit))

    """
    if isinstance(V, (PhysicalField, Variable, _BinaryTerm)):
        # This should also cover fipy.CellVariable and fipy.variables.binaryOperatorVariable.binOp
        Vunit = V.unit.name()
        try:
            if base:
                var = V.inBaseUnits()
            else:
                if to_unit:
                    var = V.inUnitsOf(to_unit)
                else:
                    var = V.inUnitsOf(V.unit)
        except:
            import logging
            logger = logging.getLogger(__name__)
            logger.error('V={!r} could not be expressed in units: {}'.format(
                V, V.unit),
                         exc_info=True)
            raise

        if Vunit != '1':
            unit = var.unit.name()
            arr = np.array(var.value)

        else:
            arr = var
            unit = Vunit

    elif isinstance(V, np.ndarray):
        arr = V
        unit = '1'

    elif isinstance(V, (int, float)):
        arr = np.array(V)
        unit = '1'

    else:
        raise ValueError('Cannot snapshot variable of type {}'.format(type(V)))

    return arr, dict(unit=unit)
Example #27
0
    def _calcValueInline(self):

        id1, id2 = self.mesh._adjacentCellIDs

        tangents1 = self.mesh._faceTangents1
        tangents2 = self.mesh._faceTangents2

        val = self._array.copy()

        faceNormals = self.mesh._orientedFaceNormals
        if numerix.MA.isMaskedArray(faceNormals):
            faceNormals = faceNormals.filled()

        inline._runIterateElementInline("""
            int j;
            double t1grad1, t1grad2, t2grad1, t2grad2, N, N2;
            int ID1 = ITEM(id1, i, NULL);
            int ID2 = ITEM(id2, i, NULL);

            if ITEM(exteriorFaces, i, NULL) {
                 N2 = ITEM(facevar, i, NULL);
            } else {
                 N2 = ITEM(var, ID2, NULL);
            }

            N = (N2 - ITEM(var, ID1, NULL)) / ITEM(dAP, i, NULL);

            t1grad1 = t1grad2 = t2grad1 = t2grad2 = 0.;

            t1grad1 += ITEM(tangents1, i, vec) * ITEM(cellGrad, ID1, vec);
            t1grad2 += ITEM(tangents1, i, vec) * ITEM(cellGrad, ID2, vec);
            t2grad1 += ITEM(tangents2, i, vec) * ITEM(cellGrad, ID1, vec);
            t2grad2 += ITEM(tangents2, i, vec) * ITEM(cellGrad, ID2, vec);

            ITEM(val, i, vec) =  ITEM(normals, i, vec) * N;
            ITEM(val, i, vec) += ITEM(tangents1, i, vec) * (t1grad1 + t1grad2) / 2.;
            ITEM(val, i, vec) += ITEM(tangents2, i, vec) * (t2grad1 + t2grad2) / 2.;
        """, tangents1 = tangents1,
            tangents2 = tangents2,
            cellGrad = self.var.grad.numericValue,
            normals = faceNormals,
            id1 = id1,
            id2 = id2,
            dAP = numerix.array(self.mesh._cellDistances),
            var = self.var.numericValue,
            facevar = self.var.faceValue.numericValue,
            exteriorFaces = self.mesh.exteriorFaces.numericValue,
            val = val,
            ni = tangents1.shape[1],
            shape=numerix.array(numerix.shape(tangents1)))

        return self._makeValue(value = val)
Example #28
0
    def _createVertices(self):

        x = numerix.arange(self.nx + 1) * self.dx
        y = numerix.arange(self.ny + 1) * self.dy
        x = numerix.resize(x, (self.numberOfCornerVertices, ))
        y = numerix.repeat(y, self.nx + 1)
        boxCorners = numerix.array((x, y))
        x = numerix.arange(0.5, self.nx + 0.5) * self.dx
        y = numerix.arange(0.5, self.ny + 0.5) * self.dy
        x = numerix.resize(x, (self.numberOfCenterVertices, ))
        y = numerix.repeat(y, self.nx)
        boxCenters = numerix.array((x, y))
        return numerix.concatenate((boxCorners, boxCenters), axis=1)
Example #29
0
    def _getDiagonalSign(self, transientGeomCoeff=None, diffusionGeomCoeff=None):
        if transientGeomCoeff is not None and diffusionGeomCoeff is not None:
            diagonalSign = numerix.where(numerix.array(numerix.all(transientGeomCoeff == 0, axis=-1)),
                                         numerix.array(2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1),
                                         numerix.array(2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1))
        elif transientGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1
        elif diffusionGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1
        else:
            diagonalSign = 1

        return diagonalSign
Example #30
0
    def _createVertices(self):

        x = numerix.arange(self.nx + 1) * self.dx
        y = numerix.arange(self.ny + 1) * self.dy
        x = numerix.resize(x, (self.numberOfCornerVertices,))
        y = numerix.repeat(y, self.nx + 1)
        boxCorners = numerix.array((x, y))
        x = numerix.arange(0.5, self.nx + 0.5) * self.dx
        y = numerix.arange(0.5, self.ny + 0.5) * self.dy
        x = numerix.resize(x, (self.numberOfCenterVertices,))
        y = numerix.repeat(y, self.nx)
        boxCenters = numerix.array((x, y))
        return numerix.concatenate((boxCorners, boxCenters), axis=1)
Example #31
0
    def _getCstring(self, argDict={}, id="", freshen=None):
         """
         Generate the string and dictionary to be used in inline
             >>> (Variable((1)))._getCstring(argDict={})
             'var'
           
             >>> (Variable((1,2,3,4)))._getCstring(argDict={})
             'var[i]'
       
             >>> (Variable(((1,2),(3,4))))._getCstring(argDict={})
             'var[i + j * ni]'

             >>> Variable((((1,2),(3,4)),((5,6),(7,8))))._getCstring(argDict={})
             'var[i + j * ni + k * ni * nj]'

             >>> (Variable(1) * Variable((1,2,3)))._getCstring(argDict={})
             '(var0 * var1[i])'

         freshen is ignored
         """
         
         identifier = 'var%s' % (id)

         v = self.getValue()

         if type(v) not in (type(numerix.array(1)),):
             varray = numerix.array(v)
         else:
             varray = v

         if len(varray.shape) == 0:
             if varray.dtype in (numerix.array(1).dtype,):
                 argDict[identifier] = int(varray)
             elif varray.dtype in (numerix.array(1.).dtype,):
                 argDict[identifier] = float(varray)
             else:
                 argDict[identifier] = varray
         else:
             argDict[identifier] = varray
             
         try:
             shape = self.opShape
         except AttributeError:
             shape = self.shape

         if len(shape) == 0:
##             return identifier + '(0)'         
             return identifier
         else:
             return identifier + self._getCIndexString(shape)
Example #32
0
    def __init__(self, mesh, name = '', value = 0., unit = None, hasOld = 0, narrowBandWidth = 1e+10):
        """
        Creates a `distanceVariable` object.

        :Parameters:
          - `mesh`: The mesh that defines the geometry of this variable.
          - `name`: The name of the variable.
	  - `value`: The initial value.
	  - `unit`: the physical units of the variable
          - `hasOld`: Whether the variable maintains an old value.
          - `narrowBandWidth`: The width of the region about the zero level set
            within which the distance function is evaluated.

        """
        CellVariable.__init__(self, mesh, name = name, value = value, unit = unit, hasOld = hasOld)
        self._markStale()
        self.narrowBandWidth = narrowBandWidth

        self.cellToCellDistances = MA.filled(self.mesh._getCellToCellDistances(), 0)
        self.cellNormals = MA.filled(self.mesh._getCellNormals(), 0)      
        self.cellAreas = MA.filled(self.mesh._getCellAreas(), 0)
##         self.cellToCellDistances = numerix.array(MA.array(self.mesh._getCellToCellDistances()).filled(0))
##         self.cellNormals = numerix.array(MA.array(self.mesh._getCellNormals()).filled(0))       
##         self.cellAreas = numerix.array(MA.array(self.mesh._getCellAreas()).filled(0))
        self.cellToCellIDs = numerix.array(self.mesh._getCellToCellIDsFilled())
        self.adjacentCellIDs = self.mesh._getAdjacentCellIDs()
        self.exteriorFaces = self.mesh.getExteriorFaces()
        self.cellFaceIDs = self.mesh._getCellFaceIDs()
Example #33
0
    def extrude(self, extrudeFunc=lambda x: x + numerix.array((0, 0, 1))[:, numerix.newaxis] , layers=1):
        """
        This function returns a new 3D mesh. The 2D mesh is extruded
        using the `extrudeFunc` and the number of layers.

        >>> from fipy.meshes.nonUniformGrid2D import NonUniformGrid2D
        >>> print(NonUniformGrid2D(nx=2, ny=2).extrude(layers=2).cellCenters)
        [[ 0.5  1.5  0.5  1.5  0.5  1.5  0.5  1.5]
         [ 0.5  0.5  1.5  1.5  0.5  0.5  1.5  1.5]
         [ 0.5  0.5  0.5  0.5  1.5  1.5  1.5  1.5]]

        >>> from fipy.meshes.tri2D import Tri2D
        >>> print(Tri2D().extrude(layers=2).cellCenters.allclose([[ 0.83333333, 0.5,        0.16666667, 0.5,       0.83333333, 0.5,
        ...                                                      0.16666667, 0.5       ],
        ...                                                       [ 0.5,        0.83333333, 0.5,        0.16666667, 0.5,        0.83333333,
        ...                                                      0.5,        0.16666667],
        ...                                                      [ 0.5,        0.5,        0.5,        0.5,        1.5,        1.5,        1.5,
        ...                                                      1.5       ]]))
        True

        Parameters
        ----------
        extrudeFunc : function
            Takes the vertex coordinates and returns the displaced values
        layers : int
            Number of layers in the extruded mesh (number of times
            `extrudeFunc` will be called)
        """

        return self._extrude(self, extrudeFunc, layers)
Example #34
0
def _putAdd(vector, ids, additionVector, mask=False):
    """This is a temporary replacement for Numeric.put as it was not doing
    what we thought it was doing.
    """
    additionVector = numerix.array(additionVector)

    if numerix.sometrue(mask):
        if len(vector.shape) < len(additionVector.shape):
            for j in range(vector.shape[0]):
                for id, value, masked in zip(ids.flat, additionVector[j].flat, mask.flat):
                    if not masked:
                        vector[j].flat[id] += value
        else:
            for id, value, masked in zip(ids.flat, additionVector.flat, mask.flat):
                if not masked:
                    vector.flat[id] += value

    else:
        if len(vector.shape) < len(additionVector.shape):
            for j in range(vector.shape[0]):
                for id, value in zip(ids.flat, additionVector[j].flat):
                    vector[j].flat[id] += value
        else:
            for id, value in zip(ids.flat, additionVector.flat):
                vector.flat[id] += value
Example #35
0
    def _explicitBuildMatrix_(self, SparseMatrix, oldArray, id1, id2, b,
                              weight, var, boundaryConditions, interiorFaces,
                              dt):

        mesh = var.mesh
        coeffMatrix = self._getCoeffMatrix_(var, weight)

        self._explicitBuildMatrixInline_(oldArray=oldArray,
                                         id1=id1,
                                         id2=id2,
                                         b=b,
                                         coeffMatrix=coeffMatrix,
                                         mesh=var.mesh,
                                         interiorFaces=interiorFaces,
                                         dt=dt,
                                         weight=weight)

        N = mesh.numberOfCells
        M = mesh._maxFacesPerCell

        for boundaryCondition in boundaryConditions:

            LL, bb = boundaryCondition._buildMatrix(SparseMatrix, N, M,
                                                    coeffMatrix)
            if LL != 0:
                ##              b -= LL.takeDiagonal() * numerix.array(oldArray)
                b -= LL * numerix.array(oldArray)
            b += bb
Example #36
0
    def _buildMatrix(self, var, SparseMatrix, boundaryCondtions=(), dt=None, equation=None):

        oldArray = var.getOld()

        mesh = var.getMesh()
        NCells = mesh.getNumberOfCells()
        NCellFaces = mesh._getMaxFacesPerCell()

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)
        
        cellIDs = numerix.repeat(numerix.arange(NCells)[numerix.newaxis, ...], NCellFaces, axis = 0)
        cellToCellIDs = mesh._getCellToCellIDs()

        if NCells > 0:
            cellToCellIDs = MA.where(MA.getmask(cellToCellIDs), cellIDs, cellToCellIDs) 

            adjacentValues = numerix.take(oldArray, cellToCellIDs)

            differences = self._getDifferences(adjacentValues, cellValues, oldArray, cellToCellIDs, mesh)
            differences = MA.filled(differences, 0)
            
            minsq = numerix.sqrt(numerix.sum(numerix.minimum(differences, numerix.zeros((NCellFaces, NCells)))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells)))**2, axis=0))

            coeff = numerix.array(self._getGeomCoeff(mesh))

            coeffXdiffereneces = coeff * ((coeff > 0.) * minsq + (coeff < 0.) * maxsq)
        else:
            coeffXdiffereneces = 0.

        return (SparseMatrix(mesh=var.getMesh()), -coeffXdiffereneces * mesh.getCellVolumes())
Example #37
0
    def _calcResidualVector(self, residualFn=None):
        if residualFn is not None:
            return residualFn(self.var, self.matrix, self.RHSvector)
        else:
            Lx = self.matrix * numerix.array(self.var).flatten()

            return Lx - self.RHSvector
Example #38
0
def _getOrderedLines(IDs, coordinates, thresholdDistance = 0.0):
    """
    This function takes a set of IDs and corresponding coordinates and makes
    a set of closed curves.

    :Parameters:

      - `IDs`: An array of integers.
      - `coordinates`: An array of coordinates of the same length as IDs.

    The following are a general set of test cases.

       >>> _getOrderedLines((0, 1, 2, 3), ((0, 0), (2, 0), (0, 1), (2, 1)))
       [[0, 2, 3, 1]]
       >>> _getOrderedLines((0, 1, 2, 3, 4), ((-10, -10), (0, 0), (2, 0), (0, 1), (2, 1)))
       [[0], [1, 3, 4, 2]]
       >>> _getOrderedLines((0, 1, 2, 3), ((0, 0), (0.9, 0), (0, 1), (1, 1)))
       [[0, 1, 3, 2]]
       >>> _getOrderedLines((0, 1, 2, 3, 4, 5), ((0, 0), (1, 0), (2, 0), (0, 1.1), (1, 1.1), (2, 1.1)))
       [[0, 1, 2, 5, 4, 3]]
       >>> _getOrderedLines((4, 5, 0, 1, 3, 2, 6), ((0, 0), (1, 0), (3, 0), (0, 1.1), (1, 1.1), (3, 1), (4, 1)))
       [[4, 5, 3, 1], [0, 2, 6]]
       >>> _getOrderedLines((4, 5, 3, 2, 1, 0, 9, 8, 7, 6), ((0, 0), (1, 0), (0, 1.1), (1, 1.1), (0, 3), (1, 3), (-1, 4), (2, 4), (-2, 4), (3, 4)))
       [[4, 5, 2, 3], [7, 9, 1, 0, 8, 6]]
       >>> from builtins import range
       >>> _getOrderedLines(list(range(7)), ((-7, 0), (-6, 0), (-5, 0), (0, 0), (5, 0), (6, 0), (7, 0)))
       [[0, 1, 2], [3], [4, 5, 6]]
       >>> from builtins import range
       >>> _getOrderedLines(list(range(7)), ((-7, 0), (-6, 0), (-5, 0), (0, 0), (5, 0), (6, 0), (7, 0)), thresholdDistance = 5.5)
       [[0, 1, 2, 3, 4, 5, 6]]
    """

    from fipy.tools import numerix
    coordinates = numerix.array(coordinates)
    closeIDs = numerix.zeros((len(IDs), len(IDs)), 'l')
    vertices = []
    for ID in IDs:
        distances = numerix.zeros(len(IDs), 'd')
        for i in range(len(coordinates[0,:])):
            distances += (coordinates[:, i] - coordinates[ID, i])**2
        vertices.append(_Vertex(ID, coordinates[ID, 0], coordinates[ID, 1]))
        closeIDs[ID,:] = numerix.argsort(distances)


    for ID in IDs:
        i = 1
        closeVertices = []
        while i < 3 or vertices[ID].distance(vertices[closeIDs[ID, i]]) < thresholdDistance:
            closeVertices.append(vertices[closeIDs[ID, i]])
            i += 1

        vertices[ID].setCloseVertices(closeVertices)

    listOfVertexLists = []

    for vertex in vertices:
        if not vertex.getInLine():
            listOfVertexLists.append(_Line(vertex).getVertexListIDs())

    return listOfVertexLists
Example #39
0
    def _createCells(self):
        """
        cells = (front face, back face, left face, right face, bottom face, top face)
        front and back faces are YZ faces
        left and right faces are XZ faces
        top and bottom faces are XY faces
        """
        self.numberOfCells = self.nx * self.ny * self.nz
        
        ## front and back faces
        frontFaces = numerix.arange(self.numberOfYZFaces)
        frontFaces = vector.prune(frontFaces, self.nx + 1, self.nx)
        frontFaces = frontFaces + self.numberOfXYFaces + self.numberOfXZFaces
        backFaces = frontFaces + 1

        ## left and right faces
        leftFaces = numerix.arange(self.nx * self.ny)
        leftFaces = self._repeatWithOffset(leftFaces, self.nx * (self.ny + 1), self.nz)
        leftFaces = numerix.ravel(leftFaces)
        leftFaces = leftFaces + self.numberOfXYFaces
        rightFaces = leftFaces + self.nx

        ## bottom and top faces
        bottomFaces = numerix.arange(self.nx * self.ny * self.nz)
        topFaces = bottomFaces + (self.nx * self.ny)

        return numerix.array((frontFaces, backFaces, leftFaces, rightFaces, bottomFaces, topFaces))
Example #40
0
    def put(self, vector, id1, id2, overlapping=False):
        """Put elements of `vector` at positions of the matrix corresponding to (`id1`, `id2`)

        Parameters
        ----------
        vector : array_like
            The values to insert.
        id1 : array_like
            The row indices.
        id2 : array_like
            The column indices.
        overlapping : bool
            Whether to insert ghosted values or not (Ignored. Default False).

        Examples
        --------

            >>> L = _ScipyMatrixFromShape(rows=3, cols=3)
            >>> L.put([3., 10., numerix.pi, 2.5], [0, 0, 1, 2], [2, 1, 1, 0])
            >>> print(L)
                ---    10.000000   3.000000  
                ---     3.141593      ---    
             2.500000      ---        ---    
        """
        assert len(id1) == len(id2) == len(vector)

        # done in such a way to vectorize everything
        tempVec = numerix.array(vector) - self.matrix[id1, id2].flat
        tempMat = sp.csr_matrix((tempVec, (id1, id2)), self.matrix.shape)

        self.matrix = self.matrix + tempMat
        def _calcValue_(self, alpha, id1, id2):
            val = self._array.copy()

            inline._runIterateElementInline("""
                int ID1 = ITEM(id1, i, NULL);
                int ID2 = ITEM(id2, i, NULL);
                double cell1 = ITEM(var, ID1, vec);
                double cell2 = ITEM(var, ID2, vec);
                double cell1Xcell2 = cell1 * cell2;
                double tmp = ((cell2 - cell1) * ITEM(alpha, i, NULL) + cell1);
                if (tmp != 0 && cell1Xcell2 > 0.) {
                    ITEM(val, i, vec) = cell1Xcell2 / tmp;
                } else {
                    ITEM(val, i, vec) = 0.;
                }
            """,
                                            var=self.var.numericValue,
                                            val=val,
                                            alpha=alpha,
                                            id1=id1,
                                            id2=id2,
                                            shape=numerix.array(
                                                numerix.shape(val)),
                                            ni=self.mesh.numberOfFaces)

            return self._makeValue(value=val)
Example #42
0
    def _globalMatrixAndVectors(self):
        if not hasattr(self, 'globalVectors'):
            globalMatrix = self.matrix.asTrilinosMeshMatrix()

            mesh = self.var.mesh
            localNonOverlappingCellIDs = mesh._localNonOverlappingCellIDs

            ## The following conditional is required because empty indexing is not altogether functional.
            ## This numpy.empty((0,))[[]] and this numpy.empty((0,))[...,[]] both work, but this
            ## numpy.empty((3, 0))[...,[]] is broken.
            if self.var.shape[-1] != 0:
                s = (Ellipsis, localNonOverlappingCellIDs)
            else:
                s = (localNonOverlappingCellIDs,)

            nonOverlappingVector = Epetra.Vector(globalMatrix.domainMap,
                                                 self.var[s].ravel())
            from fipy.variables.coupledCellVariable import _CoupledCellVariable

            if isinstance(self.RHSvector, _CoupledCellVariable):
                RHSvector = self.RHSvector[localNonOverlappingCellIDs]
            else:
                RHSvector = numerix.reshape(numerix.array(self.RHSvector), self.var.shape)[s].ravel()


            nonOverlappingRHSvector = Epetra.Vector(globalMatrix.rangeMap,
                                                    RHSvector)

            del RHSvector

            overlappingVector = Epetra.Vector(globalMatrix.colMap, self.var)

            self.globalVectors = (globalMatrix, nonOverlappingVector, nonOverlappingRHSvector, overlappingVector)

        return self.globalVectors
Example #43
0
def _trilinosToNumpyVector(v):
    """
    Takes a distributed Trilinos vector and gives all processors a copy of it
    in a numpy vector.
    """

    if(v.Comm().NumProc() == 1):
        return numerix.array(v)
    else:
        PersonalMap = Epetra.Map(-1, range(0, v.GlobalLength()), 0, v.Comm())
        DistToPers = Epetra.Import(PersonalMap, v.Map())

        PersonalV = Epetra.Vector(PersonalMap)
        PersonalV.Import(v, DistToPers, Epetra.Insert) 

        return numerix.array(PersonalV)
Example #44
0
 def _numberOfFacesPerCell(self):
     cellFaceIDs = self.cellFaceIDs
     if isinstance(cellFaceIDs, type(MA.array(0))):
         ## bug in count returns float values when there is no mask
         return numerix.array(cellFaceIDs.count(axis=0), 'l')
     else:
         return self._maxFacesPerCell * numerix.ones(cellFaceIDs.shape[-1], 'l')
Example #45
0
 def __init__(self,
              dx=1.,
              dy=1.,
              dz=1.,
              nx=None,
              ny=None,
              nz=None,
              overlap=2,
              communicator=parallelComm,
              *args,
              **kwargs):
     super(_BasePeriodicGrid3D, self).__init__(dx=dx,
                                               dy=dy,
                                               dz=dz,
                                               nx=nx,
                                               ny=ny,
                                               nz=nz,
                                               overlap=overlap,
                                               communicator=communicator,
                                               *args,
                                               **kwargs)
     self._nonPeriodicCellVertexIDs = super(_BasePeriodicGrid3D,
                                            self)._cellVertexIDs
     self._orderedCellVertexIDs_data = super(_BasePeriodicGrid3D,
                                             self)._orderedCellVertexIDs
     self._nonPeriodicCellFaceIDs = numerix.array(
         super(_BasePeriodicGrid3D, self).cellFaceIDs)
     self._makePeriodic()
        def _calcValue_(self, alpha, id1, id2):
            distance = numerix.array(self.var)
            cell1 = numerix.take(distance, id1)
            cell2 = numerix.take(distance, id2)

            return numerix.where(numerix.logical_or(cell1 < 0, cell2 < 0), 0,
                                 self.diffusionCoeff)
Example #47
0
    def _globalMatrixAndVectors(self):
        if not hasattr(self, 'globalVectors'):
            globalMatrix = self.matrix.asTrilinosMeshMatrix()

            mesh = self.var.mesh
            localNonOverlappingCellIDs = mesh._localNonOverlappingCellIDs
            
            ## The following conditional is required because empty indexing is not altogether functional.
            ## This numpy.empty((0,))[[]] and this numpy.empty((0,))[...,[]] both work, but this
            ## numpy.empty((3, 0))[...,[]] is broken.
            if self.var.shape[-1] != 0:
                s = (Ellipsis, localNonOverlappingCellIDs)
            else:
                s = (localNonOverlappingCellIDs,)
                
            nonOverlappingVector = Epetra.Vector(globalMatrix.domainMap,
                                                 self.var[s].ravel())
            from fipy.variables.coupledCellVariable import _CoupledCellVariable

            if isinstance(self.RHSvector, _CoupledCellVariable):
                RHSvector = self.RHSvector[localNonOverlappingCellIDs]
            else:
                RHSvector = numerix.reshape(numerix.array(self.RHSvector), self.var.shape)[s].ravel()
                
                    
            nonOverlappingRHSvector = Epetra.Vector(globalMatrix.rangeMap,
                                                    RHSvector)

            del RHSvector

            overlappingVector = Epetra.Vector(globalMatrix.colMap, self.var)

            self.globalVectors = (globalMatrix, nonOverlappingVector, nonOverlappingRHSvector, overlappingVector)

        return self.globalVectors
def _putAdd(vector, ids, additionVector, mask=False):
    """This is a temporary replacement for Numeric.put as it was not doing
    what we thought it was doing.
    """
    additionVector = numerix.array(additionVector)

    if numerix.sometrue(mask):
        if len(vector.shape) < len(additionVector.shape):
            for j in range(vector.shape[0]):
                for id, value, masked in zip(ids.flat, additionVector[j].flat,
                                             mask.flat):
                    if not masked:
                        vector[j].flat[id] += value
        else:
            for id, value, masked in zip(ids.flat, additionVector.flat,
                                         mask.flat):
                if not masked:
                    vector.flat[id] += value

    else:
        if len(vector.shape) < len(additionVector.shape):
            for j in range(vector.shape[0]):
                for id, value in zip(ids.flat, additionVector[j].flat):
                    vector[j].flat[id] += value
        else:
            for id, value in zip(ids.flat, additionVector.flat):
                vector.flat[id] += value
Example #49
0
    def _getWeight(self,
                   var,
                   transientGeomCoeff=None,
                   diffusionGeomCoeff=None):
        """
        Test for a bug due to the sign operator not being updating
        correctly.

            >>> from fipy import *
            >>> m = Grid1D(nx=1)
            >>> v = CellVariable(mesh=m, value=1.)
            >>> eq = TransientTerm() == ImplicitSourceTerm(v)
            >>> eq.solve(v, dt=1.)
            >>> print v
            [ 2.]
            >>> v.setValue(-1.)
            >>> eq.solve(v, dt=1.)
            >>> print v
            [-0.5]

        """

        coeff = self._getGeomCoeff(var)
        diagonalSign = self._getDiagonalSign(transientGeomCoeff,
                                             diffusionGeomCoeff)
        combinedSign = numerix.array(diagonalSign)[
            ..., numerix.newaxis] * numerix.sign(coeff)

        return {
            'diagonal': (combinedSign >= 0),
            'old value': numerix.zeros(var.shape, 'd'),
            'b vector': -var * (combinedSign < 0),
            'new value': numerix.zeros(var.shape, 'd')
        }
Example #50
0
 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
Example #51
0
    def _getWeight(self, var, transientGeomCoeff=None, diffusionGeomCoeff=None):
        """
        Test for a bug due to the sign operator not being updating
        correctly.

            >>> from fipy import *
            >>> m = Grid1D(nx=1)
            >>> v = CellVariable(mesh=m, value=1.)
            >>> eq = TransientTerm() == ImplicitSourceTerm(v)
            >>> eq.solve(v, dt=1.)
            >>> print(v)
            [ 2.]
            >>> v.setValue(-1.)
            >>> eq.solve(v, dt=1.)
            >>> print(v)
            [-0.5]

        """

        coeff = self._getGeomCoeff(var)
        diagonalSign = self._getDiagonalSign(transientGeomCoeff, diffusionGeomCoeff)
        combinedSign = numerix.array(diagonalSign)[..., numerix.newaxis] * numerix.sign(coeff)

        return {'diagonal' : (combinedSign >= 0),
                'old value' : numerix.zeros(var.shape, 'd'),
                'b vector' :  -var * (combinedSign < 0),
                'new value' : numerix.zeros(var.shape, 'd')}
Example #52
0
    def _cellValueOverFaces(self):
        """

        Returns the cells values at the faces.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.cellVariable import CellVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> answer = CellVariable(mesh=mesh,
           ...                       value=((-.5, .5, .5, 1.5),
           ...                              (-.5, .5, .5, 1.5),
           ...                              (-.5, .5, .5, 1.5),
           ...                              (-.5, .5, .5, 1.5)))
           >>> print numerix.allclose(distanceVariable._cellValueOverFaces, answer)
           True

        """

        M = self.mesh._maxFacesPerCell
        N = self.mesh.numberOfCells
        return numerix.reshape(
            numerix.repeat(numerix.array(self._value)[numerix.newaxis, ...],
                           M,
                           axis=0), (M, N))
Example #53
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, transientGeomCoeff=None, diffusionGeomCoeff=None):

        var, L, b = FaceTerm._buildMatrix(self, var, SparseMatrix, boundaryConditions=boundaryConditions, dt=dt, transientGeomCoeff=transientGeomCoeff, diffusionGeomCoeff=diffusionGeomCoeff)

##        if var.rank != 1:

        mesh = var.mesh

        if (not hasattr(self, 'constraintL')) or (not hasattr(self, 'constraintB')):

            constraintMask = var.faceGrad.constraintMask | var.arithmeticFaceValue.constraintMask

            weight = self._getWeight(var, transientGeomCoeff, diffusionGeomCoeff)

            if 'implicit' in weight:
                alpha = weight['implicit']['cell 1 diag']
            else:
                alpha = 0.0

            exteriorCoeff =  self.coeff * mesh.exteriorFaces

            self.constraintL = (alpha * constraintMask * exteriorCoeff).divergence * mesh.cellVolumes
            self.constraintB =  -((1 - alpha) * var.arithmeticFaceValue * constraintMask * exteriorCoeff).divergence * mesh.cellVolumes

        ids = self._reshapeIDs(var, numerix.arange(mesh.numberOfCells))
        L.addAt(numerix.array(self.constraintL).ravel(), ids.ravel(), ids.swapaxes(0, 1).ravel())
        b += numerix.reshape(self.constraintB.value, ids.shape).sum(0).ravel()

        return (var, L, b)
Example #54
0
    def extrude(self, extrudeFunc=lambda x: x + numerix.array((0, 0, 1))[:,numerix.newaxis] , layers=1):
        """
        This function returns a new 3D mesh. The 2D mesh is extruded
        using the extrudeFunc and the number of layers.

        :Parameters:
          - `extrudeFunc`: function that takes the vertex coordinates and returns the displaced values
          - `layers`: the number of layers in the extruded mesh (number of times extrudeFunc will be called)

        >>> from fipy.meshes.nonUniformGrid2D import NonUniformGrid2D
        >>> print NonUniformGrid2D(nx=2,ny=2).extrude(layers=2).cellCenters
        [[ 0.5  1.5  0.5  1.5  0.5  1.5  0.5  1.5]
         [ 0.5  0.5  1.5  1.5  0.5  0.5  1.5  1.5]
         [ 0.5  0.5  0.5  0.5  1.5  1.5  1.5  1.5]]

        >>> from fipy.meshes.tri2D import Tri2D
        >>> print Tri2D().extrude(layers=2).cellCenters
        [[ 0.83333333  0.5         0.16666667  0.5         0.83333333  0.5
           0.16666667  0.5       ]
         [ 0.5         0.83333333  0.5         0.16666667  0.5         0.83333333
           0.5         0.16666667]
         [ 0.5         0.5         0.5         0.5         1.5         1.5         1.5
           1.5       ]]
        """

        return self._extrude(self, extrudeFunc, layers)
Example #55
0
    def _calcResidualVector(self, residualFn=None):
        if residualFn is not None:
            return residualFn(self.var, self.matrix, self.RHSvector)
        else:
            Lx = self.matrix * numerix.array(self.var)

            return Lx - self.RHSvector