inline_meson_block_matelem_w.cc

Go to the documentation of this file.
00001 // $Id: inline_meson_block_matelem_w.cc,v 3.8 2009/03/19 17:12:20 mcneile Exp $
00002 /*! \file
00003  * \brief Inline measurement of meson operators via colorvector matrix elements
00004  */
00005 
00006 #include "handle.h"
00007 #include "meas/inline/hadron/inline_meson_block_matelem_w.h"
00008 #include "meas/inline/abs_inline_measurement_factory.h"
00009 #include "meas/smear/link_smearing_aggregate.h"
00010 #include "meas/smear/link_smearing_factory.h"
00011 #include "meas/smear/displace.h"
00012 #include "meas/glue/mesplq.h"
00013 #include "util/ferm/block_subset.h"
00014 #include "util/ferm/block_couplings.h"
00015 #include "util/ferm/subset_vectors.h"
00016 #include "util/ferm/key_val_db.h"
00017 #include "util/ft/sftmom.h"
00018 #include "util/info/proginfo.h"
00019 #include "meas/inline/make_xml_file.h"
00020 
00021 #include "meas/inline/io/named_objmap.h"
00022 
00023 #define COLORVEC_MATELEM_TYPE_ZERO       0
00024 #define COLORVEC_MATELEM_TYPE_ONE        1
00025 #define COLORVEC_MATELEM_TYPE_MONE       -1
00026 #define COLORVEC_MATELEM_TYPE_GENERIC    10
00027 
00028 namespace Chroma 
00029 { 
00030   /*!
00031    * \ingroup hadron
00032    *
00033    * @{
00034    */
00035   namespace InlineMesonBlockMatElemEnv 
00036   { 
00037     // Reader for input parameters
00038     void read(XMLReader& xml, const string& path, InlineMesonBlockMatElemEnv::Params::Param_t& param)
00039     {
00040       XMLReader paramtop(xml, path);
00041     
00042       int version;
00043       read(paramtop, "version", version);
00044 
00045       switch (version) 
00046       {
00047       case 1:
00048         /**************************************************************************/
00049         break;
00050 
00051       default :
00052         /**************************************************************************/
00053 
00054         QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00055         QDP_abort(1);
00056       }
00057 
00058       read(paramtop, "mom2_max", param.mom2_max);
00059       read(paramtop, "displacement_length", param.displacement_length);
00060       read(paramtop, "displacement_list", param.displacement_list);
00061       read(paramtop, "num_vecs", param.num_vecs);
00062       read(paramtop, "decay_dir", param.decay_dir);
00063       read(paramtop, "orthog_basis", param.orthog_basis);
00064       read(paramtop, "block_size", param.block_size);
00065 
00066       param.link_smearing  = readXMLGroup(paramtop, "LinkSmearing", "LinkSmearingType");
00067     }
00068 
00069 
00070     // Writer for input parameters
00071     void write(XMLWriter& xml, const string& path, const InlineMesonBlockMatElemEnv::Params::Param_t& param)
00072     {
00073       push(xml, path);
00074 
00075       int version = 1;
00076 
00077       write(xml, "version", version);
00078       write(xml, "mom2_max", param.mom2_max);
00079       write(xml, "displacement_length", param.displacement_length);
00080       write(xml, "displacement_list", param.displacement_list);
00081       write(xml, "num_vecs", param.num_vecs);
00082       write(xml, "decay_dir", param.decay_dir);
00083       write(xml, "orthog_basis", param.orthog_basis);
00084       write(xml, "block_size", param.block_size);
00085       xml << param.link_smearing.xml;
00086 
00087       pop(xml);
00088     }
00089 
00090     //! Read named objects 
00091     void read(XMLReader& xml, const string& path, InlineMesonBlockMatElemEnv::Params::NamedObject_t& input)
00092     {
00093       XMLReader inputtop(xml, path);
00094 
00095       read(inputtop, "gauge_id", input.gauge_id);
00096       read(inputtop, "colorvec_id", input.colorvec_id);
00097       read(inputtop, "meson_op_file", input.meson_op_file);
00098     }
00099 
00100     //! Write named objects
00101     void write(XMLWriter& xml, const string& path, const InlineMesonBlockMatElemEnv::Params::NamedObject_t& input)
00102     {
00103       push(xml, path);
00104 
00105       write(xml, "gauge_id", input.gauge_id);
00106       write(xml, "colorvec_id", input.colorvec_id);
00107       write(xml, "meson_op_file", input.meson_op_file);
00108 
00109       pop(xml);
00110     }
00111 
00112     // Writer for input parameters
00113     void write(XMLWriter& xml, const string& path, const InlineMesonBlockMatElemEnv::Params& param)
00114     {
00115       param.writeXML(xml, path);
00116     }
00117   }
00118 
00119 
00120   namespace InlineMesonBlockMatElemEnv 
00121   { 
00122     // Anonymous namespace for registration
00123     namespace
00124     {
00125       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00126                                               const std::string& path) 
00127       {
00128         return new InlineMeas(Params(xml_in, path));
00129       }
00130 
00131       //! Local registration flag
00132       bool registered = false;
00133     }
00134 
00135     const std::string name = "MESON_BLOCK_MATELEM";
00136 
00137     //! Register all the factories
00138     bool registerAll() 
00139     {
00140       bool success = true; 
00141       if (! registered)
00142       {
00143         success &= LinkSmearingEnv::registerAll();
00144         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00145         registered = true;
00146       }
00147       return success;
00148     }
00149 
00150 
00151     //! Anonymous namespace
00152     /*! Diagnostic stuff */
00153     namespace
00154     {
00155       StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<int>& d)
00156       {
00157         if (d.size() > 0)
00158         {
00159           os << d[0];
00160 
00161           for(int i=1; i < d.size(); ++i)
00162             os << " " << d[i];
00163         }
00164 
00165         return os;
00166       }
00167     }
00168 
00169 
00170     //----------------------------------------------------------------------------
00171     // Param stuff
00172     Params::Params()
00173     { 
00174       frequency = 0; 
00175       param.mom2_max = 0;
00176     }
00177 
00178     Params::Params(XMLReader& xml_in, const std::string& path) 
00179     {
00180       try 
00181       {
00182         XMLReader paramtop(xml_in, path);
00183 
00184         if (paramtop.count("Frequency") == 1)
00185           read(paramtop, "Frequency", frequency);
00186         else
00187           frequency = 1;
00188 
00189         // Read program parameters
00190         read(paramtop, "Param", param);
00191 
00192         // Read in the output propagator/source configuration info
00193         read(paramtop, "NamedObject", named_obj);
00194 
00195         // Possible alternate XML file pattern
00196         if (paramtop.count("xml_file") != 0) 
00197         {
00198           read(paramtop, "xml_file", xml_file);
00199         }
00200       }
00201       catch(const std::string& e) 
00202       {
00203         QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00204         QDP_abort(1);
00205       }
00206     }
00207 
00208 
00209     void
00210     Params::writeXML(XMLWriter& xml_out, const std::string& path) const
00211     {
00212       push(xml_out, path);
00213     
00214       // Parameters for source construction
00215       write(xml_out, "Param", param);
00216 
00217       // Write out the output propagator/source configuration info
00218       write(xml_out, "NamedObject", named_obj);
00219 
00220       pop(xml_out);
00221     }
00222 
00223 
00224     //----------------------------------------------------------------------------
00225     //! Meson operator
00226     struct KeyMesonElementalOperator_t
00227     {
00228       int                t_slice;             /*!< Meson operator time slice */
00229       int                displacement_length; /*!< Displacement length for creat. and annih. ops */
00230       multi1d<int>       displacement;        /*!< Displacement dirs of right colorvector */
00231       multi1d<int>       mom;                 /*!< D-1 momentum of this operator */
00232       int                blk_l;            /*!< Block of the anti-quark */
00233       int                blk_r;           /*!< Block for the quark */
00234     };
00235 
00236     //! Meson operator
00237     struct ValMesonElementalOperator_t
00238     {
00239       int                type_of_data; /*!< Flag indicating type of data (maybe trivial) */
00240       multi2d<ComplexD>  op;          /*!< Colorvector source and sink with momentum projection */
00241     };
00242 
00243 
00244     //----------------------------------------------------------------------------
00245     //! Holds key and value as temporaries
00246     struct KeyValMesonElementalOperator_t
00247     {
00248       SerialDBKey<KeyMesonElementalOperator_t>  key;
00249       SerialDBData<ValMesonElementalOperator_t> val;
00250     };
00251 
00252 
00253     //----------------------------------------------------------------------------
00254     //! KeyMesonElementalOperator reader
00255     void read(BinaryReader& bin, KeyMesonElementalOperator_t& param)
00256     {
00257       read(bin, param.t_slice);
00258       read(bin, param.displacement_length);
00259       read(bin, param.displacement);
00260       read(bin, param.mom);
00261       read(bin, param.blk_l);
00262       read(bin, param.blk_r);
00263     }
00264 
00265     //! MesonElementalOperator write
00266     void write(BinaryWriter& bin, const KeyMesonElementalOperator_t& param)
00267     {
00268       write(bin, param.t_slice);
00269       write(bin, param.displacement_length);
00270       write(bin, param.displacement);
00271       write(bin, param.mom);
00272       write(bin, param.blk_l);
00273       write(bin, param.blk_r);
00274     }
00275 
00276     //! MesonElementalOperator reader
00277     void read(XMLReader& xml, const std::string& path, KeyMesonElementalOperator_t& param)
00278     {
00279       XMLReader paramtop(xml, path);
00280     
00281       read(paramtop, "t_slice", param.t_slice);
00282       read(paramtop, "displacement_length", param.displacement_length);
00283       read(paramtop, "displacement", param.displacement);
00284       read(paramtop, "mom", param.mom);
00285       read(paramtop, "blk_l", param.blk_l);
00286       read(paramtop, "blk_r", param.blk_r);
00287     }
00288 
00289     //! MesonElementalOperator writer
00290     void write(XMLWriter& xml, const std::string& path, const KeyMesonElementalOperator_t& param)
00291     {
00292       push(xml, path);
00293 
00294       write(xml, "t_slice", param.t_slice);
00295       write(xml, "displacement_length", param.displacement);
00296       write(xml, "displacement", param.displacement);
00297       write(xml, "mom", param.mom);
00298       write(xml, "blk_l", param.blk_l);
00299       write(xml, "blk_r", param.blk_r);
00300       pop(xml);
00301     }
00302 
00303 
00304     //------------------------------------------------------------------------
00305     //! MesonElementalOperator reader
00306     void read(BinaryReader& bin, ValMesonElementalOperator_t& param)
00307     {
00308       read(bin, param.type_of_data);
00309 
00310       int n;
00311       read(bin, n);    // the size is always written, even if 0
00312       param.op.resize(n,n);
00313   
00314       for(int i=0; i < n; ++i)
00315       {
00316         for(int j=0; j < n; ++j)
00317         {
00318           read(bin, param.op(i,j));
00319         }
00320       }
00321     }
00322 
00323     //! MesonElementalOperator write
00324     void write(BinaryWriter& bin, const ValMesonElementalOperator_t& param)
00325     {
00326       write(bin, param.type_of_data);
00327 
00328       int n = param.op.size1();  // all sizes the same
00329       write(bin, n);
00330       for(int i=0; i < n; ++i)
00331       {
00332         for(int j=0; j < n; ++j)
00333         {
00334           write(bin, param.op(i,j));
00335         }
00336       }
00337     }
00338 
00339 
00340     //----------------------------------------------------------------------------
00341     //! Normalize just one displacement array
00342     multi1d<int> normDisp(const multi1d<int>& orig)
00343     {
00344       START_CODE();
00345 
00346       multi1d<int> disp;
00347       multi1d<int> empty; 
00348       multi1d<int> no_disp(1); no_disp[0] = 0;
00349 
00350       // NOTE: a no-displacement is recorded as a zero-length array
00351       // Convert a length one array with no displacement into a no-displacement array
00352       if (orig.size() == 1)
00353       {
00354         if (orig == no_disp)
00355           disp = empty;
00356         else
00357           disp = orig;
00358       }
00359       else
00360       {
00361         disp = orig;
00362       }
00363 
00364       END_CODE();
00365 
00366       return disp;
00367     } // void normDisp
00368 
00369 
00370     //-------------------------------------------------------------------------------
00371     // Function call
00372     void 
00373     InlineMeas::operator()(unsigned long update_no,
00374                            XMLWriter& xml_out) 
00375     {
00376       // If xml file not empty, then use alternate
00377       if (params.xml_file != "")
00378       {
00379         string xml_file = makeXMLFileName(params.xml_file, update_no);
00380 
00381         push(xml_out, "MesonMatElemColorVec");
00382         write(xml_out, "update_no", update_no);
00383         write(xml_out, "xml_file", xml_file);
00384         pop(xml_out);
00385 
00386         XMLFileWriter xml(xml_file);
00387         func(update_no, xml);
00388       }
00389       else
00390       {
00391         func(update_no, xml_out);
00392       }
00393     }
00394 
00395 
00396     // Function call
00397     void 
00398     InlineMeas::func(unsigned long update_no,
00399                      XMLWriter& xml_out) 
00400     {
00401       START_CODE();
00402 
00403       StopWatch snoop;
00404       snoop.reset();
00405       snoop.start();
00406 
00407       
00408       StopWatch swiss;
00409                         
00410       // Test and grab a reference to the gauge field
00411       XMLBufferWriter gauge_xml;
00412       try
00413       {
00414         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00415         TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00416 
00417         TheNamedObjMap::Instance().getData< SubsetVectors<LatticeColorVector> >(params.named_obj.colorvec_id).getEvectors();
00418       }
00419       catch( std::bad_cast ) 
00420       {
00421         QDPIO::cerr << name << ": caught dynamic cast error" << endl;
00422         QDP_abort(1);
00423       }
00424       catch (const string& e) 
00425       {
00426         QDPIO::cerr << name << ": map call failed: " << e << endl;
00427         QDP_abort(1);
00428       }
00429       const multi1d<LatticeColorMatrix>& u = 
00430         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00431 
00432       const SubsetVectors<LatticeColorVector>& eigen_source = 
00433         TheNamedObjMap::Instance().getData< SubsetVectors<LatticeColorVector> >(params.named_obj.colorvec_id);
00434 
00435       push(xml_out, "MesonMatElemColorVec");
00436       write(xml_out, "update_no", update_no);
00437 
00438       QDPIO::cout << name << ": Meson color-vector matrix element" << endl;
00439 
00440       proginfo(xml_out);    // Print out basic program info
00441 
00442       // Write out the input
00443       params.writeXML(xml_out, "Input");
00444 
00445       // Write out the config info
00446       write(xml_out, "Config_info", gauge_xml);
00447 
00448       push(xml_out, "Output_version");
00449       write(xml_out, "out_version", 1);
00450       pop(xml_out);
00451 
00452       //First calculate some gauge invariant observables just for info.
00453       //This is really cheap.
00454       MesPlq(xml_out, "Observables", u);
00455 
00456       //
00457       // Initialize the slow Fourier transform phases
00458       //
00459       SftMom phases(params.param.mom2_max, false, params.param.decay_dir);
00460 
00461       //
00462       // Smear the gauge field if needed
00463       //
00464       multi1d<LatticeColorMatrix> u_smr = u;
00465 
00466       try
00467       {
00468         std::istringstream  xml_l(params.param.link_smearing.xml);
00469         XMLReader  linktop(xml_l);
00470         QDPIO::cout << "Link smearing type = " << params.param.link_smearing.id << endl;
00471         
00472         
00473         Handle< LinkSmearing >
00474           linkSmearing(TheLinkSmearingFactory::Instance().createObject(params.param.link_smearing.id,
00475                                                                        linktop, 
00476                                                                        params.param.link_smearing.path));
00477 
00478         (*linkSmearing)(u_smr);
00479       }
00480       catch(const std::string& e) 
00481       {
00482         QDPIO::cerr << name << ": Caught Exception link smearing: " << e << endl;
00483         QDP_abort(1);
00484       }
00485 
00486       // Record the smeared observables
00487       MesPlq(xml_out, "Smeared_Observables", u_smr);
00488 
00489 
00490       //
00491       // DB storage
00492       //
00493       BinaryStoreDB< SerialDBKey<KeyMesonElementalOperator_t>, SerialDBData<ValMesonElementalOperator_t> > qdp_db;
00494 
00495       // Write the meta-data and the binary for this operator
00496       {
00497         XMLBufferWriter file_xml;
00498 
00499         push(file_xml, "DBMetaData");
00500         write(file_xml, "id", "blockMesonElemOp");
00501         write(file_xml, "lattSize", QDP::Layout::lattSize());
00502         write(file_xml, "blockSize", params.param.block_size);
00503         write(file_xml, "decay_dir", params.param.decay_dir);
00504         write(file_xml, "Weights", eigen_source.getEvalues());
00505         write(file_xml, "Params", params.param);
00506         write(file_xml, "Config_info", gauge_xml);
00507         write(file_xml, "Op_Info",params.param.displacement_list);
00508         pop(file_xml);
00509 
00510         std::string file_str(file_xml.str());
00511         qdp_db.setMaxUserInfoLen(file_str.size());
00512 
00513         qdp_db.open(params.named_obj.meson_op_file, O_RDWR | O_CREAT, 0664);
00514 
00515         qdp_db.insertUserdata(file_str);
00516       }
00517 
00518 
00519       // Keep track of no displacements and zero momentum
00520       multi1d<int> no_displacement;
00521       multi1d<int> zero_mom(3); zero_mom = 0;
00522 
00523       //
00524       // Meson operators
00525       //
00526       // The creation and annihilation operators are the same without the
00527       // spin matrices.
00528       //
00529       QDPIO::cout << "Building meson operators" << endl;
00530 
00531       push(xml_out, "ElementalOps");
00532 
00533       // Loop over all time slices for the source. This is the same 
00534       // as the subsets for  phases
00535 
00536       //Make the block Set                             
00537       Set blocks;
00538       blocks.make(BlockFunc(params.param.decay_dir, params.param.block_size));
00539 
00540       // Loop over each operator 
00541       for(int l=0; l < params.param.displacement_list.size(); ++l)
00542       {
00543         StopWatch watch;
00544 
00545         QDPIO::cout << "Elemental operator: op = " << l << endl;
00546 
00547         // Make sure displacement is something sensible
00548         multi1d<int> disp = normDisp(params.param.displacement_list[l]);
00549 
00550         QDPIO::cout << "displacement = " << disp << endl;
00551 
00552         // Build the operator
00553         swiss.reset();
00554         swiss.start();
00555 
00556         for(int b(0); b < blocks.numSubsets(); b++)
00557         {
00558           int blk_left = b;
00559           vector<int> blk_couplings;
00560 
00561           // call a routine that calculate the couplings
00562           blk_couplings = block_couplings(b, blocks, disp, params.param.displacement_length);
00563 
00564           for(int blk_c(0); blk_c < blk_couplings.size(); blk_c++)
00565           {
00566             int blk_right = blk_couplings[blk_c];
00567             QDPIO::cout << "Doing block: " << blk_left << " " << blk_right << endl;
00568 
00569             // Big loop over the momentum projection
00570             for(int mom_num = 0; mom_num < phases.numMom(); ++mom_num) 
00571             {
00572               // The keys for the spin and displacements for this particular elemental operator
00573               // No displacement for left colorvector, only displace right colorvector
00574               // Invert the time - make it an independent key
00575               multi1d<KeyValMesonElementalOperator_t> buf(phases.numSubsets());
00576               for(int t=0; t < phases.numSubsets(); ++t)
00577               {
00578                 buf[t].key.key().t_slice       = t;
00579                 buf[t].key.key().mom           = phases.numToMom(mom_num);
00580                 buf[t].key.key().displacement_length = params.param.displacement_length;
00581                 buf[t].key.key().displacement  = disp; // only right colorvector
00582                 buf[t].key.key().blk_l      = blk_left;
00583                 buf[t].key.key().blk_r     = blk_right;
00584                 buf[t].val.data().op.resize(params.param.num_vecs,params.param.num_vecs);
00585                     
00586                 if ( params.param.orthog_basis && 
00587                      (phases.numToMom(mom_num)) == zero_mom && 
00588                      (disp == no_displacement) )
00589                 {
00590                   buf[t].val.data().type_of_data = COLORVEC_MATELEM_TYPE_ONE;
00591                 }
00592                 else
00593                 {
00594                   buf[t].val.data().type_of_data = COLORVEC_MATELEM_TYPE_GENERIC;
00595                 }
00596               }
00597 
00598               for(int j = 0; j < params.param.num_vecs; ++j)
00599               {
00600                 // Displace the right vector and multiply by the momentum phase
00601                 LatticeColorVector tt = zero;
00602                 tt[blocks[blk_right]] = eigen_source.getEvectors()[j];
00603                 LatticeColorVector shift_vec = phases[mom_num] * 
00604                   displace(u_smr, tt, params.param.displacement_length, disp);
00605 
00606                 for(int i = 0; i <  params.param.num_vecs; ++i)
00607                 {
00608                   watch.reset();
00609                   watch.start();
00610                         
00611                   tt = zero;
00612                   tt[blocks[blk_left]] = eigen_source.getEvectors()[i];
00613 
00614                   // Contract over color indices
00615                   // Do the relevant quark contraction
00616                   LatticeComplex lop = localInnerProduct(tt, shift_vec);
00617                         
00618                   // Slow fourier-transform
00619                   multi1d<ComplexD> op_sum = sumMulti(lop, phases.getSet());
00620                         
00621                   watch.stop();
00622                         
00623                   for(int t=0; t < op_sum.size(); ++t)
00624                   {
00625                     buf[t].val.data().op(i,j) = op_sum[t];
00626                   }
00627 
00628                   //  write(xml_out, "elem", key.key());  // debugging
00629                 } // end for j
00630               } // end for i
00631 
00632               QDPIO::cout << "insert: mom= " << phases.numToMom(mom_num) << " displacement= " << disp << endl; 
00633               for(int t=0; t < phases.numSubsets(); ++t)
00634               {
00635                 qdp_db.insert(buf[t].key, buf[t].val);
00636               }
00637                 
00638             } // mom_num
00639 
00640           }// block couplings loop
00641         }// loop over blocks
00642         swiss.stop();
00643         
00644         QDPIO::cout << "Meson operator= " << l 
00645                     << "  time= "
00646                     << swiss.getTimeInSeconds() 
00647                     << " secs" << endl;
00648         
00649       } // for l
00650       
00651       pop(xml_out); // ElementalOps
00652 
00653       QDPIO::cout << "Meson Operator written:"
00654                   << "  time= " << swiss.getTimeInSeconds() << " secs" << endl;
00655 
00656       // Close the namelist output file XMLDAT
00657       pop(xml_out);     // MesonMatElemColorVector
00658 
00659       snoop.stop();
00660       QDPIO::cout << name << ": total time = " 
00661                   << snoop.getTimeInSeconds() 
00662                   << " secs" << endl;
00663 
00664       QDPIO::cout << name << ": ran successfully" << endl;
00665 
00666       END_CODE();
00667     } // func
00668   } // namespace InlineMesonBlockMatElemEnv
00669 
00670   /*! @} */  // end of group hadron
00671 
00672 } // namespace Chroma
00673 

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