CHROMA
t_ov_pbp.cc
Go to the documentation of this file.
1 
2 #include <iostream>
3 #include <sstream>
4 #include <iomanip>
5 #include <string>
6 
7 #include <cstdio>
8 
9 #include <stdlib.h>
10 #include <sys/time.h>
11 #include <math.h>
12 
13 #include "chroma.h"
14 
15 using namespace Chroma;
16 
19 
20 
21 
22 // Struct for test parameters
23 //
24 typedef struct {
25  multi1d<int> nrow;
26  multi1d<int> boundary;
27  multi1d<int> rng_seed;
28  multi1d<Real> lambda;
29  Real lambda_max;
30  bool szin_eig;
34 
36  multi1d<Real> quark_mass; // Many quark masses
38  double approx_min;
39  double approx_max;
40  Real rsd_cg;
42 
43  int max_cg;
45 
46  int num_noise; // Number of noise vectors
48 
49 } Param_t;
50 
51 
52 // Declare routine to read the parameters
53 void readParams(const std::string& filename, Param_t& params)
54 {
55  XMLReader reader(filename);
56 
57  try {
58  // Read Params
59  read(reader, "/params/lattice/nrow", params.nrow);
60  read(reader, "/params/lattice/boundary", params.boundary);
61  read(reader, "/params/RNG/seed", params.rng_seed);
62  read(reader, "/params/zolotarev/wilsonMass", params.wilson_mass);
63 
64  // Read EigenValues:
65  //
66 
67  if ( reader.count("/params/SZINEValues") > 0 ) {
68 
69  // SZIN EValues
70  read(reader, "/params/SZINEValues/lambda", params.lambda);
71  read(reader, "/params/SZINEValues/lambdaMax", params.lambda_max);
72  for(int i=0; i < params.lambda.size(); i++) {
73  params.lambda[i] *= Real(Nd) + params.wilson_mass;
74  }
75  params.lambda_max *= Real(Nd) + params.wilson_mass;
76  params.szin_eig = true;
77  }
78  else if ( reader.count("/params/eValues") > 0 ) {
79 
80  // Chroma EValues
81  read(reader, "/params/eValues/lambda", params.lambda);
82  read(reader, "/params/eValues/lambdaMax", params.lambda_max);
83  params.szin_eig = false;
84  }
85  else {
86 
87  // No EValues
88  params.lambda.resize(0);
89  params.szin_eig = false;
90  }
91 
92  read(reader, "/params/Cfg/startType", params.gauge_start_type);
93  if( params.gauge_start_type == FILE_START ) {
94  read(reader, "/params/Cfg/gaugeFilename", params.gauge_filename);
95  read(reader, "/params/Cfg/gaugeFileFormat", params.gauge_file_format);
96  }
97 
98 
99  read(reader, "/params/zolotarev/approxOrder", params.approx_order);
100 
101  if( reader.count("/params/zolotarev/approxMin") == 1 ) {
102  read(reader, "/params/zolotarev/approxMin", params.approx_min);
103  }
104  else {
105  params.approx_min = -1;
106  }
107 
108  if( reader.count("/params/zolotarev/approxMax") == 1 ) {
109  read(reader, "/params/zolotarev/approxMax", params.approx_max);
110  } else {
111  params.approx_max = -1;
112  }
113 
114 
115  read(reader, "/params/zolotarev/quarkMass", params.quark_mass);
116  read(reader, "/params/zolotarev/RsdCG", params.rsd_cg_inner);
117  read(reader, "/params/zolotarev/MaxCG", params.max_cg_inner);
118 
119  read(reader, "/params/PsiBarPsi/RsdCG", params.rsd_cg);
120  read(reader, "/params/PsiBarPsi/MaxCG", params.max_cg);
121 
122  read(reader, "/params/PsiBarPsi/NumNoise", params.num_noise);
123  int s_ch;
124  read(reader, "/params/PsiBarPsi/SrcChirality", s_ch);
125 
126  switch(s_ch) {
127  case 1 :
128  params.src_chirality = CH_PLUS;
129  break;
130  case -1:
131  params.src_chirality = CH_MINUS;
132  break;
133  case 0:
134  params.src_chirality = CH_NONE;
135  break;
136  default:
137  std::cerr << "Unknown value for SrcChirality " << s_ch << std::endl;
138  exit(1);
139  }
140 
141 
142  }
143  catch(const std::string& e) {
144  throw e;
145  }
146 }
147 
148 void dumpParams(XMLWriter& writer, Param_t& params)
149 {
150  push(writer, "params");
151  push(writer, "lattice");
152  write(writer, "nrow", params.nrow);
153  write(writer, "boundary", params.boundary);
154  pop(writer); // lattice
155  push(writer, "RNG");
156  write(writer, "seed", params.rng_seed);
157  pop(writer); // RNG
158 
159  if( params.lambda.size() > 0 ) {
160  if ( params.szin_eig ) {
161 
162  push(writer, "eValues");
163  write(writer, "lambda", params.lambda);
164  write(writer, "lambdaMax", params.lambda_max);
165  pop(writer); // eValues
166 
167  push(writer, "SZINEValues");
168  multi1d<Real> szin_lambda(params.lambda);
169  Real szin_lambda_max = params.lambda_max;
170 
171  for(int i = 0; i < params.lambda.size(); i++) {
172  szin_lambda[i] /= (Real(Nd) + params.wilson_mass);
173  }
174  szin_lambda_max /= (Real(Nd) + params.wilson_mass);
175 
176  write(writer, "lambda", szin_lambda);
177  write(writer, "lambdaMax", szin_lambda_max);
178  pop(writer); // SZINEValues
179  }
180  else {
181  push(writer, "eValues");
182  write(writer, "lambda", params.lambda);
183  write(writer, "lambdaMax", params.lambda_max);
184  pop(writer); // eValues
185  }
186  }
187  push(writer, "Cfg");
188  write(writer, "startType", params.gauge_start_type);
189  if( params.gauge_start_type == FILE_START ) {
190  write(writer, "gaugeFileFormat", params.gauge_file_format);
191  write(writer, "gaugeFilename", params.gauge_filename);
192  }
193  pop(writer); // Cfg
194 
195  push(writer, "zolotarev");
196  write(writer, "approxOrder", params.approx_order);
197  if( params.approx_min > 0 ) {
198  write(writer, "approxMin", params.approx_min);
199  }
200 
201  if( params.approx_max > 0 ) {
202  write(writer, "approxMax", params.approx_max);
203  }
204 
205  write(writer, "wilsonMass", params.wilson_mass);
206  write(writer, "quarkMass", params.quark_mass);
207  write(writer, "RsdCG", params.rsd_cg_inner);
208  write(writer, "MaxCG", params.max_cg_inner);
209  pop(writer); // zolotarev
210 
211  push(writer, "PsiBarPsi");
212  write(writer, "RsdCG", params.rsd_cg);
213  write(writer, "MaxCG", params.max_cg);
214  write(writer, "NumNoise", params.num_noise);
215 
216  int s_ch;
217  switch( params.src_chirality ) {
218  case CH_PLUS:
219  s_ch = +1;
220  break;
221  case CH_MINUS:
222  s_ch = -1;
223  break;
224  case CH_NONE:
225  s_ch = 0;
226  break;
227  default:
228  std::cerr << "I have reached a place where I shouldnt have reached." << std::endl;
229  exit(1);
230  }
231  write(writer, "SrcChirality", s_ch);
232 
233  pop(writer);
234 
235  pop(writer); // params
236 }
237 
238 //! Read in the old SZIN eigenvectors.
239 // Not only do we read the eigenvectors but we also check them
240 // by computing the norm:
241 //
242 // || gamma_5 D_wils e_i - lambda_i e_i ||
243 //
244 // Since D_wils = (Nd + m_wils) D_wils_szin, we expect this
245 // norm to be
246 //
247 // (Nd + m_wils) || gamma_5 D_wils_szin e_i - lambda_i e_i ||
248 //
249 // We also compute the old SZIN norm:
250 //
251 // || gamma_5 D_wils_szin e_i - lambda_i e_i ||
252 //
253 // by dividing our original eigen nom by (Nd + m_wils)
254 //
255 // This latter norm can be checked against SZIN NMLDAT files.
256 //
257 void readEigenVecs(const multi1d<LatticeColorMatrix>& u,
258  const UnprecWilsonFermAct& S_aux,
259  const multi1d<Real>& lambda_lo,
260  multi1d<LatticeFermion>& eigen_vec,
261  const Real wilson_mass,
262  const bool szin_eig,
263  XMLWriter& xml_out,
264  const std::string& root_prefix)
265 {
266 
267 
268  // Create a connect State
269  // This is where the boundary conditions are applied.
270 
273 
274 
275  // Create Space for the eigen vecs
276  eigen_vec.resize(lambda_lo.size());
277 
278  // Create Space for the eigenstd::vector norms
279  multi1d<Real> e_norms(lambda_lo.size());
280  multi1d<Real> evec_norms(lambda_lo.size());
281 
282  for(int i = 0; i < lambda_lo.size(); i++) {
283 
284  // Make up the filename
285  std::ostringstream filename;
286 
287  // this will produce eigenvector_XXX
288  // where XXX is a 0 padded integer -- eg 001, 002, 010 etc
289  filename << root_prefix << "eigenvector_" << std::setw(3) << std::setfill('0') << i;
290 
291 
292  std::cout << "Reading eigenstd::vector: " << filename.str() << std::endl;
293  readSzinFerm(eigen_vec[i], filename.str());
294 
295  // Check e-vectors are normalized
296  evec_norms[i] = (Real)sqrt(norm2(eigen_vec[i]));
297 
298  // Check the norm || Gamma_5 D e_v - lambda
299  LatticeFermion D_ev, tmp_ev, lambda_e;
300 
301  // D_ew = D ev(i)
302  (*D_w)(tmp_ev, eigen_vec[i], PLUS);
303 
304  D_ev = Gamma(15)*tmp_ev;
305 
306  // Lambda_e
307  lambda_e = lambda_lo[i]*eigen_vec[i];
308 
309  D_ev -= lambda_e;
310 
311  e_norms[i] = (Real)sqrt(norm2(D_ev));
312  }
313  push(xml_out, "Eigenstd::vectorTest");
314  push(xml_out, "EigenVecNorms");
315  write(xml_out, "evec_norms", evec_norms);
316  pop(xml_out);
317  push(xml_out, "EigenTestNorms");
318  write(xml_out, "e_norms", e_norms);
319  pop(xml_out);
320 
321  if( szin_eig ) {
322  multi1d<Real> szin_enorms(e_norms);
323  for(int i=0; i < lambda_lo.size(); i++) {
324  szin_enorms[i] /= (Real(Nd)+wilson_mass);
325  }
326  push(xml_out, "SZINEigenTestNorms");
327  write(xml_out, "szin_enorms",szin_enorms);
328  pop(xml_out);
329  }
330  pop(xml_out); // eigenstd::vector test
331 }
332 
333 int main(int argc, char **argv)
334 {
335  // Put the machine into a known state
336  Chroma::initialize(&argc, &argv);
337 
338  std::string root_prefix="";
339 
340  if( argc == 2 ) {
341  root_prefix += argv[1];
342  root_prefix += "/";
343  }
344 
345  // Read the parameters
346  Param_t params;
347 
348  try {
349  readParams(root_prefix+"DATA", params);
350  }
351  catch(const std::string& s) {
352  QDPIO::cerr << "Caught exception " << s << std::endl;
353  exit(1);
354  }
355 
356 
357  // Setup the lattice
358  Layout::setLattSize(params.nrow);
359  Layout::create();
360 
361  // Write out the params
362  XMLFileWriter xml_out(root_prefix+"t_ov_pbp.xml");
363  push(xml_out, "psiBarPsiTest");
364 
365  dumpParams(xml_out, params);
366 
367 
368  // Create a FermBC
370 
371  // The Gauge Field
372  multi1d<LatticeColorMatrix> u(Nd);
373 
374  switch ((GaugeStartType)params.gauge_start_type) {
375  case COLD_START:
376  for(int j = 0; j < Nd; j++) {
377  u(j) = Real(1);
378  }
379  break;
380  case HOT_START:
381  // Hot (disordered) start
382  for(int j=0; j < Nd; j++) {
383  random(u(j));
384  reunit(u(j));
385  }
386  break;
387  case FILE_START:
388 
389  // Start from File
390  switch( (GaugeFormat)params.gauge_file_format) {
391  case SZIN_GAUGE_FORMAT:
392  {
393  XMLReader szin_xml;
394  readSzin(szin_xml, u, params.gauge_filename);
395  try {
396  push(xml_out, "GaugeInfo");
397  xml_out << szin_xml;
398  pop(xml_out);
399 
400  }
401  catch(const std::string& e) {
402  std::cerr << "Error: " << e << std::endl;
403  }
404 
405  }
406  break;
407 
408  case NERSC_GAUGE_FORMAT:
409  {
410  XMLReader nersc_xml;
411  readArchiv(nersc_xml, u, params.gauge_filename);
412 
413  try {
414  push(xml_out, "GaugeInfo");
415  xml_out << nersc_xml;
416  pop(xml_out);
417 
418  }
419  catch(const std::string& e) {
420  std::cerr << "Error: " << e << std::endl;
421  }
422  }
423  break;
424 
425  default:
426  std::ostringstream file_read_error;
427  file_read_error << "Unknown gauge file format" << params.gauge_file_format ;
428  throw file_read_error.str();
429  }
430  break;
431  default:
432  std::ostringstream startup_error;
433  startup_error << "Unknown start type " << params.gauge_start_type <<std::endl;
434  throw startup_error.str();
435  }
436 
437 
438  // Measure the plaquette on the gauge
439  MesPlq(xml_out, "Observables", u);
440  xml_out.flush();
441 
442  //! Wilsoniums;
443  // Put this puppy into a handle to allow Zolo to copy it around as a **BASE** class
444  // WARNING: the handle now owns the data. The use of a bare S_w below is legal,
445  // but just don't delete it.
447 
448 
449  XMLBufferWriter my_writer;
450 
451  //! N order Zolo approx, with wilson action.
452  // Zero quark mass explicitly, because we will use multi mass
453  Zolotarev4DFermAct S(fbc, S_w,
454  Real(0),
455  params.approx_order,
456  params.rsd_cg_inner,
457  params.max_cg_inner,
458  my_writer);
459 
460 
461  const ConnectState* connect_state_ptr;
462  multi1d<LatticeFermion> eigen_vecs;
463 
464 
465  // Flick on BC's - do not do this. Now let it be down in createState
466 // phfctr(u);
467 
468  if( params.lambda.size() == 0 ) {
469 
470  // Connect State with no eigenvectors
471  connect_state_ptr = S.createState(u,
472  Real(params.approx_min),
473  Real(params.approx_max));
474  }
475  else {
476 
477  // Connect State with eigenvectors
478  if( params.szin_eig ) {
479  readEigenVecs(u,
480  dynamic_cast<UnprecWilsonFermAct&>(*S_w),
481  params.lambda,
482  eigen_vecs,
483  params.wilson_mass,
484  params.szin_eig,
485  xml_out,
486  root_prefix);
487  }
488  else {
489  QDP_error_exit("Non SZIN e-values not yet implmeneted");
490  }
491 
492  connect_state_ptr = S.createState(u,
493  params.lambda,
494  eigen_vecs,
495  params.lambda_max);
496  }
497 
498 
499  // Stuff the pointer into a handle. Now, the handle owns the data.
500  Handle<const ConnectState> connect_state(connect_state_ptr);
501 
502  // This is tricksy. I think the first size, comes into the SECOND index
503  multi2d<DComplex> psi_bar_psi(params.quark_mass.size(), params.num_noise);
504 
505  for(int noise = 0; noise < params.num_noise; noise++) {
506 
507  int multi_n_count=0;
508 
509  LatticeFermion noise_source;
510  multi1d<LatticeFermion> inverse(params.quark_mass.size());
511 
512  // Fill source with noise
513  gaussian(noise_source);
514 
515  if ( params.src_chirality != CH_NONE ) {
516  // Project with gamma_5 for positive chirality
517  LatticeFermion tmp = Gamma(15)*noise_source;
518 
519  if ( params.src_chirality == CH_PLUS ) {
520 
521  // noise source = noise_source + gamma_5 noise_source
522  noise_source += tmp;
523 
524  }
525  else {
526  noise_source -= tmp;
527  }
528 
529  // noise source = (1/2) ( 1 + gamma_5 ) noise_source
530  noise_source *= Real(0.5);
531  }
532 
533 
534  // Normalise noise_src to 1 (for inversion)
535  Double noise_norm = sqrt(norm2(noise_source));
536  noise_source /= Real(noise_norm);
537 
538 
539  // Fill inverse with zero (note it is "zero" not 0 )
540  inverse = zero;
541 
542 
543  // Invert multi mass
544  int minv_ncount = 0;
545 
546  multi1d<Real> rsd_array(params.quark_mass.size());
547  for(int m=0; m < params.quark_mass.size(); m++) {
548  rsd_array[m] = params.rsd_cg;
549  }
550 
551 
552  // Compute 2/(1-m)[ D^{-1} - 1 ]
553  S.multiQprop(inverse,
554  params.quark_mass,
555  connect_state,
556  noise_source,
557  CG_INVERTER,
558  rsd_array,
559  params.quark_mass.size(),
560  params.max_cg,
561  minv_ncount);
562 
563 
564 
565  Real vol = Real(Layout::vol());
566 
567  for(int m=0; m < params.quark_mass.size(); m++) {
568 
569  // Construct < source , solution > inner products for the trace
570  psi_bar_psi[m][noise] = innerProduct( noise_source, inverse[m]);
571 
572  // Normalise psi-bar-psi
573  psi_bar_psi[m][noise] *= Real(2)*params.quark_mass[m];
574  psi_bar_psi[m][noise] /= (Real(1) - params.quark_mass[m]*params.quark_mass[m]);
575  }
576 
577  }
578 
579  for(int m=0; m < params.quark_mass.size(); m++) {
580  push(xml_out, "psiBarPsi");
581  write(xml_out, "mass", params.quark_mass[m]);
582  write(xml_out, "pbp", psi_bar_psi[m]);
583  pop(xml_out);
584  }
585 
586  pop(xml_out);
587  xml_out.close();
588 
590 
591  exit(0);
592 }
Primary include file for CHROMA in application codes.
Support class for fermion actions and linear operators.
Definition: state.h:28
virtual FermState< T, P, Q > * createState(const Q &q) const
Given links (coordinates Q) create the state needed for the linear operators.
Definition: fermact.h:59
Class for counted reference semantics.
Definition: handle.h:33
Concrete class for all gauge actions with simple boundary conditions.
Definition: simple_fermbc.h:42
Unpreconditioned Wilson fermion action.
UnprecLinearOperator< T, P, Q > * linOp(Handle< FermState< T, P, Q > > state) const
Produce a linear operator for this action.
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams &param)
Read parameters.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
void readSzinFerm(LatticeFermion &q, const std::string &file)
Read a SZIN fermion. This is a simple memory dump reader.
void readSzin(SzinGauge_t &header, multi1d< LatticeColorMatrix > &u, const std::string &cfg_file)
Read a SZIN configuration file.
Definition: readszin.cc:31
Params params
unsigned j
Definition: ldumul_w.cc:35
static int m[4]
Definition: make_seeds.cc:16
Nd
Definition: meslate.cc:74
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
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
gaussian(aux)
Double psi_bar_psi
Definition: mespbp_s.cc:22
QDP_error_exit("too many BiCG iterations", n_count, rsd_sq, cp, c, re_rvr, im_rvr, re_a, im_a, re_b, im_b)
Chirality
Definition: ischiral_w.h:8
@ CH_NONE
Definition: ischiral_w.h:8
@ CH_PLUS
Definition: ischiral_w.h:8
@ CH_MINUS
Definition: ischiral_w.h:8
static multi1d< LatticeColorMatrix > u
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
push(xml_out,"Condensates")
int i
Definition: pbg5p_w.cc:55
void initialize(int *argc, char ***argv)
Chroma initialisation routine.
Definition: chroma_init.cc:114
@ PLUS
Definition: chromabase.h:45
void finalize(void)
Chroma finalization routine.
Definition: chroma_init.cc:308
void reunit(LatticeColorMatrixF3 &xa)
Definition: reunit.cc:467
pop(xml_out)
void MesPlq(const multi1d< LatticeColorMatrixF3 > &u, multi2d< Double > &plane_plaq, Double &link)
Definition: mesplq.cc:83
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
FloatingPoint< double > Double
Definition: gtest.h:7351
::std::string string
Definition: gtest.h:1979
Parameters for running program.
Definition: qpropadd.cc:17
int gauge_file_format
Definition: t_ov_pbp.cc:32
Real wilson_mass
Definition: t_ov_pbp.cc:35
Real lambda_max
Definition: t_ov_pbp.cc:29
Real rsd_cg_inner
Definition: t_ov_pbp.cc:41
int max_cg
Definition: t_ov_pbp.cc:43
multi1d< int > rng_seed
Definition: t_ov_pbp.cc:27
Real rsd_cg
Definition: t_ov_pbp.cc:40
std::string gauge_filename
Definition: t_ov_pbp.cc:33
double approx_max
Definition: t_ov_pbp.cc:39
multi1d< Real > quark_mass
Definition: t_ov_pbp.cc:36
int num_noise
Definition: t_ov_pbp.cc:46
int approx_order
Definition: t_ov_pbp.cc:37
Chirality src_chirality
Definition: t_ov_pbp.cc:47
multi1d< Real > lambda
Definition: t_ov_pbp.cc:28
int max_cg_inner
Definition: t_ov_pbp.cc:44
int gauge_start_type
Definition: t_ov_pbp.cc:31
double approx_min
Definition: t_ov_pbp.cc:38
bool szin_eig
Definition: t_ov_pbp.cc:30
GaugeStartType
GaugeFormat
Definition: t_ov_pbp.cc:18
@ NERSC_GAUGE_FORMAT
Definition: t_ov_pbp.cc:18
@ SZIN_GAUGE_FORMAT
Definition: t_ov_pbp.cc:18
void readParams(const std::string &filename, Param_t &params)
Definition: t_ov_pbp.cc:53
int main(int argc, char **argv)
Definition: t_ov_pbp.cc:333
void dumpParams(XMLWriter &writer, Param_t &params)
Definition: t_ov_pbp.cc:148
@ HOT_START
Definition: t_ov_pbp.cc:17
@ FILE_START
Definition: t_ov_pbp.cc:17
@ COLD_START
Definition: t_ov_pbp.cc:17
void readEigenVecs(const multi1d< LatticeColorMatrix > &u, const UnprecWilsonFermAct &S_aux, const multi1d< Real > &lambda_lo, multi1d< LatticeFermion > &eigen_vec, const Real wilson_mass, const bool szin_eig, XMLWriter &xml_out, const std::string &root_prefix)
Read in the old SZIN eigenvectors.
Definition: t_ov_pbp.cc:257