예제 #1
0
 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)
예제 #2
0
 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)
예제 #3
0
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
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
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
예제 #7
0
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
예제 #8
0
 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)