Allink  v0.1
ForcesCalcEnergies.cpp
00001 #include "Forces.h"
00002 //-----------------------ENERGY-BONDED-----------------------
00003 double Forces::CalcSpring(int p1){
00004   double Nrg = 0.;
00005   double Dist[4];
00006   int NLink = 0;
00007   int Link[2] = {-1,-1};
00008   if(p1 > 0){
00009     if( Pm[p1].CId == Pm[p1-1].CId ){
00010       Link[NLink++] = p1 - 1;
00011     }
00012   }
00013   if(p1 <= pNPart()){
00014     if( Pm[p1].CId == Pm[p1+1].CId ){
00015       Link[NLink++] = p1 + 1;
00016     }
00017   }
00018   for(int l=0;l<NLink;l++){
00019     TwoPartDist(p1,Link[l],Dist);
00020     Nrg += .5*pkSpr()*SQR(Dist[3] - pSprRest());
00021   }
00022   return Nrg;
00023 }
00029 double Forces::CalcBonded(int p,double *Pot){
00030   double NrgSpr = 0.;
00031   double NrgBen = 0.;
00032   int pA = p-1;
00033   int pB = p;
00034   int pC = p+1;
00035   int IfBefore = 1;
00036   int IfAfter = 1;
00037   if(p > 0){
00038     if(Pm[p].CId -1 == Pm[p-1].CId){
00039       pA = p;
00040       pB = p+1;
00041       pC = p+2;
00042       IfBefore = 0;
00043     }
00044   }
00045   if(p <= pNPart() ){
00046     if(Pm[p].CId + 1 == Pm[p+1].CId || p == pNPart()-1){
00047       pC = p;
00048       pB = p-1;
00049       pA = p-2;
00050       IfAfter = 0;
00051     }
00052   }
00053   double DistBA[4];
00054   double DistCB[4];
00055   double CosAngle = 0.;
00056   for(int d=0;d<3;d++){
00057     DistBA[d] = Pm[pB].Pos[d] - Pm[pA].Pos[d];
00058     DistCB[d] = Pm[pC].Pos[d] - Pm[pB].Pos[d];
00059   }
00060   DistBA[3] = (SQR(DistBA[0])+SQR(DistBA[1])+SQR(DistBA[2]));
00061   DistCB[3] = (SQR(DistCB[0])+SQR(DistCB[1])+SQR(DistCB[2]));
00062   for(int d=0;d<3;d++)
00063     CosAngle += DistBA[d]*DistCB[d];
00064   CosAngle /= (DistBA[3]*DistCB[3]);
00065   if(IfAfter)
00066     NrgSpr += .5*pkSpr()*SQR(DistBA[3] - pSprRest());
00067   if(IfBefore)
00068     NrgSpr += .5*pkSpr()*SQR(DistCB[3] - pSprRest());
00069   NrgBen += pkBen()*(1.-CosAngle);
00070   Pot[0] = NrgSpr;
00071   Pot[1] = NrgBen;
00072   return NrgSpr + NrgBen;
00073 }
00080 double Forces::CalcBendingGhost(double *Pos,int p){
00081   if(pkBen() <= 0.) return 0.;
00082   double NrgBen = 0.;
00083   int pA = p;
00084   int pB = p-1;
00085   int pC = p-2;
00086   if(pC < pChain(p)*pNPCh()){
00087     return 0.;
00088   }
00089   double DistBA[3];
00090   double DistCB[3];
00091   double DistBA2  = 0.;
00092   double DistCB2  = 0.;
00093   double CosAngle = 0.;
00094   for(int d=0;d<3;d++){
00095     DistBA[d] = pPos(pB,d) - pPos(pA,d);
00096     DistBA[d] -= floor(DistBA[d]*pInvEdge(d) + .5)*pEdge(d);
00097     DistCB[d] = pPos(pC,d) - pPos(pB,d);
00098     DistCB[d] -= floor(DistCB[d]*pInvEdge(d) + .5)*pEdge(d);
00099     DistBA2 += SQR(DistBA[d]);
00100     DistCB2 += SQR(DistCB[d]);
00101     CosAngle += DistBA[d]*DistCB[d];
00102   }
00103   DistCB2 = sqrt(DistCB2);
00104   DistBA2 = sqrt(DistBA2);
00105   CosAngle /= (DistBA2*DistCB2);
00106   NrgBen += pkBen()*(1.-CosAngle);
00107   return NrgBen;
00108 }
00109 double Forces::CalcBondedCh(int c,double *Pot){
00110   double DistBA[3];
00111   double DistCB[3];
00112   double NrgBend = 0.;
00113   double NrgSpr = 0.;
00114   for(int p=c*pNPCh();p<(c+1)*pNPCh()-1;p++){
00115     double DistBA2 = 0.;
00116     double DistCB2 = 0.;
00117     double CosAngle = 0.;
00118     for(int d=0;d<3;d++){
00119       DistCB[d] = pPos(p+1,d) + pPos(p,d);
00120       DistCB[d] -= floor(DistCB[d]*pInvEdge(d) + .5)*pEdge(d);
00121       DistCB2 += SQR(DistCB[d]);
00122     }
00123     DistCB2 = sqrt(DistCB2);
00124     NrgSpr += .5*pkSpr()*SQR(DistCB2 - pSprRest());
00125     if(p == c*pNPCh()) continue;
00126     for(int d=0;d<3;d++){
00127       DistBA[d] = pPos(p,d) - pPos(p-1,d);
00128       DistBA[d] -= floor(DistBA[d]*pInvEdge(d) + .5)*pEdge(d);
00129       DistBA2 += SQR(DistBA[d]);
00130       CosAngle += DistBA[d]*DistCB[d];
00131     }
00132     DistBA2 = sqrt(DistBA2);
00133     CosAngle /= (DistBA2*DistCB2);
00134     NrgBend += pkBen()*(1.-CosAngle);
00135   }
00136   Pot[0] = NrgSpr;
00137   Pot[1] = NrgBend;
00138   return NrgBend + NrgSpr;
00139 }
00140 double Forces::CalcBending(int p1){
00141   if(Ln[p1].NLink < 1) return 0.;
00142   if( !(p1%pNPCh()) ) return 0.;
00143   int l1 = p1+1;
00144   int l2 = p1-1;
00145   Vettore v1(pPos(l1,0) - pPos(p1,0),pPos(l1,1) - pPos(p1,1),pPos(l1,2) - pPos(p1,2));
00146   Vettore v2(pPos(p1,0) - pPos(l2,0),pPos(p1,1) - pPos(l2,1),pPos(p1,2) - pPos(l2,2));
00147   return pkBen()*(1. - v1.CosAngle(&v2));
00148 }
00149 //%%%%%%%%%%%%%%%%%%%%%%%%%MC%NON%BONDED%%%%%%%%%%%%%%%%%%%%%
00153 double Forces::NrgStep(int p1){
00154   double DistRel[4];
00155   double Nrg = 0.;
00156   for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00157     int p2 = Pc->p2Curr;
00158     Pc->Dist2Curr(DistRel);
00159     int t2 = pType(p2);
00160     if(DistRel[3] > Kf.CutOff2) continue;
00161     if(Pm[p1].Typ == Pm[p2].Typ)
00162       Nrg += Kf.LJ;
00163     else
00164       Nrg += -Kf.LJ;
00165   }
00166   return Nrg;
00167 }
00168 double Forces::NrgStepCh(int c,double *Pot){
00169   Pot[0] = 0.;Pot[1] = 0.;Pot[2] = 0.;
00170   int p1 = c*pNPCh();
00171   double DistRel[4];
00172   double Pos[3];
00173   //loop in the chain
00174   for(int p=p1;p<p1+pNPCh();p++){
00175     int t1 = pType(p);
00176     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00177       int p2 = Pc->p2Curr;
00178       int t2 = pType(p2);
00179       // avoid self interactions in the chains
00180       if(p2 > p1 && p2 < p1 + pNPCh() && p2 < p) continue;
00181       Pc->Dist2Curr(DistRel);
00182       if(DistRel[3] > Kf.CutOff2) continue;
00183       // if(DistRel[3] < .1) Pot[2] += 55.;
00184    // else Pot[2] += -.1;
00185       Pot[2] += 1.;
00186     }
00187   }
00188   return Pot[2];
00189 }
00190 //--------------------------Dens----------------------
00191 int Forces::RemDens(int pInit,int pEnd){
00192   double DistRel[4] = {0.,0.,0.,0.};
00193   int NCutOff = 0;
00194   double Count = 0.;
00195   double Pos[3];
00196   for(int p1=pInit;p1<pEnd;p1++){
00197     int t1 = pType(p1);
00198     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00199       int p2 = Pc->p2Curr;
00200       int t2 = pType(p2);
00201       // avoid self interactions in the chains
00202       if(p2>=pInit && p2<pEnd && p2<=p1) continue;
00203       Pc->Dist2Curr(DistRel);
00204       if(DistRel[3] > Kf.CutOff2) continue;
00205       double Dist = sqrt(DistRel[3]);
00206       double w2 = Wei2(Dist,pWei2Par());
00207       double w3 = Wei3(Dist,pWei3Par());
00208       Dens2[p2*pNType()+t1] -= w2;
00209       Dens2[p1*pNType()+t2] -= w2;
00210       Dens3[p2*pNType()+t1] -= w3;
00211       Dens3[p1*pNType()+t2] -= w3;
00212       NCutOff++;
00213     }
00214   }
00215   return NCutOff;
00216 }
00217 //Bottleneck!!!
00218 int Forces::AddDens(int pInit,int pEnd){
00219   double DistRel[4] = {0.,0.,0.,0.};
00220   int NCutOff = 0;
00221   double Pos[3];
00222   for(int p1=pInit;p1<pEnd;p1++){
00223     int t1 = pType(p1);
00224     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00225       int p2 = Pc->p2Curr;
00226       int t2 = pType(p2);
00227       // avoid self interactions in the chains
00228       if(p2>=pInit && p2<pEnd && p2<=p1)continue;
00229       Pc->Dist2Curr(DistRel);
00230       if(DistRel[3] > Kf.CutOff2) continue;
00231       double Dist = sqrt(DistRel[3]);
00232       double w2 = Wei2(Dist,pWei2Par());
00233       double w3 = Wei3(Dist,pWei3Par());
00234       Dens2[p2*pNType()+t1] += w2;
00235       Dens2[p1*pNType()+t2] += w2;
00236       Dens3[p2*pNType()+t1] += w3;
00237       Dens3[p1*pNType()+t2] += w3;
00238       NCutOff++;
00239     }
00240   }
00241   return NCutOff;
00242 }
00243 double Forces::SumDens(int pInit,int pEnd){
00244   double Nrg = 0.;
00245   double OneThird = 1./3.;
00246   for(int p=pInit;p<pEnd;p++){
00247     int t1 = pType(p);
00248     for(int t2=0;t2<pNType();t2++){
00249       Nrg += .5*Dens2[p*pNType()+t2]*MInt->Coeff(t1,t2);
00250       for(int t3=0;t3<pNType();t3++){
00251    Nrg += Dens3[p*pNType()+t2]*Dens3[p*pNType()+t3]*OneThird*MInt->Coeff(t1,t2,t3);
00252       }
00253     }
00254   }
00255   return Nrg;
00256 }
00257 double Forces::DensFuncNrgGhost(double *Pos,int p1,int t1){
00258   double DistRel[4] = {0.,0.,0.,0.};
00259   double Nrg = 0.;
00260   int NCutOff = 0;
00261   double OneThird = 1./3.;
00262   memset(LocDens2,0,pNType()*sizeof(double));
00263   memset(LocDens3,0,pNType()*sizeof(double));
00264   for(Pc->SetCurrGhost(Pos);Pc->IfCurrGhost();Pc->NextCurrGhost()){
00265     int p2 = Pc->p2Curr;
00266     int t2 = pType(p2);
00267     if(p1 == p2) continue;
00268     Pc->Dist2CurrGhost(DistRel);
00269     if(DistRel[3] > Kf.CutOff2) continue;
00270     double Dist = sqrt(DistRel[3]);
00271     double w2 = Wei2(Dist,pWei2Par());
00272     double w3 = Wei3(Dist,pWei3Par());
00273     LocDens2[t2] += w2*2.;
00274     LocDens3[t2] += w3;
00275     double W3Add[3] = {0.,0.,0.};
00276     W3Add[t1] = w3;
00277     for(int t3=0;t3<pNType();t3++){
00278       for(int t4=0;t4<pNType();t4++){
00279    double Fact = Dens3[p2*pNType()+t3]*W3Add[t4];
00280    Fact += W3Add[t3]*Dens3[p2*pNType()+t4];
00281    Fact += W3Add[t3]*W3Add[t4];
00282    //Why t2?
00283    Nrg += Fact*OneThird*MInt->Coeff(t2,t3,t4);
00284       }
00285     }
00286     NCutOff++;
00287   }
00288   for(int t2=0;t2<pNType();t2++){
00289     Nrg += .5*LocDens2[t2]*MInt->Coeff(t1,t2);
00290     for(int t3=0;t3<pNType();t3++){
00291       Nrg += LocDens3[t2]*LocDens3[t3]*OneThird*MInt->Coeff(t1,t2,t3);
00292     }
00293   }
00294   return Nrg;
00295 }
00296 double Forces::DensFuncNrgChInternal(int c){
00297   double DistRel[4] = {0.,0.,0.,0.};
00298   double Nrg = 0.;
00299   int NCutOff = 0;
00300   double OneThird = 1./3.;
00301   memset(LocDens2,0,pNPCh()*pNType()*sizeof(double));
00302   memset(LocDens3,0,pNPCh()*pNType()*sizeof(double));
00303   // for(int pt=0;pt<pNPCh()*pNType();pt++){
00304   //   LocDens2[pt] = 0.;
00305   //   LocDens3[pt] = 0.;
00306   // }
00307   int pInit = Ch[c].InitBead;
00308   int pEnd = Ch[c].EndBead;
00309   double Pos[3];
00310   for(int p1=pInit,pc=0;p1<pEnd;p1++,pc++){ 
00311     int t1 = pType(p1);
00312     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00313       int p2 = Pc->p2Curr;
00314       int t2 = pType(p2);
00315       if(p1 == p2) continue;
00316       Pc->Dist2Curr(DistRel);
00317       if(DistRel[3] > Kf.CutOff2) continue;
00318       double Dist = sqrt(DistRel[3]);
00319       double w2 = Wei2(Dist,pWei2Par());
00320       double w3 = Wei3(Dist,pWei3Par());
00321       LocDens2[pc*pNType()+t2] += w2;
00322       LocDens3[pc*pNType()+t2] += w3;
00323       //energy change for the neighbouring chains
00324       if(p2 < p1 || p2 >= pEnd){
00325    LocDens2[pc*pNType()+t2] += w2;
00326    double W3Add[3] = {0.,0.,0.};
00327    W3Add[t1] = w3;
00328    //2FIX: multiple change in the 3 order density
00329    for(int t3=0;t3<pNType();t3++){
00330      for(int t4=0;t4<pNType();t4++){
00331        double Fact = Dens3[p2*pNType()+t3]*W3Add[t4];
00332        Fact += W3Add[t3]*Dens3[p2*pNType()+t4];
00333        Fact += W3Add[t3]*W3Add[t4];
00334        //Why t2?
00335        Nrg += Fact*OneThird*MInt->Coeff(t2,t3,t4);
00336      }
00337      }
00338    NCutOff++;
00339       }
00340     }
00341   }
00342   for(int pt=0;pt<pNPCh();pt++){
00343     int t1 = pType(pInit+pt);
00344     for(int t2=0;t2<pNType();t2++){
00345       Nrg += .5*LocDens2[pt*pNType()+t2]*MInt->Coeff(t1,t2);
00346       for(int t3=0;t3<pNType();t3++){
00347    Nrg += LocDens3[pt*pNType()+t2]*LocDens3[pt*pNType()+t3]*OneThird*MInt->Coeff(t1,t2,t3);
00348       }
00349     }
00350   }
00351   return Nrg;
00352 }
00353 double Forces::DensFuncNrgGhostInternal(double *Pos,int p1,int t1){
00354   double DistRel[4] = {0.,0.,0.,0.};
00355   double Nrg = 0.;
00356   int NCutOff = 0;
00357   double OneThird = 1./3.;
00358   memset(LocDens2,0,pNType()*sizeof(double));
00359   memset(LocDens3,0,pNType()*sizeof(double));
00360   int c = (int)(p1/pNPCh());
00361   int pInit = Ch[c].InitBead;
00362   int pEnd = Ch[c].EndBead;
00363   for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00364     int p2 = Pc->p2Curr;
00365     int t2 = pType(p2);
00366     if(p1 == p2) continue;
00367     if(p2 < pInit) continue;
00368     if(p2 >= pEnd) continue;
00369     Pc->Dist2Curr(DistRel);
00370     if(DistRel[3] > Kf.CutOff2) continue;
00371     double Dist = sqrt(DistRel[3]);
00372     double w2 = Wei2(Dist,pWei2Par());
00373     double w3 = Wei3(Dist,pWei3Par());
00374     LocDens2[t2] += w2*2.;
00375     LocDens3[t2] += w3;
00376     double W3Add[3] = {0.,0.,0.};
00377     W3Add[t1] = w3;
00378     for(int t3=0;t3<pNType();t3++){
00379       for(int t4=0;t4<pNType();t4++){
00380    double Fact = Dens3[p2*pNType()+t3]*W3Add[t4];
00381    Fact += W3Add[t3]*Dens3[p2*pNType()+t4];
00382    Fact += W3Add[t3]*W3Add[t4];
00383    //Why t2?
00384    Nrg += Fact*OneThird*MInt->Coeff(t2,t3,t4);
00385       }
00386     }
00387     NCutOff++;
00388   }
00389   for(int t2=0;t2<pNType();t2++){
00390     Nrg += .5*LocDens2[t2]*MInt->Coeff(t1,t2);
00391     for(int t3=0;t3<pNType();t3++){
00392       Nrg += LocDens3[t2]*LocDens3[t3]*OneThird*MInt->Coeff(t1,t2,t3);
00393     }
00394   }
00395   return Nrg;
00396 }
00397 double Forces::DensFuncNrgSys(){
00398   CalcDens(0,pNPart());
00399   return SumDens(0,pNPart());
00400 }
00401 void Forces::ClearDens(){
00402   memset(Dens2,0,pNPart()*pNType()*sizeof(double));
00403   memset(Dens3,0,pNPart()*pNType()*sizeof(double));
00404 }
00405 void Forces::CalcDens(int pInit,int pEnd){
00406   ClearDens();
00407   AddDens(pInit,pEnd);
00408 }
00409 //------------------Calc-Ch-Nrg----------------------------
00411 double Forces::CalcTotNrgCh(){
00412   Shout("Calculate chains energy");
00413   double Pot[3] = {0.,0.,0.};
00414   double Nrg = 0.;
00415   for(int c=0;c<pNChain();c++){
00416     /* sustract to the densities the values of the c chain */
00417     int p1 = c*pNPCh();
00418     CalcNrgCh(c,Pot);
00419     OldNrgCh[c*3  ] = Pot[0];
00420     OldNrgCh[c*3+1] = Pot[1];
00421     OldNrgCh[c*3+2] = Pot[2];
00422     Nrg += Pot[0] + Pot[1] + Pot[2];
00423     //fprintf(StatFile1,"%d %d %lf\n",c,pNPCh(c),Pot[0]);
00424   }
00425   return Nrg;
00426 }
00428 double Forces::DensFuncNrgCh(int c,double *Pot){
00429   int p1 = c*pNPCh();
00430   Pot[2] = DensFuncNrgChInternal(c);
00431   for(int p=0;p<pNPCh();p++) Pot[2] += NanoNrg(p+p1);
00432   return Pot[2];
00433 }
00435 double Forces::NrgChBondDens(int c,double *Pot){
00436   CalcBondedCh(c,Pot);
00437   int p1 = c*pNPCh();
00438   Pot[2] = DensFuncNrgChInternal(c);
00439   return Pot[0] + Pot[1] + Pot[2];
00440 }
00441 double Forces::DensFuncNrgChAv(int Ch){
00442   CalcDens(Ch*pNPCh(),(Ch+1)*pNPCh());
00443   return SumDens(Ch*pNPCh(),(Ch+1)*pNPCh());
00444 }
00445 double Forces::CalcPairwiseCh(int c,double *Pot){
00446   Pot[0] = 0.;Pot[1] = 0.;Pot[2] = 0.;
00447   int p1 = c*pNPCh();
00448   double DistRel[4] = {0.,0.,0.,0.};;
00449   double Pot1[3] = {0.,0.,0.};
00450   //loop in the chain
00451   double Pos[3];
00452   for(int p=p1;p<p1+pNPCh();p++){
00453     int t1 = pType(p);
00454     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00455       int p2 = Pc->p2Curr;
00456       Pc->Dist2Curr(DistRel);
00457       if(p1 >= p2) continue;
00458       if(p2 > p1 && p2 < p1 + pNPCh() && p2 < p) continue;
00459       int t2 = pType(p2);
00460       // avoid self interactions in the chains
00461       if(DistRel[3] > Kf.CutOff2) continue;
00462       Potential(DistRel[3],pType(p1),pType(p2),Pot1);
00463       Pot[2] += Pot1[0];
00464     }
00465   }
00466   return Pot[0] + Pot[1] + Pot[2];
00467 }
00468 //------------------Calc-Part-Nrg----------------------------
00470 double Forces::CalcTotNrgBead(){
00471   Shout("Calculate chains energy");
00472   double Pot[3] = {0.,0.,0.};
00473   double Nrg = 0.;
00474   for(int p=0;p<pNChain();p++){
00475     /* sustract to the densities the values of the c chain */
00476     CalcNrgBead(p,Pot);
00477     OldNrgBead[p*3  ] = Pot[0];
00478     OldNrgBead[p*3+1] = Pot[1];
00479     OldNrgBead[p*3+2] = Pot[2];
00480     Nrg += Pot[0] + Pot[1] + Pot[2];
00481   }
00482   return Nrg;
00483 }
00484 double Forces::DensFuncNrgBead(int p1){
00485   double Pos[3];
00486   pPos(p1,Pos);
00487   return DensFuncNrgGhost(Pos,p1,pType(p1));
00488   RemDens(p1,p1+1);
00489   double Nrg = OldNrgSys - SumDens(0,pNPart());
00490   AddDens(p1,p1+1);
00491   return Nrg;
00492 }
00494 double Forces::CalcNrgBeadDensFunc(int p,double *Pot){
00495   CalcBonded(p,Pot);
00496   Pot[2] = DensFuncNrgBead(p);
00497   return Pot[0] + Pot[1] + Pot[2];
00498 }
00499 double Forces::CalcPairwise(int p1,double *Pot){
00500   //return CheckDomDec(p1);
00501   double NrgSum = 0.;
00502   int NCutOff = 0;
00503   double Pos[3];
00504   double DistRel[4] = {0.,0.,0.,0.};
00505   Pot[0] = 0.;Pot[1] = 0.;Pot[2] = 0.;
00506   for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00507   int p2 = Pc->p2Curr;
00508   // for(int p2 = 0;p2<pNPart();p2++){
00509     if(p2 == p1) continue;
00510     //if(p2 >= p1) continue;
00511     // TwoPartDist(p1,p2,DistRel);
00512     Pc->Dist2Curr(DistRel);
00513     if(DistRel[3] > Kf.CutOff2) continue;
00514     Potential(DistRel[3],pType(p1),pType(p2),Pot);
00515     NrgSum += Pot[0] + Pot[1] + Pot[2];
00516     NCutOff++;
00517   }
00518   return NrgSum;
00519 }
00520 //----------------------MOLECULAR-DYNAMICS----------------------
00521 void Forces::ChooseCalcMode(int Mode){
00522   printf("Calculation mode: ");
00523   if(VAR_IF_TYPE(Mode,CALC_PAIR)){
00524     NrgBead = &Forces::CalcPairwise;
00525     NrgCh = &Forces::CalcPairwiseCh;
00526     printf("Pairwise interactions\n");
00527   }
00528   else if(VAR_IF_TYPE(Mode,CALC_DENS)){
00529     NrgBead = &Forces::CalcNrgBeadDensFunc;
00530     NrgCh = &Forces::DensFuncNrgCh;
00531     Kf.CutOff2 = 1.;
00532     printf("Lipid model particle energy\n");
00533   }
00534   else if(VAR_IF_TYPE(Mode,CALC_DENS_CH)){
00535     NrgBead = &Forces::CalcNrgBeadDensFunc;
00536     NrgCh = &Forces::DensFuncNrgCh;
00537     Kf.CutOff2 = 1.;
00538     printf("Lipid model chain energy\n");
00539   }
00540   else{
00541     printf("mode not present\n");
00542     exit(1);
00543   }
00544 }
00545 void Forces::ChoosePot(int Mode){
00546   printf("Potential: ");
00547   if(VAR_IF_TYPE(Mode,CALC_LJ)){
00548     CalcPot = &Forces::LJPot;
00549     printf("Lennard Jones\n");
00550   }
00551   else if(VAR_IF_TYPE(Mode,CALC_LJ39)){
00552     CalcPot = &Forces::LJ39;
00553     printf("Lennard Jones 3-9\n");
00554   }
00555   else if(VAR_IF_TYPE(Mode,CALC_HARM)){
00556     CalcPot = &Forces::Harmonic;
00557     printf("Harmonic\n");
00558   }
00559   else if(VAR_IF_TYPE(Mode,CALC_STEP)){
00560     CalcPot = &Forces::StepPot;
00561     printf("Step\n");
00562   }
00563   else if(VAR_IF_TYPE(Mode,CALC_ELECTRO)){
00564     CalcPot = &Forces::ElectroPot;
00565     printf("Step\n");
00566   }
00567   else{
00568    printf("not present\n");
00569    exit(1);
00570   }
00571   DefForceParam();
00572 }
00573 double Forces::SumForcesMD(){
00574   double Pot[3];
00575   double DistRel[4] = {0.,0.,0.,0.};
00576   double Nrg = 0.;
00577   for(int p1=0;p1<pNPart();p1++){
00578     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00579       int p2 = Pc->p2Curr;
00580       if(p1 >= p2) continue;
00581       Pc->Dist2Curr(DistRel);
00582       if(DistRel[3] > Kf.CutOff2) continue;
00583       double InvDist = 1./sqrt(DistRel[3]);
00584       double Cons = Potential(DistRel[3],pType(p1),pType(p2),Pot);
00585       for(int d=0;d<3;d++){
00586    Fm[p1].Dir[d] += Cons*DistRel[d]*InvDist;
00587    Fm[p2].Dir[d] -= Cons*DistRel[d]*InvDist;
00588       }
00589       Nrg += Pot[0];
00590     }
00591   }
00592   return Nrg;
00593 }
00594 #include <sys/time.h>
00595 void Forces::CheckPairList(){
00596   int NAll = pNPart();
00597   int *PDom = (int *)calloc(NAll*NAll,sizeof(int));
00598   if(PDom == NULL){printf("Could not alloc PDom\n");return;};
00599   int *PLoop = (int *)calloc(NAll*NAll,sizeof(int));
00600   if(PLoop == NULL){printf("Could not alloc PLoop\n");return;};
00601   int NDom = 0;
00602   int NLoop = 0;
00603   double NPairDom  = 0.;
00604   double NPairLoop = 0.;
00605   double Dist[3];
00606   double Nrg = 0.;
00607   double Pot[2];
00608   double DistRel[4] = {0.,0.,0.,0.};
00609   double TimeDomDec;
00610   double TimeLoop;
00611   timespec TimeInit;
00612   timespec TimeEnd;
00613 //  clock_gettime(CLOCK_REALTIME, &TimeInit);
00614   double Pos[3]; 
00615   for(int p1=0;p1<pNPart();p1++){
00616     for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00617       int p2 = Pc->p2Curr;
00618       if(p2 <= p1) continue;
00619       Pc->Dist2Curr(DistRel);
00620       NPairDom += 1.;
00621       if(DistRel[3] > Kf.CutOff2) continue;
00622       PLoop[NDom*2+0] = p2;
00623       PLoop[NDom*2+1] = p2;
00624       NDom++;
00625     }
00626   }
00627 //  clock_gettime(CLOCK_REALTIME, &TimeEnd);
00628   TimeDomDec = (double)(TimeInit.tv_nsec - TimeEnd.tv_nsec);
00629 //  clock_gettime(CLOCK_REALTIME, &TimeInit);
00630   for(int p1=0;p1<pNPart();p1++){
00631     for(int p2=p1+1;p2<pNPart();p2++){
00632       double Dist2 = 0.;
00633       for(int d=0;d<3;d++){
00634    Dist[d] = pPos(p1,d) - pPos(p2,d);
00635    Dist[d] -= floor(Dist[d]*pInvEdge(d) + .5)*pEdge(d);
00636    Dist2 += SQR(Dist[d]);
00637       }
00638       NPairLoop += 1.;
00639       if(Dist2 > Kf.CutOff2) continue;
00640       PLoop[NLoop*2+0] = p1;
00641       PLoop[NLoop*2+1] = p2;
00642       NLoop++;
00643     }
00644   }
00645 //  clock_gettime(CLOCK_REALTIME, &TimeEnd);
00646   TimeLoop = (double)(TimeInit.tv_nsec - TimeEnd.tv_nsec);
00647   //Mat->Sort(PDom,NDom);
00648   printf("[Pairs] %d=%d Gain (pair): %lf (time): %lf\n",NDom,NLoop,NPairLoop/NPairDom,TimeLoop/TimeDomDec);
00649   for(int p=0;p<MAX(NDom,NLoop);p++){
00650     //printf("%d %d %d\n",p,PDom[p],PLoop[p]);
00651     //if(p >= NDom)
00652     //printf(" %d %d\n",PLoop[p],Pc->pCell(PLoop[p]));
00653   }
00654   free(PDom);
00655   free(PLoop);
00656 }
00658 double Forces::CheckDomDec(int p1){
00659   const int NAll = pNPart();
00660   int *PDom = new int[NAll];
00661   int *PCell = new int[NAll];
00662   int NDom = 0;
00663   int *PLoop = new int[NAll];
00664   int NLoop = 0;
00665   double NCell = 0.;
00666   double Pos[3];
00667   double DistRel[4] = {0.,0.,0.,0.};
00668   double Nrg=0.;
00669   double Pot[2];
00670   for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
00671     int p2 = Pc->p2Curr;
00672     if(p2 == p1) continue;
00673     Pc->Dist2Curr(DistRel);
00674     if(DistRel[3] > Kf.CutOff2) continue;
00675     PDom[NDom++] = p2;
00676     PCell[NDom] = Pc->cCurr;
00677   }
00678   for(int p2=0;p2<pNPart();p2++){
00679     if(p1 == p2) continue; 
00680     double Dist2 = 0.;
00681     for(int d=0;d<3;d++){
00682       DistRel[d] = pPos(p1,d) - pPos(p2,d);
00683       DistRel[d] -= floor(DistRel[d]*pInvEdge(d) + .5)*pEdge(d);
00684       Dist2 += SQR(DistRel[d]);
00685     }
00686     if(Dist2 > Kf.CutOff2) continue;
00687     PLoop[NLoop++] = p2;
00688   }
00689   //Mat->Sort(PDom,NDom);
00690   printf("-------------%d=%d Ratio %lf\n",NDom,NLoop,pNPart()/NCell);
00691   for(int p=0;p<MAX(NDom,NLoop);p++){
00692     printf("%d %d %d %d\n",p,PDom[p],PLoop[p],PCell[p]);
00693     //if(p >= NDom)
00694     //printf(" %d %d\n",PLoop[p],Pc->pCell(PLoop[p]));
00695   }
00696   printf("nei \n");
00697   delete [] PDom;
00698   delete [] PCell;
00699   delete [] PLoop;
00700   return 0.;
00701 }