Skip to content

Commit b531d7d

Browse files
committed
refactor: new and renamed variables
Basic maintenance in the context of the major update of the core algorithm to include carrier transport through the barriers into the QWs: 3fd99e4 In particular, a number of variables were created/renamed to improve consistency and readability: - N -> Nb, Nw: carrier density in the barriers and in the QWs, respectively. Nb is described with just one additional equation coupled with the equations describing Nw - ni, nm -> nNb, nNw, nS: number of equations (array dimensions) describing respectively the carrier density in the barrier Nb, the carrier density in the QWs Nw, and the photon densities in each optical mode S - tauN -> tauNb, tauNw: recombination lifetime in the barriers and QW, respectively - taub: aggregated non-stimulated recombination lifetime in the barriers: taub = (1/tauNb + 1/tauCap)**-1 - tauw: aggregated non-stimulated recombination lifetime in the barriers: taub = (1/tauNw + 1/tauEsc)**-1 - nqw -> nw: number of quantum wells - dqw -> dw: quantum well thickness - Vcav -> Vw: active volume - Vbar -> Vb: barriers volume - Vr -> ratio of Vw to Vb - etaI -> etai: current injection efficiency - rOx -> rox: oxide aperture - SCHTransp -> SCHtransp: bool variable describing whether carrier transport should be simulated or not
1 parent 3fd99e4 commit b531d7d

File tree

4 files changed

+55
-54
lines changed

4 files changed

+55
-54
lines changed

VISTAS_gui.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# GUI/params mgmt: check the type and correct the unit (ns->s, mA->A) to make sure correct values are stored in the dictionaries sp and vp
3333
def check_value(k, v):
3434

35-
if k in ['SCHTransp', 'ThermMod', 'Noise', 'Parasitics', '2D', 'storeN', 'Uxyplot', 'PIplot', 'Ptplot', 'NSxyplot', 'RINplot', 'Hfplot', 'Eyeplot']:
35+
if k in ['SCHtransp', 'ThermMod', 'Noise', 'Parasitics', '2D', 'storeN', 'Uxyplot', 'PIplot', 'Ptplot', 'NSxyplot', 'RINplot', 'Hfplot', 'Eyeplot']:
3636
try:
3737
v = bool(v)
3838
except:
@@ -46,7 +46,7 @@ def check_value(k, v):
4646
sg.popup('String input expected', button_type=5, auto_close = True, auto_close_duration = 1.5)
4747
v = None # in case last_params.json is saved before the value is corrected, it saves it as None (jsaon: null)
4848

49-
elif k == 'ni':
49+
elif k == 'nNw':
5050
try:
5151
v = int(v)
5252
except:
@@ -85,7 +85,6 @@ def save_params(sp, vp, sr, file_name):
8585
def update_dict(values, d):
8686
for k, v in d.items(): # update entire dictionary
8787
k, d[k] = check_value(k, values[k])
88-
8988
return d
9089

9190

@@ -159,7 +158,7 @@ def update_gui(window, values, sp, vp):
159158

