def _getOldAdjacentValues(self, oldArray, id1, id2, dt):
        oldArray1, oldArray2 = ExplicitUpwindConvectionTerm._getOldAdjacentValues(self, oldArray, id1, id2, dt)
        
        mesh = oldArray.mesh

        interiorIDs = numerix.nonzero(mesh.interiorFaces)[0]
        interiorFaceAreas = numerix.take(mesh._faceAreas, interiorIDs)
        interiorFaceNormals = numerix.take(mesh._orientedFaceNormals, interiorIDs, axis=-1)
        
        # Courant-Friedrichs-Levy number
        interiorCFL = abs(numerix.take(self._getGeomCoeff(oldArray), interiorIDs)) * dt
        
        gradUpwind = (oldArray2 - oldArray1) / numerix.take(mesh._cellDistances, interiorIDs)
        
        vol1 = numerix.take(mesh.cellVolumes, id1)
        
        oldArray1 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.grad, id1, axis=-1), interiorFaceNormals), gradUpwind) \
            * (vol1 - interiorCFL) / interiorFaceAreas

        vol2 = numerix.take(mesh.cellVolumes, id2)
        
        oldArray2 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.grad, id2, axis=-1), -interiorFaceNormals), -gradUpwind) \
            * (vol2 - interiorCFL) / interiorFaceAreas
        
        return oldArray1, oldArray2
Ejemplo n.º 2
0
    def _getOldAdjacentValues(self, oldArray, id1, id2, dt):
        oldArray1, oldArray2 = ExplicitUpwindConvectionTerm._getOldAdjacentValues(self, oldArray, id1, id2, dt)
        
        mesh = oldArray.getMesh()

        interiorIDs = numerix.nonzero(mesh.getInteriorFaces())[0]
        interiorFaceAreas = numerix.take(mesh._getFaceAreas(), interiorIDs)
        interiorFaceNormals = numerix.take(mesh._getOrientedFaceNormals(), interiorIDs, axis=-1)
        
        # Courant-Friedrichs-Levy number
        interiorCFL = abs(numerix.take(self._getGeomCoeff(mesh), interiorIDs)) * dt
        
        gradUpwind = (oldArray2 - oldArray1) / numerix.take(mesh._getCellDistances(), interiorIDs)
        
        vol1 = numerix.take(mesh.getCellVolumes(), id1)
        self.CFL = interiorCFL / vol1
        
        oldArray1 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.getGrad(), id1, axis=-1), interiorFaceNormals), gradUpwind) \
            * (vol1 - interiorCFL) / interiorFaceAreas

        vol2 = numerix.take(mesh.getCellVolumes(), id2)
        
        self.CFL = numerix.maximum(interiorCFL / vol2, self.CFL)

        oldArray2 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.getGrad(), id2, axis=-1), -interiorFaceNormals), -gradUpwind) \
            * (vol2 - interiorCFL) / interiorFaceAreas
        
        return oldArray1, oldArray2
Ejemplo n.º 3
0
    def _getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh):

        dAP = mesh._cellToCellDistances

