Ejemplo n.º 1
0
    def GetResult(self):
        print "fit list: ", self.fit_list
        #Propagate any value changes through all tied parameters
        for i in range(len(self.fit_list)):
            group = self._paramGroupList[i]
            print "group: ", group
            for param in group:
                #This will change the values in the matrices
                param.value = self.fit_list[i]
        monteCarloMats = []
        #Used later for spinwave calculation
        jnums = []
        jmats = []
        print "matrices[0]: ", self._matrices[0].tolist()
        for i in range(len(self._matrices)):
            j11 = self._matrices[i][0][0].value
            j12 = self._matrices[i][0][1].value
            j13 = self._matrices[i][0][2].value
            j21 = self._matrices[i][1][0].value
            j22 = self._matrices[i][1][1].value
            j23 = self._matrices[i][1][2].value
            j31 = self._matrices[i][2][0].value
            j32 = self._matrices[i][2][1].value
            j33 = self._matrices[i][2][2].value
            monteCarloMats.append(numpy.array([[j11,j12,j13],
                                               [j21,j22,j23],
                                               [j31,j32,j33]]))
            #Used later for spinwave calculation
            jij=sympy.matrices.Matrix([[j11,j12,j13],
                                       [j21,j22,j23],
                                       [j31,j32,j33]])
            jnums.append(i)
            jmats.append(jij)
        
        
        
        #Run the monteCarlo simulation
        #temporary (bad) method of picking tMin/tMax
#        jAvg = 0
#        for mat in monteCarloMats:
#            jSum = 0
#            for i in range(3):
#                for j in range(3):
#                    val = abs(mat[i][j])
#                    jSum += val
#            jAvg += jSum/9
#        
#        self._tMax = jAvg*12
#        self._tMin = jAvg/10000
#        self._tMax = 10
#        self._tMin = 1E-6
        print "\n\n\nmonte Carlo Mats:\n", monteCarloMats
        
        if self._runMCeveryTime or self._run == 0:
            #self._handle.write("\n\n\n\n\n------------Get Ground State---------------\n\n")
            self.spins = get_ground_state(self._k, self._tMax, self._tMin, self._tFactor,
                        self._simpleAtoms, monteCarloMats)
        else:
            #self._handle.write("\n\n\n\n\n------------Opt Aux---------------\n\n")
            self.spins = opt_aux(self._simpleAtoms, monteCarloMats, self.spins)
        #self.spins = opt_aux(self._simpleAtoms, monteCarloMats, self.spins)
        
        #print "\nspins:\n", self.spins
        #self._handle.write("\n\n\n\nparam:\n\n")
        #self._handle.write(str(self.fit_list))
        #self._handle.write("\n\nSpins After:\n\n")
        #self._handle.write(str(self.spins))
        #self._handle.flush()
        
        
        def inUnitCell(atom):
            """Returns true of the atom is in the unit cell at Na, Nb, Nc, where
            those are the dimensions of the interaction cell.  That cell is being
            used to ensure that it is completely surrounded and no interactions
            are left out.  Handles simpleAtom type"""
            if atom.pos[0] >= self._interactionCellDimensions[0] and atom.pos[0] < (self._interactionCellDimensions[0] + 1):
                if atom.pos[1] >= self._interactionCellDimensions[1] and atom.pos[1] < (self._interactionCellDimensions[1] + 1):
                    if atom.pos[2] >= self._interactionCellDimensions[2] and atom.pos[2] < (self._interactionCellDimensions[2] + 1):
                        return True
            return False
            
        
        def inInteractionCell(atoms, atom):
            """Handles simpleAtom type."""
            #First check if the atom is in the first crystallographic cell
