abs_hmc.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // $Id: abs_hmc.h,v 3.7 2009/01/30 20:57:51 bjoo Exp $
00003 /*! \file
00004  * \brief Abstract HMC trajectory Using the new structure
00005  *
00006  * HMC trajectories
00007  */
00008 #ifndef abs_hmc_new_h
00009 #define abs_hmc_new_h
00010 
00011 #include "chromabase.h"
00012 #include "io/xmllog_io.h"
00013 #include "update/molecdyn/field_state.h"
00014 #include "update/molecdyn/hamiltonian//abs_hamiltonian.h"
00015 #include "update/molecdyn/integrator/abs_integrator.h"
00016 #include "update/molecdyn/hmc/global_metropolis_accrej.h"
00017 
00018 
00019 
00020 namespace Chroma 
00021 { 
00022 
00023   //! Abstract HMC trajectory
00024   /*! @ingroup hmc */
00025   template<typename P, typename Q>
00026   class AbsHMCTrj {
00027   public: 
00028     
00029     // Virtual destructor
00030     virtual ~AbsHMCTrj() {};
00031     
00032 
00033     // Do the HMC trajectory
00034     virtual void operator()(AbsFieldState<P,Q>& s,
00035                             const bool WarmUpP, 
00036                             const bool CheckRevP)
00037     {
00038       START_CODE();
00039 
00040       AbsMDIntegrator<P,Q>& MD = getMDIntegrator();
00041       AbsHamiltonian<P,Q>& H_MC = getMCHamiltonian();
00042 
00043       XMLWriter& xml_out = TheXMLOutputWriter::Instance();
00044       XMLWriter& xml_log = TheXMLLogWriter::Instance();
00045 
00046       // Self encapsulation rule 
00047       push(xml_out, "HMCTrajectory");
00048       push(xml_log, "HMCTrajectory");
00049 
00050       write(xml_out, "WarmUpP", WarmUpP);
00051       write(xml_log, "WarmUpP", WarmUpP);
00052 
00053       // HMC Algorithm.
00054       // 1) Refresh momenta
00055       //
00056       refreshP(s);
00057       
00058       // Refresh Pseudofermions
00059       H_MC.refreshInternalFields(s);
00060       
00061       // SaveState -- Perhaps this could be done better?
00062       Handle< AbsFieldState<P,Q> >  s_old(s.clone());
00063       
00064       // Measure energy of the old state
00065       Double KE_old, PE_old;
00066 
00067       push(xml_out, "H_old");
00068       push(xml_log, "H_old");
00069 
00070       H_MC.mesE(*s_old, KE_old, PE_old);
00071 
00072       write(xml_out, "KE_old", KE_old);
00073       write(xml_log, "KE_old", KE_old);
00074 
00075       write(xml_out, "PE_old", PE_old);
00076       write(xml_log, "PE_old", PE_old);
00077 
00078       pop(xml_log); // pop H_old
00079       pop(xml_out); // pop H_old
00080       
00081       
00082       // Copy in fields from the Hamiltonian as needed using the
00083       // CopyList
00084       MD.copyFields();
00085 
00086       // Integrate MD trajectory
00087       MD(s, MD.getTrajLength());
00088            
00089 
00090       // If this is a reverse trajectory
00091       if( CheckRevP ) { 
00092 
00093         QDPIO::cout << "Reversing trajectory for reversability test" <<endl;
00094 
00095         // Copy state
00096         Handle< AbsFieldState<P,Q> >  s_rev(s.clone());
00097         
00098         // Flip Momenta
00099         flipMomenta(*s_rev);
00100         
00101         // Go back
00102         MD(*s_rev, MD.getTrajLength());
00103 
00104         // Flip Momenta back (to original)
00105         flipMomenta(*s_rev);
00106 
00107 
00108         Double KE_rev;
00109         Double PE_rev;
00110        
00111         H_MC.mesE(*s_rev, KE_rev, PE_rev);
00112 
00113         Double DeltaDeltaKE = KE_rev - KE_old;
00114         Double DeltaDeltaPE = PE_rev - PE_old;
00115         Double DeltaDeltaH = DeltaDeltaKE + DeltaDeltaPE;
00116 
00117         
00118         Double dq;
00119         Double dp;
00120         reverseCheckMetrics(dq,dp, *s_rev, *s_old);
00121 
00122         push(xml_log, "ReversibilityMetrics");
00123         write(xml_log, "DeltaDeltaH", fabs(DeltaDeltaH));
00124         write(xml_log, "DeltaDeltaKE", fabs(DeltaDeltaKE));
00125         write(xml_log, "DeltaDeltaPE", fabs(DeltaDeltaPE));
00126         write(xml_log, "DeltaQPerSite", dq);
00127         write(xml_log, "DeltaPPerSite", dp);
00128         pop(xml_log);
00129 
00130         QDPIO::cout << "Reversibility: DeltaDeltaH = " << fabs(DeltaDeltaH) <<endl;
00131         QDPIO::cout << "Reversibility: DeltaQ      = " << dq << endl;
00132         QDPIO::cout << "Reversibility: DeltaP      = " << dp << endl;
00133 
00134 
00135         // s_rev goes away... We continue as if nothing happened
00136         
00137       }
00138 
00139       //  Measure the energy of the new state
00140       Double KE, PE;
00141 
00142 
00143       push(xml_out, "H_new");
00144       push(xml_log, "H_new");
00145       H_MC.mesE(s, KE, PE);
00146       write(xml_out, "KE_new", KE);
00147       write(xml_log, "KE_new", KE);
00148       write(xml_out, "PE_new", PE);
00149       write(xml_log, "PE_new", PE);
00150       pop(xml_log);
00151       pop(xml_out);
00152 
00153       // Work out energy differences
00154       Double DeltaKE = KE - KE_old;
00155       Double DeltaPE = PE - PE_old;
00156       Double DeltaH  = DeltaKE + DeltaPE;
00157       Double AccProb = where(DeltaH < 0.0, Double(1), exp(-DeltaH));
00158       write(xml_out, "deltaKE", DeltaKE);
00159       write(xml_log, "deltaKE", DeltaKE);
00160 
00161       write(xml_out, "deltaPE", DeltaPE);
00162       write(xml_log, "deltaPE", DeltaPE);
00163 
00164       write(xml_out, "deltaH", DeltaH);
00165       write(xml_log, "deltaH", DeltaH);
00166 
00167       write(xml_out, "AccProb", AccProb);
00168       write(xml_log, "AccProb", AccProb);
00169 
00170       QDPIO::cout << "Delta H = " << DeltaH << endl;
00171       QDPIO::cout << "AccProb = " << AccProb << endl;
00172 
00173       // If we intend to do an accept reject step
00174       // (ie we are not warming up)
00175       if( ! WarmUpP ) 
00176       { 
00177         // Measure Acceptance
00178         bool acceptTestResult = acceptReject(DeltaH);
00179         write(xml_out, "AcceptP", acceptTestResult);
00180         write(xml_log, "AcceptP", acceptTestResult);
00181 
00182         QDPIO::cout << "AcceptP = " << acceptTestResult << endl;
00183 
00184         // If rejected restore fields
00185         // If accepted no need to do anything
00186         if ( ! acceptTestResult ) 
00187         { 
00188           s.getQ() = s_old->getQ();
00189           
00190           // I am going to refresh these so maybe these copies 
00191           //  for the momenta and the pseudofermions
00192           // are not really needed...
00193           //
00194           // restore momenta
00195           s.getP() = s_old->getP();
00196         }
00197       }
00198 
00199       pop(xml_log); // HMCTrajectory
00200       pop(xml_out); // HMCTrajectory
00201     
00202       END_CODE();
00203     }
00204     
00205   protected:
00206     // Get at the Exact Hamiltonian
00207     virtual AbsHamiltonian<P,Q>& getMCHamiltonian(void) = 0;
00208     
00209     // Get at the TopLevelIntegrator
00210     virtual AbsMDIntegrator<P,Q>& getMDIntegrator(void)  = 0;
00211     
00212     virtual void refreshP(AbsFieldState<P,Q>& state) const = 0;
00213     
00214     virtual bool acceptReject(const Double& DeltaH) const = 0;
00215     
00216 
00217     // These things are for reversebility checking...
00218     virtual void flipMomenta(AbsFieldState<P,Q>& state) const = 0;
00219     virtual void reverseCheckMetrics(Double& deltaQ, Double& deltaP,
00220                                      const AbsFieldState<P,Q>& s, 
00221                                      const AbsFieldState<P,Q>& s_old) const = 0;
00222   };
00223 
00224 } // end namespace chroma 
00225 
00226 
00227 
00228 #endif

Generated on Sun Nov 22 04:28:48 2009 for CHROMA by  doxygen 1.4.7