00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef __GNUG__
00029 #pragma implementation
00030 #endif
00031
00032 #ifndef _mpqc_src_lib_chemistry_qc_mbptr12_orbitalspacetimpl_h
00033 #define _mpqc_src_lib_chemistry_qc_mbptr12_orbitalspacetimpl_h
00034
00035
00036 #include <chemistry/qc/mbptr12/orbitalspace.h>
00037 #include <algorithm>
00038 #include <cassert>
00039 #include <vector>
00040
00041 namespace sc {
00042
00043 template <typename Order>
00044 ClassDesc
00045 OrderedOrbitalSpace<Order>::class_desc_(typeid(this_type),
00046 (std::string("OrderedOrbitalSpace<") +
00047 std::string(typeid(Order).name()) +
00048 std::string(">")
00049 ).c_str(), 1,
00050 "public OrbitalSpace", 0, 0,
00051 create<this_type> );
00052
00053 template <typename Order>
00054 OrderedOrbitalSpace<Order>::OrderedOrbitalSpace(StateIn& si) :
00055 OrbitalSpace(si) {}
00056
00057 template <typename Order>
00058 void
00059 OrderedOrbitalSpace<Order>::save_data_state(StateOut& so) {
00060 OrbitalSpace::save_data_state(so);
00061 }
00062
00063 template <typename Order>
00064 OrderedOrbitalSpace<Order>::~OrderedOrbitalSpace() {
00065
00066 const bool make_sure_class_desc_is_initialized = (&class_desc_ == 0);
00067 }
00068
00069 template <typename Order>
00070 OrderedOrbitalSpace<Order>::OrderedOrbitalSpace(const std::string& id,
00071 const std::string& name,
00072 const Ref<GaussianBasisSet>& basis,
00073 const Ref<Integral>& integral,
00074 const RefSCMatrix& coefs,
00075 const RefDiagSCMatrix& evals,
00076 const RefDiagSCMatrix& occnums,
00077 const std::vector<unsigned int>& orbsyms,
00078 const Order& order) :
00079 OrbitalSpace() {
00080
00081
00082 const size_t norbs = coefs.coldim().n();
00083 assert(norbs != 0);
00084 const unsigned int max_orbsym = *(std::max_element(orbsyms.begin(), orbsyms.end()));
00085 const unsigned int min_orbsym = *(std::min_element(orbsyms.begin(), orbsyms.end()));
00086 const unsigned int nirreps = basis->molecule()->point_group()->char_table().order();
00087 if (min_orbsym >= nirreps || max_orbsym >= nirreps)
00088 throw ProgrammingError("OrderedOrbitalSpace -- invalid orbital symmetry array",__FILE__,__LINE__);
00089
00090
00091 std::vector<MolecularOrbital> orbs;
00092 for(size_t o=0; o<norbs; ++o) {
00093 using detail::MolecularOrbitalAttributes;
00094 orbs.push_back(MolecularOrbital(o,
00095 MolecularOrbitalAttributes(orbsyms.at(o),
00096 evals.get_element(o),
00097 occnums.get_element(o)
00098 )
00099 ));
00100 }
00101
00102
00103 std::stable_sort(orbs.begin(), orbs.end(), order);
00104
00105
00106 std::vector<BlockedOrbital> blocked_orbs;
00107 for(size_t o=0; o<norbs; ++o) {
00108 blocked_orbs.push_back(BlockedOrbital(orbs[o].index(),
00109 order.block(orbs[o])
00110 ));
00111 }
00112
00113 init(id, name, basis, integral, coefs, evals, orbsyms, order.nblocks(), blocked_orbs);
00114
00115 }
00116
00118
00119 template <typename Order>
00120 ClassDesc
00121 OrderedSpinOrbitalSpace<Order>::class_desc_(typeid(this_type),
00122 (std::string("OrderedSpinOrbitalSpace<") +
00123 std::string(typeid(Order).name()) +
00124 std::string(">")
00125 ).c_str(), 1,
00126 "public OrbitalSpace", 0, 0,
00127 create<this_type> );
00128
00129 template <typename Order>
00130 OrderedSpinOrbitalSpace<Order>::OrderedSpinOrbitalSpace(StateIn& si) :
00131 OrbitalSpace(si) {}
00132
00133 template <typename Order>
00134 void
00135 OrderedSpinOrbitalSpace<Order>::save_data_state(StateOut& so) {
00136 OrbitalSpace::save_data_state(so);
00137 }
00138
00139 template <typename Order>
00140 OrderedSpinOrbitalSpace<Order>::~OrderedSpinOrbitalSpace() {
00141
00142 const bool make_sure_class_desc_is_initialized = (&class_desc_ == 0);
00143 }
00144
00145 template <typename Order>
00146 OrderedSpinOrbitalSpace<Order>::OrderedSpinOrbitalSpace(const std::string& id,
00147 const std::string& name,
00148 const Ref<GaussianBasisSet>& basis,
00149 const Ref<Integral>& integral,
00150 const RefSCMatrix& coefs_a,
00151 const RefSCMatrix& coefs_b,
00152 const RefDiagSCMatrix& evals_a,
00153 const RefDiagSCMatrix& evals_b,
00154 const RefDiagSCMatrix& occnums_a,
00155 const RefDiagSCMatrix& occnums_b,
00156 const std::vector<unsigned int>& orbsyms_a,
00157 const std::vector<unsigned int>& orbsyms_b,
00158 const Order& order) :
00159 OrbitalSpace() {
00160
00161
00162 const size_t norbs = coefs_a.coldim().n();
00163 assert(norbs != 0);
00164 assert(norbs == coefs_b.coldim().n());
00165 const unsigned int max_orbsym_a = *(std::max_element(orbsyms_a.begin(), orbsyms_a.end()));
00166 const unsigned int min_orbsym_a = *(std::min_element(orbsyms_a.begin(), orbsyms_a.end()));
00167 const unsigned int max_orbsym_b = *(std::max_element(orbsyms_b.begin(), orbsyms_b.end()));
00168 const unsigned int min_orbsym_b = *(std::min_element(orbsyms_b.begin(), orbsyms_b.end()));
00169 const unsigned int max_orbsym = std::max(max_orbsym_a,max_orbsym_b);
00170 const unsigned int min_orbsym = std::min(min_orbsym_a,min_orbsym_b);
00171 const unsigned int nirreps = basis->molecule()->point_group()->char_table().order();
00172 if (min_orbsym >= nirreps || max_orbsym >= nirreps)
00173 throw ProgrammingError("OrderedSpinOrbitalSpace -- invalid orbital symmetry arrays",__FILE__,__LINE__);
00174
00176
00178
00179
00180 std::vector<MolecularSpinOrbital> orbs;
00181 for(size_t o=0; o<norbs; ++o) {
00182 using detail::MolecularSpinOrbitalAttributes;
00183 orbs.push_back(MolecularSpinOrbital(o,
00184 MolecularSpinOrbitalAttributes(orbsyms_a.at(o),
00185 evals_a.get_element(o),
00186 occnums_a.get_element(o),
00187 Alpha
00188 )
00189 ));
00190 }
00191 for(size_t o=0; o<norbs; ++o) {
00192 using detail::MolecularSpinOrbitalAttributes;
00193 orbs.push_back(MolecularSpinOrbital(o + norbs,
00194 MolecularSpinOrbitalAttributes(orbsyms_b.at(o),
00195 evals_b.get_element(o),
00196 occnums_b.get_element(o),
00197 Beta
00198 )
00199 ));
00200 }
00201
00202
00203 std::stable_sort(orbs.begin(), orbs.end(), order);
00204
00205
00206 std::vector<BlockedOrbital> blocked_orbs;
00207 for(size_t o=0; o<norbs*2; ++o) {
00208 const unsigned index = orbs[o].index();
00209 const unsigned block = order.block(orbs[o]);
00210 BlockedOrbital orb(index,block);
00211 blocked_orbs.push_back(orb);
00212 }
00213
00214
00215 RefSCDimension orbdim;
00216 {
00217 const unsigned int nblocks = coefs_a.coldim()->blocks()->nblock() * 2;
00218
00219 int* nfunc_per_block = new int[nblocks];
00220 for (unsigned int i = 0; i < nblocks/2; ++i)
00221 nfunc_per_block[i] = coefs_a.coldim()->blocks()->size(i);
00222 for (unsigned int i = 0, ii=nblocks/2; i < nblocks/2; ++i, ++ii)
00223 nfunc_per_block[ii] = coefs_a.coldim()->blocks()->size(i);
00224 orbdim = new SCDimension(norbs * 2, nblocks, nfunc_per_block, id.c_str());
00225 if (norbs) {
00226 for (unsigned int i = 0; i < nblocks; ++i)
00227 orbdim->blocks()->set_subdim(i, new SCDimension(nfunc_per_block[i]));
00228 }
00229 delete[] nfunc_per_block;
00230 }
00231 RefSCMatrix coefs = coefs_a.kit()->matrix(coefs_a.rowdim(),orbdim);
00232 RefDiagSCMatrix evals = evals_a.kit()->diagmatrix(orbdim);
00233 std::vector<unsigned int> orbsyms(norbs*2);
00234 const unsigned int nao = coefs_a.rowdim().n();
00235 for (unsigned int i = 0, ii=0; i < norbs; ++i, ++ii) {
00236 for(unsigned int ao=0; ao<nao; ++ao) {
00237 coefs(ao,ii) = coefs_a(ao,i);
00238 }
00239 evals(ii) = evals_a(i);
00240 orbsyms[ii] = orbsyms_a[i];
00241 }
00242 for (unsigned int i = 0, ii=norbs; i < norbs; ++i, ++ii) {
00243 for(unsigned int ao=0; ao<nao; ++ao) {
00244 coefs(ao,ii) = coefs_b(ao,i);
00245 }
00246 evals(ii) = evals_b(i);
00247 orbsyms[ii] = orbsyms_b[i];
00248 }
00249
00250 init(id, name, basis, integral, coefs, evals, orbsyms, order.nblocks(), blocked_orbs);
00251
00252 }
00253
00254
00255 }
00256
00257 #endif // end of header guard
00258
00259
00260
00261
00262