CHROMA
inline_stoch_group_baryon_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Inline measurement of stochastic group baryon operator
3  *
4  */
5 
6 #include "handle.h"
17 #include "meas/glue/mesplq.h"
19 #include "util/ferm/diractodr.h"
20 #include "util/ft/sftmom.h"
21 #include "util/info/proginfo.h"
23 #include <sstream>
24 
26 
27 namespace Chroma
28 {
29  /*!
30  * \ingroup hadron
31  *
32  * @{
33  */
34  namespace InlineStochGroupBaryonEnv
35  {
36  //! Number of quarks to be used in this construction
37  const int N_quarks = 3;
38 
39 
40  //
41  // The spin basis matrix to goto Dirac
42  //
43  SpinMatrix rotate_mat(adj(DiracToDRMat()));
44 
45  // Reader for input parameters
46  void read(XMLReader& xml, const std::string& path, InlineStochGroupBaryonEnv::Params::Param_t& param)
47  {
48  XMLReader paramtop(xml, path);
49 
50  int version;
51  read(paramtop, "version", version);
52 
53  multi1d< multi1d<int> > temp;
54  switch (version)
55  {
56  case 1:
57 
58  QDPIO::cerr << "version 1 no longer supported. " << std::endl;
59  exit(0);
60  /*
61  read(paramtop, "mom2_max", param.mom2_max);
62 
63 
64 
65  param.moms.resize(1,3);
66 
67  param.moms[0][0] = 0;
68  param.moms[0][1] = 0;
69  param.moms[0][2] = 0;
70 
71  */
72 
73  break;
74 
75  case 2:
76 
77  read(paramtop, "moms" , temp);
78 
79  param.mom2_max = 0;
80  param.moms.resize(temp.size(), temp[0].size() );
81 
82  for (int i = 0 ; i < temp.size() ; ++i)
83  param.moms[i] = temp[i];
84 
85 
86  break;
87 
88  default :
89 
90  QDPIO::cerr << "Input parameter version " << version << " unsupported." << std::endl;
91  QDP_abort(1);
92  }
93 
94  read(paramtop, "displacement_length", param.displacement_length);
95 
96  param.quark_smearing = readXMLGroup(paramtop, "QuarkSmearing", "wvf_kind");
97  param.link_smearing = readXMLGroup(paramtop, "LinkSmearing", "LinkSmearingType");
98  param.quark_dils = readXMLArrayGroup(paramtop, "QuarkDilutions", "DilutionType");
99 
100 
101  }
102 
103 
104  // Writer for input parameters
105  void write(XMLWriter& xml, const std::string& path, const InlineStochGroupBaryonEnv::Params::Param_t& param)
106  {
107  push(xml, path);
108 
109  int version = 1;
110 
111  write(xml, "version", version);
112  write(xml, "mom2_max", param.mom2_max);
113  write(xml, "displacement_length", param.displacement_length);
114  xml << param.quark_smearing.xml;
115  xml << param.link_smearing.xml;
116 
117  push(xml, "QuarkDilutions");
118 
119  for(int i=0; i < param.quark_dils.size(); ++i)
120  xml << param.quark_dils[i].xml;
121 
122  pop(xml);
123 
124  pop(xml);
125  }
126 
127 
128  //Reader for 3-quark operator file
130  {
131  XMLReader inputtop(xml, path);
132 
133  read(inputtop, "ops_file", input.ops_file);
134  read(inputtop, "id", input.id);
135  }
136 
137 
138  // Writer for 3-quark operator file
140  {
141  push(xml, path);
142  write(xml, "ops_file", input.ops_file);
143  write(xml, "id", input.id);
144  pop(xml);
145  }
146 
147 
148  //! Read named objects
149  void read(XMLReader& xml, const std::string& path, InlineStochGroupBaryonEnv::Params::NamedObject_t& input)
150  {
151  XMLReader inputtop(xml, path);
152 
153  read(inputtop, "gauge_id", input.gauge_id);
154  read(inputtop, "operators_file", input.operators_file);
155  read(inputtop, "Quark_ids", input.quark_ids);
156  }
157 
158  //! Write named objects
159  void write(XMLWriter& xml, const std::string& path, const InlineStochGroupBaryonEnv::Params::NamedObject_t& input)
160  {
161  push(xml, path);
162 
163  write(xml, "gauge_id", input.gauge_id);
164  write(xml, "operators_file", input.operators_file);
165  write(xml, "Quark_ids", input.quark_ids);
166 
167  pop(xml);
168  }
169  }
170 
171 
172  namespace InlineStochGroupBaryonEnv
173  {
174  // Anonymous namespace for registration
175  namespace
176  {
177  AbsInlineMeasurement* createMeasurement(XMLReader& xml_in,
178  const std::string& path)
179  {
180  return new InlineMeas(Params(xml_in, path));
181  }
182 
183  //! Local registration flag
184  bool registered = false;
185  }
186 
187  const std::string name = "STOCH_GROUP_BARYON";
188 
189  //! Register all the factories
190  bool registerAll()
191  {
192  bool success = true;
193  if (! registered)
194  {
197  success &= DilutionSchemeEnv::registerAll();
198  success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
199  registered = true;
200  }
201  return success;
202  }
203 
204 
205  //----------------------------------------------------------------------------
206  // Param stuff
208  {
209  frequency = 0;
210  param.mom2_max = 0;
211  }
212 
213  Params::Params(XMLReader& xml_in, const std::string& path)
214  {
215  try
216  {
217  XMLReader paramtop(xml_in, path);
218 
219  if (paramtop.count("Frequency") == 1)
220  read(paramtop, "Frequency", frequency);
221  else
222  frequency = 1;
223 
224  // Read program parameters
225  read(paramtop, "Param", param);
226 
227  // Read in the output propagator/source configuration info
228  read(paramtop, "NamedObject", named_obj);
229 
230  // Possible alternate XML file pattern
231  if (paramtop.count("xml_file") != 0)
232  {
233  read(paramtop, "xml_file", xml_file);
234  }
235  }
236  catch(const std::string& e)
237  {
238  QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << std::endl;
239  QDP_abort(1);
240  }
241  }
242 
243 
244  void
245  Params::writeXML(XMLWriter& xml_out, const std::string& path)
246  {
247  push(xml_out, path);
248 
249  // Parameters for source construction
250  write(xml_out, "Param", param);
251 
252  // Write out the output propagator/source configuration info
253  write(xml_out, "NamedObject", named_obj);
254 
255  pop(xml_out);
256  }
257 
258 
259 
260  //--------------------------------------------------------------
261  //! 3-quark operator structure
263  {
265  {
266  struct QuarkInfo_t
267  {
268  int displacement; /*!< Orig plus/minus 1-based directional displacements */
269  int spin; /*!< 1-based spin index */
270  };
271 
272  multi1d<QuarkInfo_t> quark; /*!< Displacement and spin for each quark */
273  std::string name; /*!< Name of the 3-quark operator */
274  };
275 
276  multi1d<ThreeQuarkOp_t> ops; /*!< 3-quark ops within a file */
277  };
278 
279  //! Write quark
280  void write(XMLWriter& xml, const std::string& path,
282  {
283  push(xml, path);
284 
285  write(xml, "Displacement", input.displacement);
286  write(xml, "Spin", input.spin);
287 
288  pop(xml);
289  }
290 
291  //! Write three quark op
292  void write(XMLWriter& xml, const std::string& path,
293  const ThreeQuarkOps_t::ThreeQuarkOp_t& input)
294  {
295  push(xml, path);
296 
297  write(xml, "Quarks", input.quark);
298  write(xml, "Name", input.name);
299 
300  pop(xml);
301  }
302 
303 
304 
305  //---------------------------------------------------------------------------
306 
307 
308  //! The key for smeared quarks
310  {
311  int t0; /*!< Time of source */
312  int dil; /*!< dilution component per timeslice */
313 
314  };
315 
316 
317  //! Support for the keys of smeared quarks
319  {
320  multi1d<int> lga(2);
321  lga[0] = a.t0;
322  lga[1] = a.dil;
323 
324  multi1d<int> lgb(2);
325  lgb[0] = b.t0;
326  lgb[1] = b.dil;
327 
328  return (lga < lgb);
329  }
330 
331 
333  {
334  LatticeFermion quark;
335  };
336 
337  //----------------------------------------------------------------------------
338  //! The key for smeared and displaced color vectors
340  {
341  int t0; /*!< Time of source */
342  int dil; /*!< dilution component per timeslice */
343 
344  int displacement; /*!< Orig plus/minus 1-based directional displacements */
345  int spin; /*!< 1-based spin index */
346  };
347 
348 
349  //! Support for the keys of smeared and displaced color vectors
351  {
352  multi1d<int> lga(4);
353  lga[0] = a.displacement;
354  lga[1] = a.spin;
355  lga[2] = a.t0;
356  lga[3] = a.dil;
357 
358  multi1d<int> lgb(4);
359  lgb[0] = b.displacement;
360  lgb[1] = b.spin;
361  lgb[2] = b.t0;
362  lgb[3] = b.dil;
363 
364  return (lga < lgb);
365  }
366 
367 
368  //! The value of the std::map
370  {
371  multi1d<LatticeComplex> vec;
372  };
373 
374 
375  //----------------------------------------------------------------------------
376  //! The smeared and displaced objects
378  {
379  public:
380  //! Constructor from smeared std::map
381  SmearedDispObjects(int disp_length,
382  multi1d< Handle< DilutionScheme<LatticeFermion> > > dil_quarks,
384  const multi1d<LatticeColorMatrix> & u_smr) :
385  displacement_length(disp_length),diluted_quarks(dil_quarks),
386  quarkSmearing(qsmr), u(u_smr)
387  {
388  smeared_src_maps.resize(N_quarks);
389  smeared_soln_maps.resize(N_quarks);
390 
391  disp_src_maps.resize(N_quarks);
392  disp_soln_maps.resize(N_quarks);
393 
394  }
395 
396  //! Destructor
398 
399  //! Accessor
400  virtual multi1d<LatticeComplex> getDispSource(int quark_num,
401  const KeySmearedDispColorVector_t& key);
402 
403  //! Accessor
404  virtual multi1d<LatticeComplex> getDispSolution(int quark_num,
405  const KeySmearedDispColorVector_t& key);
406 
407  protected:
408 
409  //! Displace an object
410  virtual const multi1d<LatticeComplex>& displaceObject(
411  std::map<KeySmearedDispColorVector_t, SmearedDispColorVector_t>& disp_quark_map,
412  const KeySmearedDispColorVector_t& key,
413  const LatticeFermion& smrd_q);
414 
415  //! Smear sources and solutions
416  virtual const LatticeFermion&
417  smearSource(int qnum , const KeySmearedQuark_t & key);
418 
419  virtual const LatticeFermion&
420  smearSolution(int qnum , const KeySmearedQuark_t & key);
421 
422 
423  private:
424 
425  multi1d< Handle< DilutionScheme<LatticeFermion> > > diluted_quarks;
426 
428 
429 
430  //!Gauge field
431  const multi1d<LatticeColorMatrix> & u;
432 
433  //! Displacement length
435 
436 
437  //! Maps of smeared color vectors
438  multi1d< std::map<KeySmearedQuark_t, SmearedQuark_t> > smeared_src_maps;
439  multi1d< std::map<KeySmearedQuark_t, SmearedQuark_t> > smeared_soln_maps;
440 
441 
442  //!Maps of smeared displaced color vectors
443  multi1d< std::map<KeySmearedDispColorVector_t, SmearedDispColorVector_t> > disp_src_maps;
444  multi1d< std::map<KeySmearedDispColorVector_t, SmearedDispColorVector_t> > disp_soln_maps;
445  };
446 
447 
448  const LatticeFermion&
450  const KeySmearedQuark_t & key)
451  {
452 
453  std::map<KeySmearedQuark_t, SmearedQuark_t> & qmap = smeared_src_maps[qnum];
454 
455  //If entry is not in std::map create it
456  if ( qmap.find(key) == qmap.end() )
457  {
458 
459  // Insert an empty entry and then modify it. This saves on
460  // copying the data around
461  {
462  SmearedQuark_t smrd_empty;
463  qmap.insert(std::make_pair(key, smrd_empty));
464 
465  // Sanity check - the entry better be there
466  if ( qmap.find(key) == qmap.end() )
467  {
468  QDPIO::cerr << __func__
469  << ": internal error - could not insert empty key in std::map"
470  << std::endl;
471  QDP_abort(1);
472  }
473  }
474 
475  // Modify the previous empty entry
476  SmearedQuark_t& smrd_q = qmap.find(key)->second;
477 
478  StopWatch snoop;
479 
480  snoop.reset();
481  snoop.start();
482 
483  smrd_q.quark = diluted_quarks[qnum]->dilutedSource(key.t0, key.dil);
484 
485  (*quarkSmearing)(smrd_q.quark, u);
486 
487  SpinMatrix mat = rotate_mat * Gamma(8);
488 
489  smrd_q.quark = mat * smrd_q.quark;
490 
491 
492  snoop.stop();
493 
494  QDPIO::cout << " Smeared Sources: Quark = "<< qnum <<" t0 = "
495  << key.t0 <<" dil = "<< key.dil << " Time = "<< snoop.getTimeInSeconds() <<" sec"<<std::endl;
496 
497  // Insert
498  qmap.insert(std::make_pair(key, smrd_q));
499 
500  } // if find in std::map
501 
502  // The key now must exist in the std::map, so return the smeared quark field
503 
504  return (qmap.find(key)->second).quark ;
505  }
506 
507 
508 
509  const LatticeFermion&
511  const KeySmearedQuark_t & key)
512  {
513 
514  std::map<KeySmearedQuark_t, SmearedQuark_t> & qmap = smeared_soln_maps[qnum];
515 
516 
517  //If entry is not in std::map create it
518  if ( qmap.find(key) == qmap.end() )
519  {
520 
521  // Insert an empty entry and then modify it. This saves on
522  // copying the data around
523  {
524  SmearedQuark_t smrd_empty;
525  qmap.insert(std::make_pair(key, smrd_empty));
526 
527  // Sanity check - the entry better be there
528  if ( qmap.find(key) == qmap.end() )
529  {
530  QDPIO::cerr << __func__
531  << ": internal error - could not insert empty key in std::map"
532  << std::endl;
533  QDP_abort(1);
534  }
535  }
536 
537  // Modify the previous empty entry
538  SmearedQuark_t& smrd_q = qmap.find(key)->second;
539 
540  StopWatch snoop;
541  snoop.reset();
542  snoop.start();
543 
544  smrd_q.quark = diluted_quarks[qnum]->dilutedSolution(key.t0, key.dil);
545 
546  (*quarkSmearing)(smrd_q.quark, u);
547 
548  smrd_q.quark = rotate_mat * smrd_q.quark;
549 
550  snoop.stop();
551 
552  QDPIO::cout << " Smeared Sinks: Quark = "<< qnum <<" t0 = "
553  << key.t0 <<" dil = "<< key.dil << " Time = "<< snoop.getTimeInSeconds() <<" sec"<<std::endl;
554 
555  // Insert
556  qmap.insert(std::make_pair(key, smrd_q));
557 
558  } // if find in std::map
559 
560  // The key now must exist in the std::map, so return the smeared quark field
561 
562  return (qmap.find(key)->second).quark ;
563  }
564 
565  //! Accessor
566  multi1d<LatticeComplex>
568  const KeySmearedDispColorVector_t& key)
569  {
570 
571  //Get Smeared quark
572  KeySmearedQuark_t smr_key;
573  smr_key.t0 = key.t0;
574  smr_key.dil = key.dil;
575 
576  const LatticeFermion& smrd_q = smearSource(quark_num, smr_key);
577 
578  multi1d<LatticeComplex> vec;
579 
580  //Check if any displacement is needed
581  if (displacement_length == 0)
582  {
583  vec.resize(Nc);
584  LatticeColorVector colvec = peekSpin( smrd_q, key.spin - 1);
585 
586  for (int c = 0 ; c < Nc ; ++c)
587  vec[c] = peekColor( colvec, c);
588 
589  }
590  else
591  {
592  vec = displaceObject( disp_src_maps[quark_num] , key , smrd_q);
593  }
594 
595  return vec;
596 
597  }
598 
599  //! Accessor
600  multi1d<LatticeComplex>
602  const KeySmearedDispColorVector_t& key)
603  {
604 
605  //Get Smeared quark
606  KeySmearedQuark_t smr_key;
607  smr_key.t0 = key.t0;
608  smr_key.dil = key.dil;
609 
610  const LatticeFermion& smrd_q = smearSolution(quark_num, smr_key);
611 
612  multi1d<LatticeComplex> vec;
613 
614  //Check if any displacement is needed
615  if (displacement_length == 0)
616  {
617  vec.resize(Nc);
618  LatticeColorVector colvec = peekSpin( smrd_q, key.spin - 1);
619 
620  for (int c = 0 ; c < Nc ; ++c)
621  vec[c] = peekColor( colvec, c);
622 
623  }
624  else
625  {
626  vec = displaceObject( disp_soln_maps[quark_num] , key , smrd_q);
627  }
628 
629  return vec;
630  }
631 
632 
633  //! Accessor
634  const multi1d<LatticeComplex> &
636  std::map<KeySmearedDispColorVector_t, SmearedDispColorVector_t>& disp_quark_map,
637  const KeySmearedDispColorVector_t& key,
638  const LatticeFermion& smrd_q)
639  {
640 
641  StopWatch snoop;
642 
643  // If no entry, then create a displaced version of the quark
644  if (disp_quark_map.find(key) == disp_quark_map.end())
645  {
646  // std::cout << __func__
647  // << ": n=" << n
648  // << " l=" << l
649  // << " i=" << i
650  // << " disp=" << term.quark[i].displacement
651  // << " len=" << term.quark[i].disp_len
652  // << " dir=" << term.quark[i].disp_dir
653  // << std::endl;
654 
655 
656 
657  // Insert an empty entry and then modify it. This saves on
658  // copying the data around
659  {
660  SmearedDispColorVector_t disp_empty;
661 
662  snoop.reset();
663  snoop.start();
664 
665  disp_quark_map.insert(std::make_pair(key, disp_empty));
666 
667  snoop.stop();
668 
669  QDPIO::cout<<"Inserted key in std::map: time = "<< snoop.getTimeInSeconds() << "secs"<<std::endl;
670 
671  // Sanity check - the entry better be there
672  if (disp_quark_map.find(key) == disp_quark_map.end())
673  {
674  QDPIO::cerr << __func__
675  << ": internal error - could not insert empty key in std::map"
676  << std::endl;
677  QDP_abort(1);
678  }
679  }
680 
681  // Modify the previous empty entry
682  SmearedDispColorVector_t& disp_q = disp_quark_map.find(key)->second;
683 
684  snoop.reset();
685  snoop.start();
686 
687  //Chroma uses a zero-based spin convention
688  LatticeColorVector vec = peekSpin(smrd_q, key.spin - 1);
689 
690  if (key.displacement > 0)
691  {
692  int disp_dir = key.displacement - 1;
693  int disp_len = displacement_length;
694  displacement(u, vec, disp_len, disp_dir);
695  }
696  else if (key.displacement < 0)
697  {
698  int disp_dir = -key.displacement - 1;
699  int disp_len = -displacement_length;
700  displacement(u, vec, disp_len, disp_dir);
701  }
702 
703  snoop.stop();
704 
705  QDPIO::cout << "Displaced Quarks: Spin = "<<key.spin<<" Disp = "
706  << key.displacement <<" Time = "<<snoop.getTimeInSeconds() <<" sec"<<std::endl;
707 
708  disp_q.vec.resize(Nc);
709 
710  for(int i = 0 ; i < Nc ; ++i )
711  {
712  disp_q.vec[i] = peekColor(vec, i);
713  }
714 
715  } // if find in std::map
716 
717  snoop.reset();
718  snoop.start();
719 
720  // The key now must exist in the std::map, so return the std::vector
721  SmearedDispColorVector_t& disp_q = disp_quark_map.find(key)->second;
722 
723  snoop.stop();
724 
725  //QDPIO::cout << "Retrieved entry from std::map : time = "<< snoop.getTimeInSeconds() << "secs "<<std::endl;
726 
727  return disp_q.vec;
728  }
729 
730 
731  //----------------------------------------------------------------------------
732  //Support for the diquarks
733 
734  void makeDiquark( multi1d<LatticeComplex> & diquark, const multi1d<LatticeComplex> & q0,
735  const multi1d<LatticeComplex> & q1, const Subset & subset )
736  {
737 
738 
739  //The signs for the diquark are taken from
740  //the colorContract function in qdp_primcolorvec.h
741  diquark[0][subset] = q0[0]*q1[1] - q0[1]*q1[0];
742  diquark[1][subset] = q0[1]*q1[2] - q0[2]*q1[1];
743  diquark[2][subset] = q0[2]*q1[0] - q0[0]*q1[2];
744 
745 
746  }
747 
748 
749  void makeColorSinglet (LatticeComplex & singlet, const multi1d<LatticeComplex> & diquark,
750  const multi1d<LatticeComplex> & q2, const Subset & subset)
751  {
752 
753  singlet[subset] = diquark[0] * q2[2];
754  singlet[subset] += diquark[1] * q2[0];
755  singlet[subset] += diquark[2] * q2[1];
756  }
757 
758 
759  //! Baryon operator
761  {
762  //! Baryon operator time slices corresponding to location of operator source
764  {
765  //! Quark orderings within a baryon operator
766  struct Orderings_t
767  {
768  //! Baryon operator dilutions
769  struct Dilutions_t
770  {
771  //! Momentum projected correlator
772  struct Mom_t
773  {
774  multi1d<int> mom; /*!< D-1 momentum of this operator */
775  multi1d<DComplex> op; /*!< Momentum projected operator */
776  };
777 
778  multi1d<Mom_t> mom_projs; /*!< Holds momentum projections of the operator */
779 
780  };
781 
782  multi1d<int> perm; /*!< This particular permutation of quark orderings */
783 
784  multi3d<Dilutions_t> dilutions; /*!< Hybrid list indices */
785  };
786 
787  multi1d<Orderings_t> orderings; /*!< Array is over quark orderings */
788 
789  int t0; /*!< Actual time corresponding to this timeslice */
790  };
791 
792  multi1d< multi1d<int> > perms; /*!< Permutations of quark enumeration */
793 
794  GroupXML_t smearing; /*!< String holding quark smearing xml */
795 
796  Seed seed_l; /*!< Id of left quark */
797  Seed seed_m; /*!< Id of middle quark */
798  Seed seed_r; /*!< Id of right quark */
799 
800 
801  GroupXML_t dilution_l; /*!< Dilution scheme of left quark */
802  GroupXML_t dilution_m; /*!< Dilution scheme of middle quark */
803  GroupXML_t dilution_r; /*!< Dilution scheme of right quark */
804 
805  std::string id; /*!< Tag/ID used in analysis codes */
806 
807  int mom2_max; /*!< |\vec{p}|^2 */
808  int decay_dir; /*!< Direction of decay */
809 
810  multi1d<TimeSlices_t> time_slices; /*!< Time slices of the lattice that are used */
811  };
812 
813 
814  //----------------------------------------------------------------------------
815  //! BaryonOperator header writer
816  void write(XMLWriter& xml, const std::string& path, const BaryonOperator_t& param)
817  {
818  push(xml, path);
819 
820  int version = 1;
821  write(xml, "version", version);
822  write(xml, "id", param.id);
823  write(xml, "mom2_max", param.mom2_max);
824  write(xml, "decay_dir", param.decay_dir);
825  write(xml, "seed_l", param.seed_l);
826  write(xml, "seed_m", param.seed_m);
827  write(xml, "seed_r", param.seed_r);
828  write(xml, "perms", param.perms);
829 
830  push(xml, "dilution_l");
831  xml << param.dilution_l.xml;
832  pop(xml);
833 
834  push(xml, "dilution_m");
835  xml << param.dilution_m.xml;
836  pop(xml);
837 
838  push(xml, "dilution_r");
839  xml << param.dilution_r.xml;
840  pop(xml);
841 
842  xml << param.smearing.xml;
843 
844  pop(xml);
845  }
846 
847 
848 
849  //! BaryonOperator binary writer
851  {
852  write(bin, param.mom);
853  write(bin, param.op);
854  }
855 
856  //! BaryonOperator binary writer
858  {
859  write(bin, param.mom_projs);
860  }
861 
862  //! BaryonOperator binary writer
863  void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t::Orderings_t& param)
864  {
865  write(bin, param.dilutions);
866  write(bin, param.perm);
867  }
868 
869  //! BaryonOperator binary writer
870  void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t& param)
871  {
872  write(bin, param.orderings);
873  write(bin, param.t0);
874  }
875 
876  //! BaryonOperator binary writer
877  void write(BinaryWriter& bin, const BaryonOperator_t& param)
878  {
879  write(bin, param.seed_l);
880  write(bin, param.seed_m);
881  write(bin, param.seed_r);
882  write(bin, param.mom2_max);
883  write(bin, param.decay_dir);
884  write(bin, param.perms);
885  write(bin, param.time_slices);
886  }
887 
888 
889  //! Read 3-quark operators file, assign correct displacement length
890  void readOps(ThreeQuarkOps_t& oplist,
891  const std::string& ops_file)
892  {
893  START_CODE();
894 
895  TextFileReader reader(ops_file);
896 
897  int num_ops;
898  reader >> num_ops;
899  oplist.ops.resize(num_ops);
900 
901  //Loop over ops within a file
902  for(int n=0; n < oplist.ops.size(); ++n)
903  {
904  std::string name;
905  reader >> name;
906  oplist.ops[n].name = name;
907 
908  ThreeQuarkOps_t::ThreeQuarkOp_t& qqq = oplist.ops[n];
909  qqq.quark.resize(N_quarks);
910 
911  // Read 1-based spin
912  multi1d<int> spin(N_quarks);
913  reader >> spin[0] >> spin[1] >> spin[2];
914 
915  // Read 1-based displacement
916  multi1d<int> displacement(N_quarks);
917  reader >> displacement[0] >> displacement[1] >> displacement[2];
918 
919  // Insert for each quark
920  for(int i=0; i < qqq.quark.size(); ++i)
921  {
922  qqq.quark[i].spin = spin[i];
923  qqq.quark[i].displacement = displacement[i];
924  }
925 
926  } //n
927 
928  reader.close();
929 
930  END_CODE();
931  } //void readOps
932 
933 
934  //-------------------------------------------------------------------------------
935  // Function call
936  void
937  InlineMeas::operator()(unsigned long update_no,
938  XMLWriter& xml_out)
939  {
940  // If xml file not empty, then use alternate
941  if (params.xml_file != "")
942  {
943  std::string xml_file = makeXMLFileName(params.xml_file, update_no);
944 
945  push(xml_out, "stoch_baryon");
946  write(xml_out, "update_no", update_no);
947  write(xml_out, "xml_file", xml_file);
948  pop(xml_out);
949 
950  XMLFileWriter xml(xml_file);
951  func(update_no, xml);
952  }
953  else
954  {
955  func(update_no, xml_out);
956  }
957  }
958 
959 
960  // Function call
961  void
962  InlineMeas::func(unsigned long update_no,
963  XMLWriter& xml_out)
964  {
965  START_CODE();
966 
967  StopWatch snoop;
968  snoop.reset();
969  snoop.start();
970 
971 
972  StopWatch swiss;
973 
974  // Test and grab a reference to the gauge field
975  XMLBufferWriter gauge_xml;
976  try
977  {
978  TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
979  TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
980  }
981  catch( std::bad_cast )
982  {
983  QDPIO::cerr << InlineStochGroupBaryonEnv::name << ": caught dynamic cast error"
984  << std::endl;
985  QDP_abort(1);
986  }
987  catch (const std::string& e)
988  {
989  QDPIO::cerr << InlineStochGroupBaryonEnv::name << ": std::map call failed: " << e
990  << std::endl;
991  QDP_abort(1);
992  }
993  const multi1d<LatticeColorMatrix>& u =
994  TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
995 
996  push(xml_out, "StochGroupBaryon");
997  write(xml_out, "update_no", update_no);
998 
999  QDPIO::cout << InlineStochGroupBaryonEnv::name << ": Stochastic Baryon Operator" << std::endl;
1000 
1001  proginfo(xml_out); // Print out basic program info
1002 
1003  // Write out the input
1004  params.writeXML(xml_out, "Input");
1005 
1006  // Write out the config info
1007  write(xml_out, "Config_info", gauge_xml);
1008 
1009  push(xml_out, "Output_version");
1010  write(xml_out, "out_version", 1);
1011  pop(xml_out);
1012 
1013  //First calculate some gauge invariant observables just for info.
1014  //This is really cheap.
1015  MesPlq(xml_out, "Observables", u);
1016 
1017  // Save current seed
1018  Seed ran_seed;
1019  QDP::RNG::savern(ran_seed);
1020 
1021  //
1022  // Construct the dilution scheme for each of the 3 quarks
1023  //
1024  if (params.param.quark_dils.size() != N_quarks)
1025  {
1026  QDPIO::cerr << name << ": expecting 3 quark dilutions" << std::endl;
1027  QDP_abort(1);
1028  }
1029 
1030  multi1d< Handle< DilutionScheme<LatticeFermion> > > diluted_quarks(N_quarks); /*!< Here is the big (dil) pickle */
1031 
1032  try
1033  {
1034  // Loop over the 3 quark dilutions
1035  for(int n = 0; n < params.param.quark_dils.size(); ++n)
1036  {
1037  const GroupXML_t& dil_xml = params.param.quark_dils[n];
1038 
1039  std::istringstream xml_d(dil_xml.xml);
1040  XMLReader diltop(xml_d);
1041  QDPIO::cout << "Dilution type = " << dil_xml.id << std::endl;
1042 
1043  diluted_quarks[n] = TheFermDilutionSchemeFactory::Instance().createObject(
1044  dil_xml.id, diltop, dil_xml.path);
1045  }
1046  }
1047  catch(const std::string& e)
1048  {
1049  QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << std::endl;
1050  QDP_abort(1);
1051  }
1052 //------------------------------------------------------------------------
1053 //Sanity checks
1054 
1055  //The participating timeslices must match for each quark
1056  //grab info from first quark to prime the work
1057 
1058  multi1d<int> participating_timeslices( diluted_quarks[0]->getNumTimeSlices() );
1059 
1060  for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0)
1061  {
1062  participating_timeslices[t0] = diluted_quarks[0]->getT0(t0);
1063  }
1064 
1065  for (int n = 1 ; n < N_quarks ; ++n)
1066  {
1067  if ( diluted_quarks[n]->getNumTimeSlices() != participating_timeslices.size() )
1068  {
1069  QDPIO::cerr << name << " : Quarks do not contain the same number of dilution timeslices: Quark "
1070  << n << std::endl;
1071 
1072  QDP_abort(1);
1073  }
1074 
1075  for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0)
1076  {
1077  if ( diluted_quarks[n]->getT0(t0) != participating_timeslices[t0] )
1078  {
1079  QDPIO::cerr << name << " : Quarks do not contain the same participating timeslices: Quark "<<
1080  n << " timeslice "<< t0 << std::endl;
1081 
1082  QDP_abort(1);
1083  }
1084  }
1085  }
1086 
1087  //Another Sanity check, the three quarks must all be
1088  //inverted on the same cfg
1089  for (int n = 1 ; n < N_quarks ; ++n)
1090  {
1091  if (diluted_quarks[0]->getCfgInfo() != diluted_quarks[n]->getCfgInfo())
1092  {
1093  QDPIO::cerr << name
1094  << " : Quarks do not contain the same cfg info, quark "<< n << std::endl;
1095 
1096  QDP_abort(1);
1097  }
1098 
1099  }
1100 
1101  //Also ensure that the cfg on which the inversions were performed
1102  //is the same as the cfg that we are using
1103  {
1104  std::string cfgInfo;
1105 
1106  //Really ugly way of doing this(Robert Heeeelp!!)
1107  XMLBufferWriter top;
1108  write(top, "Config_info", gauge_xml);
1109  XMLReader from(top);
1110  XMLReader from2(from, "/Config_info");
1111  std::ostringstream os;
1112  from2.print(os);
1113 
1114  cfgInfo = os.str();
1115 
1116  if (cfgInfo != diluted_quarks[0]->getCfgInfo())
1117  {
1118  QDPIO::cerr << name
1119  << " : Quarks do not contain the same cfg info as the gauge field."
1120  << "gauge: XX"<<cfgInfo<<"XX quarks: XX"<<diluted_quarks[0]->getCfgInfo()<<"XX"<< std::endl;
1121 
1122 
1123  QDP_abort(1);
1124  }
1125  }
1126 
1127  //
1128  // Initialize the slow Fourier transform phases
1129  //
1130  int decay_dir = diluted_quarks[0]->getDecayDir();
1131 
1132  //SftMom phases(params.param.mom2_max, false, decay_dir);
1133  //Changed this to cut down on the size of the files created
1134  //Stupid way to do this.....
1135  //phases1 is the instance to be used if version one has been selected
1136 //likewise for phases2
1137  //Idea: make a constructor for SftMom that takes a bit of
1138  //xml and handles the problem.
1139 
1140 
1141  SftMom phases(params.param.moms, decay_dir);
1142 
1143  // Sanity check - if this doesn't work we have serious problems
1144  if (phases.numSubsets() != QDP::Layout::lattSize()[decay_dir])
1145  {
1146  QDPIO::cerr << name << ": number of time slices not equal to that in the decay direction: "
1147  << QDP::Layout::lattSize()[decay_dir]
1148  << std::endl;
1149  QDP_abort(1);
1150  }
1151 
1152 
1153  // Another sanity check. The seeds of all the quarks must be different
1154  // and thier decay directions must be the same
1155  for(int n = 1 ; n < diluted_quarks.size(); ++n)
1156  {
1157  if ( toBool( diluted_quarks[n]->getSeed() == diluted_quarks[0]->getSeed() ) )
1158  {
1159  QDPIO::cerr << name << ": error, quark seeds are the same" << std::endl;
1160  QDP_abort(1);
1161  }
1162 
1163  if ( toBool( diluted_quarks[n]->getDecayDir() != diluted_quarks[0]->getDecayDir() ) )
1164  {
1165  QDPIO::cerr << name << ": error, quark decay dirs do not match" <<std::endl;
1166  QDP_abort(1);
1167  }
1168 
1169  }
1170 
1171  //
1172  // Smear the gauge field if needed
1173  //
1174  multi1d<LatticeColorMatrix> u_smr = u;
1175 
1176  try
1177  {
1178  std::istringstream xml_l(params.param.link_smearing.xml);
1179  XMLReader linktop(xml_l);
1180  QDPIO::cout << "Link smearing type = " << params.param.link_smearing.id << std::endl;
1181 
1182 
1184  linkSmearing(TheLinkSmearingFactory::Instance().createObject(params.param.link_smearing.id,
1185  linktop, params.param.link_smearing.path));
1186 
1187  (*linkSmearing)(u_smr);
1188  }
1189  catch(const std::string& e)
1190  {
1191  QDPIO::cerr << name << ": Caught Exception link smearing: " << e << std::endl;
1192  QDP_abort(1);
1193  }
1194 
1195  MesPlq(xml_out, "Smeared_Observables", u_smr);
1196 
1197  //Used for testing purposes
1198  multi1d<int> orig(4);
1199  for (int ind = 0 ; ind < 4 ; ++ind)
1200  {
1201  orig[ind] = 0;
1202  }
1203 
1204  //
1205  // Read operator coefficients
1206  //
1207  QDPIO::cout << "Reading 3-quark operators" << std::endl;
1208  ThreeQuarkOps_t qqq_oplist;
1209 
1211 
1212  //
1213  // Create the quark smearing factory
1214  //
1215  Handle< QuarkSmearing<LatticeFermion> > quarkSmearing;
1216 
1217  try
1218  {
1219  QDPIO::cout << "Create quark smearing object" << std::endl;
1220 
1221  // Create the quark smearing object
1222  std::istringstream xml_s(params.param.quark_smearing.xml);
1223  XMLReader smeartop(xml_s);
1224 
1225  quarkSmearing =
1227  smeartop, params.param.quark_smearing.path);
1228 
1229  }
1230  catch(const std::string& e)
1231  {
1232  QDPIO::cerr << ": Caught Exception creating quark smearing object: " << e << std::endl;
1233  QDP_abort(1);
1234  }
1235  catch(...)
1236  {
1237  QDPIO::cerr << ": Caught generic exception creating smearing object" << std::endl;
1238  QDP_abort(1);
1239  }
1240 
1241  //
1242  // Baryon operators
1243  //
1244 
1245  //
1246  // Permutations of quarks within an operator
1247  //
1248  const std::string& pstr = params.named_obj.quark_ids;
1249  int num_orderings = 1;
1250 
1251  //Should think of a cleverer algorithm for n quarks
1252  if (pstr.size() != N_quarks)
1253  {
1254  QDPIO::cerr << "Invalid size for 'quark_ids'. Must be 3 but is " << pstr.size() << std::endl;
1255  QDP_abort(1);
1256  }
1257 
1258  //If 2 identical quarks, different one must be in the fisrt position
1259  if ( ( (pstr[0] == pstr[2]) && (pstr[1] != pstr[2]) ) ||
1260  ( (pstr[0] == pstr[1]) && (pstr[1] != pstr[2]) ) )
1261  {
1262  QDPIO::cerr << "Invalid format for 'quark_ids'. Identical q's must be last 2 entries.: "
1263  << pstr << std::endl;
1264  QDP_abort(1);
1265  }
1266 
1267  //Check that the kappas of the supposed identical quarks are the same.
1268  if ( (pstr[0] != pstr[1]) && (pstr[1] == pstr[2]) )
1269  {
1270  num_orderings = 2;
1271 
1272  if ( toBool(diluted_quarks[0]->getKappa() == diluted_quarks[1]->getKappa()) ||
1273  toBool(diluted_quarks[1]->getKappa() != diluted_quarks[2]->getKappa()) )
1274  {
1275  QDPIO::cerr << "quark_id's do not correspond to the correct identical quarks"
1276  << std::endl;
1277  QDP_abort(1);
1278  }
1279  }
1280 
1281  if (pstr[0] == pstr[2])
1282  {
1283  num_orderings = 6;
1284 
1285  if ( toBool(diluted_quarks[0]->getKappa() != diluted_quarks[1]->getKappa()) ||
1286  toBool(diluted_quarks[0]->getKappa() != diluted_quarks[2]->getKappa()) )
1287  {
1288 
1289  QDPIO::cerr << "quark_id's do not correspond to the correct identical quarks"
1290  << std::endl;
1291  QDP_abort(1);
1292  }
1293  }
1294 
1295  QDPIO::cout << "Num Ordering = " << num_orderings << std::endl;
1296 
1297  multi1d< multi1d<int> > perms(num_orderings);
1298  {
1299  multi1d<int> p(N_quarks);
1300 
1301  if (num_orderings >= 1)
1302  {
1303  p[0] = 0; p[1] = 1; p[2] = 2;
1304  perms[0] = p;
1305  }
1306 
1307  if (num_orderings >= 2)
1308  {
1309  p[0] = 0; p[1] = 2; p[2] = 1;
1310  perms[1] = p;
1311  }
1312 
1313  if (num_orderings >= 3)
1314  {
1315  p[0] = 1; p[1] = 0; p[2] = 2;
1316  perms[2] = p;
1317  }
1318 
1319  if (num_orderings >= 4)
1320  {
1321  p[0] = 1; p[1] = 2; p[2] = 0;
1322  perms[3] = p;
1323  }
1324 
1325  if (num_orderings >= 5)
1326  {
1327  p[0] = 2; p[1] = 1; p[2] = 0;
1328  perms[4] = p;
1329  }
1330 
1331  if (num_orderings >= 6)
1332  {
1333  p[0] = 2; p[1] = 0; p[2] = 1;
1334  perms[5] = p;
1335  }
1336  }
1337 
1338  //We make all source operators before we make all sink operators to
1339  //save on memory.
1340 
1341  for(int t0 = 0; t0 < participating_timeslices.size() ; ++t0)
1342  {
1343  StopWatch watch;
1344  //Make the source operators
1345  {
1346 
1347  // The object holding the smeared and displaced color std::vector std::maps
1349  diluted_quarks, quarkSmearing, u_smr );
1350 
1351  // Creation operator
1352  BaryonOperator_t creat_oper;
1353  creat_oper.mom2_max = 0;
1354  creat_oper.decay_dir = decay_dir;
1355  creat_oper.seed_l = diluted_quarks[0]->getSeed();
1356  creat_oper.seed_m = diluted_quarks[1]->getSeed();
1357  creat_oper.seed_r = diluted_quarks[2]->getSeed();
1358  creat_oper.dilution_l = params.param.quark_dils[0];
1359  creat_oper.dilution_m = params.param.quark_dils[1];
1360  creat_oper.dilution_r = params.param.quark_dils[2];
1361  creat_oper.smearing = params.param.quark_smearing;
1362  creat_oper.perms = perms;
1363  creat_oper.time_slices.resize( 1 ); //Only a single t0 per file
1364 
1365  // Construct creation operator
1366  // Loop over each operator
1367  for(int l=0; l < qqq_oplist.ops.size(); ++l)
1368  {
1369  QDPIO::cout << "Elemental operator: op = " << l << std::endl;
1370 
1371  push(xml_out, "BaryonOperator");
1372 
1373  creat_oper.id = qqq_oplist.ops[l].name;
1374 
1375  write(xml_out, "Name", creat_oper.id);
1376 
1377  // Loop over all orderings and build the operator
1378  swiss.reset();
1379  swiss.start();
1380 
1381  // The keys for the spin and displacements for this particular elemental operator
1382  multi1d<KeySmearedDispColorVector_t> keySmearedDispColorVector(N_quarks);
1383 
1384  for(int n = 0 ; n < N_quarks ; ++n)
1385  {
1386  keySmearedDispColorVector[n].displacement = qqq_oplist.ops[l].quark[n].displacement;
1387  keySmearedDispColorVector[n].spin = qqq_oplist.ops[l].quark[n].spin;
1388  }
1389 
1390 
1391  creat_oper.time_slices[0].t0 = participating_timeslices[t0];
1392  creat_oper.time_slices[0].orderings.resize(num_orderings);
1393 
1394  for(int ord = 0; ord < num_orderings ; ++ord)
1395  {
1396  QDPIO::cout << "Ordering = " << ord << std::endl;
1397 
1398  creat_oper.time_slices[0].orderings[ord].perm = perms[ord];
1399 
1400  const int n0 = perms[ord][0];
1401  const int n1 = perms[ord][1];
1402  const int n2 = perms[ord][2];
1403 
1404  // The operator must hold all the dilutions
1405 
1406  // Creation operator
1407  BaryonOperator_t::TimeSlices_t::Orderings_t& cop = creat_oper.time_slices[0].orderings[ord];
1408 
1409  cop.dilutions.resize(diluted_quarks[n0]->getDilSize(t0), diluted_quarks[n1]->getDilSize(t0),
1410  diluted_quarks[n2]->getDilSize(t0) );
1411 
1412  for (int n = 0 ; n < N_quarks ; ++n)
1413  {
1414  keySmearedDispColorVector[n].t0 = t0;
1415  }
1416 
1417  for(int i = 0 ; i < diluted_quarks[n0]->getDilSize(t0) ; ++i)
1418  {
1419  for(int j = 0 ; j < diluted_quarks[n1]->getDilSize(t0) ; ++j)
1420  {
1421 
1422  keySmearedDispColorVector[0].dil = i;
1423  keySmearedDispColorVector[1].dil = j;
1424 
1425  //Form the di-quark to save on recalculating
1426  multi1d<LatticeComplex> diquark(Nc);
1427 
1428  const multi1d<LatticeComplex> &q0 = smrd_disp_srcs.getDispSource(n0,
1429  keySmearedDispColorVector[0]);
1430 
1431  const multi1d<LatticeComplex> &q1 = smrd_disp_srcs.getDispSource(n1,
1432  keySmearedDispColorVector[1]);
1433 
1434  /*QDPIO::cout<<"q0[0] testval= "<< peekSite(q0[0], orig)
1435  << std::endl;
1436 
1437  QDPIO::cout<<"q1[0] testval= "<< peekSite(q1[0], orig)
1438  << std::endl;
1439 
1440  */
1441 
1442  watch.reset();
1443  watch.start();
1444  //For the source, restrict this operation to a subset
1445  makeDiquark( diquark, q0 , q1, phases.getSet()[ participating_timeslices[t0] ] );
1446  watch.stop();
1447 
1448  /*QDPIO::cout<< " Made diquark : time = " <<
1449  watch.getTimeInSeconds() << "secs" << std::endl;
1450  */
1451 
1452  for(int k = 0 ; k < diluted_quarks[n2]->getDilSize(t0) ; ++k)
1453  {
1454 
1455  keySmearedDispColorVector[2].dil = k;
1456 
1457  // Contract over color indices with antisym tensor.
1458  // NOTE: the creation operator only lives on a time slice, so restrict
1459  // the operation to that time slice
1460 
1461  LatticeComplex c_oper;
1462 
1463  const multi1d<LatticeComplex> &q2 = smrd_disp_srcs.getDispSource(n2,
1464  keySmearedDispColorVector[2]);
1465 
1466  /*QDPIO::cout<<"q2[0] testval= "<< peekSite(q2[0], orig)
1467  << std::endl;
1468  */
1469  watch.reset();
1470  watch.start();
1471 
1472  makeColorSinglet( c_oper, diquark, q2, phases.getSet()[
1473  participating_timeslices[t0] ] );
1474 
1475  watch.stop();
1476 
1477  /*QDPIO::cout<< "Made Color singlet : time = " <<
1478  watch.getTimeInSeconds() << "secs" << std::endl;
1479  */
1480  /*QDPIO::cout << "testval = " << peekSite(c_oper, orig)
1481  << std::endl;
1482  */
1483  // Slow fourier-transform
1484  // We can restrict what the FT routine requires to a subset.
1485  watch.reset();
1486  watch.start();
1487 
1488  /*
1489  multi2d<DComplex> c_sum(phases.sft(c_oper,
1490  participating_timeslices[t0] ));
1491  */
1492 
1493  multi2d<DComplex> c_sum;
1494  int num_mom;
1495 
1496  c_sum = phases.sft(c_oper, participating_timeslices[t0]);
1497  num_mom = phases.numMom();
1498 
1499  watch.stop();
1500 
1501  /*QDPIO::cout << " Spatial sums completed: time = " <<
1502  watch.getTimeInSeconds() << "secs " << std::endl;
1503  */
1504  // Unpack into separate momentum and correlator
1505 
1506  cop.dilutions(i,j,k).mom_projs.resize(num_mom);
1507 
1508  for(int mom_num = 0 ; mom_num < num_mom ; ++mom_num)
1509  {
1510  cop.dilutions(i,j,k).mom_projs[mom_num].mom =
1511  params.param.moms[mom_num];
1512 
1513  cop.dilutions(i,j,k).mom_projs[mom_num].op.resize(1);
1514 
1515  cop.dilutions(i,j,k).mom_projs[mom_num].op[ 0 ] = c_sum[mom_num][
1516  participating_timeslices[t0] ];
1517  }
1518 
1519  } // end for k
1520  } // end for j
1521  } // end for i
1522  }//end ord
1523 
1524  swiss.stop();
1525 
1526 
1527  QDPIO::cout << "Source operator construction: operator= " << l
1528  << " time= "
1529  << swiss.getTimeInSeconds()
1530  << " secs" << std::endl;
1531 
1532  QDPIO::cout << "Source operator testval(t0 = " <<
1533  participating_timeslices[t0] << ") = " <<
1534  creat_oper.time_slices[0].orderings[0].dilutions(0,0,0).mom_projs[0].op[0];
1535 
1536 
1537 
1538  //Hard code the elemental op name for now
1539  std::stringstream cnvrt;
1540  cnvrt << creat_oper.id << "_t" << participating_timeslices[t0] << "_src.lime";
1541 
1542  std::string filename;
1543 
1544  filename = cnvrt.str();
1545 
1546  // Write the meta-data and the binary for this operator
1547  swiss.reset();
1548  swiss.start();
1549  {
1550  XMLBufferWriter src_record_xml, file_xml;
1551  BinaryBufferWriter src_record_bin;
1552 
1553  push(file_xml, "SourceBaryonOperator");
1554  write(file_xml, "Params", params.param);
1555  write(file_xml, "Config_info", gauge_xml);
1556  write(file_xml, "Op_Info",qqq_oplist.ops[l]);
1557 
1558  push(file_xml, "QuarkSources");
1559 
1560  push(file_xml, "Quark_l");
1561  push(file_xml, "TimeSlice");
1562  push(file_xml, "Dilutions");
1563  for (int dil = 0; dil < diluted_quarks[0]->getDilSize(t0) ; ++dil)
1564  {
1565  write( file_xml, "elem",
1566  diluted_quarks[0]->getSourceHeader(t0, dil) );
1567 
1568  // QDPIO::cout<< "t0 = " << t0 << " dil = "<< dil <<
1569  // " srdhdr = XX"<<diluted_quarks[0]->getSourceHeader(t0,dil) << std::endl;
1570  }
1571  pop(file_xml); //dilutions
1572  pop(file_xml); //TimeSlice
1573  pop(file_xml); //Quark_l
1574 
1575  push(file_xml, "Quark_m");
1576  push(file_xml, "TimeSlice");
1577  push(file_xml, "Dilutions");
1578  for (int dil = 0; dil < diluted_quarks[1]->getDilSize(t0) ; ++dil)
1579  {
1580  write( file_xml, "elem",
1581  diluted_quarks[1]->getSourceHeader(t0, dil) );
1582  }
1583  pop(file_xml); //dilutions
1584  pop(file_xml); //TimeSlice
1585  pop(file_xml); //Quark_m
1586 
1587  push(file_xml, "Quark_r");
1588  push(file_xml, "TimeSlice");
1589  push(file_xml, "Dilutions");
1590  for (int dil = 0; dil < diluted_quarks[2]->getDilSize(t0) ; ++dil)
1591  {
1592  write( file_xml, "elem",
1593  diluted_quarks[2]->getSourceHeader(t0, dil) );
1594  }
1595  pop(file_xml); //dilutions
1596  pop(file_xml); //TimeSlice
1597  pop(file_xml); //Quark_r
1598 
1599  pop(file_xml);//QuarkSources
1600  push(file_xml, "QuarkSinks");
1601 
1602  push(file_xml, "Quark_l");
1603  write(file_xml, "PropHeader", diluted_quarks[0]->getPropHeader(0,0) );
1604  pop(file_xml);
1605 
1606  push(file_xml, "Quark_m");
1607  write(file_xml, "PropHeader", diluted_quarks[1]->getPropHeader(0,0) );
1608  pop(file_xml);
1609 
1610  push(file_xml, "Quark_r");
1611  write(file_xml, "PropHeader", diluted_quarks[2]->getPropHeader(0,0) );
1612  pop(file_xml);
1613 
1614  pop(file_xml); //Quark Sinks
1615  pop(file_xml);//SourceBaryonOp
1616 
1617  QDPFileWriter qdp_file(file_xml, filename, // are there one or two files???
1618  QDPIO_SINGLEFILE, QDPIO_SERIAL, QDPIO_OPEN);
1619 
1620 
1621  write(src_record_xml, "BaryonCreationOperator", creat_oper);
1622  write(src_record_bin, creat_oper);
1623 
1624  write(qdp_file, src_record_xml, src_record_bin);
1625 
1626  }
1627  swiss.stop();
1628 
1629  QDPIO::cout << "Source Operator writing: operator = " <<
1630  l << " time= "
1631  << swiss.getTimeInSeconds()
1632  << " secs" << std::endl;
1633 
1634  pop(xml_out); // BaryonOperator
1635 
1636  } // end for l (operator )
1637 
1638  } //End Make creation operator
1639 
1640 
1641 
1642  //Make Annilation Operator
1643  {
1644 
1645  // The object holding the smeared and displaced color std::vector std::maps
1647  diluted_quarks, quarkSmearing, u_smr );
1648 
1649 
1650  // Annihilation operator
1651  BaryonOperator_t annih_oper;
1652  annih_oper.mom2_max = 0;
1653  annih_oper.decay_dir = decay_dir;
1654  annih_oper.seed_l = diluted_quarks[0]->getSeed();
1655  annih_oper.seed_m = diluted_quarks[1]->getSeed();
1656  annih_oper.seed_r = diluted_quarks[2]->getSeed();
1657  annih_oper.dilution_l = params.param.quark_dils[0];
1658  annih_oper.dilution_m = params.param.quark_dils[1];
1659  annih_oper.dilution_r = params.param.quark_dils[2];
1660  annih_oper.smearing = params.param.quark_smearing;
1661  annih_oper.perms = perms;
1662  annih_oper.time_slices.resize( 1 );
1663 
1664  // Construct annihilation operator
1665  QDPIO::cout << "Building Sink operators" << std::endl;
1666 
1667  // Loop over each operator
1668  for(int l=0; l < qqq_oplist.ops.size(); ++l)
1669  {
1670  QDPIO::cout << "Elemental operator: op = " << l << std::endl;
1671 
1672  annih_oper.id = qqq_oplist.ops[l].name;
1673 
1674  // Loop over all orderings and build the operator
1675  swiss.reset();
1676  swiss.start();
1677 
1678  // The keys for the spin and displacements for this particular elemental operator
1679  multi1d<KeySmearedDispColorVector_t> keySmearedDispColorVector(N_quarks);
1680 
1681  for(int n = 0 ; n < N_quarks ; ++n)
1682  {
1683  keySmearedDispColorVector[n].displacement = qqq_oplist.ops[l].quark[n].displacement;
1684  keySmearedDispColorVector[n].spin = qqq_oplist.ops[l].quark[n].spin;
1685  }
1686 
1687  annih_oper.time_slices[0].t0 = participating_timeslices[t0];
1688  //annih_oper.time_slices[0].orderings.resize(num_orderings);
1689  annih_oper.time_slices[0].orderings.resize(1);
1690 
1691 
1692  int ord = 0;
1693  //for(int ord = 0 ; ord < num_orderings ; ++ord)
1694  {
1695  QDPIO::cout << "Ordering = " << ord << std::endl;
1696 
1697  annih_oper.time_slices[0].orderings[ord].perm = perms[ord];
1698 
1699  const int n0 = perms[ord][0];
1700  const int n1 = perms[ord][1];
1701  const int n2 = perms[ord][2];
1702 
1703  // The operator must hold all the dilutions
1704  // We know that all time slices match. However, not all time slices of the
1705  // lattice maybe used
1706 
1707  // Creation operator
1708  BaryonOperator_t::TimeSlices_t::Orderings_t& aop = annih_oper.time_slices[0].orderings[ord];
1709 
1710  aop.dilutions.resize(diluted_quarks[n0]->getDilSize(t0), diluted_quarks[n1]->getDilSize(t0),
1711  diluted_quarks[n2]->getDilSize(t0) );
1712 
1713  for (int n = 0 ; n < N_quarks ; ++n)
1714  {
1715  keySmearedDispColorVector[n].t0 = t0;
1716  }
1717 
1718  for(int i = 0 ; i < diluted_quarks[n0]->getDilSize(t0) ; ++i)
1719  {
1720  for(int j = 0 ; j < diluted_quarks[n1]->getDilSize(t0) ; ++j)
1721  {
1722 
1723  keySmearedDispColorVector[0].dil = i;
1724  keySmearedDispColorVector[1].dil = j;
1725 
1726  //Form the di-quark to save on recalculating
1727  multi1d<LatticeComplex> diquark(Nc);
1728 
1729  const multi1d<LatticeComplex> &q0 = smrd_disp_snks.getDispSolution(n0,
1730  keySmearedDispColorVector[0]);
1731 
1732  const multi1d<LatticeComplex> &q1 = smrd_disp_snks.getDispSolution(n1,
1733  keySmearedDispColorVector[1]);
1734 
1735 
1736  //QDPIO::cout<<"q0[0] testval= "<< peekSite(q0[0], orig)
1737  // << std::endl;
1738 
1739  //QDPIO::cout<<"q1[0] testval= "<< peekSite(q1[0], orig)
1740  // << std::endl;
1741 
1742 
1743  watch.reset();
1744  watch.start();
1745 
1746  makeDiquark( diquark, q0 , q1, all );
1747 
1748  watch.stop();
1749  /*QDPIO::cout << "Made diquark: time = " <<
1750  watch.getTimeInSeconds() << "secs " << std::endl;
1751  */
1752 
1753  for(int k = 0 ; k < diluted_quarks[n2]->getDilSize(t0) ; ++k)
1754  {
1755 
1756  keySmearedDispColorVector[2].dil = k;
1757 
1758  // Contract over color indices with antisym tensor.
1759  // There is a potential optimization here - the colorcontract of
1760  // the first two quarks could be pulled outside the innermost dilution
1761  // loop.
1762  // NOTE: the creation operator only lives on a time slice, so restrict
1763  // the operation to that time slice
1764 
1765  LatticeComplex a_oper;
1766 
1767  const multi1d<LatticeComplex> &q2 = smrd_disp_snks.getDispSolution(n2,
1768  keySmearedDispColorVector[2]);
1769 
1770  //QDPIO::cout<<"q2[0] testval= "<< peekSite(q2[0], orig)
1771  //<< std::endl;
1772 
1773  watch.reset();
1774  watch.start();
1775 
1776  makeColorSinglet( a_oper, diquark, q2, all);
1777 
1778  watch.stop();
1779 
1780  /*
1781  QDPIO::cout << "Made Color Singlet: time = " <<
1782  watch.getTimeInSeconds() << "secs" << std::endl;
1783  */
1784  /*QDPIO::cout << "testval = " << peekSite(a_oper, orig)
1785  << std::endl;
1786  */
1787 
1788  watch.reset();
1789  watch.start();
1790 
1791  // Slow fourier-transform
1792  multi2d<DComplex> a_sum;
1793  int num_mom;
1794 
1795  a_sum = phases.sft(
1796  a_oper);
1797  num_mom = phases.numMom();
1798 
1799  watch.stop();
1800  /*
1801  QDPIO::cout << "Spatial Sums completed: time " <<
1802  watch.getTimeInSeconds() << "secs" << std::endl;
1803  */
1804  // Unpack into separate momentum and correlator
1805  aop.dilutions(i,j,k).mom_projs.resize(num_mom);
1806 
1807  for(int mom_num = 0 ; mom_num < num_mom ; ++mom_num)
1808  {
1809  aop.dilutions(i,j,k).mom_projs[mom_num].mom = params.param.moms[mom_num];
1810 
1811  aop.dilutions(i,j,k).mom_projs[mom_num].op = a_sum[mom_num];
1812 
1813  }
1814 
1815  } // end for k
1816  } // end for j
1817  } // end for i
1818  }//end ord
1819  swiss.stop();
1820 
1821 
1822  QDPIO::cout << "Sink operator construction: operator= " << l
1823  << " time= "
1824  << swiss.getTimeInSeconds()
1825  << " secs" << std::endl;
1826 
1827  QDPIO::cout << "Sink op testval( t0 = " <<
1828  participating_timeslices[t0] << ") = " <<
1829  annih_oper.time_slices[0].orderings[0].dilutions(0,0,0).mom_projs[0].op[0]
1830  << std::endl;
1831 
1832  //Hard code the elemental op name for now
1833  std::stringstream cnvrt;
1834  cnvrt << annih_oper.id << "_t" << participating_timeslices[t0] << "_snk.lime";
1835 
1836  std::string filename;
1837 
1838  filename = cnvrt.str();
1839 
1840  // Write the meta-data and the binary for this operator
1841  swiss.reset();
1842  swiss.start();
1843  {
1844  XMLBufferWriter src_record_xml, file_xml;
1845  BinaryBufferWriter src_record_bin;
1846 
1847  push(file_xml, "SinkBaryonOperator");
1848  write(file_xml, "Params", params.param);
1849  write(file_xml, "Config_info", gauge_xml);
1850  write(file_xml, "Op_Info",qqq_oplist.ops[l]);
1851  push(file_xml, "QuarkSources");
1852 
1853  push(file_xml, "Quark_l");
1854  push(file_xml, "TimeSlice");
1855  push(file_xml, "Dilutions");
1856  for (int dil = 0; dil < diluted_quarks[0]->getDilSize(t0) ; ++dil)
1857  {
1858  write( file_xml, "elem",
1859  diluted_quarks[0]->getSourceHeader(t0, dil) );
1860  }
1861  pop(file_xml); //dilutions
1862  pop(file_xml); //TimeSlice
1863  pop(file_xml); //Quark_l
1864 
1865  push(file_xml, "Quark_m");
1866  push(file_xml, "TimeSlice");
1867  push(file_xml, "Dilutions");
1868  for (int dil = 0; dil < diluted_quarks[1]->getDilSize(t0) ; ++dil)
1869  {
1870  write( file_xml, "elem",
1871  diluted_quarks[1]->getSourceHeader(t0, dil) );
1872  }
1873  pop(file_xml); //dilutions
1874  pop(file_xml); //TimeSlice
1875  pop(file_xml); //Quark_m
1876 
1877  push(file_xml, "Quark_r");
1878  push(file_xml, "TimeSlice");
1879  push(file_xml, "Dilutions");
1880  for (int dil = 0; dil < diluted_quarks[2]->getDilSize(t0) ; ++dil)
1881  {
1882  write( file_xml, "elem",
1883  diluted_quarks[2]->getSourceHeader(t0, dil) );
1884  }
1885  pop(file_xml); //dilutions
1886  pop(file_xml); //TimeSlice
1887  pop(file_xml); //Quark_r
1888 
1889  pop(file_xml);//QuarkSources
1890  push(file_xml, "QuarkSinks");
1891 
1892  push(file_xml, "Quark_l");
1893  write(file_xml, "PropHeader", diluted_quarks[0]->getPropHeader(0,0) );
1894  pop(file_xml);
1895 
1896  push(file_xml, "Quark_m");
1897  write(file_xml, "PropHeader", diluted_quarks[1]->getPropHeader(0,0) );
1898  pop(file_xml);
1899 
1900  push(file_xml, "Quark_r");
1901  write(file_xml, "PropHeader", diluted_quarks[2]->getPropHeader(0,0) );
1902  pop(file_xml);
1903 
1904  pop(file_xml);//QuarkSinks
1905  pop(file_xml);//SinkBaryonOperator
1906 
1907  QDPFileWriter qdp_file(file_xml, filename, // are there one or two files???
1908  QDPIO_SINGLEFILE, QDPIO_SERIAL, QDPIO_OPEN);
1909 
1910 
1911  write(src_record_xml, "BaryonAnnihilationOperator", annih_oper);
1912  write(src_record_bin, annih_oper);
1913 
1914  write(qdp_file, src_record_xml, src_record_bin);
1915 
1916  }
1917  swiss.stop();
1918 
1919  QDPIO::cout << "Sink Operator writing: operator = " << l
1920  << " time= " << swiss.getTimeInSeconds() << " secs" << std::endl;
1921 
1922  } // end for l (operator )
1923 
1924  } //End Make annihilation operator
1925 
1926  } //end t0
1927  // Close the namelist output file XMLDAT
1928  pop(xml_out); // StochBaryon
1929 
1930  snoop.stop();
1931  QDPIO::cout << InlineStochGroupBaryonEnv::name << ": total time = "
1932  << snoop.getTimeInSeconds()
1933  << " secs" << std::endl;
1934 
1935  QDPIO::cout << InlineStochGroupBaryonEnv::name << ": ran successfully" << std::endl;
1936 
1937  END_CODE();
1938  } // func
1939 
1940  } // namespace InlineStochGroupBaryonEnv
1941 
1942  /*! @} */ // end of group hadron
1943 
1944 } // namespace Chroma
Inline measurement factory.
Class for counted reference semantics.
Definition: handle.h:33
void operator()(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
void func(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
multi1d< std::map< KeySmearedDispColorVector_t, SmearedDispColorVector_t > > disp_soln_maps
virtual const LatticeFermion & smearSource(int qnum, const KeySmearedQuark_t &key)
Smear sources and solutions.
virtual const LatticeFermion & smearSolution(int qnum, const KeySmearedQuark_t &key)
virtual multi1d< LatticeComplex > getDispSolution(int quark_num, const KeySmearedDispColorVector_t &key)
Accessor.
SmearedDispObjects(int disp_length, multi1d< Handle< DilutionScheme< LatticeFermion > > > dil_quarks, Handle< QuarkSmearing< LatticeFermion > > qsmr, const multi1d< LatticeColorMatrix > &u_smr)
Constructor from smeared std::map.
multi1d< std::map< KeySmearedQuark_t, SmearedQuark_t > > smeared_soln_maps
virtual const multi1d< LatticeComplex > & displaceObject(std::map< KeySmearedDispColorVector_t, SmearedDispColorVector_t > &disp_quark_map, const KeySmearedDispColorVector_t &key, const LatticeFermion &smrd_q)
Displace an object.
const multi1d< LatticeColorMatrix > & u
Gauge field.
virtual multi1d< LatticeComplex > getDispSource(int quark_num, const KeySmearedDispColorVector_t &key)
Accessor.
multi1d< std::map< KeySmearedDispColorVector_t, SmearedDispColorVector_t > > disp_src_maps
Maps of smeared displaced color vectors.
multi1d< Handle< DilutionScheme< LatticeFermion > > > diluted_quarks
multi1d< std::map< KeySmearedQuark_t, SmearedQuark_t > > smeared_src_maps
Maps of smeared color vectors.
Base class for quark smearing.
Fourier transform phase factor support.
Definition: sftmom.h:35
int numSubsets() const
Number of subsets - length in decay direction.
Definition: sftmom.h:63
multi2d< DComplex > sft(const LatticeComplex &cf) const
Do a sumMulti(cf*phases,getSet())
Definition: sftmom.cc:524
int numMom() const
Number of momenta.
Definition: sftmom.h:60
const Set & getSet() const
The set to be used in sumMulti.
Definition: sftmom.h:57
static T & Instance()
Definition: singleton.h:432
All dilution scheme factories.
Factory for dilution schemes.
Basis rotation matrix from Dirac to Degrand-Rossi (and reverse)
Parallel transport a lattice field.
SpinMatrixD DiracToDRMat()
The Dirac to Degrand-Rossi spin transformation matrix (and reverse)
Definition: diractodr.cc:22
void proginfo(XMLWriter &xml)
Print out basic information about this program.
Definition: proginfo.cc:24
std::string makeXMLFileName(std::string xml_file, unsigned long update_no)
Return a xml file name for inline measurements.
multi1d< GroupXML_t > readXMLArrayGroup(XMLReader &xml_in, const std::string &path, const std::string &type_name)
Read group and return as a std::string.
GroupXML_t readXMLGroup(XMLReader &xml_in, const std::string &path, const std::string &type_name)
Read group and return as a std::string.
LatticePropagator displacement(const multi1d< LatticeColorMatrix > &u, const LatticePropagator &chi, int length, int dir)
Apply a displacement operator to a lattice field.
Class for counted reference semantics.
Inline measurement of stochastic group baryon operator.
unsigned j
Definition: ldumul_w.cc:35
unsigned n
Definition: ldumul_w.cc:36
void savern(int iseed[4])
Definition: make_seeds.cc:46
Make xml file writer.
Named object function std::map.
static bool registered
Local registration flag.
bool registerAll()
Register all the factories.
SpinMatrix rotate_mat(adj(DiracToDRMat()))
bool registerAll()
Register all the factories.
void makeDiquark(multi1d< LatticeComplex > &diquark, const multi1d< LatticeComplex > &q0, const multi1d< LatticeComplex > &q1, const Subset &subset)
void read(XMLReader &xml, const std::string &path, InlineStochGroupBaryonEnv::Params::Param_t &param)
const int N_quarks
Number of quarks to be used in this construction.
void write(XMLWriter &xml, const std::string &path, const InlineStochGroupBaryonEnv::Params::Param_t &param)
bool operator<(const KeySmearedQuark_t &a, const KeySmearedQuark_t &b)
Support for the keys of smeared quarks.
void makeColorSinglet(LatticeComplex &singlet, const multi1d< LatticeComplex > &diquark, const multi1d< LatticeComplex > &q2, const Subset &subset)
void readOps(ThreeQuarkOps_t &oplist, const std::string &ops_file)
Read 3-quark operators file, assign correct displacement length.
bool registerAll()
Register all the factories.
bool registerAll()
Register all the factories.
Handle< FermBC< LatticeStaggeredFermion, multi1d< LatticeColorMatrix >, multi1d< LatticeColorMatrix > > > reader(XMLReader &xml_in, const std::string &path)
Helper function for the FermionAction readers.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
push(xml_out,"Condensates")
Double c
Definition: invbicg.cc:108
int i
Definition: pbg5p_w.cc:55
Complex a
Definition: invbicg.cc:95
pop(xml_out)
void MesPlq(const multi1d< LatticeColorMatrixF3 > &u, multi2d< Double > &plane_plaq, Double &link)
Definition: mesplq.cc:83
START_CODE()
Complex b
Definition: invbicg.cc:96
int k
Definition: invbicg.cc:119
::std::string string
Definition: gtest.h:1979
int l
Definition: pade_trln_w.cc:111
Print out basic info about this program.
All quark smearing constructors.
Factory for producing quark smearing objects.
Fourier transform phase factor support.
All make sink constructors.
Factory for producing quark prop sinks.
All source smearing.
Factory for producing quark smearing objects.
Hold group xml and type id.
Baryon operator time slices corresponding to location of operator source.
void writeXML(XMLWriter &xml_out, const std::string &path)