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
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')
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)