Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
multihydrogen.cpp
Go to the documentation of this file.
1 #include "multihydrogen.h"
2 
3 #include <fstream>
4 
11 MultiHydrogen::MultiHydrogen(mat nucleiPositions) :
12  R(nucleiPositions),
13  m_nNuclei(nucleiPositions.n_rows),
14  m_nOrbitalsPerNuclei(4)
15 {
16  alpha = zeros(m_nOrbitalsPerNuclei);
17  alpha(0) = 13.00773;
18  alpha(1) = 1.962079;
19  alpha(2) = 0.444529;
20  alpha(3) = 0.1219492;
21 }
22 
24 {
25 }
26 
27 double MultiHydrogen::coupledIntegral(int p, int q, int r, int s) {
28  int pIndex = p % m_nOrbitalsPerNuclei;
29  int qIndex = q % m_nOrbitalsPerNuclei;
30  int rIndex = r % m_nOrbitalsPerNuclei;
31  int sIndex = s % m_nOrbitalsPerNuclei;
32 
33  int Rp = p / m_nOrbitalsPerNuclei;
34  int Rq = q / m_nOrbitalsPerNuclei;
35  int Rr = r / m_nOrbitalsPerNuclei;
36  int Rs = s / m_nOrbitalsPerNuclei;
37 
38  double A = alpha[pIndex] + alpha[qIndex];
39  double B = alpha[rIndex] + alpha[sIndex];
40 
41  rowvec Ra = (alpha[pIndex]*R.row(Rp) + alpha[qIndex]*R.row(Rq))/A;
42  rowvec Rb = (alpha[rIndex]*R.row(Rr) + alpha[sIndex]*R.row(Rs))/B;
43 
44 
45  double t = (A*B/(A + B))*dot(Ra-Rb,Ra-Rb);
46 
47  double arg = 2*sqrt(A*B/(acos(-1)*(A+B)))*errorFunction(t)*overlapIntegral(p,q)*overlapIntegral(s,r);
48  return arg;
49 }
50 
52  double repulsionEnergy = 0;
53  for(uint i = 0; i < m_nNuclei; i++) {
54  for(uint j = i + 1; j < m_nNuclei; j++) {
55  rowvec Rij = R.row(i) - R.row(j);
56  repulsionEnergy += 1/sqrt(dot(Rij, Rij));
57  }
58  }
59  return repulsionEnergy;
60 }
61 
62 double MultiHydrogen::errorFunction(double arg){
63 
64  if (arg < 1.0E-6){
65  return 1.0;
66  }
67 
68  else{
69  arg = sqrt(arg);
70  double f = 1.0/arg * erf(arg) *sqrt(acos(-1))/2.0;
71  return f;
72  }
73 
74 }
75 
83 double MultiHydrogen::kineticIntegral(int p, int q) {
84  int pIndex = p % m_nOrbitalsPerNuclei;
85  int qIndex = q % m_nOrbitalsPerNuclei;
86 
87  double ap = alpha(pIndex);
88  double aq = alpha(qIndex);
89 
90  double factor = ap*aq/(ap+aq);
91 
92  int RpIndex = p / m_nOrbitalsPerNuclei;
93  int RqIndex = q / m_nOrbitalsPerNuclei;
94 
95  rowvec Rp = R.row(RpIndex);
96  rowvec Rq = R.row(RqIndex);
97 
98  double Rpq = dot(Rp-Rq,Rp-Rq);
99  double expTerm = exp(-factor*Rpq);
100  double kin = 0.5*factor*(6-4*factor*Rpq)*pow(acos(-1)/(ap+aq),3.0/2.0)*expTerm;
101 
102  return kin;
103 }
104 
113  int pIndex = p % m_nOrbitalsPerNuclei;
114  int qIndex = q % m_nOrbitalsPerNuclei;
115 
116  double ap = alpha(pIndex);
117  double aq = alpha(qIndex);
118 
119  double apPlusAq = ap + aq;
120  double oneOverApPlusAq = 1.0/(apPlusAq);
121 
122  int RpIndex = p / m_nOrbitalsPerNuclei;
123  int RqIndex = q / m_nOrbitalsPerNuclei;
124 
125  rowvec Rp = R.row(RpIndex);
126  rowvec Rq = R.row(RqIndex);
127 
128  int Z = 1;
129 
130  double Rpq =dot(Rp-Rq,Rp-Rq);
131  double expTerm = exp(-ap*aq*oneOverApPlusAq*Rpq);
132 
133  rowvec RP = (ap*Rp + aq*Rq)*oneOverApPlusAq;
134 
135  double errorFunctionSum = 0;
136 
137  for(uint i = 0; i < m_nNuclei; i++) {
138  errorFunctionSum += errorFunction(apPlusAq*dot(RP-R.row(i),RP-R.row(i)));
139  }
140 
141  double nucAtt = -2*Z*oneOverApPlusAq*acos(-1)*expTerm*errorFunctionSum;
142 
143  return nucAtt;
144 }
145 
146 double MultiHydrogen::overlapIntegral(int p, int q) {
147  int pIndex = p % m_nOrbitalsPerNuclei;
148  int qIndex = q % m_nOrbitalsPerNuclei;
149 
150  double ap = alpha(pIndex);
151  double aq = alpha(qIndex);
152 
153  double factor = 1.0/(ap+aq);
154 
155  int RpIndex = p / m_nOrbitalsPerNuclei;
156  int RqIndex = q / m_nOrbitalsPerNuclei;
157 
158  rowvec Rp = R.row(RpIndex);
159  rowvec Rq = R.row(RqIndex);
160 
161  double Rpq = dot(Rp-Rq,Rp-Rq);
162  double expTerm = exp(-ap*aq*factor*Rpq);
163  double overlap = pow(acos(-1)*factor,3.0/2.0)*expTerm;
164 
165  return overlap;
166 }
167 
168 
170 {
171  return kineticIntegral(p,q) + nuclearAttractionIntegral(p,q);
172 }