#            if atom.pos[0] < 1.0 and atom.pos[1] < 1.0 and atom.pos[2] < 1.0:
#                return True
#Now the crystallographic unit cell being used is at Na, Nb, Nc, not 0,0,0
            if inUnitCell(atom):
                return True
                        
            #If not, check if it bonds to an atom that is
            for i in range(len(atom.interactions)):
                if inUnitCell(atoms[atom.interactions[i][0]]):
                    return True
            return False
        
        #Do the spinwave calculation
        spinwave_atoms = []
        first_cell_atoms = 0
        for i in range(len(self._simpleAtoms)):
            atom = self._simpleAtoms[i]
            if inInteractionCell(self._simpleAtoms, atom):
                Dx = atom.anisotropy[0]
                Dy = atom.anisotropy[1]
                Dz = atom.anisotropy[2]
                spinwave_atom = SpinwaveAtom(pos=atom.pos, Dx=Dx,Dy=Dy,Dz=Dz,
                                             orig_Index = i)
                rmat = findmat(self.spins[i])#indices match up
                spinwave_atom.spinRmatrix = rmat
                
                for interaction in atom.interactions:
                    spinwave_atom.neighbors.append(interaction[0])
                    spinwave_atom.interactions.append(interaction[1])
                spinwave_atoms.append(spinwave_atom)
                #x,y,z = spinwave_atom.pos
                #if x<1 and y<1 and z<1:
                #    first_cell_atoms +=1
        
        #Find atoms in desired cell and organize list so they come first
        tmp = []
        for i in range(len(spinwave_atoms)):
            if inUnitCell(spinwave_atoms[i]):
                first_cell_atoms += 1
                tmp.append(spinwave_atoms.pop(i))
        for a in spinwave_atoms:
            tmp.append(a)
        spinwave_atoms = tmp       
        
        #change interaction indices to match indices in new list
        for a in spinwave_atoms:
            neighborList = a.neighbors
            i = 0
            while i < len(neighborList):
                neighbor_index = neighborList[i]
                for atom_index in range(len(spinwave_atoms)):
                    atom = spinwave_atoms[atom_index]
                    if atom.origIndex == neighbor_index:
                        a.neighbors[i] = atom_index
                        i +=1
                        break
                else:#This neighbor index is not in the interaction cell
                    neighborList.pop(i)
                    a.interactions.pop(i)
        
        N_atoms=len(spinwave_atoms)
        Hsave=calculate_dispersion(spinwave_atoms,first_cell_atoms,N_atoms,jmats
                                   ,showEigs=False)
        qrange = []
        wrange = []
        q = 0
        for point in self.spinwave_domain:
            #print "point:", point
            wrange.append(calc_eigs(Hsave,point[0], point[1], point[2]))
            qrange.append(q)
            q += 1
     
        wrange=numpy.real(wrange)
        wrange=numpy.array(wrange)
        wrange=numpy.real(wrange.T)
        
        #for wrange1 in wrange:
        #    pylab.plot(qrange,wrange1,'s')
        #pylab.show()
        self._run+=1
        
        #self._handle.write("\n\ndispersion:\n\n")
        #self._handle.write(str(wrange[0]))
        
        return wrange[0]#for now just one set

        
            
Ejemplo n.º 2
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()
Ejemplo n.º 3
0
    def GetResult(self):
        print "fit list: ", self.fit_list
        #Propagate any value changes through all tied parameters
        for i in range(len(self.fit_list)):
            group = self._paramGroupList[i]
            print "group: ", group
            for param in group:
                #This will change the values in the matrices
                param.value = self.fit_list[i]
        monteCarloMats = []
        #Used later for spinwave calculation
        jnums = []
        jmats = []
        print "matrices[0]: ", self._matrices[0].tolist()
        for i in range(len(self._matrices)):
            j11 = self._matrices[i][0][0].value
            j12 = self._matrices[i][0][1].value
            j13 = self._matrices[i][0][2].value
            j21 = self._matrices[i][1][0].value
            j22 = self._matrices[i][1][1].value
            j23 = self._matrices[i][1][2].value
            j31 = self._matrices[i][2][0].value
            j32 = self._matrices[i][2][1].value
            j33 = self._matrices[i][2][2].value
            monteCarloMats.append(numpy.array([[j11,j12,j13],
                                               [j21,j22,j23],
                                               [j31,j32,j33]]))
            #Used later for spinwave calculation
            jij=sympy.matrices.Matrix([[j11,j12,j13],
                                       [j21,j22,j23],
                                       [j31,j32,j33]])
            jnums.append(i)
            jmats.append(jij)
        
        
        
        #Run the monteCarlo simulation
        #temporary (bad) method of picking tMin/tMax
