def __init__(self,
                 surfactantVar = None,
                 distanceVar = None,
                 bulkVar = None,
                 rateConstant = None,
                 otherVar = None,
                 otherBulkVar = None,
                 otherRateConstant = None,
                 consumptionCoeff = None):
        """
        Create a `AdsorbingSurfactantEquation` object.

        :Parameters:
          - `surfactantVar`: The `SurfactantVariable` to be solved for.
          - `distanceVar`: The `DistanceVariable` that marks the interface.
          - `bulkVar`: The value of the `surfactantVar` in the bulk.
          - `rateConstant`: The adsorption rate of the `surfactantVar`.
          - `otherVar`: Another `SurfactantVariable` with more surface affinity.
          - `otherBulkVar`: The value of the `otherVar` in the bulk.
          - `otherRateConstant`: The adsorption rate of the `otherVar`.
          - `consumptionCoeff`: The rate that the `surfactantVar` is consumed during deposition.
                             
        """

        self.eq = TransientTerm(coeff = 1) - ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVar))

        self.dt = Variable(0.)
        mesh = distanceVar.mesh
        adsorptionCoeff = self.dt * bulkVar * rateConstant
        spCoeff = adsorptionCoeff * distanceVar._cellInterfaceFlag
        scCoeff = adsorptionCoeff * distanceVar.cellInterfaceAreas / mesh.cellVolumes

        self.eq += ImplicitSourceTerm(spCoeff) - scCoeff

        if otherVar is not None:
            otherSpCoeff = self.dt * otherBulkVar * otherRateConstant * distanceVar._cellInterfaceFlag
            otherScCoeff = -otherVar.interfaceVar * scCoeff

            self.eq += ImplicitSourceTerm(otherSpCoeff) - otherScCoeff

            vars = (surfactantVar, otherVar)
        else:
            vars = (surfactantVar,)

        total = 0
        for var in vars:
            total += var.interfaceVar
        maxVar = (total > 1) * distanceVar._cellInterfaceFlag

        val = distanceVar.cellInterfaceAreas / mesh.cellVolumes
        for var in vars[1:]:
            val -= distanceVar._cellInterfaceFlag * var
        
        spMaxCoeff = 1e20 * maxVar
        scMaxCoeff = spMaxCoeff * val * (val > 0)
            
        self.eq += ImplicitSourceTerm(spMaxCoeff) - scMaxCoeff - 1e-40

        if consumptionCoeff is not None:
            self.eq += ImplicitSourceTerm(consumptionCoeff)
Esempio n. 2
0
    def buildPhaseEquation(phase, theta):

        mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
        thetaMag = theta.getOld().getGrad().getMag()
        implicitSource = mPhiVar * (phase - (mPhiVar < 0))
        implicitSource += (2 * s + epsilon**2 * thetaMag) * thetaMag

        return TransientTerm(phaseTransientCoeff) == \
                  ExplicitDiffusionTerm(alpha**2) \
                  - ImplicitSourceTerm(implicitSource) \
                  + (mPhiVar > 0) * mPhiVar * phase
Esempio n. 3
0
    def buildThetaEquation(phase, theta):

        phaseMod = phase + (phase < thetaSmallValue) * thetaSmallValue
        phaseModSq = phaseMod * phaseMod
        expo = epsilon * beta * theta.getGrad().getMag()
        expo = (expo < 100.) * (expo - 100.) + 100.
        pFunc = 1. + numerix.exp(-expo) * (mu / epsilon - 1.)

        phaseFace = phase.getArithmeticFaceValue()
        phaseSq = phaseFace * phaseFace
        gradMag = theta.getFaceGrad().getMag()
        eps = 1. / gamma / 10.
        gradMag += (gradMag < eps) * eps
        IGamma = (gradMag > 1. / gamma) * (1 / gradMag - gamma) + gamma
        diffusionCoeff = phaseSq * (s * IGamma + epsilon**2)

        thetaGradDiff = theta.getFaceGrad() - theta.getFaceGradNoMod()
        sourceCoeff = (diffusionCoeff * thetaGradDiff).getDivergence()

        from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
        return TransientTerm(thetaTransientCoeff * phaseModSq * pFunc) == \
                   ImplicitDiffusionTerm(diffusionCoeff) \
                   + sourceCoeff
Esempio n. 4
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
Esempio n. 5
0
File: test1d.py Progetto: ghorn/Eg
mesh = Grid1D(nx=nx, dx=dx)

from fipy.variables.cellVariable import CellVariable
phi = CellVariable(name="solution variable", mesh=mesh, value=0)
D = 1

valueLeft = 1
valueRight = 0

from fipy.boundaryConditions.fixedValue import FixedValue
BCs = (FixedValue(faces=mesh.getFacesRight(), value=valueRight),
       FixedValue(faces=mesh.getFacesLeft(), value=valueLeft))

from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
from fipy.terms.transientTerm import TransientTerm
eqX = TransientTerm() == ExplicitDiffusionTerm(coeff=D)

timeStepDuration = 0.9 * dx**2 / (2 * D)
steps = 100

from fipy import viewers
viewer = viewers.make(vars=(phi), limits={'datamin': 0., 'datamax': 1.})


def hit_continue(Prompt='Hit any key to continue'):
    raw_input(Prompt)


for step in range(steps):
    eqX.solve(var=phi, boundaryConditions=BCs, dt=timeStepDuration)
    viewer.plot()
Esempio n. 6
0
from fipy.meshes.periodicGrid1D import PeriodicGrid1D
periodicMesh = PeriodicGrid1D(dx=dx, nx=nx / 2)

startingArray = numerix.zeros(nx, 'd')
startingArray[2 * nx / 10:3 * nx / 10] = 1.

from fipy.variables.cellVariable import CellVariable
var1 = CellVariable(name="non-periodic", mesh=mesh, value=startingArray)

var2 = CellVariable(name="periodic",
                    mesh=periodicMesh,
                    value=startingArray[:nx / 2])

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.vanLeerConvectionTerm import VanLeerConvectionTerm
eq1 = TransientTerm() - VanLeerConvectionTerm(coeff=(-velocity, ))
eq2 = TransientTerm() - VanLeerConvectionTerm(coeff=(-velocity, ))

if __name__ == '__main__':

    import fipy.viewers
    viewer1 = fipy.viewers.make(vars=var1)
    viewer2 = fipy.viewers.make(vars=var2)
    viewer1.plot()
    viewer2.plot()
    from fipy.solvers.linearLUSolver import LinearLUSolver

    newVar2 = var2.copy()

    for step in range(steps):
        eq1.solve(var=var1, dt=dt, solver=LinearLUSolver())
