Beispiel #1
0
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
Beispiel #2
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
Beispiel #3
0
def phase_matrix(alpha, kd, mode=None, mask=None, out=None):
    kd = np.asarray(kd, dtype=FDTYPE)
    out = phase_mat(alpha, kd[..., None, None], out=out)
    if mode == "t" or mode == +1:
        out[..., 1::2] = 0.
    elif mode == "r" or mode == -1:
        out[..., ::2] = 0.
    if mask is not None:
        out[mask] = 0.
    return out
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
#build field matrices
a, f, fi = tmm.alphaffi(betas, phi, eps_layer, eps_angles)
aout, fout, g = tmm.alphaffi(
    betas, phi, eps_out,
    eps_angles)  #eps_angles does nothing because eps_out is isotropic
ain, fin, g = tmm.alphaffi(
    betas, phi, eps_in,
    eps_angles)  #eps_angles does nothing because eps_in is isotropic

dot = dtmm.linalg.dotmm
dotd = dtmm.linalg.dotmd
dotmdm = dtmm.linalg.dotmdm
dotmv = dtmm.linalg.dotmv
intensity = tmm.intensity
intensity = tmm.poynting
p = tmm.phase_mat(a, -kd)
#p = np.exp(-1j*a*kd)

#characteristic matrix
cmat = dotmdm(f, p, fi)

#field projection matrices - used to take the forward propagating or backward propagating waves
pmat = tmm.projection_mat(fout, mode=+1)
mmat = tmm.projection_mat(fin, mode=-1)
pmatin = tmm.projection_mat(fin, mode=+1)
#: build EM field 4-vector (Ex, Hy, Ey, Hx) of a given polarization
fvec = tmm.fvec(fin, jones=pol1)
fvec = dotmv(pmatin, fvec)

#: transmit the field and update fvec with reflected waves
tfvec = tmm.transmit(fvec, cmat, fmatin=fin, fmatout=fout)
Beispiel #10
0

#stack = d,eps_values, eps_angles

#cmat = tmm.stack_mat(stack,kd, beta = beta, phi = phi)

#build field matrices
a,f,fi = tmm.alphaffi(beta,phi,eps_values, eps_angles)

fout = f[-1]
fin = f[0]

#now build layer matrices

#: in 4x4 we are propagating backward--- minus sign must be taken in the phase
p = tmm.phase_mat(a,-kd)

# uncoment this to test that setting backward propagating waves to zero, 
# you have single reflections only... -same result as 2x2 with reflection.
#p[...,1::2] = 0.

#4x4 characteristic matrix
m = dotmdm(f,p,fi)
#we could have built layer matrices directly, note the there is no negative value in front of kd:
#m = tmm.layer_mat(kd,eps_values, eps_angles, beta = beta, phi = phi)

#e field 2x22 matrix.. skip the first layer (air)
e = tmm.E_mat(f[1:], mode = +1)
# the inverse, no reflections
ei = linalg.inv(e)
# the inverse, with reflections