Hinamarth

Cannon shot!

Oct 26th, 2012
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.28 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define g 9.81
  6. #define EARTH 0
  7. #define TOWER 100
  8. #define POSITIVE 9
  9. #define NEVER_MIND 10
  10. #define YES 1
  11. #define NO 2
  12.  
  13. struct pos_vel{
  14.   double x;
  15.   double y;
  16.   double v;
  17. } xyAndv0={0,0,20}, xyAndv;
  18.  
  19. struct velocities{
  20.   double x;
  21.   double y;
  22. } velocity;
  23.  
  24. void energy(FILE*, struct pos_vel xyAndv, struct pos_vel xyAndv0, struct velocities velocity, int);
  25.  
  26. void heavy_motion( struct pos_vel, struct pos_vel, struct velocities, FILE*, FILE*, int, int, double, int);
  27.  
  28. void relative_error( double, double, struct pos_vel, struct pos_vel, struct velocities, double, double, int);
  29.  
  30. struct pos_vel only_motion_rk4( double, double, struct pos_vel, struct pos_vel, struct velocities, int, double, FILE*, int, int );
  31.  
  32. void gnuplot_command( FILE* );
  33.  
  34. void energy(FILE *fp, struct pos_vel xyAndv, struct pos_vel xyAndv0, struct velocities velocity, int choice ){
  35.   double dt=1000;
  36.   int i;
  37.   for(i=0; i<7; i++){
  38.     xyAndv=only_motion_rk4( dt, 45., xyAndv0, xyAndv, velocity, 0, 0, NULL, NO, choice );
  39.     fprintf(fp,"%lf          %lf\n", dt, ((1./2.*pow(xyAndv.v,2.)+g*xyAndv.y)-(1./2.*pow(xyAndv0.v,2.)+g*xyAndv0.y))/(1./2.*pow(xyAndv0.v,2.)+g*xyAndv0.y) );
  40.     dt*=0.1;
  41.   }
  42. }
  43.  
  44. struct pos_vel only_motion_rk4( double dt, double theta, struct pos_vel xyAndv0, struct pos_vel xyAndv, struct velocities velocity, int h, double A, FILE*fp, int answer, int answer2){
  45.   int i;
  46.   double x, y, x1, x2, y1, y2, vx1, vx2, vy1, vy2, rad, yn;
  47.   struct pos_vel xyvSUM, s1, s2, s3, s4;
  48.   struct velocities vxvySUM, v1, v2, v3, v4;
  49.   rad=(theta*M_PI)/(180.);
  50.   xyAndv0.y=h;
  51.   yn=xyAndv0.y;
  52.   xyAndv=xyAndv0;
  53.   velocity.x=xyAndv.v*cos(rad);
  54.   velocity.y=xyAndv.v*sin(rad);
  55.   for(i=0; xyAndv.y>=0 ; i++){
  56.     if(answer==YES){
  57.       fprintf(fp, "%lf         %lf         %lf        %lf\n", i*dt, xyAndv.x, yn, 1./2.*pow(xyAndv.v,2.)+g*yn );
  58.     }
  59.     x=xyAndv.x;
  60.     y=xyAndv.y;
  61.     s1.x=velocity.x*dt;
  62.     s1.y=velocity.y*dt;
  63.     v1.x=(-A*xyAndv.v*velocity.x)*dt;
  64.     v1.y=(-g-A*xyAndv.v*velocity.y)*dt;
  65.     xyvSUM.x=xyAndv.x+0.5*s1.x;
  66.     xyvSUM.y=xyAndv.y+0.5*s1.y;
  67.     vxvySUM.x=velocity.x+0.5*v1.x;
  68.     vxvySUM.y=velocity.y+0.5*v1.y;
  69.     xyvSUM.v=sqrt(pow(vxvySUM.x,2.)+pow(vxvySUM.y,2.));
  70.     s2.x=vxvySUM.x*dt;
  71.     s2.y=vxvySUM.y*dt;
  72.     v2.x=(-A*xyvSUM.v*vxvySUM.x)*dt;
  73.     v2.y=(-g-A*xyvSUM.v*vxvySUM.y)*dt;
  74.     xyvSUM.x=xyAndv.x+0.5*s2.x;
  75.     xyvSUM.y=xyAndv.y+0.5*s2.y;
  76.     vxvySUM.x=velocity.x+0.5*v2.x;
  77.     vxvySUM.y=velocity.y+0.5*v2.y;
  78.     s3.x=vxvySUM.x*dt;
  79.     s3.y=vxvySUM.y*dt;
  80.     v3.x=(-A*xyvSUM.v*vxvySUM.x)*dt;
  81.     v3.y=(-g-A*xyvSUM.v*vxvySUM.y)*dt;
  82.     xyvSUM.x=xyAndv.x+s3.x;
  83.     xyvSUM.y=xyAndv.y+s3.y;
  84.     vxvySUM.x=velocity.x+v3.x;
  85.     vxvySUM.y=velocity.y+v3.y;
  86.     s4.x=vxvySUM.x*dt;
  87.     s4.y=vxvySUM.y*dt;
  88.     v4.x=(-A*xyvSUM.v*vxvySUM.x)*dt;
  89.     v4.y=(-g-A*xyvSUM.v*vxvySUM.y)*dt;
  90.     xyAndv.x+=1./6.*(s1.x+2.*s2.x+2.*s3.x+s4.x);
  91.     xyAndv.y+=1./6.*(s1.y+2.*s2.y+2.*s3.y+s4.y);
  92.     velocity.x+=1./6.*(v1.x+2.*v2.x+2*v3.x+v4.x);
  93.     velocity.y+=1./6.*(v1.y+2.*v2.y+2*v3.y+v4.y);
  94.     xyAndv.v=sqrt(pow(velocity.x,2.)+pow(velocity.y,2.));
  95.     yn=xyAndv.y;
  96.     if(xyAndv.y<0 && answer2==YES){
  97.       xyAndv.x=x+((xyAndv.x-x)*y)/(y-xyAndv.y);
  98.       yn=0;
  99.     }
  100.   }
  101.   if(answer==YES){
  102.     fprintf(fp, "%lf       %lf        %lf         %lf\n", i*dt, xyAndv.x, yn, 1./2.*pow(xyAndv.v,2.)+g*yn );
  103.   };
  104.   xyAndv.y=yn;
  105.   return xyAndv;
  106. }
  107.  
  108. void relative_error( double dt, double distance_max, struct pos_vel xyAndv0, struct pos_vel xyAndv, struct velocities velocity, double theta_max, double A, int h){
  109.   int i;
  110.   double max_distance, d1, d2, d3, precisione;
  111.   for( dt=1; fabs((max_distance-d1)/((max_distance+d1)/2))>pow(10,-4); dt*=0.5 ){
  112.     xyAndv=only_motion_rk4(2.*dt,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  113.     d1=xyAndv.x;
  114.     xyAndv=only_motion_rk4(dt,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  115.     max_distance=xyAndv.x;
  116.     while(max_distance+d1==0){
  117.       dt*=0.5;
  118.       xyAndv=only_motion_rk4(2.*dt,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  119.       d1=xyAndv.x;
  120.       xyAndv=only_motion_rk4(dt,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  121.       max_distance=xyAndv.x;
  122.     }
  123.   }
  124.   xyAndv=only_motion_rk4(2.*0.001,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  125.   d2=xyAndv.x;
  126.   xyAndv=only_motion_rk4(0.001,theta_max, xyAndv0, xyAndv, velocity, h, A, NULL, NO, YES);
  127.   d3=xyAndv.x;
  128.   precisione=fabs(d2-d3)*100.;
  129.   printf("Fissati h = %d m e A = %lf 1/m e facendo variare il dt, l'errore relativo commesso sulla gittata e' : %lf, per un dt di %lf s.\n La precisione che si ha se ha un dt = 0.001 e' del %lf percento. \n\n", h, A, fabs((max_distance-d1)/((max_distance+d1)/2)), dt, precisione);
  130. }
  131.  
  132. void heavy_motion( struct pos_vel xyAndv0, struct pos_vel xyAndv, struct velocities velocity, FILE *fp, FILE *mp, int h, int ang, double A, int answer2){
  133.   int i;
  134.   double T, x, y, xm, vxp, vyp, rad, yn, distance_max=0, theta_max, theta, dt=0.001;
  135.   for(theta=ang; theta<91; theta++){        
  136.     xyAndv=only_motion_rk4(dt,theta, xyAndv0, xyAndv, velocity, h, A, NULL, NO, answer2);
  137.     if(mp!=NULL){
  138.       fprintf(mp, "%lf       %lf\n", theta, xyAndv.x);
  139.     }
  140.     if(distance_max<xyAndv.x){
  141.       distance_max=xyAndv.x;
  142.       theta_max=theta;
  143.     }
  144.   }
  145.   theta=theta_max;
  146.   for(i=0; i<800; i++){
  147.     xyAndv=only_motion_rk4(dt,(theta-1+i*0.0025), xyAndv0, xyAndv, velocity, h, A, NULL, NO, answer2);
  148.     if(distance_max<xyAndv.x){
  149.       distance_max=xyAndv.x;
  150.       theta_max=theta-1+i*0.0025;
  151.     }
  152.   }
  153.   if(answer2==YES){
  154.     printf("Dati iniziali: h = %d - A = %lf.\nDati finali: Rmax = %lf - Theta = %lf°. \n", h, A, distance_max, theta_max);
  155.     relative_error(dt,distance_max,xyAndv0,xyAndv,velocity,theta_max,A,h);
  156.   }
  157.   xyAndv=only_motion_rk4(dt,theta_max, xyAndv0, xyAndv, velocity, h, A, fp, YES, answer2);
  158. }
  159.  
  160. void gnuplot_command( FILE *fp ){
  161.   fprintf(fp,"set term pos col \n");
  162.   fprintf(fp,"set out 'grafici.ps' \n");
  163.   fprintf(fp,"plot 'moto_grave0.dat' u 2:3 \n");
  164.   fprintf(fp,"plot 'moto_grave0.dat' u 1:4 \n");
  165.   fprintf(fp,"plot 'moto_grave100.dat' u 2:3 \n");
  166.   fprintf(fp,"plot 'moto_grave100.dat' u 1:4 \n");
  167.   fprintf(fp,"plot 'moto_grave_A01.dat' u 2:3 \n");
  168.   fprintf(fp,"plot 'moto_grave_A01.dat' u 1:4 \n");
  169.   fprintf(fp,"plot 'moto_grave_A1.dat' u 2:3 \n");
  170.   fprintf(fp,"plot 'moto_grave_A1.dat' u 1:4 \n");
  171.   fprintf(fp,"plot 'errore_energia.dat' \n");
  172.   fprintf(fp,"plot 'errore_energia1.dat' \n");
  173.   fprintf(fp,"set terminal x11");
  174.  }
  175.  
  176. main(){
  177.   int i;
  178.   FILE *hm, *hmh, *fm, *fmA, *inter, *command, *ene, *ene1, *dRdT;
  179.   if((hm=fopen("moto_grave0.dat", "w"))==NULL){
  180.     printf("Errore nell'apertura file moto_grave0.dat.\n");
  181.     exit(EXIT_FAILURE);
  182.   }
  183.   if((hmh=fopen("moto_grave100.dat", "w"))==NULL){
  184.     printf("Errore nell'apertura file moto_grave100.dat.\n");
  185.     exit(EXIT_FAILURE);
  186.   }
  187.   if((fm=fopen("moto_grave_A01.dat", "w"))==NULL){
  188.     printf("Errore nell'apertura file moto_grave_A01.dat.\n");
  189.     exit(EXIT_FAILURE);
  190.   }
  191.   if((fmA=fopen("moto_grave_A1.dat", "w"))==NULL){
  192.     printf("Errore nell'apertura file moto_grave_A1.dat.\n");
  193.     exit(EXIT_FAILURE);
  194.   }
  195.   if((inter=fopen("interpolazione.dat", "w"))==NULL){
  196.     printf("Errore nell'apertura file interpolazione.dat.\n");
  197.     exit(EXIT_FAILURE);
  198.   }
  199.   if((command=fopen("myCommand.dat", "w"))==NULL){
  200.     printf("Errore nell'apertura file myCommnd.dat.\n");
  201.     exit(EXIT_FAILURE);
  202.   }
  203.  if((ene=fopen("errore_energia.dat", "w"))==NULL){
  204.     printf("Errore nell'apertura file errore_energia.dat.\n");
  205.     exit(EXIT_FAILURE);
  206.   }
  207.  if((ene1=fopen("errore_energia1.dat", "w"))==NULL){
  208.     printf("Errore nell'apertura file errore_energia1.dat.\n");
  209.     exit(EXIT_FAILURE);
  210.   }
  211.  if((dRdT=fopen("variazione_R_in_theta.dat", "w"))==NULL){
  212.     printf("Errore nell'apertura file variazione_R_in_theta.dat.\n");
  213.     exit(EXIT_FAILURE);
  214.   }
  215.   fprintf(hm, "#Tempo         Ascissa         Ordinata         Energia\n");
  216.   fprintf(hmh, "#Tempo         Ascissa         Ordinata          Energia\n");
  217.   fprintf(fm, "#Tempo         Ascissa         Ordinata         Energia\n");
  218.   fprintf(fmA, "#Tempo         Ascissa         Ordinata          Energia\n");
  219.   fprintf(inter, "#Tempo         Ascissa         Ordinata          Energia\n");
  220.   fprintf(ene, "#dt         DE/E0 \n");
  221.   fprintf(ene1, "#dt         DE/E0 \n");
  222.   fprintf(dRdT, "#theta         R(theta)\n");
  223.   printf("Il programma simula il moto bidimensionale di un grave, sparato da un cannone con velocita' iniziale v0=20 m/s.\n");
  224.   printf("\n");
  225.   heavy_motion(xyAndv0, xyAndv, velocity, hm, NULL, EARTH, 0, 0.,YES);
  226.   heavy_motion(xyAndv0, xyAndv, velocity, inter, NULL, EARTH, 0, 0.,NO);
  227.   heavy_motion(xyAndv0, xyAndv, velocity, hmh, NULL, TOWER, -90, 0.,YES);
  228.   heavy_motion(xyAndv0, xyAndv, velocity, fm, NULL, EARTH, 0, 0.1,YES);
  229.   heavy_motion(xyAndv0, xyAndv, velocity, fmA, dRdT, EARTH, 0, 1.,YES);
  230.   energy(ene, xyAndv, xyAndv0, velocity, NO);
  231.   energy(ene1, xyAndv, xyAndv0, velocity, YES);
  232.   gnuplot_command(command);
  233.   fclose(hm);
  234.   fclose(hmh);
  235.   fclose(fm);
  236.   fclose(fmA);
  237.   fclose(inter);
  238.   fclose(command);
  239.   fclose(ene);
  240.   fclose(ene1);
  241.   i=system("gnuplot <myCommand.dat");
  242.   if(i!=0){
  243.     printf("Errore di utilizzo di gnuplot.\n");
  244.   }
  245. }
Advertisement
Add Comment
Please, Sign In to add comment