Beispiel #1
0
def run_cross_section(interactionfile, spinfile):
    start = clock()

    # Generate Inputs
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)
    
    atom_list=atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)

    kx = sp.Symbol('kx', real = True)
    ky = sp.Symbol('ky', real = True)
    kz = sp.Symbol('kz', real = True)
    k = spm.Matrix([kx,ky,kz])
    
    (b,bd) = generate_b_bd_operators(atom_list)
    (a,ad) = generate_a_ad_operators(atom_list, k, b, bd)
    (Sp,Sm) = generate_Sp_Sm_operators(atom_list, a, ad)
    (Sa,Sb,Sn) = generate_Sa_Sb_Sn_operators(atom_list, Sp, Sm)
    (Sx,Sy,Sz) = generate_Sx_Sy_Sz_operators(atom_list, Sa, Sb, Sn)
    print ''
    
    #Ham = generate_Hamiltonian(N_atoms, atom_list, b, bd)
    ops = generate_possible_combinations(atom_list, [Sx,Sy,Sz])
    ops = holstein(atom_list, ops)
    ops = apply_commutation(atom_list, ops)
    ops = replace_bdb(atom_list, ops)

    ops = reduce_options(atom_list, ops)
    list_print(ops)
    
    print "prelims complete. generating cross-section","\n"

    aa = bb = cc = np.array([2.0*np.pi], 'Float64')
    alpha = beta = gamma = np.array([np.pi/2.0], 'Float64')
    vect1 = np.array([[1,0,0]])
    vect2 = np.array([[0,0,1]])
    lattice = Lattice(aa, bb, cc, alpha, beta, gamma, Orientation(vect1, vect2))
    
    tau_list = []
    for i in range(1):
        tau_list.append(np.array([0,0,0], 'Float64'))

    h_list = np.linspace(0.1,6.3,50)
    k_list = np.zeros(h_list.shape)
    l_list = np.zeros(h_list.shape)
    
    w_list = np.linspace(-10,10,50)

    (N_atoms_uc,csection,kaprange,
     tau_list,eig_list,kapvect,wtlist,fflist) = generate_cross_section(interactionfile, spinfile, lattice, ops, 
                                                                tau_list, h_list, k_list, l_list, w_list)
    print csection

    return N_atoms_uc,csection,kaprange,tau_list,eig_list,kapvect,wtlist,fflist
    end = clock()
    print "\nFinished %i atoms in %.2f seconds" %(N_atoms,end-start)
Beispiel #2
0
def optimization_driver(interfile, spinfile):
    """ runs the local optimization routine given just an interactionfile and spinfile. this should be called by the GUI """
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile,spinfile,allAtoms=True)
    N_atoms = len(atom_list)
    jij = gen_Jij(atom_list,jmats)
    anis = gen_anisotropy(atom_list)
    sij = gen_spinVector(atom_list)
    Ham = calculate_Ham(sij, anis, jij)
    
    return local_optimizer(interfile, spinfile)
Beispiel #3
0
def run_dispersion_from_file(interactionfile,spinfile, eigs=False, eigsP = (False,None)):
    atom_list, jnums, jmats,N_atoms_uc=rf.readFiles(interactionfile,spinfile)
    N_atoms=len(atom_list)
    Hsave = calculate_dispersion(atom_list,N_atoms_uc,N_atoms,jmats,showEigs=eigs)
    if eigs == True:
        temp = 1
        x = sp.Symbol('x')
        for i in range(Hsave.cols): temp *= x-Hsave[i,i]
        poly = sp.simplify(temp.expand())
        print poly
    return sp.simplify(Hsave[0])
Beispiel #4
0
def optimization_driver(interfile, spinfile):
    """ runs the local optimization routine given just an interactionfile and spinfile. this should be called by the GUI """
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile,
                                                       spinfile,
                                                       allAtoms=True)
    N_atoms = len(atom_list)
    jij = gen_Jij(atom_list, jmats)
    anis = gen_anisotropy(atom_list)
    sij = gen_spinVector(atom_list)
    Ham = calculate_Ham(sij, anis, jij)

    return local_optimizer(interfile, spinfile)
Beispiel #5
0
def local_optimizer(interfile, spinfile):
    """
    Given an interaction file and a spin file, this optimizer will uses readfiles.readfiles to populate 
    an atom list as well as return the interaction matrices. Given that information, it will recalculate
    the hamiltonian and attempt to minimize it as a function of theta and phi. The annealing will get the
    spins close to the global minimum and this method makes sure the spins are aligned. This routine uses
    only python instead of C. 
    """

    # Get atoms list, jmats from the interaction and spin files
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile, spinfile, allAtoms=True)

    return opt_aux(atom_list, jmats)
def cs_driver():
    file_pathname = os.path.abspath('')
    interfile = os.path.join(file_pathname,r'montecarlo.txt')
    spinfile = os.path.join(file_pathname,r'spins.txt')

    h_list = np.linspace(0.001,3.14,15)
    k_list = np.zeros(h_list.shape)
    l_list = np.zeros(h_list.shape)
    w_list = np.linspace(0,5,15)
    tau = np.array([0,0,0])
    wt = np.array(1.0)
    rad = 1.0

    atom_list, jnums, jmats,N_atoms_uc=readFiles(interfile,spinfile)
    N_atoms_uc,csection,kaprange,tau_list,eig_list,kapvect,wt_list,fflist = run_cross_section(interfile,spinfile)
    
    x,y,z=run_spherical_averaging(N_atoms_uc,atom_list,rad,csection,kapvect,tau_list,eig_list,wt_list,temperature)
    np.save(os.path.join(file_pathname,r'myfilex.txt'),x)
    np.save(os.path.join(file_pathname,r'myfiley.txt'),y)
    np.save(os.path.join(file_pathname,r'myfilez.txt'),z)
Beispiel #7
0
def run_dispersion_from_file(interactionfile,
                             spinfile,
                             eigs=False,
                             eigsP=(False, None)):
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interactionfile,
                                                       spinfile)
    N_atoms = len(atom_list)
    Hsave = calculate_dispersion(atom_list,
                                 N_atoms_uc,
                                 N_atoms,
                                 jmats,
                                 showEigs=eigs)
    if eigs == True:
        temp = 1
        x = sp.Symbol('x')
        for i in range(Hsave.cols):
            temp *= x - Hsave[i, i]
        poly = sp.simplify(temp.expand())
        print poly
    return sp.simplify(Hsave[0])
