6 using std::setprecision;
16 m_initialCoefficientMatricesSetManually(false),
17 m_diisSampleCount(10),
18 m_diisStartingIteration(20),
29 resetCoefficientMatrices();
31 setupDensityMatrices();
32 if(m_densityMatrixUp.n_rows > 0 && m_densityMatrixUp.n_cols > 1) {
33 m_densityMatrixUp(0,1) = 0.1;
38 void UnrestrictedHartreeFockSolver::resetFockMatrices() {
40 m_fockMatrixUp = zeros(n,n);
41 m_fockMatrixDown = zeros(n,n);
44 void UnrestrictedHartreeFockSolver::resetCoefficientMatrices() {
47 if(!m_initialCoefficientMatricesSetManually
49 || m_initialCoefficientMatrixUp.n_cols != f->
nParticlesUp()
56 m_coefficientMatrixUp = m_initialCoefficientMatrixUp;
57 m_coefficientMatrixDown = m_initialCoefficientMatrixDown;
60 void UnrestrictedHartreeFockSolver::randomizeCoefficientMatrices() {
66 void UnrestrictedHartreeFockSolver::setupFockMatrices() {
70 mat &Fu = m_fockMatrixUp;
71 mat &Fd = m_fockMatrixDown;
72 const mat &Pu = m_densityMatrixUp;
73 const mat &Pd = m_densityMatrixDown;
76 for(uint p = 0; p < n; p++) {
77 for(uint q = p; q < n; q++) {
82 for(uint r = 0; r < n; r++) {
83 for(uint s = 0; s < n; s++) {
84 double Qprqs = Q(p,r)(q,s);
85 double Qprsq = Q(p,r)(s,q);
86 double QprqsMinusQprsq = Qprqs - Qprsq;
87 double Pusr = Pu(s,r);
88 double Pdsr = Pd(s,r);
89 Fupq += Pusr * QprqsMinusQprsq + Pdsr * Qprqs;
90 Fdpq += Pdsr * QprqsMinusQprsq + Pusr * Qprqs;
102 void UnrestrictedHartreeFockSolver::setupDensityMatrices() {
103 mat &Pu = m_densityMatrixUp;
104 mat &Pd = m_densityMatrixDown;
105 mat &Cu = m_coefficientMatrixUp;
106 mat &Cd = m_coefficientMatrixDown;
107 mat tempPu = Cu * Cu.t();
108 mat tempPd = Cd * Cd.t();
110 if(Pu.n_elem > 0 && Pd.n_elem > 0) {
111 Pu = mixFactor * Pu + (1 - mixFactor) * tempPu;
112 Pd = mixFactor * Pd + (1 - mixFactor) * tempPd;
126 mat &Fu = m_fockMatrixUp;
127 mat &Fd = m_fockMatrixDown;
128 mat &Cu = m_coefficientMatrixUp;
129 mat &Cd = m_coefficientMatrixDown;
130 vec &fockEnergiesUp = m_fockEnergiesUp;
131 vec &fockEnergiesDn = m_fockEnergiesDown;
135 mat FprimeUp = V.t() * Fu * V;
136 mat FprimeDn = V.t() * Fd * V;
141 eig_sym(fockEnergiesUp, CprimeUp, FprimeUp);
142 eig_sym(fockEnergiesDn, CprimeDn, FprimeDn);
145 Cu = V*CprimeUp.submat(0, 0, no - 1, nkUp - 1);
148 Cd = V*CprimeDn.submat(0, 0, no - 1, nkDn - 1);
154 setupDensityMatrices();
162 vec previousFockEnergies = m_fockEnergiesUp;
163 if(m_isDiisEnabled && i > m_diisStartingIteration) {
168 double stdDeviation = sum(abs(m_fockEnergiesUp - previousFockEnergies)) / m_fockEnergiesUp.n_elem;
177 void UnrestrictedHartreeFockSolver::calculateEnergy()
180 mat &Pu = m_densityMatrixUp;
181 mat &Pd = m_densityMatrixDown;
182 mat &Fu = m_fockMatrixUp;
183 mat &Fd = m_fockMatrixDown;
186 energy += 0.5 * accu( (Pu + Pd) % h + Fu % Pu + Fd % Pd);
194 return m_coefficientMatrixUp;
199 return m_coefficientMatrixDown;
204 return m_densityMatrixUp;
209 return m_densityMatrixDown;
214 m_initialCoefficientMatricesSetManually =
true;
215 m_initialCoefficientMatrixUp = up;
216 m_initialCoefficientMatrixDown = down;
230 void UnrestrictedHartreeFockSolver::performDIIS()
232 mat &Fu = m_fockMatrixUp;
233 mat &Fd = m_fockMatrixDown;
234 mat &Pu = m_densityMatrixUp;
235 mat &Pd = m_densityMatrixDown;
238 m_errorsU.push_back(Fu*Pu*S - S*Pu*Fu);
239 m_fockMatricesU.push_back(m_fockMatrixUp);
241 m_errorsD.push_back(Fd*Pd*S - S*Pd*Fd);
242 m_fockMatricesD.push_back(m_fockMatrixDown);
244 if(
signed(m_errorsU.size()) > m_diisSampleCount){
245 m_errorsU.erase(m_errorsU.begin());
246 m_fockMatricesU.erase(m_fockMatricesU.begin());
248 m_errorsD.erase(m_errorsD.begin());
249 m_fockMatricesD.erase(m_fockMatricesD.begin());
251 mat Au = zeros(m_errorsU.size()+1, m_errorsU.size()+1);
252 mat Ad = zeros(m_errorsD.size()+1, m_errorsD.size()+1);
254 for(uint i = 0; i < m_errorsU.size(); i++){
255 Au(i, m_errorsU.size()) = -1;
256 Au(m_errorsU.size(), i) = -1;
258 Ad(i, m_errorsD.size()) = -1;
259 Ad(m_errorsD.size(), i) = -1;
261 for(uint j = 0; j < m_errorsU.size(); j++){
262 Au(i,j) = trace(m_errorsU.at(i) * m_errorsU.at(j));
263 Ad(i,j) = trace(m_errorsD.at(i) * m_errorsD.at(j));
267 vec bu = zeros(Au.n_rows);
268 vec bd = zeros(Ad.n_rows);
270 bu(bu.n_elem -1) = -1.0;
271 bd(bd.n_elem -1) = -1.0;
275 for(uint i = 0; i < bu.n_elem - 1; i++){
276 m_fockMatrixUp += bu(i) * m_fockMatricesU.at(i);
277 m_fockMatrixDown += bd(i) * m_fockMatricesD.at(i);
283 return m_diisStartingIteration;
293 return m_diisSampleCount;
298 m_diisSampleCount = diisIterationCount;
303 return m_isDiisEnabled;
308 m_isDiisEnabled = useDIIS;