Exemplo n.º 1
0
    def testLoadFromDatabase(self):
        wavelength = 0.1879  # Should load from Johnson nk table
        source = Source(wavelength=wavelength)
        Ag = Material('Ag', source=source)
        n_desired = 1.07 + 1.212j
        n_observed = Ag.n
        assertAlmostEqual(n_desired, n_observed, absoluteTolerance=1e-3)

        source.wavelength = 0.2262
        n_desired = 1.26 + 1.344j
        n_observed = Ag.n
        assertAlmostEqual(n_desired, n_observed, absoluteTolerance=1e-3)
Exemplo n.º 2
0
    def testaTEM(self):
        aTEActual = complexArray([-0.39073, 0.920505, 0])
        aTMActual = complexArray([0.50137, 0.21282, -0.838671])
        (aTECalculated, aTMCalculated) = self.source.aTE, self.source.aTM
        assertAlmostEqual(aTEActual, aTECalculated, self.absoluteTolerance,
                          self.relativeTolerance,
                          "Oblique incidence TE vector wrong")
        assertAlmostEqual(aTMActual, aTMCalculated, self.absoluteTolerance,
                          self.relativeTolerance,
                          "Oblique incidence TM vector wrong")

        ATEMActual = np.vstack((aTEActual, aTMActual))
        ATEMCalculated = self.source.ATEM
        assertAlmostEqual(ATEMActual, ATEMCalculated, self.absoluteTolerance,
                          self.relativeTolerance,
                          "Oblique incidence TM vector wrong")

        # Important corner case where the cross product fails
        aTEActual = complexArray([0, 1, 0])
        aTMActual = complexArray([1, 0, 0])
        zeroAngleSource = Source()
        (aTECalculated,
         aTMCalculated) = zeroAngleSource.aTE, zeroAngleSource.aTM
        assertAlmostEqual(aTEActual, aTECalculated, self.absoluteTolerance,
                          self.relativeTolerance,
                          "Near-normal Incidence TE vector wrong")
        assertAlmostEqual(aTMActual, aTMCalculated, self.absoluteTolerance,
                          self.relativeTolerance,
                          "Near-normal incidence TM vector wrong")
Exemplo n.º 3
0
 def setUp(self):
     self.absoluteTolerance = 1e-5
     self.relativeTolerance = 1e-4
     wavelength = 0.02
     theta = 60 * deg
     phi = 30 * deg
     pTEM = 1 / sqrt(2) * complexArray([1, 1j])
     reflectionLayer = Layer(er=2, ur=1)
     self.source = Source(wavelength, theta, phi, pTEM, reflectionLayer)
Exemplo n.º 4
0
    def testAvoidDiscontinuities(self):
        source = Source(wavelength=0.495)
        silicon = Material(filename='main/Si/Aspnes.yml', source=source)

        n_desired = 4.325778947368422 + 0.07380526315789473j
        n_observed = silicon.n
        assertAlmostEqual(n_observed,
                          n_desired,
                          errorMessage="material: testnk: n25",
                          absoluteTolerance=1e-6)

        source.wavelength = 0.496
        n_desired = 4.319492753623189 + 0.07293719806763285j
        n_observed = silicon.n
        assertAlmostEqual(n_observed,
                          n_desired,
                          errorMessage="material: testnk: n26",
                          absoluteTolerance=1e-6)
Exemplo n.º 5
0
    def setUp(self):
        self.absoluteTolerance = 1e-4
        self.relativeTolerance = 1e-3

        devicePermittivityCellData = np.transpose(
            np.loadtxt(testLocation + '/triangleData.csv', delimiter=','))
        devicePermeabilityCellData = 1 + 0 * devicePermittivityCellData

        reflectionLayer = Layer(er=2.0, ur=1.0)
        transmissionLayer = Layer(er=9.0, ur=1.0)

        # NOTE: t1 AND t2 MUST BE NORMALIZED BY MULTIPLYING BY k0, OTHERWISE THIS WILL NOT WORK, AS
        # EVERYTHING WAS FORMULATED IN TERMS OF NORMALIZED WAVEVECTORS. I DON'T KNOW OF AN ELEGANT WAY
        # TO DO THIS OTHER THAN REQUIRING A CRYSTAL TO HAVE A SOURCE AS THE INPUT. I DON'T KNOW OF
        # AN EASY WAY TO FIX THIS. I'M GOING TO FUDGE IT FOR NOW.
        wavelength = 2
        k0 = 2 * pi / wavelength
        theta = 60 * deg
        phi = 30 * deg
        pTEM = 1 / sqrt(2) * complexArray([1, 1j])
        source = Source(wavelength=wavelength,
                        theta=theta,
                        phi=phi,
                        pTEM=pTEM,
                        layer=reflectionLayer)
        t1, t2 = complexArray([1.75, 0, 0]), complexArray([0, 1.5, 0])

        thicknessLayer1 = 0.5  # should be 0.5
        thicknessLayer2 = 0.3  # should be 0.3

        numberHarmonics = (3, 3)

        deviceCrystal = Crystal(devicePermittivityCellData,
                                devicePermeabilityCellData, t1, t2)
        layer1 = Layer(crystal=deviceCrystal,
                       L=thicknessLayer1,
                       numberHarmonics=numberHarmonics)
        layer2 = Layer(er=6.0, ur=1.0, L=thicknessLayer2)
        layerStack = LayerStack(reflectionLayer, layer1, layer2,
                                transmissionLayer)

        self.solver = Solver(layerStack, source, numberHarmonics)
