Пример #1
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L.matrix.to_csr())

        if DEBUG:
            import sys
            print >> sys.stderr, L.matrix

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b),'d')
            LU.solve(errorVector, xError)
            x[:] = x - xError
            
        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT        
            PRINT('iterations: %d / %d' % (iteration+1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))
Пример #2
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L.matrix.to_csr())

        if DEBUG:
            import sys
            print(L.matrix, file=sys.stderr)

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b), 'd')
            LU.solve(errorVector, xError)
            x[:] = x - xError

        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT
            PRINT('iterations: %d / %d' % (iteration+1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))
Пример #3
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = splu(L.matrix.asformat("csc"), diag_pivot_thresh=1.,
                                            relax=1,
                                            panel_size=10,
                                            permc_spec=3)

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(min(self.iterations, 10)):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = LU.solve(errorVector)
            x[:] = x - xError

        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT
            PRINT('iterations: %d / %d' % (iteration+1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))

        return x
Пример #4
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())
Пример #5
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, equation=None, transientGeomCoeff=None, diffusionGeomCoeff=None):

        oldArray = var.old

        mesh = var.mesh
        NCells = mesh.numberOfCells
        NCellFaces = mesh._maxFacesPerCell

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)

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

        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), 'l'))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))

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

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

        return (var, SparseMatrix(mesh=var.mesh), -coeffXdiffereneces * mesh.cellVolumes)
Пример #6
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, equation=None, transientGeomCoeff=None, diffusionGeomCoeff=None):

        oldArray = var.old

        mesh = var.mesh
        NCells = mesh.numberOfCells
        NCellFaces = mesh._maxFacesPerCell

        cellValues = numerix.repeat(oldArray[numerix.newaxis, ...], NCellFaces, axis = 0)

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

        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), 'l'))**2, axis=0))
            maxsq = numerix.sqrt(numerix.sum(numerix.maximum(differences, numerix.zeros((NCellFaces, NCells), 'l'))**2, axis=0))

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

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

        return (var, SparseMatrix(mesh=var.mesh), -coeffXdifferences * mesh.cellVolumes)
Пример #7
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = splu(L.matrix.asformat("csc"),
                  diag_pivot_thresh=1.,
                  drop_tol=0.,
                  relax=1,
                  panel_size=10,
                  permc_spec=3)

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(min(self.iterations, 10)):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) /
                    error0) <= self.tolerance:
                break

            xError = LU.solve(errorVector)
            x[:] = x - xError

        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT
            PRINT('iterations: %d / %d' % (iteration + 1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))

        return x
Пример #8
0
 def _calcValue(self):
     flag = MA.filled(
         numerix.take(self.distanceVar._interfaceFlag,
                      self.mesh.cellFaceIDs), 0)
     flag = numerix.sum(flag, axis=0)
     return numerix.where(
         numerix.logical_and(self.distanceVar.value > 0, flag > 0), 1, 0)
Пример #9
0
    def _calcValuePy(self):
        ids = self.mesh._getCellFaceIDs()
        
        contributions = numerix.take(self.faceVariable, ids)

        # FIXME: numerix.MA.filled casts away dimensions
        return numerix.MA.filled(numerix.sum(contributions * self.mesh._getCellFaceOrientations(), 0)) / self.mesh.getCellVolumes()
Пример #10
0
 def cellCenters(self):
     """Defined outside of a geometry class since we need the `CellVariable`
     version of `cellCenters`; that is, the `cellCenters` defined in
     fipy.meshes.mesh and not in any geometry (since a `CellVariable` requires
     a reference to a mesh)."""
     return super(PeriodicGrid1D, self).cellCenters \
             % numerix.sum(self.globalNumberOfCells * self.args['dx'])
Пример #11
0
    def _ao(self):
        """Application Ordering to relate FiPy matrix rows to PETSc matrix rows
        
        FiPy naturally blocks matrix rows, one set of Equations (or Variables) at a time.
        PETSc requires that all rows pertaining to a particular MPI node be contiguous.
        This PETSc `AO` (Application Ordering) object converts between them.
        
        Only needed for FiPy to PETSc. We can efficiently slice from PETSc to
        FiPy, but PETSc requires us to know the row IDs. 
        """
        if not hasattr(self, "_ao_"):
            comm = self.mesh.communicator

            from mpi4py import MPI

            fipyIDs = self._globalNonOverlappingColIDs
            N = len(fipyIDs)

            count = numerix.zeros((comm.Nproc, ), dtype=int)
            count[comm.procID] = N
            comm.mpi4py_comm.Allreduce(sendbuf=MPI.IN_PLACE,
                                       recvbuf=count,
                                       op=MPI.MAX)

            petscIDs = numerix.arange(N) + numerix.sum(count[:comm.procID])

            self._ao_ = PETSc.AO().createBasic(petsc=petscIDs.astype('int32'),
                                               app=fipyIDs.astype('int32'),
                                               comm=comm.petsc4py_comm)
        return self._ao_
Пример #12
0
    def __init__(self, dx=1., nx=None, overlap=2, communicator=parallel):
        self.args = {
            'dx': dx, 
            'nx': nx, 
            'overlap': overlap
        }

        from fipy.tools.dimensions.physicalField import PhysicalField
        self.dx = PhysicalField(value=dx)
        scale = PhysicalField(value=1, unit=self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d=self.dx, n=nx)

        (self.nx,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, overlap, communicator)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset])
            self.dx = self.dx[self.offset:self.offset + self.nx]
        else:
            Xoffset = self.dx * self.offset
            
        vertices = self._createVertices() + ((Xoffset,),)
        self.numberOfVertices = len(vertices[0])
        faces = self._createFaces()
        self.numberOfFaces = len(faces[0])
        cells = self._createCells()
        Mesh1D.__init__(self, vertices, faces, cells, communicator=communicator)
        
        self.setScale(value = scale)
