00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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>
00025 #include <util/verbose.h>
00026 #include <util/error.h>
00027 #include <string.h>
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
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
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
00058
00059
00060
00061
00062
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
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
00091
00092
00093 void QuarkPropS::setupQuarkPropS()
00094 {
00095 char *fname = "setupQuarkPropS()";
00096
00097
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
00119
00120 QuarkPropSMng::qadd(this);
00121
00122
00123
00124
00125 ++prop_count;
00126
00127 }
00128
00129
00130
00131
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
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
00155
00156 void QuarkPropS::destroyQuarkPropS(int id)
00157 {
00158 QuarkPropSMng::destroyQuarkPropS(id);
00159 }
00160
00161
00162
00163
00164
00165 void QuarkPropS::setPntSrc(const int *src_p, int color)
00166 {
00167 VRB.Func(cname,"setPntSrc(const int *, int)");
00168
00169
00170
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
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
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
00203
00204
00205
00206 static int hasOverlapSrc(const int *src_origin, const int *src_end)
00207 {
00208
00209
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
00219
00220 return 1;
00221 }
00222
00223
00224
00225
00226
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
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
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
00266
00267
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 }
00276
00277
00278
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
00293
00294
00295
00296
00297
00298
00299
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
00307
00308
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
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
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
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;
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
00382 vecTimesEquFloat(sln, GJP.XiBare()/GJP.XiV(), 2*vsize);
00383
00384
00385
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
00398
00399 if (qarg.sln == NONLOCAL) {
00400 Matrix **agm = lat.FixGaugePtr();
00401 coulomb(sln, agm, qarg.src.dir);
00402 }
00403 }
00404 }
00405
00406
00407
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
00449
00450 QuarkPropSMng::QuarkPropSMng()
00451 {
00452 char *fname = "QuarkPropSMng()";
00453 VRB.Func(cname, fname);
00454
00455
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
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
00490
00491 void QuarkPropSMng::qadd(QuarkPropS *qp)
00492 {
00493 char *fname = "qadd(QuarkPropS *)";
00494 VRB.Func(cname, fname);
00495
00496
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
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
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
00533
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
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;
00564 VRB.Flow(cname,fname,"QuarkPropS of id = %d is destroyed\n", id);
00565 }
00566 }
00567
00568
00569 CPS_END_NAMESPACE