inline_stoch_meson_w.cc

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

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