差分問題を解くための2つのコードを書きました。どちらも予測子補正ツールを使っています。この2つのコードの違いは何ですか?
最初は差分系の解法でもありますので、基本的には系で解く方程式の数に等しい大きさのベクトルy
を使いますので、基本的には各工程を上書きしています前のステップを保存します。
代わりに、ステップ数に等しいサイズのベクトルを使用するので、使用している要素を簡単に制御できます。私はデバッグの多くをやったが、私は私が間違って何をしたか理解していない最初のルーチンに使用されるもの、および第二のルーチン
ための第二1:
私は2つの異なる(しかし、基本的に同一の)機能を書きました。ここで
ソルバの2つの異なるバージョンです:
# include <iostream>
# include <functional>
# include <vector>
# include <string>
# include <cmath>
# include <fstream>
# include <valarray>
using namespace std;
std::vector<std::function<const double(const double t , std::valarray<double> u)>> func ;
auto f2 = [](double t , double u) {return -20*u+20*sin(t)+cos(t) ; } ;
auto numFun = [](double t , std::valarray<double> u) {return -20*u[0]+20*sin(t)+cos(t) ; } ;
int main(){
double t0 = 0.0 ;
double tf = 2.5 ;
double dt = 0.01;
const int N = (tf-t0)/dt;
func.push_back(numFun);
auto& f = func ;
double t1 ;
std::valarray<double> y1 ;
y1.resize(func.size()) ; // size = 1
std::valarray<double> yp1 ;
yp1.resize(func.size()) ; // size = 1
std::vector<double> t2(N+1) ;
std::vector<double> y2(N+1) ;
std::vector<double> yp2(N+1) ;
std::vector<double> u(1);
u.at(0) = 1.0 ;
t1 = t0 ;
for(auto i=0; i< u.size() ; i++)
{
y1[i]= u.at(i);
yp1[i] = u.at(i);
}
ofstream fn("output1.dat", ios::out);
for(auto i=1 ; i <=N ; i++)
{
fn << t1 << " " ;
for(auto j =0 ; j < y1.size() ; j++)
fn << y1[j] << " " ;
fn << endl ;
for(auto j=0 ; j < y1.size() ; j++)
{
yp1[j] = yp1[j] + dt * f[j](t1 , y1) ;
y1[j] += dt/2 * (f[j](t1 , y1) + f[j](t1+dt , yp1));
}
t1+=dt ;
}
fn.close();
/* -------------------- Vector version --------------------------------- */
ofstream fn2("output2.dat", ios::out);
t2.at(0) = t0 ;
y2.at(0) = u.at(0) ;
yp2.at(0) = u.at(0) ;
fn2 << t2.at(0) << " " ;
fn2 << y2.at(0) << " " ;
fn2 << endl ;
for(auto i=1; i <= N ; i++)
{
t2.at(i) = t2.at(i-1) + dt ;
// Predictor step (Exp Euler)
yp2.at(i) = y2.at(i-1) + dt * f2(t2.at(i-1), y2.at(i-1)) ;
y2.at(i) = y2.at(i-1) + dt/2 * (f2(t2.at(i-1), y2.at(i-1)) + f2(t2.at(i), yp2.at(i))) ;
fn2 << t2.at(i) << ' ' << y2.at(i) << " " ;
fn2 << endl;
}
fn2.close();
return 0;
}
正しい結果はどれですか? –
output2.datので、第2ソルバー –
の最初の段落はテキストの壁であり、それに従うのは難しい – bolov