00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "ljdimer.h"
00010
00011 void LJDIMERFrame::initparser()
00012 {
00013 MDPARALLELFrame::initparser();
00014
00015
00016 bindvar("C12_00",&_ALJ_00,DOUBLE);
00017 bindvar("C6_00",&_BLJ_00,DOUBLE);
00018 bindvar("R_DIMER",&R_DIMER,DOUBLE);
00019 bindvar("F_DIMER",&F_DIMER,DOUBLE);
00020 bindvar("F_DIMER_INTERNAL",&F_DIMER_INTERNAL,DOUBLE);
00021 bindvar("F_DIMER_EXTERNAL",&F_DIMER_EXTERNAL,DOUBLE);
00022 }
00023
00024 int LJDIMERFrame::exec(char *name)
00025 {
00026 if(MDPARALLELFrame::exec(name)==0) return 0;
00027 bindcommand(name,"initLJ",initLJ());
00028 return -1;
00029 }
00030
00031 void LJDIMERFrame::initvars()
00032 {
00033 _RLIST=LJ_RC+1.1;
00034 _SKIN=_RLIST-LJ_RC;
00035 MDPARALLELFrame::initvars();
00036 }
00037
00038 void LJDIMERFrame::initLJ()
00039 {
00040 ALJ_00=_ALJ_00*LJ_ENERGY*POW12(LJ_LENGTH);
00041 BLJ_00=_BLJ_00*LJ_ENERGY*POW6(LJ_LENGTH);
00042 Uc_00=(ALJ_00*POW6(1/LJ_RC)-BLJ_00)*POW6(1/LJ_RC);
00043 DUDRc_00=-(12*ALJ_00/POW6(LJ_RC)-6*BLJ_00)/POW6(LJ_RC)/LJ_RC;
00044
00045 H_DIMER=_H_DIMER*LJ_ENERGY;
00046 W_DIMER=_W_DIMER*LJ_LENGTH;
00047
00048 INFO_Printf("ALJ_00 = %e BLJ_00 = %e Uc_00 = %e DUDRc_00 = %e\n",ALJ_00,BLJ_00,Uc_00,DUDRc_00);
00049 INFO_Printf("H_DIMER = %e W_DIMER = %e\n",H_DIMER,W_DIMER);
00050 }
00051
00052 void LJDIMERFrame::calcprop()
00053 {
00054 MDPARALLELFrame::calcprop();
00055 }
00056
00057 void LJDIMERFrame::find_dimer_indices(int *ind0,int *ind1)
00058 {
00059 int ipt, i0, i1;
00060
00061 i0 = -1; i1 = -1;
00062 for(ipt=0;ipt<_NP;ipt++)
00063 {
00064 if(species[ipt]==1)
00065 {
00066 if(i0<0)
00067 {
00068 i0=ipt;
00069 }
00070 else if(i1<0)
00071 {
00072 i1=ipt;
00073 }
00074 else
00075 {
00076 FATAL("more than two atoms with species 1");
00077 }
00078 }
00079 }
00080 *ind0 = i0;
00081 *ind1 = i1;
00082 }
00083
00084 void LJDIMERFrame::lennard_jones_dimer()
00085 {
00086
00087
00088
00089
00090
00091
00092 int i,j,ipt,jpt, i0, i1;
00093 double U,r,r2,ri6,tmp;
00094 double ALJ,BLJ,Uc,DUDRc;
00095 Vector3 sij, rij, fij;
00096
00097 DUMP(HIG"Lennard Jones"NOR);
00098
00099 refreshneighborlist();
00100
00101 _EPOT=0;
00102
00103 for(i=0;i<_NP;i++)
00104 {_F[i].clear(); _EPOT_IND[i]=0;}
00105 _VIRIAL.clear();
00106
00107 for(ipt=0;ipt<_NP;ipt++)
00108 {
00109 for(j=0;j<nn[ipt];j++)
00110 {
00111
00112 jpt=nindex[ipt][j];
00113 if(ipt>jpt) continue;
00114 sij=_SR[jpt]-_SR[ipt];
00115 sij.subint();
00116 rij=_H*sij;
00117 r2=rij.norm2();
00118 r=sqrt(r2);
00119 if(r<=LJ_RC)
00120 {
00121 if((species[ipt]==0)||(species[jpt]==0))
00122 {
00123 ALJ=ALJ_00; BLJ=BLJ_00; Uc=Uc_00; DUDRc=DUDRc_00;
00124
00125 ri6=1./(r2*r2*r2);
00126
00127 U=(ALJ*ri6-BLJ)*ri6-r*DUDRc+(LJ_RC*DUDRc-Uc);
00128 fij=rij*((12*ALJ*ri6-6*BLJ)*ri6/r2+DUDRc/r);
00129
00130 _F[ipt]-=fij;
00131 _F[jpt]+=fij;
00132 _EPOT_IND[ipt]+=U*0.5;
00133 _EPOT_IND[jpt]+=U*0.5;
00134 _EPOT+=U;
00135 _VIRIAL.addnvv(1.,fij,rij);
00136 }
00137 }
00138 }
00139 }
00140
00141 find_dimer_indices(&i0,&i1);
00142
00143
00144 if((i0>=0)&&(i1>=0))
00145 {
00146
00147 sij=_SR[i1]-_SR[i0];
00148 sij.subint();
00149 rij=_H*sij;
00150 r2=rij.norm2();
00151 r=sqrt(r2);
00152 R_DIMER = r;
00153
00154 tmp = 1 - SQR((r-LJ_RC-W_DIMER)/W_DIMER);
00155 U = H_DIMER * SQR( tmp );
00156 F_DIMER_INTERNAL = 2*H_DIMER* tmp * ( 2*(r-LJ_RC-W_DIMER)/ SQR(W_DIMER) );
00157 fij = rij *( F_DIMER_INTERNAL / r);
00158
00159 _F[i0]-=fij;
00160 _F[i1]+=fij;
00161 _EPOT_IND[i0]+=U*0.5;
00162 _EPOT_IND[i1]+=U*0.5;
00163 _EPOT+=U;
00164 _VIRIAL.addnvv(1.,fij,rij);
00165 }
00166 }
00167
00168 void LJDIMERFrame::lennard_jones_dimer_constrained(double R)
00169 {
00170
00171
00172
00173
00174
00175 int i0, i1;
00176 double r, vn, fn;
00177 Vector3 sij, rij, snij, nij, svij, vij, fij;
00178
00179
00180 find_dimer_indices(&i0,&i1);
00181 sij = _SR[i1]-_SR[i0];
00182 sij.subint(); rij = _H*sij; r = rij.norm();
00183
00184
00185 if((r!=R)&&(r>0))
00186 {
00187 _SR[i1] += sij * ((R/r-1)/2);
00188 _SR[i0] -= sij * ((R/r-1)/2);
00189 }
00190
00191 if(r==0) FATAL("lennard_jones_dimer_constrained: r=0!");
00192
00193 sij = _SR[i1]-_SR[i0];
00194 sij.subint(); rij = _H*sij; r = rij.norm(); nij = rij/r; snij = sij/r;
00195
00196
00197
00198 svij = _VSR[i1] - _VSR[i0]; vij = _H*svij;
00199 vn = dot(vij,nij);
00200
00201
00202 _VSR[i1] -= snij*(vn/2);
00203 _VSR[i0] += snij*(vn/2);
00204 svij = _VSR[i1] - _VSR[i0]; vij = _H*svij;
00205 vn = dot(vij,nij);
00206
00207
00208 lennard_jones_dimer();
00209
00210
00211 fij = _F[i1] - _F[i0]; fn = dot(fij,nij);
00212 F_DIMER = fn/2; F_DIMER_EXTERNAL = F_DIMER - F_DIMER_INTERNAL;
00213 dEdlambda = F_DIMER_EXTERNAL;
00214
00215
00216 _F[i1] -= nij*(fn/2);
00217 _F[i0] += nij*(fn/2);
00218
00219
00220 }
00221
00222 void LJDIMERFrame::potential()
00223 {
00224 lennard_jones_dimer();
00225 }
00226
00227 void LJDIMERFrame::SWITCHpotential_user(double lambda)
00228 {
00229 lennard_jones_dimer_constrained(lambda);
00230 }
00231
00232
00233 #ifdef _TEST
00234
00235
00236 class LJDIMERFrame sim;
00237
00238
00239 #include "main.cpp"
00240
00241 #endif//_TEST
00242