def _layer_mat2d(k0, d, epsv, epsa, mask, betaxs, betay, indices, method): n = len(betaxs) kd = k0 * d shape = epsv.shape[-2] out = np.empty(shape=(n, n, 4, 4), dtype=CDTYPE) beta = betaxy2beta(betaxs, betay) phi = betaxy2phi(betaxs, betay) for j, (beta, phi) in enumerate(zip(beta, phi)): alpha, f, fi = alphaffi(beta, phi, epsv, epsa) pmat = phase_mat(alpha, -kd) if method == "4x4_1": pmat[..., 1::2] = 0. elif method != "4x4": raise ValueError("Unsupported method!") wave = eigenwave1(shape, indices[j], amplitude=1.) #m is shape (...,4,4) m = dotmdm(f, pmat, fi) #wave is shape (...) make it broadcastable to (...,4,4) mw = m * wave[..., None, None] mf = mfft(mw, overwrite_x=True) mf = mf[mask, ...] out[:, j, :, :] = mf #for i,mfj in enumerate(mf): # out[i,j,:,:] = mfj return out
def E_cover_diffraction_matrix(shape, ks, n=1., d_cover=0, n_cover=1.5, mode=+1, betamax=BETAMAX, out=None): ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(refind2eps((n, ) * 3), CDTYPE) epsa = np.asarray((0., 0., 0.), dtype=FDTYPE) epsv_cover = np.asarray(refind2eps((n_cover, ) * 3), CDTYPE) epsa_cover = np.asarray((0., 0., 0.), dtype=FDTYPE) alpha, j = E_diffraction_alphaE(shape, ks, epsv=epsv, epsa=epsa, mode=mode, betamax=betamax) alpha0, j0, j0i = E_diffraction_alphaEEi(shape, ks, epsv=epsv_cover, epsa=epsa_cover, mode=mode, betamax=betamax) alphac = alpha0 - alpha * n / n_cover alphac = alphac - alphac[..., 0, 0, :][..., None, None, :] kd = ks * d_cover pmat = phase_matrix(alphac, kd) return dotmdm(j0, pmat, j0i, out=out)
def field_correction_matrix(beta, phi, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), out=None): alpha, f, fi = alphaffi(beta, phi, epsv, epsa) kd = -np.asarray(ks) * d pmat = phase_matrix(alpha, kd) return dotmdm(f, pmat, fi, out=out)
def projection_mat(fmat, fmati=None, mode=+1): if fmati is None: fmati = inv(fmat) diag = np.zeros(fmat.shape[:-1], fmat.dtype) if mode == 1: diag[..., 0::2] = 1. elif mode == -1: diag[..., 1::2] = 1. else: raise ValueError("Unknown propagation mode.") return dotmdm(fmat, diag, fmati)
def E_correction_matrix(beta, phi, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), mode=+1, out=None): alpha, j, ji = alphaEEi(beta, phi, epsv, epsa, mode=mode) kd = -np.asarray(ks) * d pmat = phase_matrix(alpha, kd) return dotmdm(j, pmat, ji, out=out)
def Epn_correction_matrix(beta, phi, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), out=None): alpha, f = alphaf(beta, phi, epsv, epsa) kd = -np.asarray(ks) * d pmat = phase_mat(alpha, kd[..., None, None]) e = E_mat(f, mode=None) ei = inv(e) return dotmdm(e, pmat, ei, out=out)
def _layer_mat3d(k0, d, epsv, epsa, mask, betas, phis, indices, method): n = len(betas) kd = k0 * d #/2. shape = epsv.shape[-3], epsv.shape[-2] if method.startswith("2x2"): out = np.empty(shape=(n, n, 2, 2), dtype=CDTYPE) else: out = np.empty(shape=(n, n, 4, 4), dtype=CDTYPE) for j, (beta, phi) in enumerate(zip(betas, phis)): if method.startswith("2x2"): alpha, fmat = alphaf(beta, phi, epsv, epsa) f = tmm.E_mat(fmat, mode=+1, copy=False) fi = inv(f) pmat = phase_mat(alpha[..., ::2], kd) else: alpha, f, fi = alphaffi(beta, phi, epsv, epsa) pmat = phase_mat(alpha, -kd) if method == "4x4_1": pmat[..., 1::2] = 0. if method != "4x4": raise ValueError("Unsupported method.") wave = eigenwave(shape, indices[j, 0], indices[j, 1], amplitude=1.) m = dotmdm(f, pmat, fi) mw = m * wave[..., None, None] mf = mfft2(mw, overwrite_x=True) #dd = np.linspace(0,1.,10)*d # dmat = 0. # for dm in dd: # dmat = dmat + second_field_diffraction_matrix(shape, -k0, beta, phi,dm, # epsv = (1.5,1.5,1.5), # epsa = (0.,0.,0.), betamax = 1.4) /len(dd) # mf = dotmm(dmat,mf) mf = mf[mask, ...] out[:, j, :, :] = mf return out
def field_thick_cover_diffraction_matrix(shape, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), d_cover=0, epsv_cover=(1., 1., 1.), epsa_cover=(0., 0., 0.), mode="b", betamax=BETAMAX, out=None): """Build field diffraction matrix. """ ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(epsv, dtype=CDTYPE) epsa = np.asarray(epsa, dtype=FDTYPE) alpha, f, fi = diffraction_alphaffi(shape, ks, epsv=epsv, epsa=epsa, betamax=betamax) alpha0, f0 = diffraction_alphaf(shape, ks, epsv=epsv_cover, epsa=epsa_cover, betamax=betamax) alphac = alpha0 - alpha / 1.5 alphac = alphac - alphac[..., 0, 0, :][..., None, None, :] #offset = (alphac.mean(axis = (-2,-3)))[...,None,None,:] #alphac = alphac - offset kd = ks * d_cover pmatc = phase_matrix(alphac, kd, mode=mode) kd = ks * d pmat = phase_matrix(alpha, kd, mode=mode) pmat = pmat * pmatc return dotmdm(f, pmat, fi, out=out)
def field_diffraction_matrix(shape, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), mode="b", betamax=BETAMAX, out=None): ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(epsv, dtype=CDTYPE) epsa = np.asarray(epsa, dtype=FDTYPE) alpha, f, fi = diffraction_alphaffi(shape, ks, epsv=epsv, epsa=epsa, betamax=betamax) kd = ks * d pmat = phase_matrix(alpha, kd, mode=mode) return dotmdm(f, pmat, fi, out=out)
def first_Epn_diffraction_matrix(shape, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), betamax=BETAMAX, out=None): ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(epsv, dtype=CDTYPE) epsa = np.asarray(epsa, dtype=FDTYPE) alpha, f, fi = diffraction_alphaffi(shape, ks, epsv=epsv, epsa=epsa, betamax=betamax) kd = ks * d e = E_mat(f, mode=None) pmat = phase_mat(alpha, kd[..., None, None]) return dotmdm(e, pmat, fi, out=out)
def projection_matrix(shape, ks, epsv=(1, 1, 1), epsa=(0, 0, 0.), mode=+1, betamax=BETAMAX, out=None): """Computes a reciprocial field projection matrix. """ ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(epsv, dtype=CDTYPE) epsa = np.asarray(epsa, dtype=FDTYPE) alpha, f, fi = diffraction_alphaffi(shape, ks, epsv=epsv, epsa=epsa, betamax=betamax) kd = np.zeros_like(ks) pmat = phase_matrix(alpha, kd, mode=mode) return dotmdm(f, pmat, fi, out=out)
def E_diffraction_matrix(shape, ks, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), mode=+1, betamax=BETAMAX, out=None): ks = np.asarray(ks, dtype=FDTYPE) epsv = np.asarray(epsv, dtype=CDTYPE) epsa = np.asarray(epsa, dtype=FDTYPE) alpha, j, ji = E_diffraction_alphaEEi(shape, ks, epsv=epsv, epsa=epsa, mode=mode, betamax=betamax) kd = ks * d pmat = phase_matrix(alpha, kd) return dotmdm(j, pmat, ji, out=out)
def layer_mat(kd, epsv, epsa, beta=0, phi=0, method="4x4", out=None): """Computes characteristic matrix of a single layer M=F.P.Fi, Numpy broadcasting rules apply Parameters ---------- kd : float A sequence of phase values (layer thickness times wavenumber in vacuum). len(kd) must match len(epsv) and len(epsa). epsv : array_like Epsilon eigenvalues. epsa : array_like Optical axes orientation angles (psi, theta, phi). beta : float Beta angle of input light. phi : float Phi angle of input light. method : str One of `4x4` (4x4 berreman), `2x2` (2x2 jones) or `4x2` (4x4 single reflections) out : ndarray, optional Returns ------- cmat : ndarray Characteristic matrix of the layer. """ if method == "2x2": alpha, f, fi = alphaEEi(beta, phi, epsv, epsa) pmat = phase_mat(alpha, kd) else: alpha, f, fi = alphaffi(beta, phi, epsv, epsa) pmat = phase_mat(alpha, -kd) if method in ("4x2", "2x4"): pmat[..., 1::2] = 0. return dotmdm(f, pmat, fi, out=out)