ForceBalance API  1.3
Automated optimization of force fields and empirical potentials
qchemio.py
Go to the documentation of this file.
1 """ @package forcebalance.qchemio Q-Chem input file parser. """
2 
3 from builtins import str
4 from builtins import range
5 import os
6 from re import match, sub
7 from forcebalance import BaseReader
8 from forcebalance.nifty import *
9 from forcebalance.molecule import Molecule
10 
11 from forcebalance.output import getLogger
12 logger=getLogger(__name__)
13 
14 
17 ndtypes = [None]
18 
19 
22 
23 
24 pdict = {'BASS':{0:'A', 1:'C'},
25  'BASSP' :{0:'A', 1:'B', 2:'C'}
26  }
27 
28 class QCIn_Reader(BaseReader):
29  """Finite state machine for parsing Q-Chem input files.
30 
31  """
32 
33  def __init__(self,fnm):
34  # Initialize the superclass. :)
35  super(QCIn_Reader,self).__init__(fnm)
36  self.atom = ''
37  self.snum = -1
38  self.cnum = -1
39  self.shell = None
40  self.pdict = pdict
41 
42  def feed(self, line):
43  """ Feed in a line.
44 
45  @param[in] line The line of data
46 
47  """
48  line = line.split('!')[0].strip()
49  s = line.split()
50  #self.itype = None
51  self.ln += 1
52  # No sense in doing anything for an empty line or a comment line.
53  if len(s) == 0 or match('^!',line): return None, None
54  # Now go through all the cases.
55  if match('^\$',line):
56  # Makes a word like "atoms", "bonds" etc.
57  self.sec = sub('^\$','',line)
58  elif self.sec == 'basis':
59  if match('^[A-Za-z][a-z]* +0$',line):
60  self.atom = s[0]
61  self.snum = -1
62  elif match('^[SPDFGH]P? +[0-9]+ +1\.0+$',line):
63  self.snum += 1
64  self.cnum = -1
65  self.shell = s[0]
66  self.itype = 'BAS'+self.shell
67  logger.info(line + '\n')
68  elif all([isfloat(i) for i in s]):
69  self.cnum += 1
70  logger.info("%s %s %s\n" % (line, str(self.snum), str(self.cnum)))
71  self.suffix = '_at%s.sh%i.cf%i' % (self.atom,self.snum,self.cnum)
72 
73 def QChem_Dielectric_Energy(fnm,wq):
74  QCIn = Molecule(fnm)
75  for i in range(QCIn.na):
76  # Q-Chem crashes if it doesn't recognize the chemical element
77  if QCIn.Data['elem'][i] in ['M','L']:
78  QCIn.Data['elem'][i] = 'He'
79  CalcDir=os.path.splitext(fnm)[0]+".d"
80  GoInto(CalcDir)
81  digits = len(str(QCIn.ns))
82  for i in range(QCIn.ns):
83  sdir = "%%0%ii" % digits % i
84  GoInto(sdir)
85  QCIn.write("qchem.in",selection=i)
86  queue_up(wq,"qchem40 qchem.in qchem.out",input_files=["qchem.in"],output_files=["qchem.out"],verbose=False)
87  Leave(sdir)
88  wq_wait(wq,verbose=False)
89  PCM_Energies = []
90  for i in range(QCIn.ns):
91  sdir = "%%0%ii" % digits % i
92  GoInto(sdir)
93  for line in open("qchem.out"):
94  if "PCM electrostatic energy" in line:
95  PCM_Energies.append(float(line.split()[-2]))
96  Leave(sdir)
97  Leave(CalcDir)
98  return np.array(PCM_Energies) * 2625.5
def feed(self, line)
Feed in a line.
Definition: qchemio.py:50
def Leave(Dir)
Definition: nifty.py:1270
Nifty functions, intended to be imported by any module within ForceBalance.
def QChem_Dielectric_Energy(fnm, wq)
Definition: qchemio.py:76
def GoInto(Dir)
Definition: nifty.py:1254
def queue_up(wq, command, input_files, output_files, tag=None, tgt=None, verbose=True, print_time=60)
Submit a job to the Work Queue.
Definition: nifty.py:941
def wq_wait(wq, wait_time=10, wait_intvl=10, print_time=60, verbose=False)
This function waits until the work queue is completely empty.
Definition: nifty.py:1056
def __init__(self, fnm)
Definition: qchemio.py:35
Finite state machine for parsing Q-Chem input files.
Definition: qchemio.py:33
def isfloat(word)
Matches ANY number; it can be a decimal, scientific notation, integer, or what have you...
Definition: molecule.py:406