PLaSK library
Loading...
Searching...
No Matches
eim.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 optical import effective
21
22
23@material.simple()
25 def Nr(self, wl, T=300., n=0.): return 1.3
26
27
28@material.simple()
30 def Nr(self, wl, T=300., n=0.): return 1.28
31
32
34
35 def setUp(self):
37 rect = geometry.Rectangle(0.75, 0.5, Glass())
38 space = geometry.Cartesian2D(rect, left="mirror")
39 self.solver.geometry = space
40
41 def testBasic(self):
42 self.assertEqual(self.solver.id, "eim:optical.EffectiveIndex2D")
43
44 def testExceptions(self):
45 with self.assertRaisesRegex(ValueError, r"^Effective index \[0\] cannot be provided now$"):
46 self.solver.outNeff(0)
47 with self.assertRaisesRegex(ValueError, r"^Optical field magnitude \[0\] cannot be provided now$"):
48 self.solver.outLightMagnitude(0, mesh.Rectangular2D([1,2], [3,4]))
49
51 self.solver.wavelength = 1000.
52 self.solver.polarization = "TE"
53 self.assertAlmostEqual(self.solver.modes[self.solver.find_mode(1.15, '+')].neff, 1.1465, 3)
54 self.solver.root.method = 'muller'
55 self.solver.stripe_root.method = 'muller'
56 self.solver.polarization = "TM"
57 self.assertAlmostEqual( self.solver.modes[self.solver.find_mode(1.11, '+')].neff, 1.111, 3)
58
59 def testMesh(self):
60 mesh = self.solver.mesh
61
64 msh = self.solver.mesh.elements.mesh
65 geo = self.solver.geometry
66 refr = [geo.get_material(point).Nr(1000., 300.) for point in msh]
67 self.assertEqual(list(self.solver.outRefractiveIndex(msh)), refr)
68
69 def testDeltaNeffs(self):
70 xx = array([0.0, 0.5, 1.0])
71 neffs = self.solver.get_delta_neff(xx)
72 self.assertAlmostEqual(neffs[0], 1.1829, 3)
73 self.assertAlmostEqual(neffs[1], 1.1829, 3)
74 self.assertAlmostEqual(neffs[2], 0.9240, 3)
75
76
78
79 def setUp(self):
81 rect1 = geometry.Rectangle(0.75, 0.24, Glass())
82 self.rect2 = geometry.Rectangle(0.75, 0.02, Glass())
83 self.rect2.role = 'gain'
84 stack = geometry.Stack2D()
85 stack.prepend(rect1)
87 stack.prepend(rect1)
88 space = geometry.Cartesian2D(stack, left="mirror", length=1000)
90 self.solver.geometry = space
91 self.solver.mirrors = 0.7, 1.0
92 self.profile = StepProfile(space)
93 self.solver.inGain = self.profile.outGain
94
95 def testThreshold(self):
96 try:
97 from scipy.optimize import brentq
98 except ImportError:
99 pass
100 else:
101 self.solver.stripe_root.method = 'muller'
102 def fun(g):
103 self.profile[self.rect2] = g
104 m = self.solver.find_mode(1.15)
105 return self.solver.modes[m].neff.imag
106 gain = brentq(fun, 0., 100.)
107 self.assertAlmostEqual(gain, 81.648, 2)
108
110 self.profile[self.rect2] = 81.649513489
111 m = self.solver.find_mode(1.15)
112 self.solver.modes[m].power = 1.4
113 self.assertAlmostEqual(self.solver.get_total_absorption(m), -2.0, 1)
114
116 self.profile[self.rect2] = 81.649513489
117 m = self.solver.find_mode(1.15)
118 self.solver.modes[m].power = 0.7
119 box = self.solver.geometry.item.bbox
121 heat = self.solver.outHeat(msh)
122 # 1e-15: µm³->m³ W->mW
123 integral = 2e-15 * sum(heat) * (msh.axis0[1] - msh.axis0[0]) * (msh.axis1[1] - msh.axis1[0]) * self.solver.geometry.extrusion.length
124 self.assertAlmostEqual(integral, self.solver.get_total_absorption(m), 2)