예제 #1
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
예제 #2
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.
예제 #3
0
 def _calcValue_(self, alpha, id1, id2):
     cell1 = numerix.take(self.var, id1, axis=-1)
     cell2 = numerix.take(self.var, id2, axis=-1)
     return numerix.where((cell1 > 0) & (cell2 > 0),
                          numerix.minimum(cell1, cell2),
                          numerix.where((cell1 < 0) & (cell2 < 0),
                                        numerix.maximum(cell1, cell2), 0))
예제 #4
0
    def _calcValue(self):
        """

        Test case added because `and` was being used instead of bitwise `&`.

            >>> from fipy.meshes import Grid1D
            >>> mesh = Grid1D(nx = 3)
            >>> from fipy.variables.faceVariable import FaceVariable
            >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3))
            >>> alpha = ExponentialConvectionTerm([1])._alpha(P)
            >>> print alpha
            [ 0.5  1.   0.5  0.5]

        """
        eps = 1e-3
        largeValue = 101.0
        P = self.P.numericValue

        P = numerix.where(abs(P) < eps, eps, P)
        alpha = numerix.where(P > largeValue, (P - 1) / P, 0.5)
        Pmin = numerix.where(P > largeValue + 1, largeValue + 1, P)
        alpha = numerix.where((abs(Pmin) > eps) & (Pmin <= largeValue),
                              ((Pmin - 1) * numerix.exp(Pmin) + 1) /
                              (Pmin * (numerix.exp(Pmin) - 1)), alpha)

        return alpha
예제 #5
0
    def __getRotationTensor(self, mesh):
        if not hasattr(self, 'rotationTensor'):

            rotationTensor = FaceVariable(mesh=mesh, rank=2)

            rotationTensor[:, 0] = self._getNormals(mesh)

            if mesh.dim == 2:
                rotationTensor[:, 1] = rotationTensor[:, 0].dot(
                    (((0, 1), (-1, 0))))
            elif mesh.dim == 3:
                epsilon = 1e-20

                div = numerix.sqrt(1 - rotationTensor[2, 0]**2)
                flag = numerix.resize(div > epsilon,
                                      (mesh.dim, mesh.numberOfFaces))

                rotationTensor[0, 1] = 1
                rotationTensor[:, 1] = numerix.where(
                    flag, rotationTensor[:, 0].dot(
                        (((0, 1, 0), (-1, 0, 0), (0, 0, 0)))) / div,
                    rotationTensor[:, 1])

                rotationTensor[1, 2] = 1
                rotationTensor[:, 2] = numerix.where(
                    flag, rotationTensor[:, 0] * rotationTensor[2, 0] / div,
                    rotationTensor[:, 2])
                rotationTensor[2, 2] = -div

            self.rotationTensor = rotationTensor

        return self.rotationTensor
예제 #6
0
    def _getRotationTensor(self, mesh):
        if not hasattr(self, 'rotationTensor'):

            from fipy.variables.faceVariable import FaceVariable
            rotationTensor = FaceVariable(mesh=mesh, rank=2)
            
            rotationTensor[:, 0] = self._getNormals(mesh)

            if mesh.getDim() == 2:
                rotationTensor[:,1] = rotationTensor[:,0].dot((((0, 1), (-1, 0))))
            elif mesh.getDim() ==3:
                epsilon = 1e-20

                div = numerix.sqrt(1 - rotationTensor[2,0]**2)
                flag = numerix.resize(div > epsilon, (mesh.getDim(), mesh._getNumberOfFaces()))

                rotationTensor[0, 1] = 1
                rotationTensor[:, 1] = numerix.where(flag,
                                                     rotationTensor[:,0].dot((((0, 1, 0), (-1, 0, 0), (0, 0, 0)))) / div,
                                                     rotationTensor[:, 1])

                rotationTensor[1, 2] = 1
                rotationTensor[:, 2] = numerix.where(flag,
                                                     rotationTensor[:,0] * rotationTensor[2,0] / div,
                                                     rotationTensor[:, 2])
                rotationTensor[2, 2] = -div
                
            self.rotationTensor = rotationTensor

        return self.rotationTensor
예제 #7
0
	def _calcValuePy(self, eps, P):
            """

            Test case added because `and` was being used instead of bitwise `&`.

                >>> from fipy.meshes.grid1D import Grid1D
                >>> mesh = Grid1D(nx = 3)
                >>> from fipy.variables.faceVariable import FaceVariable
                >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3))
                >>> alpha = PowerLawConvectionTerm._Alpha(P)
                >>> print numerix.allclose(alpha, [ 0.5,  1.,   0.5 , 0.5])
                True
                
            """
            
	    P = numerix.where(abs(P) < eps, eps, P)
	    
	    alpha = numerix.where(                  P > 10.,                     (P - 1.) / P,   0.5)

	    tmp = (1. - P / 10.)
	    tmpSqr = tmp * tmp
	    alpha = numerix.where(  (10. >= P) & (P > eps), ((P-1.) + tmpSqr*tmpSqr*tmp) / P, alpha)

	    tmp = (1. + P / 10.)
	    tmpSqr = tmp * tmp
	    alpha = numerix.where((-eps >  P) & (P >= -10.),     (tmpSqr*tmpSqr*tmp - 1.) / P, alpha)

	    alpha = numerix.where(                 P < -10.,                          -1. / P, alpha)

	    return PhysicalField(value = alpha)
예제 #8
0
def _orderVertices(vertexCoords, vertices):
    coordinates = numerix.take(vertexCoords, vertices, axis=1)
    centroid = numerix.add.reduce(coordinates, axis=1) / coordinates.shape[1]
    coordinates = coordinates - centroid[..., numerix.newaxis]
    coordinates = numerix.where(coordinates == 0, 1.e-10, coordinates) ## to prevent division by zero
    angles = numerix.arctan(coordinates[1] / coordinates[0]) + numerix.where(coordinates[0] < 0, numerix.pi, 0) ## angles go from -pi / 2 to 3*pi / 2
    sortorder = numerix.argsort(angles)
    return numerix.take(vertices, sortorder)
예제 #9
0
 def _calcValue_(self, alpha, id1, id2):
     cell1 = numerix.take(self.var,id1, axis=-1)
     cell2 = numerix.take(self.var,id2, axis=-1)
     return numerix.where((cell1 > 0) & (cell2 > 0),
                          numerix.minimum(cell1, cell2),
                          numerix.where((cell1 < 0) & (cell2 < 0),
                                        numerix.maximum(cell1, cell2),
                                        0))
    def _calcValue(self):
        eps = 1e-3
        P  = self.P

        alpha = numerix.where(                                 P > 2., (P - 1) / P,    0.)
        alpha = numerix.where( numerix.logical_and(2. >= P, P >= -2.),         0.5, alpha)
        alpha = numerix.where(                               -2. >  P,      -1 / P, alpha)

        return alpha