##        adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs)
        adjacentGradient = numerix.take(oldArray.grad, mesh._cellToCellIDs, axis=-1)
        adjacentNormalGradient = numerix.dot(adjacentGradient, mesh._cellNormals)
        adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient

        cellIDs = numerix.repeat(numerix.arange(mesh.numberOfCells)[numerix.newaxis, ...],
                mesh._maxFacesPerCell, axis=0)
        cellIDs = MA.masked_array(cellIDs, mask = MA.getmask(mesh._cellToCellIDs))
        cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1)
        cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals)
        cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient

        cellLaplacian = (cellUpValues + adjacentValues - 2 * cellValues) / dAP**2

        adjacentLaplacian = (adjacentUpValues + cellValues - 2 * adjacentValues) / dAP**2
        adjacentLaplacian = adjacentLaplacian.filled(0)
        cellLaplacian = cellLaplacian.filled(0)

        mm = numerix.where(cellLaplacian * adjacentLaplacian < 0.,
                           0.,
                           numerix.where(abs(cellLaplacian) > abs(adjacentLaplacian),
                                         adjacentLaplacian,
                                         cellLaplacian))

        return FirstOrderAdvectionTerm._getDifferences(self, adjacentValues, cellValues, oldArray, cellToCellIDs, mesh) -  mm * dAP / 2.
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def H_UniaxialAnisotropy(mUnit, uAxis, Ku2, Msat):
    global mu0
    ############ calculate normalized direction #####
    uAxisNorm = numerix.linalg.norm(uAxis)
    uAxisUnit = uAxis / uAxisNorm
    #################################################
    mArray = mUnit
    #################################################
    #################################################
    # repeat uniaxial direction vector for n times
    # where n= number of cells. uAxisUnit=3X1
    # uAxisArr=nX3, represents uniaxial direction for
    # each cells in the unit sphere
    #################################################
    uAxisArr = numerix.tile(uAxisUnit, (len(mUnit[0]), 1))
    uAxisArr = numerix.transpose(uAxisArr)  # converted to 3Xn
    mdotu = numerix.dot(mArray,
                        uAxisArr)  # projection of m along uniaxial direction
    scaleFac = numerix.multiply(
        mdotu, (2.0 * Ku2 / (mu0 * Msat)))  # calculate the magnitude in A/m
    Heff = numerix.zeros((3, len(scaleFac)),
                         'd')  # Uniaxial vector for each cell
    Heff[0] = numerix.multiply(scaleFac, uAxisArr[0])
    Heff[1] = numerix.multiply(scaleFac, uAxisArr[1])
    Heff[2] = numerix.multiply(scaleFac, uAxisArr[2])
    # unit is in A/m
    return Heff
Ejemplo n.º 6
0
    def __call__(self, points=None, order=0, nearestCellIDs=None):
        r"""
        Interpolates the `CellVariable` to a set of points using a
        method that has a memory requirement on the order of `Ncells` by
        `Npoints` in general, but uses only `Ncells` when the
        `CellVariable`'s mesh is a `UniformGrid` object.

        Tests

            >>> from fipy import *
            >>> m = Grid2D(nx=3, ny=2)
            >>> v = CellVariable(mesh=m, value=m.cellCenters[0])
            >>> print(v(((0., 1.1, 1.2), (0., 1., 1.))))
            [ 0.5  1.5  1.5]
            >>> print(v(((0., 1.1, 1.2), (0., 1., 1.)), order=1))
            [ 0.25  1.1   1.2 ]
            >>> m0 = Grid2D(nx=2, ny=2, dx=1., dy=1.)
            >>> m1 = Grid2D(nx=4, ny=4, dx=.5, dy=.5)
            >>> x, y = m0.cellCenters
            >>> v0 = CellVariable(mesh=m0, value=x * y)
            >>> print(v0(m1.cellCenters.globalValue))
            [ 0.25  0.25  0.75  0.75  0.25  0.25  0.75  0.75  0.75  0.75  2.25  2.25
              0.75  0.75  2.25  2.25]
            >>> print(v0(m1.cellCenters.globalValue, order=1))
            [ 0.125  0.25   0.5    0.625  0.25   0.375  0.875  1.     0.5    0.875
              1.875  2.25   0.625  1.     2.25   2.625]

        Parameters
        ----------
        points : tuple or :obj:`list` of :obj:`tuple`
            A point or set of points in the format (X, Y, Z)
        order : {`0`, `1`}
            The order of interpolation, default is 0
        nearestCellIDs : array_like
            Optional argument if user can calculate own
            nearest cell IDs array, shape should be same as points
        """
        if points is not None:

            if nearestCellIDs is None:
                nearestCellIDs = self.mesh._getNearestCellID(points)

            if order == 0:
                return self.globalValue[..., nearestCellIDs]

            elif order == 1:
                ##cellID = self.mesh._getNearestCellID(points)
                ##                return self[...,self.mesh._getNearestCellID(points)] + numerix.dot(points - self.mesh.cellCenters[...,cellID], self.grad[...,cellID])
                return (self.globalValue[..., nearestCellIDs] + numerix.dot(
                    points -
                    self.mesh.cellCenters.globalValue[..., nearestCellIDs],
                    self.grad.globalValue[..., nearestCellIDs]))

            else:
                raise ValueError('order should be either 0 or 1')

        else:
            return _MeshVariable.__call__(self)
Ejemplo n.º 7
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))
Ejemplo n.º 8
0
    def __call__(self, points=None, order=0, nearestCellIDs=None):
        r"""
        Interpolates the CellVariable to a set of points using a
        method that has a memory requirement on the order of Ncells by
        Npoints in general, but uses only Ncells when the
        CellVariable's mesh is a UniformGrid object.

        :Parameters:

           - `points`: A point or set of points in the format (X, Y, Z)
           - `order`: The order of interpolation, 0 or 1, default is 0 
           - `nearestCellIDs` : Optional argument if user can calculate own
             nearest cell IDs array, shape should be same as points

        Tests

            >>> from fipy import *
            >>> m = Grid2D(nx=3, ny=2)
            >>> v = CellVariable(mesh=m, value=m.cellCenters[0])
            >>> print v(((0., 1.1, 1.2), (0., 1., 1.)))
            [ 0.5  1.5  1.5]
            >>> print v(((0., 1.1, 1.2), (0., 1., 1.)), order=1)
            [ 0.25  1.1   1.2 ]
            >>> m0 = Grid2D(nx=2, ny=2, dx=1., dy=1.)
            >>> m1 = Grid2D(nx=4, ny=4, dx=.5, dy=.5)
            >>> x, y = m0.cellCenters
            >>> v0 = CellVariable(mesh=m0, value=x * y)
            >>> print v0(m1.cellCenters.globalValue)
            [ 0.25  0.25  0.75  0.75  0.25  0.25  0.75  0.75  0.75  0.75  2.25  2.25
              0.75  0.75  2.25  2.25]
            >>> print v0(m1.cellCenters.globalValue, order=1)
            [ 0.125  0.25   0.5    0.625  0.25   0.375  0.875  1.     0.5    0.875
              1.875  2.25   0.625  1.     2.25   2.625]

        """
        if points is not None:

            if nearestCellIDs is None:
                nearestCellIDs = self.mesh._getNearestCellID(points)

            if order == 0:
                return self.globalValue[..., nearestCellIDs]

            elif order == 1:
                ##cellID = self.mesh._getNearestCellID(points)
                ##                return self[...,self.mesh._getNearestCellID(points)] + numerix.dot(points - self.mesh.cellCenters[...,cellID], self.grad[...,cellID])
                return (self.globalValue[..., nearestCellIDs] + numerix.dot(
                    points -
                    self.mesh.cellCenters.globalValue[..., nearestCellIDs],
                    self.grad.globalValue[..., nearestCellIDs]))

            else:
                raise ValueError, 'order should be either 0 or 1'

        else:
            return _MeshVariable.__call__(self)
Ejemplo n.º 9
0
    def _calcFaceNormals(self):
        faceVertexCoords = numerix.take(self.vertexCoords, self.faceVertexIDs, axis=1)
        t1 = faceVertexCoords[:, 1,:] - faceVertexCoords[:, 0,:]
        faceNormals = t1.copy()
        mag = numerix.sqrt(t1[1]**2 + t1[0]**2)
        faceNormals[0] = -t1[1] / mag
        faceNormals[1] = t1[0] / mag

        orientation = 1 - 2 * (numerix.dot(faceNormals, self.cellDistanceVectors) < 0)
        return faceNormals * orientation
Ejemplo n.º 10
0
 def _calcFaceNormals(self):
     faceVertexCoords = numerix.take(self.vertexCoords, self.faceVertexIDs, axis=1)
     t1 = faceVertexCoords[:,1,:] - faceVertexCoords[:,0,:]
     faceNormals = t1.copy()
     mag = numerix.sqrt(t1[1]**2 + t1[0]**2)
     faceNormals[0] = -t1[1] / mag
     faceNormals[1] = t1[0] / mag
     
     orientation = 1 - 2 * (numerix.dot(faceNormals, self.cellDistanceVectors) < 0)
     return faceNormals * orientation