Пример #13
0
 def cellCenters(self):
     """Defined outside of a geometry class since we need the `CellVariable`
     version of `cellCenters`; that is, the `cellCenters` defined in
     fipy.meshes.mesh and not in any geometry (since a `CellVariable` requires
     a reference to a mesh)."""
     return super(PeriodicGrid1D, self).cellCenters \
             % numerix.sum(self.globalNumberOfCells * self.args['dx'])
Пример #14
0
    def calcDOffsets(ds, ns, offset):
        """
        :Parameters:
            - `ds`: A list, e.g. [dx, dy]
            - `ns`: A list, e.g. [nx, ny, nz]
            - `offset`

        :Returns:
            - `offsetList`: a list which contains the analogous scalars to
              `XOffset`, `YOffset`, and `ZOffset`, whichever are applicable for
              the dimensionality.
            - `newDs`: a list containing proper [dx, [dy, ...]] values
        """
        offsetList = []
        newDs = []

        if type(offset) in [int, float]:
            offset = [offset]

        for d, n, i in zip(ds, ns, list(range(len(ds)))):
            if numerix.getShape(d) is not ():
                offsetList.append(numerix.sum(d[0:offset[i]]))
                newDs.append(d[offset[i]:offset[i] + n])
            else:
                if len(offset) == 1:
                    offsetList.append(d * offset[0])
                else:
                    offsetList.append(d * offset[i])

                newDs.append(d)

        return offsetList, newDs
Пример #15
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
Пример #16
0
    def _calcValueNoInline(self):
        dAP = self.mesh._cellDistances
        id1, id2 = self.mesh._adjacentCellIDs

        N2 = numerix.take(self.var.value, id2, axis=-1)

        faceMask = numerix.array(self.mesh.exteriorFaces)

        ## 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.faceValue.shape[-1] != 0:
            s = (Ellipsis, faceMask)
        else:
            s = (faceMask, )

        N2[s] = self.var.faceValue[s]

        N = (N2 - numerix.take(self.var, id1, axis=-1)) / dAP

        normals = self.mesh._orientedFaceNormals

        tangents1 = self.mesh._faceTangents1
        tangents2 = self.mesh._faceTangents2
        cellGrad = self.var.grad.numericValue

        grad1 = numerix.take(cellGrad, id1, axis=-1)
        grad2 = numerix.take(cellGrad, id2, axis=-1)

        s = (slice(0, None,
                   None), ) + (numerix.newaxis, ) * (len(grad1.shape) - 2) + (
                       slice(0, None, None), )
        t1grad1 = numerix.sum(tangents1[s] * grad1, 0)
        t1grad2 = numerix.sum(tangents1[s] * grad2, 0)
        t2grad1 = numerix.sum(tangents2[s] * grad1, 0)
        t2grad2 = numerix.sum(tangents2[s] * grad2, 0)

        T1 = (t1grad1 + t1grad2) / 2.
        T2 = (t2grad1 + t2grad2) / 2.

        return normals[s] * N[numerix.newaxis] + tangents1[s] * T1[
            numerix.newaxis] + tangents2[s] * T2[numerix.newaxis]
Пример #17
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))
Пример #18
0
    def _calcValueNoInline(self):
        dAP = self.mesh._cellDistances
        id1, id2 = self.mesh._adjacentCellIDs

        N2 = numerix.take(self.var.value, id2, axis=-1)

        faceMask = numerix.array(self.mesh.exteriorFaces)

        ## 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.faceValue.shape[-1] != 0:
            s = (Ellipsis, faceMask)
        else:
            s = (faceMask,)

        N2[s] = self.var.faceValue[s]

        N = (N2 - numerix.take(self.var, id1, axis=-1)) / dAP

        normals = self.mesh._orientedFaceNormals

        tangents1 = self.mesh._faceTangents1
        tangents2 = self.mesh._faceTangents2
        cellGrad = self.var.grad.numericValue

        grad1 = numerix.take(cellGrad, id1, axis=-1)
        grad2 = numerix.take(cellGrad, id2, axis=-1)

        s = (slice(0, None, None),) + (numerix.newaxis,) * (len(grad1.shape) - 2) + (slice(0, None, None),)
        t1grad1 = numerix.sum(tangents1[s] * grad1, 0)
        t1grad2 = numerix.sum(tangents1[s] * grad2, 0)
        t2grad1 = numerix.sum(tangents2[s] * grad1, 0)
        t2grad2 = numerix.sum(tangents2[s] * grad2, 0)

        T1 = (t1grad1 + t1grad2) / 2.
        T2 = (t2grad1 + t2grad2) / 2.

        return normals[s] * N[numerix.newaxis] + tangents1[s] * T1[numerix.newaxis] + tangents2[s] * T2[numerix.newaxis]
Пример #19
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L._getMatrix().to_csr())

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b),'d')
            LU.solve(errorVector, xError)
            x[:] = x - xError
Пример #20
0
 def _calcValue(self):
     dAP = self.mesh._cellDistances
     id1, id2 = self.mesh._adjacentCellIDs
     N = (numerix.take(self.var,id2) - numerix.take(self.var,id1)) / dAP
     normals = self.mesh._orientedFaceNormals
     
     tangents1 = self.mesh._faceTangents1
     tangents2 = self.mesh._faceTangents2
     cellGrad = self.var.grad.numericValue
     
     grad1 = numerix.take(cellGrad, id1, axis=1)
     grad2 = numerix.take(cellGrad, id2, axis=1)
     t1grad1 = numerix.sum(tangents1*grad1,0)
     t1grad2 = numerix.sum(tangents1*grad2,0)
     t2grad1 = numerix.sum(tangents2*grad1,0)
     t2grad2 = numerix.sum(tangents2*grad2,0)
     
     T1 = (t1grad1 + t1grad2) / 2.
     T2 = (t2grad1 + t2grad2) / 2.
     
     return normals * N + tangents1 * T1 + tangents2 * T2
