Equation de la chaleur en 2D. Problème avec mon logiciel.

Equation de la chaleur en 2D. Problème avec mon logiciel. - C - Programmation

Marsh Posté le 30-05-2007 à 13:14:46    

Voilà dans le cadre d'un projet avec mon école, j'ai à programmer une méthode de résoluton numérique de l'équation de la chaleur en 2D. VOilà la sujet :
 
http://img181.imageshack.us/img181/7708/clanu1yz2.th.jpghttp://img381.imageshack.us/img381/144/clanu2sh0.th.jpghttp://img381.imageshack.us/img381/7238/clanu3fn2.th.jpg
 
Voilà mon code :  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. int N;
  5. //---------------------------------------------
  6. // Structure et fonctions pour gérer des matrices
  7. //---------------------------------------------
  8. typedef struct _Matrix
  9. {
  10.     float * data;
  11.     int line;
  12.     int col;
  13. } Matrix;
  14. void AllocMatrix(Matrix * matrix, int l, int c)
  15. {
  16.     matrix->line = l;
  17.     matrix->col = c;
  18.     matrix->data = (float *)malloc(sizeof(float) * l * c);
  19. }
  20. void FreeMatrix(Matrix * matrix)
  21. {
  22.     free(matrix->data);
  23. }
  24. void MatrixSet(Matrix * matrix, int i, int j, float value)
  25. {
  26.     matrix->data[j * matrix->line + i] = value;
  27. }
  28. float MatrixGet(Matrix * matrix, int i, int j)
  29. {
  30.     return matrix->data[j * matrix->line + i];
  31. }
  32. //-----------------------------------------------------
  33. //Fonction Choleski
  34. //-----------------------------------------------------
  35. Choleski (Matrix A, int N, Matrix H, Matrix Out)
  36. {
  37.     int I=1,J=1,K,L,M;
  38.     Matrix B;
  39.     float S;
  40.     float X[N+1], Y[N+1];
  41.     int Bool=1;
  42.     AllocMatrix(&B, N, N);
  43.    
  44.     //Affichage de Aj dans Choleski
  45.    /*printf("Aj dans Choleski \n" );
  46.     for (I=1 ; I<=N ; I++)
  47.     {
  48.         for (K=1 ; K<=N ; K++)
  49.         {
  50.             printf("%f ",MatrixGet(&A, I, K));
  51.         }
  52.         printf("\n" );
  53.     }
  54.    //*/
  55.    
  56.     for (I=0 ; I<=N ; I++)
  57.     {
  58.         S=0;
  59.         for (K=0 ; K<=I-1 ; K++)
  60.         {
  61.             S=(S+( MatrixGet(&B, I, K)*MatrixGet(&B, I, K) ) );
  62.         }
  63.         if ( (MatrixGet(&A, I, I) - S )> 0 )
  64.         {
  65.             MatrixSet(&B, I, I, sqrt(MatrixGet(&A, I, I)-S));
  66.             for (J=I+1 ; J<=N ; J++)
  67.             {
  68.                 S=0;
  69.                 for (K=1 ; K<=I-1 ; K++)
  70.                 {
  71.                     S=S+(MatrixGet(&B, I, K)*MatrixGet(&B, J, K));
  72.                 }
  73.                 MatrixSet(&B, J, I, (MatrixGet(&A, I, J)-S)/(MatrixGet(&B, I, I)));
  74.             }
  75.             for (L=1 ; L<=N-1 ; L++)
  76.             {
  77.                 for (M=I+1 ; M<=N ; M++)
  78.                 {
  79.                     MatrixSet(&B ,L, M, 0);
  80.                 }
  81.             }
  82.         }
  83.         else
  84.         {
  85.             Bool=0;
  86.         }
  87.     }
  88.    
  89.     if (Bool==0)
  90.     {
  91.       printf("\n\nResolution impossible\n" );
  92.     }
  93.     else
  94.         printf("\n\nResolution de By=h" );
  95.         Y[1]=MatrixGet(&H, 1, 1)/(MatrixGet(&B, 1, 1));
  96.     for (I=2 ; I<=N ; I++)
  97.     {
  98.         S=0;
  99.         for (K=1 ; K<=I-1 ; K++)
  100.         {
  101.             S=S+(MatrixGet(&B, K, I))*Y[K];
  102.         }
  103.         Y[I]=(MatrixGet(&H, I,1)-S)/MatrixGet(&B, I, I);
  104.     }
  105.     printf("\n\nResolution de B trans x = y" );
  106.     X[N]=Y[N]/(MatrixGet(&B ,N ,N));
  107.     for (I=N-1 ; I>= 1 ; I--)
  108.     {
  109.         S=0;
  110.         for (K=I+1 ; K <= N ; K++)
  111.         {
  112.             S=S+(MatrixGet(&B, K, I)*X[K]);
  113.         }
  114.         X[I]=(Y[I]-S)/(MatrixGet(&B, I, I));
  115.     }
  116.     printf("\nX=\n" );
  117.     for (I=1 ; I<=N ; I++)
  118.     {
  119.         printf("   %f\n",X[I]);
  120.         MatrixSet(&Out, I, 1, X[I]);
  121.     }
  122. FreeMatrix(&B);
  123. }
  124. //------------------------------------------------------------------------
  125. //Fonction principale
  126. //------------------------------------------------------------------------
  127. int main(void)
  128. {
  129.      
  130.     //Déclaration des variables
  131.     int n;
  132.      
  133.     //Choix du nombre de colonnes du tableau et donc du pas
  134.     printf ("Bienvenue dans le programme de resolution de l'équation de la chaleur  \n" );
  135.     printf ("               en deux dimension d'espace. \n" );
  136.     printf("\n" );
  137.     printf("Veuillez entrer le nombre de colonnes pour la matrice initiale \n" );
  138.     printf("     On rapelle que le pas est egal a 1/(n+1) \n \n" );
  139.     printf("n = " );
  140.     scanf("%d",&n);
  141.     printf("\n" );
  142.     //
  143.      
  144.     //Suite de la déclaration des variables
  145.          
  146.     float T=10;
  147.     int i,j,l,k,c=15,t_etoile=4,p=200;
  148.     float dy,dt,dx,x=0,y=0,t,f;
  149.     Matrix u_etoile;
  150.     Matrix u_avant;
  151.     Matrix u_apres;
  152.     Matrix u0, uc1;
  153.     Matrix Aj;
  154.     Matrix ucl;
  155.     Matrix bj;
  156.     Matrix Xc;
  157.     Matrix Xc2;
  158.     Matrix bi;
  159.     dx=1.0/(n+1);
  160.     dy=1.0/(n+1);
  161.     dt= T/p;
  162.     float n1= 0.5*dt/(dx*dx);
  163.     float n2= 0.5*dt/(dy*dy);
  164.     printf("Le pas sera donc de %f \n \n",dx);
  165.     printf("Appuyez sur une touche pour continuer \n" );
  166.     getchar();
  167.     getchar();
  168.      
  169.     // Allocation des divers tableaux
  170.     AllocMatrix(&u_etoile, n+1, n+1);
  171.     AllocMatrix(&u_avant, n+1, n+1);
  172.     AllocMatrix(&u0, n+1, n+1);
  173.     AllocMatrix(&ucl, n+1, n+1);
  174.     AllocMatrix(&Aj, n+1, n+1);
  175.     AllocMatrix(&bj, n+1, 1);
  176.     AllocMatrix(&Xc, n+1, 1);
  177.     AllocMatrix(&Xc2, n+1, 1);
  178.     AllocMatrix(&bi, n+1, 1);
  179.      
  180.     //Fin allocation variable   
  181.      
  182.     //-----------------------------------------------------------------
  183.     //1ere ETAPE : PASSAGE de u_k à u*
  184.     //-----------------------------------------------------------------
  185.      
  186.       // Remplissage de Aj
  187.      
  188.       for (i=1 ; i<n+1 ; i++)
  189.         {
  190.             for (j=1 ; j<n+1 ; j++)
  191.             {
  192.                 MatrixSet(&Aj, i, j,0);
  193.                 MatrixSet(&Aj, i, i,1+2*n1);
  194.                 if (j==(i+1))
  195.                    MatrixSet(&Aj, i, j,-n1);
  196.                 if (i==(j+1))
  197.                    MatrixSet(&Aj, i, j,-n1);
  198.              }
  199.         }
  200.          
  201.                
  202.       //
  203.      
  204.     //Début de la boucle principal qui effectuera les divers calculs
  205.      
  206.     for (k=0 ; k<1 ; k=k+1)
  207.     {
  208.         for (y=dy ; y<1 ; y=y+dy)
  209.         {
  210.             for (x=dx ; x<1 ; x=x+dx)
  211.             {
  212.                 i = 1 / dx * x;
  213.                 j = 1 / dy * y;
  214.                            
  215.                 // Conditions aux limites
  216.                 MatrixSet(&ucl, 0, 0, 1);
  217.                 MatrixSet(&ucl, 0, j, 1);
  218.                 MatrixSet(&ucl, i, 0, 1);
  219.                 MatrixSet(&ucl, n+1, j, exp(-y));
  220.                 MatrixSet(&ucl, i, n+1, exp(-x));
  221.                 MatrixSet(&ucl, n+1, n+1, exp(-1));
  222.                 MatrixSet(&u0, i, 0, 1);
  223.                 MatrixSet(&u0, i, n+1, exp(-x));
  224.                
  225.                 // Conditions initiales
  226.                 if (x+y>1)
  227.                      MatrixSet(&u0, i, j, exp(1-x-y));
  228.                 else
  229.                      MatrixSet(&u0, i, j, 1);
  230.                      
  231.                 // Calcul des valeurs de la fonction f
  232.                 t=k*(dt);
  233.                 f=c*exp(-((x-0.8)*(x-0.8)+(y-0.8)*(y-0.8)))*exp(-(t-t_etoile)*(t-t_etoile));
  234.                 //
  235.            
  236.                 //
  237.                 if(k==0)
  238.                 {
  239.                     MatrixSet(&u_avant, i, j, MatrixGet(&u0, i, j));
  240.                     MatrixSet(&u_avant, i, j-1, MatrixGet(&u0, i, j));
  241.                     MatrixSet(&u_avant, i, j+1, MatrixGet(&u0, i, j));
  242.                 }
  243.                 //
  244.                 //
  245.                MatrixSet(&u_avant, i, 0, MatrixGet(&ucl, i, 0));
  246.                MatrixSet(&u_avant, i, n+1, MatrixGet(&ucl, i, n+1));
  247.                 //
  248.                 // Remplissage de bj
  249.                 MatrixSet(&bj, i,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1) - 2*MatrixGet(&u_avant, i,j) ) + 0.5*dt*f );
  250.                 MatrixSet(&bj, 0,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1))+ (0.5*(dt)*f) + n1*MatrixGet(&ucl, 0, j) );
  251.                 MatrixSet(&bj, n,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1) - 2*MatrixGet(&u_avant, i,j) ) + (0.5*(dt)*f) + n1*MatrixGet(&ucl, n+1, j) );
  252.                 //
  253.             }
  254.              
  255.             //Appel de la fonction Choleski
  256.             Choleski (Aj, n, bj, Xc);
  257.    
  258.             printf("\n" );
  259.             //Remplissage de u* avec les résultats de Choleski
  260.             for (l=1 ; l<n+1 ; l++)
  261.             {
  262.                 MatrixSet(&u_etoile, l, j, MatrixGet(&Xc, l, 1));
  263.             }
  264.         }
  265.      
  266.      
  267.      
  268.     //////////////////////////////Fin étape 1//////////////////////////
  269.      
  270.      
  271.     //-----------------------------------------------------------------
  272.     //2nde ETAPE : PASSAGE de u* à u_k+1
  273.     //-----------------------------------------------------------------
  274.      
  275.      
  276.         for (y=dy ; y<1 ; y=y+dy)
  277.         {
  278.             for (x=dx ; x<1 ; x=x+dx)
  279.             {   
  280.                 i = 1 / dx * x;
  281.                 j = 1 / dy * y;
  282.                  
  283.                 if(k==0)  
  284.                 {
  285.                     MatrixSet(&u_avant, i, j, MatrixGet(&u_etoile, i, j));
  286.                     MatrixSet(&u_avant, i, j-1, MatrixGet(&u_etoile, i, j));
  287.                     MatrixSet(&u_avant, i, j+1, MatrixGet(&u_etoile, i, j));
  288.                 }
  289.                  
  290.                 //Calcul des valeurs de la fonction f
  291.                 t=k*(dt);
  292.                 f=c*exp(-((x-0.8)*(x-0.8)+(y-0.8)*(y-0.8)))*exp(-(t-t_etoile)*(t-t_etoile));
  293.                 //
  294.                  
  295.                 // Remplissage de bi
  296.                 MatrixSet(&bi, i,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1) - 2*MatrixGet(&u_avant, i,j) ) + 0.5*dt*f );
  297.                 MatrixSet(&bi, 0,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1))+ (0.5*dt*f) + n1*MatrixGet(&ucl, 0, j) );
  298.                 MatrixSet(&bi, n,1, MatrixGet(&u_avant, i, j) + n2*( MatrixGet(&u_avant, i, j-1) + MatrixGet(&u_avant, i, j+1) - 2*MatrixGet(&u_avant, i,j) ) + (0.5*(dt)*f) + n1*MatrixGet(&ucl, n+1, j) );
  299.                 //
  300.                  
  301.                  
  302.                 //Appel de Choleski pour déterminer u_k+1
  303.                 //Choleski (Aj, n, bi, Xc2);
  304.                 //
  305.                  
  306.             /*   //Remplissage de u_k+1 avec les résultats de Choleski
  307.             for (l=1 ; l<n+1 ; l++)
  308.             {
  309.                 MatrixSet(&u_apres, i, l, MatrixGet(&Xc2, l, 1));
  310.             }
  311.            
  312. */
  313.          
  314.             }
  315.         }
  316.        
  317.   /*    for (y=dy ; y<1 ; y=y+dy)
  318.         {
  319.             for (x=dx ; x<1 ; x=x+dx)
  320.             {   
  321.                 i = 1 / dx * x;
  322.                 j = 1 / dy * y;
  323.                MatrixSet(&u_avant, i, j, MatrixGet(&u_apres, i, j));  
  324.             }
  325.         }*/
  326. }
  327. //-----------------------------------------------------------------
  328. //Affichage divers pour tests des valeurs
  329. //-----------------------------------------------------------------   
  330.     //Test de u0
  331.     printf("\nAffichage de u0 \n \n" );
  332.     for(x=dx ; x<1 ; x=x+dx)
  333.     {
  334.         for(y=dy ; y<1 ; y=y+dy)
  335.         {
  336.             i= 1 / dx * x;
  337.             j= 1 / dy * y;
  338.             printf("%f ", MatrixGet(&u0, i, j));
  339.         }
  340.         printf("\n" );
  341.     }
  342.    
  343.     //Test de Ai
  344.     printf("\nAffichage de Aj \n \n" );
  345.     for(x=dx ; x<1 ; x=x+dx)
  346.     {
  347.         for(y=dy ; y<1 ; y=y+dy)
  348.         {
  349.             i= 1 / dx * x;
  350.             j= 1 / dy * y;
  351.             printf("%f ", MatrixGet(&Aj, i, j));
  352.         }
  353.         printf("\n" );
  354.     }
  355.     printf("\n" );
  356.    
  357.    //Test de bj
  358.    printf("\nAffichage de bj \n \n" );
  359.    for(x=dx ; x<1 ; x=x+dx)
  360.    {
  361.              int i= 1 / dx * x;
  362.              printf("%f \n", MatrixGet(&bj, i, 1));           
  363.    }
  364.    //Test de Xc
  365.    printf("\nAffichage de Xc \n \n" );
  366.    for(x=dx ; x<1 ; x=x+dx)
  367.    {
  368.              int i= 1 / dx * x;
  369.              printf("%f \n", MatrixGet(&Xc, i, 1));           
  370.    }
  371.     //Test de u*
  372.     printf("\nAffichage de u* \n \n" );
  373.     for(x=dx ; x<1 ; x=x+dx)
  374.     {
  375.         for(y=dy ; y<1 ; y=y+dy)
  376.         {
  377.             i= 1 / dx * x;
  378.             j= 1 / dy * y;
  379.             printf("%f ", MatrixGet(&u_etoile, i, j));
  380.         }
  381.         printf("\n" );
  382.     }
  383.    
  384.    //Test de bi
  385.    printf("\nAffichage de bi \n \n" );
  386.    for(x=dx ; x<1 ; x=x+dx)
  387.    {
  388.              int i= 1 / dx * x;
  389.              printf("%f \n", MatrixGet(&bi, i, 1));           
  390.    }
  391.  
  392.    //Test de Xc2
  393.    printf("\nAffichage de Xc2 \n \n" );
  394.    for(x=dx ; x<1 ; x=x+dx)
  395.    {
  396.              int i= 1 / dx * x;
  397.              printf("%f \n", MatrixGet(&Xc2, i, 1));           
  398.    }
  399. ////////////////////////////Fin affichage des tests///////////////////////
  400.            
  401. getchar();
  402. getchar();
  403.     // Libération des divers tableaux
  404.     FreeMatrix(&bj);
  405.     FreeMatrix(&bi);
  406.     FreeMatrix(&Aj);
  407.     FreeMatrix(&ucl);
  408.     FreeMatrix(&u0);
  409.     FreeMatrix(&u_avant);
  410.     FreeMatrix(&u_etoile);
  411.     FreeMatrix(&Xc); 
  412.     FreeMatrix(&Xc2);
  413. }
  414. //Fin programme


 
