def jones2H(jones, wavenumbers, n=1., betamax=BETAMAX, mode=+1, out=None): eps = refind2eps([n] * 3) shape = jones.shape[-2:] layer = np.asarray((0., 0., 0.), dtype=FDTYPE) alpha, f, fi = diffraction_alphaffi(shape, wavenumbers, epsv=eps, epsa=layer, betamax=betamax) # A = f[...,::2,::2] # B = f[...,1::2,::2] # Ai = inv(A) # D = dotmm(B,Ai) D = E2H_mat(f, mode=mode) return diffract(jones, D, out=out)
def as2x2(pmat, fmat, mode=+1, out=None): """Converts jones 4x4 matrix to 2x2 E-field matrix""" H = E2H_mat(fmat, mode=mode) out = dotmm(pmat[..., ::2, 1::2], H, out) out += pmat[..., ::2, ::2] return out
def _transfer_ray_2x2_1(fft_field, wavenumbers, layer, effective_layer_in, effective_layer_out, dmat1, dmat2, beta=0, phi=0, nsteps=1, mode=+1, reflection=True, betamax=BETAMAX, refl=None, bulk=None, out=None, tmpdata=None): _out = {} if tmpdata is None else tmpdata #fft_field = fft2(fft_field, out = out) shape = fft_field.shape[-2:] d_in, epsv_in, epsa_in = effective_layer_in d_out, epsv_out, epsa_out = effective_layer_out if reflection: tmat, rmat = E_tr_matrix(shape, wavenumbers, epsv_in=epsv_in, epsa_in=epsa_in, epsv_out=epsv_out, epsa_out=epsa_out, mode=mode, betamax=betamax) d, epsv, epsa = layer alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("alphaf")) e = E_mat(fmat, mode=mode, copy=False) #2x2 E-only view of fmat ei = inv(e, out=_out.get("ei")) # kd = wavenumbers * d p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p")) if tmpdata is not None: _out["alphaf"] = alpha, fmat _out["ei"] = ei _out["p"] = p for j in range(nsteps): if j == 0 and reflection: #reflect only at the beginning if refl is not None: trans = refl.copy() refl = dotmf(rmat, fft_field, out=refl) fft_field = dotmf(tmat, fft_field, out=out) fft_field = np.add(fft_field, trans, out=fft_field) if mode == -1 and bulk is not None: field = ifft2(fft_field) e2h = E2H_mat(fmat, mode=mode) bulk[..., ::2, :, :] += field bulk[..., 1::2, :, :] += dotmf(e2h, field, out=field) fft_field = dotmf(dmat1, fft_field, out=fft_field) out = fft_field else: fft_field = dotmf(tmat, fft_field, out=out) fft_field = dotmf(dmat1, fft_field, out=fft_field) out = fft_field else: if dmat1 is not None: fft_field = dotmf(dmat1, fft_field, out=out) out = fft_field field = ifft2(fft_field, out=out) field = dotmdmf(e, p, ei, field, out=field) fft_field = fft2(field, out=field) if dmat2 is not None: fft_field = dotmf(dmat2, fft_field, out=fft_field) #return fft_field, refl #out = ifft2(fft_field, out = out) if mode == +1 and bulk is not None: field = ifft2(fft_field) e2h = E2H_mat(fmat, mode=mode) bulk[..., 1::2, :, :] += dotmf(e2h, field) bulk[..., ::2, :, :] += field return fft_field, refl
def propagate_2x2_full(field, wavenumbers, layer, input_layer=None, nsteps=1, mode=+1, reflection=True, betamax=BETAMAX, refl=None, bulk=None, out=None): shape = field.shape[-2:] d, epsv, epsa = layer if input_layer is not None: d_in, epsv_in, epsa_in = input_layer kd = wavenumbers * d / nsteps if out is None: out = np.empty_like(field) ii, jj = np.meshgrid(range(shape[0]), range(shape[1]), copy=False, indexing="ij") for step in range(nsteps): for i in range(len(wavenumbers)): ffield = fft2(field[..., i, :, :, :]) ofield = np.zeros_like(out[..., i, :, :, :]) b, p = betaphi(shape, wavenumbers[i]) mask = b < betamax amplitude = ffield[..., mask] betas = b[mask] phis = p[mask] iind = ii[mask] jind = jj[mask] if bulk is not None: obulk = bulk[..., i, :, :, :] if refl is not None: tampl = fft2(refl[..., i, :, :, :])[..., mask] orefl = refl[..., i, :, :, :] orefl[...] = 0. for bp in sorted(zip(range(len(betas)), betas, phis, iind, jind), key=lambda el: el[1], reverse=False): #for j,bp in enumerate(zip(betas,phis,iind,jind)): j, beta, phi, ieig, jeig = bp out_af = alphaf(beta, phi, epsv, epsa) alpha, fmat_out = out_af e = E_mat(fmat_out, mode=mode) ei0 = inv(e) ei = ei0 pm = phase_mat(alpha, kd[i, None, None], mode=mode) w = eigenwave(amplitude.shape[:-1] + shape, ieig, jeig, amplitude=amplitude[..., j]) if step == 0 and reflection != False: alphain, fmat_in = alphaf(beta, phi, epsv_in, epsa_in) if refl is not None: ei, eri = Etri_mat(fmat_in, fmat_out, mode=mode) ein = E_mat(fmat_in, mode=-1 * mode) t = eigenwave(amplitude.shape[:-1] + shape, ieig, jeig, amplitude=tampl[..., j]) r = dotmf(eri, w) r = dotmf(ein, r, out=r) np.add(orefl, r, orefl) w = dotmf(ei, w, out=w) t = dotmf(ei0, t, out=t) w = np.add(t, w, out=w) else: ei = Eti_mat(fmat_in, fmat_out, mode=mode) w = dotmf(ei, w, out=w) w = dotmf(dotmd(e, pm), w, out=w) np.add(ofield, w, ofield) else: w = dotmdmf(e, pm, ei, w, out=w) np.add(ofield, w, ofield) if bulk is not None: e2h = E2H_mat(fmat_out, mode=mode) obulk[..., 1::2, :, :] += dotmf(e2h, w) obulk[..., ::2, :, :] += w out[..., i, :, :, :] = ofield field = out return out, refl
def _transfer_ray_2x2_2(field, wavenumbers, in_layer, out_layer, dmat=None, beta=0, phi=0, nsteps=1, mode=+1, reflection=True, betamax=BETAMAX, refl=None, bulk=None, out=None, tmpdata=None): _out = {} if tmpdata is None else tmpdata if in_layer is not None: d, epsv, epsa = in_layer alpha, fmat_in = alphaf(beta, phi, epsv, epsa, out=_out.get("afin")) if tmpdata is not None: _out["afin"] = alpha, fmat_in d, epsv, epsa = out_layer alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("afout")) e = E_mat(fmat, mode=mode, copy=False) #2x2 E-only view of fmat # if refl is not None: # ein = E_mat(fmat_in, mode = mode * (-1)) #reverse direction # # if reflection == 0: # kd = wavenumbers * d # else: kd = wavenumbers * d / 2 p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p")) ei0 = inv(e, out=_out.get("ei0")) ei = ei0 if tmpdata is not None: _out["afout"] = alpha, fmat _out["ei0"] = ei _out["p"] = p for j in range(nsteps): #reflect only at the beginning if j == 0 and reflection != 0: #if we need to track reflections (multipass) if refl is not None: #ei,eri = Etri_mat(fmat_in, fmat, mode = mode, out = _out.get("eieri")) tmat, rmat = tr_mat(fmat_in, fmat, mode=mode, out=_out.get("eieri")) if tmpdata is not None: #_out["eieri"] = ei,eri _out["eieri"] = tmat, rmat trans = refl.copy() #refl = dotmf(eri, field, out = refl) refl = dotmf(rmat, field, out=refl) #field = dotmf(ei,field, out = out) field = dotmf(tmat, field, out=out) field = np.add(field, trans, out=field) if mode == -1 and bulk is not None: #tmp_field = dotmf(e,field) tmp_field = field e2h = E2H_mat(fmat, mode=mode) bulk[..., ::2, :, :] += tmp_field bulk[..., 1::2, :, :] += dotmf(e2h, tmp_field) field = dotmf(ei, field, out=field) if d != 0.: field = dotmf(dotmd(e, p), field, out=field) else: field = dotmf(e, field, out=field) out = field # rmat = dotmm(ein, eri, out = eri) # trans = refl.copy() # refl = dotmf(rmat, field, out = refl) # ei0 = inv(e) # field = dotmf(ei,field, out = out) # field = dotmf(e,field) + trans # if d != 0.: # field = dotmdmf(e,p,ei0,field, out = out) ei = ei0 else: ei = Eti_mat(fmat_in, fmat, mode=mode, out=_out.get("eti")) field = dotmdmf(e, p, ei, field, out=out) out = field if tmpdata is not None: _out["eti"] = ei ei = ei0 else: #no need to compute if d == 0!.. identity if d != 0.: field = dotmdmf(e, p, ei, field, out=out) out = field if dmat is not None: field = diffract(field, dmat, out=out) out = field #no need to compute if d == 0!.. identity if d != 0.: field = dotmdmf(e, p, ei, field, out=out) if mode == +1 and bulk is not None: e2h = E2H_mat(fmat, mode=mode) bulk[..., 1::2, :, :] += dotmf(e2h, field) bulk[..., ::2, :, :] += field return field, refl