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 *
17
18from plask import *
19from plask import material, geometry, mesh, flow
20
21from gain import WasiakNewCyl
22
23plask.config.axes = 'rz'
24
25@material.simple('GaAs')
26class Barrier(material.Material):
27 lattC = 5.654
28 Dso = 0.3548
29 Me = 0.103
30 Mhh = 0.6
31 Mlh = 0.14
32 D = 10
33 @staticmethod
34 def VB(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 @staticmethod
67 def VB(T=300., e=0., point=None, hole=None):
68 return -0.5
69 @staticmethod
70 def Eg(T=300., e=0., point=None):
71 return 0.9
72
73
74@material.simple('Well')
76 @staticmethod
77 def VB(T=300., e=0., point=None, hole=None):
78 return -0.2
79 @staticmethod
80 def Eg(T=300., e=0., point=None):
81 return 0.1
82
83
85
86 def build_geometry(self, well_material, barrier_material):
87 substrate = geometry.Rectangle(20., 500., 'GaAs')
88 substrate.role = 'substrate'
89 well = geometry.Rectangle(20., 0.0060, well_material)
90 well.role = 'QW'
91 barrier = geometry.Rectangle(20., 0.0067, barrier_material)
92 stack = geometry.Stack2D()
93 stack.prepend(substrate)
94 stack.prepend(substrate)
95 active = geometry.Stack2D()
96 active.role = 'active'
97 for i in range(4):
98 active.prepend(barrier)
99 active.prepend(well)
100 active.prepend(barrier)
101 stack.prepend(active)
102 stack.prepend(substrate)
103 stack.prepend(substrate)
104 return geometry.Cylindrical(stack), active, well
105
106 def setUp(self):
107 self.msh = mesh.Rectangular2D([0.], [1000.0100])
108 self.geometry, self.active, well = self.build_geometrybuild_geometry('Well', 'Barrier')
110 self.concentration[well] = 3.5e18
111
112 def get_bands(self, band, dest_mesh, interp=None):
113 if band == 'CONDUCTION':
114 return array([self.geometry.get_material(p).CB() for p in dest_mesh])
115 elif band == 'VALENCE_LIGHT':
116 return array([self.geometry.get_material(p).VB(hole='L') for p in dest_mesh])
117 elif band == 'VALENCE_HEAVY':
118 return array([self.geometry.get_material(p).VB(hole='H') for p in dest_mesh])
119 elif band == 'SPINOFF':
120 return array([self.geometry.get_material(p).Dso() for p in dest_mesh])
121
122 def get_fermi_level(self, which, dest_mesh, interp=None):
123 value = {'ELECTRONS': 0.4290875146658184, 'HOLES': -0.5893720196570111}[which]
124 return array([value] * len(dest_mesh))
125
126 def plot_bands(self):
127 box = self.geometry.get_object_bboxes(self.active)[0]
128 zz = linspace(box.lower.z-0.002, box.upper.z+0.002, 1001)
129 msh = mesh.Rectangular2D([0.], zz)
130 CC = self.get_bandsget_bands('CONDUCTION', msh)
131 VV = self.get_bandsget_bands('VALENCE_HEAVY', msh)
132 plot(1e3*zz, CC)
133 plot(1e3*zz, VV)
134 xlim(1e3*zz[0], 1e3*zz[-1])
135 xlabel("$z$ (nm)")
136 ylabel("Band Edges (eV)")
137 window_title("Band Edges")
138 tight_layout(pad=0.5)
139
140 def assertSequenceAlmostEqual(self, first, second, places=None, delta=None):
141 self.assertEqual(len(first), len(second))
142 for i in range(len(first)):
143 self.assertAlmostEqual(first[i], second[i], places=places, delta=delta)
144
145 def test_gain(self):
146 solver = WasiakNewCyl("self.solver")
148 solver.inCarriersConcentration = self.concentration.outCarriersConcentration
149 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1254., 0)
150 msh = mesh.Rectangular2D([0.], [100.])
151 self.assertEqual(len(solver.outEnergyLevels('ELECTRONS', msh)[0]), 0)
152
154 solver = WasiakNewCyl("self.solver")
155 geom, _, _ = self.build_geometrybuild_geometry('Well0', 'Barrier0')
156 solver.geometry = geom
158 solver.inCarriersConcentration = self.concentration.outCarriersConcentration
159 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1254., 0)
161 solver.outEnergyLevels('ELECTRONS', self.msh)[0],
162 [0.3337, 0.3337, 0.3337, 0.3337, 0.5259, 0.5259, 0.5263, 0.5263, 0.5979, 0.5987],
163 3 )
165 solver.outEnergyLevels('HEAVY_HOLES', self.msh)[0],
166 [-0.6166, -0.6166, -0.6166, -0.6166, -0.6561, -0.6561, -0.6562, -0.6562, -0.7174, -0.7174, -0.7174,
167 -0.7174, -0.7978, -0.7916, -0.7859, -0.7813, -0.7788, -0.7651, -0.7627, -0.7606, -0.7591, -0.7586],
168 3 )
170 solver.outEnergyLevels('LIGHT_HOLES', self.msh)[0],
171 [-0.6415, -0.6415, -0.6415, -0.6415, -0.7386, -0.7386, -0.7390, -0.7390, -0.7997, -0.7844, -0.7833],
172 3 )
173
175 solver = WasiakNewCyl("self.solver")
179 self.assertAlmostEqual(solver.outGain(self.msh, 1275.)[0][0], 1254., 0)
180
181
182if __name__ == '__main__':
183 test = unittest.main(exit=False)
184 #instance = TestStructureGain('plot_bands')
185 #instance.setUp()
186 #instance.plot_bands()
187 #show()