Kindfield
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Friends Pages
hartreefock.cpp
Go to the documentation of this file.
1 #include "hartreefock.h"
2 
3 #include <QDebug>
4 #include <cmath>
5 
10 
11 using namespace std;
12 
13 HartreeFock::HartreeFock(QQuickItem *parent) :
14  QQuickItem(parent),
15  m_nSampleSteps(0),
16  m_voxelData(0),
17  m_voxelEdgeMin(0),
18  m_voxelEdgeMax(0),
19  m_orbital(0)
20 {
22 }
23 
25 {
26 
27 }
28 
30  m_filePositions.reset();
31  m_filePositions = arma::zeros(1,20*20*20,3);
32  int nPerDim = 20;
33  int counter = 0;
34  for(int i = 0; i < nPerDim; i++) {
35  for(int j = 0; j < nPerDim; j++) {
36  for(int k = 0; k < nPerDim; k++) {
37  m_filePositions(0,counter,0) = -nPerDim / 2 + i;
38  m_filePositions(0,counter,1) = -nPerDim / 2 + j;
39  m_filePositions(0,counter,2) = -nPerDim / 2 + k;
40  counter++;
41  }
42  }
43  }
44  m_nSampleSteps = 1;
45  emit nSampleStepsChanged(m_nSampleSteps);
46  emit dataChanged();
47 }
48 
50 {
51  return m_orbitalDensities(0).n_rows;
52 }
53 
55 {
56  return m_orbitalDensities(0).n_cols;
57 }
58 
60 {
61  return m_orbitalDensities(0).n_slices;
62 }
63 
64 const cube &HartreeFock::positions() const
65 {
66  return m_filePositions;
67 }
68 
69 
71 {
72  double edge = 10;
73  vec x = linspace(-edge, edge, 50);
74  vec y = linspace(-edge, edge, 50);
75  vec z = linspace(-edge, edge, 50);
76  cout << "Solving system with Hartree-Fock..." << endl;
77  vector<GaussianCore> cores;
78 // cores.push_back(GaussianCore({0, 0.0, 0.0000}, "atom_8_basis_STO-3G.tm"));
79  cores.push_back(GaussianCore({ -5, 0.0, 0.0000}, "atom_1_basis_6-311++Gdsds.tm"));
80  cores.push_back(GaussianCore({ 5, 0.0, 0.0000}, "atom_1_basis_6-311++Gdsds.tm"));
81  GaussianSystem system;
82  for(const GaussianCore &core : cores) {
83  system.addCore(core);
84  }
85 // system.setNParticlesDown(9);
86  mat C;
87 // RestrictedHartreeFockSolver solver(&system);
88  UnrestrictedHartreeFockSolver solver(&system);
89  solver.setNIterationsMax(1e4);
90  solver.setConvergenceTreshold(1e-10);
91  solver.solve();
92  cout << "Energy: " << solver.energy() << endl;
93  C = join_rows(solver.coeffcientMatrixUp(), solver.coeffcientMatrixDown());
94 // C = solver.coefficientMatrix();
95  m_orbitalDensities.set_size(C.n_cols);
96  m_totalDensity = zeros(x.n_elem, y.n_elem, z.n_elem);
97  for(cube& orbitalDensity : m_orbitalDensities) {
98  orbitalDensity = zeros(x.n_elem, y.n_elem, z.n_elem);
99  }
100  cout << "Calculating density..." << endl;
101  double maxDensity = 0.0;
102  double densitySum = 0.0;
103  for(uint i = 0; i < x.n_elem; i++) {
104  for(uint j = 0; j < y.n_elem; j++) {
105  for(uint k = 0; k < z.n_elem; k++) {
106  rowvec orbitalDensities = system.orbitalDensities(C, Vector3(x(i), y(j), z(k)));
107  for(uint orbital = 0; orbital < orbitalDensities.n_elem; orbital++) {
108  double density = orbitalDensities(orbital);
109  densitySum += density;
110  m_totalDensity(i,j,k) += density;
111  m_orbitalDensities(orbital)(i,j,k) = density;
112  maxDensity = fmax(maxDensity, density);
113  }
114  }
115  }
116  }
117  int elementCount = x.n_elem * y.n_elem * z.n_elem;
118  double meanDensity = (densitySum / elementCount);
119  m_totalDensity /= (meanDensity * m_orbitalDensities.n_elem);
120  for(cube& orbitalDensity : m_orbitalDensities) {
121  orbitalDensity /= meanDensity; // Normalize densities to the mean
122  }
123  m_energy = solver.energy();
124  emit energyChanged(m_energy);
125  double minValue = x.min();
126  double maxValue = x.max();
127  double mostMaxValue = max(-minValue, maxValue);
128  minValue = -mostMaxValue;
129  maxValue = mostMaxValue;
130  setupVoxelData();
131  m_voxelEdgeMin = minValue;
132  m_voxelEdgeMax = maxValue;
133  emit voxelEdgeMinChanged(m_voxelEdgeMin);
134  emit voxelEdgeMaxChanged(m_voxelEdgeMax);
135  emit nSampleStepsChanged(m_nSampleSteps);
136  emit orbitalCountChanged(m_orbitalDensities.n_elem);
137 }
138 
140  if(m_orbitalDensities.n_elem < 1) {
141  return;
142  }
143  if(m_voxelData) {
144  delete[] m_voxelData;
145  }
146  uint nElements = m_orbitalDensities(0).n_rows * m_orbitalDensities(0).n_cols * m_orbitalDensities(0).n_slices;
147  m_voxelData = new GLuint[nElements];
148  cube *densityPointer = &m_totalDensity;
149  if(m_orbital != -1) {
150  densityPointer = &(m_orbitalDensities(m_orbital));
151  }
152  cube &density = *densityPointer;
153  uint rowCount = density.n_rows;
154  uint colCount = density.n_rows;
155  uint sliceCount = density.n_rows;
156 
157  for(uint i = 0; i < (rowCount); i++) {
158  for(uint j = 0; j < (colCount); j++) {
159  for(uint k = 0; k < (sliceCount); k++) {
160  int index = i
161  + j * rowCount
162  + k * colCount * rowCount;
163  double value = density(i,j,k);
164 // double value = pow(value / m_contrast, m_contrast);
165  value = fmin(1.0, value);
166  m_voxelData[index] = value * 2147483647;
167  }
168  }
169  }
170  emit dataChanged();
171 }
172 
173 GLuint *HartreeFock::voxelData() const
174 {
175  return m_voxelData;
176 }
177 
179 {
180  if (m_orbital != arg) {
181  m_orbital = arg;
182  setupVoxelData();
183  emit orbitalChanged(arg);
184  }
185 }