Exemplo n.º 6
0
    def setUpClass(self):  # NOTE - self here refers to class
        self.absoluteTolerance = 1e-3
        self.relativeTolerance = 1e-3
        deg = pi / 180
        wavelength = 2
        theta = 60 * deg
        phi = 30 * deg
        pTEM = 1 / sqrt(2) * complexArray([1, 1j])

        erReflectionRegion = 2
        urReflectionRegion = 1
        erTransmissionRegion = 9
        urTransmissionRegion = 1
        erDeviceRegion = 6
        urDeviceRegion = 1
        thicknessLayer1 = 0.5
        thicknessLayer2 = 0.3
        numberHarmonicsX = 3
        numberHarmonicsY = 3

        reflectionLayer = Layer(erReflectionRegion, urReflectionRegion)
        transmissionLayer = Layer(erTransmissionRegion, urTransmissionRegion)
        layer1 = Layer(erDeviceRegion, urDeviceRegion, thicknessLayer1)
        layer1.homogenous = False
        layer2 = Layer(erDeviceRegion, urDeviceRegion, thicknessLayer2)

        self.layerStack = LayerStack(reflectionLayer, layer1, layer2,
                                     transmissionLayer)
        self.source = Source(wavelength, theta, phi, pTEM, reflectionLayer)
        self.numberHarmonics = (numberHarmonicsX, numberHarmonicsY)

        erConvolutionMatrixLayer1 = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/layer1/erConvolutionData.txt")
        urConvolutionMatrixLayer1 = complexIdentity(9)
        erConvolutionMatrixLayer2 = erDeviceRegion * complexIdentity(9)
        urConvolutionMatrixLayer2 = complexIdentity(9)
        # This is a bit of a hack, but that's good for test purposes.
        self.layerStack.internalLayer[0].er = erConvolutionMatrixLayer1
        self.layerStack.internalLayer[0].ur = urConvolutionMatrixLayer1
        self.layerStack.internalLayer[1].er = erConvolutionMatrixLayer2
        self.layerStack.internalLayer[1].ur = urConvolutionMatrixLayer2

        self.Kx = np.diag(
            complexArray([
                2.2035, 1.0607, -0.0822, 2.2035, 1.0607, -0.0822, 2.2035,
                1.0607, -0.0822
            ]))
        self.Ky = np.diag(
            complexArray([
                1.9457, 1.9457, 1.9457, 0.6124, 0.6124, 0.6124, -0.7210,
                -0.7210, -0.7210
            ]))
        self.KzReflectionRegion = numpyArrayFromFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/KzReflectionRegion.txt")
        self.KzTransmissionRegion = np.diag(
            complexArray([
                0.5989, 2.0222, 2.2820, 1.9415, 2.7386, 2.9357, 1.9039, 2.7121,
                2.9109
            ]))

        self.KzFreeSpace = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/freeSpace/KzFreeSpace.txt")
        self.QFreeSpace = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/freeSpace/QFreeSpace.txt")
        self.WFreeSpace = complexIdentity(18)
        self.LambdaFreeSpace = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/freeSpace/LambdaFreeSpace.txt")
        self.VFreeSpace = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/freeSpace/VFreeSpace.txt")

        self.S11Transparent = complexZeros((18, 18))
        self.S22Transparent = complexZeros((18, 18))
        self.S21Transparent = complexIdentity(18)
        self.S12Transparent = complexIdentity(18)

        self.PLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/PLayer1.txt")
        self.QLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/QLayer1.txt")
        self.OmegaSquaredLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/OmegaSquaredLayer1.txt")
        self.LambdaLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/LambdaLayer1.txt")
        # NOTE - THE LAYER 1 VALUES ARE MODIFIED SO THAT ELEMENTS 7, 11, 12, AND 16 ALONG THE MAIN
        # DIAGONAL OF THE EIGENVALUE MATRIX ARE THEIR OWN CONJUGATE. THIS IS A NUMERICAL ERROR ISSUE
        # THAT I DON'T KNOW HOW TO RESOLVE AND I DON'T THINK IT SHOULD HAVE ANY PHYSICAL CONSEQUENCES.
        # SO I HAVE MODIFIED THE X AND V MATRICES. PHYSICALLY,
        self.VLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/VLayer1.txt")
        self.ALayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/ALayer1.txt")
        self.BLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/BLayer1.txt")
        self.XLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/XLayer1.txt")
        self.WLayer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/WLayer1.txt")
        self.S11Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/S11Layer1.txt")
        self.S12Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/S12Layer1.txt")
        self.S21Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/S21Layer1.txt")
        self.S22Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/S22Layer1.txt")
        self.SLayer1 = complexArray([[self.S11Layer1, self.S12Layer1],
                                     [self.S21Layer1, self.S22Layer1]])

        self.SGlobal11Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/SGlobal11Layer1.txt")
        self.SGlobal12Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/SGlobal12Layer1.txt")
        self.SGlobal21Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/SGlobal21Layer1.txt")
        self.SGlobal22Layer1 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer1/SGlobal22Layer1.txt")
        self.SGlobalLayer1 = complexArray(
            [[self.SGlobal11Layer1, self.SGlobal12Layer1],
             [self.SGlobal21Layer1, self.SGlobal22Layer1]])

        self.PLayer2 = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/layer2/PLayer2.txt")
        self.QLayer2 = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/layer2/QLayer2.txt")
        self.OmegaSquaredLayer2 = numpyArrayFromFile(
            testLocation + "/matrixDataOblique/layer2/OmegaSquaredLayer2.txt")
        self.WLayer2 = complexIdentity(18)
        self.LambdaLayer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/LambdaLayer2.txt")
        self.VLayer2 = np.loadtxt(
            testLocation + "/matrixDataOblique/layer2/VLayer2MYSELF.csv",
            dtype=np.cdouble
        )  # This is to rearrange the eigenvalue columns so that they display properly.
        self.ALayer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/ALayer2.txt")
        self.BLayer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/BLayer2.txt")
        self.XLayer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/XLayer2.txt")
        self.S11Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/S11Layer2.txt")
        self.S12Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/S12Layer2.txt")
        self.S21Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/S21Layer2.txt")
        self.S22Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/S22Layer2.txt")
        self.SLayer2 = complexArray([[self.S11Layer2, self.S12Layer2],
                                     [self.S21Layer2, self.S22Layer2]])
        self.DLayer12 = np.loadtxt(testLocation +
                                   '/matrixDataOblique/layer2/D12.csv',
                                   dtype=np.cdouble)
        self.FLayer12 = np.loadtxt(testLocation +
                                   '/matrixDataOblique/layer2/F12.csv',
                                   dtype=np.cdouble)

        self.SGlobal11Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/SGlobal11Layer2.txt")
        self.SGlobal12Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/SGlobal12Layer2.txt")
        self.SGlobal21Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/SGlobal21Layer2.txt")
        self.SGlobal22Layer2 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/layer2/SGlobal22Layer2.txt")
        self.SGlobalLayer2 = complexArray(
            [[self.SGlobal11Layer2, self.SGlobal12Layer2],
             [self.SGlobal21Layer2, self.SGlobal22Layer2]])

        self.QReflectionRegion = numpyArrayFromFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/QReflectionRegion.txt")
        self.LambdaReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/LambdaReflectionRegion.txt")
        self.WReflectionRegion = complexIdentity(18)
        self.VReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/VReflectionRegion.txt")
        self.LambdaReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/LambdaReflectionRegion.txt")
        self.AReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/AReflectionRegion.txt")
        self.BReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/BReflectionRegion.txt")
        self.S11ReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/S11ReflectionRegion.txt")
        self.S12ReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/S12ReflectionRegion.txt")
        self.S21ReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/S21ReflectionRegion.txt")
        self.S22ReflectionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/reflectionRegion/S22ReflectionRegion.txt")
        self.SReflectionRegion = complexArray(
            [[self.S11ReflectionRegion, self.S12ReflectionRegion],
             [self.S21ReflectionRegion, self.S22ReflectionRegion]])

        self.QTransmissionRegion = numpyArrayFromFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/QTransmissionRegion.txt")
        self.LambdaTransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/LambdaTransmissionRegion.txt"
        )
        self.WTransmissionRegion = complexIdentity(18)
        self.VTransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/VTransmissionRegion.txt")
        self.LambdaTransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/LambdaTransmissionRegion.txt"
        )
        self.ATransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/ATransmissionRegion.txt")
        self.BTransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/BTransmissionRegion.txt")
        self.S11TransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/S11TransmissionRegion.txt")
        self.S12TransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/S12TransmissionRegion.txt")
        self.S21TransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/S21TransmissionRegion.txt")
        self.S22TransmissionRegion = numpyArrayFromSeparatedColumnsFile(
            testLocation +
            "/matrixDataOblique/transmissionRegion/S22TransmissionRegion.txt")
        self.STransmissionRegion = complexArray(
            [[self.S11TransmissionRegion, self.S12TransmissionRegion],
             [self.S21TransmissionRegion, self.S22TransmissionRegion]])

        # Overall global scattering matrices
        self.SGlobal11 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/SGlobal11.txt")
        self.SGlobal12 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/SGlobal12.txt")
        self.SGlobal21 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/SGlobal21.txt")
        self.SGlobal22 = numpyArrayFromSeparatedColumnsFile(
            testLocation + "/matrixDataOblique/SGlobal22.txt")
        self.SGlobal = complexArray([[self.SGlobal11, self.SGlobal12],
                                     [self.SGlobal21, self.SGlobal22]])

        self.transparentSMatrix = complexZeros((2, 2, 18, 18))
        self.transparentSMatrix[0, 1] = complexIdentity(18)
        self.transparentSMatrix[1, 0] = complexIdentity(18)

        self.rx = complexArray([
            -0.0187 - 0.0155j, 0.0486 - 0.0467j, 0.0016 + 0.0012j,
            0.0324 - 0.0229j, -0.1606 - 0.0348j, -0.0089 + 0.0156j,
            0.0020 + 0.0105j, 0.0076 + 0.0187j, -0.0027 - 0.0129j
        ])
        self.ry = complexArray([
            -0.0077 - 0.0106j, 0.0184 + 0.0323j, -0.0267 - 0.0070j,
            -0.0286 + 0.0472j, 0.2335 + 0.0138j, 0.0243 + 0.0164j,
            0.0435 - 0.018j, 0.0183 + 0.0146j, -0.0062 + 0.0011j
        ])
        self.rT = np.hstack((self.rx, self.ry))
        self.rz = complexArray([
            0.0213 - 0.0218j, -0.0078 + 0.0512j, 0.0103 - 0.0388j,
            0.0120 + 0.0300j, -0.0386 - 0.0403j, 0.0123 + 0.0069j,
            -0.0197 - 0.0147j, -0.0087 + 0.0157j, 0.0039 + 0.0002j
        ])
        self.tx = complexArray([
            0.0015 - 0.0016j, -0.0583 + 0.0256j, -0.0245 - 0.0098j,
            0.0060 + 0.0210j, 0.3040 + 0.0664j, -0.0054 - 0.0632j,
            -0.0123 - 0.0262j, -0.0323 - 0.0534j, 0.0169 + 0.0455j
        ])
        self.ty = complexArray([
            -0.0024 + 0.0011j, 0.0356 + 0.0282j, -0.0230 - 0.0071j,
            0.0610 - 0.0011j, 0.0523 - 0.2913j, -0.0645 - 0.0027j,
            -0.0170 - 0.0165j, -0.0420 + 0.0298j, 0.0258 - 0.0234j
        ])
        self.tT = np.hstack((self.tx, self.ty))
        self.tz = complexArray([
            0.0023 + 0.0021j, -0.0036 - 0.0406j, 0.0187 + 0.0057j,
            -0.0261 - 0.0235j, -0.1294 + 0.0394j, 0.0133 - 0.0012j,
            0.0078 + 0.0241j, 0.0014 + 0.0288j, 0.0069 - 0.0045j
        ])

        self.R = np.array([[0, 0, 0], [0, 0.0848, 0.0011], [0, 0.0025,
                                                            0.0004]])
        self.T = np.array([[0, 0.0149, 0.0055], [0.0222, 0.7851, 0.0283],
                           [0.0053, 0.0348, 0.0150]])
        self.R = np.transpose(self.R)
        self.T = np.transpose(self.T)
        self.RTot = 0.088768
        self.TTot = 0.91123
