Beispiel #1
0
def calcvrt0(M, Mvv, Mrv, Mvr, Mtv, Mvt, fvn, frn, ftn):
    lu = splu(Mvv)
    #Mhatrr and Mhattr
    b = lu.solve(Mvr)
    Mhatrr = -Mrv * b
    _addToDiagonal(Mhatrr, M.lx)
    Mhattr = -Mtv * b
    #Mhatrt and Mhattt
    b = lu.solve(Mvt)
    Mhatrt = -Mrv * b
    Mhattt = -Mtv * b
    _addToDiagonal(Mhattt, M.lx)

    #fhatrn
    b = lu.solve(fvn)
    a = Mrv * b
    fhatrn = frn - a

    #fhattn
    b = lu.solve(fvn)
    a = Mtv * b
    fhattn = ftn - a

    MAT = pl.bmat([[Mhatrr, Mhatrt], [Mhattr, Mhattt]])
    RHS = pl.bmat([[fhatrn], [fhattn]])

    V = pl.solve(MAT, RHS)
    r = V[:M.NM, 0]
    t = V[M.NM:, 0]
    sol = lu.solve(fvn - Mvr * r - Mvt * t)
    return sol, r, t
Beispiel #2
0
def calcScatteringMatrix(M,P,x):
	## FE analysis to acquire scattering matrices (see Dossou2006) instead of solving for one incident
	##  condition as done in FE().
	#
	#@param M		Model object containing geometrical information
	#@param P		Physics object containing physical parameters
	#@param x		The design domain with 0 corresponding to eps1 and 1 corresponding to eps2
	#						and intermediate values to weighted averages in between. See physics.interpolate
	#@return			Dictionary containing the matrices R,T,R',T' that the scattering matrix consists of.
	#						as well as normal data
	#
	#see also FE()
	A,B = P.interpolate(x)
	Mvv = assembleMvv(A,B,M,P)
	Mrv,Mvr,Mtv,Mvt,fvn,frn = assembleMxxfx(M,P)

	lu = splu(Mvv)
	#Mhatrr and Mhattr
	b = lu.solve(Mvr)
	Mhatrr = -Mrv*b
	_addToDiagonal(Mhatrr, M.lx)
	Mhattr = -Mtv*b

	#Mhatrt and Mhattt
	b = lu.solve(Mvt)
	Mhatrt = -Mrv*b
	Mhattt = -Mtv*b
	_addToDiagonal(Mhattt, M.lx)

	#fhatrn
	b = lu.solve(fvn)
	a = Mrv*b
	fhatrn = frn-a

	#fhattn
	b = lu.solve(fvn)
	a = Mtv*b
	fhattn = -a

	MAT = pl.bmat([[Mhatrr, Mhatrt],
						[Mhattr, Mhattt]])

	RHS = pl.bmat([[ Mhatrr-2*M.lx*pl.identity(M.NM), Mhatrt],
						[Mhattr, Mhattt-2*M.lx*pl.identity(M.NM)]])
	#Solve Eq (53) in Dossou 2006
	RTtilde = pl.solve(MAT,RHS)
	RIn = RTtilde[:M.NM,:M.NM]
	TIn = RTtilde[M.NM:,:M.NM]
	ROut = RTtilde[M.NM:,M.NM:]
	TOut = RTtilde[:M.NM,M.NM:]

	results = {}
	results["RIn"] = RIn
	results["TIn"] = TIn
	results["ROut"] = ROut
	results["TOut"] = TOut
	results.update(M.getParameters())
	results.update(P.getParameters())
	return results
