PLaSK library
Loading...
Searching...
No Matches
diffusion3d.py
Go to the documentation of this file.
1
# This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
2
# Copyright (c) 2023 Lodz University of Technology
3
#
4
# This program is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation, version 3.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
12
13
import
unittest
14
15
from
numpy
import
*
16
from
numpy.testing
import
assert_allclose
17
18
from
plask
import
*
19
from
plask
import
material, geometry, mesh
20
21
from
plask.flow
import
CurrentDensityProvider3D
22
23
from
electrical.diffusion
import
Diffusion3D
24
25
config.loglevel
=
'debug'
26
config.axes
=
'xyz'
27
np.set_printoptions
(linewidth=132)
28
29
A = 3e7
# [1/s]
30
B = 1.7e-10
# [cm³/s]
31
C = 6e-27
# [cm⁶/s]
32
D = 10.
# [cm²/s]
33
34
L = 4.0
35
36
37
@material.simple('GaAs')
38
class
GaAsQW
(
material.Material
):
39
40
def
A
(self, T=300):
41
return
A
42
43
def
B
(self, T=300):
44
return
B
45
46
def
C
(self, T=300):
47
return
C
48
49
def
D
(self, T=300):
50
return
D
51
52
53
class
DiffusionTest
(
unittest.TestCase
):
54
55
def
setUp
(self):
56
# clad = geometry.Cuboid(L, L, 0.100, 'GaAs')
57
# qw = geometry.Cuboid(L, L, 0.002, 'GaAsQW')
58
# ba = geometry.Cuboid(L, L, 0.001, 'GaAs')
59
clad =
geometry.Cylinder
(L, 0.100,
'GaAs'
)
60
qw =
geometry.Cylinder
(L, 0.002,
'GaAsQW'
)
61
ba =
geometry.Cylinder
(L, 0.001,
'GaAs'
)
62
qw.role
=
'QW'
63
active =
geometry.Stack3D
(x=0, y=0)
64
active.role
=
'active'
65
active.prepend
(qw)
66
active.prepend
(ba)
67
active.prepend
(qw)
68
active.prepend
(ba)
69
active.prepend
(qw)
70
stack =
geometry.Stack3D
(x=0, y=0)
71
stack.prepend
(clad)
72
stack.prepend
(active)
73
stack.prepend
(clad)
74
clip =
geometry.Clip3D
(stack, left=0., back=0.)
75
self.
geometry
=
geometry.Cartesian3D
(clip, left=
'mirror'
, right=
'air'
, back=
'mirror'
, front=
'air'
)
76
self.
solver
= Diffusion3D(
"diffusion3d"
)
77
# self.solver.algorithm = 'iterative'
78
self.
solver
.geometry = self.
geometry
79
self.
solver
.mesh =
mesh.Rectangular3D.RegularGenerator
(0.01 * L, 0.01 * L, 0.01)
80
self.
solver
.maxerr = 0.0001
81
self.
qwm
=
qw.material
82
self.
test_mesh
=
mesh.Rectangular3D
(
linspace
(-0.8 * L, 0.8 * L, 5),
linspace
(-0.8 * L, 0.8 * L, 5), [0.104])
83
84
def
filter
(self, values, x, y):
85
mask = x**2 + y**2 <= L**2
86
values[~mask] = 0.
87
return
values
88
89
def
test_uniform
(self):
90
n = 1.0e19
91
j = 1e-7 * (self.
qwm
.
A
() * n + self.
qwm
.
B
() * n**2 + self.
qwm
.
C
() * n**3) * (
phys.qe
* 0.006)
92
self.
solver
.inCurrentDensity =
vec
(0., 0., j)
93
self.
solver
.compute()
94
res = self.
solver
.outCarriersConcentration(self.
test_mesh
).array[:, :, 0]
95
ref = n *
ones_like
(res)
96
y, x =
meshgrid
(self.
test_mesh
.axis0, self.
test_mesh
.axis1)
97
assert_allclose(res, self.
filter
(ref, x, y), 1e-5)
98
99
def
n
(self, p):
100
x, y, z =
p.T
101
return
self.
filter
(1e19 * (
exp
(-x**2) *
exp
(-y**2) + 0.5), x, y)
102
103
def
d2nx
(self, p):
104
x, y, z =
p.T
105
return
self.
filter
(2e19 * (2 * x**2 - 1) *
exp
(-x**2) *
exp
(-y**2), x, y)
106
107
def
d2ny
(self, p):
108
x, y, z =
p.T
109
return
self.
filter
(2e19 *
exp
(-x**2) * (2 * y**2 - 1) *
exp
(-y**2), x, y)
110
111
def
j
(self, p):
112
x, y, z =
p.T
113
n = self.
n
(p)
114
nj = 1e8 * D * (self.
d2nx
(p) + self.
d2ny
(p)) - A * n - B * n**2 - C * n**3
115
return
self.
filter
(-1e-7 * (
phys.qe
* 0.006) * nj, x, y)
116
117
def
test_gaussian
(self):
118
self.
solver
.inCurrentDensity = CurrentDensityProvider3D(
119
lambda
m, _: array([
zeros
(
len
(m)),
zeros
(
len
(m)), self.
j
(array(m))]).T
120
)
121
self.
solver
.compute()
122
n = array(self.
solver
.outCarriersConcentration(self.
test_mesh
))
123
assert_allclose(n, self.
n
(array(self.
test_mesh
)), 0.5e-3)
124
125
126
if
__name__ ==
'__main__'
:
127
test =
DiffusionTest
()
128
test.setUp
()
129
130
x =
linspace
(-1.1 * L, 1.1 * L, 5001)
131
xm =
mesh.Rectangular3D
(x, [0.25 * L], [0.104])
132
133
axhline
(0., lw=0.7, color=
'k'
)
134
plot
(x,
test.j
(array(xm)), color=
'C0'
, label=
'current'
)
135
xlabel
(f
"${config.axes[1]}$ [µm]"
)
136
ylabel
(
"$j$ [kA/cm]"
)
137
legend
(loc=
'upper left'
)
138
twinx
()
139
140
test.solver.inCurrentDensity
= CurrentDensityProvider3D(
lambda
m, _: array([
zeros
(
len
(m)),
zeros
(
len
(m)),
test.j
(array(m))]).T)
141
test.solver.compute
()
142
plot_profile
(
test.solver.outCarriersConcentration
(xm), color=
'C2'
, label=
'concentration (numeric)'
)
143
144
plot
(x,
test.n
(array(xm)),
'C1'
, ls=
'--'
, label=
'concentration (analytic)'
)
145
146
xlabel
(f
"${config.axes[1]}$ [µm]"
)
147
ylabel
(
"$n$ [cm$^{-3}$]"
)
148
legend
(loc=
'upper right'
)
149
150
show
()
solvers
electrical
diffusion
tests
diffusion3d.py
Generated by
1.9.8