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/)
-   -   OF-2.2.x: Derived class from cellZone and "undefined symbol error" (https://www.cfd-online.com/Forums/openfoam-programming-development/131630-2-2-x-derived-class-cellzone-undefined-symbol-error.html)

A_Pete March 18, 2014 11:10

OF-2.2.x: Derived class from cellZone and "undefined symbol error"
 
I derived a class from the cellZone class. The most important things of the .H file are:

Code:

namespace Foam
{

class specialVolume
:
    public cellZone
{

protected:
    const cellZone& zone_;

...

//Constructor
specialVolume(const cellZone& cz);
...
}
}

And the .C file:
Code:

...
//Constructor
Foam::specialVolume::specialVolume
(
    const cellZone& cz
)
:
    cellZone(cz), //constructor of cellZone (base class) has to be called before attributes
    zone_(cz)
{}

...

In a functionObject I now want to use that class and define an object with the first cellZone of the cellZoneMesh:
Code:

const cellZoneMesh& czm(mesh.cellZones());
specialVolume specVol(czm[0]);

This does all compile without problems. But when I run my solution with the functionObject, it gives an error exactly at the position where I defined my specialVolume object:

Code:

interPhaseChangeFoam: symbol lookup error: /home/OpenFOAM/user-2.2.x/platforms/linux64GccDPOpt/lib/libspecial.so: undefined symbol: _ZN4Foam8cellZoneC2ERKS0_
This has definitely something to do with my own class, since the solution is running well if I comment my own object out. It does also work if I define a cellZone instead of my specialZone there, since they should be very similar. But it seems like I did do something wrong with the constructor.

Has anybody an idea what I could be doing wrong in this code? Thank you very much.

wyldckat March 23, 2014 15:41

Greetings A_Pete,

Knowing the contents of "Make/files" and "Make/options" for your custom library would help. It would also help to know how exactly you've built it (i.e., the commands used).

Because without that information, my guess from that error message is that the problem is one of the following:
  1. The entry "-lOpenFOAM" is missing from "Make/options", specifically from the entry "LIB_LIBS". Example:
    Code:

    LIB_LIBS = \
        -lOpenFOAM

  2. Or you might have a shell environment that is a mixture of various installed versions of OpenFOAM, which leads to a linking conflict, resulting in having your library linked to the wrong OpenFOAM version.
  3. Or you're trying to use a constructor for "cellZone" that doesn't exist.
Best regards,
Bruno

A_Pete March 24, 2014 09:54

Hi Bruno,

first of all thank you very much for your answer.

To complete my post, my "Make/files" looks like this:
Code:

cavEroNew/cavEroNew.C
cavEroNew/cavEroNewFunctionObject.C

erosionPatch/erosionPatch.C
erosionPatch/erosionVolume.C //- was called specialVolume.C before

LIB = $(FOAM_USER_LIBBIN)/libcaveroTEST

The erosionVolume.C is what was my specialVolume.C before.


And my "Make/options" looks like this:
Code:

EXE_INC = \ 
    -I$(LIB_SRC)/finiteVolume/lnInclude \
    -I$(LIB_SRC)/OpenFOAM/lnInclude

LIB_LIBS = \
    -lfiniteVolume \
    -lOpenFOAM

To 1): I used both "wmake" and "wmake libso" compiling my library and both worked. Before, I executed "wclean", "rmoall" and "rmdepall" to make sure that there are no dependencies of the old library existing.
I also had in mind that "-lOpenFOAM" needs to be added, but this didn't help as I had it already in my "Make/options". The error was still the same.

To 2): I just have OpenFOAM 2.2.x installed right now. I didn't have any other version on my computer installed.

To 3): Thanks for your hint. I think that this is where the problem lies! But I am not sure how to solve it. When I derive a class "erosionVolume" from a base class "cellZone", am I able to call the private constructor of the cellZone class?

What I want is this: I want a new class "erosionVolume", that can be constructed by:
a) just a cellZone or
b) a cellZone and a name/label to identify it.
For now, I would like to realize just option a): I want to construct my erosionVolume, by initializing it with a cellZone. The problem is, that in my erosionVolume.C a constructor of the cellZone class has to be called in order to be able to use all its properties in my derived class, right? This is what I have shown in the .C file in my first post:

Code:

...

:
cellZone(cz), //constructor of cellZone (base class)
zone_(cz)

...

Generally I just want to have a class derived from cellZone, that can be constructed by a cellZone and will later have some additional properties.

Any further help would be appreciated.

Thank you very much.

Best regards,
Andreas

A_Pete March 31, 2014 09:35

How to assign a cellZone to derived class?
 
I have now edited my code so that I am able to use a constructor of the cellZone class. The header and source file got modified in the following way:

Header:
Code:

...
protected:
    const cellZoneMesh& zoneMesh_;
...

public:
    erosionVolume(const cellZoneMesh&);
...

Source:
Code:

namespace Foam
{
    ...
    const labelUList emptyList(0, 0);
}

Foam::erosionVolume::erosionVolume
(
    const cellZoneMesh& zm
)
:
    cellZone(name, emptyList, 0, zm),
    zoneMesh_(zm)
{}
...

So this was obviously just a crutch that I built myself, to see wether I can use the cellZone's constructors to build a derived class. And it worked! The bad thing is, that I don't want to use this constructor or that I have to give the right input parameters, which I don't know.

