Exemple #1
0
def buildMetalIonDiffusionEquation(ionVar=None,
                                   distanceVar=None,
                                   depositionRate=1,
                                   transientCoeff=1,
                                   diffusionCoeff=1,
                                   metalIonMolarVolume=1):
    r"""

    The `MetalIonDiffusionEquation` solves the diffusion of the metal
    species with a source term at the electrolyte interface. The governing
    equation is given by,

    .. math::

       \frac{\partial c}{\partial t} = \nabla \cdot D \nabla  c

    where,

    .. math::

       D = \begin{cases}
           D_c & \text{when $\phi > 0$} \\
           0  & \text{when $\phi \le 0$}
       \end{cases}

    The velocity of the interface generally has a linear dependence on ion
    concentration. The following boundary condition applies at the zero
    level set,

    .. math::

       D \hat{n} \cdot \nabla c = \frac{v(c)}{\Omega} \qquad \text{at $phi = 0$}

    where

    .. math::

       v(c) = c V_0

    The test case below is for a 1D steady state problem. The solution is
    given by:

    .. math::

       c(x) = \frac{c^{\infty}}{\Omega D / V_0 + L}\left(x - L\right) + c^{\infty}

    This is the test case,

    >>> from fipy.meshes import Grid1D
    >>> nx = 11
    >>> dx = 1.
    >>> from fipy.tools import serialComm
    >>> mesh = Grid1D(nx = nx, dx = dx, communicator=serialComm)
    >>> x, = mesh.cellCenters
    >>> from fipy.variables.cellVariable import CellVariable
    >>> ionVar = CellVariable(mesh = mesh, value = 1.)
    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> disVar = DistanceVariable(mesh = mesh,
    ...                           value = (x - 0.5) - 0.99,
    ...                           hasOld = 1)

    >>> v = 1.
    >>> diffusion = 1.
    >>> omega = 1.
    >>> cinf = 1.

    >>> eqn = buildMetalIonDiffusionEquation(ionVar = ionVar,
    ...                                      distanceVar = disVar,
    ...                                      depositionRate = v * ionVar,
    ...                                      diffusionCoeff = diffusion,
    ...                                      metalIonMolarVolume = omega)

    >>> ionVar.constrain(cinf, mesh.facesRight)

    >>> from builtins import range
    >>> for i in range(10):
    ...     eqn.solve(ionVar, dt = 1000)

    >>> L = (nx - 1) * dx - dx / 2
    >>> gradient = cinf / (omega * diffusion / v + L)
    >>> answer = gradient * (x - L - dx * 3 / 2) + cinf
    >>> answer[x < dx] = 1
    >>> print(ionVar.allclose(answer))
    1

    Testing the interface source term

    >>> from fipy.meshes import Grid2D
    >>> from fipy import numerix, serialComm
    >>> mesh = Grid2D(dx = 1., dy = 1., nx = 2, ny = 2, communicator=serialComm)
    >>> from fipy.variables.distanceVariable import DistanceVariable
    >>> distance = DistanceVariable(mesh = mesh, value = (-.5, .5, .5, 1.5))
    >>> ionVar = CellVariable(mesh = mesh, value = (1, 1, 1, 1))
    >>> depositionRate = CellVariable(mesh=mesh, value=(1, 1, 1, 1))
    >>> source = depositionRate * distance.cellInterfaceAreas / mesh.cellVolumes / ionVar
    >>> sqrt = numerix.sqrt(2)
    >>> ans = CellVariable(mesh=mesh, value=(0, 1 / sqrt, 1 / sqrt, 0))
    >>> print(numerix.allclose(source, ans))
    True
    >>> distance[:] = (-1.5, -0.5, -0.5, 0.5)
    >>> print(numerix.allclose(source, (0, 0, 0, sqrt)))
    True

    :Parameters:
      - `ionVar`: The metal ion concentration variable.
      - `distanceVar`: A `DistanceVariable` object.
      - `depositionRate`: A float or a `CellVariable` representing the interface deposition rate.
      - `transientCoeff`: The transient coefficient.
      - `diffusionCoeff`: The diffusion coefficient
      - `metalIonMolarVolume`: Molar volume of the metal ions.

    """

    diffusionCoeff = _LevelSetDiffusionVariable(distanceVar, diffusionCoeff)

    eq = TransientTerm(transientCoeff) - DiffusionTermNoCorrection(
        diffusionCoeff)

    mesh = distanceVar.mesh
    coeff = depositionRate * distanceVar.cellInterfaceAreas / (
        mesh.cellVolumes * metalIonMolarVolume) / ionVar

    return eq + ImplicitSourceTerm(coeff)
