OpenFOAM中的对象注册(objectRegistry)

本文编译自openfoam wiki(http://openfoamwiki.net/index.php/OpenFOAM_guide/objectRegistry)


objectRegistry是OpenFOAM用于组织模型相关数据的一个分层数据库,它通过IOobjectregIOobject实现。IOobject是用于提供标准输入输出的类,同时具有访问runTime的能力,也是objectRegistry的根类。regIOobjectobjectRegistry自动管理对象(object)的注册与反注册。


1. 为何需要这个类


objectRegistry的主要作用是简化求解器与其数据之间的通讯过程。OpenFOAM为了实现多种求解方法而对这些方法进行了抽象建模,例如:有限体积法,有限差分方法,有线面积方法以及常微分方程求解器。


OpenFOAM主要是通过抽象模板的方式来实现这些方法,具体来说,就是将这些方法的过程分割成一个个很小的模块,各种方法都可以使用这些模块。为了实现这一目标,建模过程中使用的各类数据都利用一个通用的架构进行打包,这就是objectRegistry


2. 什么时候会需要这个类


任何处理模型数据的时候都需要这个类,例如:物理模型,场数据,字典和网格本身。


很难想到有什么不需要这个类的场合。


3. 如何使用这个类


请参阅 Input/Output operations using dictionaries and the IOobject class.


4. 它是如何实现的


4.1 概述


objectRegistry主要由IOobjectregIOobjectobjectRegistry三个部分组成。objectRegistry是一个带有数个成员变量和方法的哈希表,表中使用IOobject::name_记录regIOobjec指针,并实现其读/写操作。objectRegistry中所记录的每一个对象都有在内存在硬盘两种组织方式和状态,具体是由每个对象自身regIOobject的读写选项来决定的。


4.2 继承关系


实际上对于objectRegistry的继承关系有两类:在内存对象的继承关系和在硬盘对象的继承关系。


4.2.1 在内存对象的继承关系


一个objectRegistry其本身就是一个regIOobject,这意味着该对象可以同时被注册为另一个objectRegistry的成员。例如,scalarTransportFoam在初始化的时候就建立了如下表这样的继承关系(按照出现的先后次序)。


runTime                 //Time              (objectRegistry)
|-controlDict           //IOdictionary      (regIOobject)
`-mesh                  //fvMesh            (objectRegistry)
 |-fvSchemes            //IOdictionary      (regIOobject)
 |-fvSolution           //IOdictionary      (regIOobject)
 |-points               //pointIOField      (regIOobject)
 |-faces                //faceIOlist        (regIOobject)
 |-owner                //labelIOlist       (regIOobject)
 |-neighbour            //labelIOlist       (regIOobject)
 |-boundary             //polyBoundaryMesh  (regIOobject)
 |-pointZones           //pointZoneMesh     (regIOobject)
 |-faceZones            //faceZoneMesh      (regIOobject)
 |-cellZones            //cellZoneMesh      (regIOobject)
 |-T                    //volScalarField    (regIOobject)
 |-U                    //volVectorField    (regIOobject)
 `-transportProperties  //IOdictionary      (regIOobject)

以上就是scalarTransportFoam objectRegistry在内存继承方式。


每一个objectRegistry对象都有:指向其所有子regIOobject的指针,其父objectRegistry的引用,以及其拥有者objectRegistry的引用(一般来讲拥有者objectRegistry都是runTime)。


4.2.2 在硬盘继承方式


在硬盘继承方式取决于对象的读/写行为,objectRegistry的读写行为与一般的regIOobject的不同。在典型的写操作过程中,一个regIOobject仅仅把其数据写入文件中,而objectRegistry的写行为则是遍历将其所有子对象,通知它们进行写入操作,读操作则是按需执行。


regIOobject将数据写入自己的文件:


instance_/local_/name_

其中:

instance_可以是:

* timeName()        normally [caseDirectory]/[timeName]     e.g. reactor/0.045
* system()          normally [caseDirectory]/system         e.g. reactor/system
* constant()        normally [caseDirectory]/constant       e.g. reactor/constant
* caseSystem()      normally [caseDirectory]/system, but becomes ../system in parallel runs
* caseConstant()    normally [caseDirectory]/constant, but becomes ../constant in parallel runs

以上函数将local_传递给runTime

  • local_ 是可选的,且可以是任意的。
  • name_ 可以是任意的。

类似的,在以上这些位置中的只读文件也都可以被求解器读取,当然前提是求解器知道这些文件的存在。scalarTransportFoam在硬盘继承如下表所示:

caseDirectory           // directory
|-system                // directory
| |-controlDict         // read-only
| |-fvSchemes           // read-only
| `-fvSolution          // read-only
|-constant              // directory
| |-transportProperties // read-only
| `-polyMesh            // directory
|   |-boundary          // read-only
|   |-faces             // read-only
|   |-neighbour         // read-only
|   |-owner             // read-only
|   `-points            // read-only
`-[timeName, eg 1.5]    // directory
  |-uniform             // directory
  | `-time              // read / write
  |-phi                 // read / write
  |-T                   // read / write
  `-U                   // read / write

scalarTransportFoam objectRegistry在硬盘继承方式。


4.3 读/写函数


objectRegistry运用虚函数来实现一个通用框架,当调用runTime.writeNow()函数时,经历了以下过程:

  1. runTime 调用 regIOobject::write()
  2. regIOobject 调用虚函数 writeObject. 通常这会调用 objectRegistry::writeObject, 但是 Time 重载了这一方法:
  3. 在调用通常的objectRegistry::writeObject之前,runTime::writeObject 首先在位于[caseName]/[timeName]/constant路径写一个名为timeIOdictionary
  4. objectRegistry::writeObject遍历所有的子regIOobject,并调用它们各自的的 writeObject。
  5. 如果子对象是一个普通的regIOobject,则调用regIOobject::writeObject
  6. regIOobject::writeObject将会打开OFstream并调用writeData, 该函数必须在所有的regIOobject中定义。

重要的写函数有:

  • writeObject:
    • objectRegistry 使用该函数调用所有子regIOobjects的 writeObject
    • regIOobject 使用该函数调用自己的 writeData
    • 一些objectRegistry 的派生类会重载这个函数, 如 Time.
  • writeData:
    • objectRegistry 使用error-throw来实现,正常情况下是不会调用的。
    • regIOobject 的纯虚函数 (即 = 0). 所有的继承类必须给出具体实现。


重要的读函数:

  • objectRegistry 会扫描算例文件夹下所有需要重新读取的,发生过该表的文件。这一过程是通过以下两者实现的:
    • readIfModified
    • readModifiedObjects
  • regIOobject
    • read - 使用 readStream 打开文件流并使用 readData 读取数据,最终关闭文件流;
    • readData - 必须由继承类重载,否则会返回失败;
    • readStream - 打开文件流并检查类型.

IOobject 处理其他读写操作,如对header的读写。


4.4 IOobject 与 regIOobject 之间的对比

一个 IOobject 可以看做是一个休眠的 regIOobject. 它并不具备数据输入输出的能力,也不会自动在其objectRegistry注册和反注册对象。事实上IOobjects 甚至并不真正存在,没有单独的IOobject或者regIOobject(除了IOobject本身). 这种分离只出现在将这两类对象做参数进行传递的过程中。

  • 有些对象需要专门使用 IOobject& 进行传递; 
  • regIOobject& 只是用来在将它们自身在objectRegistry进行注册(以及作为他们自身构造函数的参数)。

 IOobject 实际上是一个对象的信息描述,这些信息则是用于注册 objectRegistry 并进行记录所需要的. 这些信息包括:

  • name_ - 用于以下两个用途:
    • 硬盘上的文件名称; and
    • objectRegistry 哈希表中的键值(key);
  • instance_ - 算例文件路径, 不包括最终的反斜杠;
  • local_ - 可选本地路径;
  • db_ - the objectRegistry with which it will register or has registered;
  • rOpt - 读选项
  • wOpt - 写选项

另一方面,regIOobject 是一个可以从其父objectRegistry中注册和反注册的 IOobject 这一点是通过其构造和析构函数实现的。


你可能感兴趣的:(OpenFOAM用户手册)