私は現在、クラス内で微分方程式を解くためにgsl_odeiv2メソッドを使用しています。しかし、よく知られているメンバ関数の問題のため、私はクラスの中で私のode-systemを定義することはできません。私は現在、回避策を使用しています: 私はグローバル名前空間で私のODEを定義します。gsl_odeiv2 in C++クラス:int(...)のテンプレートラッパー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
}
}
、パラメータとしてcoustomタイプ(クラス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};
...
私のシステムをinitaliseする:これはうまくいきますが、グローバルな名前空間で微分方程式を宣言する必要があるため、ちょっと混乱します。
gsl_functions stackoverflow.com/questions/.../how-to-avoid-static-member-function-when-using-gsl-with-c/...にテンプレートラッパーを使用して、C++クラスでそれらを使用できることがわかっています。私は実際にそこに記述されているラッパーを使用して、クラス内のgsl_integrationメソッドの関数を定義し、完全に動作し、書くのがはるかにクリーンでコードも少なくなっています。例えば:私は私のstar_eosは、関数の内部で上記直接使うからオブジェクトを使用することができます:私はint型(ダブルR、constのダブル*のPM、このようなテンプレートのラッパーを記述しようとした
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);
ダブル* dPdM、void *型のp )関数はgsl_odeiv2_systemが必要ですが、私はC++を初めて使っていて、テンプレート/ static_castメカニズムを完全に理解していないため失敗しました。
gsl_odeivメソッドとそのodeシステムをテンプレートラッパーとともに使用する人がいますか?あるいは、gsl_functionsで説明したものと似たテンプレートをint(...)odeで作ることができます。