Allink  v0.1
ForcesLoop.cpp
00001 #include "Forces.h"
00003 void Forces::ChooseSimMode(){
00004   if(VAR_IF_TYPE(SysShape,SYS_2D)){
00005     //CalcUpdate = &Forces::Sim2d;
00006   }
00007 }
00009 void Forces::Solve(){
00010   if(VAR_IF_TYPE(SysShape,SYS_2D))
00011     SolveLinksIterative();
00012   //SolveLinks();
00013   else if(VAR_IF_TYPE(SysShape,SYS_LEAVES))
00014     SolveLeaves();
00015   else if(VAR_IF_TYPE(SysShape,SYS_PORE))
00016     SolveLeaves();
00017   else if(VAR_IF_TYPE(SysShape,SYS_ROD))
00018     SolveRod();
00019 }
00020 void Forces::Dynamics(){
00021   if(VAR_IF_TYPE(SysShape,SYS_MD)){
00022     VelVerlet1();
00023   }
00024   if(VAR_IF_TYPE(SysShape,SYS_2D)){
00025     Wave();
00026   }
00027   else if(VAR_IF_TYPE(SysShape,SYS_LEAVES)){
00028     ForceFieldLeaves();
00029   }
00030   else if(VAR_IF_TYPE(SysShape,SYS_1D)){
00031     ForceFieldLine();
00032   }
00033   else if(VAR_IF_TYPE(SysShape,SYS_3D)){
00034     ForceFieldBulk();
00035   }
00036   else if(VAR_IF_TYPE(SysShape,SYS_ROD)){
00037     ForceFieldRod();
00038   }
00039   else if(VAR_IF_TYPE(SysShape,SYS_RIGID)){
00040     ForceFieldRigid();
00041     VelVerletRigid();
00042   }
00043   else if(VAR_IF_TYPE(SysShape,SYS_MC)){
00044     if(VAR_IF_TYPE(CalcMode,CALC_NVT)){
00045       //for(int p=0;p<2*pNPCh();p++) 
00046       NInsertion += TryMove();
00047     }
00048     else if(VAR_IF_TYPE(CalcMode,CALC_NcVT)){
00049       NInsertion += TryMoveCh();
00050     }
00051     else if(VAR_IF_TYPE(CalcMode,CALC_mVT)){
00052       if(Mat->Casuale() < .5) 
00053    NRemoval += TryRemove();
00054       else 
00055    NInsertion += TryInsert();
00056     }
00057     else if(VAR_IF_TYPE(CalcMode,CALC_mcVT)){
00058       if(!VAR_IF_TYPE(CalcMode,CALC_CONF_BIAS)){
00059    if(Mat->Casuale() < .5) NRemoval += TryRemoveCh();
00060    else NInsertion += TryInsertCh();
00061       }
00062       else {
00063    if(Mat->Casuale() < .5) 
00064      NRemoval += TryRemoveChBias();
00065    else 
00066      NInsertion += TryInsertChBias();
00067       }
00068     }
00069   }
00070   else if(VAR_IF_TYPE(SysShape,SYS_ELECTRO)){
00071     if(VAR_IF_TYPE(CalcMode,CALC_NVT)){
00072       NInsertion += TryMove();
00073     }
00074     else if(VAR_IF_TYPE(CalcMode,CALC_mVT)){
00075       if(Mat->Casuale() < .5) 
00076    NRemoval += TryRemove();
00077       else 
00078    NInsertion += TryInsert();
00079     }
00080   }
00081   else if(VAR_IF_TYPE(SysShape,SYS_MD)){
00082     OldNrgSys = SumForcesMD();
00083     Pc->Erase();
00084     for(int p=0;p<pNPart();p++){
00085       Pc->AddPart(p,Pm[p].Pos);
00086     }
00087   }
00088   if(VAR_IF_TYPE(SysShape,SYS_MD)){
00089     ApplyTherm();
00090     VelVerlet2();
00091   }
00092   Time += pDeltat();
00093   IncrStep();
00094   SetTime(Time);
00095   Task();
00096 }
00097 void Forces::ExplorePepSize(){
00098   Shout("Explore pep size\n");
00099   if(SysShape != SYS_LEAVES) return ;
00100   char FName[120];
00101   double HeiMin = .15;
00102   double HeiMax = .4;
00103   double HeiStep = (HeiMax-HeiMin)/(double)NGrid;
00104   double AngMin = 5.;
00105   double AngMax = 35.;
00106   double AngStep = (AngMax-AngMin)/(double)NGrid;
00107   double SLapMin = 0.001;
00108   double SLapMax = 10.0;
00109   double SLapStep = 10.;
00110   for(double SLap=SLapMin;SLap<SLapMax;SLap*=SLapStep){
00111     sprintf(FName,"PepHeiElThickSLap%lf.dat",SLap);
00112     FILE *FWrite = fopen(FName,"w");
00113     for(double Hei=HeiMin;Hei<HeiMax;Hei+=HeiStep){
00114       for(double Angle=AngMin;Angle<AngMax;Angle+=AngStep){
00115    fprintf(stderr,"%lf %lf %lf\r",SLap,Hei,Angle);
00116    Nano->Height = Hei;
00117    Kf.SLap = SLap;
00118    Nano->Hamaker = Angle;
00119    Solve();
00120    int c = 0;
00121    double Min = pEdge(2);
00122    double Max = 0.;
00123    double xMin = 0.;
00124    double xMax = 0.;
00125    for(int p = c*pNPCh();p<(c+1)*pNPCh();p++){
00126      if(Pm[p].Pos[2] > Max && Pm[p].Typ == 0){
00127        Max = Pm[p].Pos[2];
00128        xMax = Pm[p].Pos[0];
00129      }
00130    }
00131    c = 1;
00132    for(int p = c*pNPCh();p<(c+1)*pNPCh();p++){
00133      if(Pm[p].Pos[2] < Min && Pm[p].Typ == 0){
00134        Min = Pm[p].Pos[2];
00135        xMin = Pm[p].Pos[0];
00136      }
00137    }
00138    fprintf(FWrite,"%lf %lf %lf %lf %lf\n",Hei/.2,Angle,(Min-Max)/.2,SLap,.5*(xMin+xMax)/.2);
00139       }
00140     }
00141     fclose(FWrite);
00142   }
00143   printf("\n");
00144 }
00145 void Forces::ExplorePepSize2d(){
00146   Shout("Explore pep size 2d\n");
00147   if(SysShape != SYS_2D) return ;
00148   SetEdge(.5*MIN(pEdge(0),pEdge(1)),3);
00149   char FName[120];
00150   double HeiMin = 0.2;
00151   double HeiMax = 4.2;
00152   double HeiStep = (HeiMax-HeiMin)/(double)NGrid;
00153   double AngMin = 0.;
00154   double AngMax = 80.;
00155   double AngStep = (AngMax-AngMin)/(double)NGrid;
00156   double InvNBin = 1./(double)NBin;
00157   SysFormat = VAR_SYS_TXVL;
00158   for(double Angle=AngMin;Angle<AngMax;Angle+=AngStep){
00159     for(double Hei=HeiMin;Hei<HeiMax;Hei+=HeiStep){
00160       fprintf(stderr,"%lf %lf\r",Hei,Angle);
00161       Nano->Height = Hei;
00162       Nano->Hamaker = Angle;
00163       Solve();
00164       sprintf(FName,"Sol2dHei%.1fAng%02d.dat",Hei,(int)Angle);
00165       Write(FName);
00166     }
00167   }
00168   printf("\n");
00169 }
00170 void Forces::ExploreDoubleMin(){
00171   Shout("Explore pep size\n");
00172   char String[120];
00173   if(SysShape != SYS_2D) return;
00174   if(pNNano() < 2) return;
00175   double DistMin = pNanoPos(1,0);
00176   double DistDelta = (pEdge(0)-pNanoPos(1,0))/(double)NGrid;
00177   double DeltaGrid = pEdge(0)/(double)nEdge[0];
00178   // DistDelta = floor(2.*DistDelta/DeltaGrid)*DeltaGrid;
00179   // SigErr(DistDelta <= 0.,"The grid step is too short for %d distances ",NGrid);
00180   char FName[60];
00181   FILE *FProf = fopen("DistThinMin.dat","w");
00182   for(int i=0;i<NGrid;i++){
00183     fprintf(stderr,"done %.2f %%\r",100.*i/(double)NGrid);
00184     IfFillMatrix = 1;
00185     Solve();
00186     sprintf(FName,"MinProf%03d.dat",i);
00187     FILE *FWrite = fopen(FName,"w");
00188     StringNano(String,0);
00189     fprintf(FWrite,String);
00190     StringNano(String,1);
00191     fprintf(FWrite,String);
00192     double Min = 100000.;
00193     double Dist = 0.;
00194     double zOld = 100000.;
00195     int IfContinue = 0;
00196     int nBin = 0;
00197     for(int p=nEdge[1]/2+1;p<pNPart();p+=nEdge[1]){
00198       double x = pPos(p,0) - pNanoPos(0,0);
00199       double z = pPos(p,2);
00200       if(pType(p) == 1) z = pNanoPos(0,2) + .5*Nano[0].Height;
00201       if( x > (pNanoPos(1,0) - pNanoPos(0,0) )) continue;
00202       fprintf(FWrite,"%lf %lf\n",x,z);
00203       if( x > .6*(pNanoPos(1,0) - pNanoPos(0,0) )) continue;
00204       if(Min > z){// && IfContinue){
00205    Min = z;
00206    Dist = x;
00207    nBin = p;
00208       }
00209       // if(z > zOld){IfContinue = 1;}
00210       // zOld = z;
00211     }
00212     fprintf(FProf,"%lf %lf %lf\n",Nano[1].Pos[0]-Nano[0].Pos[0],Dist,Min);
00213     fflush(FProf);
00214     fclose(FWrite);
00215     sprintf(FName,"Sol2dDist%.3f.dat",Nano[1].Pos[0]-Nano[0].Pos[0]);
00216     WriteTxvl(FName);
00217     Nano[1].Pos[0] += DistDelta;
00218     if(Nano[1].Pos[0] > pEdge(0)) return;
00219   }
00220   printf("\n");
00221   fclose(FProf);
00222 }
00223 void Forces::RunWidom(char *File2Open,int f){
00224   Shout("Widom on particles\n");
00225   int NInt = 10000;
00226   double NrgDiff = 0.;
00227   char File2Write[60];
00228   sprintf(File2Write,"WidomOut%05d.dat",f);
00229   ReOpen(File2Open,BF_PART);
00230   FILE *WidomOut = fopen(File2Write,"w");
00231   SigErr(WidomOut==NULL,"Cannot allocate %s\n",File2Write);
00232   for(int p=0;p<pNPart();p++){
00233     WidomRemove(&NrgDiff,p);
00234     fprintf(WidomOut,"%lf\n",NrgDiff);
00235   }
00236   fclose(WidomOut);
00237   sprintf(File2Write,"WidomIn%05d.dat",f);
00238   FILE *WidomIn = fopen(File2Write,"w");
00239   for(int p=0;p<NInt;p++){
00240     WidomInsert(&NrgDiff);
00241     fprintf(WidomIn,"%lf\n",NrgDiff);
00242   }
00243   fclose(WidomIn);
00244 }
00245 void Forces::RosenIn(FILE *WidomIn){
00246   Shout("Widom insertion biased/Rosenbluth\n");
00247   int NInt = 10000;
00248   double Weight = 0.;
00249   for(int p=0;p<NInt;p++){
00250     WidomBiasChIn(&Weight);
00251     fprintf(WidomIn,"%g\n",Weight);
00252   }
00253 }
00254 void Forces::RosenOut(FILE *WidomIn){
00255   Shout("Widom deletion biased/Rosenbluth\n");
00256   int NInt = 10000;
00257   double Weight = 0.;
00258   for(int c=0;c<pNChain();c++){
00259     WidomBiasChOut(&Weight,c);
00260     fprintf(WidomIn,"%g\n",Weight);
00261   }
00262 }
00263 void Forces::RunWidomChIn(char *File2Open,int f){
00264   Shout("Widom chain in\n");
00265   int NInt = 5*pNChain();
00266   double NrgDiff[3];
00267   char File2Write[60];
00268   ReOpen(File2Open,BF_PART);
00269   sprintf(File2Write,"WidomIn%05d.dat",f);
00270   FILE *WidomIn = fopen(File2Write,"w");
00271   //StudySys();
00272   for(int p=0;p<NInt;p++){
00273     IncrStep();
00274     WidomInsertCh(NrgDiff);
00275     fprintf(WidomIn ,"%lf\n",NrgDiff[2]);
00276   }
00277   fclose(WidomIn);
00278 }
00279 void Forces::RunWidomChOut(char *File2Open,int f){
00280   Shout("Widom chain out\n");
00281   double NrgDiff[3];
00282   char File2Write[60];
00283   sprintf(File2Write,"WidomOut%05d.dat",f);
00284   ReOpen(File2Open,BF_PART);
00285   FILE *WidomOut = fopen(File2Write,"w");
00286   CalcTotNrgCh();
00287   for(int c=0;c<pNChain();c++){
00288     WidomRemoveCh(NrgDiff,c);
00289     fprintf(WidomOut,"%lf\n",NrgDiff[2]);
00290   }
00291   fclose(WidomOut);
00292 }
00293 void Forces::CalcTotNrg(char *File2Open,int f){
00294   Shout("Calculating total energy\n");
00295   ReOpen(File2Open,BF_PART);
00296   double NrgNb = 0.;
00297   double NrgSpr = 0.;
00298   double NrgSpr2 = 0.;
00299   double NrgBend = 0.;
00300   for(int c=0;c<pNChain();c++){
00301     for(int p=c*pNPCh();p<(c+1)*pNPCh()-1;p++){
00302       double DistBA[3];
00303       double DistCB[3];
00304       double DistBA2 = 0.;
00305       double DistCB2 = 0.;
00306       double CosAngle = 0.;
00307       for(int d=0;d<3;d++){
00308    DistBA[d] = Pm[p].Pos[d] - Pm[p-1].Pos[d];
00309    DistBA[d] -= floor(DistBA[d]/(pEdge(d)) + .5)*pEdge(d);
00310    DistCB[d] = Pm[p+1].Pos[d] - Pm[p].Pos[d];
00311    DistCB[d] -= floor(DistCB[d]/(pEdge(d)) + .5)*pEdge(d);
00312    DistBA2 += SQR(DistBA[d]);
00313    DistCB2 += SQR(DistCB[d]);
00314    CosAngle += DistBA[d]*DistCB[d];
00315       }
00316       DistCB2 = sqrt(DistCB2);
00317       NrgSpr += .5*pkSpr()*SQR(DistCB2 - pSprRest());
00318       if(p == c*pNPCh()) continue;
00319       DistBA2 = sqrt(DistBA2);
00320       CosAngle /= (DistBA2*DistCB2);
00321       NrgBend += pkBen()*(1.-CosAngle);
00322    }
00323   }
00324   double NrgNano = 0.;
00325   for(int p=0;p<pNPart();p++){
00326     NrgNano += NanoNrg(p);
00327   }
00328   CalcTotNrgCh();
00329   printf("Nb %lf + Nano %lf = %lf Spr %lf + Ben %lf = %lf\n",OldNrgSys,NrgNano,OldNrgSys+NrgNano,NrgSpr,NrgBend,NrgSpr+NrgBend);
00330   fprintf(StatFile1,"%d %lf %lf %lf %lf\n",f,OldNrgSys,NrgSpr,NrgBend,NrgNano);
00331   fflush(StatFile1);
00332 }
00333 void Forces::CalcNrgPep(char *File2Open,int f){
00334   Shout("Calculating total energy\n");
00335   ReOpen(File2Open,BF_PART);
00336   AddDens(0,pNPart());
00337   OldNrgSys = SumDens(0,pNPart());  
00338   ClearDens();
00339   for(int b=0,NPep=0,cOff=0,pOff=0;b<pNBlock();cOff+=pNChain(b++)){
00340     if(!strncmp(Block[b].Name,"PEP",3)){
00341       continue;
00342     }
00343     for(int c=cOff;c<cOff+pNChain(b);c++,pOff+=pNPCh(b)){
00344       for(int p=pOff,link=0;p<MIN(pOff+pNPCh(b),pNPart());p++){
00345    AddDens(p,p+1);
00346       }
00347     }
00348   }
00349   double NrgPep = OldNrgSys - SumDens(0,pNPart());  
00350   printf("Nrg pep %lf\n",NrgPep);
00351   fprintf(StatFile1,"%d %lf %lf\n",f,NrgPep,OldNrgSys);
00352   fflush(StatFile1);
00353 }
00354 void Forces::CalcTens(char **argv,int *FilePos,int NFile){
00355   Shout("Calculating tension\n");
00356   AllocTens();
00357   char FName[60];
00358   for(int f=0;f<NFile;f++){
00359     fprintf(stderr,"Elaborating file %s %.3f %%\r",argv[FilePos[f]],f/(double)NFile*100.);
00360     ReOpen(argv[FilePos[f]],BF_PART);
00361     CalcTens();
00362     CalcDens();
00363     if( !(f%(NWrite)) ){
00364       for(int c=0;c<Tens.NComp;c++){
00365    if(VAR_IF_TYPE(Tens.CalcMode,CALC_2d))
00366      sprintf(FName,"Tension2d%05dL%d.dat",f,c);
00367    if(VAR_IF_TYPE(Tens.CalcMode,CALC_3d))
00368      sprintf(FName,"Tension3d%05dL%d.dat",f,c);
00369    WriteTens(FName,c,1./(double)NFile);
00370       }
00371     }
00372   }
00373   printf("\n");
00374 }
00375 void Forces::AvForces(char **argv,int *FilePos,int NFile){
00376   Shout("Calculating force field/average force\n");
00377   AllocTens();
00378   char FName[60];
00379   const int NBin = 120;
00380   double *Profile = (double *)calloc(3*NBin,sizeof(double));
00381   for(int f=0;f<NFile;f++){
00382     fprintf(stderr,"Elaborating file %s %.3f %%\r",argv[FilePos[f]],f/(double)NFile*100.);
00383     ReOpen(argv[FilePos[f]],BF_PART);
00384     CalcForcesDensFunc();
00385     FILE *FForce = fopen("ForceProfile.dat","w");
00386     double Force[3] = {0.,0.,0.};
00387     int cBin[3];
00388     for(int p=0;p<pNPart();p++){
00389       for(int d=0;d<3;d++){
00390    cBin[d] = (int)(Pm[p].Pos[d]*pInvEdge(d)*NBin);
00391    if(cBin[d] < 0 || cBin[d] >= NBin) continue;
00392    Profile[cBin[d]*3+d] += Fm[p].Dir[d];
00393    Force[d] += Fm[p].Dir[d];
00394    fprintf(FForce,"%d %g %g %g\n",p,Force[0],Force[1],Force[2]);
00395       }
00396     }
00397     printf("%g %g %g\n",Force[0],Force[1],Force[2]);
00398     fclose(FForce);
00399   }
00400   FILE *FProf = fopen("ForceProfile.dat","w");
00401   for(int b=0;b<NBin;b++){
00402     fprintf(FProf,"%d %lf %lf %lf\n",b,Profile[b*3],Profile[b*3+1],Profile[b*3+2]);
00403   }
00404   FILE *FField = fopen("ForceField.dat","w");
00405   double Delta = sqrt(Kf.CutOff2)/(double)NTab;
00406   for(int b=0;b<NTab;b++){
00407     double x = b*Delta;
00408     fprintf(FField,"%lf ",x);
00409     for(int t1=0;t1<pNType();t1++){
00410       for(int t2=0;t2<pNType();t2++){
00411    fprintf(FField,"%lf ",FTab[(b*pNType()+t1)*pNType()+t2]);
00412       }
00413     }
00414     fprintf(FField,"\n");
00415   }
00416   free(Profile);
00417   fclose(FProf);
00418   fclose(FField);
00419   printf("\n");
00420 }
00421 void Forces::Task(){
00422   if(VAR_IF_TYPE(SysAlloc,ALL_MC)){
00423     return;
00424     if((pStep()%NUpdate)!=0) return;
00425     OldNrgSys = 0.;
00426     double Pot[3];
00427     for(int c=0;c<pNChain();c++) OldNrgSys += CalcNrgCh(c,Pot);
00428     //fprintf(TempFile,"%d %d %lf \n",pStep(),pNChain(),NrgSys/(double)pNChain());
00429     //fprintf(StatFile1,"%d %d %lf \n",pStep(),pNChain(),OldNrgSys/(double)pNChain());
00430     //fflush(StatFile1);
00431     // int c = 0;//p%pNPCh();
00432     // double Pot[3];
00433     // CalcNrgCh(c,Pot);
00434     // for(int e=0;e<3;e++) OldNrgCh[c*3+e] = Pot[e];
00435     // double Dist[4];
00436     // TwoPartDist(0,pNPCh()-1,Dist);
00437     // fprintf(TempFile,"%d %lf %lf %lf %lf\n",pStep(),OldNrgCh[3*0],OldNrgCh[3*0+1],OldNrgCh[3*0+2],Dist[3]);
00438   }
00439   else if(VAR_IF_TYPE(SysAlloc,ALL_MD)){
00440     if( !(pStep()%NUpdate) ){
00441       double v2 = 0.;
00442       for(int p=0;p<pNPart();p++){
00443    for(int d=0;d<3;d++){
00444      v2 += SQR(Pm[p].Vel[d]);
00445    }
00446       }
00447       //fprintf(StatFile1,"%d %lf %lf\n",pStep(),v2/(double)(3*pNPart()),OldNrgSys);
00448       //fflush(StatFile1);
00449     }
00450   }
00451 }
00452 void Forces::Trial(){
00453   CheckPairList();
00454 }
00455 void Forces::RunDynamics(){
00456   Shout("run dynamics\n");
00457   double NLoopSec = 0.;
00458   char FileName[60];
00459   DefForceParam();
00460   //MinimalNrg();
00461   for(int s=0;s<SimLimit;s++){
00462     Dynamics();
00463     //MinimalMD();
00464     if( !(s%NUpdate) ){
00465       CurrTime = time(NULL);
00466       NLoopSec += (s)/(double)(CurrTime-InitTime);
00467       double Temp = 0.;
00468       for(int p=0;p<pNPart();p++){
00469    for(int d=0;d<3;d++){
00470      Temp += SQR(Pm[p].Vel[d]);
00471    }
00472       }
00473       Temp = Temp/(double)(3*pNPart());
00474       fprintf(stderr,"NPart %d loop/ms %.3g acc/step %.3f in/out %.4f T %.4f accomplished %.3f %% Nrg %lf\n",pNPart(),NLoopSec,(NRemoval+NInsertion)/(double)s,NInsertion/(double)NRemoval,Temp,s/(double)(SimLimit)*100.,OldNrgSys);
00475       fprintf(StatFile1,"%d %lf %lf\n",s,OldNrgSys,Temp);
00476     }
00477     if( !(s%(NWrite)) ){
00478       sprintf(FileName,"Trajectory%09d.dat",pStep());
00479       Write(FileName);
00480     }
00481   }
00482   printf("\n");
00483   CurrTime = time(NULL);
00484   NLoopSec += (SimLimit)/(double)(CurrTime-InitTime);
00485   double v2 = 0.;
00486   for(int p=0;p<pNPart();p++){
00487     for(int d=0;d<3;d++){
00488       v2 += SQR(Pm[p].Vel[d]);
00489     }
00490   }
00491   fprintf(StatFile1,"##NPart %d loop/ms %.3g acc/step %.3f in/out %.4f T %.4f accomplished Nrg %lf\r",pNPart(),NLoopSec,(NRemoval+NInsertion)/(double)pStep(),NInsertion/(double)NRemoval,v2/(double)(3*pNPart()),OldNrgSys);
00492 }
00493 double Forces::MinimalNrg(){
00494   double Pos[3];
00495   double Pot[3];
00496   double DistRel[4];
00497   OldNrgSys = 0.;
00498   Pc->Erase();
00499   for(int p=0;p<pNPart();p++){pPos(p,Pos);Pc->AddPart(p,Pos);}
00500   for(int p1=0;p1<pNPart();p1++){
00501     if(VAR_IF_TYPE(SysAlloc,ALL_FORCES)){
00502       for(int d=0;d<3;d++) Fm[p1].Dir[d] = 0.;
00503     }
00504     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00505       int p2 = Pc->p2Curr;
00506       if(p2 <= p1) continue;
00507       Pc->Dist2Curr(DistRel);
00508       if(DistRel[3] > Kf.CutOff2) continue;
00509       double Cons = Potential(DistRel[3],pType(p1),pType(p2),Pot);
00510       double InvDist = DistRel[3];
00511       if(VAR_IF_TYPE(SysAlloc,ALL_FORCES)){
00512    for(int d=0;d<3;d++){
00513      Fm[p1].Dir[d] += Cons*DistRel[d]*InvDist;
00514      Fm[p2].Dir[d] -= Cons*DistRel[d]*InvDist;
00515    }
00516       }
00517       OldNrgSys += Pot[0];
00518     }
00519   }
00520 }
00521 void Forces::MinimalMD(){
00522   double Sigma = sqrt(pTemp());
00523   double Pos[3];
00524   for(int p=0;p<pNPart();p++){
00525     for(int d=0;d<3;d++){
00526       Pm[p].Vel[d] += .5*Fm[p].Dir[d]*pDeltat();
00527       Pm[p].Pos[d] += Pm[p].Vel[d]*pDeltat();
00528       Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00529     }
00530   }
00531   MinimalNrg();
00532   //vv2
00533   double Temp = 0.;
00534   for(int p=0;p<pNPart();p++){
00535     for(int d=0;d<3;d++){
00536       Pm[p].Vel[d] += .5*Fm[p].Dir[d]*pDeltat();
00537       Temp += SQR(Pm[p].Vel[d]);
00538     }
00539   }
00540   //Andersen
00541   for(int p=0;p<pNPart();p++){
00542     if(Mat->Casuale() < pDeltat()){
00543       for(int d=0;d<3;d++){
00544    Pm[p].Vel[d] = Mat->Gaussiano(0.,Sigma);//Mat->Gaussiano(0.,Sigma);
00545       }
00546     }
00547   }
00548   Temp = Temp/(3*pNPart());
00549   double Norm = 1./sqrt(Temp);
00550   // for(int p=0;p<pNPart();p++){
00551   //   for(int d=0;d<3;d++){
00552   //     Pm[p].Vel[d] *= Norm;
00553   //   }
00554   // }
00555 }
00556 void Forces::MinimizeSol(){
00557   double *Sol2d = (double *)calloc(SQR(NEdge),sizeof(double));
00558   double *Count = (double *)calloc(SQR(NEdge),sizeof(double));
00559   double NInvEdge = 1./(double)NEdge;
00560   for(int p=0;p<pNPart();p++){
00561     if(pType(p) != 0) continue;
00562     int vx = (Pm[p].Pos[0]*NEdge*pInvEdge(0));
00563     if(vx < 0 || vx >= NEdge) continue;
00564     int vy = (Pm[p].Pos[1]*NEdge*pInvEdge(1));
00565     if(vy < 0 || vy >= NEdge) continue;
00566     Sol2d[vx*NEdge+vx] = Pm[p].Pos[2];
00567     Count[vx*NEdge+vx] = 1.;
00568   }
00569   for(int vx=0;vx<SQR(NEdge);vx++){
00570     double Norm = Count[vx] > 0. ?  1./Count[vx] : 1.;
00571     Sol2d[vx] *= Norm;
00572   }
00573   Create2d();
00574   int NInt = 1000;
00575   for(int n=0;n<NInt;n++){
00576     
00577   }
00578 }