def stackElements(S1, S2):
    # Reursive relations, eq (59-62) in "A combined three-dimensional finite element and scattering matrix
    #  method for the analysis of plane wave diffraction by bi-periodic, multilayered structures"
    #  (Dossou 2012a)
    RIn1, TIn1, TOut1, ROut1 = StoRT(S1)
    RIn2, TIn2, TOut2, ROut2 = StoRT(S2)
    I = pl.identity(RIn1.shape[0])
    RIn = RIn1 + TOut1 * RIn2 * pl.inv(I - ROut1 * RIn2) * TIn1
    TIn = TIn2 * pl.inv(I - ROut1 * RIn2) * TIn1
    ROut = ROut2 + TIn2 * ROut1 * pl.inv(I - RIn2 * ROut1) * TOut2
    TOut = TOut1 * pl.inv(I - RIn2 * ROut1) * TOut2
    return RTtoS(RIn, TIn, TOut, ROut)
def compute_registeration(P0, Yk):
	'''
    compute the registeration. which is transformation martix
    ref: http://www.cs.virginia.edu/~mjh7v/bib/Besl92.pdf
    Input:
        P0: Point set 
        Yk:  P0 corresponding Point set
    Output:
        qk: transform matrix
    '''

    # compute mu p and mu x

	mup = np.mean(P0, axis=0)

	Nx = len(P0)
	mux = np.mean(Yk, axis=0)
	
	# Cross-covariance martix sigma_px

	sigma_px =  (np.dot(P0.T,Yk) - np.dot(mup.T,mux))/Nx

	Aij = sigma_px - sigma_px.T
	tr = trace(sigma_px)

	Sym = sigma_px + sigma_px.T - tr*identity(3)

	Q_sigma_px = np.array([
        [tr,        Aij[1][2],     Aij[2][0],    Aij[0][1]], 
        [Aij[1][2], Sym[0][0],             0,            0],
        [Aij[2][0],         0,     Sym[1][1],            0],
        [Aij[0][1],         0,             0,    Sym[2][2]]])

    # eigenvalue to get optimal R and T

	w, v = np.linalg.eig(Q_sigma_px)

	qR = v[:, argmin(w)]

	R = get_rotation_matrix(qR)
	qT = (mux.T - R.dot(mup.T)).T

	return qR, qT
# inputs
un = array([0]) # control vector
zn = [] # measurement vector

# outputs
xn = array([3]) # newest estimate of true state
pn = array([1]) # newest estimate of average error

# constants
A = array ([1]) # state transition matrix, used to convert last time's state to newest state
B = array([0]) # control matrix
H = array([1]) # observation matrix, used to convert measurement to state
Q = array([0.00001]) # estimated process error covariance
R = array([0.1]) # estimated measurement error covariance
I = identity(1)

# A is 1 as the state is constant
# H is 1 as the measurement is already in voltage 

measure_count = 500
measurements = []
estimations = []
for i in range(measure_count):
    zn = 0.75 + random.random ()

    xn = A*xn + B*un
    pn = A * pn * A.transpose () + Q
    y = zn - H * xn
    S = H * pn * H.transpose () + R
    K = pn * H.transpose () * (1/S)
    # Apply the acceleration to velocity.
    self.velocity = map(self.add, self.velocity, sliced_acceleration)
    sliced_velocity = map(self.mult, self.velocity, timeslicevec )
    # Apply the velocity to location.
    self.loc = map(self.add, self.loc, sliced_velocity)
    # Cannonballs shouldn't go into the ground.
    if self.loc[1] < 0:
      self.loc[1] = 0


# constants
g = -9.81
dt = 0.1
A = matrix ([[1, dt, 0, 0], [0,1,0,0], [0,0,1,dt], [0,0,0,1]]) # state transition matrix, used to convert last time's state to newest state
B = matrix([[0,0,0,0], [0,0,0,0], [0,0,1,0], [0,0,0,1]]) # control matrix
H = identity (4) # observation matrix, used to convert measurement to state
Q = zeros ((4,4)) # estimated process error covariance
R = identity(4) * 0.2 # estimated measurement error covariance
I = identity (4)

# inputs
un = matrix([[0], [0], [0.5 * g * dt * dt], [g * dt]]) # control vector
zn = [] # measurement vector

# outputs
xn = matrix([[0], [100 * math.cos (math.pi/4)], [500], [100 * math.sin (math.pi / 4)]]) # newest estimate of true state
pn = identity (4) # newest estimate of average error

