差分方程式爆炸 - C.

时间:2013-06-15 22:09:49

标签: c

对于我的一个班级,我应该编写一个程序来实现微分方程,以找到100度杆的温度,其中两端都浸入冰浴中。给出差分方程来解决它。我有一个数组,在x方向上作为杆的分段,在y方向上作为时间的迭代。 r值决定了杆冷却的速度。值得注意的是,实际程序的实现方式并不重要,该程序旨在在计算机集群上运行,分配的目的是向我们介绍在集群上发布的作业。该程序仍然必须是正确的(显然),我甚至无法达到这一点。

我的程序出现问题,因为我的数组似乎开始在时间迭代中的(看似)随机点上获取垃圾数据。我有Netbeans并且已经尝试过调试这个但是上次我这样做时我无法查看数组变量的不同元素(使调试过程几乎没用),现在我甚至可以让它停在我的断点处。我一直在反对这个问题,我希望有一个比我更聪明的人可以简单地“看到”问题并帮助我。

感谢。

这是我的代码:

#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");}
            }
    }

}

以下是一些示例输出:

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,

2 个答案:

答案 0 :(得分:4)

除了

中的整数除法
k = (float)(i/(segmentsl-1));

您设置了错误的终点:

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]); 
    }
  }
}

如果i为0或最后一个索引,则为其他tempvstime[i][j]设置i,设置tempvstime[i][j+1]

您还应为终点设置tempvstime[i][j+1]。否则,在下一次迭代中,使用未初始化(垃圾)值,调用未定义的行为。

在设置k时进行该更改和浮点除法,我得到了合理的值:

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,20.370747,0.000000,
0.000000,16.480280,26.665649,26.665653,16.480278,0.000000,
0.000000,13.332825,21.572968,21.572964,13.332827,0.000000,
0.000000,10.786484,17.452894,17.452896,10.786482,0.000000,
0.000000,8.726447,14.119690,14.119688,8.726448,0.000000,

答案 1 :(得分:0)

我注意到这一行:

k = (float)(i/(segmentsl-1));

执行整数除法。从i<segmentsl开始,i/segmentsl为0.这可能不是你想要的。

在您的计划中,您使用tempvstime[i][j+1]tempvstime[i][j]的情况也是如此,而两者都应为j+1

程序的修改版本,它正确运行并且在数学中改变了变量名称和更少的括号。

#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");
    }

}