CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Symbol lookup error @ new thermophysical model (https://www.cfd-online.com/Forums/openfoam-programming-development/225397-symbol-lookup-error-new-thermophysical-model.html)

stockzahn March 25, 2020 15:53

Symbol lookup error @ new thermophysical model
 
Dear Foamers,


still having issues with my own thermophysical model. It contains functions to calculate different properties with pressure and temperature input. The main function to call is "PN_ByPT(word prop_, scalar p_, scalar T_)" from which other functions are called depending on the name of the property (word prop_).



However, the compilation finishes without error/warning, but when I run an adapted solver (containing the adapted libraries), the code stops with an Symbol lookup error:


Code:

rhoHePimpleFoam: symbol lookup error: /home/ck/OpenFOAM/ck-6/platforms/linux64GccDPInt32Opt/lib/libfluidThermophysicalModels.so: undefined symbol: _Z7PN_ByPTN4Foam4wordEdd
with c++filt \rightarrow


Code:

PN_ByPT(Foam::word, double, double)
That seems strange to me, since I assume it should be something like


Code:

PN_ByPT(Foam::word, Foam::scalar, Foam::scalar)
Although I have the newly compiled library/model in my user project folder and the new library explicitly defined in my solver's Make/options file, also the original OpenFOAM solver (rhoPimpleFoam) stops at the same line with the same symbol lookup error. To get rid of it I have to copy the original thermophysical model into my user project folder, change the Make-files accordingly and compile it.



1) Does anybody know what the problem could be and how to solve it?
2) Could anybody explain why the compilation of my model effects the original OF solvers?


Sincerely,
stockzahn

alexeym March 26, 2020 04:03

Hi,

Foam::scalar is double if OpenFOAM is compiled with double precision (WM_DP).

In general it is not great idea to name modified libraries as original ones. The error states, that solver can not find PN_byPT function in your library. But the error can be misleading, since solver can try to lookup the symbol in original libfluidThermophysicalModels.so. What if you call your modified library "libmesprecieuxfluidThermophysicalModels.so" and load it in controlDict?

stockzahn March 26, 2020 12:23

Dear Alexey,


thanks for your response. Like you suggested I renamed the library files, but for now I didn't include them via controlDict, but still in the Make files. The compilation of the libraries work, but now compiling the solver produces a linker error (very similar, I suppose):


Code:

undefined reference to `PN_ByPT(Foam::word, double, double)'

After some time I find the following:



- If I #include the c-files with the functions in the H-files the compiler/linker recognises the functions, but stops due to multiple definition (see 1.post here: https://www.cfd-online.com/Forums/op...cal-model.html)



- If I don't #include the C-files the compilation of the library works, but the functions don't seem to exist in the library


So maybe I don't understand the processes. I put all the C- and H-files for my model into the include-folder, so they are all copied in to the lnInclude-folder, like every other file as well. I thought that all these files are automatically included into the compilation process, but that doesn't seem to be the case.


If I may ask: Could you maybe give a hint how to organize the files to integrate them into the compilation without getting the multiple definition error?


stockzahn

alexeym March 26, 2020 15:11

Hi,

It would be simpler to comment if you have shown your files, but let's try to imagine.

So, you have solver and thermophysical properties library. Solver consists of single C file (solver.C) with possible additional H files, which are meant only for preprocessing step.

Your library consists of a C file with implementation (library.C) and H file (library.H), which defines interface (I assume, your do not deal with templates here).

You would like your library be linked to the solver, so you put solver.C and library.C into Make/files. And you compile it.

If you would like to have possibility to modify/recompile library without recompilation of the solver, you put it into separate folder and put only library.C into Make/files.

I wonder how do you call PN_ByPT and where it is defined.

stockzahn March 26, 2020 17:38

Dear Alexey,


thanks again. It's quite a lot, therefor I try to break it down to the essential information and the current status:


- Basically I would like to calculate state variables (e.g. rho) with my own equations. Therefore I made my own equationOfState-, transport- and thermo-files, where I inserted my function. E.g. "cv" in thermoI.H, ~line 110



Code:

template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::Cv(const scalar p, const scalar T) const
{
    //return this->Cp(p, T) - this->CpMCv(p, T); //old code
    return PN_ByPT("cv", p, T); //new code
}


- my function PN_ByPT(word prop_, scalar p_, scalar T_) is defined in a file "PN_ByPT.C" and declared in a header file "heliumThermo.H":


Code:

//heliumThermo.H



#ifndef HELIUMTHERMO_H
#define HELIUMTHERMO_H


// declare and define some constants
const double Tcrit{5.1953};   

...



// declare some general functions & templates
template <class number>       
number FORTSIGN (number z1, number z2)
{   
    if(z2 >= 0) return mag(z1);
    else return - mag(z1);
}

...


// include header files

#include "PN.H" //contains declaration PN_ByPT(word prop_, scalar p_, scalar T_)
...



#endif


e.g. in the header file PN.H the function PN_ByPT is declared


Code:

//PN.H



#ifndef PN_H
#define PN_H



//declaration of functions
scalar PN_ByPT(word prop_, scalar p_, scalar T_);
...


// include C-files
#include "PN_ByTP.C" //contains function PN_ByPT(word prop_, scalar p_, scalar T_) -> !!this is the critical line!!



#endif


The C-file PN_ByTP.C contains the function:


Code:



double PN_ByPT(string prop_, double p_, double T_)
{


//What the function does
if (prop_ == "cv") return cv;



}


I put all the header- and C-files into the include folder of "specie", they are copied into lnInclude, when compiling.


1) If I don't #include the files in the header of e.g. thermoI.H, the template function does not know PN_ByPT -> compiler error



Code:

template<class Thermo, template<class> class Type>
inline Foam::scalar
Foam::species::thermo<Thermo, Type>::Cv(const scalar p, const scalar T) const
{
    //return this->Cp(p, T) - this->CpMCv(p, T); //old code
    return PN_ByPT("cv", p, T); //new code
}



2) I put #include "heliumThermo.H" into the header of thermoI.H and



a) #include "PN_ByTP.C" in the header file "PN.H" -> library compiler error "multiple definition", since several source files call thermoI.H


b) //#include "PN_ByTP.C" in the header file "PN.H" -> solver compiler error "undefined reference", since the function is not linked, because it was never included during the library compilation


I hope that somehow gives an overview about the structure.



Thanks for your help,
stockzahn

alexeym March 27, 2020 02:43

Hi,

Well, all this is caused by strange OpenFOAM tradition to have the same .C extension for templated and non-templated code.

If we exclude solver files, your library consists of:
- template header files
- template implementation files
- concrete header file (PN.H), which contains constants and declaration of PN_ByTP function (it is not clear why this declaration is not in heliumThermo.H, why you need FORTSIGN function, yet, they are your decisions)
- concrete implementation file (PN_ByTP.C)

Since PN_ByTP.C contains concrete implementation of the PN_ByPT function, you do not include it in header files (i.e. remove line #include "PN_ByTP.C" from PN.H), you simply compile it (add to Make/files).

You include PN.H into thermoI.H file, so it can resolve PN_ByPT function.

Finally you create additional C file, where you instantiate templates, similar to src/thermophysicalModels/basic/rhoThermo/rhoThermos.C. And you compile it (add to Make/files).

stockzahn March 27, 2020 12:25

Dear Alexey,


adding the C-files to Make/files was the solution. Thanks for your help, the code compiled (with some additional changes), also for the solver, and works. Still I would have some questions for better understanding and to improve my C++/OF-skills. not urgent, but I would be grateful if you could share some insights:


1) I wasn't able to declare a global non-const variable. If I didn't include the declaration in a header file e.g. in thermoI.H, then there was a "non-declaration" error. If I included it, I got the "multiple declaration-error". Is it possible to declare global non-const variables for the entire library?


2) I don't get your comment regarding the template instantiation:



Quote:

Originally Posted by alexeym (Post 763107)
Finally you create additional C file, where you instantiate templates, similar to src/thermophysicalModels/basic/rhoThermo/rhoThermos.C. And you compile it (add to Make/files).


Since I don't get how the template instantiation in rhoThermos.C works (I never would have guessed that), I consulted my books and couldn't find any similarities of code. However, as you already knew, my templates didn't compile correctly ("no reference" - error). Therefore, as preliminary measure I wrote functions to be able to compile my code. Could you elucidate your comment?


Nevertheless, it works now, thanks for your help again!


Sincerely,
stockzahn

alexeym March 29, 2020 16:58

Hi,

1. You declare it as extern in a header (.H file), you define somewhere in compiled code (.C file).

2. If you create manually object of your templated class in your solver (since, you have said, that everything compiles and works as expected, guess, that is what you do), there is no need to do anything else. rhoThermos.C invokes machinery to make thermophysical model available for run-time selection. Not everyone needs run-time selection.

stockzahn April 1, 2020 12:47

Dear Alexey,


thanks again for your advice and all the help!


Read you,
sincerely,
stockzahn


All times are GMT -4. The time now is 01:24.