Пример #21
0
        def _calcValue(self):
            dAP = self.mesh._cellDistances
            id1, id2 = self.mesh._adjacentCellIDs
            N = (numerix.take(self.var, id2) -
                 numerix.take(self.var, id1)) / dAP
            normals = self.mesh._orientedFaceNormals

            tangents1 = self.mesh._faceTangents1
            tangents2 = self.mesh._faceTangents2
            cellGrad = self.var.grad.numericValue

            grad1 = numerix.take(cellGrad, id1, axis=1)
            grad2 = numerix.take(cellGrad, id2, axis=1)
            t1grad1 = numerix.sum(tangents1 * grad1, 0)
            t1grad2 = numerix.sum(tangents1 * grad2, 0)
            t2grad1 = numerix.sum(tangents2 * grad1, 0)
            t2grad2 = numerix.sum(tangents2 * grad2, 0)

            T1 = (t1grad1 + t1grad2) / 2.
            T2 = (t2grad1 + t2grad2) / 2.

            return normals * N + tangents1 * T1 + tangents2 * T2
Пример #22
0
    def _calcFaceCellToCellNormals(self):
        faceCellCentersUp = numerix.take(self._cellCenters, self.faceCellIDs[1], axis=1)
        faceCellCentersDown = numerix.take(self._cellCenters, self.faceCellIDs[0], axis=1)
        faceCellCentersUp = numerix.where(MA.getmaskarray(faceCellCentersUp),
                                          self._faceCenters,
                                          faceCellCentersUp)

        diff = faceCellCentersDown - faceCellCentersUp
        mag = numerix.sqrt(numerix.sum(diff**2))
        faceCellToCellNormals = diff / numerix.resize(mag, (self.dim, len(mag)))

        orientation = 1 - 2 * (numerix.dot(self.faceNormals, faceCellToCellNormals) < 0)
        return faceCellToCellNormals * orientation
Пример #23
0
Файл: mesh.py Проект: regmi/fipy
 def _calcFaceAreas(self):
     faceVertexIDs = MA.filled(self.faceVertexIDs, -1)
     substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], 
                                 faceVertexIDs.shape[0], axis=0)
     faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), substitute, faceVertexIDs)
     faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1)
     faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0)
     faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords))
     faceVertexCoords = faceVertexCoords - faceOrigins
     left = range(faceVertexIDs.shape[0])
     right = left[1:] + [left[0]]
     cross = numerix.sum(numerix.cross(faceVertexCoords, numerix.take(faceVertexCoords, right, 1), axis=0), 1)
     self.faceAreas = numerix.sqrtDot(cross, cross) / 2.
Пример #24
0
    def _calcValuePy(self):
        dAP = self.mesh._getCellDistances()
        id1, id2 = self.mesh._getAdjacentCellIDs()
##      N = self.mod(numerix.take(self.var,id2) - numerix.take(self.var,id1)) / dAP
        N = (numerix.take(self.var,id2) - numerix.take(self.var,id1)) / dAP
        normals = self.mesh._getOrientedFaceNormals()
        
        tangents1 = self.mesh._getFaceTangents1()
        tangents2 = self.mesh._getFaceTangents2()
        cellGrad = self.var.getGrad().getNumericValue()
        
        grad1 = numerix.take(cellGrad, id1, axis=1)
        grad2 = numerix.take(cellGrad, id2, axis=1)
        t1grad1 = numerix.sum(tangents1*grad1,0)
        t1grad2 = numerix.sum(tangents1*grad2,0)
        t2grad1 = numerix.sum(tangents2*grad1,0)
        t2grad2 = numerix.sum(tangents2*grad2,0)
        
        T1 = (t1grad1 + t1grad2) / 2.
        T2 = (t2grad1 + t2grad2) / 2.
        
        return normals * N + tangents1 * T1 + tangents2 * T2
Пример #25
0
    def _calcValue(self):
        cellToCellDistances = self.mesh._cellToCellDistances
        cellNormals = self.mesh._cellNormals
        neighborValue = self._neighborValue
        value = numerix.array(self.var)
        cellDistanceNormals = cellToCellDistances * cellNormals

        N = self.mesh.numberOfCells
        M = self.mesh._maxFacesPerCell
        D = self.mesh.dim

        mat = numerix.zeros((D, D, M, N), 'd')

        ## good god! numpy.outer should have an axis argument!!!
        for i in range(D):
            for j in range(D):
                mat[i, j] = cellDistanceNormals[i] * cellDistanceNormals[j]

        mat = numerix.sum(mat, axis=2)

        vec = numerix.array(
            numerix.sum((neighborValue - value) * cellDistanceNormals, axis=1))

        if D == 1:
            vec[0] = vec[0] / mat[0, 0]
        elif D == 2:
            divisor = mat[0, 0] * mat[1, 1] - mat[0, 1] * mat[1, 0]
            gradx = (vec[0] * mat[1, 1] - vec[1] * mat[1, 0]) / divisor
            grady = (vec[1] * mat[0, 0] - vec[0] * mat[0, 1]) / divisor
            vec[0] = gradx
            vec[1] = grady
        else:
            ## very stuppy! numerix.linalg.solve should have an axis argument!!!
            for i in range(N):
                vec[..., i] = numerix.linalg.solve(mat[..., i], vec[..., i])

        return vec
    def _calcValue(self):
        cellToCellDistances = self.mesh._getCellToCellDistances()
        cellNormals = self.mesh._getCellNormals()
        neighborValue = self._getNeighborValue()
        value = numerix.array(self.var)
        cellDistanceNormals = cellToCellDistances * cellNormals

        N = self.mesh.getNumberOfCells()
        M = self.mesh._getMaxFacesPerCell()
        D = self.mesh.getDim()

        mat = numerix.zeros((D, D, M, N), 'd')

        ## good god! numpy.outer should have an axis argument!!!
        for i in range(D):
            for j in range(D):
                mat[i,j] = cellDistanceNormals[i] * cellDistanceNormals[j]

        mat = numerix.sum(mat, axis=2)

        vec = numerix.array(numerix.sum((neighborValue - value) * cellDistanceNormals, axis=1))

        if D == 1:
            vec[0] = vec[0] / mat[0, 0]
        elif D == 2:
            divisor = mat[0,0] * mat[1,1] - mat[0,1] * mat[1,0]
            gradx = (vec[0] * mat[1,1] - vec[1] * mat[1,0]) / divisor
            grady = (vec[1] * mat[0,0] - vec[0] * mat[0,1]) / divisor
            vec[0] = gradx
            vec[1] = grady
        else:
            ## very stuppy! numerix.linalg.solve should have an axis argument!!!        
            for i in range(N):
                vec[...,i] = numerix.linalg.solve(mat[...,i],vec[...,i])

        return vec
Пример #27
0
 def _calcFaceAreas(self):
     faceVertexIDs = MA.filled(self.faceVertexIDs, -1)
     substitute = numerix.repeat(faceVertexIDs[numerix.newaxis, 0], 
                                 faceVertexIDs.shape[0], axis=0)
     faceVertexIDs = numerix.where(MA.getmaskarray(self.faceVertexIDs), 
                                   substitute, faceVertexIDs)
     faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1)
     faceOrigins = numerix.repeat(faceVertexCoords[:,0], faceVertexIDs.shape[0], axis=0)
     faceOrigins = numerix.reshape(faceOrigins, MA.shape(faceVertexCoords))
     faceVertexCoords = faceVertexCoords - faceOrigins
     left = range(faceVertexIDs.shape[0])
     right = left[1:] + [left[0]]
     cross = numerix.sum(numerix.cross(faceVertexCoords, 
                                       numerix.take(faceVertexCoords, right, 1), 
                                       axis=0), 
                         1)
     return numerix.sqrtDot(cross, cross) / 2.
Пример #28
0
    def _dot(a, b, index):
        """
        Workhorse method to calculate the scalar product
        
        .. math::
        
           \mathsf{a} \cdot \mathsf{b}

        for all but the last index of `a` and `b`. Both `a` and `b` can be of
        arbitrary rank, but at this point, both must be appropriately broadcast
        `array` objects.
        """
        rankA = len(a.shape) - 1
        rankB = len(b.shape) - 1
        if rankA <= 0 or rankB <= 0:
            # if either a or b is scalar, then just do multiplication
            return a[index] * b
        else:
            return numerix.sum(a[index] * b, axis=rankA - 1)
Пример #29
0
    def _dot(a, b, index):
        """
        Workhorse method to calculate the scalar product
        
        .. math::
        
           \mathsf{a} \cdot \mathsf{b}

        for all but the last index of `a` and `b`. Both `a` and `b` can be of
        arbitrary rank, but at this point, both must be appropriately broadcast
        `array` objects.
        """
        rankA = len(a.shape) - 1
        rankB = len(b.shape) - 1
        if rankA <= 0 or rankB <= 0:
            # if either a or b is scalar, then just do multiplication
            return a[index] * b
        else:
            return numerix.sum(a[index] * b, axis=rankA - 1)
Пример #30
0
    def _getCellInterfaceFlag(self):
        """

        Returns 1 for those cells on the interface:

        >>> from fipy.meshes.grid2D 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=(0, 1, 1, 0))
        >>> print numerix.allclose(distanceVariable._getCellInterfaceFlag(), answer)
        True

        """
        flag = MA.filled(numerix.take(self._getInterfaceFlag(), self.cellFaceIDs), 0)

        flag = numerix.sum(flag, axis=0)
        
        return numerix.where(numerix.logical_and(self.value > 0, flag > 0), 1, 0)
Пример #31
0
    def _getCoefficientMatrix(self, SparseMatrix, mesh, coeff):
        interiorCoeff = numerix.array(coeff)
        
        interiorCoeff[mesh.getExteriorFaces().getValue()] = 0
        
        interiorCoeff = numerix.take(interiorCoeff, mesh._getCellFaceIDs())

        coefficientMatrix = SparseMatrix(mesh=mesh, bandwidth = mesh._getMaxFacesPerCell() + 1)
        coefficientMatrix.addAtDiagonal(numerix.sum(interiorCoeff, 0))
        del interiorCoeff

        interiorFaces = mesh.getInteriorFaceIDs()
        interiorFaceCellIDs = mesh.getInteriorFaceCellIDs()

        interiorCoeff = -numerix.take(coeff, interiorFaces, axis=-1)
        coefficientMatrix.addAt(interiorCoeff, interiorFaceCellIDs[0], interiorFaceCellIDs[1])
        interiorCoeff = -numerix.take(coeff, interiorFaces, axis=-1)
        coefficientMatrix.addAt(interiorCoeff, interiorFaceCellIDs[1], interiorFaceCellIDs[0])
        
        return coefficientMatrix
Пример #32
0
    def _cellVertexIDs(self):
        ## Get all the vertices from all the faces for each cell
        cellFaceVertices = numerix.take(self.faceVertexIDs, self.cellFaceIDs, axis=1)

        ## get a sorted list of vertices for each cell 
        cellVertexIDs = numerix.reshape(cellFaceVertices, (-1, self.numberOfCells))
        cellVertexIDs = MA.sort(cellVertexIDs, axis=0, fill_value=-1)

        cellVertexIDs = MA.sort(MA.concatenate((cellVertexIDs[-1, numerix.newaxis], 
                                                MA.masked_where(cellVertexIDs[:-1] 
                                                                == cellVertexIDs[1:], 
                                                                cellVertexIDs[:-1]))), 
                                axis=0, fill_value=-1)
        
        ## resize the array to remove extra masked values
        if cellVertexIDs.shape[-1] == 0:
            length = 0
        else:
            length = min(numerix.sum(MA.getmaskarray(cellVertexIDs), axis=0))
        return cellVertexIDs[length:][::-1]