class AdsorbingSurfactantEquation():
    r"""

    The `AdsorbingSurfactantEquation` object solves the
    `SurfactantEquation` but with an adsorbing species from some bulk
    value. The equation that describes the surfactant adsorbing is
    given by,

    .. math::

       \dot{\theta} = J v \theta + k c (1 - \theta - \theta_{\text{other}}) - \theta c_{\text{other}} k_{\text{other}} - k^- \theta

    where :math:`\theta`, :math:`J`, :math:`v`, :math:`k`, :math:`c`,
    :math:`k^-` and :math:`n` represent the surfactant coverage, the curvature,
    the interface normal velocity, the adsorption rate, the concentration in the
    bulk at the interface, the consumption rate and an exponent of consumption,
    respectively. The :math:`\text{other}` subscript refers to another
    surfactant with greater surface affinity.

    The terms on the RHS of the above equation represent conservation of
    surfactant on a non-uniform surface, Langmuir adsorption, removal of
    surfactant due to adsorption of the other surfactant onto non-vacant sites
    and consumption of the surfactant respectively. The adsorption term is added
    to the source by setting :math:` S_c = k c (1 - \theta_{\text{other}})` and
    :math:`S_p = -k c`. The other terms are added to the source in a similar
    way.

    The following is a test case:

    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> from fipy import SurfactantVariable
    >>> from fipy.meshes import Grid2D
    >>> from fipy.tools import numerix
    >>> from fipy.variables.cellVariable import CellVariable
    >>> dx = .5
    >>> dy = 2.3
    >>> dt = 0.25
    >>> k = 0.56
    >>> initialValue = 0.1
    >>> c = 0.2
    
    >>> from fipy.meshes import Grid2D
    >>> from fipy import serialComm
    >>> mesh = Grid2D(dx = dx, dy = dy, nx = 5, ny = 1, communicator=serialComm)
    >>> distanceVar = DistanceVariable(mesh = mesh, 
    ...                                value = (-dx*3/2, -dx/2, dx/2, 
    ...                                          3*dx/2,  5*dx/2),
    ...                                hasOld = 1)
    >>> surfactantVar = SurfactantVariable(value = (0, 0, initialValue, 0 ,0), 
    ...                                    distanceVar = distanceVar)
    >>> bulkVar = CellVariable(mesh = mesh, value = (c , c, c, c, c))
    >>> eqn = AdsorbingSurfactantEquation(surfactantVar = surfactantVar,
    ...                                   distanceVar = distanceVar,
    ...                                   bulkVar = bulkVar,
    ...                                   rateConstant = k)
    >>> eqn.solve(surfactantVar, dt = dt)
    >>> answer = (initialValue + dt * k * c) / (1 + dt * k * c)
    >>> print numerix.allclose(surfactantVar.interfaceVar, 
    ...                  numerix.array((0, 0, answer, 0, 0)))
    1

    The following test case is for two surfactant variables. One has more
    surface affinity than the other.

    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> from fipy import SurfactantVariable
    >>> from fipy.meshes import Grid2D
    >>> dx = 0.5
    >>> dy = 2.73
    >>> dt = 0.001
    >>> k0 = 1.
    >>> k1 = 10.
    >>> theta0 = 0.
    >>> theta1 = 0.
    >>> c0 = 1.
    >>> c1 = 1.
    >>> totalSteps = 10
    >>> mesh = Grid2D(dx = dx, dy = dy, nx = 5, ny = 1, communicator=serialComm)
    >>> distanceVar = DistanceVariable(mesh = mesh, 
    ...                                value = dx * (numerix.arange(5) - 1.5),
    ...                                hasOld = 1)
    >>> var0 = SurfactantVariable(value = (0, 0, theta0, 0 ,0), 
    ...                           distanceVar = distanceVar)
    >>> var1 = SurfactantVariable(value = (0, 0, theta1, 0 ,0), 
    ...                           distanceVar = distanceVar)
    >>> bulkVar0 = CellVariable(mesh = mesh, value = (c0, c0, c0, c0, c0))
    >>> bulkVar1 = CellVariable(mesh = mesh, value = (c1, c1, c1, c1, c1))

    >>> eqn0 = AdsorbingSurfactantEquation(surfactantVar = var0,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar0,
    ...                                    rateConstant = k0)

    >>> eqn1 = AdsorbingSurfactantEquation(surfactantVar = var1,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar1,
    ...                                    rateConstant = k1,
    ...                                    otherVar = var0,
    ...                                    otherBulkVar = bulkVar0,
    ...                                    otherRateConstant = k0)

    >>> for step in range(totalSteps):
    ...     eqn0.solve(var0, dt = dt)
    ...     eqn1.solve(var1, dt = dt)
    >>> answer0 = 1 - numerix.exp(-k0 * c0 * dt * totalSteps)
    >>> answer1 = (1 - numerix.exp(-k1 * c1 * dt * totalSteps)) * (1 - answer0)
    >>> print numerix.allclose(var0.interfaceVar, 
    ...                  numerix.array((0, 0, answer0, 0, 0)), rtol = 1e-2)
    1
    >>> print numerix.allclose(var1.interfaceVar, 
    ...                  numerix.array((0, 0, answer1, 0, 0)), rtol = 1e-2)
    1
    >>> dt = 0.1
    >>> for step in range(10):
    ...     eqn0.solve(var0, dt = dt)
    ...     eqn1.solve(var1, dt = dt)

    >>> x, y = mesh.cellCenters
    >>> check = var0.interfaceVar + var1.interfaceVar
    >>> answer = CellVariable(mesh=mesh, value=check)
    >>> answer[x==1.25] = 1.
    >>> print check.allequal(answer)
    True

    The following test case is to fix a bug where setting the adosrbtion
    coefficient to zero leads to the solver not converging and an eventual
    failure.

    >>> var0 = SurfactantVariable(value = (0, 0, theta0, 0 ,0), 
    ...                           distanceVar = distanceVar)
    >>> bulkVar0 = CellVariable(mesh = mesh, value = (c0, c0, c0, c0, c0))

    >>> eqn0 = AdsorbingSurfactantEquation(surfactantVar = var0,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar0,
    ...                                    rateConstant = 0)

    >>> eqn0.solve(var0, dt = dt)
    >>> eqn0.solve(var0, dt = dt)
    >>> answer = CellVariable(mesh=mesh, value=var0.interfaceVar)
    >>> answer[x==1.25] = 0.
    
    >>> print var0.interfaceVar.allclose(answer)
    True

    The following test case is to fix a bug that allows the accelerator to
    become negative.

    >>> nx = 5
    >>> ny = 5
    >>> dx = 1.
    >>> dy = 1.
    >>> mesh = Grid2D(dx=dx, dy=dy, nx = nx, ny = ny, communicator=serialComm)
    >>> x, y = mesh.cellCenters

    >>> disVar = DistanceVariable(mesh=mesh, value=1., hasOld=True)
    >>> disVar[y < dy] = -1
    >>> disVar[x < dx] = -1
    >>> disVar.calcDistanceFunction() #doctest: +LSM

    >>> levVar = SurfactantVariable(value = 0.5, distanceVar = disVar)
    >>> accVar = SurfactantVariable(value = 0.5, distanceVar = disVar)

    >>> levEq = AdsorbingSurfactantEquation(levVar,
    ...                                     distanceVar = disVar,
    ...                                     bulkVar = 0,
    ...                                     rateConstant = 0)

    >>> accEq = AdsorbingSurfactantEquation(accVar,
    ...                                     distanceVar = disVar,
    ...                                     bulkVar = 0,
    ...                                     rateConstant = 0,
    ...                                     otherVar = levVar,
    ...                                     otherBulkVar = 0,
    ...                                     otherRateConstant = 0)

    >>> extVar = CellVariable(mesh = mesh, value = accVar.interfaceVar)

    >>> from fipy import TransientTerm, AdvectionTerm
    >>> advEq = TransientTerm() + AdvectionTerm(extVar)

    >>> dt = 0.1

    >>> for i in range(50):
    ...     disVar.calcDistanceFunction()
    ...     extVar.value = (numerix.array(accVar.interfaceVar))
    ...     disVar.extendVariable(extVar)
    ...     disVar.updateOld()
    ...     advEq.solve(disVar, dt = dt)
    ...     levEq.solve(levVar, dt = dt)
    ...     accEq.solve(accVar, dt = dt) #doctest: +LSM

    >>> print (accVar >= -1e-10).all()
    True
    """
    def __init__(self,
                 surfactantVar = None,
                 distanceVar = None,
                 bulkVar = None,
                 rateConstant = None,
                 otherVar = None,
                 otherBulkVar = None,
                 otherRateConstant = None,
                 consumptionCoeff = None):
        """
        Create a `AdsorbingSurfactantEquation` object.

        :Parameters:
          - `surfactantVar`: The `SurfactantVariable` to be solved for.
          - `distanceVar`: The `DistanceVariable` that marks the interface.
          - `bulkVar`: The value of the `surfactantVar` in the bulk.
          - `rateConstant`: The adsorption rate of the `surfactantVar`.
          - `otherVar`: Another `SurfactantVariable` with more surface affinity.
          - `otherBulkVar`: The value of the `otherVar` in the bulk.
          - `otherRateConstant`: The adsorption rate of the `otherVar`.
          - `consumptionCoeff`: The rate that the `surfactantVar` is consumed during deposition.
                             
        """

        self.eq = TransientTerm(coeff = 1) - ExplicitUpwindConvectionTerm(SurfactantConvectionVariable(distanceVar))

        self.dt = Variable(0.)
        mesh = distanceVar.mesh
        adsorptionCoeff = self.dt * bulkVar * rateConstant
        spCoeff = adsorptionCoeff * distanceVar._cellInterfaceFlag
        scCoeff = adsorptionCoeff * distanceVar.cellInterfaceAreas / mesh.cellVolumes

        self.eq += ImplicitSourceTerm(spCoeff) - scCoeff

        if otherVar is not None:
            otherSpCoeff = self.dt * otherBulkVar * otherRateConstant * distanceVar._cellInterfaceFlag
            otherScCoeff = -otherVar.interfaceVar * scCoeff

            self.eq += ImplicitSourceTerm(otherSpCoeff) - otherScCoeff

            vars = (surfactantVar, otherVar)
        else:
            vars = (surfactantVar,)

        total = 0
        for var in vars:
            total += var.interfaceVar
        maxVar = (total > 1) * distanceVar._cellInterfaceFlag

        val = distanceVar.cellInterfaceAreas / mesh.cellVolumes
        for var in vars[1:]:
            val -= distanceVar._cellInterfaceFlag * var
        
        spMaxCoeff = 1e20 * maxVar
        scMaxCoeff = spMaxCoeff * val * (val > 0)
            
        self.eq += ImplicitSourceTerm(spMaxCoeff) - scMaxCoeff - 1e-40

        if consumptionCoeff is not None:
            self.eq += ImplicitSourceTerm(consumptionCoeff)

    def solve(self, var, boundaryConditions=(), solver=None, dt=None):
        """
        Builds and solves the `AdsorbingSurfactantEquation`'s linear system once.
        	
        :Parameters:
           - `var`: A `SurfactantVariable` to be solved for. Provides the initial condition, the old value and holds the solution on completion.
           - `solver`: The iterative solver to be used to solve the linear system of equations.
           - `boundaryConditions`: A tuple of boundaryConditions.
           - `dt`: The time step size.
           
	"""
        self.dt.setValue(dt)
        if solver is None:
            import fipy.solvers.solver
            if fipy.solvers.solver == 'pyamg':
                from fipy.solvers.pyAMG.linearGeneralSolver import LinearGeneralSolver
                solver = LinearGeneralSolver(tolerance=1e-15, iterations=2000)
            else:
                from fipy.solvers import LinearPCGSolver
                solver = LinearPCGSolver()
            
        if type(boundaryConditions) not in (type(()), type([])):
            boundaryConditions = (boundaryConditions,)
        
        var.constrain(0, var.mesh.exteriorFaces)
        
        self.eq.solve(var,
                      boundaryConditions=boundaryConditions,
                      solver = solver,
                      dt=1.)
        
    def sweep(self, var, solver=None, boundaryConditions=(), dt=None, underRelaxation=None, residualFn=None):
        r"""
        Builds and solves the `AdsorbingSurfactantEquation`'s linear
        system once. This method also recalculates and returns the
        residual as well as applying under-relaxation.

        :Parameters:

           - `var`: The variable to be solved for. Provides the initial condition, the old value and holds the solution on completion.
           - `solver`: The iterative solver to be used to solve the linear system of equations. 
           - `boundaryConditions`: A tuple of boundaryConditions.
           - `dt`: The time step size.
           - `underRelaxation`: Usually a value between `0` and `1` or `None` in the case of no under-relaxation

	"""
        self.dt.setValue(dt)
        if solver is None:
            from fipy.solvers import DefaultAsymmetricSolver
            solver = DefaultAsymmetricSolver()
        
        if type(boundaryConditions) not in (type(()), type([])):
            boundaryConditions = (boundaryConditions,)
        
        var.constrain(0, var.mesh.exteriorFaces)

        return self.eq.sweep(var, solver=solver, boundaryConditions=boundaryConditions, underRelaxation=underRelaxation, residualFn=residualFn, dt=1.)