The question is now, how I can assign a cellZone to my derived class? Just like erosionVolume = cellZone.

wyldckat April 5, 2014 16:59

Hi Andreas,

Sorry, I'm a bit short on time for the past and coming weeks, so could you please provide an example test case + source code to make it easier for me to test this and to to try and to figure out the issue?
Because OpenFOAM uses C++ in such a way, that only looking at the source code is not enough to figure out the issue, unless one has a lot of experience with the code... and I'm not that good yet with it :(

Best regards,
Bruno

wyldckat April 25, 2014 13:57

For future readers, here's small report on the information exchanged on this topic, from private messages exchanged with Andreas, just in case someone in the future want to ask about this as well.


The objective was/is to have a class that can manage a keep track of a "cellZone" and do additional operations to that "cellZone", such as calculate equations, do averages, keep a history and so on.

On my first iteration of looking into this, the hypothesis was to perhaps use an "fvOption", but:
Quote:

Originally Posted by wyldckat
[...] after looking a bit more into OpenFOAM's own code, I believe that we're not meant to derive a class from "cellZone", because it's a base class and there is no way to fit a derived class into an existing "cellZone".
And the "cellZone" is mostly a way to select a group of cells, to know which ones to get from the mesh; it's not a way to handle a part of the mesh directly... or at least I haven't found this yet in the good example that is the "fvOptions" library.
Although the "fvOptions" library is mostly for operating directly in the equations.

On the second iteration:
Quote:

Originally Posted by wyldckat
Then "fvOptions" is not the way to go, since you don't want to affect the fields, you just want to analyse them and keep a record of how they're behaving. Nonetheless, "fvOptions" could be a good source of information... although it conceals some of the details you need.

OK, the first thing that comes to mind is the "porous medium" modelling as it is done in OpenFOAM. It usually operates in a "cellZone", which is why it's the first thing that comes to mind.
The reference source code for it is shown by the following commands:
Code:

echo $FOAM_SRC/finiteVolume/cfdTools/general/porosityModel/porosityModel
echo $FOAM_SRC/finiteVolume/cfdTools/general/porosityModel/powerLaw/

But both of these only use the "cellZones" as a cell identification methodology.

Then there is the "sampledSet" class at "$FOAM_SRC/sampling/sampledSet/sampledSet/", but it works in a similar way.

The more I look at these source code examples and the more I believe that "cellZone" isn't exactly what you're looking for. What you're probably looking for is a mesh region, not a zone; because a mesh region is a self contained mesh with fields, while cellSets and cellZones only register the selected cells...
On the other hand, it's more likely that you need "cellZoneMesh" and not just "cellZone", because "cellZoneMesh" has mesh searching features.

Either way, most of the reference codes I've mentioned above, rely on the "cellZones" only to know which cells to operate upon, not to keep a snapshot of the mesh in that zone. For example, have a look into the file "src/finiteVolume/cfdTools/general/porosityModel/powerLaw/powerLawTemplates.C" - you'll see how it goes through all cells in the cells zones.
And in the file "porosityModel.C" you'll see this piece of code:
Code:

    cellZoneIDs_ = mesh_.cellZones().findIndices(zoneName_);

    Info<< "    creating porous zone: " << zoneName_ << endl;

    bool foundZone = !cellZoneIDs_.empty();
    reduce(foundZone, orOp<bool>());

That code ensures that it checks if at least one processor has a populated "cellZoneIDs_" list.

Therefore, my suggestion is that you shift your focus from deriving directly from a "cellZone" and going either to a similar structure as the classes I mentioned above, namely where the new class only needs to know the "cellZone" name and to have access to the mesh and fields.

Or to look into how the region meshes are handled... although region meshes also seem a bit of an overkill and somewhat complicated to implement. The advantage of a mesh region is that it's a somewhat good way to keep a copy of the cells with fields you're analysing.
Either way, a starting point for looking into region meshes is the solver "applications/solvers/heatTransfer/chtMultiRegionFoam".

I have not looked more into this, but I can add a bit to the multi-region topic: blockMesh can be used to generate the main mesh and a separate region mesh. Although I have not tested this myself, this should mean that we can generate a new mesh region that is a subset of the main region, e.g. by using the utility subsetMesh. This would help to keep this new region created right from the start of the case and to be able to map the data from the main region to this smaller region and therefore be able to keep a history only for that region.
But then again, as I mentioned before, multi-region capabilities for this case might be overkill and possibly will need more RAM then it should be necessary.

Best regards,
Bruno

A_Pete April 28, 2014 01:53

Thanks for the update, Bruno.

I will also update this thread given my last message to Bruno.

Quote:

Originally Posted by A_Pete
Both the porous medium modelling, as well as the region meshes sound very interesting to me. As you suggested, the porous medium seems to be a better choice first, since it would be a lower effort to go this way. It seems to use cellZones to create some kind of a porous zone. This looks also very similar to what I am trying to do with my erosion volumes.

The main problem I have, has to do with parallelization: I want to access all the cells from one cellZone on one processor. Per default this is not generally possible, since cells of one cellZone may be decomposed to different partitions. And I am not sure if this problem gets solved with the "porous medium approach".

I will have a much more detailed look into all these things in the next weeks and will report about my progress.

Best regards,
Andreas


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