| 1 | //
 | 
|---|
| 2 | // moindexspace.cc
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Copyright (C) 2003 Edward Valeev
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
 | 
|---|
| 7 | // Maintainer: EV
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // This file is part of the SC Toolkit.
 | 
|---|
| 10 | //
 | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 14 | // any later version.
 | 
|---|
| 15 | //
 | 
|---|
| 16 | // The SC Toolkit 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 Library General Public License for more details.
 | 
|---|
| 20 | //
 | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 24 | //
 | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
| 26 | //
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #ifdef __GNUG__
 | 
|---|
| 29 | #pragma implementation
 | 
|---|
| 30 | #endif
 | 
|---|
| 31 | 
 | 
|---|
| 32 | #include <stdexcept>
 | 
|---|
| 33 | #include <algorithm>
 | 
|---|
| 34 | #include <stdlib.h>
 | 
|---|
| 35 | #include <util/misc/formio.h>
 | 
|---|
| 36 | #include <chemistry/qc/basis/petite.h>
 | 
|---|
| 37 | #include <chemistry/qc/mbptr12/moindexspace.h>
 | 
|---|
| 38 | 
 | 
|---|
| 39 | using namespace std;
 | 
|---|
| 40 | using namespace sc;
 | 
|---|
| 41 | 
 | 
|---|
| 42 | inline int max(int a,int b) { return (a > b) ? a : b;}
 | 
|---|
| 43 | 
 | 
|---|
| 44 | /*---------------
 | 
|---|
| 45 |   MOIndexSpace
 | 
|---|
| 46 |  ---------------*/
 | 
|---|
| 47 | static ClassDesc MOIndexSpace_cd(
 | 
|---|
| 48 |   typeid(MOIndexSpace),"MOIndexSpace",1,"virtual public SavableState",
 | 
|---|
| 49 |   0, 0, create<MOIndexSpace>);
 | 
|---|
| 50 | 
 | 
|---|
| 51 | MOIndexSpace::MOIndexSpace(std::string name, const RefSCMatrix& full_coefs,
 | 
|---|
| 52 |                            const Ref<GaussianBasisSet> basis, const Ref<Integral>& integral,
 | 
|---|
| 53 |                            const vector<int>& offsets, const vector<int>& nmopi, IndexOrder moorder,
 | 
|---|
| 54 |                            const RefDiagSCMatrix& evals) :
 | 
|---|
| 55 |   name_(name), basis_(basis), integral_(integral), offsets_(offsets), nmo_(nmopi), full_rank_(full_coefs.coldim().n()),
 | 
|---|
| 56 |   moorder_(moorder)
 | 
|---|
| 57 | {
 | 
|---|
| 58 |   full_coefs_to_coefs(full_coefs, evals);
 | 
|---|
| 59 |   
 | 
|---|
| 60 |   init();
 | 
|---|
| 61 | }
 | 
|---|
| 62 | 
 | 
|---|
| 63 | MOIndexSpace::MOIndexSpace(std::string name, const RefSCMatrix& full_coefs,
 | 
|---|
| 64 |                            const Ref<GaussianBasisSet> basis, const Ref<Integral>& integral,
 | 
|---|
| 65 |                            const RefDiagSCMatrix& evals, int nfzc, int nfzv, IndexOrder moorder) :
 | 
|---|
| 66 |   name_(name), basis_(basis), integral_(integral), full_rank_(full_coefs.coldim().n()), moorder_(moorder)
 | 
|---|
| 67 | {
 | 
|---|
| 68 |   if (evals.null())
 | 
|---|
| 69 |     throw std::runtime_error("MOIndexSpace::MOIndexSpace() -- null eigenvalues matrix");
 | 
|---|
| 70 |   if (nfzc < 0 || nfzc >= full_coefs.coldim().n())
 | 
|---|
| 71 |     throw std::runtime_error("MOIndexSpace::MOIndexSpace() -- invalid nfzc");
 | 
|---|
| 72 |   if (nfzc + nfzv >= full_coefs.coldim().n())
 | 
|---|
| 73 |     throw std::runtime_error("MOIndexSpace::MOIndexSpace() -- invalid nfzc+nfzv");
 | 
|---|
| 74 |   frozen_to_blockinfo(nfzc,nfzv,evals);
 | 
|---|
| 75 |   full_coefs_to_coefs(full_coefs, evals);
 | 
|---|
| 76 |   
 | 
|---|
| 77 |   init();
 | 
|---|
| 78 | }
 | 