예제 #11
0
    def __init__(self,
                 trenchDepth=None,
                 trenchSpacing=None,
                 boundaryLayerDepth=None,
                 cellSize=None,
                 aspectRatio=None,
                 angle=0.,
                 communicator=parallelComm):
        """

        `trenchDepth` - Depth of the trench.

        `trenchSpacing` - The distance between the trenches.

        `boundaryLayerDepth` - The depth of the hydrodynamic boundary
        layer.

        `cellSize` - The cell Size.

        `aspectRatio` - trenchDepth / trenchWidth

        `angle` - The angle for the taper of the trench.

        The trench mesh takes the parameters generally used to define
        a trench region and recasts then for the general
        `GapFillMesh`.

        """

        heightBelowTrench = cellSize * 10.

        heightAboveTrench = trenchDepth / 1.

        fineRegionHeight = heightBelowTrench + trenchDepth + heightAboveTrench
        transitionHeight = fineRegionHeight * 3.
        domainWidth = trenchSpacing / 2.
        domainHeight = heightBelowTrench + trenchDepth + boundaryLayerDepth

        super(TrenchMesh, self).__init__(cellSize=cellSize,
                                         desiredDomainWidth=domainWidth,
                                         desiredDomainHeight=domainHeight,
                                         desiredFineRegionHeight=fineRegionHeight,
                                         transitionRegionHeight=transitionHeight,
                                         communicator=parallelComm)

        trenchWidth = trenchDepth / aspectRatio

        x, y = self.cellCenters
        Y = (y - (heightBelowTrench + trenchDepth / 2))
        taper = numerix.tan(angle) * Y
        self.electrolyteMask = numerix.where(y > trenchDepth + heightBelowTrench,
                                             1,
                                             numerix.where(y < heightBelowTrench,
                                                           0,
                                                           numerix.where(x > trenchWidth / 2 + taper,
                                                                         0,
                                                                         1)))
예제 #12
0
    def __init__(self,
                 trenchDepth=None,
                 trenchSpacing=None,
                 boundaryLayerDepth=None,
                 cellSize=None,
                 aspectRatio=None,
                 angle=0.,
                 communicator=parallelComm):
        """

        `trenchDepth` - Depth of the trench.

        `trenchSpacing` - The distance between the trenches.

        `boundaryLayerDepth` - The depth of the hydrodynamic boundary
        layer.

        `cellSize` - The cell Size.

        `aspectRatio` - trenchDepth / trenchWidth

        `angle` - The angle for the taper of the trench.

        The trench mesh takes the parameters generally used to define
        a trench region and recasts then for the general
        `GapFillMesh`.

        """

        heightBelowTrench = cellSize * 10.

        heightAboveTrench = trenchDepth / 1.

        fineRegionHeight = heightBelowTrench + trenchDepth + heightAboveTrench
        transitionHeight = fineRegionHeight * 3.
        domainWidth = trenchSpacing / 2.
        domainHeight = heightBelowTrench + trenchDepth + boundaryLayerDepth

        super(TrenchMesh, self).__init__(cellSize=cellSize,
                                         desiredDomainWidth=domainWidth,
                                         desiredDomainHeight=domainHeight,
                                         desiredFineRegionHeight=fineRegionHeight,
                                         transitionRegionHeight=transitionHeight,
                                         communicator=parallelComm)

        trenchWidth = trenchDepth / aspectRatio

        x, y = self.cellCenters
        Y = (y - (heightBelowTrench + trenchDepth / 2))
        taper = numerix.tan(angle) * Y
        self.electrolyteMask = numerix.where(y > trenchDepth + heightBelowTrench,
                                             1,
                                             numerix.where(y < heightBelowTrench,
                                                           0,
                                                           numerix.where(x > trenchWidth / 2 + taper,
                                                                         0,
                                                                         1)))
예제 #13
0
        def _calcValue(self):
            eps = 1e-3
            P  = self.P

            alpha = numerix.where(                                 P > 2., (P - 1) / P,    0.)
            alpha = numerix.where( numerix.logical_and(2. >= P, P >= -2.),         0.5, alpha)
            alpha = numerix.where(                               -2. >  P,      -1 / P, alpha)

            return alpha
예제 #14
0
파일: mesh2D.py 프로젝트: LWhitson2/fipy
def _orderVertices(vertexCoords, vertices):
    coordinates = numerix.take(vertexCoords, vertices)
    centroid = numerix.add.reduce(coordinates) / coordinates.shape[0]
    coordinates = coordinates - centroid
    # to prevent division by zero
    coordinates = numerix.where(coordinates == 0, 1.e-100, coordinates) 
    # angles go from -pi / 2 to 3*pi / 2
    angles = numerix.arctan(coordinates[:, 1] / coordinates[:, 0]) \
               + numerix.where(coordinates[:, 0] < 0, numerix.pi, 0) 
    sortorder = numerix.argsort(angles)
    return numerix.take(vertices, sortorder)
예제 #15
0
파일: mesh2D.py 프로젝트: ztrautt/fipy
def _orderVertices(vertexCoords, vertices):
    coordinates = numerix.take(vertexCoords, vertices)
    centroid = numerix.add.reduce(coordinates) / coordinates.shape[0]
    coordinates = coordinates - centroid
    # to prevent division by zero
    coordinates = numerix.where(coordinates == 0, 1.e-100, coordinates)
    # angles go from -pi / 2 to 3*pi / 2
    angles = numerix.arctan(coordinates[:, 1] / coordinates[:, 0]) \
               + numerix.where(coordinates[:, 0] < 0, numerix.pi, 0)
    sortorder = numerix.argsort(angles)
    return numerix.take(vertices, sortorder)
예제 #16
0
    def _getGradient(self, normalGradient, gradUpwind):
        gradUpUpwind = -gradUpwind + 2 * normalGradient

        avg = 0.5 * (abs(gradUpwind) + abs(gradUpUpwind))
        min3 = numerix.minimum(
            numerix.minimum(abs(2 * gradUpwind), abs(2 * gradUpUpwind)), avg)

        grad = numerix.where(gradUpwind * gradUpUpwind < 0., 0.,
                             numerix.where(gradUpUpwind > 0., min3, -min3))

        return grad
예제 #17
0
    def _getGradient(self, normalGradient, gradUpwind):
        gradUpUpwind = -gradUpwind + 2 * normalGradient

        avg = 0.5 * (abs(gradUpwind) + abs(gradUpUpwind))
        min3 = numerix.minimum(numerix.minimum(abs(gradUpwind), abs(gradUpUpwind)), avg)

        grad = numerix.where(gradUpwind * gradUpUpwind < 0.,
                             0., 
                             numerix.where(gradUpUpwind > 0.,
                                           min3,
                                           -min3))

        return grad
예제 #18
0
        def _calcValue_(self, alpha, id1, id2):
            distance = numerix.array(self.var)
            cell1 = numerix.take(distance, id1)
            cell2 = numerix.take(distance, id2)

            return numerix.where(numerix.logical_or(cell1 < 0, cell2 < 0), 0,
                                 self.diffusionCoeff)
