示例#1
0
    def __prepare(self, structure, source, harmonics):
        # initialise parameters for the computation
        Nharm = harmonics.Nharm
        nr1 = np.sqrt(structure.UR2 * structure.ER2)
        self.k_inc = source.K0 * nr1 * np.array(([
            np.sin(source.THETA) * np.cos(source.PHI),
            np.sin(source.THETA) * np.sin(source.PHI),
            np.cos(source.THETA)
        ]))
        self.k_inc /= source.K0
        self.k_ref = np.array(([self.k_inc[0], self.k_inc[1], -self.k_inc[2]]))
        nr2 = np.sqrt(structure.UR1 * structure.ER1)
        self.k_trn = np.array(([self.k_ref[0], self.k_ref[1], 0]))
        self.k_trn[2] = np.sqrt(source.K0 * source.K0 * nr2 * nr2 -
                                self.k_trn[0] * self.k_trn[0] -
                                self.k_trn[1] * self.k_trn[1])

        self.kx_mat = np.zeros((Nharm, Nharm), dtype=complex)
        self.ky_mat = np.zeros((Nharm, Nharm), dtype=complex)
        kz_0_mat = np.zeros((Nharm, Nharm), dtype=complex)
        self.kz_ref_mat = np.zeros((Nharm, Nharm), dtype=complex)
        self.kz_trn_mat = np.zeros((Nharm, Nharm), dtype=complex)
        for i, i_harm in enumerate(harmonics.P_vec):
            for j, j_harm in enumerate(harmonics.Q_vec):
                pos = i * harmonics.P_range + j
                self.kx_mat[pos, pos] = self.k_inc[0] - j_harm * 2 * np.pi / (
                    structure.Lx * source.K0)
                self.ky_mat[pos, pos] = self.k_inc[1] - i_harm * 2 * np.pi / (
                    structure.Ly * source.K0)
                kz_0_mat[pos, pos] = np.conj(
                    np.lib.scimath.sqrt(1 - (self.kx_mat[pos, pos])**2 -
                                        (self.ky_mat[pos, pos])**2))
                self.kz_ref_mat[pos, pos] = -np.conj(np.lib.scimath.sqrt(np.conj(structure.ER2)*np.conj(structure.UR2)-\
                                            self.kx_mat[pos, pos]**2-self.ky_mat[pos, pos]**2))
                self.kz_trn_mat[pos, pos] = np.conj(np.lib.scimath.sqrt(np.conj(structure.ER1)*np.conj(structure.UR1)-\
                                            self.kx_mat[pos, pos]**2-self.ky_mat[pos, pos]**2))

        self.I_mat = np.diag(np.ones(Nharm))
        self.I_big_mat = np.diag(np.ones(2 * Nharm))
        self.zeros_mat = np.zeros((Nharm, Nharm))
        zeros_big_mat = np.zeros((2 * Nharm, 2 * Nharm))
        self.W0_mat = np.diag(np.ones(2 * Nharm))
        P0_mat = np.zeros((2 * Nharm, 2 * Nharm), dtype=complex)
        P0_mat[0:Nharm, 0:Nharm] = matmul(self.kx_mat, self.ky_mat)
        P0_mat[0:Nharm,
               Nharm:2 * Nharm] = self.I_mat - matmul(self.kx_mat, self.kx_mat)
        P0_mat[Nharm:2 * Nharm,
               0:Nharm] = matmul(self.ky_mat, self.ky_mat) - self.I_mat
        P0_mat[Nharm:2 * Nharm,
               Nharm:2 * Nharm] = -matmul(self.ky_mat, self.kx_mat)
        Q0_mat = P0_mat
        lambda0_mat = np.concatenate((np.concatenate(
            (1j * kz_0_mat, self.zeros_mat),
            axis=1), np.concatenate((self.zeros_mat, 1j * kz_0_mat), axis=1)))
        self.V0_mat = matmul(Q0_mat, np.linalg.inv(lambda0_mat))

        S_global = np.concatenate((np.concatenate(
            (zeros_big_mat, self.I_big_mat),
            axis=1), np.concatenate((self.I_big_mat, zeros_big_mat), axis=1)))
        return S_global
