Allink
v0.1
|
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 }