00001 #include<config.h>
00002 CPS_START_NAMESPACE
00003
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 CPS_END_NAMESPACE
00026 #include <util/qcdio.h>
00027 #include <util/enum.h>
00028 #include <math.h>
00029 #include <alg/alg_eig.h>
00030 #include <util/lattice.h>
00031 #include <util/gjp.h>
00032 #include <util/smalloc.h>
00033 #include <util/time_cps.h>
00034 #include <util/vector.h>
00035 #include <util/verbose.h>
00036 #include <util/error.h>
00037 CPS_START_NAMESPACE
00038
00039 #include <iostream>
00040 #include <fstream>
00041 #include <iomanip>
00042 using namespace std;
00043
00044 extern void gamma_5(Float *v_out, Float *v_in, int num_sites);
00045
00046 int NumChkb( RitzMatType ritz_mat)
00047 {
00048
00049 int Ncb=0;
00050 char *fname = "NumChkb(RitzType)";
00051 switch(ritz_mat)
00052 {
00053 case MAT_HERM:
00054 case MATDAG_MAT:
00055 case NEG_MATDAG_MAT:
00056 case MATDAG_MAT_NORM:
00057 case NEG_MATDAG_MAT_NORM:
00058 Ncb = 2;
00059 break;
00060
00061 case MATPC_HERM:
00062 case MATPCDAG_MATPC:
00063 case NEG_MATPCDAG_MATPC:
00064 Ncb = 1;
00065 break;
00066
00067 default:
00068 ERR.General("",fname,"RitzMatOper %d not implemented",
00069 ritz_mat);
00070 }
00071 return Ncb;
00072 }
00073
00074
00075
00081
00082 AlgEig::AlgEig(Lattice& latt,
00083 CommonArg *c_arg,
00084 EigArg *arg) :
00085 Alg(latt, c_arg)
00086 {
00087 cname = "AlgEig";
00088 char *fname = "AlgEig(L&,CommonArg*,EigArg*)";
00089 VRB.Func(cname,fname);
00090
00091
00092
00093 if(arg == 0)
00094 ERR.Pointer(cname,fname, "arg");
00095 alg_eig_arg = arg;
00096
00097 Ncb = NumChkb(alg_eig_arg->RitzMatOper);
00098
00099
00100
00101
00102
00103 int f_size = GJP.VolNodeSites() * latt.FsiteSize() * Ncb / 2;
00104 VRB.Flow(cname,fname,"f_size=%d\n",0);
00105
00106
00107 int N_eig = alg_eig_arg->N_eig;
00108
00109
00110
00111 eigenv = (Vector **) smalloc (cname,fname, "eigenv", N_eig * sizeof(Vector *));
00112
00113 for(int n = 0; n < N_eig; ++n)
00114 {
00115 eigenv[n] = (Vector *) smalloc(cname,fname, "eigenv[n]", (f_size)* sizeof(Float));
00116 }
00117
00118 lambda = (Float *) smalloc(cname,fname, "lambda", 2*N_eig * sizeof(Float));
00119
00120 chirality = (Float *) smalloc(cname,fname,"chirality", N_eig * sizeof(Float));
00121
00122 valid_eig = (int *) smalloc(cname,fname,"valid_eig",N_eig * sizeof(int));
00123
00124
00125
00126 VRB.Input(cname,fname,
00127 "N_eig = %d\n",int(N_eig));
00128 VRB.Input(cname,fname,
00129 "MaxCG = %d\n",alg_eig_arg->MaxCG);
00130 VRB.Input(cname,fname,
00131 "Mass_init = %g\n",IFloat(alg_eig_arg->Mass_init));
00132 VRB.Input(cname,fname,
00133 "Mass_final = %g\n",IFloat(alg_eig_arg->Mass_final));
00134 VRB.Input(cname,fname,
00135 "Mass_step = %g\n",IFloat(alg_eig_arg->Mass_step));
00136
00137
00138 VRB.Flow(cname,fname,"alg_eig_arg->pattern_kind=%d\n",alg_eig_arg->pattern_kind);
00139 switch( alg_eig_arg->pattern_kind ) {
00140 case ARRAY:
00141 n_masses = alg_eig_arg->Mass.Mass_len;
00142 break;
00143 case LOG:
00144 n_masses = (int) ((log(alg_eig_arg->Mass_final - alg_eig_arg->Mass_init)
00145 / log(alg_eig_arg->Mass_step)) + 1.000001);
00146 break;
00147 case LIN:
00148 n_masses = (int) (fabs((alg_eig_arg->Mass_final
00149 - alg_eig_arg->Mass_init)/alg_eig_arg->Mass_step) + 1.000001);
00150 break;
00151 default:
00152 ERR.General(cname, fname,
00153 "alg_eig_arg->pattern_kind = %d is unrecognized\n",
00154 alg_eig_arg->pattern_kind);
00155 break;
00156 }
00157 VRB.FuncEnd(cname,fname);
00158
00159 }
00160
00161
00162
00163
00164
00165 AlgEig::~AlgEig() {
00166 char *fname = "~AlgEig()";
00167 VRB.Func(cname,fname);
00168
00169
00170
00171 sfree(cname,fname, "valid_eig", valid_eig);
00172
00173 sfree(cname,fname, "chirality", chirality);
00174
00175 sfree(cname,fname, "lambda", lambda);
00176
00177 for(int n = alg_eig_arg->N_eig - 1; n >= 0; --n)
00178 {
00179 sfree(cname,fname, "eigenv[n] ",eigenv[n]);
00180 }
00181
00182 sfree(cname,fname, "eigenv", eigenv);
00183
00184
00185 }
00186
00188 void AlgEig::run()
00189 {
00190 run((Float**)0);
00191 }
00192
00193
00194
00196
00200
00201 void AlgEig::run(Float **evalues)
00202 {
00203 #if TARGET==cpsMPI
00204 using MPISCU::fprintf;
00205 #endif
00206
00207 Float time = -dclock();
00208 int iter=0;
00209 EigArg *eig_arg;
00210 char *fname = "run()";
00211 VRB.Func(cname,fname);
00212
00213
00214
00215 Lattice& lat = AlgLattice();
00216 eig_arg = alg_eig_arg;
00217 Float **hsum;
00218 const int N_eig = eig_arg->N_eig;
00219 const int f_size = GJP.VolNodeSites() * lat.FsiteSize() * Ncb / 2;
00220 int hsum_len = 0;
00221 int n;
00222
00223 if (eig_arg->print_hsum)
00224 {
00225 switch(eig_arg->hsum_dir)
00226 {
00227 case 0:
00228 hsum_len = GJP.Xnodes()*GJP.XnodeSites();
00229 break;
00230 case 1:
00231 hsum_len = GJP.Ynodes()*GJP.YnodeSites();
00232 break;
00233 case 2:
00234 hsum_len = GJP.Znodes()*GJP.ZnodeSites();
00235 break;
00236 case 3:
00237 hsum_len = GJP.Tnodes()*GJP.TnodeSites();
00238 break;
00239 case 4:
00240 if (lat.Fclass() == F_CLASS_DWF)
00241 hsum_len = GJP.Snodes()*GJP.SnodeSites();
00242 else
00243 ERR.General(cname,fname,"Invalid direction\n");
00244 break;
00245 default:
00246 ERR.General(cname,fname,"Invalid direction\n");
00247 }
00248
00249 hsum = (Float **) smalloc(cname,fname,"hsum",N_eig * sizeof(Float*));
00250
00251 for(n = 0; n < N_eig; ++n)
00252 {
00253 hsum[n] = (Float *) smalloc(cname,fname,"hsum[n]",hsum_len * sizeof(Float));
00254 }
00255 }
00256 else
00257 {
00258 hsum = (Float **) 0;
00259 }
00260
00261
00262 Vector** eig_store=0;
00263 if(eig_arg->ncorr)
00264 {
00265 eig_store = (Vector**)smalloc(cname,fname, "eig_store",N_eig * sizeof(Vector*));
00266 for(n=0;n<N_eig;++n)
00267 {
00268 eig_store[n] = (Vector*) smalloc(cname,fname, "eig_store",f_size * sizeof(Float));
00269 }
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279 int sign_dm=1;
00280
00281
00282
00283 switch( eig_arg->pattern_kind ) {
00284 case ARRAY:
00285 eig_arg->mass = eig_arg->Mass.Mass_val[0];
00286 break;
00287 case LIN:
00288
00289 sign_dm = (eig_arg->Mass_step < 0.0) ? -1 : 1;
00290 eig_arg->mass = eig_arg->Mass_init;
00291 if (sign_dm*eig_arg->Mass_init > sign_dm*eig_arg->Mass_final)
00292 ERR.General(cname,fname,"initial and final mass not valid\n");
00293 break;
00294 case LOG:
00295 eig_arg->mass = eig_arg->Mass_init;
00296 break;
00297 default:
00298 ERR.General(cname, fname,
00299 "eig_arg->pattern_kind = %d is unrecognized\n",
00300 eig_arg->pattern_kind);
00301 break;
00302 }
00303
00304
00305 for(int m=0; m<n_masses; m++){
00306
00307
00308
00309
00310
00311
00312
00313 int count(0);
00314
00315
00316
00317 if(eig_arg->ncorr && ( count > 0 ) ){
00318 for ( n=0; n<N_eig; n++ )
00319 {
00320 eig_store[n]->CopyVec(eigenv[n],f_size);
00321 }
00322 }
00323
00324
00325
00326 for(n = 0; n<N_eig; ++n)
00327 {
00328 lat.RandGaussVector(eigenv[n], 0.5, Ncb);
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 if (eig_arg->fname!=0)
00355 {
00356 FILE* filep;
00357 filep=Fopen(eig_arg->fname,"a");
00358 Fprintf(filep,"mass = %g\n",(Float)eig_arg->mass);
00359 Fclose(filep);
00360 }
00361
00362 VRB.Result(cname,fname, "mass = %g\n", (Float)eig_arg->mass);
00363
00364
00365
00366
00367 if(Ncb==2)
00368 iter = lat.FeigSolv(eigenv, lambda, chirality, valid_eig,
00369 hsum, eig_arg, CNV_FRM_YES);
00370 else if(Ncb==1)
00371 iter = lat.FeigSolv(eigenv, lambda, chirality, valid_eig,
00372 hsum, eig_arg, CNV_FRM_NO);
00373
00374
00375
00376
00377
00378
00379 #if 0
00380 iter = lat.FeigSolv(eigenv,lambda,chirality, valid_eig,
00381 hsum, eig_arg, CNV_FRM_YES);
00382 #endif
00383
00385 if (evalues != 0) {
00386 for (int eig=0; eig<eig_arg->N_eig; eig++) {
00387 evalues[eig][m] = lambda[eig];
00388 }
00389 }
00390
00391 if ( iter < 0 )
00392 {
00393 FILE* filep;
00394 filep=Fopen(eig_arg->fname,"a");
00395 if ( iter == -1 )
00396 {
00397 Fprintf(filep, "maxed out in ritz\n");
00398 }
00399 else
00400 {
00401 Fprintf(filep, "maxed out for KS steps\n");
00402 }
00403 Fclose(filep);
00404 }
00405 else
00406 {
00407
00408
00409
00410
00411 if ( eig_arg->fname != 0x0 )
00412 {
00413
00414 FILE* filep;
00415 filep=Fopen(eig_arg->fname,"a");
00416
00417 int i_eig,j_eig;
00418
00419
00420
00421
00422 Vector* v1 = (Vector *)smalloc(cname, fname, "v1",f_size*sizeof(Float));
00423
00424 for(i_eig=0;i_eig<N_eig;i_eig++){
00425 for(j_eig=i_eig;j_eig<N_eig;j_eig++){
00426 gamma_5((Float*)v1,
00427 (Float*)eigenv[j_eig],
00428 f_size/24);
00429 Complex cr = eigenv[i_eig]->CompDotProductGlbSum(v1,f_size);
00430 Fprintf(filep,"GM5CORR: %d %d %g %g\n",
00431 i_eig, j_eig, (Float)cr.real(), (Float)cr.imag());
00432 }
00433 }
00434 sfree(cname,fname, "v1", v1);
00435
00436
00437 if(count >0 && eig_arg->ncorr ){
00438 for(i_eig=0;i_eig<N_eig;i_eig++){
00439 for(j_eig=0;j_eig<N_eig;j_eig++){
00440 Complex cr = eig_store[i_eig]
00441 ->CompDotProductGlbSum(eigenv[j_eig],f_size);
00442 Fprintf(filep,"NeibCORR: %d %d %g %g\n",
00443 i_eig, j_eig, (Float)cr.real(), (Float)cr.imag());
00444 }
00445 }
00446 }
00447
00448
00449
00450
00451
00452
00453 int i;
00454 Fprintf(filep, " iter = %d\n", iter);
00455 if (eig_arg->print_hsum)
00456 {
00457 for(n = 0; n < eig_arg->N_eig; ++n)
00458 {
00459 for(i = 0; i < hsum_len; ++i)
00460 {
00461 Fprintf(filep, " hsum[%d][%d] = %g\n",n,i,
00462 (Float)hsum[n][i]);
00463 }
00464 }
00465 }
00466 Fclose(filep);
00467 }
00468 }
00469
00470
00471
00472 if( m < n_masses - 1 ) {
00473 switch( eig_arg->pattern_kind ) {
00474 case ARRAY:
00475 eig_arg->mass = eig_arg->Mass.Mass_val[m+1];
00476 break;
00477 case LIN:
00478 eig_arg->mass += eig_arg->Mass_step;
00479 break;
00480 case LOG:
00481 eig_arg->mass *= eig_arg->Mass_step;
00482 break;
00483 }
00484 }
00485 count++;
00486 }
00487
00488
00489
00490
00491
00492 if ( eig_arg->ncorr )
00493 {
00494 for(n = 0; n < N_eig; ++n)
00495 {
00496 sfree(cname,fname,"eig_store[n]",eig_store[n]);
00497 }
00498 sfree(cname,fname,"eig_store",eig_store);
00499 }
00500 time +=dclock();
00501 print_flops(cname,fname,0,time);
00502
00503 }
00504
00505 CPS_END_NAMESPACE