160159
# GUI/params mgmt: main function, incl. layout and events loop
161160
def GUI():
162-
161+
163162
# 0. load last parameters into sp and vp dictionaries -------------------------------------------------------
164163
params = load_params('last_params.json') # loads params file and populates dictionaries sp and vp
165164
sp, vp = params['simParams'], params['vcselParams'] # simulation results not loaded (for that, chose "load params" and select any file but last_params.json or default_params.json)
@@ -171,16 +170,16 @@ def GUI():
171170
# 1. Tabs layout -------------------------------------------------------
172171
spTab_layout = [
173172
[sg.Frame('Simulated effects',[
174-
[sg.Checkbox('carrier transport into the quantum wells', key='SCHTransp', default=sp['SCHTransp'], size=(45,1), disabled=True, tooltip=ttips['SCHTransp'], enable_events=True)],
173+
[sg.Checkbox('carrier transport into the quantum wells', key='SCHtransp', default=sp['SCHtransp'], size=(45,1), disabled=False, tooltip=ttips['SCHtransp'], enable_events=True)],
175174
[sg.Checkbox('thermal effects', key='ThermMod', default=sp['ThermMod'], disabled=True, tooltip=ttips['ThermMod'], enable_events=True)],
176175
[sg.Checkbox('noise', key='Noise', default=sp['Noise'], disabled=True, tooltip=ttips['Noise'], enable_events=True)],
177176
[sg.Checkbox('electrical parasitics', key='Parasitics', default=sp['Parasitics'], disabled=True, tooltip=ttips['Parasitics'], enable_events=True)],
178177
[sg.Checkbox('2D', key='2D', default=sp['2D'], disabled=True, tooltip=ttips['2D'], enable_events=True)],
179178
])],
180179
[sg.Frame('Simulation parameters',[
181-
[sg.InputText(sp['ni'], key='ni', size=(7,1), tooltip=ttips['ni'], enable_events=True), sg.Text('radial resolution (typically 7-20 terms)', size=(40,1))],
180+
[sg.InputText(sp['nNw'], key='nNw', size=(7,1), tooltip=ttips['nNw'], enable_events=True), sg.Text('radial resolution (typically 7-20 terms)', size=(40,1))],
182181
[sg.Checkbox('store carrier terms Ni', key='storeN', default=sp['storeN'], disabled=True, tooltip=ttips['storeN'], enable_events=True)],
183-
[sg.Combo(values=('RK45', 'RK23', 'DOP853', 'LSODA', 'Finite Diff.'), key='odeSolver', default_value=sp['odeSolver'], size=(12,1), tooltip=ttips['odeSolver'], enable_events=True), sg.Text('ODE solver')],
182+
[sg.Combo(values=('RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA', 'Finite Diff.'), key='odeSolver', default_value=sp['odeSolver'], size=(12,1), tooltip=ttips['odeSolver'], enable_events=True), sg.Text('ODE solver')],
184183
[sg.InputText(round(float(0 if sp['tmax'] is None else sp['tmax'])*1e9,0), key='tmax', size=(7,1), tooltip=ttips['tmax'], enable_events=True, readonly=(sp['modFormat']=='small signal'), disabled_readonly_background_color='grey'), sg.Text('simulated time (ns)')],
185184
[sg.InputText(round(float(0 if sp['dt'] is None else sp['dt'])*1e9,3), key='dt', size=(7,1), tooltip=ttips['dt'], enable_events=True), sg.Text('time resolution for storing and plotting (ns)')],
186185
[sg.InputText(round(float(0 if sp['dtFD'] is None else sp['dtFD'])*1e9,3), key='dtFD', size=(7,1), tooltip=ttips['dtFD'], enable_events=True, readonly=(sp['odeSolver']!='Finite Diff.'), disabled_readonly_background_color='grey'), sg.Text('time step for FD solution (ns)')],
@@ -208,14 +207,14 @@ def GUI():
208207
[sg.Multiline(vp['vcselDescr'], key='vcselDescr', size=(52,2), tooltip=ttips['vcselDescr'], enable_events=True)],
209208
])],
210209
[sg.Frame('Cavity geometry parameters',[
211-
[sg.InputText(vp['rOx'], key='rOx', size=(7,1), tooltip=ttips['rOx'], enable_events=True), sg.Text('rOx: oxide aperture radius (cm)', size=(40,1))],
210+
[sg.InputText(vp['rox'], key='rox', size=(7,1), tooltip=ttips['rox'], enable_events=True), sg.Text('rox: oxide aperture radius (cm)', size=(40,1))],
212211
[sg.InputText(vp['Leff'], key='Leff', size=(7,1), tooltip=ttips['Leff'], enable_events=True), sg.Text('Leff: effective cavity length (cm)')],
213-
[sg.InputText(vp['nqw'], key='nqw', size=(7,1), tooltip=ttips['nqw'], enable_events=True), sg.Text('nqw: number of quantum wells')],
214-
[sg.InputText(vp['dqw'], key='dqw', size=(7,1), tooltip=ttips['dqw'], enable_events=True), sg.Text('dqw: single QW thickness (cm)')],
212+
[sg.InputText(vp['nw'], key='nw', size=(7,1), tooltip=ttips['nw'], enable_events=True), sg.Text('nw: number of quantum wells')],
213+
[sg.InputText(vp['dw'], key='dw', size=(7,1), tooltip=ttips['dw'], enable_events=True), sg.Text('dw: single QW thickness (cm)')],
215214
[sg.InputText(vp['db'], key='db', size=(7,1), tooltip=ttips['db'], enable_events=True), sg.Text('db: SCH thickness (cm)')],
216215
])],
217216
[sg.Frame('Equivalent waveguide parameters',[
218-
[sg.InputText(vp['wl0'], key='wl0', size=(7,1), tooltip=ttips['wl0'], enable_events=True), sg.Text('wl0: emission wavelength @300k (nm)', size=(40,1))],
217+
[sg.InputText(vp['wl0'], key='wl0', size=(7,1), tooltip=ttips['wl0'], enable_events=True), sg.Text('wl0: emission wavelength @300k (nS)', size=(40,1))],
219218
[sg.InputText(vp['nc'], key='nc', size=(7,1), tooltip=ttips['nc'], enable_events=True), sg.Text('nc: core equivalent refractive index')],
220219
[sg.InputText(vp['ng'], key='ng', size=(7,1), tooltip=ttips['ng'], enable_events=True), sg.Text('ng: group refractive index')],
221220
[sg.InputText(vp['dn'], key='dn', size=(7,1), tooltip=ttips['dn'], enable_events=True), sg.Text('dn: equivalent fractional refractive index change')],
@@ -234,10 +233,10 @@ def GUI():
234233
])],
235234
[sg.Frame('Carrier transport and diffusion parameters',[
236235
[sg.InputText(vp['tauNb'], key='tauNb', size=(7,1), tooltip=ttips['tauNb'], enable_events=True), sg.Text('tauNb: carrier lifetime in the barriers (s)', size=(40,1))],
237-
[sg.InputText(vp['tauN'], key='tauN', size=(7,1), tooltip=ttips['tauN'], enable_events=True), sg.Text('tauN: carrier lifetime in the QWs (s)', size=(40,1))],
236+
[sg.InputText(vp['tauNw'], key='tauNw', size=(7,1), tooltip=ttips['tauNw'], enable_events=True), sg.Text('tauNw: carrier lifetime in the QWs (s)', size=(40,1))],
238237
[sg.InputText(vp['tauCap'], key='tauCap', size=(7,1), tooltip=ttips['tauCap'], enable_events=True), sg.Text('tauCap: ambipolar diffusion time (s)')],
239238
[sg.InputText(vp['tauEsc'], key='tauEsc', size=(7,1), tooltip=ttips['tauEsc'], enable_events=True), sg.Text('tauEsc: thermionic emission lifetime (s)', size=(40,1))],
240-
[sg.InputText(vp['etaI'], key='etaI', size=(7,1), tooltip=ttips['etaI'], enable_events=True), sg.Text('etaI: current injection efficiency')],
239+
[sg.InputText(vp['etai'], key='etai', size=(7,1), tooltip=ttips['etai'], enable_events=True), sg.Text('etai: current injection efficiency')],
241240
[sg.InputText(vp['rs'], key='rs', size=(7,1), tooltip=ttips['rs'], enable_events=True), sg.Text('rs: current spreading coefficient (cm)')],
242241
[sg.InputText(vp['DN'], key='DN', size=(7,1), tooltip=ttips['DN'], enable_events=True), sg.Text('DN: ambipolar diffusion coeff. (cm2/s)')],
243242
])],
@@ -264,7 +263,7 @@ def GUI():
264263

265264
elif event == 'initialize params':
266265
if 'S' in locals():
267-
del rho, nrho, phi, nphi, nm, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, N
266+
del rho, nrho, phi, nphi, nNw, nS, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, Nb, Nw
268267
if 'sr' in locals():
269268
del sp, vp, sr
270269
else:
@@ -277,15 +276,15 @@ def GUI():
277276

278277
elif event == 'load file':
279278
if 'S' in locals():
280-
del rho, nrho, phi, nphi, nm, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, N
279+
del rho, nrho, phi, nphi, nNw, nS, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, Nb, Nw
281280
if 'sr' in locals():
282281
del sp, vp, sr
283282
else:
284283
del sp, vp
285284
file_name = values['load file']
286285
if file_name != '':
287286
params = load_params(file_name) # loads params file and populates dictionaries sp and vp
288-
sp, vp, sr = params['simParams'], params['vcselParams'], params['simResults'] # for post-processing, simulations results should be converted from list to numpy array and saved in the respective variables (S, N, ur, etc.)
287+
sp, vp, sr = params['simParams'], params['vcselParams'], params['simResults'] # for post-processing, simulations results should be converted from list to numpy array and saved in the respective variables (S, Nw, ur, etc.)
289288
del params
290289
update_gui(window, values, sp, vp)
291290

@@ -297,7 +296,8 @@ def GUI():
297296
"nphi": nphi,
298297
"rho": rho.tolist(),
299298
"nrho": nrho,
300-
"nm": nm,
299+
"nNw": nNw,
300+
"nS": nS,
301301
"LPlm": LPlm,
302302
"lvec": lvec.tolist(),
303303
"Ur": Ur.tolist(),
@@ -307,7 +307,8 @@ def GUI():
307307
"f": f.tolist(),
308308
"H": H.tolist(),
309309
"S2P": S2P.tolist(),
310-
"N": N.tolist(),
310+
"Nb": Nb.tolist(),
311+
"Nw": Nw.tolist(),
311312
"S": S.tolist(),
312313
}
313314
else:
@@ -319,15 +320,15 @@ def GUI():
319320
elif event == 'run simulation':
320321
save_params(sp, vp, {}, 'last_params.json') # simulation results not saved to "last_params.json"
321322
if 'S' in locals():
322-
del rho, nrho, phi, nphi, nm, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, N
323+
del rho, nrho, phi, nphi, nNw, nS, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, Nb, Nw
323324