Esempio n. 8
0
    phaseY = phase.getFaceGrad().dot((0, 1))
    phaseX = phase.getFaceGrad().dot((1, 0))
    psi = theta + numerix.arctan2(phaseY, phaseX)
    Phi = numerix.tan(N * psi / 2)
    PhiSq = Phi**2
    beta = (1. - PhiSq) / (1. + PhiSq)
    betaPsi = -N * 2 * Phi / (1 + PhiSq)
    A = alpha**2 * c * (1. + c * beta) * betaPsi
    D = alpha**2 * (1. + c * beta)**2
    dxi = phase.getFaceGrad()._take((1, 0), axis=1) * (-1, 1)
    anisotropySource = (A * dxi).getDivergence()
    from fipy.terms.transientTerm import TransientTerm
    from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
    from fipy.terms.implicitSourceTerm import ImplicitSourceTerm
    phaseEq = TransientTerm(tau) == ExplicitDiffusionTerm(D) + \
        ImplicitSourceTerm(mVar * ((mVar < 0) - phase)) + \
        ((mVar > 0.) * mVar * phase + anisotropySource)

    from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
    temperatureEq = TransientTerm() == \
                    ImplicitDiffusionTerm(tempDiffusionCoeff) + \
                    (phase - phase.getOld()) / timeStepDuration

    bench.stop('terms')

    phase.updateOld()
    temperature.updateOld()
    phaseEq.solve(phase, dt=timeStepDuration)
    temperatureEq.solve(temperature, dt=timeStepDuration)
Esempio n. 9
0
shift = 1.

KMVar = CellVariable(mesh = mesh, value = params['KM'] * shift, hasOld = 1)
KCVar = CellVariable(mesh = mesh, value = params['KC'] * shift, hasOld = 1)
TMVar = CellVariable(mesh = mesh, value = params['TM'] * shift, hasOld = 1)
TCVar = CellVariable(mesh = mesh, value = params['TC'] * shift, hasOld = 1)
P3Var = CellVariable(mesh = mesh, value = params['P3'] * shift, hasOld = 1)
P2Var = CellVariable(mesh = mesh, value = params['P2'] * shift, hasOld = 1)
RVar = CellVariable(mesh = mesh, value = params['R'], hasOld = 1)

PN = P3Var + P2Var

KMscCoeff = params['chiK'] * (RVar + 1) * (1 - KCVar - KMVar.getCellVolumeAverage())
KMspCoeff = params['lambdaK'] / (1 + PN / params['kappaK'])
KMEq = TransientTerm() - KMscCoeff + ImplicitSourceTerm(KMspCoeff)

