PLaSK library
Loading...
Searching...
No Matches
shockley3d.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
20from electrical.shockley import Shockley3D
21
22eps0 = 8.854187817e-6 # pF/µm
23
25
26@material.simple()
28 def cond(self, T):
29 return (1e+9, 1e+9)
30 def eps(self, T):
31 return 1.
32
33
35
36 def setUp(self):
37 cond = Conductor()
38 contact = geometry.Cuboid(700., 700., 1., cond)
39 #rect = geometry.Cylinder(500., 300., cond)
40 #junc = geometry.Cylinder(500., 0.02, 'GaAs')
41 #self.S = pi * 0.25e6
42 rect = geometry.Cuboid(1000., 1000., 300., cond)
43 junc = geometry.Cuboid(1000., 1000., 0.02, 'GaAs')
44 self.S = 1e6
45 junc.role = 'active'
46 stack = geometry.Stack3D(xcenter=0, ycenter=0)
47 top = stack.prepend(contact)
48 stack.prepend(rect)
49 stack.prepend(junc)
50 stack.prepend(rect)
51 bottom = stack.prepend(contact)
52 space = geometry.Cartesian3D(stack)
53 self.solver = Shockley3D("electrical3d")
54 self.solver.geometry = space
55 self.solver.mesh = mesh.Rectangular3D.DivideGenerator(prediv=(3,3,2), gradual=False)
56 self.solver.beta = 10.
57 self.solver.js = 1.
58 self.solver.maxerr = 1e-3
59 self.solver.voltage_boundary.append(self.solver.mesh.TopOf(contact,top), 0.)
60 self.solver.voltage_boundary.append(self.solver.mesh.BottomOf(contact, bottom), 1.)
61
63 self.solver.compute(1000)
64 correct_current = 1e-9 * self.S * self.solver.js * (exp(self.solver.beta) - 1)
65 self.assertAlmostEqual(self.solver.get_total_current(), correct_current, 3)
66 capacitance = eps0 * material.GaAs().eps() * self.S / 0.02 # pF
67 self.assertAlmostEqual(self.solver.get_capacitance(), capacitance, 2)
68 heat = correct_current * 1.
69 self.assertAlmostEqual(self.solver.get_total_heat(), heat, 3)
70
72 self.solver.empty_elements = 'exclude'
73 self.testComputations()
74
76 self.solver.beta = lambda T: log(T * 70)
77 self.solver.compute(1000)
78 correct_current = 1e-9 * self.S * self.solver.js * (21000 - 1)
79 self.assertAlmostEqual(self.solver.get_total_current(), correct_current, 3)
80 self.solver.inTemperature = 250
81 self.solver.compute(1000)
82 correct_current = 1e-9 * self.S * self.solver.js * (17500 - 1)
83 self.assertAlmostEqual(self.solver.get_total_current(), correct_current, 3)
84
86 msh = self.solver.mesh.elements.mesh
87 geo = self.solver.geometry
88 conds = [geo.get_material(point).cond(300.) if not geo.has_role('active', point) else (0.,5.) for point in msh]
89 ac = material.Air().cond(300.)
90 result = [ac if isnan(c[0]) else c for c in self.solver.outConductivity(msh)]
91 self.assertSequenceEqual(result, conds)
92
93 if __name__ == '__main__':
94 def testGeometry(self):
95 for plane in ('xy', 'xz', 'yz'):
96 fig = figure()
97 plot_geometry(self.solver.geometry, plane=plane, margin=0.1, color='k')
98 plot_mesh(self.solver.mesh, plane=plane, color='c')
99 plot_boundary(self.solver.voltage_boundary, self.solver.mesh, self.solver.geometry, plane=plane,
100 cmap='bwr', s=40)
101 window_title(plane)
102
103
104if __name__ == '__main__':
105 test = unittest.main(exit=False)
106 show()