00001
00002
00003
00004
00005
00006 #include "fs.h"
00007
00008 void FSParam::initparser()
00009 {
00010 bindvar("A",&const_A,DOUBLE);
00011 bindvar("d",&const_d,DOUBLE);
00012 bindvar("beta",&const_beta,DOUBLE);
00013 bindvar("c",&const_c,DOUBLE);
00014 bindvar("c0",&const_c0,DOUBLE);
00015 bindvar("c1",&const_c1,DOUBLE);
00016 bindvar("c2",&const_c2,DOUBLE);
00017
00018 bindvar("alpha",&const_alpha,DOUBLE);
00019 bindvar("b0",&const_b0,DOUBLE);
00020 bindvar("B",&const_B,DOUBLE);
00021 }
00022
00023 int FSParam::readfile(const char *ppmfile)
00024 {
00025
00026 FILE *f; char extname[200];
00027 LFile::SubHomeDir(ppmfile,extname);
00028 f=fopen(extname,"r");
00029 if(f==NULL)
00030 {
00031 FATAL("Potential file:"<<ppmfile<<" not found!");
00032 return -1;
00033 }
00034 parse(f); fclose(f);
00035 const_d_sq=const_d*const_d;
00036 const_c_sq=const_c*const_c;
00037
00038 rcut=max(const_c,const_d);
00039 INFO("Rcut="<<rcut);
00040 rlist=1.1*rcut;
00041 skin=rlist - rcut;
00042 return 0;
00043 }
00044
00045 void FSParam::print()
00046 {
00047 char tmp[2000];
00048 sprintf(tmp,HIB"FS Potential Parameters"NOR
00049 "const_d=%f const_A=%f const_beta=%f\n"
00050 "const_c=%f const_c0=%f const_c1=%f const_c2=%f\n"
00051 "const_B=%f const_alpha=%f const_b0=%f\n",
00052 const_d,const_A,const_beta,const_c,const_c0,const_c1,
00053 const_c2,const_B,const_alpha,const_b0);
00054 INFO(tmp);
00055 }
00056
00057 int FSParam::exec(char *name)
00058 {
00059 WARNING(HIC"EXEC "NOR<<name<<" (ignored)");
00060 return -1;
00061 }
00062
00063
00064 int FSParam::assignvar(int offset)
00065 {
00066 int s;
00067 switch(vartype[curn])
00068 {
00069 case(INT): s=read_buffer("%d",int); break;
00070 case(LONG): s=read_buffer("%ld",long); break;
00071 case(DOUBLE): s=read_buffer("%lf",double); break;
00072 case(STRING): s=read_buffer("%s",char); break;
00073 default: FATAL("unknown vartype ("<<vartype[curn]<<")");
00074 }
00075 if(s==0)WARNING("Expression syntax error: ("
00076 <<varname[curn]<<" = "<<buffer<<"), variable "
00077 <<varname[curn]<<" unchanged");
00078 switch(vartype[curn])
00079 {
00080 case(INT): INFO_buffer(ah,*,int); break;
00081 case(LONG): INFO_buffer(ah,*,long); break;
00082 case(DOUBLE): INFO_buffer(ah,*,double); break;
00083 case(STRING): INFO_buffer(ah,,char); break;
00084
00085 default: WARNING("unknown vartype ("<<vartype[curn]<<")");
00086 }
00087 return (!s);
00088 }
00089
00090
00091 int FSFrame::readpot()
00092 {
00093 int ret;
00094 ret=_FSPM.readfile(potfile);
00095 _RLIST=_FSPM.rlist;_SKIN=_FSPM.skin;
00096 return ret;
00097 }
00098 void FSFrame::initvars()
00099 {
00100 MDPARALLELFrame::initvars();
00101
00102 strcpy(incnfile,"../bcc.cn");
00103 }
00104 void FSFrame::initparser()
00105 {
00106 MDPARALLELFrame::initparser();
00107 }
00108
00109 int FSFrame::exec(char *name)
00110 {
00111 if(MDPARALLELFrame::exec(name)==0) return 0;
00112 bindcommand(name,"readpot",readpot());
00113 #ifdef _PARALLEL
00114 bindcommand(name,"Broadcast_FS_Param",Broadcast_FS_Param());
00115 #endif
00116 return -1;
00117 }
00118
00119 void FSFrame::Alloc()
00120 {
00121 MDPARALLELFrame::Alloc();
00122 int size;
00123 size=_NP*allocmultiple;
00124
00125 Realloc(rhoh,double,size);
00126 Realloc(af,double,size);
00127 }
00128
00129 void FSFrame::finnis_sinclair()
00130 {
00131 int i, j, jpt;
00132
00133
00134 Vector3 sij,rij,uij,fij,fs;
00135 double r2ij,rrij,rhij,vij,temp0,temp1,temp2,ddtemp;
00136 double dr, dr2, dr3;
00137
00138 DUMP("Finnis-Sinclair Mo");
00139 DUMP("NP="<<_NP);
00140
00141
00142 refreshneighborlist();
00143
00144 _EPOT=0;
00145
00146 for(i=0;i<_NP;i++)
00147 { _F[i].clear(); _EPOT_IND[i]=0;}
00148
00149 for(i=0;i<_NP;i++)
00150 rhoh[i]=0;
00151 _VIRIAL.clear();
00152
00153 for(i=0;i<_NP;i++)
00154 {
00155 for(j=0;j<nn[i];j++)
00156 {
00157 jpt=nindex[i][j];
00158 if(i>=jpt) continue;
00159 sij=_SR[jpt]-_SR[i];
00160 sij.subint();
00161 rij=_H*sij;
00162 r2ij=rij.norm2();
00163 if(r2ij<_FSPM.const_d_sq)
00164 {
00165 rrij=sqrt(r2ij);
00166 dr=(rrij-_FSPM.const_d);
00167 dr2=dr*dr; dr3=dr*dr2;
00168 rhij=dr2+_FSPM.const_beta*dr3/_FSPM.const_d;
00169 rhoh[i]+=rhij;
00170 rhoh[jpt]+=rhij;
00171 }
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 for(i=0;i<_NP;i++)
00201 {
00202 af[i]=sqrt(rhoh[i]);
00203 }
00204
00205 for(i=0;i<_NP;i++)
00206 {
00207 if((fixedatomenergypartition==0)||(fixed[i]!=1))
00208 {
00209 _EPOT-=_FSPM.const_A*af[i];
00210 _EPOT_IND[i]-=_FSPM.const_A*af[i];
00211 }
00212 }
00213
00214
00215 for(i=0;i<_NP;i++)
00216 {
00217 if(fixedatomenergypartition)
00218 if(fixed[i]==1) continue;
00219 for(j=0;j<nn[i];j++)
00220 {
00221 jpt=nindex[i][j];
00222 if(fixedatomenergypartition)
00223 {
00224 if(fixed[jpt]!=1)
00225 if(i>=jpt) continue;
00226 }
00227 else
00228 {
00229 if(i>=jpt) continue;
00230 }
00231
00232 sij=_SR[jpt]-_SR[i];
00233 sij.subint();
00234 rij=_H*sij;
00235 r2ij=rij.norm2();
00236 rrij=sqrt(r2ij);
00237 dr=(rrij-_FSPM.const_d);
00238 dr2=dr*dr; dr3=dr*dr2;
00239
00240 if(rrij<_FSPM.rcut)
00241 {
00242 uij=rij/rrij;
00243 vij=0;
00244
00245 if(rrij<_FSPM.const_c)
00246 {
00247 temp1=rrij-_FSPM.const_c;
00248 temp2 = _FSPM.const_c0+
00249 _FSPM.const_c1*rrij+_FSPM.const_c2*r2ij;
00250 ddtemp=temp1*temp1*temp2;
00251 _EPOT_IND[i]+=ddtemp*.5;
00252 _EPOT_IND[jpt]+=ddtemp*.5;
00253
00254 if(fixedatomenergypartition==0)
00255 {
00256 _EPOT+=ddtemp;
00257 vij+=2*temp1*temp2+temp1*temp1*
00258 (_FSPM.const_c1 + 2*_FSPM.const_c2*rrij);
00259 }
00260 else
00261 {
00262 if(fixed[jpt]!=1)
00263 {
00264 _EPOT+=ddtemp;
00265 vij+=2*temp1*temp2+temp1*temp1*
00266 (_FSPM.const_c1 + 2*_FSPM.const_c2*rrij);
00267 }
00268 else
00269 {
00270 _EPOT+=ddtemp*.5;
00271 vij+=(2*temp1*temp2+temp1*temp1*
00272 (_FSPM.const_c1 + 2*_FSPM.const_c2*rrij))*.5;
00273
00274 }
00275 }
00276 }
00277
00278 if(rrij<_FSPM.const_b0)
00279 {
00280 temp0=_FSPM.const_b0-rrij;
00281 temp1=temp0*temp0;
00282 temp2=exp(-_FSPM.const_alpha*rrij);
00283
00284 ddtemp=_FSPM.const_B*temp0*temp1*temp2;
00285 _EPOT_IND[i]+=ddtemp*.5;
00286 _EPOT_IND[jpt]+=ddtemp*.5;
00287
00288 if(fixedatomenergypartition==0)
00289 {
00290 _EPOT+=ddtemp;
00291 vij-=_FSPM.const_B*temp1*temp2*
00292 (3+_FSPM.const_alpha*temp0);
00293 }
00294 else
00295 {
00296 if(fixed[jpt]!=1)
00297 {
00298 _EPOT+=ddtemp;
00299 vij-=_FSPM.const_B*temp1*temp2*
00300 (3+_FSPM.const_alpha*temp0);
00301 }
00302 else
00303 {
00304 _EPOT+=ddtemp*.5;
00305 vij-=_FSPM.const_B*temp1*temp2*
00306 (3+_FSPM.const_alpha*temp0)*.5;
00307 }
00308 }
00309 }
00310
00311 if(rrij<_FSPM.const_d)
00312 {
00313 if(fixedatomenergypartition==0)
00314 {
00315 vij-=_FSPM.const_A*
00316 ( 1./af[i]+1./af[jpt] )/2*(
00317 2* dr +
00318 _FSPM.const_beta * 3 * dr2/_FSPM.const_d);
00319 }
00320 else
00321 {
00322 if(fixed[jpt]!=1)
00323 vij-=_FSPM.const_A*
00324 ( 1./af[i]+1./af[jpt] )/2*(
00325 2* dr +
00326 _FSPM.const_beta * 3 * dr2/_FSPM.const_d);
00327 else
00328 vij-=_FSPM.const_A*
00329 ( 1./af[i] )/2*(
00330 2* dr +
00331 _FSPM.const_beta * 3 * dr2/_FSPM.const_d);
00332 }
00333 }
00334 fij=uij*vij;
00335 _F[i]+=fij;
00336 _F[jpt]-=fij;
00337
00338 _VIRIAL.addnvv(-vij*rrij,uij,uij);
00339 }
00340 }
00341 }
00342
00343 for(i=0;i<_NP;i++)
00344 {
00345 if(fixed[i])
00346 _F[i].clear();
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 }
00404
00405
00406
00407 void FSFrame::potential()
00408 {
00409 finnis_sinclair();
00410 }
00411
00412 #ifdef _PARALLEL
00413 void FSFrame::Broadcast_FS_Param()
00414 {
00415 double *buf_double;
00416 int nparam, i, j;
00417
00418
00419 if(myDomain==0) Master_to_Slave("Broadcast_FS_Param");
00420
00421
00422 nparam = 17;
00423
00424 buf_double = (double *) malloc(nparam*sizeof(double));
00425 if(myDomain==0)
00426 {
00427 buf_double[0] = _FSPM.const_d;
00428 buf_double[1] = _FSPM.const_A;
00429 buf_double[2] = _FSPM.const_beta;
00430 buf_double[3] = _FSPM.const_c;
00431 buf_double[4] = _FSPM.const_c0;
00432 buf_double[5] = _FSPM.const_c1;
00433 buf_double[6] = _FSPM.const_c2;
00434 buf_double[7] = _FSPM.const_d_sq;
00435 buf_double[8] = _FSPM.const_c_sq;
00436 buf_double[9] = _FSPM.rcut;
00437 buf_double[10] = _FSPM.const_B;
00438 buf_double[11] = _FSPM.const_alpha;
00439 buf_double[12] = _FSPM.const_b0;
00440 buf_double[13] = _RLIST;
00441 buf_double[14] = _SKIN;
00442 buf_double[15] = (double) _NNM;
00443 buf_double[16] = (double) _NIC;
00444 }
00445
00446
00447 MPI_Bcast(buf_double,nparam,MPI_DOUBLE,0,MPI_COMM_WORLD);
00448
00449 if(myDomain!=0)
00450 {
00451
00452
00453
00454
00455
00456
00457 _FSPM.const_d = buf_double[0];
00458 _FSPM.const_A = buf_double[1];
00459 _FSPM.const_beta = buf_double[2];
00460 _FSPM.const_c = buf_double[3];
00461 _FSPM.const_c0 = buf_double[4];
00462 _FSPM.const_c1 = buf_double[5];
00463 _FSPM.const_c2 = buf_double[6];
00464 _FSPM.const_d_sq = buf_double[7];
00465 _FSPM.const_c_sq = buf_double[8];
00466 _FSPM.rcut = buf_double[9];
00467 _FSPM.const_B = buf_double[10];
00468 _FSPM.const_alpha = buf_double[11];
00469 _FSPM.const_b0 = buf_double[12];
00470 _RLIST = buf_double[13];
00471 _SKIN = buf_double[14];
00472 _NNM = (int) buf_double[15];
00473 _NIC = (int) buf_double[16];
00474 }
00475
00476 free(buf_double);
00477
00478 }
00479 #endif//_PARALLEL
00480
00481 #ifdef _TEST
00482
00483
00484 class FSFrame sim;
00485
00486
00487 #include "main.cpp"
00488
00489 #endif//_TEST