cannon_ball = CannonBall (dt, 30)
measure_count = 144
measurements = []
def main():
    # do we want an image of the loops in 3D for different A?
    loops = False
    # do we want to make a movie of the stability multipliers in the complex plane?
    mk_stab_mov = True

    if loops:
        fig3d = pl.figure
        d3ax = fig.add_subplot(111,projection='3d')

    #os.mkdir('LoopImgs')

    # make a directory for the stability multiplier images --> this will be a movie as a function of
    # A
    if mk_stab_mov: os.mkdir('StabMovie')

    # this variable just exsits so we dont print the A value of the bifurcation point more than
    # once.
    found_bif = False

    # make file to store q (periodicity)
    q_file = open("qdata.txt","w")

    # make file to store stability multipliers
    eig_file  = open("data.txt","w")
    eig_file.write("eig1   eig2   A\n")

    dt = .001 
    # total number of iterations to perform
    # totIter = 10000000
    totIter = 50000
    totTime = totIter*dt
    time = pl.arange(0.0,totTime,dt)
    
    beta = .6
    qq = 1.0

    # how many cells is till periodicity use x = n*pi/k (n must be even #) modNum = 2*pl.pi/k
    modNum = 2.0*pl.pi
    
    # initial conditions for p1 and p2
    p1_init_x = pl.pi
    p1_init_vx = 0.0

    p2_init_x = 0.0
    p2_init_vx = 0.0

    A_start = 0.2
    A = A_start
    A_max = .8
    A_step = .01

    
    count = 0

    # make arrays to keep eigen values. There willl be four eigen values for N=2 so lets hve two seperate
    # arrays for them
    eigs1 = pl.array([])
    eigs2 = pl.array([])
    eigs3 = pl.array([])
    eigs4 = pl.array([])


    # file to write final poition of particle to
    final = open("final_position.txt","w")
    final.write("Last position of orbit,   A\n")
    x0 = pl.array([p1_init_vx,p2_init_vx,p1_init_x,p2_init_x])
    
    previous_q = 0.0
    while A < A_max:
        # initial conditions vector
        # set up: [xdot,ydot,x,y]
        apx = Two_Particle_Sin1D(A,beta,qq,dt)
        sol = odeint(apx.f,x0,time)
        print("x0")
        print(x0)
        
        #sol[:,2]=sol[:,2]%(2*pl.pi)

        # find a single loop of the limit cycle. Might be periodoc over more than one cycle
        # returns the solution of just that loop AND the periodicity of the loop
        # takes a threshhold number. If it cant find a solution where the begining and end of the
        # trajectroy lye within this threshold value than it quits and prints an error
        #thresh is distance in the phase place
        #thresh = .01
        thresh = .00005
        
        # change this back for bifrucation other than FIRST PI BIF
        #loop = find_one_full_closed(sol,thresh,dt)
        loop = pl.zeros([int(2.0*pl.pi/dt),4])
        loop[:,2]+=pl.pi
        # the other particle needs to be at zero. Already is

        if "stop" in loop:
            break

        loop_t = pl.arange(0.0,(len(loop))*dt,dt)
        
        if loops :
            d3ax.plot(pl.zeros(len(loop))+A,loop[:,2],loop[:,0],color="Black")

        #fig = pl.figure()
        #ax = fig.add_subplot(111)
        ##ax.scatter([0.0,pl.pi,2.0*pl.pi],[0.0,0.0,0.0],color="Red")
        ##ax.plot(loop[:,2],loop[:,0],":",color="Black")
        #ax.plot(loop[:,2],loop[:,0],color="Black")
        #ax.set_xlabel("$x_1$",fontsize=25)
        #ax.set_ylabel("$x_2$",fontsize=25)
        ##ax.set_xlim([pl.pi-pl.pi/3.0,pl.pi+pl.pi/3.0])
        ##ax.set_ylim([-.3,.3])
        #fig.tight_layout()
        #fig.savefig("LoopImgs/"+str(A)+".png",dpi = 300,transparent=True)
        ##os.system("open LoopImgs/" +str(A)+".png")
        #pl.close(fig)
       
        apx.set_sol(loop)

    
        # solution matrix at t=0 is identity matrix -> we need it in 1d arrar form for odeint though
        # -> reshape takes care of the the form
        w0 = pl.identity(4).reshape(-1)
        w_of_t = odeint(apx.mw,w0,loop_t,hmax=dt,hmin=dt)
        #w_of_t = odeint(apx.mw,w0,loop_t)

        current_q = loop_t[-1]/(2.0*pl.pi)
        # print the period of the orbit we are working on
        print("q: " + str(current_q))
        q_file.write(str(loop_t[-1]/(2.0*pl.pi))+" "+str(A)+"\n")

        if current_q > (previous_q+1.0):
            print("bifurcation point. A = " +str(A))

        previous_q=current_q
    
        # make the matrix form of w_of_t
        matrix = w_of_t[-1,:].reshape(4,4)

        print('solution matrix is:')
        for i in range(len(matrix)):
            print(str(matrix[i,:]))

        # print('solution matrix times the initial conditions vector:')
        # This is wrong because the x0 needs to be re-ordered to b e consistant with the way the
        # Jacobian is set up.
        # print(pl.dot(matrix,x0))
        
        
        # use linalg to get the eigen values of the W(t=q) where q is the period time of the orbit
        vals,vect = numpy.linalg.eig(matrix) 
        print('the trace is' + str(matrix.trace()))
        print('determinant is: '+ str(pl.det(matrix)))
        
        if((abs(vals[0])<=1.0) and (not found_bif)):
            print("this is the bifurcation point (l1)")
            print(A)
            found_bif = True
        if(abs(vals[1])<=1.0 and (not found_bif)):
            print("this is the bifurcation point (l2)")
            print(A)
            found_bif = True
        
        print('number of eigen values is: ' + str(len(vals)))
        eigs1 = pl.append(eigs1,vals[0])
        eigs2 = pl.append(eigs2,vals[1])
        eigs3 = pl.append(eigs3,vals[2])
        eigs4 = pl.append(eigs4,vals[3])


        eig_file.write(str(vals[0])+" "+str(vals[1])+" "+str(vals[2])+" "+str(vals[3])+" "+str(A)+"\n")

        count+=1
        x0 = loop[-1,:]
        final.write(str(x0)[1:-1]+" "+str(A) +"\n")
        A += A_step
        print("A: "+str(A))

    theta = pl.arange(0,10,.05)
    A_arr = pl.arange(A_start,A,A_step)

    print('we are above')
    while len(A_arr)>len([k.real for k in eigs1]):
        A_arr = A_arr[:-1]
    while len(A_arr)<len([k.real for k in eigs1]):
        A_arr = pl.append(A_arr,A_arr[-1]+A_step)
    print('we are below')

    fig1 = pl.figure()
    ax1 = fig1.add_subplot(111)
    ax1.plot(pl.cos(theta),pl.sin(theta))
    ax1.plot([k.real for k in eigs1],[l.imag for l in eigs1])
    ax1.set_xlabel("Re[$\lambda_1$]",fontsize=25)
    ax1.set_ylabel("Im[$\lambda_1$]",fontsize=25)
    fig1.tight_layout()
    fig1.savefig("eig1.png")
    os.system("open eig1.png")

    fig2 = pl.figure()
    ax2 = fig2.add_subplot(111)
    ax2.plot(pl.cos(theta),pl.sin(theta))
    ax2.plot([k.real for k in eigs2],[l.imag for l in eigs2])
    ax2.set_xlabel("Re[$\lambda_2$]",fontsize=25)
    ax2.set_ylabel("Im[$\lambda_2$]",fontsize=25)
    fig2.tight_layout()
    fig2.savefig("eig2.png")
    os.system("open eig2.png")

    fig3, ax3 = pl.subplots(2,sharex=True)
    ax3[0].plot(A_arr,[k.real for k in eigs1],color='k')
    ax3[1].plot(A_arr,[k.imag for k in eigs1],color='k')
    ax3[0].set_ylabel("Re[$\lambda_1$]",fontsize = 25)
    ax3[1].set_ylabel("Im[$\lambda_1$]",fontsize = 25)
    ax3[1].set_xlabel("$A$",fontsize = 25)
    fig3.tight_layout()
    fig3.savefig("A_vs_eig1.png")
    os.system("open A_vs_eig1.png")

    fig4, ax4 = pl.subplots(2,sharex=True)
    ax4[0].plot(A_arr,[k.real for k in eigs2], color = 'k')
    ax4[1].plot(A_arr,[k.imag for k in eigs2], color = 'k')
    ax4[0].set_ylabel("Re[$\lambda_2$]",fontsize = 25)
    ax4[1].set_ylabel("Im[$\lambda_2$]",fontsize = 25)
    ax4[1].set_xlabel("$A$",fontsize = 25)
    fig4.tight_layout()
    fig4.savefig("A_vs_eig2.png")
    os.system("open A_vs_eig2.png")

    eig_file.close()

    final.close()    
        
    ## make text file with all extra information
    #outFile = open("info.dat","w")
    #outFile.write("Info \n coefficient: " + str(coef) \
    #        + "\nwave number: " +str(k)\
    #        + "\nomega: " + str(w)\
    #        + "\ndamping: " + str(damp)\
    #        + "\ng: " + str(g)\
    #        + "\ntime step: " + str(dt)\
    #        + "\ntotal time: " + str(dt*totIter)\
    #        + "\ntotal iterations: " + str(totIter)\
    #        + "\nInitial Conditions: \n" +
    #        "initial x: " +str(initx) \
    #        +"\ninitial y: " +str(inity) \
    #        +"\ninitial vx: " +str(initvx)\
    #        +"\ninitial vy: " +str(initvy) )
    #outFile.close()
    
    # line for stable static point

    if loops:
        line = pl.arange(start_A-.01,start_A,A_step)
        pi_line = pl.zeros(len(line))+pl.pi
        z_line = pl.zeros(len(line))
        d3ax.plot(line,pi_line,z_line,color="Black")
        d3ax.set_xlabel("$A$",fontsize=25)
        d3ax.set_ylabel("$x_1$",fontsize=25)
        d3ax.set_zlabel("$x_2$",fontsize=25)
        d3fig.tight_layout()
        d3fig.savefig("loops.png",dpi=300)

    if mk_stab_mov:
        for i in range(len(eigs1)):
            s_fig = pl.figure()
            s_ax = s_fig.add_subplot(111)
            s_ax.plot(pl.cos(theta),pl.sin(theta))
            s_ax.scatter(eigs1[i].real,eigs1[i].imag,c='r',s=20)
            s_ax.scatter(eigs2[i].real,eigs2[i].imag,c='b',s=20)
            s_ax.scatter(eigs3[i].real,eigs3[i].imag,c='b',s=20)
            s_ax.scatter(eigs4[i].real,eigs4[i].imag,c='b',s=20)
            s_ax.set_xlabel("Re[$\lambda$]",fontsize=25)
            s_ax.set_ylabel("Im[$\lambda$]",fontsize=25)
            s_fig.tight_layout()
            s_fig.savefig("StabMovie/%(num)0.5d_stbl.png"%{"num":i})
            pl.close(s_fig)