Et enfin, voilà mon problème :
Quand j'appelle Choleski une première fois, tout va bien, il s'exécute. Par contre quand le programme arrive dans la seconde boucle et appelle Choleski une seconde fois, il plante.
Si je n'appelle pas Choleski dans la première et que je le fais dans la seconde, ça fonctionne.
 
Donc j'aimerais savoir si vous pouviez me dire pourquoi quand j'appelle une seconde fois ma fonction ça plante. Merci d'avance :)

Reply

Marsh Posté le 30-05-2007 à 13:14:46   

Reply

Marsh Posté le 30-05-2007 à 13:18:44    

Reflexe : Utiliser le debugger de ton environnement, voir la ligne ou ca part en couille, analyser la valeur des données en jeu à ce moment et hop.


---------------
Töp of the plöp
Reply

Marsh Posté le 30-05-2007 à 13:20:49    

Je sais t rès bien d'où vient le problème : à la ligne 328. Quand je rappelle Choleski ça plante. Si je l'appelle pas une seconde fois tout s'exécute très bien. Et si je ne l'appelle pas à la ligne 280, là il s'exécutera bien à la ligne 328.

 

Je pense à un problème d'allocation mémoire ou un truc qui me dépasse.


Message édité par StarHunter le 30-05-2007 à 13:21:36
Reply

Marsh Posté le 30-05-2007 à 13:24:09    

Ben tu rentres dans cette fonction et tu vois exactement où ca plante.


---------------
Töp of the plöp
Reply

Marsh Posté le 30-05-2007 à 13:27:05    

Je fais ça comment ?

Reply

Marsh Posté le 30-05-2007 à 13:27:31    

T'as quoi comme environnement de dev ?
 
Si t'as visual, F11


---------------
Töp of the plöp
Reply

Marsh Posté le 30-05-2007 à 13:28:38    

DEV C++.

Reply

Marsh Posté le 30-05-2007 à 13:33:36    

Je sais pas sous devcpp, check la doc.


---------------
Töp of the plöp
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed