Outils pour utilisateurs

Outils du site


wiki:projet:simu_air

MIRAGES : SIMULATIONS DANS L'AIR

CODE C++

#include <cmath>
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

double c =2.99792458e8;     //vitesse lumière
double lambda = 632.8e-3;   //longueur d'onde du laser

int Npas;           // Discrétisation de l'espace
double Tmin, Tmax;

int conv(double y, double ymax){    // converti une position vers l'indice de discrétisation de l'espace
    return int(y*Npas/ymax);
}

void gradient(int Npas, double grad[]){   //initialisation du tableau de gradient avec une fonction
    int i;
    for(i=0;i<Npas;i++){
        grad[i]=Tmin+(Tmax-Tmin)*double(i)/double(Npas); //fonction que l'on peut changer
    }
}

double n(double y, double ymax, double grad[]){   // renvoie l'indice optique correspondant à la position entré
    return 1+(1e-6 *(288.02+1.478/lambda/lambda+0.0316/pow(lambda,4))/(1+0.003716*grad[conv(y,ymax)]));
}

void deriv(double ymax, double dt, double grad[],double y[], double dy[]){ //Equation du mouvement d'un " grain de laser "
    dy[0]=y[2];                                                 // x
    dy[1]=y[3];                                                 // z
    dy[2]=0;                                                    // vx, calculer après de manière analytique à partir de vz et c²/n²
    dy[3]=pow(y[2],2)/n(y[1],ymax,grad)*(n(y[1]+dy[1]*dt,ymax,grad)-n(y[1],ymax,grad))/(1e-100+dy[1]*dt);           // vz
}

void rk4(double grad[],double ymax,int m, double x, double y[] ,double dx, void deriv(double,double, double[],double[], double[])){
    // Algorythme de runge kutta d'ordre 4
    int i ;
    double ddx ;
    double d1[m], d2[m], d3[m], d4[m], yp[m];
    ddx = dx/2.;
    deriv(ymax,ddx,grad,y,d1) ;
    for( i = 0; i< m; i++){ yp[i] = y[i] + d1[i]*ddx ; }
    yp[2]=sqrt(c*c/n(yp[1],ymax,grad)/n(yp[1],ymax,grad)-yp[3]*yp[3]);  // calcul de la valeur de vx en fonction de la valeur de vy
    deriv(ymax,ddx,grad,yp,d2) ;
    for( i = 0; i < m; i++){ yp[i] = y[i] + d2[i]*ddx ; }
    yp[2]=sqrt(c*c/n(yp[1],ymax,grad)/n(yp[1],ymax,grad)-yp[3]*yp[3]);
    deriv(ymax,ddx,grad,yp,d3) ;
    for( i = 0; i< m; i++){ yp[i] = y[i] + d3[i]*dx ;}
    yp[2]=sqrt(c*c/n(yp[1],ymax,grad)/n(yp[1],ymax,grad)-yp[3]*yp[3]);
    deriv(ymax,ddx,grad,yp,d4) ;
    for( i = 0; i < m ; i++)
    { y[i] = y[i] + dx*( d1[i] + 2*d2[i] + 2*d3[i] + d4[i] )/6 ; }
    y[2]=sqrt(c*c/n(y[1],ymax,grad)/n(y[1],ymax,grad)-y[3]*y[3]);
}

int main(){
    double xmax = 0.6;
    double zmax = 0.1;

    //initialisation:

    cout << "Tmin (Celcius) (z=0) ?" << endl;
    cin >> Tmin;
    cout << "Tmax (Celcius) (z=zmax)?" << endl;
    cin >> Tmax;
    cout << "Proportion de la cuve : 10x10x60" << endl;
    Npas=100000;
    double theta;
    cout <<"Angle incident (degre) " << endl;
    cin >> theta;
    theta *= M_PI/180.;      //conversion en rad

    double dz = zmax/Npas;

    // Evolution rayon :

    double grad[Npas];  // n(z)
    gradient(Npas,grad);
    double y[4];
    y[0]=0; //x
    y[1]=zmax/2; //z
    y[2]=cos(theta)*c/n(y[1],zmax,grad);   //vx
    y[3]=sin(theta)*c/n(y[1],zmax,grad);   //vz
    double dt =1e-14;


    ofstream fichier("Air_1_nograd.res");     //on enregistre les différents paramètres dans un fichier
    for(double t=0;t<=2.2e-9;t+=dt)
    {

        if(y[0]>xmax){break;}
        if(y[1]>0.1-1.5*dz){y[3]=-y[3];}
        if(y[1]<1.5*dz){y[3]=-y[3];}
        fichier << t ;
        cout << t << endl ;       //affiche le temps (juste pour montrer que le programme tourne !
        for(int i=0;i<4;i++)    fichier << " " << y[i]  ;   //enregistre chaque paramètres
        fichier << endl;
        rk4(grad,zmax,4,t,y,dt,deriv);      //évolution des coordonnées
    }
    fichier.close();

}

GRAPHES

wiki/projet/simu_air.txt · Dernière modification: 2017/03/31 14:31 de http_fablab.sorbonne-universites.fr_wiki_doku.php_id_wiki_projet_laser