Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
gaussiansystem.cpp
Go to the documentation of this file.
1 #include "gaussiansystem.h"
2 
3 #include "math/vector3.h"
10 
11 #include <iostream>
12 #include <cmath>
13 
14 using namespace std;
15 
22  m_nParticles(0),
23  m_nBasisFunctions(0),
24  m_angularMomentumMax(0),
25  m_overlapIntegral(0),
26  m_kineticIntegral(0),
27  m_coulombIntegral(0),
28  m_electronInteractionIntegral(0)
29 {
30 }
31 
32 double GaussianSystem::coupledIntegral(int p, int q, int r, int s)
33 {
34  double result = 0;
35  const GaussianContractedOrbital& pBF = m_basisFunctions.at(p);
36  const GaussianContractedOrbital& qBF = m_basisFunctions.at(q);
37  const GaussianContractedOrbital& rBF = m_basisFunctions.at(r);
38  const GaussianContractedOrbital& sBF = m_basisFunctions.at(s);
39  for(const GaussianPrimitiveOrbital& pP : pBF.primitiveBasisFunctions()) {
40  for(const GaussianPrimitiveOrbital& qP : qBF.primitiveBasisFunctions()) {
41  m_electronInteractionIntegral.setAB(pBF.corePosition(), qBF.corePosition(), pP, qP);
42  for(const GaussianPrimitiveOrbital& rP : rBF.primitiveBasisFunctions()) {
43  for(const GaussianPrimitiveOrbital& sP : sBF.primitiveBasisFunctions()) {
44  m_electronInteractionIntegral.setCD(rBF.corePosition(), sBF.corePosition(),
45  rP, sP);
46  result += pP.weight() * rP.weight() * qP.weight() * sP.weight()
47  * m_electronInteractionIntegral.electronInteractionIntegral(pP, qP, rP, sP);
48  }
49  }
50  }
51  }
52  return result;
53 }
54 
56 {
57  double result = 0;
58  const GaussianContractedOrbital& pBF = m_basisFunctions.at(p);
59  const GaussianContractedOrbital& qBF = m_basisFunctions.at(q);
60  for(const GaussianPrimitiveOrbital& pP : pBF.primitiveBasisFunctions()) {
61  for(const GaussianPrimitiveOrbital& qP : qBF.primitiveBasisFunctions()) {
62  m_kineticIntegral.set(pBF.corePosition(), qBF.corePosition(), pP, qP);
63  result += pP.weight() * qP.weight() * m_kineticIntegral.kineticIntegral(pP, qP);
64  for(uint i = 0; i < m_cores.size(); i++) {
65  const GaussianCore &core = m_cores.at(i);
66  const Vector3 &corePositionC = core.position();
67  m_coulombIntegral.set(pBF.corePosition(), qBF.corePosition(), corePositionC,
68  pP, qP);
69  result -= core.charge() * pP.weight() * qP.weight() * m_coulombIntegral.coloumbAttractionIntegral(pP, qP);
70  }
71  }
72  }
73  return result;
74 }
75 
76 double GaussianSystem::overlapIntegral(int p, int q)
77 {
78  double result = 0;
79  const GaussianContractedOrbital& pBF = m_basisFunctions.at(p);
80  const GaussianContractedOrbital& qBF = m_basisFunctions.at(q);
81  for(const GaussianPrimitiveOrbital& pP : pBF.primitiveBasisFunctions()) {
82  for(const GaussianPrimitiveOrbital& qP : qBF.primitiveBasisFunctions()) { // TODO Optimize for symmetry if pBF = qBF
83  m_overlapIntegral.set(pBF.corePosition(), qBF.corePosition(), pP, qP);
84  result += pP.weight() * qP.weight() * m_overlapIntegral.overlapIntegral(pP, qP);
85  }
86  }
87  return result;
88 }
89 
91 {
92  return m_nBasisFunctions;
93 }
94 
96 {
97  return m_nParticles;
98 }
99 
101 {
102  double result = 0;
103  for(uint i = 0; i < m_cores.size(); i++) {
104  const GaussianCore &core1 = m_cores.at(i);
105  for(uint j = i + 1; j < m_cores.size(); j++) {
106  const GaussianCore &core2 = m_cores.at(j);
107  result += core1.charge()*core2.charge() / sqrt(dot(core1.position() - core2.position(), core1.position() - core2.position()));
108  }
109  }
110  return result;
111 }
112 
113 double GaussianSystem::electrostaticPotential(const mat& C, const Vector3 &position)
114 {
115  double result = 0;
116  result += corePotential(position);
117  result -= electronPotential(C, position);
118  return result;
119 }
120 
121 double GaussianSystem::corePotential(const Vector3 &position)
122 {
123  double potential = 0;
124  for(const GaussianCore &core : m_cores) {
125  Vector3 diff = position - core.position();
126  double distance = sqrt(dot(diff, diff));
127  potential += core.charge() / distance;
128  }
129  return potential;
130 }
131 
132 double GaussianSystem::electronPotential(const mat& C, const Vector3 position)
133 {
134  double result = 0;
135  for(uint p = 0; p < (m_basisFunctions.size()); p++) {
136  double potential = electronPotential(p,p,position);
137  for(uint orbital = 0; orbital < C.n_cols; orbital++) {
138  result += C(p, orbital) * C(p,orbital) * potential;
139  }
140  for(uint q = p+1; q < (m_basisFunctions.size()); q++) {
141  potential = electronPotential(p,q,position);
142  for(uint orbital = 0; orbital < C.n_cols; orbital++) {
143  result += 2.0 * C(p, orbital) * C(q, orbital) * potential;
144  }
145  }
146  }
147  return result;
148 }
149 
150 double GaussianSystem::electronPotential(uint p, uint q, const Vector3 &position)
151 {
152  double result = 0;
153  const GaussianContractedOrbital &pBF = m_basisFunctions.at(p);
154  const GaussianContractedOrbital& qBF = m_basisFunctions.at(q);
155  for(const GaussianPrimitiveOrbital& pP : pBF.primitiveBasisFunctions()) {
156  for(const GaussianPrimitiveOrbital& qP : qBF.primitiveBasisFunctions()) {
157  const Vector3 &corePositionC = position;
158  m_coulombIntegral.set(pBF.corePosition(), qBF.corePosition(), corePositionC, pP, qP);
159  result += pP.weight() * qP.weight() * m_coulombIntegral.coloumbAttractionIntegral(pP, qP);
160  }
161  }
162  return result;
163 }
164 
165 //double GaussianSystem::orbitalDensity(uint orbital, const mat& C, double x, double y, double z) const
166 //{
167 // double innerProduct = 0;
168 // for(uint p = 0; p < (m_basisFunctions.size()); p++) {
169 // const GaussianContractedOrbital &bfp = m_basisFunctions.at(p);
170 // double evaluationp = bfp.evaluated(x,y,z);
171 // double Cp = C(p,orbital);
172 // innerProduct += C(p,orbital) * C(p,orbital) * evaluationp * evaluationp;
173 // for(uint q = p+1; q < (m_basisFunctions.size()); q++) {
174 // const GaussianContractedOrbital &bfq = m_basisFunctions.at(q);
175 // double evaluationq = bfq.evaluated(x,y,z);
176 // innerProduct += 2.0 * Cp * C(q,orbital) * evaluationp * evaluationq;
177 // }
178 // }
179 // return innerProduct * innerProduct;
180 //}
181 
182 rowvec GaussianSystem::orbitalDensities(const mat& C, const Vector3 &position) const
183 {
184  rowvec result = zeros(C.n_cols);
185  for(uint p = 0; p < (m_basisFunctions.size()); p++) {
186  const GaussianContractedOrbital &bfp = m_basisFunctions.at(p);
187  double evaluationp = bfp.evaluated(position);
188  for(uint orbital = 0; orbital < C.n_cols; orbital++) {
189  result(orbital) += C(p,orbital) * C(p,orbital) * evaluationp * evaluationp;
190  }
191  for(uint q = p+1; q < (m_basisFunctions.size()); q++) {
192  const GaussianContractedOrbital &bfq = m_basisFunctions.at(q);
193  double evaluationq = bfq.evaluated(position);
194  for(uint orbital = 0; orbital < C.n_cols; orbital++) {
195  result(orbital) += 2.0 * C(p,orbital) * C(q,orbital) * evaluationp * evaluationq;
196  }
197  }
198  }
199  return result;
200 }
201 
202 double GaussianSystem::electronDensity(const mat& C, const Vector3 &position) const
203 {
204  double result = sum(orbitalDensities(C, position));
205 // for(uint p = 0; p < (m_basisFunctions.size()); p++) {
206 // const GaussianContractedOrbital &bfp = m_basisFunctions.at(p);
207 // double evaluationp = bfp.evaluated(position);
208 // for(uint orbital = 0; orbital < C.n_cols; orbital++) {
209 // result += C(p,orbital) * C(p,orbital) * evaluationp * evaluationp;
210 // }
211 // for(uint q = p+1; q < (m_basisFunctions.size()); q++) {
212 // const GaussianContractedOrbital &bfq = m_basisFunctions.at(q);
213 // double evaluationq = bfq.evaluated(position);
214 // for(uint orbital = 0; orbital < C.n_cols; orbital++) {
215 // result += 2.0 * C(p,orbital) * C(q,orbital) * evaluationp * evaluationq;
216 // }
217 // }
218 // }
219  return result;
220 }
221 
223 {
224  m_nBasisFunctions += core.contractedOrbitals().size();
225  m_nParticles += core.nElectrons();
226  m_basisFunctions.insert(m_basisFunctions.end(), core.contractedOrbitals().begin(), core.contractedOrbitals().end());
227  m_cores.push_back(core);
228  int angularMomentumMax = 0;
229  for(const GaussianContractedOrbital &contracted : m_basisFunctions) {
230  for(const GaussianPrimitiveOrbital &primitive : contracted.primitiveBasisFunctions()) {
231  angularMomentumMax = max(angularMomentumMax, primitive.xExponent());
232  angularMomentumMax = max(angularMomentumMax, primitive.yExponent());
233  angularMomentumMax = max(angularMomentumMax, primitive.zExponent());
234  }
235  }
236  setAngularMomentumMax(angularMomentumMax);
237 }
238 
239 void GaussianSystem::setAngularMomentumMax(int angularMomentumMax)
240 {
241  m_angularMomentumMax = angularMomentumMax;
242  m_overlapIntegral = GaussianOverlapIntegral(angularMomentumMax);
243  m_electronInteractionIntegral = GaussianElectronInteractionIntegral(angularMomentumMax);
244  m_kineticIntegral = GaussianKineticIntegral(angularMomentumMax);
245  m_coulombIntegral = GaussianColoumbAttractionIntegral(angularMomentumMax);
246 }