Пример #33
0
    def calcDOffsets(ds, ns, offset):
        """
        Parameters
        ----------
        ds : list
            Spacing in each grid direction, e.g. `[dx, dy]`
        ns : list
            Number of grid spacings in each direction, e.g. `[nx, ny]`
        offset : list
            Displacement of grid spacings, e.g., `[Ox, Oy]`

        Returns
        -------
        offsetList : list
            Contains the analogous scalars to `XOffset`, `YOffset`, and
            `ZOffset`, whichever are applicable for the dimensionality.
        newDs : list
            proper `[dx, [dy, ...]]` values
        """
        offsetList = []
        newDs = []

        if type(offset) in [int, float]:
            offset = [offset]

        for d, n, i in zip(ds, ns, list(range(len(ds)))):
            if numerix.getShape(d) is not ():
                offsetList.append(numerix.sum(d[0:offset[i]]))
                newDs.append(d[offset[i]:offset[i] + n])
            else:
                if len(offset) == 1:
                    offsetList.append(d * offset[0])
                else:
                    offsetList.append(d * offset[i])

                newDs.append(d)

        return offsetList, newDs
Пример #34
0
    surfactantViewer.plot()
    velocityViewer.plot()

    totalTime = 0

    for step in range(steps):
        print('step', step)
        velocity.setValue(surfactantVariable.interfaceVar * k)
        distanceVariable.extendVariable(velocity)
        timeStepDuration = cfl * dx / velocity.max()
        distanceVariable.updateOld()
        advectionEquation.solve(distanceVariable, dt=timeStepDuration)
        surfactantEquation.solve(surfactantVariable, dt=1)

        totalTime += timeStepDuration

        velocityViewer.plot()
        distanceViewer.plot()
        surfactantViewer.plot()

        finalRadius = numerix.sqrt(2 * k * initialRadius *
                                   initialSurfactantValue * totalTime +
                                   initialRadius**2)
        answer = initialSurfactantValue * initialRadius / finalRadius
        coverage = surfactantVariable.interfaceVar
        error = (coverage / answer - 1)**2 * (coverage > 1e-3)
        print('error',
              numerix.sqrt(numerix.sum(error) / numerix.sum(error > 0)))

    input('finished')
Пример #35
0
 def _calcValueNoInline(self, N, M, ids, orientations, volumes):
     contributions = numerix.take(self.faceGradientContributions, ids, axis=-1)
     grad = numerix.array(numerix.sum(orientations * contributions, -2))
     return grad / volumes
Пример #36
0
 def sum(self, axis=None):
     return self._axisOperator(opname="sumVar", 
                               op=lambda a: numerix.sum(a, axis=axis), 
                               axis=axis)
Пример #37
0
        print('----------------------------------------------------------')
        print(i)
        print('Phi = ' + str(phi[iphi] * conv_fac) + ' to ' +
              str(phi[iphi + 1] * conv_fac))
        print('Theta = ' + str(theta[ith] * conv_fac) + ' to ' +
              str(theta[ith + 1] * conv_fac))

        phi_min = phi[iphi]
        phi_max = phi[iphi + 1]

        theta_min = theta[ith]
        theta_max = theta[ith + 1]

        #prob=prob_val.remote(phi_min,phi_max,theta_min,theta_max,rho)
        #prob_id.append(prob)
        #probability=numerix.append(probability,ray.get(prob))
        probability[ith] = prob_val.remote(phi_min, phi_max, theta_min,
                                           theta_max, rho)  # ray.get(prob)
        #probability.append(prob_val.remote(phi_min,phi_max,theta_min,theta_max,rho))
        #i=i+1
    prob_mid = ray.get(probability)
    prob_phi[iphi] = numerix.sum(prob_mid)
#file.write('\n-----------------------------------------------------------------')
probability_all = numerix.sum(prob_phi)
#prob_all=ray.get(prob_id)

print('Probability = ' + str(probability_all))

#file.write('Total Probability = ' + str(total_probability))
#file.close()
Пример #38
0
                          where=((x0 < x) & (x < x1)) & ((x0 < y) & (y < x1)))

surfactantVariable = SurfactantVariable(distanceVar=distanceVariable, value=1.)

from fipy.variables.surfactantConvectionVariable import SurfactantConvectionVariable
surfactantEquation = TransientTerm() - \
    ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVariable))

advectionEquation = TransientTerm() + AdvectionTerm(velocity)

if __name__ == '__main__':
    distanceViewer = Viewer(vars=distanceVariable, datamin=-.001, datamax=.001)
    surfactantViewer = Viewer(vars=surfactantVariable, datamin=0., datamax=2.)

    distanceVariable.calcDistanceFunction()

    for step in range(steps):
        print numerix.sum(surfactantVariable)
        distanceVariable.updateOld()
        surfactantEquation.solve(surfactantVariable, dt=1)
        advectionEquation.solve(distanceVariable, dt=timeStepDuration)
        distanceViewer.plot()
        surfactantViewer.plot()

    surfactantEquation.solve(surfactantVariable, dt=1)

    distanceViewer.plot()
    surfactantViewer.plot()
    print surfactantVariable
    raw_input('finished')
Пример #39
0
    def _calcDistanceFunction(self, extensionVariable = None, narrowBandWidth = None, deleteIslands = False):

        if narrowBandWidth == None:
            narrowBandWidth = self.narrowBandWidth

        ## calculate interface values

        cellToCellIDs = self.mesh._getCellToCellIDs()

        if deleteIslands:
            adjVals = numerix.take(self.value, cellToCellIDs)
            adjInterfaceValues = MA.masked_array(adjVals, mask = (adjVals * self.value) > 0)
            masksum = numerix.sum(numerix.logical_not(MA.getmask(adjInterfaceValues)), 0)
            tmp = MA.logical_and(masksum == 4, self.value > 0)
            self.value = MA.where(tmp, -1, self.value)

        adjVals = numerix.take(self.value, cellToCellIDs)
        adjInterfaceValues = MA.masked_array(adjVals, mask = (adjVals * self.value) > 0)
        dAP = self.mesh._getCellToCellDistances()
        distances = abs(self.value * dAP / (self.value - adjInterfaceValues))
        indices = MA.argsort(distances, 0)
        sign = (self.value > 0) * 2 - 1

        s = distances[indices[0], numerix.arange(indices.shape[1])]

        if self.mesh.getDim() == 2:

            t = distances[indices[1], numerix.arange(indices.shape[1])]
            u = distances[indices[2], numerix.arange(indices.shape[1])]

            if indices.shape[1] > 0:
                ns = self.cellNormals[..., indices[0], numerix.arange(indices.shape[1])]
                nt = self.cellNormals[..., indices[1], numerix.arange(indices.shape[1])]
            else:
                ns = MA.zeros(self.cellNormals.shape[:-1] + (0,))
                nt = MA.zeros(self.cellNormals.shape[:-1] + (0,))

            signedDistance = MA.where(MA.getmask(s),
                                      self.value,
                                      MA.where(MA.getmask(t),
                                               sign * s,
                                               MA.where(abs(numerix.dot(ns,nt)) < 0.9,
                                                        sign * s * t / MA.sqrt(s**2 + t**2),
                                                        MA.where(MA.getmask(u),
                                                                 sign * s,
                                                                 sign * s * u / MA.sqrt(s**2 + u**2)
                                                                 )
                                                        )
                                               )
                                      )
        else:
            signedDistance = MA.where(MA.getmask(s),
                                      self.value,
                                      sign * s)
            

        self.value = signedDistance

        ## calculate interface flag
        masksum = numerix.sum(numerix.logical_not(MA.getmask(distances)), 0)
        interfaceFlag = (masksum > 0).astype('l')

        ## spread the extensionVariable to the whole interface
        flag = True
        if extensionVariable is None:
            extensionVariable = numerix.zeros(self.mesh.getNumberOfCells(), 'd')
            flag = False
            
        ext = numerix.zeros(self.mesh.getNumberOfCells(), 'd')

        positiveInterfaceFlag = numerix.where(self.value > 0, interfaceFlag, 0)
        negativeInterfaceIDs = numerix.nonzero(numerix.where(self.value < 0, interfaceFlag, 0))[0]

        for id in negativeInterfaceIDs:
            tmp, extensionVariable[...,id] = self._calcTrialValue(id, positiveInterfaceFlag, extensionVariable)

        if flag:
            self.value = self.tmpValue.copy()

        ## evaluate the trialIDs
        adjInterfaceFlag = numerix.take(interfaceFlag, cellToCellIDs)
        hasAdjInterface = (numerix.sum(MA.filled(adjInterfaceFlag, 0), 0) > 0).astype('l')

        trialFlag = numerix.logical_and(numerix.logical_not(interfaceFlag), hasAdjInterface).astype('l')

        trialIDs = list(numerix.nonzero(trialFlag)[0])
        evaluatedFlag = interfaceFlag


        for id in trialIDs:
            self.value[...,id], extensionVariable[id] = self._calcTrialValue(id, evaluatedFlag, extensionVariable)

        while len(trialIDs):

            id = trialIDs[numerix.argmin(abs(numerix.take(self.value, trialIDs)))]

            if abs(self.value[...,id]) > narrowBandWidth / 2:
                break

            trialIDs.remove(id)
            evaluatedFlag[...,id] = 1


            for adjID in MA.filled(cellToCellIDs[...,id], -1):
                if adjID != -1:
                    if not evaluatedFlag[...,adjID]:
                        self.value[...,adjID], extensionVariable[...,adjID] = self._calcTrialValue(adjID, evaluatedFlag, extensionVariable)
                        if adjID not in trialIDs:
                            trialIDs.append(adjID)

        self.value = numerix.array(self.value)
 def _calcValue(self):
     normals = numerix.array(
         MA.filled(self.distanceVar._cellInterfaceNormals, 0))
     areas = numerix.array(MA.filled(self.mesh._cellAreaProjections, 0))
     return numerix.sum(abs(numerix.dot(normals, areas)), axis=0)
Пример #41
0
    def __init__(self, dx=1., dy=1., nx=None, ny=None, overlap=2, parallelModule=parallel):
        
        self.args = {
            'dx': dx, 
            'dy': dy, 
            'nx': nx, 
            'ny': ny, 
            'overlap': overlap,
            'parallelModule': parallelModule
        }

        self.dx = PhysicalField(value = dx)
        scale = PhysicalField(value=1, unit=self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d=self.dx, n=nx, axis="x")
        
        self.dy = PhysicalField(value = dy)
        if self.dy.getUnit().isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale
            
        ny = self._calcNumPts(d=self.dy, n=ny, axis="y")
        
        (self.nx,
         self.ny,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, ny, overlap, parallelModule)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset[0]])
            self.dx = self.dx[self.offset[0]:self.offset[0] + self.nx]
        else:
            Xoffset = 0

        if numerix.getShape(self.dy) is not ():
            Yoffset =  numerix.sum(self.dy[0:self.offset[1]])
            self.dy = self.dy[self.offset[1]:self.offset[1] + self.ny]
        else:
            Yoffset = 0
            
        if self.nx == 0:
            self.ny = 0
        if self.ny == 0:
            self.nx = 0
        if self.nx == 0 or self.ny == 0:
            self.numberOfHorizontalRows = 0
            self.numberOfVerticalColumns = 0
        else:
            self.numberOfHorizontalRows = (self.ny + 1)
            self.numberOfVerticalColumns = (self.nx + 1)

        self.numberOfVertices = self.numberOfHorizontalRows * self.numberOfVerticalColumns

        vertices = self._createVertices() + ((Xoffset,), (Yoffset,))
        faces = self._createFaces()
        self.numberOfFaces = len(faces[0])
        cells = self._createCells()
        Mesh2D.__init__(self, vertices, faces, cells)
        
        self.setScale(value = scale)