#        jAvg = 0
#        for mat in monteCarloMats:
#            jSum = 0
#            for i in range(3):
#                for j in range(3):
#                    val = abs(mat[i][j])
#                    jSum += val
#            jAvg += jSum/9
#        
#        self._tMax = jAvg*12
#        self._tMin = jAvg/10000
#        self._tMax = 10
#        self._tMin = 1E-6
        print "\n\n\nmonte Carlo Mats:\n", monteCarloMats
        
        if self._runMCeveryTime or self._run == 0:
            #self._handle.write("\n\n\n\n\n------------Get Ground State---------------\n\n")
            self.spins = get_ground_state(self._k, self._tMax, self._tMin, self._tFactor,
                        self._simpleAtoms, monteCarloMats)
        else:
            #self._handle.write("\n\n\n\n\n------------Opt Aux---------------\n\n")
            self.spins = opt_aux(self._simpleAtoms, monteCarloMats, self.spins)
        #self.spins = opt_aux(self._simpleAtoms, monteCarloMats, self.spins)
        
        #print "\nspins:\n", self.spins
        #self._handle.write("\n\n\n\nparam:\n\n")
        #self._handle.write(str(self.fit_list))
        #self._handle.write("\n\nSpins After:\n\n")
        #self._handle.write(str(self.spins))
        #self._handle.flush()
        
        
        def inUnitCell(atom):
            """Returns true of the atom is in the unit cell at Na, Nb, Nc, where
            those are the dimensions of the interaction cell.  That cell is being
            used to ensure that it is completely surrounded and no interactions
            are left out.  Handles simpleAtom type"""
            if atom.pos[0] >= self._interactionCellDimensions[0] and atom.pos[0] < (self._interactionCellDimensions[0] + 1):
                if atom.pos[1] >= self._interactionCellDimensions[1] and atom.pos[1] < (self._interactionCellDimensions[1] + 1):
                    if atom.pos[2] >= self._interactionCellDimensions[2] and atom.pos[2] < (self._interactionCellDimensions[2] + 1):
                        return True
            return False
            
        
        def inInteractionCell(atoms, atom):
            """Handles simpleAtom type."""
            #First check if the atom is in the first crystallographic cell
#            if atom.pos[0] < 1.0 and atom.pos[1] < 1.0 and atom.pos[2] < 1.0:
#                return True
#Now the crystallographic unit cell being used is at Na, Nb, Nc, not 0,0,0
            if inUnitCell(atom):
                return True
                        
            #If not, check if it bonds to an atom that is
            for i in range(len(atom.interactions)):
                if inUnitCell(atoms[atom.interactions[i][0]]):
                    return True
            return False
        
        #Do the spinwave calculation
        spinwave_atoms = []
        first_cell_atoms = 0
        for i in range(len(self._simpleAtoms)):
            atom = self._simpleAtoms[i]
            if inInteractionCell(self._simpleAtoms, atom):
                Dx = atom.anisotropy[0]
                Dy = atom.anisotropy[1]
                Dz = atom.anisotropy[2]
                spinwave_atom = SpinwaveAtom(pos=atom.pos, Dx=Dx,Dy=Dy,Dz=Dz,
                                             orig_Index = i)
                rmat = findmat(self.spins[i])#indices match up
                spinwave_atom.spinRmatrix = rmat
                
                for interaction in atom.interactions:
                    spinwave_atom.neighbors.append(interaction[0])
                    spinwave_atom.interactions.append(interaction[1])
                spinwave_atoms.append(spinwave_atom)
                #x,y,z = spinwave_atom.pos
                #if x<1 and y<1 and z<1:
                #    first_cell_atoms +=1
        
        #Find atoms in desired cell and organize list so they come first
        tmp = []
        for i in range(len(spinwave_atoms)):
            if inUnitCell(spinwave_atoms[i]):
                first_cell_atoms += 1
                tmp.append(spinwave_atoms.pop(i))
        for a in spinwave_atoms:
            tmp.append(a)
        spinwave_atoms = tmp       
        
        #change interaction indices to match indices in new list
        for a in spinwave_atoms:
            neighborList = a.neighbors
            i = 0
            while i < len(neighborList):
                neighbor_index = neighborList[i]
                for atom_index in range(len(spinwave_atoms)):
                    atom = spinwave_atoms[atom_index]
                    if atom.origIndex == neighbor_index:
                        a.neighbors[i] = atom_index
                        i +=1
                        break
                else:#This neighbor index is not in the interaction cell
                    neighborList.pop(i)
                    a.interactions.pop(i)
        
        N_atoms=len(spinwave_atoms)
        Hsave=calculate_dispersion(spinwave_atoms,first_cell_atoms,N_atoms,jmats
                                   ,showEigs=False)
        qrange = []
        wrange = []
        q = 0
        for point in self.spinwave_domain:
            #print "point:", point
            wrange.append(calc_eigs(Hsave,point[0], point[1], point[2]))
            qrange.append(q)
            q += 1
     
        wrange=numpy.real(wrange)
        wrange=numpy.array(wrange)
        wrange=numpy.real(wrange.T)
        
        #for wrange1 in wrange:
        #    pylab.plot(qrange,wrange1,'s')
        #pylab.show()
        self._run+=1
        
        #self._handle.write("\n\ndispersion:\n\n")
        #self._handle.write(str(wrange[0]))
        
        return wrange[0]#for now just one set
Ejemplo n.º 4
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()