Exemplo n.º 1
0
 def __init__(self, hamiltonian, beta, verbose = False):
     self.hamiltonian = hamiltonian
     self.singleParticleBasis = hamiltonian.singleParticleBasis
     self.orderedSingleParticleStates = hamiltonian.orderedSingleParticleStates
     self.fockspaceSize = hamiltonian.fockspaceSize
     self.partitionFunction = None
     self.beta = beta
     self.energyEigenstates = None
     self.energyEigenvalues = None
     self.verbose = verbose
     self.occupation = StaticObservable(verbose = self.verbose)
     self.g1 = DynamicObservable(verbose = self.verbose)
Exemplo n.º 2
0
class CanonicalEnsemble(object):
    def __init__(self, hamiltonian, beta, verbose = False):
        self.hamiltonian = hamiltonian
        self.singleParticleBasis = hamiltonian.singleParticleBasis
        self.orderedSingleParticleStates = hamiltonian.orderedSingleParticleStates
        self.fockspaceSize = hamiltonian.fockspaceSize
        self.partitionFunction = None
        self.beta = beta
        self.energyEigenstates = None
        self.energyEigenvalues = None
        self.verbose = verbose
        self.occupation = StaticObservable(verbose = self.verbose)
        self.g1 = DynamicObservable(verbose = self.verbose)

    def setLehmannSumStatic(self, staticObservable):
        assert type(staticObservable) == StaticObservable, 'StaticObservable expected.'
        e = self.getEnergyEigenvalues()
        ve = self.getEnergyEigenstates().toarray()
        z = self.getPartitionFunction()
        fockstates = range(self.fockspaceSize)
        for index, matrix in staticObservable.operators.items():
            if type(matrix) != ndarray:
                m = matrix.toarray()
            else:
                m = matrix
            n_inds_p = array(scatter_list(fockstates))
            terms_p = list()
            for n in n_inds_p:
                el = ve[:,n].dot(m.dot(ve[:,n]))
                expn = exp(-self.beta*e[n])
                if not equals(el, 0) and not equals(expn, 0):
                    terms_p.append(expn * el)
            staticObservable.expectationValue.update({index: sumScatteredLists(terms_p)/z})

    def calcOccupation(self, singleParticleState = None):
        c = AnnihilationOperator(self.singleParticleBasis)
        if singleParticleState == None:
            states = self.orderedSingleParticleStates
        else:
            states = [singleParticleState]
        report('Calculating Occupation...', self.verbose)
        t0 = time()
        for state in states:
            n_state = c[state].H.dot(c[state])
            self.occupation.addOperator(state, n_state)
        self.setLehmannSumStatic(self.occupation)
        report('took '+str(time()-t0)[:4]+' seconds', self.verbose)

    def getTotalOccupation(self):
        return nsum(self.occupation.expectationValue.values())

    def calcPartitionFunction(self):
        report('Calculating Partition Function...', self.verbose)
        t0 = time()
        self.partitionFunction = nsum([exp(-self.beta*eva) for eva in self.getEnergyEigenvalues()])
        report('took '+str(time()-t0)[:4]+' seconds', self.verbose)

    def getPartitionFunction(self):
        if self.partitionFunction != None:
            return self.partitionFunction
        else:
            self.calcPartitionFunction()
            return self.partitionFunction

    def getEnergyEigenstates(self):
        if self.energyEigenstates != None:
            return self.energyEigenstates
        else:
            self.calcEigensystem()
            return self.energyEigenstates

    def getEnergyEigenvalues(self):
        if self.energyEigenvalues != None:
            return self.energyEigenvalues
        else:
            self.calcEigensystem()
            return self.energyEigenvalues

    def calcEigensystem(self):
        self.hamiltonian.solve()
        self.energyEigenstates = self.hamiltonian.eigenStates
        self.energyEigenvalues = self.hamiltonian.eigenEnergies

    def setLehmannTermsDynamic(self, dynamicObservable):
        assert type(dynamicObservable) == DynamicObservable, 'Type DynamicObservable expected.'
        if dynamicObservable.species == 'fermionic':
            self.setLehmannTermsDynamicFermionic(dynamicObservable)
        elif dynamicObservable.species == 'bosonic':
            self.setLehmannTermsDynamicBosonic(dynamicObservable)

    def setLehmannTermsDynamicFermionic(self, dynamicObservable):
        for statePair, operatorPair in dynamicObservable.operatorPairs.items():
            operator1 = operatorPair[0]
            operator2 = operatorPair[1]
            if type(operator1) != ndarray:
                operator1 = operator1.toarray()
                operator2 = operator2.toarray()
            e = self.getEnergyEigenvalues()
            ve = self.getEnergyEigenstates().toarray()
            fockstates = range(self.fockspaceSize)

            n_inds_p = array(scatter_list(fockstates))
            nominators_p = []
            denominators_p = []
            for n in n_inds_p:
                n_op1 = ve[:,n].dot(operator1)
                op2_n = operator2.dot(ve[:,n])
                expn = exp(-self.beta*e[n])
                for m in fockstates:
                    if dynamicObservable.species == 'bosonic':
                        if equals(e[n], e[m]):
                            continue
                    el1 = n_op1.dot(ve[:,m])
                    if not equals(el1, 0):
                        el2 = ve[:,m].dot(op2_n)
                        if not equals(el2, 0):
                            expm = exp(-self.beta*e[m])
                            el = el1*el2
                            nominators_p.append([])
                            nominators_p[-1].append(expn*el)
                            nominators_p[-1].append(expm*el)
                            denominators_p.append(e[n]-e[m])
            dynamicObservable.lehmannNominators.update({statePair: allgather_list(nominators_p)})
            dynamicObservable.lehmannDenominators.update({statePair: allgather_list(denominators_p)})
        dynamicObservable.partitionFunction = self.getPartitionFunction()

    def setZeroFrequencyTerms(self, dynamicObservable):
        for statePair, operatorPair in dynamicObservable.operatorPairs.items():
            operator1 = operatorPair[0]
            operator2 = operatorPair[1]
            if type(operator1) != ndarray:
                operator1 = operator1.toarray()
                operator2 = operator2.toarray()
            e = self.getEnergyEigenvalues()
            ve = self.getEnergyEigenstates().toarray()
            fockstates = range(self.fockspaceSize)

            n_inds_p = array(scatter_list(fockstates))
            zeroFrequencyTerms_p = []
            for n in n_inds_p:
                n_op1 = ve[:,n].dot(operator1)
                op2_n = operator2.dot(ve[:,n])
                expn = exp(-self.beta*e[n])
                for m in fockstates:
                    if equals(e[n], e[m]):
                        el1 = n_op1.dot(ve[:,m])
                        if not equals(el1, 0):
                            el2 = ve[:,m].dot(op2_n)
                            if not equals(el2, 0):
                                el = el1*el2
                                zeroFrequencyTerms_p.append(-self.beta*expn*el)
            dynamicObservable.zeroFrequencyTerms.update({statePair: allgather_list(zeroFrequencyTerms_p)})

    def setLehmannTermsDynamicBosonic(self, dynamicObservable):
        self.setLehmannTermsDynamicFermionic(dynamicObservable)
        self.setZeroFrequencyTerms(dynamicObservable)

    def calcG1(self, singleParticleStatePairs = None):
        c = AnnihilationOperator(self.singleParticleBasis)
        if singleParticleStatePairs == None:
            statePairs = [(state1, state2) for state1, state2 in product(self.orderedSingleParticleStates, self.orderedSingleParticleStates)]
        else:
            statePairs = singleParticleStatePairs
        report('Calculating one-particle Green\'s function transition elements and energies...', self.verbose)
        t0 = time()
        for statePair in statePairs:
            c_state = c[statePair[0]]
            c_state_dag = c[statePair[1]].H
            self.g1.addOperatorPair(statePair, (c_state, c_state_dag))
        self.setLehmannTermsDynamic(self.g1)
        report('took '+str(time()-t0)[:4]+' seconds', self.verbose)