|---|
| 79 | 
 | 
|---|
| 80 | MOIndexSpace::MOIndexSpace(std::string name, const RefSCMatrix& full_coefs,
 | 
|---|
| 81 |   const Ref<GaussianBasisSet> basis, const Ref<Integral>& integral) :
 | 
|---|
| 82 |   name_(name), basis_(basis), integral_(integral),
 | 
|---|
| 83 |   full_rank_(full_coefs.coldim().n()), moorder_(symmetry)
 | 
|---|
| 84 | {
 | 
|---|
| 85 |   Ref<SCBlockInfo> modim_blocks = full_coefs.coldim()->blocks();
 | 
|---|
| 86 |   int nb = modim_blocks->nblock();
 | 
|---|
| 87 |   offsets_.resize(nb);
 | 
|---|
| 88 |   nmo_.resize(nb);
 | 
|---|
| 89 |   for(int i=0; i<nb; i++) {
 | 
|---|
| 90 |     offsets_[i] = 0;
 | 
|---|
| 91 |     nmo_[i] = modim_blocks->size(i);
 | 
|---|
| 92 |   }
 | 
|---|
| 93 |   
 | 
|---|
| 94 |   full_coefs_to_coefs(full_coefs, 0);
 | 
|---|
| 95 |   
 | 
|---|
| 96 |   init();
 | 
|---|
| 97 | }
 | 
|---|
| 98 | 
 | 
|---|
| 99 | MOIndexSpace::MOIndexSpace(std::string name, const Ref<MOIndexSpace>& orig_space, const RefSCMatrix& new_coefs,
 | 
|---|
| 100 |                            const Ref<GaussianBasisSet>& new_basis) :
 | 
|---|
| 101 |   name_(name), integral_(orig_space->integral()), mosym_(orig_space->mosym_), evals_(orig_space->evals_),
 | 
|---|
| 102 |   rank_(orig_space->rank_), full_rank_(orig_space->full_rank_), nblocks_(orig_space->nblocks_),
 | 
|---|
| 103 |   offsets_(orig_space->offsets_), nmo_(orig_space->nmo_), map_to_full_space_(orig_space->map_to_full_space_),
 | 
|---|
| 104 |   moorder_(orig_space->moorder_)
 | 
|---|
| 105 | {
 | 
|---|
| 106 |   if (rank_ != new_coefs.coldim()->n())
 | 
|---|
| 107 |     throw std::runtime_error("MOIndexSpace::MOIndexSpace() -- new_coefs have different number of orbitals");
 | 
|---|
| 108 |   coefs_ = new_coefs;
 | 
|---|
| 109 |   basis_ = new_basis;
 | 
|---|
| 110 |   init();
 | 
|---|
| 111 | }
 | 
|---|
| 112 | 
 | 
|---|
| 113 | MOIndexSpace::MOIndexSpace(StateIn& si) : SavableState(si)
 | 
|---|
| 114 | {
 | 
|---|
| 115 |   si.get(name_);
 | 
|---|
| 116 | 
 | 
|---|
| 117 |   coefs_.restore(si);
 | 
|---|
| 118 |   evals_.restore(si);
 | 
|---|
| 119 |   basis_ << SavableState::restore_state(si);
 | 
|---|
| 120 |   integral_ << SavableState::restore_state(si);
 | 
|---|
| 121 |   si.get(mosym_);
 | 
|---|
| 122 | 
 | 
|---|
| 123 |   si.get(rank_);
 | 
|---|
| 124 |   si.get(full_rank_);
 | 
|---|
| 125 |   si.get(nblocks_);
 | 
|---|
| 126 |   si.get(offsets_);
 | 
|---|
| 127 |   si.get(nmo_);
 | 
|---|
| 128 |   si.get(map_to_full_space_);
 | 
|---|
| 129 | 
 | 
|---|
| 130 |   int moorder; si.get(moorder); moorder = (int) moorder_;
 | 
|---|
| 131 |   
 | 
|---|
| 132 |   init();
 | 
|---|
| 133 | }
 | 