示例#2
0
文件: tmm.py 项目: paulgoulain/RCWA
 def __compute_substrate(self, structure, S_global):
     kx, ky = self.k_inc[0], self.k_inc[1]
     # take substrate into account
     _, v_trn_mat = self.__calc_layer_params(structure.UR2, structure.ER2, kx, ky)
     vg_mat = self.__calc_gap_layer_params(kx, ky)
     a_trn_mat = UNIT_MAT_2D + matmul(np.linalg.inv(vg_mat), v_trn_mat)
     b_trn_mat = UNIT_MAT_2D - matmul(np.linalg.inv(vg_mat), v_trn_mat)
     s_trn_11_mat = matmul(b_trn_mat, np.linalg.inv(a_trn_mat))
     s_trn_12_mat = 0.5*(a_trn_mat - matmul(b_trn_mat,
                                            np.linalg.inv(a_trn_mat), b_trn_mat))
     s_trn_21_mat = 2*np.linalg.inv(a_trn_mat)
     s_trn_22_mat = -matmul(np.linalg.inv(a_trn_mat), b_trn_mat)
     s_trn_mat = np.concatenate((np.concatenate((s_trn_11_mat, s_trn_12_mat), axis=1),
                                 np.concatenate((s_trn_21_mat, s_trn_22_mat), axis=1)))
     S_global = redheffer_star_prod(S_global, s_trn_mat, UNIT_MAT_2D)
     return S_global
示例#3
0
文件: tmm.py 项目: paulgoulain/RCWA
 def __calc_s_mat(self, layer_thickness, ur, er, kx, ky, K0):
     omegai_mat, vi_mat = self.__calc_layer_params(ur, er, kx, ky)
     vg_mat = self.__calc_gap_layer_params(kx, ky)
     ai_mat = UNIT_MAT_2D + np.matmul(np.linalg.inv(vi_mat), vg_mat)
     bi_mat = UNIT_MAT_2D - np.matmul(np.linalg.inv(vi_mat), vg_mat)
     xi_mat = np.diag(np.exp(np.diag(omegai_mat)*K0*layer_thickness))
     ai_inv_mat = np.linalg.inv(ai_mat)
     di_mat = ai_mat - matmul(xi_mat, bi_mat, ai_inv_mat, xi_mat, bi_mat)
     di_inv_mat = np.linalg.inv(di_mat)
     s_11_mat = matmul(di_inv_mat, matmul(
         xi_mat, bi_mat, ai_inv_mat, xi_mat, ai_mat) - bi_mat)
     s_12_mat = matmul(di_inv_mat, xi_mat, ai_mat
                       - matmul(bi_mat, ai_inv_mat, bi_mat))
     # S_12 = S_21, S_11 = S_22
     s_mat = np.concatenate((np.concatenate((s_11_mat, s_12_mat), axis=1),
                             np.concatenate((s_12_mat, s_11_mat), axis=1)))
     return s_mat
示例#4
0
文件: tmm.py 项目: paulgoulain/RCWA
    def __get_R_T(self, structure, source, S_global):
        z_unit_vec = np.array(([0, 0, 1]))
        alpha_te = np.cross(z_unit_vec, self.k_inc)
        alpha_te = alpha_te/np.linalg.norm(alpha_te)
        alpha_tm = np.cross(alpha_te, self.k_inc)
        alpha_tm = alpha_tm/np.linalg.norm(alpha_tm)
        E_inc = source.norm_P_TM*alpha_tm + source.norm_P_TE*alpha_te
        c_inc = np.array(([E_inc[0], E_inc[1], 0, 0]))

        c_ret = matmul(S_global, c_inc)
        e_field_ref = np.array(([c_ret[0], c_ret[1], 0]))
        e_field_ref[2] = -(self.k_inc[0]*e_field_ref[0]+self.k_inc[1]*e_field_ref[1])/self.k_inc[2]
        k_trn = np.array(([self.k_inc[0], self.k_inc[1], 0]))
        nr2 = np.sqrt(structure.ER2*structure.UR2)
        k_trn[2] = np.sqrt(source.K0*source.K0*nr2*nr2 - k_trn[0]*k_trn[0] - k_trn[1]*k_trn[1])
        e_field_trn = np.array(([c_ret[2], c_ret[3], 0]))
        e_field_trn[2] = -(k_trn[0]*e_field_trn[0]+k_trn[1]*e_field_trn[1])\
            /(k_trn[2])
        R = round((np.linalg.norm(e_field_ref))**2, 4)
        T = round((np.linalg.norm(e_field_trn))**2*((k_trn[2]/structure.UR2).real)\
                /((self.k_inc[2]/structure.UR1).real), 4)
        return R, T
