2016-07-27 3 views
1

의 템플릿 래퍼 나는 현재 미분 방정식을 해결하기 위해 내 수업 내부 gsl_odeiv2 방법을 사용하고 있습니다. 그러나 잘 알려진 memberfunction 문제로 인해 클래스 내 내 ode-system을 정의 할 수 없습니다. 나는 글로벌 네임 스페이스 내 송시를 정의 :gsl_odeiv2 : 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}; 
... 

내 시스템을 활성화하십시오. 이것은 잘 동작하지만 전역 네임 스페이스에서 미분 방정식을 선언해야하기 때문에 약간 지저분합니다.

가 나는 C++ 클래스에서 사용하는 gsl_functions stackoverflow.com/questions/.../how-to-avoid-static-member-function-when-using-gsl-with-c/...에 대한 템플릿 래퍼를 사용하는 것이 가능하다는 것을 알고있다. 나는 실제로 클래스 내에서 gsl_integration 메소드에 대한 함수를 정의하기 위해 거기에 설명 된 래퍼를 사용하며 완벽하게 작동하며 작성하기가 훨씬 깨끗하고 코드가 적습니다. 예를 들어 : 내 star_eos가 함수 내에서 위의 direcly에서 객체 사용할 수 있습니다 : 나는 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, 무효 * P) 함수는 gsl_odeiv2_system이 필요하지만 C++을 처음 사용하고 템플릿/static_cast 메커니즘을 완전히 이해하지 못해 실패했습니다.

템플릿 래퍼 gsl_odeiv 방법과는 ODE 시스템을 사용하는 사람이 있습니까? 또는 gsl_functions에 대해 위에서 설명한 것과 비슷한 템플리트를 만들 수도 있지만 int (...) ode에 대해 만들 수 있습니까?

답변

0

나는 내 문제에 대한 해결책을 발견하는 글로벌 네임 스페이스에 설정된 미분 방정식 작업을 얻었는지에 대해 생각. 이제는 작동하는 래퍼가 있습니다. 그래서 bassically 때문에 시스템의 크기와 포인터를 지정하는 희미한 INT있다 ode_System 내 새로운 클래스 에 저장된 모든 내 특정 정보를 가지고

//gsl_wrapper.hpp 
#include <iostream> 
#include <vector> 
#include <functional> 

#include <gsl/gsl_math.h> 
#include <gsl/gsl_errno.h> 

namespace gsl_wrapper { 

    class ode_System{ 
    public: 
     ode_System(int); 
     int dim; 
     std::function<double (double, const double *, double *, int)> *df; 

    }; 

    struct ode_struct {ode_System *ode;}; 
    int ode(double, const double *, double *, void *); 
} 

//gsl_wrapper.cpp 
#include "../../include/gsl_wrapper.hpp" 

namespace gsl_wrapper { 

    ode_System::ode_System(int dim) { 
     this->dim=dim; 
    } 

    int ode(double r, const double *f, double *df, void *p) { 
     struct ode_struct * params = (struct ode_struct *)p; 
     ode_System *odeFunc = (params->ode); 

     int dim = odeFunc->dim; 
     std::function<double (double, const double *, double *, int)> dfeq=*(odeFunc->df); 

     for(int i=0;i<dim;i++){ 
      df[i] = dfeq(r,f,df,i); 
     } 

     return GSL_SUCCESS; 
    } 

}; 

: 글로벌 네임 스페이스에서 나는 다음과 같은이 표준 : : 기능 개체. 이 객체는 mathematica 미분 방정식 시스템을 나타냅니다. I는 gsl_odeiv2를 사용하여 미분 방정식을 해결하려는 제 클래스 내부

는 I 시스템은 람다 함수를 사용하는 것으로 정의

std::function<double (double, const double *, double *, int)> dPMeq = [=](double r , const double * PM, double *dPdM, int i)->double{ 
    double df; 
    switch (i) 
    { 
     case 0: 
      df = ... // df_1/dr 
      break; 
     case 1: 
      df = ... // df_2/dr 
      break; 
     case 2: 
      df = ... // df_3/dr 
      break; 
     default: 
      GSL_ERROR_VAL ("comp_tov_eq:", GSL_FAILURE,GSL_FAILURE); 
      df = 0; 
    } 
    return df; 
}; 

상기 시스템은 3 개 차 방정식의 결합 시스템을 나타낸다. 나는 다음 오른쪽 차원으로 ode_System 객체를 선언하고 내 정의 된 시스템의 기능 포인터 DF을 설정합니다. 그럼 난 단지 그 시스템에 대한 참조 및 수행과 구조를 필요 :이뿐만 아니라 단지 작동 말할 수있는 지금까지

ode_System tov(3); 
tov.df= &dPMeq; 
struct ode_struct comp_tov_params = {&tov}; 
gsl_odeiv2_evolve *comp_tov_evolve = gsl_odeiv2_evolve_alloc(3); 
gsl_odeiv2_system comp_tov_system = {ode, NULL, 3, &comp_tov_params}; 
... 

을 (또는 : 나는 gsl_odeiv2_system 내 클래스 내에 정의 내 미분 방정식을 사용할 수 있습니다 나쁜) 내 질문에 제시 구현으로. 그것은 약간 정리를 사용할 수 있지만 원칙적으로 이것은 잘 작동합니다.

그러나 사람이 할 수있는 더 좋은 방법을 알고 있다면이 공유 주시기 바랍니다!