【已解决】OpenFOAM对象作用域问题

OpenFOAM版本: v1812
系统版本: Ubuntu v18.04.06
该问题已经被解决,解决方案如下:
在phaseSystem.C中使用lookupObjectRef生成非const的引用,操作不涉及变更const fvMesh& ,不需要使用mesh2或添加其他独立于网格对象mesh的单独参数传递过程,避开下列所有问题,使用方法与lookupObject完全相同
Note:
fvc::interpolate等常用操作函数输入变量均为const fvMesh&且不存在非常量引用作为输入参数
非const的fvMesh&对象在OpenFOAM中使用受限很大,同时fvMesh类不能拷贝构造
变更mesh对应场量直接通过lookupObjectRef完成,并不需要构造非常量的fvMesh对象

原始问题:
因原始代码中的mesh的类型为const fvMesh &且该对象牵涉内容多,修改困难
部分代码功能实现需要实时修改对应对象的值,故新增对象mesh2,类型为fvMesh &
该执行程序内对象初始化顺序为 createFields → MultiphaseSystem → phaseSystem,当前插入新增对象mesh2位于 MultiphaseSystem.H,以上三个文件不在同一个文件中,其简要关系如下:

                     // 主文件夹                            //  1层子文件夹                                //  2层子文件夹                                     //  3层子文件夹
                   CreateFields.H  ———    (文件夹phasesSystem)   ————  (文件夹phaseSystem)————    (文件夹multiphaseSystem)
                                                                                                                                       |                                                          |
                                                                                                                                       |                                                          |
                                                                                                                           phaseSystem.H/.C                         multiphaseSystem.H/.C

当前存在问题有三:
(1)在类内对象初始化时,即便包含了相应的头文件依然会显示未定义,这里meshPtr()并非fvMesh的成员函数,可以定位到CreateMesh.H
但是这里似乎不能包含这个用于初始化mesh对象的头文件

Foam::autoPtr<Foam::fvMesh> meshPtr(nullptr);

(2)本问题的根本目的是构造一个类型为fvMesh&,除了不是const,与mesh完全相同的对象以记录即时修改的数据,因为此执行代码高度耦合,若不进行完全重构,并不能通过构造一个与mesh等大小数组的形式完成,原因是位于phaseSystem的修改参数难以传递出来,已尝试过声明为extern无效,通过友元类对象先行初始化mesh2无效,修改或重载构造函数以完成传参在类multiphaseSystem中因为代码执行耦合度高,行不通
(3)为什么对类对象列表初始化时,定义在全局上的变量,如Foam::IOobject::AUTO_WRITE有效,而在类内使用有时会出现无效
涉及代码段:

//  此代码片段为   MultiphaseSystem.H  
#ifndef multiphaseSystem_H
#define multiphaseSystem_H

#include "phaseSystem.H"  // 这里关联到phaseSystem,
#include "UPtrList.H"
#include "phasePairKey.H"
#include "HashPtrTable.H"

#include "fvMesh.H"  // 这里是新增的包含文件,即便加入也同样会报上述相同错误

namespace Foam
{
     class multiphaseSystem : public phaseSystem     //  这一段是什么意思?
     {
          public: 
           fvMesh & mesh2 = meshPtr();
           volScalarField E;
          // 省略不相关部分   
          //  此处报错:  lnInclude/multiphaseSystem.H:135:26: error: ‘meshPtr’ was not declared in this scope
     }
}

另一种方案,用友元类对象绕开multiphaseSystem构造函数难以修改的问题,遇到相类似的报错信息:

// 位于createFields.H的部分
fvMesh & mesh2 = meshPtr();
    volScalarField E
        (
            IOobject
            (
                "E",
                //runTime.timeName(),
                mesh2,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh2
        );
    extern TSI= Foam::TS(mesh2,E);    // 这里的全局变量声明显然没有生效
    autoPtr<multiphaseSystem> fluidPtr = multiphaseSystem::New(mesh);  // 由于这里导致不能直接修改对应的构造函数
//  位于multiphaseSystem.H的部分
   class TS
{
    public:
    fvMesh & mesh2;
    volScalarField E;
    friend multiphaseSystem;      //  与类multiphaseSystem声明在同一个文件中
};
  //  位于multiphaseSystem.C的部分
Foam::multiphaseSystem::multiphaseSystem
(
     const fvMesh& mesh
)
: 
    phaseSystem(mesh,TSI.mesh2,TSI.E),
    cAlphas_(mesh.solverDict("alpha").lookup("cAlphas")),
    ddtAlphaMax_(0.0),
    limitedPhiAlphas_(phaseModels_.size()),
    Su_(phaseModels_.size()),
    Sp_(phaseModels_.size())
//  其他对象成员实例化部分省略
// 报错信息:phaseSystem/multiphaseSystem/multiphaseSystem.C:70:22: error: ‘TSI’ was not declared in this scope
     phaseSystem(mesh,TSI.mesh2,TSI.E),

基于Monster 组和GPT的调写:

  • 针对问题1:在类内对象初始化时,即便包含了相应的头文件依然会显示未定义
    这可能是由于在某个类内使用了其它类的对象,但是该类的头文件没有被正确地包含,从而导致未定义的错误。建议检查头文件是否都被正确地包含,并且在编译时是否能够找到这些头文件。
  • 针对问题2:构造一个类型为 fvMesh &,除了不是 const,与 mesh 完全相同的对象以记录即时修改的数据
    由于 fvMesh 是一个 C++ 对象,如果要在运行时修改其成员变量的值,要用一个非常量的引用或指针来访问 fvMesh 对象。如果不能在原始代码中修改 fvMesh 对象的类型,可考虑用继承或者组合的方式来扩展 fvMesh 类型,以实现目的。
  • 针对问题3:为什么对类对象列表初始化时,在类内使用有时会出现无效
    这可能是因为全局变量或静态变量在编译时已经被初始化了,而局部变量则需要在运行时才能初始化。如果在使用全局变量或静态变量时出现问题,确保这些变量已经被正确地初始化,或者将其声明为静态成员变量。另外,如果代码被分散在多个文件中,确保这些变量的声明和定义是一致的,以避免链接错误。

引用chatGPT作答,针对你提出的三个问题,我分别给出如下的解答:

(1)关于meshPtr未定义的问题,需要在multiphaseSystem.H中包含CreateMesh.H头文件。需要注意的是,由于CreateMesh.H包含fvMesh.H头文件,因此需要在multiphaseSystem.H中添加包含fvMesh.H头文件的语句。

(2)关于构造一个类型为fvMesh&的对象来记录即时修改的数据,如果声明为extern无效,那么可以考虑使用静态变量或单例模式来实现。静态变量可以在类内或类外定义,只要其定义在程序可见的作用域内即可。单例模式则可以保证全局只有一个实例对象,并且可以在任何地方获取该对象的引用。使用单例模式的话,需要注意多线程安全问题。

(3)关于全局变量在类内使用有时无效的问题,可能是由于变量的初始化顺序问题导致的。全局变量的初始化顺序是未定义的,可能会在某些情况下导致使用时还没有初始化。建议在类内使用全局变量时,将其声明为静态成员变量,并在类外进行初始化,以保证初始化顺序的正确性。

关于multiphaseSystem类继承phaseSystem类的问题,它的含义是multiphaseSystem类继承自phaseSystem类,并且可以使用phaseSystem类中的成员函数和数据成员。在multiphaseSystem类中,可以通过调用phaseSystem类的构造函数来初始化从phaseSystem类继承来的数据成员,例如在multiphaseSystem类的构造函数中调用phaseSystem类的构造函数来初始化mesh、alpha、U等成员变量。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632