Code of the Week #23: IOobject::MUST_READ

#201910

OpenFOAM中很多输入输出的操作都是使用 IOobject 类来实现的,其头文件 src/foam/db/IOobject/IOobject.H 对它的功能进行了说明:

IOobject 定义了对象的一些由 objectRegistry 隐式管理时所需要的属性,同时还提供了基础性的输入/输出流。一个 IOobject 对象在构造的时候需要六个参数:对象名称,类名称,实例路径,一个objectRegistry的引用,以及描述读写方式的参数。

IOobject 的构造函数

IOobject 类有两种构造函数

从对象名称,实例路径,objectRegistry 引用和读写设置来构造。

IOobject  	
(  
   const word &            name,
   const word &            instance,
   const objectRegistry &  registry,
   readOption              r = NO_READ,
   writeOption             w = NO_WRITE,
   bool                    registerObject = true
)

从对象名称,实例路径,位置,objectRegistry引用和读写设置来构造。

IOobject  	
(
   const word &             name,
   const word &             instance,
   const fileName &  		local,
   const objectRegistry &  	registry,
   readOption               r = NO_READ,
   writeOption              w = NO_WRITE,
   bool                     registerObject = true
)

注意 word 是从 string 派生出来的,fileName 也是从 string 派生出来的。Time 和 polyMesh 是从objectRegistry 继承而来。 因此,作为 polyMesh 的派生类,fvMesh 同样也是 objectRegistry 非直接继承的派生类。

读设置选项

读设置选项定义了 IOobject 对象在构造和调用读操作时的行为:

MUST_READ

在对象构造时必须从 Istream 中读取,如果 Istream 不存在或者不能读取时会产生一个错误信息。

READ_IF_PRESENT

如果 Istream 存在,则读取对象,否则不读取。仅仅在 Istream 存在,但是不可读取的情况下才会产生错误信息。

NO_READ

不读取对象

写设置选项

写选项定义了对象在析构和写操作时的行为。

AUTO_WRITE

当objectRegistry要求写的时候会自动写。

NO_WRITE

在对象析构的时候不会自动写,但是可以显式调用写操作。

IOobject 和字典的读写

字典在声明的同时可以使用 IOobject 进行读取。通常,一个字典的内容是设置信息时,其读设置选项会设置成 MUST_READ,而写设置选项则设置为 NO_WRITE 以防设置信息被错误的覆盖。例如通常用来读取输运性质的 transportProperties 字典的定义:

IOdictionary transportProperties
(
    IOobject
    (
         "transportProperties",
         runTime.constant(),
         mesh,
         IOobject::MUST_READ,
         IOobject::NO_WRITE
    )
);

本例中使用了第一种构造函数,其中:

  • “transportProperties” 是含有字典的文件名称。
  • runTime.constant() 实例路径,给出字典的位置,constant 指存在于算例的 constant 路径下。
  • objectRegistry 为 mesh(前面提过 polyMesh 和 fvMesh 都是 objectRegistry 的派生类)。

IOobject 与场的读写

类似于字典,对于场数据的读写设置同样通过 IOobject 类来实现。对于各种类型的场来说,调用的语法甚至都是相同的,可以参考下面的例子。如果我们想定义一个名字叫做 T 的 volScalarField 场,并将其每个时间点计算的场数据保存下来,并放在以时间点命名的路径下,可以这样实现:

volScalarField p
(
    IOobject
    (
        "p",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
);

其中:

  • "p" 为文件名,指的是把 p 数据存为以 p 为文件名的文件。
  • runTime.timeName() 实例路径,这里是告诉 OpenFOAM 将每个文件存储在以运行时间为名称的路径下。
  • mesh 是所需的 objectRegistry。
  • 读/写设置选项设置为 MUST_READAUTO_WRITE 以便 OpenFOAM 可以读取场数据并自动保存。如果不需要读场数据,则需要将 MUST_READ 改为 NO_READ
1 Like