MPQC  3.0.0-alpha
src/lib/chemistry/qc/wfn/rdm.h
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:

Generated at Sat Jul 7 2012 11:52:47 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.0.