def calcdp(rep_no, thetainput):
    rep_no = rep_no
    wav = 505
    lam = 400
    thetain = thetainput / 180 * pl.pi
    nAir = 1.0
    nBac = 1.38
    nMed = 1.34
    pol = 'Ey'
    nelx = 40
    z_uc = 2.0 * math.sqrt(3)

    ##Reference model
    FE_start_time = time.time()
    Mres = model(lx=2 * lam, lz=(1 + rep_no) * (z_uc) * lam, nelx=nelx)
    Pres = physics(Mres, wav, nAir, nBac, thetaIn=thetain, pol=pol)
    if 1:  #Put to zero to avoid re-simulation and use last saved results
        materialResAir = Pres.newMaterial(nAir)
        materialResBac = Pres.newMaterial(nBac)
        materialResMed = Pres.newMaterial(nMed)

        xres = Mres.generateEmptyDesign()
        makeSlab(xres, Mres, (rep_no) * (z_uc) * lam,
                 (1 + rep_no) * (z_uc) * lam, materialResAir)
        makeSlab(xres, Mres, 0 * (z_uc) * lam, (rep_no) * (z_uc) * lam,
                 materialResMed)

        for x in range(0, rep_no):
            makeCircle(xres, Mres, lam, x * (z_uc) * lam, lam, materialResBac)
            makeCircle(xres, Mres, 0, (x + 1 / 2) * (z_uc) * lam, lam,
                       materialResBac)
            makeCircle(xres, Mres, 2 * lam, (x + 1 / 2) * (z_uc) * lam, lam,
                       materialResBac)
        makeCircle(xres, Mres, lam, (rep_no) * (z_uc) * lam, lam,
                   materialResBac)

        if 0:  #Show design
            pl.imshow(xres.T, interpolation='none', vmin=0, vmax=4)
            pl.colorbar()
            pl.savefig("full_structure.png", bbox_inches='tight')
            pl.show()
            exit()

        res = FE(Mres, Pres, xres)
        #saveDicts("SmatrixRIInternalReference.h5",res,'a')
    #else:
    #res = loadDicts("SmatrixRIInternalReference.h5")[0]
    mR, thetaR, R, mT, thetaT, T = calcRT(Mres, Pres, res["r"], res["t"])
    Rres = R
    Tres = T
    FE_time = time.time() - FE_start_time

    CSM_start_time = time.time()

    ##Scattering matrix model air-material boundary
    M = model(lx=2.0 * lam, lz=1 * (z_uc) * lam, nelx=nelx)
    P = physics(M, wav, nAir, nBac, thetaIn=thetain, pol=pol)
    materialAir = P.newMaterial(nAir)
    materialBac = P.newMaterial(nBac)
    materialMed = P.newMaterial(nMed)
    x = M.generateEmptyDesign()
    makeSlab(x, M, 0, 1.0 * (z_uc) * lam, materialAir)
    makeCircle(x, M, lam, 0, lam, materialBac)
    if 0:  #Show design
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("upper_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)

    S1 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S1real = matL * S1 * matR

    Stot = S1
    Stotreal = S1real
    thetainNew = thetain

    ##Scattering matrix model unit cell
    M = model(lx=2.0 * lam, lz=(z_uc) * lam, nelx=nelx)
    thetainNew = pl.arcsin(P.nIn / P.nOut * pl.sin(thetainNew))
    P = physics(M, wav, nBac, nBac, thetaIn=thetainNew, pol=pol)  #
    materialAir = P.newMaterial(nAir)
    materialBac = P.newMaterial(nBac)
    materialMed = P.newMaterial(nMed)
    x = M.generateEmptyDesign()
    makeSlab(x, M, 0, 1.0 * (z_uc) * lam, materialMed)
    makeCircle(x, M, lam, 0, lam, materialBac)
    makeCircle(x, M, lam, 1.0 * (z_uc) * lam, lam, materialBac)
    makeCircle(x, M, 0, (1 / 2) * (z_uc) * lam, lam, materialBac)
    makeCircle(x, M, 2 * lam, (1 / 2) * (z_uc) * lam, lam, materialBac)
    if 0:  #Show design
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("lower_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)
    S2 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S2real = matL * S2 * matR
    for x in range(1, rep_no + 1):
        Stot = stackElements(Stot, S2)
        Stotreal = stackElements(Stotreal, S2real)
    CSM_time = time.time() - CSM_start_time

    #Stack the two scattering elements
    #Stot = stackElements(S1,S2)

    RIn, TIn, TOut, ROut = StoRT(Stot)
    results = {}
    results["RIn"] = RIn
    results["TIn"] = TIn
    results["ROut"] = ROut
    results["TOut"] = TOut
    results.update(M.getParameters())
    results.update(P.getParameters())
    #saveDicts("SmatrixRICalculations.h5",results,'a')

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.
    tmp = Stot * einc
    rnew = tmp[:M.NM].view(pl.ndarray).flatten()
    tnew = tmp[M.NM:].view(pl.ndarray).flatten()
    mR, thetaR, Rnew, mT, thetaT, Tnew = calcRT(Mres, Pres, rnew, tnew)
    title = "speed_wrt_rep_no_FE.csv"
    txtdata = open(title, "a")
    txtdata.write("{:f}, {:.8f}\n".format(rep_no, FE_time))
    title = "speed_wrt_rep_no_CSM.csv"
    txtdata = open(title, "a")
    txtdata.write("{:f}, {:.8f}\n".format(rep_no, CSM_time))
    print("rep_no={:f}, FE_time={:.8f}, CSM_time={:.8f}".format(
        rep_no, FE_time, CSM_time))
    txtdata.close()

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.
    #Stotreal = S1real
    if 0:
        pl.imshow(abs(S1real), interpolation='none', vmin=0, vmax=1)
        print abs(S1real).max()
        pl.colorbar()
        pl.show()
        pl.imshow(abs(S2real), interpolation='none', vmin=0, vmax=1)
        print abs(S2real).max()
        pl.colorbar()
        pl.show()

    tmp = Stotreal * einc
    r = tmp[:M.NM].view(pl.ndarray).flatten()
    t = tmp[M.NM:].view(pl.ndarray).flatten()

    idx = Pres.propModesIn
    R = abs(r[idx])**2

    idx = Pres.propModesOut
    T = abs(t[idx])**2

    return
def RTtoS(RIn, TIn, TOut, ROut):
    S = pl.bmat([[RIn, TOut], [TIn, ROut]])
    return S
Beispiel #5
0
def calcdp(wavinput, thetainput):
    rep_no = 50
    wav = wavinput
    lam = 400
    thetain = thetainput / 180 * pl.pi
    nAir = 1.0
    nBac = 1.38
    nMed = 1.34
    #nMaterial2 = nIn	#When nMaterial2 == nIn, the methods works
    #nOut = nMaterial2
    pol = 'Ey'
    nelx = 40
    z_uc = 2.0 * math.sqrt(3)

    ##Scattering matrix model air-material boundary
    Mres = model(lx=2 * lam, lz=(1 + rep_no) * (z_uc) * lam, nelx=nelx)
    Pres = physics(Mres, wav, nAir, nBac, thetaIn=thetain, pol=pol)
    if 1:  #Put to zero to avoid re-simulation and use last saved results
        materialResAir = Pres.newMaterial(nAir)
        materialResBac = Pres.newMaterial(nBac)
        materialResMed = Pres.newMaterial(nMed)

        xres = Mres.generateEmptyDesign()
        makeSlab(xres, Mres, (rep_no) * (z_uc) * lam,
                 (1 + rep_no) * (z_uc) * lam, materialResAir)
        makeSlab(xres, Mres, 0 * (z_uc) * lam, (rep_no) * (z_uc) * lam,
                 materialResMed)

        for x in range(0, rep_no):
            makeCircle(xres, Mres, lam, x * (z_uc) * lam, lam, materialResBac)
            makeCircle(xres, Mres, 0, (x + 1 / 2) * (z_uc) * lam, lam,
                       materialResBac)
            makeCircle(xres, Mres, 2 * lam, (x + 1 / 2) * (z_uc) * lam, lam,
                       materialResBac)
        makeCircle(xres, Mres, lam, (rep_no) * (z_uc) * lam, lam,
                   materialResBac)

        if 0:  #Show design
            pl.imshow(xres.T, interpolation='none', vmin=0, vmax=4)
            pl.colorbar()
            pl.savefig("full_structure.png", bbox_inches='tight')
            pl.show()
            exit()

    ##Scattering matrix model air-material boundary
    M = model(lx=2.0 * lam, lz=1 * (z_uc) * lam, nelx=nelx)
    #Notice how nOut here is nMaterial2
    P = physics(M, wav, nAir, nBac, thetaIn=thetain, pol=pol)
    materialAir = P.newMaterial(nAir)
    materialBac = P.newMaterial(nBac)
    materialMed = P.newMaterial(nMed)
    x = M.generateEmptyDesign()
    makeSlab(x, M, 0, 1.0 * (z_uc) * lam, materialAir)
    makeCircle(x, M, lam, 0, lam, materialBac)
    if 0:  #Show design
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("upper_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)

    S1 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S1real = matL * S1 * matR

    Stot = S1
    Stotreal = S1real
    thetainNew = thetain

    ##Scattering matrix model unit cell
    M = model(lx=2.0 * lam, lz=(z_uc) * lam, nelx=nelx)
    thetainNew = pl.arcsin(P.nIn / P.nOut * pl.sin(thetainNew))
    P = physics(M, wav, nBac, nBac, thetaIn=thetainNew, pol=pol)  #
    materialAir = P.newMaterial(nAir)
    materialBac = P.newMaterial(nBac)
    materialMed = P.newMaterial(nMed)
    x = M.generateEmptyDesign()
    makeSlab(x, M, 0, 1.0 * (z_uc) * lam, materialMed)
    makeCircle(x, M, lam, 0, lam, materialBac)
    makeCircle(x, M, lam, 1.0 * (z_uc) * lam, lam, materialBac)
    makeCircle(x, M, 0, (1 / 2) * (z_uc) * lam, lam, materialBac)
    makeCircle(x, M, 2 * lam, (1 / 2) * (z_uc) * lam, lam, materialBac)
    if 0:
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("lower_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)
    S2 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S2real = matL * S2 * matR
    for x in range(1, rep_no + 1):
        Stot = stackElements(Stot, S2)
        Stotreal = stackElements(Stotreal, S2real)

    RIn, TIn, TOut, ROut = StoRT(Stot)
    results = {}
    results["RIn"] = RIn
    results["TIn"] = TIn
    results["ROut"] = ROut
    results["TOut"] = TOut
    results.update(M.getParameters())
    results.update(P.getParameters())
    #saveDicts("SmatrixRICalculations.h5",results,'a')

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.
    tmp = Stot * einc
    rnew = tmp[:M.NM].view(pl.ndarray).flatten()
    tnew = tmp[M.NM:].view(pl.ndarray).flatten()
    mR, thetaR, Rnew, mT, thetaT, Tnew = calcRT(Mres, Pres, rnew, tnew)
    for i in range(len(mR)):
        title = "reflect_mode_n_equals_{:d}_50.csv".format(mR[i])
        txtdata = open(title, "a")
        txtdata.write("{:d}, {:f}, {:.8f}\n".format(wavinput, thetainput,
                                                    Rnew[i]))
        #print("m={:d}, theta={:f}, mode={:d}, R={:.8f}".format(wavinput,thetainput,mR[i],Rnew[i]))
        txtdata.close()
    for i in range(len(mT)):
        title = "trans_mode_n_equals_{:d}_50.csv".format(mT[i])
        txtdata = open(title, "a")
        txtdata.write("{:d}, {:f}, {:.8f}\n".format(wavinput, thetainput,
                                                    Tnew[i]))
        #print("m={:d}, theta={:f}, mode={:d}, T={:.8f}".format(wavinput,thetainput,mT[i],Tnew[i]))
        txtdata.close()

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.
    #Stotreal = S1real
    if 0:
        pl.imshow(abs(S1real), interpolation='none', vmin=0, vmax=1)
        print abs(S1real).max()
        pl.colorbar()
        pl.show()
        pl.imshow(abs(S2real), interpolation='none', vmin=0, vmax=1)
        print abs(S2real).max()
        pl.colorbar()
        pl.show()

    tmp = Stotreal * einc
    r = tmp[:M.NM].view(pl.ndarray).flatten()
    t = tmp[M.NM:].view(pl.ndarray).flatten()

    idx = Pres.propModesIn
    R = abs(r[idx])**2

    idx = Pres.propModesOut
    T = abs(t[idx])**2
    return
Beispiel #6
0
def main():
    lam = 505
    thetain = -30 / 180 * pl.pi
    nIn = 2.8
    nMaterial1 = 5.9
    nMaterial2 = 4.2
    #nMaterial2 = nIn	#When nMaterial2 == nIn, the methods works
    nOut = 4.3  #If nOut<nIn, we can have values in the S matrix exceeding 1
    nOut = 2.1
    #nOut = nMaterial2
    pol = 'Ey'
    nelx = 80

    ##Reference model (one circle + one burried circle)
    Mres = model(lx=lam, lz=2 * lam, nelx=nelx)
    Pres = physics(Mres, lam, nIn, nOut, thetaIn=thetain, pol=pol)
    if 1:  #Put to zero to avoid re-simulation and use last saved results
        materialRes1 = Pres.newMaterial(nMaterial1)
        materialRes2 = Pres.newMaterial(nMaterial2)
        materialResOut = Pres.newMaterial(nOut)

        xres = Mres.generateEmptyDesign()
        makeSlab(xres, Mres, 0, 0.5 * lam, materialResOut)
        makeSlab(xres, Mres, 0.5 * lam, 1.5 * lam, materialRes2)
        makeCircle(xres, Mres, 250, 200, materialRes1)
        makeCircle(xres, Mres, 250 + lam, 200, materialRes1)

        if 0:  #Show design
            pl.imshow(xres.T, interpolation='none', vmin=0, vmax=4)
            pl.colorbar()
            pl.savefig("full_structure.png", bbox_inches='tight')
            pl.show()
            exit()

        res = FE(Mres, Pres, xres)
        saveDicts("SmatrixRIInternalReference.h5", res, 'w')
    else:
        res = loadDicts("SmatrixRIInternalReference.h5")[0]
    mR, thetaR, R, mT, thetaT, T = calcRT(Mres, Pres, res["r"], res["t"])
    Rres = R
    Tres = T

    ##Scattering matrix model 1 (one burried circle)
    M = model(lx=lam, lz=lam, nelx=nelx)
    #Notice how nOut here is nMaterial2
    P = physics(M, lam, nIn, nMaterial2, thetaIn=thetain, pol=pol)
    material1 = P.newMaterial(nMaterial1)
    material2 = P.newMaterial(nMaterial2)
    x = M.generateEmptyDesign()
    makeSlab(x, M, 0, .5 * lam, material2)
    makeCircle(x, M, 250, 200, material1)
    if 0:  #Show design
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("upper_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)

    S1 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S1real = matL * S1 * matR

    ##Scattering matrix model 2 (one burried circle)
    M = model(lx=lam, lz=lam, nelx=nelx)
    thetainNew = pl.arcsin(P.nIn / P.nOut * pl.sin(thetain))
    P = physics(M, lam, nMaterial2, nOut, thetaIn=thetainNew, pol=pol)
    material1 = P.newMaterial(nMaterial1)
    material2 = P.newMaterial(nMaterial2)
    materialOut = P.newMaterial(nOut)
    x = M.generateEmptyDesign()
    makeSlab(x, M, .5 * lam, lam, material2)
    makeSlab(x, M, 0, .5 * lam, materialOut)
    makeCircle(x, M, 250, 200, material1)
    if 0:  #Show design
        pl.imshow(x.T, interpolation='none', vmin=0, vmax=4)
        pl.colorbar()
        pl.savefig("lower_half.png", bbox_inches='tight')
        pl.show()
        exit()
    res = calcScatteringMatrix(M, P, x)
    S2 = RTtoS(res["RIn"], res["TIn"], res["TOut"], res["ROut"])
    matL = pl.bmat([[pl.diag(pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(pl.sqrt(P.chiOut))]])
    matR = pl.bmat([[pl.diag(1 / pl.sqrt(P.chiIn)),
                     pl.zeros((M.NM, M.NM))],
                    [pl.zeros((M.NM, M.NM)),
                     pl.diag(1 / pl.sqrt(P.chiOut))]])
    S2real = matL * S2 * matR

    if 0:
        #Define incident wave as a plane wave
        einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
        einc[M.NM // 2, 0] = 1.

        tmp = S2 * einc
        rnew = tmp[:M.NM].view(pl.ndarray).flatten()
        tnew = tmp[M.NM:].view(pl.ndarray).flatten()
        mR, thetaR, Rnew, mT, thetaT, Tnew = calcRT(M, P, rnew, tnew)

        tmp = S2real * einc
        r = tmp[:M.NM].view(pl.ndarray).flatten()
        t = tmp[M.NM:].view(pl.ndarray).flatten()
        idx = P.propModesIn
        R = abs(r[idx])**2
        idx = P.propModesOut
        T = abs(t[idx])**2
        print "-" * 50
        print R
        print Rnew
        print T
        print Tnew
        print abs(R - Rnew).max()
        print abs(T - Tnew).max()
        exit()

    #Stack the two scattering elements
    Stot = stackElements(S1, S2)

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.
    tmp = Stot * einc
    rnew = tmp[:M.NM].view(pl.ndarray).flatten()
    tnew = tmp[M.NM:].view(pl.ndarray).flatten()
    mR, thetaR, Rnew, mT, thetaT, Tnew = calcRT(Mres, Pres, rnew, tnew)
    print("-" * 32)
    print(Rres)
    print(Rnew)
    print("-" * 10)
    print(Tres)
    print(Tnew)
    print("-" * 32)
    print("Error in reflection  : {:.2e}".format(abs(Rnew - Rres).max()))
    print("Error in transmission: {:.2e}".format(abs(Tnew - Tres).max()))
    #print("(note: since the significant numbers are in general between 0.01 and 1")
    #print(" we required a much lower error (1e-6 or better) to confirm that it works)")

    #Define incident wave as a plane wave
    einc = pl.zeros((2 * M.NM, 1), dtype='complex').view(pl.matrix)
    einc[M.NM // 2, 0] = 1.

    Stotreal = stackElements(S1real, S2real)
    #Stotreal = S1real
    if 1:
        pl.imshow(abs(S1real), interpolation='none', vmin=0, vmax=1)
        print abs(S1real).max()
        pl.colorbar()
        pl.show()
        pl.imshow(abs(S2real), interpolation='none', vmin=0, vmax=1)
        print abs(S2real).max()
        pl.colorbar()
        pl.show()

    tmp = Stotreal * einc
    r = tmp[:M.NM].view(pl.ndarray).flatten()
    t = tmp[M.NM:].view(pl.ndarray).flatten()

    idx = Pres.propModesIn
    R = abs(r[idx])**2

    idx = Pres.propModesOut
    T = abs(t[idx])**2

    print "-" * 50
    print Rres
    print Rnew
    print R
    print("Error in reflection  : {:.2e}".format(abs(R - Rres).max()))
    print("Error in transmission: {:.2e}".format(abs(T - Tres).max()))
Beispiel #7
0
def pade(N, lam0, dlam, M, P, x):
    N = 2  #The current implementation is only valid for N=2
    #diferenctaite all the elemnts of K by k
    #Fvec has relation to k_0 through alpha - facter hthat
    #if possible separte Fvec out into elements of facters of alpha
    #equal to eq 3 in papser, make into coo_matrix for input
    A, B = P.interpolate(x)

    Mvv_0 = assembleMvv(A, B, M, P)
    Mrv_0, Mvr_0, Mtv_0, Mvt_0, fvn_0, frn_0, FFUp_0, FFDown_0 = assembleMxxfx(
        M, P)

    Mvv_1 = assembledev1Mvv(A, B, M, P)
    Mrv_1, Mvr_1, Mtv_1, Mvt_1, fvn_1, frn_1, FFUp_1, FFDown_1 = assembledev1Mxxfx(
        M, P, FFUp_0, FFDown_0)

    Mvv_2 = assembledev2Mvv(A, B, M, P)
    #check fvn. frn
    Mrv_2, Mvr_2, Mtv_2, Mvt_2, fvn_2, frn_2 = assembledev2Mxxfx(
        M, P, FFUp_0, FFDown_0, FFUp_1, FFDown_1)

    # These matrices are just used for checks later on:
    I = pl.identity(M.NM)  #Identity matrix
    Z = pl.zeros((M.NM, M.NM))
    P_0 = pl.bmat([[Mvv_0, Mvr_0, Mvt_0], [Mrv_0, M.lx * I, Z],
                   [Mtv_0, Z, M.lx * I]])
    P_1 = pl.bmat([[Mvv_1, Mvr_1, Mvt_1], [Mrv_1, Z, Z], [Mtv_1, Z, Z]])
    P_2 = pl.bmat([[Mvv_2, Mvr_2, Mvt_2], [Mrv_2, Z, Z], [Mtv_2, Z, Z]])
    #Note that u contains the same content as sol,r and t
    u = []
    sol = []
    r = []
    t = []

    #Note that the LU factorisation on calcvrt0 can be reused for calculating all the u's!
    #(which would speed up things, but not change the result obviously...)
    frn_0[M.Nm, 0] = -M.lx  #mode 0 incidence
    ftn_0 = pl.zeros(frn_0.shape, dtype=complex)
    sol_0, r_0, t_0 = calcvrt0(M, Mvv_0, Mrv_0, Mvr_0, Mtv_0, Mvt_0, fvn_0,
                               frn_0, ftn_0)
    sol.append(sol_0)
    r.append(r_0)
    t.append(t_0)
    u.append(pl.concatenate((sol_0, r_0, t_0)))
    if 1:
        #Check that the solution is correct
        f = pl.concatenate((fvn_0, frn_0, ftn_0))
        print("Solution error for 0'th order: ", abs(P_0 * u[0] - f).max())
    _Mvv = Mvv_0
    _Mrv = Mrv_0
    _Mvr = Mvr_0
    _Mtv = Mtv_0
    _Mvt = Mvt_0
    _fvn = -(Mvv_1 * sol[0] + Mvr_1 * r[0] + Mvt_1 * t[0])
    _frn = -(Mrv_1 * sol[0])
    _ftn = -(Mtv_1 * sol[0])

    sol_1, r_1, t_1 = calcvrt0(M, _Mvv, _Mrv, _Mvr, _Mtv, _Mvt, _fvn, _frn,
                               _ftn)
    sol.append(sol_1)
    r.append(r_1)
    t.append(t_1)
    u.append(pl.concatenate((sol_1, r_1, t_1)))
    if 1:
        print("Solution error for 1'th order: ",
              abs(P_0 * u[1] + P_1 * u[0]).max())

    #This will not work for our implementation since higher order derivates of the matrix is non-zero
    #And eqn(19) in Jensen 2007 therefore has to be recalculated for our specific case. This is caused by
    #derivations of the small dense transmission/reflection matrices (Mrv,Mvt and so on) being non-zero
    if 0:
        for i in range(2, N + 1):
            sol_i, r_i, t_i = calcvrt0(
                M, Mvv_0, Mrv_0, Mvr_0, Mtv_0, Mvt_0,
                -(Mvv_1 * sol[i - 1] + Mvr_1 * r[i - 1] + Mvt_1 * t[i - 1]) -
                (Mvv_2 * sol[i - 2] + Mvr_2 * r[i - 2] + Mvt_2 * t[i - 2]),
                -(Mrv_1 * sol[i - 1]) - (Mrv_2 * sol[i - 2]),
                -(Mtv_1 * sol[i - 1]) - (Mtv_2 * sol[i - 2]))
            sol.append(sol_i)
            r.append(r_i)
            t.append(t_i)
            u.append(pl.concatenate((sol_i, r_i, t_i)))

        sol_N1, r_N1, t_N1 = calcvrt0(
            M, Mvv_0, Mrv_0, Mvr_0, Mtv_0, Mvt_0,
            -(Mvv_1 * sol[N] + Mvr_1 * r[N] + Mvt_1 * t[N]) -
            (Mvv_2 * sol[N - 1] + Mvr_2 * r[N - 1] + Mvt_2 * t[N - 1]),
            -(Mrv_1 * sol[N]) - (Mrv_2 * sol[N - 1]),
            -(Mtv_1 * sol[N]) - (Mtv_2 * sol[N - 1]))

    _fvn = -(Mvv_1 * sol[1] + Mvr_1 * r[1] + Mvt_1 * t[1])
    _fvn += -(Mvv_2 * sol[0] + Mvr_2 * r[0] + Mvt_2 * t[0])
    _frn = -(Mrv_1 * sol[1])
    _frn += -(Mrv_2 * sol[0])
    _ftn = -(Mtv_1 * sol[1])
    _ftn += -(Mtv_2 * sol[0])
    sol_2, r_2, t_2 = calcvrt0(M, _Mvv, _Mrv, _Mvr, _Mtv, _Mvt, _fvn, _frn,
                               _ftn)
    sol.append(sol_2)
    r.append(r_2)
    t.append(t_2)
    u.append(pl.concatenate((sol_2, r_2, t_2)))
    if 1:
        print("Solution error for 2'th order: ",
              abs(P_0 * u[2] + P_1 * u[1] + P_2 * u[0]).max())

    uconjT = pl.bmat([vec.conj() for vec in u[::-2]]).T
    urev = pl.bmat(u[::-2])
    Pmat = uconjT * urev
    Q = pl.linalg.inv(Pmat)
    #Check the inversion... Even though it succeeds
    if 0:
        print("Pmax:", abs(Pmat).max())
        print("P*Q:")
        print(Pmat * Q)
    uplus = Q * uconjT
    b = -uplus * u[N]
    #Check if b solves the equation we wanted
    if 1:
        print("Error for b:", abs(urev * b + u[N]).max())

    a = []
    a += [0]  #If we start summing at 1, then the 0'th element should be zero
    #b starts at index 1 and not zero in Jensen 2007, there the elements have to be shifted one
    a += [u[1] + b[0, 0] * u[0]]
    if N != 2:
        exit("this part only implemented for N=2")
    a += [u[2] + b[0, 0] * u[1] + b[1, 0] * u[0]]

    #List of wavelengths
    llam = pl.linspace(lam0 - dlam, lam0 + dlam, 81)
    #List of sigmas with k0 subtracted
    lsigma = 2 * pl.pi / llam - 2 * pl.pi / lam0
    lR = []
    for sigma in lsigma:
        u_nom = u[0] + a[1] * sigma + a[2] * sigma**2
        u_denom = 1 + b[0, 0] * sigma + b[1, 0] * sigma**2
        usigma = u_nom / u_denom

        nnodes = (M.nelx + 1) * (M.nelz + 1)
        solsigma = usigma[:nnodes]
        rsigma = usigma[nnodes:nnodes + M.NM]
        tsigma = usigma[nnodes + M.NM:]
        mR, thetaR, R, mT, thetaT, T = calcRT(M, P, rsigma, tsigma)
        lR += [float(R[mR == 0])]

    return llam, lR
Beispiel #8
0
def FE(M,P,x,printResults=True):
	## FE analysis to solve Maxwell's equations in 2D for either H or E polarisation (=Helmholtz's equation)
	##		using periodic boundary conditions and wave expansions at the boundaries. The approach was originally
	##		implemented using Fuchi2010 and later modifications from Dossou2006 (original article) were added
	#
	#@param M		Model object containing geometrical information
	#@param P		Physics object containing physical parameters
	#@param x		The design domain with 0 corresponding to eps1 and 1 corresponding to eps2
	#						and intermediate values to weighted averages in between. See physics.interpolate
	#@param printResults	print results to stdout after simulation
	#@return			sol is the discretised solution, r are the complex reflection coefficients
	#						and t are the complex transmission coefficients

	#Calculate A and B, as the would be given in the Helmholtz equation in Eq (1) in Friis2012.
	#	(this notation makes it easy to switch between E and H field due to duality)

	A,B = P.interpolate(x)
	Mvv = assembleMvv(A,B,M,P)
	Mrv,Mvr,Mtv,Mvt,fvn,frn = assembleMxxfx(M,P)

	frn[M.Nm,0] = -M.lx			#mode 0

	lu = splu(Mvv)
	#Mhatrr and Mhattr
	b = lu.solve(Mvr)
	Mhatrr = -Mrv*b
	_addToDiagonal(Mhatrr, M.lx)
	Mhattr = -Mtv*b

	#Mhatrt and Mhattt
	b = lu.solve(Mvt)
	Mhatrt = -Mrv*b
	Mhattt = -Mtv*b
	_addToDiagonal(Mhattt, M.lx)

	#fhatrn
	b = lu.solve(fvn)
	a = Mrv*b
	fhatrn = frn-a

	#fhattn
	b = lu.solve(fvn)
	a = Mtv*b
	fhattn = -a

	MAT = pl.bmat([[Mhatrr, Mhatrt],
						[Mhattr, Mhattt]])
	RHS = pl.bmat([ [fhatrn],[fhattn]])

	V  = pl.solve(MAT,RHS)
	r = V[:M.NM,0]
	t = V[M.NM:,0]

	#Solve the system using LU factorisation (as recommended in Dossou2006, p 130, bottom)
	sol = lu.solve(fvn-Mvr*r-Mvt*t)
	print(pl.shape(r))
	print(pl.shape(t))
	print(pl.shape(sol))

	r = r.view(pl.ndarray).ravel()
	t = t.view(pl.ndarray).ravel()
	#Cast solution into a form that matches the input model
	sol = sol.reshape(M.nelx+1,M.nelz+1,order='F')
	#Print simulation results
	if printResults:
		_printResultsToScreen(M,P,r,t)
	print("r")
	print(r)
	print(t)
	print(sol)

	results = {}
	results["solution"] = sol
	results["x"] = x
	results["r"] = r
	results["t"] = t
	results.update(M.getParameters())
	results.update(P.getParameters())
	return results