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
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
def _getWeight(self, var, transientGeomCoeff=None, diffusionGeomCoeff=None): r""" Testing that the sign of the equation is taken into account when evaluation upwind direction. >>> from fipy import Grid1D, CellVariable >>> from fipy import TransientTerm, ConvectionTerm, ImplicitSourceTerm >>> m = Grid1D(nx=3, dx=0.5) >>> v = CellVariable(mesh=m) >>> v.constrain(1, m.facesLeft) >>> v.constrain(0, m.facesRight) >>> (-TransientTerm(coeff=1 / m.x) == ... ConvectionTerm(coeff=[[1]]) ... + ImplicitSourceTerm(coeff=m.x)).solve(v, dt=1.) >>> v0 = v.copy() >>> v[:] = 0 >>> (TransientTerm(coeff=1 / m.x) == ... - ConvectionTerm(coeff=[[1]]) ... - ImplicitSourceTerm(coeff=m.x)).solve(v, dt=1.) >>> print(numerix.allclose(v, v0)) True """ if self.stencil is None: geomCoeff = self._getGeomCoeff(var) large = 1e+20 pecletLarge = large - (geomCoeff < 0) * (2 * large) if numerix.all(self._getDiagonalSign(transientGeomCoeff, diffusionGeomCoeff) < 0): pecletLarge = -pecletLarge if diffusionGeomCoeff is None or diffusionGeomCoeff[0] is None: peclet = pecletLarge else: diffCoeff = diffusionGeomCoeff[0].numericValue diffCoeff = diffCoeff - (diffCoeff == 0) * geomCoeff / pecletLarge peclet = -geomCoeff / diffCoeff alpha = self._alpha(peclet) self.stencil = {'implicit' : {'cell 1 diag' : alpha, 'cell 1 offdiag' : (1-alpha), 'cell 2 diag' : -(1-alpha), 'cell 2 offdiag' : -alpha}} return self.stencil