PLaSK library
Loading...
Searching...
No Matches
gaussian.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
21from plask.geometry import Cartesian2D, Cylindrical
22from plask.flow import CurrentDensityProvider2D, CurrentDensityProviderCyl
23
24from electrical.olddiffusion import OldDiffusion2D, OldDiffusionCyl
25
26
27A = 3e7 # (1/s)
28B = 1.7e-10 # (cm³/s)
29C = 6e-27 # (cm⁶/s)
30D = 10 # (cm²/s)
31
32@material.simple('GaAs')
33class GaAsQW(material.Material):
34
35 def A(self, T=300):
36 return A
37
38 def B(self, T=300):
39 return B
40
41 def C(self, T=300):
42 return C
43
44 def D(self, T=300):
45 return D
46
47
48class DiffusionTest:
49 name = None
50 Geometry = None
51 Solver = None
52 geometry_kwargs = {}
53 provider = None
54 axes = None
55
56 def setUp(self):
57 config.axes = self.axes
58 L = 4.000
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.accuracy = 0.0001
78 self.solver.mesh = mesh.Regular(0., L, 801)
79 self.solver.inCurrentDensity = self.provider(lambda m, _: array([zeros(len(m.axis0)), self.jj(array(m.axis0))]).T)
80 self.test_mesh = mesh.Rectangular2D(linspace(-3.5, 3.5, 15), [0.104])
81
82 def n(self, x):
83 return 1e19 * (exp(-x**2) + 0.5)
84
85 def d2n(self, x):
86 return 2e27 * (2 * x**2 - 1) * exp(-x**2)
87
88 def j(self, x):
89 n = self.nn(x)
90 nj = D * self.d2nd2n(x) - A * n - B * n**2 - C * n**3
91 return -1e-7 * (phys.qe * 0.006) * nj
92
93 def test_diffusion(self):
94 self.solver.compute_threshold()
95 n = array(self.solver.outCarriersConcentration(self.test_mesh))
96 assert_allclose(n, self.nn(array(self.test_mesh.axis0)), 1e-5)
97
98
100 name = "diffusion2d"
101 Geometry = Cartesian2D
102 geometry_kwargs = {'left': 'mirror', 'right': 'air'}
103 Solver = OldDiffusion2D
104 provider = CurrentDensityProvider2D
105 axes = 'xy'
106
107
109 name = "diffusioncyl"
110 Geometry = Cylindrical
111 Solver = OldDiffusionCyl
112 provider = CurrentDensityProviderCyl
113 axes = 'rz'
114
115 def d2n(self, x):
116 return 4e27 * (x**2 - 1) * exp(-x**2)
117
118
119if __name__ == '__main__':
120 for Test in Diffusion2D, DiffusionCyl:
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$^2$)")
129 legend(loc='upper left')
130 twinx()
131 plot(x, test.n(x), 'C1', label='concentration (analytic)')
134 label='concentration (numeric)')
135 xlabel(f"${config.axes[1]}$ (µm)")
136 ylabel("$n$ [cm$^{-3}$]")
137 legend(loc='upper right')
139 show()