PLaSK library
Loading...
Searching...
No Matches
gaussian.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
13import unittest
14
15from numpy import *
16from numpy.testing import assert_allclose
17
18from plask import *
19from plask import material, geometry, mesh
20from plask.geometry import Cartesian2D, Cylindrical
21from plask.flow import CurrentDensityProvider2D, CurrentDensityProviderCyl
22
23from electrical.diffusion import Diffusion2D, DiffusionCyl
24
25A = 3e7 # [1/s]
26B = 1.7e-10 # [cm³/s]
27C = 6e-27 # [cm⁶/s]
28D = 10. # [cm²/s]
29
30L = 4.0
31
32
33@material.simple('GaAs')
35
36 def A(self, T=300):
37 return A
38
39 def B(self, T=300):
40 return B
41
42 def C(self, T=300):
43 return C
44
45 def D(self, T=300):
46 return D
47
48
50 name = None
51 Geometry = None
52 Solver = None
53 geometry_kwargs = {}
54 provider = None
55 axes = None
56
57 def setUp(self):
58 config.axes = self.axes
59 clad = geometry.Rectangle(L, 0.100, 'GaAs')
60 qw = geometry.Rectangle(L, 0.002, 'GaAsQW')
61 qw.role = 'QW'
62 ba = geometry.Rectangle(L, 0.001, 'GaAs')
63 active = geometry.Stack2D()
64 active.role = 'active'
70 stack = geometry.Stack2D()
71 stack.prepend(clad)
72 stack.prepend(active)
73 stack.prepend(clad)
74 self.geometry = self.Geometry(stack, **self.geometry_kwargs)
75 self.solver = self.Solver(self.name)
76 self.solver.geometry = self.geometry
77 self.solver.maxerr = 0.0001
78 self.solver.inCurrentDensity = self.provider(lambda m, _: array([zeros(len(m.axis0)), self.jj(array(m.axis0))]).T)
79 self.test_mesh = mesh.Rectangular2D(linspace(-3.5, 3.5, 15), [0.104])
80
81 def n(self, x):
82 return 1e19 * (exp(-x**2) + 0.5)
83
84 def d2n(self, x):
85 return 2e19 * (2 * x**2 - 1) * exp(-x**2)
86
87 def j(self, x):
88 n = self.nn(x)
89 nj = 1e8 * D * self.d2nd2n(x) - A * n - B * n**2 - C * n**3
90 return -1e-7 * (phys.qe * 0.006) * nj
91
92 def test_diffusion(self):
93 self.solver.compute()
94 n = array(self.solver.outCarriersConcentration(self.test_mesh))
95 assert_allclose(n, self.nn(array(self.test_mesh.axis0)), 1e-5)
96
97
99 name = "diffusion2d"
100 Geometry = Cartesian2D
101 geometry_kwargs = {'left': 'mirror', 'right': 'air'}
102 Solver = Diffusion2D
103 provider = CurrentDensityProvider2D
104 axes = 'xy'
105
106
108 name = "diffusioncyl"
109 Geometry = Cylindrical
110 Solver = DiffusionCyl
111 provider = CurrentDensityProviderCyl
112 axes = 'rz'
113
114 def d2n(self, x):
115 return 4e19 * (x**2 - 1) * exp(-x**2)
116
117
118if __name__ == '__main__':
119 for Test in Diffusion2D, DiffusionCyl:
120 try:
121 figure()
122 test = Test()
123 test.setUp()
124 x = linspace(-4.1, 4.1, 821)
125 axhline(0., lw=0.7, color='k')
126 plot(x, test.j(x), color='C0', label='current')
127 xlabel(f"${config.axes[1]}$ [µm]")
128 ylabel("$j$ [kA/cm]")
129 legend(loc='upper left')
130 twinx()
131 plot(x, test.n(x), 'C1', label='concentration (analytic)')
135 color='C2',
136 ls='--',
137 label='concentration (numeric)'
138 )
139 xlabel(f"${config.axes[1]}$ [µm]")
140 ylabel("$n$ [cm$^{-3}$]")
141 legend(loc='upper right')
143 except Exception as e:
144 import traceback
146 show()