This notebook reproduces published transient simulations of electrochemical doping.
Note that the simulation may not work for longer times than investigated in the paper because of the formation of an EDL which is poorly handled without further assumptions.
Also, all the profiles of electrical potential are inverted in the paper.
In [1]:
%matplotlib inline
import matplotlib.pylab as plt
from oedes import *
init_notebook()
In [2]:
electrolyte_mesh = fvm.mesh1d(
25e-9,
boundary_names=[
'electrode0',
'internal_boundary'])
pedot_mesh = fvm.mesh1d(
175e-9,
boundary_names=[
'internal_boundary',
'electrode1'])
mesh = fvm.multilayer1d(
[('electrolyte', electrolyte_mesh), ('pedot', pedot_mesh)])
electrolyte_model = models.BaseModel()
electrolyte_model.name = 'electrolyte'
pedot_model = models.BaseModel()
pedot_model.name = 'pedot'
ions_electrolyte=models.add_ions(electrolyte_model,electrolyte_mesh)
ions_pedot=models.add_ions(pedot_model,pedot_mesh)
hole_eqn=models.add_transport(pedot_model,pedot_mesh,z=1,name='hole')
Doping of PEDOT:
In [3]:
pedot_model.species.append(models.FixedCharge(poisson=pedot_model.poisson))
BCs for Poisson's equation:
In [4]:
electrolyte_model.poisson.bc = [
models.AppliedVoltage('electrode0'),
models.Equal(
pedot_model.poisson,
'internal_boundary')]
pedot_model.poisson.bc = [models.AppliedVoltage('electrode1')]
BCs for holes and ions:
In [5]:
hole_eqn.bc = [models.DirichletFromParams('electrode1')]
for ion_electrolyte in ions_electrolyte:
ion_electrolyte.bc = [models.DirichletFromParams('electrode0')]
for ion_pedot,ion_electrolyte in zip(ions_pedot,ions_electrolyte):
ion_pedot.bc = [models.Equal(ion_electrolyte,'internal_boundary')]
Coupled model:
In [6]:
model = models.CompositeModel()
model.sub = [electrolyte_model, pedot_model]
model.other = [models.RamoShockleyCurrentCalculation([electrolyte_model.poisson,pedot_model.poisson])]
model.setUp()
Parameters:
In [7]:
params = {
'electrolyte.epsilon_r': 3.,
'pedot.epsilon_r': 3,
'electrolyte.T': 300,
'pedot.T': 300,
'electrolyte.electrode0.voltage': 0,
'electrolyte.electrode0.workfunction': 0,
'pedot.electrode1.voltage': 0,
'pedot.electrode1.workfunction': 0,
'pedot.hole.N0': 1e27,
'pedot.hole.electrode1': 1e25,
'pedot.hole.mu': 1e-7,
'pedot.hole.energy': 0,
'pedot.Na': 1e25,
'pedot.Nd': 0,
'electrolyte.cation.electrode0': 1e25,
'electrolyte.cation.mu': 1e-7,
'electrolyte.cation.N0': 1e27,
'electrolyte.cation.energy': 0.,
'electrolyte.anion.electrode0': 1e25,
'electrolyte.anion.mu': 1e-7,
'electrolyte.anion.N0': 1e27,
'electrolyte.anion.energy': 0.,
'pedot.cation.mu': 1e-9,
'pedot.cation.N0': 1e27,
'pedot.cation.energy': 0.,
'pedot.anion.mu': 1e-9,
'pedot.anion.N0': 1e27,
'pedot.anion.energy': 0.
}
In [8]:
def store(out):
testing.store(out['electrolyte.potential'])
testing.store(out['electrolyte.anion.c'], atol=1e12)
testing.store(out['electrolyte.cation.c'], atol=1e12)
testing.store(out['pedot.potential'], atol=1e12)
testing.store(out['pedot.hole.c'], atol=1e12)
testing.store(out['pedot.anion.c'], atol=1e12)
testing.store(out['pedot.cation.c'], atol=1e12)
Figure numbers given below correspond to Figures in the reference.
In [9]:
x = model.X.copy()
x[hole_eqn.idx] = params['pedot.Na']
c = context(model, x=x)
params['electrolyte.electrode0.voltage'] = 0.
params['pedot.electrode1.voltage'] = -1
c.transient(params, 1e-5, 1e-9)
In [10]:
from oedes import mpl
In [11]:
fig, (ion_plot, hole_plot, potential_plot) = plt.subplots(
nrows=3, figsize=(6, 8))
for time in [2e-6, 4e-6, 6e-6, 8e-6, 10e-6]:
ts = c.attime(time)
store(ts.output())
ts.mpl(fig, ion_plot).species('cation', settings=mpl.Settings.c_x_nm)
ts.mpl(fig, ion_plot).species('anion', settings=mpl.Settings.c_x_nm)
o = ts.output()
ts.mpl(fig, hole_plot).species('hole')
ts.mpl(fig, potential_plot).potential()
fig.tight_layout()
In [12]:
def length(out):
store(out)
c = out['pedot.hole.c']
i = np.argwhere(c > 0.5e25)[0]
return pedot_mesh.cells['center'][i] - pedot_mesh.cells['center'][0]
times = np.asarray([2e-6, 4e-6, 6e-6, 8e-6, 10e-6])
plt.plot(times * 1e6, [length(c.attime(t).output())
** 2 * 1e18 for t in times], '-o')
plt.xlabel('t [$\mu s$]')
plt.ylabel('$\ell^2$ [$nm%2$]')
Out[12]:
In [13]:
t, j = c.teval('time', 'electrode1.J')
t, j = t[t > 0], j[t > 0]
plt.plot(1. / np.sqrt(t * 1e6), j * 1e-4, 'o-')
plt.xlim([0.25, 1.1])
plt.ylim([0.75, 4])
plt.xlabel('$t^{-1/2}$ [$\mu s^{-1/2}$]')
plt.ylabel('j [$A/cm^2$]')
Out[13]:
In [14]:
x0 = model.X.copy()
x0[hole_eqn.idx] = params['pedot.Na']
by_v = {}
voltages = [0.01, 0.05, 0.1, 0.5, 1]
for v in voltages:
params['pedot.electrode1.voltage'] = -v
c = context(model, x=x0)
c.transient(params, 1e-5, 1e-9)
by_v[v] = c
In [15]:
fig, (ion_plot, potential_plot) = plt.subplots(ncols=2, figsize=(12, 4))
for v in voltages:
o = by_v[v].attime(1e-5).output()
store(o)
ion_plot.plot(
electrolyte_mesh.cells['center'] *
1e9,
o['electrolyte.cation.c'] -
o['electrolyte.anion.c'])
ion_plot.plot(
pedot_mesh.cells['center'] *
1e9,
o['pedot.cation.c'] -
o['pedot.anion.c'])
ion_plot.set_xlabel('x [nm]')
ion_plot.set_ylabel('P-N [1/m^3]')
potential_plot.plot(
electrolyte_mesh.cells['center'] * 1e9, o['electrolyte.potential'] / (-v))
potential_plot.plot(
pedot_mesh.cells['center'] * 1e9, o['pedot.potential'] / (-v))
potential_plot.set_xlabel('x [nm]')
potential_plot.set_ylabel('$V/V_{appl}$')
In [16]:
x0 = model.X.copy()
x0[hole_eqn.idx] = params['pedot.Na']
params['pedot.electrode1.voltage'] = -1.
concentrations = [1e24, 1e25, 1e26]
by_c = {}
for conc in concentrations:
params['electrolyte.cation.electrode0'] = conc
params['electrolyte.anion.electrode0'] = conc
c = context(model, x=x0)
c.transient(params, 1e-5, 1e-9)
by_c[conc] = c
In [17]:
fig, (ion_plot, potential_plot) = plt.subplots(ncols=2, figsize=(12, 4))
for conc in concentrations:
o = by_c[conc].attime(1e-5).output()
store(o)
ion_plot.plot(
electrolyte_mesh.cells['center'] *
1e9,
o['electrolyte.cation.c'] -
o['electrolyte.anion.c'])
ion_plot.plot(
pedot_mesh.cells['center'] *
1e9,
o['pedot.cation.c'] -
o['pedot.anion.c'])
ion_plot.set_xlabel('x [nm]')
ion_plot.set_ylabel('P-N [1/m^3]')
potential_plot.plot(
electrolyte_mesh.cells['center'] * 1e9, -o['electrolyte.potential'])
potential_plot.plot(
pedot_mesh.cells['center'] * 1e9, -o['pedot.potential'])
potential_plot.set_xlabel('x [nm]')
potential_plot.set_ylabel('- electrostatic potential [V]')
In [18]:
x0 = model.X.copy()
x0[hole_eqn.idx] = params['pedot.Na']
params['pedot.electrode1.voltage'] = -1.
params['electrolyte.cation.electrode'] = 1e25
params['electrolyte.anion.electrode'] = 1e25
mu_values = [1e-10, 1e-9, 1e-8]
by_mu = {}
for mu in mu_values:
params['pedot.cation.mu'] = mu
params['pedot.anion.mu'] = mu
c = context(model, x=x0)
c.transient(params, 1e-5, 1e-9)
by_mu[mu] = c
In [19]:
fig, (ion_plot, potential_plot) = plt.subplots(ncols=2, figsize=(12, 4))
time = {1e-10: 6e-6, 1e-9: 6e-6, 1e-8: 1e-6}
for mu in mu_values:
o = by_mu[mu].attime(time[mu]).output()
store(o)
ion_plot.plot(
electrolyte_mesh.cells['center'] *
1e9,
o['electrolyte.cation.c'] -
o['electrolyte.anion.c'])
ion_plot.plot(
pedot_mesh.cells['center'] *
1e9,
o['pedot.cation.c'] -
o['pedot.anion.c'])
ion_plot.set_xlabel('x [nm]')
ion_plot.set_ylabel('P-N [1/m^3]')
potential_plot.plot(
electrolyte_mesh.cells['center'] * 1e9, -o['electrolyte.potential'] / v)
potential_plot.plot(
pedot_mesh.cells['center'] * 1e9, -o['pedot.potential'] / v)
potential_plot.set_xlabel('x [nm]')
potential_plot.set_ylabel('- electrostatic potential [V]')
Eleni Stavrinidou, Pierre Leleux, Harizo Rajaona, Michel Fiocchi, Sébastien Sanaur, George G. Malliaras A simple model for ion injection and transport in conducting polymers, Journal of Applied Physics 113, 244501 (2013).
This file is a part of oedes, an open source organic electronic device simulator. For more information, see https://www.github.com/mzszym/oedes.