Beispiel #8
0
def local_optimizer(interfile, spinfile):
    """
    Given an interaction file and a spin file, this optimizer will uses readfiles.readfiles to populate 
    an atom list as well as return the interaction matrices. Given that information, it will recalculate
    the hamiltonian and attempt to minimize it as a function of theta and phi. The annealing will get the
    spins close to the global minimum and this method makes sure the spins are aligned. This routine uses
    only python instead of C. 
    """

    # Get atoms list, jmats from the interaction and spin files
    atom_list, jnums, jmats,N_atoms_uc=rf.readFiles(interfile,spinfile,allAtoms=True)
    N_atoms = len(atom_list)
    # Generate the Jij and anisotropy arrays
    Jij = gen_Jij(atom_list,jmats)
    anis = gen_anisotropy(atom_list)
    # Get the spin magnitudes from the atoms in atom list
    spin_mags = []
    for i in range(len(atom_list)):
        spin_mags.append(atom_list[i].spinMagnitude)
    spin_mags = np.array(spin_mags)
    
    # hamiltonian method
    def hamiltonian(p, Jij = None, spins = None, anis = None):
        """ Computes the hamiltonian given a list a thetas and phis"""
        # Thetas are the first half, phis the second half
        theta = p[:len(p)//2]
        phi = p[len(p)//2:]

        # Sx,Sy,Sz
        Sx = spins*cos(theta)*cos(phi)
        Sy = spins*cos(theta)*sin(phi)
        Sz = spins*sin(theta)

        # Array of spin vectors for each atom. Reshape it. Calculate hamiltonian with it and return the hamiltonian. 
        Sij = np.array([Sx,Sy,Sz])
        Sij = Sij.T.reshape(1,3*len(p)//2).T

        SijT =Sij.T
        
        # Normal mode
        # sij.T * jij * sij
        res1 = SijT * Jij
        Hij = np.dot(res1,Sij).flat[0]
    
        Ham = - Hij - np.dot(anis, Sij**2)

        return Ham
    
    # derivative of the hamiltonian
    def deriv(p, Jij = None, spins = None, anis = None):
        """ Computes the derivative of the hamiltonian with respect to each theta and then each phi"""
        # Thetas are the first half, phis the second half
        half = len(p)/2
        theta = p[:half]
        phi = p[half:]        

        # Sx,Sy,Sz
        Sx = spins*cos(theta)*cos(phi)
        Sy = spins*cos(theta)*sin(phi)
        Sz = spins*sin(theta)

        # dSx/dtheta,dSy/dtheta,dSz/dtheta
        Sxt = -spins*sin(theta)*cos(phi)
        Syt = -spins*sin(theta)*sin(phi)
        Szt = spins*cos(theta)
        # dSx/dphi,dSy/dphi,dSz/dphi
        Sxp = -spins*cos(theta)*sin(phi)
        Syp = spins*cos(theta)*cos(phi)
        Szp = 0*cos(theta)
        
        # Makes an array of the derivatives with respect to theta, then another with respect to phi
        # (dSx1/dtheta1,dSy1/dtheta1,dSz1/dtheta1
        # (                                      dSx2/dtheta2,dSy2/dtheta2,dSz2/dtheta2
        # (                                                                             ...
        # Similarly for phis
        # Then we multiply this by Jij which yields a half by 3*half array. We then multiply this by
        # the Sij vector which finally yields a half by 1 array. Thus
        # dSijt * Jij * Sij -> [dE/dtheta1, dE/dtheta2, dE/dtheta3, ...]
        # and similarly for phi
        dSijt = np.zeros((half,3*half))
        dSijp = np.zeros((half,3*half))
        dSijt[range(half),range(0,3*half,3)]=Sxt
        dSijt[range(half),range(1,3*half,3)]=Syt
        dSijt[range(half),range(2,3*half,3)]=Szt
        dSijp[range(half),range(0,3*half,3)]=Sxp
        dSijp[range(half),range(1,3*half,3)]=Syp
        dSijp[range(half),range(2,3*half,3)]=Szp
        
        # Standard Sij spin vector we've been using
        Sij = np.array([Sx,Sy,Sz])
        Sij = Sij.T.reshape(1,3*len(p)//2).T
        # Calculate a hamiltonian for both theta and phi
        
        res1t = dSijt * Jij
        Hijt = np.dot(res1t,Sij)
        Hamt = - Hijt - np.matrix(np.dot((dSijt**2),anis)).T
        res1p = dSijp * Jij
        Hijp = np.dot(res1p,Sij)
        Hamp = - Hijp - np.matrix(np.dot((dSijp**2),anis)).T

        #rest = calculate_Ham(Sij,anis,Jij,dsij = dSijt)
        #resp = calculate_Ham(Sij,anis,Jij,dsij = dSijp)
        # Concatenate the two and return the result
        result = np.concatenate((np.array(Hamt),np.array(Hamp)))

        return result.T

    # populate initial p list
    # returns a numpy array of all the thetas followed by all the phis
    thetas = []
    phis = []
    for i in range(N_atoms):
        sx = atom_list[i].spin[0]
        sy = atom_list[i].spin[1]
        sz = atom_list[i].spin[2]
        s  = atom_list[i].spinMagnitude
        
        theta = arcsin(sz/s)
        phi   = np.arctan2(sy,sx)
        
        thetas.append(theta)
        phis.append(phi)
    p0 = np.array(thetas+phis)
    
    # define the limits parameter list
    limits = []
    for i in range(len(p0)):
        if i < len(p0)//2:#theta
            limits.append((-pi,pi))
        else:#phi
            limits.append((0,pi))
    
    # call minimizing function
    m = fmin_l_bfgs_b(hamiltonian, p0, fprime = deriv, args = (Jij, spin_mags, anis), bounds = limits)

    # grab returned parameters
    # thetas are the first half of the list, phis are the second half
    pout=m[0]
    theta=pout[0:len(pout)/2]
    phi=pout[len(pout)/2::]
    # recreate sx,sy,sz's
    sx=spin_mags*cos(theta)*cos(phi)
    sy=spin_mags*cos(theta)*sin(phi)
    sz=spin_mags*sin(theta)
    
    # return spin vector array
    return np.array([sx,sy,sz]).T
Beispiel #9
0
def local_optimizer(interfile, spinfile):
    """
    Given an interaction file and a spin file, this optimizer will uses readfiles.readfiles to populate 
    an atom list as well as return the interaction matrices. Given that information, it will recalculate
    the hamiltonian and attempt to minimize it as a function of theta and phi. The annealing will get the
    spins close to the global minimum and this method makes sure the spins are aligned. This routine uses
    only python instead of C. 
    """

    # Get atoms list, jmats from the interaction and spin files
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile,
                                                       spinfile,
                                                       allAtoms=True)
    N_atoms = len(atom_list)
    # Generate the Jij and anisotropy arrays
    Jij = gen_Jij(atom_list, jmats)
    anis = gen_anisotropy(atom_list)
    # Get the spin magnitudes from the atoms in atom list
    spin_mags = []
    for i in range(len(atom_list)):
        spin_mags.append(atom_list[i].spinMagnitude)
    spin_mags = np.array(spin_mags)

    # hamiltonian method
    def hamiltonian(p, Jij=None, spins=None, anis=None):
        """ Computes the hamiltonian given a list a thetas and phis"""
        # Thetas are the first half, phis the second half
        theta = p[:len(p) // 2]
        phi = p[len(p) // 2:]

        # Sx,Sy,Sz
        Sx = spins * cos(theta) * cos(phi)
        Sy = spins * cos(theta) * sin(phi)
        Sz = spins * sin(theta)

        # Array of spin vectors for each atom. Reshape it. Calculate hamiltonian with it and return the hamiltonian.
        Sij = np.array([Sx, Sy, Sz])
        Sij = Sij.T.reshape(1, 3 * len(p) // 2).T

        SijT = Sij.T

        # Normal mode
        # sij.T * jij * sij
        res1 = SijT * Jij
        Hij = np.dot(res1, Sij).flat[0]

        Ham = -Hij - np.dot(anis, Sij**2)

        return Ham

    # derivative of the hamiltonian
    def deriv(p, Jij=None, spins=None, anis=None):
        """ Computes the derivative of the hamiltonian with respect to each theta and then each phi"""
        # Thetas are the first half, phis the second half
        half = len(p) / 2
        theta = p[:half]
        phi = p[half:]

        # Sx,Sy,Sz
        Sx = spins * cos(theta) * cos(phi)
        Sy = spins * cos(theta) * sin(phi)
        Sz = spins * sin(theta)

        # dSx/dtheta,dSy/dtheta,dSz/dtheta
        Sxt = -spins * sin(theta) * cos(phi)
        Syt = -spins * sin(theta) * sin(phi)
        Szt = spins * cos(theta)
        # dSx/dphi,dSy/dphi,dSz/dphi
        Sxp = -spins * cos(theta) * sin(phi)
        Syp = spins * cos(theta) * cos(phi)
        Szp = 0 * cos(theta)

        # Makes an array of the derivatives with respect to theta, then another with respect to phi
        # (dSx1/dtheta1,dSy1/dtheta1,dSz1/dtheta1
        # (                                      dSx2/dtheta2,dSy2/dtheta2,dSz2/dtheta2
        # (                                                                             ...
        # Similarly for phis
        # Then we multiply this by Jij which yields a half by 3*half array. We then multiply this by
        # the Sij vector which finally yields a half by 1 array. Thus
        # dSijt * Jij * Sij -> [dE/dtheta1, dE/dtheta2, dE/dtheta3, ...]
        # and similarly for phi
        dSijt = np.zeros((half, 3 * half))
        dSijp = np.zeros((half, 3 * half))
        dSijt[range(half), range(0, 3 * half, 3)] = Sxt
        dSijt[range(half), range(1, 3 * half, 3)] = Syt
        dSijt[range(half), range(2, 3 * half, 3)] = Szt
        dSijp[range(half), range(0, 3 * half, 3)] = Sxp
        dSijp[range(half), range(1, 3 * half, 3)] = Syp
        dSijp[range(half), range(2, 3 * half, 3)] = Szp

        # Standard Sij spin vector we've been using
        Sij = np.array([Sx, Sy, Sz])
        Sij = Sij.T.reshape(1, 3 * len(p) // 2).T
        # Calculate a hamiltonian for both theta and phi

        res1t = dSijt * Jij
        Hijt = np.dot(res1t, Sij)
        Hamt = -Hijt - np.matrix(np.dot((dSijt**2), anis)).T
        res1p = dSijp * Jij
        Hijp = np.dot(res1p, Sij)
        Hamp = -Hijp - np.matrix(np.dot((dSijp**2), anis)).T

        #rest = calculate_Ham(Sij,anis,Jij,dsij = dSijt)
        #resp = calculate_Ham(Sij,anis,Jij,dsij = dSijp)
        # Concatenate the two and return the result
        result = np.concatenate((np.array(Hamt), np.array(Hamp)))

        return result.T

    # populate initial p list
    # returns a numpy array of all the thetas followed by all the phis
    thetas = []
    phis = []
    for i in range(N_atoms):
        sx = atom_list[i].spin[0]
        sy = atom_list[i].spin[1]
        sz = atom_list[i].spin[2]
        s = atom_list[i].spinMagnitude

        theta = arcsin(sz / s)
        phi = np.arctan2(sy, sx)

        thetas.append(theta)
        phis.append(phi)
    p0 = np.array(thetas + phis)

    # define the limits parameter list
    limits = []
    for i in range(len(p0)):
        if i < len(p0) // 2:  #theta
            limits.append((-pi, pi))
        else:  #phi
            limits.append((0, pi))

    # call minimizing function
    m = fmin_l_bfgs_b(hamiltonian,
                      p0,
                      fprime=deriv,
                      args=(Jij, spin_mags, anis),
                      bounds=limits)

    # grab returned parameters
    # thetas are the first half of the list, phis are the second half
    pout = m[0]
    theta = pout[0:len(pout) / 2]
    phi = pout[len(pout) / 2::]
    # recreate sx,sy,sz's
    sx = spin_mags * cos(theta) * cos(phi)
    sy = spin_mags * cos(theta) * sin(phi)
    sz = spin_mags * sin(theta)

    # return spin vector array
    return np.array([sx, sy, sz]).T
Beispiel #10
0
def run_cross_section(interactionfile, spinfile):
    start = clock()

    # Generate Inputs
    atom_list, jnums, jmats, N_atoms_uc = readFiles(interactionfile, spinfile)
    atom1 = atom(pos=[0.00, 0, 0],
                 neighbors=[1],
                 interactions=[0],
                 int_cell=[0],
                 atomicNum=26,
                 valence=3)
    atom2 = atom(pos=[0.25, 0, 0],
                 neighbors=[0, 2],
                 interactions=[0],
                 int_cell=[0],
                 atomicNum=26,
                 valence=3)
    atom3 = atom(pos=[0.50, 0, 0],
                 neighbors=[1, 3],
                 interactions=[0],
                 int_cell=[0],
                 atomicNum=26,
                 valence=3)
    atom4 = atom(pos=[0.75, 0, 0],
                 neighbors=[2],
                 interactions=[0],
                 int_cell=[0],
                 atomicNum=26,
                 valence=3)
    #    atom_list,N_atoms_uc = ([atom1, atom2, atom3, atom4],1)
    N_atoms = len(atom_list)

    print N_atoms
    if 1:
        kx = sp.Symbol('kx', real=True, commutative=True)
        ky = sp.Symbol('ky', real=True, commutative=True)
        kz = sp.Symbol('kz', real=True, commutative=True)
        k = spm.Matrix([kx, ky, kz])

    (b, bd) = generate_b_bd_operators(atom_list)
    #    list_print(b)
    (a, ad) = generate_a_ad_operators(atom_list, k, b, bd)
    list_print(a)
    (Sp, Sm) = generate_Sp_Sm_operators(atom_list, a, ad)
    list_print(Sp)
    (Sa, Sb, Sn) = generate_Sa_Sb_Sn_operators(atom_list, Sp, Sm)
    #    list_print(Sa)
    (Sx, Sy, Sz) = generate_Sx_Sy_Sz_operators(atom_list, Sa, Sb, Sn)
    list_print(Sx)
    print ''

    #Ham = generate_Hamiltonian(N_atoms, atom_list, b, bd)
    ops = generate_possible_combinations(atom_list, [Sx, Sy, Sz])
    #    list_print(ops)
    ops = holstein(atom_list, ops)
    #    list_print(ops)
    ops = apply_commutation(atom_list, ops)
    #    list_print(ops)
    ops = replace_bdb(atom_list, ops)
    #    list_print(ops)

    ops = reduce_options(atom_list, ops)
    list_print(ops)

    # Old Method
    #cross_sect = generate_cross_section(atom_list, ops, 1, real, recip)
    #print '\n', cross_sect

    if 1:
        aa = bb = cc = np.array([2.0 * np.pi], 'Float64')
        alpha = beta = gamma = np.array([np.pi / 2.0], 'Float64')
        vect1 = np.array([[1, 0, 0]])
        vect2 = np.array([[0, 0, 1]])
        lattice = Lattice(aa, bb, cc, alpha, beta, gamma,
                          Orientation(vect1, vect2))
        data = {}
        data['kx'] = 1.
        data['ky'] = 0.
        data['kz'] = 0.
        direction = data

        temperature = 100.0
        min = 0
        max = 2 * sp.pi
        steps = 25

        tau_list = []
        for i in range(1):
            tau_list.append(np.array([0, 0, 0], 'Float64'))

        h_list = np.linspace(0, 2, 100)
        k_list = np.zeros(h_list.shape)
        l_list = np.zeros(h_list.shape)
        w_list = np.linspace(-4, 4, 100)

        efixed = 14.7  #meV
        eief = True
        eval_cross_section(interactionfile, spinfile, lattice, ops, tau_list,
                           h_list, k_list, l_list, w_list, data, temperature,
                           min, max, steps, eief, efixed)

    end = clock()
    print "\nFinished %i atoms in %.2f seconds" % (N_atoms, end - start)
Beispiel #11
0
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile,spinfile,allAtoms=True)
    N_atoms = len(atom_list)
    jij = gen_Jij(atom_list,jmats)
    anis = gen_anisotropy(atom_list)
    sij = gen_spinVector(atom_list)
    Ham = calculate_Ham(sij, anis, jij)
    
    return local_optimizer(interfile, spinfile)
    


if __name__ == '__main__':
    #print optimizeSpins('C:\\export.txt', 'C:\\spins.txt', 'C:\\spins2.txt')
    #interfile = 'c:/test_montecarlo.txt'
    #spinfile  = 'c:/test_Spins.txt'
    interfile='c:/montecarlo_ferro.txt'
    spinfile='c:/Spins_ferro.txt'

    atom_list, jnums, jmats,N_atoms_uc=rf.readFiles(interfile,spinfile,allAtoms=True)
    N_atoms = len(atom_list)

    jij = gen_Jij(atom_list, jmats)
    anis = gen_anisotropy(atom_list)
    sij = gen_spinVector(atom_list)
    Ham = calculate_Ham(sij, anis, jij)
    print Ham
    
    print local_optimizer(interfile, spinfile)
    
    
    
    N_atoms_uc,csection,kaprange,tau_list,eig_list,kapvect,wt_list,fflist = run_cross_section(interfile,spinfile)
    
    x,y,z=run_spherical_averaging(N_atoms_uc,atom_list,rad,csection,kapvect,tau_list,eig_list,wt_list,temperature)
    np.save(os.path.join(file_pathname,r'myfilex.txt'),x)
    np.save(os.path.join(file_pathname,r'myfiley.txt'),y)
    np.save(os.path.join(file_pathname,r'myfilez.txt'),z)

if __name__=='__main__':
#def pd():
    #from spinwaves.cross_section.csection_calc import spherical_averaging as sph

    file_pathname = os.path.abspath('')
    interfile = os.path.join(file_pathname,r'montecarlo.txt')
    spinfile = os.path.join(file_pathname,r'spins.txt')

    atom_list, jnums, jmats,N_atoms_uc=readFiles(interfile,spinfile)
    
    N_atoms_uc,csection,kaprange,tau_list,eig_list,kapvect,wt_list,fflist = run_cross_section(interfile,spinfile)
#    left_conn, right_conn = Pipe()
#    p = Process(target = create_latex, args = (right_conn, csection, "Cross-Section"))
#    p.start()
#    eig_frame = LaTeXDisplayFrame(self.parent, p.pid, left_conn.recv(), 'Cross-Section')
#    self.process_list.append(p)
#    p.join()
#    p.terminate()

    # ORIGINAL METHOD TO GENERATE CROSS SECTION
    if 0:
        kapvect,wt_list,csdata=run_eval_cross_section(N_atoms_uc,csection,kaprange,tau_list,eig_list,kapvect,wt_list,fflist)
        plot_cross_section(kapvect[:,0],wt_list,csdata)
Beispiel #13
0
def eval_cross_section(interactionfile,
                       spinfile,
                       lattice,
                       arg,
                       tau_list,
                       h_list,
                       k_list,
                       l_list,
                       w_vect_list,
                       direction,
                       temperature,
                       kmin,
                       kmax,
                       steps,
                       eief,
                       efixed=14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    direction   - direction of scan
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if the energy scheme is Ei - Ef, False if it is Ef - Ei
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats, N_atoms_uc = readFiles(interactionfile, spinfile)
    N_atoms = len(atom_list)
    N = N_atoms

    # TEMPORARY TO OVERRIDE ATOM_LIST ABOVE
    #    atom1 = atom(pos = [0.00,0,0], neighbors = [1],   interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom2 = atom(pos = [0.25,0,0], neighbors = [0,2], interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom3 = atom(pos = [0.50,0,0], neighbors = [1,3], interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom4 = atom(pos = [0.75,0,0], neighbors = [2],   interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom_list,N_atoms_uc = ([atom1, atom2, atom3, atom4],1)
    N_atoms = len(atom_list)

    # Get Hsave to calculate its eigenvalues
    (Hsave, charpoly, eigs) = calculate_dispersion(atom_list,
                                                   N_atoms_uc,
                                                   N_atoms,
                                                   jmats,
                                                   showEigs=True)
    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    if len(h_list) == len(k_list) == len(l_list):
        for i in range(len(h_list)):
            kappa = lattice.modvec(h_list[i], k_list[i], l_list[i],
                                   'latticestar')
            kaprange.append(kappa[0])
            kapvect.append(np.array([h_list[i], k_list[i], l_list[i]]))
#            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    else:
        raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    pqrange = []
    mqrange = []
    for tau in tau_list:
        ptemp = []
        mtemp = []
        for kap in kapvect:
            #tau = lattice.modvec(tau[0],tau[1],tau[2], 'latticestar')
            ptemp.append(kap - tau)
            mtemp.append(tau - kap)
        pqrange.append(ptemp)
        mqrange.append(mtemp)
    # Calculate w_q's using q
    qrange = []
    #    krange = []
    wrange = []
    if 1:  # Change this later
        for set in pqrange:
            temp = []
            temp1 = []
            for q in set:
                eigs = calc_eigs(Hsave, q[0] * direction['kx'],
                                 q[1] * direction['ky'],
                                 q[2] * direction['kz'])
                # Take only one set of eigs. Should probably have a flag here.
                temp.append(eigs[0])
                #                krange.append(np.array([q*direction['kx'], q*direction['ky'], q*direction['kz']]))
                temp1.append(q)
            wrange.append(temp)
            qrange.append(temp1)
    print "Calculated: Eigenvalues"

    wrange = np.array(np.real(wrange))
    qrange = np.array(np.real(qrange))
    kaprange = np.array(np.real(kaprange))

    print qrange.shape
    print wrange.shape
    print kaprange.shape

    # Calculate w (not _q) as well as kp/k
    w_calc = []
    kpk = []
    if eief == True:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(om - efixed)
                temp1.append(np.sqrt(om / efixed))
            w_calc.append(temp)
            kpk.append(temp1)
    else:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(-(om - efixed))
                temp1.append(np.sqrt(efixed / om))
            w_calc.append(temp)
            kpk.append(temp1)

    w_calc = np.array(np.real(w_calc))

    # Grab Form Factors
    ff_list = []
    s = sp.Symbol('s')
    for i in range(N_atoms):
        el = elements[atom_list[i].atomicNum]
        val = atom_list[i].valence
        if val != None:
            Mq = el.magnetic_ff[val].M_Q(kaprange)
        else:
            Mq = el.magnetic_ff[0].M_Q(kaprange)
        ff_list.append(Mq)
    print "Calculated: Form Factors"

    # Other Constants
    gamr0 = 2 * 0.2695 * 10**(-12)  #sp.Symbol('gamma', commutative = True)
    hbar = 1.0  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.  #sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol(
        'kappa', real=True
    )  #spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real=True)
    w = sp.Symbol('w', real=True)
    W = sp.Symbol('W', real=True)
    tau = sp.Symbol('tau', real=True)
    q = sp.Symbol('q', real=True)
    L = sp.Symbol('L', real=True)
    boltz = 1.  #1.3806503*10**(-23)

    # Wilds for sub_in method
    A = sp.Wild('A', exclude=[0, t])
    B = sp.Wild('B', exclude=[0, t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')

    # First the exponentials are turned into delta functions:
    for i in range(len(arg)):
        for j in range(N):
            print '1', arg[i][j]
            arg[i][j] = sp.powsimp(
                arg[i]
                [j])  #sp.powsimp(arg[i][j], deep = True, combine = 'all')
            arg[i][j] = (
                arg[i][j] * exp(-I * w * t) * exp(I * kap * L)).expand(
                )  # * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
            arg[i][j] = sp.powsimp(
                arg[i]
                [j])  #sp.powsimp(arg[i][j], deep = True, combine = 'all')
            #            print '2', arg[i][j]
            arg[i][j] = sub_in(
                arg[i][j], exp(I * t * A + I * t * B + I * C + I * D + I * K),
                sp.DiracDelta(A * t + B * t + C + D + K))  #*sp.DiracDelta(C))
            #            print '3', arg[i][j]
            arg[i][j] = sub_in(
                arg[i][j],
                sp.DiracDelta(A * t + B * t + C * L + D * L + K * L),
                sp.DiracDelta(A * hbar + B * hbar) *
                sp.simplify(sp.DiracDelta(C + D + K + tau)))
            #            print '4', arg[i][j]
            arg[i][j] = sub_in(arg[i][j],
                               sp.DiracDelta(-A - B) * sp.DiracDelta(C),
                               sp.DiracDelta(A + B) * sp.DiracDelta(C))
            print '5', arg[i][j]
    print "Applied: Delta Function Conversion"

    # Grabs the unit vectors from the back of the lists.
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat', commutative=False)
    kapyhat = sp.Symbol('kapyhat', commutative=False)
    kapzhat = sp.Symbol('kapzhat', commutative=False)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #

    csdata = []
    for i in range(len(arg)):
        temp1 = []
        for j in range(len(arg[i])):
            temp2 = []
            for k in range(len(tau_list)):
                temp3 = []
                print i, j, k
                for g in range(len(qrange[k])):
                    pvalue = tau_list[k] + kapvect[g] + qrange[k][g]
                    mvalue = tau_list[k] + kapvect[g] - qrange[k][g]
                    if pvalue[0] == 0 and pvalue[1] == 0 and pvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau + q), sp.DiracDelta(0))
                    else:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau + q), 0)
                    if mvalue[0] == 0 and mvalue[1] == 0 and mvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau - q), sp.DiracDelta(0))
                    else:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau - q), 0)
                    wq = sp.Symbol('wq', real=True)
                    nq = sp.Symbol('n%i' % (k, ), commutative=False)
                    arg[i][j] = arg[i][j].subs(wq, wrange[k][g])
                    arg[i][j] = arg[i][j].subs(w, w_calc[k][g])
                    n = sp.Pow(
                        sp.exp(hbar * wrange[k][g] / boltz * temperature) - 1,
                        -1)
                    arg[i][j] = arg[i][j].subs(nq, n)
                    temp3.append(arg[i][j])
                temp2.append(temp3)
            temp1.append(temp2)
        csdata.append(temp1)
