00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 CPS_END_NAMESPACE
00019 #include <alg/w_all.h>
00020 #include <util/gjp.h>
00021 #include <util/error.h>
00022 #include <util/verbose.h>
00023 #include <util/sproj_tr.h>
00024 #include <util/lattice.h>
00025 #include <util/qcdio.h>
00026 #include <util/data_types.h>
00027 CPS_START_NAMESPACE
00028
00029
00030 CPS_END_NAMESPACE
00031 #include <comms/glb.h>
00032 #include <comms/scu.h>
00033 #include <alg/alg_w_spect.h>
00034 CPS_START_NAMESPACE
00035
00036
00037
00038
00039
00040
00041 char * WspectAxialCurrent::d_class_name = "WspectAxialCurrent";
00042
00043
00044
00045
00046 WspectAxialCurrent::WspectAxialCurrent(Lattice & lat,
00047 WspectArg & arg,
00048 const WspectHyperRectangle & whr,
00049 char * ap_corr_outfile )
00050 : d_lat(lat), d_whr(whr), ap_filename(ap_corr_outfile), warg(arg)
00051 {
00052
00053 VRB.Func(d_class_name, ctor_str);
00054
00055
00056 if (lat.Fclass() == F_CLASS_DWF && ap_corr_outfile != 0) {
00057
00058
00059
00060
00061 ls_glb = GJP.SnodeSites() * GJP.Snodes();
00062 prop_dir = d_whr.dir();
00063 glb_walls = glb_sites[prop_dir];
00064 {
00065 const int *low = d_whr.lclMin();
00066 const int *high = d_whr.lclMax();
00067 for (int i = 0; i < LORENTZs; ++i) {
00068 lclMin[i] = low[i];
00069 lclMax[i] = high[i];
00070 }
00071 }
00072
00073
00074
00075
00076
00077 {
00078 int fsize = glb_walls * sizeof(Float);
00079
00080
00081 d_local_p = (Float *) smalloc(fsize);
00082
00083 if (!d_local_p)
00084 ERR.Pointer(d_class_name, ctor_str, empty_str);
00085
00086 VRB.Smalloc(d_class_name, ctor_str, empty_str, d_local_p, fsize);
00087
00088 Float *flt_p = (Float *)d_local_p;
00089 {
00090 for ( int i = 0; i < glb_walls; i++)
00091 *flt_p++ = 0.0;
00092 }
00093
00094
00095 d_local_p_wall = (Float *) smalloc(fsize);
00096
00097 if (!d_local_p_wall)
00098 ERR.Pointer(d_class_name, ctor_str, empty_str);
00099
00100 VRB.Smalloc(d_class_name, ctor_str, empty_str, d_local_p_wall, fsize);
00101
00102 flt_p = (Float *)d_local_p_wall;
00103 {
00104 for ( int i = 0; i < glb_walls; i++)
00105 *flt_p++ = 0.0;
00106 }
00107
00108
00109 d_conserved_p = (Float *) smalloc(fsize);
00110
00111 if (!d_conserved_p)
00112 ERR.Pointer(d_class_name, ctor_str, empty_str);
00113
00114 VRB.Smalloc(d_class_name, ctor_str, empty_str, d_conserved_p, fsize);
00115
00116 flt_p = (Float *)d_conserved_p;
00117 {
00118 for ( int i = 0; i < glb_walls; i++)
00119 *flt_p++ = 0.0;
00120 }
00121 }
00122
00123
00124
00125
00126 {
00127 int d_size_4d = GJP.VolNodeSites() * SPINORs ;
00128
00129 d_data_p1 = (IFloat *) smalloc(d_size_4d * sizeof(IFloat));
00130 if ( d_data_p1 == 0)
00131 ERR.Pointer(d_class_name,ctor_str, "d_data_p1");
00132 VRB.Smalloc(d_class_name,ctor_str, "d_data_p1", d_data_p1,
00133 d_size_4d * sizeof(IFloat));
00134
00135 d_data_p2 = (IFloat *) smalloc(d_size_4d * sizeof(IFloat));
00136 if ( d_data_p2 == 0)
00137 ERR.Pointer(d_class_name,ctor_str, "d_data_p2");
00138 VRB.Smalloc(d_class_name,ctor_str, "d_data_p2", d_data_p2,
00139 d_size_4d * sizeof(IFloat));
00140 }
00141
00142
00143
00144
00145
00146 {
00147 tmp_p1 = (Float *)smalloc(SPINORs * sizeof(Float));
00148 if (tmp_p1 == 0)
00149 ERR.Pointer(d_class_name, ctor_str, "tmp_p1") ;
00150 VRB.Smalloc(d_class_name, ctor_str, "tmp_p1", tmp_p1,
00151 SPINORs * sizeof(Float)) ;
00152
00153 tmp_p2 = (Float *)smalloc(SPINORs * sizeof(Float));
00154 if (tmp_p2 == 0)
00155 ERR.Pointer(d_class_name, ctor_str, "tmp_p2") ;
00156 VRB.Smalloc(d_class_name, ctor_str, "tmp_p2", tmp_p2,
00157 SPINORs * sizeof(Float)) ;
00158
00159 }
00160
00161
00162
00163
00164
00165 {
00166 v1_g5 = (Float *)smalloc(SPINORs * sizeof(Float));
00167 if (v1_g5 == 0)
00168 ERR.Pointer(d_class_name, ctor_str, "v1_g5") ;
00169 VRB.Smalloc(d_class_name, ctor_str, "v1_g5", v1_g5,
00170 SPINORs * sizeof(Float)) ;
00171
00172 v1_next_g5 = (Float *)smalloc(d_class_name, ctor_str,
00173 "v1_next_g5", SPINORs * sizeof(Float));
00174 if (v1_next_g5 == 0)
00175 ERR.Pointer(d_class_name, ctor_str, "v1_next_g5") ;
00176
00177
00178
00179 }
00180
00181
00182
00183
00184 sproj_tr[SPROJ_XM] = sprojTrXm;
00185 sproj_tr[SPROJ_YM] = sprojTrYm;
00186 sproj_tr[SPROJ_ZM] = sprojTrZm;
00187 sproj_tr[SPROJ_TM] = sprojTrTm;
00188 sproj_tr[SPROJ_XP] = sprojTrXp;
00189 sproj_tr[SPROJ_YP] = sprojTrYp;
00190 sproj_tr[SPROJ_ZP] = sprojTrZp;
00191 sproj_tr[SPROJ_TP] = sprojTrTp;
00192
00193 }
00194
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 WspectAxialCurrent::~WspectAxialCurrent()
00204 {
00205
00206 VRB.Func(d_class_name, dtor_str);
00207
00208 if (d_lat.Fclass() == F_CLASS_DWF && ap_filename != 0) {
00209
00210 sfree(d_class_name, dtor_str, "v1_next_g5", v1_next_g5);
00211
00212
00213 VRB.Func(d_class_name, dtor_str);
00214 VRB.Sfree(d_class_name, dtor_str, empty_str, v1_g5);
00215 sfree(v1_g5);
00216
00217 VRB.Func(d_class_name, dtor_str);
00218 VRB.Sfree(d_class_name, dtor_str, empty_str, tmp_p2);
00219 sfree(tmp_p2);
00220
00221 VRB.Func(d_class_name, dtor_str);
00222 VRB.Sfree(d_class_name, dtor_str, empty_str, tmp_p1);
00223 sfree(tmp_p1);
00224
00225 VRB.Func(d_class_name, dtor_str);
00226 VRB.Sfree(d_class_name, dtor_str, empty_str, d_data_p2);
00227 sfree(d_data_p2);
00228
00229 VRB.Func(d_class_name, dtor_str);
00230 VRB.Sfree(d_class_name, dtor_str, empty_str, d_data_p1);
00231 sfree(d_data_p1);
00232
00233 VRB.Func(d_class_name, dtor_str);
00234 VRB.Sfree(d_class_name, dtor_str, empty_str, d_conserved_p);
00235 sfree(d_conserved_p);
00236
00237 VRB.Func(d_class_name, dtor_str);
00238 VRB.Sfree(d_class_name, dtor_str, empty_str, d_local_p);
00239 sfree(d_local_p);
00240
00241 VRB.Func(d_class_name, dtor_str);
00242 VRB.Sfree(d_class_name, dtor_str, empty_str, d_local_p_wall);
00243 sfree(d_local_p_wall);
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void WspectAxialCurrent::measureAll(Vector * data_5d_p) {
00256
00257 measureConserved(data_5d_p);
00258
00259
00260
00261
00262
00263
00264 if ( warg.source_kind == WALL_W || warg.source_kind == BOX_W )
00265 {
00266 measureLocalWall(data_5d_p);
00267 }
00268
00269
00270
00271
00272 measureLocalPoint(data_5d_p);
00273
00274
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 void WspectAxialCurrent::measureConserved(Vector * data_5d_p) {
00286
00287 Matrix *gauge_field = d_lat.GaugeField();
00288
00289
00290 for (int s = 0; s < ls_glb/2; s++) {
00291 d_lat.Ffive2four((Vector *) d_data_p1, data_5d_p, s, s);
00292 d_lat.Ffive2four((Vector *) d_data_p2, data_5d_p, ls_glb-1-s, ls_glb-1-s);
00293
00294 {
00295 int lcl_walls = lcl_sites[prop_dir];
00296
00297 for( int lclW = 0; lclW < lcl_walls; ++lclW) {
00298 int lcl[LORENTZs];
00299 int lcl_next[LORENTZs];
00300
00301
00302 lclMin[prop_dir]=lclMax[prop_dir] = lclW;
00303
00304 for(lcl[0]=lclMin[0]; lcl[0]<=lclMax[0]; lcl[0]++)
00305 for(lcl[1]=lclMin[1]; lcl[1]<=lclMax[1]; lcl[1]++)
00306 for(lcl[2]=lclMin[2]; lcl[2]<=lclMax[2]; lcl[2]++)
00307 for(lcl[3]=lclMin[3]; lcl[3]<=lclMax[3]; lcl[3]++) {
00308
00309 int lcl_offset = siteOffset(lcl) * SPINORs ;
00310
00311
00312 for (int i = 0; i < LORENTZs; i++ )
00313 lcl_next[i] = ( (i == prop_dir) ? (lcl[i]+1)%lcl_sites[i]
00314 : lcl[i] );
00315
00316 int lcl_next_offset = siteOffset(lcl_next) * SPINORs;
00317
00318
00319 Matrix * link = gauge_field + siteOffset(lcl) * 4 + prop_dir ;
00320
00321 {
00322 Float * v1, * v2;
00323 Float * v1_next, * v2_next;
00324 Float coeff = 1.0;
00325
00326
00327 v1 = (Float *)d_data_p1+lcl_offset ;
00328
00329 v2 = (Float *)d_data_p2+lcl_offset ;
00330
00331
00332
00333 if ((lcl[prop_dir]+1) == lcl_sites[prop_dir]) {
00334 getPlusData( (IFloat *)tmp_p1,
00335 (IFloat *)d_data_p1+lcl_next_offset, SPINORs,
00336 prop_dir) ;
00337 getPlusData( (IFloat *)tmp_p2,
00338 (IFloat *)d_data_p2+lcl_next_offset, SPINORs,
00339 prop_dir) ;
00340 v1_next = tmp_p1;
00341 v2_next = tmp_p2;
00342
00343
00344 switch( prop_dir ) {
00345 case 0:
00346 if (GJP.XnodeBc()==BND_CND_APRD) coeff = -coeff ;
00347 break;
00348 case 1:
00349 if (GJP.YnodeBc()==BND_CND_APRD) coeff = -coeff ;
00350 break;
00351 case 2:
00352 if (GJP.ZnodeBc()==BND_CND_APRD) coeff = -coeff ;
00353 break;
00354 case 3:
00355 if (GJP.TnodeBc()==BND_CND_APRD) coeff = -coeff ;
00356 break;
00357 }
00358
00359 } else {
00360 v1_next = (Float *)d_data_p1+lcl_next_offset ;
00361 v2_next = (Float *)d_data_p2+lcl_next_offset ;
00362 }
00363
00364 {
00365
00366 d_lat.Gamma5((Vector *) v1_g5, (Vector *) v1, 1 );
00367
00368
00369 d_lat.Gamma5((Vector *) v1_next_g5, (Vector *) v1_next, 1 );
00370
00371 Matrix tmp1, tmp2, f;
00372 Float result = 0.0 ;
00373
00374
00375
00376 sproj_tr[prop_dir+4]((IFloat *)&tmp1,
00377 (IFloat *)v1_next_g5,
00378 (IFloat *)v2, 1, 0, 0);
00379
00380 f.DotMEqual(*link, tmp1);
00381
00382 result = f.ReTr();
00383
00384
00385
00386 sproj_tr[prop_dir]( (IFloat *)&tmp2,
00387 (IFloat *)v1_g5,
00388 (IFloat *)v2_next, 1, 0, 0);
00389
00390 tmp1.Dagger(*link);
00391 f.DotMEqual(tmp1, tmp2);
00392 result -= f.ReTr();
00393
00394 result *= coeff;
00395
00396 *( d_conserved_p + lclW + lcl2glb_offset[prop_dir] ) += result;
00397 }
00398
00399 }
00400 }
00401 }
00402 }
00403 }
00404
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 void WspectAxialCurrent::measureLocalWall(Vector * data_5d_p) {
00416 char *fname = "measureLocalWall(Vector *)";
00417 VRB.Func(d_class_name,fname);
00418
00419 int box_b[LORENTZs];
00420 int box_e[LORENTZs];
00421 FermionVector data_4d;
00422 d_lat.Ffive2four((Vector *)data_4d.data(), data_5d_p, ls_glb-1, 0);
00423
00424
00425
00426
00427
00428
00429 data_4d.gaugeFixSink(d_lat, prop_dir);
00430
00431 if (warg.source_kind == WALL_W)
00432 {
00433 for ( int n = 0; n < LORENTZs; n++ ){
00434 box_b[n] = 0;
00435 box_e[n] = glb_sites[n] - 1;
00436 }
00437 data_4d.sumOverHyperPlane(prop_dir,box_b,box_e);
00438
00439 }
00440
00441
00442
00443 else if ( warg.source_kind == BOX_W ){
00444 for ( int n = 0; n < LORENTZs; n++ ){
00445 box_b[n] = warg.src_box_b[n];
00446 box_e[n] = warg.src_box_e[n];
00447 }
00448
00449 switch (warg.zero_mom_box_snk){
00450
00451 case 0:
00452 data_4d.sumOverHyperPlane(prop_dir,box_b,box_e);
00453 break;
00454 case 1:
00455 data_4d.sumOverHyperPlaneZeroMom(prop_dir,box_b,box_e);
00456 break;
00457 }
00458
00459 }
00460
00461
00462 measureLocal(data_4d.data(), d_local_p_wall);
00463
00464
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 void WspectAxialCurrent::measureLocalPoint(Vector * data_5d_p) {
00476
00477 d_lat.Ffive2four((Vector *) d_data_p1, data_5d_p, ls_glb-1, 0);
00478 measureLocal(d_data_p1, d_local_p);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 void WspectAxialCurrent::measureLocal(const Float *ferm_vec_4d, Float *out) {
00490
00491 int lcl_walls = lcl_sites[prop_dir];
00492
00493 for( int lclW = 0; lclW < lcl_walls; ++lclW) {
00494 int lcl[LORENTZs];
00495
00496
00497 lclMin[prop_dir]=lclMax[prop_dir] = lclW;
00498
00499 for(lcl[0]=lclMin[0]; lcl[0]<=lclMax[0]; lcl[0]++)
00500 for(lcl[1]=lclMin[1]; lcl[1]<=lclMax[1]; lcl[1]++)
00501 for(lcl[2]=lclMin[2]; lcl[2]<=lclMax[2]; lcl[2]++)
00502 for(lcl[3]=lclMin[3]; lcl[3]<=lclMax[3]; lcl[3]++) {
00503
00504 int lcl_offset = siteOffset(lcl) * SPINORs ;
00505
00506 Complex * v1 = (Complex *) (ferm_vec_4d + lcl_offset) ;
00507
00508 Complex d_proj[DIRACs][DIRACs];
00509
00510 {
00511 IFloat *p = (IFloat *) d_proj;
00512 for(int i = 0; i < COMPLEXs*DIRACs*DIRACs; i++)
00513 *p++ = 0;
00514 }
00515
00516
00517
00518 {
00519 for(int D1x = 0; D1x < DIRACs/2; D1x ++ )
00520 for(int D2x = DIRACs/2; D2x< DIRACs; D2x ++) {
00521
00522 const Complex * v1_p = v1 + COLORs * D1x;
00523 const Complex * v2_p = v1 + COLORs * D2x;
00524
00525 d_proj[D1x][D2x] += v2_p[0]*conj(v1_p[0]);
00526 d_proj[D1x][D2x] += v2_p[1]*conj(v1_p[1]);
00527 d_proj[D1x][D2x] += v2_p[2]*conj(v1_p[2]);
00528
00529 d_proj[D2x][D1x] += v1_p[0]*conj(v2_p[0]);
00530 d_proj[D2x][D1x] += v1_p[1]*conj(v2_p[1]);
00531 d_proj[D2x][D1x] += v1_p[2]*conj(v2_p[2]);
00532 }
00533
00534 }
00535
00536 Complex result(0.0, 0.0), I(0, 1);
00537
00538
00539
00540 switch(prop_dir) {
00541 case 0 :
00542 result -= d_proj[0][3];
00543 result -= d_proj[1][2];
00544 result += d_proj[2][1];
00545 result += d_proj[3][0];
00546 result *= I;
00547 break;
00548 case 1 :
00549 result += d_proj[0][3];
00550 result -= d_proj[1][2];
00551 result -= d_proj[2][1];
00552 result += d_proj[3][0];
00553 break;
00554 case 2 :
00555 result -= d_proj[0][2];
00556 result += d_proj[1][3];
00557 result += d_proj[2][0];
00558 result -= d_proj[3][1];
00559 result *= I;
00560 break;
00561 case 3 :
00562 result -= d_proj[0][2];
00563 result -= d_proj[1][3];
00564 result -= d_proj[2][0];
00565 result -= d_proj[3][1];
00566 break;
00567 }
00568
00569 *( out + lclW + lcl2glb_offset[prop_dir] ) += result.real();
00570
00571 }
00572 }
00573
00574 }
00575
00576
00577
00578
00579
00580 void WspectAxialCurrent::doSum()
00581 {
00582 char *fname = "doSum";
00583 VRB.Func(d_class_name, fname);
00584
00585
00586
00587 {
00588 Float *flt_p = d_conserved_p;
00589 for (int i=0; i < glb_walls; i++)
00590 glb_sum(flt_p++);
00591 }
00592
00593
00594
00595 {
00596 Float *flt_p = d_local_p;
00597 for (int i=0; i < glb_walls; i++)
00598 glb_sum(flt_p++);
00599 }
00600
00601
00602 {
00603 Float *flt_p = d_local_p_wall;
00604 for (int i=0; i < glb_walls; i++)
00605 glb_sum(flt_p++);
00606 }
00607
00608 }
00609
00610
00611
00612
00613 void WspectAxialCurrent::print() const
00614 {
00615 #if TARGET==cpsMPI
00616 using MPISCU::fprintf;
00617 #endif
00618 char *fname = "print";
00619 VRB.Func(d_class_name, fname);
00620
00621
00622
00623
00624 FILE *fp=NULL;
00625
00626 if ( !ap_filename || !(fp = Fopen(ap_filename, "a")) )
00627 ERR.FileA(d_class_name,fname, ap_filename);
00628
00629 for (int wall = 0; wall < glb_walls; ++wall) {
00630
00631 IFloat conserved_result, local_result, local_result_wall;
00632 conserved_result =
00633 d_conserved_p[(d_whr.glbCoord() + wall)%glb_walls];
00634
00635 local_result = d_local_p[(d_whr.glbCoord() + wall)%glb_walls];
00636 local_result_wall = d_local_p_wall[(d_whr.glbCoord() + wall)%glb_walls];
00637
00638 Fprintf(fp, "%d %d %16.12e %16.12e %16.12e\n",
00639 AlgWspect::GetCounter(), wall,
00640 local_result,conserved_result,
00641 local_result_wall
00642 );
00643 }
00644 Fclose(fp);
00645
00646 }
00647
00648
00649
00650
00651 void WspectAxialCurrent::dumpData(char *filename) const {
00652
00653 #if TARGET==cpsMPI
00654 using MPISCU::fprintf;
00655 #endif
00656 FILE *fp;
00657
00658 if (filename && (fp = Fopen(filename, "a"))) {
00659 for (int i = 0; i < glb_walls; ++i) {
00660 Fprintf(fp, "%e %e\n", d_local_p[i], d_conserved_p[i]);
00661 }
00662 Fclose(fp);
00663 } else {
00664 ERR.FileA(d_class_name, "dumpData", filename);
00665 }
00666
00667 }
00668
00669
00670
00671 CPS_END_NAMESPACE