def test_eigenwave(self): w = wave.eigenwave((4, 3), 0, 0, amplitude=4 * 3) self.allclose(w, np.ones((4, 3))) w = wave.eigenwave((4, 3), 0, 0) self.allclose(w, np.ones((4, 3))) out = np.empty_like(w) wave.eigenwave((4, 3), 0, 0, out=out) self.allclose(out, np.ones((4, 3))) self.iscomplex(out)
def test_wave2eigenwave(self): w = wave.planewave((12, 14), (1, 2), 0.5, 0) e = wave.wave2eigenwave(w) e0 = wave.eigenwave((12, 14), 0, 1) self.allclose(e[0], e0) e0 = wave.eigenwave((12, 14), 0, 2) self.allclose(e[1], e0) out = np.empty_like(e) wave.wave2eigenwave(w, out=out) self.allclose(out, e) self.iscomplex(e)
def propagate_4x4_full(field, wavenumbers, layer, nsteps=1, betamax=BETAMAX, out=None): shape = field.shape[-2:] d, epsv, epsa = layer kd = wavenumbers * d / nsteps if out is None: out = np.empty_like(field) out_af = None pm = None 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] 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 = alphaffi(beta, phi, epsv, epsa, out=out_af) alpha, f, fi = out_af pm = phasem(alpha, kd[i], out=pm) w = eigenwave(amplitude.shape[:-1] + shape, ieig, jeig, amplitude=amplitude[..., j]) w = dotmdmf(f, pm, fi, w, out=w) np.add(ofield, w, ofield) out[..., i, :, :, :] = ofield field = out return out
def test_planewave_k(self): shape = (13, 11) for k in (0.1, 1., 10): b, p = wave.betaphi(shape, k) for i in range(shape[0]): for j in range(shape[1]): w1 = wave.planewave(shape, k, b[i, j], p[i, j]) w2 = wave.eigenwave(shape, i, j) self.allclose(w1, w2)
def test_planewave_shapes(self): shapes = ((16, 16), (15, 15), (12, 13), (7, 6)) k = 1 for shape in shapes: b, p = wave.betaphi(shape, k) for i in range(shape[0]): for j in range(shape[1]): w1 = wave.planewave(shape, k, b[i, j], p[i, j]) w2 = wave.eigenwave(shape, i, j) self.allclose(w1, w2)
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 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 test_eigenwave1(self): w = wave.eigenwave((1, 12), 0, 2) w1 = wave.eigenwave1(12, 2) self.allclose(w[0, :], w1) w1 = wave.eigenwave1(12, 2, amplitude=12) self.allclose(w[0, :], w1)