Exemplo n.º 7
0
    def setUpClass(self):
        deg = pi / 180
        self.absoluteTolerance = 1e-4
        self.relativeTolerance = 1e-3
        self.theta = 57 * deg
        self.phi = 23 * deg
        self.pTE = 1
        self.pTM = 1j
        self.wavelength = 2.7
        erReflectionRegion = 1.4
        urReflectionRegion = 1.2
        erTransmissionRegion = 1.8
        urTransmissionRegion = 1.6
        erLayer1 = 2.0
        urLayer1 = 1.0
        erLayer2 = 1.0
        urLayer2 = 3.0

        reflectionLayer = Layer(erReflectionRegion, urReflectionRegion)
        self.source = Source(wavelength=self.wavelength,
                             theta=self.theta,
                             phi=self.phi,
                             pTEM=[self.pTE, self.pTM],
                             layer=reflectionLayer)
        thicknessLayer1 = 0.25 * self.source.wavelength
        thicknessLayer2 = 0.5 * self.source.wavelength

        transmissionLayer = Layer(erTransmissionRegion, urTransmissionRegion)
        layer1 = Layer(er=erLayer1, ur=urLayer1, L=thicknessLayer1)
        layer2 = Layer(er=erLayer2, ur=urLayer2, L=thicknessLayer2)
        self.layerStack = LayerStack(reflectionLayer, layer1, layer2,
                                     transmissionLayer)

        self.Kx = reflectionLayer.n * sin(self.theta) * cos(self.phi)
        self.Ky = reflectionLayer.n * sin(self.theta) * sin(self.phi)
        self.layerStack.gapLayer.er = 1 + sq(self.Kx) + sq(self.Ky)
        self.layerStack.gapLayer.ur = 1
        self.KzReflectionRegion = 0.705995
        self.KzTransmissionRegion = 1.3032
        self.KzLayer1 = 0.9046
        self.KzLayer2 = 1.3485

        self.ExReflected = 0.0519 - 0.2856j
        self.EyReflected = -0.4324 + 0.0780j
        self.EzReflected = 0.1866 + 0.3580j
        self.ExyzReflected = complexArray(
            [self.ExReflected, self.EyReflected, self.EzReflected])
        self.ExTransmitted = -0.0101 + 0.3577j
        self.EyTransmitted = 0.4358 - 0.0820j
        self.EzTransmitted = -0.1343 - 0.2480j
        self.ExyzTransmitted = complexArray(
            [self.ExTransmitted, self.EyTransmitted, self.EzTransmitted])

        self.rx = 0.0519 - 0.2856j
        self.ry = -0.4324 + 0.0780j
        self.rz = 0.1866 + 0.3580j
        self.tx = -0.0101 + 0.3577j
        self.ty = 0.4358 - 0.0820j
        self.tz = -0.1343 - 0.2480j
        self.R = 0.4403
        self.T = 0.5597

        self.KzGap = 1
        self.WGap = complexIdentity(2)
        self.VGap = complexArray([[0 - 0.4250j, 0 - 1.1804j],
                                  [0 + 2.0013j, 0 + 0.4250j]])

        self.ALayer1 = complexArray([[2.0049, -0.0427], [-0.0427, 2.0873]])
        self.BLayer1 = complexArray([[-0.0049, 0.0427], [0.0427, -0.0873]])
        self.XLayer1 = complexArray([[0.1493 + 0.9888j, 0 + 0j],
                                     [0 + 0j, 0.1493 + 0.9888j]])
        self.DLayer1 = complexArray([[2.0057 - 0.0003j, -0.0445 + 0.0006j],
                                     [-0.0445 + 0.0006j, 2.0916 - 0.0013j]])
        self.ALayer2 = complexArray([[3.8324, 0.2579], [0.2579, 3.3342]])
        self.BLayer2 = complexArray([[-1.8324, -0.2579], [-0.2579, -1.3342]])
        self.XLayer2 = complexArray([[-0.4583 - 0.8888j, 0 + 0j],
                                     [0 + 0j, -0.4583 - 0.8888j]])
        self.DLayer2 = complexArray([[4.3436 - 0.7182j, 0.3604 - 0.1440j],
                                     [0.3604 - 0.1440j, 3.6475 - 0.4401j]])
        self.S11Layer1 = complexArray([[0.0039 - 0.0006j, -0.0398 + 0.0060j],
                                       [-0.0398 + 0.0060j, 0.0808 - 0.0121j]])
        self.S11Layer2 = complexArray([[0.6997 - 0.2262j, 0.0517 - 0.0014j],
                                       [0.0517 - 0.0014j, 0.5998 - 0.2235j]])
        self.S12Layer1 = complexArray([[0.1490 + 0.9880j, 0.0005 + 0.0017j],
                                       [0.0005 + 0.0017j, 0.1480 + 0.9848j]])
        self.S12Layer2 = complexArray([[-0.2093 - 0.6406j, 0.0311 + 0.0390j],
                                       [0.0311 + 0.0390j, -0.2693 - 0.7160j]])
        self.S21Layer1 = complexArray([[0.1490 + 0.9880j, 0.0005 + 0.0017j],
                                       [0.0005 + 0.0017j, 0.1480 + 0.9848j]])
        self.S21Layer2 = complexArray([[-0.2093 - 0.6406j, 0.0311 + 0.0390j],
                                       [0.0311 + 0.0390j, -0.2693 - 0.7160j]])
        self.S22Layer1 = complexArray([[0.0039 - 0.0006j, -0.0398 + 0.0060j],
                                       [-0.0398 + 0.0060j, 0.0808 - 0.0121j]])
        self.S22Layer2 = complexArray([[0.6997 - 0.2262j, 0.0517 - 0.0014j],
                                       [0.0517 - 0.0014j, 0.5998 - 0.2235j]])
        self.SLayer1 = complexArray([[self.S11Layer1, self.S12Layer1],
                                     [self.S21Layer1, self.S22Layer1]])
        self.SLayer2 = complexArray([[self.S11Layer2, self.S12Layer2],
                                     [self.S21Layer2, self.S22Layer2]])

        self.transparentSMatrix = complexZeros((2, 2, 2, 2))
        self.transparentSMatrix[1, 0] = complexIdentity(2)
        self.transparentSMatrix[0, 1] = complexIdentity(2)

        self.SReflectionRegion = complexZeros((2, 2, 2, 2))
        self.SReflectionRegion[0, 0] = complexArray([[-0.0800, 0.0761],
                                                     [0.0761, -0.2269]])
        self.SReflectionRegion[0, 1] = complexArray([[1.0800, -0.0761],
                                                     [-0.0761, 1.2269]])
        self.SReflectionRegion[1, 0] = complexArray([[0.9200, 0.0761],
                                                     [0.0761, 0.7731]])
        self.SReflectionRegion[1, 1] = complexArray([[0.0800, -0.0761],
                                                     [-0.0761, 0.2269]])

        self.STransmissionRegion = complexZeros((2, 2, 2, 2))
        self.STransmissionRegion[0, 0] = complexArray([[0.2060, 0.0440],
                                                       [0.0440, 0.1209]])
        self.STransmissionRegion[0, 1] = complexArray([[0.7940, -0.0440],
                                                       [-0.0440, 0.8791]])
        self.STransmissionRegion[1, 0] = complexArray([[1.2060, 0.0440],
                                                       [0.0440, 1.1209]])
        self.STransmissionRegion[1, 1] = complexArray([[-0.2060, -0.0440],
                                                       [-0.0440, -0.1209]])
