forked from sanshar/Block
-
Notifications
You must be signed in to change notification settings - Fork 1
/
hfOccGenerator.C
125 lines (110 loc) · 3.47 KB
/
hfOccGenerator.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Guess configuration generator as a member function of Input
// "hf_occ = integral" with symmetry
// Written by N.Nakatani, 2014.12.25
#include <cassert>
#include <vector>
#include <map>
#include "global.h"
#include "input.h"
// from Symmetry.C
extern array_2d<int> groupTable;
std::vector<int> SpinAdapted::Input::hfOccGenerator_ ()
{
typedef std::multimap<double,int>::iterator mapIter;
int irep = m_total_symmetry_number.getirrep();
if (NonabelianSym) irep = 0; //with nonabelian symmetry this code will only work with Ag symmetry
int spac_norbs = m_norbs/2;
// Sorting orbitals by 1-el. Hamiltonian, i.e. h(i, i)
std::vector<int> reorder(spac_norbs,0);
{
// NOTE: v_1 in lattice order
std::multimap<double,int> orbMap;
for(int i = 0; i < spac_norbs; ++i)
orbMap.insert(std::make_pair(v_1[0](2*i, 2*i), i));
mapIter it = orbMap.begin();
for(int i = 0; i < spac_norbs; ++i, ++it)
reorder[i] = it->second;
}
int refIrep = 0;
// NOTE: m_spin_orbs_symmetry in lattice order
std::vector<int> refOcc(m_norbs,0);
for(int i = 0; i < m_alpha; ++i) {
int ir = reorder[i];
refOcc[2*ir] = 1;
refIrep = Symmetry::add(refIrep, m_spin_orbs_symmetry[2*ir])[0];
if(i < m_beta) {
refOcc[2*ir+1] = 1;
refIrep = Symmetry::add(refIrep, m_spin_orbs_symmetry[2*ir+1])[0];
}
}
if(refIrep != irep) {
std::vector<std::vector<int>> exOccs;
// beta el. excitation
// --- --- --- ---
// --- --- --- ---
// -o- --- -o- ---
// -o- --- ==> -o- -o-
// -o- --- -o- ---
// -o- --- -o- ---
// -o- -o- ==> -o- ---
// -o- -o- -o- -o-
// -o- -o- -o- -o-
// a b a b
for(int i = 0; i < m_beta; ++i) {
int ir = reorder[i];
for(int j = m_beta; j < m_alpha; ++j) {
int jr = reorder[j];
int exIrep = Symmetry::add(m_spin_orbs_symmetry[2*ir+1],m_spin_orbs_symmetry[2*jr+1])[0];
if(Symmetry::add(refIrep,exIrep)[0] == irep) {
std::vector<int> exOcc = refOcc;
std::swap(exOcc[2*ir+1],exOcc[2*jr+1]);
exOccs.push_back(exOcc);
}
}
}
// alpha el. excitation
// --- --- ==> -o- ---
// --- --- --- ---
// -o- --- -o- ---
// -o- --- -o- ---
// -o- --- -o- ---
// -o- --- -o- ---
// -o- -o- -o- -o-
// -o- -o- ==> --- -o-
// -o- -o- -o- -o-
// a b a b
for(int i = 0; i < m_alpha; ++i) {
int ir = reorder[i];
for(int j = m_alpha; j < spac_norbs; ++j) {
int jr = reorder[j];
int exIrep = Symmetry::add(m_spin_orbs_symmetry[2*ir],m_spin_orbs_symmetry[2*jr])[0];
if(Symmetry::add(refIrep,exIrep)[0] == irep) {
std::vector<int> exOcc = refOcc;
std::swap(exOcc[2*ir],exOcc[2*jr]);
exOccs.push_back(exOcc);
}
}
}
// No 1-el. configuration was found for the requested state symmetry, irep
assert(exOccs.size() > 0);
double confE = 1.0e8;
for(int i = 0; i < exOccs.size(); ++i) {
double confE_tmp = 0.0;
for(int j = 0; j < m_norbs; ++j) {
if(exOccs[i][j] != 0) confE_tmp += v_1[0](j, j);
}
if(confE_tmp < confE) {
confE = confE_tmp;
refOcc = exOccs[i];
}
}
}
// NOTE: hfOcc in original order
std::vector<int> hfOcc(m_norbs);
for(int i = 0; i < spac_norbs; ++i) {
int ir = m_reorder[i];
hfOcc[2*ir] = refOcc[2*i];
hfOcc[2*ir+1] = refOcc[2*i+1];
}
return hfOcc;
}