Пример #42
0
    def _calcTrialValue(self, id, evaluatedFlag, extensionVariable):
        adjIDs = self.cellToCellIDs[...,id]
        adjEvaluatedFlag = numerix.take(evaluatedFlag, adjIDs)
        adjValues = numerix.take(self.value, adjIDs)
        adjValues = numerix.where(adjEvaluatedFlag, adjValues, 1e+10)
        try:
            indices = numerix.argsort(abs(adjValues))
        except TypeError:
            # numpy 1.1 raises a TypeError when using argsort function
            indices = abs(adjValues).argsort()
        sign = (self.value[id] > 0) * 2 - 1
        d0 = self.cellToCellDistances[indices[0], id]
        v0 = self.value[..., adjIDs[indices[0]]]
        e0 = extensionVariable[..., adjIDs[indices[0]]]

        N = numerix.sum(adjEvaluatedFlag)

        index0 = indices[0]
        index1 = indices[1]
        index2 = indices[self.mesh.getDim()]
        
        if N > 1:
            n0 = self.cellNormals[..., index0, id]
            n1 = self.cellNormals[..., index1, id]

            if self.mesh.getDim() == 2:
                cross = (n0[0] * n1[1] - n0[1] * n1[0])
            else:
                cross = 0.0
                
            if abs(cross) < 0.1:
                if N == 2:
                    N = 1
                elif N == 3:
                    index1 = index2

        if N == 0:
            raise Exception 
        elif N == 1:
            return v0 + sign * d0, e0
        else:
            d1 = self.cellToCellDistances[index1, id]
            n0 = self.cellNormals[..., index0, id]
            n1 = self.cellNormals[..., index1, id]
            v1 = self.value[..., adjIDs[index1]]
            
            crossProd = d0 * d1 * (n0[0] * n1[1] - n0[1] * n1[0])
            dotProd = d0 * d1 * numerix.dot(n0, n1)
            dsq = d0**2 + d1**2 - 2 * dotProd
            
            top = -v0 * (dotProd - d1**2) - v1 * (dotProd - d0**2)
            sqrt = crossProd**2 *(dsq - (v0 - v1)**2)
            sqrt = numerix.sqrt(max(sqrt, 0))



            dis = (top + sign * sqrt) / dsq

            ## extension variable

            e1 = extensionVariable[..., adjIDs[index1]]
            a0 = self.cellAreas[index0, id]
            a1 = self.cellAreas[index1, id]

            if self.value[id] > 0:
                phi = max(dis, 0)
            else:
                phi = min(dis, 0)

            n0grad = a0 * abs(v0 - phi) / d0
            n1grad = a1 * abs(v1 - phi) / d1
            
            return dis, (e0 * n0grad + e1 * n1grad) / (n0grad + n1grad)
Пример #43
0
surfactantEquation = TransientTerm() - \
    ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVariable))

