2016-04-23 12 views
1

Dies ist ein persönliches Projekt, an dem ich gearbeitet habe und ich kann nicht herausfinden, was hier vor sich geht (nur lernen C++). Ich habe Antworten auf sehr ähnliche Probleme gefunden, aber ich kann die Lösung nicht ausführen. Hier ist mein Code mit einigen der unwichtigen Bits getrimmt:boost :: Odein genannt innerhalb Mitglied Klasse

#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 

} 

Was geschieht ist der Code durchläuft, ruft Riemann :: rarefactionvelocity ganz gut, aber aus irgendeinem Grund RfODE wird nie ausgeführt (ex print-Anweisungen. in dieser Funktion niemals ausführen) und der Wert für vrhovt [0] zurückgegeben ist natürlich der Wert, mit dem es begann, vx. Auch keine Compilerfehler (mit gcc 4.8.1 und -std = C++ 11 und -O2-Tags) Das ist sehr seltsam, weil ich die rarefaction-spezifischen Funktionen (außerhalb der Riemann-Klasse) und sie selbst getestet habe Arbeit - das Problem scheint zu sein, dass sie in dieser Klasse sind. Angesichts der Funktionsweise von Riemann-Lösern hatte ich jedoch Gründe, aus diesen Funktionen eine Klasse zu machen, und ich würde wirklich gerne einen Weg finden, um das zu erreichen, ohne die Klassenstruktur massiv zu überarbeiten und zu ändern.

Jede Hilfe wird sehr geschätzt! Vielen Dank! :)

Antwort

0

Möglicherweise ist P nicht korrekt initialisiert. Zumindest sehe ich es nicht in deinem Code. P muss kleiner sein als PG sonst sind Sie bereits hinter dem Ende der Integration.

Verwenden Sie auch nicht binden, verwenden Sie stattdessen ein Lambda. Ich denke, Bind ist in C++ 11/C++ 14 irgendwie veraltet. Es ist möglich, dass die Bindung die Referenzen nicht korrekt erhält.

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

Es sieht aus wie Sie das Problem gefunden haben und es war überhaupt nicht das, was ich erwartet hatte. Als ich meine Rarefaction-Funktion selbst getestet habe, habe ich einen Fall mit P = Pg (weil das das Kriterium dafür ist, wann wir sehen würden eine Verdünnungswelle anstelle einer Schockwelle). Das Testen der Rarefaction-Funktion mit P> Pg ergibt das gleiche unerwünschte Verhalten (Überspringen der Integration vollständig) Vielen Dank für Ihre Hilfe! Sieht so aus, als müsste ich einen anderen Integrator finden, der mit diesem Fall umgehen kann. – CBerard14

+0

Ich habe es gerade getestet und es funktioniert mit einer negativen Schrittgröße. Ich bin so froh, dass dies behoben ist und hoffentlich werden andere dies sehen und von meiner Dummheit lernen. Ich werde auch mit einer Lambda-Funktion aktualisieren, um aktuell zu bleiben. Danke nochmal! – CBerard14