I'm trying to set up an equations solver using the GSL root finder routines. In short, I have various combinations of equations that are functions of two variables (temperature & density). I've already coded these equations and have proven them to be accurate. I'm now attempting to calculate the required variables for various combinations of their results (pressure, specific enthalpy, specific entropy, etc).
In my first attempt I've run into a problem with the function pointers utilized by GSL for solving (
https://www.gnu.org/software/gsl/manual/html_node/Providing-the-function-to-solve.html). The pertinent parts of the code are below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
class State
{
public:
State(); // Constructor
virtual ~State(); // Destructor
// Simple Set functions - Probably won't be used much.
/* code here */
// Complex Set Functions
/* Other set functions */
//This is the one causing problems
void setState_PT(num_t P, num_t T); // Sets the state on the given Pressure & Temperature
protected:
// Helper functions and structures required set functions
struct helpPressureStruct
{
num_t T; // Temperature
num_t desPress; // desired pressure
};
double helpPressurePT(double P, void* params);
private:
num_t temperature;
num_t density;
num_t pressure;
};
void State::setState_PT(num_t P, num_t T)
{
if (P == helmholtz::psat(T))
{
setState_Tsat(T);
return;
}
int status;
int iter = 0, max_iter = 100;
const gsl_root_fsolver_type* solver_t;
gsl_root_fsolver* s;
double r = 0;
double rhomin = 0.0, rhomax = 2000;
gsl_function F;
struct helpPressureStruct params;
params.T = T;
params.desPress = P;
F.function = &helpPressurePT;
F.params = ¶ms;
solver_t = gsl_root_fsolver_brent;
s = gsl_root_fsolver_alloc(solver_t);
gsl_root_fsolver_set(s, &F, rhomin, rhomax);
do
{
iter++;
status = gsl_root_fsolver_iterate(s);
r = gsl_root_fsolver_root(s);
rhomin = gsl_root_fsolver_x_lower(s);
rhomax = gsl_root_fsolver_x_upper(s);
status = gsl_root_test_interval(rhomin, rhomax, 0, 0.001);
}
while (status == GSL_CONTINUE && iter < max_iter);
gsl_root_fsolver_free(s);
/* Finish setting the state using results from above */
return;
}
double State::helpPressurePT(double P, void* params)
{
struct helpPressureStruct* pHelp = (struct helpPressureStruct*) params;
num_t T = pHelp->T;
num_t desPress = pHelp->desPress;
return helmholtz::p(T, P) - desPress;
}
|
|52| error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&State::helpPressurePT’ [-fpermissive]
However, making that line:
F.function = &State::helpPressurePT;
produces
error: cannot convert ‘double (State::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment
I understand this is a pointer to member function, which doesn't behave like a normal function pointer. Unfortunately, the typical searches are turning up answers that are more difficult to understand than the original error. In any case, how would you kind folks recommend getting this function over to GSL for solving?