Exemple #6
0
        # Apply the velocity to location.
        self.loc = map(self.add, self.loc, sliced_velocity)
        # Cannonballs shouldn't go into the ground.
        if self.loc[1] < 0:
            self.loc[1] = 0


# constants
g = -9.81
dt = 0.1
A = matrix(
    [[1, dt, 0, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0, 1]]
)  # state transition matrix, used to convert last time's state to newest state
B = matrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0,
                                                       1]])  # control matrix
H = identity(4)  # observation matrix, used to convert measurement to state
Q = zeros((4, 4))  # estimated process error covariance
R = identity(4) * 0.2  # estimated measurement error covariance
I = identity(4)

# inputs
un = matrix([[0], [0], [0.5 * g * dt * dt], [g * dt]])  # control vector
zn = []  # measurement vector

# outputs
xn = matrix([[0], [100 * math.cos(math.pi / 4)], [500],
             [100 * math.sin(math.pi / 4)]])  # newest estimate of true state
pn = identity(4)  # newest estimate of average error

cannon_ball = CannonBall(dt, 30)
measure_count = 144
Exemple #7
0
un = array([0])  # control vector
zn = []  # measurement vector

# outputs
xn = array([3])  # newest estimate of true state
pn = array([1])  # newest estimate of average error

# constants
A = array(
    [1]
)  # state transition matrix, used to convert last time's state to newest state
B = array([0])  # control matrix
H = array([1])  # observation matrix, used to convert measurement to state
Q = array([0.00001])  # estimated process error covariance
R = array([0.1])  # estimated measurement error covariance
I = identity(1)

# A is 1 as the state is constant
# H is 1 as the measurement is already in voltage

measure_count = 500
measurements = []
estimations = []
for i in range(measure_count):
    zn = 0.75 + random.random()

    xn = A * xn + B * un
    pn = A * pn * A.transpose() + Q
    y = zn - H * xn
    S = H * pn * H.transpose() + R
    K = pn * H.transpose() * (1 / S)
Exemple #8
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
Exemple #9
0
def calcScatteringMatrix2(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)
    #print("pl.diag(pl.asarray(pl.transpose(RTtilde)).reshape(-1))")
    #print(pl.diag(pl.asarray(pl.transpose(RTtilde)).reshape(-1)))
    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))]])
    V = matL * RTtilde * matR

    RIn = V[:M.NM, :M.NM]
    TIn = V[M.NM:, :M.NM]
    ROut = V[M.NM:, M.NM:]
    TOut = V[:M.NM, M.NM:]

    results = {}
    results["x"] = x
    results["RIn"] = RIn
    results["TIn"] = TIn
    results["ROut"] = ROut
    results["TOut"] = TOut
    results.update(M.getParameters())
    results.update(P.getParameters())
    return results