2016-04-23 10 views
1

これは私が取り組んできた個人的なプロジェクトです。ここで何が起こっているのか分かりません(C++を学ぶだけです)。私は非常によく似た問題に対する答えを見つけましたが、私は解決策を実行しているようには見えません。何が起こっているboost :: odeintはメンバークラス内で呼び出されました

#include <iostream> 
#include <cmath> 
#include <complex> 
#include <boost/array.hpp> 
#include <boost/numeric/odeint.hpp> 
#include <gsl/gsl_roots.h> 

class Riemann 
{ 
public: 
    // constructor 
    Riemann(double leftP, double rightP, double leftrho, double rightrho, \ 
     double leftvx, double rightvx, double leftvy, double rightvy, double gam); 

    double PL,PR,rhoL,rhoR,vxL,vxR,vyL,vyR,gamma; 

    // function prototypes 
    double shockvelocity(double Pg, int sign); 
    double rarefactionvelocity(double Pg, int sign); 
    void RfODE(const boost::array<double,6> &vrhovt, \ 
     boost::array<double,6> &dvrhovtdp, double t); 

// ~Riemann(); 
}; 

Riemann::Riemann(double leftP, double rightP, double leftrho, double rightrho, \ 
     double leftvx, double rightvx, double leftvy, double rightvy, double gam){ 
    // constructs Riemann public variables 
} 

double Riemann::shockvelocity(double Pg,int sign){ 
    // calculate a shock velocity, not important here... 
} 



void Riemann::RfODE(const boost::array<double,6> &vrhovt, \ 
    boost::array<double,6> &dvrhovtdp, double t){ 
    // calculates the ODE I want to solve 

} 

double Riemann::rarefactionvelocity(double Pg, int sign){ 
    double dpsize=0.00001; 
    double P,rho,vx,vy,vtest; 
    // 
    boost::array<double,6> vrhovt = {vx,rho,vy,double(sign),P,gamma}; // initial conditions 
    boost::numeric::odeint::integrate(std::bind(&Riemann::RfODE,std::ref(*this),std::placeholders::_1, 
     std::placeholders::_2, std::placeholders::_3),vrhovt,P,Pg,dpsize); 
    std::cout<<"vRarefaction="<<vrhovt[0]<<std::endl; 
    return vrhovt[0]; 
} 

double FRiemann(double Pg, void* Riemannvalues){ 
    Riemann* Rvals = (Riemann*)Riemannvalues; 
    // calls on Riemann::rarefactionvelocity at some point 
} 


int main(){ 
    double PL= 1000.0; 
    double PR= 0.01; 
    double rhoL= 1.0; 
    double rhoR= 1.0; 
    double vxL= 0.0; 
    double vxR= 0.0; 
    double vyL= 0.0; 
    double vyR= 0.0; 
    double gam = 5.0/3.0; 

    // calls FRiemann to get a root 

} 

コードがリーマン:: rarefactionvelocityがうまく呼び出し、通過しているが、何らかの理由RfODE用(EX print文を実行されることはありません。ここでは重要でないビットの一部と私のコードは出てトリミング。この関数の中では決して実行されません)、返されるvrhovt [0]の値は当然vxで始まる値です。コンパイラエラーはありません(gcc 4.8.1と-std = C++ 11と-O2タグを使用)これは非常に奇妙です。私は希薄化特有の関数を独自に(Riemannクラスの外で)テストし、仕事 - 問題は、彼らがこのクラスにいるようだ。リーマンのソルバーがどのように機能するかを考えると、これらの関数からクラスを作成する理由があり、クラス構造を変更したり大量のリライトをせずにこの作業を行う方法を実際に探したいと思っています。

ご協力いただきありがとうございます。ありがとうございました! :)

答えて

0

Pが正しく初期化されていない可能性があります。少なくともあなたのコードには表示されません。 PPGより小さくする必要があります。そうしないと、統合の最後にはすでに遅れています。

また、bindを使用しないで、代わりにラムダを使用してください。バインドはC++ 11/C++ 14で廃止されていると思います。バインドによって正しい参照が得られない可能性があります。

double Riemann::rarefactionvelocity(double Pg, int sign) 
{ 
    // ... 

    // not tested 
    using namspace boost::numeric::odeint; 
    integrate([this](auto const& x, auto &dxdt ,auto t) { 
     this->RfODE(x, dt, t); } ,vrhovt,P,Pg,dpsize); 
} 
+0

あなたが問題を発見したように見えますが、それはまったく期待していなかったようです。私が自分の希薄化関数をテストしていたとき、私はP = Pgのときにはリーマンソルバーで呼び出される必要があります(これは、衝撃波の代わりに希薄波)。 P> Pgで独自の希薄化関数をテストすると、同じ望ましくない振る舞いをします(統合全体をスキップします) ありがとうございました!このケースを扱うことができる別のインテグレータを見つける必要があるように見えます。 – CBerard14

+0

私はそれをテストしただけで、負のステップサイズで動作します。私はこれが修正されてうれしいですし、うまくいけば他の人がこれを見て、私の愚かさから学ぶでしょう。また、ラムダ関数を使って最新の状態に更新します。ありがとうございました! – CBerard14

関連する問題