c++;1D波函数不良输出(有限差分) 我对C和C++编程有点新,我已经在R中实现了,现在我尝试用C++编写。

c++;1D波函数不良输出(有限差分) 我对C和C++编程有点新,我已经在R中实现了,现在我尝试用C++编写。,c++,c++11,C++,C++11,我使用了std::vector和std::vector并按值传递,因为它一次只需要传递一行来填充std::vector u(t.size(),vector(n)),它的大小基于h,k和总运行时间 我遇到的问题是,当波穿过轴时,输出数据似乎出错。我无法从逻辑上找出问题所在,但我可能遗漏了一些东西,我认为更可能是我误用了std::vector,或者存在一些我无法识别的数据类型冲突 也许其他人可以看到我看不到的东西,以下是我的代码: #include <iostream> #include

我使用了
std::vector
std::vector
并按值传递,因为它一次只需要传递一行来填充
std::vector u(t.size(),vector(n))
,它的大小基于
h
k
和总运行时间

我遇到的问题是,当波穿过轴时,输出数据似乎出错。我无法从逻辑上找出问题所在,但我可能遗漏了一些东西,我认为更可能是我误用了
std::vector
,或者存在一些我无法识别的数据类型冲突

也许其他人可以看到我看不到的东西,以下是我的代码:

#include <iostream>
#include<math.h>
#include<vector>
#include<fstream>

using namespace std;

vector<double> takestep (double h,double k,vector<double> ukm1,vector<double> ukm2){

   int n = ukm1.size();

   vector<double> uk(n);

   uk[0]=0;
   uk[n-1]=0;

   for(int i = 1; i < (n-1); i++)
   {
       uk[i] = (pow(k,2)/pow(h,2))*(ukm1[i+1]-2*ukm1[i]+ukm1[i-1])+2*ukm1[i]-ukm2[i];
   }

   return uk;
}

//-----------------------------------------------------------------
vector<vector<double> > solve1D (double tf, double h, double k, vector<double> ukm1, vector<double> ukm2){

  int n = ukm1.size(); 
  vector<double> t((int)tf/k);

  for(int i = 0; i<t.size(); i++)
  {
      t[i] = k*i;
  }

  vector<vector<double> > u(t.size(),vector<double>(n));

  u[0] = ukm1;
  u[1] =  takestep(k,h,ukm1,ukm2); 

  for(int i = 2;i<t.size();i++)
  {
      u[i]= takestep(h,k,u[i-1],u[i-2]);
  }

  return u;
}