##            print arg[i][j]
#            for g in range(len(kaprange)):
#                arg[i][j] = arg[i][j].subs(kap, kaprange[g])
#            for g in range(len(krange)):
##                print 'calculating'
#                temp3 = []
#                wg = sp.Symbol('w%i'%(g,), real = True)
#                ng = sp.Symbol('n%i'%(g,), commutative = False)
##                kx = sp.Symbol('kx', real = True, commutative = True)
##                ky = sp.Symbol('ky', real = True, commutative = True)
##                kz = sp.Symbol('kz', real = True, commutative = True)
##                arg[i][j] = arg[i][j].subs(kx,krange[g][0])
##                arg[i][j] = arg[i][j].subs(ky,krange[g][1])
##                arg[i][j] = arg[i][j].subs(kz,krange[g][2])
#                arg[i][j] = arg[i][j].subs(wg,wrange[g])
#                arg[i][j] = arg[i][j].subs(w,w_calc[g])
#                nq = sp.Pow( sp.exp(hbar*wrange[g]/boltz*temp) - 1 ,-1)
#                arg[i][j] = arg[i][j].subs(ng,nq)
##                arg[i][j] = arg[i][j].subs(tau,tau_list[0])
#
#                temp3.append(arg[i][j])
##                print arg[i][j]
#            temp2.append(temp3)
##            print arg[i][j]
#        csdata.append(temp2)

    print csdata

    # Front constants and stuff for the cross-section
    front_constant = 1.0  # (gamr0)**2/(2*pi*hbar)
    front_func = (1. / 2.) * g  #*F(k)
    vanderwaals = 1.  #exp(-2*W)

    csrange = []
    if 1:
        temp1 = []
        temp2 = []
        for q in range(len(qrange)):
            print 'calculating'
            for ii in range(len(csdata)):
                for jj in range(len(csdata[ii])):
                    temp1.append(csdata[ii][jj])
            # Put on gamr0, 2pi hbar, form factor, kp/k, vanderwaals first
            dif = front_func**2 * front_constant  # * kpk[q][0] * vanderwaals * ff_list[0][q]
            #            for vect in unit_vect:
            #                vect.subs(kapxhat,kapvect[q][0][0])
            #                vect.subs(kapyhat,kapvect[q][1][0])
            #                vect.subs(kapzhat,kapvect[q][2][0])
            print 'diff', dif
            print 'temp1', temp1
            print sum(temp1)
            dif = (dif * sum(temp1))  # * sum(unit_vect))#.expand()
            csrange.append(dif)
    print "Calculated: Cross-section"
    csrange = np.real(csrange)
    csrange = np.array(csrange)

    xi = qrange
    yi = wrange
    zi = csrange
    Z = np.zeros((xi.shape[0], yi.shape[0]))
    Z[range(len(xi)), range(len(yi))] = zi

    pylab.contourf(xi, yi, Z)
    pylab.colorbar()
    pylab.show()
Beispiel #14
0
def generate_cross_section(interactionfile, spinfile, lattice, arg, 
                       tau_list, h_list, k_list, l_list, w_list, 
                       temperature, steps, eief, efixed = 14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if fixed Ef
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)
    

    # Get Hsave to calculate its eigenvalues
    N_atoms = len(atom_list)
    Hsave = calculate_dispersion(atom_list,N_atoms_uc,N_atoms,jmats,showEigs=False)
    atom_list=atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    N = N_atoms
    
    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    #if len(h_list) == len(k_list) == len(l_list):
        #for i in range(len(h_list)):
            #kappa = lattice.modvec(h_list[i],k_list[i],l_list[i], 'latticestar')
            #kaprange.append(kappa[0])
            #kapvect.append(np.array([h_list[i],k_list[i],l_list[i]]))
##            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    #else:
        #raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    kaprange=lattice.modvec(h_list,k_list,l_list, 'latticestar')
    nkpts=len(kaprange)
    kapvect=np.empty((nkpts,3),'Float64')
    kapvect[:,0]=h_list
    kapvect[:,1]=k_list
    kapvect[:,2]=l_list
#    print kapvect.shape
#    print kaprange.shape
    kapunit = kapvect.copy()
    kapunit[:,0]=kapvect[:,0]/kaprange
    kapunit[:,1]=kapvect[:,1]/kaprange
    kapunit[:,2]=kapvect[:,2]/kaprange
    #plusq=kappa-tau
    plusq=[]
    minusq=[]
    qlist=[]
    ones_list=np.ones((1,nkpts),'Float64')
    #wtlist=np.ones((1,nkpts*2),'Float64').flatten()
    wtlist=np.hstack([w_list,w_list])
    #weven=np.array(range(0,nkpts*2,2))
    #wodd=np.array(range(1,nkpts*2,2))
    #wtlist[wodd]=w_list
    #wtlist[weven]=w_list    
    qtlist=[]
    
    
    
    for tau in tau_list:
        taui=np.ones((nkpts,3),'Float64')
        taui[:,0]=ones_list*tau[0]
        taui[:,1]=ones_list*tau[1]
        taui[:,2]=ones_list*tau[2]
        kappa_minus_tau=kapvect-taui
        tau_minus_kappa=taui - kapvect
               
        qlist.append(np.vstack([kappa_minus_tau,tau_minus_kappa]))
    #calculate kfki
    nqpts=nkpts*2
    kfki=calc_kfki(w_list,eief,efixed)


    eig_list=[]
#    print qlist
    for q in qlist:
        #eigs = calc_eigs_direct(Hsave,q[:,0],q[:,1],q[:,2])
        eigs = Hsave.eigenvals().keys()
        eig_list.append(eigs)
    print "Calculated: Eigenvalues"
    
 #   print len(qlist)
 #   print len(eig_list[0])
#    sys.exit()
    # Grab Form Factors
#----Commented out 9/14/09 by Tom becuase of magnetic_ff error--------------
    #ff_list = []
    #s = sp.Symbol('s')
    #for i in range(N_atoms):
        #el = elements[atom_list[i].atomicNum]
        #val = atom_list[i].valence
        #if val != None:
            #Mq = el.magnetic_ff[val].M_Q(kaprange)
        #else:
            #Mq = el.magnetic_ff[0].M_Q(kaprange)
        #ff_list.append(Mq)
    #print "Calculated: Form Factors"