예제 #19
0
    def _levelSetNormals(self):
        """

        Return the face level set normals.

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

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

        ## set faceGrad zero on exteriorFaces
        exteriorFaces = self.mesh.exteriorFaces
        if len(exteriorFaces.value) > 0:
            faceGrad[..., exteriorFaces.value] = 0.
        
        return faceGrad / faceGradMag 
예제 #20
0
    def _interfaceNormals(self):
        """

        Returns the normals on the boundary faces only, the other are set to zero.

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

        M = self.mesh.dim
        interfaceFlag = numerix.repeat(self._interfaceFlag[numerix.newaxis,
                                                           ...],
                                       M,
                                       axis=0)
        return numerix.where(interfaceFlag, self._levelSetNormals, 0)
예제 #21
0
    def _levelSetNormals(self):
        """

        Return the face level set normals.

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

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

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

        return faceGrad / faceGradMag
예제 #22
0
    def _plot(self):

        var = self.vars[0]
        mesh = var.mesh

        U, V = var.numericValue

        U = numerix.take(U, self.indices)
        V = numerix.take(V, self.indices)
        
        ang = numerix.arctan2(V, U)
        mag = numerix.sqrt(U**2 + V**2)
        
        datamin, datamax = self._autoscale(vars=(mag,),
                                           datamin=self._getLimit('datamin'),
                                           datamax=self._getLimit('datamax'))
        
        mag = numerix.where(mag > datamax, datamax, mag)
        mag = numerix.ma.masked_array(mag, mag < datamin)
        
        if self.log:
            mag = numerix.log10(mag)
            mag = numerix.ma.masked_array(mag, numerix.isnan(mag))
            
        U = mag * numerix.cos(ang)
        V = mag * numerix.sin(ang)

        self._quiver.set_UVC(U, V)
        
        self.axes.set_xlim(xmin=self._getLimit('xmin'),
                           xmax=self._getLimit('xmax'))
        self.axes.set_ylim(ymin=self._getLimit('ymin'),
                           ymax=self._getLimit('ymax'))
예제 #23
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)
예제 #24
0
    def _plot(self):

        var = self.vars[0]
        mesh = var.mesh

        U, V = var.numericValue

        U = numerix.take(U, self.indices)
        V = numerix.take(V, self.indices)

        ang = numerix.arctan2(V, U)
        mag = numerix.sqrt(U**2 + V**2)

        datamin, datamax = self._autoscale(vars=(mag, ),
                                           datamin=self._getLimit('datamin'),
                                           datamax=self._getLimit('datamax'))

        mag = numerix.where(mag > datamax, datamax, mag)
        mag = numerix.ma.masked_array(mag, mag < datamin)

        if self.log:
            mag = numerix.log10(mag)
            mag = numerix.ma.masked_array(mag, numerix.isnan(mag))

        U = mag * numerix.cos(ang)
        V = mag * numerix.sin(ang)

        self._quiver.set_UVC(U, V)

        self.axes.set_xlim(xmin=self._getLimit('xmin'),
                           xmax=self._getLimit('xmax'))
        self.axes.set_ylim(ymin=self._getLimit('ymin'),
                           ymax=self._getLimit('ymax'))
예제 #25
0
    def run(self):
        MayaviDaemon._viewers.append(self)

        mlab.clf()

        self.cellsource = self.setup_source(self.cellfname)
        self.has_cell, bounds = self._examine_data(source=self.cellsource,
                                                   datatype="cell_data",
                                                   bounds=zeros((0, 6), 'l'))

        self.facesource = self.setup_source(self.facefname)
        self.has_face, bounds = self._examine_data(source=self.facesource,
                                                   datatype="point_data",
                                                   bounds=bounds)

        boundsmin = bounds.min(axis=0)
        boundsmax = bounds.max(axis=0)

        bounds = (boundsmin[0], boundsmax[1], boundsmin[2], boundsmax[3],
                  boundsmin[4], boundsmax[5])

        self.bounds = where(self.bounds == array((None, )), bounds,
                            self.bounds).astype(float)

        self.view_data()

        # Poll the lock file.
        self.timer = Timer(1000 / self.fps, self.poll_file)
예제 #26
0
    def _calcValue_(self, alpha, id1, id2):
        cell1 = take(self.var, id1)
        cell2 = take(self.var, id2)
        delta = cell1 - cell2

        eps = 1e-14
        value = where(abs(delta) < eps, 1.0 / exp(delta), 0.0)
        delta = where(abs(delta) < eps, eps, delta)
        value = where((abs(delta) > eps) & (delta < 100), delta / (exp(delta) - 1), value)

        value *= exp(cell1)

        for bc in self.bcs:
            if isinstance(bc, FixedValue):
                value[bc.faces.value] = bc._value

        return value
예제 #27
0
        def _calcValue_(self, alpha, id1, id2):
            distance = numerix.array(self.var)
            cell1 = numerix.take(distance, id1)
            cell2 = numerix.take(distance, id2)

            return numerix.where(numerix.logical_or(cell1 < 0, cell2 < 0),
                                 0,
                                 self.diffusionCoeff)
예제 #28
0
        def _calcValue(self):
            eps = self.eps 
            P = self.P.numericValue
            P = numerix.where(abs(P) < eps, eps, P)

            alpha = numerix.where(                  P > 10.,                     (P - 1.) / P,   0.5)

            tmp = (1. - P / 10.)
            tmpSqr = tmp * tmp
            alpha = numerix.where(  (10. >= P) & (P > eps), ((P-1.) + tmpSqr*tmpSqr*tmp) / P, alpha)

            tmp = (1. + P / 10.)
            tmpSqr = tmp * tmp
            alpha = numerix.where((-eps >  P) & (P >= -10.),     (tmpSqr*tmpSqr*tmp - 1.) / P, alpha)

            alpha = numerix.where(                 P < -10.,                          -1. / P, alpha)

            return PhysicalField(value = alpha)
예제 #29
0
        def _calcValue(self):
            eps = self.eps
            P = self.P.numericValue
            P = numerix.where(abs(P) < eps, eps, P)

            alpha = numerix.where(                  P > 10.,                     (P - 1.) / P,   0.5)

            tmp = (1. - P / 10.)
            tmpSqr = tmp * tmp
            alpha = numerix.where(  (10. >= P) & (P > eps),  ((P-1.) + tmpSqr*tmpSqr*tmp) / P, alpha)

            tmp = (1. + P / 10.)
            tmpSqr = tmp * tmp
            alpha = numerix.where((-eps >  P) & (P >= -10.),     (tmpSqr*tmpSqr*tmp - 1.) / P, alpha)

            alpha = numerix.where(                 P < -10.,                          -1. / P, alpha)

            return PhysicalField(value = alpha)
예제 #30
0
    def _calcValue_(self, alpha, id1, id2):
        cell1 = take(self.var,id1)
        cell2 = take(self.var,id2)
        delta = cell1 - cell2

        eps = 1e-14
        value = where(abs(delta) < eps, 1. / exp(delta), 0.)
        delta = where(abs(delta) < eps, eps, delta)
        value = where((abs(delta) > eps) & (delta < 100),
                      delta / (exp(delta) - 1), value)

        value *= exp(cell1)

        for bc in self.bcs:
            if isinstance(bc, FixedValue):
                value[bc.faces.value] = bc._value

        return value
예제 #31
0
    def _buildMatrix(self,
                     var,
                     SparseMatrix,
                     boundaryConditions=(),
                     dt=None,
                     transientGeomCoeff=None,
                     diffusionGeomCoeff=None):

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

        ##        if var.rank != 1:

        mesh = var.mesh

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

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

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

            alpha_constraint = numerix.where(var.faceGrad.constraintMask, 1.0,
                                             alpha)

            def divergence(face_value):
                return (
                    face_value * \
                    (var.faceGrad.constraintMask | var.arithmeticFaceValue.constraintMask) * \
                    self.coeff * mesh.exteriorFaces
                ).divergence * mesh.cellVolumes

            self.constraintL = divergence(alpha_constraint)
            dvar = (var.faceGrad * mesh._cellDistances *
                    mesh.faceNormals).sum(axis=0)
            self.constraintB = divergence(
                (alpha_constraint - 1) * var.arithmeticFaceValue +
                (alpha - 1) * dvar * var.faceGrad.constraintMask)

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

        return (var, L, b)
예제 #32
0
    def run(self):
        MayaviDaemon._viewers.append(self)
        
        mlab.clf()

        bounds = zeros((0, 6), 'l')
        
        self.cellsource = self.setup_source(self.cellfname)
        if self.cellsource is not None:
            tmp = [out.cell_data.scalars for out in self.cellsource.outputs \
                   if out.cell_data.scalars is not None]
            self.has_cell_scalars = (len(tmp) > 0)
            tmp = [out.cell_data.vectors for out in self.cellsource.outputs \
                   if out.cell_data.vectors is not None]
            self.has_cell_vectors = (len(tmp) > 0)
            tmp = [out.cell_data.tensors for out in self.cellsource.outputs \
                   if out.cell_data.tensors is not None]
            self.has_cell_tensors = (len(tmp) > 0)

            bounds = concatenate((bounds, 
                                  [out.bounds for out in self.cellsource.outputs]),
                                 axis=0)


        self.facesource = self.setup_source(self.facefname)
        if self.facesource is not None:
            tmp = [out.point_data.scalars for out in self.facesource.outputs \
                   if out.point_data.scalars is not None]
            self.has_face_scalars = (len(tmp) > 0)
            tmp = [out.point_data.vectors for out in self.facesource.outputs \
                   if out.point_data.vectors is not None]
            self.has_face_vectors = (len(tmp) > 0)
            tmp = [out.point_data.tensors for out in self.facesource.outputs \
                   if out.point_data.tensors is not None]
            self.has_face_tensors = (len(tmp) > 0)
            
            bounds = concatenate((bounds, 
                                  [out.bounds for out in self.facesource.outputs]),
                                 axis=0)
                                 
        boundsmin = bounds.min(axis=0)
        boundsmax = bounds.max(axis=0)
        
        bounds = (boundsmin[0], boundsmax[1], 
                  boundsmin[2], boundsmax[3], 
                  boundsmin[4], boundsmax[5])

        self.bounds = where(self.bounds == array((None,)),
                            bounds, 
                            self.bounds).astype(float)

        self.view_data()

        # Poll the lock file.
        self.timer = Timer(1000 / self.fps, self.poll_file)
예제 #33
0
    def run(self):
        MayaviDaemon._viewers.append(self)
        
        mlab.clf()

        bounds = zeros((0, 6), 'l')
        
        self.cellsource = self.setup_source(self.cellfname)
        if self.cellsource is not None:
            tmp = [out.cell_data.scalars for out in self.cellsource.outputs \
                   if out.cell_data.scalars is not None]
            self.has_cell_scalars = (len(tmp) > 0)
            tmp = [out.cell_data.vectors for out in self.cellsource.outputs \
                   if out.cell_data.vectors is not None]
            self.has_cell_vectors = (len(tmp) > 0)
            tmp = [out.cell_data.tensors for out in self.cellsource.outputs \
                   if out.cell_data.tensors is not None]
            self.has_cell_tensors = (len(tmp) > 0)

            bounds = concatenate((bounds, 
                                  [out.bounds for out in self.cellsource.outputs]),
                                 axis=0)


        self.facesource = self.setup_source(self.facefname)
        if self.facesource is not None:
            tmp = [out.point_data.scalars for out in self.facesource.outputs \
                   if out.point_data.scalars is not None]
            self.has_face_scalars = (len(tmp) > 0)
            tmp = [out.point_data.vectors for out in self.facesource.outputs \
                   if out.point_data.vectors is not None]
            self.has_face_vectors = (len(tmp) > 0)
            tmp = [out.point_data.tensors for out in self.facesource.outputs \
                   if out.point_data.tensors is not None]
            self.has_face_tensors = (len(tmp) > 0)
            
            bounds = concatenate((bounds, 
                                  [out.bounds for out in self.facesource.outputs]),
                                 axis=0)
                                 
        boundsmin = bounds.min(axis=0)
        boundsmax = bounds.max(axis=0)
        
        bounds = (boundsmin[0], boundsmax[1], 
                  boundsmin[2], boundsmax[3], 
                  boundsmin[4], boundsmax[5])

        self.bounds = where(self.bounds == array((None,)),
                            bounds, 
                            self.bounds).astype(float)

        self.view_data()

        # Poll the lock file.
        self.timer = Timer(1000 / self.fps, self.poll_file)
예제 #34
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.
예제 #35
0
파일: mesh.py 프로젝트: xinxinboss/fipy
    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
예제 #36
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.
예제 #37
0
    def _getDiagonalSign(self, transientGeomCoeff=None, diffusionGeomCoeff=None):
        if transientGeomCoeff is not None and diffusionGeomCoeff is not None:
            diagonalSign = numerix.where(numerix.array(numerix.all(transientGeomCoeff == 0, axis=-1)),
                                         numerix.array(2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1),
                                         numerix.array(2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1))
        elif transientGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(transientGeomCoeff >= 0, axis=-1) - 1
        elif diffusionGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1
        else:
            diagonalSign = 1

        return diagonalSign
예제 #38
0
파일: variable.py 프로젝트: regmi/fipy
    def setValue(self, value, unit=None, where=None):
        """
        Set the value of the Variable. Can take a masked array.

            >>> a = Variable((1,2,3))
            >>> a.setValue(5, where=(1, 0, 1))
            >>> print a
            [5 2 5]

            >>> b = Variable((4,5,6))
            >>> a.setValue(b, where=(1, 0, 1))
            >>> print a
            [4 2 6]
            >>> print b
            [4 5 6]
            >>> a.setValue(3)
            >>> print a
            [3 3 3]

            >>> b = numerix.array((3,4,5))
            >>> a.setValue(b)
            >>> a[:] = 1
            >>> print b
            [3 4 5]

            >>> a.setValue((4,5,6), where=(1, 0))
            Traceback (most recent call last):
                ....
            ValueError: shape mismatch: objects cannot be broadcast to a single shape
            
        """
        if where is not None:
            tmp = numerix.empty(numerix.getShape(where), self.getsctype())
            tmp[:] = value
            tmp = numerix.where(where, tmp, self.getValue())
        else:
            if hasattr(value, 'copy'):
                tmp = value.copy()
            else:
                tmp = value

        value = self._makeValue(value=tmp, unit=unit, array=None)

        if numerix.getShape(self.value) == ():
            self.value.itemset(value)
        else:
            self.value[:] = value
            
        self._markFresh()
예제 #39
0
    def _calcValue(self):
        """

        Test case added because `and` was being used instead of bitwise `&`.

            >>> from fipy.meshes import Grid1D
            >>> mesh = Grid1D(nx = 3)
            >>> from fipy.variables.faceVariable import FaceVariable
            >>> P = FaceVariable(mesh = mesh, value = (1e-3, 1e+71, 1e-3, 1e-3))
            >>> alpha = ExponentialConvectionTerm([1])._alpha(P)
            >>> print(alpha)
            [ 0.5  1.   0.5  0.5]

        """
        eps = 1e-3
        largeValue = 101.0
        P  = self.P.numericValue

        P = numerix.where(abs(P) < eps, eps, P)
        alpha = numerix.where(P > largeValue, (P - 1) / P, 0.5)
        Pmin = numerix.where(P > largeValue + 1, largeValue + 1, P)
        alpha = numerix.where((abs(Pmin) > eps) & (Pmin <= largeValue), ((Pmin - 1) * numerix.exp(Pmin) + 1) / (Pmin * (numerix.exp(Pmin) - 1)), alpha)

        return alpha
예제 #40
0
파일: mesh.py 프로젝트: xinxinboss/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)
     return numerix.sqrtDot(cross, cross) / 2.
예제 #41
0
파일: mesh2D.py 프로젝트: regmi/fipy
   def _getNonOrthogonality(self):
       
       exteriorFaceArray = numerix.zeros((self.faceCellIDs.shape[1],))
       numerix.put(exteriorFaceArray, numerix.nonzero(self.getExteriorFaces()), 1)
       unmaskedFaceCellIDs = MA.filled(self.faceCellIDs, 0) ## what we put in for the "fill" doesn't matter because only exterior faces have anything masked, and exterior faces have their displacement vectors set to zero.
       ## if it's an exterior face, make the "displacement vector" equal to zero so the cross product will be zero.
   
       faceDisplacementVectors = numerix.where(numerix.array(zip(exteriorFaceArray, exteriorFaceArray)), 0.0, numerix.take(self._getCellCenters().swapaxes(0,1), unmaskedFaceCellIDs[1, :]) - numerix.take(self._getCellCenters().swapaxes(0,1), unmaskedFaceCellIDs[0, :])).swapaxes(0,1)
       faceCrossProducts = (faceDisplacementVectors[0, :] * self.faceNormals[1, :]) - (faceDisplacementVectors[1, :] * self.faceNormals[0, :])
       faceDisplacementVectorLengths = numerix.maximum(((faceDisplacementVectors[0, :] ** 2) + (faceDisplacementVectors[1, :] ** 2)) ** 0.5, 1.e-100)
       faceWeightedNonOrthogonalities = abs(faceCrossProducts / faceDisplacementVectorLengths) * self.faceAreas
       cellFaceWeightedNonOrthogonalities = numerix.take(faceWeightedNonOrthogonalities, self.cellFaceIDs)
       cellFaceAreas = numerix.take(self.faceAreas, self.cellFaceIDs)
       cellTotalWeightedValues = numerix.add.reduce(cellFaceWeightedNonOrthogonalities, axis = 0)  
       cellTotalFaceAreas = numerix.add.reduce(cellFaceAreas, axis = 0)
 
       return (cellTotalWeightedValues / cellTotalFaceAreas)
예제 #42
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)
예제 #43
0
    def _nonOrthogonality(self):

        exteriorFaceArray = numerix.zeros((self.faceCellIDs.shape[1], ), 'l')
        numerix.put(exteriorFaceArray, numerix.nonzero(self.exteriorFaces), 1)
        unmaskedFaceCellIDs = MA.filled(self.faceCellIDs, 0)
        # what we put in for the "fill" doesn't matter because only exterior
        # faces have anything masked, and exterior faces have their displacement
        # vectors set to zero.
        #
        # if it's an exterior face, make the "displacement vector" equal to zero
        # so the cross product will be zero.

        faceDisplacementVectors = \
          numerix.where(numerix.array(zip(exteriorFaceArray, exteriorFaceArray)),
                        0.0,
                        numerix.take(self._scaledCellCenters.swapaxes(0,1),
                                     unmaskedFaceCellIDs[1, :]) \
                          - numerix.take(self._scaledCellCenters.swapaxes(0,1),
                        unmaskedFaceCellIDs[0, :]))

        faceDisplacementVectors = faceDisplacementVectors.swapaxes(0, 1)

        faceCrossProducts = (faceDisplacementVectors[0, :] * self.faceNormals[1,:]) \
          - (faceDisplacementVectors[1, :] * self.faceNormals[0, :])

        faceDisplacementVectorLengths = numerix.maximum(((faceDisplacementVectors[0, :] ** 2) \
          + (faceDisplacementVectors[1, :] ** 2)) ** 0.5, 1.e-100)

        faceWeightedNonOrthogonalities = abs(
            faceCrossProducts /
            faceDisplacementVectorLengths) * self._faceAreas

        cellFaceWeightedNonOrthogonalities = numerix.take(
            faceWeightedNonOrthogonalities, self.cellFaceIDs)

        cellFaceAreas = numerix.take(self._faceAreas, self.cellFaceIDs)
        cellTotalWeightedValues = numerix.add.reduce(
            cellFaceWeightedNonOrthogonalities, axis=0)
        cellTotalFaceAreas = numerix.add.reduce(cellFaceAreas, axis=0)

        return (cellTotalWeightedValues / cellTotalFaceAreas)
예제 #44
0
    def _getDiagonalSign(self,
                         transientGeomCoeff=None,
                         diffusionGeomCoeff=None):
        if transientGeomCoeff is not None and diffusionGeomCoeff is not None:
            diagonalSign = numerix.where(
                numerix.array(numerix.all(transientGeomCoeff == 0, axis=-1)),
                numerix.array(
                    2 * numerix.all(diffusionGeomCoeff[0] <= 0, axis=-1) - 1),
                numerix.array(2 *
                              numerix.all(transientGeomCoeff >= 0, axis=-1) -
                              1))
        elif transientGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(transientGeomCoeff >= 0,
                                           axis=-1) - 1
        elif diffusionGeomCoeff is not None:
            diagonalSign = 2 * numerix.all(diffusionGeomCoeff[0] <= 0,
                                           axis=-1) - 1
        else:
            diagonalSign = 1

        return diagonalSign
예제 #45
0
    def _interfaceFlag(self):
        """

        Returns 1 for faces on boundary and 0 otherwise.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.faceVariable import FaceVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> answer = FaceVariable(mesh=mesh,
           ...                       value=(0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0))
           >>> print numerix.allclose(distanceVariable._interfaceFlag, answer)
           True
           
        """
        adjacentCellIDs = self.mesh._adjacentCellIDs
        val0 = numerix.take(numerix.array(self._value), adjacentCellIDs[0])
        val1 = numerix.take(numerix.array(self._value), adjacentCellIDs[1])
        
        return numerix.where(val1 * val0 < 0, 1, 0)
예제 #46
0
    def _interfaceFlag(self):
        """

        Returns 1 for faces on boundary and 0 otherwise.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.faceVariable import FaceVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> answer = FaceVariable(mesh=mesh,
           ...                       value=(0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0))
           >>> print numerix.allclose(distanceVariable._interfaceFlag, answer)
           True
           
        """
        adjacentCellIDs = self.mesh._adjacentCellIDs
        val0 = numerix.take(numerix.array(self._value), adjacentCellIDs[0])
        val1 = numerix.take(numerix.array(self._value), adjacentCellIDs[1])

        return numerix.where(val1 * val0 < 0, 1, 0)
예제 #47
0
    def _interfaceNormals(self):
        """

        Returns the normals on the boundary faces only, the other are set to zero.

           >>> from fipy.meshes import Grid2D
           >>> from fipy.variables.faceVariable import FaceVariable
           >>> mesh = Grid2D(dx = .5, dy = .5, nx = 2, ny = 2)
           >>> distanceVariable = DistanceVariable(mesh = mesh, 
           ...                                     value = (-0.5, 0.5, 0.5, 1.5))
           >>> v = 1 / numerix.sqrt(2)
           >>> answer = FaceVariable(mesh=mesh,
           ...                       value=((0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0),
           ...                              (0, 0, v, 0, 0, 0, 0, v, 0, 0, 0, 0)))
           >>> print numerix.allclose(distanceVariable._interfaceNormals, answer)
           True
           
        """
        
        M = self.mesh.dim
        interfaceFlag = numerix.repeat(self._interfaceFlag[numerix.newaxis, ...], M, axis=0)
        return numerix.where(interfaceFlag, self._levelSetNormals, 0)
예제 #48
0
파일: gapFillMesh.py 프로젝트: regmi/fipy
    def getElectrolyteMask(self):
        x, y = self.getCellCenters()
        
        Y = (y - (self.heightBelowTrench + self.trenchDepth / 2))

        ## taper
        taper = numerix.tan(self.angle) * Y

        ## bow
        if abs(self.bowWidth) > 1e-12 and (-self.trenchDepth / 2 < Y < self.trenchDepth / 2):
            param1 = self.trenchDepth**2 / 8 / self.bowWidth
            param2 = self.bowWidth / 2
            bow = -numerix.sqrt((param1 + param2)**2 - Y**2) + param1 - param2
        else:
            bow = 0

        ## over hang
        Y = y - (self.heightBelowTrench + self.trenchDepth - self.overBumpRadius)

        overBump = 0

        if self.overBumpRadius > 1e-12:            
            overBump += numerix.where(Y > -self.overBumpRadius,
                                      self.overBumpWidth / 2 * (1 + numerix.cos(Y * numerix.pi / self.overBumpRadius)),
                                      0)

        tmp = self.overBumpRadius**2 - Y**2
        tmp = (tmp > 0) * tmp
        overBump += numerix.where((Y > -self.overBumpRadius) & (Y > 0),
                                  numerix.where(Y > self.overBumpRadius,
                                                -self.overBumpRadius,
                                                -(self.overBumpRadius - numerix.sqrt(tmp))),
                                  0)

        return numerix.where(y > self.trenchDepth + self.heightBelowTrench,
                             1,
                             numerix.where(y < self.heightBelowTrench,
                                           0,
                                           numerix.where(x > self.trenchWidth / 2 + taper - bow - overBump,
                                                         0,
                                                         1)))
예제 #49
0
        timeStepDuration = cfl * dx / velocity
        distanceVariable.updateOld()
        distanceVariable.setValue(numerix.array(distanceVariable) - velocity * timeStepDuration)
        surfactantEquation.solve(surfactantVariable)
        
        totalTime += timeStepDuration
        
        distanceViewer.plot()
        surfactantViewer.plot()
        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]
예제 #50
0
    def _plot(self):
        from scipy.interpolate import griddata

        var = self.vars[0]
        mesh = var.mesh

        xmin, ymin = mesh.extents['min']
        xmax, ymax = mesh.extents['max']

        N = 100
        X = numerix.linspace(xmin, xmax, N)
        Y = numerix.linspace(ymin, ymax, N)

        grid_x, grid_y = numerix.mgrid[xmin:xmax:N * 1j, ymin:ymax:N * 1j]

        if isinstance(var, FaceVariable):
            C = mesh.faceCenters
        elif isinstance(var, CellVariable):
            C = mesh.cellCenters

        U = griddata(C.value.T, var.value[0], (grid_x, grid_y), method='cubic')
        V = griddata(C.value.T, var.value[1], (grid_x, grid_y), method='cubic')

        lw = self.linewidth
        if isinstance(lw, (FaceVariable, CellVariable)):
            lw = griddata(C.value.T,
                          lw.value, (grid_x, grid_y),
                          method='cubic')

        color = self.color
        if isinstance(color, (FaceVariable, CellVariable)):
            color = griddata(C.value.T,
                             color.value, (grid_x, grid_y),
                             method='cubic',
                             fill_value=color.min())

        U = U.T
        V = V.T

        ang = numerix.arctan2(V, U)
        mag = numerix.sqrt(U**2 + V**2)

        datamin, datamax = self._autoscale(vars=(mag, ),
                                           datamin=self._getLimit('datamin'),
                                           datamax=self._getLimit('datamax'))

        mag = numerix.where(mag > datamax, numerix.nan, mag)
        mag = numerix.where(mag < datamin, numerix.nan, mag)

        if self.log:
            mag = numerix.log10(mag)

        U = mag * numerix.cos(ang)
        V = mag * numerix.sin(ang)

        #         if self._stream is not None:
        #             # the following doesn't work, nor does it help to `add_collection` first
        #             # self._stream.arrows.remove()
        #             self._stream.lines.remove()

        self.axes.cla()
        self._stream = self.axes.streamplot(X,
                                            Y,
                                            U,
                                            V,
                                            linewidth=lw,
                                            color=color,
                                            **self.kwargs)

        self.axes.set_xlim(xmin=self._getLimit('xmin'),
                           xmax=self._getLimit('xmax'))
        self.axes.set_ylim(ymin=self._getLimit('ymin'),
                           ymax=self._getLimit('ymax'))
예제 #51
0
파일: inputLeveler.py 프로젝트: ghorn/Eg
def runLeveler(kLeveler=0.018,
               bulkLevelerConcentration=0.02,
               cellSize=0.1e-7,
               rateConstant=0.00026,
               initialAcceleratorCoverage=0.0,
               levelerDiffusionCoefficient=5e-10,
               numberOfSteps=400,
               displayRate=10,
               displayViewers=True):

    kLevelerConsumption = 0.0005
    aspectRatio = 1.5
    faradaysConstant = 9.6485e4
    gasConstant = 8.314
    acceleratorDiffusionCoefficient = 4e-10
    siteDensity = 6.35e-6
    atomicVolume = 7.1e-6
    charge = 2
    metalDiffusionCoefficient = 4e-10
    temperature = 298.
    overpotential = -0.25
    bulkMetalConcentration = 250.
    bulkAcceleratorConcentration = 50.0e-3
    initialLevelerCoverage = 0.
    cflNumber = 0.2
    numberOfCellsInNarrowBand = 20
    cellsBelowTrench = 10
    trenchDepth = 0.4e-6
    trenchSpacing = 0.6e-6
    boundaryLayerDepth = 98.7e-6
    i0Suppressor = 0.3
    i0Accelerator = 22.5
    alphaSuppressor = 0.5
    alphaAccelerator = 0.4
    alphaAdsorption = 0.62
    m = 4
    b = 2.65
    A = 0.3
    Ba = -40
    Bb = 60
    Vd = 0.098
    Bd = 0.0008

    etaPrime = faradaysConstant * overpotential / gasConstant / temperature

    from fipy import TrenchMesh
    from fipy.tools import numerix
    mesh = TrenchMesh(cellSize=cellSize,
                      trenchSpacing=trenchSpacing,
                      trenchDepth=trenchDepth,
                      boundaryLayerDepth=boundaryLayerDepth,
                      aspectRatio=aspectRatio,
                      angle=numerix.pi * 4. / 180.,
                      bowWidth=0.,
                      overBumpRadius=0.,
                      overBumpWidth=0.)

    narrowBandWidth = numberOfCellsInNarrowBand * cellSize
    from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable
    distanceVar = DistanceVariable(name='distance variable',
                                   mesh=mesh,
                                   value=-1,
                                   narrowBandWidth=narrowBandWidth)

    distanceVar.setValue(1, where=mesh.getElectrolyteMask())

    distanceVar.calcDistanceFunction(narrowBandWidth=1e10)
    from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable
    levelerVar = SurfactantVariable(name="leveler variable",
                                    value=initialLevelerCoverage,
                                    distanceVar=distanceVar)

    acceleratorVar = SurfactantVariable(name="accelerator variable",
                                        value=initialAcceleratorCoverage,
                                        distanceVar=distanceVar)

    from fipy.variables.cellVariable import CellVariable
    bulkAcceleratorVar = CellVariable(name='bulk accelerator variable',
                                      mesh=mesh,
                                      value=bulkAcceleratorConcentration)

    bulkLevelerVar = CellVariable(name='bulk leveler variable',
                                  mesh=mesh,
                                  value=bulkLevelerConcentration)

    metalVar = CellVariable(name='metal variable',
                            mesh=mesh,
                            value=bulkMetalConcentration)

    def depositionCoeff(alpha, i0):
        expo = numerix.exp(-alpha * etaPrime)
        return 2 * i0 * (expo - expo * numerix.exp(etaPrime))

    coeffSuppressor = depositionCoeff(alphaSuppressor, i0Suppressor)
    coeffAccelerator = depositionCoeff(alphaAccelerator, i0Accelerator)

    exchangeCurrentDensity = acceleratorVar.getInterfaceVar() * (
        coeffAccelerator - coeffSuppressor) + coeffSuppressor

    currentDensity = metalVar / bulkMetalConcentration * exchangeCurrentDensity

    depositionRateVariable = currentDensity * atomicVolume / charge / faradaysConstant

    extensionVelocityVariable = CellVariable(name='extension velocity',
                                             mesh=mesh,
                                             value=depositionRateVariable)

    from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \
             import AdsorbingSurfactantEquation

    kAccelerator = rateConstant * numerix.exp(-alphaAdsorption * etaPrime)
    kAcceleratorConsumption = Bd + A / (numerix.exp(Ba *
                                                    (overpotential + Vd)) +
                                        numerix.exp(Bb * (overpotential + Vd)))
    q = m * overpotential + b

    levelerSurfactantEquation = AdsorbingSurfactantEquation(
        levelerVar,
        distanceVar=distanceVar,
        bulkVar=bulkLevelerVar,
        rateConstant=kLeveler,
        consumptionCoeff=kLevelerConsumption * depositionRateVariable)

    accVar1 = acceleratorVar.getInterfaceVar()
    accVar2 = (accVar1 > 0) * accVar1
    accConsumptionCoeff = kAcceleratorConsumption * (accVar2**(q - 1))

    acceleratorSurfactantEquation = AdsorbingSurfactantEquation(
        acceleratorVar,
        distanceVar=distanceVar,
        bulkVar=bulkAcceleratorVar,
        rateConstant=kAccelerator,
        otherVar=levelerVar,
        otherBulkVar=bulkLevelerVar,
        otherRateConstant=kLeveler,
        consumptionCoeff=accConsumptionCoeff)

    from fipy.models.levelSet.advection.higherOrderAdvectionEquation \
         import buildHigherOrderAdvectionEquation

    advectionEquation = buildHigherOrderAdvectionEquation(
        advectionCoeff=extensionVelocityVariable)

    from fipy.boundaryConditions.fixedValue import FixedValue
    from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \
         import buildMetalIonDiffusionEquation

    metalEquation = buildMetalIonDiffusionEquation(
        ionVar=metalVar,
        distanceVar=distanceVar,
        depositionRate=depositionRateVariable,
        diffusionCoeff=metalDiffusionCoefficient,
        metalIonMolarVolume=atomicVolume)

    metalEquationBCs = FixedValue(mesh.getTopFaces(), bulkMetalConcentration)

    from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \
         import buildSurfactantBulkDiffusionEquation

    bulkAcceleratorEquation = buildSurfactantBulkDiffusionEquation(
        bulkVar=bulkAcceleratorVar,
        distanceVar=distanceVar,
        surfactantVar=acceleratorVar,
        otherSurfactantVar=levelerVar,
        diffusionCoeff=acceleratorDiffusionCoefficient,
        rateConstant=kAccelerator * siteDensity)

    bulkAcceleratorEquationBCs = (FixedValue(mesh.getTopFaces(),
                                             bulkAcceleratorConcentration), )

    bulkLevelerEquation = buildSurfactantBulkDiffusionEquation(
        bulkVar=bulkLevelerVar,
        distanceVar=distanceVar,
        surfactantVar=levelerVar,
        diffusionCoeff=levelerDiffusionCoefficient,
        rateConstant=kLeveler * siteDensity)

    bulkLevelerEquationBCs = (FixedValue(mesh.getTopFaces(),
                                         bulkLevelerConcentration), )

    eqnTuple = ((advectionEquation, distanceVar,
                 ()), (levelerSurfactantEquation, levelerVar,
                       ()), (acceleratorSurfactantEquation, acceleratorVar,
                             ()), (metalEquation, metalVar, metalEquationBCs),
                (bulkAcceleratorEquation, bulkAcceleratorVar,
                 bulkAcceleratorEquationBCs),
                (bulkLevelerEquation, bulkLevelerVar, bulkLevelerEquationBCs))

    levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize /
                                  cflNumber / 2)

    totalTime = 0.0

    if displayViewers:
        from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer
        viewers = (MayaviSurfactantViewer(distanceVar,
                                          acceleratorVar.getInterfaceVar(),
                                          zoomFactor=1e6,
                                          limits={
                                              'datamax': 0.5,
                                              'datamin': 0.0
                                          },
                                          smooth=1,
                                          title='accelerator coverage'),
                   MayaviSurfactantViewer(distanceVar,
                                          levelerVar.getInterfaceVar(),
                                          zoomFactor=1e6,
                                          limits={
                                              'datamax': 0.5,
                                              'datamin': 0.0
                                          },
                                          smooth=1,
                                          title='leveler coverage'))

    for step in range(numberOfSteps):

        if displayViewers:
            if step % displayRate == 0:
                for viewer in viewers:
                    viewer.plot()

        if step % levelSetUpdateFrequency == 0:
            distanceVar.calcDistanceFunction(deleteIslands=True)

        extensionVelocityVariable.setValue(depositionRateVariable)

        extOnInt = numerix.where(
            distanceVar > 0,
            numerix.where(distanceVar < 2 * cellSize,
                          extensionVelocityVariable, 0), 0)

        dt = cflNumber * cellSize / numerix.max(extOnInt)

        id = numerix.max(numerix.nonzero(distanceVar._getInterfaceFlag()))
        distanceVar.extendVariable(extensionVelocityVariable,
                                   deleteIslands=True)

        extensionVelocityVariable[mesh.getFineMesh().getNumberOfCells():] = 0.

        for eqn, var, BCs in eqnTuple:
            var.updateOld()

        for eqn, var, BCs in eqnTuple:
            eqn.solve(var, boundaryConditions=BCs, dt=dt)

        totalTime += dt

    try:
        testFile = 'testLeveler.gz'
        import os
        import examples.levelSet.electroChem
        from fipy.tools import dump
        data = dump.read(
            os.path.join(examples.levelSet.electroChem.__path__[0], testFile))
        N = mesh.getFineMesh().getNumberOfCells()
        print numerix.allclose(data[:N], levelerVar[:N], rtol=1e-3)
    except:
        return 0
예제 #52
0
    def _getStructure(self):

        ##maxX = self.distanceVar.mesh.faceCenters[0].max()
        ##minX = self.distanceVar.mesh.faceCenters[0].min()

        IDs = numerix.nonzero(self.distanceVar._cellInterfaceFlag)[0]
        coordinates = numerix.take(numerix.array(self.distanceVar.mesh.cellCenters).swapaxes(0, 1), IDs)

        coordinates -= numerix.take(numerix.array(self.distanceVar.grad * self.distanceVar).swapaxes(0, 1), IDs)

        coordinates *= self.zoomFactor

        shiftedCoords = coordinates.copy()
        shiftedCoords[:, 0] = -coordinates[:, 0] ##+ (maxX - minX)
        coordinates = numerix.concatenate((coordinates, shiftedCoords))

        from .lines import _getOrderedLines

        lines = _getOrderedLines(list(range(2 * len(IDs))), coordinates, thresholdDistance = self.distanceVar.mesh._cellDistances.min() * 10)

        data = numerix.take(self.surfactantVar, IDs)

        data = numerix.concatenate((data, data))

        tmpIDs = numerix.nonzero(data > 0.0001)[0]
        if len(tmpIDs) > 0:
            val = numerix.take(data, tmpIDs).min()
        else:
            val = 0.0001

        data = numerix.where(data < 0.0001,
                             val,
                             data)

        for line in lines:
            if len(line) > 2:
                for smooth in range(self.smooth):
                    for arr in (coordinates, data):
                        tmp = numerix.take(arr, line)
                        tmp[1:-1] = tmp[2:] * 0.25 + tmp[:-2] * 0.25 + tmp[1:-1] * 0.5
                        if len(arr.shape) > 1:
                            for i in range(len(arr[0])):
                                arrI = arr[:, i].copy()
                                numerix.put(arrI, line, tmp[:, i])
                                arr[:, i] = arrI
                        else:
                            numerix.put(arrI, line, tmp)

        name = self.title
        name = name.strip()
        if name == '':
            name = None

        coords = numerix.zeros((coordinates.shape[0], 3), 'd')
        coords[:, :coordinates.shape[1]] = coordinates

        import pyvtk

        ## making lists as pyvtk doesn't know what to do with numpy arrays

        coords = list(coords)
        coords = [[float(coord[0]), float(coord[1]), float(coord[2])] for coord in coords]

        data = list(data)
        data = [float(item) for item in data]

        return (pyvtk.UnstructuredGrid(points = coords,
                                       poly_line = lines),
                pyvtk.PointData(pyvtk.Scalars(data, name = name)))
        def logs_to_signed(v, plus, minus):
            v = numerix.where(v > 0, plus, -minus)
            v = numerix.where(numerix.isnan(v), 0., v)

            return v
 def signed_to_logs(v):
     return (numerix.where(v > 0, numerix.log10(v), numerix.nan),
             numerix.where(v < 0, numerix.log10(-v), numerix.nan))
예제 #55
0
 def _calcValue(self):
     P  = self.P.numericValue
     alpha = numerix.where(P > 0., 1., 0.)
     return PhysicalField(value=alpha)
예제 #56
0
파일: input.py 프로젝트: ghorn/Eg
nx = 50

valueLeft = 0.
fluxRight = 1.
timeStepDuration = 1. 

L = 1.

dx = L / nx

mesh = Grid1D(dx = dx, nx = nx)
    
var = CellVariable(
    name = "solution variable",
    mesh = mesh,
    value = valueLeft)

x = mesh.getFaceCenters()[:,0]
middleFaces = numerix.logical_or(x < L / 4.,x >= 3. * L / 4.)
diffCoeff = numerix.where(middleFaces, 1., 0.1)

boundaryConditions=(FixedValue(mesh.getFacesLeft(),valueLeft),
                    FixedFlux(mesh.getFacesRight(),fluxRight))

if __name__ == '__main__':
    import fipy.viewers
    viewer = fipy.viewers.make(vars = var, limits = {'datamax': L + 18. * L / 4.})
    viewer.plot()
    raw_input('finished')
예제 #57
0
 def _calcValue(self):
     areas = numerix.array(
         self.surfactantVar.distanceVar.cellInterfaceAreas)
     areas = numerix.where(areas > 1e-20, areas, 1)
     return numerix.array(
         self.surfactantVar) * self.mesh.cellVolumes / areas
예제 #58
0
 def _calcValue(self):
     P = self.P.numericValue
     alpha = numerix.where(P > 0., 1., 0.)
     return PhysicalField(value=alpha)