Example #1
0
    def setupKMatrices(self):
        """
        Sets up the Kx, Ky, and Kz matrices for solving the simulation once the source, crystal, and
        number harmonics are known.
        """
        self.Kx = generateKxMatrix(self.source, self.baseCrystal,
                                   self.numberHarmonics)
        self.Ky = generateKyMatrix(self.source, self.baseCrystal,
                                   self.numberHarmonics)
        if isinstance(self.Kx, np.ndarray):
            self.KDimension = self.Kx.shape[0]
            self.TMMSimulation = False
        else:
            self.KDimension = 1
            # Ensure that Kz for the gap layer is 1
            self.layerStack.gapLayer = Layer(er=1 + sq(self.Kx) + sq(self.Ky),
                                             ur=1,
                                             L=0)
            self.TMMSimulation = True
        self.KzReflectionRegion = calculateKzBackward(
            self.Kx, self.Ky, self.layerStack.reflectionLayer)
        self.KzTransmissionRegion = calculateKzForward(
            self.Kx, self.Ky, self.layerStack.transmissionLayer)
        self.KzGapRegion = calculateKzForward(self.Kx, self.Ky,
                                              self.layerStack.gapLayer)

        self.scatteringElementDimension = self.KDimension * 2
        self.scatteringElementShape = (self.scatteringElementDimension,
                                       self.scatteringElementDimension)
Example #2
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)
    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)
Example #4
0
    def testSetConvolutionMatrix(self):
        t1 = complexArray([1.75, 0, 0])
        t2 = complexArray([0, 1.5, 0])
        erData = np.transpose(
            np.loadtxt(testLocation + '/triangleData.csv', delimiter=','))
        urData = 1 * complexOnes((512, 439))
        triangleCrystal = Crystal(erData, urData, t1, t2)
        dummyLayer = Layer(crystal=triangleCrystal)
        dummyLayer.setConvolutionMatrix(self.numberHarmonics)

        convolutionMatrixActual = complexIdentity(9)
        convolutionMatrixCalculated = dummyLayer.ur
        assertAlmostEqual(convolutionMatrixActual, convolutionMatrixCalculated,
                          self.absoluteTolerance, self.relativeTolerance,
                          "UR convolution matrices for layer 1 not equal")

        convolutionMatrixCalculated = dummyLayer.er
        convolutionMatrixActual = self.layerStack.internalLayer[0].er
        assertAlmostEqual(convolutionMatrixActual, convolutionMatrixCalculated,
                          self.absoluteTolerance, self.relativeTolerance,
                          "ER convolution matrices for layer 1 not equal")
Example #5
0
    def testExtractCrystal(self):
        t1 = np.array([1, 0, 0])
        t2 = np.array([0, 1, 0])
        testCrystal = Crystal(t1, t2)
        testLayer = Layer(crystal=testCrystal)
        testStack = LayerStack(freeSpaceLayer, testLayer, freeSpaceLayer)

        actualCrystal = testCrystal
        calculatedCrystal = testStack.extractCrystal()
        assertEqual(testCrystal, actualCrystal)

        testStack = LayerStack(freeSpaceLayer, freeSpaceLayer, testLayer,
                               freeSpaceLayer)

        calculatedCrystal = testStack.extractCrystal()
        assertEqual(calculatedCrystal, actualCrystal)
Example #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
Example #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]])
Example #8
0
from rcwa import Layer, LayerStack, Source, Solver, Plotter

import numpy as np
from matplotlib import pyplot as plt

designWavelength = 1.3
startWavelength = 0.6
stopWavelength = 2.2
stepWavelength = 0.005

n1 = 3.5  # refractive index of layer 1 (Si)
n2 = 1.45  # refractive index of layer 2 (SiO2)
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)
Example #9
0
# 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

designWavelength = 1.3
startWavelength = 0.25
stopWavelength = 0.85
stepWavelength = 0.001

source = Source(wavelength=designWavelength)
siO2 = Material(material_name='SiO2')

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

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

TMMSolver.Solve(wavelengths=wavelengths)
#Plotter.plotEllipsometrySpectra(TMMSolver.results)
Plotter.plotRTSpectra(TMMSolver.results)
plt.show()
    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]])