00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "meam-lammps.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00039 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00040
00041 #define MAXLINE 1024
00042
00043 void MEAMFrame::Alloc()
00044 {
00045 MDPARALLELFrame::Alloc();
00046 int size;
00047 size=_NP*allocmultiple;
00048
00049
00050 Realloc(rho,double,size);
00051 Realloc(rho0,double,size);
00052 Realloc(rho1,double,size);
00053 Realloc(rho2,double,size);
00054 Realloc(rho3,double,size);
00055 Realloc(frhop,double,size);
00056 Realloc(gamma,double,size);
00057 Realloc(dgamma1,double,size);
00058 Realloc(dgamma2,double,size);
00059 Realloc(dgamma3,double,size);
00060 Realloc(arho2b,double,size);
00061 Realloc(arho1,Vector3,size);
00062 Realloc(arho2,Vector6,size);
00063 Realloc(arho3,Vector10,size);
00064 Realloc(arho3b,Vector3,size);
00065 Realloc(t_ave,Vector3,size);
00066 Realloc(type,int,size);
00067 Realloc(rtmp,Vector3,size);
00068 Realloc(num_neigh_full,int,size);
00069 Realloc(num_neigh_half,int,size);
00070
00071 bindvar("rho",rho,DOUBLE);
00072 bindvar("rho0",rho0,DOUBLE);
00073 bindvar("rho1",rho1,DOUBLE);
00074 bindvar("rho2",rho2,DOUBLE);
00075 bindvar("rho3",rho3,DOUBLE);
00076 bindvar("frhop",frhop,DOUBLE);
00077 bindvar("gamma",gamma,DOUBLE);
00078 bindvar("dgamma1",dgamma1,DOUBLE);
00079 bindvar("dgamma2",dgamma2,DOUBLE);
00080 bindvar("dgamma3",dgamma3,DOUBLE);
00081 bindvar("arho2b",arho2b,DOUBLE);
00082 bindvar("arho1",arho1,DOUBLE);
00083 bindvar("arho2",arho2,DOUBLE);
00084 bindvar("arho3",arho3,DOUBLE);
00085 bindvar("arho3b",arho3b,DOUBLE);
00086 bindvar("t_ave",t_ave,DOUBLE);
00087
00088 }
00089
00090 void MEAMFrame::potential()
00091 {
00092 MEAM();
00093 }
00094
00095 int MEAMFrame::readMEAM()
00096 {
00097 int select, errorflag;
00098
00099
00100 #ifdef _PARALLEL
00101 INFO_Printf("[%d]: readMEAM meamfile = %s element[%d]=%s element[%d]=%s\n",
00102 myDomain,meamfile,0,element[0],1,element[1]);
00103 #else
00104 INFO_Printf("readMEAM meamfile = %s element[%d]=%s element[%d]=%s\n",
00105 meamfile,0,element[0],1,element[1]);
00106 #endif
00107
00108 LFile::SubHomeDir(meamfile,meamfile);
00109 LFile::SubHomeDir(meafile, meafile);
00110 read_files(meamfile,meafile);
00111
00112 select=10;
00113 meam_setup_param_(&select,&rcut,NULL,NULL,&errorflag);
00114
00115 meam_setup_done_(&rcut);
00116
00117 #ifdef _PARALLEL
00118 INFO_Printf("[%d] readMEAM: rcut=%f\n",myDomain,rcut);
00119 #else
00120 INFO_Printf("readMEAM: rcut=%f\n",rcut);
00121 #endif
00122
00123 Realloc(fmap,int,nspecies);
00124 for(int i=0;i<nspecies;i++) fmap[i]=i+1;
00125
00126 _RLIST = 1.1*rcut;
00127 _SKIN = _RLIST - rcut;
00128 return 0;
00129 }
00130
00131 void MEAMFrame::NbrList_reconstruct(int iatom)
00132 {
00133 MDPARALLELFrame::NbrList_reconstruct();
00134 }
00135
00136 void MEAMFrame::NbrList_translate()
00137 {
00138 int i, j, jpt, n;
00139
00140 maxneigh=0; for(i=0;i<_NP;i++) { if (fixed[i]!=-1) maxneigh+=nn[i]; }
00141
00142
00143
00144
00145 Realloc(ind_neigh_full_mem,char,_NP*_NNM*sizeof(int)+_NP*sizeof(int *));
00146 ind_neigh_full=(int **)(ind_neigh_full_mem+_NP*_NNM*sizeof(int));
00147 for(i=0;i<_NP;i++) ind_neigh_full[i]=(int *)(ind_neigh_full_mem+i*_NNM*sizeof(int));
00148
00149 Realloc(ind_neigh_half_mem,char,_NP*_NNM*sizeof(int)+_NP*sizeof(int *));
00150 ind_neigh_half=(int **)(ind_neigh_half_mem+_NP*_NNM*sizeof(int));
00151 for(i=0;i<_NP;i++) ind_neigh_half[i]=(int *)(ind_neigh_half_mem+i*_NNM*sizeof(int));
00152
00153 for(i=0;i<_NP;i++)
00154 {
00155 if(fixed[i]==-1) continue;
00156
00157
00158 n = 0;
00159 for(j=0;j<nn[i];j++)
00160 {
00161 jpt=nindex[i][j];
00162 if(fixed[jpt]==-1) continue;
00163 if(jpt>i)
00164 {
00165 ind_neigh_half[i][n]=jpt+1;
00166 ind_neigh_full[i][n]=jpt+1;
00167 n++;
00168 }
00169 }
00170 num_neigh_half[i] = n;
00171
00172 for(j=0;j<nn[i];j++)
00173 {
00174 jpt=nindex[i][j];
00175 if(fixed[jpt]==-1) continue;
00176 if(jpt<i)
00177 {
00178 ind_neigh_full[i][n]=jpt+1;
00179 n++;
00180 }
00181 }
00182 num_neigh_full[i] = n;
00183 }
00184 }
00185
00186 void MEAMFrame::MEAM()
00187 {
00188 int i, j, jpt, eflag, errorflag, offset, ifort, strscomp;
00189 Vector3 ds, ds0;
00190
00191 refreshneighborlist();
00192 NbrList_translate();
00193
00194
00195 Realloc(scrfcn, double,maxneigh);
00196 Realloc(dscrfcn,double,maxneigh);
00197 Realloc(fcpair, double,maxneigh);
00198 Realloc(rtmp, Vector3,_NP);
00199
00200 SHtoR(); memcpy(rtmp,_R,sizeof(Vector3)*_NP);
00201 eflag = 1;
00202
00203
00204
00205 for(i=0;i<_NP;i++)
00206 {
00207
00208
00209 _EPOT_IND[i]=0;
00210 _F[i].clear();
00211 _VIRIAL_IND[i].clear();
00212 _TORQUE_IND[i]=0;
00213 _BENDMOMENT_IND[i]=0;
00214
00215 rho0[i]=0;
00216 arho2b[i]=0;
00217
00218 arho1[i].clear();
00219 arho3b[i].clear();
00220 t_ave[i].clear();
00221
00222 for(j=0;j<6;j++) arho2[i][j]=0;
00223 for(j=0;j<10;j++) arho3[i][j]=0;
00224 }
00225 _EPOT=0;
00226 _VIRIAL.clear();
00227 _TORQUE = 0;
00228 _BENDMOMENT = 0;
00229
00230 errorflag = 0;
00231 offset = 0;
00232
00233 for(i=0;i<_NP;i++)
00234 {
00235 if(fixed[i]==-1) continue;
00236 type[i] = species[i] + 1;
00237 }
00238
00239 for(i=0;i<_NP;i++)
00240 {
00241 if(fixed[i]==-1) continue;
00242
00243 ds0=_SR[i]; ds0.subint(); rtmp[i]=_H*ds0;
00244 for(j=0;j<nn[i];j++)
00245 {
00246 jpt=nindex[i][j];
00247 if(fixed[jpt]==-1) continue;
00248 ds=_SR[jpt]-ds0;
00249 ds.subint();
00250 ds+=ds0;
00251 rtmp[jpt]=_H*ds;
00252 }
00253 ifort = i+1;
00254 meam_dens_init_(&ifort,&_NP,&eflag,&_EPOT,&nspecies,type,fmap,(double *)rtmp,
00255 &num_neigh_half[i],ind_neigh_half[i],&num_neigh_full[i],ind_neigh_full[i],
00256 &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
00257 rho0,&arho1[0][0],&arho2[0][0],arho2b,
00258 &arho3[0][0],&arho3b[0][0],&t_ave[0][0],&errorflag);
00259
00260
00261
00262
00263
00264
00265 if (errorflag) {
00266 FATAL("meam_dens_init library error "<<errorflag);
00267 }
00268 offset += num_neigh_half[i];
00269 }
00270
00271
00272
00273
00274
00275 meam_dens_final_(&_NP,&_NP,&eflag,&_EPOT,&nspecies,type,fmap,
00276 &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],
00277 &arho3b[0][0],&t_ave[0][0],gamma,dgamma1,
00278 dgamma2,dgamma3,rho,rho0,rho1,rho2,rho3,frhop,
00279 _EPOT_IND,fixed,&errorflag);
00280
00281 if (errorflag) {
00282 FATAL("meam_dens_final library error "<<errorflag);
00283 }
00284
00285 offset = 0;
00286
00287 for(i=0;i<_NP;i++)
00288 {
00289 if(fixed[i]==-1) continue;
00290
00291
00292 ds0=_SR[i]; ds0.subint(); rtmp[i]=_H*ds0;
00293 for(j=0;j<num_neigh_full[i];j++)
00294 {
00295 jpt=ind_neigh_full[i][j]-1;
00296 ds=_SR[jpt]-ds0;
00297 ds.subint();
00298 ds+=ds0;
00299 rtmp[jpt]=_H*ds;
00300 }
00301 ifort = i+1;
00302 strscomp = 1;
00303
00304 #ifdef _TORSION_OR_BENDING
00305 meam_force_(&ifort,&_NP,&_NP0,&eflag,&_EPOT,&nspecies,type,fmap,(double *)rtmp,
00306 &num_neigh_half[i],ind_neigh_half[i],&num_neigh_full[i],ind_neigh_full[i],
00307 &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
00308 dgamma1,dgamma2,dgamma3,rho0,rho1,rho2,rho3,frhop,
00309 &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],&arho3b[0][0],
00310 &t_ave[0][0],&_F[0][0],_EPOT_IND,
00311 &strscomp, &_VIRIAL_IND[0][0][0],
00312 &_TORSIONSIM, _TORQUE_IND,
00313 &_BENDSIM, bendspec, _BENDMOMENT_IND,
00314 &errorflag);
00315 #else
00316 meam_force_(&ifort,&_NP,&eflag,&_EPOT,&nspecies,type,fmap,(double *)rtmp,
00317 &num_neigh_half[i],ind_neigh_half[i],&num_neigh_full[i],ind_neigh_full[i],
00318 &scrfcn[offset],&dscrfcn[offset],&fcpair[offset],
00319 dgamma1,dgamma2,dgamma3,rho0,rho1,rho2,rho3,frhop,
00320 &arho1[0][0],&arho2[0][0],arho2b,&arho3[0][0],&arho3b[0][0],
00321 &t_ave[0][0],&_F[0][0],&_VIRIAL_IND[0][0][0],
00322 _EPOT_IND,&errorflag);
00323 #endif
00324
00325 if (errorflag) {
00326 FATAL("meam_force library error "<<errorflag);
00327 }
00328 offset += num_neigh_half[i];
00329 }
00330
00331 _TORQUE = 0;
00332 _BENDMOMENT = 0;
00333 for(i=0;i<_NP;i++)
00334 {
00335 if(fixed[i]==-1) continue;
00336 _VIRIAL_IND[i] *= -0.5;
00337 _VIRIAL += _VIRIAL_IND[i];
00338 _TORQUE += _TORQUE_IND[i];
00339 _BENDMOMENT += _BENDMOMENT_IND[i];
00340
00341
00342 }
00343 }
00344
00345 void MEAMFrame::initvars()
00346 {
00347 MDPARALLELFrame::initvars();
00348
00349 strcpy(meamfile,"meamf");
00350 strcpy(meafile,"NULL");
00351 }
00352
00353 void MEAMFrame::initparser()
00354 {
00355 MDPARALLELFrame::initparser();
00356 bindvar("meamfile",meamfile,STRING);
00357 bindvar("meafile",meafile,STRING);
00358 bindvar("rcut",&rcut,DOUBLE);
00359 }
00360
00361 int MEAMFrame::exec(char *name)
00362 {
00363 if(MDPARALLELFrame::exec(name)==0) return 0;
00364 bindcommand(name,"readMEAM",readMEAM());
00365 bindcommand(name,"printpairpot",printpairpot());
00366
00367 #ifdef _PARALLEL
00368 bindcommand(name,"Broadcast_MEAM_Param",Broadcast_MEAM_Param());
00369 #endif
00370 return -1;
00371 }
00372
00373
00374 int count_words(char *line)
00375 {
00376 int n = strlen(line) + 1;
00377 char *copy = (char *) malloc(n*sizeof(char));
00378 strcpy(copy,line);
00379
00380 char *ptr;
00381 if ((ptr = strchr(copy,'#'))) *ptr = '\0';
00382
00383 if (strtok(copy," \t\n\r\f") == NULL) {
00384 free(copy);
00385 return 0;
00386 }
00387 n = 1;
00388 while (strtok(NULL," \t\n\r\f")) n++;
00389
00390 free(copy);
00391 return n;
00392 }
00393
00394
00395 void MEAMFrame::read_files(char *globalfile, char *userfile)
00396 {
00397
00398 FILE *fp;
00399
00400 fp = fopen(globalfile,"r");
00401 if (fp == NULL) {
00402 ERROR("Cannot open MEAM potential file"<<globalfile);
00403 }
00404
00405
00406
00407 int params_per_line = 19;
00408 int nelements;
00409
00410 nelements = nspecies;
00411
00412 int *lat = new int[nelements];
00413 int *ielement = new int[nelements];
00414 int *ibar = new int[nelements];
00415 double *z = new double[nelements];
00416 double *atwt = new double[nelements];
00417 double *alpha = new double[nelements];
00418 double *b0 = new double[nelements];
00419 double *b1 = new double[nelements];
00420 double *b2 = new double[nelements];
00421 double *b3 = new double[nelements];
00422 double *alat = new double[nelements];
00423 double *esub = new double[nelements];
00424 double *asub = new double[nelements];
00425 double *t0 = new double[nelements];
00426 double *t1 = new double[nelements];
00427 double *t2 = new double[nelements];
00428 double *t3 = new double[nelements];
00429 double *rozero = new double[nelements];
00430
00431 bool *found = new bool[nelements];
00432 for (int i = 0; i < nelements; i++) found[i] = false;
00433
00434
00435
00436
00437
00438
00439 int i,n,nwords;
00440 char **words = new char*[params_per_line+1];
00441 char line[MAXLINE],*ptr;
00442 int eof = 0;
00443
00444 int nset = 0;
00445 while (1) {
00446
00447 ptr = fgets(line,MAXLINE,fp);
00448 if (ptr == NULL) {
00449 eof = 1;
00450 fclose(fp);
00451 } else n = strlen(line) + 1;
00452
00453
00454 if (eof) break;
00455
00456
00457
00458
00459
00460 if ((ptr = strchr(line,'#'))) *ptr = '\0';
00461 nwords = count_words(line);
00462 if (nwords == 0) continue;
00463
00464
00465
00466 while (nwords < params_per_line) {
00467 n = strlen(line);
00468
00469 ptr = fgets(&line[n],MAXLINE-n,fp);
00470 if (ptr == NULL) {
00471 eof = 1;
00472 fclose(fp);
00473 } else n = strlen(line) + 1;
00474
00475
00476 if (eof) break;
00477
00478
00479 if ((ptr = strchr(line,'#'))) *ptr = '\0';
00480 nwords = count_words(line);
00481 }
00482
00483 if (nwords != params_per_line)
00484 ERROR("Incorrect format in MEAM potential file");
00485
00486
00487
00488
00489 nwords = 0;
00490 words[nwords++] = strtok(line,"' \t\n\r\f");
00491 while ((words[nwords++] = strtok(NULL,"' \t\n\r\f"))) continue;
00492
00493
00494
00495 for (i = 0; i < nelements; i++)
00496 if (strcmp(words[0],element[i]) == 0) break;
00497 if (i == nelements) continue;
00498
00499
00500
00501 if (found[i] == true) continue;
00502 found[i] = true;
00503
00504
00505
00506 if (strcmp(words[1],"fcc") == 0) lat[i] = FCC;
00507 else if (strcmp(words[1],"bcc") == 0) lat[i] = BCC;
00508 else if (strcmp(words[1],"hcp") == 0) lat[i] = HCP;
00509 else if (strcmp(words[1],"dim") == 0) lat[i] = DIM;
00510 else if (strcmp(words[1],"dia") == 0) lat[i] = DIAMOND;
00511 else ERROR("Unrecognized lattice type in MEAM file 1");
00512
00513
00514
00515
00516
00517
00518 z[i] = atof(words[2]);
00519 ielement[i] = atoi(words[3]);
00520 atwt[i] = atof(words[4]);
00521 alpha[i] = atof(words[5]);
00522 b0[i] = atof(words[6]);
00523 b1[i] = atof(words[7]);
00524 b2[i] = atof(words[8]);
00525 b3[i] = atof(words[9]);
00526 alat[i] = atof(words[10]);
00527 esub[i] = atof(words[11]);
00528 asub[i] = atof(words[12]);
00529 t0[i] = atof(words[13]);
00530 t1[i] = atof(words[14]);
00531 t2[i] = atof(words[15]);
00532 t3[i] = atof(words[16]);
00533 rozero[i] = atof(words[17]);
00534 ibar[i] = atoi(words[18]);
00535
00536 nset++;
00537
00538
00539
00540 }
00541
00542
00543
00544 if (nset != nelements)
00545 ERROR("Did not find all elements in MEAM library file");
00546
00547
00548
00549 meam_setup_global_(&nelements,lat,z,ielement,atwt,alpha,b0,b1,b2,b3,
00550 alat,esub,asub,t0,t1,t2,t3,rozero,ibar);
00551
00552
00553
00554 for (i = 0; i < nelements; i++) _ATOMMASS[i] = atwt[i];
00555
00556
00557
00558 delete [] words;
00559
00560 delete [] lat;
00561 delete [] ielement;
00562 delete [] ibar;
00563 delete [] z;
00564 delete [] atwt;
00565 delete [] alpha;
00566 delete [] b0;
00567 delete [] b1;
00568 delete [] b2;
00569 delete [] b3;
00570 delete [] alat;
00571 delete [] esub;
00572 delete [] asub;
00573 delete [] t0;
00574 delete [] t1;
00575 delete [] t2;
00576 delete [] t3;
00577 delete [] rozero;
00578 delete [] found;
00579
00580
00581
00582 if (strcmp(userfile,"NULL") == 0) return;
00583
00584
00585
00586
00587 fp = fopen(userfile,"r");
00588 if (fp == NULL) {
00589 ERROR("Cannot open MEAM potential file "<<userfile);
00590 }
00591
00592
00593
00594
00595
00596
00597 int which;
00598 double value;
00599 int nindex,index[3];
00600 int maxparams = 6;
00601 int nparams;
00602 char *params[maxparams];
00603
00604 eof = 0;
00605 while (1) {
00606
00607 ptr = fgets(line,MAXLINE,fp);
00608 if (ptr == NULL) {
00609 eof = 1;
00610 fclose(fp);
00611 } else n = strlen(line) + 1;
00612
00613
00614 if (eof) break;
00615
00616
00617
00618
00619
00620 if ((ptr = strchr(line,'#'))) *ptr = '\0';
00621 nparams = count_words(line);
00622 if (nparams == 0) continue;
00623
00624
00625
00626 nparams = 0;
00627 params[nparams++] = strtok(line,"=(), '\t\n\r\f");
00628 while (nparams < maxparams &&
00629 (params[nparams++] = strtok(NULL,"=(), '\t\n\r\f")))
00630 continue;
00631 nparams--;
00632
00633 for (which = 0; which < nkeywords; which++)
00634 if (strcmp(params[0],keywords[which]) == 0) break;
00635 if (which == nkeywords) {
00636 ERROR("Keyword "<<params[0]<<" in MEAM parameter file not recognized");
00637 }
00638 nindex = nparams - 2;
00639 for (i = 0; i < nindex; i++) index[i] = atoi(params[i+1]);
00640
00641
00642
00643 if (which == 4) {
00644 if (strcmp(params[nparams-1],"fcc") == 0) value = FCC;
00645 else if (strcmp(params[nparams-1],"bcc") == 0) value = BCC;
00646 else if (strcmp(params[nparams-1],"hcp") == 0) value = HCP;
00647 else if (strcmp(params[nparams-1],"dim") == 0) value = DIM;
00648 else if (strcmp(params[nparams-1],"dia") == 0) value = DIAMOND;
00649 else if (strcmp(params[nparams-1],"b1") == 0) value = B1;
00650 else if (strcmp(params[nparams-1],"c11") == 0) value = C11;
00651 else ERROR("Unrecognized lattice type in MEAM file 2");
00652 }
00653 else value = atof(params[nparams-1]);
00654
00655
00656
00657 int errorflag = 0;
00658 meam_setup_param_(&which,&value,&nindex,index,&errorflag);
00659 if (errorflag) {
00660 ERROR("MEAM library error "<<errorflag);
00661 }
00662 }
00663 }
00664
00665 void MEAMFrame::printpairpot()
00666 {
00667 int elti, eltj;
00668 double rmin, dr, rmax, r, phi, phip;
00669 char pairfile[200];
00670 FILE *fp;
00671
00672 elti = (int) input[0] + 1;
00673 eltj = (int) input[1] + 1;
00674 rmin = input[2];
00675 dr = input[3];
00676 rmax = input[4];
00677
00678 strcpy(pairfile,"pairpot_lammps.dat");
00679 fp=fopen(pairfile,"w");
00680 if(fp==NULL)
00681 {
00682 FATAL("printpairpot: file "<<pairfile<<" open failure.");
00683 }
00684 if((rmax<rmin)||(dr<=0))
00685 FATAL("rmax cannot be smaller than rmin, dr must be positive");
00686 for(r=rmin;r<=rmax;r+=dr)
00687 {
00688 phif_(&elti,&eltj,&r,&phi,&phip);
00689 fprintf(fp,"%21.14e %21.14e %21.14e\n",r,phi,phip);
00690 }
00691 fclose(fp);
00692 INFO("results written to "<<pairfile);
00693 }
00694
00695
00696
00697 #ifdef _PARALLEL
00698 void MEAMFrame::Broadcast_MEAM_Param()
00699 {
00700 double *buf_double;
00701 int nparam;
00702
00703
00704 if(myDomain==0) Master_to_Slave("Broadcast_MEAM_Param");
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 MPI_Bcast(meamfile,1000,MPI_CHAR,0,MPI_COMM_WORLD);
00716 MPI_Bcast(element,MAXSPECIES*10,MPI_CHAR,0,MPI_COMM_WORLD);
00717
00718
00719
00720
00721
00722 nparam = 4;
00723 buf_double = (double *) malloc(nparam*sizeof(double));
00724
00725 if(myDomain==0)
00726 {
00727 buf_double[0] = rcut;
00728 buf_double[1] = (double) nspecies;
00729 buf_double[2] = (double) _NNM;
00730 buf_double[3] = (double) _NIC;
00731 }
00732
00733 MPI_Bcast(buf_double,nparam,MPI_DOUBLE,0,MPI_COMM_WORLD);
00734
00735 if(myDomain!=0)
00736 {
00737
00738 rcut = buf_double[0];
00739 nspecies = (int) buf_double[1];
00740 _NNM = (int) buf_double[2];
00741 _NIC = (int) buf_double[3];
00742
00743 readMEAM();
00744 }
00745
00746 free(buf_double);
00747 }
00748 #endif//_PARALLEL
00749
00750
00751
00752
00753 #ifdef _TEST
00754
00755
00756 class MEAMFrame sim;
00757
00758
00759 #include "main.cpp"
00760
00761 #endif//_