Beispiel #1
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
Beispiel #2
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
Beispiel #3
0
    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