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
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
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
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)
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)