|---|
| 134 | 
 | 
|---|
| 135 | MOIndexSpace::~MOIndexSpace()
 | 
|---|
| 136 | {
 | 
|---|
| 137 | }
 | 
|---|
| 138 | 
 | 
|---|
| 139 | void
 | 
|---|
| 140 | MOIndexSpace::save_data_state(StateOut& so)
 | 
|---|
| 141 | {
 | 
|---|
| 142 |   so.put(name_);
 | 
|---|
| 143 | 
 | 
|---|
| 144 |   coefs_.save(so);
 | 
|---|
| 145 |   evals_.save(so);
 | 
|---|
| 146 |   modim_ = evals_.dim();
 | 
|---|
| 147 |   SavableState::save_state(basis_.pointer(),so);
 | 
|---|
| 148 |   SavableState::save_state(integral_.pointer(),so);
 | 
|---|
| 149 |   so.put(mosym_);
 | 
|---|
| 150 | 
 | 
|---|
| 151 |   so.put(rank_);
 | 
|---|
| 152 |   so.put(full_rank_);
 | 
|---|
| 153 |   so.put(nblocks_);
 | 
|---|
| 154 |   so.put(offsets_);
 | 
|---|
| 155 |   so.put(nmo_);
 | 
|---|
| 156 |   so.put(map_to_full_space_);
 | 
|---|
| 157 | 
 | 
|---|
| 158 |   so.put((int)moorder_);
 | 
|---|
| 159 | }
 | 
|---|
| 160 | 
 | 
|---|
| 161 | const std::string
 | 
|---|
| 162 | MOIndexSpace::name() const { return name_; }
 | 
|---|
| 163 | 
 | 
|---|
| 164 | const Ref<GaussianBasisSet>
 | 
|---|
| 165 | MOIndexSpace::basis() const { return basis_; }
 | 
|---|
| 166 | 
 | 
|---|
| 167 | Ref<Integral>
 | 
|---|
| 168 | MOIndexSpace::integral() const { return integral_; }
 | 
|---|
| 169 | 
 | 
|---|
| 170 | const RefSCMatrix
 | 
|---|
| 171 | MOIndexSpace::coefs() const { return coefs_; }
 | 
|---|
| 172 | 
 | 
|---|
| 173 | const RefDiagSCMatrix
 | 
|---|
| 174 | MOIndexSpace::evals() const { return evals_; }
 | 
|---|
| 175 | 
 | 
|---|
| 176 | vector<int>
 | 
|---|
| 177 | MOIndexSpace::mosym() const { return mosym_; }
 | 
|---|
| 178 | 
 | 
|---|
| 179 | MOIndexSpace::IndexOrder
 | 
|---|
| 180 | MOIndexSpace::moorder() const { return moorder_; }
 | 
|---|
| 181 | 
 | 
|---|
| 182 | int
 | 
|---|
| 183 | MOIndexSpace::rank() const { return rank_; }
 | 
|---|
| 184 | 
 | 
|---|
| 185 | int
 | 
|---|
| 186 | MOIndexSpace::full_rank() const { return full_rank_; }
 | 
|---|
| 187 | 
 | 
|---|
| 188 | int
 | 
|---|
| 189 | MOIndexSpace::nblocks() const { return nblocks_; }
 | 
|---|
| 190 | 
 | 
|---|
| 191 | vector<int>
 | 
|---|
| 192 | MOIndexSpace::nmo() const { return nmo_; }
 | 
|---|
| 193 | 
 | 
|---|
| 194 | vector<int>
 | 
|---|
| 195 | MOIndexSpace::offsets() const { return offsets_; }
 | 
|---|
| 196 | 
 | 
|---|
| 197 | int
 | 
|---|
| 198 | MOIndexSpace::to_full_space(const int i) const { return map_to_full_space_.at(i); }
 | 
|---|
| 199 | 
 | 
|---|
| 200 | void
 | 
|---|
| 201 | MOIndexSpace::check_mosym() const
 | 
|---|
| 202 | {
 | 
|---|
| 203 |   int ng = basis_->molecule()->point_group()->char_table().order();
 | 
|---|
| 204 |   
 | 
|---|
| 205 |   for(vector<int>::const_iterator p=mosym_.begin(); p != mosym_.end(); ++p) {
 | 
|---|
| 206 |     if (*p < 0 || *p >= ng)
 | 
|---|
| 207 |       throw std::runtime_error("MOIndexSpace::check_mosym() -- invalid value in the list of orbital irreps");
 | 
|---|
| 208 |   }
 | 
|---|
| 209 | }
 | 
|---|
| 210 | 
 | 
|---|
| 211 | 
 | 
|---|
| 212 | void
 | 
|---|
| 213 | MOIndexSpace::frozen_to_blockinfo(const int nfzc, const int nfzv, const RefDiagSCMatrix& evals)
 | 
|---|
| 214 | {
 | 
|---|
| 215 |   int rank = evals.dim().n();
 | 
|---|
| 216 | 
 | 
|---|
| 217 |   int nb = evals.dim()->blocks()->nblock();
 | 
|---|
| 218 |   nmo_.resize(nb);
 | 
|---|
| 219 |   offsets_.resize(nb);
 | 
|---|
| 220 |   for(int b=0; b<nb; b++) {
 | 
|---|
| 221 |     nmo_[b] = evals.dim()->blocks()->size(b);
 | 
|---|
| 222 |     offsets_[b] = 0;
 | 
|---|
| 223 |   }
 | 
|---|
| 224 |   
 | 
|---|
| 225 |   // Get the energies of the orbitals in this space
 | 
|---|
| 226 |   double* energy = new double[rank];
 | 
|---|
| 227 |   int* index_map = new int[rank];
 | 
|---|
| 228 |   vector<int> blocked_index_to_irrep(rank);
 | 
|---|
| 229 |   int ii = 0;     // blocked index to this space
 | 
|---|
| 230 |   int offset = 0;
 | 
|---|
| 231 |   for(int b=0; b<nb; b++) {
 | 
|---|
| 232 |     for(int i=0; i<nmo_[b]; i++, ii++) {
 | 
|---|
| 233 |       energy[ii] = evals.get_element(i+offset);
 | 
|---|
| 234 |       blocked_index_to_irrep[ii] = b;
 | 
|---|
| 235 |     }
 | 
|---|
| 236 |     offset += nmo_[b];
 | 
|---|
| 237 |   }
 | 
|---|
| 238 |     
 | 
|---|
| 239 |   // Do the sort
 | 
|---|
| 240 |   dquicksort(energy,index_map,rank);
 | 
|---|
| 241 |   delete[] energy;
 | 
|---|
| 242 |   
 | 
|---|
| 243 |   // Get rid of nfzc lowest orbitals
 | 
|---|
| 244 |   for(int i=0; i<nfzc; i++) {
 | 
|---|
| 245 |     int b = blocked_index_to_irrep[index_map[i]];
 | 
|---|
| 246 |     ++offsets_[b];
 | 
|---|
| 247 |     --nmo_[b];
 | 
|---|
| 248 |   }
 | 
|---|
| 249 | 
 | 
|---|
| 250 |   // Get rid of nfzv highest orbitals
 | 
|---|
| 251 |   for(int i=rank-nfzv; i<rank; i++) {
 | 
|---|
| 252 |     int b = blocked_index_to_irrep[index_map[i]];
 | 
|---|
| 253 |     --nmo_[b];
 | 
|---|
| 254 |   }
 | 
|---|
| 255 |   
 | 
|---|
| 256 |   delete[] index_map;
 | 
|---|
| 257 | }
 | 
