Skip to content

Instantly share code, notes, and snippets.

@oskooi
Last active June 27, 2021 18:22
Show Gist options
  • Save oskooi/47b59852bb5965ecf98950605fccd45a to your computer and use it in GitHub Desktop.
Save oskooi/47b59852bb5965ecf98950605fccd45a to your computer and use it in GitHub Desktop.
Meep Simulation of 3d Organic Light Emitting Diode (OLED)
import meep as mp
from meep.materials import Al as ALU
import argparse
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
def main(args):
resolution = args.res # pixels/um
lambda_min = 0.4 # minimum source wavelength
lambda_max = 0.8 # maximum source wavelength
fmin = 1/lambda_max # minimum source frequency
fmax = 1/lambda_min # maximum source frequency
fcen = 0.5*(fmin+fmax) # source frequency center
df = fmax-fmin # source frequency width
tABS = lambda_max # absorber/PML thickness
tGLS = 1.0 # glass thickness
tITO = 0.1 # indium tin oxide thickness
tORG = 0.1 # organic thickness
tAl = 0.1 # aluminum thickness
# length of computational cell along Z
sz = tABS+tGLS+tITO+tORG+tAl
# length of non-absorbing region of computational cell in X and Y
L = args.L
sxy = L+2*tABS
cell_size = mp.Vector3(sxy,sxy,sz)
boundary_layers = [mp.Absorber(tABS,direction=mp.X),
mp.Absorber(tABS,direction=mp.Y),
mp.PML(tABS,direction=mp.Z,side=mp.High)]
ORG = mp.Medium(index=1.75)
ITO = mp.Medium(index=1.80)
GLS = mp.Medium(index=1.45)
geometry = [mp.Block(material=GLS, size=mp.Vector3(mp.inf,mp.inf,tABS+tGLS), center=mp.Vector3(0,0,0.5*sz-0.5*(tABS+tGLS))),
mp.Block(material=ITO, size=mp.Vector3(mp.inf,mp.inf,tITO), center=mp.Vector3(0,0,0.5*sz-tABS-tGLS-0.5*tITO)),
mp.Block(material=ORG, size=mp.Vector3(mp.inf,mp.inf,tORG), center=mp.Vector3(0,0,0.5*sz-tABS-tGLS-tITO-0.5*tORG)),
mp.Block(material=ALU, size=mp.Vector3(mp.inf,mp.inf,tAl), center=mp.Vector3(0,0,0.5*sz-tABS-tGLS-tITO-tORG-0.5*tAl))]
# current-source component
if args.perp_dipole:
src_cmpt = mp.Ez
else:
src_cmpt = mp.Ex
num_src = 10 # number of point sources
sources = [];
for n in range(num_src):
sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df),
component=src_cmpt,
center=mp.Vector3(0,0,0.5*sz-tABS-tGLS-tITO-0.4*tORG-0.2*tORG*n/num_src),
amplitude=1.0))
sim = mp.Simulation(resolution=resolution,
cell_size=cell_size,
boundary_layers=boundary_layers,
geometry=geometry,
dimensions=3,
sources=sources,
split_chunks_evenly=False,
force_complex_fields=True)
# number of frequency bins for DFT fields
nfreq = 50
# surround source with a six-sided box of flux planes
srcbox_width = 0.05
srcbox_top = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0,0,0.5*sz-tABS-tGLS),
size=mp.Vector3(srcbox_width,srcbox_width,0), direction=mp.Z, weight=+1))
srcbox_bot = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0,0,0.5*sz-tABS-tGLS-tITO-0.8*tORG),
size=mp.Vector3(srcbox_width,srcbox_width,0), direction=mp.Z, weight=-1))
srcbox_xp = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0.5*srcbox_width,0,0.5*sz-tABS-tGLS-0.5*(tITO+0.8*tORG)),
size=mp.Vector3(0,srcbox_width,tITO+0.8*tORG), direction=mp.X, weight=+1))
srcbox_xm = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(-0.5*srcbox_width,0,0.5*sz-tABS-tGLS-0.5*(tITO+0.8*tORG)),
size=mp.Vector3(0,srcbox_width,tITO+0.8*tORG), direction=mp.X, weight=-1))
srcbox_yp = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0,0.5*srcbox_width,0.5*sz-tABS-tGLS-0.5*(tITO+0.8*tORG)),
size=mp.Vector3(srcbox_width,0,tITO+0.8*tORG), direction=mp.Y, weight=+1))
srcbox_ym = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0,-0.5*srcbox_width,0.5*sz-tABS-tGLS-0.5*(tITO+0.8*tORG)),
size=mp.Vector3(srcbox_width,0,tITO+0.8*tORG), direction=mp.Y, weight=-1))
# padding for flux box to fully capture waveguide mode
fluxbox_dpad = 0.05
# upward flux into glass substrate
glass_flux = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0,0,0.5*sz-tABS-(tGLS-fluxbox_dpad)), size = mp.Vector3(L,L,0), direction=mp.Z, weight=+1))
# surround ORG/ITO waveguide with four-sided box of flux planes
# NOTE: waveguide mode extends partially into Al cathode and glass substrate
wvgbox_xp = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(size=mp.Vector3(0,L,fluxbox_dpad+tITO+tORG+fluxbox_dpad), direction=mp.X,
center=mp.Vector3(0.5*L,0,0.5*sz-tABS-tGLS-0.5*(tITO+tORG)), weight=+1))
wvgbox_xm = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(size=mp.Vector3(0,L,fluxbox_dpad+tITO+tORG+fluxbox_dpad), direction=mp.X,
center=mp.Vector3(-0.5*L,0,0.5*sz-tABS-tGLS-0.5*(tITO+tORG)), weight=-1))
wvgbox_yp = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(size=mp.Vector3(L,0,fluxbox_dpad+tITO+tORG+fluxbox_dpad), direction=mp.Y,
center=mp.Vector3(0,0.5*L,0.5*sz-tABS-tGLS-0.5*(tITO+tORG)), weight=+1))
wvgbox_ym = sim.add_flux(fcen, df, nfreq, mp.FluxRegion(size=mp.Vector3(L,0,fluxbox_dpad+tITO+tORG+fluxbox_dpad), direction=mp.Y,
center=mp.Vector3(0,-0.5*L,0.5*sz-tABS-tGLS-0.5*(tITO+tORG)), weight=-1))
sim.init_sim()
sim.fields.step()
sim.fields.reset_timers()
sim.run(until_after_sources=4.0)
print("field:, {}, {}".format(sim.fields.t,sim.get_field_point(mp.Ez,mp.Vector3())))
sim.output_times('timings.csv')
sim.visualize_chunks()
plt.savefig('chunk_layout.png',bbox_inches='tight',dpi=150)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-res', type=int, default=50, help='resolution (default: 50 pixels/um)')
parser.add_argument('-L', type=float, default=5.0, help='length of OLED (default: 5.0 um)')
parser.add_argument('--perp_dipole', action='store_true', help='perpendicular dipole (default: False)')
args = parser.parse_args()
main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment