Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
turbomoleparser.cpp
Go to the documentation of this file.
1 #include "turbomoleparser.h"
2 
3 #include <fstream>
4 #include <iostream>
5 #include <boost/regex.hpp>
6 #include <clocale>
7 
8 using namespace std;
9 using namespace boost;
10 
12 {
13 }
14 
15 bool TurboMoleParser::load(string fileName)
16 {
17  setlocale(LC_ALL, "C");
18  m_contractedBasisFunctions.clear();
19  ifstream dataFile(fileName);
20  if(!dataFile.is_open()) {
21  return false;
22  }
23  string line;
24 
25  vector<int> nValenceOrbitals;
26  string atomTypeAbbreviation;
27  while (getline(dataFile, line))
28  {
29  bool ignoredLine = false;
30  ignoredLine |= regex_match(line, regex("#.*"));
31  ignoredLine |= regex_match(line, regex("$basis.*"));
32  ignoredLine |= regex_match(line, regex("$end.*"));
33  ignoredLine |= regex_match(line, regex("\\*.*"));
34  if(ignoredLine) {
35  continue;
36  }
37  smatch what;
38  regex basisRegex("^\\s*([a-zA-Z]+)");
39  while(regex_search(line, what, basisRegex)) { // n 4-31G
40  atomTypeAbbreviation = string(what[1]);
41  m_atomType = HF::abbreviationToAtomType(atomTypeAbbreviation);
42  break;
43  }
44  regex orbitalRegex("\\s*([0-9])\\s*([spdf])\\s*");
45  if(regex_search(line, what, orbitalRegex)) { // 4 s
46  mergePrimitivesIntoContracted();
47  if(what[2] == "s") {
48  m_currentOrbitalType = HF::sOrbitalType;
49  } else if(what[2] == "p") {
50  m_currentOrbitalType = HF::pOrbitalType;
51  } else if(what[2] == "d") {
52  m_currentOrbitalType = HF::dOrbitalType;
53  } else if(what[2] == "f") {
54  m_currentOrbitalType = HF::fOrbitalType;
55  } else {
56  cerr << "Unknown orbital type " << string(what[1]) << endl;
57  return false;
58  }
59  }
60  regex exponentWeightRegex("\\s*(-?[0-9]+\\.?[0-9]+)\\s*(-?[0-9]+\\.?[0-9]+)\\s*"); // 2.1 4.9
61  if(regex_search(line, what, exponentWeightRegex)) {
62  double exponent = stod(string(what[1]));
63  double weight = stod(string(what[2]));
64 
65  GaussianPrimitiveOrbital primitive;
66  primitive.setWeight(weight);
67  primitive.setExponent(exponent);
68  m_collectedPrimitiveBasisFunctions.push_back(primitive);
69  }
70  }
71  mergePrimitivesIntoContracted();
72  // for(GaussianContractedOrbital orbital : m_contractedBasisFunctions) {
73  // cout << "Contracted:" << endl;
74  // for(GaussianPrimitiveOrbital primitive : orbital.primitiveBasisFunctions()) {
75  // cout << primitive.weight() << " * " << primitive.exponent() << endl;
76  // }
77  // }
78  // cout << "Done!" << endl;
79  return true;
80 }
81 
82 const vector<GaussianContractedOrbital> &TurboMoleParser::contractedBasisFunctions() const
83 {
84  return m_contractedBasisFunctions;
85 }
86 
87 void TurboMoleParser::mergePrimitivesIntoContracted()
88 {
89  if(m_collectedPrimitiveBasisFunctions.size() > 0) {
90  switch(m_currentOrbitalType) {
91  case HF::sOrbitalType: {
92  GaussianContractedOrbital contractedOrbital;
93  for(GaussianPrimitiveOrbital primitive : m_collectedPrimitiveBasisFunctions) {
94  double weightAdjusted = primitive.weight() * pow(2 * primitive.exponent() / M_PI, 3.0/4.0);
95  primitive.setWeight(weightAdjusted);
96  contractedOrbital.addPrimitiveBasisFunction(primitive);
97  }
98  m_contractedBasisFunctions.push_back(contractedOrbital);
99  break;
100  }
101  case HF::pOrbitalType: {
102  int dim = 3;
103  for(int i = 0; i < dim; i++) {
104  GaussianContractedOrbital contractedOrbital;
105  for(GaussianPrimitiveOrbital primitive : m_collectedPrimitiveBasisFunctions) {
106  double weightAdjusted = primitive.weight() * pow(2 * primitive.exponent() / M_PI, 3.0/4.0) * 2 * sqrt(primitive.exponent());
107  primitive.setWeight(weightAdjusted);
108  primitive.setXExponent(i == 0);
109  primitive.setYExponent(i == 1);
110  primitive.setZExponent(i == 2);
111  contractedOrbital.addPrimitiveBasisFunction(primitive);
112  }
113  m_contractedBasisFunctions.push_back(contractedOrbital);
114  }
115  break;
116  }
117  case HF::dOrbitalType: {
118  umat exponents;
119  exponents << 2 << 0 << 0 << endr
120  << 0 << 2 << 0 << endr
121  << 0 << 0 << 2 << endr
122  << 1 << 1 << 0 << endr
123  << 1 << 0 << 1 << endr
124  << 0 << 1 << 1 << endr;
125  for(int i = 0; i < int(exponents.n_rows); i++) {
126  GaussianContractedOrbital contractedOrbital;
127  for(GaussianPrimitiveOrbital primitive : m_collectedPrimitiveBasisFunctions) {
128  double weightAdjusted = primitive.weight() * normalizationFactor(primitive.exponent(), exponents.row(i));
129  primitive.setWeight(weightAdjusted);
130  primitive.setXExponent(exponents(i, 0));
131  primitive.setYExponent(exponents(i, 1));
132  primitive.setZExponent(exponents(i, 2));
133  contractedOrbital.addPrimitiveBasisFunction(primitive);
134  }
135  m_contractedBasisFunctions.push_back(contractedOrbital);
136  }
137  break;
138  }
139  case HF::fOrbitalType: {
140  cout << "ERROR: f orbitals not yet supported" << endl;
141  break;
142  }
143  default: {
144  cout << "ERROR: Unknown orbital type." << endl;
145  break;
146  }
147  }
148  m_collectedPrimitiveBasisFunctions.clear();
149  }
150 }
152 {
153  return m_atomType;
154 }
155 
156 //TODO: Change urowvec to std::array<int, 3>
157 double TurboMoleParser::normalizationFactor(double exp, urowvec pows)
158 {
159  int i = pows.at(0);
160  int j = pows.at(1);
161  int k = pows.at(2);
162  return pow((2*exp/M_PI),0.75)*sqrt(pow(8*exp,i+j+k)*factorial(i)*factorial(j)*factorial(k)/(factorial(2*i)*factorial(2*j)*factorial(2*k)));
163 }
164 
166 {
167  double value = 1;
168  double i = 1;
169 
170  while(i < n){
171  i += 1;
172  value *= i;
173  }
174  return value;
175 }