示例#5
0
    def __get_R_T(self, structure, source, harmonics, S_global):
        Nharm = harmonics.Nharm
        # computing input and output fields
        delta_vec = np.zeros(Nharm)
        delta_vec[int(np.floor(Nharm / 2))] = 1
        z_unit_vec = np.array(([0, 0, 1]))
        alpha_TE = np.cross(z_unit_vec, self.k_inc)
        alpha_TE = alpha_TE / np.linalg.norm(alpha_TE)
        alpha_TM = np.cross(alpha_TE, self.k_inc)
        alpha_TM = alpha_TM / np.linalg.norm(alpha_TM)
        E_inc = np.zeros(2 * Nharm, dtype=complex)
        E_inc[0:Nharm] = (source.P_TM * alpha_TM +
                          source.P_TE * alpha_TE)[0] * delta_vec
        E_inc[Nharm:2 * Nharm] = (source.P_TM * alpha_TM +
                                  source.P_TE * alpha_TE)[1] * delta_vec
        c_inc = matmul(np.linalg.inv(self.W_ref_mat), E_inc)
        E_ref_xy = matmul(self.W_ref_mat, S_global[0:2 * Nharm, 0:2 * Nharm],
                          c_inc)
        E_trn_xy = matmul(self.W_trn_mat, S_global[2 * Nharm:4 * Nharm,
                                                   0:2 * Nharm], c_inc)
        E_ref_z = -matmul(np.linalg.inv(self.kz_ref_mat),\
                  matmul(self.kx_mat, E_ref_xy[0:Nharm]) +\
                  matmul(self.ky_mat, E_ref_xy[Nharm:2*Nharm]))
        E_trn_z = -matmul(np.linalg.inv(self.kz_trn_mat),\
                  matmul(self.kx_mat, E_trn_xy[0:Nharm]) +\
                  matmul(self.ky_mat, E_trn_xy[Nharm:2*Nharm]))

        r_sq = np.zeros((Nharm), dtype=complex)
        t_sq = np.zeros((Nharm), dtype=complex)
        for i in range(0, Nharm):
            r_sq[i] = E_ref_xy[i]*np.conj(E_ref_xy[i]) +\
                      E_ref_xy[Nharm+i]*np.conj(E_ref_xy[Nharm+i]) +\
                      E_ref_z[i]*np.conj(E_ref_z[i])
            t_sq[i] = E_trn_xy[i]*np.conj(E_trn_xy[i]) +\
                      E_trn_xy[Nharm+i]*np.conj(E_trn_xy[Nharm+i]) +\
                      E_trn_z[i]*np.conj(E_trn_z[i])

        R = -np.real(matmul(self.kz_ref_mat, r_sq) / structure.UR2)
        R /= np.real(self.k_inc[2] / structure.UR2)  #

        T = np.real(matmul(self.kz_trn_mat, t_sq) / structure.UR1)
        T /= np.real(self.k_inc[2] / structure.UR1)
        return R, T