|---|
| 258 | 
 | 
|---|
| 259 | void
 | 
|---|
| 260 | MOIndexSpace::full_coefs_to_coefs(const RefSCMatrix& full_coefs, const RefDiagSCMatrix& evals)
 | 
|---|
| 261 | {
 | 
|---|
| 262 |   // compute the rank of this
 | 
|---|
| 263 |   rank_ = 0;
 | 
|---|
| 264 |   for(vector<int>::const_iterator p=nmo_.begin(); p != nmo_.end(); ++p) {
 | 
|---|
| 265 |     rank_ += *p;
 | 
|---|
| 266 |   }
 | 
|---|
| 267 | 
 | 
|---|
| 268 |   mosym_.resize(rank_);
 | 
|---|
| 269 |   RefSCDimension modim = full_coefs.coldim();  // the dimension of the full space
 | 
|---|
| 270 |   
 | 
|---|
| 271 |   // In general vectors are ordered differently from the original
 | 
|---|
| 272 |   int* index_map = new int[rank_];                      // maps index in this (sorted) space to this (blocked) space
 | 
|---|
| 273 |   vector<int> blocked_subindex_to_full_index(rank_);    // maps index from this space(in blocked form) into the full space
 | 
|---|
| 274 |   vector<int> blocked_subindex_to_irrep(rank_);         // maps index from this space(in blocked form) to the irrep
 | 
|---|
| 275 |   if (moorder_ == symmetry) {
 | 
|---|
| 276 |     // coefs_ has the same number of blocks as full_coefs_
 | 
|---|
| 277 |     int nb = modim->blocks()->nblock();
 | 
|---|
| 278 |     int* nfunc_per_block = new int[nb];
 | 
|---|
| 279 |     for(int i=0; i<nb; i++)
 | 
|---|
| 280 |       nfunc_per_block[i] = nmo_[i];
 | 
|---|
| 281 |     modim_ = new SCDimension(rank_, nb, nfunc_per_block, ("MO(" + name_ + ")").c_str());
 | 
|---|
| 282 |     for(int i=0; i<nb; i++)
 | 
|---|
| 283 |       modim_->blocks()->set_subdim(i, new SCDimension(nfunc_per_block[i]));
 | 
|---|
| 284 |     delete[] nfunc_per_block;
 | 
|---|
| 285 |   
 | 
|---|
| 286 |     // The sorted->blocked reordering array is trivial when no resorting is done
 | 
|---|
| 287 |     for(int i=0; i<rank_; i++) {
 | 
|---|
| 288 |       index_map[i] = i;
 | 
|---|
| 289 |     }
 | 
|---|
| 290 |     
 | 
|---|
| 291 |     int ii = 0;     // blocked index to this space
 | 
|---|
| 292 |     int offset = 0;
 | 
|---|
| 293 |     for(int b=0; b<nb; b++) {
 | 
|---|
| 294 |       for(int i=0; i<nmo_[b]; i++, ii++) {
 | 
|---|
| 295 |         blocked_subindex_to_full_index[ii] = i+offsets_[b]+offset;
 | 
|---|
| 296 |         blocked_subindex_to_irrep[ii] = b;
 | 
|---|
| 297 |       }
 | 
|---|
| 298 |       offset += modim->blocks()->size(b);
 | 
|---|
| 299 |     }    
 | 
|---|
| 300 |   }
 | 
|---|
| 301 |   else if (moorder_ == energy) {
 | 
|---|
| 302 |     //
 | 
|---|
| 303 |     // Sort vectors by their energy
 | 
|---|
| 304 |     //
 | 
|---|
| 305 |     
 | 
|---|
| 306 |     // Get the energies of the orbitals in this space
 | 
|---|
| 307 |     double* energy = new double[rank_];
 | 
|---|
| 308 |     int nb = nmo_.size();
 | 
|---|
| 309 |     int ii = 0;     // blocked index to this space
 | 
|---|
| 310 |     int offset = 0;
 | 
|---|
| 311 |     for(int b=0; b<nb; b++) {
 | 
|---|
| 312 |       for(int i=0; i<nmo_[b]; i++, ii++) {
 | 
|---|
| 313 |         energy[ii] = evals.get_element(i+offsets_[b]+offset);
 | 
|---|
| 314 |         blocked_subindex_to_full_index[ii] = i+offsets_[b]+offset;
 | 
|---|
| 315 |         blocked_subindex_to_irrep[ii] = b;
 | 
|---|
| 316 |       }
 | 
|---|
| 317 |       offset += modim->blocks()->size(b);
 | 
|---|
| 318 |     }
 | 
|---|
| 319 |     
 | 
|---|
| 320 |     // Do the sort
 | 
|---|
| 321 |     dquicksort(energy,index_map,rank_);
 | 
|---|
| 322 |     
 | 
|---|
| 323 |     // coefs_ has 1 block
 | 
|---|
| 324 |     int* nfunc_per_block = new int[1];
 | 
|---|
| 325 |     nfunc_per_block[0] = rank_;
 | 
|---|
| 326 |     modim_ = new SCDimension(rank_, 1, nfunc_per_block, ("MO(" + name_ + ")").c_str());
 | 
|---|
| 327 |     modim_->blocks()->set_subdim(0, new SCDimension(nfunc_per_block[0]));
 | 
|---|
| 328 |     
 | 
|---|
| 329 |     // Recompute offsets_ and nmo_ to conform the energy ordering
 | 
|---|
| 330 |     offset = 0;
 | 
|---|
| 331 |     for(vector<int>::const_iterator p=offsets_.begin(); p != offsets_.end(); ++p) {
 | 
|---|
| 332 |       offset += *p;
 | 
|---|
| 333 |     }
 | 
|---|
| 334 |     offsets_.resize(1);
 | 
|---|
| 335 |     offsets_[0] = offset;
 | 
|---|
| 336 |     nmo_.resize(1);
 | 
|---|
| 337 |     nmo_[0] = rank_;
 | 
|---|
| 338 |     
 | 
|---|
| 339 |     delete[] energy;
 | 
|---|
| 340 |     delete[] nfunc_per_block;
 | 
|---|
| 341 |   }
 | 
|---|
| 342 |   else
 | 
|---|
| 343 |     throw std::runtime_error("MOIndexSpace::full_coefs_to_coefs() -- moorder should be either energy or symmetry");
 | 
|---|
| 344 |   
 | 
|---|
| 345 |   // Copy required columns of full_coefs_ into coefs_
 | 
|---|
| 346 |   RefSCDimension aodim = full_coefs.rowdim();
 | 
|---|
| 347 |   Ref<SCMatrixKit> so_matrixkit = basis_->so_matrixkit();
 | 
|---|
| 348 |   coefs_ = so_matrixkit->matrix(aodim, modim_);
 | 
|---|
| 349 |   evals_ = so_matrixkit->diagmatrix(modim_);
 | 
|---|
| 350 |   for (int i=0; i<rank_; i++) {
 | 
|---|
| 351 |     int ii = blocked_subindex_to_full_index[index_map[i]];
 | 
|---|
| 352 |     mosym_[i] = blocked_subindex_to_irrep[index_map[i]];
 | 
|---|
| 353 |     for (int j=0; j<aodim.n(); j++) {
 | 
|---|
| 354 |       coefs_(j,i) = full_coefs(j,ii);
 | 
|---|
| 355 |     }
 | 
|---|
| 356 |   }
 | 
|---|
| 357 |   if (evals.nonnull())
 | 
|---|
| 358 |     for (int i=0; i<rank_; i++) {
 | 
|---|
| 359 |       int ii = blocked_subindex_to_full_index[index_map[i]];
 | 
|---|
| 360 |       evals_(i) = evals(ii);
 | 
|---|
| 361 |     }
 | 
|---|
| 362 |   else
 | 
|---|
| 363 |     evals_.assign(0.0);
 | 
|---|
| 364 | 
 | 
|---|
| 365 |   nblocks_ = modim_->blocks()->nblock();
 | 
|---|
| 366 | 
 | 
|---|
| 367 |   // Compute the map to the full space
 | 
|---|
| 368 |   map_to_full_space_.resize(rank_);
 | 
|---|
| 369 |   for (int i=0; i<rank_; i++) {
 | 
|---|
| 370 |     map_to_full_space_[i] = blocked_subindex_to_full_index[index_map[i]];
 | 
|---|
| 371 |   }
 | 
|---|
| 372 | 
 | 
|---|
| 373 |   delete[] index_map;  
 | 
|---|
| 374 | }
 | 
