00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tersoff.h"
00025
00026 void TersoffFrame::initvars()
00027 {
00028
00029 A_Si = 1.8308e3;
00030 B_Si = 4.7118e2;
00031 Lam_Si = 2.4799;
00032 Mu_Si = 1.7322;
00033 R_Si = 2.7;
00034 S_Si = 3.0;
00035 Beta_Si = 1.1e-6;
00036 nTf_Si = 0.78734;
00037 cTf_Si = 1.0039e5;
00038 dTf_Si = 16.217;
00039 hTf_Si = -0.59825;
00040
00041
00042 A_C = 1.3936e3;
00043 B_C = 3.467e2;
00044 Lam_C = 3.4879;
00045 Mu_C = 2.2119;
00046 R_C = 1.8;
00047 S_C = 2.1;
00048 Beta_C = 1.5724e-7;
00049 nTf_C = 0.72751;
00050 cTf_C = 3.8049e4;
00051 dTf_C = 4.3484;
00052 hTf_C = -0.57058;
00053
00054
00055 A_Ge = 1.769e3;
00056 B_Ge = 4.1923e2;
00057 Lam_Ge = 2.4451;
00058 Mu_Ge = 1.7047;
00059 R_Ge = 2.8;
00060 S_Ge = 3.1;
00061 Beta_Ge = 9.0166e-7;
00062 nTf_Ge = 0.75627;
00063 cTf_Ge = 1.0643e5;
00064 dTf_Ge = 15.652;
00065 hTf_Ge = -0.43884;
00066
00067
00068 Chi_C_Si = 0.9776;
00069 Chi_Si_Ge = 1.00061;
00070 Chi_C_Ge = 1.0;
00071
00072 acut=S_Ge*1.0;
00073 _RLIST=acut*1.1;
00074 _SKIN=_RLIST-acut;
00075 acutsq=acut*acut;
00076
00077 strcpy(incnfile,"../si.cn");
00078 DUMP(HIG"TersoffFrame initvars"NOR);
00079 MDFrame::initvars();
00080 }
00081
00082 void TersoffFrame::tersoff()
00083 {
00084 #ifndef NNM
00085 #define NNM 60
00086 #endif
00087
00088 int i,j,k,ipt,jpt,kpt,neg;
00089 Vector3 sij,rij,f3i,fZ,fTheta;
00090 double cSqr, dSqr, cdSqr, invn2, fC, fA, fR, dfCdr, dfAdr, dfRdr;
00091 double Arg, temp, Z, CosTheta, dCosTheta, gTheta, BetaZN, BetaZN1, bij;
00092 double r2ij, rrij, r;
00093 double V, dVdr, dVdZ;
00094 double rr[NNM], Asave[NNM], Bsave[NNM], Musave[NNM], Lamsave[NNM];
00095 double Rsave[NNM], Ssave[NNM];
00096 double fCsave[NNM], dfCdrsave[NNM], fAsave[NNM], dfAdrsave[NNM];
00097 double fRsave[NNM], dfRdrsave[NNM], dZdr[NNM], dZdCosTheta[NNM];
00098 Vector3 rg[NNM], rt[NNM];
00099 int list2[NNM];
00100 int n0, n1;
00101
00102 DUMP("Tersoff");
00103
00104 refreshneighborlist();
00105
00106
00107 _EPOT=0;
00108 for(i=0;i<_NP;i++)
00109 { _F[i].clear(); _EPOT_IND[i]=0;}
00110 _VIRIAL.clear();
00111
00112 n0=0;
00113 n1=_NP;
00114
00115 for(ipt=n0;ipt<n1;ipt++)
00116 {
00117 if(fixed[ipt]==-1) continue;
00118
00119
00120 switch (species[ipt]) {
00121 case 0: A_i=A_Si; B_i=B_Si; Lam_i=Lam_Si;
00122 Mu_i=Mu_Si; R_i=R_Si; S_i=S_Si; Beta=Beta_Si;
00123 nTf=nTf_Si; cTf=cTf_Si; dTf=dTf_Si; hTf=hTf_Si; break;
00124 case 1: A_i=A_Ge; B_i=B_Ge; Lam_i=Lam_Ge;
00125 Mu_i=Mu_Ge; R_i=R_Ge; S_i=S_Ge; Beta=Beta_Ge;
00126 nTf=nTf_Ge; cTf=cTf_Ge; dTf=dTf_Ge; hTf=hTf_Ge; break;
00127 case 2: A_i=A_C; B_i=B_C; Lam_i=Lam_C;
00128 Mu_i=Mu_C; R_i=R_C; S_i=S_C; Beta=Beta_C;
00129 nTf=nTf_C; cTf=cTf_C; dTf=dTf_C; hTf=hTf_C; break;
00130 }
00131
00132 cSqr = cTf*cTf;
00133 dSqr = dTf*dTf;
00134 cdSqr = cSqr/dSqr;
00135 invn2 = -1.0/2.0/nTf;
00136
00137 neg = 0;
00138 for(j=0;j<nn[ipt];j++)
00139 {
00140 jpt=nindex[ipt][j];
00141 if(fixed[jpt]==-1) continue;
00142
00143 sij.subtract(_SR[jpt],_SR[ipt]);
00144 sij.subint();
00145 _H.multiply(sij,rij);
00146
00147 r2ij=rij.norm2();
00148 if(r2ij>acutsq) continue;
00149 rrij=sqrt(r2ij);
00150
00151
00152 switch (species[jpt]) {
00153 case 0: A_j=A_Si; B_j=B_Si; Lam_j=Lam_Si;
00154 Mu_j=Mu_Si; R_j=R_Si; S_j=S_Si; break;
00155 case 1: A_j=A_Ge; B_j=B_Ge; Lam_j=Lam_Ge;
00156 Mu_j=Mu_Ge; R_j=R_Ge; S_j=S_Ge; break;
00157 case 2: A_j=A_C; B_j=B_C; Lam_j=Lam_C;
00158 Mu_j=Mu_C; R_j=R_C; S_j=S_C; break;
00159 }
00160
00161
00162 A = sqrt(A_i*A_j);
00163 B = sqrt(B_i*B_j);
00164 Lam = (Lam_i + Lam_j)*0.5;
00165 Mu = (Mu_i + Mu_j)*0.5;
00166 R = sqrt(R_i*R_j);
00167 S = sqrt(S_i*S_j);
00168
00169 r = rrij;
00170
00171 if(r>=S) continue;
00172
00173 if(r<R)
00174 {
00175 fC = 1;
00176 dfCdr = 0;
00177 }
00178 else if (r<S)
00179 {
00180 Arg = M_PI*(r-R)/(S-R);
00181 fC = 0.5+0.5*cos(Arg);
00182 dfCdr = -0.5*M_PI*sin(Arg)/(S-R);
00183 }
00184 else
00185 {
00186 fC = 0;
00187 dfCdr = 0;
00188 }
00189
00190 fR = A*exp(-Lam*r);
00191 dfRdr = -Lam*fR;
00192 fA = -B*exp(-Mu*r);
00193 dfAdr = -Mu*fA;
00194
00195
00196 rg[neg]=rij;
00197 rt[neg]=rij; rt[neg]/=rrij;
00198 rr[neg]=rrij;
00199 list2[neg]=jpt;
00200
00201 Asave[neg]=A_j;
00202 Bsave[neg]=B_j;
00203 Lamsave[neg]=Lam_j;
00204 Musave[neg]=Mu_j;
00205 Rsave[neg]=R_j;
00206 Ssave[neg]=S_j;
00207
00208 fCsave[neg]=fC;
00209 dfCdrsave[neg]=dfCdr;
00210 fAsave[neg]=fA;
00211 dfAdrsave[neg]=dfAdr;
00212 fRsave[neg]=fR;
00213 dfRdrsave[neg]=dfRdr;
00214
00215 neg++;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225 for(j=0;j<neg;j++)
00226 {
00227 jpt=list2[j];
00228 if(fixed[jpt]==-1) continue;
00229
00230 Z = 0;
00231
00232 for(k=0;k<neg;k++)
00233 {
00234 if(k==j) continue;
00235 kpt=list2[k];
00236
00237 if(fixed[kpt]==-1) continue;
00238
00239
00240 CosTheta=rt[j]*rt[k];
00241
00242 dCosTheta = dSqr+(hTf-CosTheta)*(hTf-CosTheta);
00243 gTheta = 1+cdSqr-cSqr/dCosTheta;
00244 Z += fCsave[k]*gTheta;
00245 dZdr[k] = dfCdrsave[k]*gTheta;
00246 dZdCosTheta[k] = fCsave[k]*(-2.0*cSqr*(hTf-CosTheta)/(dCosTheta*dCosTheta));
00247 }
00248
00249
00250
00251 fC = fCsave[j];
00252 dfCdr = dfCdrsave[j];
00253 fA = fAsave[j];
00254 dfAdr = dfAdrsave[j];
00255 fR = fRsave[j];
00256 dfRdr = dfRdrsave[j];
00257
00258 BetaZN = pow((Beta*Z),nTf);
00259
00260
00261
00262
00263 BetaZN1 = pow(Beta,nTf)*pow(Z,(nTf-1.0));
00264
00265 Chi = 1.0;
00266 if ((species[ipt]==0)&&(species[jpt]==1))
00267 Chi = Chi_Si_Ge;
00268 else if ((species[ipt]==1)&&(species[jpt]==0))
00269 Chi = Chi_Si_Ge;
00270 else if ((species[ipt]==0)&&(species[jpt]==2))
00271 Chi = Chi_C_Si;
00272 else if ((species[ipt]==2)&&(species[jpt]==0))
00273 Chi = Chi_C_Si;
00274
00275 bij = Chi*pow((1.0+BetaZN),invn2);
00276 V = 0.5*fC*(fR+bij*fA);
00277 _EPOT += V;
00278 _EPOT_IND[ipt] += V;
00279
00280 dVdr = 0.5*dfCdr*(fR+bij*fA) + 0.5*fC*(dfRdr+bij*dfAdr);
00281 f3i=rt[j]*dVdr;
00282 _F[ipt]+=f3i;
00283 _F[jpt]-=f3i;
00284 _VIRIAL.addnvv(-1.,f3i,rg[j]);
00285
00286
00287
00288
00289 dVdZ = 0.25*fC*fA*(-bij*BetaZN1/(1+BetaZN));
00290
00291
00292 for(k=0;k<neg;k++)
00293 {
00294 if(k==j) continue;
00295 kpt=list2[k];
00296 if(fixed[kpt]==-1) continue;
00297
00298
00299 CosTheta=rt[j]*rt[k];
00300
00301
00302 temp = dVdZ*dZdr[k];
00303
00304 fZ = rt[k]*temp;
00305 _F[ipt]+=fZ;
00306 _F[kpt]-=fZ;
00307 _VIRIAL.addnvv(-1.,fZ,rg[k]);
00308
00309
00310 temp = dVdZ*dZdCosTheta[k];
00311
00312 fTheta = (rt[j]*CosTheta-rt[k])*(-temp/rr[j]);
00313 _F[ipt]+=fTheta;
00314 _F[jpt]-=fTheta;
00315 _VIRIAL.addnvv(-1.,fTheta,rg[j]);
00316
00317 fTheta = (rt[k]*CosTheta-rt[j])*(-temp/rr[k]);
00318 _F[ipt]+=fTheta;
00319 _F[kpt]-=fTheta;
00320 _VIRIAL.addnvv(-1.,fTheta,rg[k]);
00321 }
00322 }
00323 }
00324
00325 for(i=0;i<_NP;i++)
00326 {
00327 if(fixed[i])
00328 _F[i].clear();
00329 }
00330
00331 #if 0
00332 DUMP("Tersoff Collect");
00333
00334 MP_AccumulateTo(_shmEPOTptr,&(_EPOT),1);
00335 MP_AccumulateTo((double *)_shmF,(double *)_F,3*_NP);
00336 MP_AccumulateTo(_shmEPOT_IND,_EPOT_IND,_NP);
00337 MP_AccumulateTo((double *)((*_shmVIRIALptr)[0]),
00338 (double *)(_VIRIAL[0]),9);
00339
00340 StrMemCpy(&(_EPOT),_shmEPOTptr,sizeof(double));
00341 StrMemCpy((double *)_F,(double *)_shmF,3*_NP*sizeof(double));
00342 StrMemCpy(_EPOT_IND,_shmEPOT_IND,_NP*sizeof(double));
00343 StrMemCpy((double *)(_VIRIAL[0]),
00344 (double *)((*_shmVIRIALptr)[0]),9*sizeof(double));
00345
00346 DUMP("Tersoff complete");
00347 #endif
00348 }
00349
00350
00351 void TersoffFrame::potential()
00352 {
00353 tersoff();
00354 }
00355
00356 #ifdef _TEST
00357
00358
00359 class TersoffFrame sim;
00360
00361
00362 #include "main.cpp"
00363
00364 #endif//_TEST
00365