def buildMetalIonDiffusionEquation(ionVar = None,
                                   distanceVar = None,
                                   depositionRate = 1,
                                   transientCoeff = 1,
                                   diffusionCoeff = 1,
                                   metalIonMolarVolume = 1):

    r"""

    The `MetalIonDiffusionEquation` solves the diffusion of the metal
    species with a source term at the electrolyte interface. The governing
    equation is given by,

    .. math::

       \frac{\partial c}{\partial t} = \nabla \cdot D \nabla  c

    where,

    .. math::

       D = \begin{cases}
           D_c & \text{when $\phi > 0$} \\
           0  & \text{when $\phi \le 0$}
       \end{cases}

    The velocity of the interface generally has a linear dependence on ion
    concentration. The following boundary condition applies at the zero
    level set,

    .. math::

       D \hat{n} \cdot \nabla c = \frac{v(c)}{\Omega} \qquad \text{at $phi = 0$}

    where

    .. math::

       v(c) = c V_0

    The test case below is for a 1D steady state problem. The solution is
    given by:

    .. math::

       c(x) = \frac{c^{\infty}}{\Omega D / V_0 + L}\left(x - L\right) + c^{\infty}

    This is the test case,

    >>> from fipy.meshes import Grid1D
    >>> nx = 11
    >>> dx = 1.
    >>> from fipy.tools import serialComm
    >>> mesh = Grid1D(nx = nx, dx = dx, communicator=serialComm)
    >>> x, = mesh.cellCenters
    >>> from fipy.variables.cellVariable import CellVariable
    >>> ionVar = CellVariable(mesh = mesh, value = 1.)
    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> disVar = DistanceVariable(mesh = mesh, 
    ...                           value = (x - 0.5) - 0.99,
    ...                           hasOld = 1)

    >>> v = 1.
    >>> diffusion = 1.
    >>> omega = 1.
    >>> cinf = 1.

    >>> eqn = buildMetalIonDiffusionEquation(ionVar = ionVar,
    ...                                      distanceVar = disVar,
    ...                                      depositionRate = v * ionVar,
    ...                                      diffusionCoeff = diffusion,
    ...                                      metalIonMolarVolume = omega)

    >>> ionVar.constrain(cinf, mesh.facesRight)
    
    >>> for i in range(10):
    ...     eqn.solve(ionVar, dt = 1000)

    >>> L = (nx - 1) * dx - dx / 2
    >>> gradient = cinf / (omega * diffusion / v + L)
    >>> answer = gradient * (x - L - dx * 3 / 2) + cinf
    >>> answer[x < dx] = 1
    >>> print ionVar.allclose(answer)
    1

    Testing the interface source term

    >>> from fipy.meshes import Grid2D
    >>> from fipy import numerix, serialComm
    >>> mesh = Grid2D(dx = 1., dy = 1., nx = 2, ny = 2, communicator=serialComm)
    >>> from fipy.variables.distanceVariable import DistanceVariable
    >>> distance = DistanceVariable(mesh = mesh, value = (-.5, .5, .5, 1.5))
    >>> ionVar = CellVariable(mesh = mesh, value = (1, 1, 1, 1))
    >>> depositionRate = CellVariable(mesh=mesh, value=(1, 1, 1, 1))
    >>> source = depositionRate * distance.cellInterfaceAreas / mesh.cellVolumes / ionVar
    >>> sqrt = numerix.sqrt(2)
    >>> ans = CellVariable(mesh=mesh, value=(0, 1 / sqrt, 1 / sqrt, 0))
    >>> print numerix.allclose(source, ans)
    True
    >>> distance[:] = (-1.5, -0.5, -0.5, 0.5)
    >>> print numerix.allclose(source, (0, 0, 0, sqrt))
    True

    :Parameters:
      - `ionVar`: The metal ion concentration variable.
      - `distanceVar`: A `DistanceVariable` object.
      - `depositionRate`: A float or a `CellVariable` representing the interface deposition rate.
      - `transientCoeff`: The transient coefficient.
      - `diffusionCoeff`: The diffusion coefficient
      - `metalIonMolarVolume`: Molar volume of the metal ions.

    """

    diffusionCoeff = _LevelSetDiffusionVariable(distanceVar,
                                                diffusionCoeff)

    eq =  TransientTerm(transientCoeff) - DiffusionTermNoCorrection(diffusionCoeff)

    mesh = distanceVar.mesh
    coeff = depositionRate * distanceVar.cellInterfaceAreas / (mesh.cellVolumes * metalIonMolarVolume) / ionVar

    return eq + ImplicitSourceTerm(coeff)