Ejemplo n.º 11
0
    def __call__(self, points=None, order=0, nearestCellIDs=None):
        r"""
        Interpolates the CellVariable to a set of points using a
        method that has a memory requirement on the order of Ncells by
        Npoints in general, but uses only Ncells when the
        CellVariable's mesh is a UniformGrid object.

        :Parameters:

           - `points`: A point or set of points in the format (X, Y, Z)
           - `order`: The order of interpolation, 0 or 1, default is 0 
           - `nearestCellIDs` : Optional argument if user can calculate own
             nearest cell IDs array, shape should be same as points

        Tests

            >>> from fipy import *
            >>> m = Grid2D(nx=3, ny=2)
            >>> v = CellVariable(mesh=m, value=m.getCellCenters()[0])
            >>> print v(((0., 1.1, 1.2), (0., 1., 1.)))
            [ 0.5  1.5  1.5]
            >>> print v(((0., 1.1, 1.2), (0., 1., 1.)), order=1)
            [ 0.25  1.1   1.2 ]
            >>> m0 = Grid2D(nx=2, ny=2, dx=1., dy=1.)
            >>> m1 = Grid2D(nx=4, ny=4, dx=.5, dy=.5)
            >>> x, y = m0.getCellCenters()
            >>> v0 = CellVariable(mesh=m0, value=x * y)
            >>> print v0(m1.getCellCenters().getGlobalValue())
            [ 0.25  0.25  0.75  0.75  0.25  0.25  0.75  0.75  0.75  0.75  2.25  2.25
              0.75  0.75  2.25  2.25]
            >>> print v0(m1.getCellCenters().getGlobalValue(), order=1)
            [ 0.125  0.25   0.5    0.625  0.25   0.375  0.875  1.     0.5    0.875
              1.875  2.25   0.625  1.     2.25   2.625]

        """           
        if points is not None:

            if nearestCellIDs is None:
                nearestCellIDs = self.getMesh()._getNearestCellID(points)

            if order == 0:
                return self.getGlobalValue()[..., nearestCellIDs]

            elif order == 1:
                ##cellID = self.getMesh()._getNearestCellID(points)
##                return self[...,self.getMesh()._getNearestCellID(points)] + numerix.dot(points - self.getMesh().getCellCenters()[...,cellID], self.getGrad()[...,cellID])
                return (self.getGlobalValue()[..., nearestCellIDs] 
                        + numerix.dot(points - self.getMesh().getCellCenters().getGlobalValue()[...,nearestCellIDs], 
                                      self.getGrad().getGlobalValue()[...,nearestCellIDs]))

            else:
                raise ValueError, 'order should be either 0 or 1'

        else:
            return _MeshVariable.__call__(self)
Ejemplo n.º 12
0
 def dot(self, other, opShape=None, operatorClass=None, axis=0):
     if not isinstance(other, Variable):
         from fipy.variables.constant import _Constant
         other = _Constant(value=other)
     if opShape is None:
         opShape = self._broadcastShape(other)
     return self._BinaryOperatorVariable(lambda a,b: numerix.dot(a,b, axis=axis), 
                                         other, 
                                         opShape=opShape[:axis]+opShape[axis+1:],
                                         operatorClass=operatorClass,
                                         canInline=False)
Ejemplo n.º 13
0
    def _getDifferences(self, adjacentValues, cellValues, oldArray,
                        cellToCellIDs, mesh):

        dAP = mesh._cellToCellDistances

        ##        adjacentGradient = numerix.take(oldArray.grad, cellToCellIDs)
        adjacentGradient = numerix.take(oldArray.grad,
                                        mesh._cellToCellIDs,
                                        axis=-1)
        adjacentNormalGradient = numerix.dot(adjacentGradient,
                                             mesh._cellNormals)
        adjacentUpValues = cellValues + 2 * dAP * adjacentNormalGradient

        cellIDs = numerix.repeat(numerix.arange(
            mesh.numberOfCells)[numerix.newaxis, ...],
                                 mesh._maxFacesPerCell,
                                 axis=0)
        cellIDs = MA.masked_array(cellIDs,
                                  mask=MA.getmask(mesh._cellToCellIDs))
        cellGradient = numerix.take(oldArray.grad, cellIDs, axis=-1)
        cellNormalGradient = numerix.dot(cellGradient, mesh._cellNormals)
        cellUpValues = adjacentValues - 2 * dAP * cellNormalGradient

        cellLaplacian = (cellUpValues + adjacentValues -
                         2 * cellValues) / dAP**2

        adjacentLaplacian = (adjacentUpValues + cellValues -
                             2 * adjacentValues) / dAP**2
        adjacentLaplacian = adjacentLaplacian.filled(0)
        cellLaplacian = cellLaplacian.filled(0)

        mm = numerix.where(
            cellLaplacian * adjacentLaplacian < 0., 0.,
            numerix.where(
                abs(cellLaplacian) > abs(adjacentLaplacian), adjacentLaplacian,
                cellLaplacian))

        return FirstOrderAdvectionTerm._getDifferences(
            self, adjacentValues, cellValues, oldArray, cellToCellIDs,
            mesh) - mm * dAP / 2.