#--------------------------------------------------------------------------

    # Other Constants
    gamr0 = 2*0.2695e-12 #sp.Symbol('gamma', commutative = True)
    hbar = sp.S(1.0) # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.#sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol('kappa', real = True)#spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real = True)
    w = sp.Symbol('w', real = True)
    W = sp.Symbol('W', real = True)
    tau = sp.Symbol('tau', real = True)
    Q = sp.Symbol('q', real = True)
    L = sp.Symbol('L', real = True)
    lifetime=sp.Symbol('V',real=True)
    boltz = 8.617343e-2
    
    # Wilds for sub_in method
    A = sp.Wild('A',exclude = [0,t])
    B = sp.Wild('B',exclude = [0,t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')
    
    # Grabs the unit vectors from the back of the lists. 
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat',real=True)
    kapyhat = sp.Symbol('kapyhat',real=True)
    kapzhat = sp.Symbol('kapzhat',real=True)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
    #print unit_vect
    unit_vect = sum(unit_vect)
    print unit_vect
    
    csection=0
    for i in range(len(arg)):
        for j in range(len(arg[i])):
            csection=csection+arg[i][j]*unit_vect
    
    print csection
    
 
    
    csection=sp.powsimp(csection)
    csection = (csection * exp(-I*w*t) * exp(I*kap*L)).expand(deep = False)
    print 'intermediate'
    #print csection
    csection= sp.powsimp(csection)
    csection = sub_in(csection,exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))
    csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),sp.DiracDelta(A*hbar + B*hbar)*sp.simplify(sp.DiracDelta(C + D  - tau)))  #This is correct
    #csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),sp.simplify(lifetime*sp.DiracDelta(C + D  - tau)*
                                                                                 #sp.Pow((A-B)**2+lifetime**2,-1)))
    print "Applied: Delta Function Conversion"
   # print csection
    print 'done'

    ## First the exponentials are turned into delta functions:
    #for i in range(len(arg)):
        #for j in range(N):
##            print '1', arg[i][j]
            #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
            #arg[i][j] = (arg[i][j] * exp(-I*w*t) * exp(I*kap*L)).expand()# * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
            #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
##            print '2', arg[i][j]
            #arg[i][j] = sub_in(arg[i][j],exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))#*sp.DiracDelta(C))
##            print '3', arg[i][j]
            #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(A*t + B*t + C*L + D*L + K*L),sp.DiracDelta(A*hbar + B*hbar)*sp.simplify(sp.DiracDelta(C + D + K + tau)))
##            print '4', arg[i][j]
            #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(-A - B)*sp.DiracDelta(C),sp.DiracDelta(A + B)*sp.DiracDelta(C))
##            arg[i][j] = arg[i][j].subs(-w - wq, w + wq)
##            print '5', arg[i][j]
            
    print "Applied: Delta Function Conversion"

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #
    csection=sub_in(csection,sp.DiracDelta(-A - B)*sp.DiracDelta(C),sp.DiracDelta(A + B)*sp.DiracDelta(C))

    print "end part 1"
    #print csection
    return (N_atoms_uc, csection, kaprange, qlist, tau_list, eig_list, kapvect, wtlist)
