【问题标题】:boost::odeint called within member classboost::odeint 在成员类中调用
【发布时间】:2016-04-23 23:43:33
【问题描述】:

这是我一直在从事的个人项目,我不知道这里发生了什么(只是学习 C++)。我找到了非常相似问题的答案,但我似乎无法执行解决方案。这是我的代码,去掉了一些不重要的部分:

#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

}

发生的情况是代码正在执行,调用 Riemann::rarefactionvelocity 就好了,但由于某种原因,RfODE 从未执行(例如,此函数中的打印语句从未执行)并且返回的 vrhovt[0] 的值为当然是它开始时的值,vx。也没有编译器错误(使用 gcc 4.8.1 和 -std=c++11 和 -O2 标记)这很奇怪,因为我已经自己测试了稀疏化特定函数(在 Riemann 类之外)并且它们工作——问题似乎是他们在这个班上。不过,鉴于黎曼求解器的工作原理,我有理由从这些函数中创建一个类,并且真的很想找到一种方法来完成这项工作,而无需进行大量重写和更改类结构。

非常感谢任何帮助!谢谢! :)

【问题讨论】:

    标签: c++ class boost odeint


    【解决方案1】:

    P 可能未正确初始化。至少我没有在你的代码中看到它。 P 需要小于 PG 否则您已经落后于集成的结束。

    另外,不要使用绑定,而是使用 lambda。我认为 bind 在 C++11/C++14 中已经过时了。 bind 可能无法正确获取引用。

    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);
    }
    

    【讨论】:

    • 您似乎发现了问题,但它完全不是我所期望的。当我自己测试我的稀疏函数时,我正在测试一个 P=Pg 时,才应该在黎曼求解器中调用稀疏函数(因为这是我们何时会看到的标准稀疏波而不是冲击波)。使用 P>Pg 单独测试稀疏函数会产生相同的不良行为(完全跳过集成) 感谢您的帮助!看来我需要找到可以处理这种情况的其他集成商。
    • 我刚刚对其进行了测试,它可以在负步长下工作。我很高兴这是固定的,希望其他人会看到这一点并从我的愚蠢中学习。我还将使用 lambda 函数进行更新以保持最新状态。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 2011-01-01
    • 1970-01-01
    相关资源
    最近更新 更多