Пример #1
0
    def _calcGeomCoeff(self, var):

        mesh = var.mesh
        if self.nthCoeff is not None:

            coeff = self.nthCoeff

            shape = numerix.getShape(coeff)

            if isinstance(coeff, FaceVariable):
                rank = coeff.rank
            else:
                rank = len(shape)

            if var.rank == 0:
                anisotropicRank = rank
            elif var.rank == 1:
                anisotropicRank = rank - 2
            else:
                raise IndexError('the solution variable has the wrong rank')

            if anisotropicRank == 0 and self._treatMeshAsOrthogonal(mesh):

                if coeff.shape != () and not isinstance(coeff, FaceVariable):
                    coeff = coeff[..., numerix.newaxis]

                tmpBop = (coeff *
                          FaceVariable(mesh=mesh, value=mesh._faceAreas) /
                          mesh._cellDistances)[numerix.newaxis, :]

            else:

                if anisotropicRank == 1 or anisotropicRank == 0:
                    coeff = coeff * numerix.identity(mesh.dim)

                if anisotropicRank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.dim != shape[0] or mesh.dim != shape[1]:
                        raise IndexError(
                            'diffusion coefficient tensor is not an appropriate shape for this mesh'
                        )

                faceNormals = FaceVariable(mesh=mesh,
                                           rank=1,
                                           value=mesh.faceNormals)
                rotationTensor = self.__getRotationTensor(mesh)
                rotationTensor[:,
                               0] = rotationTensor[:, 0] / mesh._cellDistances

                tmpBop = faceNormals.dot(coeff).dot(
                    rotationTensor) * mesh._faceAreas

            return tmpBop

        else:

            return None
Пример #2
0
    def _calcGeomCoeff(self, var):

        mesh = var.mesh
        if self.nthCoeff is not None:
          
            coeff = self.nthCoeff

            shape = numerix.getShape(coeff)

            if isinstance(coeff, FaceVariable):
                rank = coeff.rank
            else:
                rank = len(shape)

            if var.rank == 0:
                anisotropicRank = rank
            elif var.rank == 1:
                anisotropicRank = rank - 2
            else:
                raise IndexError, 'the solution variable has the wrong rank'
                
            if anisotropicRank == 0 and self._treatMeshAsOrthogonal(mesh):
                
                if coeff.shape != () and not isinstance(coeff, FaceVariable):
                    coeff = coeff[...,numerix.newaxis]

                tmpBop = (coeff * FaceVariable(mesh=mesh, value=mesh._faceAreas) / mesh._cellDistances)[numerix.newaxis, :]

            else:

                if anisotropicRank == 1 or anisotropicRank == 0:
                    coeff = coeff * numerix.identity(mesh.dim)
                
                if anisotropicRank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.dim != shape[0] or mesh.dim != shape[1]:
                        raise IndexError, 'diffusion coefficent tensor is not an appropriate shape for this mesh'          
                    
                faceNormals = FaceVariable(mesh=mesh, rank=1, value=mesh.faceNormals)
                rotationTensor = self.__getRotationTensor(mesh)
                rotationTensor[:,0] = rotationTensor[:,0] / mesh._cellDistances

                tmpBop = faceNormals.dot(coeff).dot(rotationTensor) * mesh._faceAreas

            return tmpBop

        else:

            return None
Пример #3
0
    def _calcGeomCoeff(self, mesh):
        if self.nthCoeff is not None:
          
            coeff = self.nthCoeff
            shape = numerix.getShape(coeff)

            from fipy.variables.faceVariable import FaceVariable
            if isinstance(coeff, FaceVariable):
                rank = coeff.getRank()
            else:
                rank = len(shape)

            if rank == 0 and self._treatMeshAsOrthogonal(mesh):
                tmpBop = (coeff * mesh._getFaceAreas() / mesh._getCellDistances())[numerix.newaxis, :]

            else:

                if rank == 1 or rank == 0:
                    coeff = coeff * numerix.identity(mesh.getDim())

                if rank > 0:
                    shape = numerix.getShape(coeff)
                    if mesh.getDim() != shape[0] or mesh.getDim() != shape[1]:
                        raise IndexError, 'diffusion coefficent tensor is not an appropriate shape for this mesh'          

                faceNormals = FaceVariable(mesh=mesh, rank=1, value=mesh._getFaceNormals())
                rotationTensor = self._getRotationTensor(mesh)
                rotationTensor[:,0] = rotationTensor[:,0] / mesh._getCellDistances()
                
                tmpBop = faceNormals.dot(coeff).dot(rotationTensor) * mesh._getFaceAreas()

            return tmpBop

        else:

            return None