Exemplo n.º 8
0
t1 = designWavelength / 4 / n1
t2 = designWavelength / 4 / n2

reflectionLayer = Layer(n=1)
transmissionLayer = Layer(n=n1)
layer0 = Layer(n=n1, L=t1)
layer1 = Layer(n=n2, L=t2)
layer2 = Layer(n=n1, L=t1)
layer3 = Layer(n=n2, L=t2)
layer4 = Layer(n=n1, L=t1)
layer5 = Layer(n=n2, L=t2)
layer6 = Layer(n=n1, L=t1)
layer7 = Layer(n=n2, L=t2)
layer8 = Layer(n=n1, L=t1)
layer9 = Layer(n=n2, L=t2)
layer10 = Layer(n=n1, L=t1)
stack = LayerStack(reflectionLayer, layer0, layer1, layer2, layer3, layer4,
                   layer5, layer6, layer7, layer8, layer9, layer10,
                   transmissionLayer)
source = Source(wavelength=designWavelength)

print("Solving system...")
TMMSolver = Solver(stack, source, (1, 1))
wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
                        stepWavelength)

TMMSolver.Solve(wavelengths=wavelengths)
#Plotter.plotEllipsometrySpectra(TMMSolver1.results)
Plotter.plotRTSpectra(TMMSolver.results)
plt.show()
Exemplo n.º 9
0
 def setUpClass(cls):
     source = Source(wavelength=1)
     cls.silicon = Material(filename='main/Si/Schinke.yml', source=source)
