PLaSK library
Loading...
Searching...
No Matches
gaas.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3# Copyright (c) 2022 Lodz University of Technology
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, version 3.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14import unittest
15
16from numpy import *
17from numpy.testing import assert_allclose
18
19from plask import *
20from plask import material, geometry, mesh, flow
21
22from gain import FreeCarrierCyl
23
25
26@material.simple('GaAs')
28 lattC = 5.654
29 Dso = 0.3548
30 Me = 0.103
31 Mhh = 0.6
32 Mlh = 0.14
33 D = 10
34 def VB(self, T=300., e=0., point=None, hole=None):
35 return -0.75
36 def A(self, T=300.):
37 return 7e7 + (T-300) * 1.4e5
38 def B(self, T=300.):
39 return 1.1e-10 - (T-300) * -2.2e-13
40 def C(self, T=300.):
41 return 1.130976e-28 - (T-300) * 1.028743e-30 + (T-300)**2 * 8.694142e-32
42 def Eg(self, T=300., e=0., point=None):
43 return 1.30 - 0.0003 * (T-300)
44 def nr(self, wl, T=300., n=0.):
45 return 3.3 + (wl-1310) * 5.00e-4 + (T-300) * 7e-4
46 def absp(self, wl, T=300.):
47 return 50. + (T-300) * 7e-2
48
49
50@material.simple('Barrier')
52 Me = 0.052
53 Mhh = 0.477
54 Mlh = 0.103
55 absp = 1000.
56 def VB(self, T=300., e=0., point=None, hole=None):
57 return 0.14676 + 0.000033 * (T-300) - 0.75
58 def Eg(self, T=300., e=0., point=None):
59 return 0.87 - 0.0002 * (T-300) - 100. * e
60 def nr(self, wl, T=300., n=0.):
61 return 3.6 + (wl-1310) * 5.00e-4 + (T-300) * 7e-4
62
63
64@material.simple('Barrier')
66 def VB(self, T=300., e=0., point=None, hole=None):
67 return -0.5
68 def Eg(self, T=300., e=0., point=None):
69 return 0.9
70
71
72@material.simple('Well')
74 def VB(self, T=300., e=0., point=None, hole=None):
75 return -0.2
76 def Eg(self, T=300., e=0., point=None):
77 return 0.1
78
79
81
82 def build_geometry(self, well_material, barrier_material):
83 substrate = geometry.Rectangle(20., 500., 'GaAs')
84 well = geometry.Rectangle(20., 0.0060, well_material)
85 well.role = 'QW'
86 barrier = geometry.Rectangle(20., 0.0067, barrier_material)
87 stack = geometry.Stack2D()
88 cap = geometry.Rectangle(10., 500., 'GaAs')
89 shelf = geometry.Shelf2D()
90 shelf.append(cap)
91 shelf.append(cap)
92 stack.prepend(shelf)
93 active = geometry.Stack2D()
94 active.role = 'active'
95 for i in range(4):
96 active.prepend(barrier)
97 active.prepend(well)
98 active.prepend(barrier)
99 stack.prepend(active)
100 stack.prepend(substrate)
101 return geometry.Cylindrical(stack), active, well
102
103 def setUp(self):
104 self.msh = mesh.Rectangular2D([0.], [500.0100])
105 self.geometry, self.active, well = self.build_geometrybuild_geometry('Well', 'Barrier')
107 self.concentration[well] = 3.5e18
108
109 def get_bands(self, band, dest_mesh, interp=None):
110 if band == 'CONDUCTION':
111 return array([self.geometry.get_material(p).CB() for p in dest_mesh])
112 elif band == 'VALENCE_LIGHT':
113 return array([self.geometry.get_material(p).VB(hole='L') for p in dest_mesh])
114 elif band == 'VALENCE_HEAVY':
115 return array([self.geometry.get_material(p).VB(hole='H') for p in dest_mesh])
116 elif band == 'SPINOFF':
117 return array([self.geometry.get_material(p).Dso() for p in dest_mesh])
118
119 def get_fermi_level(self, which, dest_mesh, interp=None):
120 value = {'ELECTRONS': 0.4290875146658184, 'HOLES': -0.5893720196570111}[which]
121 return array([value] * len(dest_mesh))
122
123 def plot_bands(self):
124 box = self.geometry.get_object_bboxes(self.active)[0]
125 zz = linspace(box.lower.z-0.002, box.upper.z+0.002, 1001)
126 msh = mesh.Rectangular2D([0.], zz)
127 CC = self.get_bandsget_bands('CONDUCTION', msh)
128 VV = self.get_bandsget_bands('VALENCE_HEAVY', msh)
129 plot(1e3*zz, CC)
130 plot(1e3*zz, VV)
131 xlim(1e3*zz[0], 1e3*zz[-1])
132 xlabel("$z$ (nm)")
133 ylabel("Band Edges (eV)")
134 window_title("Band Edges")
135 tight_layout(pad=0.5)
136
137 def test_gain(self):
138 solver = FreeCarrierCyl("self.solver")
139 solver.strained = True
140 solver.substrate = 'GaAs'
142 solver.inCarriersConcentration = self.concentration.outCarriersConcentration
143 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1314., 0)
144 msh = mesh.Rectangular2D([0.], [-400.])
145 self.assertEqual(len(solver.outEnergyLevels('ELECTRONS', msh)[0]), 0)
146
148 solver = FreeCarrierCyl("self.solver")
149 geom, _, _ = self.build_geometrybuild_geometry('Well0', 'Barrier0')
150 solver.geometry = geom
152 solver.inCarriersConcentration = self.concentration.outCarriersConcentration
153 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1254., 0)
154 assert_allclose(
155 solver.outEnergyLevels('ELECTRONS', self.msh)[0],
156 [0.3337, 0.3337, 0.3337, 0.3337, 0.5259, 0.5259, 0.5263, 0.5263, 0.5979, 0.5987],
157 rtol=1e-3)
158 assert_allclose(
159 solver.outEnergyLevels('HEAVY_HOLES', self.msh)[0],
160 [-0.6166, -0.6166, -0.6166, -0.6166, -0.6561, -0.6561, -0.6562, -0.6562, -0.7174, -0.7174, -0.7174,
161 -0.7174, -0.7978, -0.7916, -0.7859, -0.7813, -0.7788, -0.7651, -0.7627, -0.7606, -0.7591, -0.7586],
162 rtol=1e-3)
163 assert_allclose(
164 solver.outEnergyLevels('LIGHT_HOLES', self.msh)[0],
165 [-0.6415, -0.6415, -0.6415, -0.6415, -0.7386, -0.7386, -0.7390, -0.7390, -0.7997, -0.7844, -0.7833],
166 rtol=1e-3)
167
169 solver = FreeCarrierCyl("self.solver")
173 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1254., 0)
174
175
176if __name__ == '__main__':
177 test = unittest.main(exit=False)
178 instance = TestStructureGain('plot_bands')
181 show()