Beispiel #15
0
def generate_cross_section(interactionfile,
                           spinfile,
                           lattice,
                           arg,
                           tau_list,
                           h_list,
                           k_list,
                           l_list,
                           w_list,
                           temperature,
                           steps,
                           eief,
                           efixed=14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if fixed Ef
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats, N_atoms_uc = readFiles(interactionfile, spinfile)

    # Get Hsave to calculate its eigenvalues
    N_atoms = len(atom_list)
    Hsave = calculate_dispersion(atom_list,
                                 N_atoms_uc,
                                 N_atoms,
                                 jmats,
                                 showEigs=False)
    atom_list = atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    N = N_atoms

    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    #if len(h_list) == len(k_list) == len(l_list):
    #for i in range(len(h_list)):
    #kappa = lattice.modvec(h_list[i],k_list[i],l_list[i], 'latticestar')
    #kaprange.append(kappa[0])
    #kapvect.append(np.array([h_list[i],k_list[i],l_list[i]]))
    ##            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    #else:
    #raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    kaprange = lattice.modvec(h_list, k_list, l_list, 'latticestar')
    nkpts = len(kaprange)
    kapvect = np.empty((nkpts, 3), 'Float64')
    kapvect[:, 0] = h_list
    kapvect[:, 1] = k_list
    kapvect[:, 2] = l_list
    #    print kapvect.shape
    #    print kaprange.shape
    kapunit = kapvect.copy()
    kapunit[:, 0] = kapvect[:, 0] / kaprange
    kapunit[:, 1] = kapvect[:, 1] / kaprange
    kapunit[:, 2] = kapvect[:, 2] / kaprange
    #plusq=kappa-tau
    plusq = []
    minusq = []
    qlist = []
    ones_list = np.ones((1, nkpts), 'Float64')
    #wtlist=np.ones((1,nkpts*2),'Float64').flatten()
    wtlist = np.hstack([w_list, w_list])
    #weven=np.array(range(0,nkpts*2,2))
    #wodd=np.array(range(1,nkpts*2,2))
    #wtlist[wodd]=w_list
    #wtlist[weven]=w_list
    qtlist = []

    for tau in tau_list:
        taui = np.ones((nkpts, 3), 'Float64')
        taui[:, 0] = ones_list * tau[0]
        taui[:, 1] = ones_list * tau[1]
        taui[:, 2] = ones_list * tau[2]
        kappa_minus_tau = kapvect - taui
        tau_minus_kappa = taui - kapvect

        qlist.append(np.vstack([kappa_minus_tau, tau_minus_kappa]))
    #calculate kfki
    nqpts = nkpts * 2
    kfki = calc_kfki(w_list, eief, efixed)

    eig_list = []
    #    print qlist
    for q in qlist:
        #eigs = calc_eigs_direct(Hsave,q[:,0],q[:,1],q[:,2])
        eigs = Hsave.eigenvals().keys()
        eig_list.append(eigs)
    print "Calculated: Eigenvalues"

    #   print len(qlist)
    #   print len(eig_list[0])
    #    sys.exit()
    # Grab Form Factors
    #----Commented out 9/14/09 by Tom becuase of magnetic_ff error--------------
    #ff_list = []
    #s = sp.Symbol('s')
    #for i in range(N_atoms):
    #el = elements[atom_list[i].atomicNum]
    #val = atom_list[i].valence
    #if val != None:
    #Mq = el.magnetic_ff[val].M_Q(kaprange)
    #else:
    #Mq = el.magnetic_ff[0].M_Q(kaprange)
    #ff_list.append(Mq)
    #print "Calculated: Form Factors"
    #--------------------------------------------------------------------------

    # Other Constants
    gamr0 = 2 * 0.2695e-12  #sp.Symbol('gamma', commutative = True)
    hbar = sp.S(
        1.0)  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.  #sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol(
        'kappa', real=True
    )  #spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real=True)
    w = sp.Symbol('w', real=True)
    W = sp.Symbol('W', real=True)
    tau = sp.Symbol('tau', real=True)
    Q = sp.Symbol('q', real=True)
    L = sp.Symbol('L', real=True)
    lifetime = sp.Symbol('V', real=True)
    boltz = 8.617343e-2

    # Wilds for sub_in method
    A = sp.Wild('A', exclude=[0, t])
    B = sp.Wild('B', exclude=[0, t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')

    # Grabs the unit vectors from the back of the lists.
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat', real=True)
    kapyhat = sp.Symbol('kapyhat', real=True)
    kapzhat = sp.Symbol('kapzhat', real=True)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
    #print unit_vect
    unit_vect = sum(unit_vect)
    print unit_vect

    csection = 0
    for i in range(len(arg)):
        for j in range(len(arg[i])):
            csection = csection + arg[i][j] * unit_vect

    print csection

    csection = sp.powsimp(csection)
    csection = (csection * exp(-I * w * t) *
                exp(I * kap * L)).expand(deep=False)
    print 'intermediate'
    #print csection
    csection = sp.powsimp(csection)
    csection = sub_in(csection,
                      exp(I * t * A + I * t * B + I * C + I * D + I * K),
                      sp.DiracDelta(A * t + B * t + C + D + K))
    csection = sub_in(
        csection, sp.DiracDelta(A * t + B * t + C * L + D * L),
        sp.DiracDelta(A * hbar + B * hbar) *
        sp.simplify(sp.DiracDelta(C + D - tau)))  #This is correct
    #csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),sp.simplify(lifetime*sp.DiracDelta(C + D  - tau)*
    #sp.Pow((A-B)**2+lifetime**2,-1)))
    print "Applied: Delta Function Conversion"
    # print csection
    print 'done'

    ## First the exponentials are turned into delta functions:
    #for i in range(len(arg)):
    #for j in range(N):
    ##            print '1', arg[i][j]
    #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
    #arg[i][j] = (arg[i][j] * exp(-I*w*t) * exp(I*kap*L)).expand()# * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
    #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
    ##            print '2', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))#*sp.DiracDelta(C))
    ##            print '3', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(A*t + B*t + C*L + D*L + K*L),sp.DiracDelta(A*hbar + B*hbar)*sp.simplify(sp.DiracDelta(C + D + K + tau)))
    ##            print '4', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(-A - B)*sp.DiracDelta(C),sp.DiracDelta(A + B)*sp.DiracDelta(C))
    ##            arg[i][j] = arg[i][j].subs(-w - wq, w + wq)
    ##            print '5', arg[i][j]

    print "Applied: Delta Function Conversion"

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #
    csection = sub_in(csection,
                      sp.DiracDelta(-A - B) * sp.DiracDelta(C),
                      sp.DiracDelta(A + B) * sp.DiracDelta(C))

    print "end part 1"
    #print csection
    return (N_atoms_uc, csection, kaprange, qlist, tau_list, eig_list, kapvect,
            wtlist)
Beispiel #16
0
def mcQueeny_case(interactionfile, spinfile, tau_list, temperature,
                      direction={'kx':1,'ky':0,'kz':0}, hkl_interval=[1e-3,2*np.pi,100],
                      omega_interval=[0,5,100], eig_eps = 0.001):

    initial_time = time.clock()


    atom_list, jnums, jmats, N_atoms_uc, numCutOff, magCellSize = readFiles(interactionfile,spinfile, rtn_cutOffInfo = True)


    h_list, k_list, l_list = generate_hkl(hkl_interval, direction)
    e = generate_wt(omega_interval)
    ff_list = generate_form_factors(N_atoms_uc, atom_list, hkl_interval)
    s = []
    basis = []
    for a in atom_list:
        s.append(a.spin[2])#z component of spin (assume aligned with z)
        basis.append(a.pos - magCellSize) #translate  back to 0,0,0


    mesh = np.zeros((len(h_list), len(e)))

    for Qindex in range(len(h_list)):
        Q = (np.array([h_list,k_list,l_list]).transpose())[Qindex]

        M = create_matrix(atom_list, jnums, jmats, numCutOff, magCellSize, Q-np.array(tau_list))
        w, evec = np.linalg.eig(M)

        ff = ff_list[Qindex]


        numAtoms = numCutOff

        evec2 = evec.copy()

        T = evec
        sigma = []
        for i in range(numAtoms):
            sigma.append(s[i]/np.abs(s[i]))
        for n in range(numAtoms):
            norm = 0
            for i in range(numAtoms):
                norm += sigma[i]*(np.abs(evec2[n][i])**2)
            for i in range(numAtoms):
                T[n][i] = evec2[n][i]/np.sqrt(np.abs(norm))
        evec = T
        strfac = np.zeros(numAtoms)

        ff = 1

        for i in range(numAtoms):
            dum = 0
            for j in range(numAtoms):
                dum += (s[j]/np.sqrt(np.abs(s[j]))) * ff * evec[j][i] #* np.exp(1.0j*
                exp = np.exp(1.0j*(-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
            strfac[i] = np.abs(dum)**2
        sqw = np.zeros(len(e))
        for j in range(numAtoms):
            for i in range(len(e)):
                y = LIFETIME_VALUE/2
                lorentzian = (1/np.pi)*y/((e[i]- w[j])**2+y**2)
                sqw[i] = sqw[i] + strfac[j] * lorentzian #he has some 'bose' factor in here
        mesh[Qindex] = sqw #* 0.5*(1 + Q[0]**2) #along x, Q_hat is just 1?

    print "Run Time: ", time.clock()-initial_time, " seconds"
Beispiel #17
0
def mcQueeny_case(interactionfile,
                  spinfile,
                  tau_list,
                  temperature,
                  direction={
                      'kx': 1,
                      'ky': 0,
                      'kz': 0
                  },
                  hkl_interval=[1e-3, 2 * np.pi, 100],
                  omega_interval=[0, 5, 100],
                  eig_eps=0.001):

    initial_time = time.clock()

    #to plot eigenvector components
    #    q1 = []
    #    q2 = []

    #to plot w's
    #w1_list = []
    #w2_list = []
    #w3_list = []
    #w4_list = []
    #w5_list = []
    #w6_list = []
    #w7_list = []
    #w8_list = []
    #    w_output_list = []

    #plot the structure factor to compare with lovesey (In McQueeny Paper)
    #    strfac_sums = []
    #    strfac1 = []
    #    strfac2 = []

    atom_list, jnums, jmats, N_atoms_uc, numCutOff, magCellSize = readFiles(
        interactionfile, spinfile, rtn_cutOffInfo=True)
    #Hardcoding body-center cubic
    if 0:
        atom_list = []
        jnums = [0]
        N_atom_uc = 1
        numCutOff = 7
        magCellSize = np.array([1, 1, 1])
        jmats = [np.array([[-1, 0, 0], [0, -1, 0], [0, 0, -1]])]
        atom_list.append(
            atom(pos=np.array([0.5, 0.5, 0.5]),
                 spin=np.array([0, 0, 1]),
                 interactions=[0, 0, 0, 0, 0, 0],
                 neighbors=[1, 2, 3, 4, 5, 6]))

        atom_list.append(
            atom(pos=np.array([0., 0., 0.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([1., 0., 0.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([1., 1., 0.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([1., 0., 1.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([1., 1., 1.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([0., 1., 0.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([0., 0., 1.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))
        atom_list.append(
            atom(pos=np.array([0., 1., 1.]),
                 spin=np.array([0, 0, -1]),
                 interactions=[0],
                 neighbors=[0]))

    h_list, k_list, l_list = generate_hkl(hkl_interval, direction)
    e = generate_wt(omega_interval)
    ff_list = generate_form_factors(N_atoms_uc, atom_list, hkl_interval)
    s = []
    basis = []
    for a in atom_list:
        s.append(a.spin[2])  #z component of spin (assume aligned with z)
        #basis.append(a.pos)
        basis.append(a.pos - magCellSize)  #translate  back to 0,0,0
        #normalize? NO!
        #basis.append([a.pos[0] - int(a.pos[0]), a.pos[1]-int(a.pos[1]), a.pos[2] - int(a.pos[2])])
    #print "\n\nbasis vectors:\n"

    #mess with basis vectors and spin
    #basis[0] = [0.25,0,0]
    #basis[0] = [1.0,0,0]
    #tmp = s[0]
    #s[0] = s[1]
    #s[1] = tmp
    #for pos in basis:
    #    print pos
    #print "\n\nspins:\n"
    #for spin in s:
    #    print spin

    mesh = np.zeros((len(h_list), len(e)))

    #output q, w, and eigenvectors before and after normalization to compare with McQueeny's
    #    f = open("/home/tom/Desktop/Python_Eigs.txt", 'w')
    #    f.write("q w eigVec_before_norm T\n\n")

    #    f2 = open("/home/tom/Desktop/Values.txt", 'w')
    #    f2.write("Q w wvec (wvec norm) e^(-i*Q.d_i)\n\n")

    #create the T_ni matricies (eigenvector matrices)
    #This algorithm uses a differnt matrix:
    #evecs, mats = calc_eig_mats_numerically(Hsave, h_list,k_list,l_list)
    #eigvals = calc_eigs_numerically(Hsave, h_list, k_list, l_list)#This is innefficient, eigs already calculated and thrown away in calc_eig_mats_..
    #w_list = gen_eigs_with_sign(Hsave, h_list, k_list, l_list, 0.001)
    for Qindex in range(len(h_list)):
        Q = (np.array([h_list, k_list, l_list]).transpose())[Qindex]
        #        f2.write(str(Q))
        #CALL SPINWAVE(q,w,evec) - get w, evec for given q
        M = create_matrix(atom_list, jnums, jmats, numCutOff, magCellSize,
                          Q - np.array(tau_list))
        w, evec = np.linalg.eig(M)
        #        f2.write(" " + str(w))
        #        f2.write(" " + str(evec.flatten()))

        #                evec = evecs[Qindex]
        #                w = w_list[Qindex]

        #  print "\nw = ", w
        #w1_list.append(w[0])
        #w2_list.append(w[1])
        #w3_list.append(w[1])
        #w4_list.append(w[1])
        #w5_list.append(w[1])
        #w6_list.append(w[1])
        #w7_list.append(w[1])
        #w8_list.append(w[1])
        #        w_output_list.append(w)

        ff = ff_list[Qindex]

        #Get number of atoms
        numAtoms = numCutOff
        #numAtoms = np.sqrt(evec.size)#This should be the number of atoms that I need to loop through.
        #if int(numAtoms) != numAtoms:#I beleive t_mat should always be square, but lets check
        #    raise Exception("t_mat not square!")

        #Normalize evec to get T_ni
        #for i in range(0, numAtoms):
        #    normi = 0
        #    for j in range(0, numAtoms):
        #        sigma_j = s[j]/np.abs(s[j])
        #        normi += sigma_j * np.abs(evec[j][i])**2
        #    for j in range(0, numAtoms):
        #        evec[i][j] = evec[j][i]/np.sqrt(np.abs(normi))

        evec2 = evec.copy()
        #I'm going to write this from scratch
        #  print "evec before = ", evec
        T = evec
        sigma = []
        for i in range(numAtoms):
            sigma.append(s[i] / np.abs(s[i]))
        for n in range(numAtoms):
            norm = 0
            for i in range(numAtoms):
                norm += sigma[i] * (np.abs(evec2[n][i])**2)
            for i in range(numAtoms):
                #          print "norm : ", norm
                #          print "w sign: ", np.sign(w[n])
                #T[n][i] = T[n][i]*np.sqrt((w[n]/np.abs(w[n]))/norm + 0j)
                T[n][i] = evec2[n][i] / np.sqrt(np.abs(norm))
        evec = T
        #        f2.write(" " + str(T.flatten()))
        #evec = evec2
        #        q1.append(evec[0][0])
        #        q2.append(evec[0][0])

        #output eigs to file
        #        f.write(str(Q))
        #        f.write(" w:" + str(w))
        #        f.write("\nmat: " + str(M))#the matrix for which the eigs were found
        #        f.write("\nbefore_norm: " + str(evec2.flatten()))
        #        f.write("\nafterNorm: " + str(evec.flatten()) + "\n\n")

        #evec = evec.transpose()
        #test = 0
        #for i in range(numAtoms):
        #    sigma_i = s[j]/np.abs(s[j])
        #    test += sigma_i * np.dot(evec[i],evec[i])
        #    print "sigma_i = ", sigma_i
        #print "\n\nsum{sigma_i * |T_ni|^2} = ", test, "\n\n"

        #                print "evec = " , evec
        #                print "sigma1: ", s[0]/np.abs(s[0])
        #                print "sigma2: ", s[1]/np.abs(s[1])
        #                print "sign lambda_0: ", (s[0]/np.abs(s[0]))*(evec[0][0]**2) + (s[1]/np.abs(s[1]))*(evec[0][1]**2)
        #                print "sign lambda_1: ", (s[0]/np.abs(s[0]))*(evec[1][0]**2) + (s[1]/np.abs(s[1]))*(evec[1][1]**2)

        #using only positive eigenvalue
        #w = [w[0]]
        #evec = [evec[0]]
        #print "eigenvalues used: ", w
        #print "eigenvectors used: ", evec

        strfac = np.zeros(numAtoms)

        #for testing:
        ff = 1

        for i in range(numAtoms):
            dum = 0
            for j in range(numAtoms):
                dum += (s[j] / np.sqrt(np.abs(
                    s[j]))) * ff * evec[j][i]  #* np.exp(1.0j*
                #(-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
                #                print "\n\n\nwritting to f2:\n\n\n", np.exp(1.0j*
                #                        (-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
                #                print "j: ", j
                #                print "basis: ", basis[j]
                #                print "Q.di", (-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2])
                exp = np.exp(1.0j * (-Q[0] * basis[j][0] - Q[1] * basis[j][1] -
                                     Q[2] * basis[j][2]))
#                f2.write(" " + str(exp))
            strfac[i] = np.abs(dum)**2
    #     print "Q: ", Q, "    strfac[",i,"]: ", strfac[i]


#            f2.write("\n\n")
#        strfac_sums.append(0.0);
#        strfac1.append(strfac[0])
#        strfac2.append(strfac[1])
        sqw = np.zeros(len(e))
        for j in range(numAtoms):
            #            strfac_sums[Qindex] +=strfac[j]
            for i in range(len(e)):
                y = LIFETIME_VALUE / 2
                lorentzian = (1 / np.pi) * y / ((e[i] - w[j])**2 + y**2)
                #test
                #strfac[j] = ff*1
                sqw[i] = sqw[i] + strfac[
                    j] * lorentzian  #he has some 'bose' factor in here
                #more test
                #sqw[i] = sqw[i] + strfac[j]
        mesh[Qindex] = sqw  #* 0.5*(1 + Q[0]**2) #along x, Q_hat is just 1?

    #f.close()
    #f = open("/home/tom/Desktop/output.txt", 'w')
    #for q in range(0,len(h_list)):
    #for w in range(0,len(e)):
    #f.write(str(h_list[q]))
    #f.write(" ")
    #f.write(str(e[w]))
    #f.write(" ")
    #f.write(str(mesh[q][w]))
    #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/output2.txt", 'w')
    #for q in range(0,len(h_list)):
    #f.write(str(h_list[q]))
    #f.write(" ")
    #f.write(str(np.abs(q1[q])))
    #f.write(" ")
    #f.write(str(np.abs(q2[q])))
    #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/output3.txt", 'w')
    #for q in range(0,len(h_list)):
    #f.write(str(h_list[q]))
    #f.write(" ")
    #f.write(str(np.real(w1_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w2_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w3_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w4_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w5_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w6_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w7_list[q])))
    #f.write(" ")
    #f.write(str(np.real(w8_list[q])))
    #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/strfacs.txt", 'w')
    #for q in range(0,len(h_list)):
    #f.write(str(h_list[q]))
    #f.write(" ")
    #f.write(str(k_list[q]))
    #f.write(" ")
    #f.write(str(l_list[q]))
    #f.write(" ")
    #f.write(str(strfac1[q]))
    #f.write(" ")
    #f.write(str(strfac2[q]))
    #f.write(" ")
    #f.write(str(strfac_sums[q]))
    #f.write("\n")
    #f.close()
    #plt.plot(w1_list)
    #plt.plot(w2_list)
    #plt.show()
    print "Run Time: ", time.clock() - initial_time, " seconds"
Beispiel #18
0
def mcQueeny_case(interactionfile, spinfile, tau_list, temperature, 
                      direction={'kx':1,'ky':0,'kz':0}, hkl_interval=[1e-3,2*np.pi,100], 
                      omega_interval=[0,5,100], eig_eps = 0.001):
    
    initial_time = time.clock()
    
    #to plot eigenvector components
#    q1 = []
#    q2 = []
    
    #to plot w's
    #w1_list = []
    #w2_list = []
    #w3_list = []
    #w4_list = []
    #w5_list = []
    #w6_list = []
    #w7_list = []
    #w8_list = []
#    w_output_list = []
    
    #plot the structure factor to compare with lovesey (In McQueeny Paper)
#    strfac_sums = []
#    strfac1 = []
#    strfac2 = []
    
    atom_list, jnums, jmats, N_atoms_uc, numCutOff, magCellSize = readFiles(interactionfile,spinfile, rtn_cutOffInfo = True)
    #Hardcoding body-center cubic
    if 0:
        atom_list = []
        jnums = [0]
        N_atom_uc = 1
        numCutOff = 7
        magCellSize = np.array([1,1,1])
        jmats = [np.array([[-1,0,0],[0,-1,0],[0,0,-1]])]
        atom_list.append(atom(pos = np.array([0.5,0.5,0.5]),
                              spin = np.array([0,0,1]),
                              interactions = [0,0,0,0,0,0],
                              neighbors = [1,2,3,4,5,6]))
        
        atom_list.append(atom(pos = np.array([0.,0.,0.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([1.,0.,0.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([1.,1.,0.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([1.,0.,1.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([1.,1.,1.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([0.,1.,0.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([0.,0.,1.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))
        atom_list.append(atom(pos = np.array([0.,1.,1.]),
                              spin = np.array([0,0,-1]),
                              interactions = [0],
                              neighbors = [0]))

    h_list, k_list, l_list = generate_hkl(hkl_interval, direction)
    e = generate_wt(omega_interval)
    ff_list = generate_form_factors(N_atoms_uc, atom_list, hkl_interval)
    s = []
    basis = []
    for a in atom_list:
        s.append(a.spin[2])#z component of spin (assume aligned with z)                
        #basis.append(a.pos)
        basis.append(a.pos - magCellSize) #translate  back to 0,0,0
        #normalize? NO!
        #basis.append([a.pos[0] - int(a.pos[0]), a.pos[1]-int(a.pos[1]), a.pos[2] - int(a.pos[2])])
    #print "\n\nbasis vectors:\n"
    
    #mess with basis vectors and spin
    #basis[0] = [0.25,0,0]
    #basis[0] = [1.0,0,0]
    #tmp = s[0]
    #s[0] = s[1]
    #s[1] = tmp
    #for pos in basis:
    #    print pos
    #print "\n\nspins:\n"
    #for spin in s:
    #    print spin
        
    
    mesh = np.zeros((len(h_list), len(e)))

    #output q, w, and eigenvectors before and after normalization to compare with McQueeny's
#    f = open("/home/tom/Desktop/Python_Eigs.txt", 'w')
#    f.write("q w eigVec_before_norm T\n\n")
    
#    f2 = open("/home/tom/Desktop/Values.txt", 'w')
#    f2.write("Q w wvec (wvec norm) e^(-i*Q.d_i)\n\n")
    
    
    #create the T_ni matricies (eigenvector matrices)
    #This algorithm uses a differnt matrix:
    #evecs, mats = calc_eig_mats_numerically(Hsave, h_list,k_list,l_list)
    #eigvals = calc_eigs_numerically(Hsave, h_list, k_list, l_list)#This is innefficient, eigs already calculated and thrown away in calc_eig_mats_..
    #w_list = gen_eigs_with_sign(Hsave, h_list, k_list, l_list, 0.001)
    for Qindex in range(len(h_list)):
        Q = (np.array([h_list,k_list,l_list]).transpose())[Qindex]
#        f2.write(str(Q))
        #CALL SPINWAVE(q,w,evec) - get w, evec for given q
        M = create_matrix(atom_list, jnums, jmats, numCutOff, magCellSize, Q-np.array(tau_list))
        w, evec = np.linalg.eig(M)
#        f2.write(" " + str(w))
#        f2.write(" " + str(evec.flatten()))
        
        #                evec = evecs[Qindex]
        #                w = w_list[Qindex]
        
        
        
        
      #  print "\nw = ", w
        #w1_list.append(w[0])
        #w2_list.append(w[1])
        #w3_list.append(w[1])
        #w4_list.append(w[1])
        #w5_list.append(w[1])
        #w6_list.append(w[1])
        #w7_list.append(w[1])
        #w8_list.append(w[1])
#        w_output_list.append(w)
        
        
        ff = ff_list[Qindex]
        
        #Get number of atoms
        numAtoms = numCutOff
        #numAtoms = np.sqrt(evec.size)#This should be the number of atoms that I need to loop through.
        #if int(numAtoms) != numAtoms:#I beleive t_mat should always be square, but lets check
        #    raise Exception("t_mat not square!")
        
        #Normalize evec to get T_ni
        #for i in range(0, numAtoms):
        #    normi = 0
        #    for j in range(0, numAtoms):
        #        sigma_j = s[j]/np.abs(s[j])
        #        normi += sigma_j * np.abs(evec[j][i])**2
        #    for j in range(0, numAtoms):
        #        evec[i][j] = evec[j][i]/np.sqrt(np.abs(normi))
        
        evec2 = evec.copy()
        #I'm going to write this from scratch
      #  print "evec before = ", evec
        T = evec
        sigma = []
        for i in range(numAtoms):
            sigma.append(s[i]/np.abs(s[i]))
        for n in range(numAtoms):
            norm = 0
            for i in range(numAtoms):
                norm += sigma[i]*(np.abs(evec2[n][i])**2)
            for i in range(numAtoms):
      #          print "norm : ", norm
      #          print "w sign: ", np.sign(w[n])
                #T[n][i] = T[n][i]*np.sqrt((w[n]/np.abs(w[n]))/norm + 0j)
                T[n][i] = evec2[n][i]/np.sqrt(np.abs(norm))
        evec = T
#        f2.write(" " + str(T.flatten()))
        #evec = evec2
#        q1.append(evec[0][0])
#        q2.append(evec[0][0])
        
        #output eigs to file
#        f.write(str(Q))
#        f.write(" w:" + str(w))
#        f.write("\nmat: " + str(M))#the matrix for which the eigs were found
#        f.write("\nbefore_norm: " + str(evec2.flatten()))
#        f.write("\nafterNorm: " + str(evec.flatten()) + "\n\n")
        
        #evec = evec.transpose()
        #test = 0
        #for i in range(numAtoms):
        #    sigma_i = s[j]/np.abs(s[j])
        #    test += sigma_i * np.dot(evec[i],evec[i])
        #    print "sigma_i = ", sigma_i
        #print "\n\nsum{sigma_i * |T_ni|^2} = ", test, "\n\n"
        
        #                print "evec = " , evec
        #                print "sigma1: ", s[0]/np.abs(s[0])
        #                print "sigma2: ", s[1]/np.abs(s[1])
        #                print "sign lambda_0: ", (s[0]/np.abs(s[0]))*(evec[0][0]**2) + (s[1]/np.abs(s[1]))*(evec[0][1]**2)
        #                print "sign lambda_1: ", (s[0]/np.abs(s[0]))*(evec[1][0]**2) + (s[1]/np.abs(s[1]))*(evec[1][1]**2)
                        
        
        #using only positive eigenvalue
        #w = [w[0]]
        #evec = [evec[0]]
        #print "eigenvalues used: ", w
        #print "eigenvectors used: ", evec    
    
    
          
        strfac = np.zeros(numAtoms)
        
        #for testing:
        ff = 1
        
        for i in range(numAtoms):
            dum = 0
            for j in range(numAtoms):
                dum += (s[j]/np.sqrt(np.abs(s[j]))) * ff * evec[j][i] #* np.exp(1.0j*
                        #(-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
#                print "\n\n\nwritting to f2:\n\n\n", np.exp(1.0j*
#                        (-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
#                print "j: ", j
#                print "basis: ", basis[j]
#                print "Q.di", (-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2])
                exp = np.exp(1.0j*(-Q[0]*basis[j][0] -Q[1]*basis[j][1] -Q[2]*basis[j][2]))
#                f2.write(" " + str(exp))
            strfac[i] = np.abs(dum)**2
       #     print "Q: ", Q, "    strfac[",i,"]: ", strfac[i]
#            f2.write("\n\n")
#        strfac_sums.append(0.0);
#        strfac1.append(strfac[0])
#        strfac2.append(strfac[1])
        sqw = np.zeros(len(e))
        for j in range(numAtoms):
#            strfac_sums[Qindex] +=strfac[j]
            for i in range(len(e)):
                y = LIFETIME_VALUE/2
                lorentzian = (1/np.pi)*y/((e[i]- w[j])**2+y**2)
                #test
                #strfac[j] = ff*1
                sqw[i] = sqw[i] + strfac[j] * lorentzian #he has some 'bose' factor in here      
                #more test
                #sqw[i] = sqw[i] + strfac[j]
        mesh[Qindex] = sqw #* 0.5*(1 + Q[0]**2) #along x, Q_hat is just 1?

    #f.close()
    #f = open("/home/tom/Desktop/output.txt", 'w')
    #for q in range(0,len(h_list)):
        #for w in range(0,len(e)):
            #f.write(str(h_list[q]))
            #f.write(" ")
            #f.write(str(e[w]))
            #f.write(" ")
            #f.write(str(mesh[q][w]))
            #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/output2.txt", 'w')
    #for q in range(0,len(h_list)):
            #f.write(str(h_list[q]))
            #f.write(" ")
            #f.write(str(np.abs(q1[q])))
            #f.write(" ")
            #f.write(str(np.abs(q2[q])))
            #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/output3.txt", 'w')
    #for q in range(0,len(h_list)):
            #f.write(str(h_list[q]))
            #f.write(" ")
            #f.write(str(np.real(w1_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w2_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w3_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w4_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w5_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w6_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w7_list[q])))
            #f.write(" ")
            #f.write(str(np.real(w8_list[q])))
            #f.write("\n")
    #f.close()
    #f = open("/home/tom/Desktop/strfacs.txt", 'w')
    #for q in range(0,len(h_list)):
            #f.write(str(h_list[q]))
            #f.write(" ")
            #f.write(str(k_list[q]))
            #f.write(" ")
            #f.write(str(l_list[q]))
            #f.write(" ")
            #f.write(str(strfac1[q]))
            #f.write(" ")
            #f.write(str(strfac2[q]))
            #f.write(" ")
            #f.write(str(strfac_sums[q]))
            #f.write("\n")
    #f.close()
    #plt.plot(w1_list)
    #plt.plot(w2_list)
    #plt.show()
    print "Run Time: ", time.clock()-initial_time, " seconds"
def generate_cross_section(interactionfile, spinfile, lattice, arg, 
                       tau_list, h_list, k_list, l_list, w_list):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)

    # Get Hsave to calculate its eigenvalues
    N_atoms = len(atom_list)
    Hsave,poly,heigs = calculate_dispersion(atom_list,N_atoms_uc,N_atoms,jmats,showEigs=True)
    atom_list=atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    N = N_atoms
    
    print "Calculated: Dispersion Relation"

    # Generate kappas from (h,k,l)
    kaprange=lattice.modvec(h_list,k_list,l_list, 'latticestar')
    nkpts=len(kaprange)
    kapvect=np.empty((nkpts,3),'Float64')
    kapvect[:,0]=h_list
    kapvect[:,1]=k_list
    kapvect[:,2]=l_list

    # Grabs the unit vectors from the back of the lists. 
    kapunit = kapvect.copy()
    kapunit[:,0]=kapvect[:,0]/kaprange
    kapunit[:,1]=kapvect[:,1]/kaprange
    kapunit[:,2]=kapvect[:,2]/kaprange

    unit_vect = []
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
    #print unit_vect
    unit_vect = sum(unit_vect)

    # Generate qs from kappas and taus
    qlist=[]
    ones_list=np.ones((1,nkpts),'Float64')
    
    for tau in tau_list:
        taui=np.ones((nkpts,3),'Float64')
        taui[:,0]=ones_list*tau[0]
        taui[:,1]=ones_list*tau[1]
        taui[:,2]=ones_list*tau[2]
        kappa_minus_tau=kapvect-taui
        tau_minus_kappa=taui - kapvect
               
        qlist.append(np.vstack([kappa_minus_tau,tau_minus_kappa]))

    # Eigenvalues and omegas
    wtlist=w_list
    eig_list=[]

    eigs = Hsave.eigenvals().keys()
    for q in qlist:
        eig_list.append(eigs)
    eig_list = np.array(eig_list)
    print "Calculated: Eigenvalues"

    # Form Factor
    ff_list = []
    for i in range(N_atoms_uc):
        el = elements[atom_list[i].atomicNum]
        val = atom_list[i].valence
        if val != None:
            Mq = el.magnetic_ff[val].M_Q(kaprange)
        else:
            Mq = el.magnetic_ff[0].M_Q(kaprange)
        ff_list = Mq #ff_list.append(Mq)
    print "Calculated: Form Factors"
    
    # Generate most general form of csection
    csection=0
    for i in range(len(arg)):
        for j in range(len(arg[i])):
            csection = (csection + arg[i][j]*unit_vect)
                
    for i in range(N):
        ni = sp.Symbol('n%i'%(i,), real = True)
        np1i = sp.Symbol('np1%i'%(i,), Real = True)
        csection.subs(ni+1,np1i)

    csection = csection.expand()

    csection = csection.subs(KAPXHAT_SYM*KAPYHAT_SYM,0)
    csection = csection.subs(KAPXHAT_SYM*KAPZHAT_SYM,0)
    csection = csection.subs(KAPYHAT_SYM*KAPZHAT_SYM,0)
    csection = csection.subs(KAPZHAT_SYM*KAPYHAT_SYM,0)
    csection = csection.subs(KAPZHAT_SYM*KAPXHAT_SYM,0)
    csection = csection.subs(KAPYHAT_SYM*KAPXHAT_SYM,0)
        
    csection = (csection * exp(-I * W_SYM * T_SYM) * exp(I * KAP_SYM * L_SYM)).expand(deep=False)
    csection = sp.powsimp(csection, deep=True)
    print 'beginning'
#    print csection
    csection = sp.powsimp(csection)
    csection = sub_in(csection,exp(I*T_SYM*A_WILD + I*T_SYM*B_WILD + I*C_WILD + I*D_WILD + I*K_WILD),sp.DiracDelta(A_WILD*T_SYM + B_WILD*T_SYM + C_WILD + D_WILD + K_WILD))
    print 'intermediate'
#    print csection
#    csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),(1./hbar)*sp.DiracDelta(A + B)*sp.simplify(sp.DiracDelta(C + D  - tau)))  #This is correct
    csection = sub_in(csection,sp.DiracDelta(A_WILD*T_SYM + B_WILD*T_SYM + C_WILD*L_SYM + D_WILD*L_SYM ),sp.Pow(pi,-1)*(LIFETIME_VALUE*0.5)*sp.Pow((A_WILD+B_WILD)**2+(LIFETIME_VALUE*0.5)**2,-1)*sp.simplify(sp.DiracDelta(C_WILD + D_WILD  - TAU_SYM)))
    print 'ending'
#    print csection
    
    # Do some associative clean up to make it easier for later substitutions
    csection = sub_in(csection,sp.DiracDelta(-A_WILD - B_WILD),sp.DiracDelta(A_WILD + B_WILD))
    csection = sub_in(csection,(-A_WILD - B_WILD)**2,(A_WILD + B_WILD)**2)
    csection = csection.subs(sp.DiracDelta(Q_SYM + TAU_SYM - KAP_SYM),sp.DiracDelta(KAP_SYM - Q_SYM - TAU_SYM))
    csection = csection.subs(sp.DiracDelta(TAU_SYM - KAP_SYM - Q_SYM),sp.DiracDelta(KAP_SYM + Q_SYM - TAU_SYM))

    csection = csection.subs(sp.DiracDelta(KAP_SYM - Q_SYM - TAU_SYM),DD_KTMQ_SYM)
    csection = csection.subs(sp.DiracDelta(KAP_SYM + Q_SYM - TAU_SYM),DD_KTPQ_SYM)
    print "Applied: Delta Function Conversion"
    
    print csection
    
    print "Generated: Analytic Cross-Section Expression"
    return (N_atoms_uc, csection, kaprange, tau_list, eig_list, kapvect, wtlist, ff_list)
Beispiel #20
0
def generate_cross_section(interactionfile, spinfile, lattice, arg, 
                       tau_list, h_list, k_list, l_list, w_list):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)
    
    # Get Hsave to calculate its eigenvalues
    N_atoms = len(atom_list)
    Hsave,poly,heigs = calculate_dispersion(atom_list,N_atoms_uc,N_atoms,jmats,showEigs=True)
    atom_list=atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    N = N_atoms
    print "Calculated: Dispersion Relation"

    kaprange=lattice.modvec(h_list,k_list,l_list, 'latticestar')
    nkpts=len(kaprange)
    kapvect=np.empty((nkpts,3),'Float64')
    kapvect[:,0]=h_list
    kapvect[:,1]=k_list
    kapvect[:,2]=l_list

    kapunit = kapvect.copy()
    kapunit[:,0]=kapvect[:,0]/kaprange
    kapunit[:,1]=kapvect[:,1]/kaprange
    kapunit[:,2]=kapvect[:,2]/kaprange

    plusq=[]
    minusq=[]
    qlist=[]
    ones_list=np.ones((1,nkpts),'Float64')
    wtlist=w_list
    qtlist=[]
    
    for tau in tau_list:
        taui=np.ones((nkpts,3),'Float64')
        taui[:,0]=ones_list*tau[0]
        taui[:,1]=ones_list*tau[1]
        taui[:,2]=ones_list*tau[2]
        kappa_minus_tau=kapvect-taui
        tau_minus_kappa=taui - kapvect
               
        qlist.append(np.vstack([kappa_minus_tau,tau_minus_kappa]))

    eig_list=[]
    eigs = Hsave.eigenvals().keys()
    for q in qlist:
        eig_list.append(eigs)
    eig_list = np.array(eig_list)
    print "Calculated: Eigenvalues"

    # Other Constants
    kap = sp.Symbol('kappa', real = True)
    t = sp.Symbol('t', real = True)
    w = sp.Symbol('w', real = True)
    W = sp.Symbol('W', real = True)
    tau = sp.Symbol('tau', real = True)
    Q = sp.Symbol('q', real = True)
    L = sp.Symbol('L', real = True)
    lifetime=0.5

    # Form Factor
    ff_list = []
    for i in range(N_atoms_uc):
        el = elements[atom_list[i].atomicNum]
        val = atom_list[i].valence
        if val != None:
            Mq = el.magnetic_ff[val].M_Q(kaprange)
        else:
            Mq = el.magnetic_ff[0].M_Q(kaprange)
        ff_list = Mq #ff_list.append(Mq)
    print "Calculated: Form Factors"
  
    # Wilds for sub_in method
    A = sp.Wild('A',exclude = [0,t])
    B = sp.Wild('B',exclude = [0,t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    
    # Grabs the unit vectors from the back of the lists. 
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat',real=True)
    kapyhat = sp.Symbol('kapyhat',real=True)
    kapzhat = sp.Symbol('kapzhat',real=True)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
    unit_vect = sum(unit_vect)
    
    csection=0
    for i in range(len(arg)):
        for j in range(len(arg[i])):
            csection = (csection + arg[i][j]*unit_vect)
                
    for i in range(N):
        ni = sp.Symbol('n%i'%(i,), real = True)
        np1i = sp.Symbol('np1%i'%(i,), Real = True)
        csection.subs(ni+1,np1i)

    csection = csection.expand()
        
    csection = csection.subs(kapxhat*kapyhat,0)
    csection = csection.subs(kapxhat*kapzhat,0)
    csection = csection.subs(kapyhat*kapzhat,0)
    csection = csection.subs(kapzhat*kapyhat,0)
    csection = csection.subs(kapzhat*kapxhat,0)
    csection = csection.subs(kapyhat*kapxhat,0)
        
    csection = (csection * exp(-I*w*t) * exp(I*kap*L)).expand(deep=False)
    csection = sp.powsimp(csection, deep=True)
    print 'beginning delta conversion'
    print csection
    csection = sp.powsimp(csection)
    csection = sub_in(csection,exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))
    print 'intermediate'
    print csection
#    csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),(1./hbar)*sp.DiracDelta(A + B)*sp.simplify(sp.DiracDelta(C + D  - tau)))  #This is correct
    csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),sp.Pow(pi,-1)*(lifetime*0.5)*sp.Pow((A+B)**2+(lifetime*0.5)**2,-1)*sp.simplify(sp.DiracDelta(C + D  - tau)))
    print 'ending  delta conversion'
    print csection
    

    csection = sub_in(csection,sp.DiracDelta(-A - B),sp.DiracDelta(A + B))
    csection = sub_in(csection,(-A - B)**2,(A + B)**2)
    csection = csection.subs(sp.DiracDelta(Q+tau-kap),sp.DiracDelta(kap-Q-tau))
    csection = csection.subs(sp.DiracDelta(tau-kap-Q),sp.DiracDelta(kap+Q-tau))
    print "Applied: Delta Function Conversion"

    print "end part 1"
    #print csection
    return (N_atoms_uc, csection, kaprange, tau_list, eig_list, kapvect, wtlist, ff_list)
Beispiel #21
0
if 0:
    a = [1, 2, 3, 4, 5, 6, 7]
    b = [1, 2, 5]
    comms = [a[i] in b for i in range(len(a))]
    print comms
    x = sp.Symbol('x')
    y = x**2
    print type(y)
    print y.is_commutative
    print y.atoms()

if 0:
    interfile = 'c:/test_montecarlo.txt'
    spinfile = 'c:/test_Spins.txt'
    atom_list, jnums, jmats, N_atoms_uc = rf.readFiles(interfile, spinfile)
    N_atoms = len(atom_list)
    jij_values = []
    jij_columns = []
    jij_rowIndex = []

    # Scan through atom_list
    num_inters = 0
    for i in range(N_atoms):
        ints_list = atom_list[i].interactions
        nbrs_list = atom_list[i].neighbors
        print 'ints', ints_list
        print 'nbrs', nbrs_list
        nbrs_ints = [(nbrs_list[x], ints_list[x])
                     for x in range(len(nbrs_list))]
        nbrs_ints.sort()
Beispiel #22
0
def run_cross_section(interactionfile, spinfile):
    start = clock()

    # Generate Inputs
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)
    atom1 = atom(pos = [0.00,0,0], neighbors = [1],   interactions = [0], int_cell = [0], 
                 atomicNum = 26, valence = 3)
    atom2 = atom(pos = [0.25,0,0], neighbors = [0,2], interactions = [0], int_cell = [0], 
                 atomicNum = 26, valence = 3)
    atom3 = atom(pos = [0.50,0,0], neighbors = [1,3], interactions = [0], int_cell = [0], 
                 atomicNum = 26, valence = 3)
    atom4 = atom(pos = [0.75,0,0], neighbors = [2],   interactions = [0], int_cell = [0], 
                 atomicNum = 26, valence = 3)
#    atom_list,N_atoms_uc = ([atom1, atom2, atom3, atom4],1)
    
    atom_list=atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    
    print N_atoms
    if 1:
        kx = sp.Symbol('kx', real = True)
        ky = sp.Symbol('ky', real = True)
        kz = sp.Symbol('kz', real = True)
        k = spm.Matrix([kx,ky,kz])
    
    (b,bd) = generate_b_bd_operators(atom_list)
#    list_print(b)
    (a,ad) = generate_a_ad_operators(atom_list, k, b, bd)
#    list_print(a)
    (Sp,Sm) = generate_Sp_Sm_operators(atom_list, a, ad)
#    list_print(Sp)
    (Sa,Sb,Sn) = generate_Sa_Sb_Sn_operators(atom_list, Sp, Sm)
#    list_print(Sa)
    (Sx,Sy,Sz) = generate_Sx_Sy_Sz_operators(atom_list, Sa, Sb, Sn)
#    list_print(Sx)
    print ''
    
    #Ham = generate_Hamiltonian(N_atoms, atom_list, b, bd)
    ops = generate_possible_combinations(atom_list, [Sx,Sy,Sz])
#    list_print(ops)
    ops = holstein(atom_list, ops)
#    list_print(ops)
    ops = apply_commutation(atom_list, ops)
#    list_print(ops)
    ops = replace_bdb(atom_list, ops)
#    list_print(ops)

    ops = reduce_options(atom_list, ops)
    list_print(ops)

    # Old Method
    #cross_sect = generate_cross_section(atom_list, ops, 1, real, recip)
    #print '\n', cross_sect
    
    if 1:
        aa = bb = cc = np.array([2.0*np.pi], 'Float64')
        alpha = beta = gamma = np.array([np.pi/2.0], 'Float64')
        vect1 = np.array([[1,0,0]])
        vect2 = np.array([[0,0,1]])
        lattice = Lattice(aa, bb, cc, alpha, beta, gamma, Orientation(vect1, vect2))
        data={}
        data['kx']=1.
        data['ky']=0.
        data['kz']=0.
        direction=data

        temperature = 1.0
        kmin = 0
        kmax = 2*sp.pi
        steps = 25

        tau_list = []
        for i in range(1):
            tau_list.append(np.array([0,0,0], 'Float64'))

        h_list = np.linspace(0.1,12.0,200)
        k_list = np.zeros(h_list.shape)
        l_list = np.zeros(h_list.shape)
        w_list = np.linspace(0.1,10.0,200)

        efixed = 14.7 #meV
        eief = True
        N_atoms_uc,csection,kaprange,qlist,tau_list,eig_list,kapvect,wtlist = generate_cross_section(interactionfile, spinfile, lattice, ops, 
                                                                                                     tau_list, h_list, k_list, l_list, w_list,
                                                                                                     temperature, steps, eief, efixed)
        print csection

        return N_atoms_uc,csection,kaprange,qlist,tau_list,eig_list,kapvect,wtlist
    end = clock()
    print "\nFinished %i atoms in %.2f seconds" %(N_atoms,end-start)
Beispiel #23
0
def csection(interactionfile, spinfile, tau_list, temp = 0.0001, HWHM = 1/np.pi,
            direction={'kx':1,'ky':0,'kz':0}, hkl_interval=[1e-3,2*np.pi,100],
            omega_interval=[0,5,100], kb = 0.086173423):
    """
    kb is the boltzman constant in whatever units the user is using.  The
    default is 0.086173423 meV/K.
    
    HWHM is the half width at half maximum of the lorentzian broadening
    function (the resolution of the energy)."""

    initial_time = time.clock()
    

    atom_list, jnums, jmats, N_atoms_uc, numCutOff, magCellSize = readFiles(interactionfile,spinfile, rtn_cutOffInfo = True)
    #Atoms in the first interaction cell come first in the list (atom_list),so
    #I can iterate through the first numCutOff atoms in the list top iterate
    #only through the atoms in the first interaction cell - I beleive 1/4/12
    
    #Right now (1/12/12) a major issue is that this method requires the size
    #of the magnetic cell and the cutOffCell size is not necesssarilly the
    #same as the magenetic cell size.  In fact, even in the very simple
    #ferromagnetic chain it is not. - Same issue with numCutOff - should be
    #numMagCell
    
    #Simple Ferro Case
    #magCellSize = np.array([1,1,1])
    #numCutOff =1
    
    
    #testing
    #numCutOff = 2
    #magCellSize = np.array([1,1,1])
    
    #generate all the parameters I will need
    h_list, k_list, l_list = generate_hkl(hkl_interval, direction)
    #test
    #h_list = 2*np.pi*h_list
    #k_list = 2*np.pi*k_list
    #l_list = 2*np.pi*l_list
    
    e_vals = generate_wt(omega_interval)
    
    mesh = np.zeros((len(h_list),len(e_vals)), dtype = complex)
    
    #mu_hat is a unit vector pointing in the direction of positive spin, which
    #I defined to be the direction of the spin of the atom whcih comes first in
    #the list.  I haven't though about whether the sign will make a difference
    #in the final result, but it does not really matter as the choice of
    #positive direction will always be arbitrary.
    spin = np.array(atom_list[0].spin)
    mu_hat = spin/np.sqrt(np.dot(spin,spin))
    
    ff_list = generate_form_factors(N_atoms_uc, atom_list, hkl_interval)
    s = []
    sigmas = []
    basis = []
    for a in atom_list:
        s.append(np.abs(np.dot(a.spin, mu_hat)))
        sigmas.append(np.dot(a.spin,mu_hat)/s[-1])
        #translate back to 0,0,0, but leave in crystallographic cell dimensions
        basis.append(a.pos - magCellSize)
        #I'm leaving it in crystallographic cell dimensions rather than magnetic
        #cell dimensions so that the periodicity of the dispersion relation
        #matches what we already calculate with the William's code, rather than
        #McQueeny's
        
    w_list = []
    Q_points = (np.array([h_list,k_list,l_list]).transpose())
    
    S_q = [] #For testing - S at the w points where S is maximized

    #calculate the cross section for each Q point (h,k,l)
    for Qindex in range(len(h_list)):
        Q = np.array(Q_points[Qindex])

        #create the matrix and find the eigenvalues and eigenvectors
        M = create_matrix(atom_list, jnums, jmats, numCutOff, magCellSize, Q-np.array(tau_list), mu_hat)
        w, evec = np.linalg.eig(M)
        
        w_list.append(w)#testing

        ff = ff_list[Qindex]

        #Get number of atoms
        numAtoms = numCutOff

        T = np.empty((numAtoms, numAtoms), dtype = complex)#normalized eigenvectors

        #Normalize evec to get T_ni
        for n in range(0, numAtoms):
            sgn_ln = w[n]/abs(w[n])
            tmp = 0.0
            for i in range(0, numAtoms):
                tmp += sigmas[i] * abs(evec[i][n])**2
            C = sgn_ln/tmp
            for i in range(0, numAtoms):
                T[i][n] = evec[i][n]*cmath.sqrt(C)
        #The indices of T actually go T[i][n], where n corresponds to the
        #eigenvalue, w[n], and i corresponds to the ith atom on the cell
        
        #1/12/12 The Matrix and T are tested for the simple antiferro case and
        #found to be correct
        
        #Now calculate the S(Q,w) / structure factor
        
        #mu_hat is a unit vector pointing in the direction of the spins
        #All the pins are aligned up to their sign, which does not matter here.
        #This method will work whether the spins are aligned along the z axis
        #or not.
        pol_factor = 0.5*(1.0 + (np.dot(mu_hat,Q)**2)/np.dot(Q,Q))
        
        gamma = ff #I need to make sure this is the same as his formfactor
        gamma = 1.0#testing
        
        #strfac = 0.0
        #For this one Q point, we get a whole S vs. e array
        tmp_e_dimension_array = np.zeros((len(e_vals)), dtype = complex)
        
        S_q.append(0.0)
        
        for n in range(numAtoms):
            strfac = 0.0
            for i in range(numAtoms):
                d_i = np.array(basis[i], dtype = np.float64)/np.array(magCellSize, dtype = np.float64)
                strfac += gamma*sigmas[i]*np.sqrt(s[i])*T[i][n]*np.exp(-1j*np.dot(Q,d_i))
            strfac = np.abs(strfac)**2
            #test:
            S_q[-1] += strfac
            #The 'Bose Occupation Factor,' as McQueeny calls it, which, I
            #believe is the Bose-Einstein distribution for identical bosons
            n_qn = 1.0/(np.exp(w[n]/(temp*kb)) - 1.0)
            
            #replace the delta function with a lorentzian
            for e_index in range(len(e_vals)):
                #delta(w - w_n(q))
                lorentzian1 = (1.0/np.pi)*HWHM/((e_vals[e_index] - w[n])**2 + HWHM**2)
                tmp_e_dimension_array += strfac*(n_qn+1.0)*lorentzian1
                #McQueeny left the other delta function out of his code, so for
                #now, I did too.
                
        #A test shows that numpy actually copies the values (not references)        
        mesh[Qindex] = pol_factor * tmp_e_dimension_array
                 
                 
    #Right now, mesh is only S(Q,w), not the full cross section, which is:
    #r_0^2 * k'/k * S(Q,w)
    r_0 = 1.0
    kp = 1.0
    k = 1.0             

    #print "Run Time: ", time.clock()-initial_time, " seconds"
    
    #testing
    w_list = np.array(w_list)
    for i in range(len(w_list)):
        print Q_points[i], "\t", S_q[i]
    plt.plot(np.linspace(hkl_interval[0],hkl_interval[1], hkl_interval[2])[2:-2], S_q[2:-2])
    plt.show()

    return (r_0**2) * (kp/k) * mesh
Beispiel #24
0
def eval_cross_section(interactionfile, spinfile, lattice, arg, 
                       tau_list, h_list, k_list, l_list, w_vect_list, 
                       direction, temperature, kmin, kmax, steps, eief, efixed = 14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    direction   - direction of scan
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if the energy scheme is Ei - Ef, False if it is Ef - Ei
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats,N_atoms_uc=readFiles(interactionfile,spinfile)
    N_atoms = len(atom_list)
    N = N_atoms

    # TEMPORARY TO OVERRIDE ATOM_LIST ABOVE
#    atom1 = atom(pos = [0.00,0,0], neighbors = [1],   interactions = [0], int_cell = [0], 
#                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
#    atom2 = atom(pos = [0.25,0,0], neighbors = [0,2], interactions = [0], int_cell = [0], 
#                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
#    atom3 = atom(pos = [0.50,0,0], neighbors = [1,3], interactions = [0], int_cell = [0], 
#                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
#    atom4 = atom(pos = [0.75,0,0], neighbors = [2],   interactions = [0], int_cell = [0], 
#                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
#    atom_list,N_atoms_uc = ([atom1, atom2, atom3, atom4],1)
    N_atoms = len(atom_list)

    # Get Hsave to calculate its eigenvalues
    (Hsave, charpoly, eigs) = calculate_dispersion(atom_list,N_atoms_uc,N_atoms,jmats,showEigs=True)
    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    if len(h_list) == len(k_list) == len(l_list):
        for i in range(len(h_list)):
            kappa = lattice.modvec(h_list[i],k_list[i],l_list[i], 'latticestar')
            kaprange.append(kappa[0])
            kapvect.append(np.array([h_list[i],k_list[i],l_list[i]]))
#            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    else:
        raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    pqrange = []
    mqrange = []
    for tau in tau_list:
        ptemp = []
        mtemp = []
        for kap in kapvect:
            #tau = lattice.modvec(tau[0],tau[1],tau[2], 'latticestar')
            ptemp.append(kap - tau)
            mtemp.append(tau - kap)
        pqrange.append(ptemp)
        mqrange.append(mtemp)
    # Calculate w_q's using q
    qrange = []
#    krange = []
    wrange = []
    if 1: # Change this later
        for set in pqrange:
            temp = []
            temp1 = [] 
            for q in set:
                eigs = calc_eigs(Hsave,q[0]*direction['kx'], q[1]*direction['ky'], q[2]*direction['kz'])
                # Take only one set of eigs. Should probably have a flag here. 
                temp.append(eigs[0])
#                krange.append(np.array([q*direction['kx'], q*direction['ky'], q*direction['kz']]))
                temp1.append(q)
            wrange.append(temp)
            qrange.append(temp1)
    print "Calculated: Eigenvalues"
    
    wrange=np.array(np.real(wrange))
    qrange=np.array(np.real(qrange))
    kaprange=np.array(np.real(kaprange))
    
    print qrange.shape
    print wrange.shape
    print kaprange.shape
    
    # Calculate w (not _q) as well as kp/k
    w_calc = []
    kpk = []
    if eief == True:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(om - efixed)
                temp1.append(np.sqrt(om/efixed))
            w_calc.append(temp)
            kpk.append(temp1)                
    else:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(-(om - efixed))
                temp1.append(np.sqrt(efixed/om))
            w_calc.append(temp)
            kpk.append(temp1)

    w_calc = np.array(np.real(w_calc))
    

    # Grab Form Factors
    ff_list = []
    s = sp.Symbol('s')
    for i in range(N_atoms):
        el = elements[atom_list[i].atomicNum]
        val = atom_list[i].valence
        if val != None:
            Mq = el.magnetic_ff[val].M_Q(kaprange)
        else:
            Mq = el.magnetic_ff[0].M_Q(kaprange)
        ff_list.append(Mq)
    print "Calculated: Form Factors"

    # Other Constants
    gamr0 = 2*0.2695*10**(-12) #sp.Symbol('gamma', commutative = True)
    hbar = 1.0 # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.#sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol('kappa', real = True)#spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real = True)
    w = sp.Symbol('w', real = True)
    W = sp.Symbol('W', real = True)
    tau = sp.Symbol('tau', real = True)
    q = sp.Symbol('q', real = True)
    L = sp.Symbol('L', real = True)
    boltz = 1.#1.3806503*10**(-23)     
    
    # Wilds for sub_in method
    A = sp.Wild('A',exclude = [0,t])
    B = sp.Wild('B',exclude = [0,t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')

    # First the exponentials are turned into delta functions:
    for i in range(len(arg)):
        for j in range(N):
            print '1', arg[i][j]
            arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
            arg[i][j] = (arg[i][j] * exp(-I*w*t) * exp(I*kap*L)).expand()# * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
            arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
#            print '2', arg[i][j]
            arg[i][j] = sub_in(arg[i][j],exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))#*sp.DiracDelta(C))
#            print '3', arg[i][j]
            arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(A*t + B*t + C*L + D*L + K*L),sp.DiracDelta(A*hbar + B*hbar)*sp.simplify(sp.DiracDelta(C + D + K + tau)))
#            print '4', arg[i][j]
            arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(-A - B)*sp.DiracDelta(C),sp.DiracDelta(A + B)*sp.DiracDelta(C))
            print '5', arg[i][j]
    print "Applied: Delta Function Conversion"

    # Grabs the unit vectors from the back of the lists. 
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat',commutative = False)
    kapyhat = sp.Symbol('kapyhat',commutative = False)
    kapzhat = sp.Symbol('kapzhat',commutative = False)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #
    
    csdata = []
    for i in range(len(arg)):
        temp1 = []
        for j in range(len(arg[i])):
            temp2 = []
            for k in range(len(tau_list)):
                temp3 = []
                print i,j,k
                for g in range(len(qrange[k])):
                    pvalue = tau_list[k] + kapvect[g] + qrange[k][g]
                    mvalue = tau_list[k] + kapvect[g] - qrange[k][g]
                    if pvalue[0] == 0 and pvalue[1] == 0 and pvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(sp.DiracDelta(kap+tau+q),sp.DiracDelta(0))
                    else: arg[i][j] = arg[i][j].subs(sp.DiracDelta(kap+tau+q),0)
                    if mvalue[0] == 0 and mvalue[1] == 0 and mvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(sp.DiracDelta(kap+tau-q),sp.DiracDelta(0))
                    else: arg[i][j] = arg[i][j].subs(sp.DiracDelta(kap+tau-q),0)               
                    wq = sp.Symbol('wq', real = True)
                    nq = sp.Symbol('n%i'%(k,), commutative = False)
                    arg[i][j] = arg[i][j].subs(wq,wrange[k][g])
                    arg[i][j] = arg[i][j].subs(w,w_calc[k][g])
                    n = sp.Pow( sp.exp(hbar*wrange[k][g]/boltz*temperature) - 1 ,-1)
                    arg[i][j] = arg[i][j].subs(nq,n)
                    temp3.append(arg[i][j])
                temp2.append(temp3)
            temp1.append(temp2)
        csdata.append(temp1)
##            print arg[i][j]
#            for g in range(len(kaprange)):
#                arg[i][j] = arg[i][j].subs(kap, kaprange[g])
#            for g in range(len(krange)):
##                print 'calculating'
#                temp3 = []
#                wg = sp.Symbol('w%i'%(g,), real = True)
#                ng = sp.Symbol('n%i'%(g,), commutative = False)
##                kx = sp.Symbol('kx', real = True, commutative = True)
##                ky = sp.Symbol('ky', real = True, commutative = True)
##                kz = sp.Symbol('kz', real = True, commutative = True)
##                arg[i][j] = arg[i][j].subs(kx,krange[g][0])
##                arg[i][j] = arg[i][j].subs(ky,krange[g][1])
##                arg[i][j] = arg[i][j].subs(kz,krange[g][2])
#                arg[i][j] = arg[i][j].subs(wg,wrange[g])
#                arg[i][j] = arg[i][j].subs(w,w_calc[g])
#                nq = sp.Pow( sp.exp(hbar*wrange[g]/boltz*temp) - 1 ,-1)
#                arg[i][j] = arg[i][j].subs(ng,nq)
##                arg[i][j] = arg[i][j].subs(tau,tau_list[0])
#
#                temp3.append(arg[i][j])
##                print arg[i][j]
#            temp2.append(temp3)
##            print arg[i][j]
#        csdata.append(temp2)

    print csdata


    # Front constants and stuff for the cross-section
    front_constant = 1.0 # (gamr0)**2/(2*pi*hbar)
    front_func = (1./2.)*g#*F(k)
    vanderwaals = 1. #exp(-2*W)

    csrange = []
    if 1:
        temp1 = []
        temp2 = []
        for q in range(len(qrange)):
            print 'calculating'
            for ii in range(len(csdata)):
                for jj in range(len(csdata[ii])):
                    temp1.append(csdata[ii][jj])
            # Put on gamr0, 2pi hbar, form factor, kp/k, vanderwaals first
            dif = front_func**2 * front_constant# * kpk[q][0] * vanderwaals * ff_list[0][q]
#            for vect in unit_vect:
#                vect.subs(kapxhat,kapvect[q][0][0])
#                vect.subs(kapyhat,kapvect[q][1][0])
#                vect.subs(kapzhat,kapvect[q][2][0])
            print 'diff',dif
            print 'temp1',temp1
            print sum(temp1)
            dif = (dif * sum(temp1))# * sum(unit_vect))#.expand()
            csrange.append(dif)
    print "Calculated: Cross-section"
    csrange=np.real(csrange)
    csrange=np.array(csrange)

    xi=qrange
    yi=wrange
    zi=csrange
    Z=np.zeros((xi.shape[0],yi.shape[0])) 
    Z[range(len(xi)),range(len(yi))]=zi

    pylab.contourf(xi,yi,Z)
    pylab.colorbar()
    pylab.show()