Allink
v0.1
|
00001 #include "Forces.h" 00002 //-------------------------SPLINES-------------------------------- 00004 int Forces::ForceFieldLine(){ 00005 double Sign=1.; 00006 SPLINE Sp1; 00007 SPLINE Sp2; 00008 SPLINE Cub1; 00009 SPLINE Cub2; 00010 SPLINE Par1; 00011 SPLINE Par2; 00012 double fSLap=0.; 00013 double fLap=0.; 00014 //Fm[Part2Move].fExt[2] = -Fm[Part2Move].fHel[2]; 00015 //Fm[Part2Move].fExt[2] = 0.; 00016 for(int p=0;p<pNPart();p++){ 00017 Fm[p].Ext[2] = -Fm[p].Dir[2]/1.1; 00018 if(IfInterp==FIT_SPLINE3){ 00019 if( p == 0) 00020 Sp2 = Mat->Spline3Beg(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00021 else if( p < pNPart() - 2 ) 00022 Sp2 = Mat->Spline3(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00023 else if( p == pNPart() - 2 ) 00024 Sp2 = Mat->Spline3End(Pm[p].Pos,Pm[p+1].Pos,0,2); 00025 fSLap = 0.;//atan(Sp2.a1); 00026 fLap = 2.*Sp2.a2; 00027 } 00028 else if(IfInterp==FIT_SPLINE4){ 00029 if( p == 0){ 00030 Sp2 = Mat->Spline4Beg(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,2); 00031 //Pm[p].Typ = 2; 00032 } 00033 else if( p < pNPart() - 3 ) 00034 Sp2 = Mat->Spline4(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,2); 00035 else if( p == pNPart() - 3 ){ 00036 Sp2 = Mat->Spline3(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00037 //Sp2 = Mate->Spline4PreEnd(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,1); 00038 //Pm[p].Typ = 2; 00039 } 00040 else if( p == pNPart() - 2 ){ 00041 Sp2 = Mat->Spline3End(Pm[p].Pos,Pm[p+1].Pos,0,2); 00042 //Sp2 = Mate->Spline4End(Pm[p].Pos,Pm[p+1].Pos,0,1); 00043 //Pm[p].Typ = 2; 00044 } 00045 fSLap = (24.*Sp2.a4); 00046 fLap = (2.*Sp2.a2); 00047 } 00048 // else if(IfInterp==FIT_PARAB){ 00049 // if(p < Gen->NPart - 2){ 00050 // Par1 = Mate->Parab(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00051 // } 00052 // fSLap = 0.;//(2.*Par2.A*Pm[p].Pos[0]+Par2.B); 00053 // fLap = 2.*Par1.A/100.; 00054 // } 00055 else if(IfInterp==FIT_PARAB2){ 00056 if(p == 0){ 00057 Sp2 = Mat->Parab(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00058 } 00059 if(p < pNPart() - 1){ 00060 Sp2 = Mat->Parab2(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,0,2); 00061 } 00062 fSLap = 0.;//(Par2.B); 00063 fLap = 2.*Sp2.a2; 00064 } 00065 else if(IfInterp==FIT_CUBIC){ 00066 if(p == 0){ 00067 Cub2 = Mat->Parab(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00068 } 00069 if(p < pNPart() - 2){ 00070 Cub2 = Mat->Cubica(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00071 } 00072 if(p == pNPart() - 2){ 00073 Cub2 = Mat->Parab2(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,0,2); 00074 } 00075 fSLap = 0.; 00076 fLap = 2.*Cub2.a2; 00077 } 00078 else if(IfInterp==FIT_FORTH){ 00079 double Ref=0.; 00080 if(p < 1){ 00081 //Sp1 = Mat->Forth(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,Pm[p+4].Pos,0,1); 00082 Sp2 = Mat->Forth(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,Pm[p+4].Pos,0,2); 00083 Ref = Pm[p].Pos[0] - Pm[p+2].Pos[0]; 00084 } 00085 else if(p < 2){ 00086 //Sp1 = Mat->Forth(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,1); 00087 Sp2 = Mat->Forth(Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,2); 00088 Ref = Pm[p].Pos[0] - Pm[p+1].Pos[0]; 00089 } 00090 else if(p < pNPart()-2){ 00091 //Sp1 = Mat->Forth(Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,1); 00092 Sp2 = Mat->Forth(Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00093 Ref = 0.; 00094 } 00095 else if(p == pNPart()-2){ 00096 //Sp1 = Mat->Forth(Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,0,1); 00097 Sp2 = Mat->Forth(Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,0,2); 00098 Ref = Pm[p].Pos[0] - Pm[p-1].Pos[0]; 00099 } 00100 else if(p <= pNPart()-1){ 00101 //Sp1 = Mat->Forth(Pm[p-4].Pos,Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,0,1); 00102 Sp2 = Mat->Forth(Pm[p-4].Pos,Pm[p-3].Pos,Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,0,2); 00103 Ref = Pm[p].Pos[0] - Pm[p-2].Pos[0]; 00104 } 00105 fSLap = -(24.*Sp2.a4)*QUAD(QUAD(Dx)); 00106 fLap = (2.*Sp2.a2)*QUAD(Dx); 00107 //printf("%d) %lf %lf\n",p,Kf.kLap*fLap,Kf.kSLap*fSLap); 00108 } 00109 if(fLap > 100.) 00110 fLap = 100.; 00111 if(fSLap < -100.) 00112 fSLap = -100.; 00113 if(fSLap > 100.) 00114 fSLap = 100.; 00115 if(fSLap < -100.) 00116 fSLap = -100.; 00117 Fm[p].Dir[2] = Kf.SLap*fSLap + Kf.Lap*fLap; 00118 //if(Pm[p].Pos[2] <0) Sign = -1.; 00119 //else Sign = 1; 00120 //Fm[p].fHel[2] *= Sign; 00121 //if(p == Part2Move) 00122 //if(p > Part2Move -4 && p < Part2Move +4) 00123 { 00124 //printf("%d in (%lf,%lf) ha %lf|%lf Sp %lf %lf\n",p,Pm[p].Pos[2],Pm[p].Vel[2],Fm[p].fHel[2],Fm[p].fExt[2],fSLap,fLap); 00125 } 00126 } 00127 return 0; 00128 } 00130 int Forces::ForceFieldLeaves(){ 00131 double Sign=1.; 00132 SPLINE Sp1; 00133 SPLINE Sp2; 00134 PARABOLA Par1; 00135 PARABOLA Par2; 00136 double fSLap=0.; 00137 double fLap=0.; 00138 for(int c=0;c<pNChain();c++){ 00139 for(int p=c*NEdge;p<NEdge*(c+1);p++){ 00140 Fm[p].Ext[2] = -(Fm[p].Dir[2])/1.1; 00141 // Fm[p].El[2] = - Kf.El[2]*( c*Kf.Elong[2] + .5 - Pm[p].Pos[2]); 00142 if( p == c*NEdge){ 00143 Sp2 = Mat->Spline4Beg(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,Pm[p+3].Pos,0,2); 00144 //Pm[p].Typ = 2; 00145 } 00146 else if( p < NEdge*(c+1) - 3 ) 00147 Sp2 = Mat->Forth(Pm[p-2].Pos,Pm[p-1].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00148 //Sp2 = Mat->Spline4(Pm[p].Pos,Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00149 // else Pm[p].Typ = 2; 00150 else if( p == NEdge*(c+1) - 3 ){ 00151 Sp2 = Mat->Spline3(Pm[p].Pos,Pm[p+1].Pos,Pm[p+2].Pos,0,2); 00152 //Pm[p].Typ = 2; 00153 } 00154 else if( p == pNPart() - 2 ){ 00155 Sp2 = Mat->Spline3End(Pm[p].Pos,Pm[p+1].Pos,0,2); 00156 //Pm[p].Typ = 2; 00157 } 00158 fSLap = -(24.*Sp2.a4)*QUAD(QUAD(Dx)); 00159 fLap = (2.*Sp2.a2)*QUAD(Dx); 00160 if(fLap > 100.)fLap = 100.; 00161 if(fLap < -100.)fLap = -100.; 00162 if(fSLap > 100.)fSLap = 100.; 00163 if(fSLap < -100.)fSLap = -100.; 00164 Fm[p].Dir[2] = +Kf.SLap*fSLap + Kf.Lap*fLap; 00165 continue; 00166 { 00167 double Rad2=0.; 00168 for(int d=0;d<3;d++){ 00169 Rad2 += QUAD((Pm[p].Pos[d] - Nano->Pos[d])); 00170 } 00171 if( Rad2 > QUAD((3.*Nano->Rad))) continue; 00172 double CosTh = (Nano->Pos[0] - Pm[p].Pos[0])/Nano->Rad; 00173 double SenTh = sqrt(1 - QUAD(CosTh)); 00174 double Sign = 1.; 00175 double Rad = sqrt(Rad2); 00176 double Strength = 12.*pow( (Nano->Rad/Rad) , 13) + 6.*pow( (Nano->Rad/Rad) , 7); 00177 if(p <= NEdge) 00178 Sign *= -1.; 00179 Fm[p].Dir[0] = Kf.LJ * Strength * CosTh; 00180 Fm[p].Dir[2] = Kf.LJ * Strength * SenTh * Sign; 00181 } 00182 } 00183 } 00184 } 00185 //----------------------HARMONIC-POTENTIAL------------------- 00187 int Forces::ForceFieldBulk(){ 00188 for(int p=0;p<pNPart();p++){ 00189 for(int d=0;d<3;d++){ 00190 Fm[p].Ext[d] = -(Fm[p].Dir[d])/2.; 00191 } 00192 for(int l=0;l<Ln[p].NLink;l++){ 00193 int link = Ln[p].Link[l]; 00194 for(int d=0;d<3;d++){ 00195 double Delta = ASS((Pm[link].Pos[d] - Pm[p].Pos[d])); 00196 if(Delta < 0.001) continue; 00197 // printf("%d-%d (%d) %lf ",p,link,d,Delta); 00198 double Sign = 1.; 00199 if(Pm[p].Pos[d] < Pm[link].Pos[d] ) 00200 Sign = -1.; 00201 Fm[p].Dir[d] += - Sign*Kf.El[d]*(Delta - Kf.Elong[d])/1.1; 00202 } 00203 // printf("\n"); 00204 } 00205 //if(p > Part2Move -4 && p < Part2Move +4) 00206 //printf("%d) in (%lf,%lf) ha %lf|%lf|%lf Sp %lf %lf\n",p,Pm[p].Pos[2],Pm[p].Vel[2],Fm[p].fHel[2],Fm[p].fExt[2],Fm[p].fEl[2]); 00207 } 00208 } 00210 void Forces::ForceFieldRod(){ 00211 double DistRelBA[4]; 00212 double DistRelBC[4]; 00213 double Pre[12]; 00214 for(int b=0;b<pNBlock();b++){ 00215 for(int c=0;c<pNChain(b);c++){ 00216 for(int p=c*pNPCh(b);p<(c+1)*pNPCh(b)-1;p++){ 00217 TwoPartDist(p+1,p,DistRelBA); 00218 double ForceSp = pkSpr()*(1. - pSprRest()/DistRelBA[3]); 00219 for(int d=0;d<3;d++){ 00220 Fm[p].Dir[d] += ForceSp*DistRelBA[d]; 00221 Fm[p+1].Dir[d] -= ForceSp*DistRelBA[d]; 00222 } 00223 if(p < (c+1)*pNPCh(b)-2){ 00224 TwoPartDist(p+2,p+1,DistRelBC); 00225 double CosAngle = 0.; 00226 for(int d=0;d<3;d++){ 00227 DistRelBA[d] /= DistRelBA[3]; 00228 DistRelBC[d] /= DistRelBC[3]; 00229 CosAngle += DistRelBA[d]*DistRelBC[d]; 00230 } 00231 double PreFactBA = pkBen()/DistRelBA[3]; 00232 double PreFactBC = pkBen()/DistRelBC[3]; 00233 for(int d=0;d<3;d++){ 00234 Fm[p+0].Dir[d] += PreFactBA*(DistRelBC[d]-DistRelBA[d]*CosAngle); 00235 Fm[p+1].Dir[d] -= PreFactBA*(DistRelBC[d]-DistRelBA[d]*CosAngle); 00236 Fm[p+1].Dir[d] += PreFactBC*(DistRelBA[d]-DistRelBC[d]*CosAngle); 00237 Fm[p+2].Dir[d] -= PreFactBC*(DistRelBA[d]-DistRelBC[d]*CosAngle); 00238 } 00239 } 00240 } 00241 } 00242 } 00243 } 00244 /* obsolete? */ 00245 int Forces::SumSomeForces(int HowMany){ 00246 double Sign=1.; 00247 SPLINE Par1; 00248 SPLINE Par2; 00249 double Slope1; 00250 double Slope2; 00251 if(Bead2Move - HowMany < 1 || Bead2Move + HowMany > pNPart() - 2) 00252 return 1; 00253 //Fm[Part2Move].fExt[2] = -Fm[Part2Move].fHel[2]; 00254 //Fm[Part2Move].fExt[2] = 0.; 00255 int pp = Bead2Move; 00256 for(int h = 0;h<HowMany;h++){ 00257 int link1 = Ln[pp].Link[0]; 00258 int link2 = Ln[pp].Link[1]; 00259 // printf("(%lf %lf %lf), (%lf %lf %lf), (%lf %lf %lf)\n", 00260 // Pm[link1].Pos[0],Pm[link1].Pos[1],Pm[link1].Pos[2], 00261 // Pm[pp].Pos[0],Pm[pp].Pos[1],Pm[pp].Pos[2], 00262 // Pm[link2].Pos[0],Pm[link2].Pos[1],Pm[link2].Pos[2]); 00263 // Par1 = Mat->Parab2(Pm[link1].Pos,Pm[pp].Pos,Pm[link2].Pos,0,2); 00264 Par2 = Mat->Parab2(Pm[link1].Pos,Pm[pp].Pos,Pm[link2].Pos,1,2); 00265 Fm[pp].Dir[2] = - Kf.Lap*QUAD(2.*Par1.a2); 00266 Fm[pp].Dir[2] += - Kf.Lap*QUAD(2.*Par2.a2); 00267 //printf("%d-%d|%d) %lf %lf %lf %lf ",pp,link1,link2,Slope1,Par1.A,Slope2,Par2.A); 00268 link1 = Ln[pp].Link[2]; 00269 link2 = Ln[pp].Link[3]; 00270 Par1 = Mat->Parab2(Pm[link1].Pos,Pm[pp].Pos,Pm[link2].Pos,0,2); 00271 //Par2 = Mat->Parab2(Pm[link1].Pos,Pm[pp].Pos,Pm[link2].Pos,1,2); 00272 Fm[pp].Dir[2] += - Kf.Lap*QUAD(2.*Par1.a2); 00273 Fm[pp].Dir[2] += - Kf.Lap*QUAD(2.*Par2.a2); 00274 //printf("%d-%d|%d) %lf %lf %lf %lf\n",pp,link1,link2,Slope1,Par1.A,Slope2,Par2.A); 00275 if(Pm[pp].Pos[2] <0) Sign = -1.; 00276 else Sign = 1; 00277 Fm[pp].Dir[2] *= Sign; 00278 //printf("%d) Pos %lf Force %lf %lf\n",pp,Pm[pp].Pos[2],Fm[pp].fHel[2],Fm[pp].fExt[2]); 00279 } 00280 return 0; 00281 } 00282 //-----------------------------RIGID------------------------- 00283 void Forces::ForceFieldRigid(){ 00284 double Pot[2]; 00285 for(int n=0;n<pNNano();n++){ 00286 for(int d=0;d<3;d++){ 00287 Nano[n].Force[d] = 0.; 00288 Nano[n].AMom[d] = 0.; 00289 } 00290 } 00291 for(int n=0;n<pNNano();n++){ 00292 for(int nn=n+1;nn<pNNano();nn++){ 00293 double dr[3] = {0.,0.,0.}; 00294 double Dist = RigidDistanceAxis(n,nn,dr); 00295 //if( Dist > CutOff ) continue; 00296 double Cons = RigidLJ(n,Dist,Pot,0); 00297 for(int d=0;d<3;d++){ 00298 Nano[n].Force[d] -= Cons*dr[d]; 00299 Nano[nn].Force[d] += Cons*dr[d]; 00300 Nano[n].AMom[d] -= Nano[n].AMomTemp[d]*Cons; 00301 Nano[nn].AMom[d] += Nano[n].AMomTemp[d]*Cons; 00302 //printf("%d %lf %lf\n",d,Cons*dr[d],Nano[nn].AMom[d]); 00303 } 00304 } 00305 for(int d=0;d<3;d++){ 00306 double Ran = Nano[n].Zeta * (2.*Mat->Casuale() - 1.); 00307 double Dis = - Nano[n].Gamma*Nano[n].Vel[d]; 00308 //Nano->Force[d] += Ran + Dis; 00309 } 00310 //printf("%d %lf %lf %lf\n",n,Nano[n].AMom[0],Nano[n].AMom[1],Nano[n].AMom[2]); 00311 } 00312 } 00313 double Forces::RigidDistanceAxis(int n,int nn,double *dr){ 00314 Vettore Pos1(Nano[n].Pos,3); 00315 Vettore Pos2(Nano[nn].Pos,3); 00316 Vettore PosRel(Pos2[0]-Pos1[0],Pos2[1]-Pos1[1],Pos2[2]-Pos1[2]); 00317 Vettore Axis(Nano[n].Axis,3); 00318 Vettore Perp(3); 00319 Vettore AMomTemp(3); 00320 double Dist = Perp.PerpTo(&PosRel,&Axis); 00321 Perp.Export(dr); 00322 AMomTemp.VetV(&Perp,&PosRel); 00323 AMomTemp.Export(Nano[n].AMomTemp); 00324 //AMomTemp.Export(Nano[nn].AMomTemp); 00325 double HeiOnAxis = Perp.ProjOnAxis(&PosRel,&Axis); 00326 if( fabs(HeiOnAxis) > Nano[n].Height*.5){ 00327 double Sign = HeiOnAxis > 0 ? 1. : -1.; 00328 Dist = 0.; 00329 for(int d=0;d<3;d++){ 00330 dr[d] = Pos2[d] - Pos1[d]; 00331 Dist = SQR(dr[d]); 00332 } 00333 Dist = sqrt(Dist); 00334 } 00335 return Dist; 00336 } 00337 void Forces::NanoInteraction(){ 00338 double Pot[2]; 00339 for(int n=0;n<pNNano();n++){ 00340 for(int d=0;d<3;d++){ 00341 Nano[n].Force[d] = 0.; 00342 Nano[n].AMom[d] = 0.; 00343 } 00344 } 00345 for(int n=0;n<pNNano();n++){ 00346 Point2Shape(Nano[n].Shape); 00347 for(int p=0;p<pNPart();p++){ 00348 double dr[3] = {0.,0.,0.}; 00349 double Dist2 = NanoDist2(Pm[p].Pos,n); 00350 if( Dist2 > Kf.CutOff2 ) continue; 00351 double Cons = RigidLJ(n,Dist2,Pot,0); 00352 for(int d=0;d<3;d++){ 00353 Nano[n].Force[d] -= Cons*dr[d]; 00354 Fm[p].Dir[d] += Cons*dr[d]; 00355 Nano[n].AMom[d] -= Nano[n].AMomTemp[d]*Cons; 00356 } 00357 } 00358 for(int d=0;d<3;d++){ 00359 double Ran = Nano[n].Zeta * (2.*Mat->Casuale() - 1.); 00360 double Dis = - Nano[n].Gamma*Nano[n].Vel[d]; 00361 //Nano->Force[d] += Ran + Dis; 00362 } 00363 //printf("%d %lf %lf %lf\n",n,Nano[n].AMom[0],Nano[n].AMom[1],Nano[n].AMom[2]); 00364 } 00365 } 00366 double Forces::NanoNrg(int p){ 00367 double Nrg = NanoNrg(pPos(p),pType(p)); 00368 return Nrg; 00369 } 00370 double Forces::NanoNrg(double *Pos,int t){ 00371 double Pot[2]; 00372 double Cons = 0.; 00373 double Nrg = 0.; 00374 for(int n=0;n<pNNano();n++){ 00375 Point2Shape(Nano[n].Shape); 00376 double Dist2 = NanoDist2(Pos,n); 00377 if( Dist2 > SQR(Nano[n].CutOff) ) continue; 00378 double Dist = sqrt(Dist2); 00379 double Sign = -1.; 00380 if(t == 1) Sign = 1.; 00381 Cons += RigidHamaker(n,Dist,Pot,Sign); 00382 //Cons += RigidLJ(n,Dist2,Pot,0); 00383 Nrg += Pot[0]; 00384 } 00385 Nrg *= Nano->Coating; 00386 return Nrg; 00387 } 00388 void Forces::DefForceParam(){ 00389 double Pot[2]; 00390 Kf.ForThr = 50.; 00391 Kf.DistThr = 0.; 00392 Potential(Kf.CutOff2,0,0,Pot); 00393 Kf.BaseLine = -Pot[0]; 00394 double CutOff = sqrt(Kf.CutOff2); 00395 for(int i=10000;i>0;i--){ 00396 double x = CutOff/10000.*i; 00397 double For = Potential(SQR(x),0,0,Pot)/x; 00398 if(For >= Kf.ForThr){ 00399 Kf.DistThr = x; 00400 Kf.PotThr = Pot[0]; 00401 break; 00402 } 00403 } 00404 } 00405 void Forces::DefNanoForceParam(){ 00406 double Pot[2]; 00407 for(int n=0;n<pNNano();n++){ 00408 Nano[n].ForThr = 50.; 00409 Point2Shape(Nano[n].Shape); 00410 Nano[n].CutOff = Nano[n].Rad*3.; 00411 Nano[n].BaseLine = 0.; 00412 double For = RigidLJ(n,Nano[n].CutOff,Pot,0); 00413 Nano[n].BaseLine = -Pot[0]; 00414 Nano[n].DistThr = 0.; 00415 for(int i=10000;i>0;i--){ 00416 double x = (Nano[n].CutOff)/10000.*i; 00417 For = RigidHamaker(n,x,Pot,0); 00418 //For = RigidLJ(n,x,Pot,0); 00419 if(For >= Nano[n].ForThr){ 00420 Nano[n].DistThr = x; 00421 Nano[n].PotThr = Pot[0]; 00422 break; 00423 } 00424 } 00425 //printf("DefForce %lf %lf %lf\n",Nano[n].DistThr,Nano[n].PotThr,Nano[n].BaseLine); 00426 } 00427 } 00428 double Forces::RigidDistanceRad(int n,int nn,double *dr){ 00429 Vettore Pos1(Nano[n].Pos,3); 00430 Vettore Pos2(Nano[nn].Pos,3); 00431 double Dist = 0.; 00432 for(int d=0;d<3;d++){ 00433 dr[d] = Pos2[d] - Pos1[d]; 00434 Dist += SQR(dr[d]); 00435 } 00436 return sqrt(Dist); 00437 } 00438 double Forces::RigidLJ(int n,double Dist,double *Pot,double Sign){ 00439 double Cons = 0.; 00440 double Strength = pow(Nano[n].Coating,9.)*Nano[n].Hamaker; 00441 double Hamaker = pow(Nano[n].Coating,3.)*Nano[n].Hamaker; 00442 if( Dist < Nano[n].DistThr){ 00443 Pot[0] = Nano[n].PotThr - Nano[n].ForThr*(Dist - Nano[n].DistThr); 00444 Pot[1] = Nano[n].ForThr; 00445 Cons = Nano[n].ForThr; 00446 return Cons; 00447 } 00448 double idr = 1./(Dist-Nano[n].Rad+Nano[n].Coating); 00449 double idr2 = idr*idr; 00450 double idr4 = idr2*idr2; 00451 double idr6 = idr2*idr4; 00452 Pot[0] = idr*idr2*(Strength*idr6 +Sign*Hamaker)+Nano[n].BaseLine; 00453 Cons = idr4 *(Strength*9.*idr6+Sign*3.*Hamaker); 00454 Pot[1] = idr4 *(Strength*9.*idr6+Sign*3.*Hamaker); 00455 return Cons; 00456 } 00458 double Forces::RigidHamaker(int n,double Dr,double *Pot,double Sign){ 00459 double SurfTens = 3.*Nano[n].Hamaker; 00460 double Cons = 0.; 00461 double Sigma = 1.0;//0.04; 00462 double Slope = 1.00203; 00463 double Intercept = 0.31739; 00464 double Rnp = Nano[n].Rad/Slope-Intercept; 00465 if( Dr < Nano[n].DistThr){ 00466 Pot[0] = Nano[n].PotThr - Nano[n].ForThr*(Dr - Nano[n].DistThr); 00467 Pot[1] = Nano[n].PotThr; 00468 return Nano[n].ForThr; 00469 } 00470 double DrInv = 1./Dr; 00471 double DrP1 = 1./(Dr+Rnp); 00472 double DrP3 = CUBE(DrP1); 00473 double DrP6 = SQR(DrP3); 00474 double DrP9 = DrP6*DrP3; 00475 double DrM1 = 1./(-Dr+Rnp); 00476 double DrM3 = CUBE(DrM1); 00477 double DrM6 = SQR(DrM3); 00478 double DrM9 = DrM6*DrM3; 00479 double PreRep = Sigma*1./360.*DrInv*SurfTens; 00480 double PreAttr = 1./12.*DrInv*SurfTens; 00481 double Rep = (9.0*Rnp+Dr)*DrP9 - (9.0*Rnp-Dr)*DrM9; 00482 double Attr= (3.0*Rnp+Dr)*DrP3 - (3.0*Rnp-Dr)*DrM3; 00483 double RepP = -DrP9+9.*(9.*Rnp+Dr)*DrP9*DrP1 00484 -(9.*Rnp+Dr)*DrP9*DrInv; 00485 double RepM = -DrM9+9.*(9.*Rnp-Dr)*DrM9*DrM1 00486 -(9.*Rnp-Dr)*DrM9*DrInv; 00487 double AttrP = -DrP3+3.*(3.*Rnp+Dr)*DrP3*DrP1 00488 -(3.*Rnp+Dr)*DrP3*DrInv; 00489 double AttrM = -DrM3+3.*(3.*Rnp-Dr)*DrM3*DrM1 00490 -(3.*Rnp-Dr)*DrM3*DrInv; 00491 double RepChem = 9.*DrP9 - (9.*Rnp+Dr)*9.*DrP9*DrP1 00492 - 9.*DrM9 + 9.*(9.*Rnp-Dr)*DrM9*DrM1; 00493 double AttrChem = 3.*DrP3 - (3.*Rnp+Dr)*3.*DrP3*DrP1 00494 - 3.*DrM9 + 3.*(3.*Rnp-Dr)*DrM3*DrM1; 00495 Pot[0] = PreRep*Rep + Sign*PreAttr*Attr + Nano[n].BaseLine; 00496 Pot[1] = PreRep*RepChem + Sign*PreAttr*AttrChem; 00497 Cons = PreRep*(RepP+RepM) + Sign*PreAttr*(AttrP+AttrM); 00498 return Cons; 00499 } 00500 double Forces::RigidCoulomb(int n,double Dist,double *Pot,double Sign){ 00501 if(Dist < 2.*Nano[n].Rad) 00502 return 300.; 00503 Pot[0] = Sign*Nano[n].Hamaker/(Dist); 00504 return -Sign*Nano[n].Hamaker/SQR(Dist); 00505 } 00506 //----------------------------DEF-FORCES-POTENTIAL------------- 00507 void Forces::PointShape(int iShape){ 00508 Point2Shape(iShape); 00509 if(VAR_IF_TYPE(iShape,SHAPE_SPH)) 00510 CalcPot = &Forces::LJ39; 00511 if(VAR_IF_TYPE(iShape,SHAPE_CYL)) 00512 CalcPot = &Forces::LJ39; 00513 if(VAR_IF_TYPE(iShape,SHAPE_PILL)) 00514 CalcPot = &Forces::LJ39; 00515 if(VAR_IF_TYPE(iShape,SHAPE_TILT)) 00516 CalcPot = &Forces::LJ39; 00517 if(VAR_IF_TYPE(iShape,SHAPE_WALL)) 00518 CalcPot = &Forces::LJ39; 00519 if(VAR_IF_TYPE(iShape,SHAPE_PORE)) 00520 CalcPot = &Forces::LJ39; 00521 if(VAR_IF_TYPE(iShape,SHAPE_EXT)) 00522 CalcPot = &Forces::LJ39; 00523 if(VAR_IF_TYPE(iShape,SHAPE_JANUS)) 00524 CalcPot = &Forces::LJ39; 00525 if(VAR_IF_TYPE(iShape,SHAPE_STALK)) 00526 CalcPot = &Forces::LJ39; 00527 if(VAR_IF_TYPE(iShape,SHAPE_TIP)) 00528 CalcPot = &Forces::LJ39; 00529 if(VAR_IF_TYPE(iShape,SHAPE_TORUS)) 00530 CalcPot = &Forces::LJ39; 00531 if(VAR_IF_TYPE(iShape,SHAPE_HARM)) 00532 CalcPot = &Forces::LJ39; 00533 if(VAR_IF_TYPE(iShape,SHAPE_UMBR)) 00534 CalcPot = &Forces::LJ39; 00535 DefNanoForceParam(); 00536 } 00537 double Forces::Harmonic(double Dist2,int t1,int t2,double *Pot){ 00538 double Dist = sqrt(Dist2); 00539 double a = Kf.LJ; 00540 double b = -2.*a*Kf.LJMin; 00541 double c = -a*SQR(Kf.LJMin) - b*Kf.LJMin; 00542 Pot[2] = a*Dist2 + b*Dist + c; 00543 double For = - 2.*a*Dist2 - b*Dist; 00544 if(t1 != t2){ 00545 Pot[2] *= -1.; 00546 return -For; 00547 } 00548 //Pot[2] = 0.; 00549 return For; 00550 } 00551 double Forces::LJ39(double Dist2,int t1,int t2,double *Pot){ 00552 double idr6 = CUBE(SQR(Kf.LJMin)/Dist2); 00553 double idr3 = CUBE(Kf.LJMin)/(Dist2*sqrt(Dist2)); 00554 // if( Dist2 < Kf.DistThr){ 00555 // Pot[0] = Kf.PotThr - Kf.ForThr*(Dist2 - Kf.DistThr); 00556 // return Cons = Kf.ForThr; 00557 // } 00558 if(t1 == t2){ 00559 Pot[2] = Kf.LJ*idr3*(idr6-1.)+Kf.BaseLine; 00560 return Kf.LJ*idr3*(9.*idr6-3.); 00561 } 00562 else{ 00563 Pot[2] = Kf.LJ*idr3*(idr6+1.)+Kf.BaseLine; 00564 return Kf.LJ*idr3*(9.*idr6+3.); 00565 } 00566 } 00567 double Forces::LJPot(double Dist2,int t1,int t2,double *Pot){ 00568 double idr6 = CUBE(SQR(Kf.LJMin)/Dist2); 00569 // if( Dist2 < Kf.DistThr){ 00570 // Pot[0] = Kf.PotThr - Kf.ForThr*(Dist2 - Kf.DistThr); 00571 // return Kf.ForThr; 00572 // } 00573 if(t1 == t2){ 00574 Pot[2] = Kf.LJ*4.*(idr6*idr6-idr6) + Kf.BaseLine; 00575 return Kf.LJ*48.*(idr6*idr6-.5*idr6); 00576 } 00577 else{ 00578 Pot[2] = Kf.LJ*4.*(idr6*idr6+idr6) + Kf.BaseLine; 00579 return Kf.LJ*48.*(idr6*idr6+.5*idr6); 00580 } 00581 } 00582 double Forces::StepPot(double Dist2,int t1,int t2,double *Pot){ 00583 if(t1 != t2){ 00584 Pot[2] = -Kf.LJ; 00585 return -Kf.LJ*sqrt(Dist2/Kf.CutOff2); 00586 } 00587 Pot[2] = Kf.LJ; 00588 return Kf.LJ*sqrt(Dist2/Kf.CutOff2); 00589 } 00590 double Forces::ElectroPot(double Dist2,int t1,int t2,double *Pot){ 00591 if(t1 == t2) 00592 Pot[2] = Kf.Ext/Dist2; 00593 else 00594 Pot[2] = -Kf.LJ/Dist2; 00595 return Pot[2]; 00596 } 00597 void Forces::CalcForcesDensFunc(){ 00598 if(!VAR_IF_TYPE(SysAlloc,ALL_FORCES)){ 00599 printf("Forces not allocated\n"); 00600 return; 00601 } 00602 int NTabF = 300; 00603 TabForceAlloc(NTabF); 00604 double *Count = (double *)calloc(NTab*pNType()*pNType(),sizeof(double)); 00605 ClearDens(); 00606 AddDens(0,pNPart()); 00607 SumDens(0,pNPart()); 00608 double Dist = 0.; 00609 double DistRelBA[4]; 00610 double InvCutOff = 1./sqrt(Kf.CutOff2); 00611 for(int p=0;p<pNPart();p++){ 00612 for(int d=0;d<3;d++){ 00613 Fm[p].Dir[d] = 0.; 00614 } 00615 } 00616 // non bonded 00617 for(int p1=0;p1<pNPart();p1++){ 00618 for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){ 00619 int p2 = Pc->p2Curr; 00620 if(p2 <= p1) continue; 00621 Pc->Dist2Curr(DistRelBA); 00622 if(DistRelBA[3] > Kf.CutOff2) continue; 00623 double Force = 0.; 00624 double Dist = sqrt(DistRelBA[3]); 00625 for(int t=0;t<pNType();t++){ 00626 Force += MInt->Coeff(Pm[p1].Typ,Pm[p2].Typ,t)*(Dens3[p1*pNType()+t]+Dens3[p2*pNType()+t]); 00627 } 00628 Force *= DerWei3(Dist,pWei3Par())*2./3.; 00629 Force += DerWei2(Dist,pWei2Par())*MInt->Coeff(Pm[p1].Typ,Pm[p2].Typ); 00630 Force /= -Dist; 00631 int x = (int)(Dist*InvCutOff*NTab); 00632 if( x < 0 || x >= NTab) continue; 00633 int t = MIN(Pm[p1].Typ,Pm[p2].Typ)*pNType()+MAX(Pm[p1].Typ,Pm[p2].Typ); 00634 FTab[x*pNType()*pNType()+t] += Force; 00635 Count[x*pNType()*pNType()+t] += 1.; 00636 for(int d=0;d<3;d++){ 00637 Fm[p1].Dir[d] += Force*DistRelBA[d]; 00638 Fm[p2].Dir[d] -= Force*DistRelBA[d]; 00639 } 00640 } 00641 } 00642 for(int t=0;t<NTab;t++){ 00643 for(int t1=0;t1<pNType();t1++){ 00644 for(int t2=0;t2<pNType();t2++){ 00645 int tType = MIN(t1,t2)*pNType()+MAX(t1,t2); 00646 double Norm = Count[t*pNType()*pNType()+tType] > 0. ? 1./Count[t*pNType()*pNType()+tType] : 1.; 00647 FTab[t*pNType()*pNType()+tType] *= Norm; 00648 } 00649 } 00650 } 00651 // bonded 00652 double DistRelBC[4]; 00653 double Pre[12]; 00654 for(int b=0;b<pNBlock();b++){ 00655 for(int c=0;c<pNChain(b);c++){ 00656 for(int p=c*pNPCh(b);p<(c+1)*pNPCh(b)-1;p++){ 00657 TwoPartDist(p+1,p,DistRelBA); 00658 double ForceSp = pkSpr()*(1. - pSprRest()/DistRelBA[3]); 00659 for(int d=0;d<3;d++){ 00660 Fm[p].Dir[d] += ForceSp*DistRelBA[d]; 00661 Fm[p+1].Dir[d] -= ForceSp*DistRelBA[d]; 00662 } 00663 if(p < (c+1)*pNPCh(b)-2){ 00664 TwoPartDist(p+2,p+1,DistRelBC); 00665 double CosAngle = 0.; 00666 for(int d=0;d<3;d++){ 00667 DistRelBA[d] /= DistRelBA[3]; 00668 DistRelBC[d] /= DistRelBC[3]; 00669 CosAngle += DistRelBA[d]*DistRelBC[d]; 00670 } 00671 double PreFactBA = pkBen()/DistRelBA[3]; 00672 double PreFactBC = pkBen()/DistRelBC[3]; 00673 for(int d=0;d<3;d++){ 00674 Fm[p+0].Dir[d] -= PreFactBA*(DistRelBC[d]-DistRelBA[d]*CosAngle); 00675 Fm[p+1].Dir[d] += PreFactBA*(DistRelBC[d]-DistRelBA[d]*CosAngle); 00676 Fm[p+1].Dir[d] -= PreFactBC*(DistRelBA[d]-DistRelBC[d]*CosAngle); 00677 Fm[p+2].Dir[d] += PreFactBC*(DistRelBA[d]-DistRelBC[d]*CosAngle); 00678 } 00679 } 00680 } 00681 } 00682 } 00683 } 00684 void Forces::PrintForce(){ 00685 double NPoint = 1000.; 00686 FILE *FWrite = fopen("Force.dat","w"); 00687 double Pot[2]; 00688 double Delta = sqrt(Kf.CutOff2)/NPoint; 00689 double CutOff = sqrt(Kf.CutOff2); 00690 for(double x=Delta;x<CutOff;x+=Delta){ 00691 double Cons = LJPot(x,0,0,Pot); 00692 fprintf(FWrite,"%lf %lf %lf\n",x,Cons,*Pot); 00693 } 00694 fclose(FWrite); 00695 } 00696 void Forces::TabForceAlloc(int NTabExt){ 00697 NTab = NTabExt; 00698 double Pot[2]; 00699 double Delta = sqrt(Kf.CutOff2)/(double)NTab; 00700 double NrgLim = 20.; 00701 FTab = (double *)calloc(NTab*pNType()*pNType(),sizeof(double)); 00702 MTab = (double *)calloc(NTab,sizeof(double)); 00703 PTab = (double *)calloc(NTab*pNType()*pNType(),sizeof(double)); 00704 VAR_ADD_TYPE(DynFlag,ALL_FORCES); 00705 } 00706 void Forces::TabPot(){ 00707 NTab = 10000; 00708 double NrgLim = 10.; 00709 double Delta = 2.*NrgLim/(double)NTab; 00710 int i = 0; 00711 for(double Nrg=-NrgLim;Nrg<NrgLim;Nrg+=Delta,i++){ 00712 PTab[i] = Nrg; 00713 MTab[i] = exp(-pTemp()*Nrg); 00714 } 00715 VAR_ADD_TYPE(DynFlag,ALL_METR); 00716 VAR_ADD_TYPE(DynFlag,ALL_POT); 00717 } 00718 double Forces::Wei3(const double r, const double b){ 00719 if(r < 0.0001) return 0.; 00720 return (r < b) ? 15. / (2. * M_PI * CUBE(b)) * SQR(1. - r / b) : 0.; 00721 } 00722 double Forces::DerWei3(const double r, const double b){ 00723 if(r < 0.0001) return 0.; 00724 return (r < b) ? 15. / (M_PI * SQR(SQR(b))) * (r / b - 1.) : 0.; 00725 } 00726 double Forces::Wei2(const double r, const double a){ 00727 if(r < 0.0001) return 0.; 00728 const double b = 1.; 00729 double Ai = .5 * 15. / M_PI / (CUBE(a) + CUBE(a + b) + CUBE(b)); 00730 return (r < a) ? Ai : (Ai / CUBE(a - b)) * 00731 ((((-2. * r) + 3. * (a + b)) * r - 6. * a * b) * r + 00732 3. * a * b * b - b * b * b); 00733 } 00734 double Forces::DerWei2(const double r, const double a){ 00735 if(r < 0.0001) return 0.; 00736 const double b = 1.; 00737 double Ai = 15. / (M_PI * (((((4. * a) + 6.) * a) + 6.) * a + 4.)); 00738 return (r > a && r < b) ? (6. * Ai / CUBE(a - b) * (-r * r + (a + b) * 00739 r - a * b)) : 0.; 00740 }