CHROMA
abs_hmc.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Abstract HMC trajectory Using the new structure
4  *
5  * HMC trajectories
6  */
7 #ifndef abs_hmc_new_h
8 #define abs_hmc_new_h
9 
10 #include "chromabase.h"
11 #include "io/xmllog_io.h"
17 
18 
19 namespace Chroma
20 {
21 
22  //! Abstract HMC trajectory
23  /*! @ingroup hmc */
24  template<typename P, typename Q>
25  class AbsHMCTrj {
26  public:
27 
28  // Virtual destructor
29  virtual ~AbsHMCTrj() {};
30 
31 
32  // Do the HMC trajectory
34  const bool WarmUpP,
35  const bool CheckRevP)
36  {
37  START_CODE();
38  StopWatch swatch;
39 
40 
43 
44  XMLWriter& xml_out = TheXMLOutputWriter::Instance();
45  XMLWriter& xml_log = TheXMLLogWriter::Instance();
46 
47  // Self encapsulation rule
48  push(xml_out, "HMCTrajectory");
49  push(xml_log, "HMCTrajectory");
50 
51 
52  write(xml_out, "WarmUpP", WarmUpP);
53  write(xml_log, "WarmUpP", WarmUpP);
54 
55  // HMC Algorithm.
56  // 1) Refresh momenta
57  //
58  swatch.reset(); swatch.start();
59  refreshP(s);
60  swatch.stop();
61  QDPIO::cout << "HMC_TIME: Momentum Refresh Time: " << swatch.getTimeInSeconds() << " \n";
62 
63  bool acceptTraj = false; // Default value. Acceptance check can change this
64  Double KE_old, PE_old;
65 
66 
67  // Try catch block in case MG Solver fails in any pseudofermion refresh.
68  // That should cause an abort.
69  try {
70  // Refresh Pseudofermions
71  swatch.reset(); swatch.start();
73  swatch.stop();
74  QDPIO::cout << "HMC_TIME: Pseudofermion Refres Time: " << swatch.getTimeInSeconds() << " \n";
75  }
76  catch ( MGSolverException e ) {
77  QDPIO::cout << "ERROR: Caught MG Solver exception in pseudofermion refresh" << std::endl;
78  QDPIO::cout << "ERROR: Exception Was: " << e.whatStr() << std::endl;
79  QDPIO::cout << "Aborting";
80  QDP_abort(2);
81  }
82 
83  // SaveState -- Perhaps this could be done better?
84  Handle< AbsFieldState<P,Q> > s_old(s.clone());
85 
86 
87  // Try Catch block in case MG Solver fails in Energy Calculation
88  // That should also be an abort
89  try {
90  // Measure energy of the old state
91 
92  push(xml_out, "H_old");
93  push(xml_log, "H_old");
94  swatch.reset(); swatch.start();
95  H_MC.mesE(*s_old, KE_old, PE_old);
96  swatch.stop();
97  QDPIO::cout << "HMC_TIME: Start Energy Time: " << swatch.getTimeInSeconds() << " \n";
98 
99  write(xml_out, "KE_old", KE_old);
100  write(xml_log, "KE_old", KE_old);
101 
102  write(xml_out, "PE_old", PE_old);
103  write(xml_log, "PE_old", PE_old);
104 
105  pop(xml_log); // pop H_old
106  pop(xml_out); // pop H_old
107  }
108  catch( MGSolverException e ) {
109  QDPIO::cout << "ERROR: Caught MG Solver exception in Start Energy Calculation" << std::endl;
110  QDPIO::cout << "ERROR: Exception Was: " << e.whatStr() << std::endl;
111  QDPIO::cout << "Aborting";
112  QDP_abort(2);
113  }
114 
115  // Try-Catch Case for MD
116  // If solver fails in MD, we reject by setting acceptTraj = false
117  // If traj is sccessful (no exception is thrown) acceptTraj = true for WarmUp traj and
118  // is decided by Accept/Reject step otherwise
119 
120  try {
121  swatch.start();
122 
123  // Copy in fields from the Hamiltonian as needed using the
124  // CopyList
125  MD.copyFields();
126 
127  // Integrate MD trajectory
128  MD(s, MD.getTrajLength());
129  swatch.stop();
130  QDPIO::cout << "HMC_TIME: Traj MD Time: " << swatch.getTimeInSeconds() << " \n";
131 
132  // Measure the energy of the new state - before reverse check
133  // This is because if an MG preconditioner is used, the reverse
134  // traj may change it to where it is a poor preconditioner for the
135  // Final energy calculation
136  swatch.reset();
137  swatch.start();
138  Double KE, PE;
139  push(xml_out, "H_new");
140  push(xml_log, "H_new");
141  H_MC.mesE(s, KE, PE);
142  write(xml_out, "KE_new", KE);
143  write(xml_log, "KE_new", KE);
144  write(xml_out, "PE_new", PE);
145  write(xml_log, "PE_new", PE);
146  pop(xml_log);
147  pop(xml_out);
148  swatch.stop();
149  QDPIO::cout << "HMC_TIME: Finish Energy Time: " << swatch.getTimeInSeconds() << " \n";
150  // Work out energy differences
151  Double DeltaKE = KE - KE_old;
152  Double DeltaPE = PE - PE_old;
153  Double DeltaH = DeltaKE + DeltaPE;
154  Double AccProb = where(DeltaH < 0.0, Double(1), exp(-DeltaH));
155  write(xml_out, "deltaKE", DeltaKE);
156  write(xml_log, "deltaKE", DeltaKE);
157 
158  write(xml_out, "deltaPE", DeltaPE);
159  write(xml_log, "deltaPE", DeltaPE);
160 
161  write(xml_out, "deltaH", DeltaH);
162  write(xml_log, "deltaH", DeltaH);
163 
164  write(xml_out, "AccProb", AccProb);
165  write(xml_log, "AccProb", AccProb);
166 
167  QDPIO::cout << "Delta H = " << DeltaH << std::endl;
168  QDPIO::cout << "AccProb = " << AccProb << std::endl;
169 
170  // If we intend to do an accept reject step
171  // (ie we are not warming up)
172  if( !WarmUpP ) {
173 
174  // Measure Acceptance
175  acceptTraj = acceptReject(DeltaH);
176  }
177  else {
178  // Warm Up: acceptTraj = true -- always
179  acceptTraj = true;
180  }
181 
182  }
183  catch( MGSolverException e ) {
184 
185  // Exception Handling if the solver didnt converge
186  // Automatic rejection
187  QDPIO::cout << "WARNING: Caught MG Solver Convergence Exception, during MD or Final Energy Calculation!" << std::endl;
188  QDPIO::cout << "WARNING: Exception was: " << e.whatStr() << std::endl;
189  QDPIO::cout << "WARNING: Aborting" << std::endl;
190  QDP_abort(2);
191  }
192 
193  write(xml_out, "AcceptP", acceptTraj);
194  write(xml_log, "AcceptP", acceptTraj);
195  QDPIO::cout << "AcceptP = " << acceptTraj << std::endl;
196 
197 
198  // If reversebility check is due, do it. It doesn't affect the final state 's'
199  if( CheckRevP ) {
200 
201  // Copy State
202  Handle< AbsFieldState<P,Q> > s_rev(s.clone());
203 
204  // Try and do reverse trajectory
205  // If the MG solver fails in this, in some sense I don't care
206  // It doesn't affect acceptance of 's'
207 
208  try {
209  swatch.reset(); swatch.start();
210 
211  QDPIO::cout << "Reversing trajectory for reversability test" <<std::endl;
212 
213  // Flip Momenta
214  flipMomenta(*s_rev);
215 
216  // Go back
217  MD(*s_rev, MD.getTrajLength());
218 
219  // Flip Momenta back (to original)
220  flipMomenta(*s_rev);
221 
222 
223  Double KE_rev;
224  Double PE_rev;
225 
226  H_MC.mesE(*s_rev, KE_rev, PE_rev);
227 
228  Double DeltaDeltaKE = KE_rev - KE_old;
229  Double DeltaDeltaPE = PE_rev - PE_old;
230  Double DeltaDeltaH = DeltaDeltaKE + DeltaDeltaPE;
231 
232 
233  Double dq;
234  Double dp;
235  reverseCheckMetrics(dq,dp, *s_rev, *s_old);
236 
237  push(xml_log, "ReversibilityMetrics");
238  write(xml_log, "DeltaDeltaH", fabs(DeltaDeltaH));
239  write(xml_log, "DeltaDeltaKE", fabs(DeltaDeltaKE));
240  write(xml_log, "DeltaDeltaPE", fabs(DeltaDeltaPE));
241  write(xml_log, "DeltaQPerSite", dq);
242  write(xml_log, "DeltaPPerSite", dp);
243  pop(xml_log);
244 
245  QDPIO::cout << "Reversibility: DeltaDeltaH = " << fabs(DeltaDeltaH) <<std::endl;
246  QDPIO::cout << "Reversibility: DeltaQ = " << dq << std::endl;
247  QDPIO::cout << "Reversibility: DeltaP = " << dp << std::endl;
248  swatch.stop();
249  QDPIO::cout << "HMC_TIME: Reverse Check Time: " << swatch.getTimeInSeconds() << " \n";
250  }
251  catch( MGSolverException e ) {
252 
253  QDPIO::cout << "WARNING: Caught MG Solver Exception in Reverse Trajectory" << std::endl;
254  QDPIO::cout << "WARNING: Exception was: " << e.whatStr() << std::endl;
255  QDPIO::cout << "WARNING: Aborting" << std::endl;
256  QDP_abort(2);
257  }
258 
259  // s_rev goes away here.
260 
261  } // if (CheckRevP)
262 
263  // Rejection: acceptTraj is false
264  // Either because of exception handling, or
265  // because of the MC Test
266  if ( ! acceptTraj ) {
267 
268  // restore the old state
269  s.getQ() = s_old->getQ();
270  s.getP() = s_old->getP();
271 
272  }
273 
274  pop(xml_log); // HMCTrajectory
275  pop(xml_out); // HMCTrajectory
276 
277  END_CODE();
278  }
279 
280  protected:
281  // Get at the Exact Hamiltonian
283 
284  // Get at the TopLevelIntegrator
286 
287  virtual void refreshP(AbsFieldState<P,Q>& state) const = 0;
288 
289  virtual bool acceptReject(const Double& DeltaH) const = 0;
290 
291 
292  // These things are for reversebility checking...
293  virtual void flipMomenta(AbsFieldState<P,Q>& state) const = 0;
294  virtual void reverseCheckMetrics(Double& deltaQ, Double& deltaP,
295  const AbsFieldState<P,Q>& s,
296  const AbsFieldState<P,Q>& s_old) const = 0;
297  };
298 
299 } // end namespace chroma
300 
301 
302 
303 #endif
Abstract Hamiltonian.
Integrators.
Primary include file for CHROMA library code.
Abstract field state.
Definition: field_state.h:27
Abstract HMC trajectory.
Definition: abs_hmc.h:25
virtual AbsHamiltonian< P, Q > & getMCHamiltonian(void)=0
virtual void refreshP(AbsFieldState< P, Q > &state) const =0
virtual AbsMDIntegrator< P, Q > & getMDIntegrator(void)=0
virtual ~AbsHMCTrj()
Definition: abs_hmc.h:29
virtual void operator()(AbsFieldState< P, Q > &s, const bool WarmUpP, const bool CheckRevP)
Definition: abs_hmc.h:33
virtual void reverseCheckMetrics(Double &deltaQ, Double &deltaP, const AbsFieldState< P, Q > &s, const AbsFieldState< P, Q > &s_old) const =0
virtual void flipMomenta(AbsFieldState< P, Q > &state) const =0
virtual bool acceptReject(const Double &DeltaH) const =0
New Abstract Hamiltonian.
virtual void mesE(const AbsFieldState< P, Q > &s, Double &KE, Double &PE) const
virtual void refreshInternalFields(const AbsFieldState< P, Q > &s)=0
Refresh pseudofermsions (if any)
New MD integrator interface.
virtual void copyFields(void) const =0
Copy equivalent fields into MD monomals before integration.
virtual Real getTrajLength(void) const =0
Get the trajectory length.
Class for counted reference semantics.
Definition: handle.h:33
const std::string & whatStr() const
static T & Instance()
Definition: singleton.h:432
Field state.
Global metropolis.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
push(xml_out,"Condensates")
pop(xml_out)
START_CODE()
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
Singleton instances of xml output.