Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

quark_prop_s.C

Go to the documentation of this file.
00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003 //--------------------------------------------------------------------
00004 //  CVS keywords
00005 //
00006 //  $Author: chulwoo $
00007 //  $Date: 2008/07/21 16:56:44 $
00008 //  $Header: /space/cvs/cps/cps++/src/alg/alg_s_spect/quark_prop_s.C,v 1.13 2008/07/21 16:56:44 chulwoo Exp $
00009 //  $Id: quark_prop_s.C,v 1.13 2008/07/21 16:56:44 chulwoo Exp $
00010 //  $Name: v5_0_8 $
00011 //  $Locker:  $
00012 //  $RCSfile: quark_prop_s.C,v $
00013 //  $Revision: 1.13 $
00014 //  $Source: /space/cvs/cps/cps++/src/alg/alg_s_spect/quark_prop_s.C,v $
00015 //  $State: Exp $
00016 //
00017 //--------------------------------------------------------------------
00018 // quark_prop_s.C
00019 
00020 CPS_END_NAMESPACE
00021 #include <alg/quark_prop_s.h>
00022 #include <util/smalloc.h>
00023 #include <util/gjp.h>
00024 #include <util/vector.h>        // uDotXEqual()
00025 #include <util/verbose.h>
00026 #include <util/error.h>
00027 #include <string.h>                     // memcpy()
00028 #ifdef PARALLEL
00029 #include <comms/sysfunc_cps.h>
00030 #endif
00031 #include <alg/myenum.h>
00032 #include <util/qcdio.h>
00033 CPS_START_NAMESPACE
00034 
00035 //------------------------------------------------------------
00036 //  class static members initializations
00037 //------------------------------------------------------------
00038 
00039 char QuarkPropS::cname[] = "QuarkPropS";
00040 Float* QuarkPropS::qSrc = 0;    
00041 int QuarkPropS::prop_count = 0;
00042 
00043 char QuarkPropSMng::cname[] = "QuarkPropSMng";
00044 int QuarkPropSMng::isInit = 0;
00045 int* QuarkPropSMng::slice = 0;
00046 Float ***QuarkPropSMng::qtab = 0;
00047 
00048 //------------------------------------------------------------
00049 //  static variables used inside this file
00050 //------------------------------------------------------------
00051 
00052 static int nx[4];
00053 
00054 static int vsize;
00055 static int node_origin[4];
00056 static int node_end[4];
00057         // used when setting up quark source. 
00058         // and node_origin[] is the global (x,y,z,t)
00059         // coordinates of the origin of this node 
00060 
00061 //------------------------------------------------------------
00062 // functions local to this file
00063 //------------------------------------------------------------
00064 
00065 inline int max(int a, int b) { return a > b ? a : b; }
00066 inline int min(int a, int b) { return a < b ? a : b; }
00067 
00068 void getNodeOriginEnd()
00069 {
00070    node_origin[0] =  GJP.XnodeCoor() * nx[0];
00071    node_origin[1] =  GJP.YnodeCoor() * nx[1];
00072    node_origin[2] =  GJP.ZnodeCoor() * nx[2];
00073    node_origin[3] =  GJP.TnodeCoor() * nx[3];
00074    for (int i = 0 ; i < 4; ++i) {
00075      node_end[i] = node_origin[i] + nx[i] - 1; 
00076    }
00077 }
00078 
00079 //------------------------------------------------------------
00080 // private function: index the staggered fermion vector correctly
00081 //------------------------------------------------------------
00082 
00083 int QuarkPropS::X_OFFSET(const int *x)
00084 {
00085   return lat.FsiteOffsetChkb(x) * VECT_LEN
00086          + ((x[0]+x[1]+x[2]+x[3]) & 1 ? vsize : 0);
00087 }
00088 
00089 //------------------------------------------------------------
00090 //  qSrc is allocated here 
00091 //------------------------------------------------------------
00092 
00093 void QuarkPropS::setupQuarkPropS() 
00094 {
00095     char *fname = "setupQuarkPropS()";
00096     //--------------------------------------------
00097     // need to do class initializations?
00098     //--------------------------------------------
00099 
00100     if(prop_count == 0)
00101     {
00102         nx[0] = GJP.XnodeSites();
00103         nx[1] = GJP.YnodeSites();
00104         nx[2] = GJP.ZnodeSites();
00105         nx[3] = GJP.TnodeSites();
00106  
00107         vsize = GJP.VolNodeSites() * VECT_LEN / 2;
00108         qSrc = (Float *)smalloc(2*vsize*sizeof(Float)); 
00109         if(qSrc == 0)
00110           ERR.Pointer(cname,fname, "qSrc");
00111         VRB.Smalloc(cname,fname, "qSrc", qSrc, 2*vsize*sizeof(Float));
00112 
00113         getNodeOriginEnd();
00114     }
00115 
00116 
00117     //--------------------------------------------
00118     // register this quark propagator
00119     //--------------------------------------------
00120     QuarkPropSMng::qadd(this);
00121 
00122     //--------------------------------------------
00123     // increase the propagator counter
00124     //--------------------------------------------
00125     ++prop_count;
00126 
00127 }
00128 
00129 
00130 //------------------------------------------------------------
00131 // CTOR 
00132 //------------------------------------------------------------
00133 
00134 QuarkPropS::QuarkPropS(Lattice& lattice, StagQuarkArg& arg) 
00135 : qid(arg.qid), qarg(arg), lat(lattice)
00136 { VRB.Func(cname,"QuarkPropS(Lattice& , StagQuarkArg& )"); }
00137 
00138 //------------------------------------------------------------
00139 // DTOR free the source vector if out of scope
00140 //------------------------------------------------------------
00141 
00142 QuarkPropS::~QuarkPropS() 
00143 {
00144   char *fname = "~QuarkPropS()";
00145   VRB.Func(cname,"~QuarkPropS()"); 
00146   prop_count--;
00147   if(prop_count == 0) {
00148     VRB.Sfree(cname,fname, "qSrc", qSrc);
00149     sfree(qSrc);
00150   }
00151 }
00152 
00153 //------------------------------------------------------------
00154 // free the quark propagator memory 
00155 //------------------------------------------------------------
00156 void QuarkPropS::destroyQuarkPropS(int id)
00157 {
00158   QuarkPropSMng::destroyQuarkPropS(id);
00159 }
00160         
00161 //------------------------------------------------------------
00162 //  set up Point source
00163 //------------------------------------------------------------
00164 
00165 void QuarkPropS::setPntSrc(const int *src_p, int color)
00166 { 
00167     VRB.Func(cname,"setPntSrc(const int *, int)"); 
00168 
00169     //-----------------------------------------
00170     // zero source vector first
00171     //-----------------------------------------
00172     Float *src_tmp = qSrc;
00173 
00174     for (int i = 0; i < 2*vsize; ++i) {
00175       *src_tmp++ = 0.0;  
00176     }
00177 
00178     //-----------------------------------------
00179     // determine if the POINT source is on this node
00180     //-----------------------------------------
00181     int site[4] = { src_p[0], src_p[1],src_p[2],src_p[3] };
00182     int isOnNode = 1;
00183 
00184     for (int j = 0; j < 4; j++) {
00185       isOnNode *= (site[j] >= node_origin[j]);
00186       isOnNode *= (site[j] <= node_end[j]);
00187     }
00188     //-----------------------------------------
00189     // calculate the offset and set the source
00190     //-----------------------------------------
00191     if (isOnNode) {
00192       for (int k = 0; k < 4; k++) {
00193         site[k] -= node_origin[k];
00194       }
00195       int soff = X_OFFSET(site);
00196       *(qSrc+soff+2*color) = 1.0;
00197     }
00198 
00199 }
00200 
00201 //------------------------------------------------------------
00202 // if there is overlap with src, return 1;
00203 // else return 0;
00204 //------------------------------------------------------------
00205 
00206 static int hasOverlapSrc(const int *src_origin, const int *src_end) 
00207 {
00208     //---------------------------------------
00209     // No overlap with source on this node
00210     //---------------------------------------
00211     for (int i = 0; i < 4; ++i) {
00212       if ( src_end[i] < node_origin[i] || 
00213            src_origin[i] > node_end[i])
00214         return 0;   
00215     }
00216 
00217     //---------------------------------------
00218     // there IS overlap with the source
00219     //---------------------------------------
00220     return 1;
00221 }
00222 
00223 
00224    
00225 //------------------------------------------------------------
00226 // set up a wall source: Z-wall or 2Z-wall
00227 //------------------------------------------------------------
00228 
00229 void QuarkPropS::setWallSrc(Matrix **gm, StagQuarkSrc& qs, int color )
00230 {
00231     char *fname = "setWallSrc(const Float **, StagQuarkSrc&, int)";
00232 
00233     VRB.Func(cname,"setWallSrc(const Float *, QuarkSrc&, int)"); 
00234     int i;
00235 
00236     //-----------------------------------------
00237     // check if the source is valid
00238     //-----------------------------------------
00239     int wall = 0;
00240     int count = 0; 
00241     for (i = 0; i < 4; ++i) {
00242       if ( qs.origin[i] == qs.end[i] ) {
00243         wall = i;
00244         count++;
00245       }
00246     }
00247     if ( count != 1 ) {
00248         ERR.General(cname, fname, "Not a 3D-wall source\n");
00249     }
00250     if ( qs.dir != wall) {
00251         ERR.General(cname, fname, "Wall source direction not correct\n");
00252     }
00253 
00254     //-----------------------------------------
00255     // zero source vector first
00256     //-----------------------------------------
00257     Float *src_tmp = qSrc;
00258 
00259     for (i = 0; i < 2*vsize; ++i) {  
00260       *src_tmp++ = 0.0;
00261     }   
00262 
00263 
00264     //-----------------------------------------------
00265     // determine if source has overlap with this node
00266     // if yes, local coordinates of the source are 
00267     // calculated
00268     //-----------------------------------------------
00269     if (hasOverlapSrc(qs.origin, qs.end)) {   
00270 
00271       int src_origin[4], src_end[4];
00272       for (i = 0; i < 4; ++i) {
00273         src_origin[i] = max(qs.origin[i], node_origin[i]) - node_origin[i];
00274         src_end[i]    = min(qs.end[i], node_end[i]) - node_origin[i];
00275       } // ASSERT: src_origin[wall] = src_end[wall]
00276     
00277       //-------------------------------------------------------
00278       // walk through the 3D world and set the sources 
00279       //-------------------------------------------------------
00280       int dir = qs.dir;
00281       int dim[4] = { nx[0], nx[1], nx[2], nx[3] };
00282       dim[dir] = 1;
00283 
00284       int i = (dir + 1)%4;
00285       int j = (dir + 2)%4;
00286       int k = (dir + 3)%4;
00287 
00288       int s[4];
00289       s[dir] = src_origin[dir];
00290 
00291       const Float *g = (Float *)gm[s[dir]] + color*VECT_LEN;
00292       // Note:
00293       // base offset to the source slice and color offset
00294       // CAUTION:
00295       // g_dagger * delta is
00296       //
00297       // | a11+ib11 a12+ib12 a13+ib13|^dagger   (1)     (0)     (0)
00298       // | a21+ib21 a22+ib22 a23+ib23|          (0) or  (1) or  (0)
00299       // | a31+ib31 a32+ib32 a33+ib33|          (0)     (0)     (1)
00300 
00301       for(s[i] = src_origin[i]; s[i] <= src_end[i]; s[i]++)
00302         for(s[j] = src_origin[j]; s[j] <= src_end[j]; s[j]++)
00303           for(s[k] = src_origin[k]; s[k] <= src_end[k]; s[k]++)
00304           {
00305             //--------------------------------------------------
00306             // if this is WALLZ source
00307             // or WALL2Z source with all 3d coordinates even
00308             // need to set the source on this site
00309             //--------------------------------------------------
00310             if ( qs.type == WALLZ || ( qs.type == WALL2Z)&&
00311                ( (s[i]%2 == qs.origin[i]%2) 
00312                  && (s[j]%2 == qs.origin[j]%2) 
00313                  && (s[k]%2 == qs.origin[k]%2))) {
00314 
00315               int s3d[4] = { s[0], s[1], s[2], s[3] };
00316               s3d[dir] = 0;
00317 
00318               //------------------------------------------------
00319               // set the source: g(s)^dagger * delta(s)
00320               //------------------------------------------------
00321               const Float *gp = g + MATRIX_SIZE * g_offset(s3d, dim);
00322               Float *src = qSrc + X_OFFSET(s);
00323 
00324               for(int color = 0; color < 3; color++) {
00325                 *src++ = *gp++;
00326                 *src++ = -*gp++;
00327               }
00328             }
00329           } 
00330     } 
00331 }
00332 
00333 //------------------------------------------------------------
00334 // Calculate all three columns(color) of quark propagator, and
00335 // stored in 3 vectors prop[3]. Three cases are handled here:
00336 //
00337 // 1.  POINT source is used 
00338 //
00339 // 2.  Wall sources used 
00340 //        (D + 2m) G'(x) = delta(x)_Coulomb
00341 //
00342 //     we get G'(x) = g(x)^dagger * G(x)^Coulomb.
00343 // 
00344 //     For local hadron operator using G'(x) is fine
00345 //     because 
00346 //        
00347 //        G'(x)G'(x)^dag == G(x)G(x)^dag (meson)
00348 //        e_ijk * g_i(x)*g_j(x)*g_k(x) = det(g) = 1 (nucleon)
00349 // 
00350 // 3.  Wall source used.
00351 //     Solution G(x)^Coulomb is needed because for non-local 
00352 //     hadron operators the identities in case 2 are not true.
00353 //------------------------------------------------------------
00354 
00355 void QuarkPropS::getQuarkPropS(char *results)
00356 {
00357 #if TARGET==cpsMPI
00358     using MPISCU::fprintf;
00359 #endif
00360     char *fname = "getQuarkPropS(const char *)";
00361     VRB.Func(cname, fname);
00362 
00363     int cg_iter;
00364     Float true_res;
00365     FILE *fp;           // monitoring info of CG
00366 
00367     for (int color = 0; color < 3; ++color)  {
00368       if ( qarg.src.type == S_QUARK_POINT ) {
00369         setPntSrc(qarg.src.origin, color);
00370       }
00371       else {
00372         Matrix **gm = lat.FixGaugePtr();
00373         setWallSrc(gm, qarg.src, color);
00374       }
00375 
00376       IFloat *src = (IFloat *)qSrc;
00377       IFloat *sln = (IFloat *)prop[color];
00378       cg_iter = lat.FmatInv((Vector *)sln, (Vector *)src, 
00379                             &(qarg.cg), &true_res, CNV_FRM_NO);
00380 
00381       // Added for anisotropic lattices
00382       vecTimesEquFloat(sln, GJP.XiBare()/GJP.XiV(), 2*vsize); 
00383       // End modification 
00384 
00385       // Print out monitor info of the inversion
00386       //---------------------------------------------------------------
00387       if(results != 0){
00388         if( NULL == (fp = Fopen(results, "a")) ) {
00389           ERR.FileA(cname,fname, results);
00390         }
00391         Fprintf(fp,"%e %d %e\n", IFloat(qarg.cg.mass), cg_iter, 
00392                                  IFloat(true_res));
00393         Fclose(fp);
00394       }
00395  
00396       //------------------------------------------------------
00397       // if it is non-local, realize case 3
00398       //------------------------------------------------------
00399       if (qarg.sln == NONLOCAL) {
00400         Matrix **agm = lat.FixGaugePtr();
00401         coulomb(sln, agm, qarg.src.dir); 
00402       }
00403     }
00404 }
00405 
00406 //-------------------------------------------------------------
00407 //  x = g(n1, n2, n3, n4 ) * x(n1, n2, n3, n4)
00408 //-------------------------------------------------------------
00409 
00410 void QuarkPropS::coulomb(IFloat *x, Matrix **g, int dir)
00411 {
00412   char *fname = "coulomb(IFloat *, Matrix **, int)";
00413   VRB.Func(cname, fname);
00414 
00415   Vector *vr_tmp = (Vector *)smalloc(VECT_LEN * sizeof(IFloat));
00416   if(vr_tmp == 0)
00417     ERR.Pointer(cname,fname, "vr_tmp");
00418   VRB.Smalloc(cname,fname, "vr_tmp", vr_tmp, VECT_LEN * sizeof(IFloat));
00419 
00420   int dim[4] = { nx[0], nx[1], nx[2], nx[3] };
00421   dim[dir] = 1;
00422 
00423   int i = (dir + 1)%4;
00424   int j = (dir + 2)%4;
00425   int k = (dir + 3)%4;
00426 
00427   int s[4];
00428   for(s[dir] = 0; s[dir] < nx[dir]; s[dir]++) {
00429     Matrix *g_base = g[s[dir]];
00430 
00431     for(s[i] = 0; s[i] < nx[i]; s[i]++) 
00432       for(s[j] = 0; s[j] < nx[j]; s[j]++) 
00433         for(s[k] = 0; s[k] < nx[k]; s[k]++) 
00434         {
00435           int s3d[4] = { s[0], s[1], s[2], s[3] };
00436           s3d[dir] = 0;
00437           Matrix *gp = g_base + g_offset(s3d, dim);
00438           IFloat *xp = x + X_OFFSET(s);
00439           memcpy((IFloat *)vr_tmp, xp, VECT_LEN * sizeof(IFloat));
00440           uDotXEqual(xp, (IFloat *)gp, (IFloat *)vr_tmp);
00441         }
00442   }
00443   VRB.Sfree(cname,fname, "vr_tmp",vr_tmp);
00444   sfree(vr_tmp);
00445 }
00446 
00447 //============================================================
00448 // Functions of QuarkPropSMng class
00449 //============================================================
00450 QuarkPropSMng::QuarkPropSMng()
00451 {
00452   char *fname = "QuarkPropSMng()";
00453   VRB.Func(cname, fname); 
00454   //--------------------------------------------
00455   // class initialization
00456   //--------------------------------------------
00457   if (!isInit) {
00458     qtab = (Float ***)smalloc(MAXNUMQP*sizeof(Float **));
00459     if(qtab == 0)
00460       ERR.Pointer(cname,fname, "qtab");
00461     VRB.Smalloc(cname,fname, "qtab", qtab, MAXNUMQP*sizeof(Float **));
00462 
00463     slice = (int *)smalloc(MAXNUMQP*sizeof(int));
00464     if(slice == 0)
00465       ERR.Pointer(cname,fname, "slice");
00466     VRB.Smalloc(cname,fname, "slice", slice, MAXNUMQP*sizeof(int));
00467     for (int j = 0; j < MAXNUMQP; j++) {
00468       qtab[j] = 0;
00469       slice[j] = 0;
00470     }
00471     isInit = 1;
00472   }
00473 }
00474 
00475 //------------------------------------------------------------
00476 //  DTOR
00477 //------------------------------------------------------------
00478 QuarkPropSMng::~QuarkPropSMng()
00479 {
00480   char *fname = "~QuarkPropSMng()";
00481   VRB.Func(cname,fname);
00482  
00483   QuarkPropSMng::destroyQuarkPropS();
00484   VRB.Sfree(cname,fname, "qtab",qtab);
00485   sfree(qtab);
00486 }
00487 
00488 //------------------------------------------------------------
00489 // allocate memory and register the quark propagator
00490 //------------------------------------------------------------
00491 void QuarkPropSMng::qadd(QuarkPropS *qp)
00492 {
00493   char *fname = "qadd(QuarkPropS *)";
00494   VRB.Func(cname, fname); 
00495   //--------------------------------------------
00496   // Allocate memory for this propagator
00497   //--------------------------------------------
00498   qp->prop = (Float **)smalloc(3*sizeof(Float *));
00499   if(qp->prop == 0)
00500     ERR.Pointer(cname,fname, "qp->prop");
00501   VRB.Smalloc(cname,fname, "qp->prop", qp->prop, 3*sizeof(Float *));
00502 
00503   int color;
00504   for (color = 0; color < 3; ++color) {
00505     qp->prop[color] = (Float *)smalloc(2*vsize*sizeof(Float)); 
00506     if(qp->prop[color] == 0)
00507       ERR.Pointer(cname,fname, "qp->prop[color]");
00508     VRB.Smalloc(cname,fname, "qp->prop[color]", qp->prop[color], 2*vsize*sizeof(Float));
00509   }
00510 
00511   //--------------------------------------------
00512   // always zero the propagator when registering
00513   //--------------------------------------------
00514   for (color = 0; color < 3; ++color) {
00515     Float *tmp = qp->prop[color];
00516     for(int i=0; i<2*vsize; ++i) {
00517       *tmp++ = 0;
00518     }
00519   }
00520 
00521   //--------------------------------------------
00522   // register prop and keep the prop ptr
00523   //--------------------------------------------
00524   int index = qp->qid;
00525   qtab[index] = qp->prop;
00526   slice[index] = qp->qarg.src.origin[qp->qarg.src.dir];
00527 
00528   VRB.Flow(cname,fname, "QuarkPropS of id = %d is registered\n", index);
00529 }
00530 
00531 //------------------------------------------------------------
00532 // free the quark propagator of qid = id;
00533 // By default (id = -1) all quark propagators are freed.
00534 //------------------------------------------------------------
00535 void QuarkPropSMng::destroyQuarkPropS(int id)
00536 {
00537   if (id == -1) {
00538     for (int i = 0; i < MAXNUMQP; i++) {
00539       release(i);
00540     }
00541   }
00542   else 
00543     release(id);
00544 }
00545 
00546 //------------------------------------------------------------
00547 // release the quark propagator of qid = id
00548 //------------------------------------------------------------
00549 void QuarkPropSMng::release(int id) 
00550 {
00551   char *fname = "release(int id)";
00552   VRB.Func(cname, fname); 
00553   Float **tmp_prop = qtab[id];
00554   if (tmp_prop) {       
00555     for (int color = 0; color < 3; ++color) {
00556       if (tmp_prop[color]) {
00557         VRB.Sfree(cname,fname, "tmp_prop[color]",tmp_prop[color]);
00558         sfree(tmp_prop[color]);
00559       }
00560     }   
00561     VRB.Sfree(cname,fname, "tmp_prop", tmp_prop);
00562     sfree(tmp_prop); 
00563     qtab[id] = 0;       // turn off the entry light
00564     VRB.Flow(cname,fname,"QuarkPropS of id = %d is destroyed\n", id);
00565   }
00566 }
00567 
00568 
00569 CPS_END_NAMESPACE

Generated on Sat Oct 10 14:11:20 2009 for Columbia Physics System by  doxygen 1.3.9.1