def HLC_generic(A=0.009170, B=0.004455, C=0.009155, D=0.001947): '''calculate High Level Correction term from alpha and beta VALENCE electron count. ''' global Ehlc say('HLC.') nClosed = nwchem.rtdb_get("scf:nclosed") nOpen = nwchem.rtdb_get("scf:nopen") nElec = nwchem.rtdb_get("scf:nelec") nFrozen = sum_core_orbitals() # According to Curtiss, # nBeta = num valence pairs # nAlpha = num unpaired or remaining valence electrons # subject to the constraint that nAlpha >= nBeta nBeta = nClosed - nFrozen nAlpha = nElec - (nFrozen * 2) - nBeta debug('\nclosed=%d open=%d frozen=%d nAlpha=%d nBeta=%d\n' % (nClosed,nOpen,nFrozen,nAlpha,nBeta)) if nAlpha < nBeta: nAlpha, nBeta = nBeta, nAlpha if is_molecule(): Ehlc = -(A * nBeta) - B * (nAlpha - nBeta) else: # it's an atom, calc is different Ehlc = -(C * nBeta) - D * (nAlpha - nBeta) return False
def E_hlc (): # E_hlc = High Level Correction global Ehlc # Correction coefficients in milli Hartrees # closed shell A = 0.009472 # open shell Ap = 0.009769 B = 0.003179 # atoms and atom ions C = 0.009741 D = 0.002115 # single electron pair species # e.g.: Li2, Na2, LiNa, BeH2, BeH+ E = 0.002379 say('HLC.') nClosed = nwchem.rtdb_get("scf:nclosed") nOpen = nwchem.rtdb_get("scf:nopen") nElec = nwchem.rtdb_get("scf:nelec") nFrozen = sum_core_orbitals() # According to Curtiss, # nBeta = num valence pairs # nAlpha = num unpaired or remaining valence electrons # subject to the constraint that nAlpha >= nBeta nBeta = nClosed - nFrozen nAlpha = nElec - nFrozen - nClosed debug ('\nclosed=%d open=%d frozen=%d nAlpha=%d nBeta=%d\n' % \ (nClosed,nOpen,nFrozen,nAlpha,nBeta)) if nAlpha < nBeta: nAlpha,nBeta = nBeta,nAlpha # test for single (valence) electron pair species if (nOpen == 0) and (nClosed - nFrozen) == 1 and \ (nAlpha == 1) and (nBeta == 1): hlc = E elif is_atom(): hlc = -C * (nBeta) - D * (nAlpha-nBeta) elif Multiplicity > 1: hlc = -Ap * (nBeta) - B * (nAlpha-nBeta) else: # USUAL CASE: singlet, closed shell hlc = -A * (nBeta) Ehlc = hlc return False
def E_hlc(self): """E_hlc = High Level Correction """ # Correction coefficients in milli Hartrees # closed shell A = 0.009472 # open shell Ap = 0.009769 B = 0.003179 # atoms and atom ions C = 0.009741 D = 0.002115 # single electron pair species # e.g.: Li2, Na2, LiNa, BeH2, BeH+ E = 0.002379 self.say('HLC.') nClosed = nwchem.rtdb_get("scf:nclosed") nOpen = nwchem.rtdb_get("scf:nopen") nElec = nwchem.rtdb_get("scf:nelec") self.nFrozen = self.sum_core_orbitals() # According to Curtiss, # nBeta = num valence pairs # nAlpha = num unpaired or remaining valence electrons # subject to the constraint that nAlpha >= nBeta self.nBeta = nClosed - self.nFrozen self.nAlpha = nElec - self.nFrozen - nClosed self.debug('\nclosed=%d open=%d frozen=%d nAlpha=%d nBeta=%d\n' % \ (nClosed, nOpen, self.nFrozen, self.nAlpha, self.nBeta)) if self.nAlpha < self.nBeta: self.nAlpha, self.nBeta = self.nBeta, self.nAlpha #self.say('** a<->b swap: nAlpha=%d nBeta=%d\n' % (self.nAlpha,self.nBeta)) # test for single (valence) electron pair species if (nOpen == 0) and (nClosed - self.nFrozen) == 1 and \ (self.nAlpha == 1) and (self.nBeta == 1): hlc = E elif self.is_atom(): hlc = -C * (self.nBeta) - D * (self.nAlpha - self.nBeta) elif self.multiplicity != "singlet": hlc = -Ap * (self.nBeta) - B * (self.nAlpha - self.nBeta) else: # USUAL CASE: singlet, closed shell hlc = -A * (self.nBeta) self.Ehlc = hlc
def set_atoms_list(): global AtomsList global NumAtoms # rtdb_get() returns a string if only one atom # or a list of atoms (i.e., tags). # Absent type handling, # len('CU') is the same as len(['C','U']) # tags = nwchem.rtdb_get("geometry:geometry:tags") tag_type = type(tags).__name__ if type(tags).__name__ == 'str': AtomsList.append(tags) debug('AtomsList: %s\n' % tags) elif tag_type == 'list': AtomsList.extend(tags) if debug_flag: atmstr = '' for atm in tags: atmstr += ' ' + atm debug('AtomsList: %s\n' % atmstr) else: AtomsList = [] NumAtoms = len(AtomsList) debug('NumAtoms=%d\n' % NumAtoms)
def init_g3mp2(charge=0, mult='singlet', use_qcisdt_f=False): '''say hello ''' set_charge(charge) set_multiplicity(mult) if get_multiplicity() > 1: set_HFtype('uhf') else: set_HFtype('rhf') if use_qcisdt_f: use_qcisdt() else: use_ccsdt() if QCISDT_flag: ccstring = 'QCISD(T)' else: ccstring = 'CCSD(T)' title = nwchem.rtdb_get("title") say(" %s -- NWChem G3(MP2,%s) Composite Method\n" % (title, ccstring)) return False
def set_atoms_list(): global AtomsList global NumAtoms # rtdb_get() returns EITHER # a string if only one atom, or # a list of atoms (i.e., tags). # # Without type handling, # len('CU') is the same as len(['C','U']) # tags = nwchem.rtdb_get("geometry:geometry:tags") tag_type = type(tags).__name__ if tag_type == "str": AtomsList.append(tags) debug("AtomsList: %s\n" % tags) elif tag_type == "list": AtomsList.extend(tags) if debug_flag: atmstr = "" for atm in tags: atmstr += " " + atm debug("AtomsList: %s\n" % atmstr) else: AtomsList = [] NumAtoms = len(AtomsList) debug("NumAtoms=%d\n" % NumAtoms)
def init_g4mp2(self): """Say hello. """ title = nwchem.rtdb_get("title") self.say(" %s -- NWChem G4(MP2) Composite Method\n" % (title)) return False
def get_theory(): theory = nwchem.rtdb_get('task:theory').lower() if theory == 'dft': scf = nwchem.rtdb_get('dft:scftype').lower() else: scf = nwchem.rtdb_get('scf:scftype').lower() if theory == 'scf': return scf elif theory == 'dft': if scf == 'uhf': return 'uks' elif scf == 'rhf': return 'rks' # if here, it wasn't handled raise NotImplementedError('%s %s' % (theory, scf))
def get_theory(): theory = nwchem.rtdb_get('task:theory').lower() if theory == 'dft': scf = nwchem.rtdb_get('dft:scftype').lower() else: scf = nwchem.rtdb_get('scf:scftype').lower() if theory == 'scf': return scf elif theory == 'dft': if scf == 'uhf': return 'uks' elif scf =='rhf': return 'rks' # if here, it wasn't handled raise NotImplementedError('%s %s' % (theory, scf))
def geometry_hash(self): """Produce a hashed geometry identifier from the geometry in the RTDB. This is useful to generate file names for writing and reading geometry to/from disk. :return: sha1 hex digest of geometry :rtype : str """ keys = [nwchem.rtdb_first()] while True: try: keys.append(nwchem.rtdb_next()) except nwchem.NWChemError: break ckey = [k for k in keys if "coords" in k and "geometry" in k][0] tkey = [k for k in keys if "tags" in k and "geometry" in k][0] coords = nwchem.rtdb_get(ckey) tags = nwchem.rtdb_get(tkey) fused = " ".join([str(c) for c in coords]) + " ".join([str(t) for t in tags]) result = hashlib.sha1(fused).hexdigest() return result
def init_g4mp2(charge=0, mult="singlet"): """say hello """ set_charge(charge) set_multiplicity(mult) if get_multiplicity() > 1: set_HFtype("uhf") else: set_HFtype("rhf") title = nwchem.rtdb_get("title") say(" %s -- NWChem G4(MP2) Composite Method\n" % (title)) return False
def init_g4mp2(charge=0,mult='singlet'): '''say hello ''' set_charge(charge) set_multiplicity(mult) if get_multiplicity() > 1: set_HFtype('uhf') else: set_HFtype('rhf') title = nwchem.rtdb_get("title") say(" %s -- NWChem G4(MP2) Composite Method\n" % (title)) return False
def initialize_atoms_list(self): """Use NWChem's RTDB geometry to initialize self.atoms, e.g. CH3OH gives ['C','H','H','H','O''H'] """ # rtdb_get() returns a string if only one atom # or a list of atoms (i.e., tags). # Absent type handling, # len('CU') is the same as len(['C','U']) tags = nwchem.rtdb_get("geometry:geometry:tags") if type(tags) == str: self.atoms.append(tags) self.debug('AtomsList: %s\n' % tags) else: self.atoms.extend(tags) if self.debug_flag: atmstr='' for atm in tags: atmstr += ' '+atm self.debug('AtomsList: %s\n' % atmstr) self.debug('NumAtoms={0}\n'.format(len(self.atoms)))
def get_scftype(): if nwchem.rtdb_get('task:theory').lower() == 'dft': return nwchem.rtdb_get('dft:scftype') else: return nwchem.rtdb_get('scf:scftype')
def get_spin_multiplicity(): return nwchem.rtdb_get('dft:mult')
def get_dipole(): return nwchem.rtdb_get('%s:dipole' % _PROPERTYGROUP)
def prep(): global _PROPERTYGROUP nwchem.rtdb_open('perm/mol.db', 'old') _PROPERTYGROUP = nwchem.rtdb_get('task:theory')
def get_atomic_numbers(): return map(int, nwchem.rtdb_get('geometry:geometry:charges'))
def get_atom_names(): return nwchem.rtdb_get('geometry:geometry:tags')
def get_total_charge(): return int(nwchem.rtdb_get('charge'))
def get_converged(): return 1 == nwchem.rtdb_get('%s:converged' % _PROPERTYGROUP)
def get_functional(): return nwchem.rtdb_get('dft:xc_spec')
def get_symmetry(): return nwchem.rtdb_get('geometry:geometry:group name')
def get_basis(): return nwchem.rtdb_get('basis:ao basis:star bas type')
def get_potential_energy(): return nwchem.rtdb_get('%s:energy' % _PROPERTYGROUP)
def HF_zpe(): ''' run hessian on equilibrium geometry get zero point energy. n note: linear tri-atomics and larger give high ZPE values in NWChem @ HF/6-31G* ''' global Ezpe global Ethermal global Hthermal global AtomsList #AUKCAL = 627.5093314 # bogus AUKCAL = kCalPerHartree c = 2.99792458E+10 h = 6.62606957E-27 kgas = 1.3806488E-16 # cgs units Rgas = 1.9872041 / 1000.0 / AUKCAL # atomic units temperature = T298 say("zpe.") if is_atom(): Ezpe = 0.0 Ethermal = 1.5 * Rgas * temperature Hthermal = Ethermal + (Rgas * temperature) # Ethermal = 0.001416 # 3/2 * RT # Hthermal = 0.002360 # Ethermal + kT return False # run hessian on equilibrium geometry # ignore ZPE, calculate it from vibrations list zpe, vibs, intens = nwchem.task_freq("scf") # Handroll the ZPE because NWChem's zpe accumulates # truncation error from 3 sigfig physical constants. vibsum = 0.0 for freq in vibs: if (freq > 0.1): vibsum += freq cm2Ha = 219474.6 # cm-1 to Hartree conversion Ezpe = vibsum / (2.0 * cm2Ha) # get total thermal energy, enthalpy eth = nwchem.rtdb_get("vib:ethermal") hth = nwchem.rtdb_get("vib:hthermal") debug("NWChem zpe,E,H thermal= %.6f, %.6f, %.6f\n" % (Ezpe,eth, hth)) eth = 0.0 hth = 0.0 xdum = 0.0 for freq in vibs: if (freq > 0.1): # freqency temperature in Kelvin from cm-1 thetav = freq * (h * c / kgas) if (temperature > 0.0): xdum = math.exp(-thetav / temperature) else: xdum = 0.0 xdum = xdum / (1.0 - xdum) eth = eth + thetav * (0.5 + xdum) # linear boolean is available only after task_freq('scf') runs # NWChem only writes the flag if molecule is linear eth = eth * Rgas try: is_linear = nwchem.rtdb_get("vib:linear") except: is_linear = False if (is_linear and QCISDT_flag): # translational(3/2RT) and rotation(2/2RT) thermal corrections eth = eth + 2.5 * Rgas * temperature else: # translational(3/2RT) and rotation(3/2RT) thermal corrections eth = eth + 3.0 * Rgas * temperature # Hthermal = eth+pV=eth+RT, since pV=RT hth = eth + Rgas * temperature debug("RgasT= %.9f, kT_298_perMol= %.9f\n" % (Rgas * temperature, kT_298_perMol)) debug("Handrolled E,H thermal= %.6f, %.6f\n" % (eth, hth)) Ethermal = eth Hthermal = hth return False
def get_spin_multiplicity(): try: return nwchem.rtdb_get('dft:mult') except SystemError: return None
def get_atom_masses(): return nwchem.rtdb_get('geometry:geometry:masses')
def get_positions(): return _reshape_atom_vector(nwchem.rtdb_get('geometry:geometry:coords'))
def get_forces(): try: forces = nwchem.rtdb_get('%s:gradient' % _PROPERTYGROUP) return _reshape_atom_vector([-f for f in forces]) except SystemError: return None
def get_functional(): try: return nwchem.rtdb_get('dft:xc_spec') except SystemError: return None
def get_dipole(): try: return nwchem.rtdb_get('%s:dipole' % _PROPERTYGROUP) except SystemError: return None
def E_zpe(self): """Run hessian on equilibrium geometry, get zero point energy. n Note: linear tri-atomics and larger give high ZPE values in NWChem @ HF/6-31G* """ self.say('ZPE.') AUKCAL = 627.5093314 c = 2.99792458E+10 h = 6.62606957E-27 kgas = 1.3806488E-16 # cgs units Rgas = 1.9872041/1000.0/AUKCAL # atomic units temperature = 298.15 if self.is_atom(): self.Ezpe = 0.0 self.Ethermal = 1.5 * Rgas * temperature # 3/2 * RT self.Hthermal = self.Ethermal + (Rgas * temperature) return False # run hessian on equilibrium geometry # ignore ZPE, calculate it from vibrations list zpe, vibs, intens = nwchem.task_freq("dft") # Handroll the ZPE because NWChem's zpe accumulates # truncation error from 3 sigfig physical constants. vibsum = 0.0 for freq in vibs: if (freq > 0.1): vibsum += freq cm2Ha = 219474.6 # cm-1 to Hartree conversion self.Ezpe = vibsum / (2.0 * cm2Ha) # shamelessly swipe code from NWCHEM/src/vib_wrtFreq.F eth = 0.0 hth = 0.0 xdum = 0.0 for freq in vibs: if (freq > 0.1): thetav = freq * (h * c / kgas) #freqency temperature in Kelvin from cm-1 if (temperature > 0.0): xdum = math.exp(-thetav/temperature) else: xdum = 0.0 xdum = xdum / (1.0 - xdum) eth = eth + thetav * (0.5 + xdum) eth = eth * Rgas # linear boolean is available only after task_freq('scf') runs # NWChem only writes the flag if molecule is linear try: is_linear = nwchem.rtdb_get("vib:linear") except: is_linear = False if (is_linear): # translational(3/2RT) and rotation(2/2RT) thermal corrections eth = eth + 2.5 * Rgas * temperature else: # translational(3/2RT) and rotation(3/2RT) thermal corrections eth = eth + 3.0 * Rgas * temperature # Hthermal = eth+pV=eth+RT, since pV=RT hth = eth + Rgas * temperature self.debug("Handrolled E,H thermal= %.6f, %.6f\n" % (eth,hth)) self.Ethermal = eth self.Hthermal = hth
thetav = freq * (h * c / kgas) # freqency temperature in Kelvin from cm-1 if temperature > 0.0: xdum = math.exp(-thetav / temperature) else: xdum = 0.0 xdum = xdum / (1.0 - xdum) eth = eth + thetav * (0.5 + xdum) eth = eth * Rgas # linear boolean is available only after task_freq('???') runs # NWChem only writes the flag if molecule is linear try: is_linear = nwchem.rtdb_get("vib:linear") except: is_linear = False if is_linear: # translational(3/2RT) and rotation(2/2RT) thermal corrections eth = eth + 2.5 * Rgas * temperature else: # translational(3/2RT) and rotation(3/2RT) thermal corrections eth = eth + 3.0 * Rgas * temperature # Hthermal = eth+pV=eth+RT, since pV=RT hth = eth + Rgas * temperature debug("ZPE,E,H thermal= %.6f, %.6f, %.6f\n" % (Ezpe, eth, hth))
def get_basisname(): return nwchem.rtdb_get('basis:ao basis:star bas type')
def get_forces(): try: forces = nwchem.rtdb_get('%s:gradient' % _PROPERTYGROUP) return _reshape_atom_vector([-f for f in forces]) except: return None