本文编译自openfoam wiki(http://openfoamwiki.net/index.php/OpenFOAM_guide/objectRegistry)
objectRegistry是OpenFOAM用于组织模型相关数据的一个分层数据库,它通过IOobject和regIOobject实现。IOobject是用于提供标准输入输出的类,同时具有访问runTime的能力,也是objectRegistry的根类。regIOobject为objectRegistry自动管理对象(object)的注册与反注册。
objectRegistry的主要作用是简化求解器与其数据之间的通讯过程。OpenFOAM为了实现多种求解方法而对这些方法进行了抽象建模,例如:有限体积法,有限差分方法,有线面积方法以及常微分方程求解器。
OpenFOAM主要是通过抽象和模板的方式来实现这些方法,具体来说,就是将这些方法的过程分割成一个个很小的模块,各种方法都可以使用这些模块。为了实现这一目标,建模过程中使用的各类数据都利用一个通用的架构进行打包,这就是objectRegistry。
任何处理模型数据的时候都需要这个类,例如:物理模型,场数据,字典和网格本身。
很难想到有什么不需要这个类的场合。
请参阅 Input/Output operations using dictionaries and the IOobject class.
objectRegistry主要由IOobject,regIOobject和objectRegistry三个部分组成。objectRegistry是一个带有数个成员变量和方法的哈希表,表中使用IOobject::name_记录regIOobjec指针,并实现其读/写操作。objectRegistry中所记录的每一个对象都有在内存和在硬盘两种组织方式和状态,具体是由每个对象自身regIOobject的读写选项来决定的。
实际上对于objectRegistry的继承关系有两类:在内存对象的继承关系和在硬盘对象的继承关系。
一个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)。
在硬盘继承方式取决于对象的读/写行为,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
类似的,在以上这些位置中的只读文件也都可以被求解器读取,当然前提是求解器知道这些文件的存在。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在硬盘继承方式。
objectRegistry运用虚函数来实现一个通用框架,当调用runTime.writeNow()函数时,经历了以下过程:
重要的写函数有:
重要的读函数:
IOobject 处理其他读写操作,如对header的读写。
一个 IOobject 可以看做是一个休眠的 regIOobject. 它并不具备数据输入输出的能力,也不会自动在其objectRegistry注册和反注册对象。事实上, IOobjects 甚至并不真正存在,没有单独的IOobject或者regIOobject(除了IOobject本身). 这种分离只出现在将这两类对象做参数进行传递的过程中。
IOobject 实际上是一个对象的信息描述,这些信息则是用于注册 objectRegistry 并进行记录所需要的. 这些信息包括:
另一方面,regIOobject 是一个可以从其父objectRegistry中注册和反注册的 IOobject 这一点是通过其构造和析构函数实现的。