Exemplo n.º 10
0
 def test_extract_dispersion_formula_1(self):
     src = Source(wavelength=0.5)
     SiO2 = Material(filename='main/SiO2/Radhakrishnan-o.yml', source=src)
     n_desired = 1.548755
     n_actual = SiO2.n
     assertAlmostEqual(n_actual, n_desired, absoluteTolerance=1e-5)
Exemplo n.º 11
0
 def test_extract_dispersion_formula_2(self):
     src = Source(wavelength=0.5)
     SiO2 = Material(filename='main/SiO2/Ghosh-e.yml', source=src)
     n_desired = 1.5580
     n_actual = SiO2.n
     assertAlmostEqual(n_actual, n_desired, absoluteTolerance=1e-5)
Exemplo n.º 12
0
# Contact: [email protected]
# Creation Date: 11/01/2019
#
import context
from rcwa import Material, Layer, LayerStack, Source, Solver, Plotter

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

startWavelength = 0.25
stopWavelength = 0.850
stepWavelength = 0.001
incident_angle = np.radians(75)

source = Source(wavelength=startWavelength, theta=incident_angle)
si = Material('Si')
breakpoint()

reflectionLayer = Layer(n=1) # Free space
transmissionLayer = Layer(material=si)
stack = LayerStack(reflectionLayer, transmissionLayer)