|---|
| 375 | 
 | 
|---|
| 376 | void
 | 
|---|
| 377 | MOIndexSpace::init()
 | 
|---|
| 378 | {
 | 
|---|
| 379 | }
 | 
|---|
| 380 | 
 | 
|---|
| 381 | 
 | 
|---|
| 382 | size_t
 | 
|---|
| 383 | MOIndexSpace::memory_in_use() const
 | 
|---|
| 384 | {
 | 
|---|
| 385 |   size_t memory = (size_t)basis_->nbasis() * rank_ * sizeof(double);
 | 
|---|
| 386 |   return memory;
 | 
|---|
| 387 | }
 | 
|---|
| 388 | 
 | 
|---|
| 389 | void
 | 
|---|
| 390 | MOIndexSpace::print(ostream&o) const
 | 
|---|
| 391 | {
 | 
|---|
| 392 |   o << indent << "MOIndexSpace \"" << name_ << "\":" << endl;
 | 
|---|
| 393 |   o << incindent;
 | 
|---|
| 394 |   o << indent << "Basis Set:" << endl;
 | 
|---|
| 395 |   o << incindent; basis_->print(o); o << decindent << endl;
 | 
|---|
| 396 |   o << decindent;
 | 
|---|
| 397 | }
 | 
|---|
| 398 | 
 | 
