1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: determinants.h
4 // Copyright (C) 2014 Toru Shiozaki
5 //
6 // Author: Toru Shiozaki <shiozaki@northwestern.edu>
7 // Maintainer: Shiozaki group
8 //
9 // This file is part of the BAGEL package.
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
24
25
26 #ifndef __SRC_CIUTIL_DETERMINANTS_BASE_H
27 #define __SRC_CIUTIL_DETERMINANTS_BASE_H
28
29 #include <src/ci/ciutil/ciblock.h>
30 #include <src/ci/ciutil/cistringspace.h>
31
32 namespace bagel {
33
34 template <class StringType>
35 class Determinants_base {
36 protected:
37 std::vector<std::shared_ptr<const CIBlockInfo<StringType>>> blockinfo_;
38
39 std::shared_ptr<const CIStringSet<StringType>> alphaspaces_;
40 std::shared_ptr<const CIStringSet<StringType>> betaspaces_;
41
42 bool compress_;
43 size_t size_;
44
45 // configuration list i^dagger j compressed
46 std::shared_ptr<const StringMap> phia_;
47 std::shared_ptr<const StringMap> phib_;
48
49 // configuration list i^dagger j uncompressed
50 std::shared_ptr<const StringMap> phia_uncompressed_;
51 std::shared_ptr<const StringMap> phib_uncompressed_;
52
53 // configuration list i^dagger
54 std::shared_ptr<const StringMap> phiupa_;
55 std::shared_ptr<const StringMap> phiupb_;
56
57 // configuration list i
58 std::shared_ptr<const StringMap> phidowna_;
59 std::shared_ptr<const StringMap> phidownb_;
60
blockinfo(const int i)61 const std::shared_ptr<const CIBlockInfo<StringType>>& blockinfo(const int i) const { return blockinfo_[i]; }
62
63 private:
64 friend class boost::serialization::access;
65 template<class Archive>
serialize(Archive & ar,const unsigned int)66 void serialize(Archive& ar, const unsigned int) {
67 ar & blockinfo_ & alphaspaces_ & betaspaces_ & phia_ & phib_ & phia_uncompressed_ & phib_uncompressed_
68 & phiupa_ & phiupb_ & phidowna_ & phidownb_;
69 }
70
71 public:
Determinants_base()72 Determinants_base() { }
~Determinants_base()73 virtual ~Determinants_base() { }
74
75 // some functions to retrieve members of CIBlockInfo<StringType>
76 // block-independent members
norb()77 int norb() const { return alphaspaces_->norb(); }
nelea()78 int nelea() const { return alphaspaces_->nele(); }
neleb()79 int neleb() const { return betaspaces_->nele(); }
nspin()80 int nspin() const { return nelea() - neleb(); }
81 // block dependent members
lena()82 size_t lena() const { return alphaspaces_->size(); }
lenb()83 size_t lenb() const { return betaspaces_->size(); }
size()84 size_t size() const { return size_; }
85
86 template<int spin>
sign(const std::bitset<nbit__> & bit,const size_t pos)87 int sign(const std::bitset<nbit__>& bit, const size_t pos) const {
88 auto iter = std::find_if(blockinfo_.begin(), blockinfo_.end(), [](const std::shared_ptr<const CIBlockInfo<StringType>>& o){ return !o->empty(); });
89 return (*iter)->template sign<spin>(bit, pos);
90 }
91
sign(const std::bitset<nbit__> & bit,const size_t pos0,const size_t pos1)92 static int sign(const std::bitset<nbit__>& bit, const size_t pos0, const size_t pos1) {
93 return CIBlockInfo<StringType>::sign(bit, pos0, pos1);
94 }
95
96 template <int spin>
lexical_zero(const std::bitset<nbit__> & bit)97 size_t lexical_zero(const std::bitset<nbit__>& bit) const { return (spin == 0 ? alphaspaces_ : betaspaces_)->lexical_zero(bit); }
98 template <int spin>
lexical_offset(const std::bitset<nbit__> & bit)99 size_t lexical_offset(const std::bitset<nbit__>& bit) const { return (spin == 0 ? alphaspaces_ : betaspaces_)->lexical_offset(bit); }
100
blockinfo()101 const std::vector<std::shared_ptr<const CIBlockInfo<StringType>>>& blockinfo() const { return blockinfo_; }
blockinfo(std::shared_ptr<const StringType> beta,std::shared_ptr<const StringType> alpha)102 std::shared_ptr<const CIBlockInfo<StringType>> blockinfo(std::shared_ptr<const StringType> beta, std::shared_ptr<const StringType> alpha) const {
103 auto iter = std::find_if(blockinfo_.begin(), blockinfo_.end(),
104 [&alpha, &beta] (const std::shared_ptr<const CIBlockInfo<StringType>>& o) {
105 return (o->empty() ? false :
106 o->stringsa()->matches(alpha) &&
107 o->stringsb()->matches(beta));
108 });
109 return (iter != blockinfo_.end() ? *iter : nullptr);
110 }
stringspacea()111 const std::shared_ptr<const CIStringSet<StringType>>& stringspacea() const { return alphaspaces_; }
stringspaceb()112 const std::shared_ptr<const CIStringSet<StringType>>& stringspaceb() const { return betaspaces_; }
113
string_bits_a(const size_t i)114 const std::bitset<nbit__>& string_bits_a(const size_t i) const { return alphaspaces_->strings(i); }
string_bits_b(const size_t i)115 const std::bitset<nbit__>& string_bits_b(const size_t i) const { return betaspaces_->strings(i); }
string_bits_a()116 const std::vector<std::bitset<nbit__>>& string_bits_a() const { return alphaspaces_->strings(); }
string_bits_b()117 const std::vector<std::bitset<nbit__>>& string_bits_b() const { return betaspaces_->strings(); }
118
119 bool operator==(const Determinants_base<StringType>& o) const
120 { return (norb() == o.norb() && nelea() == o.nelea() && neleb() == o.neleb() && compress_ == o.compress_); }
121
compress()122 bool compress() const { return compress_; }
123
124 // single index goes to normal versions (compressed based on compress_)
phia(const int i)125 const std::vector<DetMap>& phia(const int i) const { return phia_->data(i); }
phib(const int i)126 const std::vector<DetMap>& phib(const int i) const { return phib_->data(i); }
127
128 // two indices goes to uncompressed versions
phia(const int i,const int j)129 const std::vector<DetMap>& phia(const int i, const int j) const { return phia_uncompressed_->data(i + j*norb()); }
phib(const int i,const int j)130 const std::vector<DetMap>& phib(const int i, const int j) const { return phib_uncompressed_->data(i + j*norb()); }
131
phiupa(const int i)132 const std::vector<DetMap>& phiupa(const int i) const { return phiupa_->data(i); }
phiupb(const int i)133 const std::vector<DetMap>& phiupb(const int i) const { return phiupb_->data(i); }
phidowna(const int i)134 const std::vector<DetMap>& phidowna(const int i) const { return phidowna_->data(i); }
phidownb(const int i)135 const std::vector<DetMap>& phidownb(const int i) const { return phidownb_->data(i); }
set_phiupa(std::shared_ptr<const StringMap> o)136 void set_phiupa(std::shared_ptr<const StringMap> o) { phiupa_ = o; }
set_phiupb(std::shared_ptr<const StringMap> o)137 void set_phiupb(std::shared_ptr<const StringMap> o) { phiupb_ = o; }
set_phidowna(std::shared_ptr<const StringMap> o)138 void set_phidowna(std::shared_ptr<const StringMap> o) { phidowna_ = o; }
set_phidownb(std::shared_ptr<const StringMap> o)139 void set_phidownb(std::shared_ptr<const StringMap> o) { phidownb_ = o; }
140
141 };
142
link(std::shared_ptr<DetClass> mdet,std::shared_ptr<DetClass> odet)143 template<int spin, typename StringType, class DetClass> void link(std::shared_ptr<DetClass> mdet, std::shared_ptr<DetClass> odet) {
144 std::shared_ptr<DetClass> plusdet;
145 std::shared_ptr<DetClass> det;
146
147 const int de = spin == 0 ? mdet->nelea() - odet->nelea() : mdet->neleb() - odet->neleb();
148 if (de == 1) std::tie(det, plusdet) = std::make_pair(odet, mdet);
149 else if (de == -1) std::tie(det, plusdet) = std::make_pair(mdet, odet);
150 else throw std::logic_error("Determinants::link failed");
151
152 const int fac = (spin == 1 && (mdet->nelea() & 1)) ? -1 : 1;
153 CIStringSpace<CIStringSet<StringType>> space{spin==0?mdet->stringspacea():mdet->stringspaceb(),
154 spin==0?odet->stringspacea():odet->stringspaceb()};
155 space.build_linkage(fac);
156
157 // finally link
158 if (spin == 0) {
159 plusdet->set_remalpha(det);
160 plusdet->set_phidowna(space.phidown(plusdet->stringspacea()));
161
162 det->set_addalpha(plusdet);
163 det->set_phiupa(space.phiup(det->stringspacea()));
164 } else {
165 plusdet->set_rembeta(det);
166 plusdet->set_phidownb(space.phidown(plusdet->stringspaceb()));
167
168 det->set_addbeta(plusdet);
169 det->set_phiupb(space.phiup(det->stringspaceb()));
170 }
171 }
172
173 }
174
175 extern template class bagel::Determinants_base<bagel::FCIString>;
176 extern template class bagel::Determinants_base<bagel::RASString>;
177
178 #include <src/util/archive.h>
179 BOOST_CLASS_EXPORT_KEY(bagel::Determinants_base<bagel::FCIString>)
180 BOOST_CLASS_EXPORT_KEY(bagel::Determinants_base<bagel::RASString>)
181
182 #endif
183