inline_disco_eoprec_w.cc

Go to the documentation of this file.
00001 // $Id: inline_disco_eoprec_w.cc,v 3.1 2009/04/08 18:34:11 caubin Exp $
00002 /*! \file
00003  * \brief Inline measurement 3pt_prop
00004  *
00005  */
00006 #include <vector> 
00007 #include <map> 
00008 
00009 #include "handle.h"
00010 #include "meas/inline/hadron/inline_disco_eoprec_w.h"
00011 #include "meas/inline/abs_inline_measurement_factory.h"
00012 #include "meas/smear/quark_smearing_factory.h"
00013 #include "meas/smear/quark_smearing_aggregate.h"
00014 #include "meas/smear/displacement.h"
00015 #include "meas/sources/source_smearing_aggregate.h"
00016 #include "meas/sources/source_smearing_factory.h"
00017 #include "meas/sources/dilutezN_source_const.h"
00018 #include "meas/sources/zN_src.h"
00019 #include "meas/sinks/sink_smearing_aggregate.h"
00020 #include "meas/sinks/sink_smearing_factory.h"
00021 #include "meas/hadron/barspinmat_w.h"
00022 #include "meas/hadron/baryon_operator_aggregate_w.h"
00023 #include "meas/hadron/baryon_operator_factory_w.h"
00024 #include "meas/hadron/dilution_scheme_aggregate.h"
00025 #include "meas/hadron/dilution_scheme_factory.h"
00026 #include "meas/glue/mesplq.h"
00027 #include "util/ft/sftmom.h"
00028 #include "util/info/proginfo.h"
00029 #include "meas/inline/make_xml_file.h"
00030 #include "util/info/unique_id.h"
00031 #include "util/ferm/transf.h"
00032 #include "meas/inline/io/named_objmap.h"
00033 
00034 #include "util/ferm/key_val_db.h"
00035 #include "actions/ferm/linop/linop_w.h"
00036 #include "actions/ferm/fermacts/fermact_factory_w.h"
00037 #include "actions/ferm/fermacts/fermacts_aggregate_w.h"
00038 
00039 #include "eoprec_logdet_wilstype_fermact_w.h"
00040 #include "actions/ferm/linop/lgherm_w.h"
00041 
00042 #include "actions/ferm/fermacts/clover_fermact_params_w.h"
00043 #include "actions/ferm/fermacts/wilson_fermact_params_w.h"
00044 
00045 namespace Chroma{ 
00046   namespace InlineDiscoEOPrecEnv{ 
00047     namespace{
00048       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00049                                               const std::string& path) 
00050       {
00051         return new InlineMeas(Params(xml_in, path));
00052       }
00053 
00054       //! Local registration flag
00055       bool registered = false;
00056     }
00057 
00058     const std::string name = "DISCO_EOPREC";
00059 
00060     //! Register all the factories
00061     bool registerAll() 
00062     {
00063       bool success = true; 
00064       if (! registered)
00065       {
00066         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00067         registered = true;
00068       }
00069       return success;
00070     }
00071   
00072   // Reader for input parameters
00073   void read(XMLReader& xml, const string& path, Params::Param_t& param){
00074       XMLReader paramtop(xml, path);
00075       
00076       int version;
00077       read(paramtop, "version", version);
00078       
00079       switch (version) 
00080         {
00081         case 1:
00082           /************************************************************/
00083           read(paramtop,"max_path_length",param.max_path_length);
00084           read(paramtop,"p2_max",param.p2_max);
00085           read(paramtop,"mass_label",param.mass_label);
00086           param.chi = readXMLArrayGroup(paramtop, "Quarks", "DilutionType");
00087           param.action = readXMLGroup(paramtop, "FermionAction","FermAct");
00088           
00089           break;
00090           
00091         default :
00092           /**************************************************************/
00093 
00094           QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00095           QDP_abort(1);
00096         }
00097     }
00098 
00099 
00100     // Writer for input parameters
00101     void write(XMLWriter& xml, const string& path, const Params::Param_t& param){
00102       push(xml, path);
00103       
00104       int version = 1;
00105       
00106       write(xml, "version", version);
00107 
00108       write(xml,"max_path_length",param.max_path_length);
00109       write(xml,"p2_max",param.p2_max);
00110       write(xml,"mass_label",param.mass_label);
00111       push(xml,"FermionAction");
00112       xml<<param.action.xml ;
00113       pop(xml);
00114 
00115       push(xml,"Quarks");
00116       for( int t(0);t<param.chi.size();t++){
00117         push(xml,"elem");
00118         xml<<param.chi[t].xml;
00119         pop(xml);
00120       }
00121       pop(xml);
00122             
00123       pop(xml); // final pop
00124     }
00125 
00126 
00127     //! Gauge field parameters
00128   void read(XMLReader& xml, const string& path, Params::NamedObject_t& input)
00129     {
00130       XMLReader inputtop(xml, path);
00131       
00132       read(inputtop, "gauge_id", input.gauge_id);
00133       read(inputtop, "op_db_file", input.op_db_file);
00134     }
00135     
00136     //! Gauge field parameters
00137   void write(XMLWriter& xml, const string& path, const Params::NamedObject_t& input){
00138       push(xml, path);
00139       
00140       write(xml, "gauge_id", input.gauge_id);
00141       write(xml, "op_db_file", input.op_db_file);
00142       pop(xml);
00143     }
00144     
00145     // Param stuff
00146     Params::Params(){ 
00147       frequency = 0;
00148     }
00149     
00150     Params::Params(XMLReader& xml_in, const std::string& path) 
00151     {
00152       try 
00153         {
00154           XMLReader paramtop(xml_in, path);
00155           
00156           if (paramtop.count("Frequency") == 1)
00157             read(paramtop, "Frequency", frequency);
00158           else
00159             frequency = 1;
00160           
00161           // Read program parameters
00162           read(paramtop, "Param", param);
00163           
00164           // Read in the output propagator/source configuration info
00165           read(paramtop, "NamedObject", named_obj);
00166           
00167           // Possible alternate XML file pattern
00168           if (paramtop.count("xml_file") != 0) 
00169             {
00170               read(paramtop, "xml_file", xml_file);
00171             }
00172         }
00173       catch(const std::string& e) 
00174         {
00175           QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00176           QDP_abort(1);
00177         }
00178     }
00179 
00180     void Params::write(XMLWriter& xml_out, const std::string& path) 
00181     {
00182       push(xml_out, path);
00183       
00184       // Parameters for source construction
00185       InlineDiscoEOPrecEnv::write(xml_out, "Param", param);
00186       
00187       // Write out the output propagator/source configuration info
00188       InlineDiscoEOPrecEnv::write(xml_out, "NamedObject", named_obj);
00189 
00190       pop(xml_out);
00191     }
00192 
00193     
00194     //! Meson operator     
00195     struct KeyOperator_t
00196     {
00197       unsigned short int t_slice ; /*!< Meson operator time slice */
00198       multi1d<short int> disp    ; /*!< Displacement dirs of quark (right)*/
00199       multi1d<short int> mom     ; /*!< D-1 momentum of this operator */
00200       
00201       KeyOperator_t(){
00202         mom.resize(Nd-1);
00203       }
00204     };
00205     
00206     bool operator<(const KeyOperator_t& a, const KeyOperator_t& b){
00207       return ((a.t_slice<b.t_slice)||(a.mom<b.mom)||(a.disp<b.disp));
00208     }
00209     
00210     std::ostream& operator<<(std::ostream& os, const KeyOperator_t& d)
00211     {
00212       os << "KeyOperator_t:"
00213          << " t_slice = " << d.t_slice
00214          << ", disp = ";
00215       for (int i=0; i<d.disp.size();i++){
00216         os << d.disp[i] << " " ;
00217       }
00218       os << ", mom = ";
00219       for (int i=0; i<d.mom.size();i++){
00220         os << d.mom[i] << " " ;
00221       }
00222       os << std::endl;
00223 
00224       return os;
00225     }
00226     class ValOperator_t{
00227     public:
00228       multi1d<ComplexD> op ;  
00229       ValOperator_t(){op.resize(Ns*Ns);} // Here go the 16 gamma matrices
00230       ~ValOperator_t(){}
00231     } ;
00232 
00233     //-------------------------------------------------------------------------
00234     //! stream IO
00235     std::ostream& operator<<(std::ostream& os, const ValOperator_t& d)
00236     {
00237       os << "ValOperator_t:\n";
00238       for (int i=0; i<d.op.size();i++){
00239         os <<"     gamma["<<i<<"] = "<< d.op[i] << endl ;
00240       }
00241       
00242       return os;
00243     }
00244     
00245     struct KeyVal_t{
00246       SerialDBKey <KeyOperator_t> k ;
00247       SerialDBData<ValOperator_t> v ;
00248     };
00249 
00250     //! KeyOperator reader    
00251     void read(BinaryReader& bin, KeyOperator_t& d){
00252       read(bin,d.t_slice);
00253       unsigned short int n ;
00254       read(bin,n);
00255       d.disp.resize(n); 
00256       read(bin,d.disp);
00257       d.mom.resize(Nd-1) ;
00258       read(bin,d.mom);
00259     }
00260     //! KeyOperator writer
00261     void write(BinaryWriter& bin, KeyOperator_t& d){
00262       write(bin,d.t_slice);
00263       unsigned short int n ;
00264       n = d.disp.size();
00265       write(bin,n);
00266       write(bin,d.disp);
00267       write(bin,d.mom);
00268     }
00269 
00270     //! ValOperator reader    
00271     void read(BinaryReader& bin, ValOperator_t& d){
00272       d.op.resize(Ns*Ns);
00273       read(bin,d.op);
00274     }
00275     //! ValOperator writer
00276     void write(BinaryWriter& bin, ValOperator_t& d){
00277       write(bin,d.op);
00278     }
00279 
00280     namespace{
00281       StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<short int>& d){
00282         if (d.size() > 0){
00283           os << d[0]; 
00284           for(int i=1; i < d.size(); ++i)
00285             os << " " << d[i];
00286         }
00287         return os;
00288       }
00289     }
00290 
00291     typedef LatticeFermion               T;
00292     typedef multi1d<LatticeColorMatrix>  P;
00293     typedef multi1d<LatticeColorMatrix>  Q;
00294 
00295     Handle<EvenOddPrecLinearOperator<T,P,Q> >
00296     createOddOdd_Op( const Params::Param_t& param, const P& u){
00297       //                                                                                                 
00298       // Initialize fermion action                                                                       
00299       //                                                                                                 
00300       std::istringstream  xml_s(param.action.xml);
00301       XMLReader  fermacttop(xml_s);
00302       QDPIO::cout << "FermAct = " << param.action.id << endl;
00303       //                                                                                                 
00304       // Try the factories                                                                               
00305       //                                                                                                 
00306       Handle< FermState< T,P,Q> > state ;
00307       try{
00308         QDPIO::cout << "Try the various Wilson fermion factories" << endl;
00309         // Generic Wilson-Type stuff                                                                   
00310         Handle< FermionAction< T,P,Q > >
00311           Sf(TheFermionActionFactory::Instance().createObject(param.action.id,
00312                                                               fermacttop,
00313                                                               param.action.path));
00314         state = Sf->createState(u);//got the state                                                     
00315         QDPIO::cout << "Suitable factory found: compute the trace quark prop"<<endl;
00316       }
00317       catch (const std::string& e){
00318         QDPIO::cout << name
00319                     << ": caught exception instantiating the action: " << e << endl;
00320       }
00321       
00322       // Now need to construct the operator                                                              
00323       // this seems tricky and maybe there is a better way... (Robert-Balint help!)                      
00324       // We only work with Wilson and Clover Wilson fermions so check the following 2                    
00325       
00326       //this is the Odd-Odd piece                                                                        
00327       Handle<EvenOddPrecLinearOperator<T,P,Q> > Doo ;
00328       if(param.action.id == "WILSON"){
00329         WilsonFermActParams wp(fermacttop,param.action.path);
00330         return new EvenOddPrecWilsonLinOp(state,wp.Mass,wp.anisoParam ) ;
00331       }
00332       else if(param.action.id == "CLOVER"){
00333         CloverFermActParams cp(fermacttop,param.action.path);
00334         return new EvenOddPrecCloverLinOp(state,cp) ;
00335       }
00336       else{
00337         QDPIO::cout<<name<<" : Tough luck dude! No code for you..."<<endl ;
00338         QDP_abort(1);
00339       }
00340       return NULL ;
00341     }
00342     
00343     void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00344                   const LatticeFermion& qbar,
00345                   const LatticeFermion& q,
00346                   const SftMom& p,
00347                   const int& t, 
00348                   const Subset& trb,
00349                   const multi1d<short int>& path,
00350                   const int& max_path_length ){
00351       QDPIO::cout<<" Computing Operator with path length "<<path.size()
00352                  <<" on timeslice "<<t<<".   Path: "<<path <<endl;
00353       
00354       ValOperator_t val ;
00355       KeyOperator_t key ;
00356       pair<KeyOperator_t, ValOperator_t> kv ; 
00357       kv.first.t_slice = t ;
00358       if(path.size()==0){
00359         kv.first.disp.resize(1);
00360         kv.first.disp[0] = 0 ;
00361       }
00362       else
00363         kv.first.disp = path ;
00364 
00365       multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00366       for (int m(0); m < p.numMom(); m++)
00367         foo[m].resize(Ns*Ns);
00368       for(int g(0);g<Ns*Ns;g++){
00369         LatticeComplex cc = localInnerProduct(qbar,Gamma(g)*q);
00370         for (int m(0); m < p.numMom(); m++){
00371           foo[m][g] = sum(p[m]*cc,p.getSet()[t]) ;// Since ferms are defined only on odd/even sites,
00372           //      Don't need to restrict this...
00373           //      foo[m][g] = sum(p[m]*cc,trb) ;//Only sum even/odd sites on time t
00374         }
00375       }
00376       for (int m(0); m < p.numMom(); m++){
00377         for(int i(0);i<(Nd-1);i++)
00378           kv.first.mom[i] = p.numToMom(m)[i] ;
00379         
00380         kv.second.op = foo[m];
00381         pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00382 
00383         itbo = db.insert(kv);
00384         if( itbo.second ){ 
00385           QDPIO::cout<<"Inserting new entry in map\n";
00386         }
00387         else{ // if insert fails, key already exists, so add result
00388           cout<<"Key = "<<kv.first<<endl;
00389           QDPIO::cout<<"Adding result to value already there"<<endl;
00390           for(int i(0);i<kv.second.op.size();i++){
00391             itbo.first->second.op[i] += kv.second.op[i] ;
00392           }
00393         }
00394       }
00395 
00396       if(path.size()<max_path_length){
00397         QDPIO::cout<<" attempt to add new path. "
00398                    <<" current path length is : "<<path.size();
00399         multi1d<short int> new_path(path.size()+1);
00400         QDPIO::cout<<" new path length is : "<<new_path.size()<<endl;
00401         for(int i(0);i<path.size();i++)
00402           new_path[i] = path[i] ;
00403         for(int sign(-1);sign<2;sign+=2)
00404           for(int mu(0);mu<Nd;mu++){
00405             new_path[path.size()]= sign*(mu+1) ;
00406             //skip back tracking 
00407             bool back_track=false ;
00408             if(path.size()>0)
00409               if(path[path.size()-1] == -new_path[path.size()])
00410                 back_track=true;
00411             if(!back_track){
00412               QDPIO::cout<<" Added path: "<<new_path<<endl;
00413               LatticeFermion q_mu ;
00414               if(sign>0)
00415                 q_mu = shift(q, FORWARD, mu);
00416               else
00417                 q_mu = shift(q, BACKWARD, mu);
00418 
00419               do_disco(db, qbar, q_mu, p, t, trb, new_path, max_path_length);
00420             } // skip backtracking
00421           } // mu
00422       }
00423       
00424     }// do_disco
00425 
00426     void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00427                   const Params::Param_t& param,
00428                   const P& u,
00429                   const SftMom& p,
00430                   const int& t,
00431                   const Subset& trb,
00432                   const Handle<EvenOddPrecLinearOperator<T,P,Q> >& Doo,
00433                   const multi1d<short int>& path){
00434       QDPIO::cout<<" Computing Operator with path length "<<path.size()
00435                  <<" on timeslice "<<t<<".   Path: "<<path <<endl;
00436 
00437       int max_path_length = param.max_path_length;
00438       ValOperator_t val ;
00439       KeyOperator_t key ;
00440       pair<KeyOperator_t, ValOperator_t> kv ;
00441       kv.first.t_slice = t ;
00442       if(path.size()==0){
00443         kv.first.disp.resize(1);
00444         kv.first.disp[0] = 0 ;
00445       }
00446       else
00447         kv.first.disp = path ;
00448 
00449       multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00450       for (int m(0); m < p.numMom(); m++){
00451         foo[m].resize(Ns*Ns);
00452         for (int g(0); g<Ns*Ns;g++){
00453           foo[m][g] = 0.0;
00454         }
00455       }
00456       for(int g(0);g<Ns*Ns;g++){
00457         for(int col=0;col<3;col++){
00458           for(int sp=0;sp<4;sp++){
00459             Fermion tt = zero ;
00460             ColorVector cv = zero ;
00461             Complex z = cmplx(Real(1.0),0.0) ;
00462             pokeColor(cv,z,col);
00463             pokeSpin(tt,cv,sp);
00464             LatticeFermion V = tt ;
00465             for (int m(0); m < p.numMom(); m++){
00466               //only on even sites                                                                       
00467               LatticeFermion DV = zero;
00468               Doo->evenEvenInvLinOp(DV,V,PLUS);
00469               foo[m][g] += sum(p[m]*localInnerProduct(V,Gamma(g)*DV),p.getSet()[t]);
00470               //              foo[m][g] += sum(p[m]*localInnerProduct(V,Gamma(g)*DV),trb);
00471             }//m                                                                                         
00472           }//spin                                                                                        
00473         }//col                                                                                           
00474       }//g                                                                                               
00475 
00476       for (int m(0); m < p.numMom(); m++){
00477         for(int i(0);i<(Nd-1);i++)
00478           kv.first.mom[i] = p.numToMom(m)[i] ;
00479 
00480         kv.second.op = foo[m];
00481         pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00482 
00483         itbo = db.insert(kv);
00484         if( itbo.second ){
00485           QDPIO::cout<<"Inserting new entry in map\n";
00486         }
00487         else{ // if insert fails, key already exists, so add result                                      
00488           for(int i(0);i<kv.second.op.size();i++)
00489             itbo.first->second.op[i] += kv.second.op[i] ;
00490         }
00491       }//m                                                                                               
00492 
00493     }// do_disco                                                                                         
00494 
00495   //--------------------------------------------------------------
00496   // Function call
00497   //  void 
00498   //InlineDisco::operator()(unsigned long update_no,
00499   //                            XMLWriter& xml_out) 
00500     void InlineMeas::operator()(unsigned long update_no,
00501                                 XMLWriter& xml_out) 
00502     {
00503       // If xml file not empty, then use alternate
00504       if (params.xml_file != ""){
00505         string xml_file = makeXMLFileName(params.xml_file, update_no);
00506         
00507         push(xml_out, "propagator_3pt");
00508         write(xml_out, "update_no", update_no);
00509         write(xml_out, "xml_file", xml_file);
00510         pop(xml_out);
00511         
00512         XMLFileWriter xml(xml_file);
00513         func(update_no, xml);
00514       }
00515       else{
00516         func(update_no, xml_out);
00517       }
00518     }
00519     
00520     
00521     // Function call
00522     //void 
00523     //InlineDisco::func(unsigned long update_no,
00524     //                    XMLWriter& xml_out) 
00525     void InlineMeas::func(unsigned long update_no,
00526                           XMLWriter& xml_out) 
00527     {
00528       START_CODE();
00529       
00530       StopWatch snoop;
00531       snoop.reset();
00532       snoop.start();
00533       
00534       // Test and grab a reference to the gauge field
00535       XMLBufferWriter gauge_xml;
00536       try
00537         {
00538           TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00539           TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00540         }
00541       catch( std::bad_cast ) 
00542         {
00543           QDPIO::cerr << InlineDiscoEOPrecEnv::name << ": caught dynamic cast error" 
00544                       << endl;
00545           QDP_abort(1);
00546         }
00547       catch (const string& e) 
00548         {
00549           QDPIO::cerr << name << ": map call failed: " << e 
00550                       << endl;
00551           QDP_abort(1);
00552         }
00553       const multi1d<LatticeColorMatrix>& u = 
00554         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00555       
00556       push(xml_out, "disco");
00557       write(xml_out, "update_no", update_no);
00558       
00559       QDPIO::cout << name << ": Disconnected diagrams" << endl;
00560       
00561       proginfo(xml_out);    // Print out basic program info
00562       
00563       // Write out the input
00564       params.write(xml_out, "Input");
00565       
00566       // Write out the config info
00567       write(xml_out, "Config_info", gauge_xml);
00568       
00569       push(xml_out, "Output_version");
00570       write(xml_out, "out_version", 1);
00571       pop(xml_out);
00572       
00573       // First calculate some gauge invariant observables just for info.
00574       // This is really cheap.
00575       MesPlq(xml_out, "Observables", u);
00576       
00577       // Save current seed
00578       Seed ran_seed;
00579       QDP::RNG::savern(ran_seed);
00580       
00581       //
00582       // Read the source and solutions
00583       //
00584       StopWatch swatch;
00585       swatch.reset();
00586       swatch.start();
00587       
00588       int N_quarks = params.param.chi.size() ;
00589 
00590       multi1d< Handle< DilutionScheme<LatticeFermion> > > quarks(N_quarks);
00591 
00592       try{
00593         // Loop over quark dilutions
00594         for(int n(0); n < params.param.chi.size(); ++n){
00595           const GroupXML_t& dil_xml = params.param.chi[n];
00596           std::istringstream  xml_d(dil_xml.xml);
00597           XMLReader  diltop(xml_d);
00598           QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
00599           quarks[n] = 
00600             TheFermDilutionSchemeFactory::Instance().createObject(dil_xml.id, 
00601                                                                   diltop, 
00602                                                                   dil_xml.path);
00603         }
00604       }
00605       catch(const std::string& e){
00606         QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
00607         QDP_abort(1);
00608       }
00609       
00610       
00611       //-------------------------------------------------------------------
00612       //Sanity checks   
00613 
00614       //Another Sanity check, the three quarks must all be 
00615       //inverted on the same cfg
00616       for (int n = 1 ; n < N_quarks ; ++n){
00617         if (quarks[0]->getCfgInfo() != quarks[n]->getCfgInfo()){
00618           QDPIO::cerr << name << " : Quarks do not contain the same cfg info";
00619           QDPIO::cerr << ", quark "<< n << endl;
00620           QDP_abort(1);
00621         }               
00622       }
00623 
00624       //Also ensure that the cfg on which the inversions were performed 
00625       //is the same as the cfg that we are using
00626       { 
00627         std::string cfgInfo; 
00628         
00629         //Really ugly way of doing this(Robert Heeeelp!!)
00630         XMLBufferWriter top;
00631         write(top, "Config_info", gauge_xml);
00632         XMLReader from(top);
00633         XMLReader from2(from, "/Config_info");
00634         std::ostringstream os;
00635         from2.print(os);
00636         
00637         cfgInfo = os.str();
00638         
00639         if (cfgInfo != quarks[0]->getCfgInfo()){
00640           QDPIO::cerr << name << " : Quarks do not contain the same";
00641           QDPIO::cerr << " cfg info as the gauge field." ;
00642           QDPIO::cerr << "gauge: XX"<<cfgInfo<<"XX quarks: XX" ;
00643           QDPIO::cerr << quarks[0]->getCfgInfo()<<"XX"<<  endl;
00644           QDP_abort(1);
00645         }
00646       }
00647       
00648       int decay_dir = quarks[0]->getDecayDir();
00649       //
00650       // Initialize the slow Fourier transform phases
00651       //
00652       //SftMom phases(params.param.mom2_max, false, decay_dir);
00653       SftMom phases(params.param.p2_max, false, decay_dir);
00654       
00655       // Another sanity check. The seeds of all the quarks must be different
00656       // and thier decay directions must be the same 
00657       for(int n = 1 ; n < quarks.size(); ++n){
00658         if(toBool(quarks[n]->getSeed()==quarks[0]->getSeed())){
00659           QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
00660           QDP_abort(1);
00661         }
00662 
00663         if(toBool(quarks[n]->getDecayDir()!=quarks[0]->getDecayDir())){
00664           QDPIO::cerr<<name<< ": error, quark decay dirs do not match" <<endl;
00665           QDP_abort(1);
00666         }
00667       }
00668 
00669       map< KeyOperator_t, ValOperator_t > data ;
00670       
00671       Set timerb;
00672       timerb.make(TimeSliceRBFunc(decay_dir));
00673       
00674       Handle<EvenOddPrecLinearOperator<T,P,Q> > Doo = createOddOdd_Op(params.param,u);
00675       
00676       for(int n(0);n<quarks.size();n++){
00677         for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; ++it){
00678           int t = quarks[n]->getT0(it) ;
00679           QDPIO::cout<<" Doing quark: "<<n <<endl ;
00680           QDPIO::cout<<"   quark: "<<n <<" has "<<quarks[n]->getDilSize(it);
00681           QDPIO::cout<<" dilutions on time slice "<<t<<endl ;
00682           for(int i = 0 ; i <  quarks[n]->getDilSize(it) ; ++i){
00683             QDPIO::cout<<"   Doing dilution : "<<i<<endl ;
00684             multi1d<short int> d ;
00685             LatticeFermion qbar  = quarks[n]->dilutedSource(it,i);
00686             LatticeFermion q     = quarks[n]->dilutedSolution(it,i);
00687             QDPIO::cout<<"   Starting recursion "<<endl ;
00688             // First do_disco for odd piece:
00689             // timerb for sum over only odd sites on this timeslice
00690             do_disco(data, qbar, q, phases, t, timerb[2*t+1], d, params.param.max_path_length);
00691             QDPIO::cout<<" done with recursion! "
00692                        <<"  The length of the path is: "<<d.size()<<endl ;
00693             // Now do_disco for even piece:
00694             LatticeFermion q1 = zero;
00695             LatticeFermion q2 = zero;
00696             LatticeFermion qb1 = zero;
00697             LatticeFermion qb2 = zero;
00698             Doo->evenOddLinOp(q1,q,PLUS);
00699             Doo->evenEvenInvLinOp(q2,q1,PLUS);
00700             Doo->evenOddLinOp(qb1,qbar,MINUS);
00701             Doo->evenEvenInvLinOp(qb2,qb1,MINUS);
00702             // timerb for sum over only even sites on this timeslice
00703             do_disco(data, qb2, q2, phases, t, timerb[2*t+0], d, params.param.max_path_length);
00704             QDPIO::cout<<" done with recursion! "
00705                        <<"  The length of the path is: "<<d.size()<<endl ;
00706           }
00707           QDPIO::cout<<" Done with dilutions for quark: "<<n <<endl ;
00708         }
00709       }
00710       /**
00711          NOTE THAT WE ARE NOT NORMALIZING ANYTHING B/C FOR NOW
00712          WE ASSUME TO HAVE ONLY ONE QUARK!!!!
00713        **/
00714 
00715       // Now we have to do the tr[gamma*D^-1_ee] part
00716       for (int it(0) ; it < quarks[0]->getNumTimeSlices() ; it++){
00717         multi1d<short int> d ;
00718         int t = quarks[0]->getT0(it) ;
00719         // Now let's do the Tr[Dee^-1 gamma]                                                             
00720         do_disco(data,params.param, u, phases, t, timerb[2*t+0], Doo, d);
00721       }
00722 
00723       
00724       // DB storage          
00725       BinaryStoreDB<SerialDBKey<KeyOperator_t>,SerialDBData<ValOperator_t> > qdp_db;
00726 
00727       // Open the file, and write the meta-data and the binary for this operator
00728       {
00729         XMLBufferWriter file_xml;
00730 
00731         push(file_xml, "DBMetaData");
00732         write(file_xml, "id", string("eigElemOp"));
00733         write(file_xml, "lattSize", QDP::Layout::lattSize());
00734         write(file_xml, "decay_dir", decay_dir);
00735         write(file_xml, "Params", params.param);
00736         write(file_xml, "Config_info", gauge_xml);
00737         pop(file_xml);
00738 
00739         std::string file_str(file_xml.str());
00740         qdp_db.setMaxUserInfoLen(file_str.size());
00741 
00742         qdp_db.open(params.named_obj.op_db_file, O_RDWR | O_CREAT, 0664);
00743 
00744         qdp_db.insertUserdata(file_str);
00745       }
00746 
00747       // Write the data
00748       SerialDBKey <KeyOperator_t> key ;
00749       SerialDBData<ValOperator_t> val ;
00750       map< KeyOperator_t, ValOperator_t >::iterator it;
00751       for(it=data.begin();it!=data.end();it++){
00752         key.key()  = it->first  ;
00753         val.data().op.resize(it->second.op.size()) ;
00754         // normalize to number of quarks 
00755         for(int i(0);i<it->second.op.size();i++)
00756           val.data().op[i] = it->second.op[i]/toDouble(quarks.size());
00757         qdp_db.insert(key,val) ;
00758       }
00759 
00760       // Close the namelist output file XMLDAT
00761       pop(xml_out);     // Disco
00762       
00763       snoop.stop();
00764       QDPIO::cout << name << ": total time = "
00765                   << snoop.getTimeInSeconds() 
00766                   << " secs" << endl;
00767       
00768       QDPIO::cout << name << ": ran successfully" << endl;
00769       
00770       END_CODE();
00771     } 
00772   }  // namespace InlineDiscoEOPrecEnv
00773 }// namespace chroma

Generated on Sun Nov 22 04:32:26 2009 for CHROMA by  doxygen 1.4.7