examples.elphf.poisson¶
A simple 1D example to test the setup of the Poisson equation.
>>> from fipy import CellVariable, Grid1D, DiffusionTerm, Viewer
>>> from fipy.tools import numerix
>>> nx = 200
>>> dx = 0.01
>>> L = nx * dx
>>> mesh = Grid1D(dx = dx, nx = nx)
The dimensionless Poisson equation is
where \(\phi\) is the electrostatic potential, \(\epsilon\) is the permittivity, \(\rho\) is the charge density, \(C_j\) is the concentration of the \(j^\text{th}\) component, and \(z_j\) is the valence of the \(j^\text{th}\) component.
We will be solving for the electrostatic potential
>>> potential = CellVariable(mesh = mesh, name = 'phi', value = 0.)
>>> permittivity = 1.
We examine a fixed distribution of electrons with \(z_{\text{e}^{-}} = -1\).
>>> class ComponentVariable(CellVariable):
... def __init__(self, mesh, value = 0., name = '',
... standardPotential = 0., barrier = 0.,
... diffusivity = None, valence = 0, equation = None):
... CellVariable.__init__(self, mesh = mesh,
... value = value, name = name)
... self.standardPotential = standardPotential
... self.barrier = barrier
... self.diffusivity = diffusivity
... self.valence = valence
... self.equation = equation
...
... def copy(self):
... return self.__class__(mesh = self.mesh,
... value = self.value,
... name = self.name,
... standardPotential =
... self.standardPotential,
... barrier = self.barrier,
... diffusivity = self.diffusivity,
... valence = self.valence,
... equation = self.equation)
Since we’re only interested in a single species, electrons, we could simplify the following, but since we will in general be studying multiple components, we explicitly allow for multiple substitutional species and multiple interstitial species:
>>> interstitials = [
... ComponentVariable(mesh = mesh, name = 'e-', valence = -1)]
>>> substitutionals = []
Because Poisson’s equation admits an infinite number of potential profiles, we must constrain the solution by fixing the potential at one point:
>>> potential.constrain(0., mesh.facesLeft)
>>> charge = 0.
>>> for Cj in interstitials + substitutionals:
... charge += Cj * Cj.valence
>>> potential.equation = DiffusionTerm(coeff = permittivity) \
... + charge == 0
First, we obtain a uniform charge distribution by setting a uniform concentration of electrons \(C_{\text{e}^{-}} = 1\).
>>> interstitials[0].setValue(1.)
and we solve for the electrostatic potential
>>> potential.equation.solve(var = potential)
This problem has the analytical solution
We verify that the correct equilibrium is attained
>>> x = mesh.cellCenters[0]
>>> analyticalArray = (x**2)/2 - 2*x
>>> print(potential.allclose(analyticalArray, rtol = 2e-5, atol = 2e-5))
1
If we are running the example interactively, we view the result
>>> from fipy import input
>>> if __name__ == '__main__':
... viewer = Viewer(vars = (charge, potential))
... viewer.plot()
... input("Press any key to continue...")
Next, we segregate all of the electrons to right side of the domain
>>> x = mesh.cellCenters[0]
>>> interstitials[0].setValue(0.)
>>> interstitials[0].setValue(1., where=x > L / 2.)
and again solve for the electrostatic potential
>>> potential.equation.solve(var = potential)
which now has the analytical solution
We verify that the correct equilibrium is attained
>>> analyticalArray = numerix.where(x < L/2, -x, ((x-1)**2)/2 - x)
>>> potential.allclose(analyticalArray, rtol = 2e-5, atol = 2e-5).value
1
and again view the result
>>> from fipy import input
>>> if __name__ == '__main__':
... viewer.plot()
... input("Press any key to continue...")
Finally, we segregate all of the electrons to left side of the domain
>>> interstitials[0].setValue(1.)
>>> interstitials[0].setValue(0., where=x > L / 2.)
and again solve for the electrostatic potential
>>> potential.equation.solve(var = potential)
which has the analytical solution
We again verify that the correct equilibrium is attained
>>> analyticalArray = numerix.where(x < 1, (x**2)/2 - x, -0.5)
>>> potential.allclose(analyticalArray, rtol = 2e-5, atol = 2e-5).value
1
and again view the result
>>> if __name__ == '__main__':
... viewer.plot()