CFD中文网

    CFD中文网

    • 登录
    • 搜索
    • 最新

    编译自己的求解器遇到问题“undefined reference”

    OpenFOAM
    4
    25
    4326
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • H
      huiCfd 最后由 编辑

      Hello,各位大神,

      我在编译自己一个求解器的过程中出现了如下的问题:提示说有用undefined reference.

      -lincompressibleTransportModels -lOpenFOAM -ldl  \
           -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
      Make/linux64GccDPInt32Opt/dynaPorousNetFoam.o: In function `main':
      dynaPorousNetFoam.C:(.text.startup+0x1408): undefined reference to `Foam::netPanel::~netPanel()'
      dynaPorousNetFoam.C:(.text.startup+0x1f01): undefined reference to `Foam::netPanel::netPanel(Foam::dictionary const&)'
      ......
      ......
      dynaPorousNetFoam.C:(.text.startup+0x68c5): undefined reference to `Foam::netPanel::~netPanel()'
      collect2: error: ld returned 1 exit status
      /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
      make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
      
      

      下面说一下我编译的程序结构,我的dynaForousNetFoam 求解器是基于PisoFOAM 进行简单修改后编译的。这个新的求解器调用了我自己写的一个class创建了porousZones 对象,并利用相关的成员函数对U 方程进行修改。
      这个class 名是netpanel,并且这个类可以单独用wmake编译成功,结果如下:

      .
      ├── platforms
      │   └── linux64GccDPInt32Opt
      │       ├── bin
      │       └── lib
      │           └── netPanel.so
      └── run
      
      

      我求解器中部分相关的代码:

      ...
      netPanel porousZones(netDict);  // constrcut net panel
      porousZones.updatePoroField(porosityField, mesh, structuralPositions,structuralElements);
      //- write the porosity field
      porosityField.write();
      ...
      // add source term to  U equation
      porousZones.addResistance(UEqn,nu,mesh,structuralPositions,structuralElements);
      ...
      

      下面是我在编译dynaForousNetFoam 时用的file 和options 文件。从option中可以看出我在编译dynaForousNetFoam的时候已经链接到我之前写的那个class了,但是编译还是不通过。
      File:

      dynaPorousNetFoam.C
      EXE = $(FOAM_USER_APPBIN)/dynaPorousNetFoam
      

      Option:

      EXE_INC = \
          -I./Netpanels/lnInclude \
          -I$ (LIB_SRC)/finiteVolume/lnInclude \
          -I$(LIB_SRC)/meshTools/lnInclude \
          -I$(LIB_SRC)/sampling/lnInclude \
          -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
          -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
          -I$(LIB_SRC)/transportModels \
          -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel
      
      EXE_LIBS = \
          -L$(FOAM_USER_LIBBIN)\ -lnetPanel \
          -lfiniteVolume \
          -lfvOptions \
          -lmeshTools \
          -lsampling \
          -lturbulenceModels \
          -lincompressibleTurbulenceModels \
          -lincompressibleTransportModels
      

      所以有没有大神能够帮忙指点一下?

      1 条回复 最后回复 回复 引用
      • Y
        yfclark 讲师 最后由 编辑

        (1)wclean清空所有的文件,再编译看看(2)你自己的Class编写有问题,自己查找(3)看样子是想添加源项,直接在方程中添加可否

        H 1 条回复 最后回复 回复 引用
        • H
          huiCfd @yfclark 最后由 编辑

          @yfclark

          1. wclean/ wmake 已经很多次了,每次都是自己写的class可以先编译成功,并生成netPanel.so 这个lib。但是dynaPorousNetFoam.C 就编译出现问题。
          2. 如果自己写的class有问题的话,是不应该在第一步编译的时候就会出现问题?
          3. 因为研究的对象不是充满整个计算域,只有特定的范围内的网格才有源项。 又因为研究对象有大变形,不同时间对应不同的网格,所以不能直接在方程中添加源项。
          4. 所以我自己写的class就是根据结构的空间位置,找出对应的网格,并在这些网格中添加源项。
          1 条回复 最后回复 回复 引用
          • Y
            yfclark 讲师 最后由 编辑

            编译过了只是说明你骗过了编译器不代表程序没有问题,你说的可以直接添加源项解决,通过访问mesh的cells或者face解决

            H 1 条回复 最后回复 回复 引用
            • H
              huiCfd @yfclark 最后由 编辑

              @yfclark 在 编译自己的求解器遇到问题“undefined reference” 中说:

              编译过了只是说明你骗过了编译器不代表程序没有问题,你说的可以直接添加源项解决,通过访问mesh的cells或者face解决

              那个netpanel的class的作用就是找到特定的mesh,并在cells决添加源项。

              1 条回复 最后回复 回复 引用
              • Y
                yfclark 讲师 最后由 李东岳 编辑

                试一下

                //create volfield as source term
                //initial it as zero
                //forAll(mesh,celli)
                {
                        if condition  
                   S[celli]=your value
                }
                

                自己琢磨一下

                H 1 条回复 最后回复 回复 引用
                • H
                  huiCfd @yfclark 最后由 编辑

                  @yfclark
                  这个function, 我已经写到我的class中了,但是问题是在编译求解器时遇到问题“undefined reference”

                  void Foam::netPanel::addResistance
                          (
                              fvVectorMatrix&         UEqn,
                              const volScalarField&   nu,
                              const fvMesh&           mesh_,
                              const volVectorField&   structuralPositions,
                              const volVectorField&   structuralElements
                          )
                          {
                              const vectorField& centres(mesh_.C());
                              forAll(structuralElements,Elementi)
                              {
                                  dimensionedTensor d_(tensor::zero);
                                  dimensionedTensor f_(tensor::zero);
                                  transformCoeffs(D_,d_,structuralPositions,structuralElements[Elementi]);
                                  transformCoeffs(F_,f_,structuralPositions,structuralElements[Elementi]);
                                  tensor& dvalue = d_.value();
                                  tensor& fvalue = f_.value();
                                  const scalarField V = mesh_.V();
                                  vectorField& Usource = UEqn.source();
                                  const vectorField& U = UEqn.psi();
                          
                                  forAll(centres, cellI)
                                  {
                                      if(isInPorousZone(centres[cellI],structuralPositions,structuralElements[Elementi]))
                                       {
                                      tensor dragCoeff = nu[cellI]*dvalue + 0.5*mag(U[cellI])*fvalue;
                                      Usource[cellI] -=V[cellI]*dragCoeff & (U[cellI] );
                                       }
                                  }
                              }
                          
                          }
                  
                  1 条回复 最后回复 回复 引用
                  • Y
                    yfclark 讲师 最后由 编辑

                    老哥,你这么老实,你直接函数式编程不就行了嘛,非要写class

                    1 条回复 最后回复 回复 引用
                    • H
                      huiCfd 最后由 编辑

                      我在想是不是 我的这个option里买有格式错误。
                      我试过将

                      EXE_LIBS = \
                          -L$(FOAM_USER_LIBBIN)\ -lnetPanel \
                      

                      改为

                      EXE_LIBS = \
                          -L$(FOAM_USER_LIBBIN) -lnetPanel \
                      

                      结果感觉更错啦

                           -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
                      /usr/bin/ld: cannot find -lnetPanel
                      collect2: error: ld returned 1 exit status
                      /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
                      make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
                      
                      
                      1 条回复 最后回复 回复 引用
                      • 李东岳
                        李东岳 管理员 最后由 编辑

                        undefined reference可能出现在你的虚函数,具体什么问题不太清楚,检查下你的成员函数

                        CFD高性能服务器 http://dyfluid.com/servers.html
                        2023年,线下CFD课,预热一下 http://dyfluid.com/class.html

                        H 1 条回复 最后回复 回复 引用
                        • H
                          huiCfd @李东岳 最后由 编辑

                          @东岳 感谢东岳老师回复,我又看了一下错误提示,出现问题的都是我写的虚函数。

                          W 1 条回复 最后回复 回复 引用
                          • W
                            wwzhao 教授 @huiCfd 最后由 编辑

                            @huiCfd 构造函数和析构函数是不是忘记定义了?

                            H 1 条回复 最后回复 回复 引用
                            • H
                              huiCfd @wwzhao 最后由 编辑

                              @wwzhao 赵教授,这两个函数我记得定义了,

                                  // Constructors
                                     netPanel
                                     (
                                         const dictionary&        netDict
                                     );
                              
                                  //- Destructor
                                  ~netPanel();
                              

                              但是我有一点不太明白,为什么有的函数后面有一个const,有的没有。例如:
                              这个虚函数是void funname() const;

                              void addResistance
                                      (
                                          fvVectorMatrix&         UEqn,
                                          const volScalarField&   nu,
                                          const fvMesh&           mesh,
                                          const matrix&   structuralPositions,
                                          const matrix&   structuralElements
                                      )const;
                              

                              而这个函数是 bool funname(); 就没有const了。

                                      bool isInPorousZone
                                      (
                                          const point             x,
                                          const volVectorField&   structuralPositions,
                                          const vector&           structuralElementi
                                      );        
                              

                              const 在括号里面我知道是可以保证传入的参数不变,但是在外边是啥意思啊?

                              H W 2 条回复 最后回复 回复 引用
                              • H
                                huiCfd @huiCfd 最后由 编辑

                                @huiCfd
                                这个函数后面的const 是用来保护类的成员数据不发生改变。

                                1 条回复 最后回复 回复 引用
                                • W
                                  wwzhao 教授 @huiCfd 最后由 编辑

                                  @huiCfd 你这个只是声明(declaration),有没有具体的定义(definition)?

                                  H 1 条回复 最后回复 回复 引用
                                  • H
                                    huiCfd @wwzhao 最后由 编辑

                                    @wwzhao
                                    定义也是有的。如下

                                    Foam::netPanel::netPanel
                                    (
                                        const dictionary&        netDict
                                    )
                                    :   // initial components
                                        netDict_(netDict),
                                        porousPropertiesDict_(netDict_.subDict("porousProperties")),
                                        porosity_(readScalar(porousPropertiesDict_.lookup("porosity"))),
                                        thickness_(readScalar(porousPropertiesDict_.lookup("halfthickness")))
                                        // D_(readVector(porousPropertiesDict_.lookup("D"))),  // initial as zeros
                                        // F_(readVector(porousPropertiesDict_.lookup("D")))  // initial as zeros
                                    {
                                        dimensionedVector D_(porousPropertiesDict_.lookup("D"));
                                        dimensionedVector F_(porousPropertiesDict_.lookup("F"));
                                    
                                    }
                                    
                                    W 1 条回复 最后回复 回复 引用
                                    • W
                                      wwzhao 教授 @huiCfd 最后由 编辑

                                      @huiCfd 把 netPanel.so 重命名成 libnetPanel.so 试试呢?

                                      H 1 条回复 最后回复 回复 引用
                                      • H
                                        huiCfd @wwzhao 最后由 编辑

                                        @wwzhao 不行。。

                                        W 1 条回复 最后回复 回复 引用
                                        • W
                                          wwzhao 教授 @huiCfd 最后由 编辑

                                          @huiCfd $(FOAM_USER_LIBBIN) 后面的换行符去掉了吗?

                                          H 1 条回复 最后回复 回复 引用
                                          • H
                                            huiCfd @wwzhao 最后由 编辑

                                            @wwzhao 是的,去掉何不去掉都试过了,
                                            去掉后显示的错误是

                                             -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
                                            /usr/bin/ld: cannot find -llibnetPanel
                                            collect2: error: ld returned 1 exit status
                                            /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
                                            make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
                                            

                                            没去掉的话跟原来的错误一样,都是undefined reference

                                            W 1 条回复 最后回复 回复 引用
                                            • W
                                              wwzhao 教授 @huiCfd 最后由 编辑

                                              @huiCfd
                                              1、去掉$(FOAM_USER_LIBBIN)后的换行符,注意后面的 netPanel 前不要加lib

                                              EXE_LIBS = \
                                                  -L$(FOAM_USER_LIBBIN) -lnetPanel \
                                              

                                              2、编译出来的 netPanel.so 文件重命名为 libnetPanel.so

                                              H 1 条回复 最后回复 回复 引用
                                              • H
                                                huiCfd @wwzhao 最后由 编辑

                                                @wwzhao
                                                成功了啊! 非常感谢。。
                                                是不可以总结如下经验:

                                                1. 自己编写的类在编译时一定要以lib开头,
                                                2. 然后在编译主程序时,$(FOAM_USER_LIBBIN)后面不能有换行符,
                                                3. -l之后直接跟自己编译的东西但是要去掉lib
                                                H 1 条回复 最后回复 回复 引用
                                                • H
                                                  huiCfd @huiCfd 最后由 编辑

                                                  @huiCfd 可能这个适用于of1906

                                                  1 条回复 最后回复 回复 引用
                                                  • W
                                                    wwzhao 教授 最后由 编辑

                                                    说明一下:

                                                    1、换行符(\)不能随便用,必须用在行尾。如果用在行中间,那么换行符后面的内容都会被忽略,所以你加的 -lnetPanel 没用。

                                                    2、-lfoo 会找名为 libfoo.so 的库文件,-l:bar.so 则会找 bar.so 文件,这是 gcc 的链接规则。

                                                    H 1 条回复 最后回复 回复 引用
                                                    • H
                                                      huiCfd @wwzhao 最后由 编辑

                                                      @wwzhao 非常感谢指点迷津!

                                                      1 条回复 最后回复 回复 引用
                                                      • First post
                                                        Last post