Ejemplo n.º 14
0
 def _rightHandOrientation(self):
     faceVertexIDs = MA.filled(self.faceVertexIDs, 0)
     faceVertexCoords = numerix.take(self.vertexCoords, faceVertexIDs, axis=1)
     t1 = faceVertexCoords[:,1,:] - faceVertexCoords[:,0,:]
     t2 = faceVertexCoords[:,2,:] - faceVertexCoords[:,1,:]
     norm = numerix.cross(t1, t2, axis=0)
     ## reordering norm's internal memory for inlining
     norm = norm.copy()
     norm = norm / numerix.sqrtDot(norm, norm)
     
     faceNormals = -norm
     
     return 1 - 2 * (numerix.dot(faceNormals, self.cellDistanceVectors) < 0)
Ejemplo n.º 15
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
Ejemplo n.º 16
0
def HeffUniaxialAnisotropyFac(mUnit, uAxis, Hfac):
    uAxisNorm = numerix.linalg.norm(uAxis)
    uAxisUnit = uAxis / uAxisNorm
    mNorm = numerix.linalg.norm(mUnit,axis=0)
    mArray = mUnit / mNorm
    uAxisArr = numerix.tile(uAxisUnit, (len(mUnit[0]), 1))
    uAxisArr = numerix.transpose(uAxisArr)
    mdotu = numerix.dot(mArray, uAxisArr)
    scaleFac = numerix.multiply(mdotu, Hfac)
    Heff = numerix.zeros((3, len(scaleFac)), 'd')
    Heff[0] = numerix.multiply(scaleFac, uAxisArr[0])
    Heff[1] = numerix.multiply(scaleFac, uAxisArr[1])
    Heff[2] = numerix.multiply(scaleFac, uAxisArr[2])
    return Heff
