def calculateElevels(self): R = self.R kb = self.kb h = self.h amu = self.amu K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) E=[] #let us take k = -500, 500 m = 200 #print K for irot in range(len(self.Harmonics)): H = mat(zeros((2*m+1,2*m+1),dtype=complex)) kcos = self.Harmonics[irot].Kcos ksin = self.Harmonics[irot].Ksin for k in range(0,2*m+1): H[k,k] = 6.023e23*h**2*(k-m)**2/8.0/math.pi**2/K[irot]/amu/1e-20/4180 + self.Harmonics[irot].A for n in range(1,6): if k-n >= 0: H[k,k-n] = kcos[n-1]/2 + ksin[n-1]/2j if k+n < 2*m+1: H[k,k+n] = kcos[n-1]/2 - ksin[n-1]/2j (l,v) = linalg.eigh(H) #pdb.set_trace() E.append(l) return E
def printData(self, oFile): geom = self.geom Mass = self.Mass oFile.write('Geometry:\n') oFile.write('%10s' % 'Mass(amu)' + '%10s' % 'X(ang)' + '%10s' % 'Y(ang)' + '%10s' % 'Z(ang)' + '\n') for i in range(Mass.size): oFile.write('%10.3f' % float(Mass[i]) + '%10.4f' % float(geom[i, 0]) + '%10.4f' % float(geom[i, 1]) + '%10.4f' % float(geom[i, 2]) + '\n') oFile.write('\nFrequencies (cm-1):\n') Freq = self.Freq if self.TS: oFile.write('Imaginary Frequency: ' + str(self.imagFreq) + '\n') for i in range(len(Freq) / 3 + 1): for j in range(3): if 3 * i + j < len(Freq): oFile.write('%10.3f' % Freq[3 * i + j]) oFile.write('\n') oFile.write('\nExternal Symmetry = ' + str(self.extSymm) + '\n') oFile.write('Principal Moments of Inertia = ' + str(self.Iext[0]) + ' ' + str(self.Iext[1]) + ' ' + str(self.Iext[2]) + '\n') oFile.write('Electronic Degeneracy = ' + str(self.nelec) + '\n') if self.numRotors == 0: return oFile.write( '\nFitted Harmonics V(p) = sum (A_i cos(i*p) + B_i sin(i*p)) :\n') k = 1 K = geomUtility.calculateD32(self.geom, self.Mass, self.rotors) for harmonic in self.Harmonics: oFile.write('Harmonic ' + str(k) + '\n') oFile.write('Moment of Inertia: ' + str(float(K[k - 1])) + '\n') oFile.write('Symmetry ' + str(self.rotors[k].symm) + '\n') oFile.write('BarrierHeight ' + str(harmonic.Barrier_Height) + '\n') oFile.write('%12s' % 'A_i' + '%12s' % 'B_i' + '\n') for j in range(5): oFile.write('%12.3e' % harmonic.Kcos[j] + '%12.3e' % harmonic.Ksin[j] + '\n') oFile.write('\n') k = k + 1
def calculateElevels(self): R = self.R kb = self.kb h = self.h amu = self.amu K = geomUtility.calculateD32(self.geom, self.Mass, self.rotors) E = [] #let us take k = -500, 500 m = 200 ke = 6.023e23 * h**2 / 8.0 / math.pi**2 / amu / 1e-20 / 4180 #frequently used quantity for the kinetic energy part of the matrix #print K for irot in range(len(self.Harmonics)): H = mat(zeros((2 * m + 1, 2 * m + 1), dtype=complex)) kcos = self.Harmonics[irot].Kcos ksin = self.Harmonics[irot].Ksin icos = self.Harmonics[irot].Icos isin = self.Harmonics[irot].Isin for k in range(0, 2 * m + 1): H[k, k] = self.Harmonics[irot].A if self.variableInertia: H[k, k] += ke * (k - m) * (k - m) * self.Harmonics[irot].B else: H[k, k] += ke * (k - m) * (k - m) / float(K[irot]) for n in range(1, 6): if k - n >= 0: H[k, k - n] = kcos[n - 1] / 2 + ksin[n - 1] / 2j if self.variableInertia: H[k, k - n] += (icos[n - 1] / 2 + isin[n - 1] / 2j) * ke * (k - m) * (k - n - m) if k + n < 2 * m + 1: H[k, k + n] = kcos[n - 1] / 2 - ksin[n - 1] / 2j if self.variableInertia: H[k, k + n] += (icos[n - 1] / 2 - isin[n - 1] / 2j) * ke * (k - m) * (k + n - m) (l, v) = linalg.eigh(H) #pdb.set_trace() E.append(l) return E
def calculateElevels(self): R = self.R kb = self.kb h = self.h amu = self.amu K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) E=[] #let us take k = -500, 500 m = 200 ke = 6.023e23*h**2/8.0/math.pi**2/amu/1e-20/4180 #frequently used quantity for the kinetic energy part of the matrix #print K for irot in range(len(self.Harmonics)): H = mat(zeros((2*m+1,2*m+1),dtype=complex)) kcos = self.Harmonics[irot].Kcos ksin = self.Harmonics[irot].Ksin icos = self.Harmonics[irot].Icos isin = self.Harmonics[irot].Isin for k in range(0,2*m+1): H[k,k] = self.Harmonics[irot].A if self.variableInertia: H[k,k] += ke*(k-m)*(k-m)*self.Harmonics[irot].B else: H[k,k] += ke*(k-m)*(k-m)/float(K[irot]) for n in range(1,6): if k-n >= 0: H[k,k-n] = kcos[n-1]/2 + ksin[n-1]/2j if self.variableInertia: H[k,k-n]+= (icos[n-1]/2 + isin[n-1]/2j)*ke*(k-m)*(k-n-m) if k+n < 2*m+1: H[k,k+n] = kcos[n-1]/2 - ksin[n-1]/2j if self.variableInertia: H[k,k+n] += (icos[n-1]/2 - isin[n-1]/2j)*ke*(k-m)*(k+n-m) (l,v) = linalg.eigh(H) #pdb.set_trace() E.append(l) return E
def printData(self,oFile): geom = self.geom Mass = self.Mass oFile.write('Geometry:\n') oFile.write('%10s'%'Mass(amu)'+'%10s'%'X(ang)'+'%10s'%'Y(ang)'+'%10s'%'Z(ang)'+'\n') for i in range(Mass.size): oFile.write('%10.3f'%float(Mass[i])+'%10.4f'%float(geom[i,0])+'%10.4f'%float(geom[i,1])+'%10.4f'%float(geom[i,2])+'\n') oFile.write('\nFrequencies (cm-1):\n') Freq = self.Freq if self.TS: oFile.write('Imaginary Frequency: '+str(self.imagFreq)+'\n') for i in range(len(Freq)/3+1): for j in range(3): if 3*i+j <len(Freq): oFile.write('%10.3f'%Freq[3*i+j]) oFile.write('\n') oFile.write('\nExternal Symmetry = '+str(self.extSymm)+'\n') oFile.write('Principal Moments of Inertia = '+str(self.Iext[0])+' '+str(self.Iext[1])+' '+str(self.Iext[2])+'\n') oFile.write('Electronic Degeneracy = '+str(self.nelec)+'\n') if self.numRotors == 0: return oFile.write('\nFitted Harmonics V(p) = sum (A_i cos(i*p) + B_i sin(i*p)) :\n' ) k = 1 K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) for harmonic in self.Harmonics: oFile.write('Harmonic '+str(k)+'\n') oFile.write('Moment of Inertia: '+ str(float(K[k-1]))+'\n') oFile.write('Symmetry '+str(self.rotors[k].symm)+'\n') oFile.write('BarrierHeight '+str(harmonic.A)+'\n') oFile.write('%12s'%'A_i'+'%12s'%'B_i'+'\n') for j in range(5): oFile.write('%12.3e'%harmonic.Kcos[j]+'%12.3e'%harmonic.Ksin[j]+'\n') oFile.write('\n') k = k+1
def getIntRotationalThermo_Q(self,oFile,Temp): ent = [0.0]*len(Temp) cp = [0.0]*len(Temp) dH = [0.0]*len(Temp) parti = [1.0]*len(Temp) R = self.R kb = self.kb h = self.h amu = self.amu oFile.write('\n\nInternal Rotational Contributions\n') oFile.write('%12s'%'Temperature') #iterate over temperatures for T in Temp: oFile.write('%12.2f'%T) sigma = 1.0 for rotor in self.rotors: sigma = sigma*rotor.symm K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) for irot in range(len(self.rotors)-1): harm = self.Harmonics[irot] ddv = 0.0 for l in range(5): ddv = ddv-1*harm.Kcos[l]*(l+1)**2 freq = 1.0/2.0/pi*sqrt(ddv*4180.0/K[irot]/1.0e-20/amu/6.023e23)/3.0e10 #print '%12.2f'%float(freq), #print #calculate the energy levels for the hindered rotors E = self.calculateElevels() #pdb.set_trace() for iT in range(len(Temp)): T = Temp[iT] #print T, for irot in range(len(self.rotors)-1): sum = 0.0 vsum = 0.0 v2sum = 0.0 for e in E[irot]: e = e - E[irot][0] sum = sum + exp(-e*1.0e3/R/T) vsum = vsum + e*1e3*exp(-e*1.0e3/R/T) v2sum = v2sum + e**2*1e6*exp(-e*1.0e3/R/T) ent[iT] = ent[iT] + R*math.log(sum)+vsum/sum/T-R*log(self.rotors[irot+1].symm) dH[iT] = dH[iT] + vsum/sum/1.0e3 cp[iT] = cp[iT] + (v2sum*sum-vsum**2)/sum**2/R/T**2 parti[iT] = parti[iT] *sum #print (v2sum*sum-vsum**2)/sum**2/R/T**2, #print R*math.log(sum)+vsum/sum/T-R*log(self.rotors[irot+1].symm), #print oFile.write('\n%12s'%'Entropy') for i in range(len(Temp)): oFile.write('%12.2f'%ent[i]) oFile.write('\n%12s'%'Cp') for i in range(len(Temp)): oFile.write('%12.2f'%cp[i]) oFile.write('\n%12s'%'dH') for i in range(len(Temp)): oFile.write('%12.2f'%dH[i]) oFile.write('\n%12s'%'q_int') for i in range(len(Temp)): oFile.write('%12.2e'%parti[i]) oFile.write('\n') return ent, cp , dH, parti
def getIntRotationalThermo_PG(self,oFile,Temp): ent = [] cp = [] dH = [] R = self.R kb = self.kb h = self.h amu = self.amu seed = 500 numIter = 100000 oFile.write('\n\nInternal Rotational Contributions\n') oFile.write('%12s'%'Temperature') #iterate over temperatures for T in Temp: oFile.write('%12.2f'%T) sigma = 1.0 for rotor in self.rotors: sigma = sigma*rotor.symm K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) print K p = 1.0 a = 1.0 for T in Temp: #print 'Calculating rotational entropy for T: ',T Sq = 0.0 Scl = 0.0 S = 0.0 Hq = 0.0 Hcl = 0.0 H = 0.0 cpcl = 0.0 cpq = 0.0 Cp = 0.0 for l in range(self.numRotors): sum = 0.0 vsumexpv = 0.0 v2sumexpv = 0.0 minpot = 5.0 for i in range(numIter): ang = random.rand() pot = self.Harmonics[l].getPotential(ang*360) if (pot < minpot): minpot = pot for i in range(100): ang = i*360.0/100 pot = self.Harmonics[l].getPotential(ang)-minpot print pot exit() # fi = sqrt(K[l])*exp(-pot*1.0e3/R/T) fi = exp(-pot*1.0e3/R/T) sum = sum + fi vsumexpv = vsumexpv + pot*1.0e3 * fi v2sumexpv = v2sumexpv + pot**2*1.0e6 *fi average = sum/(i+1) parti = (2.0*math.pi*kb*T*amu*1e-20/h**2)**(0.5) *(2*math.pi) * average/self.rotors[l+1].symm a = a*average S = S + R*math.log(parti) + R/2 + vsumexpv/sum/T H = H + R*T/2.0 + vsumexpv/sum #reference to the minimum of the well Cp = Cp + R/2.0 + (v2sumexpv*sum-vsumexpv**2)/sum**2/R/T**2 sumfreq = 0.0 for k in range(len(self.hindFreq)): harm = self.Harmonics[k] ddv = 0.0 for l in range(5): ddv = ddv-1*harm.Kcos[l]*(l+1)**2 freq = 1.0/2.0/pi*sqrt(ddv*4180.0/K[k]/1.0e-20/amu/6.023e23)/3.0e10 #print freq, K[l], pi, ddv, K Sq = Sq -R*math.log( 1.0 - math.exp(-h*freq*3.0e10/kb/T)) + 6.023e23*(h*freq*3.0e10/T) / ( math.exp(h*freq*3.0e10/kb/T) - 1.0 )/4.18 Scl = Scl + R + R*math.log(kb*T/h/freq/3.0e10) Hq = Hq + 6.023e23*(h*freq*3.0e10)/( math.exp(h*freq*3.0e10/kb/T) - 1.0 )/4.18 Hcl = Hcl + R*T cpq = cpq + R * (h*freq*3.0e10/kb/T)**2 * math.exp(h*freq*3.0e10/kb/T)/( 1.0 - math.exp(h*freq*3.0e10/kb/T))**2 cpcl = cpcl + R sumfreq = sumfreq +freq H = H + Hq - Hcl S = S + Sq - Scl Cp = Cp + cpq - cpcl ent.append(S) dH.append(H/1e3) cp.append(Cp) oFile.write('\n%12s'%'Entropy') for i in range(len(Temp)): oFile.write('%12.2f'%ent[i]) oFile.write('\n%12s'%'Cp') for i in range(len(Temp)): oFile.write('%12.2f'%cp[i]) oFile.write('\n%12s'%'dH') for i in range(len(Temp)): oFile.write('%12.2f'%dH[i]) #oFile.write('\n') return ent, cp, dH
def getIntRotationalThermo_Q(self,oFile,Temp): ent = [0.0]*len(Temp) cp = [0.0]*len(Temp) dH = [0.0]*len(Temp) parti = [1.0]*len(Temp) R = self.R kb = self.kb h = self.h amu = self.amu # Minimum_Barrier is used to determine when a particular rotor # should be treated as a free rotor. # If the barrier height is less than this value, it is a free rotor. # the default value is 0.5 kcal/mol, which is equal to ~250 Kelvin. Minimum_Barrier = 0.5 oFile.write('\n\nInternal Rotational Contributions\n') oFile.write('%12s'%'Temperature') #iterate over temperatures for T in Temp: oFile.write('%12.2f'%T) sigma = 1.0 for rotor in self.rotors: sigma = sigma*rotor.symm K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors) for irot in range(len(self.rotors)-1): harm = self.Harmonics[irot] ddv = 0.0 for l in range(5): ddv = ddv-1*harm.Kcos[l]*(l+1)**2 freq = 1.0/2.0/pi*sqrt(ddv*4180.0/K[irot]/1.0e-20/amu/6.023e23)/3.0e10 #print '%12.2f'%float(freq), #cfg print self.Harmonics[irot].Barrier_Height #print #calculate the energy levels for the hindered rotors E = self.calculateElevels() #pdb.set_trace() for iT in range(len(Temp)): T = Temp[iT] #print T, for irot in range(len(self.rotors)-1): sum = 0.0 vsum = 0.0 v2sum = 0.0 if self.Harmonics[irot].Barrier_Height > Minimum_Barrier: for e in E[irot]: e = e - E[irot][0] sum = sum + exp(-e*1.0e3/R/T) vsum = vsum + e*1e3*exp(-e*1.0e3/R/T) v2sum = v2sum + e**2*1e6*exp(-e*1.0e3/R/T) # WHY IS THIS irot+1 ?!? ent[iT] = ent[iT] + R*math.log(sum)+vsum/sum/T-R*log(self.rotors[irot+1].symm) dH[iT] = dH[iT] + vsum/sum/1.0e3 cp[iT] = cp[iT] + (v2sum*sum-vsum**2)/sum**2/R/T**2 parti[iT] = parti[iT] *sum else: ent[iT] = ent[iT] + R*log( math.sqrt(8*math.pi**3 * K[irot] *kb*T*amu*1e-20) / self.rotors[irot+1].symm / h) + 0.5*R dH[iT] = dH[iT] + 0.5*R*T/1.0e3 cp[iT] = cp[iT] + 0.5 * R parti[iT] = parti[iT] * math.sqrt(8*math.pi**3 * K[irot] *kb*T*amu*1e-20) / self.rotors[irot+1].symm / h #print (v2sum*sum-vsum**2)/sum**2/R/T**2, #print R*math.log(sum)+vsum/sum/T-R*log(self.rotors[irot+1].symm), #print oFile.write('\n%12s'%'Entropy') for i in range(len(Temp)): oFile.write('%12.2f'%ent[i]) oFile.write('\n%12s'%'Cp') for i in range(len(Temp)): oFile.write('%12.2f'%cp[i]) oFile.write('\n%12s'%'dH') for i in range(len(Temp)): oFile.write('%12.2f'%dH[i]) oFile.write('\n%12s'%'q_int') for i in range(len(Temp)): oFile.write('%12.2e'%parti[i]) oFile.write('\n') return ent, cp , dH, parti
#inputFiles = ['12211.log','02211.log','22211.log','11011.log','11022.log'] #inputFiles = ['111122.log','212211.log', '102022.log', '002022.log', '212122.log', '022022.log'] harmonics = file('harmonics.dat_ring','w') energy_base = readGeomFc.readHFEnergy(inputFiles[0][:-4]+'_rot0_6.log') numRotors = 4 harmonics.write(str(len(inputFiles))+'\n') for files in inputFiles: y = matrix(zeros((13,1),dtype=float)) x = matrix(zeros((13,11),dtype=float)) energy = readGeomFc.readHFEnergy(files[:-4]+'_rot0_6.log') # harmonics.write(files+'\n') (geom,Mass) = readGeomFc.readGeom(open(files,'r')) inertia = open('inertia.dat','r') (rotors) = readGeomFc.readGeneralInertia(inertia,Mass) if (files == inputFiles[0]): K = geomUtility.calculateD32(geom,Mass,rotors) detD = 1.0 for i in range(numRotors): print K[i], detD = detD*K[i] harmonics.write(str(float(detD))+'\n') harmonics.write(str((energy-energy_base)*627.5095)+'\n') if (energy < energy_base): print files, " has lower energy" exit() for i in range(numRotors): potgiven = [] for j in range(13): angle = (-60.0 + j*120.0/12.0)*2*math.pi/360.0 fname = files[:-4]+'_rot'+str(i)+'_'+str(j)+'.log' y[j] = (readGeomFc.readHFEnergy(fname)-energy)*627.5095
def __init__(self,file, isTS): self.Freq = [] self.Harmonics = [] self.hindFreq = [] self.bonds = [] self.Etype = '' self.TS = isTS self.E0 = [] self.variableInertia = False #read dummy line "MOL #" line = readGeomFc.readMeaningfulLine(file) #self.linearity = line.split()[0].upper #read linearity line = readGeomFc.readMeaningfulLine(file) if line.split()[0].upper() == 'NONLINEAR' : self.linearity = 'Nonlinear' elif line.split()[0].upper() == 'LINEAR' : self.linearity = 'Linear' elif line.split()[0].upper() == 'ATOM' : self.linearity = 'Atom' else : print 'Linearity keyword not recognized ' + line exit() #linearity = line.split()[0].upper # read geometry line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() != 'GEOM' : print 'Geom keyword not found in the input file' + line exit() if len(tokens) == 1: #geometry is given following the GEOM keyword line = readGeomFc.readMeaningfulLine(file) numAtoms = int(line.split()[0]) self.geom = matrix(array(zeros((numAtoms,3),dtype=float))) self.Mass = matrix(array(zeros((numAtoms,1),dtype=float))) for i in range(numAtoms): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() self.geom[i,0]=double(tokens[3]) self.geom[i,1]=double(tokens[4]) self.geom[i,2]=double(tokens[5]) atomicNum = int(tokens[1]) if (atomicNum == 6): self.Mass[i]=12.0 if (atomicNum == 8): self.Mass[i]=15.99491 if (atomicNum == 1): self.Mass[i]=1.00783 if (atomicNum == 7): self.Mass[i]=14.0031 if (atomicNum == 17): self.Mass[i]=34.96885 if (atomicNum == 16): self.Mass[i]=31.97207 if (atomicNum == 9): self.Mass[i]=18.99840 #read geometry from the file elif tokens[1].upper() == 'FILE' : print "reading Geometry from the file: ",tokens[2] geomFile = open(tokens[2],'r') (self.geom,self.Mass) = readGeomFc.readGeom(geomFile); #print self.geom elif tokens[1].upper() == 'MM4FILE' :#mm4 option added by gmagoon print "reading MM4 Geometry from the file: ",tokens[2] geomFile = open(tokens[2],'r') (self.geom,self.Mass) = readGeomFc.readMM4Geom(geomFile); #print self.geom else: print 'Either give geometry or give keyword File followed by the file containing geometry data' exit() self.calculateMomInertia() # read force constant or frequency data line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() == 'FORCEC' and tokens[1].upper() == 'FILE': #MRH added following line on 2/Dec/2009 if self.linearity != 'Atom': fcfile = open(tokens[2],'r') self.Fc = readGeomFc.readFc(fcfile) for i in range(0,3*self.Mass.size): for j in range(i,3*self.Mass.size): self.Fc[i,j] = self.Fc[j,i] elif tokens[0].upper() == 'FORCEC' and tokens[1].upper() == 'MM4FILE':#MM4 case if self.linearity != 'Atom': fcfile = open(tokens[2],'r') self.Fc = readGeomFc.readMM4Fc(fcfile) for i in range(0,3*self.Mass.size): for j in range(i,3*self.Mass.size): self.Fc[i,j] = self.Fc[j,i] elif tokens[0].upper() == "FREQ" : line = readGeomFc.readMeaningfulLine(file) numFreq = int(line.split()[0]) i = 0 while (i < numFreq): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() i = i+ len(tokens) for j in tokens: self.Freq.append(float(j)) if self.TS : self.imagFreq = self.Freq.pop(0) if len(self.Freq) > numFreq: print 'More frequencies than ', numFreq, ' are specified' else: print 'Frequency information cannot be read, check input file again' exit() #read energy line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if (tokens[0].upper() != 'ENERGY'): print 'Energy information not given' exit() if tokens[1].upper() == 'FILE' : print 'Reading energy from file: ', tokens[2] energyFile = open(tokens[2],'r') if (tokens[3].upper() == 'CBS-QB3'): self.Etype = 'cbsqb3' elif (tokens[3].upper() == 'CBS-QB3_ULTRAFINE'): self.Etype = 'cbsqb3uf' print 'Warning: "Regular" (non-ultrafine) CBS-QB3 values will be used for P, N as a first approximation' elif (tokens[3].upper() == 'G3'): self.Etype = 'g3' elif (tokens[3].upper() == 'KLIP_1'): self.Etype = 'klip_1' elif (tokens[3].upper() == 'KLIP_2'): self.Etype = 'klip_2' elif (tokens[3].upper() == 'KLIP_2_CC'): self.Etype = 'klip_2_cc' self.Energy = readGeomFc.readEnergy(energyFile, self.Etype) print self.Energy, self.Etype elif (len(tokens) == 3): self.Energy = float(tokens[1]) if (tokens[2].upper() == 'CBS-QB3'): self.Etype = 'cbsqb3' elif (tokens[2].upper() == 'CBS-QB3_ULTRAFINE'): self.Etype = 'cbsqb3uf' print 'Warning: "Regular" (non-ultrafine) CBS-QB3 values will be used for P, N as a first approximation' elif (tokens[2].upper() == 'G3'): self.Etype = 'g3' elif (tokens[2].upper() == 'Klip_1'): self.Etype = 'klip_1' elif (tokens[2].upper() == 'Klip_2'): self.Etype = 'klip_2' elif (tokens[2].upper() == 'KLIP_2_CC'): self.Etype = 'klip_2_cc' elif (tokens[2].upper() == 'MM4'): self.Etype = 'mm4' print self.Etype.upper(),' Energy: ',self.Energy else : print 'Cannot read the Energy' exit() #read external symmetry line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'EXTSYM'): print 'Extsym keyword required' exit() self.extSymm = float(line.split()[1]) #read electronic degeneracy line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'NELEC'): print 'Nelec keyword required' exit() self.nelec = int(line.split()[1]) #read rotor information line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'ROTORS'): print 'Rotors keyword required' exit() self.numRotors = int(line.split()[1]) if self.numRotors == 0: #Line added by MRH o 2/Dec/2009 #If no rotors exist and molecule is not a single atom, still need to: # (1) Check if frequencies are already computed # (2) Read in the BAC information if self.linearity != 'Atom': self.rotors = [] if (len(self.Freq) == 0): #calculate frequencies from force constant self.getFreqFromFc() line = readGeomFc.readMeaningfulLine(file) tokens = line.split() for bond in tokens: self.bonds.append(float(bond)) return # If the molecule is a single atom, no rotors exist, no frequencies need # calculating, and no BAC information needs to be read else: return rotorFile = line.split()[2] inertiaFile = open(rotorFile,'r') #print self.Mass (self.rotors)= readGeomFc.readGeneralInertia(inertiaFile,self.Mass) if len(self.rotors)-1 != self.numRotors : print "The number of rotors specified in file, ",rotorFile,' is different than, ',self.numRotors if (len(self.Freq) == 0): #calculate frequencies from force constant #Added by MRH on 2/Dec/2009 if self.linearity != 'Atom': self.getFreqFromFc() else : if self.linearity != 'Atom': self.getFreqFromFreq() #read potential information for rotors line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() != 'POTENTIAL': print 'No information for potential given' exit() if tokens[1].upper() == 'SEPARABLE': if tokens[2].upper() == 'FILES': line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if len(tokens) != self.numRotors : print 'give a separate potential file for each rotor' for files in tokens: Kcos=[] Ksin =[] harmonic = Harmonics(5,Kcos,Ksin) harmonic.fitPotential(files) self.Harmonics.append(harmonic) elif tokens[2].upper().startswith('MM4FILES'): if tokens[2].upper() == 'MM4FILES_INERTIA':#whether to consider variable inertia or not self.variableInertia=True line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if len(tokens) != self.numRotors : print 'give a separate potential file for each rotor' line = readGeomFc.readMeaningfulLine(file)#the next line contains V0 (kcal/mol) followed by the rotor dihedrals (degrees) for the minimum energy conformation rotinfo = line.split() V0 = float(rotinfo[0]) K = geomUtility.calculateD32(self.geom,self.Mass,self.rotors)#get the rotor moments of inertia for the minimum energy conformation, which will be used during the Fourier fit i = 0 for files in tokens: i=i+1 dihedralMinimum = float(rotinfo[i]) Kcos=[] Ksin =[] harmonic = Harmonics(5,Kcos,Ksin) harmonic.fitMM4Potential(files, V0, dihedralMinimum,self.variableInertia, self.rotors[i], float(K[i-1])) self.Harmonics.append(harmonic) elif tokens[2].upper() == 'HARMONIC': for i in range(self.numRotors): line = readGeomFc.readMeaningfulLine(file) numFit = int(line.split()[0]) Ksin = [] Kcos = [] for i in range(numFit): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() Kcos.append(tokens[0]) Ksin.append(tokens[0]) harmonic = Harmonics(numFit,Kcos,Ksin) self.Harmonics.append(harmonic) elif tokens[1].upper() == 'NONSEPARABLE': line = readGeomFc.readMeaningfulLine(file) self.potentialFile = line.split()[0] # read the energy base #line = readGeomFc.readMeaningfulLine(file) #tokens = line.split() #if (tokens[0].upper() != 'ENERGYBASE'): # print 'Keyword EnergyBase required' # exit() #self.ebase=float(tokens[1]) # read the bonds line = readGeomFc.readMeaningfulLine(file) tokens = line.split() for bond in tokens: self.bonds.append(float(bond)) #read the random seed number '''line = readGeomFc.readMeaningfulLine(file)
def getIntRotationalThermo_Q(self, oFile, Temp): ent = [0.0] * len(Temp) cp = [0.0] * len(Temp) dH = [0.0] * len(Temp) parti = [1.0] * len(Temp) R = self.R kb = self.kb h = self.h amu = self.amu # Minimum_Barrier is used to determine when a particular rotor # should be treated as a free rotor. # If the barrier height is less than this value, it is a free rotor. # the default value is 0.5 kcal/mol, which is equal to ~250 Kelvin. Minimum_Barrier = 0.5 oFile.write('\n\nInternal Rotational Contributions\n') oFile.write('%12s' % 'Temperature') #iterate over temperatures for T in Temp: oFile.write('%12.2f' % T) sigma = 1.0 for rotor in self.rotors: sigma = sigma * rotor.symm K = geomUtility.calculateD32(self.geom, self.Mass, self.rotors) for irot in range(len(self.rotors) - 1): harm = self.Harmonics[irot] ddv = 0.0 for l in range(5): ddv = ddv - 1 * harm.Kcos[l] * (l + 1)**2 freq = 1.0 / 2.0 / pi * sqrt( ddv * 4180.0 / K[irot] / 1.0e-20 / amu / 6.023e23) / 3.0e10 #print '%12.2f'%float(freq), #cfg print self.Harmonics[irot].Barrier_Height #print #calculate the energy levels for the hindered rotors E = self.calculateElevels() #pdb.set_trace() for iT in range(len(Temp)): T = Temp[iT] #print T, for irot in range(len(self.rotors) - 1): sum = 0.0 vsum = 0.0 v2sum = 0.0 if self.Harmonics[irot].Barrier_Height > Minimum_Barrier: for e in E[irot]: e = e - E[irot][0] sum = sum + exp(-e * 1.0e3 / R / T) vsum = vsum + e * 1e3 * exp(-e * 1.0e3 / R / T) v2sum = v2sum + e**2 * 1e6 * exp(-e * 1.0e3 / R / T) # WHY IS THIS irot+1 ?!? ent[iT] = ent[iT] + R * math.log( sum) + vsum / sum / T - R * log( self.rotors[irot + 1].symm) dH[iT] = dH[iT] + vsum / sum / 1.0e3 cp[iT] = cp[iT] + (v2sum * sum - vsum**2) / sum**2 / R / T**2 parti[iT] = parti[iT] * sum / self.rotors[irot + 1].symm else: ent[iT] = ent[iT] + R * log( math.sqrt( 8 * math.pi**3 * K[irot] * kb * T * amu * 1e-20) / self.rotors[irot + 1].symm / h) + 0.5 * R dH[iT] = dH[iT] + 0.5 * R * T / 1.0e3 cp[iT] = cp[iT] + 0.5 * R parti[iT] = parti[iT] * math.sqrt( 8 * math.pi**3 * K[irot] * kb * T * amu * 1e-20) / self.rotors[irot + 1].symm / h #print (v2sum*sum-vsum**2)/sum**2/R/T**2, #print R*math.log(sum)+vsum/sum/T-R*log(self.rotors[irot+1].symm), #print oFile.write('\n%12s' % 'Entropy') for i in range(len(Temp)): oFile.write('%12.2f' % ent[i]) oFile.write('\n%12s' % 'Cp') for i in range(len(Temp)): oFile.write('%12.2f' % cp[i]) oFile.write('\n%12s' % 'dH') for i in range(len(Temp)): oFile.write('%12.2f' % dH[i]) oFile.write('\n%12s' % 'q_int') for i in range(len(Temp)): oFile.write('%12.2e' % parti[i]) oFile.write('\n') return ent, cp, dH, parti
def getIntRotationalThermo_PG(self, oFile, Temp): ent = [] cp = [] dH = [] R = self.R kb = self.kb h = self.h amu = self.amu seed = 500 numIter = 100000 oFile.write('\n\nInternal Rotational Contributions\n') oFile.write('%12s' % 'Temperature') #iterate over temperatures for T in Temp: oFile.write('%12.2f' % T) sigma = 1.0 for rotor in self.rotors: sigma = sigma * rotor.symm K = geomUtility.calculateD32(self.geom, self.Mass, self.rotors) print K p = 1.0 a = 1.0 for T in Temp: #print 'Calculating rotational entropy for T: ',T Sq = 0.0 Scl = 0.0 S = 0.0 Hq = 0.0 Hcl = 0.0 H = 0.0 cpcl = 0.0 cpq = 0.0 Cp = 0.0 for l in range(self.numRotors): sum = 0.0 vsumexpv = 0.0 v2sumexpv = 0.0 minpot = 5.0 for i in range(numIter): ang = random.rand() pot = self.Harmonics[l].getPotential(ang * 360) if (pot < minpot): minpot = pot for i in range(100): ang = i * 360.0 / 100 pot = self.Harmonics[l].getPotential(ang) - minpot print pot exit() # fi = sqrt(K[l])*exp(-pot*1.0e3/R/T) fi = exp(-pot * 1.0e3 / R / T) sum = sum + fi vsumexpv = vsumexpv + pot * 1.0e3 * fi v2sumexpv = v2sumexpv + pot**2 * 1.0e6 * fi average = sum / (i + 1) parti = (2.0 * math.pi * kb * T * amu * 1e-20 / h**2)**( 0.5) * (2 * math.pi) * average / self.rotors[l + 1].symm a = a * average S = S + R * math.log(parti) + R / 2 + vsumexpv / sum / T H = H + R * T / 2.0 + vsumexpv / sum #reference to the minimum of the well Cp = Cp + R / 2.0 + (v2sumexpv * sum - vsumexpv**2) / sum**2 / R / T**2 sumfreq = 0.0 for k in range(len(self.hindFreq)): harm = self.Harmonics[k] ddv = 0.0 for l in range(5): ddv = ddv - 1 * harm.Kcos[l] * (l + 1)**2 freq = 1.0 / 2.0 / pi * sqrt( ddv * 4180.0 / K[k] / 1.0e-20 / amu / 6.023e23) / 3.0e10 #print freq, K[l], pi, ddv, K Sq = Sq - R * math.log( 1.0 - math.exp(-h * freq * 3.0e10 / kb / T)) + 6.023e23 * ( h * freq * 3.0e10 / T) / ( math.exp(h * freq * 3.0e10 / kb / T) - 1.0) / 4.18 Scl = Scl + R + R * math.log(kb * T / h / freq / 3.0e10) Hq = Hq + 6.023e23 * (h * freq * 3.0e10) / ( math.exp(h * freq * 3.0e10 / kb / T) - 1.0) / 4.18 Hcl = Hcl + R * T cpq = cpq + R * (h * freq * 3.0e10 / kb / T)**2 * math.exp( h * freq * 3.0e10 / kb / T) / (1.0 - math.exp(h * freq * 3.0e10 / kb / T))**2 cpcl = cpcl + R sumfreq = sumfreq + freq H = H + Hq - Hcl S = S + Sq - Scl Cp = Cp + cpq - cpcl ent.append(S) dH.append(H / 1e3) cp.append(Cp) oFile.write('\n%12s' % 'Entropy') for i in range(len(Temp)): oFile.write('%12.2f' % ent[i]) oFile.write('\n%12s' % 'Cp') for i in range(len(Temp)): oFile.write('%12.2f' % cp[i]) oFile.write('\n%12s' % 'dH') for i in range(len(Temp)): oFile.write('%12.2f' % dH[i]) #oFile.write('\n') return ent, cp, dH
def __init__(self, file, isTS): self.Freq = [] self.Harmonics = [] self.hindFreq = [] self.bonds = [] self.Etype = '' self.TS = isTS self.E0 = [] self.variableInertia = False #read dummy line "MOL #" line = readGeomFc.readMeaningfulLine(file) #self.linearity = line.split()[0].upper #read linearity line = readGeomFc.readMeaningfulLine(file) if line.split()[0].upper() == 'NONLINEAR': self.linearity = 'Nonlinear' elif line.split()[0].upper() == 'LINEAR': self.linearity = 'Linear' elif line.split()[0].upper() == 'ATOM': self.linearity = 'Atom' else: print 'Linearity keyword not recognized ' + line exit() #linearity = line.split()[0].upper # read geometry line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() != 'GEOM': print 'Geom keyword not found in the input file' + line exit() if len(tokens) == 1: #geometry is given following the GEOM keyword line = readGeomFc.readMeaningfulLine(file) numAtoms = int(line.split()[0]) self.geom = matrix(array(zeros((numAtoms, 3), dtype=float))) self.Mass = matrix(array(zeros((numAtoms, 1), dtype=float))) for i in range(numAtoms): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() self.geom[i, 0] = double(tokens[3]) self.geom[i, 1] = double(tokens[4]) self.geom[i, 2] = double(tokens[5]) atomicNum = int(tokens[1]) if (atomicNum == 6): self.Mass[i] = 12.0 if (atomicNum == 8): self.Mass[i] = 15.99491 if (atomicNum == 1): self.Mass[i] = 1.00783 if (atomicNum == 7): self.Mass[i] = 14.0031 if (atomicNum == 17): self.Mass[i] = 34.96885 if (atomicNum == 16): self.Mass[i] = 31.97207 if (atomicNum == 9): self.Mass[i] = 18.99840 #read geometry from the file elif tokens[1].upper() == 'FILE': print "reading Geometry from the file: ", tokens[2] geomFile = open(tokens[2], 'r') (self.geom, self.Mass) = readGeomFc.readGeom(geomFile) #print self.geom elif tokens[1].upper() == 'MM4FILE': #mm4 option added by gmagoon print "reading MM4 Geometry from the file: ", tokens[2] geomFile = open(tokens[2], 'r') (self.geom, self.Mass) = readGeomFc.readMM4Geom(geomFile) #print self.geom else: print 'Either give geometry or give keyword File followed by the file containing geometry data' exit() self.calculateMomInertia() # read force constant or frequency data line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() == 'FORCEC' and tokens[1].upper() == 'FILE': #MRH added following line on 2/Dec/2009 if self.linearity != 'Atom': fcfile = open(tokens[2], 'r') self.Fc = readGeomFc.readFc(fcfile) for i in range(0, 3 * self.Mass.size): for j in range(i, 3 * self.Mass.size): self.Fc[i, j] = self.Fc[j, i] elif tokens[0].upper() == 'FORCEC' and tokens[1].upper( ) == 'MM4FILE': #MM4 case if self.linearity != 'Atom': fcfile = open(tokens[2], 'r') self.Fc = readGeomFc.readMM4Fc(fcfile) for i in range(0, 3 * self.Mass.size): for j in range(i, 3 * self.Mass.size): self.Fc[i, j] = self.Fc[j, i] elif tokens[0].upper() == "FREQ": line = readGeomFc.readMeaningfulLine(file) numFreq = int(line.split()[0]) i = 0 while (i < numFreq): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() i = i + len(tokens) for j in tokens: self.Freq.append(float(j)) if self.TS: self.imagFreq = self.Freq.pop(0) if len(self.Freq) > numFreq: print 'More frequencies than ', numFreq, ' are specified' else: print 'Frequency information cannot be read, check input file again' exit() #read energy line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if (tokens[0].upper() != 'ENERGY'): print 'Energy information not given' exit() if tokens[1].upper() == 'FILE': print 'Reading energy from file: ', tokens[2] energyFile = open(tokens[2], 'r') if (tokens[3].upper() == 'CBS-QB3'): self.Etype = 'cbsqb3' elif (tokens[3].upper() == 'CBS-QB3_ULTRAFINE'): self.Etype = 'cbsqb3uf' print 'Warning: "Regular" (non-ultrafine) CBS-QB3 values will be used for P, N as a first approximation' elif (tokens[3].upper() == 'G3'): self.Etype = 'g3' elif (tokens[3].upper() == 'KLIP_1'): self.Etype = 'klip_1' elif (tokens[3].upper() == 'KLIP_2'): self.Etype = 'klip_2' elif (tokens[3].upper() == 'KLIP_2_CC'): self.Etype = 'klip_2_cc' self.Energy = readGeomFc.readEnergy(energyFile, self.Etype) print self.Energy, self.Etype elif (len(tokens) == 3): self.Energy = float(tokens[1]) if (tokens[2].upper() == 'CBS-QB3'): self.Etype = 'cbsqb3' elif (tokens[2].upper() == 'CBS-QB3_ULTRAFINE'): self.Etype = 'cbsqb3uf' print 'Warning: "Regular" (non-ultrafine) CBS-QB3 values will be used for P, N as a first approximation' elif (tokens[2].upper() == 'G3'): self.Etype = 'g3' elif (tokens[2].upper() == 'Klip_1'): self.Etype = 'klip_1' elif (tokens[2].upper() == 'Klip_2'): self.Etype = 'klip_2' elif (tokens[2].upper() == 'KLIP_2_CC'): self.Etype = 'klip_2_cc' elif (tokens[2].upper() == 'MM4'): self.Etype = 'mm4' print self.Etype.upper(), ' Energy: ', self.Energy else: print 'Cannot read the Energy' exit() #read external symmetry line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'EXTSYM'): print 'Extsym keyword required' exit() self.extSymm = float(line.split()[1]) #read electronic degeneracy line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'NELEC'): print 'Nelec keyword required' exit() self.nelec = int(line.split()[1]) #read rotor information line = readGeomFc.readMeaningfulLine(file) if (line.split()[0].upper() != 'ROTORS'): print 'Rotors keyword required' exit() self.numRotors = int(line.split()[1]) if self.numRotors == 0: #Line added by MRH o 2/Dec/2009 #If no rotors exist and molecule is not a single atom, still need to: # (1) Check if frequencies are already computed # (2) Read in the BAC information if self.linearity != 'Atom': self.rotors = [] if (len(self.Freq) == 0): #calculate frequencies from force constant self.getFreqFromFc() line = readGeomFc.readMeaningfulLine(file) tokens = line.split() for bond in tokens: self.bonds.append(float(bond)) return # If the molecule is a single atom, no rotors exist, no frequencies need # calculating, and no BAC information needs to be read else: return rotorFile = line.split()[2] inertiaFile = open(rotorFile, 'r') #print self.Mass (self.rotors) = readGeomFc.readGeneralInertia(inertiaFile, self.Mass) if len(self.rotors) - 1 != self.numRotors: print "The number of rotors specified in file, ", rotorFile, ' is different than, ', self.numRotors if (len(self.Freq) == 0): #calculate frequencies from force constant #Added by MRH on 2/Dec/2009 if self.linearity != 'Atom': self.getFreqFromFc() else: if self.linearity != 'Atom': self.getFreqFromFreq() #read potential information for rotors line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if tokens[0].upper() != 'POTENTIAL': print 'No information for potential given' exit() if tokens[1].upper() == 'SEPARABLE': if tokens[2].upper() == 'FILES': line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if len(tokens) != self.numRotors: print 'give a separate potential file for each rotor' for files in tokens: Kcos = [] Ksin = [] harmonic = Harmonics(5, Kcos, Ksin) harmonic.fitPotential(files) self.Harmonics.append(harmonic) elif tokens[2].upper().startswith('MM4FILES'): if tokens[2].upper( ) == 'MM4FILES_INERTIA': #whether to consider variable inertia or not self.variableInertia = True line = readGeomFc.readMeaningfulLine(file) tokens = line.split() if len(tokens) != self.numRotors: print 'give a separate potential file for each rotor' line = readGeomFc.readMeaningfulLine( file ) #the next line contains V0 (kcal/mol) followed by the rotor dihedrals (degrees) for the minimum energy conformation rotinfo = line.split() V0 = float(rotinfo[0]) K = geomUtility.calculateD32( self.geom, self.Mass, self.rotors ) #get the rotor moments of inertia for the minimum energy conformation, which will be used during the Fourier fit i = 0 for files in tokens: i = i + 1 dihedralMinimum = float(rotinfo[i]) Kcos = [] Ksin = [] harmonic = Harmonics(5, Kcos, Ksin) harmonic.fitMM4Potential(files, V0, dihedralMinimum, self.variableInertia, self.rotors[i], float(K[i - 1])) self.Harmonics.append(harmonic) elif tokens[2].upper() == 'HARMONIC': for i in range(self.numRotors): line = readGeomFc.readMeaningfulLine(file) numFit = int(line.split()[0]) Ksin = [] Kcos = [] for i in range(numFit): line = readGeomFc.readMeaningfulLine(file) tokens = line.split() Kcos.append(tokens[0]) Ksin.append(tokens[0]) harmonic = Harmonics(numFit, Kcos, Ksin) self.Harmonics.append(harmonic) elif tokens[1].upper() == 'NONSEPARABLE': line = readGeomFc.readMeaningfulLine(file) self.potentialFile = line.split()[0] # read the energy base #line = readGeomFc.readMeaningfulLine(file) #tokens = line.split() #if (tokens[0].upper() != 'ENERGYBASE'): # print 'Keyword EnergyBase required' # exit() #self.ebase=float(tokens[1]) # read the bonds line = readGeomFc.readMeaningfulLine(file) tokens = line.split() for bond in tokens: self.bonds.append(float(bond)) #read the random seed number '''line = readGeomFc.readMeaningfulLine(file)
#inputFiles = ['12211.log','02211.log','22211.log','11011.log','11022.log'] #inputFiles = ['111122.log','212211.log', '102022.log', '002022.log', '212122.log', '022022.log'] harmonics = file('harmonics.dat_ring', 'w') energy_base = readGeomFc.readHFEnergy(inputFiles[0][:-4] + '_rot0_6.log') numRotors = 4 harmonics.write(str(len(inputFiles)) + '\n') for files in inputFiles: y = matrix(zeros((13, 1), dtype=float)) x = matrix(zeros((13, 11), dtype=float)) energy = readGeomFc.readHFEnergy(files[:-4] + '_rot0_6.log') # harmonics.write(files+'\n') (geom, Mass) = readGeomFc.readGeom(open(files, 'r')) inertia = open('inertia.dat', 'r') (rotors) = readGeomFc.readGeneralInertia(inertia, Mass) if (files == inputFiles[0]): K = geomUtility.calculateD32(geom, Mass, rotors) detD = 1.0 for i in range(numRotors): print(K[i]) detD = detD * K[i] harmonics.write(str(float(detD)) + '\n') harmonics.write(str((energy - energy_base) * ha_to_kcal) + '\n') if (energy < energy_base): print(files, " has lower energy") exit() for i in range(numRotors): potgiven = [] for j in range(13): angle = (-60.0 + j * 120.0 / 12.0) * 2 * math.pi / 360.0 fname = files[:-4] + '_rot' + str(i) + '_' + str(j) + '.log' y[j] = (readGeomFc.readHFEnergy(fname) - energy) * ha_to_kcal