Allink  v0.1
ForcesIntegration.cpp
00001 #include "Forces.h"
00005 void Forces::SolveLeaves(){
00006   AddRigid();
00007   double *Known = (double *) calloc(pNPCh(),sizeof(double));
00008   double *UnKnown = (double *) calloc(pNPCh(),sizeof(double));
00009   for(int c=0;c<pNChain();c++){
00010     int pInit = c*pNPCh();
00011     int pEnd = (c+1)*pNPCh();
00012     double Offset = 0.;
00013     for(int p=pInit;p<pEnd;p++)
00014       Known[p-pInit] = Pm[p].Pos[CNorm] - Offset;
00015     IntMatrix->Apply(Known,UnKnown);
00016     //IntMatrix->Solve(Known,UnKnown);
00017     for(int p=pInit;p<pEnd;p++){
00018       int p1 = p-pInit;
00019       if(Pm[p].Typ != 0){continue;}
00020       Pm[p].Pos[CNorm] = UnKnown[p1] + Offset;
00021     }
00022   }
00023   free(Known);
00024   free(UnKnown);
00025 }
00029 void Forces::SolveRod(){
00030   double *Known = (double *) calloc(pNPart(),sizeof(double));
00031   double *UnKnown = (double *) calloc(pNPart(),sizeof(double));
00032   double Offset = .5*pEdge(2);
00033   for(int p=0;p<pNPart();p++)
00034     Known[p] = Pm[p].Pos[CNorm] - Offset;
00035   IntMatrix->Apply(Known,UnKnown);
00036   //IntMatrix->Solve(Known,UnKnown);
00037   for(int p=0;p<pNPart();p++){
00038     if(Pm[p].Typ != 0){continue;}
00039     Pm[p].Pos[CNorm] = UnKnown[p] + Offset;
00040   }
00041   free(Known);
00042   free(UnKnown);
00043 }
00047 void Forces::SolveLinksIterative(){
00048   AddRigid();
00049   //SmoothGrid(NEdge);
00050   double Inter = pEdge(CLat1)/(double)NEdge;
00051   SPLINE Weight;
00052   int NIter = 2000;
00053   Weight.a0 = Kf.El[2];
00054   Weight.a1 = 0./Inter;
00055   Weight.a2 = Kf.Lap/SQR(Inter);
00056   Weight.a3 = 0./(Inter*SQR(Inter));
00057   Weight.a4 = Kf.SLap/(SQR(Inter)*SQR(Inter));
00058   int NDim = 2;
00059   Matrice *CoeffMatrix = new Matrice(Weight,NDim);
00060   double Offset = 0.;
00061   double *Known = (double *) calloc(pNPart(),sizeof(double));
00062   double *UnKnown = (double *) calloc(pNPart(),sizeof(double));
00063   double Sol = 0.;
00064   double Zed = 0.;
00065   int Link[2][5];
00066   CoeffMatrix->Print();
00067   for(int i=0;i<NIter;i++){
00068     for(int p=0;p<pNPart();p++)
00069       Known[p] = Pm[p].Pos[CNorm] - Offset;
00070     for(int p=0;p<pNPart();p++){
00071       if(Pm[p].Typ != 0){
00072    UnKnown[p] = Known[p];
00073    continue;
00074       }
00075       Sol = 0.;
00076       for(int d=0;d<2;d++){
00077    Link[d][1] = Ln[p].Link[d*2];
00078    Link[d][3] = Ln[p].Link[d*2+1];
00079    Link[d][0] = Ln[Link[d][1]].Link[d*2];
00080    Link[d][4] = Ln[Link[d][3]].Link[d*2+1];
00081    for(int l=0,l1=-2;l<5;l++,l1++){
00082      if(l==2){
00083        l1 = 0;
00084        continue;
00085      }
00086      // if(!PeriodicImage[d]){
00087      //   if(d == 0){
00088      //     if(Link[d][l] != p+l1*nEdge[1]) continue;
00089      //     if(Link[d][l] != p+l1) continue;
00090      //   }
00091      // }
00092      Sol += CoeffMatrix->Val(2,l)*Pm[Link[d][l]].Pos[2];
00093    }
00094       }
00095       UnKnown[p] = .4*Known[p] - .6*Sol/CoeffMatrix->Val(2,2);
00096     }
00097     for(int p=0;p<pNPart();p++){
00098       if(Pm[p].Typ != 0){continue;}
00099       Pm[p].Pos[CNorm] = UnKnown[p] + Offset;
00100     }
00101   }
00102   free(Known);
00103   free(UnKnown);
00104   delete CoeffMatrix;
00105 }
00109 void Forces::SolveLinks(){    
00110   AddRigid();
00111   FillMatrix();
00112   double Offset = 0.;
00113   double *Known = (double *) calloc(pNPart(),sizeof(double));
00114   double *UnKnown = (double *) calloc(pNPart(),sizeof(double));
00115   for(int p=0;p<pNPart();p++)
00116     Known[p] = Pm[p].Pos[CNorm] - Offset;
00117   IntMatrix->Apply(Known,UnKnown);
00118   for(int p=0;p<pNPart();p++){
00119     if(Pm[p].Typ != 0){continue;}
00120     Pm[p].Pos[CNorm] = UnKnown[p] + Offset;
00121   }
00122   free(Known);
00123   free(UnKnown);
00124 }
00125 // #include "compcol_double.h"
00126 // #include "comprow_double.h"
00127 // #include "ilupre_double.h"
00128 // #include "icpre_double.h"
00129 // #include "iotext_double.h"
00130 // void Forces::SolveLinksSparse(){
00131 //   int NEntries = 0;
00132 //   int NColMax = pNPart();
00133 //   int NRowMax = pNPart();
00134 //   for(int p=0;p<pNPart();p++){
00135 //     if(Pm[p].Typ != 0){
00136 //       IntMatrix->Set(p,p,1.);Entries++;
00137 //       continue;
00138 //     }
00139 //     int pym1 = Ln[p].Link[0];
00140 //     int pyp1 = Ln[p].Link[1];
00141 //     int pym2 = Ln[pym1].Link[0];
00142 //     int pyp2 = Ln[pyp1].Link[1];
00143 //     int pxm1 = Ln[p].Link[2];
00144 //     int pxp1 = Ln[p].Link[3];
00145 //     int pxm2 = Ln[pxm1].Link[2];
00146 //     int pxp2 = Ln[pxp1].Link[3];
00147 //     if(PeriodicImage[0]){ Entries += 4;
00148 //     }
00149 //     else{
00150 //       if(pxm2 == p-2*nEdge[1]) Entries++;
00151 //       if(pxm1 == p-nEdge[1]) Entries++;
00152 //       if(pxp1 == p+nEdge[1]) Entries++;
00153 //       if(pxp2 == p+2*nEdge[1]) Entries++;
00154 //     }
00155 //     Entries++;
00156 //     if(PeriodicImage[1]){Entries += 4;
00157 //     }
00158 //     else{
00159 //       if(pym2 == p-2) Entries++;
00160 //       if(pym1 == p-1) Entries++;
00161 //       if(pyp1 == p+1) Entries++;
00162 //       if(pyp2 == p+2) Entries++;
00163 //     }
00164 //   }
00165 //   double *MatVal = (double *)calloc(Entries,sizeof(double));
00166 //   int *ColIdx = (int *)calloc(Entries,sizeof(int));
00167 //   int *RowIdx = (int *)calloc(Entries,sizeof(int));
00168 //   for(int p=0,i=0;p<pNPart();p++){
00169 //     if(Pm[p].Typ != 0){
00170 //       ColIdx[i] = p;
00171 //       RowIdx[i] = p;
00172 //       MatVal[i] = 1.;
00173 //       i++;
00174 //       continue;
00175 //     }
00176 //     int pym1 = Ln[p].Link[0];
00177 //     int pyp1 = Ln[p].Link[1];
00178 //     int pym2 = Ln[pym1].Link[0];
00179 //     int pyp2 = Ln[pyp1].Link[1];
00180 //     int pxm1 = Ln[p].Link[2];
00181 //     int pxp1 = Ln[p].Link[3];
00182 //     int pxm2 = Ln[pxm1].Link[2];
00183 //     int pxp2 = Ln[pxp1].Link[3];
00184 //     // printf("%d)\n",p);
00185 //     //printf("%d %d %d %d\n",pym2,pym1,pyp1,pyp2);
00186 //     // printf("%d %d %d %d\n",pxm2,pxm1,pxp1,pxp2);
00187 //     if(PeriodicImage[0]){ 
00188 //       RowIdx[i]=p;ColIdx[i]=pxm2;ValMat[i]=CoeffMatrix->Val(2,0);i++;
00189 //       RowIdx[i]=p;ColIdx[i]=pxm1;ValMat[i]=CoeffMatrix->Val(2,1);i++;
00190 //       RowIdx[i]=p;ColIdx[i]=pxp1;ValMat[i]=CoeffMatrix->Val(2,3);i++;
00191 //       RowIdx[i]=p;ColIdx[i]=pxp2;ValMat[i]=CoeffMatrix->Val(2,4);i++;
00192 //     }
00193 //     else{
00194 //       if(pxm2 == p-2*nEdge[1])
00195 //    RowIdx[i]=p;ColIdx[i]=pxm2;ValMat[i]=CoeffMatrix->Val(2,0);i++;
00196 //       if(pxm1 == p-nEdge[1]) 
00197 //    RowIdx[i]=p;ColIdx[i]=pxm1;ValMat[i]=CoeffMatrix->Val(2,1);i++;
00198 //       if(pxp1 == p+nEdge[1]) 
00199 //    RowIdx[i]=p;ColIdx[i]=pxp1;ValMat[i]=CoeffMatrix->Val(2,3);i++;
00200 //       if(pxp2 == p+2*nEdge[1])
00201 //    RowIdx[i]=p;ColIdx[i]=pxp2;ValMat[i]=CoeffMatrix->Val(2,4);i++;
00202 //     }
00203 //     IntMatrix->Add(p,p,CoeffMatrix->Val(2,2));Entries++;
00204 //     if(PeriodicImage[1]){
00205 //       RowIdx[i]=p;ColIdx[i]=pym2;ValMat[i]=CoeffMatrix->Val(2,0);i++;
00206 //       RowIdx[i]=p;ColIdx[i]=pym1;ValMat[i]=CoeffMatrix->Val(2,1);i++;
00207 //       RowIdx[i]=p;ColIdx[i]=pyp1;ValMat[i]=CoeffMatrix->Val(2,3);i++;
00208 //       RowIdx[i]=p;ColIdx[i]=pyp2;ValMat[i]=CoeffMatrix->Val(2,4);i++;
00209 //     }
00210 //     else{
00211 //       if(pym2 == p-2) 
00212 //    RowIdx[i]=p;ColIdx[i]=pym2;ValMat[i]=CoeffMatrix->Val(2,0);i++;
00213 //       if(pym1 == p-1) 
00214 //    RowIdx[i]=p;ColIdx[i]=pym1;ValMat[i]=CoeffMatrix->Val(2,1);i++;
00215 //       if(pyp1 == p+1) 
00216 //    RowIdx[i]=p;ColIdx[i]=pyp1;ValMat[i]=CoeffMatrix->Val(2,3);i++;
00217 //       if(pyp2 == p+2) 
00218 //    RowIdx[i]=p;ColIdx[i]=pyp2;ValMat[i]=CoeffMatrix->Val(2,4);i++;
00219 //     }
00220 //   }
00221 //   Coord_Mat_double C(NRowMax,NColMax,Entries,MatVal,RowIdx,ColIdx);
00222 //   free(ColIdx);
00223 //   free(RowIdx);
00224 //   free(MatVal);
00225 // }
00226 // obsolete?
00227 // int Forces::Update(){
00228 //   for(int i=0;i<IntMax;i++){
00229 //     double Diff = Fm[Part2Move].Dir[2] - Fm[Part2Move].Ext[2];
00230 //     if(QUAD(Diff) < DiffForce ){
00231 //       printf("%d,%d) Force %lf= %lf - %lf Pos %lf \n",Part2Move,i,Diff,Fm[Part2Move].Dir[2],Fm[Part2Move].Ext[2],Pm[Part2Move].Pos[2]);
00232 //       break;
00233 //     }
00234 //     double Sign=1.;
00235 //     if( Diff < 0. ){
00236 //       Sign = -1.;
00237 //       Pm[Part2Move].Pos[2] -= IncrDist;      
00238 //     }
00239 //     else 
00240 //       Pm[Part2Move].Pos[2] += IncrDist;
00241 //     for(int p=0,pp=Part2Move-1,ppp=Part2Move+1;p<pNPart();p++)
00242 //       ;
00243 //     if( Diff < 0. ){
00244 //       Pm[Part2Move].Pos[2] -= IncrDist;
00245 //     }
00246 //     else if(Diff > 0.){
00247 //       Pm[Part2Move].Pos[2] += IncrDist;
00248 //     }
00249 //     ForceFieldLine();
00250 //     Diff = Fm[Part2Move].Dir[2] - Fm[Part2Move].Ext[2];
00251 //     if(QUAD(Diff) < DiffForce ){
00252 //       printf("%d,%d) Force %lf= %lf - %lf Pos %lf \n",Part2Move,i,Diff,Fm[Part2Move].Dir[2],Fm[Part2Move].Ext[2],Pm[Part2Move].Pos[2]);
00253 //       break;
00254 //     }
00255 //     if(Part2Move>0){
00256 //       if( Diff < 0. ){
00257 //    Pm[Part2Move-1].Pos[2] += IncrDist;
00258 //       }
00259 //       else if(Diff > 0.){
00260 //    Pm[Part2Move-1].Pos[2] -= IncrDist;
00261 //       }
00262 //     }
00263 //     if(Part2Move<pNPart()-1){
00264 //       if( Diff < 0. ){
00265 //    Pm[Part2Move+1].Pos[2] += IncrDist;
00266 //       }
00267 //       else if(Diff > 0.){
00268 //    Pm[Part2Move+1].Pos[2] -= IncrDist;
00269 //       }
00270 //     }
00271 //     ForceFieldLine();
00272 //   }
00273 // }
00274 // // obsolete?
00275 // int Forces::MinHelfrich(){
00276 //   SPLINE Par;
00277 //   SPLINE Sp2;
00278 //   double a1=0.;
00279 //   double a2=0.;
00280 //   double a3=0.;
00281 //   double a4=0.;
00282 //   double Ref=0.;
00283 //   double Dx = pEdge(0)/(double)(NEdge-1);
00284 //   for(int p=0;p<pNPart()-1;p++){
00285 //     if(p < 1){
00286 //       Sp2 = Mat->Forth(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,Pm[p+4].Pos,0,2);
00287 //       Ref = Pm[p].Pos[0] - Pm[p+2].Pos[0]; 
00288 //     }
00289 //     else if(p < 2){
00290 //       Sp2 = Mat->Forth(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,2);
00291 //       Ref = Pm[p].Pos[0] - Pm[p+1].Pos[0]; 
00292 //     }
00293 //     else if(p < pNPart()-2){
00294 //       Sp2 = Mat->Forth(Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2);
00295 //       Ref = 0.; 
00296 //     }
00297 //     else if(p == pNPart()-2){
00298 //       Sp2 = Mat->Forth(Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,0,2);
00299 //       Ref = Pm[p].Pos[0] - Pm[p-1].Pos[0]; 
00300 //     }
00301 //     else if(p <= pNPart()-1){
00302 //       Sp2 = Mat->Forth(Pm[p-4].Pos,Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,0,2);
00303 //       Ref = Pm[p].Pos[0] - Pm[p-2].Pos[0]; 
00304 //     }
00305 //     if(Pm[p].Typ == 1 || Pm[p].Typ == 2)
00306 //       continue;
00307 //     a2 = 2.*Sp2.a2 + 6.*Sp2.a3*Ref + 12.*Sp2.a4*Ref*Ref;
00308 //     a4 = 24.*Sp2.a4;
00309 //     a3 = a4*(12.*Dx*Dx - 24.*Kf.Lap/Kf.SLap) - 2.*a2;
00310 //     //a3 = a4*(12.*Dx*Dx - 24.*.1) - 2.*a2;
00311 //     a3 /= Dx;
00312 //     a1 = Pm[p+1].Pos[2] - Pm[p].Pos[2] - a2*Dx*Dx - a3*Dx*Dx*Dx - a4*Dx*Dx*Dx*Dx;
00313 //     a1 /= Dx;
00314 //     double x = Pm[p+1].Pos[0] - Pm[p].Pos[0];
00315 //     printf("%d) %lf %lf %lf %lf -> %lf\n",p,a1,a2,a3,a4,Pm[p].Pos[2] + a1*x + a2*x*x + a3*x*x*x + a4*x*x*x*x);
00316 //     Pm[p+1].Pos[2] = Pm[p].Pos[2] + a1*x + a2*x*x + a3*x*x*x + a4*x*x*x*x;
00317 //   }
00318 // }
00319 //---------------------------------RIGID--------------------------
00321 void Forces::VelVerletRigid(){
00322   for(int n=0;n<pNNano();n++){
00323     Vettore Axis(Nano[n].Axis,3);
00324     Vettore AMom(Nano[n].AMom,3);
00325     Vettore BackBone(3);
00326     Vettore VelTang(3);
00327     for(int d=0;d<3;d++){
00328       BackBone.x[d] = Nano[n].Axis[d]*Nano->Height*.5;
00329       double Ran = Nano[n].Zeta  * (2.*Mat->Casuale() - 1.);
00330       double Dis = - Nano[n].Gamma*Nano[n].AVel[d];
00331       Nano[n].AMom[d] += Ran + Dis;
00332     }
00333     Matrice InTensor(3,3);
00334     Matrice RotT(3,3);
00335     Matrice Resp(3,3);
00336     Matrice Resp2(3,3);
00337     Vettore AVel(3);
00338     Vettore Normal(0.,0.,1.);
00339     Vettore Ax(3);
00340     Axis.VetV(&Axis,&Normal);
00341     double Angle = Ax.Angle(&Axis,&Normal);
00342     Quadri q(Ax.x,Angle);
00343     Matrice Rot(q,3);
00344     Rot.CopyOn(&RotT);
00345     RotT.Transpose();
00346     InTensor.Set(0,0,1./(Nano->Mass*(.25*SQR(Nano->Rad)+1./12.*SQR(Nano->Height) ) ) );
00347     InTensor.Set(1,1,1./(Nano->Mass*(.25*SQR(Nano->Rad)+1./12.*SQR(Nano->Height) ) ) );
00348     InTensor.Set(2,2,1./(.5*Nano->Mass*SQR(Nano->Rad)) );
00349     // Calculating r^t I^-1 r L = w
00350     Resp.Mult(RotT,InTensor);
00351     Resp2.Mult(Resp,Rot);
00352     //    MatrVect(Resp2,Nano->AMom,AVel);
00353  
00354     //printf("%d) %d\n",n,Gen->Step);
00355     for(int d=0;d<3;d++){
00356       double tmp = .5*Nano[n].Force[d]*pDeltat()/Nano[n].Mass;
00357       Nano[n].Vel[d] += tmp;
00358       Nano[n].AVel[d] += Nano[n].AMom[d]/Nano[n].Mass*.01;
00359       Nano[n].Pos[d] += Nano[n].Vel[d]*pDeltat();
00360       Nano[n].Pos[d] -= floor(Nano[n].Pos[d]/pEdge(d))*pEdge(d);
00361     }
00362     if(Nano[n].Shape != 2) continue;
00363     Vettore Omega(Nano[n].AVel,3);
00364     for(int d=0;d<3;d++)
00365       BackBone.x[d] = Nano[n].Height*.5*Nano[n].Axis[d];
00366     VelTang.VetV(&Omega,&BackBone);
00367     for(int d=0;d<3;d++){
00368       BackBone.x[d] += VelTang.x[d]*pDeltat();
00369       Axis.x[d] = BackBone.x[d];
00370     }
00371     Axis.Normalize();
00372     Axis.Export(Nano[n].Axis);
00373     //printf("%lf %lf %lf\n",Nano[n].Vel[0],Nano[n].Vel[1],Nano[n].Vel[2]);
00374     //printf("%lf %lf %lf\n",Nano[n].Force[0],Nano[n].Force[1],Nano[n].Force[2]);
00375     //printf("%lf %lf %lf\n",Nano[n].Pos[0],Nano[n].Pos[1],Nano[n].Pos[2]);
00376     //printf("%lf %lf %lf\n",Nano[n].AMom[0],Nano[n].AMom[1],Nano[n].AMom[2]);
00377   }
00378 }
00382 void Forces::VelVerletRigid2(){
00383   for(int n=0;n<pNNano();n++) {
00384     for(int d=0;d<3;d++){
00385       Nano[n].AVel[d] += .5*Nano[n].AMom[d];
00386       Nano[n].Vel[d] += .5*Nano[n].Force[d]*pDeltat()/Nano[n].Mass;
00387     }
00388   }
00389 }
00390 //------------------------------------------------------------
00391 //-------------------------MONTE-CARLO------------------------
00392 //------------------------------------------------------------
00394 int Forces::IfMetropolis(double Arg,double Weight){
00395   if(exp(pBeta()*Arg)*Weight > 1. ) return 1;
00396   double Ran = Mat->Casuale();
00397   if(exp(pBeta()*Arg)*Weight > Ran ){
00398     return 1;
00399   }
00400   return 0;
00401 }
00402 //-----------------Single-particle----------------------------
00404 int Forces::InsertBead(int p){
00405   Pm[p].Pos[0] = pEdge(0)*Mat->Casuale();
00406   Pm[p].Pos[1] = pEdge(1)*Mat->Casuale();
00407   Pm[p].Pos[2] = pEdge(2)*Mat->Casuale();
00408   Pc->AddPart(p,Pm[p].Pos);
00409 }
00413 int Forces::TryInsert(){
00414   int p = pNPart();
00415   ReSetNPart(pNPart()+1);
00416   InsertBead(p);
00417   double Pot[3];
00418   double NrgDiff = CalcNrgBead(p,Pot);
00419   double Arg = ChemPotId + ChemPotEx - NrgDiff;
00420   double Weight = pVol()/(double)(pNPart()+1);
00421   if( !IfMetropolis(Arg,Weight) ){
00422     Pc->RemPart(p,Pm[p].Pos);
00423     ReSetNPart(pNPart()-1);
00424     return 0;
00425   }
00426   //printf("Added a particle %d\n",p);
00427   return 1;
00428 }
00432 int Forces::TryRemove(){
00433   printf("remove\n");
00434   int p = (int)(Mat->Casuale()*pNPart());
00435   double Pot[3];
00436   double NrgDiff = CalcNrgBead(p,Pot); 
00437   double Arg = - ChemPotId - ChemPotEx - NrgDiff;
00438   if( !IfMetropolis(Arg,pNPart()/pVol()) ){
00439     return 0;
00440   }
00441   SwapPart(p,pNPart()-1);
00442   Pc->SwapPart(p,Pm[p].Pos,pNPart()-1,Pm[pNPart()-1].Pos);
00443   Pc->RemPart(pNPart()-1,Pm[pNPart()-1].Pos);
00444   ReSetNPart(pNPart()-1);
00445   return 1;
00446 }
00448 int Forces::MoveBead(int p){
00449   for(int d=0;d<3;d++){
00450     Pm[p].Pos[d] += Mat->Gaussiano(0.,GaussVar);
00451     Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00452   }
00453 }
00457 int Forces::TryMove(){
00458   int p = (int)(Mat->Casuale()*pNPart());
00459   if(Pm[p].Typ >= 2) return 1;
00460   //old situa
00461   double Pos[3] = {Pm[p].Pos[0],Pm[p].Pos[1],Pm[p].Pos[2]};
00462   double Pot[3] = {0.,0.,0.};
00463   double Nrg0 = CalcNrgBead(p,Pot);
00464   //RemDens(p,p+1);
00465   //double Nrg0 = OldNrgPm[p*3] + OldNrgPm[p*3+1] + OldNrgPm[p*3+2];
00466   //new situa
00467   MoveBead(p);
00468   Pc->MovePart(p,Pos,Pm[p].Pos);
00469   //AddDens(p,p+1);
00470   double Nrg1 = CalcNrgBead(p,Pot);
00471   //like the new situa?
00472   double NrgDiff = Nrg1 - Nrg0;
00473   if(!IfMetropolis(-NrgDiff,1.)){
00474     //RemDens(p,p+1);
00475     Pc->MovePart(p,Pm[p].Pos,Pos);
00476     for(int d=0;d<3;d++) Pm[p].Pos[d] = Pos[d];
00477     //AddDens(p,p+1);
00478     return 0;
00479   }
00480   //OldNrgSys = SumDens(0,pNPart());
00481   OldNrgSys -= Pot[2];//DensFuncNrgCh(c);
00482   return 1;
00483 }
00484 //-----------------------------Chains---------------------
00488 void Forces::StudySys(){
00489   //getting the distribution
00490   double Norm = 0.;
00491   double *LineS = new double[NBin];
00492   for(int i=0;i<NBin;i++){
00493     FirstBeadDistr[i] = 0.;
00494   }
00495   for(int c=0;c<pNChain();c++){
00496     int p1 = c*pNPCh();
00497     int i = (int)(Pm[p1].Pos[CNorm]*NBin*pInvEdge(CNorm));
00498     if(i < 0 || i >= NBin) continue;
00499     FirstBeadDistr[i] += 1.;
00500     Norm += 1.;
00501   }
00502   //normalizing and smoothing
00503   for(int v=0;v<NBin;v++) LineS[v] = FirstBeadDistr[v];
00504   InterBSpline1D(LineS,FirstBeadDistr,NBin,NBin);
00505   for(int v=0;v<NBin;v++) LineS[v] = FirstBeadDistr[v];
00506   InterBSpline1D(LineS,FirstBeadDistr,NBin,NBin);
00507   Norm = Norm >= 0. ? 1./Norm : 1.;
00508   for(int i=0;i<NBin;i++){
00509     FirstBeadDistr[i] *= Norm;
00510   }
00511   //cumulative
00512   for(int i=1;i<NBin;i++){
00513     FirstBeadDistr[i] += FirstBeadDistr[i-1];
00514     if(FirstBeadDistr[i] > .25 && FirstBeadDistr[i-1] < .25)
00515       BorderBias[0] = i/NBin*pEdge(CNorm);
00516     else if(FirstBeadDistr[i] > .75 && FirstBeadDistr[i-1] < .75)
00517       BorderBias[1] = i/NBin*pEdge(CNorm);
00518   }
00519   delete [] LineS;
00520 }
00524 void Forces::ConsiderCh(int c){
00525   int p1 = c*pNPCh();
00526   for(int p=0;p<pNPCh();p++) Pc->AddPart(p+p1,Pm[p+p1].Pos);
00527   AddDens(p1,p1+pNPCh());
00528 }
00532 void Forces::IgnoreCh(int c){
00533   int p1 = c*pNPCh();
00534   RemDens(p1,p1+pNPCh());
00535   for(int p=0;p<pNPCh();p++) Pc->RemPart(p+p1,Pm[p+p1].Pos);
00536 }
00540 void Forces::RemChFromSys(int c){
00541   int c2 = pNChain()-1;
00542   int p1 = c*pNPCh();
00543   int p2 = c2*pNPCh();
00544   RemDens(p1,p1+pNPCh());
00545   if(c != c2){
00546     for(int e=0;e<3;e++)
00547       OldNrgCh[c*3+e] = OldNrgCh[c2*3+e];
00548     RemDens(p2,p2+pNPCh());
00549     // for(int p=0;p<pNPCh();p++)
00550     //   Pc->RemPart(p2+p,Pm[p2+p].Pos);
00551     // for(int p=0;p<pNPCh();p++)
00552     //   Pc->RemPart(p1+p,Pm[p1+p].Pos);
00553     // SwapChain(c,pNChain()-1);
00554     // for(int p=0;p<pNPCh();p++)
00555     //   Pc->AddPart(p1+p,Pm[p1+p].Pos);
00556     for(int p=0;p<pNPCh();p++)
00557       Pc->SwapPart(p+p1,Pm[p+p1].Pos,p2+p,Pm[p2+p].Pos);
00558     SwapChain(c,pNChain()-1);
00559     AddDens(p1,p1+pNPCh());
00560   }
00561   for(int p=0;p<pNPCh();p++)
00562     Pc->RemPart(p2+p,Pm[p2+p].Pos);
00563   ReSetNPart(pNPart()-pNPCh());
00564   ReSetNChain(pNChain()-1);
00565 }
00569 void Forces::SaveCh(int c){
00570   int p1 = c*pNPCh();
00571   for(int p=0;p<pNPCh();p++){
00572     for(int d=0;d<3;d++){
00573       OldPos[p][d] = Pm[p+p1].Pos[d];
00574     }
00575   }
00576 }
00580 void Forces::ReInsertCh(int c){
00581   IgnoreCh(c);
00582   int p1 = c*pNPCh();
00583   //old situa
00584   for(int p=0;p<pNPCh();p++){
00585     for(int d=0;d<3;d++){
00586       Pm[p+p1].Pos[d] = OldPos[p][d];
00587     }
00588   }
00589   ConsiderCh(c);
00590 }
00592 double Forces::InsertCh(int c){
00593   int p1 = c*pNPCh();
00594   double Weight = 1.;
00595   ReSetNPart(pNPart()+pNPCh());
00596   ReSetNChain(pNChain()+1);
00597   Pm[p1].Pos[CLat1] = Mat->Casuale()*pEdge(CLat1);
00598   Pm[p1].Pos[CLat2] = Mat->Casuale()*pEdge(CLat2);
00599   Pm[p1].Pos[CNorm] = Mat->Casuale()*pEdge(CNorm);
00600   if(VAR_IF_TYPE(CalcMode,CALC_BIL_BIAS)){
00601     Pm[p1].Pos[CNorm] = Mat->Casuale()*(BorderBias[1] - BorderBias[0]) + BorderBias[0];      
00602       //Mat->RandDiscrProb(FirstBeadDistr,NBin)*pEdge(CNorm);
00603     Weight *= (BorderBias[1]-BorderBias[0])*pEdge(CLat1)*pEdge(CLat2)/pVol();
00604   }
00605   else if(VAR_IF_TYPE(CalcMode,CALC_SPH_BIAS)){
00606     double Incr = 0.2;
00607     double z = 2.0 * Mat->Casuale() - 1.0;
00608     double t = 2.0 * M_PI * Mat->Casuale();
00609     double w = sqrt( 1 - z*z );
00610     double x = w * cos( t );
00611     double y = w * sin( t );
00612     double Rad = Mat->Casuale()*Incr + Nano->Rad;
00613     Pm[p1].Pos[CLat1] = x*Rad + Nano->Pos[0];
00614     Pm[p1].Pos[CLat2] = y*Rad + Nano->Pos[1]; 
00615     Pm[p1].Pos[CNorm] = z*Rad + Nano->Pos[2];
00616     double Vol = 4./3.*M_PI*( CUBE(Nano->Rad + Incr) - CUBE(Nano->Rad));
00617     Weight *= Vol/pVol();
00618   }
00619   Weight *= InsertRest(p1,0);
00620   // for(int p=0;p<pNPCh();p++){
00621   //   fprintf(StatFile1,"%lf %lf %lf 0. 0. 0. %d\n",Pm[p1+p].Pos[0],Pm[p1+p].Pos[1],Pm[p1+p].Pos[2],pType(p+p1));
00622   // }
00623   // fflush(StatFile1);
00624   ConsiderCh(c);
00625   return Weight;
00626 }
00628 double Forces::InsertRest(int pCurr,int StartPos){
00629   double Weight = 1.;
00630   for(int p=StartPos+1;p<pNPCh();p++){
00631     for(int d=0;d<3;d++){
00632       double Ran = Mat->Gaussiano(0.,GaussVar);
00633       Pm[p+pCurr].Pos[d] = Pm[p-1+pCurr].Pos[d] + Ran;
00634       Pm[p+pCurr].Pos[d] -= floor(Pm[p+pCurr].Pos[d]*pInvEdge(d))*pEdge(d);
00635     }
00636   }
00637   for(int p=StartPos-1;p>=0;p--){
00638     for(int d=0;d<3;d++){
00639       double Ran = Mat->Gaussiano(0.,GaussVar);
00640       Pm[p+pCurr].Pos[d] = Pm[p+1+pCurr].Pos[d] + Ran;
00641       Pm[p+pCurr].Pos[d] -= floor(Pm[p+pCurr].Pos[d]*pInvEdge(d))*pEdge(d);
00642     }
00643   }
00644   return Weight;
00645 }
00649 int Forces::TryMoveCh(){
00650   int c = (int)(Mat->Casuale()*pNChain());
00651   int p1 = c*pNPCh();
00652   double Pot[3];
00653   // old situa
00654   SaveCh(c);
00655   IgnoreCh(c);
00656   double NrgOld = CalcNrgCh(c,Pot);
00657   // new situa
00658   ReSetNPart(pNPart()-pNPCh());
00659   ReSetNChain(pNChain()-1);
00660   InsertCh(c);
00661   double NrgNew = CalcNrgCh(c,Pot);
00662   //like the new situa?
00663   double NrgDiff = NrgNew - NrgOld;
00664   if(!IfMetropolis(-NrgDiff,1.)){
00665     ReInsertCh(c);
00666     return 0;
00667   }
00668   OldNrgCh[c*3+2] = NrgNew;
00669   OldNrgSys += NrgDiff;
00670   return 1;
00671 }
00675 int Forces::TryRemoveCh(){
00676   if(pNPart() <= 0) return 0;
00677   int c = (int)(Mat->Casuale()*pNChain());
00678   int p1 = c*pNPCh();
00679   double Pot[3];
00680   //like the new situa?
00681   double NrgDiff = CalcNrgCh(c,Pot);
00682   //double NrgDiff = OldNrgCh[c*3+2];
00683   //fprintf(StatFile1,"%lf\n",NrgDiff);
00684   //fflush(StatFile1);
00685    double Arg = -ChemPotId -ChemPotEx +NrgDiff;
00686   double Weight = pNChain()/pVol();
00687   if(!IfMetropolis(Arg,Weight) ){
00688     return 0;
00689   }
00690   RemChFromSys(c);
00691   OldNrgSys -= NrgDiff;
00692   return 1;
00693 }
00697 int Forces::TryInsertCh(){
00698   //old situa
00699   int c = pNChain();
00700   int p1 = c*pNPCh();
00701   double Pot[3];
00702   //new situa
00703   InsertCh(c);
00704   //like the new situa?
00705   double NrgDiff = CalcNrgCh(c,Pot);
00706   //fprintf(StatFile2,"%lf\n",NrgDiff);
00707   fflush(StatFile2);
00708   //printf("add %lf sys %lf\n",NrgDiff,OldNrgSys);
00709   double Arg = ChemPotId + ChemPotEx - NrgDiff;
00710   double Weight = pVol()/(double)(pNChain()+1);
00711   //printf("Ins %lf\n",NrgDiff);
00712   if(!IfMetropolis(Arg,Weight)){
00713     RemChFromSys(c);
00714     return 0;
00715   }
00716   //printf("accepted\n");
00717   //printf("Inserted %lf\n",NrgDiff);
00718   OldNrgCh[c*3+2] = NrgDiff;
00719   OldNrgSys += NrgDiff;
00720   return 1;
00721 }
00722 //---------------------------Bias-------------------------------
00724 double Forces::RemoveChBias(int c){
00725   int p1 = c*pNPCh();
00726   RemDens(p1,p1+pNPCh());
00727   for(int p=0;p<pNPCh();p++) Pc->RemPart(p+p1,Pm[p+p1].Pos);
00728   double NrgDiff = DensFuncNrgGhost(Pm[p1].Pos,p1,Pm[p1].Typ);
00729   //fprintf(StatFile1,"%lf %lf\n",NrgDiff,NanoNrg(p1));
00730   NrgDiff += CalcBendingGhost(Pm[p1].Pos,p1);
00731   NrgDiff += NanoNrg(p1);
00732   double Weight = exp(-NrgDiff+NrgPBead);
00733   Pc->AddPart(p1,Pm[p1].Pos);
00734   AddDens(p1,p1+1);
00735   for(int p=p1+1;p<p1+pNPCh();p++){
00736     Weight *= WeightSetBond(p,Pm[p].Typ);
00737     Pc->AddPart(p,Pm[p].Pos);
00738     AddDens(p,p+1);
00739   }
00740   return Weight;
00741 }
00743 double Forces::WeightSetBond(int p,int Type){
00744   double NrgDiff = DensFuncNrgGhost(Pm[p].Pos,p,Pm[p].Typ);
00745   NrgDiff += CalcBendingGhost(Pm[p].Pos,p);
00746   NrgDiff += NanoNrg(p);
00747   CumProbBias[0] = exp(-NrgDiff+NrgPBead);
00748   for(int t=1;t<NTrialBias;t++){
00749     for(int d=0;d<3;d++){
00750       BondPosBias[t][d] = Pm[p-1].Pos[d] + Mat->Gaussiano(0.,GaussVar);
00751       BondPosBias[t][d] -= floor(BondPosBias[t][d]*pInvEdge(d))*pEdge(d);
00752     }
00753     NrgDiff = DensFuncNrgGhost(BondPosBias[t],p,Type);
00754     //fprintf(StatFile1,"%lf %lf\n",NrgDiff,NanoNrg(BondPosBias[t],Type));
00755     NrgDiff += CalcBendingGhost(BondPosBias[t],p);
00756     NrgDiff += NanoNrg(BondPosBias[t],Type);
00757     CumProbBias[t] = exp(-NrgDiff+NrgPBead);
00758   }
00759   double Weight = 0.;
00760   for(int t=0;t<NTrialBias;t++){
00761     Weight += CumProbBias[t];
00762   }
00763   return Weight/(double)NTrialBias;
00764 }
00766 double Forces::InsertChBias(int c){
00767   int p1 = c*pNPCh();
00768   double Weight = 1.;
00769   ReSetNPart(pNPart()+pNPCh());
00770   ReSetNChain(pNChain()+1);
00771   Pm[p1].Pos[CLat1] = Mat->Casuale()*pEdge(CLat1);
00772   Pm[p1].Pos[CLat2] = Mat->Casuale()*pEdge(CLat2);
00773   Pm[p1].Pos[CNorm] = Mat->Casuale()*pEdge(CNorm);
00774   if(VAR_IF_TYPE(CalcMode,CALC_BIL_BIAS)){
00775     Pm[p1].Pos[CNorm] = Mat->Casuale()*(BorderBias[1] - BorderBias[0]) + BorderBias[0];      
00776       //Mat->RandDiscrProb(FirstBeadDistr,NBin)*pEdge(CNorm);
00777     Weight *= (BorderBias[1]-BorderBias[0])*pEdge(CLat1)*pEdge(CLat2)/pVol();
00778   }
00779   else if(VAR_IF_TYPE(CalcMode,CALC_SPH_BIAS)){
00780     double Incr = 0.2;
00781     double z = 2.0 * Mat->Casuale() - 1.0;
00782     double t = 2.0 * M_PI * Mat->Casuale();
00783     double w = sqrt( 1 - z*z );
00784     double x = w * cos( t );
00785     double y = w * sin( t );
00786     double Rad = Mat->Casuale()*Incr + Nano->Rad;
00787     Pm[p1].Pos[CLat1] = x*Rad + Nano->Pos[0];
00788     Pm[p1].Pos[CLat2] = y*Rad + Nano->Pos[1];
00789     Pm[p1].Pos[CNorm] = z*Rad + Nano->Pos[2];
00790     double Vol = 4./3.*M_PI*( CUBE(Nano->Rad + Incr) - CUBE(Nano->Rad));
00791     Weight *= Vol/pVol();
00792     //fprintf(StatFile2,"%lf %lf %lf %d\n",Pm[p1].Pos[0],Pm[p1].Pos[1],Pm[p1].Pos[2],pType(p1));
00793     //fflush(StatFile2);
00794   }
00795   double NrgDiff = DensFuncNrgGhost(Pm[p1].Pos,p1,Pm[p1].Typ);
00796   fprintf(StatFile2,"%lf %lf\n",NrgDiff,NanoNrg(p1));
00797   NrgDiff += CalcBendingGhost(Pm[p1].Pos,p1);
00798   NrgDiff += NanoNrg(p1);
00799   Weight *= exp(-NrgDiff+NrgPBead);
00800   // printf("Weight1 %lf %lf\n",NrgDiff,Weight);
00801   Pc->AddPart(p1,Pm[p1].Pos);
00802   AddDens(p1,p1+1);
00803   for(int p=p1+1;p<(c+1)*pNPCh();p++){
00804     double Weight1 = CreateSetBond(p,Pm[p].Typ);
00805     Weight *= Weight1;
00806     Pc->AddPart(p,Pm[p].Pos);
00807     AddDens(p,p+1);
00808   }
00809   // for(int p=0;p<pNPCh();p++){
00810   //   fprintf(StatFile1,"%lf %lf %lf %d\n",Pm[p1+p].Pos[0],Pm[p1+p].Pos[1],Pm[p1+p].Pos[2],pType(p+p1));
00811   // }
00812   // fflush(StatFile1);
00813   return Weight;
00814 }
00816 double Forces::CreateSetBond(int p,int Type){
00817   int tChoosen = 0;
00818   for(int t=0;t<NTrialBias;t++){
00819     for(int d=0;d<3;d++){
00820       BondPosBias[t][d] = Pm[p-1].Pos[d] + Mat->Gaussiano(0.,GaussVar);
00821       BondPosBias[t][d] -= floor(BondPosBias[t][d]*pInvEdge(d))*pEdge(d);
00822     }
00823     double NrgDiff = DensFuncNrgGhost(BondPosBias[t],p,Type);
00824     fprintf(StatFile2,"%lf %lf\n",NrgDiff,NanoNrg(BondPosBias[t],Type));
00825     NrgDiff += CalcBendingGhost(BondPosBias[t],p);
00826     NrgDiff += NanoNrg(BondPosBias[t],Type);
00827     CumProbBias[t] = exp(-NrgDiff+NrgPBead);
00828   }
00829   double Weight = 0.;
00830   for(int t=0;t<NTrialBias;t++){
00831     Weight += CumProbBias[t];
00832   }
00833   CumProbBias[0] /= Weight;
00834   double Ran = Mat->Casuale();
00835   for(int t=1;t<NTrialBias;t++){
00836     CumProbBias[t] /= Weight;
00837     CumProbBias[t] += CumProbBias[t-1];
00838   }
00839   for(int t=0;t<NTrialBias;t++){
00840     if(Ran < CumProbBias[t]){
00841       tChoosen = t;
00842       break;
00843     }
00844   }
00845   for(int d=0;d<3;d++){
00846     Pm[p].Pos[d] = BondPosBias[tChoosen][d];
00847     Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00848   }
00849   return Weight/(double)NTrialBias;
00850 }
00854 int Forces::TryRemoveChBias(){
00855   if(pNPart() <= 0) return 0;
00856   int c = (int)(Mat->Casuale()*pNChain());
00857   int p1 = c*pNPCh();
00858   double Weight1 = RemoveChBias(c);
00859   double Arg = - ChemPotId - ChemPotEx ;
00860   double Weight = pNChain()/(Weight1*pVol());
00861   //printf("rem %lf\n",Weight1);
00862   //fprintf(TempFile,"1 %lf\n",NrgDiff);
00863   if(!IfMetropolis(Arg,Weight)){
00864     return 0;
00865   }
00866   //fprintf(TempFile,"2 %lf\n",NrgDiff);
00867   RemChFromSys(c);
00868   return 1;
00869 }
00873 int Forces::TryInsertChBias(){
00874   //add one chain
00875   int c = pNChain();
00876   int p1 = c*pNPCh();
00877   double Weight1 = InsertChBias(c);
00878   double Arg = ChemPotId + ChemPotEx;
00879   double Weight = Weight1*pVol()/(double)(pNChain()+1);
00880   if(!IfMetropolis(Arg,Weight)){
00881     RemChFromSys(c);
00882     return 0;
00883   }
00884   return 1;
00885 }
00886 //-------------------WIDOM--------------------------
00890 void Forces::WidomInsert(double *NrgDiff){
00891   int p1 = pNPart();
00892   InsertBead(p1);
00893   *NrgDiff = DensFuncNrgGhost(Pm[p1].Pos,p1,Pm[p1].Typ);
00894   *NrgDiff += CalcBendingGhost(Pm[p1].Pos,p1);
00895   *NrgDiff += NanoNrg(p1);
00896   Pc->RemPart(p1,Pm[p1].Pos);
00897 }
00901 void Forces::WidomRemove(double *NrgDiff,int p){
00902   double Pot[3];
00903   *NrgDiff = CalcNrgBead(p,Pot);
00904 }
00908 void Forces::WidomInsertCh(double *NrgDiff){
00909   int c = pNChain();
00910   int p1 = c*pNPCh();
00911   InsertCh(c);
00912   CalcNrgCh(c,NrgDiff);
00913   RemChFromSys(c);
00914 }
00918 void Forces::WidomRemoveCh(double *NrgDiff,int c){
00919   NrgDiff[0] = OldNrgCh[c*3  ];
00920   NrgDiff[1] = OldNrgCh[c*3+1];
00921   NrgDiff[2] = OldNrgCh[c*3+2];
00922 }
00926 void Forces::WidomBiasChIn(double *Weight){
00927   int c = pNChain();
00928   int p1 = c*pNPCh();
00929   *Weight = InsertChBias(c);
00930   RemChFromSys(c);
00931 }
00935 void Forces::WidomBiasChOut(double *Weight,int c){
00936   *Weight = RemoveChBias(c);
00937 }
00938 //----------------------MOLECULAR-DYNAMICS----------------------
00942 void Forces::VelVerlet1(){
00943   for(int p=0;p<pNPart();p++){
00944     if(Pm[p].Typ != 0) continue;
00945     for(int d=0;d<3;d++){
00946       //if(fabs(Fm[p].Dir[d]) > 500.) continue;
00947       Pm[p].Vel[d] += .5*(Fm[p].Dir[d] + Fm[p].Ext[d])*pDeltat();
00948       Pm[p].Pos[d] += Pm[p].Vel[d]*pDeltat();
00949       Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00950       //printf("%d %d) %lf %g %lf\n",p,d,Pm[p].Pos[d],Fm[p].Dir[d],Pm[p].Vel[d]);
00951     }
00952   }
00953 }
00957 void Forces::LangevinTherm(){
00958   double Gamma = Viscosity;//3.*3.14*10.*Viscosity;
00959   double Zeta = sqrt(12.*2.*1.*Gamma/pDeltat());
00960   for(int p=0;p<pNPart();p++){
00961     for(int d=0;d<3;d++){
00962       Fm[p].Dir[d] += Zeta*(2.*Mat->Casuale() - 1.);
00963       //Fm[p].Dir[d] += Zeta*Mat->Gaussiano(0.,1.);
00964       Fm[p].Dir[d] -= Gamma*Pm[p].Vel[d];
00965     }
00966   }
00967 }
00971 void Forces::AndersenTherm(){
00972   double Sigma = sqrt(pTemp());
00973   for(int p=0;p<pNPart();p++){
00974     if(Mat->Casuale() < pDeltat()){
00975       for(int d=0;d<3;d++){
00976    Pm[p].Vel[d] = Mat->Gaussiano(0.,Sigma);
00977       }
00978     }
00979   }
00980 }
00984 void Forces::BerendsenTherm(){
00985   double Temp = 0.;
00986   for(int p=0;p<pNPart();p++){
00987     for(int d=0;d<3;d++){
00988       Pm[p].Vel[d] += .5*Fm[p].Dir[d]*pDeltat();
00989       Temp += SQR(Pm[p].Vel[d]);
00990     }
00991   }
00992   Temp = Temp/(3*pNPart());
00993   double Norm = 1./sqrt(Temp);
00994   for(int p=0;p<pNPart();p++){
00995     for(int d=0;d<3;d++){
00996       Pm[p].Vel[d] *= Norm;
00997     }
00998   }
00999 }
01003 void Forces::ChooseThermostat(int Mode){
01004   printf("Thermostat: ");
01005   if(Mode==THERM_LANG){
01006     CalcTherm = &Forces::LangevinTherm;
01007     printf("Langevin\n");
01008   }
01009   else if((Mode==THERM_AND)){
01010     CalcTherm = &Forces::AndersenTherm;
01011     printf("Andersen\n");
01012   }
01013   else if((Mode==THERM_BERE)){
01014     CalcTherm = &Forces::BerendsenTherm;
01015     printf("Berendsen\n");
01016   }
01017   else if((Mode==THERM_NO)){
01018     CalcTherm = &Forces::NoTherm;
01019     printf("no thermostat\n");
01020   }
01021   else{
01022    printf("mode not present\n");
01023    exit(1);
01024   }
01025 }
01029 void Forces::VelVerlet2(){
01030   for(int p=0;p<pNPart();p++){
01031     for(int d=0;d<3;d++){
01032       Pm[p].Vel[d] += .5*(Fm[p].Dir[d] + Fm[p].Ext[d])*pDeltat();
01033       Fm[p].Dir[d] = 0.;
01034     }
01035   }
01036 }