|---|
| 399 | void
 | 
|---|
| 400 | MOIndexSpace::print_summary(ostream& o) const
 | 
|---|
| 401 | {
 | 
|---|
| 402 |   o << indent << "MOIndexSpace \"" << name_ << "\":" << endl;
 | 
|---|
| 403 |   o << incindent;
 | 
|---|
| 404 |   o << indent << "GaussianBasisSet \"" << basis_->name() << "\""<< endl;
 | 
|---|
| 405 |   o << indent << "  rank  nbasis  nshell  nfuncmax" << endl;
 | 
|---|
| 406 |   o << indent << scprintf("  %-6i %-6i  %-6i   %-6i",
 | 
|---|
| 407 |                           rank_,
 | 
|---|
| 408 |                           basis_->nbasis(),
 | 
|---|
| 409 |                           basis_->nshell(),
 | 
|---|
| 410 |                           basis_->max_nfunction_in_shell()) << endl;
 | 
|---|
| 411 |   o << decindent;
 | 
|---|
| 412 | 
 | 
|---|
| 413 | }
 | 
|---|
| 414 | 
 | 
|---|
| 415 | /////////////////////////////////////////////////////////////////
 | 
|---|
| 416 | // Function dquicksort performs a quick sort (smaller -> larger) 
 | 
|---|
| 417 | // of the double data in item by the integer indices in index;
 | 
|---|
| 418 | // data in item remain unchanged
 | 
|---|
| 419 | //
 | 
|---|
| 420 | // Both functions borrowed from lib/chemistry/qc/mbpt/mbpt.cc
 | 
|---|
| 421 | //
 | 
|---|
| 422 | /////////////////////////////////////////////////////////////////
 | 
|---|
| 423 | void
 | 
|---|
| 424 | MOIndexSpace::dqs(double *item,int *index,int left,int right)
 | 
