/
multilevel-atom.py
96 lines (72 loc) · 4.12 KB
/
multilevel-atom.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from __future__ import division
import math
import meep as mp
# This file realizes a 1D, one-sided Fabry-Perot laser, as described in Fig. 2 of Optics Express, Vol. 20, pp. 474-88, 2012.
# Cavity definitions
resolution = 400
ncav = 1.5 # cavity refractive index
Lcav = 1 # cavity length
dpad = 1 # padding thickness
dpml = 1 # PML thickness
sz = Lcav + dpad + dpml
cell_size = mp.Vector3(z=sz)
dimensions = 1
pml_layers = [mp.PML(dpml, side=mp.High)]
# For defining laser properties in MEEP, the transition rates / frequencies are specified in units of 2*pi*a/c.
# gamma_21 in MEEP is the Full-Width Half-Max, as opposed to gamma_perp, which is the HWHM in SALT.
# Additionally, the classical coupling element sigma = 2*theta^2*omega_a/hbar, where
# theta is the off-diagonal dipole matrix element.
# These different conventions can cause a bit of confusion when comparing against SALT, so here we perform
# this transformation explicitly.
omega_a = 40 # omega_a in SALT
freq_21 = omega_a/(2*math.pi) # emission frequency (units of 2πc/a)
gamma_perp = 4 # HWHM in angular frequency, SALT
gamma_21 = (2*gamma_perp)/(2*math.pi) # FWHM emission linewidth in sec^-1 (units of 2πc/a)
# Note that 2*pi*gamma_21 = 2*gamma_perp in SALT.
theta = 1 # theta, the off-diagonal dipole matrix element, in SALT
sigma_21 = 2*theta*theta*omega_a # dipole coupling strength (hbar = 1)
# The gain medium in MEEP is allowed to have an arbitrary number of levels, and is not
# restricted to a two-level gain medium, as it simulates the populations of every individual
# atomic energy level.
# If you are using a 2 level gain model, you can compare against
# results which only simulate the atomic inversion, using the definitions
# gamma_parallel = pumping_rate + rate_21
# D_0 = (pumping_rate - rate_21)/(pumping_rate + rate_21) * N0
# In fact, even if you arn't using a 2 level gain model, you can compare against an effective
# two level model using the formula provided in Cerjan et al., Opt. Express 20, 474 (2012).
# Here, D_0 as written above is not yet in "SALT" units. To make this conversion,
# D_0 (SALT) = theta^2/(hbar*gamma_perp) * D_0 (as written above)
# Finally, note the lack of 4*pi in the above conversion that is written in many published SALT papers.
# This 4*pi comes from using Gaussian units, in which the displacement field, D = E + 4*pi*P, whereas
# in SI units, D = eps0*E + P, which is what MEEP uses.
# Gain medium pump and decay rates are specified in units of c/a.
rate_21 = 0.005 # non-radiative rate (units of c/a)
N0 = 37 # initial population density of ground state
Rp = 0.0051 # pumping rate of ground to excited state
# so for example, these parameters have D_0 (SALT) = 0.0693.
# Make the actual medium in MEEP:
transitions = [mp.Transition(1, 2, pumping_rate=Rp, frequency=freq_21, gamma=gamma_21,
sigma_diag=mp.Vector3(sigma_21,0,0)),
mp.Transition(2, 1, transition_rate=rate_21)]
ml_atom = mp.MultilevelAtom(sigma=1, transitions=transitions, initial_populations=[N0])
two_level = mp.Medium(index=ncav, E_susceptibilities=[ml_atom])
# Specify the cavity geometry:
geometry = [mp.Block(center=mp.Vector3(z=-0.5*sz+0.5*Lcav),
size=mp.Vector3(mp.inf,mp.inf,Lcav), material=two_level)]
sim = mp.Simulation(cell_size=cell_size,
resolution=resolution,
boundary_layers=pml_layers,
geometry=geometry,
dimensions=dimensions)
sim.init_sim()
def field_func(p):
return 1 if p.z==-0.5*sz + 0.5*Lcav else 0
sim.fields.initialize_field(mp.Ex, field_func)
# Specify the end time:
endt = 7000
# Note that the total number of time steps run is endt*resolution*2. This is the origin of the extra
# factor of 2 in the definition of dt in fieldfft_meep.m.
def print_field(sim):
fp = sim.get_field_point(mp.Ex, mp.Vector3(z=(-0.5 * sz) + Lcav + (0.5 * dpad))).real
print("field:, {}, {}".format(sim.meep_time(), fp))
sim.run(mp.after_time(endt - 250, print_field), until=endt)