print("Solving system...")
TMMSolver = Solver(stack, source, (1, 1))
wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
        stepWavelength)

TMMSolver.Solve(wavelengths=wavelengths)

tan_psi_predicted = np.array([result['tanPsi'] for result in TMMSolver.results])
Exemplo n.º 13
0
    def setUp(self):
        self.absoluteTolerance = 1e-4
        self.relativeTolerance = 1e-3

        reflectionLayer = Layer(er=1.4, ur=1.2)
        transmissionLayer = Layer(er=1.8, ur=1.6)

        # NOTE: t1 AND t2 MUST BE NORMALIZED BY MULTIPLYING BY k0, OTHERWISE THIS WILL NOT WORK, AS
        # EVERYTHING WAS FORMULATED IN TERMS OF NORMALIZED WAVEVECTORS. I DON'T KNOW OF AN ELEGANT WAY
        # TO DO THIS OTHER THAN REQUIRING A CRYSTAL TO HAVE A SOURCE AS THE INPUT. I DON'T KNOW OF
        # AN EASY WAY TO FIX THIS. I'M GOING TO FUDGE IT FOR NOW.
        wavelength = 2.7
        k0 = 2 * pi / wavelength
        theta = 57 * deg
        phi = 23 * deg
        pTEM = 1 / sqrt(2) * complexArray([1, 1j])
        source = Source(wavelength=wavelength,
                        theta=theta,
                        phi=phi,
                        pTEM=pTEM,
                        layer=reflectionLayer)

        thicknessLayer1 = wavelength * 0.25  # should be 0.5
        thicknessLayer2 = wavelength * 0.5  # should be 0.3

        numberHarmonics = (1, 1)

        layer1 = Layer(er=2.0, ur=1.0, L=thicknessLayer1)
        layer2 = Layer(er=1.0, ur=3.0, L=thicknessLayer2)
        layerStack = LayerStack(reflectionLayer, layer1, layer2,
                                transmissionLayer)

        self.solver = Solver(layerStack, source, numberHarmonics)

        self.Kx = 1.0006
        self.Ky = 0.4247
        self.KzReflectionRegion = 0.705995
        self.kIncident = complexArray(
            [self.Kx, self.Ky, self.KzReflectionRegion])
        self.KzTransmissionRegion = 1.30324
        self.KzGapRegion = 1

        self.rx = 0.0519 - 0.2856j
        self.ry = -0.4324 + 0.0780j
        self.rz = 0.1866 + 0.3580j
        self.tx = -0.0101 + 0.3577j
        self.ty = 0.4358 - 0.0820j
        self.tz = -0.1343 - 0.2480j
        self.R = 0.4403
        self.T = 0.5597

        self.tanPsi = 1.0538
        self.cosDelta = 0.997733
        self.delta = -0.0673421

        #self.rTE = -0.418308 + 0.183386j
        #self.rTM = -0.222488 - 0.426831j
        self.rTE = -0.591577 + 0.259348j
        self.rTM = -0.60363 + 0.314646j

        self.KzGap = 1
        self.WGap = complexIdentity(2)
        self.VGap = complexArray([[0 - 0.4250j, 0 - 1.1804j],
                                  [0 + 2.0013j, 0 + 0.4250j]])

        self.ALayer1 = complexArray([[2.0049, -0.0427], [-0.0427, 2.0873]])
        self.BLayer1 = complexArray([[-0.0049, 0.0427], [0.0427, -0.0873]])
        self.XLayer1 = complexArray([[0.1493 + 0.9888j, 0 + 0j],
                                     [0 + 0j, 0.1493 + 0.9888j]])
        self.DLayer1 = complexArray([[2.0057 - 0.0003j, -0.0445 + 0.0006j],
                                     [-0.0445 + 0.0006j, 2.0916 - 0.0013j]])
        self.ALayer2 = complexArray([[3.8324, 0.2579], [0.2579, 3.3342]])
        self.BLayer2 = complexArray([[-1.8324, -0.2579], [-0.2579, -1.3342]])
        self.XLayer2 = complexArray([[-0.4583 - 0.8888j, 0 + 0j],
                                     [0 + 0j, -0.4583 - 0.8888j]])
        self.DLayer2 = complexArray([[4.3436 - 0.7182j, 0.3604 - 0.1440j],
                                     [0.3604 - 0.1440j, 3.6475 - 0.4401j]])
        self.S11Layer1 = complexArray([[0.0039 - 0.0006j, -0.0398 + 0.0060j],
                                       [-0.0398 + 0.0060j, 0.0808 - 0.0121j]])
        self.S11Layer2 = complexArray([[0.6997 - 0.2262j, 0.0517 - 0.0014j],
                                       [0.0517 - 0.0014j, 0.5998 - 0.2235j]])
        self.S12Layer1 = complexArray([[0.1490 + 0.9880j, 0.0005 + 0.0017j],
                                       [0.0005 + 0.0017j, 0.1480 + 0.9848j]])
        self.S12Layer2 = complexArray([[-0.2093 - 0.6406j, 0.0311 + 0.0390j],
                                       [0.0311 + 0.0390j, -0.2693 - 0.7160j]])
        self.S21Layer1 = complexArray([[0.1490 + 0.9880j, 0.0005 + 0.0017j],
                                       [0.0005 + 0.0017j, 0.1480 + 0.9848j]])
        self.S21Layer2 = complexArray([[-0.2093 - 0.6406j, 0.0311 + 0.0390j],
                                       [0.0311 + 0.0390j, -0.2693 - 0.7160j]])
        self.S22Layer1 = complexArray([[0.0039 - 0.0006j, -0.0398 + 0.0060j],
                                       [-0.0398 + 0.0060j, 0.0808 - 0.0121j]])
        self.S22Layer2 = complexArray([[0.6997 - 0.2262j, 0.0517 - 0.0014j],
                                       [0.0517 - 0.0014j, 0.5998 - 0.2235j]])
        self.SLayer1 = complexArray([[self.S11Layer1, self.S12Layer1],
                                     [self.S21Layer1, self.S22Layer1]])

        self.SLayer2 = complexArray([[self.S11Layer2, self.S12Layer2],
                                     [self.S21Layer2, self.S22Layer2]])

        self.transparentSMatrix = complexZeros((2, 2, 2, 2))
        self.transparentSMatrix[1, 0] = complexIdentity(2)
        self.transparentSMatrix[0, 1] = complexIdentity(2)

        self.SReflectionRegion = complexZeros((2, 2, 2, 2))
        self.SReflectionRegion[0, 0] = complexArray([[-0.0800, 0.0761],
                                                     [0.0761, -0.2269]])
        self.SReflectionRegion[0, 1] = complexArray([[1.0800, -0.0761],
                                                     [-0.0761, 1.2269]])
        self.SReflectionRegion[1, 0] = complexArray([[0.9200, 0.0761],
                                                     [0.0761, 0.7731]])
        self.SReflectionRegion[1, 1] = complexArray([[0.0800, -0.0761],
                                                     [-0.0761, 0.2269]])

        self.STransmissionRegion = complexZeros((2, 2, 2, 2))
        self.STransmissionRegion[0, 0] = complexArray([[0.2060, 0.0440],
                                                       [0.0440, 0.1209]])
        self.STransmissionRegion[0, 1] = complexArray([[0.7940, -0.0440],
                                                       [-0.0440, 0.8791]])
        self.STransmissionRegion[1, 0] = complexArray([[1.2060, 0.0440],
                                                       [0.0440, 1.1209]])
        self.STransmissionRegion[1, 1] = complexArray([[-0.2060, -0.0440],
                                                       [-0.0440, -0.1209]])
Exemplo n.º 14
0
    def testGenerateKxMatrix(self):
        absoluteTolerance = 1e-4
        relativeTolerance = 1e-3

        # Test our KX matrix at the gamma point
        kxMatrixActual = self.KxMatrixGPoint
        sourceGPoint = Source()
        sourceGPoint.kIncident = self.incidentKVectorGPoint
        sourceGPoint.k0 = 1
        kxMatrixCalculated = generateKxMatrix(sourceGPoint, self.crystal,
                                              self.numberHarmonics)
        assertAlmostEqual(kxMatrixActual, kxMatrixCalculated,
                          absoluteTolerance, relativeTolerance,
                          "testHarmonics: Kx at Gamma Point")

        # Test our KX matrix at the X point
        kxMatrixActual = self.KxMatrixXPoint
        sourceXPoint = Source()
        sourceXPoint.kIncident = self.incidentKVectorXPoint
        sourceXPoint.k0 = 1
        kxMatrixCalculated = generateKxMatrix(sourceXPoint, self.crystal,
                                              self.numberHarmonics)
        assertAlmostEqual(kxMatrixActual, kxMatrixCalculated,
                          absoluteTolerance, relativeTolerance,
                          "testHarmonics: Kx at X Point")

        # Test our KX matrix at the M point
        kxMatrixActual = self.KxMatrixMPoint
        sourceMPoint = Source()
        sourceMPoint.kIncident = self.incidentKVectorMPoint
        sourceMPoint.k0 = 1
        kxMatrixCalculated = generateKxMatrix(sourceMPoint, self.crystal,
                                              self.numberHarmonics)
        assertAlmostEqual(kxMatrixActual, kxMatrixCalculated,
                          absoluteTolerance, relativeTolerance,
                          "testHarmonics: Kx at M Point")
