PLaSK library

Loading...
Searching...
No Matches
carriers.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
14 import unittest
15
16 from numpy import *
17 from numpy.testing import assert_array_almost_equal
18
19 from plask import *
20 from plask import material, geometry, mesh
21 from plask.geometry import Cartesian2D, Cartesian3D, Cylindrical
22
23 from optical.modal import *
24 from electrical.diffusion import Diffusion2D, DiffusionCyl
25
26 config.axes = 'xyz'
27
28@material.simple('GaAs')
29 class Conc(material.Material):
30
31 def A(self, T=300):
32 return 30000000
33
34 def B(self, T=300):
35 return 1.7e-10
36
37 def C(self, T=300):
38 return 6e-30
39
40 def D(self, T=300):
41 return 10
42
43 def nr(self, lam, T, n):
44 return 3.0 + 1e-19 * n
45
46
47 class CarriersTest:
48 name = None
49 Geometry = None
50 Solver = None
51 size = 0
52 Diffusion = None
53 geometry_kwargs = {}
54
55 def setUp(self):
56 clad = geometry.Rectangle(0.500, 0.100, Conc())
57 qw = geometry.Rectangle(0.500, 0.002, Conc())
58 qw.role = 'QW'
59 ba = geometry.Rectangle(0.500, 0.001, Conc())
60 active = geometry.Stack2D()
61 active.role = 'active'
62 active.prepend(qw)
63 active.prepend(ba)
64 active.prepend(qw)
65 active.prepend(ba)
66 active.prepend(qw)
67 stack = geometry.Stack2D()
68 stack.prepend(clad)
69 stack.prepend(active)
70 stack.prepend(clad)
71 self.geometry = self.Geometry(stack, **self.geometry_kwargs)
72 self.solver = self.Solver(self.name)
73 self.solver.geometry = self.geometry
74 self.solver.lam0 = 1000.
75 self.solver.size = self.size
76 self.solver.refine = 0
77 self.solver.inGain = 1000.
78 self.test_mesh = mesh.Rectangular2D([0.0], [0.050, 0.104, 0.158])
79
80 def test_no_carriers(self):
81 assert_array_almost_equal(self.solver.outRefractiveIndex(self.test_mesh).array.real, 3.0, 4)
82
83 def test_carriers(self):
84 diffusion = self.Diffusion('diffusion')
85 diffusion.geometry = self.geometry
86 diffusion.inCurrentDensity = vec(0., 10.)
87 diffusion.compute()
88 cc = diffusion.outCarriersConcentration(mesh.Rectangular2D([0.], [0.104]))[0]
89 self.assertLess(1e18, cc)
90
91 self.solver.inCarriersConcentration = diffusion.outCarriersConcentration
92 nr = self.solver.outEpsilon(self.test_mesh).array[...,0,0].flatten().real
93 assert_array_almost_equal(nr, [9.0, (3.0 + 1e-19 * cc)**2, 9.0], 4)
94
95
96 class Fourier2DCarriers(CarriersTest, unittest.TestCase):
97 name = "fourier2"
98 Geometry = Cartesian2D
99 Solver = Fourier2D
100 Diffusion = Diffusion2D
101 geometry_kwargs = {'left': 'mirror', 'right': 'periodic'}
102
103
104# class BesselCylCarriers(CarriersTest, unittest.TestCase):
105# name = "bessel"
106# Geometry = Cylindrical
107# Solver = BesselCyl
108# size = 1
109# Diffusion = DiffusionCyl
110
111
112# class Fourier3DCarriers(CarriersTest, unittest.TestCase):
113# name = "fourier3"
114# Solver = Fourier3D
115# Diffusion = DiffusionCyl
116# geometry_kwargs = {'left': 'mirror', 'back': 'mirror', 'right': 'periodic', 'front': 'periodic'}
117
118# def Geometry(self, item, **kwargs):
119# return Cartesian3D(geometry.Clip3D(geometry.Revolution(item), left=0., back=0., right=0.35, front=0.35), **kwargs)
120
121# def setUp(self):
122# CarriersTest.setUp(self)
123# self.geometry = Cylindrical(self.geometry.item.item)
124# self.test_mesh = mesh.Rectangular3D([0.], [0.], [0.050, 0.104, 0.158])