def mat_tm_tm(eps_array, d_array, eps_inv_mat, gk, indmode1, oms1, As1, Bs1, chis1, indmode2, oms2, As2, Bs2, chis2, pp): """ Matrix block for TM-TM mode coupling """ # Index matrix selecting the participating modes indmat = np.ix_(indmode1, indmode2) # Number of layers Nl = eps_array.size # Build the matrix layer by layer mat = bd.zeros((indmode1.size, indmode2.size)) for il in range(0, Nl): mat = mat + eps_inv_mat[il][indmat]*( (pp[indmat] * bd.outer(bd.conj(chis1[il, :]), chis2[il, :]) + \ bd.outer(gk[indmode1], gk[indmode2])) * ( bd.outer(bd.conj(As1[il, :]), As2[il, :]) * IJ_layer(il, Nl, chis2[il, :] - bd.conj(chis1[il, :][:, bd.newaxis]), d_array) + bd.outer(bd.conj(Bs1[il, :]), Bs2[il, :]) * IJ_layer(il, Nl, -chis2[il, :] + bd.conj(chis1[il, :][:, bd.newaxis]), d_array)) - \ (pp[indmat] * bd.outer(bd.conj(chis1[il, :]), chis2[il, :]) - \ bd.outer(gk[indmode1], gk[indmode2])) * ( bd.outer(bd.conj(As1[il, :]), Bs2[il, :]) * IJ_layer(il, Nl, -chis2[il, :] - bd.conj(chis1[il, :][:, bd.newaxis]), d_array) + bd.outer(bd.conj(Bs1[il, :]), As2[il, :]) * IJ_layer(il, Nl, chis2[il, :] + bd.conj(chis1[il, :][:, bd.newaxis]), d_array)) ) return mat
def mat_tm_te(eps_array, d_array, eps_inv_mat, indmode1, oms1, As1, Bs1, chis1, indmode2, oms2, As2, Bs2, chis2, pq): """ Matrix block for TM-TE mode coupling """ # Index matrix selecting the participating modes indmat = np.ix_(indmode1, indmode2) # Number of layers Nl = eps_array.size # Build the matrix layer by layer mat = bd.zeros((indmode1.size, indmode2.size)) for il in range(0, Nl): mat = mat + 1j * eps_inv_mat[il][indmat] * \ eps_array[il] * bd.conj(chis1[il, :])[:, bd.newaxis] * ( bd.outer(bd.conj(As1[il, :]), As2[il, :]) * IJ_layer(il, Nl, chis2[il, :] - bd.conj(chis1[il, :][:, bd.newaxis]), d_array) -bd.outer(bd.conj(Bs1[il, :]), Bs2[il, :]) * IJ_layer(il, Nl, -chis2[il, :] + bd.conj(chis1[il, :][:, bd.newaxis]), d_array) +bd.outer(bd.conj(As1[il, :]), Bs2[il, :]) * IJ_layer(il, Nl, -chis2[il, :] - bd.conj(chis1[il, :][:, bd.newaxis]), d_array) -bd.outer(bd.conj(Bs1[il, :]), As2[il, :]) * IJ_layer(il, Nl, chis2[il, :] + bd.conj(chis1[il, :][:, bd.newaxis]), d_array) ) # Final pre-factor mat = mat * (oms2**2)[bd.newaxis, :] * pq[indmat] return mat
def normalization_coeff(omega, g, eps_array, d_array, chi_array, ABref, pol='TE'): """ Normalization of the guided modes (i.e. the A and B coeffs) """ assert len(d_array)==len(eps_array)-2, \ 'd_array should have length = num_layers' if chi_array is None: chi_array = chi(omega, g, eps_array) As = ABref[:, 0].ravel() Bs = ABref[:, 1].ravel() if pol == 'TM': term1 = (bd.abs(Bs[0])**2) * J_alpha(chi_array[0]-bd.conj(chi_array[0])) term2 = (bd.abs(As[-1])**2) * \ J_alpha(chi_array[-1]-bd.conj(chi_array[-1])) term3 = ( (bd.abs(As[1:-1])**2 + bd.abs(Bs[1:-1])**2) * \ I_alpha(chi_array[1:-1]-bd.conj(chi_array[1:-1]),d_array) + (bd.conj(As[1:-1]) * Bs[1:-1] + As[1:-1] * bd.conj(Bs[1:-1])) * I_alpha(-chi_array[1:-1]-bd.conj(chi_array[1:-1]),d_array) ) return term1 + term2 + bd.sum(term3) elif pol == 'TE': term1 = (bd.abs(chi_array[0])**2 + g**2) * \ (bd.abs(Bs[0])**2) * J_alpha(chi_array[0]-bd.conj(chi_array[0])) term2 = (bd.abs(chi_array[-1])**2 + g**2) * \ (bd.abs(As[-1])**2) * J_alpha(chi_array[-1]-bd.conj(chi_array[-1])) term3 = (bd.abs(chi_array[1:-1])**2 + g**2) * ( (bd.abs(As[1:-1])**2 + bd.abs(Bs[1:-1])**2) * \ I_alpha(chi_array[1:-1]-bd.conj(chi_array[1:-1]), d_array)) + \ (g**2 - bd.abs(chi_array[1:-1])**2) * ( (bd.conj(As[1:-1]) * Bs[1:-1] + As[1:-1] * bd.conj(Bs[1:-1])) * I_alpha(-chi_array[1:-1]-bd.conj(chi_array[1:-1]), d_array) ) return term1 + term2 + bd.sum(term3) else: raise Exception('Polarization should be TE or TM.')