CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Linking error in OF-1.6-ext: undefined reference to ... (http://www.cfd-online.com/Forums/openfoam-programming-development/113072-linking-error-1-6-ext-undefined-reference.html)

Hisham February 11, 2013 16:22

Linking error in OF-1.6-ext: undefined reference to ...
 
Dear Foamers,

I am trying to port a custom solver to OpenFOAM-1.6-ext. The compile process runs smoothly until a linking error is issued at the end of the process. The error is:
Code:

        -lfiniteVolume    -lOpenFOAM    -ltriSurface    -lmeshTools    -lmaterialConstitutiveModel    -L/home/hisham/OpenFOAM/hisham-1.6-ext/lib/linux64GccDPOpt    -lsoilZones    -lcontactModel    -pipe -lOpenFOAM -liberty -ldl  -lm -o /home/hisham/OpenFOAM/hisham-1.6-ext/applications/bin/linux64GccDPOpt/geotechFoam3
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<Foam::Vector<double> > >::type() const':
geotechFoam3.C:(.text._ZNK4Foam7IOFieldINS_5FieldINS_6VectorIdEEEEE4typeEv[Foam::IOField<Foam::Field<Foam::Vector<double> > >::type() const]+0x3): undefined reference to `Foam::IOField<Foam::Field<Foam::Vector<double> > >::typeName'
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<double> >::type() const':
geotechFoam3.C:(.text._ZNK4Foam7IOFieldINS_5FieldIdEEE4typeEv[Foam::IOField<Foam::Field<double> >::type() const]+0x3): undefined reference to `Foam::IOField<Foam::Field<double> >::typeName'
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<Foam::SymmTensor<double> > >::type() const':
geotechFoam3.C:(.text._ZNK4Foam7IOFieldINS_5FieldINS_10SymmTensorIdEEEEE4typeEv[Foam::IOField<Foam::Field<Foam::SymmTensor<double> > >::type() const]+0x3): undefined reference to `Foam::IOField<Foam::Field<Foam::SymmTensor<double> > >::typeName'
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<double> >::IOField(Foam::IOobject const&, int)':
geotechFoam3.C:(.text._ZN4Foam7IOFieldINS_5FieldIdEEEC2ERKNS_8IOobjectEi[_ZN4Foam7IOFieldINS_5FieldIdEEEC5ERKNS_8IOobjectEi]+0x52): undefined reference to `Foam::IOField<Foam::Field<double> >::typeName'
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<Foam::Vector<double> > >::IOField(Foam::IOobject const&, int)':
geotechFoam3.C:(.text._ZN4Foam7IOFieldINS_5FieldINS_6VectorIdEEEEEC2ERKNS_8IOobjectEi[_ZN4Foam7IOFieldINS_5FieldINS_6VectorIdEEEEEC5ERKNS_8IOobjectEi]+0x52): undefined reference to `Foam::IOField<Foam::Field<Foam::Vector<double> > >::typeName'
Make/linux64GccDPOpt/geotechFoam3.o: In function `Foam::IOField<Foam::Field<Foam::SymmTensor<double> > >::IOField(Foam::IOobject const&, int)':
geotechFoam3.C:(.text._ZN4Foam7IOFieldINS_5FieldINS_10SymmTensorIdEEEEEC2ERKNS_8IOobjectEi[_ZN4Foam7IOFieldINS_5FieldINS_10SymmTensorIdEEEEEC5ERKNS_8IOobjectEi]+0x52): undefined reference to `Foam::IOField<Foam::Field<Foam::SymmTensor<double> > >::typeName'
collect2: ld returned 1 exit status
make: *** [/home/hisham/OpenFOAM/hisham-1.6-ext/applications/bin/linux64GccDPOpt/geotechFoam3] Error 1

The linking error seems to come from this part of the code:
Code:

IOField<scalarField> matHistoryScalar(
                      IOobject
                      (
                      "matHistoryScalar",
                      runTime.timeName(),
                      mesh,
                      IOobject::READ_IF_PRESENT,
                      IOobject::AUTO_WRITE
                      ),
                      sZones.size()
                      );


IOField<vectorField> matHistoryVector(
                      IOobject
                      (
                      "matHistoryVector",
                      runTime.timeName(),
                      mesh,
                      IOobject::READ_IF_PRESENT,
                      IOobject::AUTO_WRITE
                      ),
                      sZones.size()
                      );


IOField<symmTensorField> matHistorySymmTensor(
                          IOobject
                          (
                          "matHistorySymmTensor",
                          runTime.timeName(),
                          mesh,
                          IOobject::READ_IF_PRESENT,
                          IOobject::AUTO_WRITE
                          ),
                          sZones.size()
                          );

As far as I know I have all libraries involved included in the Make/options

Code:

EXE_LIBS = -lfiniteVolume \
    -lOpenFOAM \
    -ltriSurface \
    -lmeshTools \
    -L$(FOAM_USER_LIBBIN)

Any help is appreciated!

Best regards
Hisham

ngj February 11, 2013 16:56

Hi Hisham,

I do not think you are allowed to create an IOField< Field<Type> > in OpenFoam - at least I could not get it compiled either. Is this what you want, or do you merely need an IOField<Type>?

All the best,

Niels

ngj February 11, 2013 17:08

Hi again,

I could not help trying to get something like you sketched to compile, so along your line of thought, this might be, what you need:

Code:

        PtrList<IOField<vector> > listField(sZones.size());

        forAll( listField, fieldi)
        {
            listField.set
            (
                fieldi,
                new IOField<vector>
                (
                    IOobject
                    (
                        "fjdskl",
                        runTime.timeName(),
                        mesh,
                        IOobject::READ_IF_PRESENT,
                        IOobject::AUTO_WRITE
                    )
                )
            );
        }

You must, however, be a bit careful with the naming "fjdskl", since all of the fields will be written to the same file name. It compiles, however, I do not know if it will work!?!

Good luck,

Niels

Hisham February 11, 2013 17:50

Quote:

Originally Posted by ngj (Post 407239)
Hi again,

I could not help trying to get something like you sketched to compile, so along your line of thought, this might be, what you need:

Code:

        PtrList<IOField<vector> > listField(sZones.size());

        forAll( listField, fieldi)
        {
            listField.set
            (
                fieldi,
                new IOField<vector>
                (
                    IOobject
                    (
                        "fjdskl",
                        runTime.timeName(),
                        mesh,
                        IOobject::READ_IF_PRESENT,
                        IOobject::AUTO_WRITE
                    )
                )
            );
        }

You must, however, be a bit careful with the naming "fjdskl", since all of the fields will be written to the same file name. It compiles, however, I do not know if it will work!?!

Good luck,

Niels

EDITED
Hi Niels

Thanks a lot for the super fast response.

Actually, this code compiles and works perfectly on OpenFOAM-2.1.x. I do not know what could be the problem as the implementation of IOFields seems to be the same for both editions and I can't figure out more info from the linker message.

The idea is to have a scalar(vector/symmTensor)Field for each zone that differs in size and they all write to one file (e.g. matHistoryScalar) in the time step.

This how a file looks from a run on OF-2.1.x.

Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.1.x                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      binary;
    class      scalarFieldField;
    location    "0.3";
    object      matHistoryScalar;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


2 // zones
(

0 // first zone zero


19200 // second zone
(
bla bla in binary

)

)

// ******************************  //

I am afraid I understand from your proposal that each vectorField will overwrite the same file or a new file is needed for each zone!

Is there a more similar approach to what I need?

Hisham

Hisham February 11, 2013 18:24

I think I found where the problem might be. There are files in OF that are not in OF-ext:

scalarFieldIOField.H & .C
vectorFieldIOField.H & .C
symmTensorFieldIOField.H & .C

I'll try to copy them to the solver directory.

EDIT:
No they're not. They are just typedefs:
Quote:

typedef IOField<scalarField> scalarFieldIOField;
And as it is compiling, it is only a link problem ...

deepsterblue February 12, 2013 00:20

You might be missing a defineTypeNameAndDebug macro in your .C file somewhere. Those are static class variables wrapped in macros.

Since you're dealing with a compound type, something like this might be necessary:

// Explicitly specify typeNames for IOFields
defineCompoundTypeName(Field<scalar>, scalarField);
addCompoundToRunTimeSelectionTable(Field<scalar>, scalarField);

defineCompoundTypeName(Field<vector>, vectorField);
addCompoundToRunTimeSelectionTable(Field<vector>, vectorField);

defineTemplateTypeNameAndDebugWithName
(
IOList<scalarField>, "scalarFieldList", 0
);

defineTemplateTypeNameAndDebugWithName
(
IOList<vectorField>, "vectorFieldList", 0
);

Hisham February 12, 2013 04:53

Quote:

Originally Posted by deepsterblue (Post 407273)
You might be missing a defineTypeNameAndDebug macro in your .C file somewhere. Those are static class variables wrapped in macros.

Since you're dealing with a compound type, something like this might be necessary:

// Explicitly specify typeNames for IOFields
defineCompoundTypeName(Field<scalar>, scalarField);
addCompoundToRunTimeSelectionTable(Field<scalar>, scalarField);

defineCompoundTypeName(Field<vector>, vectorField);
addCompoundToRunTimeSelectionTable(Field<vector>, vectorField);

defineTemplateTypeNameAndDebugWithName
(
IOList<scalarField>, "scalarFieldList", 0
);

defineTemplateTypeNameAndDebugWithName
(
IOList<vectorField>, "vectorFieldList", 0
);

Hi Sandeep and Niels,

Thanks a lot Sandeep. This surely makes it work :)

Code:

namespace Foam
{
    typedef IOField<vectorField> vectorFieldIOField;
    typedef IOField<scalarField> scalarFieldIOField;
    typedef IOField<symmTensorField> symmTensorFieldIOField;

    defineTemplateTypeNameAndDebugWithName
    (
        vectorFieldIOField,
        "vectorFieldField",
        0
    );

    defineTemplateTypeNameAndDebugWithName
    (
        scalarFieldIOField,
        "scalarFieldField",
        0
    );

    defineTemplateTypeNameAndDebugWithName
    (
        symmTensorFieldIOField,
        "symmTensorFieldField",
        0
    );

}

The code is copied from scalar(vector, symmTensor)FieldIOField.C and .H

Thanks again to both of you!

Best regards,
Hisham

ngj November 5, 2013 15:35

Dear Hisham and Sandeep,

I just found myself needed this solution, so thank you a lot for these posts. It was exceptionally helpful.

Kind regards,

Niels


All times are GMT -4. The time now is 09:45.