TMscCoeff = params['chiT'] * (1 - TCVar - TMVar.getCellVolumeAverage())
TMspCoeff = params['lambdaT'] * (KMVar + params['zetaT'])
TMEq = TransientTerm() - TMscCoeff + ImplicitSourceTerm(TMspCoeff)

TCscCoeff = params['lambdaT'] * (TMVar * KMVar).getCellVolumeAverage()
TCspCoeff = params['lambdaTstar']
TCEq = TransientTerm() - TCscCoeff + ImplicitSourceTerm(TCspCoeff) 

PIP2PITP = PN / (PN / params['kappam'] + PN.getCellVolumeAverage() / params['kappac'] + 1) + params['zetaPITP']

P3spCoeff = params['lambda3'] * (TMVar + params['zeta3T'])
P3scCoeff = params['chi3'] * KMVar * (PIP2PITP / (1 + KMVar / params['kappa3']) + params['zeta3PITP']) + params['zeta3']
P3Eq = TransientTerm() - ImplicitDiffusionTerm(params['diffusionCoeff']) - P3scCoeff + ImplicitSourceTerm(P3spCoeff)
Esempio n. 10
0
File: input2D.py Progetto: ghorn/Eg
from fipy.variables.cellVariable import CellVariable
from fipy.tools.numerix import random

var = CellVariable(name = "phase field",
                   mesh = mesh,
                   value = random.random(nx * ny))

faceVar = var.getArithmeticFaceValue()
doubleWellDerivative = asq * ( 1 - 6 * faceVar * (1 - faceVar))

from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
from fipy.terms.transientTerm import TransientTerm
diffTerm2 = ImplicitDiffusionTerm(coeff = (diffusionCoeff * doubleWellDerivative,))
diffTerm4 = ImplicitDiffusionTerm(coeff = (diffusionCoeff, -epsilon**2))
eqch = TransientTerm() - diffTerm2 - diffTerm4

from fipy.solvers.linearPCGSolver import LinearPCGSolver
from fipy.solvers.linearLUSolver import LinearLUSolver
##solver = LinearLUSolver(tolerance = 1e-15,steps = 1000)
solver = LinearPCGSolver(tolerance = 1e-15,steps = 1000)