示例#6
0
    def __compute_substrate(self, structure, harmonics, S_global):
        Nharm = harmonics.Nharm
        kx_mat = self.kx_mat
        ky_mat = self.ky_mat
        # transmission region
        Q_trn_mat = np.zeros((2 * Nharm, 2 * Nharm), dtype=complex)
        Q_trn_mat[0:Nharm, 0:Nharm] = matmul(kx_mat, ky_mat)
        Q_trn_mat[0:Nharm, Nharm:2*Nharm] = structure.UR1*structure.ER1*self.I_mat -\
                                            matmul(kx_mat, kx_mat)
        Q_trn_mat[Nharm:2*Nharm, 0:Nharm] = matmul(ky_mat, ky_mat) -\
                                            structure.UR1*structure.ER1*self.I_mat
        Q_trn_mat[Nharm:2 * Nharm, Nharm:2 * Nharm] = -matmul(ky_mat, kx_mat)
        Q_trn_mat /= structure.UR1

        self.W_trn_mat = np.diag(np.ones(2 * Nharm))
        lambda_trn_mat = np.concatenate(
            (np.concatenate((1j * self.kz_trn_mat, self.zeros_mat), axis=1),
             np.concatenate((self.zeros_mat, 1j * self.kz_trn_mat), axis=1)))
        V_trn_mat = matmul(Q_trn_mat, np.linalg.inv(lambda_trn_mat))
        A_trn_mat = matmul(np.linalg.inv(self.W0_mat), self.W_trn_mat) +\
                    matmul(np.linalg.inv(self.V0_mat), V_trn_mat)
        B_trn_mat = matmul(np.linalg.inv(self.W0_mat), self.W_trn_mat) -\
                    matmul(np.linalg.inv(self.V0_mat), V_trn_mat)

        S_trn_11 = matmul(B_trn_mat, np.linalg.inv(A_trn_mat))
        S_trn_12 = 0.5 * (
            A_trn_mat - matmul(B_trn_mat, np.linalg.inv(A_trn_mat), B_trn_mat))
        S_trn_21 = 2 * np.linalg.inv(A_trn_mat)
        S_trn_22 = -matmul(np.linalg.inv(A_trn_mat), B_trn_mat)
        S_trn = np.concatenate((np.concatenate((S_trn_11, S_trn_12), axis=1),
                                np.concatenate((S_trn_21, S_trn_22), axis=1)))
        S_global = redheffer_star_prod(S_global, S_trn, self.I_big_mat)
        return S_global
示例#7
0
    def __compute_superstrate(self, structure, harmonics, S_global):
        Nharm = harmonics.Nharm
        kx_mat = self.kx_mat
        ky_mat = self.ky_mat
        # reflection region
        Q_ref_mat = np.zeros((2 * Nharm, 2 * Nharm), dtype=complex)
        Q_ref_mat[0:Nharm, 0:Nharm] = matmul(kx_mat, ky_mat)
        Q_ref_mat[0:Nharm, Nharm:2*Nharm] = structure.UR2*structure.ER2*self.I_mat -\
                                            matmul(kx_mat, kx_mat)
        Q_ref_mat[Nharm:2*Nharm, 0:Nharm] = matmul(ky_mat, ky_mat) -\
                                            structure.UR2*structure.ER2*self.I_mat
        Q_ref_mat[Nharm:2 * Nharm, Nharm:2 * Nharm] = -matmul(ky_mat, kx_mat)
        Q_ref_mat /= structure.UR2

        self.W_ref_mat = np.diag(np.ones(2 * Nharm))

        lambda_ref_mat = np.concatenate(
            (np.concatenate((-1j * self.kz_ref_mat, self.zeros_mat), axis=1),
             np.concatenate((self.zeros_mat, -1j * self.kz_ref_mat), axis=1)))
        V_ref_mat = matmul(Q_ref_mat, np.linalg.inv(lambda_ref_mat))
        A_ref_mat = matmul(np.linalg.inv(self.W0_mat), self.W_ref_mat) +\
                    matmul(np.linalg.inv(self.V0_mat), V_ref_mat)
        B_ref_mat = matmul(np.linalg.inv(self.W0_mat), self.W_ref_mat) -\
                    matmul(np.linalg.inv(self.V0_mat), V_ref_mat)
        S_ref_11 = -matmul(np.linalg.inv(A_ref_mat), B_ref_mat)
        S_ref_12 = 2 * np.linalg.inv(A_ref_mat)
        S_ref_21 = 0.5 * (
            A_ref_mat - matmul(B_ref_mat, np.linalg.inv(A_ref_mat), B_ref_mat))
        S_ref_22 = matmul(B_ref_mat, np.linalg.inv(A_ref_mat))
        S_ref = np.concatenate((np.concatenate((S_ref_11, S_ref_12), axis=1),
                                np.concatenate((S_ref_21, S_ref_22), axis=1)))

        S_global = redheffer_star_prod(S_ref, S_global, self.I_big_mat)
        return S_global
