コード例 #1
0
class QuasiHarmonic():
    def __init__(self, fname, indexRange, prcntVolume, modePrefix):
        """indexRange is for files' indexing. prcntVolume - coresponding volume
       expansions"""
        self.qecalc = QECalc(fname)
        self.__modePrefix = modePrefix
        self.__indexRange = indexRange
        self.__prcntVolume = prcntVolume
        if len(indexRange) != len(prcntVolume):
            raise Exception("QuasiHarmonic dimensions: indexRange != prcntVolume")
        self.loadPhonons()
        self.__polyOrder = 1
        self.fitMatdyn()

    def fitFunc(self, p, x):
        return p[0] * x
#+ p[1] * x * x
        #+ p[2] * x * x * x + p[3] * x * x * x * x

    def fitOmega(self, prcntOmega):
    #    fitfunc = lambda p, x: p[0] * x + p[1] * x * x
        errFunc = lambda p, x, y: (y - self.fitFunc(p, x))
      # initial parameters:
        pinit = [prcntOmega[1]/self.__prcntVolume[1]]
#        pinit = [1,0]
        v, success = leastsq(errFunc, pinit, args=(self.__prcntVolume, prcntOmega))
        if success < 1 or success > 4:
            print success
            print prcntOmega
            print v
    #   assert success != 1, "fitOmega: Fitting was not successful"
        return v


    def getQuasiFreqs(prcntVol):
        """Returns array of freqs, corresponding to the provided volume expansion"""
        nPoints = shape(self.__coeffOmega)[0]
        nModes = shape(self.__coeffOmega)[1]
        fittedFreqs = zeros(shape = (nPoints, nModes) )
        for i in range( nPoints ):
            for j in range( nModes ):
                p = self.__coeffOmega[i,j]
                fittedFreqs[i,j] = p[0]*prcntVol
        return (fittedFreqs+1.0)*self.__omega0

    def getFittedFreqs(prcntVol):
        nPoints = shape(self.__coeffOmega)[0]
        nModes = shape(self.__coeffOmega)[1]
        fittedFreqs = zeros(shape = (nPoints, nModes) )
        for i in range( nPoints ):
            for j in range( nModes ):
                p = self.__coeffOmega[i,j]
                fittedFreqs[i,j] = fitFunc(p, prcntVol)
        return (fittedFreqs+1.0)*self.__omega0

    def loadPhonons(self):
        fname = self.__modePrefix + str(self.__indexRange[0]) + '.modes'
        Pol, Omega, qPoints = self.qecalc.getMultiPhonon(fname)
        self.__volOmega = zeros(shape=(len(self.__indexRange), shape(Omega)[0], shape(Omega)[1]  ) )
        self.__volPol = zeros(shape=(len(self.__indexRange), shape(Pol)[0], shape(Pol)[1], shape(Pol)[2], shape(Pol)[3] ) )
        self.__volPol[0] = Pol
        self.__volOmega[0] = Omega
        for i in range(1,len(indexRange)):
            fname = self.__modePrefix + str(self.__indexRange[i]) + '.modes'
            Pol, Omega, qPoints = self.qecalc.getMultiPhonon(fname)
            self.__volPol[i] = Pol
            self.__volOmega[i] = Omega
#        return volPol, volOmega, qPoints

    def fitMatdyn(self):
    #    volPol, volOmega, qPoints = loadPhonons(indexRange, prefix)
    #    prcntVol = array(indexRange)/1000.0
        # percent change in Omegas relative to equilibrium
        self.__volPrcntOmega = zeros(shape(self.__volOmega))
        # introduce Omega0 to get rid of 0s in denominator
        Omega0 = copy(self.__volOmega[0])
        self.__omega0 = Omega0
        for i in range(shape(Omega0)[0]):
            for j in range(shape(Omega0)[1]):
                if Omega0[i,j] == 0.:
                    Omega0[i, j] = 1
        for i in range(len(self.__indexRange)):
            self.__volPrcntOmega[i] = (self.__volOmega[i] - self.__volOmega[0])/Omega0
        self.__coeffOmega = zeros( shape = ( shape(Omega0)[0], shape(Omega0)[1], self.__polyOrder) )
        nonlinearity = 0
        for i in range( shape(Omega0)[0] ):
            for j in range( shape(Omega0)[1] ):
                self.__coeffOmega[i,j] = self.fitOmega(self.__volPrcntOmega[:,i,j])
                if self.__polyOrder > 1:
                    nonlinearity = nonlinearity + abs(self.__coeffOmega[i,j][1])
#    print volPrcntOmega[:,1000,3]
#    print fitOmega(prcntVol, volPrcntOmega[:,1000,3])
#    plot(volPrcntOmega[:,1000,3])
#    show()

#    return prcntVol, coeffOmega, volOmega, nonlinearity

    def gammaDispersion(self, *pathNPoints):
        self.qecalc.dispersion.setPath(*pathNPoints)
        self.qecalc.dispersion.setValues(-self.__coeffOmega[:,:,0])
        self.qecalc.dispersion.plot()
