def _getOldAdjacentValues(self, oldArray, id1, id2, dt):
        oldArray1, oldArray2 = ExplicitUpwindConvectionTerm._getOldAdjacentValues(self, oldArray, id1, id2, dt)
        
        mesh = oldArray.mesh

        interiorIDs = numerix.nonzero(mesh.interiorFaces)[0]
        interiorFaceAreas = numerix.take(mesh._faceAreas, interiorIDs)
        interiorFaceNormals = numerix.take(mesh._orientedFaceNormals, interiorIDs, axis=-1)
        
        # Courant-Friedrichs-Levy number
        interiorCFL = abs(numerix.take(self._getGeomCoeff(oldArray), interiorIDs)) * dt
        
        gradUpwind = (oldArray2 - oldArray1) / numerix.take(mesh._cellDistances, interiorIDs)
        
        vol1 = numerix.take(mesh.cellVolumes, id1)
        
        oldArray1 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.grad, id1, axis=-1), interiorFaceNormals), gradUpwind) \
            * (vol1 - interiorCFL) / interiorFaceAreas

        vol2 = numerix.take(mesh.cellVolumes, id2)
        
        oldArray2 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.grad, id2, axis=-1), -interiorFaceNormals), -gradUpwind) \
            * (vol2 - interiorCFL) / interiorFaceAreas
        
        return oldArray1, oldArray2
    def _getOldAdjacentValues(self, oldArray, id1, id2, dt):
        oldArray1, oldArray2 = ExplicitUpwindConvectionTerm._getOldAdjacentValues(self, oldArray, id1, id2, dt)
        
        mesh = oldArray.getMesh()

        interiorIDs = numerix.nonzero(mesh.getInteriorFaces())[0]
        interiorFaceAreas = numerix.take(mesh._getFaceAreas(), interiorIDs)
        interiorFaceNormals = numerix.take(mesh._getOrientedFaceNormals(), interiorIDs, axis=-1)
        
        # Courant-Friedrichs-Levy number
        interiorCFL = abs(numerix.take(self._getGeomCoeff(mesh), interiorIDs)) * dt
        
        gradUpwind = (oldArray2 - oldArray1) / numerix.take(mesh._getCellDistances(), interiorIDs)
        
        vol1 = numerix.take(mesh.getCellVolumes(), id1)
        self.CFL = interiorCFL / vol1
        
        oldArray1 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.getGrad(), id1, axis=-1), interiorFaceNormals), gradUpwind) \
            * (vol1 - interiorCFL) / interiorFaceAreas

        vol2 = numerix.take(mesh.getCellVolumes(), id2)
        
        self.CFL = numerix.maximum(interiorCFL / vol2, self.CFL)

        oldArray2 += 0.5 * self._getGradient(numerix.dot(numerix.take(oldArray.getGrad(), id2, axis=-1), -interiorFaceNormals), -gradUpwind) \
            * (vol2 - interiorCFL) / interiorFaceAreas
        
        return oldArray1, oldArray2
Exemple #3
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')
Exemple #4
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)