示例#8
0
    def __compute_layers(self, structure, source, harmonics, S_global):
        Nharm = harmonics.Nharm
        kx_mat = self.kx_mat
        ky_mat = self.ky_mat
        # iterating through layers
        for i in range(0, structure.num_layers):
            ERC = structure.erc_vec[i]
            URC = structure.urc_vec[i]
            thickness = structure.L[i]

            P_mat = np.zeros((2 * Nharm, 2 * Nharm), dtype=complex)
            P_mat[0:Nharm, 0:Nharm] = matmul(kx_mat, np.linalg.inv(ERC),
                                             ky_mat)
            P_mat[0:Nharm, Nharm:2 *
                  Nharm] = URC - matmul(kx_mat, np.linalg.inv(ERC), kx_mat)
            P_mat[Nharm:2 * Nharm,
                  0:Nharm] = matmul(ky_mat, np.linalg.inv(ERC), ky_mat) - URC
            P_mat[Nharm:2 * Nharm, Nharm:2 *
                  Nharm] = -matmul(ky_mat, np.linalg.inv(ERC), kx_mat)

            Q_mat = np.zeros((2 * Nharm, 2 * Nharm), dtype=complex)
            Q_mat[0:Nharm, 0:Nharm] = matmul(kx_mat, np.linalg.inv(URC),
                                             ky_mat)
            Q_mat[0:Nharm, Nharm:2 *
                  Nharm] = ERC - matmul(kx_mat, np.linalg.inv(URC), kx_mat)
            Q_mat[Nharm:2 * Nharm,
                  0:Nharm] = matmul(ky_mat, np.linalg.inv(URC), ky_mat) - ERC
            Q_mat[Nharm:2 * Nharm, Nharm:2 *
                  Nharm] = -matmul(ky_mat, np.linalg.inv(URC), kx_mat)

            Omega_sq_mat = matmul(P_mat, Q_mat)
            v_vec, W_mat = np.linalg.eig(Omega_sq_mat)
            lambda_mat = np.diag(np.conj(np.sqrt(v_vec)))
            V_mat = matmul(Q_mat, W_mat, np.linalg.inv(lambda_mat))
            A_mat = matmul(np.linalg.inv(W_mat), self.W0_mat) +\
                    matmul(np.linalg.inv(V_mat), self.V0_mat)
            B_mat = matmul(np.linalg.inv(W_mat), self.W0_mat) -\
                    matmul(np.linalg.inv(V_mat), self.V0_mat)
            X_mat = np.diag(
                np.exp(-np.diag(lambda_mat) * source.K0 * thickness))
            S_11 = matmul(np.linalg.inv(A_mat -\
                   matmul(X_mat, B_mat, np.linalg.inv(A_mat), X_mat, B_mat)),
                   (matmul(X_mat, B_mat, np.linalg.inv(A_mat), X_mat, A_mat) - B_mat))
            S_12 = matmul(np.linalg.inv(A_mat -\
                   matmul(X_mat, B_mat, np.linalg.inv(A_mat), X_mat, B_mat)),
                   X_mat, (A_mat - matmul(B_mat, np.linalg.inv(A_mat), B_mat)))
            S = np.concatenate((np.concatenate(
                (S_11, S_12), axis=1), np.concatenate((S_12, S_11), axis=1)))
            S_global = redheffer_star_prod(S_global, S, self.I_big_mat)
        return S_global