Exemplo n.º 15
0
    def setUp(self):
        self.numberHarmonics = (3, 3, 1)
        self.matrixDimensions = np.prod(self.numberHarmonics)
        self.matrixShape = (self.matrixDimensions, self.matrixDimensions)

        a = 1
        self.ax = a
        self.ay = a
        self.r = 0.35 * a
        self.er = 9.0

        self.Nx = 512
        self.Ny = 512
        self.dx = self.ax / self.Nx
        self.dy = self.ay / self.Ny

        self.t1 = complexArray([self.ax, 0])
        self.t2 = complexArray([0, self.ay])
        self.T1 = (2 * pi / self.ax) * complexArray([1, 0])
        self.T2 = (2 * pi / self.ay) * complexArray([0, 1])

        self.incidentKVectorGPoint = 0 * self.T1
        self.incidentKVectorXPoint = 0.5 * self.T1
        self.incidentKVectorMPoint = 0.5 * self.T1 + 0.5 * self.T2

        xcoors = np.linspace(-self.ax / 2 + self.dx / 2,
                             self.ax / 2 - self.dx / 2, self.Nx)
        ycoors = np.linspace(-self.ay / 2 + self.dy / 2,
                             self.ay / 2 - self.dy / 2, self.Ny)
        (X, Y) = np.meshgrid(xcoors, ycoors)
        self.UR = complexOnes((self.Nx, self.Ny))
        self.ER = (self.er - 1) * np.heaviside(sq(X) + sq(Y) - sq(self.r), 1)
        self.ER = self.ER + 1
        source = Source()
        self.crystal = Crystal(self.ER, self.UR, self.t1, self.t2)

        # The data for Kx, Ky, and Kz will be re-used at each point of key symmetry
        self.KxMatrixGPoint = complexZeros(self.matrixShape)
        self.KxMatrixGPoint[0, 0] = 6.2832
        self.KxMatrixGPoint[2, 2] = -6.2832
        self.KxMatrixGPoint[3, 3] = 6.2832
        self.KxMatrixGPoint[5, 5] = -6.2832
        self.KxMatrixGPoint[6, 6] = 6.2832
        self.KxMatrixGPoint[8, 8] = -6.2832

        self.KyMatrixGPoint = complexZeros(self.matrixShape)
        self.KyMatrixGPoint[0, 0] = 6.2832
        self.KyMatrixGPoint[1, 1] = 6.2832
        self.KyMatrixGPoint[2, 2] = 6.2832
        self.KyMatrixGPoint[6, 6] = -6.2832
        self.KyMatrixGPoint[7, 7] = -6.2832
        self.KyMatrixGPoint[8, 8] = -6.2832

        self.KxMatrixXPoint = complexZeros(self.matrixShape)
        self.KxMatrixXPoint[0, 0] = 9.4248
        self.KxMatrixXPoint[1, 1] = 3.1416
        self.KxMatrixXPoint[2, 2] = -3.1416
        self.KxMatrixXPoint[3, 3] = 9.4248
        self.KxMatrixXPoint[4, 4] = 3.1416
        self.KxMatrixXPoint[5, 5] = -3.1416
        self.KxMatrixXPoint[6, 6] = 9.4248
        self.KxMatrixXPoint[7, 7] = 3.1416
        self.KxMatrixXPoint[8, 8] = -3.1416

        diagonalValuesKyXPoint = complexArray(
            [6.2832, 6.2832, 6.2832, 0, 0, 0, -6.2832, -6.2832, -6.2832])
        self.KyMatrixXPoint = np.diag(diagonalValuesKyXPoint)

        diagonalValuesKxMPoint = complexArray([
            9.4248, 3.1416, -3.1416, 9.4248, 3.1416, -3.1416, 9.4248, 3.1416,
            -3.1416
        ])
        self.KxMatrixMPoint = np.diag(diagonalValuesKxMPoint)

        diagonalValuesKyMPoint = complexArray([
            9.4248, 9.4248, 9.4248, 3.1416, 3.1416, 3.1416, -3.1416, -3.1416,
            -3.1416
        ])
        self.KyMatrixMPoint = np.diag(diagonalValuesKyMPoint)