inline_stoch_baryon_w.cc

Go to the documentation of this file.
00001 // $Id: inline_stoch_baryon_w.cc,v 3.14 2008/11/04 18:43:57 edwards Exp $
00002 /*! \file
00003  * \brief Inline measurement of stochastic baryon operator
00004  *
00005  */
00006 
00007 #include "handle.h"
00008 #include "meas/inline/hadron/inline_stoch_baryon_w.h"
00009 #include "meas/inline/abs_inline_measurement_factory.h"
00010 #include "meas/sources/dilutezN_source_const.h"
00011 #include "meas/sources/zN_src.h"
00012 #include "meas/hadron/barspinmat_w.h"
00013 #include "meas/hadron/baryon_operator_aggregate_w.h"
00014 #include "meas/hadron/baryon_operator_factory_w.h"
00015 #include "meas/glue/mesplq.h"
00016 #include "util/ft/sftmom.h"
00017 #include "util/info/proginfo.h"
00018 #include "meas/inline/make_xml_file.h"
00019 
00020 #include "meas/inline/io/named_objmap.h"
00021 
00022 namespace Chroma 
00023 { 
00024   namespace InlineStochBaryonEnv 
00025   { 
00026     namespace
00027     {
00028       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00029                                               const std::string& path) 
00030       {
00031         return new InlineStochBaryon(InlineStochBaryonParams(xml_in, path));
00032       }
00033 
00034       //! Local registration flag
00035       bool registered = false;
00036     }
00037 
00038     const std::string name = "STOCH_BARYON";
00039 
00040     //! Register all the factories
00041     bool registerAll() 
00042     {
00043       bool success = true; 
00044       if (! registered)
00045       {
00046         success &= BaryonOperatorEnv::registerAll();
00047         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00048         registered = true;
00049       }
00050       return success;
00051     }
00052   }
00053 
00054 
00055 
00056   // Operator parameters
00057   void read(XMLReader& xml, const string& path, InlineStochBaryonParams::Prop_t::Operator_t& input)
00058   {
00059     XMLReader inputtop(xml, path);
00060 
00061     read(inputtop, "soln_files", input.soln_files);
00062   }
00063 
00064 
00065   // Operator parameters
00066   void write(XMLWriter& xml, const string& path, const InlineStochBaryonParams::Prop_t::Operator_t& input)
00067   {
00068     push(xml, path);
00069     write(xml, "soln_files", input.soln_files);
00070     pop(xml);
00071   }
00072 
00073 
00074   // Propagator parameters
00075   void read(XMLReader& xml, const string& path, InlineStochBaryonParams::Prop_t& input)
00076   {
00077     XMLReader inputtop(xml, path);
00078 
00079     read(inputtop, "operator_file", input.op_file);
00080     read(inputtop, "operator", input.op);
00081   }
00082 
00083 
00084   // Propagator parameters
00085   void write(XMLWriter& xml, const string& path, const InlineStochBaryonParams::Prop_t& input)
00086   {
00087     push(xml, path);
00088 
00089     write(xml, "operator_file", input.op_file);
00090     write(xml, "operator", input.op);
00091 
00092     pop(xml);
00093   }
00094 
00095 
00096   // Reader for input parameters
00097   void read(XMLReader& xml, const string& path, InlineStochBaryonParams::Param_t& param)
00098   {
00099     XMLReader paramtop(xml, path);
00100 
00101     int version;
00102     read(paramtop, "version", version);
00103 
00104     switch (version) 
00105     {
00106     case 2:
00107       /**************************************************************************/
00108       break;
00109 
00110     default :
00111       /**************************************************************************/
00112 
00113       QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00114       QDP_abort(1);
00115     }
00116 
00117     read(paramtop, "mom2_max", param.mom2_max);
00118     
00119     {
00120       XMLReader xml_tmp(paramtop, "BaryonOperator");
00121       std::ostringstream os;
00122       xml_tmp.print(os);
00123       read(xml_tmp, "BaryonOperatorType", param.baryon_operator_type);
00124       param.baryon_operator = os.str();
00125     }
00126 
00127   }
00128 
00129 
00130   // Reader for input parameters
00131   void write(XMLWriter& xml, const string& path, const InlineStochBaryonParams::Param_t& param)
00132   {
00133     push(xml, path);
00134 
00135     int version = 1;
00136 
00137     write(xml, "version", version);
00138     write(xml, "mom2_max", param.mom2_max);
00139 
00140     pop(xml);
00141   }
00142 
00143 
00144   //! Propagator parameters
00145   void read(XMLReader& xml, const string& path, InlineStochBaryonParams::NamedObject_t& input)
00146   {
00147     XMLReader inputtop(xml, path);
00148 
00149     read(inputtop, "gauge_id", input.gauge_id);
00150     read(inputtop, "Prop", input.prop);
00151   }
00152 
00153   //! Propagator parameters
00154   void write(XMLWriter& xml, const string& path, const InlineStochBaryonParams::NamedObject_t& input)
00155   {
00156     push(xml, path);
00157 
00158     write(xml, "gauge_id", input.gauge_id);
00159     write(xml, "Prop", input.prop);
00160 
00161     pop(xml);
00162   }
00163 
00164 
00165   // Param stuff
00166   InlineStochBaryonParams::InlineStochBaryonParams()
00167   { 
00168     frequency = 0; 
00169   }
00170 
00171   InlineStochBaryonParams::InlineStochBaryonParams(XMLReader& xml_in, const std::string& path) 
00172   {
00173     try 
00174     {
00175       XMLReader paramtop(xml_in, path);
00176 
00177       if (paramtop.count("Frequency") == 1)
00178         read(paramtop, "Frequency", frequency);
00179       else
00180         frequency = 1;
00181 
00182       // Read program parameters
00183       read(paramtop, "Param", param);
00184 
00185       // Read in the output propagator/source configuration info
00186       read(paramtop, "NamedObject", named_obj);
00187 
00188       // Possible alternate XML file pattern
00189       if (paramtop.count("xml_file") != 0) 
00190       {
00191         read(paramtop, "xml_file", xml_file);
00192       }
00193     }
00194     catch(const std::string& e) 
00195     {
00196       QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00197       QDP_abort(1);
00198     }
00199   }
00200 
00201 
00202   void
00203   InlineStochBaryonParams::write(XMLWriter& xml_out, const std::string& path) 
00204   {
00205     push(xml_out, path);
00206     
00207     // Parameters for source construction
00208     Chroma::write(xml_out, "Param", param);
00209 
00210     // Write out the output propagator/source configuration info
00211     Chroma::write(xml_out, "NamedObject", named_obj);
00212 
00213     pop(xml_out);
00214   }
00215 
00216 
00217 
00218   //--------------------------------------------------------------
00219 
00220   //! Structure holding a source and its solutions
00221   struct QuarkSourceSolutions_t
00222   {
00223     //! Structure holding solutions
00224     struct QuarkSolution_t
00225     {
00226       LatticeFermion     source;
00227       LatticeFermion     soln;
00228       PropSourceConst_t  source_header;
00229       ChromaProp_t       prop_header;
00230     };
00231 
00232     int   j_decay;
00233     Seed  seed;
00234     multi1d<QuarkSolution_t>  dilutions;
00235   };
00236 
00237 
00238   //! Baryon operator
00239   struct BaryonOperator_t
00240   {
00241 
00242     //! Baryon operator
00243     struct BaryonOperatorInsertion_t
00244     {
00245       //! Possible operator index
00246       struct BaryonOperatorIndex_t
00247       {
00248         //! Baryon operator element
00249         struct BaryonOperatorElement_t
00250         {
00251           multi2d<DComplex> elem;              /*!< time slice and momenta number */
00252         };
00253 
00254         multi1d<BaryonOperatorElement_t> ind;
00255       };
00256     
00257       multi3d<BaryonOperatorIndex_t> op;    /*!< hybrid list indices */
00258 
00259     };
00260 
00261     multi1d< multi1d<int> > perms;   /*!< Permutations of quark enumeration */
00262 
00263     Seed          seed_l;            /*!< Id of left quark */
00264     Seed          seed_m;            /*!< Id of middle quark */
00265     Seed          seed_r;            /*!< Id of right quark */
00266 
00267     int           mom2_max;
00268     int           j_decay;
00269     multi1d<BaryonOperatorInsertion_t> orderings;  /*!< Array is over quark orderings */
00270   };
00271 
00272 
00273   //! BaryonOperator binary writer
00274   void write(BinaryWriter& bin, 
00275              const BaryonOperator_t::BaryonOperatorInsertion_t::BaryonOperatorIndex_t::BaryonOperatorElement_t& p){
00276     write(bin, p.elem);
00277   }
00278 
00279   //! BaryonOperator binary writer
00280   void write(BinaryWriter& bin, 
00281              const BaryonOperator_t::BaryonOperatorInsertion_t::BaryonOperatorIndex_t& p){
00282     write(bin, p.ind);
00283   }
00284 
00285   //! BaryonOperator binary writer
00286   void write(BinaryWriter& bin, 
00287              const BaryonOperator_t::BaryonOperatorInsertion_t& p){
00288     write(bin, p.op);
00289   }
00290 
00291   //! BaryonOperator binary writer
00292   void write(BinaryWriter& bin, const BaryonOperator_t& param){
00293     write(bin, param.seed_l);
00294     write(bin, param.seed_m);
00295     write(bin, param.seed_r);
00296     write(bin, param.mom2_max);
00297     write(bin, param.j_decay);
00298     write(bin, param.perms);
00299     write(bin, param.orderings);
00300   }
00301   
00302   //! BaryonOperator header writer
00303   void write(XMLWriter& xml, const string& path, const BaryonOperator_t& param)
00304   {
00305     if( path != "." )
00306       push(xml, path);
00307 
00308     int version = 1;
00309     write(xml, "version", version);
00310     write(xml, "mom2_max", param.mom2_max);
00311     write(xml, "j_decay", param.j_decay);
00312     write(xml, "seed_l", param.seed_l);
00313     write(xml, "seed_m", param.seed_m);
00314     write(xml, "seed_r", param.seed_r);
00315     write(xml, "perms", param.perms);
00316 
00317     if( path != "." )
00318       pop(xml);
00319   }
00320 
00321 
00322 
00323   //--------------------------------------------------------------
00324   // Function call
00325   void 
00326   InlineStochBaryon::operator()(unsigned long update_no,
00327                                 XMLWriter& xml_out) 
00328   {
00329     // If xml file not empty, then use alternate
00330     if (params.xml_file != "")
00331     {
00332       string xml_file = makeXMLFileName(params.xml_file, update_no);
00333 
00334       push(xml_out, "stoch_baryon");
00335       write(xml_out, "update_no", update_no);
00336       write(xml_out, "xml_file", xml_file);
00337       pop(xml_out);
00338 
00339       XMLFileWriter xml(xml_file);
00340       func(update_no, xml);
00341     }
00342     else
00343     {
00344       func(update_no, xml_out);
00345     }
00346   }
00347 
00348 
00349   // Function call
00350   void 
00351   InlineStochBaryon::func(unsigned long update_no,
00352                           XMLWriter& xml_out) 
00353   {
00354     START_CODE();
00355 
00356     StopWatch snoop;
00357     snoop.reset();
00358     snoop.start();
00359 
00360     // Test and grab a reference to the gauge field
00361     XMLBufferWriter gauge_xml;
00362     try
00363     {
00364       TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00365       TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00366     }
00367     catch( std::bad_cast ) 
00368     {
00369       QDPIO::cerr << InlineStochBaryonEnv::name << ": caught dynamic cast error" 
00370                   << endl;
00371       QDP_abort(1);
00372     }
00373     catch (const string& e) 
00374     {
00375       QDPIO::cerr << InlineStochBaryonEnv::name << ": map call failed: " << e 
00376                   << endl;
00377       QDP_abort(1);
00378     }
00379     const multi1d<LatticeColorMatrix>& u = 
00380       TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00381 
00382     push(xml_out, "stoch_baryon");
00383     write(xml_out, "update_no", update_no);
00384 
00385     QDPIO::cout << InlineStochBaryonEnv::name << ": Stochastic Baryon Operator" << endl;
00386 
00387     proginfo(xml_out);    // Print out basic program info
00388 
00389     // Write out the input
00390     params.write(xml_out, "Input");
00391 
00392     // Write out the config info
00393     write(xml_out, "Config_info", gauge_xml);
00394 
00395     push(xml_out, "Output_version");
00396     write(xml_out, "out_version", 1);
00397     pop(xml_out);
00398 
00399     // First calculate some gauge invariant observables just for info.
00400     // This is really cheap.
00401     MesPlq(xml_out, "Observables", u);
00402 
00403     // Save current seed
00404     Seed ran_seed;
00405     QDP::RNG::savern(ran_seed);
00406 
00407     //
00408     // Read the source and solutions
00409     //
00410     StopWatch swatch;
00411     swatch.reset();
00412     swatch.start();
00413 
00414     multi1d<QuarkSourceSolutions_t>  quarks(params.named_obj.prop.op.size());
00415     QDPIO::cout << "num_quarks= " << params.named_obj.prop.op.size() << endl;
00416 
00417     try
00418     {
00419       QDPIO::cout << "quarks.size= " << quarks.size() << endl;
00420       for(int n=0; n < quarks.size(); ++n)
00421       {
00422         QDPIO::cout << "Attempt to read solutions for source number=" << n << endl;
00423         quarks[n].dilutions.resize(params.named_obj.prop.op[n].soln_files.size());
00424 
00425         QDPIO::cout << "dilutions.size= " << quarks[n].dilutions.size() << endl;
00426         for(int i=0; i < quarks[n].dilutions.size(); ++i)
00427         {
00428           XMLReader file_xml, record_xml;
00429 
00430           QDPIO::cout << "reading file= " << params.named_obj.prop.op[n].soln_files[i] << endl;
00431           QDPFileReader from(file_xml, params.named_obj.prop.op[n].soln_files[i], QDPIO_SERIAL);
00432           read(from, record_xml, quarks[n].dilutions[i].soln);
00433           close(from);
00434         
00435           read(record_xml, "/Propagator/PropSource", quarks[n].dilutions[i].source_header);
00436           read(record_xml, "/Propagator/ForwardProp", quarks[n].dilutions[i].prop_header);
00437         }
00438       }
00439     }
00440     catch (const string& e) 
00441     {
00442       QDPIO::cerr << "Error extracting headers: " << e << endl;
00443       QDP_abort(1);
00444     }
00445     swatch.stop();
00446 
00447     QDPIO::cout << "Sources and solutions successfully read: time= "
00448                 << swatch.getTimeInSeconds() 
00449                 << " secs" << endl;
00450 
00451 
00452 
00453     //
00454     // Check for each quark source that the solutions have their diluted
00455     // on every site only once
00456     //
00457     swatch.start();
00458 
00459     try
00460     {
00461       push(xml_out, "Norms");
00462       for(int n=0; n < quarks.size(); ++n)
00463       {
00464         bool first = true;
00465         int  N;
00466         LatticeFermion quark_noise;      // noisy source on entire lattice
00467 
00468         for(int i=0; i < quarks[n].dilutions.size(); ++i)
00469         {
00470           std::istringstream  xml_s(quarks[n].dilutions[i].source_header.source.xml);
00471           XMLReader  sourcetop(xml_s);
00472 //      QDPIO::cout << "Source = " << quarks[n].dilutions[i].source_header.source.id << endl;
00473 
00474           if (quarks[n].dilutions[i].source_header.source.id != DiluteZNQuarkSourceConstEnv::getName())
00475           {
00476             QDPIO::cerr << "Expected source_type = " << DiluteZNQuarkSourceConstEnv::getName() << endl;
00477             QDP_abort(1);
00478           }
00479 
00480           QDPIO::cout << "Quark num= " << n << "  dilution num= " << i << endl;
00481 
00482           // Manually create the params so I can peek into them and use the source constructor
00483           DiluteZNQuarkSourceConstEnv::Params  srcParams(sourcetop, 
00484                                                          quarks[n].dilutions[i].source_header.source.path);
00485           DiluteZNQuarkSourceConstEnv::SourceConst<LatticeFermion>  srcConst(srcParams);
00486       
00487           if (first) 
00488           {
00489             first = false;
00490 
00491             quarks[0].j_decay = srcParams.j_decay;
00492 
00493             // Grab N
00494             N = srcParams.N;
00495 
00496             // Set the seed to desired value
00497             quarks[n].seed = srcParams.ran_seed;
00498             QDP::RNG::setrn(quarks[n].seed);
00499 
00500             // Create the noisy quark source on the entire lattice
00501             zN_src(quark_noise, N);
00502           }
00503 
00504           // The seeds must always agree - here the seed is the unique id of the source
00505           if ( toBool(srcParams.ran_seed != quarks[n].seed) )
00506           {
00507             QDPIO::cerr << "quark source=" << n << "  dilution=" << i << " seed does not match" << endl;
00508             QDP_abort(1);
00509           }
00510 
00511           // The N's must always agree
00512           if ( toBool(srcParams.N != N) )
00513           {
00514             QDPIO::cerr << "quark source=" << n << "  dilution=" << i << " N does not match" << endl;
00515             QDP_abort(1);
00516           }
00517 
00518           // Use a trick here, create the source and subtract it from the global noisy
00519           // Check at the end that the global noisy is zero everywhere.
00520           // NOTE: the seed will be set every call
00521           quarks[n].dilutions[i].source = srcConst(u);
00522           quark_noise -= quarks[n].dilutions[i].source;
00523 
00524 #if 0
00525           // Diagnostic
00526           {
00527             // Keep a copy of the phases with NO momenta
00528             SftMom phases_nomom(0, true, quarks[n].dilutions[i].source_header.j_decay);
00529 
00530             multi1d<Double> source_corr = sumMulti(localNorm2(quarks[n].dilutions[i].source), 
00531                                                    phases_nomom.getSet());
00532 
00533             multi1d<Double> soln_corr = sumMulti(localNorm2(quarks[n].dilutions[i].soln), 
00534                                                  phases_nomom.getSet());
00535 
00536             push(xml_out, "elem");
00537             write(xml_out, "n", n);
00538             write(xml_out, "i", i);
00539             write(xml_out, "source_corr", source_corr);
00540             write(xml_out, "soln_corr", soln_corr);
00541             pop(xml_out);
00542           }
00543 #endif
00544         } // end for i
00545 
00546         Double dcnt = norm2(quark_noise);
00547         if (toDouble(dcnt) != 0.0)  // problematic - seems to work with unnormalized sources 
00548         {
00549           QDPIO::cerr << "Noise not saturated by all potential solutions: dcnt=" << dcnt << endl;
00550           QDP_abort(1);
00551         }
00552 
00553       } // end for n
00554 
00555       pop(xml_out);  // norms
00556     } // end try
00557     catch(const std::string& e) 
00558     {
00559       QDPIO::cerr << ": Caught Exception creating source: " << e << endl;
00560       QDP_abort(1);
00561     }
00562 
00563     swatch.stop();
00564 
00565     QDPIO::cout << "Sources saturated: time= "
00566                 << swatch.getTimeInSeconds() 
00567                 << " secs" << endl;
00568 
00569 
00570     //
00571     // Baryon operators
00572     //
00573     int j_decay = quarks[0].j_decay;
00574 
00575     // Initialize the slow Fourier transform phases
00576     SftMom phases(params.param.mom2_max, false, j_decay);
00577     
00578     // Length of lattice in decay direction
00579     int length = phases.numSubsets();
00580 
00581     if (quarks.size() != 3)
00582     {
00583       QDPIO::cerr << "expecting 3 quarks but have num quarks= " << quarks.size() << endl;
00584       QDP_abort(1);
00585     }
00586 
00587     //
00588     // Create the baryon operator object
00589     //
00590     std::istringstream  xml_op(params.param.baryon_operator);
00591     XMLReader  optop(xml_op);
00592     const string operator_path = "/BaryonOperator";
00593         
00594     Handle< BaryonOperator<LatticeFermion> >
00595       baryonOperator(TheWilsonBaryonOperatorFactory::Instance().createObject(params.param.baryon_operator_type,
00596                                                                              optop,
00597                                                                              operator_path,
00598                                                                              u));
00599 
00600     //
00601     // Permutations of quarks within an operator
00602     //
00603     int num_orderings = 6;   // number of permutations of the numbers  0,1,2
00604     multi1d< multi1d<int> >  perms(num_orderings);
00605     {
00606       multi1d<int> p(3);
00607 
00608       if (num_orderings >= 1)
00609       {
00610         p[0] = 0; p[1] = 1; p[2] = 2;
00611         perms[0] = p;
00612       }
00613 
00614       if (num_orderings >= 2)
00615       {
00616         p[0] = 0; p[1] = 2; p[2] = 1;
00617         perms[1] = p;
00618       }
00619 
00620       if (num_orderings >= 3)
00621       {
00622         p[0] = 1; p[1] = 0; p[2] = 2;
00623         perms[2] = p;
00624       }
00625 
00626       if (num_orderings >= 4)
00627       {
00628         p[0] = 1; p[1] = 2; p[2] = 0;
00629         perms[3] = p;
00630       }
00631 
00632       if (num_orderings >= 5)
00633       {
00634         p[0] = 2; p[1] = 1; p[2] = 0;
00635         perms[4] = p;
00636       }
00637  
00638       if (num_orderings >= 6)
00639       {
00640         p[0] = 2; p[1] = 0; p[2] = 1;
00641         perms[5] = p;
00642       }
00643     }
00644 
00645     // Operator A
00646     swatch.start();
00647     BaryonOperator_t  baryon_opA;
00648     baryon_opA.mom2_max    = params.param.mom2_max;
00649     baryon_opA.j_decay     = j_decay;
00650     baryon_opA.seed_l      = quarks[0].seed;
00651     baryon_opA.seed_m      = quarks[1].seed;
00652     baryon_opA.seed_r      = quarks[2].seed;
00653     baryon_opA.orderings.resize(num_orderings);
00654     baryon_opA.perms.resize(num_orderings);
00655 
00656     push(xml_out, "OperatorA");
00657 
00658     // Sanity check
00659     if ( toBool(baryon_opA.seed_l == baryon_opA.seed_m) )
00660     {
00661       QDPIO::cerr << "baryon op seeds are the same" << endl;
00662       QDP_abort(1);
00663     }
00664 
00665     // Sanity check
00666     if ( toBool(baryon_opA.seed_l == baryon_opA.seed_r) )
00667     {
00668       QDPIO::cerr << "baryon op seeds are the same" << endl;
00669       QDP_abort(1);
00670     }
00671 
00672     // Sanity check
00673     if ( toBool(baryon_opA.seed_m == baryon_opA.seed_r) )
00674     {
00675       QDPIO::cerr << "baryon op seeds are the same" << endl;
00676       QDP_abort(1);
00677     }
00678 
00679 
00680     // Construct operator A
00681     try
00682     {
00683       for(int ord=0; ord < baryon_opA.orderings.size(); ++ord)
00684       {
00685         QDPIO::cout << "Operator A: ordering = " << ord << endl;
00686 
00687         baryon_opA.perms[ord] = perms[ord];
00688       
00689         // Operator construction
00690         const QuarkSourceSolutions_t& q0 = quarks[perms[ord][0]];
00691         const QuarkSourceSolutions_t& q1 = quarks[perms[ord][1]];
00692         const QuarkSourceSolutions_t& q2 = quarks[perms[ord][2]];
00693 
00694         baryon_opA.orderings[ord].op.resize(q0.dilutions.size(),
00695                                             q1.dilutions.size(),
00696                                             q2.dilutions.size());
00697 
00698         
00699         for(int i=0; i < q0.dilutions.size(); ++i)
00700         {
00701           for(int j=0; j < q1.dilutions.size(); ++j)
00702           {
00703             for(int k=0; k < q2.dilutions.size(); ++k)
00704             {
00705               multi1d<LatticeComplex> bar = (*baryonOperator)(q0.dilutions[i].source,
00706                                                               q1.dilutions[j].source,
00707                                                               q2.dilutions[k].source,
00708                                                               MINUS);
00709 
00710               baryon_opA.orderings[ord].op(i,j,k).ind.resize(bar.size());
00711               for(int l=0; l < bar.size(); ++l)
00712                 baryon_opA.orderings[ord].op(i,j,k).ind[l].elem = phases.sft(bar[l]);
00713               
00714             } // end for k
00715           } // end for j
00716         } // end for i
00717       } // end for ord
00718     } // end try
00719     catch(const std::string& e) 
00720     {
00721       QDPIO::cerr << ": Caught Exception creating source operator: " << e << endl;
00722       QDP_abort(1);
00723     }
00724     catch(...)
00725     {
00726       QDPIO::cerr << ": Caught generic exception creating source operator" << endl;
00727       QDP_abort(1);
00728     }
00729 
00730     pop(xml_out); // OperatorA
00731 
00732     swatch.stop();
00733 
00734     QDPIO::cout << "Operator A computed: time= "
00735                 << swatch.getTimeInSeconds() 
00736                 << " secs" << endl;
00737 
00738 
00739     // Operator B
00740     swatch.start();
00741     BaryonOperator_t  baryon_opB;
00742     baryon_opB.mom2_max    = params.param.mom2_max;
00743     baryon_opB.j_decay     = j_decay;
00744     baryon_opB.seed_l      = quarks[0].seed;
00745     baryon_opB.seed_m      = quarks[1].seed;
00746     baryon_opB.seed_r      = quarks[2].seed;
00747     baryon_opB.orderings.resize(num_orderings);
00748     baryon_opB.perms.resize(num_orderings);
00749 
00750     push(xml_out, "OperatorB");
00751 
00752     // Sanity check
00753     if ( toBool(baryon_opB.seed_l == baryon_opB.seed_m) )
00754     {
00755       QDPIO::cerr << "baryon op seeds are the same" << endl;
00756       QDP_abort(1);
00757     }
00758 
00759     // Sanity check
00760     if ( toBool(baryon_opB.seed_l == baryon_opB.seed_r) )
00761     {
00762       QDPIO::cerr << "baryon op seeds are the same" << endl;
00763       QDP_abort(1);
00764     }
00765 
00766     // Sanity check
00767     if ( toBool(baryon_opB.seed_m == baryon_opB.seed_r) )
00768     {
00769       QDPIO::cerr << "baryon op seeds are the same" << endl;
00770       QDP_abort(1);
00771     }
00772 
00773 
00774     // Construct operator B
00775     try
00776     {
00777       for(int ord=0; ord < baryon_opB.orderings.size(); ++ord)
00778       {
00779         QDPIO::cout << "Operator B: ordering = " << ord << endl;
00780 
00781         baryon_opB.perms[ord] = perms[ord];
00782       
00783         // Operator construction
00784         const QuarkSourceSolutions_t& q0 = quarks[perms[ord][0]];
00785         const QuarkSourceSolutions_t& q1 = quarks[perms[ord][1]];
00786         const QuarkSourceSolutions_t& q2 = quarks[perms[ord][2]];
00787 
00788         baryon_opB.orderings[ord].op.resize(q0.dilutions.size(),
00789                                             q1.dilutions.size(),
00790                                             q2.dilutions.size());
00791         
00792         for(int i=0; i < q0.dilutions.size(); ++i)
00793         {
00794           for(int j=0; j < q1.dilutions.size(); ++j)
00795           {
00796             for(int k=0; k < q2.dilutions.size(); ++k)
00797             {
00798               multi1d<LatticeComplex> bar = (*baryonOperator)(q0.dilutions[i].soln,
00799                                                               q1.dilutions[j].soln,
00800                                                               q2.dilutions[k].soln,
00801                                                               PLUS);
00802 
00803               baryon_opB.orderings[ord].op(i,j,k).ind.resize(bar.size());
00804               for(int l=0; l < bar.size(); ++l)
00805                 baryon_opB.orderings[ord].op(i,j,k).ind[l].elem = phases.sft(bar[l]);
00806 
00807             } // end for k
00808           } // end for j
00809         } // end for i
00810       } // end for ord
00811     } // end try
00812     catch(const std::string& e) 
00813     {
00814       QDPIO::cerr << ": Caught Exception creating sink operator: " << e << endl;
00815       QDP_abort(1);
00816     }
00817     catch(...)
00818     {
00819       QDPIO::cerr << ": Caught generic exception creating sink operator" << endl;
00820       QDP_abort(1);
00821     }
00822 
00823     pop(xml_out); // OperatorB
00824 
00825     swatch.stop();
00826 
00827     QDPIO::cout << "Operator B computed: time= "
00828                 << swatch.getTimeInSeconds() 
00829                 << " secs" << endl;
00830 
00831 
00832     // Save the operators
00833     // ONLY SciDAC output format is supported!
00834     swatch.start();
00835     {
00836       XMLBufferWriter file_xml;
00837       push(file_xml, "baryon_operator");
00838       file_xml << params.param.baryon_operator;
00839       write(file_xml, "Config_info", gauge_xml);
00840       pop(file_xml);
00841 
00842       QDPFileWriter to(file_xml, params.named_obj.prop.op_file, 
00843                        QDPIO_SINGLEFILE, QDPIO_SERIAL, QDPIO_OPEN);
00844 
00845       // Write the scalar data
00846       {
00847         XMLBufferWriter record_xml;
00848         BinaryBufferWriter  record_bin;
00849         write(record_xml, "SourceBaryonOperator", baryon_opA);
00850         write(record_bin, baryon_opA);
00851         write(to, record_xml, record_bin);
00852       }
00853 
00854       // Write the scalar data
00855       {
00856         XMLBufferWriter record_xml;
00857         BinaryBufferWriter  record_bin;
00858         write(record_xml, "SinkBaryonOperator", baryon_opB);
00859         write(record_bin, baryon_opB);
00860         write(to, record_xml, record_bin);
00861       }
00862 
00863       close(to);
00864     }
00865 
00866     swatch.stop();
00867 
00868     QDPIO::cout << "Operators written: time= "
00869                 << swatch.getTimeInSeconds() 
00870                 << " secs" << endl;
00871 
00872     // Close the namelist output file XMLDAT
00873     pop(xml_out);     // StochBaryon
00874 
00875     snoop.stop();
00876     QDPIO::cout << InlineStochBaryonEnv::name << ": total time = "
00877                 << snoop.getTimeInSeconds() 
00878                 << " secs" << endl;
00879 
00880     QDPIO::cout << InlineStochBaryonEnv::name << ": ran successfully" << endl;
00881 
00882     END_CODE();
00883   } 
00884 
00885 }

Generated on Sun Nov 22 04:33:12 2009 for CHROMA by  doxygen 1.4.7