00001 #include<config.h>
00002 #include<stdlib.h>
00003 #include<math.h>
00004 CPS_START_NAMESPACE
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 CPS_END_NAMESPACE
00016 #include <stdio.h>
00017 #include <alg/alg_hmd.h>
00018 #include <comms/glb.h>
00019 #include <util/lattice.h>
00020 #include <util/vector.h>
00021 #include <util/gjp.h>
00022 #include <util/smalloc.h>
00023 #include <util/verbose.h>
00024 #include <util/error.h>
00025 CPS_START_NAMESPACE
00026
00027
00028
00029
00030
00036
00037 AlgHmdR2::AlgHmdR2(Lattice& latt,
00038 CommonArg *c_arg,
00039 HmdArg *arg) :
00040 AlgHmd(latt, c_arg, arg)
00041 {
00042 cname = "AlgHmdR2";
00043 char *fname = "AlgHmdR2(L&,CommonArg*,HmdArg*)";
00044 VRB.Func(cname,fname);
00045 int i;
00046
00047 if (latt.Fclass() != F_CLASS_STAG &&
00048 latt.Fclass() != F_CLASS_ASQTAD )
00049 ERR.General(cname,fname,"Cannot use R2 algorithm with non-staggered quarks\n");
00050
00051
00052
00053 n_frm_masses = hmd_arg->n_frm_masses;
00054 if(n_frm_masses != 2){
00055 ERR.General(cname,fname,"n_frm_masses must equal 2 for R2 algorithm\n");
00056 }
00057
00058
00059
00060
00061 if(n_frm_masses != 0){
00062 flavor_time_step = (Float *)
00063 smalloc((n_frm_masses+1)*sizeof(Float),
00064 cname, fname, "flavor_time_step");
00065 force_coeff = (Float *)
00066 smalloc((n_frm_masses)*sizeof(Float),
00067 cname, fname, "force_coeff");
00068 }
00069
00070
00071
00072
00073
00074 f_sites = GJP.SnodeSites()*GJP.VolNodeSites() / (AlgLattice().FchkbEvl()+1);
00075
00076 f_vec_count = f_sites * AlgLattice().SpinComponents();
00077
00078 f_size = f_vec_count * AlgLattice().Colors() * 2;
00079
00080
00081
00082 frm_cg_arg = (CgArg **)
00083 smalloc(sizeof(CgArg*),cname,fname,"frm_cg_arg");
00084 for (i=0; i<n_frm_masses; i++)
00085 frm_cg_arg[i] = (CgArg *)
00086 smalloc(sizeof(CgArg),cname,fname,"frm_cg_arg[i]");
00087
00088 light=0;
00089 heavy=1;
00090 if (hmd_arg->frm_mass[0] > hmd_arg->frm_mass[1]) {
00091 Float temp = hmd_arg->frm_mass[0];
00092 hmd_arg->frm_mass[0] = hmd_arg->frm_mass[1];
00093 hmd_arg->frm_mass[1] = temp;
00094 }
00095
00096
00097
00098 for (i=0; i<n_frm_masses; i++) {
00099 frm_cg_arg[i]->mass = hmd_arg->frm_mass[i];
00100 frm_cg_arg[i]->max_num_iter = hmd_arg->max_num_iter[i];
00101 frm_cg_arg[i]->stop_rsd = hmd_arg->stop_rsd[i];
00102 }
00103
00104 shift = (Float*) smalloc(n_frm_masses*sizeof(Float), cname, fname, "shift");
00105
00106 shift[light] = 0.0;
00107 shift[heavy]
00108 = 4.0*(hmd_arg->frm_mass[heavy]*hmd_arg->frm_mass[heavy] -
00109 hmd_arg->frm_mass[light]*hmd_arg->frm_mass[light]);
00110
00111
00112
00113 if(n_frm_masses != 0){
00114 phi = (Vector **)
00115 smalloc(n_frm_masses * sizeof(Vector*), cname,fname, "phi");
00116 for(i=0; i<n_frm_masses; i++)
00117 phi[i] = (Vector *)
00118 smalloc(f_size * sizeof(Float), cname,fname, "phi[i]");
00119 }
00120
00121
00122
00123
00124 frmn = (Vector**) smalloc(n_frm_masses*sizeof(Vector*), cname, fname, "frmn");
00125 frmn_d = (Vector**) smalloc(n_frm_masses*sizeof(Vector*), cname, fname, "frmn_d");
00126
00127 for (i=0; i<n_frm_masses; i++) {
00128 frmn[i] = (Vector*) smalloc(2*f_size*sizeof(Float));
00129 frmn_d[i] = frmn[i] + f_vec_count;
00130 }
00131
00132
00133 }
00134
00135
00136
00137
00138
00139 AlgHmdR2::~AlgHmdR2() {
00140 int i;
00141 char *fname = "~AlgHmdR2()" ;
00142 VRB.Func(cname,fname);
00143
00144
00145
00146 sfree(frmn_d, cname,fname, "frmn_d");
00147 for (i=0; i<n_frm_masses; i++)
00148 sfree(frmn[i], cname, fname, "frmn[i]");
00149
00150 sfree(frmn, cname, fname, "frmn");
00151
00152
00153
00154
00155 if(n_frm_masses != 0){
00156 for(i=0; i<n_frm_masses; i++){
00157 sfree(phi[i], cname, fname, "phi[i]");
00158 }
00159 sfree(phi, cname, fname, "phi");
00160 }
00161
00162
00163
00164 sfree(shift, cname, fname, "shift");
00165
00166
00167
00168 for (i=0; i<n_frm_masses; i++)
00169 sfree(frm_cg_arg[i], cname,fname, "frm_cg_arg[i]");
00170 sfree(frm_cg_arg, cname,fname, "frm_cg_arg");
00171
00172
00173
00174 if(n_frm_masses != 0) {
00175 sfree(flavor_time_step, cname, fname, "flavor_time_step");
00176 sfree(force_coeff);
00177 }
00178
00179 }
00180
00181
00182
00187
00188 Float AlgHmdR2::run(void)
00189 {
00190 #if TARGET==cpsMPI
00191 using MPISCU::fprintf;
00192 #endif
00193 int i;
00194 int step;
00195 Float frm_time_step;
00196 Float flavor_coeff;
00197 int cg_iter;
00198 Float cg_iter_av;
00199 int cg_iter_min;
00200 int cg_iter_max;
00201 Float true_res=0.;
00202 Float true_res_av;
00203 Float true_res_min;
00204 Float true_res_max;
00205 int cg_calls;
00206 char *fname = "run()";
00207 char *md_time_str = "MD_time/step_size = ";
00208
00209 FILE *fp;
00210 VRB.Func(cname,fname);
00211
00212
00213
00214 Lattice& lat = AlgLattice();
00215
00216
00217
00218 flavor_coeff = 1.0 / lat.ExactFlavors();
00219
00220
00221
00222 Float dt = hmd_arg->step_size;
00223
00224
00225
00226 int flavor_diff = hmd_arg->frm_flavors[0];
00227 flavor_time_step[0] = -0.5 * dt * flavor_diff * flavor_coeff;
00228 for(i=1; i<n_frm_masses; i++){
00229 flavor_diff = hmd_arg->frm_flavors[i] - hmd_arg->frm_flavors[i-1];
00230 flavor_time_step[i] = -0.5 * dt * flavor_diff * flavor_coeff;
00231 force_coeff[i] = hmd_arg->frm_flavors[i] * flavor_coeff;
00232 }
00233 flavor_diff = hmd_arg->frm_flavors[n_frm_masses-1];
00234 flavor_time_step[n_frm_masses] = 0.5 * dt * flavor_diff * flavor_coeff;
00235
00236
00237
00238 cg_iter_av = 0.0;
00239 cg_iter_min = 1000000;
00240 cg_iter_max = 0;
00241 true_res_av = 0.0;
00242 true_res_min = 3.4e+38;
00243 true_res_max = 0.0;
00244 cg_calls = 0;
00245
00246
00247
00248
00249 lat.MdTime(0.0);
00250 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00251
00252
00253
00254
00255 lat.RandGaussAntiHermMatrix(mom, 1.0);
00256 Float mom_sum = lat.MomHamiltonNode(mom);
00257 glb_sum(&mom_sum);
00258 VRB.Flow(cname,fname,"mom_sum = %0.14e\n",mom_sum);
00259 Float *phi_p = (Float *)mom;
00260
00261
00262
00263
00264 lat.EvolveGfield(mom, 0.5*dt);
00265 lat.MdTimeInc(0.5);
00266 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00267
00268
00269
00270
00271 step = hmd_arg->steps_per_traj;
00272 while(step) {
00273
00274
00275
00276
00277
00278
00279
00280 for(i=0; i<n_frm_masses; i++){
00281 lat.EvolveGfield(mom, flavor_time_step[i]);
00282 lat.MdTimeInc(flavor_time_step[i] / dt);
00283 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00284 lat.RandGaussVector(frmn[0], 0.5, Ncb);
00285 lat.RandGaussVector(frmn[1], 0.5, Ncb);
00286 lat.SetPhi(phi[i], frmn[0], frmn[1], hmd_arg->frm_mass[i]);
00287 }
00288
00289
00290
00291 lat.EvolveGfield(mom, flavor_time_step[n_frm_masses]);
00292 lat.MdTimeInc(flavor_time_step[n_frm_masses] / dt);
00293 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00294
00295
00296
00297 lat.EvolveMomGforce(mom, dt);
00298
00299
00300
00301
00302
00303
00304 frmn[light] -> FTimesV1MinusV2(1.0, phi[heavy], phi[light], f_size);
00305 frmn[light] -> VecTimesEquFloat(1.0/shift[heavy], f_size);
00306 frmn[heavy] -> CopyVec(frmn[light], f_size);
00307
00308 cg_iter = lat.FmatEvlMInv(frmn, phi[light], shift, n_frm_masses, light,
00309 frm_cg_arg, CNV_FRM_NO, GENERAL,
00310 frmn_d);
00311
00312 cg_iter_av = cg_iter_av + cg_iter;
00313 if(cg_iter < cg_iter_min) cg_iter_min = cg_iter;
00314 if(cg_iter > cg_iter_max) cg_iter_max = cg_iter;
00315 true_res_av = true_res_av + true_res;
00316 if(true_res < true_res_min) true_res_min = true_res;
00317 if(true_res > true_res_max) true_res_max = true_res;
00318 true_res_av = true_res_av + true_res;
00319 if(true_res < true_res_min) true_res_min = true_res;
00320 if(true_res > true_res_max) true_res_max = true_res;
00321 cg_calls++;
00322
00323
00324 lat.RHMC_EvolveMomFforce(mom, frmn, 2, 0, force_coeff, 0.0, dt, frmn_d,
00325 FORCE_MEASURE_NO);
00326
00327 step--;
00328
00329
00330
00331 if(step > 0) lat.EvolveGfield(mom, dt);
00332
00333
00334 lat.MdTimeInc(1.0);
00335 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00336 }
00337
00338
00339
00340
00341
00342
00343 lat.EvolveGfield(mom, 0.5*dt);
00344
00345
00346
00347
00348
00349 Float dev = 0.0;
00350 Float max_diff = 0.0;
00351 if(hmd_arg->reunitarize == REUNITARIZE_YES){
00352 lat.Reunitarize(dev, max_diff);
00353 }
00354
00355
00356
00357
00358 lat.GupdCntInc(1);
00359
00360
00361
00362
00363
00364
00365
00366
00367 lat.GsoCheck();
00368
00369
00370
00371 cg_iter_av = Float(cg_iter_av) / Float(cg_calls);
00372 true_res_av = Float(true_res_av) / Float(cg_calls);
00373
00374
00375
00376
00377 if(common_arg->results != 0){
00378 if( (fp = fopen((char *)common_arg->results, "a")) == NULL ) {
00379 ERR.FileA(cname,fname, (char *)common_arg->results);
00380 }
00381 fprintf(fp,"%d %e %e %e %d %d %e %e %e\n",
00382 hmd_arg->steps_per_traj,
00383 IFloat(dev),
00384 IFloat(max_diff),
00385 IFloat(cg_iter_av),
00386 cg_iter_min,
00387 cg_iter_max,
00388 IFloat(true_res_av),
00389 IFloat(true_res_min),
00390 IFloat(true_res_max));
00391 fclose(fp);
00392 }
00393
00394 VRB.Result(cname,fname,
00395 "Hmd steps = %d, dev = %e, max_diff = %e\n",
00396 hmd_arg->steps_per_traj,
00397 IFloat(dev),
00398 IFloat(max_diff));
00399 VRB.Result(cname,fname,
00400 "CG iterations: average = %e, min = %d, max = %d\n",
00401 IFloat(cg_iter_av),
00402 cg_iter_min,
00403 cg_iter_max);
00404 VRB.Result(cname,fname,
00405 "True Residual / |source|: average = %e, min = %e, max = %e\n",
00406 IFloat(true_res_av),
00407 IFloat(true_res_min),
00408 IFloat(true_res_max));
00409
00410 VRB.Result(cname,fname,"Configuration number = %d\n", lat.GupdCnt());
00411
00412
00413
00414
00415 lat.MdTime(0.0);
00416 VRB.Flow(cname,fname,"%s%f\n", md_time_str, IFloat(lat.MdTime()));
00417
00418 return (Float)1.0;
00419
00420 }
00421
00422
00423
00424
00425
00426
00427 CPS_END_NAMESPACE