from fipy.boundaryConditions.fixedValue import FixedValue
from fipy.boundaryConditions.fixedFlux import FixedFlux
from fipy.boundaryConditions.nthOrderBoundaryCondition import NthOrderBoundaryCondition
BCs = (FixedFlux(mesh.getFacesRight(), 0),
       FixedFlux(mesh.getFacesLeft(), 0),
       NthOrderBoundaryCondition(mesh.getFacesLeft(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesRight(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesTop(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesBottom(), 0, 3))
Esempio n. 11
0
startingArray[50:90] = 1. 

var = CellVariable(
    name = "advection variable",
    mesh = mesh,
    value = startingArray)

boundaryConditions = (
    FixedValue(mesh.getFacesLeft(), valueLeft),
    FixedValue(mesh.getFacesRight(), valueRight)
    )

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.powerLawConvectionTerm import PowerLawConvectionTerm

eq = TransientTerm() - PowerLawConvectionTerm(coeff = (velocity,))

if __name__ == '__main__':
    
    viewer = fipy.viewers.make(vars=(var,))
    viewer.plot()
    raw_input("press key to continue")
    for step in range(steps):
        eq.solve(var,
                 dt = timeStepDuration,
                 boundaryConditions = boundaryConditions,
                 solver = LinearLUSolver(tolerance = 1.e-15))
        viewer.plot()
    viewer.plot()
    raw_input('finished')
Esempio n. 12
0
File: input2D.py Progetto: ghorn/Eg
shift = 1.

KMVar = CellVariable(mesh=mesh, value=params['KM'] * shift, hasOld=1)
KCVar = CellVariable(mesh=mesh, value=params['KC'] * shift, hasOld=1)
TMVar = CellVariable(mesh=mesh, value=params['TM'] * shift, hasOld=1)
TCVar = CellVariable(mesh=mesh, value=params['TC'] * shift, hasOld=1)
P3Var = CellVariable(mesh=mesh, value=params['P3'] * shift, hasOld=1)
P2Var = CellVariable(mesh=mesh, value=params['P2'] * shift, hasOld=1)
RVar = CellVariable(mesh=mesh, value=params['R'], hasOld=1)

PN = P3Var + P2Var

KMscCoeff = params['chiK'] * (RVar + 1) * (1 - KCVar -
                                           KMVar.getCellVolumeAverage())
KMspCoeff = params['lambdaK'] / (1 + PN / params['kappaK'])
KMEq = TransientTerm() - KMscCoeff + ImplicitSourceTerm(KMspCoeff)

TMscCoeff = params['chiT'] * (1 - TCVar - TMVar.getCellVolumeAverage())
TMspCoeff = params['lambdaT'] * (KMVar + params['zetaT'])
TMEq = TransientTerm() - TMscCoeff + ImplicitSourceTerm(TMspCoeff)

TCscCoeff = params['lambdaT'] * (TMVar * KMVar).getCellVolumeAverage()
TCspCoeff = params['lambdaTstar']
TCEq = TransientTerm() - TCscCoeff + ImplicitSourceTerm(TCspCoeff)

PIP2PITP = PN / (PN / params['kappam'] + PN.getCellVolumeAverage() /
                 params['kappac'] + 1) + params['zetaPITP']

P3spCoeff = params['lambda3'] * (TMVar + params['zeta3T'])
P3scCoeff = params['chi3'] * KMVar * (PIP2PITP /
                                      (1 + KMVar / params['kappa3']) +
Esempio n. 13
0
File: input.py Progetto: ghorn/Eg
phase = CellVariable(name = 'PhaseField', mesh = mesh, value = 1.)

from fipy.variables.modularVariable import ModularVariable
theta = ModularVariable(name = 'Theta', mesh = mesh, value = 1.)
x, y = mesh.getCellCenters()[...,0], mesh.getCellCenters()[...,1]
theta.setValue(0., where=(x - L / 2.)**2 + (y - L / 2.)**2 < (L / 4.)**2)

from fipy.terms.implicitSourceTerm import ImplicitSourceTerm
mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
thetaMag = theta.getOld().getGrad().getMag()
implicitSource = mPhiVar * (phase - (mPhiVar < 0))
implicitSource += (2 * s + epsilon**2 * thetaMag) * thetaMag

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
phaseEq = TransientTerm(phaseTransientCoeff) == \
          ExplicitDiffusionTerm(alpha**2) \
          - ImplicitSourceTerm(implicitSource) \
          + (mPhiVar > 0) * mPhiVar * phase

if __name__ == '__main__':

    import fipy.viewers
    phaseViewer = fipy.viewers.make(vars = phase) 
    phaseViewer.plot()
    for step in range(steps):
        phase.updateOld()
        phaseEq.solve(phase, dt = timeStepDuration)
        phaseViewer.plot()
    raw_input('finished')
Esempio n. 14
0
File: test1d.py Progetto: ghorn/Eg
phi = CellVariable(name="solution variable",
                    mesh=mesh,
                    value=0)
D = 1

valueLeft = 1
valueRight = 0

from fipy.boundaryConditions.fixedValue import FixedValue
BCs = (FixedValue(faces=mesh.getFacesRight(), value=valueRight),
        FixedValue(faces=mesh.getFacesLeft(), value=valueLeft))


from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
from fipy.terms.transientTerm import TransientTerm
eqX = TransientTerm() == ExplicitDiffusionTerm(coeff=D)


timeStepDuration = 0.9 * dx**2 / (2 * D)
steps=100



from fipy import viewers
viewer = viewers.make(vars=(phi),
                      limits={'datamin': 0., 'datamax': 1.})

def hit_continue(Prompt='Hit any key to continue'):
	raw_input(Prompt)

for step in range(steps):
Esempio n. 15
0
startingArray[2 * nx / 10: 3 * nx / 10] = 1. 

from fipy.variables.cellVariable import CellVariable
var1 = CellVariable(
    name = "non-periodic",
    mesh = mesh,
    value = startingArray)

var2 = CellVariable(
    name = "periodic",
    mesh = periodicMesh,
    value = startingArray[:nx / 2])

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.vanLeerConvectionTerm import VanLeerConvectionTerm
eq1 = TransientTerm() - VanLeerConvectionTerm(coeff = (-velocity,))
eq2 = TransientTerm() - VanLeerConvectionTerm(coeff = (-velocity,))

if __name__ == '__main__':

    import fipy.viewers
    viewer1 = fipy.viewers.make(vars=var1)
    viewer2 = fipy.viewers.make(vars=var2)
    viewer1.plot()
    viewer2.plot()
    from fipy.solvers.linearLUSolver import LinearLUSolver

    newVar2 = var2.copy()

    for step in range(steps):
        eq1.solve(var = var1, dt = dt, solver = LinearLUSolver())
Esempio n. 16
0
    else:
        return 0


def allOthers(face):

    if ((leftSide(face) or inMiddle(face) or rightSide(face))
            or not (face.getID() in bigMesh.getExteriorFaces())):
        return 0
    else:
        return 1


var = CellVariable(name="concentration", mesh=bigMesh, value=valueLeft)

eqn = TransientTerm() == ExplicitDiffusionTerm()

exteriorFaces = bigMesh.getExteriorFaces()
xFace = exteriorFaces.getCenters()[..., 0]

boundaryConditions = (
    FixedValue(exteriorFaces.where(xFace**2 < 0.000000000000001), valueLeft),
    FixedValue(exteriorFaces.where((xFace - (dx * nx))**2 < 0.000000000000001),
               (valueLeft + valueRight) * 0.5),
    FixedValue(
        exteriorFaces.where((xFace - (2 * dx * nx))**2 < 0.000000000000001),
        valueRight))

answer = numerix.array([
    0.00000000e+00, 8.78906250e-23, 1.54057617e-19, 1.19644866e-16,
    5.39556276e-14, 1.55308505e-11, 2.94461712e-09, 3.63798469e-07,
Esempio n. 17
0
# create a field variable, set the initial conditions:
from fipy.variables.cellVariable import CellVariable

var = CellVariable(mesh=mesh, value=0)


def centerCells(cell):
    return abs(cell.getCenter()[0] - L / 2.0) < L / 10


var.setValue(value=1.0, cells=mesh.getCells(filter=centerCells))

# create the equation:
from fipy.terms.transientTerm import TransientTerm
from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm

eq = TransientTerm() - ImplicitDiffusionTerm(coeff=1) == 0

# create a viewer:
from fipy.viewers.gist2DViewer import Gist1DViewer

viewer = Gist1DViewer(vars=(var,), limits=('e', 'e', 0, 1))
viwer.plot()

# solve
for i in range(steps):
    var.updateOld()
    eq.solve()
    viewer.plot()
Esempio n. 18
0
startingArray = numerix.zeros(nx, 'd')
startingArray[50:90] = 1. 

var = CellVariable(
    name = "advection variable",
    mesh = mesh,
    value = startingArray)

boundaryConditions = (
    FixedValue(mesh.getFacesLeft(), valueLeft),
    FixedValue(mesh.getFacesRight(), valueRight)
    )

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.explicitUpwindConvectionTerm import ExplicitUpwindConvectionTerm

eq = TransientTerm() - ExplicitUpwindConvectionTerm(coeff = (velocity,))

if __name__ == '__main__':
    
    viewer = fipy.viewers.make(vars=(var,))
    for step in range(steps):
        eq.solve(var,
                 dt = timeStepDuration,
                 boundaryConditions = boundaryConditions,
                 solver = LinearCGSSolver(tolerance = 1.e-15, steps = 2000))
        viewer.plot()
    viewer.plot()
    raw_input('finished')
Esempio n. 19
0
    bench.start()

    from fipy.variables.cellVariable import CellVariable
    C = CellVariable(mesh = mesh)
    C.setValue(1, where=abs(mesh.getCellCenters()[...,0] - L/2.) < L / 10.)

    bench.stop('variables')

    bench.start()

    D = 1.

    from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
    from fipy.terms.transientTerm import TransientTerm
    eq = TransientTerm() == ImplicitDiffusionTerm(coeff = D)

    bench.stop('terms')

    ## from fipy import viewers
    ## viewer = viewers.make(vars = C, limits = {'datamin': 0, 'datamax': 1})
    ## viewer.plot()
    ## raw_input("initial")

    bench.start()

    dt = 1e0
    steps = 1
    for step in range(steps):
        eq.solve(var = C, dt = dt)
    ##     viewer.plot()
Esempio n. 20
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)
Esempio n. 21
0
## Define boundary condition values
leftValue = 1.0
rightValue = 0

## Creation of boundary conditions
from fipy.boundaryConditions.fixedValue import FixedValue
BCs = (FixedValue(faces = mesh_example.getFacesRight(), value=rightValue),
       FixedValue(faces=mesh_example.getFacesLeft(),value=leftValue))


D = 1.0 ## diffusivity (m^2/s)

## Transient diffusion equation is defined next
from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
from fipy.terms.transientTerm import TransientTerm
eqX = TransientTerm() == ExplicitDiffusionTerm(coeff = D)

timeStep = 0.09*deltax**2/(2*D) ## size of time step
steps = 9000 ## number of time-steps

## create a GUI
from fipy import viewers
viewer = viewers.make(vars = phi, limits={'datamin':0.0, 'datamax':1.0})

## iterate until you get tired
for step in range(steps):
    eqX.solve(var = phi, boundaryConditions = BCs, dt = timeStep) ## solving the equation
    viewer.plot() ## update the GUI


Esempio n. 22
0
steps = 1000

mesh = Grid1D(dx=dx, nx=nx)

startingArray = numerix.zeros(nx, 'd')
startingArray[50:90] = 1.

var = CellVariable(name="advection variable", mesh=mesh, value=startingArray)

boundaryConditions = (FixedValue(mesh.getFacesLeft(), valueLeft),
                      FixedValue(mesh.getFacesRight(), valueRight))

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.powerLawConvectionTerm import PowerLawConvectionTerm

eq = TransientTerm() - PowerLawConvectionTerm(coeff=(velocity, ))

if __name__ == '__main__':

    viewer = fipy.viewers.make(vars=(var, ))
    viewer.plot()
    raw_input("press key to continue")
    for step in range(steps):
        eq.solve(var,
                 dt=timeStepDuration,
                 boundaryConditions=boundaryConditions,
                 solver=LinearLUSolver(tolerance=1.e-15))
        viewer.plot()
    viewer.plot()
    raw_input('finished')
Esempio n. 23
0
class AdsorbingSurfactantEquation():
    r"""

    The `AdsorbingSurfactantEquation` object solves the
    `SurfactantEquation` but with an adsorbing species from some bulk
    value. The equation that describes the surfactant adsorbing is
    given by,

    .. math::

       \dot{\theta} = J v \theta + k c (1 - \theta - \theta_{\text{other}}) - \theta c_{\text{other}} k_{\text{other}} - k^- \theta

    where :math:`\theta`, :math:`J`, :math:`v`, :math:`k`, :math:`c`,
    :math:`k^-` and :math:`n` represent the surfactant coverage, the curvature,
    the interface normal velocity, the adsorption rate, the concentration in the
    bulk at the interface, the consumption rate and an exponent of consumption,
    respectively. The :math:`\text{other}` subscript refers to another
    surfactant with greater surface affinity.

    The terms on the RHS of the above equation represent conservation of
    surfactant on a non-uniform surface, Langmuir adsorption, removal of
    surfactant due to adsorption of the other surfactant onto non-vacant sites
    and consumption of the surfactant respectively. The adsorption term is added
    to the source by setting :math:` S_c = k c (1 - \theta_{\text{other}})` and
    :math:`S_p = -k c`. The other terms are added to the source in a similar
    way.

    The following is a test case:

    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> from fipy import SurfactantVariable
    >>> from fipy.meshes import Grid2D
    >>> from fipy.tools import numerix
    >>> from fipy.variables.cellVariable import CellVariable
    >>> dx = .5
    >>> dy = 2.3
    >>> dt = 0.25
    >>> k = 0.56
    >>> initialValue = 0.1
    >>> c = 0.2

    >>> from fipy.meshes import Grid2D
    >>> from fipy import serialComm
    >>> mesh = Grid2D(dx = dx, dy = dy, nx = 5, ny = 1, communicator=serialComm)
    >>> distanceVar = DistanceVariable(mesh = mesh,
    ...                                value = (-dx*3/2, -dx/2, dx/2,
    ...                                          3*dx/2,  5*dx/2),
    ...                                hasOld = 1)
    >>> surfactantVar = SurfactantVariable(value = (0, 0, initialValue, 0 ,0),
    ...                                    distanceVar = distanceVar)
    >>> bulkVar = CellVariable(mesh = mesh, value = (c , c, c, c, c))
    >>> eqn = AdsorbingSurfactantEquation(surfactantVar = surfactantVar,
    ...                                   distanceVar = distanceVar,
    ...                                   bulkVar = bulkVar,
    ...                                   rateConstant = k)
    >>> eqn.solve(surfactantVar, dt = dt)
    >>> answer = (initialValue + dt * k * c) / (1 + dt * k * c)
    >>> print numerix.allclose(surfactantVar.interfaceVar,
    ...                  numerix.array((0, 0, answer, 0, 0)))
    1

    The following test case is for two surfactant variables. One has more
    surface affinity than the other.

    >>> from fipy.variables.distanceVariable \
    ...     import DistanceVariable
    >>> from fipy import SurfactantVariable
    >>> from fipy.meshes import Grid2D
    >>> dx = 0.5
    >>> dy = 2.73
    >>> dt = 0.001
    >>> k0 = 1.
    >>> k1 = 10.
    >>> theta0 = 0.
    >>> theta1 = 0.
    >>> c0 = 1.
    >>> c1 = 1.
    >>> totalSteps = 10
    >>> mesh = Grid2D(dx = dx, dy = dy, nx = 5, ny = 1, communicator=serialComm)
    >>> distanceVar = DistanceVariable(mesh = mesh,
    ...                                value = dx * (numerix.arange(5) - 1.5),
    ...                                hasOld = 1)
    >>> var0 = SurfactantVariable(value = (0, 0, theta0, 0 ,0),
    ...                           distanceVar = distanceVar)
    >>> var1 = SurfactantVariable(value = (0, 0, theta1, 0 ,0),
    ...                           distanceVar = distanceVar)
    >>> bulkVar0 = CellVariable(mesh = mesh, value = (c0, c0, c0, c0, c0))
    >>> bulkVar1 = CellVariable(mesh = mesh, value = (c1, c1, c1, c1, c1))

    >>> eqn0 = AdsorbingSurfactantEquation(surfactantVar = var0,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar0,
    ...                                    rateConstant = k0)

    >>> eqn1 = AdsorbingSurfactantEquation(surfactantVar = var1,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar1,
    ...                                    rateConstant = k1,
    ...                                    otherVar = var0,
    ...                                    otherBulkVar = bulkVar0,
    ...                                    otherRateConstant = k0)

    >>> for step in range(totalSteps):
    ...     eqn0.solve(var0, dt = dt)
    ...     eqn1.solve(var1, dt = dt)
    >>> answer0 = 1 - numerix.exp(-k0 * c0 * dt * totalSteps)
    >>> answer1 = (1 - numerix.exp(-k1 * c1 * dt * totalSteps)) * (1 - answer0)
    >>> print numerix.allclose(var0.interfaceVar,
    ...                  numerix.array((0, 0, answer0, 0, 0)), rtol = 1e-2)
    1
    >>> print numerix.allclose(var1.interfaceVar,
    ...                  numerix.array((0, 0, answer1, 0, 0)), rtol = 1e-2)
    1
    >>> dt = 0.1
    >>> for step in range(10):
    ...     eqn0.solve(var0, dt = dt)
    ...     eqn1.solve(var1, dt = dt)

    >>> x, y = mesh.cellCenters
    >>> check = var0.interfaceVar + var1.interfaceVar
    >>> answer = CellVariable(mesh=mesh, value=check)
    >>> answer[x==1.25] = 1.
    >>> print check.allequal(answer)
    True

    The following test case is to fix a bug where setting the adsorption
    coefficient to zero leads to the solver not converging and an eventual
    failure.

    >>> var0 = SurfactantVariable(value = (0, 0, theta0, 0 ,0),
    ...                           distanceVar = distanceVar)
    >>> bulkVar0 = CellVariable(mesh = mesh, value = (c0, c0, c0, c0, c0))

    >>> eqn0 = AdsorbingSurfactantEquation(surfactantVar = var0,
    ...                                    distanceVar = distanceVar,
    ...                                    bulkVar = bulkVar0,
    ...                                    rateConstant = 0)

    >>> eqn0.solve(var0, dt = dt)
    >>> eqn0.solve(var0, dt = dt)
    >>> answer = CellVariable(mesh=mesh, value=var0.interfaceVar)
    >>> answer[x==1.25] = 0.

    >>> print var0.interfaceVar.allclose(answer)
    True

    The following test case is to fix a bug that allows the accelerator to
    become negative.

    >>> nx = 5
    >>> ny = 5
    >>> dx = 1.
    >>> dy = 1.
    >>> mesh = Grid2D(dx=dx, dy=dy, nx = nx, ny = ny, communicator=serialComm)
    >>> x, y = mesh.cellCenters

    >>> disVar = DistanceVariable(mesh=mesh, value=1., hasOld=True)
    >>> disVar[y < dy] = -1
    >>> disVar[x < dx] = -1
    >>> disVar.calcDistanceFunction() #doctest: +LSM

    >>> levVar = SurfactantVariable(value = 0.5, distanceVar = disVar)
    >>> accVar = SurfactantVariable(value = 0.5, distanceVar = disVar)

    >>> levEq = AdsorbingSurfactantEquation(levVar,
    ...                                     distanceVar = disVar,
    ...                                     bulkVar = 0,
    ...                                     rateConstant = 0)

    >>> accEq = AdsorbingSurfactantEquation(accVar,
    ...                                     distanceVar = disVar,
    ...                                     bulkVar = 0,
    ...                                     rateConstant = 0,
    ...                                     otherVar = levVar,
    ...                                     otherBulkVar = 0,
    ...                                     otherRateConstant = 0)

    >>> extVar = CellVariable(mesh = mesh, value = accVar.interfaceVar)

    >>> from fipy import TransientTerm, AdvectionTerm
    >>> advEq = TransientTerm() + AdvectionTerm(extVar)

    >>> dt = 0.1

    >>> for i in range(50):
    ...     disVar.calcDistanceFunction()
    ...     extVar.value = (numerix.array(accVar.interfaceVar))
    ...     disVar.extendVariable(extVar)
    ...     disVar.updateOld()
    ...     advEq.solve(disVar, dt = dt)
    ...     levEq.solve(levVar, dt = dt)
    ...     accEq.solve(accVar, dt = dt) #doctest: +LSM

    >>> # The following test fails sometimes on linux with scipy solvers
    >>> # See issue #575. We ignore for now.
    >>> print (accVar >= -1e-10).all() #doctest: +NOTLINUXSCIPY
    True
    """
    def __init__(self,
                 surfactantVar=None,
                 distanceVar=None,
                 bulkVar=None,
                 rateConstant=None,
                 otherVar=None,
                 otherBulkVar=None,
                 otherRateConstant=None,
                 consumptionCoeff=None):
        """
        Create a `AdsorbingSurfactantEquation` object.

        :Parameters:
          - `surfactantVar`: The `SurfactantVariable` to be solved for.
          - `distanceVar`: The `DistanceVariable` that marks the interface.
          - `bulkVar`: The value of the `surfactantVar` in the bulk.
          - `rateConstant`: The adsorption rate of the `surfactantVar`.
          - `otherVar`: Another `SurfactantVariable` with more surface affinity.
          - `otherBulkVar`: The value of the `otherVar` in the bulk.
          - `otherRateConstant`: The adsorption rate of the `otherVar`.
          - `consumptionCoeff`: The rate that the `surfactantVar` is consumed during deposition.

        """

        self.eq = TransientTerm(coeff=1) - ExplicitUpwindConvectionTerm(
            SurfactantConvectionVariable(distanceVar))

        self.dt = Variable(0.)
        mesh = distanceVar.mesh
        adsorptionCoeff = self.dt * bulkVar * rateConstant
        spCoeff = adsorptionCoeff * distanceVar._cellInterfaceFlag
        scCoeff = adsorptionCoeff * distanceVar.cellInterfaceAreas / mesh.cellVolumes

        self.eq += ImplicitSourceTerm(spCoeff) - scCoeff

        if otherVar is not None:
            otherSpCoeff = self.dt * otherBulkVar * otherRateConstant * distanceVar._cellInterfaceFlag
            otherScCoeff = -otherVar.interfaceVar * scCoeff

            self.eq += ImplicitSourceTerm(otherSpCoeff) - otherScCoeff

            vars = (surfactantVar, otherVar)
        else:
            vars = (surfactantVar, )

        total = 0
        for var in vars:
            total += var.interfaceVar
        maxVar = (total > 1) * distanceVar._cellInterfaceFlag

        val = distanceVar.cellInterfaceAreas / mesh.cellVolumes
        for var in vars[1:]:
            val -= distanceVar._cellInterfaceFlag * var

        spMaxCoeff = 1e20 * maxVar
        scMaxCoeff = spMaxCoeff * val * (val > 0)

        self.eq += ImplicitSourceTerm(spMaxCoeff) - scMaxCoeff - 1e-40

        if consumptionCoeff is not None:
            self.eq += ImplicitSourceTerm(consumptionCoeff)

    def solve(self, var, boundaryConditions=(), solver=None, dt=None):
        """
        Builds and solves the `AdsorbingSurfactantEquation`'s linear system once.

        :Parameters:
           - `var`: A `SurfactantVariable` to be solved for. Provides the initial condition, the old value and holds the solution on completion.
           - `solver`: The iterative solver to be used to solve the linear system of equations.
           - `boundaryConditions`: A tuple of boundaryConditions.
           - `dt`: The time step size.

	"""
        self.dt.setValue(dt)
        if solver is None:
            import fipy.solvers.solver
            if fipy.solvers.solver == 'pyamg':
                from fipy.solvers.pyAMG.linearGeneralSolver import LinearGeneralSolver
                solver = LinearGeneralSolver(tolerance=1e-15, iterations=2000)
            else:
                from fipy.solvers import LinearPCGSolver
                solver = LinearPCGSolver()

        if type(boundaryConditions) not in (type(()), type([])):
            boundaryConditions = (boundaryConditions, )

        var.constrain(0, var.mesh.exteriorFaces)

        self.eq.solve(var,
                      boundaryConditions=boundaryConditions,
                      solver=solver,
                      dt=1.)

    def sweep(self,
              var,
              solver=None,
              boundaryConditions=(),
              dt=None,
              underRelaxation=None,
              residualFn=None):
        r"""
        Builds and solves the `AdsorbingSurfactantEquation`'s linear
        system once. This method also recalculates and returns the
        residual as well as applying under-relaxation.

        :Parameters:

           - `var`: The variable to be solved for. Provides the initial condition, the old value and holds the solution on completion.
           - `solver`: The iterative solver to be used to solve the linear system of equations.
           - `boundaryConditions`: A tuple of boundaryConditions.
           - `dt`: The time step size.
           - `underRelaxation`: Usually a value between `0` and `1` or `None` in the case of no under-relaxation

	"""
        self.dt.setValue(dt)
        if solver is None:
            from fipy.solvers import DefaultAsymmetricSolver
            solver = DefaultAsymmetricSolver()

        if type(boundaryConditions) not in (type(()), type([])):
            boundaryConditions = (boundaryConditions, )

        var.constrain(0, var.mesh.exteriorFaces)

        return self.eq.sweep(var,
                             solver=solver,
                             boundaryConditions=boundaryConditions,
                             underRelaxation=underRelaxation,
                             residualFn=residualFn,
                             dt=1.)
Esempio n. 24
0
phase = CellVariable(name='PhaseField', mesh=mesh, value=1.)

from fipy.variables.modularVariable import ModularVariable

theta = ModularVariable(name='Theta', mesh=mesh, value=1.)
theta.setValue(0., where=mesh.getCellCenters()[..., 0] > L / 2.)

from fipy.terms.implicitSourceTerm import ImplicitSourceTerm

mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
thetaMag = theta.getOld().getGrad().getMag()
implicitSource = mPhiVar * (phase - (mPhiVar < 0))
implicitSource += (2 * s + epsilon**2 * thetaMag) * thetaMag

from fipy.terms.transientTerm import TransientTerm
from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
phaseEq = TransientTerm(phaseTransientCoeff) == \
          ExplicitDiffusionTerm(alpha**2) \
          - ImplicitSourceTerm(implicitSource) \
          + (mPhiVar > 0) * mPhiVar * phase

if __name__ == '__main__':

    import fipy.viewers
    phaseViewer = fipy.viewers.make(vars=phase)
    phaseViewer.plot()
    for step in range(steps):
        phaseEq.solve(phase, dt=timeStepDuration)
        phaseViewer.plot()
    raw_input('finished')
Esempio n. 25
0
    def __init__(self,
                 surfactantVar=None,
                 distanceVar=None,
                 bulkVar=None,
                 rateConstant=None,
                 otherVar=None,
                 otherBulkVar=None,
                 otherRateConstant=None,
                 consumptionCoeff=None):
        """
        Create a `AdsorbingSurfactantEquation` object.

        :Parameters:
          - `surfactantVar`: The `SurfactantVariable` to be solved for.
          - `distanceVar`: The `DistanceVariable` that marks the interface.
          - `bulkVar`: The value of the `surfactantVar` in the bulk.
          - `rateConstant`: The adsorption rate of the `surfactantVar`.
          - `otherVar`: Another `SurfactantVariable` with more surface affinity.
          - `otherBulkVar`: The value of the `otherVar` in the bulk.
          - `otherRateConstant`: The adsorption rate of the `otherVar`.
          - `consumptionCoeff`: The rate that the `surfactantVar` is consumed during deposition.

        """

        self.eq = TransientTerm(coeff=1) - ExplicitUpwindConvectionTerm(
            SurfactantConvectionVariable(distanceVar))

        self.dt = Variable(0.)
        mesh = distanceVar.mesh
        adsorptionCoeff = self.dt * bulkVar * rateConstant
        spCoeff = adsorptionCoeff * distanceVar._cellInterfaceFlag
        scCoeff = adsorptionCoeff * distanceVar.cellInterfaceAreas / mesh.cellVolumes

        self.eq += ImplicitSourceTerm(spCoeff) - scCoeff

        if otherVar is not None:
            otherSpCoeff = self.dt * otherBulkVar * otherRateConstant * distanceVar._cellInterfaceFlag
            otherScCoeff = -otherVar.interfaceVar * scCoeff

            self.eq += ImplicitSourceTerm(otherSpCoeff) - otherScCoeff

            vars = (surfactantVar, otherVar)
        else:
            vars = (surfactantVar, )

        total = 0
        for var in vars:
            total += var.interfaceVar
        maxVar = (total > 1) * distanceVar._cellInterfaceFlag

        val = distanceVar.cellInterfaceAreas / mesh.cellVolumes
        for var in vars[1:]:
            val -= distanceVar._cellInterfaceFlag * var

        spMaxCoeff = 1e20 * maxVar
        scMaxCoeff = spMaxCoeff * val * (val > 0)

        self.eq += ImplicitSourceTerm(spMaxCoeff) - scMaxCoeff - 1e-40

        if consumptionCoeff is not None:
            self.eq += ImplicitSourceTerm(consumptionCoeff)
Esempio n. 26
0
dx = 1.
dy = 1.
nx = 10
ny = 1
valueLeft = 0.
valueRight = 1.
timeStepDuration = 0.02

mesh = Tri2D(dx, dy, nx, ny)

var = CellVariable(
    name = "concentration",
    mesh = mesh,
    value = valueLeft)

eq = TransientTerm() == ExplicitDiffusionTerm()

solver = LinearLUSolver(tolerance = 1.e-6, iterations = 100)

boundaryConditions=(FixedValue(mesh.getFacesLeft(),valueLeft),
                    FixedValue(mesh.getFacesRight(),valueRight))

answer = numerix.array([  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
                          0.00000000e+00,  0.00000000e+00,  1.58508452e-07,  6.84325019e-04,
                          7.05111362e-02,  7.81376523e-01,  0.00000000e+00,  0.00000000e+00,
                          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
                          0.00000000e+00,  4.99169535e-05,  1.49682805e-02,  3.82262622e-01,
                          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
                          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  4.06838361e-06,
                          3.67632029e-03,  1.82227062e-01,  0.00000000e+00,  0.00000000e+00,
                          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
Esempio n. 27
0
File: input2D.py Progetto: ghorn/Eg
mesh = Grid2D(dx, dy, nx, ny)

from fipy.variables.cellVariable import CellVariable
from fipy.tools.numerix import random

var = CellVariable(name="phase field", mesh=mesh, value=random.random(nx * ny))

faceVar = var.getArithmeticFaceValue()
doubleWellDerivative = asq * (1 - 6 * faceVar * (1 - faceVar))

from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
from fipy.terms.transientTerm import TransientTerm
diffTerm2 = ImplicitDiffusionTerm(coeff=(diffusionCoeff *
                                         doubleWellDerivative, ))
diffTerm4 = ImplicitDiffusionTerm(coeff=(diffusionCoeff, -epsilon**2))
eqch = TransientTerm() - diffTerm2 - diffTerm4

from fipy.solvers.linearPCGSolver import LinearPCGSolver
from fipy.solvers.linearLUSolver import LinearLUSolver
##solver = LinearLUSolver(tolerance = 1e-15,steps = 1000)
solver = LinearPCGSolver(tolerance=1e-15, steps=1000)

from fipy.boundaryConditions.fixedValue import FixedValue
from fipy.boundaryConditions.fixedFlux import FixedFlux
from fipy.boundaryConditions.nthOrderBoundaryCondition import NthOrderBoundaryCondition
BCs = (FixedFlux(mesh.getFacesRight(), 0), FixedFlux(mesh.getFacesLeft(), 0),
       NthOrderBoundaryCondition(mesh.getFacesLeft(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesRight(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesTop(), 0, 3),
       NthOrderBoundaryCondition(mesh.getFacesBottom(), 0, 3))
Esempio n. 28
0
    phaseY = phase.getFaceGrad().dot((0, 1))
    phaseX = phase.getFaceGrad().dot((1, 0))
    psi = theta + numerix.arctan2(phaseY, phaseX)
    Phi = numerix.tan(N * psi / 2)
    PhiSq = Phi**2
    beta = (1. - PhiSq) / (1. + PhiSq)
    betaPsi = -N * 2 * Phi / (1 + PhiSq)
    A = alpha**2 * c * (1.+ c * beta) * betaPsi
    D = alpha**2 * (1.+ c * beta)**2
    dxi = phase.getFaceGrad()._take((1, 0), axis = 1) * (-1, 1)
    anisotropySource = (A * dxi).getDivergence()
    from fipy.terms.transientTerm import TransientTerm
    from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm
    from fipy.terms.implicitSourceTerm import ImplicitSourceTerm
    phaseEq = TransientTerm(tau) == ExplicitDiffusionTerm(D) + \
        ImplicitSourceTerm(mVar * ((mVar < 0) - phase)) + \
        ((mVar > 0.) * mVar * phase + anisotropySource)

    from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
    temperatureEq = TransientTerm() == \
                    ImplicitDiffusionTerm(tempDiffusionCoeff) + \
                    (phase - phase.getOld()) / timeStepDuration

    bench.stop('terms')

    phase.updateOld()
    temperature.updateOld()
    phaseEq.solve(phase, dt=timeStepDuration)
    temperatureEq.solve(temperature, dt=timeStepDuration)

    steps = 10
Esempio n. 29
0
    bench.start()

    from fipy.variables.cellVariable import CellVariable
    C = CellVariable(mesh=mesh)
    C.setValue(1, where=abs(mesh.getCellCenters()[..., 0] - L / 2.) < L / 10.)

    bench.stop('variables')

    bench.start()

    D = 1.

    from fipy.terms.implicitDiffusionTerm import ImplicitDiffusionTerm
    from fipy.terms.transientTerm import TransientTerm
    eq = TransientTerm() == ImplicitDiffusionTerm(coeff=D)

    bench.stop('terms')

    ## from fipy import viewers
    ## viewer = viewers.make(vars = C, limits = {'datamin': 0, 'datamax': 1})
    ## viewer.plot()
    ## raw_input("initial")

    bench.start()

    dt = 1e0
    steps = 1
    for step in range(steps):
        eq.solve(var=C, dt=dt)
    ##     viewer.plot()