Hinamarth

Integration Methods (Euler Cromer,Verlet,Runge-Kutta, etc.)

Oct 11th, 2012
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define EULER 1
  6. #define EULER_CROMER 2
  7. #define MID_POINT 3
  8. #define HALF_PACE 4
  9. #define VERLET 5
  10. #define AUTO_VERLET 6
  11. #define PRE_COR 7
  12. #define RUNGE_KUTTA 8
  13. #define POSITIVE 9
  14. #define NEVER_MIND 10
  15.  
  16. struct pos_vel{
  17.   double x;
  18.   double v;
  19. } xAndv0, xAndv;
  20.  
  21. double readdouble( double, int );
  22.  
  23. double energia( double, double, double, struct pos_vel, struct pos_vel, FILE* );
  24.  
  25. void eulero( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  26.  
  27. void eulero_cromer( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  28.  
  29. void punto_centrale( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  30.  
  31. void mezzo_passo( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  32.  
  33. void verlet( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  34.  
  35. void verlet_auto( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  36.  
  37. void pred_corr( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  38.  
  39. void runge_kutta( double, double, double, double, struct pos_vel, struct pos_vel, FILE*, FILE* );
  40.  
  41. double readdouble( double data, int pos ){
  42.   scanf("%lf", &data);
  43.   if( pos == POSITIVE ){
  44.     while( data<=0 ){
  45.       printf("Il valore inserito è errato! Reinseriscilo :\n");
  46.       scanf("%lf", &data);
  47.     }
  48.   }
  49.   printf("Il valore appena inserito è %lf. \n \n", data );
  50.   return data;
  51. }
  52.  
  53. double energia( double k, double m, double dt, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e){
  54.   fprintf( e, "%lf                     %lf \n", dt, ((0.5*m*pow(xAndv.v,2.)+0.5*k*pow(xAndv.x,2.))-(0.5*m*pow(xAndv0.v,2.)+0.5*k*pow(xAndv0.x,2.)))/(0.5*m*pow(xAndv0.v,2.)+0.5*k*pow(xAndv0.x,2.)) );
  55.   dt+=0.01;
  56.   return dt;
  57. }
  58.  
  59. void eulero( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  60.   int j;
  61.   double i, v;
  62.   for( j=0; j<7; j++ ){
  63.     xAndv=xAndv0;
  64.     for(i=0; i<T; i+=dt){
  65.       v=xAndv.v;
  66.       xAndv.v-=(k/m)*xAndv.x*dt;
  67.       xAndv.x+=v*dt;
  68.       if(j==0){
  69.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  70.       }
  71.     }
  72.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  73.   }
  74. }
  75.  
  76. void eulero_cromer( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  77.   int j;
  78.   double i;
  79.   for( j=0; j<7; j++ ){
  80.     xAndv=xAndv0;
  81.     for(i=0; i<T; i+=dt){
  82.       xAndv.v-=(k/m)*xAndv.x*dt;
  83.       xAndv.x+=xAndv.v*dt;
  84.       if(j==0){
  85.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  86.       }
  87.     }
  88.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  89.   }
  90. }
  91.  
  92. void punto_centrale( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  93.   int j;
  94.   double i;
  95.   for( j=0; j<7; j++ ){
  96.     xAndv=xAndv0;
  97.     for(i=0; i<T; i+=dt){
  98.       xAndv.v-=(k/m)*xAndv.x*dt;
  99.       xAndv.x+=xAndv.v*dt-0.5*(k/m)*xAndv.x*pow(dt,2.);
  100.       if(j==0){
  101.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  102.       }
  103.     }
  104.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  105.   }
  106. }
  107.  
  108. void mezzo_passo( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  109.   int j;
  110.   double i;
  111.   for( j=0; j<7; j++ ){
  112.     xAndv.x=xAndv0.x;
  113.     xAndv.v=xAndv0.v-0.5*(k/m)*xAndv.x*dt;
  114.     for(i=0; i<T; i+=dt){
  115.       xAndv.v-=(k/m)*xAndv.x*dt;
  116.       xAndv.x+=xAndv.v*dt;
  117.       if(j==0){
  118.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  119.       }
  120.     }
  121.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  122.   }
  123. }
  124.  
  125. void verlet( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  126.   int j;
  127.   double i, x_1, x=0.;
  128.   for( j=0; j<7; j++ ){
  129.     x_1=xAndv0.x;
  130.     x=x_1+xAndv0.v*dt;
  131.     for(i=0; i<T; i+=dt){
  132.       xAndv.x=2.*x-x_1-(k/m)*x*pow(dt,2.);
  133.       xAndv.v=(xAndv.x-x_1)/(2*dt);
  134.       x_1=x;
  135.       x=xAndv.x;
  136.       if(j==0){
  137.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  138.       }
  139.     }
  140.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  141.   }
  142. }
  143.  
  144. void verlet_auto( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  145.   int j;
  146.   double i, x;
  147.   for( j=0; j<7; j++ ){
  148.     xAndv=xAndv0;
  149.     for(i=0; i<T; i+=dt){
  150.       x=xAndv.x+xAndv.v*dt-0.5*(k/m)*xAndv.x*pow(dt,2.);
  151.       xAndv.v+=0.5*(-(k/m)*xAndv.x - (k/m)*x)*dt;
  152.       xAndv.x=x;
  153.       if(j==0){
  154.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  155.       }
  156.     }
  157.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  158.   }
  159. }
  160.  
  161. void pred_corr( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  162.   int j;
  163.   double i, xp, x, x_1, vn;
  164.   for( j=0; j<7; j++ ){
  165.     x_1=xAndv0.x;
  166.     x=x_1+xAndv0.v*dt;
  167.     vn-=(k/m)*xAndv0.x*dt;
  168.     for(i=0; i<T; i+=dt){
  169.       xp=x_1+2*xAndv.v*dt;
  170.       xAndv.v=vn+((-(k/m)*xp-(k/m)*x)/2)*dt;
  171.       xAndv.x=x+((xAndv.v+vn)/2)*dt;
  172.       if(j==0){
  173.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  174.       }
  175.       x_1=x;
  176.       x=xAndv.x;
  177.       vn=xAndv.v;
  178.     }
  179.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  180.   }
  181. }
  182.  
  183. void runge_kutta( double k, double m, double dt, double T, struct pos_vel xAndv0, struct pos_vel xAndv, FILE *e, FILE *fp ){
  184.   int j;
  185.   double i, xp, vp;
  186.   for( j=0; j<7; j++ ){
  187.     xAndv=xAndv0;
  188.     for(i=0; i<T; i+=dt){
  189.       xp=xAndv.v*dt;
  190.       vp=-(k/m)*xAndv.x*dt;
  191.       xAndv.x+=(xAndv.v+0.5*vp)*dt;
  192.       xAndv.v+=-(k/m)*(xAndv.x+0.5*xp)*dt;
  193.       if(j==0){
  194.     fprintf(fp, "%lf       %lf       %lf\n", i, xAndv.x, xAndv.v);
  195.       }
  196.     }
  197.     dt=energia(k, m, dt, xAndv0, xAndv, e);
  198.   }
  199. }
  200.  
  201. main(){
  202.   double k, m, dt, T;
  203.   int i, algorithm;
  204.   FILE *e, *fp;
  205.   if((e=fopen("energia.dat", "w"))==NULL){
  206.     printf("Errore nell'apertura del file energia.dat.\n");
  207.     exit(EXIT_FAILURE);
  208.   }
  209.   if((fp=fopen("moto.dat", "w"))==NULL){
  210.     printf("Errore nell'apertura del file energia.dat.\n");
  211.     exit(EXIT_FAILURE);
  212.   }
  213.   fprintf(fp, "#Tempo         Spazio         Velocità\n");
  214.   fprintf(e, "#Distanza temporale         Energia\n");
  215.   printf("Il programma simula il moto di un oscillatore armonico facendo scegliere all'utente il metodo di integrazione più opportuno./n");
  216.   printf("Il problema sta nel studiare come si muove un corpo di massa m attaccato ad una molla di costante elastica k che, al tempo t=0s, ha posizione x0 e velocità v0.\n");
  217.   printf("Per iniziare quindi, ho bisogno che tu inserisca alcune quantità.\n");
  218.   printf("Inserisci un valore di k positivo.\nk = ");
  219.   k=readdouble( k, POSITIVE );
  220.   printf("Inserisci un valore di m positivo.\nm = ");
  221.   m=readdouble( m, POSITIVE );
  222.   printf("Inserisci la posizione inziale x0.\nx0 = ");
  223.   xAndv0.x=readdouble( xAndv0.x, NEVER_MIND );
  224.   printf("Inserisci la velocità iniziale v0.\nv0 = ");
  225.   xAndv0.v=readdouble( xAndv0.v, NEVER_MIND );
  226.   printf("Inserisci il passo dt positivo con cui vuoi andare avanti nel tempo.\ndt = ");
  227.   dt=readdouble( dt, POSITIVE );
  228.   printf("Inserisci il tempo T positivo in cui l'analisi si deve fermare.\nT = ");
  229.   T=readdouble( T, POSITIVE );
  230.   printf("Ora che hai immesso i dati, scegli l'algoritmo di integrazione, immettendo il numero che lo affianca.\n");
  231.   printf("1. Eulero\n2. Eulero-Cromer\n3. Metodo del punto centrale\n4. Metodo del mezzo passo\n5. Verlet\n6. Verlet autosufficiente\n7. Metodo di predizione e correzione\n8. Runge-Kutta\nLa tua scelta è : ");
  232.   scanf("%d", &algorithm );
  233.   while( algorithm<1 || algorithm>8 ){
  234.     printf("Il valore inserito è errato! Reinseriscilo :\n");
  235.     scanf("%d", &algorithm);
  236.   }
  237.   if( algorithm == EULER ){
  238.     eulero( k, m, dt, T, xAndv0, xAndv, e, fp );
  239.   }
  240.   if( algorithm == EULER_CROMER ){
  241.     eulero_cromer( k, m, dt, T, xAndv0, xAndv, e, fp );
  242.   }
  243.   if( algorithm == MID_POINT ){
  244.     punto_centrale( k, m, dt, T, xAndv0, xAndv, e, fp );
  245.   }
  246.   if( algorithm == HALF_PACE ){
  247.     mezzo_passo( k, m, dt, T, xAndv0, xAndv, e, fp );
  248.   }
  249.   if( algorithm == VERLET ){
  250.     verlet( k, m, dt, T, xAndv0, xAndv, e, fp );
  251.   }
  252.   if( algorithm == AUTO_VERLET ){
  253.     verlet_auto( k, m, dt, T, xAndv0, xAndv, e, fp );
  254.   }
  255.   if( algorithm == PRE_COR ){
  256.     pred_corr( k, m, dt, T, xAndv0, xAndv, e, fp );
  257.   }
  258.   if( algorithm == RUNGE_KUTTA ){
  259.     runge_kutta( k, m, dt, T, xAndv0, xAndv, e, fp );
  260.   }
  261. }
Advertisement
Add Comment
Please, Sign In to add comment