Home > Software design >  Numerical solution to heat equation
Numerical solution to heat equation

Time:11-17

After solving the heat equation with analytical procedures, I'm trying to solve it numerically by the explicit Euler method. I'm given the following discretization, where T is the temperature. My code is:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define N 100

double T[N 1][N];

int main(){
    int i,j;
    double dt=1./N;
    double dz=1./N;
    double b=43351./94400;
    for (i=0;i<N 2;i  ){
        T[i][0]=b;
        T[i][N-1]=b;
    }
    
    for (j=0;j<N 1;j  ){
        T[0][j 1]=b;
    }
    for (i=0;i<N 1;i  ){
        for (j=1;j<N;j  ){
            T[i 1][j] = (dt/pow(dz, 2))*(T[i][j 1] - 2*T[i][j]   T[i][j-1])   dt   T[i][j];
            
        }
    }

    FILE* output;
    
    output = fopen("numerica.txt", "w");
    
    for (i=0;i<N 2;i  ){
        for (j=0;j<N 1;j  ){
            fprintf(output, "%lf\t", T[i][j]);
        }
        fprintf(output,"\n");
    }
    fclose(output);
    return 0;
        
}

What I'm trying to do is to create a N 1xN matrix that saves all the values from the function. After compiling it I have an infinite .txt file. Some help?

CodePudding user response:

The output file should have 102 lines unless the program crashes, as your loops are wrong.

$ gcc -O -Wall t.c 
t.c: In function ‘main’:
t.c:35:13: warning: iteration 100 invokes undefined behavior [-Waggressive-loop-optimizations]
   35 |             fprintf(output, "%lf\t", T[i][j]);
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:34:19: note: within this loop
   34 |         for (j=0;j<N 1;j  ){
      |                  ~^~~~
t.c:24:46: warning: iteration 98 invokes undefined behavior [-Waggressive-loop-optimizations]
   24 |             T[i 1][j] = (dt/pow(dz, 2))*(T[i][j 1] - 2*T[i][j]   T[i][j-1])   dt   T[i][j];
      |                                          ~~~~^~~~~
t.c:23:19: note: within this loop
   23 |         for (j=1;j<N;j  ){
      |                   ^
t.c:20:18: warning: iteration 99 invokes undefined behavior [-Waggressive-loop-optimizations]
   20 |         T[0][j 1]=b;
      |         ~~~~~~~~~^~
t.c:19:15: note: within this loop
   19 |     for (j=0;j<N 1;j  ){
      |              ~^~~~
t.c:15:16: warning: iteration 101 invokes undefined behavior [-Waggressive-loop-optimizations]
   15 |         T[i][0]=b;
      |         ~~~~~~~^~
t.c:14:15: note: within this loop
   14 |     for (i=0;i<N 2;i  ){
      |              ~^~~~

CodePudding user response:

As vm666 pointed out, the compiler notices that the loop reads past the end of the array T, which is undefined behaviour. The compiler is allowed to do anything with undefined behaviour. In this case - where a certain iteration of the loop - the compiler might have assumed that iteration 101 never happens. This is an allowed interpretation of undefined behaviour, because it's (surprisingly) often correct. Then, the compiler can reason that if iteration 101 never happens, some magical force (like calling exit) must stop the loop before iteration 101, so it can never get past iteration 101, so it never needs to check whether it gets past iteration 101, and the program can be a bit faster if it never actually checks and the loop is just infinite.

Sneaky compiler.

If this is actually the reason, you can fix it by not printing numbers from outside the array. It seems you accidentally added another 1 to both the i and j loops so just take that off again.

  • Related