324-
rho, nrho, phi, nphi, nm, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, N = VISTAS1D(sp, vp)
325+
rho, nrho, phi, nphi, nNw, nS, LPlm, lvec, Ur, Icw, NScw, f, H, S2P, teval, S, Nb, Nw = VISTAS1D(sp, vp)
325326
# visualization
326327
if sp['Uxyplot'] == 1: # 2D mode profiles (cosine azimuthal distribution) Ur(x,y)
327-
plot2D(Ur, LPlm, lvec, nm, rho*1e-2, nrho, phi, nphi, nfig = 1)
328+
plot2D(Ur, LPlm, lvec, nS, rho*1e-2, nrho, phi, nphi, nfig = 1)
328329

329330
if sp['PIplot'] == 1: # steady-state LI characteristic Popt(I)
330-
plotPower(Icw * 1e3, S2P*NScw[sp['ni']:,:], LPlm, xlabel = 'current (mA)')
331+
plotPower(Icw * 1e3, S2P*NScw[NScw.shape[0]-nS:,:], LPlm, xlabel = 'current (mA)')
331332

332333
if sp['Ptplot'] == 1: # dynamic response Popt(t)
333334
plotPower(teval * 1e9, S2P*S, LPlm, xlabel = 'time (ns)')

default_params.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"simParams": {
3-
"SCHTransp": false,
3+
"SCHtransp": true,
44
"ThermMod": false,
55
"Noise": false,
66
"Parasitics": false,
77
"2D": false,
8-
"ni": 15,
8+
"nNw": 15,
99
"storeN": true,
1010
"odeSolver": "RK45",
1111
"tmax": 10e-9,
@@ -26,10 +26,10 @@
2626
},
2727
"vcselParams": {
2828
"vcselDescr": "free text",
29-
"rOx": 0.0005,
29+
"rox": 0.0005,
3030
"Leff": 0.00013,
31-
"nqw": 3.0,
32-
"dqw": 8e-07,
31+
"nw": 3.0,
32+
"dw": 8e-07,
3333
"db": 4e-06,
3434
"wl0": 858.0,
3535
"nc": 3.6,
@@ -44,10 +44,10 @@
4444
"epsilon": 5e-17,
4545
"GamR": 1.8,
4646
"tauNb": 1.6e-09,
47-
"tauN": 1.6e-09,
48-
"tauCap": 4.5e-11,
49-
"tauEsc": 4e-10,
50-
"etaI": 0.9,
47+
"tauNw": 1.6e-09,
48+
"tauCap": 5e-11,
49+
"tauEsc": 5e-10,
50+
"etai": 1,
5151
"rs": 5e-05,
5252
"DN": 12.0
5353
},