Ejemplo n.º 17
0
Archivo: mesh.py Proyecto: regmi/fipy
    def _getNearestCellID(self, points):
        """
        Test cases

           >>> from fipy import *
           >>> m0 = Grid2D(dx=(.1, 1., 10.), dy=(.1, 1., 10.))
           >>> m1 = Grid2D(nx=2, ny=2, dx=5., dy=5.)
           >>> print m0._getNearestCellID(m1.getCellCenters().getGlobalValue())
           [4 5 7 8]
           
        """
        if self.globalNumberOfCells == 0:
            return numerix.arange(0)
            
        points = numerix.resize(points, (self.globalNumberOfCells, len(points), len(points[0]))).swapaxes(0,1)

        centers = self.getCellCenters().getGlobalValue()[...,numerix.newaxis]
        try:
            tmp = centers - points
        except TypeError:
            tmp = centers - PhysicalField(points)

        return numerix.argmin(numerix.dot(tmp, tmp, axis = 0), axis=0)
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
    def _getAddedMeshValues(self, other, resolution=1e-2):
        """Calculate the parameters to define a concatenation of `other` with `self`
        
        :Parameters:
          - `other`: The :class:`~fipy.meshes.numMesh.Mesh` to concatenate with `self`
          - `resolution`: How close vertices have to be (relative to the smallest 
            cell-to-cell distance in either mesh) to be considered the same

        :Returns:
          A `dict` with 3 elements: the new mesh vertexCoords, faceVertexIDs, and cellFaceIDs.
        """
        
        selfc = self._getConcatenableMesh()
        other = other._getConcatenableMesh()

        selfNumFaces = selfc.faceVertexIDs.shape[-1]
        selfNumVertices = selfc.vertexCoords.shape[-1]
        otherNumFaces = other.faceVertexIDs.shape[-1]
        otherNumVertices = other.vertexCoords.shape[-1]
        ## check dimensions
        if(selfc.vertexCoords.shape[0] != other.vertexCoords.shape[0]):
            raise MeshAdditionError, "Dimensions do not match"
            
        ## compute vertex correlates

        ## only try to match exterior (X) vertices
        self_Xvertices = numerix.unique(selfc._getFaceVertexIDs().filled()[..., selfc.getExteriorFaces().getValue()].flatten())
        other_Xvertices = numerix.unique(other._getFaceVertexIDs().filled()[..., other.getExteriorFaces().getValue()].flatten())

        self_XvertexCoords = selfc.vertexCoords[..., self_Xvertices]
        other_XvertexCoords = other.vertexCoords[..., other_Xvertices]
        
        # lifted from Mesh._getNearestCellID()
        other_vertexCoordMap = numerix.resize(other_XvertexCoords, 
                                              (self_XvertexCoords.shape[-1], 
                                               other_XvertexCoords.shape[0], 
                                               other_XvertexCoords.shape[-1])).swapaxes(0,1)
        tmp = self_XvertexCoords[..., numerix.newaxis] - other_vertexCoordMap
        closest = numerix.argmin(numerix.dot(tmp, tmp), axis=0)
        
        # just because they're closest, doesn't mean they're close
        tmp = self_XvertexCoords[..., closest] - other_XvertexCoords
        distance = numerix.sqrtDot(tmp, tmp)
        # only want vertex pairs that are 100x closer than the smallest 
        # cell-to-cell distance
        close = distance < resolution * min(selfc._getCellToCellDistances().min(), 
                                            other._getCellToCellDistances().min())
        vertexCorrelates = numerix.array((self_Xvertices[closest[close]],
                                          other_Xvertices[close]))
        
        # warn if meshes don't touch, but allow it
        if (selfc._getNumberOfVertices() > 0 
            and other._getNumberOfVertices() > 0 
            and vertexCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Vertices are not aligned", UserWarning, stacklevel=4)

        ## compute face correlates

        # ensure that both sets of faceVertexIDs have the same maximum number of (masked) elements
        self_faceVertexIDs = selfc.faceVertexIDs
        other_faceVertexIDs = other.faceVertexIDs

        diff = self_faceVertexIDs.shape[0] - other_faceVertexIDs.shape[0]
        if diff > 0:
            other_faceVertexIDs = numerix.append(other_faceVertexIDs, 
                                                 -1 * numerix.ones((diff,) 
                                                                   + other_faceVertexIDs.shape[1:]),
                                                 axis=0)
            other_faceVertexIDs = MA.masked_values(other_faceVertexIDs, -1)
        elif diff < 0:
            self_faceVertexIDs = numerix.append(self_faceVertexIDs, 
                                                -1 * numerix.ones((-diff,) 
                                                                  + self_faceVertexIDs.shape[1:]),
                                                axis=0)
            self_faceVertexIDs = MA.masked_values(self_faceVertexIDs, -1)

        # want self's Faces for which all faceVertexIDs are in vertexCorrelates
        self_matchingFaces = numerix.in1d(self_faceVertexIDs, 
                                          vertexCorrelates[0]).reshape(self_faceVertexIDs.shape).all(axis=0).nonzero()[0]

        # want other's Faces for which all faceVertexIDs are in vertexCorrelates
        other_matchingFaces = numerix.in1d(other_faceVertexIDs, 
                                           vertexCorrelates[1]).reshape(other_faceVertexIDs.shape).all(axis=0).nonzero()[0]
                                           
        # map other's Vertex IDs to new Vertex IDs, 
        # accounting for overlaps with self's Vertex IDs
        vertex_map = numerix.empty(otherNumVertices, dtype=int)
        verticesToAdd = numerix.delete(numerix.arange(otherNumVertices), vertexCorrelates[1])
        vertex_map[verticesToAdd] = numerix.arange(otherNumVertices - len(vertexCorrelates[1])) + selfNumVertices
        vertex_map[vertexCorrelates[1]] = vertexCorrelates[0]

        # calculate hashes of faceVertexIDs for comparing Faces
        
        if self_matchingFaces.shape[-1] == 0:
            self_faceHash = numerix.empty(self_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # sort each of self's Face's vertexIDs for canonical comparison
            self_faceHash = numerix.sort(self_faceVertexIDs[..., self_matchingFaces], axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            self_faceHash = numerix.apply_along_axis(str, axis=0, arr=self_faceHash)
            
        face_sort = numerix.argsort(self_faceHash)
        self_faceHash = self_faceHash[face_sort]
        self_matchingFaces = self_matchingFaces[face_sort]

        if other_matchingFaces.shape[-1] == 0:
            other_faceHash = numerix.empty(other_matchingFaces.shape[:-1] + (0,), dtype="str")
        else:
            # convert each of other's Face's vertexIDs to new IDs
            other_faceHash = vertex_map[other_faceVertexIDs[..., other_matchingFaces]]
            # sort each of other's Face's vertexIDs for canonical comparison
            other_faceHash = numerix.sort(other_faceHash, axis=0)
            # then hash the Faces for comparison (NumPy set operations are only for 1D arrays)
            other_faceHash = numerix.apply_along_axis(str, axis=0, arr=other_faceHash)

        face_sort = numerix.argsort(other_faceHash)
        other_faceHash = other_faceHash[face_sort]
        other_matchingFaces = other_matchingFaces[face_sort]

        self_matchingFaces = self_matchingFaces[numerix.in1d(self_faceHash, 
                                                             other_faceHash)]
        other_matchingFaces = other_matchingFaces[numerix.in1d(other_faceHash, 
                                                               self_faceHash)]
        
        faceCorrelates = numerix.array((self_matchingFaces,
                                        other_matchingFaces))

        # warn if meshes don't touch, but allow it
        if (selfc._getNumberOfFaces() > 0 
            and other._getNumberOfFaces() > 0 
            and faceCorrelates.shape[-1] == 0):
            import warnings
            warnings.warn("Faces are not aligned", UserWarning, stacklevel=4)

        # map other's Face IDs to new Face IDs, 
        # accounting for overlaps with self's Face IDs
        face_map = numerix.empty(otherNumFaces, dtype=int)
        facesToAdd = numerix.delete(numerix.arange(otherNumFaces), faceCorrelates[1])
        face_map[facesToAdd] = numerix.arange(otherNumFaces - len(faceCorrelates[1])) + selfNumFaces
        face_map[faceCorrelates[1]] = faceCorrelates[0]
        
        other_faceVertexIDs = vertex_map[other.faceVertexIDs[..., facesToAdd]]
        
        # ensure that both sets of cellFaceIDs have the same maximum number of (masked) elements
        self_cellFaceIDs = selfc.cellFaceIDs
        other_cellFaceIDs = face_map[other.cellFaceIDs]
        diff = self_cellFaceIDs.shape[0] - other_cellFaceIDs.shape[0]
        if diff > 0:
            other_cellFaceIDs = numerix.append(other_cellFaceIDs, 
                                               -1 * numerix.ones((diff,) 
                                                                 + other_cellFaceIDs.shape[1:]),
                                               axis=0)
            other_cellFaceIDs = MA.masked_values(other_cellFaceIDs, -1)
        elif diff < 0:
            self_cellFaceIDs = numerix.append(self_cellFaceIDs, 
                                              -1 * numerix.ones((-diff,) 
                                                                + self_cellFaceIDs.shape[1:]),
                                              axis=0)
            self_cellFaceIDs = MA.masked_values(self_cellFaceIDs, -1)

        # concatenate everything and return
        return {
            'vertexCoords': numerix.concatenate((selfc.vertexCoords, 
                                                 other.vertexCoords[..., verticesToAdd]), axis=1), 
            'faceVertexIDs': numerix.concatenate((self_faceVertexIDs, 
                                                  other_faceVertexIDs), axis=1), 
            'cellFaceIDs': MA.concatenate((self_cellFaceIDs, 
                                           other_cellFaceIDs), axis=1)
            }
Ejemplo n.º 20
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)
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
Z = CellVariable(name=r"$Z$", mesh=mesh, hasOld=True)

Diffusivity = CellVariable(name=r"$D$", mesh=mesh, hasOld=True)

# ----------- Initial Conditions of Z ---------------------
Z0L = 1.0  # L--mode
Z0H = Z_S * (1.0 - numerix.tanh((L * x - L) / 2.0))  # H--mode
Z.setValue(Z0H)

# ----------------- Diffusivities -------------------------
# Itohs'/Zohm's model
D_Zohm = (D_max + D_min) / 2.0 + ((D_max - D_min) * numerix.tanh(Z)) / 2.0
# Stap's Model
alpha_sup = 0.5
D_Staps = D_min + (D_max - D_min) / (1.0 +
                                     alpha_sup * numerix.dot(Z.grad, Z.grad))
# Flow-Shear Model
a1, a3 = 1.0, 0.5  # ASSUMES a2 = 0
D_Shear = D_min + (D_max - D_min) / (1.0 + a1 *
                                     (Z)**2 + a3 * numerix.dot(Z.grad, Z.grad))

# CHOOSE DIFFUSIVITY HERE!
D_choice = D_Staps

# If Diffusivity is a Cell/Face variable
Diffusivity.setValue(D_choice)
Diffusivity.equation = (ImplicitSourceTerm(1.0))

# ----------------- Boundary Conditions -------------------
"""
	Density Boundary Conditions:
 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)