2016-04-23 84 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永遠不會執行(例如打印報表。在這個函數中永遠不會執行),返回的vrhovt [0]的值當然是它開始的值,vx。沒有編譯器錯誤(使用gcc 4.8.1和-std = C++ 11和-O2標籤)這非常奇怪,因爲我已經測試了它們自己的特定函數(在Riemann類之外),它們工作 - 問題似乎是他們在這個班上。但是,考慮到黎曼解算器的工作原理,我有理由讓這些函數成爲一個班級,並且真的想找到一種方法來完成這項工作,而不需要進行大規模的重寫和改變班級結構。

任何幫助非常感謝!謝謝! :)

回答

0

可能P未正確初始化。至少我沒有在你的代碼中看到它。 P需要小於PG,否則您已經落後於集成的結束。

此外,不要使用綁定,而是使用lambda。我認爲綁定在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

我剛剛測試過它,它的工作負步長。我很高興這是固定的,希望別人會看到這一點,並從我的愚蠢學習。我還會使用lambda函數進行更新以保持最新狀態。再次感謝你! – CBerard14