Frage

I'm editing the source code for a Computational Fluid Dynamics program and although I'm new to C++ I cannot seem to work out where the errors are coming from. They are as follows:

Make/linux64GccDPOpt/mySTCompressibleInterFoam.o: In function `main':

mySTCompressibleInterFoam.C:(.text.startup+0x333c): undefined reference to `Foam::surfaceTension::surfaceTension(Foam::GeometricField, Foam::fvPatchField, Foam::volMesh> const&, Foam::GeometricField const&)'

mySTCompressibleInterFoam.C:(.text.startup+0x3580): undefined reference to `Foam::surfaceTension::surfaceTensionForce() const'

mySTCompressibleInterFoam.C:(.text.startup+0x3cff): undefined reference to `vtable for Foam::surfaceTension'

mySTCompressibleInterFoam.C:(.text.startup+0x8246): undefined reference to `vtable for Foam::surfaceTension'

The code structure is quite complex however I'm fairly sure that I've found the lines of code that are causing the problem but I have no idea how to fix it.

The top level file is thus:

  #include "fvCFD.H"
  #include "MULES.H"
  #include "subCycle.H"
  #include "rhoThermo.H"
  #include "interfaceProperties.H"
  #include "twoPhaseMixture.H"
  #include "twoPhaseMixtureThermo.H"
  #include "surfaceTension.H"
  #include "turbulenceModel.H"
  #include "pimpleControl.H"

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

int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"

pimpleControl pimple(mesh);

#include "readControls.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"

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

Info<< "\nStarting time loop\n" << endl;

while (runTime.run())
{
    #include "readControls.H"
    #include "CourantNo.H"
    #include "alphaCourantNo.H"
    #include "setDeltaT.H"

    runTime++;

    Info<< "Time = " << runTime.timeName() << nl << endl;

    // --- Pressure-velocity PIMPLE corrector loop
    while (pimple.loop())
    {
        #include "alphaEqnsSubCycle.H"

        // correct interface on first PIMPLE corrector
        if (pimple.corr() == 1)
        {
            interface.correct();
        }

        solve(fvm::ddt(rho) + fvc::div(rhoPhi));

        #include "UEqn.H"
        #include "TEqn.H"

        // --- Pressure corrector loop
        while (pimple.correct())
        {
            #include "pEqn.H"
        }

        if (pimple.turbCorr())
        {
            turbulence->correct();
        }
    }

    runTime.write();

    Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
        << "  ClockTime = " << runTime.elapsedClockTime() << " s"
        << nl << endl;
}

Info<< "End\n" << endl;

return 0;
}


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

From the errors my understanding is that the errors are coming from the surfaceTension class and functions.

surfaceTension.H is as follows:

#ifndef surfaceTension_H
#define surfaceTension_H

#include "incompressible/transportModel/transportModel.H"
#include "phase.H"
#include "PtrDictionary.H"
#include "volFields.H"
#include "surfaceFields.H"


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

namespace Foam
{

/*---------------------------------------------------------------------------*\
                  Class surfaceTension Declaration
\*---------------------------------------------------------------------------*/

class surfaceTension
:
public transportModel
{
public:

class interfacePair
:
    public Pair<word>
{
public:

    class hash
    :
        public Hash<interfacePair>
    {
    public:

        hash()
        {}

        label operator()(const interfacePair& key) const
        {
            return word::hash()(key.first()) + word::hash()(key.second());
        }
    };


    // Constructors

        interfacePair()
        {}

        interfacePair(const word& alpha1Name, const word& alpha2Name)
        :
            Pair<word>(alpha1Name, alpha2Name)
        {}

        interfacePair(const phase& alpha1, const phase& alpha2)
        :
            Pair<word>(alpha1.name(), alpha2.name())
        {}


    // Friend Operators

        friend bool operator==
        (
            const interfacePair& a,
            const interfacePair& b
        )
        {
            return
            (
                ((a.first() == b.first()) && (a.second() == b.second()))
             || ((a.first() == b.second()) && (a.second() == b.first()))
            );
        }

        friend bool operator!=
        (
            const interfacePair& a,
            const interfacePair& b
        )
        {
            return (!(a == b));
        }
};


private:

// Private data

    //- Dictionary of phases
    PtrDictionary<phase> phases_;

    const fvMesh& mesh_;
    const volVectorField& U_;
    const surfaceScalarField& phi_;

    surfaceScalarField rhoPhi_;

    volScalarField alphas_;

    typedef HashTable<scalar, interfacePair, interfacePair::hash>
        sigmaTable;

    sigmaTable sigmas_;
    dimensionSet dimSigma_;

    //- Stabilisation for normalisation of the interface normal
    const dimensionedScalar deltaN_;

    //- Conversion factor for degrees into radians
    static const scalar convertToRad;


// Private member functions

    tmp<surfaceVectorField> nHatfv
    (
        const volScalarField& alpha1,
        const volScalarField& alpha2
    ) const;

    tmp<surfaceScalarField> nHatf
    (
        const volScalarField& alpha1,
        const volScalarField& alpha2
    ) const;

    void correctContactAngle
    (
        const phase& alpha1,
        const phase& alpha2,
        surfaceVectorField::GeometricBoundaryField& nHatb
    ) const;

    tmp<volScalarField> nabla
    (
        const phase& alpha1,
        const phase& alpha2
    ) const;


 public:

// Constructors

    //- Construct from components
    surfaceTension
    (
        const volVectorField& U,
        const surfaceScalarField& phi
    );


//- Destructor
virtual ~surfaceTension()
{}    


// Member Functions

    //- Return the phases
    const PtrDictionary<phase>& phases() const
    {
        return phases_;
    }

    //- Return the velocity
    const volVectorField& U() const
    {
        return U_;
    }

    //- Return the volumetric flux
    const surfaceScalarField& phi() const
    {
        return phi_;
    }

    const surfaceScalarField& rhoPhi() const
    {
        return rhoPhi_;
    }

    //- Return the mixture density
    tmp<volScalarField> rho() const;

    //- Return the dynamic laminar viscosity
    tmp<volScalarField> mu() const;

    //- Return the kinematic laminar viscosity
    tmp<volScalarField> nu() const;

    //- Return surface Tension Force

    tmp<surfaceScalarField> surfaceTensionForce() const;

    //- Correct the mixture properties
    void correct();

    //- Read base transportProperties dictionary
    bool read();

};


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

} // End namespace Foam

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

#endif

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

SurfaceTension.c is then

#include "surfaceTension.H"
#include "alphaContactAngleFvPatchScalarField.H"
#include "Time.H"
#include "subCycle.H"
#include "MULES.H"
#include "fvcSnGrad.H"
#include "fvcFlux.H"

// * * * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * //

const Foam::scalar Foam::surfaceTension::convertToRad =
Foam::constant::mathematical::pi/180.0;

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::surfaceTension::surfaceTension
(
const volVectorField& U,
const surfaceScalarField& phi
)
:
transportModel(U, phi),
phases_(lookup("phases"), phase::iNew(U, phi)),

mesh_(U.mesh()),
U_(U),
phi_(phi),

rhoPhi_
(
    IOobject
    (
        "rho*phi",
        mesh_.time().timeName(),
        mesh_,
        IOobject::NO_READ,
        IOobject::NO_WRITE
    ),
    mesh_,
    dimensionedScalar("rho*phi", dimMass/dimTime, 0.0)
),

alphas_
(
    IOobject
    (
        "alphas",
        mesh_.time().timeName(),
        mesh_,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh_,
    dimensionedScalar("alphas", dimless, 0.0),
    zeroGradientFvPatchScalarField::typeName
),

sigmas_(lookup("sigmas")),
dimSigma_(1, 0, -2, 0, 0),
deltaN_
(
    "deltaN",
    1e-8/pow(average(mesh_.V()), 1.0/3.0)
)

{
}

// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //

Foam::tmp<Foam::volScalarField> Foam::surfaceTension::nu() const
{
return mu()/rho();
}

Foam::tmp<Foam::surfaceScalarField>
Foam::surfaceTension::surfaceTensionForce() const
{
tmp<surfaceScalarField> tstf
(
    new surfaceScalarField
    (
        IOobject
        (
            "surfaceTensionForce",
            mesh_.time().timeName(),
            mesh_
        ),
        mesh_,
        dimensionedScalar
        (
            "surfaceTensionForce",
            dimensionSet(1, -2, -2, 0, 0),
            0.0
        )
    )
);

surfaceScalarField& stf = tstf();

forAllConstIter(PtrDictionary<phase>, phases_, iter1)
{
    const phase& alpha1 = iter1();

    PtrDictionary<phase>::const_iterator iter2 = iter1;
    ++iter2;

    for (; iter2 != phases_.end(); ++iter2)
    {
        const phase& alpha2 = iter2();

        sigmaTable::const_iterator sigma =
            sigmas_.find(interfacePair(alpha1, alpha2));

        if (sigma == sigmas_.end())
        {
            FatalErrorIn("surfaceTension::surfaceTensionForce() const")
                << "Cannot find interface " << interfacePair(alpha1, alpha2)
                << " in list of sigma values"
                << exit(FatalError);
        }

        stf += dimensionedScalar("sigma", dimSigma_, sigma())
           *fvc::interpolate(nabla(alpha1, alpha2))*
            (
                fvc::interpolate(alpha2)*fvc::snGrad(alpha1)
              - fvc::interpolate(alpha1)*fvc::snGrad(alpha2)
            );
    }
}

return tstf;
}

void Foam::surfaceTension::correct()
{}

Foam::tmp<Foam::surfaceVectorField> Foam::surfaceTension::nHatfv
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const
{

surfaceVectorField gradAlphaf
(
    fvc::interpolate(alpha2)*fvc::interpolate(fvc::grad(alpha1))
  - fvc::interpolate(alpha1)*fvc::interpolate(fvc::grad(alpha2))
);

// Face unit interface normal
return gradAlphaf/(mag(gradAlphaf) + deltaN_);
}

Foam::tmp<Foam::surfaceScalarField> Foam::surfaceTension::nHatf
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const
{
// Face unit interface normal flux
return nHatfv(alpha1, alpha2) & mesh_.Sf();
}

Foam::tmp<Foam::volScalarField> Foam::surfaceTension::nabla
(
const phase& alpha1,
const phase& alpha2
) const
{
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);

correctContactAngle(alpha1, alpha2, tnHatfv().boundaryField());

    // Simple expression for curvature
return -fvc::div(tnHatfv & mesh_.Sf());
}

bool Foam::surfaceTension::read()
{
if (transportModel::read())
{
    bool readOK = true;

    PtrList<entry> phaseData(lookup("phases"));
    label phasei = 0;

    forAllIter(PtrDictionary<phase>, phases_, iter)
    {
        readOK &= iter().read(phaseData[phasei++].dict());
    }

    lookup("sigmas") >> sigmas_;

    return readOK;
}
else
{
    return false;
}
}

In order to calculate the surface tension at each time step the surfaceTensionForce function is called in the file UEqn.H which is as follows:

surfaceTension mixture(U, phi);

fvVectorMatrix UEqn
(
    fvm::ddt(rho, U)
  + fvm::div(rhoPhi, U)
  + turbulence->divDevRhoReff(U)
);

UEqn.relax();

if (pimple.momentumPredictor())
{
    solve
    (
        UEqn
     ==
        fvc::reconstruct
        (
            (
                mixture.surfaceTensionForce()
              - ghf*fvc::snGrad(rho)
              - fvc::snGrad(p_rgh)
            ) * mesh.magSf()
        )
    );

//        K = 0.5*magSqr(U);
}

If I remove the first line of this file the undefined referance erros do not appear and the code compiles fine. I've looked at a number of similar problems and the most common solution was that the files weren’t linked properly, I'm certain this is not the case.

Thank you in advance.

War es hilfreich?

Lösung

This is pretty much the most common linker error there is. The reason as to why the error disappears when you remove the first line of your last file, is probably because that will cause a compiler error (symbol not declared), and the linker won't even run.

I can only guess, but it seems like surfaceTension belongs to a different binary and is not properly linked when you are compiling UEqn.h.

I am also guessing that you are trying to run an example application of OpenFOAM. Make sure, you took all the installation steps, laid out on their wiki.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top