last_params.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
{
22
"simParams": {
3-
"SCHTransp": false,
3+
"SCHtransp": false,
44
"ThermMod": false,
55
"Noise": false,
66
"Parasitics": false,
77
"2D": false,
8-
"ni": 15,
8+
"nNw": 15,
99
"storeN": true,
1010
"odeSolver": "RK45",
1111
"tmax": 1e-08,
1212
"dt": 1e-11,
1313
"dtFD": 1e-12,
14-
"modFormat": "step",
14+
"modFormat": "pulse",
1515
"Ion": 0.005,
1616
"Ioff": 0.002,
1717
"Iss": 0.0001,
1818
"tb": 5e-10,
1919
"Uxyplot": false,
20-
"PIplot": true,
20+
"PIplot": false,
2121
"Ptplot": true,
2222
"NSxyplot": true,
2323
"RINplot": true,
2424
"Hfplot": true,
2525
"Eyeplot": true
2626
},
2727
"vcselParams": {
28-
"vcselDescr": "free text",
29-
"rOx": 0.0005,
28+
"vcselDescr": "free text\n",
29+
"rox": 0.0005,
3030
"Leff": 0.00013,
31-
"nqw": 3.0,
32-
"dqw": 8e-07,
31+
"nw": 3.0,
32+
"dw": 8e-07,
3333
"db": 4e-06,
3434
"wl0": 858.0,
3535
"nc": 3.6,
@@ -44,10 +44,10 @@
4444
"epsilon": 5e-17,
4545
"GamR": 1.8,
4646
"tauNb": 1.6e-09,
47-
"tauN": 1.6e-09,
48-
"tauCap": 4.5e-11,
49-
"tauEsc": 4e-10,
50-
"etaI": 0.9,
47+
"tauNw": 1.6e-09,
48+
"tauCap": 5e-11,
49+
"tauEsc": 5e-10,
50+
"etai": 1.0,
5151
"rs": 5e-05,
5252
"DN": 12.0
5353
},

ttips.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
2-
"SCHTransp": "SCHTransp: boolean\n -----",
2+
"SCHtransp": "SCHtransp: boolean\n -----\n Essential mechanism affecting the dynamic behaviour of electrically pumped VCSELs.",
33
"ThermMod": "ThermMod: boolean\n -----",
44
"Noise": "Noise: boolean\n -----",
55
"Parasitics": "Parasitics: boolean\n -----",
66
"2D": "2D: boolean\n -----",
7-
"ni": "ni: int\n -----\n Number of Bessel terms in the carrier radial series expansion.",
7+
"nNw": "nNw: int\n -----\n Number of Bessel terms in the carrier radial series expansion of the carrier density Nw in the QWs.",
88
"storeN": "storeN: boolean\n -----",
99
"odeSolver": "odeSolver: string\n -----\n Check scipy.integrate.solve_ivp documentation for more details.",
1010
"tmax": "tmax: float\n -----\n Fixed to 2^13*dt for small signal modulation (power of two\n to allow use of FFT algorithm).",
1111
"dt": "dt: float\n -----\n This time-step is used to define the parameter teval of solve_ivp, that is,\n it defines the spatial resolution for storing/plotting the results.",
12-
"dtFD":"dtFD: float\n -----\n Fixed time-step for the Finite Differences solver.\n Generally approximately one order of magnitude smaller than dt.\n Once the computation is complete, the results are subsampled to dt",
12+
"dtFD":"dtFD: float\n -----\n Fixed time-step for the Finite Differences solver.\n Generally approximately one order of magnitude smaller than dt.\n Once the computation is complete, the results are subsampled to dt.",
1313
"modFormat": "modFormat: string\n -----\n 'step': turn vcsel on from 0 to Ion.\n 'pulse': step up from Ioff (steady-state as starting point) to Ion at t=0,\n and back down to Ioff at t=tmax/2\n 'random bits': generate sequence of random bits of duration tb\n between Ioff (steady-state as starting point) and Ion\n 'small signal': apply small signal step to steady-state bias current Ion\n to compute the frequency response. Simulation time and\n number of time steps are hard-coded for best results.",
1414
"Ion": "Ion: float\n -----\n 'high' current in selected modulation pattern.",
1515
"Ioff": "Ioff: float\n -----\n 'low' current in selected pattern.",
@@ -23,11 +23,11 @@
2323
"Hfplot": "MTF: boolean\n -----",
2424
"Eyeplot": "eye: boolean\n -----",
2525
"vcselDescr": "vcselDescr: string\n -----\n ",
26-
"rOx": "rOx: float\n -----\n Oxide aperture, considered to delimit the 'active area' of the cavity.",
26+
"rox": "rox: float\n -----\n Oxide aperture, proxy to delimit the 'active area' of the cavity.",
2727
"Leff": "Leff: float\n -----\n Effective cavity length, consisting approximately of the wavelength\n plus the penetration depth into the Distributed Bragg Reflectors (DBR).",
28-
"nqw": "nqw: float\n -----\n Number of quantum wells, required to calculate the equivalent active volume.",
29-
"dqw": "dqw: float\n -----\n Single quantum well thickness, required to calculate the equivalent active volume.",
30-
"db": "db: float\n -----\n Thickness of the Single Confinement Heterostructure, required to compute transport into the QWs.",
28+
"nw": "nw: float\n -----\n Number of quantum wells, required to calculate the equivalent active volume.",
29+
"dw": "dw: float\n -----\n Single quantum well thickness, required to calculate the equivalent active volume.",
30+
"db": "db: float\n -----\n Barrier thickness (Single Confinement Heterostructure), required to compute transport into the QWs.",
3131
"wl0": "wl0: float\n -----\n ",
3232
"nc": "nc: float\n -----\n ",
3333
"ng": "ng: float\n -----\n ",
@@ -39,12 +39,12 @@
3939
"gln": "gln: float\n -----\n ",
4040
"Ntr": "Ntr: float\n -----\n ",
4141
"epsilon": "epsilon: float\n -----\n ",
42-
"GamR": "Gam_r: float\n -----\n Also referred to as gain enhancement factor.\n Not to be mistaken with the longitudinal confinement factor Gam_z!",
43-
"tauNb": "tauNb: float\n -----\n ",
44-
"tauN": "tauN: float\n -----\n ",
42+
"GamR": "GamR: float\n -----\n Also referred to as gain enhancement factor.\n Not to be mistaken with the longitudinal confinement factor Gam_z!",
43+
"tauNb": "tauNb: float\n -----\n Carrier lifetime in the barriers (SCH)",
44+
"tauNw": "tauNw: float\n -----\n ",
4545
"tauEsc": "tauEsc: float\n -----\n ",
4646
"tauCap": "tauCap: float\n -----\n ",
47-
"etaI": "eta_i: float\n -----\n ",
47+
"etai": "etai: float\n -----\n ",
4848
"rs": "rs: float\n -----\n ",
4949
"DN": "DN: float\n -----\n "
5050
}

0 commit comments

Comments
 (0)