|
MPQC
3.0.0-alpha
|
00001 // 00002 // rdm.h 00003 // 00004 // Copyright (C) 2009 Edward Valeev 00005 // 00006 // Author: Edward Valeev <evaleev@vt.edu> 00007 // Maintainer: EV 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 00026 // 00027 00028 #ifndef _mpqc_src_lib_chemistry_qc_mbptr12_rdm_h 00029 #define _mpqc_src_lib_chemistry_qc_mbptr12_rdm_h 00030 00031 #include <chemistry/qc/wfn/wfn.h> 00032 #include <chemistry/qc/wfn/obwfn.h> 00033 #include <chemistry/qc/wfn/spin.h> 00034 #include <math/distarray4/distarray4.h> 00035 00036 namespace sc { 00037 00039 typedef enum {Zero=0, One = 1, Two = 2, Three = 3, Four = 4} Rank; 00040 00041 namespace { 00042 template <Rank R> struct __spincase; 00043 template <> struct __spincase<One> { 00044 typedef SpinCase1 type; 00045 }; 00046 template <> struct __spincase<Two> { 00047 typedef SpinCase2 type; 00048 }; 00049 00050 template <Rank R> struct __nspincases; 00051 template <> struct __nspincases<One> { 00052 static const int value = NSpinCases1; 00053 }; 00054 template <> struct __nspincases<Two> { 00055 static const int value = NSpinCases2; 00056 }; 00057 00058 } 00059 00060 template <Rank R> class RDMCumulant; 00061 class OrbitalSpace; 00062 00065 template <Rank R> 00066 class RDM : public Compute, virtual public SavableState { 00067 typedef RDM<R> this_type; 00068 typedef typename __spincase<R>::type spincase; 00069 public: 00082 RDM(const Ref<KeyVal>& kv) { 00083 wfn_ = require_dynamic_cast<Wavefunction*>( 00084 kv->describedclassvalue("wfn").pointer(), 00085 "RDM<R>::RDM\n" 00086 ); 00087 } 00088 RDM(StateIn& si) : SavableState(si) { 00089 wfn_ << SavableState::restore_state(si); 00090 } 00091 RDM(const Ref<Wavefunction>& wfn) : wfn_(wfn) { 00092 } 00093 ~RDM() { 00094 } 00095 void save_data_state(StateOut& so) { 00096 SavableState::save_state(wfn_.pointer(), so); 00097 } 00098 00099 virtual void obsolete() { 00100 wfn_->obsolete(); 00101 for(int s=0; s<__nspincases<R>::value; ++s) 00102 scmat_[s] = 0; 00103 } 00104 00106 Ref<Wavefunction> wfn() const { return wfn_; } 00107 virtual void compute() { 00108 const double energy = wfn_->value(); 00109 } 00111 virtual Ref<OrbitalSpace> orbs(SpinCase1 s) const =0; 00113 virtual size_t ndim(spincase spincase) const; 00115 virtual const double* obtain_block(spincase spin, size_t bra) const { 00116 throw ProgrammingError("RDM<R>::obtain_block() is not yet implemented", 00117 __FILE__, 00118 __LINE__); 00119 } 00121 virtual void release_block(spincase spin, size_t bra, double*) const { 00122 throw ProgrammingError("RDM<R>::release_block() is not yet implemented", 00123 __FILE__, 00124 __LINE__); 00125 } 00127 virtual RefSymmSCMatrix scmat(spincase spin) const; 00128 00130 virtual Ref< RDMCumulant<R> > cumulant() const; 00132 virtual Ref< RDM< static_cast<Rank>(R-1) > > rdm_m_1() const; 00133 00134 private: 00135 static ClassDesc class_desc_; 00136 Ref<Wavefunction> wfn_; 00137 00138 protected: 00139 mutable RefSymmSCMatrix scmat_[__nspincases<R>::value]; 00140 }; 00141 00142 template <Rank R> 00143 ClassDesc 00144 RDM<R>::class_desc_(typeid(this_type), 00145 (std::string("RDM<") + 00146 char('1' + R - 1) + 00147 std::string(">") 00148 ).c_str(), 1, 00149 "virtual public SavableState", 0, 0, 0 ); 00150 00152 template <> class RDM<Zero> : public RefCount {}; 00153 00155 00158 template <Rank R> 00159 class RDMCumulant : public Compute, virtual public SavableState { 00160 typedef RDMCumulant<R> this_type; 00161 typedef RDM<R> density_type; 00162 typedef typename __spincase<R>::type spincase; 00163 public: 00164 RDMCumulant(const Ref<density_type>& density) : density_(density) { 00165 } 00166 RDMCumulant(StateIn& si) : SavableState(si) { 00167 density_ << SavableState::restore_state(si); 00168 } 00169 ~RDMCumulant() { 00170 } 00171 void save_data_state(StateOut& so) { 00172 SavableState::save_state(density_.pointer(), so); 00173 } 00174 void obsolete() { 00175 density_->obsolete(); 00176 for(int s=0; s<__nspincases<R>::value; ++s) 00177 scmat_[s] = 0; 00178 } 00179 00181 Ref<Wavefunction> wfn() const { return density_->wfn(); } 00182 void compute() { density_->compute(); } 00184 Ref<density_type> density() const { return density_; } 00186 size_t ndim(spincase spincase) const { return density_->ndim(); } 00188 virtual const double* obtain_block(spincase spin, size_t bra) const { 00189 throw ProgrammingError("RDMCumulant<R>::obtain_block() is not yet implemented", 00190 __FILE__, 00191 __LINE__); 00192 } 00194 virtual void release_block(spincase spin, size_t bra, double*) const { 00195 throw ProgrammingError("RDMCumulant<R>::release_block() is not yet implemented", 00196 __FILE__, 00197 __LINE__); 00198 } 00200 virtual RefSymmSCMatrix scmat(spincase spin) const; 00201 00202 private: 00203 static ClassDesc class_desc_; 00204 Ref<density_type> density_; 00205 00206 protected: 00207 mutable RefSymmSCMatrix scmat_[__nspincases<R>::value]; 00208 }; 00209 00210 template <Rank R> 00211 ClassDesc 00212 RDMCumulant<R>::class_desc_(typeid(this_type), 00213 (std::string("RDMCumulant<") + 00214 char('1' + R - 1) + 00215 std::string(">") 00216 ).c_str(), 1, 00217 "virtual public SavableState", 0, 0, 0 ); 00218 00219 00222 template <Rank R> 00223 class SpinFreeRDM : public Compute, virtual public SavableState { 00224 typedef SpinFreeRDM<R> this_type; 00225 typedef typename __spincase<R>::type spincase; 00226 public: 00239 SpinFreeRDM(const Ref<KeyVal>& kv) { 00240 wfn_ = require_dynamic_cast<Wavefunction*>( 00241 kv->describedclassvalue("wfn").pointer(), 00242 "RDM<R>::RDM\n" 00243 ); 00244 } 00245 SpinFreeRDM(StateIn& si) : SavableState(si) { 00246 wfn_ << SavableState::restore_state(si); 00247 } 00248 SpinFreeRDM(const Ref<Wavefunction>& wfn) : wfn_(wfn) { 00249 } 00250 ~SpinFreeRDM() { 00251 } 00252 void save_data_state(StateOut& so) { 00253 SavableState::save_state(wfn_.pointer(), so); 00254 } 00255 00256 virtual void obsolete() { 00257 wfn_->obsolete(); 00258 scmat_ = 0; 00259 da4_ = 0; 00260 } 00261 00263 Ref<Wavefunction> wfn() const { return wfn_; } 00264 virtual void compute() { 00265 const double energy = wfn_->value(); 00266 } 00268 virtual Ref<OrbitalSpace> orbs() const =0; 00270 virtual size_t ndim() const; 00272 virtual const double* obtain_block(spincase spin, size_t bra) const { 00273 throw ProgrammingError("SpinFreeRDM<R>::obtain_block() is not yet implemented", 00274 __FILE__, 00275 __LINE__); 00276 } 00278 virtual void release_block(spincase spin, size_t bra, double*) const { 00279 throw ProgrammingError("SpinFreeRDM<R>::release_block() is not yet implemented", 00280 __FILE__, 00281 __LINE__); 00282 } 00284 virtual RefSymmSCMatrix scmat() const; 00288 virtual const Ref<DistArray4>& da4() const; 00289 00291 virtual Ref< SpinFreeRDM< static_cast<Rank>(R-1) > > rdm_m_1() const; 00292 00293 private: 00294 static ClassDesc class_desc_; 00295 Ref<Wavefunction> wfn_; 00296 00297 protected: 00298 // used for R=1 00299 mutable RefSymmSCMatrix scmat_; 00300 // used for R=2 00301 mutable Ref<DistArray4> da4_; 00302 }; 00303 00304 template <Rank R> 00305 ClassDesc 00306 SpinFreeRDM<R>::class_desc_(typeid(this_type), 00307 (std::string("SpinFreeRDM<") + 00308 char('1' + R - 1) + 00309 std::string(">") 00310 ).c_str(), 1, 00311 "virtual public SavableState", 0, 0, 0 ); 00312 00314 template <> class SpinFreeRDM<Zero> : public RefCount {}; 00315 00317 00318 class OrbitalSpace; 00319 00321 class OBWfnRDMTwo : public RDM<Two> { 00322 typedef RDMCumulant<Two> cumulant_type; 00323 typedef RDM<One> rdm_m_1_type; 00324 public: 00337 OBWfnRDMTwo(const Ref<KeyVal>& kv); 00338 OBWfnRDMTwo(StateIn& si); 00339 OBWfnRDMTwo(const Ref<OneBodyWavefunction>& wfn); 00340 virtual ~OBWfnRDMTwo(); 00341 void save_data_state(StateOut& so); 00342 00343 Ref<OneBodyWavefunction> wfn() const { return wfn_; } 00344 Ref<OrbitalSpace> orbs(SpinCase1 s) const; 00345 RefSymmSCMatrix scmat(SpinCase2 spincase) const; 00346 Ref<cumulant_type> cumulant() const; 00347 Ref<rdm_m_1_type> rdm_m_1() const; 00348 00349 private: 00350 Ref<OneBodyWavefunction> wfn_; 00351 mutable RefSymmSCMatrix scmat_[NSpinCases2]; 00352 mutable Ref<OrbitalSpace> orbs_[NSpinCases1]; 00353 00354 static ClassDesc class_desc_; 00355 }; 00356 00358 class OBWfnRDMCumulantTwo : public RDMCumulant<Two> { 00359 public: 00360 OBWfnRDMCumulantTwo(const Ref<OBWfnRDMTwo>& density); 00361 OBWfnRDMCumulantTwo(StateIn& si); 00362 virtual ~OBWfnRDMCumulantTwo(); 00363 void save_data_state(StateOut& so); 00364 00365 void compute(); 00366 const double* obtain_block(SpinCase2 spin, size_t bra) const; 00367 void release_block(SpinCase2, size_t bra, double*) const; 00368 RefSymmSCMatrix scmat(SpinCase2 spincase) const; 00369 00370 private: 00371 Ref<OBWfnRDMTwo> density_; 00372 mutable RefSymmSCMatrix scmat_[NSpinCases2]; 00373 00374 static ClassDesc class_desc_; 00375 }; 00376 00377 #if 0 00378 00379 00380 class WfnRDMOne : public RDM<One> { 00381 typedef RDMCumulant<One> cumulant_type; 00382 public: 00395 WfnRDMOne(const Ref<KeyVal>& kv); 00396 WfnRDMOne(StateIn& si); 00397 WfnRDMOne(const Ref<Wavefunction>& wfn); 00398 ~WfnRDMOne(); 00399 void save_data_state(StateOut& so); 00400 00401 Ref<Wavefunction> wfn() const { return wfn_; } 00402 void compute(); 00403 size_t ndim(SpinCase1 spincase) const; 00404 const double* obtain_block(SpinCase1 spin, size_t bra) const; 00405 void release_block(SpinCase1, size_t bra, double*) const; 00406 RefSymmSCMatrix scmat(SpinCase1 spincase) const; 00407 Ref<cumulant_type> cumulant() const; 00408 Ref< RDM<Zero> > rdm_m_1() const; 00409 00410 private: 00411 Ref<Wavefunction> wfn_; 00412 mutable RefSymmSCMatrix scmat_[NSpinCases1]; 00413 00414 static ClassDesc class_desc_; 00415 }; 00416 00418 class WfnRDMCumulantOne : public RDMCumulant<One> { 00419 public: 00420 WfnRDMCumulantOne(const Ref<WfnRDMOne>& density); 00421 WfnRDMCumulantOne(StateIn& si); 00422 ~WfnRDMCumulantOne(); 00423 void save_data_state(StateOut& so); 00424 00425 void compute(); 00426 const double* obtain_block(SpinCase1 spin, size_t bra) const; 00427 void release_block(SpinCase1, size_t bra, double*) const; 00428 RefSymmSCMatrix scmat(SpinCase1 spincase) const; 00429 00430 private: 00431 Ref<WfnRDMOne> density_; 00432 mutable RefSymmSCMatrix scmat_[NSpinCases1]; 00433 00434 static ClassDesc class_desc_; 00435 }; 00436 #endif 00437 00439 class OBWfnRDMOne : public RDM<One> { 00440 public: 00453 OBWfnRDMOne(const Ref<KeyVal>& kv); 00454 OBWfnRDMOne(StateIn& si); 00455 OBWfnRDMOne(const Ref<OneBodyWavefunction>& wfn); 00456 virtual ~OBWfnRDMOne(); 00457 void save_data_state(StateOut& so); 00458 00459 Ref<OneBodyWavefunction> wfn() const { return wfn_; } 00460 Ref<OrbitalSpace> orbs(SpinCase1 s) const; 00461 00462 private: 00463 Ref<OneBodyWavefunction> wfn_; 00464 mutable Ref<OrbitalSpace> orbs_[NSpinCases1]; 00465 00466 static ClassDesc class_desc_; 00467 }; 00468 00469 } // end of namespace sc 00470 00471 #endif // end of header guard 00472 00473 00474 // Local Variables: 00475 // mode: c++ 00476 // c-file-style: "CLJ-CONDENSED" 00477 // End: