Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <float.h>
- #define G 6.67e-11 //m^3/(kg*s^2)
- #define UA 15e10 //m unita astronomica
- #define MS 2e30 //kg massa sole
- #define ANNO 31556736 //secondi anno solare della terra
- #define NOMEFILE "moto.dat"
- /****************************************/
- //struttura usata per i corpi
- struct corpo{
- double x, y, m, vx, vy, x1, y1;
- };
- typedef struct corpo pianeta;
- struct status{
- pianeta p1,p2;
- double gamma, tn, dt, t1, epsilon;
- char integrazione;
- };
- typedef struct status stato;
- /****************************************/
- /****************************************/
- //funzioni generali
- double modulo(double x, double y);
- double acc(stato* s, int n, char asse);
- double dinput(double min, double max);
- void cordinput(pianeta* p);
- char cinput(int n, char* caratteri);
- /****************************************/
- /****************************************/
- //funzioni principali
- void input(stato* s, char norm);
- void integra(stato* s);
- void inizializza(stato* s);
- void passo_integra(stato* s);
- /****************************************/
- /****************************************/
- //metodi d'integrazione
- void verlet(stato* s);
- void rungekutta(stato* s);
- /****************************************/
- /****************************************/
- /****************************************/
- /****************************************/
- // MAIN
- int main(void){
- stato s;
- printf("calcolare in coordinate normalizzate al sistema terra sole\n(y/n) = ");
- char norm = cinput(4, (char[]){'y', 'Y', 'n', 'N'});
- input(&s, norm);
- integra(&s);
- return 0;
- }
- /****************************************/
- /****************************************/
- /****************************************/
- /****************************************/
- //funzioni generali
- double modulo(double x, double y){
- return sqrt(pow(x, 2) + pow(y, 2));
- }
- double acc(stato* s, int n, char asse){
- if(n==1){
- if(asse=='x'){
- return 0 - s->gamma * (s->p1).x / pow(modulo((s->p1).x, (s->p1).y), 3) + s->epsilon * (s->p2).m * s->gamma * ((s->p2).x - (s->p1).x) / pow(modulo((s->p2).x - (s->p1).x, (s->p2).y - (s->p1).y), 3);
- }else if(asse=='y'){
- return 0 - s->gamma * (s->p1).y / pow(modulo((s->p1).x, (s->p1).y), 3) + s->epsilon * (s->p2).m * s->gamma * ((s->p2).y - (s->p1).y) / pow(modulo((s->p2).x - (s->p1).x, (s->p2).y - (s->p1).y), 3);
- }else{
- printf("\n\n\nERROR ACC asse ne x ne y\n\n\n");
- exit(EXIT_FAILURE);
- }
- }else if(n==2){
- if(asse=='x'){
- return 0 - s->gamma * (s->p2).x / pow(modulo((s->p2).x, (s->p2).y), 3) + s->epsilon * (s->p1).m * s->gamma * ((s->p1).x - (s->p2).x) / pow(modulo((s->p2).x - (s->p1).x, (s->p2).y - (s->p1).y), 3);
- }else if(asse=='y'){
- return 0 - s->gamma * (s->p2).y / pow(modulo((s->p2).x, (s->p2).y), 3) + s->epsilon * (s->p1).m * s->gamma * ((s->p1).y - (s->p2).y) / pow(modulo((s->p2).x - (s->p1).x, (s->p2).y - (s->p1).y), 3);
- }else{
- printf("\n\n\nERROR ACC asse ne x ne y\n\n\n");
- exit(EXIT_FAILURE);
- }
- }else{
- printf("\n\n\nERROR ACC n ne 1 ne 2\n\n\n");
- exit(EXIT_FAILURE);
- }
- }
- double dinputs(double min, double max){
- double num;
- do{
- scanf("%lf", &num);
- if(num <= min || num >= max){
- printf("il valore deve essere compreso tra %lf e %lf\nreinserisci il valore = ", min, max);
- }
- }while(num <= min || num >= max);
- return num;
- }
- double dinput(double min, double max){
- double num;
- do{
- scanf("%lf", &num);
- if(num < min || num > max){
- printf("il valore deve essere compreso tra %lf e %lf\nreinserisci il valore = ", min, max);
- }
- }while(num < min || num > max);
- return num;
- }
- void cordinput(pianeta* p){
- do{
- printf("x = ");
- p->x = dinput(-DBL_MAX, DBL_MAX);
- printf("y = ");
- p->y = dinput(-DBL_MAX, DBL_MAX);
- if(p->x==0 && p->y==0){
- printf("il pianeta non puo stare nel sole, dammi altre coordinate\n");
- }
- }while(p->x==0 && p->y==0);
- }
- char cinput(int n, char* caratteri){
- char input;
- for(;;){
- scanf("%c", &input);
- int i;
- for(i=0;i<n;i++){
- if(input==caratteri[i]){
- return input;
- }
- }
- printf("gli unici caratteri accettati sono");
- for(i=0;i<n;i++){
- printf(" \'%c\'", caratteri[i]);
- }
- printf("\ninput = ");
- }
- }
- /****************************************/
- /****************************************/
- //funzioni principali
- void input(stato* s, char norm){
- printf("scegli il metodo di integrazione\nv = verlet\nr = runge kutta\nscegli = ");
- s->integrazione = cinput(2, (char[]){'v', 'r'});
- printf("dammi la massa del sole (kg)\nM = ");
- double M = dinputs(0.0, DBL_MAX);
- s->gamma = M * G;
- printf("dammi la massa del primo pianeta (kg)\nm1 = ");
- (s->p1).m = dinputs(0.0, DBL_MAX) / M;
- printf("dammi la massa del secondo pianeta (kg)\nm2 = ");
- (s->p2).m = dinputs(0.0, DBL_MAX) / M;
- do{
- printf("dammi la posizione del primo pianeta in coordinate cartesiane (m)\n");
- cordinput(&((s->p1)));
- printf("dammi la posizione del secondo pianeta in coordinate cartesiane (m)\n");
- cordinput(&((s->p2)));
- if((s->p1).x==(s->p2).x && (s->p1).y==(s->p2).y){
- printf("i pianeti non possono stare alle stesse coordinate\n");
- }
- }while((s->p1).x==(s->p2).x && (s->p1).y==(s->p2).y);
- printf("dammi le velocita iniziali del primo pianeta (m/s)\nvx = ");
- (s->p1).vx = dinput(-DBL_MAX, DBL_MAX);
- printf("vy = ");
- (s->p1).vy = dinput(-DBL_MAX, DBL_MAX);
- printf("dammi le velocita iniziali del secondo pianeta (m/s)\nvx = ");
- (s->p2).vx = dinput(-DBL_MAX, DBL_MAX);
- printf("vy = ");
- (s->p2).vy = dinput(-DBL_MAX, DBL_MAX);
- printf("dammi epsilon\neps = ");
- s->epsilon = dinput(0.0, 1.0);
- printf("dammi la durata (s)\nt1 = ");
- s->t1 = dinputs(0.0, DBL_MAX);
- printf("dt (s) = ");
- s->dt = dinputs(0.0, DBL_MAX);
- if(norm=='y' || norm=='Y'){
- s->gamma *= (pow(ANNO, 2) / pow(UA, 3));
- (s->p1).x /= UA;
- (s->p1).y /= UA;
- (s->p2).x /= UA;
- (s->p2).y /= UA;
- (s->p1).vx *= ANNO / UA;
- (s->p1).vy *= ANNO / UA;
- (s->p2).vx *= ANNO / UA;
- (s->p2).vy *= ANNO / UA;
- s->t1 /= ANNO;
- s->dt /= ANNO;
- }
- FILE *file;
- file = fopen(NOMEFILE, "w");
- fprintf(file, "%c M = %lf, m1%cM = %lf, m2%cM = %lf\n", '#', M, '/', (s->p1).m, '/', (s->p2).m);
- if(fclose(file)==EOF){
- printf("\n\nERRORE CHIUSURA FILE\n\n");
- exit(EXIT_FAILURE);
- }
- }
- void integra(stato* s){
- FILE *file;
- file = fopen(NOMEFILE, "a");
- if(file==NULL){
- printf("\n\nERRORE APERTURA FILE\n\n");
- exit(EXIT_FAILURE);
- }
- fprintf(file, "%ctn x1 y1 x2 y2\n", '#');
- inizializza(s);
- for(s->tn = 0; s->tn <= s->t1; s->tn += s->dt){
- passo_integra(s);
- fprintf(file, "%lf %lf %lf %lf %lf\n", s->tn, (s->p1).x, (s->p1).y, (s->p2).x, (s->p2).y);
- }
- if(fclose(file)==EOF){
- printf("\n\nERRORE CHIUSURA FILE\n\n");
- exit(EXIT_FAILURE);
- }
- }
- void inizializza(stato* s){
- if(s->integrazione=='v'){
- (s->p1).x1 = (s->p1).x;
- (s->p1).y1 = (s->p1).y;
- (s->p2).x1 = (s->p2).x;
- (s->p2).y1 = (s->p2).y;
- (s->p1).x = (s->p1).x1 + (s->p1).vx * s->dt;
- (s->p1).y = (s->p1).y1 + (s->p1).vy * s->dt;
- (s->p2).x = (s->p2).x1 + (s->p2).vx * s->dt;
- (s->p2).y = (s->p2).y1 + (s->p2).vy * s->dt;
- }else if(s->integrazione!='r'){
- printf("\n\nERRORE S INTEGRAZIONE\n\n");
- exit(EXIT_FAILURE);
- }
- }
- void passo_integra(stato* s){
- if(s->integrazione=='v'){
- verlet(s);
- }else if(s->integrazione=='r'){
- rungekutta(s);
- }else{
- printf("\n\nERRORE S INTEGRAZIONE\n\n");
- exit(EXIT_FAILURE);
- }
- }
- /****************************************/
- /****************************************/
- //metodi d'integrazione
- void verlet(stato* s){
- double temp1, temp2, temp3, temp4;
- temp1 = 2 * (s->p1).x - (s->p1).x1 + acc(s, 1, 'x') * pow(s->dt, 2);
- temp2 = 2 * (s->p1).y - (s->p1).y1 + acc(s, 1, 'y') * pow(s->dt, 2);
- temp3 = 2 * (s->p2).x - (s->p2).x1 + acc(s, 2, 'x') * pow(s->dt, 2);
- temp4 = 2 * (s->p2).y - (s->p2).y1 + acc(s, 2, 'y') * pow(s->dt, 2);
- (s->p1).x1 = (s->p1).x;
- (s->p1).x = temp1;
- (s->p1).y1 = (s->p1).y;
- (s->p1).y = temp2;
- (s->p2).x1 = (s->p2).x;
- (s->p2).x = temp3;
- (s->p2).y1 = (s->p2).y;
- (s->p2).y = temp4;
- }
- void rungekutta(stato* s){
- double v1x = acc(s, 1, 'x') * s->dt / 2 + (s->p1).vx;
- double v1y = acc(s, 1, 'y') * s->dt / 2 + (s->p1).vy;
- double v2x = acc(s, 2, 'x') * s->dt / 2 + (s->p2).vx;
- double v2y = acc(s, 2, 'y') * s->dt / 2 + (s->p2).vy;
- (s->p1).x1 = (s->p1).x;
- (s->p1).y1 = (s->p1).y;
- (s->p2).x1 = (s->p2).x;
- (s->p2).y1 = (s->p2).y;
- (s->p1).x += (s->p1).vx * s->dt / 2;
- (s->p1).y += (s->p1).vy * s->dt / 2;
- (s->p2).x += (s->p2).vx * s->dt / 2;
- (s->p2).y += (s->p2).vy * s->dt / 2;
- (s->p1).vx += acc(s, 1, 'x') * s->dt;
- (s->p1).vy += acc(s, 1, 'y') * s->dt;
- (s->p2).vx += acc(s, 2, 'x') * s->dt;
- (s->p2).vy += acc(s, 2, 'y') * s->dt;
- (s->p1).x = (s->p1).x1 + v1x * s->dt;
- (s->p1).y = (s->p1).y1 + v1y * s->dt;
- (s->p2).x = (s->p2).x1 + v2x * s->dt;
- (s->p2).y = (s->p2).y1 + v2y * s->dt;
- }
- /****************************************/
Advertisement
Add Comment
Please, Sign In to add comment