编译求解器出现 undefined reference



  • 各位朋友好!

    我现在在compressibleInterFoam里面尝试添加空化模型,空化模型的组建参考interPhaseChangeFoam的思路,,编写的class “phaseChangeTwoPhaseMixture”用于组装空化源项,,wmake编译没有报错

    但编译求解器myFoam(自己起的名字)时,就报错:

    /project/zywang2/OpenFOAM/OpenFOAM-4.1/platforms/linux64GccDPInt32Opt/applications/solvers/multiphase/myFoam/myFoam.o: In function `main':
    myFoam.C:(.text.startup+0xcde): undefined reference to `Foam::phaseChangeTwoPhaseMixture::New(Foam::fvMesh const&)'
    myFoam.C:(.text.startup+0x2acd): undefined reference to `Foam::phaseChangeTwoPhaseMixture::New(Foam::fvMesh const&)'
    collect2: error: ld returned 1 exit status
    make: *** [/home/zywang2/OpenFOAM/zywang2-4.1/platforms/linux64GccDPInt32Opt/bin/myFoam] Error 1
    
    

    自己看了好多前辈有关“undefined reference ”讨论的帖子,,目前自己分析有几种错误原因:
    1、optional文件里面 关于phaseChangeTwoPhaseMixture的链接有问题
    求解器的optional文件如下:

    EXE_INC = \
        -ItwoPhaseMixtureThermo/lnInclude \ 
        -IphaseChangeTwoPhaseMixtures/lnInclude \
    	-I(LIB_SRC)/thermophysicalModels/basic/lnInclude \
        -I(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
        -I(LIB_SRC)/TurbulenceModels/compressible/lnInclude \
        -I(LIB_SRC)/meshTools/lnInclude
    
    EXE_LIBS = \
        -L$(FOAM_USER_LIBBIN) \
        -ltwoPhaseMixtureThermo \
    	-lphaseChangeTwoPhaseMixtures \
        -lcompressibleTransportModels \
        -lfluidThermophysicalModels \
        -lspecie \
        -ltwoPhaseMixture \
        -ltwoPhaseProperties \
        -linterfaceProperties \
        -lturbulenceModels \
        -lcompressibleTurbulenceModels \
        -lfiniteVolume \
        -lfvOptions \
        -lmeshTools
    

    第二个原因是myFoam.C调用phaseChangeTwoPhaseMixture的格式不对,,具体就是creatFields.H中的应用代码:

    #include "createPhi.H"
    
    
    Info<< "Constructing phaseChangeTwoPhaseMixture\n" << endl;
    
    autoPtr<phaseChangeTwoPhaseMixture> mixture =
    	phaseChangeTwoPhaseMixture::New(mesh);
    
     volScalarField& alpha1(mixture->alpha1()); 
     volScalarField& alpha2(mixture->alpha2()); 
    
    

    同时,我自己查验了pahseChangeTwoPhaseMixture.H 和 .C文件,,感觉应该没有问题,编译通过,而且自己完全是参考interPhaseChangeFoam中对应的class写的

    请哪位前辈指点能够一下呢?感激不尽


  • Linux讲师

    • 可能错误1 new函数没有定义,如果是定义了,那就是定义的形参和调用时的实参不是一个数据类型。

    因为c++默认的函数重载,参数不同就是不同的函数。

    • 可能错误2 新的class没有包含进编译时的链接库,就是你在尝试解决的方向。
      用这个命令进入
    cd $FOAM_USER_LIBBIN
    

    看看新的class的so文件在不在。如果在,那基本就是可能错误1了。

    • 另:编译class能过这点没有太大的说明意义。因为是个库文件,里面都是类的定义和成员函数,除了成员函数之间互相调用,不会有其他调用,所以很难出错。如果细看,也能看见myFoam.o是已经编译出来了的,错误是出在链接各.o文件。这时候就要检查调用了,就出错了。


  • @bestucan 感谢前辈的热心解答,根据前辈的建议,我目前认为我的问题应该是错误1。

    我写的这个类phaseChangeTwoPhaseMixture,参考的是InterPhaseChangeFoam里的对应代码,不可压中该类应用RTS机制传递的参数是

    Foam::phaseChangeTwoPhaseMixture::New
    (
        const volVectorField& U,
        const surfaceScalarField& phi
    )
    

    为了应用于可压缩,我将phaseChangeTwoPhaseMixture.C phaseChangeTwoPhaseMixture.H 和 newphaseChangeTwoPhaseMixture.C文件对应部分都改成了

    Foam::phaseChangeTwoPhaseMixture::New
    (
        const fvMesh& mesh
    )
    

    在phaseChangeTwoPhaseMixture.H中定义代码如下:

    public:
    
        //- Runtime type information
        TypeName("phaseChangeTwoPhaseMixture");
    
    
        // Declare run-time constructor selection table
    
            declareRunTimeSelectionTable
            (
                autoPtr,
                phaseChangeTwoPhaseMixture,
                components,
                (
                    const fvMesh& mesh  ////////////////////
                ),
                (mesh)
            );
    
    
        // Selectors
    
            //- Return a reference to the selected phaseChange model
            static autoPtr<phaseChangeTwoPhaseMixture> New
            (
                const fvMesh& mesh     ///////////////////////
            );
    
    
        // Constructors
    
            //- Construct from components
            phaseChangeTwoPhaseMixture
            (
                const word& type,
                const fvMesh& mesh  
            );
    
    
        //- Destructor
        virtual ~phaseChangeTwoPhaseMixture()
        {}
    
    

    由于自己是个C++菜鸟,自己感觉就phseChangeTwoPhaseMixture这个class而言,内部的形参是mesh,,,外部我写的也是mesh,,我这个理解哪里出了问题呢?

    麻烦前辈再指点一下,谢谢


  • Linux讲师

    @小考拉 为什么有三个文件?

    我将phaseChangeTwoPhaseMixture.C phaseChangeTwoPhaseMixture.H 和 newphaseChangeTwoPhaseMixture.C文件对应部分都改成了

    定义一个类应该两个文件就行了。看样子类型也对上了。



  • @bestucan 感谢前辈的回复,,由于我这里要调用不同的空化模型,,所有要应用runTimeSelection机制,, newphaseChangeTwoPhaseMixture.C文件主要用于定义phaseChangeTwoPhaseMixture::New函数,,代码如下:

    #include "phaseChangeTwoPhaseMixture.H"
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    Foam::autoPtr<Foam::phaseChangeTwoPhaseMixture>
    Foam::phaseChangeTwoPhaseMixture::New
    (
      
    	const fvMesh& mesh 
    )
    {
        IOdictionary transportPropertiesDict
        (
            IOobject
            (
                "transportProperties",
                mesh.time().constant(),    
                mesh,             
                IOobject::MUST_READ,
                IOobject::NO_WRITE,
                false
            )
        );
    
        word phaseChangeTwoPhaseMixtureTypeName
        (
            transportPropertiesDict.lookup("phaseChangeTwoPhaseMixture")
        );
    
        Info<< "Selecting phaseChange model "
            << phaseChangeTwoPhaseMixtureTypeName << endl;
    
        componentsConstructorTable::iterator cstrIter =
            componentsConstructorTablePtr_             
                ->find(phaseChangeTwoPhaseMixtureTypeName);
    
        if (cstrIter == componentsConstructorTablePtr_->end()) 
        {
            FatalErrorInFunction
                << "Unknown phaseChangeTwoPhaseMixture type "
                << phaseChangeTwoPhaseMixtureTypeName << endl << endl
                << "Valid  phaseChangeTwoPhaseMixtures are : " << endl
                << dictionaryConstructorTablePtr_->sortedToc() 
                << exit(FatalError);
        }
    
        return autoPtr<phaseChangeTwoPhaseMixture>(cstrIter()(mesh));
    

    我现在分析问题出现New函数,,我这里定义的New函数的形参是

    const fvMesh& mesh 
    

    但phaseChangeTwoPhaseMixture里面形参是

     // Constructors
    
            //- Construct from components
            phaseChangeTwoPhaseMixture
            (
                const word& type,
                const fvMesh& mesh 
            );
    

    但感觉这里也没有影响吧,,debug好久仍然解决不了

    有做过可压缩空化的朋友能够指点一下吗?


  • Linux讲师

    你这个,new是你自己起得函数名用来代替 phaseChangTwoPhaseMixture 这个函数的?

    替代就直接替代,不能改名字啊。如果我没猜错,原始的调用代码是

    phaseChangeTwoPhaseMixture(mesh);
    

    这个不是函数调用,是类变量的隐性初始化(隐性初始化也用括号,容易和函数混),这是个声明类变量并赋值的过程,隐性初始化会调用构造函数并传递参数。那个和类名称同名的函数叫构造函数,必须和类名称一模一样。在声明该类变量时会自动调用构造函数。

    也就是说,看着你在调用new函数,但是new函数是属于某个类对象的,而你没有声明这样的类对象,所以就找不到new函数。

    改就直接改构造函数,不要换名字。要么复刻一个一模一样,只有类名不一样的类。

    建议先看看C++,不用多么精,至少都浏览一遍有印象。你调试的这些时间用来浏览早就浏览完了…



  • @bestucan 感谢前辈的热心回复,目前问题已经解决,问题出现在类phaseChangeTwoPhaseMixture的make文件的files文件里面,

    LIB = $(FOAM_USER_LIBBIN)/libphaseChangeTwoPhaseMixtures    //会报错
    
    LIB = (FOAM_USER_LIBBIN)/libtwoPhaseChange //随便叫一个名字均可,均可编译通过,但不能是libphaseChangeTwoPhaseMixtures 
    

    自己也是偶然发现的,但也比较困惑为什么这么神奇:mihu:

    不过最终问题还是解决了,很感谢前辈耐心的解答:xinxin: ,自己后面也应该好好补一点C++知识


Log in to reply
 

CFD中文网 2016 - 2020 | 京ICP备15017992号-2