if __name__ == '__main__':

    distanceViewer = Viewer(vars=distanceVariable,
                            datamin=-initialRadius,
                            datamax=initialRadius)
    surfactantViewer = Viewer(vars=surfactantVariable,
                              datamin=-1.,
                              datamax=100.)
    distanceViewer.plot()
    surfactantViewer.plot()

    print('total surfactant before:',
          numerix.sum(surfactantVariable * mesh.cellVolumes))

    for step in range(steps):
        distanceVariable.updateOld()
        surfactantEquation.solve(surfactantVariable, dt=1.)
        advectionEquation.solve(distanceVariable, dt=timeStepDuration)
        distanceViewer.plot()
        surfactantViewer.plot()
    surfactantEquation.solve(surfactantVariable, dt=1.)

    print('total surfactant after:',
          numerix.sum(surfactantVariable * mesh.cellVolumes))

    areas = (distanceVariable.cellInterfaceAreas <
             1e-6) * 1e+10 + distanceVariable.cellInterfaceAreas
    answer = initialSurfactantValue * initialRadius / (initialRadius +
Пример #44
0
surfactantEquation = SurfactantEquation(
    distanceVar = distanceVariable)


advectionEquation = buildHigherOrderAdvectionEquation(
    advectionCoeff = velocity)

if __name__ == '__main__':
    import fipy.viewers
    distanceViewer = fipy.viewers.make(vars = distanceVariable, limits = {'datamin': -.001, 'datamax': .001})
    surfactantViewer = fipy.viewers.make(vars = surfactantVariable, limits = {'datamin': 0., 'datamax': 2.})


    distanceVariable.calcDistanceFunction()

    for step in range(steps):
        print numerix.sum(surfactantVariable)
        surfactantVariable.updateOld()
        distanceVariable.updateOld()
        surfactantEquation.solve(surfactantVariable)
        advectionEquation.solve(distanceVariable, dt = timeStepDuration)
        distanceViewer.plot()
        surfactantViewer.plot()

    surfactantEquation.solve(surfactantVariable)

    distanceViewer.plot()
    surfactantViewer.plot()
    print surfactantVariable
    raw_input('finished')
Пример #45
0
    def __init__(self, dx = 1., dy = 1., dz = 1., nx = None, ny = None, nz = None, overlap=2, communicator=parallel):
        
        self.args = {
            'dx': dx, 
            'dy': dy,
            'dz' :dz,
            'nx': nx, 
            'ny': ny,
            'nz': nz,
            'overlap': overlap,
            'communicator': communicator
        }
        
        self.dx = PhysicalField(value = dx)
        scale = PhysicalField(value = 1, unit = self.dx.getUnit())
        self.dx /= scale
        
        nx = self._calcNumPts(d = self.dx, n = nx, axis = "x")
        
        self.dy = PhysicalField(value = dy)
        if self.dy.getUnit().isDimensionless():
            self.dy = dy
        else:
            self.dy /= scale

        ny = self._calcNumPts(d = self.dy, n = ny, axis = "y")
        
        self.dz = PhysicalField(value = dz)
        if self.dz.getUnit().isDimensionless():
            self.dz = dz
        else:
            self.dz /= scale
        
        nz = self._calcNumPts(d = self.dz, n = nz, axis = "z")

        (self.nx,
         self.ny,
         self.nz,
         self.overlap,
         self.offset) = self._calcParallelGridInfo(nx, ny, nz, overlap, communicator)

        if numerix.getShape(self.dx) is not ():
            Xoffset = numerix.sum(self.dx[0:self.offset[0]])
            self.dx = self.dx[self.offset[0]:self.offset[0] + self.nx]
        else:
            Xoffset = 0

        if numerix.getShape(self.dy) is not ():
            Yoffset =  numerix.sum(self.dy[0:self.offset[1]])
            self.dy = self.dy[self.offset[1]:self.offset[1] + self.ny]
        else:
            Yoffset = 0

        if numerix.getShape(self.dy) is not ():
            Zoffset =  numerix.sum(self.dz[0:self.offset[2]])
            self.dz = self.dz[self.offset[2]:self.offset[2] + self.nz]
        else:
            Zoffset = 0

        if self.nx == 0 or self.ny == 0 or self.nz == 0:
            self.nx = 0
            self.ny = 0
            self.nz = 0

        if self.nx == 0 or self.ny == 0 or self.nz == 0:
            self.numberOfHorizontalRows = 0
            self.numberOfVerticalColumns = 0
            self.numberOfLayersDeep = 0
        else:
            self.numberOfHorizontalRows = (self.ny + 1)
            self.numberOfVerticalColumns = (self.nx + 1)
            self.numberOfLayersDeep = (self.nz + 1)
            
        self.numberOfVertices = self.numberOfHorizontalRows * self.numberOfVerticalColumns * self.numberOfLayersDeep
        
        vertices = self._createVertices() + ((Xoffset,), (Yoffset,), (Zoffset,))
        faces = self._createFaces()
        cells = self._createCells()
        Mesh.__init__(self, vertices, faces, cells)
        
        self.setScale(value = scale)
Пример #46
0
 def _calcValueNoInline(self, N, M, ids, orientations, volumes):
     contributions = numerix.take(self.faceGradientContributions,
                                  ids,
                                  axis=-1)
     grad = numerix.array(numerix.sum(orientations * contributions, -2))
     return grad / volumes
Пример #47
0
        errorViewer.plot()

        finalRadius = initialRadius + totalTime * velocity + distanceVariable
        answer = initialSurfactantValue * initialRadius / finalRadius
        coverage = surfactantVariable.getInterfaceVar()

        error.setValue(numerix.where((coverage > 1e-3) & (distanceVariable > 0), abs(coverage - answer), 0))

        adjDistanceVariables = numerix.take(distanceVariable,  mesh._getCellToCellIDs())
        adjCoverages = numerix.take(coverage,  mesh._getCellToCellIDs())
        flag = (adjDistanceVariables < 0) & (adjCoverages > 1e-6)




        error.setValue(0, where=numerix.sum(flag, index=1) > 0)

        
        del L1[0]
        del L2[0]
        del Linf[0]

        L1.append(numerix.array(numerix.sum(error)/nx))
        L2.append(numerix.array(numerix.sqrt(numerix.sum(error**2)/nx)))
        Linf.append(numerix.array(max(error)))

##        argmax = numerix.argmax(error)

##        del errorList[0]

##        errorList.append(max(error))
Пример #48
0
 def _calcValue(self):
     normals = numerix.array(MA.filled(self.distanceVar._cellInterfaceNormals, 0))
     areas = numerix.array(MA.filled(self.mesh._cellAreaProjections, 0))
     return numerix.sum(abs(numerix.dot(normals, areas)), axis=0)
Пример #49
0
    surfactantViewer.plot()
    velocityViewer.plot()

    totalTime = 0

    for step in range(steps):
        print 'step',step
        velocity.setValue(surfactantVariable.interfaceVar * k)
        distanceVariable.extendVariable(velocity)
        timeStepDuration = cfl * dx / velocity.max()
        distanceVariable.updateOld()
        advectionEquation.solve(distanceVariable, dt = timeStepDuration)
        surfactantEquation.solve(surfactantVariable, dt=1)

        totalTime += timeStepDuration

        velocityViewer.plot()
        distanceViewer.plot()
        surfactantViewer.plot()

        finalRadius = numerix.sqrt(2 * k * initialRadius * initialSurfactantValue * totalTime + initialRadius**2)
        answer = initialSurfactantValue * initialRadius / finalRadius
        coverage = surfactantVariable.interfaceVar
        error = (coverage / answer - 1)**2 * (coverage > 1e-3)
        print 'error', numerix.sqrt(numerix.sum(error) / numerix.sum(error > 0))




    raw_input('finished')
Пример #50
0
advectionEquation = TransientTerm() + AdvectionTerm(velocity)

from fipy.variables.surfactantConvectionVariable import SurfactantConvectionVariable
surfactantEquation = TransientTerm() - \
    ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVariable))

if __name__ == '__main__':

    distanceViewer = Viewer(vars=distanceVariable,
                            datamin=-initialRadius, datamax=initialRadius)
    surfactantViewer = Viewer(vars=surfactantVariable, datamin=-1., datamax=100.)
    distanceViewer.plot()
    surfactantViewer.plot()

    print 'total surfactant before:', numerix.sum(surfactantVariable * mesh.cellVolumes)

    for step in range(steps):
        distanceVariable.updateOld()
        surfactantEquation.solve(surfactantVariable, dt=1.)
        advectionEquation.solve(distanceVariable, dt = timeStepDuration)
        distanceViewer.plot()
        surfactantViewer.plot()
    surfactantEquation.solve(surfactantVariable, dt=1.)


    print 'total surfactant after:', numerix.sum(surfactantVariable * mesh.cellVolumes)

    areas = (distanceVariable.cellInterfaceAreas < 1e-6) * 1e+10 + distanceVariable.cellInterfaceAreas
    answer = initialSurfactantValue * initialRadius / (initialRadius +  distanceToTravel)
    coverage = surfactantVariable * mesh.cellVolumes / areas