|---|
| 425 | {
 | 
|---|
| 426 |   int i,j;
 | 
|---|
| 427 |   double x;
 | 
|---|
| 428 |   int y;
 | 
|---|
| 429 |   const double small_diff = 1.0e-12;
 | 
|---|
| 430 |   
 | 
|---|
| 431 |   i=left; j=right;
 | 
|---|
| 432 |   x=item[index[(left+right)/2]];
 | 
|---|
| 433 |   
 | 
|---|
| 434 |   do {
 | 
|---|
| 435 |     while(item[index[i]]<x && fabs(x-item[index[i]]) > small_diff && i<right) i++;
 | 
|---|
| 436 |     while(x<item[index[j]] && fabs(x-item[index[j]]) > small_diff && j>left) j--;
 | 
|---|
| 437 |     
 | 
|---|
| 438 |     if (i<=j) {
 | 
|---|
| 439 |       if (fabs(item[index[i]] - item[index[j]]) > small_diff) {
 | 
|---|
| 440 |         y=index[i];
 | 
|---|
| 441 |         index[i]=index[j];
 | 
|---|
| 442 |         index[j]=y;
 | 
|---|
| 443 |       }
 | 
|---|
| 444 |       i++; j--;
 | 
|---|
| 445 |     }
 | 
|---|
| 446 |   } while(i<=j);
 | 
|---|
| 447 |   
 | 
|---|
| 448 |   if (left<j) dqs(item,index,left,j);
 | 
|---|
| 449 |   if (i<right) dqs(item,index,i,right);
 | 
|---|
| 450 | }
 | 
|---|
| 451 | 
 | 
|---|
| 452 | namespace {
 | 
|---|
| 453 |   // use this to compute permutation corresponding to a sort
 | 
|---|
| 454 |   class IndexedValue {
 | 
|---|
| 455 |     int index_;
 | 
|---|
| 456 |     double value_;
 | 
|---|
| 457 |   public:
 | 
|---|
| 458 |     IndexedValue(int index, double value) : index_(index), value_(value) {}
 | 
|---|
| 459 |     int index() const { return index_; }
 | 
|---|
| 460 |     double value() const { return value_; }
 | 
|---|
| 461 | 
 | 
|---|
| 462 |     bool operator<(const IndexedValue& a) const {
 | 
|---|
| 463 |       const double small_diff = 1.0e-12;
 | 
|---|
| 464 |       if (fabs(value_-a.value_) < small_diff)
 | 
|---|
| 465 |         return false;
 | 
|---|
| 466 |       else
 | 
|---|
| 467 |         return value_ < a.value_;
 | 
|---|
| 468 |     }
 | 
|---|
| 469 |   };
 | 
|---|
| 470 | 
 | 
|---|
| 471 | };
 | 
|---|
| 472 | 
 | 
|---|
| 473 | 
 | 
|---|
| 474 | void
 | 
|---|
| 475 | MOIndexSpace::dquicksort(double *item,int *index,int n)
 | 
|---|
| 476 | {
 | 
|---|
| 477 |   if (n<=0) return;
 | 
|---|
| 478 |   typedef vector<IndexedValue> vectype;
 | 
|---|
| 479 |   typedef vector<IndexedValue>::iterator iter;
 | 
|---|
| 480 |   vector<IndexedValue> vals;
 | 
|---|
| 481 |   for (int i=0; i<n; i++) {
 | 
|---|
| 482 |     IndexedValue val(i,item[i]);
 | 
|---|
| 483 |     vals.push_back(val);
 | 
|---|
| 484 |   }
 | 
|---|
| 485 |   stable_sort(vals.begin(),vals.end());
 | 
|---|
| 486 |   for (int i=0; i<n; i++) {
 | 
|---|
| 487 |     index[i] = vals.at(i).index();
 | 
|---|
| 488 |   }
 | 
|---|
| 489 | }
 | 
|---|
| 490 | 
 | 
|---|
| 491 | 
 | 
|---|
| 492 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 493 | 
 | 
|---|
| 494 | // Local Variables:
 | 
|---|
| 495 | // mode: c++
 | 
|---|
| 496 | // c-file-style: "CLJ-CONDENSED"
 | 
|---|
| 497 | // End:
 | 
|---|