def __add__(self, other): if isinstance(other, ConvectionTerm): if other.__class__ != self.__class__: raise TypeError, "ConvectionTerms must use the same scheme: %s != %s" % (self.__class__.__name__, other.__class__.__name__) return self.__class__(coeff=self.coeff + other.coeff) else: return FaceTerm.__add__(self, other)
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')): constraintMask = var.faceGrad.constraintMask | var.arithmeticFaceValue.constraintMask weight = self._getWeight(var, transientGeomCoeff, diffusionGeomCoeff) if 'implicit' in weight: alpha = weight['implicit']['cell 1 diag'] else: alpha = 0.0 exteriorCoeff = self.coeff * mesh.exteriorFaces self.constraintL = (alpha * constraintMask * exteriorCoeff).divergence * mesh.cellVolumes self.constraintB = -((1 - alpha) * var.arithmeticFaceValue * constraintMask * exteriorCoeff).divergence * mesh.cellVolumes 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)
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)
def __init__(self, coeff=1.0, diffusionTerm=None): """ Create a `ConvectionTerm` object. >>> from fipy.meshes.grid1D import Grid1D >>> from fipy.variables.cellVariable import CellVariable >>> from fipy.variables.faceVariable import FaceVariable >>> m = Grid1D(nx = 2) >>> cv = CellVariable(mesh = m) >>> fv = FaceVariable(mesh = m) >>> vcv = CellVariable(mesh=m, rank=1) >>> vfv = FaceVariable(mesh=m, rank=1) >>> __ConvectionTerm(coeff = cv) Traceback (most recent call last): ... TypeError: The coefficient must be a vector value. >>> __ConvectionTerm(coeff = fv) Traceback (most recent call last): ... TypeError: The coefficient must be a vector value. >>> __ConvectionTerm(coeff = vcv) __ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0., 0., 0.]]), mesh=UniformGrid1D(dx=1.0, nx=2))) >>> __ConvectionTerm(coeff = vfv) __ConvectionTerm(coeff=FaceVariable(value=array([[ 0., 0., 0.]]), mesh=UniformGrid1D(dx=1.0, nx=2))) >>> __ConvectionTerm(coeff = (1,)) __ConvectionTerm(coeff=(1,)) >>> from fipy.terms.explicitUpwindConvectionTerm import ExplicitUpwindConvectionTerm >>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var = cv) >>> ExplicitUpwindConvectionTerm(coeff = 1).solve(var = cv) Traceback (most recent call last): ... TypeError: The coefficient must be a vector value. >>> from fipy.meshes.grid2D import Grid2D >>> m2 = Grid2D(nx=2, ny=1) >>> cv2 = CellVariable(mesh=m2) >>> vcv2 = CellVariable(mesh=m2, rank=1) >>> vfv2 = FaceVariable(mesh=m2, rank=1) >>> __ConvectionTerm(coeff=vcv2) __ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1))) >>> __ConvectionTerm(coeff=vfv2) __ConvectionTerm(coeff=FaceVariable(value=array([[ 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1))) >>> ExplicitUpwindConvectionTerm(coeff = ((0,),(0,))).solve(var=cv2) >>> ExplicitUpwindConvectionTerm(coeff = (0,0)).solve(var=cv2) :Parameters: - `coeff` : The `Term`'s coefficient value. - `diffusionTerm` : **deprecated**. The Peclet number is calculated automatically. """ if self.__class__ is ConvectionTerm: raise NotImplementedError, "can't instantiate abstract base class" if diffusionTerm is not None: import warnings warnings.warn("The Peclet number is calculated automatically. diffusionTerm will be ignored.", DeprecationWarning, stacklevel=2) self.stencil = None if isinstance(coeff, _MeshVariable) and coeff.getRank() != 1: raise TypeError, "The coefficient must be a vector value." if isinstance(coeff, CellVariable): coeff = coeff.getArithmeticFaceValue() FaceTerm.__init__(self, coeff = coeff)
def __init__(self, coeff=1.0, var=None): """ Create a `_AbstractConvectionTerm` object. >>> from fipy import * >>> m = Grid1D(nx = 2) >>> cv = CellVariable(mesh = m) >>> fv = FaceVariable(mesh = m) >>> vcv = CellVariable(mesh=m, rank=1) >>> vfv = FaceVariable(mesh=m, rank=1) >>> __ConvectionTerm(coeff = cv) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... VectorCoeffError: The coefficient must be a vector value. >>> __ConvectionTerm(coeff = fv) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... VectorCoeffError: The coefficient must be a vector value. >>> __ConvectionTerm(coeff = vcv) __ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0., 0., 0.]]), mesh=UniformGrid1D(dx=1.0, nx=2))) >>> __ConvectionTerm(coeff = vfv) __ConvectionTerm(coeff=FaceVariable(value=array([[ 0., 0., 0.]]), mesh=UniformGrid1D(dx=1.0, nx=2))) >>> __ConvectionTerm(coeff = (1,)) __ConvectionTerm(coeff=(1,)) >>> ExplicitUpwindConvectionTerm(coeff = (0,)).solve(var=cv, solver=DummySolver()) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TransientTermError: The equation requires a TransientTerm with explicit convection. >>> (TransientTerm(0.) - ExplicitUpwindConvectionTerm(coeff = (0,))).solve(var=cv, solver=DummySolver(), dt=1.) >>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = 1)).solve(var=cv, solver=DummySolver(), dt=1.) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... VectorCoeffError: The coefficient must be a vector value. >>> m2 = Grid2D(nx=2, ny=1) >>> cv2 = CellVariable(mesh=m2) >>> vcv2 = CellVariable(mesh=m2, rank=1) >>> vfv2 = FaceVariable(mesh=m2, rank=1) >>> __ConvectionTerm(coeff=vcv2) __ConvectionTerm(coeff=_ArithmeticCellToFaceVariable(value=array([[ 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1))) >>> __ConvectionTerm(coeff=vfv2) __ConvectionTerm(coeff=FaceVariable(value=array([[ 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0.]]), mesh=UniformGrid2D(dx=1.0, nx=2, dy=1.0, ny=1))) >>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = ((0,), (0,)))).solve(var=cv2, solver=DummySolver(), dt=1.) >>> (TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (0, 0))).solve(var=cv2, solver=DummySolver(), dt=1.) :Parameters: - `coeff` : The `Term`'s coefficient value. """ if self.__class__ is _AbstractConvectionTerm: raise AbstractBaseClassError self.stencil = None if isinstance(coeff, _MeshVariable) and coeff.rank < 1: raise VectorCoeffError if isinstance(coeff, CellVariable): coeff = coeff.arithmeticFaceValue FaceTerm.__init__(self, coeff=coeff, var=var)
def _checkVar(self, var): FaceTerm._checkVar(self, var) if not (isinstance(self.coeff, FaceVariable) and self.coeff.rank == 1): coeffShape = numerix.getShape(self.coeff) if (coeffShape is ()) or (coeffShape[0] != var.mesh.dim): raise VectorCoeffError