Advertisement
Guest User

Untitled

a guest
Dec 13th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.81 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6.  
  7. #define BIFORCAZIONE
  8.  
  9. typedef unsigned long long int INT;
  10. struct phasespace{
  11.   double x;
  12.   double v;
  13. };
  14.  
  15. struct phasespace leap_frog(struct phasespace, double, double, double);
  16. struct phasespace verlet(struct phasespace, double, double);
  17. struct phasespace sumstruct(struct phasespace, struct phasespace, double, double);
  18. struct phasespace RK2(struct phasespace, double, double, double, double, double, double);
  19. struct phasespace RK4(struct phasespace, double, double, double, double, double, double);
  20. struct phasespace RKn(struct phasespace, double, double, double, double, double, double, double, double);
  21. double energy(struct phasespace, double);
  22. double modulo(double, double);
  23. FILE *control_fopen(char *, char *);
  24.  
  25. int main(){
  26.  
  27.   clock_t begin = clock();
  28.   struct phasespace vec, vec0;
  29.   double TMAX, w2, dt, t, E0=1., E=0., xnm1, temp, f0, we, gamma, Te, eps, VAR = M_PI/500.;
  30.   INT i, j, N=2, method, STEPS, counter=0;
  31.   FILE *input, *output, *error, *poincare, *attrazione;
  32.  
  33.   input = control_fopen("input.dat", "r");
  34.  
  35.   fprintf(stderr, "%lf\n", VAR);  //controllo
  36.  
  37.   do{
  38.     printf("Inserire 1 per leap_frog, 2 per Verlet, 3 per RK2, 4 per RK4\n");
  39.     scanf("%llu", &method);
  40.   }while(method != 1 && method != 2 && method != 3 && method != 4);
  41.  
  42.   fscanf(input, "%lf %lf %lf %lf %lf %lf %lf %lf", &vec.x, &vec.v, &w2, &TMAX, &dt, &f0, &we, &gamma);
  43.   fclose(input);
  44.   Te = 2.*M_PI/we;
  45.  
  46.   #ifdef POINCARE
  47.   dt = Te/1000.;
  48.   TMAX = 30000*Te;
  49.   eps = dt/2.;
  50.   #endif
  51.  
  52.   poincare = control_fopen("poincare.dat", "w");
  53.   #ifdef ERRORE
  54.   error = control_fopen("error.dat", "w");
  55.   #endif
  56.  
  57.   STEPS = (INT)TMAX/dt+1;
  58.  
  59.   fprintf(stderr, "%llu\n", STEPS);
  60.  
  61.   #ifdef INTEGRATORE
  62.   output = control_fopen("pendolo.dat", "w");
  63.   //leap-frog
  64.   if(method == 1){
  65.     #ifdef ENERGY
  66.     E0 = energy(vec, w2);
  67.     #endif
  68.     fprintf(output, "%lf, %lf, %lf, %.10lf\n", 0., modulo(vec.x, 2*M_PI), vec.v, E0/E0-1);
  69.     xnm1 = vec.x;
  70.     vec = verlet(vec, w2, dt);
  71.     for(j=0; j<STEPS; ++j){
  72.       temp = vec.x;
  73.       vec = leap_frog(vec, xnm1, w2, dt);
  74.       xnm1 = temp;
  75.       #ifdef ENERGY
  76.       E = energy(vec, w2);
  77.       #endif
  78.       fprintf(output, "%lf, %lf, %lf, %lf\n", (j+1)*dt, modulo(vec.x, 2*M_PI), vec.v, E/E0-1);
  79.     }
  80.   }
  81.  
  82.   //Verlet
  83.   if(method == 2){
  84.     #ifdef ENERGY
  85.     E0 = energy(vec, w2);
  86.     #endif
  87.     fprintf(output, "%lf, %lf, %lf, %.10lf\n", 0., modulo(vec.x, 2*M_PI), vec.v, E0/E0-1);
  88.     for(j=0; j<STEPS; ++j){
  89.       vec = verlet(vec, w2, dt);
  90.       #ifdef ENERGY
  91.       E = energy(vec, w2);
  92.       #endif
  93.       fprintf(output, "%lf, %lf, %lf, %lf\n", (j+1)*dt, modulo(vec.x, 2*M_PI), vec.v, E/E0-1);
  94.     }
  95.   }
  96.  
  97.   //RK2
  98.   if(method == 3){
  99.     #ifdef ERRORE
  100.     for(i=0; i<6; i++){
  101.       #endif
  102.       #ifdef ENERGY
  103.       E0 = energy(vec, w2);
  104.       #endif
  105.       fprintf(output, "%lf %lf %lf %lf %.10lf\n", 0., vec.x, modulo(vec.x, 2*M_PI), vec.v, E0/E0-1);
  106.       for(j=0; j<STEPS; ++j){
  107.         vec = RK2(vec, w2, dt, j*dt, gamma, f0, we);
  108.         #ifdef ENERGY
  109.         E = energy(vec, w2);
  110.         #endif
  111.         fprintf(output, "%lf %lf %lf %lf %.10lf\n", (j+1)*dt, vec.x, modulo(vec.x, 2*M_PI), vec.v, E/E0-1);
  112.         #ifdef POINCARE
  113.         if((N*Te-(j+1)*dt) < eps){
  114.           fprintf(poincare, "%lf %lf\n", modulo(vec.x, 2*M_PI), vec.v);
  115.           ++N;
  116.         }
  117.         #endif
  118.       }
  119.       #ifdef ERRORE
  120.       fprintf(error, "%.10lf, %.10lf\n", log10(dt), log10(fabs(E/E0-1)));
  121.       dt *= 1./sqrt(10.);
  122.     }    // VERIFICA ORDINE DEL METODO --> OK
  123.     #endif
  124.   }
  125.  
  126.   //RK4
  127.   if(method == 4){
  128.     #ifdef ATTRAZIONE
  129.     attrazione = control_fopen("attrazione.dat", "w");
  130.     for(vec0.v = -M_PI; vec0.v <= M_PI; vec0.v += VAR){
  131.       fprintf(stderr, "banana %llu\n", ++counter);  //controllo
  132.       for(vec0.x = -M_PI; vec0.x <= M_PI; vec0.x += VAR){
  133.         vec.x = vec0.x;
  134.         vec.v = vec0.v;
  135.         #endif
  136.         #ifdef ENERGY
  137.         E0 = energy(vec, w2);
  138.         #endif
  139.         #ifdef TRAIETTORIA
  140.         //fprintf(output, "%lf %lf %lf %lf %.10lf\n", 0., vec.x, modulo(vec.x, 2*M_PI), vec.v, E0/E0-1);
  141.         #endif
  142.         for(j=0; j<STEPS; ++j){
  143.           vec = RK4(vec, w2, dt, j*dt, gamma, f0, we);
  144.           #ifdef ENERGY
  145.           E = energy(vec, w2);
  146.           #endif
  147.           #ifdef TRAIETTORIA
  148.           if(j>10000){
  149.             fprintf(output, "%lf %lf %lf %lf %.10lf\n", (j+1)*dt, vec.x, modulo(vec.x, 2*M_PI), vec.v, E/E0-1);
  150.           }
  151.           #endif
  152.           #ifdef POINCARE
  153.           if((j%1000) == 0 && j > 10000){
  154.             fprintf(poincare, "%lf %lf\n", modulo(vec.x, 2*M_PI), vec.v);
  155.             ++N;
  156.           }
  157.           #endif
  158.         }
  159.         #ifdef ATTRAZIONE
  160.         fprintf(attrazione, "%lf %lf %lf i\n", vec0.x, vec0.v, vec.v);
  161.       }
  162.       fprintf(attrazione, "\n");
  163.     }
  164.     fclose(attrazione);
  165.     #endif
  166.   }
  167.   fclose(output);
  168.   #endif
  169.  
  170.   #ifdef BIFORCAZIONE
  171.   struct phasespace vec0b;
  172.   FILE *biforcazione;
  173.   vec0b.x = vec.x;
  174.   INT k;
  175.   biforcazione = control_fopen("biforcazione.dat", "w");
  176.   dt = Te/100.;
  177.   TMAX = 100*Te;
  178.   STEPS = (INT)Te*100./dt+1;
  179.   for(k=0; k<11; ++k){
  180.     vec0b.v = k*M_PI/10.;
  181.     for(f0=0.90; f0<=1.50; f0+=0.0001){
  182.       printf("banana %llu\n", ++counter);
  183.       vec.x = vec0b.x;
  184.       vec.v = vec0b.v;
  185.       for(j=0; j<STEPS; ++j){
  186.         vec = RK4(vec, w2, dt, j*dt, gamma, f0, we);
  187.       }
  188.       fprintf(biforcazione, "%.10lf %.10lf %.10lf\n", f0, -modulo(vec.x, 2*M_PI), -vec.v);
  189.     }
  190.   }
  191.   #endif
  192.  
  193.   fclose(poincare);
  194.   #ifdef ERRORE
  195.   fclose(error);
  196.   #endif
  197.   clock_t end = clock();
  198.   printf("%lf\n", (double)(end-begin)/CLOCKS_PER_SEC);
  199.  
  200. }
  201.  
  202.  
  203. struct phasespace leap_frog(struct phasespace vec, double xnm1, double w2, double dt){
  204.   vec.x = 2*vec.x-xnm1-w2*vec.x*dt*dt;
  205.   vec.v = (vec.x-xnm1)/(2*dt);
  206.   return vec;
  207. }
  208.  
  209. struct phasespace verlet(struct phasespace vec, double w2, double dt){
  210.   double xnm1 = vec.x;
  211.   vec.x += vec.v*dt-w2*vec.x/2*dt*dt;
  212.   vec.v += -w2*(vec.x+xnm1)/2*dt;
  213.   return vec;
  214. }
  215.  
  216. struct phasespace sumstruct(struct phasespace vec1, struct phasespace vec2, double lambda1, double lambda2){
  217.   struct phasespace sum;
  218.   sum.x = lambda1*vec1.x+lambda2*vec2.x;
  219.   sum.v = lambda1*vec1.v+lambda2*vec2.v;
  220.   return sum;
  221. }
  222.  
  223. struct phasespace RK2(struct phasespace vec, double w2, double dt, double t, double gamma, double f0, double we){
  224.   struct phasespace k1, k2;
  225.   k1 = RKn(vec, 0., 0., w2, dt, t, gamma, f0, we);
  226.   k2 = RKn(vec, k1.x/2., k1.v/2., w2, dt, t+dt/2., gamma, f0, we);
  227.   return vec = sumstruct(vec, k2, 1., 1.);
  228. }
  229.  
  230. struct phasespace RK4(struct phasespace vec, double w2, double dt, double t, double gamma, double f0, double we){
  231.   struct phasespace k1, k2, k3, k4;
  232.   k1 = RKn(vec, 0., 0., w2, dt, t, gamma, f0, we);
  233.   k2 = RKn(vec, k1.x/2., k1.v/2., w2, dt, t+dt/2., gamma, f0, we);
  234.   k3 = RKn(vec, k2.x/2., k2.v/2., w2, dt, t+dt/2., gamma, f0, we);
  235.   k4 = RKn(vec, k3.x, k3.v, w2, dt, t+dt, gamma, f0, we);
  236.   vec.x += (k1.x+2*k2.x+2*k3.x+k4.x)/6.;
  237.   vec.v += (k1.v+2*k2.v+2*k3.v+k4.v)/6.;
  238.   return vec;
  239. }
  240.  
  241. struct phasespace RKn(struct phasespace vec, double kix, double kiv, double w2, double dt, double t, double gamma, double f0, double we){
  242.   struct phasespace kj;
  243.   kj.x = (vec.v+kiv)*dt;
  244.   kj.v = ((-w2*sin(vec.x+kix))-gamma*(vec.v+kiv)+f0*cos(we*(t)))*dt;
  245.   return kj;
  246. }
  247.  
  248. double energy(struct phasespace vec, double w2){
  249.   return vec.v*vec.v+2*w2*(1-cos(vec.x));
  250. }
  251.  
  252. double modulo(double a, double m){
  253.   a += m/2.;
  254.   double c = ((a/m)-(int)(a/m))*m;
  255.   return (c > 0 ? c : c+m)-m/2.;
  256. }
  257.  
  258.  
  259. FILE *control_fopen(char *filename, char *mode){
  260.   FILE *pointer;
  261.   if((pointer = fopen(filename, mode)) == NULL){
  262.     printf("Errore nell'apertura del file\n");
  263.     exit(EXIT_FAILURE);
  264.   }
  265.   return pointer;
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement