Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
hartreefocksolver.cpp
Go to the documentation of this file.
1 #include "hartreefocksolver.h"
2 
4 
5 #include <armadillo>
6 #include <iomanip>
7 #include <cmath>
8 
9 using namespace arma;
10 using namespace std;
11 
18  m_electronSystem(basisFunction),
19  m_convergenceTreshold(1e-8),
20  m_nIterationsMax(1e3),
21  m_densityMixFactor(0.5),
22  m_hasBeenSetup(false)
23 {
24 }
25 
27 {
28  cleanUpCoupledMatrix();
29 }
30 
32 {
33  allocateCoupledMatrix();
35  m_hasBeenSetup = true;
36 }
37 
39 {
40  if(!m_hasBeenSetup) {
41  setup();
42  }
43 }
44 
46 {
47  if(!m_hasBeenSetup) {
48  setup();
49  }
50 }
51 
53 {
54  setupUncoupledMatrix();
55  setupOverlapMatrix();
56  setupTransformationMatrix();
57  setupCoupledMatrix();
58 }
59 
60 void HartreeFockSolver::allocateCoupledMatrix() {
61  ElectronSystem* f = m_electronSystem;
62  uint n = f->nBasisFunctions();
63  m_coupledMatrix.set_size(n,n);
64  for(int i = 0; i < int(n); i++) {
65  for(int j = 0; j < int(n); j++) {
66  m_coupledMatrix(i,j) = zeros(n,n);
67  }
68  }
69 }
70 
71 void HartreeFockSolver::setupTransformationMatrix()
72 {
73  vec s;
74  mat U;
75  eig_sym(s, U, overlapMatrix());
76  m_transformationMatrix = U*diagmat(1.0/sqrt(s));
77 }
78 
79 void HartreeFockSolver::cleanUpCoupledMatrix() {
80  m_coupledMatrix.reset();
81 }
82 
83 void HartreeFockSolver::setupOverlapMatrix() {
84  ElectronSystem* f = m_electronSystem;
85  uint nOrbitals = f->nBasisFunctions();
86  m_overlapMatrix.reset();
87  m_overlapMatrix = zeros(nOrbitals,nOrbitals);
88  for(uint p = 0; p < nOrbitals; p++) {
89  for(uint q = 0; q < nOrbitals; q++) { // TODO: Optimize by symmetry and start from q = p
90  m_overlapMatrix(p,q) = f->overlapIntegral(p, q);
91  }
92  }
93 }
94 
95 void HartreeFockSolver::setupUncoupledMatrix() {
96  ElectronSystem* f = m_electronSystem;
97  uint nOrbitals = f->nBasisFunctions();
98  m_uncoupledMatrix.reset();
99  m_uncoupledMatrix = zeros(nOrbitals,nOrbitals);
100  for(uint p = 0; p < nOrbitals; p++) {
101  for(uint q = 0; q < nOrbitals; q++) { // TODO: Optimize by symmetry and start from q = p
102  m_uncoupledMatrix(p,q) = f->uncoupledIntegral(p,q);
103  }
104  }
105 }
106 
107 void HartreeFockSolver::setupCoupledMatrix() {
108  ElectronSystem* f = m_electronSystem;
109  uint n = f->nBasisFunctions();
110  for(uint p = 0; p < n; p++) {
111  for(uint r = 0; r < n; r++) {
112  for(uint q = p; q < n; q++) {
113  for(uint s = r; s < n; s++) {
114  // NOTE: Indexes changed on purpose in element and call due to
115  // notation differences between Thijssen and Helgaker
116  m_coupledMatrix(p,r)(q,s) = f->coupledIntegral(p, q, r, s);
117  }
118  }
119  }
120  }
121  for(uint p = 0; p < n; p++) {
122  for(uint r = 0; r < n; r++) {
123  for(uint q = p; q < n; q++) {
124  for(uint s = r; s < n; s++) {
125  double originalValue = m_coupledMatrix(p,r)(q,s);
126  m_coupledMatrix(q,s)(p,r) = originalValue;
127  m_coupledMatrix(q,r)(p,s) = originalValue;
128  m_coupledMatrix(p,s)(q,r) = originalValue;
129  m_coupledMatrix(r,p)(s,q) = originalValue;
130  m_coupledMatrix(s,p)(r,q) = originalValue;
131  m_coupledMatrix(r,q)(s,p) = originalValue;
132  m_coupledMatrix(s,q)(r,p) = originalValue;
133  }
134  }
135  }
136  }
137 }
138 
139 
140 void HartreeFockSolver::normalizeCoefficientMatrix(uint nParticles, mat &coefficientMatrix){
141  ElectronSystem* f = m_electronSystem;
142  uint no = f->nBasisFunctions();
143  uint nk = nParticles;
144 
145  const mat& S = m_overlapMatrix;
146  mat& C = coefficientMatrix;
147 
148  for(uint k = 0; k < nk; k++) {
149  double factor = 0.0;
150  for(uint p = 0; p < no; p++){
151  for(uint q = 0; q < no; q++){
152  factor += C(p,k) * S(p,q) * C(q,k);
153  }
154  }
155  C.col(k) = C.col(k) / sqrt(factor);
156  }
157 }
158 
160 {
161  return m_iterationsUsed;
162 }
163 
165 {
166  return m_convergenceTreshold;
167 }
168 
169 void HartreeFockSolver::setConvergenceTreshold(double convergenceTreshold)
170 {
171  m_convergenceTreshold = convergenceTreshold;
172 }
173 
175  m_electronSystem = basisFunction;
176 }
177 
179  return m_electronSystem;
180 }
181 
183  return m_overlapMatrix;
184 }
185 
187 {
188  return m_transformationMatrix;
189 }
190 
191 const field<mat> &HartreeFockSolver::coupledMatrix() const
192 {
193  return m_coupledMatrix;
194 }
195 
197 {
198  return m_nIterationsMax;
199 }
200 
201 void HartreeFockSolver::setNIterationsMax(int nIterationsMax)
202 {
203  m_nIterationsMax = nIterationsMax;
204 }
205 
207 {
208  return m_uncoupledMatrix;
209 }
210 
212 {
213  return m_densityMixFactor;
214 }
215 
216 void HartreeFockSolver::setDensityMixFactor(double densityMixFactor)
217 {
218  m_densityMixFactor = densityMixFactor;
219 }