Allink
v0.1
|
00001 #include "../include/Matematica.h" 00002 00003 double Matematica::ContactAngle(double x){ 00004 double Ris; 00005 //Ris = PreFact*pow(3./(2.+3.*sin(x)-CUB(sin(x)) ), 4./3. )*QUAD(QUAD(cos(x))) - Ypsilon; 00006 Ris = PreFact*pow(1-cos(x), -4./3. )*pow(sin(x),2.) - Ypsilon; 00007 return Ris; 00008 } 00009 double Matematica::fProva(double x){ 00010 double Ris; 00011 //Ris = pow(x,5.)/((exp(x)-1)*(1-exp(-x))); 00012 // Ris = pow(x,5.)*exp(x)/QUAD(exp(x)-1); 00013 // Ris = 1.*pow(x-150,4.)-1.*pow(x-150,5.)+x; 00014 // Ris = pow(x-150,2.)+x-150; 00015 Ris = 1./(13.9332529115775*x*x - 4.*13.9332529115775*0.13710248135043*x + 7.86306085419497) + .5/(-0.0805855688278211*x + 10.6925178203198); 00016 //Ris = 1./(12.5342*x*x) + .5/(-0.207807999999993*x + 17.4283); 00017 return Ris; 00018 } 00019 double Matematica::F(double T,double TD){ 00020 return pow((T/TD),5.)*Integrazione(.00001,TD/T); 00021 } 00022 double Matematica::Integrazione(double a,double b){ 00023 double Delta = (b-a)/(double)NPassi; 00024 double Risp = 0.; 00025 for(int i=0;a+((double)i)*Delta<b;i+=3){//+3 se si sovrappongono 00026 Risp += 3.*3.*Delta*( Evalx(a+Delta*i)+3.*Evalx(a+Delta*(i+1))+3.*Evalx(a+Delta*(i+2))+Evalx(a+Delta*(i+3)) )/8.; 00027 } 00028 return Risp; 00029 } 00030 double Matematica::Integrazione(double *st,double *sw,int NMass){ 00031 double NMassInv = 1/((double)NMass); 00032 sw[0] = st[0]; 00033 for(int i=1;i<NMass;i++){ 00034 sw[i] = st[i] + sw[i-1]; 00035 } 00036 return sw[NMass-1]; 00037 } 00038 double Matematica::Df(double x,double Delta){ 00039 return ( Evalx(x+Delta)-Evalx(x) )/Delta; 00040 } 00041 void Matematica::Derivata(double *st,double *sw,int NMass){ 00042 for(int i=0;i<NMass-1;i++){ 00043 sw[i] = (st[i+1]-st[i])/2.; 00044 } 00045 } 00046 void Matematica::DerO4(double *st,double *sw,int NMass){ 00047 sw[0] = 0.; 00048 sw[NMass-1] = 0.; 00049 for(int i=1;i<NMass-1;i++){ 00050 if(i<2) 00051 sw[i] = (st[i+1] - st[i-1])/2.; 00052 else if (i < NMass - 2) 00053 sw[i] = st[i-2] - 8.*st[i-1] + 8.*st[i+1] - st[i+2]; 00054 else if (i < NMass - 1) 00055 sw[i] = (st[i+1] - st[i-1])/2.; 00056 } 00057 } 00058 int Matematica::Zeri(double a,double b,double *Radici,int NRadici){ 00059 double Uno;double Due;double Delta; 00060 int rad=0; 00061 RADICE Rad; 00062 if( a > b ){ 00063 Uno = b ; Due = a; 00064 } 00065 else{ 00066 Uno = a ; Due = b; 00067 } 00068 Delta = (Due - Uno)/2.; 00069 // for(int p=0;p<4;p++){ 00070 for(int i=0;i<NRadici*2;i++){ 00071 Delta = (Due - Uno)/(2*NRadici); 00072 Rad = RegulaFalsi(Uno+i*Delta,Due-(2*NRadici-i-1)*Delta); 00073 //printf("%d %d) %g|%g %g|%g %g|%g\n",NRadici,i,Uno+i*Delta,Rad.iLim,Due-(2*NRadici-i-1)*Delta,Rad.sLim,Delta,Rad.sLim-Rad.iLim); 00074 if(Rad.IfRis == 1){ 00075 printf("Found a root in %lf\n",Rad.Zero); 00076 Radici[rad] = Rad.Zero; 00077 rad++; 00078 } 00079 } 00080 // } 00081 return rad; 00082 } 00083 double Matematica::Estremo(double a,double b){ 00084 double Uno;double Due;double Tre; 00085 // a<b : Delta=(b-a)/NPassi ? Delta=(a-b)/NPassi; 00086 double Delta=0.; 00087 int NLim = 1000; 00088 Delta=(b-a)/(double)NLim; 00089 Uno=a;Due=b;Tre=0.; 00090 for(int i=0;i<NLim;i++){ 00091 if( ASS((Evalx(Tre)-0.)) < PrecMinimo){ 00092 break; 00093 } 00094 Tre = Due - (Due - Uno)/(Df(Due,Delta)-Df(Uno,Delta))*Df(Due,Delta); 00095 Due = Tre; 00096 Uno = Due; 00097 } 00098 return Tre; 00099 } 00100 RADICE Matematica::RegulaFalsi(double a,double b){ 00101 RADICE Rad; 00102 double Uno=a;double Due=b;double Tre=0.; 00103 double dIncr = 100.; 00104 double Delta = (b-a)/dIncr; 00105 Uno=a;Due=b;Tre=0.; 00106 FILE *CONTROLLA; 00107 CONTROLLA = fopen("RegulaFalsi.dat","w"); 00108 for(int i=0;i<NPassi;i++){ 00109 if( ASS(Evalx(Tre)) < PrecMinimo){ 00110 break; 00111 } 00112 else if( ASS(Evalx(Due)) < PrecMinimo){ 00113 Tre = Due; 00114 break; 00115 } 00116 else if( ASS(Evalx(Uno)) < PrecMinimo){ 00117 Tre = Uno; 00118 break; 00119 } 00120 if( Evalx(Due) < 0. && Evalx(Uno) > 0.){ 00121 if( Evalx(Due) < 0. && Evalx(Uno + Delta) > 0.){ 00122 Uno += Delta; 00123 } 00124 if(Evalx(Due - Delta) < 0. && Evalx(Uno) > 0.){ 00125 Due -= Delta; 00126 } 00127 else { 00128 dIncr *= 10.; 00129 } 00130 } 00131 else if( Evalx(Due) > 0. && Evalx(Uno) < 0.){ 00132 if( Evalx(Due) > 0. && Evalx(Uno+Delta) < 0.){ 00133 Uno += Delta; 00134 } 00135 if(Evalx(Due - Delta) > 0. && Evalx(Uno) < 0.){ 00136 Due -= Delta; 00137 } 00138 else { 00139 dIncr *= 10.; 00140 } 00141 } 00142 else{ 00143 Uno += (b-a) / dIncr; 00144 } 00145 if(Uno > Due){ 00146 Uno = a; 00147 dIncr *= 10.; 00148 } 00149 Delta = (b-a)/dIncr; 00150 Tre = (Due + Uno)/2.; 00151 //printf("%d) Uno %g|%g Due %g|%g Evalx(Tre) %g|%g Delta %g Incr %g\n",i,Uno,Evalx(Uno),Due,Evalx(Due),Tre,Evalx(Tre),Delta,dIncr); 00152 //fprintf(CONTROLLA,"%lf %lf\n",Tre,Evalx(Tre)); 00153 } 00154 if( !(ASS((Evalx(Tre)-0.)) < PrecMinimo)){ 00155 Rad.IfRis = 0; 00156 } 00157 else 00158 Rad.IfRis = 1; 00159 Rad.Zero = Tre; 00160 Rad.iLim = Uno; 00161 Rad.sLim = Due; 00162 fclose(CONTROLLA); 00163 return Rad; 00164 } 00165 RADICE Matematica::Newton(double a){ 00166 RADICE Rad; 00167 double Uno=a,Due =0.,Tre=0.; 00168 double m=0.,q=0.; 00169 FILE *CONTROLLA; 00170 CONTROLLA = fopen("Newton.dat","w"); 00171 for(int i=0;i<NPassi;i++){ 00172 if( ASS((Evalx(Tre))) < PrecMinimo){ 00173 break; 00174 } 00175 Due = Uno + 1e-5; 00176 m = (Evalx(Due) - Evalx(Uno))/(Due - Uno); 00177 q = Evalx(Uno) - m*Uno; 00178 Tre = -q/m; 00179 printf("%d) %lf %lf %lf\n",i,Uno,Due,Evalx(Tre)); 00180 fprintf(CONTROLLA,"%lf %lf\n",Tre,Evalx(Tre)); 00181 Uno = Tre; 00182 } 00183 if( !(ASS((Evalx(Tre)-0.)) < PrecMinimo)){ 00184 printf("Calculation failed\n"); 00185 Rad.IfRis = 0; 00186 } 00187 else 00188 Rad.IfRis = 1; 00189 Rad.Zero = Tre; 00190 Rad.iLim = Uno; 00191 Rad.sLim = Due; 00192 fclose(CONTROLLA); 00193 return Rad; 00194 } 00195 double Matematica::Gauss(double Media,double Scarto,double x){ 00196 return 1./(Scarto*sqrt(DUE_PI))*exp(- .5*SQR((x-Media)/Scarto) ); 00197 } 00198 double Matematica::IntegrazioneGauss(double a,double b,double Scarto){ 00199 double Delta = (b-a)/(double)NPassi; 00200 double Risp = 0.; 00201 for(int i=0;a+((double)i)*Delta<b;i+=3){//+3 se si sovrappongono 00202 Risp += 3*Delta*( Gauss(0.,Scarto,a+Delta*i)+3*Gauss(0.,Scarto,a+Delta*(i+1))+3*Gauss(0.,Scarto,a+Delta*(i+2))+Gauss(0.,Scarto,a+Delta*(i+3)) )/8; 00203 } 00204 return Risp; 00205 } 00206 void Matematica::SquareGradient(double *st,double *sw,int NMass){ 00207 DerO4(st,sw,NMass); 00208 } 00209 void Matematica::NormalizeVect(double *st,int NMass){ 00210 double Norm = 0.; 00211 for(int n=0;n<NMass;n++){ 00212 Norm += SQR(st[n]); 00213 } 00214 Norm = 1./sqrt(Norm); 00215 for(int n=0;n<NMass;n++){ 00216 st[n] = st[n]*Norm; 00217 } 00218 } 00219 double Matematica::Norm(double *st,int NMass){ 00220 double Norm = 0.; 00221 for(int n=0;n<NMass;n++){ 00222 Norm += SQR(st[n]); 00223 } 00224 return sqrt(Norm); 00225 } 00226 void Matematica::Modulo(double *st,double *sw,int NMass){ 00227 for(int n=0;n<NMass;n++){ 00228 sw[n] = POS(st[n]); 00229 } 00230 } 00231 double Matematica::Fattoriale(int n){ 00232 if(n < 0) { printf("Il fattoriale di numeri negativi non ha senso\n"); return 0;} 00233 if( n == 0 ) return 1; 00234 int Ris=1; 00235 for(int i=n;i>0;i--){ 00236 // printf("Fatt %d\n",i); 00237 Ris *= i; 00238 } 00239 return (double) Ris; 00240 } 00241 double Matematica::Gamma(int n){ 00242 return Fattoriale(n-1); 00243 } 00244 double Matematica::Elevato(double x,int Volte){ 00245 double Risp=1.; 00246 double Moltx = Volte >= 0 ? x : 1./x; 00247 for(int v=0;v<Volte;v++) 00248 Risp *= Moltx; 00249 return Risp; 00250 } 00251 double Matematica::Bessel(double Val,int Ord){ 00252 int NOrd = POS(Ord); 00253 int NMax = 10; 00254 double Risp=0.; 00255 for(int n=0;n<NMax;n++){ 00256 // printf(" %d\n",n); 00257 Risp += Elevato(-1.,n)/(Fattoriale(n)*Gamma(NOrd+n+1))*Elevato(.5*Val,2*n+NOrd); 00258 } 00259 return Ord>=0 ? Risp : Elevato(-1.,Ord)*Risp; 00260 } 00261 double Matematica::Neumann(double Val,int Ord){ 00262 double Angolo = Ord*.5*DUE_PI+.0001; 00263 return Bessel(Val,Ord)*(cos(Angolo) - Elevato(-1.,Ord))/sin(Angolo); 00264 } 00265 double Matematica::QuasiBessel(double Val,int Ord){ 00266 if( Val > (double)Ord +1.) 00267 return sqrt((2./(PI*Val))) *cos( Val- (2.*Ord+1.)*PI*.25); 00268 else 00269 return Elevato(.5*Val,Ord)/(Fattoriale(Ord)); 00270 } 00271 double Matematica::QuasiNeumann(double Val,int Ord){ 00272 if(Ord == 0) 00273 return 2./PI*log(Val); 00274 if(Val > (double) Ord+1.) 00275 return sqrt(2./(PI*Val))*sin(Val-(2.*Ord+1.)*PI*.25); 00276 else 00277 return Elevato(2,Ord)*Fattoriale(Ord-1)/PI*Elevato(Val,-Ord); 00278 } 00279 double Matematica::Segno(int n){ 00280 return (n%2)==1 ? -1. : 1.; 00281 } 00282 double Matematica::WeightFunction(double x,double a){ 00283 double Risp=2.*x*x*x - 3.*(a+1.)*x*x-3.*a*a+1.; 00284 Risp /= CUB((1.-a)); 00285 return Risp; 00286 } 00287 double Matematica::WeightFunction2(double x,double a){ 00288 double Risp= -a*x*x + 1. + 4./3.*PI*a; 00289 Risp /= CUB((1.-a)); 00290 return Risp; 00291 } 00292 double Matematica::LJHamaker(double Rad,double RadNp,double Theta){ 00293 //return 1./CUB(Rad-RadNp); 00294 double Num = 2.*DUE_PI*QUAD(RadNp)*sin(Theta); 00295 double Den = QUAD(RadNp) + QUAD(Rad+RadNp) - 2.*(Rad+RadNp)*RadNp*cos(Theta); 00296 return Num/CUB(Den);// - Num/CUB(CUB(Den)); 00297 } 00298 double Matematica::LJ39(double r,double r_np){ 00299 return pow(1./(r-r_np),9.) - pow(1./(r-r_np),3.); 00300 } 00301 double Matematica::LJHamaker(double Rad,double RadNp){ 00302 double ThetaMax = PI; 00303 double ThetaMin = 0.; 00304 double ThetaDelta = (ThetaMax-ThetaMin)/100.; 00305 double Risp = 0.; 00306 for(double Theta = ThetaMin;Theta<ThetaMax;Theta+=ThetaDelta){ 00307 Risp += ThetaDelta*.5*(LJHamaker(Rad,RadNp,Theta) + LJHamaker(Rad,RadNp,Theta+ThetaDelta) ); 00308 } 00309 return Risp; 00310 } 00311 double Matematica::LJHamakerCum(double Rad,double RadNpMin,double RadNpMax){ 00312 double RadNpDelta = (RadNpMax-RadNpMin)/100.; 00313 double Risp = 0.; 00314 for(double RadNp = RadNpMin;RadNp<RadNpMax;RadNp+=RadNpDelta){ 00315 //Risp += RadNpDelta*LJHamaker(Rad,RadNp+RadNpDelta*0.5); 00316 Risp += RadNpDelta*.5*(LJHamaker(Rad,RadNp) + LJHamaker(Rad,RadNp+RadNpDelta) ); 00317 //Risp += 3.*RadNpDelta*(LJHamaker(Rad,RadNp) + 3.*LJHamaker(Rad,RadNp+RadNpDelta) + 3.*LJHamaker(Rad,RadNp+2.*RadNpDelta) + 3.*LJHamaker(Rad,RadNp+3.*RadNpDelta) )/8.; 00318 } 00319 return Risp; 00320 } 00321 double Potenziale(double Dist, double RadNp){ 00322 double Rad = Dist + RadNp; 00323 double Pre1 = 2./(12.*Rad); 00324 double Post1 = RadNp / CUB(Rad+RadNp) + RadNp/CUB(Rad-RadNp); 00325 double Pre2 = 1./(12.*Rad); 00326 double Post2 = 1./QUAD(Rad+RadNp) - 1./QUAD(Rad+RadNp); 00327 return PI*(Pre1*Post1 + Pre2*Post2); 00328 } 00329 double Potenziale2(double Dist, double RadNp){ 00330 double Rad = Dist + RadNp; 00331 double Pre1 = -( QUAD(RadNp) - QUAD(Rad) )/(4.*Rad); 00332 double Post1 = 1./QUAD(QUAD(Rad+RadNp)) - 1./QUAD(QUAD(Rad-RadNp)); 00333 double Pre2 = -2./(3.); 00334 double Post2 = 1./CUB(Rad+RadNp) - 1./CUB(Rad+RadNp); 00335 double Pre3 = 1./(2.*Rad); 00336 double Post3 = 1./QUAD(Rad+RadNp) - 1./QUAD(Rad+RadNp); 00337 return PI*(Pre1*Post1 + Pre2*Post2 + Pre3*Post3); 00338 } 00339 void Matematica::IntegraA3(){ 00340 double RadNpMin = 0.; 00341 double RadNpMax = .001; 00342 double RadNpDelta = (RadNpMax - RadNpMin)/20.; 00343 double RadMin = 0.1; 00344 double RadMax = 3.; 00345 double RadDelta = (RadMax-RadMin)/100.; 00346 char *FileName = (char *)calloc(60,sizeof(char)); 00347 double RadNp = RadNpMax; 00348 //for(double RadNp = RadNpMin;RadNp <= RadNpMax;RadNp += RadNpDelta) 00349 { 00350 sprintf(FileName,"Potential%0.2f.dat",RadNp); 00351 FILE *POT = fopen(FileName,"w"); 00352 for(double Rad = RadMin;Rad < RadMax;Rad += RadDelta){ 00353 fprintf(POT,"%lf %g %g %g \n",Rad,LJHamaker(Rad,RadNp),LJHamakerCum(Rad,RadNpMin,RadNp),Potenziale(Rad,RadNp) ); 00354 } 00355 fclose(POT); 00356 } 00357 }