//====================================================================
int main(int argc, char** argv) {

 double tf = 12.0;
 double k = .005;
 double h = .01;

 vector<double> x(1.0/h);

 for(int i = 1;i<x.size();i++)
 {
    x[i] = i*h;
 }

 vector<double> yo(x.size()); 

 yo[0]=0;
 yo[x.size()-1]=0;

 for(int i = 1;i<yo.size()-1;i++)
 {
     yo[i] = 0.5*sin(x[i]*M_PI);
 }

 vector<vector<double> > u = solve1D(tf,k,h,yo,yo);

 ofstream myfile;
 myfile.open ("Wave1D_output.txt");


 for(int i = 0;i<u.size();i++)
 {

    for(int j = 0;j<yo.size();j++)
    {
       myfile<< u[i][j]<<"\t";
    }

    myfile<<"\n"; 
 }
 myfile.close();
 return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
向量步进(双h,双k,向量ukm1,向量ukm2){
int n=ukm1.size();
矢量uk(n);
uk[0]=0;
uk[n-1]=0;
对于(int i=1;i<(n-1);i++)
{
uk[i]=(pow(k,2)/pow(h,2))*(ukm1[i+1]-2*ukm1[i]+ukm1[i-1])+2*ukm1[i]-ukm2[i];
}
返回英国;
}
//-----------------------------------------------------------------
向量解算1D(双tf,双h,双k,向量ukm1,向量ukm2){
int n=ukm1.size();
向量t((int)tf/k);

对于(int i=0;i所以,原来错误是………..我在初始调用中向后发送了h和k到解算器,我在打印时间向量的大小时发现了这一点,它是1200而不是2400。最终保留了原始索引,因为这不是问题所在。如上所述,我添加了一些注释:

    #include <iostream>
    #include<math.h>
    #include<vector>
    #include<fstream>

    using namespace std;

vector<double> takestep(double h,double k,vector<double> ukm1,vector<double> ukm2){

   int n = ukm1.size();//set n to number of elements in of input array
   vector<double> uk(n);//new array of same size
   uk[0]=0;  //
   uk[n-1]=0;//set ends to zero 

   for(int i = 1;i<(n-1);i++){//for i in length of uk
       uk[i]=(pow(k,2)/pow(h,2))*(ukm1[i+1]-2*ukm1[i]+ukm1[i-1])+2*ukm1[i]-ukm2[i];//finite difference formula
   }

   return uk;//returns next time step
}
vector<vector<double> > solve1D (double tf, double h, double k, vector<double> ukm1, vector<double> ukm2){

  int n = ukm1.size(); //set n to number of elements in input array
  vector<double> t(round(tf/k));//set size of sime sequence (final time/delta time)

  for(int i = 0; i<t.size(); i++){
      t[i] = k*(i+1);                 //fill time array with proper sequence

  }

  vector<vector<double> > u(t.size(),vector<double>(n));//create 2D array to store all the time steps

  u[0] = ukm1;//set initial state
  u[1] =  takestep(k,h,ukm1,ukm2); //set first time step
  for(int i = 2;i<t.size();i++){
      u[i]= takestep(h,k,u[i-1],u[i-2]);//take all the other time steps
  }

  return u;//return array with all steps
}
int main(int argc, char** argv) {

 double tf = 12.0;//set final time for test
 double k = .005;//set time step
 double h = .01;//set distance for finite difference
 vector<double> x((int)round(1.0/h));//create vector to store x steps
 for(int i = 0;i<x.size();i++){
    x[i] = i*h;                //fill with proper distance steps
 }
 vector<double> yo(x.size());//create vector to store wave function
 for(int i = 1;i<yo.size()-2;i++){
 yo[i] = 0.5*sin(x[i]*M_PI);      //fill with function values
 }
vector<vector<double> > u = solve1D(tf,h,k,yo,yo);//send to solver
#包括
#包括
#包括
#包括
使用名称空间std;
向量步进(双h,双k,向量ukm1,向量ukm2){
int n=ukm1.size();//将n设置为输入数组中的元素数
向量uk(n);//相同大小的新数组
uk[0]=0//
uk[n-1]=0;//设置结束为零

对于(int i=1;i所以,原来错误是………..我在最初的调用中向后发送了h和k到解算器,我在打印时间向量的大小时发现了这一点,它是1200而不是2400。最终保留了原始索引,因为这不是问题所在。如上所述,我添加了一些注释:

    #include <iostream>
    #include<math.h>
    #include<vector>
    #include<fstream>

    using namespace std;

vector<double> takestep(double h,double k,vector<double> ukm1,vector<double> ukm2){

   int n = ukm1.size();//set n to number of elements in of input array
   vector<double> uk(n);//new array of same size
   uk[0]=0;  //
   uk[n-1]=0;//set ends to zero 

   for(int i = 1;i<(n-1);i++){//for i in length of uk
       uk[i]=(pow(k,2)/pow(h,2))*(ukm1[i+1]-2*ukm1[i]+ukm1[i-1])+2*ukm1[i]-ukm2[i];//finite difference formula
   }

   return uk;//returns next time step
}
vector<vector<double> > solve1D (double tf, double h, double k, vector<double> ukm1, vector<double> ukm2){

  int n = ukm1.size(); //set n to number of elements in input array
  vector<double> t(round(tf/k));//set size of sime sequence (final time/delta time)

  for(int i = 0; i<t.size(); i++){
      t[i] = k*(i+1);                 //fill time array with proper sequence

  }

  vector<vector<double> > u(t.size(),vector<double>(n));//create 2D array to store all the time steps

  u[0] = ukm1;//set initial state
  u[1] =  takestep(k,h,ukm1,ukm2); //set first time step
  for(int i = 2;i<t.size();i++){
      u[i]= takestep(h,k,u[i-1],u[i-2]);//take all the other time steps
  }

  return u;//return array with all steps
}
int main(int argc, char** argv) {

 double tf = 12.0;//set final time for test
 double k = .005;//set time step
 double h = .01;//set distance for finite difference
 vector<double> x((int)round(1.0/h));//create vector to store x steps
 for(int i = 0;i<x.size();i++){
    x[i] = i*h;                //fill with proper distance steps
 }
 vector<double> yo(x.size());//create vector to store wave function
 for(int i = 1;i<yo.size()-2;i++){
 yo[i] = 0.5*sin(x[i]*M_PI);      //fill with function values
 }
vector<vector<double> > u = solve1D(tf,h,k,yo,yo);//send to solver
#包括
#包括
#包括
#包括
使用名称空间std;
向量步进(双h,双k,向量ukm1,向量ukm2){
int n=ukm1.size();//将n设置为输入数组中的元素数
向量uk(n);//相同大小的新数组
uk[0]=0//
uk[n-1]=0;//设置结束为零

对于(int i=1;i请尝试在代码中添加一些注释来描述其预期功能,并在函数
takestep()中打破等式
转换为几个简单易懂的关系。最后,尝试将变量名称更改为有意义的名称,而不是
i
j
k
等。完成此操作后,如果您自己还没有解决问题,我们将能够帮助您。传递两次yo来解决1D有什么意义?这是一种笨拙的方式要获得同一向量的两个副本,您不需要对它们中的任何一个执行任何操作。在takestep函数中使用ukm1和ukm2很重要,但除非我遗漏了什么,否则不会。它们只是同一向量的副本。此外,请尝试使用vector::at运算符而不是原始[]运算符-这会发现您访问数组超出范围,以防万一。另外两条注释:由于循环从1开始,因此您似乎从未获得x[0]的值。此外,使用双精度构造向量是危险的。编译器应该对此发出警告。您打算构造大小为(1.0/.01=100)的向量吗,对吗?如果双精度表示非常接近100,但仅为99.9999999…,它将删除小数部分,留下99。一种安全的廉价方法是(1/h+0.5),但我会考虑你是怎么做的。我明白了,我在看takestep的第一个呼叫。你通过它ukm1和ukm2,我相信在那一点上它将是yo和yo。对吗?别担心@Ziezi,我肯定会为你添加一些评论,不要认为我会像那样把你冷落在外面。我也会致力于swi从原始索引到
vector::at
,因为尽管我在
takeStep()中手动将其设置为零,但我的输出文件中的行的结尾不为零,这表明存在索引问题
。请尝试在代码中添加一些注释,以描述其预期功能,并打破函数中的等式
takestep()
转换为几个简单易懂的关系。最后,尝试将变量名称更改为有意义的名称,而不是
i
j
k
等。完成此操作后,如果您自己还没有解决问题,我们将能够帮助您。传递两次yo来解决1D有什么意义?这是一种笨拙的方式要获得同一向量的两个副本,您不需要对它们中的任何一个执行任何操作。在takestep函数中使用ukm1和ukm2很重要,但除非我遗漏了什么,否则不会。它们只是同一向量的副本。此外,请尝试使用vector::at运算符而不是原始[]运算符-这会发现您访问数组超出范围,以防万一。另外两条注释:由于循环从1开始,因此您似乎从未获得x[0]的值。此外,使用双精度构造向量是危险的。编译器应该对此发出警告。您打算构造大小为(1.0/.01=100)的向量吗,对吗?如果双精度表示非常接近100,但只有99.9999999…,它会去掉小数部分,剩下99。一个安全的廉价方法是(1/h+0.5),但我会考虑你是如何做到的。我明白了,我正在看takestep的第一个调用。你通过它ukm1和ukm2,我相信我会的