Difference Equation Blowing Up - C
An answer to this question on Stack Overflow.
Question
for one my classes I am supposed to write a program that implements a differential equation to find the temperature of a 100 degree rod where both ends are dipped in an ice bath. The difference equation is given to solve it. I have an array that is split in the x direction as the segments of the rod and in the y direction as the iterations of time. An r value determines the speed at which the rod cools. It might be worth noting that how the actual program is implemented isn't that important, this program is meant to run on a computer cluster and the point of the assignment is to introduce us to the issuing of jobs on the cluster. The program still has to be correct though (obviously), and I can't even get to that point.
I'm having trouble with my program, because my array seems to start getting garbage data at (seemingly) random points in the time iterations. I have Netbeans and have tried debugging this but the last time I did it I could not peek into the different elements of the array variable (making the debugging process practically useless) and now I can even get it to stop at my break point. I've been banging my head against this problem for a while and am hoping someone much wiser than me can simply "see" the problem and help me out.
Thanks.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
int segmentsl;
int segmentst;
float rvalue;
int i,j;
float k;
//Pull in initial data
printf("Enter as integers without spaces: Number of Segments - Length, Number of Segments - time ,value\n");
scanf("%d,%d,%f", &segmentsl,&segmentst,&rvalue);
float tempvstime[segmentsl][segmentst];
//at t0 -> temp = 100sin(pi*x)
for(i = 0; i < segmentsl; i++){
k = (float)(i/(segmentsl-1));
tempvstime[i][0] = 100*sin(M_PI*k);
printf("%f,",tempvstime[i][0]);
}
printf("\n\n\nEND OF INITIALIZATION \n\n\n");
for(j = 0; j < (segmentst-1); j++){
for(i = 0; i < segmentsl; i++){
if(i == 0 || i == (segmentsl - 1)){tempvstime[i][j] = 0;}
else{
tempvstime[i][j+1] = (rvalue*tempvstime[i-1][j]) + ((1-(2*rvalue))*tempvstime[i][j]) + (rvalue*tempvstime[i+1][j]);
}
}
}
for(j = 0; j < segmentst; j++){
for(i = 0; i < segmentsl; i++){
printf("%f,",tempvstime[i][j]);
if(i == segmentsl - 1){printf("\n");}
}
}
}
Here's some sample output:
Enter as integers without spaces: Number of Segments - Length, Number of Segments - time ,value
6,10,0.5
0.000000,58.778526,95.105652,95.105652,58.778522,0.000000,
END OF INITIALIZATION
0.000000,58.778526,95.105652,95.105652,58.778522,0.000000,
0.000000,47.552826,76.942093,76.942085,47.552826,0.000000,
0.000000,38.471046,62.247456,62.247459,38.471043,0.000000,
0.000000,31.123728,50.359253,50.359249,31.123730,0.000000,
0.000000,25.179626,40.741489,40.741493,25.179625,0.000000,
0.000000,20.370745,32.960560,32.960556,-nan,0.000000,
0.000000,16.480280,26.665649,-nan,-nan,0.000000,
0.000000,13.332825,-nan,-nan,-nan,0.000000,
0.000000,-nan,-nan,-nan,-nan,0.000000,
0.000000,-nan,-nan,-nan,-nan,0.000000,
Answer
I notice that this line:
k = (float)(i/(segmentsl-1));
is performing integer division. Since i<segmentsl it will be the case that i/segmentsl is 0. This is probably not what you intend.
It is also the case that farther in your program, you use tempvstime[i][j+1] and tempvstime[i][j], while both should be j+1.
A modified version of your program which runs correctly and has altered variable names and fewer parentheses in the math follows.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void){
int width, maxt;
float rvalue;
int i,t;
float k;
//Pull in initial data
printf("Enter as integers without spaces: Number of Segments - Length, Number of Segments - time ,value\n");
scanf("%d,%d,%f", &width,&maxt,&rvalue);
float tempvstime[width][maxt];
fprintf(stderr,"Initializing with %d segments...",width);
//at t0 -> temp = 100sin(pi*x)
for(i = 0; i < width; ++i)
tempvstime[i][0] = 100*sin((M_PI*i)/(width-1));
fprintf(stderr,"done.\n");
for(t = 0; t <(maxt-1); ++t){
for(i = 0; i < width; ++i){
if( i == 0 || i == (width-1) ){
tempvstime[i][t+1] = 0;
} else {
tempvstime[i][t+1] = rvalue*tempvstime[i-1][t] + (1-2*rvalue)*tempvstime[i][t] + rvalue*tempvstime[i+1][t];
}
}
}
for(t = 0; t < maxt; t++){
for(i = 0; i < width; i++)
printf("%f,",tempvstime[i][t]);
printf("\n");
}
}