'datamax': 100. }) velocityViewer = fipy.viewers.make(vars=velocity, limits={ 'datamin': 0., 'datamax': 200. }) distanceViewer.plot() surfactantViewer.plot() velocityViewer.plot() totalTime = 0 for step in range(steps): print 'step', step velocity.setValue(surfactantVariable.getInterfaceVar() * k) distanceVariable.extendVariable(velocity) timeStepDuration = cfl * dx / numerix.max(velocity) distanceVariable.updateOld() advectionEquation.solve(distanceVariable, dt=timeStepDuration) surfactantEquation.solve(surfactantVariable) totalTime += timeStepDuration velocityViewer.plot() distanceViewer.plot() surfactantViewer.plot() finalRadius = numerix.sqrt(2 * k * initialRadius * initialSurfactantValue * totalTime + initialRadius**2)
timeStepDuration = cfl * dx / velocity distanceVariable.updateOld() distanceVariable.setValue(numerix.array(distanceVariable) - velocity * timeStepDuration) surfactantEquation.solve(surfactantVariable) totalTime += timeStepDuration distanceViewer.plot() surfactantViewer.plot() errorViewer.plot() finalRadius = initialRadius + totalTime * velocity + distanceVariable answer = initialSurfactantValue * initialRadius / finalRadius coverage = surfactantVariable.getInterfaceVar() error.setValue(numerix.where((coverage > 1e-3) & (distanceVariable > 0), abs(coverage - answer), 0)) adjDistanceVariables = numerix.take(distanceVariable, mesh._getCellToCellIDs()) adjCoverages = numerix.take(coverage, mesh._getCellToCellIDs()) flag = (adjDistanceVariables < 0) & (adjCoverages > 1e-6) error.setValue(0, where=numerix.sum(flag, index=1) > 0) del L1[0] del L2[0] del Linf[0]
from fipy.variables.modularVariable import ModularVariable pi = numerix.pi theta = ModularVariable( name = 'Theta', mesh = mesh, value = -pi + 0.0001, hasOld = 1 ) x, y = mesh.getCellCenters()[...,0], mesh.getCellCenters()[...,1] for a, b, thetaValue in ((0., 0., 2. * pi / 3.), (Lx, 0., -2. * pi / 3.), (0., Lx, -2. * pi / 3. + 0.3), (Lx, Lx, 2. * pi / 3.)): segment = (x - a)**2 + (y - b)**2 < (Lx / 2.)**2 phase.setValue(1., where=segment) theta.setValue(thetaValue, where=segment) bench.stop('variables') bench.start() from fipy.terms.transientTerm import TransientTerm from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm from fipy.terms.implicitSourceTerm import ImplicitSourceTerm def buildPhaseEquation(phase, theta): mPhiVar = phase - 0.5 + temperature * phase * (1 - phase)
newIntensity = np.zeros(nx * ny * nz) mesh = Grid3D(dx, dy, dz, nx, ny, nz) print(intensity.shape) print("Setting phase...") # flatten 3D array to 1D newIntensity = intensity.flatten() print("newIntensity:") print(newIntensity) # set phase t3 = time.time() phase = CellVariable(mesh, value=0.0) phase.setValue(1 - newIntensity / 255) #Thresholding step. Values less than 255 are assigned 0. #empty space 0-254 -> 1 - 0/255 -> 1 #particles 255 -> 1 - 1 -> 0 #sets empty space phase=0, particles phase=1 print("phase:") print(phase) t4 = time.time() print("Phase Set!") # Set diffusivity. print("Setting D...") t5 = time.time() D = 1.0e-3 * phase + 1.0 * (1.0 - phase) #sets empty space to 1.0, particles to 1e-3
FixedValue( mesh.getFacesTop(), catalystConcentration ),) bench.stop('BCs') levelSetUpdateFrequency = int(0.8 * narrowBandWidth \ / (cellSize * cflNumber * 2)) step = 0 if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction() extensionVelocityVariable.setValue(depositionRateVariable()) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() bulkCatalystVar.updateOld() distanceVar.extendVariable(extensionVelocityVariable) dt = cflNumber * cellSize / numerix.max(extensionVelocityVariable) advectionEquation.solve(distanceVar, dt = dt) surfactantEquation.solve(catalystVar, dt = dt) metalEquation.solve(metalVar, dt = dt, boundaryConditions = metalEquationBCs) bulkCatalystEquation.solve(bulkCatalystVar, dt = dt, boundaryConditions = catalystBCs) bench.start()
if __name__ == '__main__': import fipy.viewers distanceViewer = fipy.viewers.make(vars = distanceVariable, limits = {'datamin': -initialRadius, 'datamax': initialRadius}) surfactantViewer = fipy.viewers.make(vars = surfactantVariable, limits = {'datamin': 0., 'datamax': 100.}) velocityViewer = fipy.viewers.make(vars = velocity, limits = {'datamin': 0., 'datamax': 200.}) distanceViewer.plot() surfactantViewer.plot() velocityViewer.plot() totalTime = 0 for step in range(steps): print 'step',step velocity.setValue(surfactantVariable.getInterfaceVar() * k) distanceVariable.extendVariable(velocity) timeStepDuration = cfl * dx / numerix.max(velocity) distanceVariable.updateOld() advectionEquation.solve(distanceVariable, dt = timeStepDuration) surfactantEquation.solve(surfactantVariable) totalTime += timeStepDuration velocityViewer.plot() distanceViewer.plot() surfactantViewer.plot() finalRadius = numerix.sqrt(2 * k * initialRadius * initialSurfactantValue * totalTime + initialRadius**2) answer = initialSurfactantValue * initialRadius / finalRadius coverage = surfactantVariable.getInterfaceVar()
bench.start() timeStepDuration = 5e-5 tau = 3e-4 alpha = 0.015 c = 0.02 N = 4. kappa1 = 0.9 kappa2 = 20. tempDiffusionCoeff = 2.25 theta = 0. from fipy.variables.cellVariable import CellVariable phase = CellVariable(name='phase field', mesh=mesh, hasOld=1) x, y = mesh.getCellCenters()[..., 0], mesh.getCellCenters()[..., 1] phase.setValue(1., where=(x - seedCenter[0])**2 + (y - seedCenter[1])**2 < radius**2) temperature = CellVariable(name='temperature', mesh=mesh, value=initialTemperature, hasOld=1) bench.stop('variables') bench.start() from fipy.tools import numerix mVar = phase - 0.5 - kappa1 / numerix.pi * \ numerix.arctan(kappa2 * temperature) phaseY = phase.getFaceGrad().dot((0, 1))
## from fipy.meshes.numMesh.grid1D import Grid1D from fipy.meshes.numMesh.uniformGrid1D import UniformGrid1D as Grid1D N = 100000 L = 10. dx = L / N mesh = Grid1D(nx = N, dx = dx) bench.stop('mesh') 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})
from fipy.variables.cellVariable import CellVariable phase = CellVariable(name='PhaseField', mesh=mesh, value=0.) from fipy.variables.modularVariable import ModularVariable pi = numerix.pi theta = ModularVariable(name='Theta', mesh=mesh, value=-pi + 0.0001, hasOld=1) x, y = mesh.getCellCenters()[..., 0], mesh.getCellCenters()[..., 1] for a, b, thetaValue in ((0., 0., 2. * pi / 3.), (Lx, 0., -2. * pi / 3.), (0., Lx, -2. * pi / 3. + 0.3), (Lx, Lx, 2. * pi / 3.)): segment = (x - a)**2 + (y - b)**2 < (Lx / 2.)**2 phase.setValue(1., where=segment) theta.setValue(thetaValue, where=segment) bench.stop('variables') bench.start() from fipy.terms.transientTerm import TransientTerm from fipy.terms.explicitDiffusionTerm import ExplicitDiffusionTerm from fipy.terms.implicitSourceTerm import ImplicitSourceTerm def buildPhaseEquation(phase, theta): mPhiVar = phase - 0.5 + temperature * phase * (1 - phase) thetaMag = theta.getOld().getGrad().getMag() implicitSource = mPhiVar * (phase - (mPhiVar < 0))
def runLeveler(kLeveler=0.018, bulkLevelerConcentration=0.02, cellSize=0.1e-7, rateConstant=0.00026, initialAcceleratorCoverage=0.0, levelerDiffusionCoefficient=5e-10, numberOfSteps=400, displayRate=10, displayViewers=True): kLevelerConsumption = 0.0005 aspectRatio = 1.5 faradaysConstant = 9.6485e4 gasConstant = 8.314 acceleratorDiffusionCoefficient = 4e-10 siteDensity = 6.35e-6 atomicVolume = 7.1e-6 charge = 2 metalDiffusionCoefficient = 4e-10 temperature = 298. overpotential = -0.25 bulkMetalConcentration = 250. bulkAcceleratorConcentration = 50.0e-3 initialLevelerCoverage = 0. cflNumber = 0.2 numberOfCellsInNarrowBand = 20 cellsBelowTrench = 10 trenchDepth = 0.4e-6 trenchSpacing = 0.6e-6 boundaryLayerDepth = 98.7e-6 i0Suppressor = 0.3 i0Accelerator = 22.5 alphaSuppressor = 0.5 alphaAccelerator = 0.4 alphaAdsorption = 0.62 m = 4 b = 2.65 A = 0.3 Ba = -40 Bb = 60 Vd = 0.098 Bd = 0.0008 etaPrime = faradaysConstant * overpotential / gasConstant / temperature from fipy import TrenchMesh from fipy.tools import numerix mesh = TrenchMesh(cellSize = cellSize, trenchSpacing = trenchSpacing, trenchDepth = trenchDepth, boundaryLayerDepth = boundaryLayerDepth, aspectRatio = aspectRatio, angle = numerix.pi * 4. / 180., bowWidth = 0., overBumpRadius = 0., overBumpWidth = 0.) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable distanceVar = DistanceVariable( name = 'distance variable', mesh = mesh, value = -1, narrowBandWidth = narrowBandWidth) distanceVar.setValue(1, where=mesh.getElectrolyteMask()) distanceVar.calcDistanceFunction(narrowBandWidth = 1e10) from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable levelerVar = SurfactantVariable( name = "leveler variable", value = initialLevelerCoverage, distanceVar = distanceVar) acceleratorVar = SurfactantVariable( name = "accelerator variable", value = initialAcceleratorCoverage, distanceVar = distanceVar) from fipy.variables.cellVariable import CellVariable bulkAcceleratorVar = CellVariable(name = 'bulk accelerator variable', mesh = mesh, value = bulkAcceleratorConcentration) bulkLevelerVar = CellVariable( name = 'bulk leveler variable', mesh = mesh, value = bulkLevelerConcentration) metalVar = CellVariable( name = 'metal variable', mesh = mesh, value = bulkMetalConcentration) def depositionCoeff(alpha, i0): expo = numerix.exp(-alpha * etaPrime) return 2 * i0 * (expo - expo * numerix.exp(etaPrime)) coeffSuppressor = depositionCoeff(alphaSuppressor, i0Suppressor) coeffAccelerator = depositionCoeff(alphaAccelerator, i0Accelerator) exchangeCurrentDensity = acceleratorVar.getInterfaceVar() * (coeffAccelerator - coeffSuppressor) + coeffSuppressor currentDensity = metalVar / bulkMetalConcentration * exchangeCurrentDensity depositionRateVariable = currentDensity * atomicVolume / charge / faradaysConstant extensionVelocityVariable = CellVariable( name = 'extension velocity', mesh = mesh, value = depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation kAccelerator = rateConstant * numerix.exp(-alphaAdsorption * etaPrime) kAcceleratorConsumption = Bd + A / (numerix.exp(Ba * (overpotential + Vd)) + numerix.exp(Bb * (overpotential + Vd))) q = m * overpotential + b levelerSurfactantEquation = AdsorbingSurfactantEquation( levelerVar, distanceVar = distanceVar, bulkVar = bulkLevelerVar, rateConstant = kLeveler, consumptionCoeff = kLevelerConsumption * depositionRateVariable) accVar1 = acceleratorVar.getInterfaceVar() accVar2 = (accVar1 > 0) * accVar1 accConsumptionCoeff = kAcceleratorConsumption * (accVar2**(q - 1)) acceleratorSurfactantEquation = AdsorbingSurfactantEquation( acceleratorVar, distanceVar = distanceVar, bulkVar = bulkAcceleratorVar, rateConstant = kAccelerator, otherVar = levelerVar, otherBulkVar = bulkLevelerVar, otherRateConstant = kLeveler, consumptionCoeff = accConsumptionCoeff) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff = extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar = metalVar, distanceVar = distanceVar, depositionRate = depositionRateVariable, diffusionCoeff = metalDiffusionCoefficient, metalIonMolarVolume = atomicVolume) metalEquationBCs = FixedValue(mesh.getTopFaces(), bulkMetalConcentration) from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \ import buildSurfactantBulkDiffusionEquation bulkAcceleratorEquation = buildSurfactantBulkDiffusionEquation( bulkVar = bulkAcceleratorVar, distanceVar = distanceVar, surfactantVar = acceleratorVar, otherSurfactantVar = levelerVar, diffusionCoeff = acceleratorDiffusionCoefficient, rateConstant = kAccelerator * siteDensity) bulkAcceleratorEquationBCs = (FixedValue( mesh.getTopFaces(), bulkAcceleratorConcentration),) bulkLevelerEquation = buildSurfactantBulkDiffusionEquation( bulkVar = bulkLevelerVar, distanceVar = distanceVar, surfactantVar = levelerVar, diffusionCoeff = levelerDiffusionCoefficient, rateConstant = kLeveler * siteDensity) bulkLevelerEquationBCs = (FixedValue( mesh.getTopFaces(), bulkLevelerConcentration),) eqnTuple = ( (advectionEquation, distanceVar, ()), (levelerSurfactantEquation, levelerVar, ()), (acceleratorSurfactantEquation, acceleratorVar, ()), (metalEquation, metalVar, metalEquationBCs), (bulkAcceleratorEquation, bulkAcceleratorVar, bulkAcceleratorEquationBCs), (bulkLevelerEquation, bulkLevelerVar, bulkLevelerEquationBCs)) levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2) totalTime = 0.0 if displayViewers: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = ( MayaviSurfactantViewer(distanceVar, acceleratorVar.getInterfaceVar(), zoomFactor = 1e6, limits = { 'datamax' : 0.5, 'datamin' : 0.0 }, smooth = 1, title = 'accelerator coverage'), MayaviSurfactantViewer(distanceVar, levelerVar.getInterfaceVar(), zoomFactor = 1e6, limits = { 'datamax' : 0.5, 'datamin' : 0.0 }, smooth = 1, title = 'leveler coverage')) for step in range(numberOfSteps): if displayViewers: if step % displayRate == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction(deleteIslands = True) extensionVelocityVariable.setValue(depositionRateVariable) extOnInt = numerix.where(distanceVar > 0, numerix.where(distanceVar < 2 * cellSize, extensionVelocityVariable, 0), 0) dt = cflNumber * cellSize / numerix.max(extOnInt) id = numerix.max(numerix.nonzero(distanceVar._getInterfaceFlag())) distanceVar.extendVariable(extensionVelocityVariable, deleteIslands = True) extensionVelocityVariable[mesh.getFineMesh().getNumberOfCells():] = 0. for eqn, var, BCs in eqnTuple: var.updateOld() for eqn, var, BCs in eqnTuple: eqn.solve(var, boundaryConditions = BCs, dt = dt) totalTime += dt try: testFile = 'testLeveler.gz' import os import examples.levelSet.electroChem from fipy.tools import dump data = dump.read(os.path.join(examples.levelSet.electroChem.__path__[0], testFile)) N = mesh.getFineMesh().getNumberOfCells() print numerix.allclose(data[:N], levelerVar[:N], rtol = 1e-3) except: return 0
L = nx * dx from fipy.meshes.grid2D import Grid2D mesh = Grid2D(nx=nx, dx=dx) # 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):
def runGold(faradaysConstant=9.6e4, consumptionRateConstant=2.6e+6, molarVolume=10.21e-6, charge=1.0, metalDiffusion=1.7e-9, metalConcentration=20.0, catalystCoverage=0.15, currentDensity0=3e-2 * 16, currentDensity1=6.5e-1 * 16, cellSize=0.1e-7, trenchDepth=0.2e-6, aspectRatio=1.47, trenchSpacing=0.5e-6, boundaryLayerDepth=90.0e-6, numberOfSteps=10, taperAngle=6.0, displayViewers=True): cflNumber = 0.2 numberOfCellsInNarrowBand = 20 cellsBelowTrench = 10 from fipy.tools import numerix from fipy import TrenchMesh mesh = TrenchMesh(cellSize = cellSize, trenchSpacing = trenchSpacing, trenchDepth = trenchDepth, boundaryLayerDepth = boundaryLayerDepth, aspectRatio = aspectRatio, angle = numerix.pi * taperAngle / 180., bowWidth = 0., overBumpRadius = 0., overBumpWidth = 0.) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable distanceVar = DistanceVariable( name = 'distance variable', mesh = mesh, value = -1, narrowBandWidth = narrowBandWidth) distanceVar.setValue(1, where=mesh.getElectrolyteMask()) distanceVar.calcDistanceFunction(narrowBandWidth = 1e10) from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable catalystVar = SurfactantVariable( name = "catalyst variable", value = catalystCoverage, distanceVar = distanceVar) from fipy.variables.cellVariable import CellVariable metalVar = CellVariable( name = 'metal variable', mesh = mesh, value = metalConcentration) exchangeCurrentDensity = currentDensity0 + currentDensity1 * catalystVar.getInterfaceVar() currentDensity = metalVar / metalConcentration * exchangeCurrentDensity depositionRateVariable = currentDensity * molarVolume / charge / faradaysConstant extensionVelocityVariable = CellVariable( name = 'extension velocity', mesh = mesh, value = depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation catalystSurfactantEquation = AdsorbingSurfactantEquation( catalystVar, distanceVar = distanceVar, bulkVar = 0, rateConstant = 0, consumptionCoeff = consumptionRateConstant * extensionVelocityVariable) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff = extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar = metalVar, distanceVar = distanceVar, depositionRate = depositionRateVariable, diffusionCoeff = metalDiffusion, metalIonMolarVolume = molarVolume) metalEquationBCs = FixedValue(mesh.getTopFaces(), metalConcentration) if displayViewers: try: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = ( MayaviSurfactantViewer(distanceVar, catalystVar.getInterfaceVar(), zoomFactor = 1e6, limits = { 'datamax' : 1.0, 'datamin' : 0.0 }, smooth = 1, title = 'catalyst coverage'),) except: class PlotVariable(CellVariable): def __init__(self, var = None, name = ''): CellVariable.__init__(self, mesh = mesh.getFineMesh(), name = name) self.var = self._requires(var) def _calcValue(self): return numerix.array(self.var[:self.mesh.getNumberOfCells()]) from fipy.viewers import make viewers = ( make(PlotVariable(var = distanceVar), limits = {'datamax' : 1e-9, 'datamin' : -1e-9}), make(PlotVariable(var = catalystVar.getInterfaceVar()))) else: viewers = () levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2) step = 0 while step < numberOfSteps: if step % 10 == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction(deleteIslands = True) extensionVelocityVariable.setValue(numerix.array(depositionRateVariable)) argmax = numerix.argmax(extensionVelocityVariable) dt = cflNumber * cellSize / extensionVelocityVariable[argmax] distanceVar.extendVariable(extensionVelocityVariable, deleteIslands = True) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() advectionEquation.solve(distanceVar, dt = dt) catalystSurfactantEquation.solve(catalystVar, dt = dt) metalEquation.solve(metalVar, boundaryConditions = metalEquationBCs, dt = dt) step += 1 try: from fipy.tools import dump import os import examples.levelSet.electroChem data = dump.read(os.path.join(examples.levelSet.electroChem.__path__[0], 'goldData.gz')) n = mesh.getFineMesh().getNumberOfCells() print numerix.allclose(catalystVar[:n], data[:n], atol=1.0) except: return 0
## from fipy.meshes.numMesh.grid1D import Grid1D from fipy.meshes.numMesh.uniformGrid1D import UniformGrid1D as Grid1D N = 100000 L = 10. dx = L / N mesh = Grid1D(nx=N, dx=dx) bench.stop('mesh') 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})
def runGold(faradaysConstant=9.6e4, consumptionRateConstant=2.6e+6, molarVolume=10.21e-6, charge=1.0, metalDiffusion=1.7e-9, metalConcentration=20.0, catalystCoverage=0.15, currentDensity0=3e-2 * 16, currentDensity1=6.5e-1 * 16, cellSize=0.1e-7, trenchDepth=0.2e-6, aspectRatio=1.47, trenchSpacing=0.5e-6, boundaryLayerDepth=90.0e-6, numberOfSteps=10, taperAngle=6.0, displayViewers=True): cflNumber = 0.2 numberOfCellsInNarrowBand = 20 cellsBelowTrench = 10 from fipy.tools import numerix from fipy import TrenchMesh mesh = TrenchMesh(cellSize=cellSize, trenchSpacing=trenchSpacing, trenchDepth=trenchDepth, boundaryLayerDepth=boundaryLayerDepth, aspectRatio=aspectRatio, angle=numerix.pi * taperAngle / 180., bowWidth=0., overBumpRadius=0., overBumpWidth=0.) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable distanceVar = DistanceVariable(name='distance variable', mesh=mesh, value=-1, narrowBandWidth=narrowBandWidth) distanceVar.setValue(1, where=mesh.getElectrolyteMask()) distanceVar.calcDistanceFunction(narrowBandWidth=1e10) from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable catalystVar = SurfactantVariable(name="catalyst variable", value=catalystCoverage, distanceVar=distanceVar) from fipy.variables.cellVariable import CellVariable metalVar = CellVariable(name='metal variable', mesh=mesh, value=metalConcentration) exchangeCurrentDensity = currentDensity0 + currentDensity1 * catalystVar.getInterfaceVar( ) currentDensity = metalVar / metalConcentration * exchangeCurrentDensity depositionRateVariable = currentDensity * molarVolume / charge / faradaysConstant extensionVelocityVariable = CellVariable(name='extension velocity', mesh=mesh, value=depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation catalystSurfactantEquation = AdsorbingSurfactantEquation( catalystVar, distanceVar=distanceVar, bulkVar=0, rateConstant=0, consumptionCoeff=consumptionRateConstant * extensionVelocityVariable) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff=extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar=metalVar, distanceVar=distanceVar, depositionRate=depositionRateVariable, diffusionCoeff=metalDiffusion, metalIonMolarVolume=molarVolume) metalEquationBCs = FixedValue(mesh.getTopFaces(), metalConcentration) if displayViewers: try: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = (MayaviSurfactantViewer(distanceVar, catalystVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 1.0, 'datamin': 0.0 }, smooth=1, title='catalyst coverage'), ) except: class PlotVariable(CellVariable): def __init__(self, var=None, name=''): CellVariable.__init__(self, mesh=mesh.getFineMesh(), name=name) self.var = self._requires(var) def _calcValue(self): return numerix.array( self.var[:self.mesh.getNumberOfCells()]) from fipy.viewers import make viewers = (make(PlotVariable(var=distanceVar), limits={ 'datamax': 1e-9, 'datamin': -1e-9 }), make(PlotVariable(var=catalystVar.getInterfaceVar()))) else: viewers = () levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2) step = 0 while step < numberOfSteps: if step % 10 == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction(deleteIslands=True) extensionVelocityVariable.setValue( numerix.array(depositionRateVariable)) argmax = numerix.argmax(extensionVelocityVariable) dt = cflNumber * cellSize / extensionVelocityVariable[argmax] distanceVar.extendVariable(extensionVelocityVariable, deleteIslands=True) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() advectionEquation.solve(distanceVar, dt=dt) catalystSurfactantEquation.solve(catalystVar, dt=dt) metalEquation.solve(metalVar, boundaryConditions=metalEquationBCs, dt=dt) step += 1 try: from fipy.tools import dump import os import examples.levelSet.electroChem data = dump.read( os.path.join(examples.levelSet.electroChem.__path__[0], 'goldData.gz')) n = mesh.getFineMesh().getNumberOfCells() print numerix.allclose(catalystVar[:n], data[:n], atol=1.0) except: return 0
metalEquationBCs = (FixedValue(mesh.getFacesTop(), bulkMetalConcentration), ) catalystBCs = (FixedValue(mesh.getFacesTop(), catalystConcentration), ) bench.stop('BCs') levelSetUpdateFrequency = int(0.8 * narrowBandWidth \ / (cellSize * cflNumber * 2)) step = 0 if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction() extensionVelocityVariable.setValue(depositionRateVariable()) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() bulkCatalystVar.updateOld() distanceVar.extendVariable(extensionVelocityVariable) dt = cflNumber * cellSize / numerix.max(extensionVelocityVariable) advectionEquation.solve(distanceVar, dt=dt) surfactantEquation.solve(catalystVar, dt=dt) metalEquation.solve(metalVar, dt=dt, boundaryConditions=metalEquationBCs) bulkCatalystEquation.solve(bulkCatalystVar, dt=dt, boundaryConditions=catalystBCs) bench.start()
def runLeveler(kLeveler=0.018, bulkLevelerConcentration=0.02, cellSize=0.1e-7, rateConstant=0.00026, initialAcceleratorCoverage=0.0, levelerDiffusionCoefficient=5e-10, numberOfSteps=400, displayRate=10, displayViewers=True): kLevelerConsumption = 0.0005 aspectRatio = 1.5 faradaysConstant = 9.6485e4 gasConstant = 8.314 acceleratorDiffusionCoefficient = 4e-10 siteDensity = 6.35e-6 atomicVolume = 7.1e-6 charge = 2 metalDiffusionCoefficient = 4e-10 temperature = 298. overpotential = -0.25 bulkMetalConcentration = 250. bulkAcceleratorConcentration = 50.0e-3 initialLevelerCoverage = 0. cflNumber = 0.2 numberOfCellsInNarrowBand = 20 cellsBelowTrench = 10 trenchDepth = 0.4e-6 trenchSpacing = 0.6e-6 boundaryLayerDepth = 98.7e-6 i0Suppressor = 0.3 i0Accelerator = 22.5 alphaSuppressor = 0.5 alphaAccelerator = 0.4 alphaAdsorption = 0.62 m = 4 b = 2.65 A = 0.3 Ba = -40 Bb = 60 Vd = 0.098 Bd = 0.0008 etaPrime = faradaysConstant * overpotential / gasConstant / temperature from fipy import TrenchMesh from fipy.tools import numerix mesh = TrenchMesh(cellSize=cellSize, trenchSpacing=trenchSpacing, trenchDepth=trenchDepth, boundaryLayerDepth=boundaryLayerDepth, aspectRatio=aspectRatio, angle=numerix.pi * 4. / 180., bowWidth=0., overBumpRadius=0., overBumpWidth=0.) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import DistanceVariable distanceVar = DistanceVariable(name='distance variable', mesh=mesh, value=-1, narrowBandWidth=narrowBandWidth) distanceVar.setValue(1, where=mesh.getElectrolyteMask()) distanceVar.calcDistanceFunction(narrowBandWidth=1e10) from fipy.models.levelSet.surfactant.surfactantVariable import SurfactantVariable levelerVar = SurfactantVariable(name="leveler variable", value=initialLevelerCoverage, distanceVar=distanceVar) acceleratorVar = SurfactantVariable(name="accelerator variable", value=initialAcceleratorCoverage, distanceVar=distanceVar) from fipy.variables.cellVariable import CellVariable bulkAcceleratorVar = CellVariable(name='bulk accelerator variable', mesh=mesh, value=bulkAcceleratorConcentration) bulkLevelerVar = CellVariable(name='bulk leveler variable', mesh=mesh, value=bulkLevelerConcentration) metalVar = CellVariable(name='metal variable', mesh=mesh, value=bulkMetalConcentration) def depositionCoeff(alpha, i0): expo = numerix.exp(-alpha * etaPrime) return 2 * i0 * (expo - expo * numerix.exp(etaPrime)) coeffSuppressor = depositionCoeff(alphaSuppressor, i0Suppressor) coeffAccelerator = depositionCoeff(alphaAccelerator, i0Accelerator) exchangeCurrentDensity = acceleratorVar.getInterfaceVar() * ( coeffAccelerator - coeffSuppressor) + coeffSuppressor currentDensity = metalVar / bulkMetalConcentration * exchangeCurrentDensity depositionRateVariable = currentDensity * atomicVolume / charge / faradaysConstant extensionVelocityVariable = CellVariable(name='extension velocity', mesh=mesh, value=depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation kAccelerator = rateConstant * numerix.exp(-alphaAdsorption * etaPrime) kAcceleratorConsumption = Bd + A / (numerix.exp(Ba * (overpotential + Vd)) + numerix.exp(Bb * (overpotential + Vd))) q = m * overpotential + b levelerSurfactantEquation = AdsorbingSurfactantEquation( levelerVar, distanceVar=distanceVar, bulkVar=bulkLevelerVar, rateConstant=kLeveler, consumptionCoeff=kLevelerConsumption * depositionRateVariable) accVar1 = acceleratorVar.getInterfaceVar() accVar2 = (accVar1 > 0) * accVar1 accConsumptionCoeff = kAcceleratorConsumption * (accVar2**(q - 1)) acceleratorSurfactantEquation = AdsorbingSurfactantEquation( acceleratorVar, distanceVar=distanceVar, bulkVar=bulkAcceleratorVar, rateConstant=kAccelerator, otherVar=levelerVar, otherBulkVar=bulkLevelerVar, otherRateConstant=kLeveler, consumptionCoeff=accConsumptionCoeff) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff=extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar=metalVar, distanceVar=distanceVar, depositionRate=depositionRateVariable, diffusionCoeff=metalDiffusionCoefficient, metalIonMolarVolume=atomicVolume) metalEquationBCs = FixedValue(mesh.getTopFaces(), bulkMetalConcentration) from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \ import buildSurfactantBulkDiffusionEquation bulkAcceleratorEquation = buildSurfactantBulkDiffusionEquation( bulkVar=bulkAcceleratorVar, distanceVar=distanceVar, surfactantVar=acceleratorVar, otherSurfactantVar=levelerVar, diffusionCoeff=acceleratorDiffusionCoefficient, rateConstant=kAccelerator * siteDensity) bulkAcceleratorEquationBCs = (FixedValue(mesh.getTopFaces(), bulkAcceleratorConcentration), ) bulkLevelerEquation = buildSurfactantBulkDiffusionEquation( bulkVar=bulkLevelerVar, distanceVar=distanceVar, surfactantVar=levelerVar, diffusionCoeff=levelerDiffusionCoefficient, rateConstant=kLeveler * siteDensity) bulkLevelerEquationBCs = (FixedValue(mesh.getTopFaces(), bulkLevelerConcentration), ) eqnTuple = ((advectionEquation, distanceVar, ()), (levelerSurfactantEquation, levelerVar, ()), (acceleratorSurfactantEquation, acceleratorVar, ()), (metalEquation, metalVar, metalEquationBCs), (bulkAcceleratorEquation, bulkAcceleratorVar, bulkAcceleratorEquationBCs), (bulkLevelerEquation, bulkLevelerVar, bulkLevelerEquationBCs)) levelSetUpdateFrequency = int(0.7 * narrowBandWidth / cellSize / cflNumber / 2) totalTime = 0.0 if displayViewers: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = (MayaviSurfactantViewer(distanceVar, acceleratorVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 0.5, 'datamin': 0.0 }, smooth=1, title='accelerator coverage'), MayaviSurfactantViewer(distanceVar, levelerVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 0.5, 'datamin': 0.0 }, smooth=1, title='leveler coverage')) for step in range(numberOfSteps): if displayViewers: if step % displayRate == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction(deleteIslands=True) extensionVelocityVariable.setValue(depositionRateVariable) extOnInt = numerix.where( distanceVar > 0, numerix.where(distanceVar < 2 * cellSize, extensionVelocityVariable, 0), 0) dt = cflNumber * cellSize / numerix.max(extOnInt) id = numerix.max(numerix.nonzero(distanceVar._getInterfaceFlag())) distanceVar.extendVariable(extensionVelocityVariable, deleteIslands=True) extensionVelocityVariable[mesh.getFineMesh().getNumberOfCells():] = 0. for eqn, var, BCs in eqnTuple: var.updateOld() for eqn, var, BCs in eqnTuple: eqn.solve(var, boundaryConditions=BCs, dt=dt) totalTime += dt try: testFile = 'testLeveler.gz' import os import examples.levelSet.electroChem from fipy.tools import dump data = dump.read( os.path.join(examples.levelSet.electroChem.__path__[0], testFile)) N = mesh.getFineMesh().getNumberOfCells() print numerix.allclose(data[:N], levelerVar[:N], rtol=1e-3) except: return 0
def runSimpleTrenchSystem(faradaysConstant=9.6e4, gasConstant=8.314, transferCoefficient=0.5, rateConstant0=1.76, rateConstant3=-245e-6, catalystDiffusion=1e-9, siteDensity=9.8e-6, molarVolume=7.1e-6, charge=2, metalDiffusion=5.6e-10, temperature=298., overpotential=-0.3, metalConcentration=250., catalystConcentration=5e-3, catalystCoverage=0., currentDensity0=0.26, currentDensity1=45., cellSize=0.1e-7, trenchDepth=0.5e-6, aspectRatio=2., trenchSpacing=0.6e-6, boundaryLayerDepth=0.3e-6, numberOfSteps=5, displayViewers=True): cflNumber = 0.2 numberOfCellsInNarrowBand = 10 cellsBelowTrench = 10 yCells = cellsBelowTrench \ + int((trenchDepth + boundaryLayerDepth) / cellSize) xCells = int(trenchSpacing / 2 / cellSize) from fipy.meshes.grid2D import Grid2D mesh = Grid2D(dx=cellSize, dy=cellSize, nx=xCells, ny=yCells) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import \ DistanceVariable distanceVar = DistanceVariable(name='distance variable', mesh=mesh, value=-1, narrowBandWidth=narrowBandWidth, hasOld=1) bottomHeight = cellsBelowTrench * cellSize trenchHeight = bottomHeight + trenchDepth trenchWidth = trenchDepth / aspectRatio sideWidth = (trenchSpacing - trenchWidth) / 2 x, y = mesh.getCellCenters()[..., 0], mesh.getCellCenters()[..., 1] distanceVar.setValue(1, where=(y > trenchHeight) | ((y > bottomHeight) & (x < xCells * cellSize - sideWidth))) distanceVar.calcDistanceFunction(narrowBandWidth=1e10) from fipy.models.levelSet.surfactant.surfactantVariable import \ SurfactantVariable catalystVar = SurfactantVariable(name="catalyst variable", value=catalystCoverage, distanceVar=distanceVar) from fipy.variables.cellVariable import CellVariable bulkCatalystVar = CellVariable(name='bulk catalyst variable', mesh=mesh, value=catalystConcentration) metalVar = CellVariable(name='metal variable', mesh=mesh, value=metalConcentration) expoConstant = -transferCoefficient * faradaysConstant \ / (gasConstant * temperature) tmp = currentDensity1 * catalystVar.getInterfaceVar() exchangeCurrentDensity = currentDensity0 + tmp import fipy.tools.numerix as numerix expo = numerix.exp(expoConstant * overpotential) currentDensity = expo * exchangeCurrentDensity * metalVar \ / metalConcentration depositionRateVariable = currentDensity * molarVolume \ / (charge * faradaysConstant) extensionVelocityVariable = CellVariable(name='extension velocity', mesh=mesh, value=depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation surfactantEquation = AdsorbingSurfactantEquation( surfactantVar=catalystVar, distanceVar=distanceVar, bulkVar=bulkCatalystVar, rateConstant=rateConstant0 + rateConstant3 * overpotential**3) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff=extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar=metalVar, distanceVar=distanceVar, depositionRate=depositionRateVariable, diffusionCoeff=metalDiffusion, metalIonMolarVolume=molarVolume, ) metalEquationBCs = FixedValue(mesh.getFacesTop(), metalConcentration) from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \ import buildSurfactantBulkDiffusionEquation bulkCatalystEquation = buildSurfactantBulkDiffusionEquation( bulkVar=bulkCatalystVar, distanceVar=distanceVar, surfactantVar=catalystVar, diffusionCoeff=catalystDiffusion, rateConstant=rateConstant0 * siteDensity) catalystBCs = FixedValue(mesh.getFacesTop(), catalystConcentration) if displayViewers: try: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = (MayaviSurfactantViewer(distanceVar, catalystVar.getInterfaceVar(), zoomFactor=1e6, limits={ 'datamax': 0.5, 'datamin': 0.0 }, smooth=1, title='catalyst coverage'), ) except: from fipy.viewers import make viewers = (make(distanceVar, limits={ 'datamin': -1e-9, 'datamax': 1e-9 }), make(catalystVar.getInterfaceVar())) else: viewers = () levelSetUpdateFrequency = int(0.8 * narrowBandWidth \ / (cellSize * cflNumber * 2)) for step in range(numberOfSteps): if step % 5 == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction() extensionVelocityVariable.setValue(depositionRateVariable()) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() bulkCatalystVar.updateOld() distanceVar.extendVariable(extensionVelocityVariable) dt = cflNumber * cellSize / numerix.max(extensionVelocityVariable) advectionEquation.solve(distanceVar, dt=dt) surfactantEquation.solve(catalystVar, dt=dt) metalEquation.solve(metalVar, dt=dt, boundaryConditions=metalEquationBCs) bulkCatalystEquation.solve(bulkCatalystVar, dt=dt, boundaryConditions=catalystBCs) try: import os import examples.levelSet.electroChem filepath = os.path.join(examples.levelSet.electroChem.__path__[0], 'test.gz') from fipy.tools import dump from fipy.tools import numerix print catalystVar.allclose(numerix.array(dump.read(filepath)), rtol=1e-4) except: return 0
bench.start() timeStepDuration = 5e-5 tau = 3e-4 alpha = 0.015 c = 0.02 N = 4. kappa1 = 0.9 kappa2 = 20. tempDiffusionCoeff = 2.25 theta = 0. from fipy.variables.cellVariable import CellVariable phase = CellVariable(name='phase field', mesh=mesh, hasOld=1) x, y = mesh.getCellCenters()[...,0], mesh.getCellCenters()[...,1] phase.setValue(1., where=(x - seedCenter[0])**2 + (y - seedCenter[1])**2 < radius**2) temperature = CellVariable( name='temperature', mesh=mesh, value=initialTemperature, hasOld=1 ) bench.stop('variables') bench.start() from fipy.tools import numerix mVar = phase - 0.5 - kappa1 / numerix.pi * \ numerix.arctan(kappa2 * temperature)
def runSimpleTrenchSystem(faradaysConstant=9.6e4, gasConstant=8.314, transferCoefficient=0.5, rateConstant0=1.76, rateConstant3=-245e-6, catalystDiffusion=1e-9, siteDensity=9.8e-6, molarVolume=7.1e-6, charge=2, metalDiffusion=5.6e-10, temperature=298., overpotential=-0.3, metalConcentration=250., catalystConcentration=5e-3, catalystCoverage=0., currentDensity0=0.26, currentDensity1=45., cellSize=0.1e-7, trenchDepth=0.5e-6, aspectRatio=2., trenchSpacing=0.6e-6, boundaryLayerDepth=0.3e-6, numberOfSteps=5, displayViewers=True): cflNumber = 0.2 numberOfCellsInNarrowBand = 10 cellsBelowTrench = 10 yCells = cellsBelowTrench \ + int((trenchDepth + boundaryLayerDepth) / cellSize) xCells = int(trenchSpacing / 2 / cellSize) from fipy.meshes.grid2D import Grid2D mesh = Grid2D(dx = cellSize, dy = cellSize, nx = xCells, ny = yCells) narrowBandWidth = numberOfCellsInNarrowBand * cellSize from fipy.models.levelSet.distanceFunction.distanceVariable import \ DistanceVariable distanceVar = DistanceVariable( name = 'distance variable', mesh = mesh, value = -1, narrowBandWidth = narrowBandWidth, hasOld = 1) bottomHeight = cellsBelowTrench * cellSize trenchHeight = bottomHeight + trenchDepth trenchWidth = trenchDepth / aspectRatio sideWidth = (trenchSpacing - trenchWidth) / 2 x, y = mesh.getCellCenters()[...,0], mesh.getCellCenters()[...,1] distanceVar.setValue(1, where=(y > trenchHeight) | ((y > bottomHeight) & (x < xCells * cellSize - sideWidth))) distanceVar.calcDistanceFunction(narrowBandWidth = 1e10) from fipy.models.levelSet.surfactant.surfactantVariable import \ SurfactantVariable catalystVar = SurfactantVariable( name = "catalyst variable", value = catalystCoverage, distanceVar = distanceVar) from fipy.variables.cellVariable import CellVariable bulkCatalystVar = CellVariable( name = 'bulk catalyst variable', mesh = mesh, value = catalystConcentration) metalVar = CellVariable( name = 'metal variable', mesh = mesh, value = metalConcentration) expoConstant = -transferCoefficient * faradaysConstant \ / (gasConstant * temperature) tmp = currentDensity1 * catalystVar.getInterfaceVar() exchangeCurrentDensity = currentDensity0 + tmp import fipy.tools.numerix as numerix expo = numerix.exp(expoConstant * overpotential) currentDensity = expo * exchangeCurrentDensity * metalVar \ / metalConcentration depositionRateVariable = currentDensity * molarVolume \ / (charge * faradaysConstant) extensionVelocityVariable = CellVariable( name = 'extension velocity', mesh = mesh, value = depositionRateVariable) from fipy.models.levelSet.surfactant.adsorbingSurfactantEquation \ import AdsorbingSurfactantEquation surfactantEquation = AdsorbingSurfactantEquation( surfactantVar = catalystVar, distanceVar = distanceVar, bulkVar = bulkCatalystVar, rateConstant = rateConstant0 + rateConstant3 * overpotential**3) from fipy.models.levelSet.advection.higherOrderAdvectionEquation \ import buildHigherOrderAdvectionEquation advectionEquation = buildHigherOrderAdvectionEquation( advectionCoeff = extensionVelocityVariable) from fipy.boundaryConditions.fixedValue import FixedValue from fipy.models.levelSet.electroChem.metalIonDiffusionEquation \ import buildMetalIonDiffusionEquation metalEquation = buildMetalIonDiffusionEquation( ionVar = metalVar, distanceVar = distanceVar, depositionRate = depositionRateVariable, diffusionCoeff = metalDiffusion, metalIonMolarVolume = molarVolume, ) metalEquationBCs = FixedValue(mesh.getFacesTop(), metalConcentration) from fipy.models.levelSet.surfactant.surfactantBulkDiffusionEquation \ import buildSurfactantBulkDiffusionEquation bulkCatalystEquation = buildSurfactantBulkDiffusionEquation( bulkVar = bulkCatalystVar, distanceVar = distanceVar, surfactantVar = catalystVar, diffusionCoeff = catalystDiffusion, rateConstant = rateConstant0 * siteDensity ) catalystBCs = FixedValue(mesh.getFacesTop(), catalystConcentration) if displayViewers: try: from fipy.viewers.mayaviViewer.mayaviSurfactantViewer import MayaviSurfactantViewer viewers = (MayaviSurfactantViewer(distanceVar, catalystVar.getInterfaceVar(), zoomFactor = 1e6, limits = { 'datamax' : 0.5, 'datamin' : 0.0 }, smooth = 1, title = 'catalyst coverage'),) except: from fipy.viewers import make viewers = ( make(distanceVar, limits = { 'datamin' :-1e-9 , 'datamax' : 1e-9 }), make(catalystVar.getInterfaceVar())) else: viewers = () levelSetUpdateFrequency = int(0.8 * narrowBandWidth \ / (cellSize * cflNumber * 2)) for step in range(numberOfSteps): if step % 5 == 0: for viewer in viewers: viewer.plot() if step % levelSetUpdateFrequency == 0: distanceVar.calcDistanceFunction() extensionVelocityVariable.setValue(depositionRateVariable()) distanceVar.updateOld() catalystVar.updateOld() metalVar.updateOld() bulkCatalystVar.updateOld() distanceVar.extendVariable(extensionVelocityVariable) dt = cflNumber * cellSize / numerix.max(extensionVelocityVariable) advectionEquation.solve(distanceVar, dt = dt) surfactantEquation.solve(catalystVar, dt = dt) metalEquation.solve(metalVar, dt = dt, boundaryConditions = metalEquationBCs) bulkCatalystEquation.solve(bulkCatalystVar, dt = dt, boundaryConditions = catalystBCs) try: import os import examples.levelSet.electroChem filepath = os.path.join(examples.levelSet.electroChem.__path__[0], 'test.gz') from fipy.tools import dump from fipy.tools import numerix print catalystVar.allclose(numerix.array(dump.read(filepath)), rtol = 1e-4) except: return 0