inline_stoch_hadron_w.cc

Go to the documentation of this file.
00001 // $Id: inline_stoch_hadron_w.cc,v 1.24 2009/03/19 17:12:20 mcneile Exp $
00002 /*! \file
00003  * \brief Inline measurement of stochastic hadron operator (mesons and baryons).
00004  *
00005  */
00006 
00007 
00008 #include "handle.h"
00009 #include "meas/inline/hadron/inline_stoch_hadron_w.h"
00010 #include "meas/inline/abs_inline_measurement_factory.h"
00011 #include "meas/smear/quark_smearing_factory.h"
00012 #include "meas/smear/quark_smearing_aggregate.h"
00013 #include "meas/smear/displacement.h"
00014 #include "meas/sources/source_smearing_aggregate.h"
00015 #include "meas/sources/source_smearing_factory.h"
00016 #include "meas/sources/dilutezN_source_const.h"
00017 #include "meas/sources/zN_src.h"
00018 #include "meas/sinks/sink_smearing_aggregate.h"
00019 #include "meas/sinks/sink_smearing_factory.h"
00020 #include "meas/hadron/barspinmat_w.h"
00021 #include "meas/hadron/baryon_operator_aggregate_w.h"
00022 #include "meas/hadron/baryon_operator_factory_w.h"
00023 #include "meas/hadron/dilution_scheme_aggregate.h"
00024 #include "meas/hadron/dilution_scheme_factory.h"
00025 #include "meas/glue/mesplq.h"
00026 #include "util/ft/sftmom.h"
00027 #include "util/info/proginfo.h"
00028 #include "meas/inline/make_xml_file.h"
00029 
00030 #include "meas/inline/io/named_objmap.h"
00031 
00032 #include "util/ferm/key_val_db.h"
00033 
00034 namespace Chroma{ 
00035   namespace InlineStochHadronEnv{ 
00036     enum HadronType {MESON_SRC_SRC, MESON_SOL_SOL,MESON_SRC_SOL,BARYON_SRC, BARYON_SOL} ;
00037 
00038     namespace{
00039       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00040                                               const std::string& path) 
00041       {
00042         return new InlineMeas(Params(xml_in, path));
00043       }
00044 
00045       //! Local registration flag
00046       bool registered = false;
00047     }
00048 
00049     const std::string name = "STOCH_HADRON";
00050 
00051     //! Register all the factories
00052     bool registerAll() 
00053     {
00054       bool success = true; 
00055       if (! registered)
00056       {
00057         success &= BaryonOperatorEnv::registerAll();
00058         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00059         registered = true;
00060       }
00061       return success;
00062     }
00063   
00064   // Reader for input parameters
00065     void read(XMLReader& xml, const string& path, Params::Param_t& param){
00066       XMLReader paramtop(xml, path);
00067       
00068       int version;
00069       read(paramtop, "version", version);
00070       
00071       switch (version) 
00072         {
00073         case 1:
00074           /************************************************************/
00075           read(paramtop, "mom2_max", param.mom2_max);
00076           
00077           param.smearing = readXMLGroup(paramtop, "Smearing", "wvf_kind");
00078           param.displace = readXMLArrayGroup(paramtop, "Displacement","DisplacementType");
00079           param.link_smear = readXMLGroup(paramtop, "LinkSmearing", "LinkSmearingType");
00080 
00081           param.ops = readXMLArrayGroup(paramtop, "HadronOperators", "Type");
00082           param.quarks = readXMLArrayGroup(paramtop, "Quarks", "DilutionType");
00083           
00084           break;
00085           
00086         default :
00087           /**************************************************************/
00088 
00089           QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00090           QDP_abort(1);
00091         }
00092       
00093       
00094     }
00095 
00096 
00097   // Writter for input parameters
00098     void write(XMLWriter& xml, const string& path, const Params::Param_t& param){
00099       push(xml, path);
00100       
00101       int version = 1;
00102       
00103       write(xml, "version", version);
00104       write(xml, "mom2_max", param.mom2_max);
00105       xml << param.link_smear.xml;
00106       
00107       push(xml,"Smearing");
00108       xml<<param.smearing.xml;
00109       pop(xml);
00110       
00111       push(xml,"Displacement");
00112       for( int t(0);t<param.displace.size();t++){
00113         push(xml,"elem");
00114         xml<<param.displace[t].xml;
00115         pop(xml);
00116       }
00117       pop(xml);
00118       
00119       push(xml,"Quarks");
00120       for( int t(0);t<param.quarks.size();t++){
00121         push(xml,"elem");
00122         xml<<param.quarks[t].xml;
00123         pop(xml);
00124       }
00125       pop(xml);
00126       
00127       push(xml,"HadronOperators");
00128       for( int t(0);t<param.ops.size();t++){
00129         push(xml,"elem");
00130         xml<<param.ops[t].xml;
00131         pop(xml);
00132       }
00133       pop(xml);
00134       
00135       
00136       pop(xml);
00137     }
00138 
00139 
00140     //! Gauge field parameters
00141     void read(XMLReader& xml, const string& path, Params::NamedObject_t& input)
00142     {
00143       XMLReader inputtop(xml, path);
00144       
00145       read(inputtop, "gauge_id", input.gauge_id);
00146       //read(inputtop, "meson_DB_file", input.meson_db);
00147       //read(inputtop, "baryon_DB_file", input.baryon_db);
00148     }
00149     
00150     //! Gauge field parameters
00151     void write(XMLWriter& xml, const string& path, const Params::NamedObject_t& input){
00152       push(xml, path);
00153       write(xml, "gauge_id", input.gauge_id);
00154       //write(xml, "meson_DB_file", input.meson_db);
00155       //write(xml, "baryon_DB_file", input.baryon_db);
00156       pop(xml);
00157     }
00158     
00159     
00160     // Param stuff
00161     Params::Params(){ 
00162       frequency = 0;
00163       param.mom2_max = 0 ;
00164     }
00165 
00166     Params::Params(XMLReader& xml_in, const std::string& path) 
00167     {
00168       try 
00169         {
00170           XMLReader paramtop(xml_in, path);
00171           
00172           if (paramtop.count("Frequency") == 1)
00173             read(paramtop, "Frequency", frequency);
00174           else
00175             frequency = 1;
00176           
00177           // Read program parameters
00178           read(paramtop, "Param", param);
00179           
00180           // Read in the output propagator/source configuration info
00181           read(paramtop, "NamedObject", named_obj);
00182           
00183           // Possible alternate XML file pattern
00184           if (paramtop.count("xml_file") != 0) 
00185             {
00186               read(paramtop, "xml_file", xml_file);
00187             }
00188         }
00189       catch(const std::string& e) 
00190         {
00191           QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00192           QDP_abort(1);
00193         }
00194     }
00195 
00196 
00197     void Params::write(XMLWriter& xml_out, const std::string& path) 
00198     {
00199       push(xml_out, path);
00200       
00201       // Parameters for source construction
00202       InlineStochHadronEnv::write(xml_out, "Param", param);
00203       
00204       // Write out the output propagator/source configuration info
00205       InlineStochHadronEnv::write(xml_out, "NamedObject", named_obj);
00206 
00207       pop(xml_out);
00208     }
00209 
00210 
00211     void ParseMeson(MesonOp& m, const GroupXML_t& grpXML){
00212       QDPIO::cout<<"I am a meson!\n" ;
00213       std::istringstream  xml_l(grpXML.xml);
00214       XMLReader xmltop(xml_l);
00215       XMLReader xml(xmltop,"/elem");
00216       QDPIO::cout << "Meson state is = " <<grpXML.id ; 
00217       QDPIO::cout << endl;
00218       QDPIO::cout << " XML =" <<grpXML.xml ; 
00219       QDPIO::cout << endl;
00220       read(xml,"Gamma",m.g);
00221       read(xml,"File",m.file);
00222     }
00223 
00224     void ParseBaryon(BaryonOp& m, const GroupXML_t& grpXML){
00225       QDPIO::cout<<"I am a Baryon!\n" ;
00226       std::istringstream  xml_l(grpXML.xml);
00227       XMLReader  xmltop(xml_l);
00228       XMLReader xml(xmltop,"/elem");
00229       QDPIO::cout << "Baryon state is = " <<grpXML.id ; 
00230       QDPIO::cout << endl;
00231       QDPIO::cout << " XML =" <<grpXML.xml ; 
00232       QDPIO::cout << endl;
00233       read(xml,"Gamma",m.g);
00234       read(xml,"File",m.file);
00235     }
00236 
00237     void meson(DComplex& corr,
00238                const int& g,
00239                const LatticeComplex& phase,
00240                const LatticeFermion& eta,
00241                const LatticeFermion& chi,
00242                const Subset& s){
00243       corr = sum(localInnerProduct(eta,Gamma(g)*chi)*phase,s) ;
00244     }
00245 
00246     
00247     void baryon(multi1d<DComplex>& d,
00248                 const int& g,
00249                 const LatticeComplex& phase,
00250                 const LatticeFermion& eta1,
00251                 const LatticeFermion& eta2,
00252                 const LatticeFermion& eta3,
00253                 const Subset& s){
00254       //QDPIO::cout<<"I am a baryon!\n" ;
00255       if ( Nc != 3 ){    /* Code is specific to Ns=4 and Nc=3. */
00256         QDPIO::cerr<<"baryon code only works for Nc=3 and Ns=4\n";
00257         QDP_abort(111) ;
00258       }
00259 #if QDP_NC == 3
00260 
00261       START_CODE();
00262 
00263       d.resize(Ns) ;
00264 
00265       d = zero;
00266 
00267       // C gamma_5 = Gamma(5)
00268       SpinMatrix g_one = 1.0 ;
00269       SpinMatrix Cg5 = Gamma(g)*g_one ; //BaryonSpinMats::Cg5();
00270 
00271       for(int k=0; k < Ns; ++k)
00272         {
00273           LatticeSpinMatrix di_quark = zero;
00274 
00275           for(int j=0; j < Ns; ++j)
00276             {
00277               for(int i=0; i < Ns; ++i)
00278                 {
00279                   // Contract over color indices with antisym tensors
00280                   LatticeComplex b_oper = colorContract(peekSpin(eta1, i),
00281                                                         peekSpin(eta2, j),
00282                                                         peekSpin(eta3, k));
00283 
00284                   pokeSpin(di_quark, b_oper, j, i);
00285                 }
00286             }
00287 
00288           d[k] += sum(traceSpin(Cg5 * di_quark)*phase,s);
00289         }
00290 
00291       END_CODE();
00292 #endif
00293     }
00294 
00295     class Key{
00296     public:
00297       multi1d<int> k;
00298 
00299       Key& set(int i,int j, int l,int s){
00300         k.resize(4);
00301         k[0]=i ; k[1]=j ; k[2]=l ; k[3]=s;
00302         return *this ;
00303       }
00304 
00305       Key& set(int i,int j, int l){
00306         k.resize(3);
00307         k[0]=i ; k[1]=j ; k[2]=l ;
00308         return *this ;
00309       }
00310 
00311       Key& set(int i,int j){
00312         k.resize(2);
00313         k[0]=i ; k[1]=j ; 
00314         return *this ;
00315       }
00316 
00317       Key(){
00318         k.resize(1);
00319         k[0]=0;
00320       }
00321       Key(int i,int j, int l){
00322         set(i,j,l);
00323       }
00324       Key(int i,int j, int l,int s){
00325         set(i,j,l,s);
00326       }
00327       Key(int i,int j){
00328         set(i,j);
00329       }
00330       
00331       Key(const Key& klidi){
00332         k.resize(klidi.k.size()) ;
00333         for(int i(0);i<k.size();i++) k[i] = klidi.k[i] ;
00334       }
00335       //     int operator[](const int i){return k[i];} const 
00336       
00337       ~Key(){} ;
00338     };
00339 
00340     
00341     bool operator<(const Key& a, const Key& b){
00342       return (a.k<b.k) ;
00343     }
00344     //! Key binary writer
00345     void write(BinaryWriter& bin, const Key& klidi){
00346       write(bin, klidi.k);
00347     }
00348 
00349     //! Key binary reader
00350     void read(BinaryReader& bin, Key& klidi){
00351       read(bin, klidi.k);
00352     }
00353 
00354 
00355     struct HadronKey{
00356       // for the moment ignore displacements
00357       int type ; // creation: 0 or anihilation: 1
00358       int t    ; // time slice 
00359       int t0   ; // source time slice
00360       //if size of qn is 3 then it's a baryon if it is 2 then it's a meson
00361       multi1d<int> qn ; // the quark noise id 
00362       multi1d<int> p ;
00363       int gamma ; // the meson gamma matrix or the diquark baryon gamma matrix
00364     } ;
00365 
00366     //! HadronKey binary writer
00367     void write(BinaryWriter& bin, const HadronKey& h){
00368       write(bin, h.type);
00369       write(bin, h.t);
00370       write(bin, h.t0);
00371       write(bin, h.qn);
00372       write(bin, h.p);
00373       write(bin, h.gamma);
00374     }
00375 
00376     //! HadronKey binary reader
00377     void read(BinaryReader& bin, HadronKey& h){
00378       read(bin, h.type);
00379       read(bin, h.t);
00380       read(bin, h.t0);
00381       read(bin, h.qn);
00382       read(bin, h.p);
00383       read(bin, h.gamma);
00384     }
00385 
00386     /*
00387       intented use: 
00388       HadronOperator foo ;
00389       foo.data(Key(1,2)) ; // should return the 1,2 dilution of a meson
00390       foo.data(Key(1,2,3,s); for baryons where s is the spin index... 
00391      */
00392     struct HadronOperator{
00393       map<Key,DComplex> data ; // the Key has size 4 for a baryon of 2 for a hadron
00394     } ;
00395     
00396      //! HadronKey binary writer
00397     void write(BinaryWriter& bin, HadronOperator& h){
00398       map<Key,DComplex>::iterator it;
00399       int count(0);
00400       for(it=h.data.begin();it!=h.data.end();it++){
00401         count++;
00402       }
00403       write(bin,count);
00404       for(it=h.data.begin();it!=h.data.end();it++){
00405         write(bin, it->first);
00406         write(bin, it->second);
00407       }
00408     }
00409 
00410     //! HadronKey binary reader
00411     void read(BinaryReader& bin, HadronOperator& h){
00412       int count ;
00413       read(bin,count);
00414       Key k ;
00415       for(int i(0);i<count;i++){
00416         read(bin, k);
00417         read(bin, h.data[k]);
00418       }
00419     }
00420 
00421     class MesonOpData{
00422     public:
00423       multi2d<DComplex> data ;
00424       MesonOpData(){}
00425       MesonOpData(int n ){
00426         data.resize(n,n) ;
00427       }
00428       void resize(int n){
00429         data.resize(n,n);
00430       }
00431     } ;
00432     class BaryonOpData{
00433     public:
00434       multi3d< multi1d<DComplex> > data ;
00435       BaryonOpData(){}
00436       BaryonOpData(int n ){
00437         data.resize(n,n,n) ;
00438       }
00439       void resize(int n){
00440         data.resize(n,n,n);
00441       } 
00442     } ;
00443 
00444 
00445     //! MesonOp reader
00446     void read(BinaryReader& bin, MesonOpData& param)
00447     {
00448       int n;
00449       read(bin, n);  
00450       param.data.resize(n,n);
00451   
00452       for(int i=0; i < n; ++i)
00453       {
00454         for(int j=0; j < n; ++j)
00455         {
00456           read(bin, param.data(i,j));
00457         }
00458       }
00459     }
00460 
00461     //! MesonOp write
00462     void write(BinaryWriter& bin, const MesonOpData& param)
00463     {
00464       int n = param.data.size1();  // all sizes the same
00465       write(bin, n);
00466       for(int i=0; i < n; ++i)
00467       {
00468         for(int j=0; j < n; ++j)
00469         {
00470           write(bin, param.data(i,j));
00471         }
00472       }
00473     }
00474 
00475 
00476 
00477     //! BaryonOp reader
00478     void read(BinaryReader& bin, BaryonOpData& param)
00479     {
00480       int n;
00481       read(bin, n);  
00482       param.data.resize(n,n,n);
00483   
00484       for(int i=0; i < n; ++i)
00485       {
00486         for(int j=0; j < n; ++j)
00487         {
00488           for(int k=0; k < n; ++k)
00489             {
00490               read(bin, param.data(i,j,k));
00491             }
00492         }
00493       }
00494     }
00495 
00496     //! BaryonOp write
00497     void write(BinaryWriter& bin, const BaryonOpData& param)
00498     {
00499       int n = param.data.size1();  // all sizes the same
00500       write(bin, n);
00501       for(int i=0; i < n; ++i)
00502       {
00503         for(int j=0; j < n; ++j)
00504         {
00505           for(int k=0; k < n; ++k)
00506             {
00507               write(bin, param.data(i,j,k));
00508             }
00509         }
00510       }
00511     }
00512 
00513 
00514   //--------------------------------------------------------------
00515   // Function call
00516   //  void 
00517   //InlineStochHadron::operator()(unsigned long update_no,
00518   //                            XMLWriter& xml_out) 
00519     void InlineMeas::operator()(unsigned long update_no,
00520                                 XMLWriter& xml_out) 
00521     {
00522       // If xml file not empty, then use alternate
00523       if (params.xml_file != ""){
00524         string xml_file = makeXMLFileName(params.xml_file, update_no);
00525         
00526         push(xml_out, "stoch_hadron");
00527         write(xml_out, "update_no", update_no);
00528         write(xml_out, "xml_file", xml_file);
00529         pop(xml_out);
00530         
00531         XMLFileWriter xml(xml_file);
00532         func(update_no, xml);
00533       }
00534       else{
00535         func(update_no, xml_out);
00536       }
00537     }
00538     
00539     
00540     // Function call
00541     //void 
00542     //InlineStochHadron::func(unsigned long update_no,
00543     //                    XMLWriter& xml_out) 
00544     void InlineMeas::func(unsigned long update_no,
00545                           XMLWriter& xml_out) 
00546     {
00547       START_CODE();
00548       
00549       StopWatch snoop;
00550       snoop.reset();
00551       snoop.start();
00552       
00553       XMLBufferWriter UserData_xml;
00554 
00555       push(UserData_xml, "StochHadron");
00556       proginfo(UserData_xml);
00557 
00558       // Test and grab a reference to the gauge field
00559       XMLBufferWriter gauge_xml;
00560       try
00561         {
00562           TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00563           TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00564         }
00565       catch( std::bad_cast ) 
00566         {
00567           QDPIO::cerr << InlineStochHadronEnv::name << ": caught dynamic cast error" 
00568                       << endl;
00569           QDP_abort(1);
00570         }
00571       catch (const string& e) 
00572         {
00573           QDPIO::cerr << name << ": map call failed: " << e 
00574                       << endl;
00575           QDP_abort(1);
00576         }
00577       const multi1d<LatticeColorMatrix>& u = 
00578         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00579       
00580       push(xml_out, "stoch_hadron");
00581       write(xml_out, "update_no", update_no);
00582     
00583 
00584       QDPIO::cout << name << ": Stochastic Hadron Operator" << endl;
00585       
00586       proginfo(xml_out);    // Print out basic program info
00587       
00588       // Write out the input
00589       params.write(xml_out, "Input");
00590       params.write(UserData_xml, "Input");
00591 
00592       // Write out the config info
00593       write(xml_out, "Config_info", gauge_xml);
00594       write(UserData_xml,"Config_info",gauge_xml);
00595       
00596       push(xml_out, "Output_version");
00597       write(xml_out, "out_version", 1);
00598       pop(xml_out);
00599       
00600       // First calculate some gauge invariant observables just for info.
00601       // This is really cheap.
00602       MesPlq(xml_out, "Observables", u);
00603       
00604       // Save current seed
00605       Seed ran_seed;
00606       QDP::RNG::savern(ran_seed);
00607       
00608       //
00609       // Read the source and solutions
00610       //
00611       StopWatch swatch;
00612       swatch.reset();
00613       swatch.start();
00614       
00615       int N_quarks = params.param.quarks.size() ;
00616       int NumBarOrd(N_quarks*(N_quarks-1)*(N_quarks-2)) ;
00617       int NumMesOrd(N_quarks*N_quarks) ; // to allow for flavor singlets
00618       if(N_quarks<2){
00619         QDPIO::cout << name << ": Need at least 2" << endl;
00620         QDP_abort(1);
00621       }
00622       bool BuildMesons(NumMesOrd>0);
00623       if(BuildMesons){
00624         QDPIO::cout << name << ": Can build mesons" << endl;
00625         QDPIO::cout<<name<< ": Number of meson orderings: "<<NumMesOrd<<endl;
00626       }
00627       else
00628         NumMesOrd=0;
00629 
00630       bool BuildBaryons(NumBarOrd>0);
00631       if(BuildBaryons){
00632         QDPIO::cout << name << ": Can build baryons" << endl;
00633         QDPIO::cout<<name<< ": Number of baryon orderings: "<<NumBarOrd<<endl;
00634       }
00635       else
00636         NumBarOrd=0;
00637       
00638       multi1d< Handle< DilutionScheme<LatticeFermion> > > quarks(N_quarks); 
00639       
00640       try{
00641         // Loop over quark dilutions
00642         for(int n(0); n < params.param.quarks.size(); ++n){
00643           const GroupXML_t& dil_xml = params.param.quarks[n];
00644           std::istringstream  xml_d(dil_xml.xml);
00645           XMLReader  diltop(xml_d);
00646           QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
00647           quarks[n] = 
00648             TheFermDilutionSchemeFactory::Instance().createObject(dil_xml.id, 
00649                                                                   diltop, 
00650                                                                   dil_xml.path);
00651         }
00652       }
00653       catch(const std::string& e){
00654         QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
00655         QDP_abort(1);
00656       }
00657       
00658       
00659       //-------------------------------------------------------------------
00660       //Sanity checks   
00661 
00662       //The participating timeslices must match for each quark
00663       //grab info from first quark to prime the work
00664       
00665       multi1d<int> participating_timeslices(quarks[0]->getNumTimeSlices());
00666       
00667       for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0){
00668         participating_timeslices[t0] = quarks[0]->getT0(t0);
00669       }
00670       
00671       for (int n = 1 ; n < N_quarks ; ++n){
00672         if(quarks[n]->getNumTimeSlices() != participating_timeslices.size()){
00673           QDPIO::cerr << name ;
00674           QDPIO::cerr << " : Quarks do not contain the same number";
00675           QDPIO::cerr << "of dilution timeslices: Quark " << n << endl; 
00676           QDP_abort(1);
00677         }
00678         
00679         for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0){
00680           if(quarks[n]->getT0(t0) != participating_timeslices[t0]){
00681             QDPIO::cerr << name << " : Quarks do not contain the same";
00682             QDPIO::cerr << "participating timeslices: Quark ";
00683             QDPIO::cerr << n << " timeslice "<< t0 << endl;
00684             QDP_abort(1);
00685           }
00686         }
00687       }
00688                 
00689       //Another Sanity check, the three quarks must all be 
00690       //inverted on the same cfg
00691       for (int n = 1 ; n < N_quarks ; ++n){
00692         if (quarks[0]->getCfgInfo() != quarks[n]->getCfgInfo()){
00693           QDPIO::cerr << name << " : Quarks do not contain the same cfg info";
00694           QDPIO::cerr << ", quark "<< n << endl;
00695           QDP_abort(1);
00696         }               
00697       }
00698 
00699       //Also ensure that the cfg on which the inversions were performed 
00700       //is the same as the cfg that we are using
00701       { 
00702         std::string cfgInfo; 
00703         
00704         //Really ugly way of doing this(Robert Heeeelp!!)
00705         XMLBufferWriter top;
00706         write(top, "Config_info", gauge_xml);
00707         XMLReader from(top);
00708         XMLReader from2(from, "/Config_info");
00709         std::ostringstream os;
00710         from2.print(os);
00711         
00712         cfgInfo = os.str();
00713         
00714         if (cfgInfo != quarks[0]->getCfgInfo()){
00715           QDPIO::cerr << name << " : Quarks do not contain the same";
00716           QDPIO::cerr << " cfg info as the gauge field." ;
00717           QDPIO::cerr << "gauge: XX"<<cfgInfo<<"XX quarks: XX" ;
00718           QDPIO::cerr << quarks[0]->getCfgInfo()<<"XX"<<  endl;
00719           QDP_abort(1);
00720         }
00721       }
00722 
00723       //
00724       // Initialize the slow Fourier transform phases
00725       //
00726       int decay_dir = quarks[0]->getDecayDir();
00727       
00728       SftMom phases(params.param.mom2_max, false, decay_dir);
00729       
00730       // Sanity check - if this doesn't work we have serious problems
00731       if (phases.numSubsets() != QDP::Layout::lattSize()[decay_dir]){
00732         QDPIO::cerr << name << ": number of time slices not equal to that";
00733         QDPIO::cerr << " in the decay direction: " 
00734                     << QDP::Layout::lattSize()[decay_dir]
00735                     << endl;
00736         QDP_abort(1);
00737       }
00738 
00739       write(UserData_xml,"decay_dir",decay_dir);
00740       push(UserData_xml,"Quarks");
00741       for(int k(0);k<quarks.size();k++){
00742         push(UserData_xml,"elem");
00743         //write(UserData_xml,"Seed",quarks[0]->getSeed());
00744         UserData_xml<<quarks[k]->getSeed();
00745         pop(UserData_xml);
00746       }
00747       pop(UserData_xml);
00748       // Another sanity check. The seeds of all the quarks must be different
00749       // and thier decay directions must be the same 
00750       for(int n = 1 ; n < quarks.size(); ++n){
00751         if(toBool(quarks[n]->getSeed()==quarks[0]->getSeed())){
00752           QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
00753           QDP_abort(1);
00754         }
00755 
00756         if(toBool(quarks[n]->getDecayDir()!=quarks[0]->getDecayDir())){
00757           QDPIO::cerr<<name<< ": error, quark decay dirs do not match" <<endl;
00758           QDP_abort(1);
00759         }
00760       }
00761       
00762       // Smear the gauge field if needed
00763       //
00764       multi1d<LatticeColorMatrix> u_smr = u;
00765 
00766       try{
00767         std::istringstream  xml_l(params.param.link_smear.xml);
00768         XMLReader  linktop(xml_l);
00769         QDPIO::cout << "Link smearing type = " << params.param.link_smear.id ; 
00770         QDPIO::cout << endl;
00771         
00772         
00773         Handle<LinkSmearing> linkSmearing(TheLinkSmearingFactory::Instance().createObject(params.param.link_smear.id, linktop, params.param.link_smear.path));
00774 
00775         (*linkSmearing)(u_smr);
00776       }
00777       catch(const std::string& e){
00778         QDPIO::cerr<<name<<": Caught Exception link smearing: " << e << endl;
00779         QDP_abort(1);
00780       }
00781 
00782       MesPlq(xml_out, "Smeared_Observables", u_smr);
00783 
00784       // Parse the Hadron operators
00785       map<string, MesonOp> LocalMesonOps ;
00786       map<string, BaryonOp> LocalBaryonOps ;
00787       for(int o(0);o<params.param.ops.size();o++){
00788         QDPIO::cout<<"Found Hadron: "<<params.param.ops[o].id<<endl ;
00789         map<string, void (*)(MesonOp&,const GroupXML_t& )>::iterator 
00790           iter=mesons.find(params.param.ops[o].id);
00791         if(iter != mesons.end()){
00792           iter->second(LocalMesonOps[params.param.ops[o].id],
00793                        params.param.ops[o]);
00794         }
00795         else{// Maybe it's a baryon
00796           map<string, void (*)(BaryonOp&, const GroupXML_t&)>::iterator 
00797             it=baryons.find(params.param.ops[o].id);
00798           if(it != baryons.end())
00799             it->second(LocalBaryonOps[params.param.ops[o].id],
00800                           params.param.ops[o]);
00801           
00802           else{
00803             QDPIO::cout<<" Operator: "<<params.param.ops[o].id ;
00804             QDPIO::cout<<" is unkown " <<endl ;
00805           }
00806         }
00807       }
00808 
00809       //We only do diagonal one smearing smearing
00810       // I could read off the smearing from the source header so that
00811       // it is guaranteed to be the same as the one in the source...
00812       // set up the smearing and then do it
00813       Handle< QuarkSmearing<LatticeFermion> >  Smearing ;
00814       try{
00815         std::istringstream  xml_l(params.param.smearing.xml);
00816         XMLReader  smrtop(xml_l);
00817         QDPIO::cout << "Quark smearing type = " <<params.param.smearing.id ; 
00818           QDPIO::cout << endl;
00819           
00820           Smearing = TheFermSmearingFactory::Instance().createObject(params.param.smearing.id, smrtop, params.param.smearing.path);
00821       }
00822       catch(const std::string& e){
00823         QDPIO::cerr <<name<< ": Caught Exception creating quark smearing object: " << e << endl;
00824         QDP_abort(1);
00825       }
00826       catch(...){
00827         QDPIO::cerr <<name<< ": Caught generic exception creating smearing object" << endl;
00828         QDP_abort(1);
00829       }
00830 
00831       multi1d< multi1d< multi1d<LatticeFermion> > > smearedSol(quarks.size());
00832       multi1d< multi1d< multi1d<LatticeFermion> > > src(quarks.size());
00833       for(int q(0);q< quarks.size() ;q++){
00834         smearedSol[q].resize(participating_timeslices.size());
00835         src[q].resize(participating_timeslices.size());
00836         for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0){
00837           smearedSol[q][t0].resize(quarks[q]->getDilSize(t0)) ;
00838           src[q][t0].resize(quarks[q]->getDilSize(t0)) ;
00839           for(int i = 0 ; i <  quarks[q]->getDilSize(t0) ; ++i){
00840             smearedSol[q][t0][i] = quarks[q]->dilutedSolution(t0,i) ;
00841             src[q][t0][i] = quarks[q]->dilutedSource(t0, i) ;
00842             (*Smearing)(smearedSol[q][t0][i], u_smr);  
00843           }
00844         }
00845       }
00846       // Solution vectors are now smeared
00847                   
00848       QDPIO::cout<<"   Doing " << phases.numMom()<< "  momenta "<<endl ;
00849       pop(UserData_xml);//done with UserData_xml 
00850       //First do all the mesons
00851       //Make a loop over meson operators
00852       //source source creation
00853       {
00854         map<string, MesonOp>::iterator it ;
00855         for(it=LocalMesonOps.begin();it!=LocalMesonOps.end();it++){
00856           MesonOp op = it->second ;
00857           // DB storage
00858           //BinaryFxStoreDB< SerialDBKey<HadronKey>, SerialDBData<HadronOperator > > 
00859           BinaryStoreDB< SerialDBKey<HadronKey>, SerialDBData<MesonOpData > > qdp_db;
00860           qdp_db.setMaxUserInfoLen(UserData_xml.str().size());
00861           qdp_db.open(op.file, O_RDWR | O_CREAT, 0664);
00862           qdp_db.insertUserdata(UserData_xml.str());
00863 
00864           SerialDBKey<HadronKey> key ;
00865           //HadronKey key ;
00866           key.key().gamma = op.g ;
00867           // loop over the momentum projection
00868           for(int mom_num = 0 ; mom_num < phases.numMom() ; ++mom_num){
00869             key.key().p = phases.numToMom(mom_num);
00870             for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0){
00871               key.key().t0 = participating_timeslices[t0] ;
00872               key.key().t = key.key().t0 ; // creation ops leave on one time slice only
00873               key.key().qn.resize(2);
00874               //first do the sources
00875               key.key().type = MESON_SRC_SRC ;
00876               QDPIO::cout<<"   Doing MESON_SRC_SRC"<<endl ;
00877               for(int q(0);q< quarks.size() ;q++){
00878                 key.key().qn[0]=q;
00879                 for(int q1(0);q1< quarks.size() ;q1++)
00880                   if(q!=q1){
00881                     key.key().qn[1] = q1 ;
00882                     SerialDBData<MesonOpData > val ;
00883                     val.data().resize(quarks[q]->getDilSize(t0));
00884                     //SerialDBData< HadronOperator > val ;
00885                     QDPIO::cout<<"   quarks: "<<q<<" "<<q1 <<endl ;
00886                     for ( int d(0) ; d < quarks[q]->getDilSize(t0); d++){
00887                       //LatticeFermion quark_bar = quarks[q]->dilutedSource(t0,d);
00888                       LatticeFermion quark_bar = src[q][t0][d];
00889                       quark_bar = Gamma(Ns-1)*quark_bar ;
00890                       for ( int d1(0) ; d1 < quarks[q1]->getDilSize(t0); d1++){
00891                         //QDPIO::cout<<" quark: "<<q<<" "<<q1 ;
00892                         //QDPIO::cout<<" dilution: "<<d<<" "<<d1<<endl ;
00893                         //LatticeFermion quark = quarks[q1]->dilutedSource(t0,d1);
00894                         LatticeFermion quark = src[q1][t0][d1];
00895                         DComplex cc ;
00896                         //meson(cc,op.g,phases[mom_num],quark_bar,quark,   
00897                         //      phases.getSet()[key.key().t]);
00898                         //if(toBool(real(cc)!=0.0) && toBool(imag(cc)!=0.0))
00899                         //  val.data().data[Key(d,d1)] = cc ;
00900                         meson(val.data().data(d,d1),op.g,phases[mom_num],
00901                               quark_bar,quark, phases.getSet()[key.key().t]);
00902                       }// dilutions d
00903                     }// dilutions d1
00904                     qdp_db.insert(key, val);
00905                   } // quark 2
00906               } // quark 1 
00907               
00908               key.key().type = MESON_SOL_SOL ;
00909               QDPIO::cout<<"   Doing MESON_SOL_SOL"<<endl ;
00910               for(int q(0);q< quarks.size() ;q++){
00911                 key.key().qn[0]=q;
00912                 for(int q1(q+1);q1< quarks.size() ;q1++){
00913                   key.key().qn[1] = q1 ;
00914                   QDPIO::cout<<"   quarks: "<<q<<" "<<q1<<endl ;
00915                   SerialDBData<MesonOpData > val ;
00916                   val.data().resize(quarks[q]->getDilSize(t0));
00917                   //SerialDBData< HadronOperator > val ;
00918                   for(int t(0);t<phases.numSubsets();t++){
00919                     key.key().t = t ;
00920                     for ( int d(0) ; d < quarks[q]->getDilSize(t0); d++){
00921                       LatticeFermion quark_bar = smearedSol[q][t0][d] ;
00922                       quark_bar = Gamma(Ns-1)*quark_bar ;
00923                       for ( int d1(0) ; d1 < quarks[q1]->getDilSize(t0); d1++){
00924                         //QDPIO::cout<<" quark: "<<q<<" "<<q1 ;
00925                         //QDPIO::cout<<" dilution: "<<d<<" "<<d1<<endl ;
00926                         LatticeFermion quark =  smearedSol[q1][t0][d1] ;
00927                         meson(val.data().data(d,d1),op.g,phases[mom_num],
00928                               quark_bar,quark, phases.getSet()[key.key().t]);
00929                         //DComplex cc ;
00930                         //meson(cc,op.g,phases[mom_num],quark_bar,quark,
00931                         //      phases.getSet()[key.key().t]);
00932                         //if(toBool(real(cc)!=0.0)&&toBool(imag(cc)!=0.0))
00933                         //  val.data().data[Key(d,d1)] = cc ;
00934                       }// dilutions d
00935                     }// dilutions d1
00936                     qdp_db.insert(key, val);
00937                   } // loop over time
00938                 } // quark 2
00939               } // quark 1 
00940               
00941 
00942               key.key().type = MESON_SRC_SOL ;
00943               QDPIO::cout<<"   Doing MESON_SRC_SOL"<<endl  ;
00944               for(int q(0);q< quarks.size() ;q++){
00945                 key.key().qn[0]=q;
00946                 for(int q1(0);q1< quarks.size() ;q1++){
00947                   key.key().qn[1] = q1 ;
00948                   QDPIO::cout<<"   quarks: "<<q<<" "<<q1<<endl ;
00949                   SerialDBData<MesonOpData > val ;
00950                   val.data().resize(quarks[q]->getDilSize(t0));
00951                   //SerialDBData< HadronOperator > val ;
00952                   for (int tt = 0 ; tt < participating_timeslices.size() ; ++tt){
00953                     int t = participating_timeslices[tt] ;
00954                     key.key().t = t ;
00955                     for ( int d(0) ; d < quarks[q]->getDilSize(tt); d++){
00956                       //LatticeFermion quark_bar = quarks[q]->dilutedSource(tt,d);
00957                       LatticeFermion quark_bar = src[q][tt][d] ;
00958                       for ( int d1(0) ; d1 < quarks[q1]->getDilSize(t0); d1++){
00959                         //QDPIO::cout<<" quark: "<<q<<" "<<q1 ;
00960                         //QDPIO::cout<<" dilution: "<<d<<" "<<d1<<endl ;
00961                         LatticeFermion quark =  smearedSol[q1][t0][d1] ;
00962                         //DComplex cc ;
00963                         meson(val.data().data(d,d1),op.g,phases[mom_num],quark_bar,quark,
00964                               phases.getSet()[key.key().t]);
00965                         //if(toBool(real(cc)!=0.0)&&toBool(imag(cc)!=0.0))
00966                         //val.data().data[Key(d,d1)] = cc ;
00967                       }// dilutions d1                                   
00968                     }// dilutions d                                        
00969                     qdp_db.insert(key, val);
00970                   } // loop over time                                              
00971                 } // quark 2                                                             
00972               } // quark 1          
00973               
00974             }// t0
00975           }//mom
00976         }// ops
00977       }// Done with Mesons
00978 
00979       //Now the Baryons
00980       {
00981         map<string, BaryonOp>::iterator it ;
00982         for(it=LocalBaryonOps.begin();it!=LocalBaryonOps.end();it++){
00983           BaryonOp op = it->second ;
00984           BinaryStoreDB< SerialDBKey<HadronKey>, SerialDBData<BaryonOpData > > qdp_db;
00985           qdp_db.setMaxUserInfoLen(UserData_xml.str().size());
00986           qdp_db.open(op.file, O_RDWR | O_CREAT, 0664);
00987           qdp_db.insertUserdata(UserData_xml.str());
00988 
00989           SerialDBKey<HadronKey> key ;
00990           //HadronKey key ;
00991           key.key().gamma = op.g ;
00992           // loop over the momentum projection
00993           for(int mom_num = 0 ; mom_num < phases.numMom() ; ++mom_num){
00994             key.key().p = phases.numToMom(mom_num);
00995             for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0){
00996               key.key().t0 = participating_timeslices[t0] ;
00997               key.key().t = key.key().t0 ; // creation ops leave on one time slice only
00998               key.key().qn.resize(3);
00999               //first do the sources
01000               key.key().type = BARYON_SRC ;
01001               QDPIO::cout<<"   Doing BARYON_SRC "<<endl ;
01002               for(int q0(0);q0< quarks.size() ;q0++){
01003                 key.key().qn[0]=q0;
01004                 for(int q1(0);q1< quarks.size() ;q1++)
01005                   if(q0!=q1){
01006                     key.key().qn[1]=q1;
01007                     for(int q2(0);q2< quarks.size() ;q2++)
01008                       if((q1!=q2)&&(q0!=q2)){               
01009                         key.key().qn[2] = q2 ;
01010                         QDPIO::cout<<"   quarks: "<<q0<<" "<<q1<<" "<<q2<<endl ;
01011                         //SerialDBData< HadronOperator > val ;
01012                         SerialDBData< BaryonOpData > val ;
01013                         val.data().resize(quarks[q0]->getDilSize(t0));
01014                         for ( int d0(0) ; d0 < quarks[q0]->getDilSize(t0); d0++){
01015                           //LatticeFermion quark0 = quarks[q0]->dilutedSource(t0,d0);
01016                           LatticeFermion quark0 = src[q0][t0][d0];
01017                           for ( int d1(0) ; d1 < quarks[q1]->getDilSize(t0); d1++){
01018                             //LatticeFermion quark1 = quarks[q1]->dilutedSource(t0,d1);
01019                             LatticeFermion quark1 = src[q1][t0][d1];
01020                             for ( int d2(0) ; d2 < quarks[q2]->getDilSize(t0); d2++){
01021                               //QDPIO::cout<<" quarks: "<<q0<<" "<<q1<<" "<<q2 ;
01022                               //QDPIO::cout<<" dilution: "<<d0<<" "<<d1<<" "<<d2<<endl ;
01023                               //LatticeFermion quark2 = quarks[q2]->dilutedSource(t0,d2);
01024                               LatticeFermion quark2 = src[q2][t0][d2];
01025                               multi1d<DComplex> cc ;
01026                               baryon(cc,op.g,phases[mom_num],quark0,quark1,quark2,   
01027                                      phases.getSet()[key.key().t]);
01028                               val.data().data(d0,d1,d2) = cc ;
01029                               //for(int s(0);s<Ns;s++)
01030                               //if(toBool(real(cc[s])!=0.0) && toBool(imag(cc[s])!=0.0))
01031                               //  val.data().data[Key(d0,d1,d2,s)] = cc[s] ;
01032                             }// dilutions d2
01033                           }//dilutions d1
01034                         }// dilutions d0
01035                         qdp_db.insert(key, val);
01036                       } // quark 2
01037                   } // quark 1 
01038               } // quark 0 
01039 
01040               
01041               // Then next block needs work
01042               key.key().type = BARYON_SOL ;
01043               QDPIO::cout<<"   Doing BARYON_SOL "<<endl ;
01044               for(int q0(0);q0< quarks.size() ;q0++){
01045                 key.key().qn[0]=q0;
01046                 for(int q1(q0+1);q1< quarks.size() ;q1++){
01047                   key.key().qn[1] = q1 ;
01048                   for(int q2(q1+1);q2< quarks.size() ;q2++){
01049                     key.key().qn[2] = q2 ;
01050                     QDPIO::cout<<"   quarks: "<<q0<<" "<<q1<<" "<<q2 <<endl ;
01051                     //SerialDBData< HadronOperator > val ;
01052                     SerialDBData< BaryonOpData > val ;
01053                     val.data().resize(quarks[q0]->getDilSize(t0));
01054                     for(int t(0);t<phases.numSubsets();t++){
01055                       key.key().t = t ;
01056                       for ( int d0(0) ; d0 < quarks[q0]->getDilSize(t0); d0++){
01057                         LatticeFermion quark0 = smearedSol[q0][t0][d0] ;
01058                         for ( int d1(0) ; d1 < quarks[q1]->getDilSize(t0); d1++){
01059                           LatticeFermion quark1 = smearedSol[q1][t0][d1] ;
01060                           for ( int d2(0) ; d2 < quarks[q2]->getDilSize(t0); d2++){
01061                             //QDPIO::cout<<" quarks: "<<q0<<" "<<q1<<" "<<q2 ;
01062                             //QDPIO::cout<<" dilution: "<<d0<<" "<<d1<<" "<<d2<<endl ;
01063                             LatticeFermion quark2 =  smearedSol[q2][t0][d2] ;
01064                             
01065                             multi1d<DComplex> cc ;
01066                             baryon(cc,op.g,phases[mom_num],quark0,quark1,quark2,
01067                                    phases.getSet()[key.key().t]);
01068                             val.data().data(d0,d1,d2) = cc ;
01069                             //for(int s(0);s<Ns;s++)
01070                             //  if(toBool(real(cc[s])!=0.0) && toBool(imag(cc[s])!=0.0))
01071                             //  val.data().data[Key(d0,d1,d2,s)] = cc[s] ;
01072                           }// dilutions d0
01073                         }// dilutions d1
01074                       }//dilutions d2
01075                       qdp_db.insert(key, val);
01076                     } // loop over time
01077                   } // quark 2
01078                 } // quark 1 
01079               }// quark 0
01080               
01081             }// t0
01082           }//mom
01083         }// ops
01084 
01085       }// done with baryons
01086       
01087       
01088       swatch.stop();
01089       
01090       QDPIO::cout << "Operators written: time= "
01091                   << swatch.getTimeInSeconds() 
01092                   << " secs" << endl;
01093       
01094       // Close the namelist output file XMLDAT
01095       pop(xml_out);     // StochHadron
01096       
01097       snoop.stop();
01098       QDPIO::cout << name << ": total time = "
01099                   << snoop.getTimeInSeconds() 
01100                   << " secs" << endl;
01101       
01102       QDPIO::cout << name << ": ran successfully" << endl;
01103       
01104       END_CODE();
01105     } 
01106   }  // namespace InlineHadronEnv
01107 }// namespace chroma
01108 

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