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),
引用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等成员变量。
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!