【发布时间】:2016-07-27 12:23:17
【问题描述】:
我目前在我的课程中使用 gsl_odeiv2 方法来求解微分方程。但是由于众所周知的成员函数问题,我无法在类中定义我的 ode 系统。我目前正在使用一种解决方法: 我在全局命名空间中定义我的 ode:
ODE.hpp:
#include "EoS.hpp"
#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>
namespace ODEs
{
struct tov_eq_params {EoS *eos;};
int tov_eq(double, const double *, double *, void *);
}
ODE.cpp:
namespace ODEs {
int tov_eq(double r, const double *PM, double *dPdM, void *p) {
struct tov_eq_params * params = (struct tov_eq_params *)p;
EoS *eos = (params->eos);
...
return GSL_SUCCESS
}
}
并使用指向自定义类型(EoS 类)对象的指针作为参数。在解决我使用的颂歌的类里面:
...
struct tov_eq_params comp_tov_params = {(this->star_eos)};
gsl_odeiv2_evolve *comp_tov_evolve = gsl_odeiv2_evolve_alloc(3);
gsl_odeiv2_system comp_tov_system = {tov_eq, NULL, 3,&comp_tov_params};
...
初始化我的系统。这工作正常,但有点混乱,因为我需要在全局命名空间中声明我的微分方程。
我知道可以使用 gsl_functions stackoverflow.com/questions/.../how-to-avoid-static-member-function-when-using-gsl-with-c/... 的模板包装器在 C++ 类中使用它们。我实际上使用那里描述的包装器在我的类中为 gsl_integration 方法定义函数,它工作得很好,而且更简洁,编写的代码更少。例如:我可以直接在函数内部使用上面的 star_eos 对象:
auto dBf = [=](double r)->double{
return 4 * M_PI * gsl_pow_2(r) * (this->star_eos)->nbar(this->P(r)) * sqrt(this->expLambda(r))* 1e54;
};
gsl_function_pp<decltype(dBf)> dBfp(dBf);
gsl_function *dB = static_cast<gsl_function*>(&dBfp);
我尝试为 gsl_odeiv2_system 需要的 int(double r, const double *PM, double *dPdM, void *p) 函数编写这样的模板包装器,但我失败了,因为我是 C++ 新手并且没有完全理解它模板/static_cast 机制。
是否有人使用带有模板包装器的 gsl_odeiv 方法及其 ode 系统?或者有人可以想出一个类似于上述 gsl_functions 的模板,但用于 int(...) ode。
【问题讨论】: