28 #ifndef _mpqc_src_lib_chemistry_qc_mbptr12_orbitalspacetimpl_h
29 #define _mpqc_src_lib_chemistry_qc_mbptr12_orbitalspacetimpl_h
32 #include <chemistry/qc/wfn/orbitalspace.h>
39 template <
typename Order>
41 OrderedOrbitalSpace<Order>::class_desc_(
typeid(this_type),
42 (std::string(
"OrderedOrbitalSpace<") +
43 std::string(
typeid(Order).name()) +
46 "public OrbitalSpace", 0, 0,
49 template <
typename Order>
50 OrderedOrbitalSpace<Order>::OrderedOrbitalSpace(StateIn& si) :
53 template <
typename Order>
59 template <
typename Order>
63 template <
typename Order>
64 OrderedOrbitalSpace<Order>::OrderedOrbitalSpace(
const std::string&
id,
65 const std::string& name,
66 const Ref<GaussianBasisSet>& basis,
67 const Ref<Integral>& integral,
68 const RefSCMatrix& coefs,
69 const RefDiagSCMatrix& evals,
70 const RefDiagSCMatrix& occnums,
71 const std::vector<unsigned int>& orbsyms,
76 const size_t norbs =
coefs.coldim().n();
77 if (orbsyms.empty() ==
false) {
78 const unsigned int max_orbsym = *(std::max_element(orbsyms.begin(), orbsyms.end()));
79 const unsigned int min_orbsym = *(std::min_element(orbsyms.begin(), orbsyms.end()));
80 const unsigned int nirreps =
basis->molecule()->point_group()->char_table().order();
81 if (min_orbsym >= nirreps || max_orbsym >= nirreps)
82 throw ProgrammingError(
"OrderedOrbitalSpace -- invalid orbital symmetry array",__FILE__,__LINE__);
86 std::vector<MolecularOrbital> orbs;
87 for(
size_t o=0; o<norbs; ++o) {
88 orbs.push_back(MolecularOrbital(o,
89 MolecularOrbitalAttributes(orbsyms.at(o),
91 occnums.get_element(o)
97 std::stable_sort(orbs.begin(), orbs.end(), order);
100 std::vector<BlockedOrbital> blocked_orbs;
101 for(
size_t o=0; o<norbs; ++o) {
113 template <
typename Order>
115 OrderedSpinOrbitalSpace<Order>::class_desc_(
typeid(this_type),
116 (std::string(
"OrderedSpinOrbitalSpace<") +
117 std::string(
typeid(Order).name()) +
120 "public OrbitalSpace", 0, 0,
123 template <
typename Order>
124 OrderedSpinOrbitalSpace<Order>::OrderedSpinOrbitalSpace(StateIn& si) :
127 template <
typename Order>
133 template <
typename Order>
137 template <
typename Order>
138 OrderedSpinOrbitalSpace<Order>::OrderedSpinOrbitalSpace(
const std::string&
id,
139 const std::string& name,
140 const Ref<GaussianBasisSet>& basis,
141 const Ref<Integral>& integral,
142 const RefSCMatrix& coefs_a,
143 const RefSCMatrix& coefs_b,
144 const RefDiagSCMatrix& evals_a,
145 const RefDiagSCMatrix& evals_b,
146 const RefDiagSCMatrix& occnums_a,
147 const RefDiagSCMatrix& occnums_b,
148 const std::vector<unsigned int>& orbsyms_a,
149 const std::vector<unsigned int>& orbsyms_b,
150 const Order& order) :
154 const size_t norbs = coefs_a.coldim().n();
155 MPQC_ASSERT(norbs != 0);
156 MPQC_ASSERT(norbs == coefs_b.coldim().n());
157 const unsigned int max_orbsym_a = *(std::max_element(orbsyms_a.begin(), orbsyms_a.end()));
158 const unsigned int min_orbsym_a = *(std::min_element(orbsyms_a.begin(), orbsyms_a.end()));
159 const unsigned int max_orbsym_b = *(std::max_element(orbsyms_b.begin(), orbsyms_b.end()));
160 const unsigned int min_orbsym_b = *(std::min_element(orbsyms_b.begin(), orbsyms_b.end()));
161 const unsigned int max_orbsym = std::max(max_orbsym_a,max_orbsym_b);
162 const unsigned int min_orbsym = std::min(min_orbsym_a,min_orbsym_b);
163 const unsigned int nirreps =
basis->molecule()->point_group()->char_table().order();
164 if (min_orbsym >= nirreps || max_orbsym >= nirreps)
165 throw ProgrammingError(
"OrderedSpinOrbitalSpace -- invalid orbital symmetry arrays",__FILE__,__LINE__);
172 std::vector<MolecularSpinOrbital> orbs;
173 for(
size_t o=0; o<norbs; ++o) {
174 orbs.push_back(MolecularSpinOrbital(o,
175 MolecularSpinOrbitalAttributes(orbsyms_a.at(o),
176 evals_a.get_element(o),
177 occnums_a.get_element(o),
182 for(
size_t o=0; o<norbs; ++o) {
183 orbs.push_back(MolecularSpinOrbital(o + norbs,
184 MolecularSpinOrbitalAttributes(orbsyms_b.at(o),
185 evals_b.get_element(o),
186 occnums_b.get_element(o),
193 std::stable_sort(orbs.begin(), orbs.end(), order);
196 std::vector<BlockedOrbital> blocked_orbs;
197 for(
size_t o=0; o<norbs*2; ++o) {
198 const unsigned index = orbs[o].index();
199 const unsigned block = order.block(orbs[o]);
201 blocked_orbs.push_back(orb);
205 RefSCDimension orbdim;
207 const unsigned int nblocks = coefs_a.coldim()->blocks()->nblock() * 2;
209 int* nfunc_per_block =
new int[
nblocks];
210 for (
unsigned int i = 0; i <
nblocks/2; ++i)
211 nfunc_per_block[i] = coefs_a.coldim()->blocks()->size(i);
213 nfunc_per_block[ii] = coefs_a.coldim()->blocks()->size(i);
214 orbdim =
new SCDimension(norbs * 2,
nblocks, nfunc_per_block,
id.c_str());
216 for (
unsigned int i = 0; i <
nblocks; ++i)
217 orbdim->blocks()->set_subdim(i,
new SCDimension(nfunc_per_block[i]));
219 delete[] nfunc_per_block;
221 RefSCMatrix
coefs = coefs_a.kit()->matrix(coefs_a.rowdim(),orbdim);
222 RefDiagSCMatrix
evals = evals_a.kit()->diagmatrix(orbdim);
223 std::vector<unsigned int> orbsyms(norbs*2);
224 const unsigned int nao = coefs_a.rowdim().n();
225 for (
unsigned int i = 0, ii=0; i < norbs; ++i, ++ii) {
226 for(
unsigned int ao=0; ao<nao; ++ao) {
227 coefs(ao,ii) = coefs_a(ao,i);
229 evals(ii) = evals_a(i);
230 orbsyms[ii] = orbsyms_a[i];
232 for (
unsigned int i = 0, ii=norbs; i < norbs; ++i, ++ii) {
233 for(
unsigned int ao=0; ao<nao; ++ao) {
234 coefs(ao,ii) = coefs_b(ao,i);
236 evals(ii) = evals_b(i);
237 orbsyms[ii] = orbsyms_b[i];
247 #endif // end of header guard