コード例 #2
0
ファイル: qeqha.py プロジェクト: nityasagarjena/AbInitio
class QuasiHarmonic():
    def __init__(self, fname, indexRange, prcntVolume, modePrefix):
        """indexRange is for files' indexing. prcntVolume - coresponding volume
       expansions"""
        self.qecalc = QECalc(fname)
        self.__modePrefix = modePrefix
        self.__indexRange = indexRange
        self.__prcntVolume = prcntVolume
        if len(indexRange) != len(prcntVolume):
            raise Exception(
                "QuasiHarmonic dimensions: indexRange != prcntVolume")
        self.loadPhonons()
        self.__polyOrder = 1
        self.fitMatdyn()

    def fitFunc(self, p, x):
        return p[0] * x
#+ p[1] * x * x
#+ p[2] * x * x * x + p[3] * x * x * x * x

    def fitOmega(self, prcntOmega):
        #    fitfunc = lambda p, x: p[0] * x + p[1] * x * x
        errFunc = lambda p, x, y: (y - self.fitFunc(p, x))
        # initial parameters:
        pinit = [prcntOmega[1] / self.__prcntVolume[1]]
        #        pinit = [1,0]
        v, success = leastsq(errFunc,
                             pinit,
                             args=(self.__prcntVolume, prcntOmega))
        if success < 1 or success > 4:
            print success
            print prcntOmega
            print v

    #   assert success != 1, "fitOmega: Fitting was not successful"
        return v

    def getQuasiFreqs(prcntVol):
        """Returns array of freqs, corresponding to the provided volume expansion"""
        nPoints = shape(self.__coeffOmega)[0]
        nModes = shape(self.__coeffOmega)[1]
        fittedFreqs = zeros(shape=(nPoints, nModes))
        for i in range(nPoints):
            for j in range(nModes):
                p = self.__coeffOmega[i, j]
                fittedFreqs[i, j] = p[0] * prcntVol
        return (fittedFreqs + 1.0) * self.__omega0

    def getFittedFreqs(prcntVol):
        nPoints = shape(self.__coeffOmega)[0]
        nModes = shape(self.__coeffOmega)[1]
        fittedFreqs = zeros(shape=(nPoints, nModes))
        for i in range(nPoints):
            for j in range(nModes):
                p = self.__coeffOmega[i, j]
                fittedFreqs[i, j] = fitFunc(p, prcntVol)
        return (fittedFreqs + 1.0) * self.__omega0

    def loadPhonons(self):
        fname = self.__modePrefix + str(self.__indexRange[0]) + '.modes'
        Pol, Omega, qPoints = self.qecalc.getMultiPhonon(fname)
        self.__volOmega = zeros(shape=(len(self.__indexRange), shape(Omega)[0],
                                       shape(Omega)[1]))
        self.__volPol = zeros(shape=(len(self.__indexRange), shape(Pol)[0],
                                     shape(Pol)[1], shape(Pol)[2],
                                     shape(Pol)[3]))
        self.__volPol[0] = Pol
        self.__volOmega[0] = Omega
        for i in range(1, len(indexRange)):
            fname = self.__modePrefix + str(self.__indexRange[i]) + '.modes'
            Pol, Omega, qPoints = self.qecalc.getMultiPhonon(fname)
            self.__volPol[i] = Pol
            self.__volOmega[i] = Omega
#        return volPol, volOmega, qPoints

    def fitMatdyn(self):
        #    volPol, volOmega, qPoints = loadPhonons(indexRange, prefix)
        #    prcntVol = array(indexRange)/1000.0
        # percent change in Omegas relative to equilibrium
        self.__volPrcntOmega = zeros(shape(self.__volOmega))
        # introduce Omega0 to get rid of 0s in denominator
        Omega0 = copy(self.__volOmega[0])
        self.__omega0 = Omega0
        for i in range(shape(Omega0)[0]):
            for j in range(shape(Omega0)[1]):
                if Omega0[i, j] == 0.:
                    Omega0[i, j] = 1
        for i in range(len(self.__indexRange)):
            self.__volPrcntOmega[i] = (self.__volOmega[i] -
                                       self.__volOmega[0]) / Omega0
        self.__coeffOmega = zeros(shape=(shape(Omega0)[0], shape(Omega0)[1],
                                         self.__polyOrder))
        nonlinearity = 0
        for i in range(shape(Omega0)[0]):
            for j in range(shape(Omega0)[1]):
                self.__coeffOmega[i,
                                  j] = self.fitOmega(self.__volPrcntOmega[:, i,
                                                                          j])
                if self.__polyOrder > 1:
                    nonlinearity = nonlinearity + abs(self.__coeffOmega[i,
                                                                        j][1])


#    print volPrcntOmega[:,1000,3]
#    print fitOmega(prcntVol, volPrcntOmega[:,1000,3])
#    plot(volPrcntOmega[:,1000,3])
#    show()

#    return prcntVol, coeffOmega, volOmega, nonlinearity

    def gammaDispersion(self, *pathNPoints):
        self.qecalc.dispersion.setPath(*pathNPoints)
        self.qecalc.dispersion.setValues(-self.__coeffOmega[:, :, 0])
        self.qecalc.dispersion.plot()