Exemple #3
0
def buildSurfactantBulkDiffusionEquation(bulkVar=None,
                                         distanceVar=None,
                                         surfactantVar=None,
                                         otherSurfactantVar=None,
                                         diffusionCoeff=None,
                                         transientCoeff=1.,
                                         rateConstant=None):
    r"""

    The `buildSurfactantBulkDiffusionEquation` function returns a bulk diffusion of a
    species with a source term for the jump from the bulk to an interface.
    The governing equation is given by,

    .. math::

       \frac{\partial c}{\partial t} = \nabla \cdot D \nabla  c

    where,

    .. math::

       D = \begin{cases}
           D_c & \text{when $\phi > 0$} \\
           0  & \text{when $\phi \le 0$}
       \end{cases}

    The jump condition at the interface is defined by Langmuir
    adsorption. Langmuir adsorption essentially states that the ability for
    a species to jump from an electrolyte to an interface is proportional to
    the concentration in the electrolyte, available site density and a
    jump coefficient. The boundary condition at the interface is given by

    .. math::

       D \hat{n} \cdot \nabla c = -k c (1 - \theta) \qquad \text{at $\phi = 0$}.

    Parameters
    ----------
    bulkVar : ~fipy.variables.cellVariable.CellVariable
        The bulk surfactant concentration variable.
    distanceVar : ~fipy.variables.distanceVariable.DistanceVariable
    surfactantVar : ~fipy.variables.surfactantVariable.SurfactantVariable
    otherSurfactantVar : ~fipy.variables.surfactantVariable.SurfactantVariable
        Any other surfactants that may remove this one.
    diffusionCoeff : float or ~fipy.variables.faceVariable.FaceVariable
    transientCoeff : float
        In general 1 is used.
    rateConstant : float
        The adsorption coefficient.

    """

    spCoeff = rateConstant * distanceVar.cellInterfaceAreas / bulkVar.mesh.cellVolumes
    spSourceTerm = ImplicitSourceTerm(spCoeff)

    bulkSpCoeff = spCoeff * bulkVar
    coeff = bulkSpCoeff * surfactantVar.interfaceVar

    diffusionCoeff = _LevelSetDiffusionVariable(distanceVar, diffusionCoeff)

    eq = TransientTerm(transientCoeff) - DiffusionTermNoCorrection(
        diffusionCoeff)

    if otherSurfactantVar is not None:
        otherCoeff = bulkSpCoeff * otherSurfactantVar.interfaceVar
    else:
        otherCoeff = 0

    return eq - coeff + spSourceTerm - otherCoeff
def buildSurfactantBulkDiffusionEquation(bulkVar = None,
                                         distanceVar = None,
                                         surfactantVar = None,
                                         otherSurfactantVar = None,
                                         diffusionCoeff = None,
                                         transientCoeff = 1.,
                                         rateConstant = None):
    r"""

    The `buildSurfactantBulkDiffusionEquation` function returns a bulk diffusion of a
    species with a source term for the jump from the bulk to an interface.
    The governing equation is given by,

    .. math::

       \frac{\partial c}{\partial t} = \nabla \cdot D \nabla  c

    where,

    .. math::

       D = \begin{cases}
           D_c & \text{when $\phi > 0$} \\
           0  & \text{when $\phi \le 0$}
       \end{cases}

    The jump condition at the interface is defined by Langmuir
    adsorption. Langmuir adsorption essentially states that the ability for
    a species to jump from an electrolyte to an interface is proportional to
    the concentration in the electrolyte, available site density and a
    jump coefficient. The boundary condition at the interface is given by

    .. math::

       D \hat{n} \cdot \nabla c = -k c (1 - \theta) \qquad \text{at $\phi = 0$}.
        
    :Parameters:
      - `bulkVar`: The bulk surfactant concentration variable.
      - `distanceVar`: A `DistanceVariable` object
      - `surfactantVar`: A `SurfactantVariable` object
      - `otherSurfactantVar`: Any other surfactants that may remove this one.
      - `diffusionCoeff`: A float or a `FaceVariable`.
      - `transientCoeff`: In general 1 is used.
      - `rateConstant`: The adsorption coefficient.

    """

    spCoeff = rateConstant * distanceVar.cellInterfaceAreas / bulkVar.mesh.cellVolumes
    spSourceTerm = ImplicitSourceTerm(spCoeff)

    bulkSpCoeff = spCoeff * bulkVar
    coeff = bulkSpCoeff * surfactantVar.interfaceVar

    diffusionCoeff = _LevelSetDiffusionVariable(distanceVar,
                                                diffusionCoeff)

    eq =  TransientTerm(transientCoeff) - DiffusionTermNoCorrection(diffusionCoeff)

    if otherSurfactantVar is not None:
        otherCoeff = bulkSpCoeff * otherSurfactantVar.interfaceVar
    else:
        otherCoeff = 0
            
    return eq - coeff + spSourceTerm - otherCoeff