Пример #4
0
    def _buildMatrix(self,
                     var,
                     SparseMatrix,
                     boundaryConditions=(),
                     dt=None,
                     transientGeomCoeff=None,
                     diffusionGeomCoeff=None):
        """
        Test to ensure that a changing coefficient influences the boundary conditions.

        >>> from fipy import *
        >>> m = Grid2D(nx=2, ny=2)
        >>> v = CellVariable(mesh=m)
        >>> c0 = Variable(1.)
        >>> v.constrain(c0, where=m.facesLeft)

        Diffusion will only be in the y-direction
        
        >>> coeff = Variable([[0. , 0.], [0. , 1.]])
        >>> eq = DiffusionTerm(coeff)
        >>> eq.solve(v, solver=DummySolver())
        >>> print v
        [ 0.  0.  0.  0.]
        
        Change the coefficient.

        >>> coeff[0, 0] = 1.
        >>> eq.solve(v)
        >>> print v
        [ 1.  1.  1.  1.]

        Change the constraints.

        >>> c0.setValue(2.)
        >>> v.constrain(3., where=m.facesRight)
        >>> print v.faceValue.constraintMask
        [False False False False False False  True False  True  True False  True]
        >>> eq.solve(v)
        >>> print v
        [ 2.25  2.75  2.25  2.75]
        
        """

        var, L, b = self.__higherOrderbuildMatrix(
            var,
            SparseMatrix,
            boundaryConditions=boundaryConditions,
            dt=dt,
            transientGeomCoeff=transientGeomCoeff,
            diffusionGeomCoeff=diffusionGeomCoeff)
        mesh = var.mesh

        if self.order == 2:

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

                normals = FaceVariable(mesh=mesh,
                                       rank=1,
                                       value=mesh._orientedFaceNormals)

                if len(var.shape) == 1 and len(self.nthCoeff.shape) > 1:
                    nthCoeffFaceGrad = var.faceGrad.dot(self.nthCoeff)
                    normalsNthCoeff = normals.dot(self.nthCoeff)
                else:

                    if self.nthCoeff.shape != () and not isinstance(
                            self.nthCoeff, FaceVariable):
                        coeff = self.nthCoeff[..., numerix.newaxis]
                    else:
                        coeff = self.nthCoeff

                    nthCoeffFaceGrad = coeff[
                        numerix.newaxis] * var.faceGrad[:, numerix.newaxis]
                    s = (slice(0, None, None), ) + (numerix.newaxis, ) * (
                        len(coeff.shape) - 1) + (slice(0, None, None), )
                    normalsNthCoeff = coeff[numerix.newaxis] * normals[s]

                self.constraintB = -(
                    var.faceGrad.constraintMask *
                    nthCoeffFaceGrad).divergence * mesh.cellVolumes

                constrainedNormalsDotCoeffOverdAP = var.arithmeticFaceValue.constraintMask * \
                                                    normalsNthCoeff / mesh._cellDistances

                self.constraintB -= (
                    constrainedNormalsDotCoeffOverdAP *
                    var.arithmeticFaceValue).divergence * mesh.cellVolumes

                ids = self._reshapeIDs(var, numerix.arange(mesh.numberOfCells))

                self.constraintL = -constrainedNormalsDotCoeffOverdAP.divergence * mesh.cellVolumes

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

        return (var, L, b)
Пример #5
0
    def _buildMatrix(self, var, SparseMatrix, boundaryConditions=(), dt=None, transientGeomCoeff=None, diffusionGeomCoeff=None):
        """
        Test to ensure that a changing coefficient influences the boundary conditions.

        >>> from fipy import *
        >>> m = Grid2D(nx=2, ny=2)
        >>> v = CellVariable(mesh=m)
        >>> c0 = Variable(1.)
        >>> v.constrain(c0, where=m.facesLeft)

        Diffusion will only be in the y-direction
        
        >>> coeff = Variable([[0. , 0.], [0. , 1.]])
        >>> eq = DiffusionTerm(coeff)
        >>> eq.solve(v, solver=DummySolver())
        >>> print v
        [ 0.  0.  0.  0.]
        
        Change the coefficient.

        >>> coeff[0, 0] = 1.
        >>> eq.solve(v)
        >>> print v
        [ 1.  1.  1.  1.]

        Change the constraints.

        >>> c0.setValue(2.)
        >>> v.constrain(3., where=m.facesRight)
        >>> print v.faceValue.constraintMask
        [False False False False False False  True False  True  True False  True]
        >>> eq.solve(v)
        >>> print v
        [ 2.25  2.75  2.25  2.75]
        
        """

        var, L, b = self.__higherOrderbuildMatrix(var, SparseMatrix, boundaryConditions=boundaryConditions, dt=dt, transientGeomCoeff=transientGeomCoeff, diffusionGeomCoeff=diffusionGeomCoeff)
        mesh = var.mesh
        
        if self.order == 2:
            
            if (not hasattr(self, 'constraintL')) or (not hasattr(self, 'constraintB')):
            
                normals = FaceVariable(mesh=mesh, rank=1, value=mesh._orientedFaceNormals)

                if len(var.shape) == 1 and len(self.nthCoeff.shape) > 1:
                    nthCoeffFaceGrad = var.faceGrad.dot(self.nthCoeff)
                    normalsNthCoeff =  normals.dot(self.nthCoeff)
                else:

                    if self.nthCoeff.shape != () and not isinstance(self.nthCoeff, FaceVariable):
                        coeff = self.nthCoeff[...,numerix.newaxis]
                    else:
                        coeff = self.nthCoeff
                    
                    nthCoeffFaceGrad = coeff[numerix.newaxis] * var.faceGrad[:,numerix.newaxis]
                    s = (slice(0,None,None),) + (numerix.newaxis,) * (len(coeff.shape) - 1) + (slice(0,None,None),)
                    normalsNthCoeff = coeff[numerix.newaxis] * normals[s]

                self.constraintB = -(var.faceGrad.constraintMask * nthCoeffFaceGrad).divergence * mesh.cellVolumes

                constrainedNormalsDotCoeffOverdAP = var.arithmeticFaceValue.constraintMask * \
                                                    normalsNthCoeff / mesh._cellDistances

                self.constraintB -= (constrainedNormalsDotCoeffOverdAP * var.arithmeticFaceValue).divergence * mesh.cellVolumes

                ids = self._reshapeIDs(var, numerix.arange(mesh.numberOfCells))

                self.constraintL = -constrainedNormalsDotCoeffOverdAP.divergence * mesh.cellVolumes
                
            ids = self._reshapeIDs(var, numerix.arange(mesh.numberOfCells))
            L.addAt(self.constraintL.ravel(), ids.ravel(), ids.swapaxes(0,1).ravel())
            b += numerix.reshape(self.constraintB.ravel(), ids.shape).sum(-2).ravel()
            
        return (var, L, b)