博文
OpenFOAM中的引用计数(2013-07-30 09:38:00)
摘要:
OpenFOAM中在进行场计算时,涉及大量内存占用量很大的对象的操作,如果对于这些对象均采用“按值”操作而不是“按址”操作那就会造成大量内存耗用,导致程序效率的降低。C++中引用的概念解决了这一问题,但是同时也带来另一个问题就是关于引用计数的问题,同一对象被多重引用所指,那么对于引用个数的跟踪就显得很重要,因为如果依然有引用指向该对象时是不能进行该对象的析构的,因而需要跟踪大内存对象的引用个数,这就出现了引用计数的概念。
可惜在STL中并没有提供引用计数这样的类,因而在OpenFOAM中编写了refCount类用于实现该功能,需要进行引用计数的类只要派生自refCount,结合另一特定的模板类tmp<T>便可实现引用计数的功能。这里需要注意的是refCount的派生类必须要封锁复制构造函数及赋值操作符函数。
......
runtimeSelctionTable宏(2009-02-01 08:32:00)
摘要:简单介绍:
在头文件runTimeSelectionTables.H中声明了两个很重要的宏:
declareRunTimeSelctionTable(autoPtr, baseType, argNames, argList, parList)
defineRunTimeSelectionTable(baseType, argNames)
这里涉及到一个专业词汇 ”run-time selection table”, 这两个宏的定义就是为了方便实现run-time selection table.
首先要说明的是这两个宏是成对的,也就是在源代码文件中这两个宏也要成对使用,一般将第一个宏放在头文件中,而第二个宏放在相应的c文件中。一个为声明另一个是定义实现。
详细描述
Ø declareRunTimeSelectionTable
该宏具有5个参数:autoPtr,baseType,argNames,argList,parList。
首先,利用typedef定义一个函数指针类型 argNamesConstructorPtr,返回值为autoPtr<baseType>,参数为argList;
接着,利用该函数指针通过typedef定义一个HashTable类型:argNamesConstructorTable,该HashTable的模板参数分别为<argNamesConstructorPtr, word, string::hash>;
接着,定一个静态argNamesConstructorTable型的指针变量:argnamesConstructorTablePtr_;
定义一个模板类:addargNamesConstructorToTable,模板参数为baseTypeType,该类中一个静态成员函数New,一个构造函数和一个析构函数。New的参数列表为argList,返回值是autoPtr<baseType>,实际上是调用autoPtr<baseType> (new baseTypeType parList)。构造函数有一个参数(const word& lookup=......
createMesh中用到的IOobject(2008-11-25 09:41:00)
摘要:
Foam::IOobject
(
Foam::fvMesh::defaultRegion,
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
上述代码是摘抄自createMesh.H中进行fvMesh构造时用到的临时IOobject对象的构造代码。
Foam::fvMesh::defaultRegion的值为"region0",这一部分是作为该IOobject的name_成员;
runTime.timeName(),返回的是的runTime的量纲部分dimensioned<scalar>的name_,这一部分是作为该IOobject的instance_c成员;
runTime是作为该IOobject的db_成员;
在由该IOobject构造其它类时这些信息是非常有用的,比如objectRegistry类,regIOobject类等,现在举objectRegistry为例,其以IOobject为参数的构造如下:
Foam::objectRegistry::objectRegistry
(
const IOobject& io,
const label nIoObjects
)
:
&n......
如何用一个IOobject对象来构造一个IOdictionary对象(2008-09-06 13:23:00)
摘要:如何用一个IOobject对象来构造一个IOdictionary对象
经常会看到下面这样的代码:
IOdictionary controlDic_
(
IOobject
(
“nameString”,
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
)
);
这段代码的意思就是要用一个IOobject对象来构造一个IOdictionary对象。就是以IOobject构造的临时对象为实参来调用IOdictionary的以IOobject为形参的构造函数,那么该构造是如何完成的呢,下面让我们来分析一下其实现源代码:
IOdictionary::IOdictionary //代码段1
(
const IOobject& io
)
:
regIOobject(io) <==//Line1
{
dictionary::name() = IOobject::objectPath();
if
(
io.readOpt() == IOo......
OF描述具量纲变量的模板类——dimesioned<Type>(2008-09-04 21:29:00)
摘要:dimensioned<Type>默板类
该类是实现具有量纲变量的类,在给变量值加量纲的同时还给变量加了名字。OF通过该类模板实现标量,矢量,张量三种类型变量的量纲化。相应的在OF中具体实例化的类分别为dimensionedScalar,dimensionedVector和dimensionedTensor。
该类模板中提供了三个私有变量:
word name_; //保存变量的名字
dimesionSet dimensions_; //保存变量的量纲
Type value_; //保存变量值,类型由模板参数Type指出
构造函数(4个):
dimensioned(const word&, const dimensionSet&, const Type); //给定名字,量纲和变量值进行构造
dimensioned(const word&, const dimensioned<Type>&); //量纲和值取自给定的具量纲变量对象,并给其重新命名
dimensioned(const Type& t)
: name_(::Foam::name(t)),
dimensions_(dimless),
value_(t)
{} //仅给出变量值,将构造一个无量纲名字为变量值的类对象
dimensioned(Istream&); //从输入流中读入数据进行对象的构造
成员访问函数对外接口(3*2个):
con......
OF描述量纲的类——dimensionSet(2008-09-04 12:22:00)
摘要:dimensionSet类
该类封装了量纲信息及对量纲的相关运算操作,是实现计算中物理量量纲运算与处理的接口类。
该类首先定义了两个公有枚举类型:
enum{ nDimensions=7 }; //国际单位制中规定了7个标准单位,这些单位在下一个枚举类型中定义
enum dimensionType{ MASS, //质量,单位是kg
LENGTH, //长度,单位是m
TIME, //时间,单位是s
TEMPERATURE, //温度,单位是K
MOLES, //摩尔数,单位是mol
CURRENT, //电流,单位是A(安培)
LUMINOUS_INTENSITY //光强,单位是Cd(坎德拉)
};
保存的私有成员变量:
scalar exponents_[nDimesions]; //用于保存7个标准单位的相应幂指数,例如:
exponents_[MASS], //就表示质量单位的幂指数。 exponents_[TIME], //表示时间单位的幂指数. ……
静态常量smallExponent保存SMALL,主要用来判断各个单位的幂指数是否足够小<abs(SMALL),若在上述范围则表明该单位的量纲是0
该类具有三个构造函数,原型分别如下:
dimensionSet( const scalar mass,
const scalar length,
const scalar time,
const scalar temperature,
const scalar moles......
Time类的基类2——TimePaths(2008-09-03 09:30:00)
摘要:TimePaths是Time的第三个基类,相对其他基类而言该类的结构也相对比较简单,主要封装了算例的相关路径信息,用于保存与算例有关的关键路径的名称,并对这些路径信息进行相应的操作。
该类具有三个类型的五个私有变量:
bool processorCase_; //判断是否是处理器进程的算例?
Foam::fineName rootPath_; //保存算例根路径
Foam::fineName case_; //保存算例名称
Foam::word system_; //保存算例system文件夹的名称
Foam::word constant_; //保存算例constant文件夹名称
构造函数:
TimePaths( const fileName& rootPath,
const fileName& caseName,
const word& systemName,
const word& constantName
);
只声明并定义了这一个构造函数,所给的四个参数分别赋予相应的四个私有成员变量:rootPath_,case_,system_,constant_;另外一个通过检视case_中是否包含"processor"来定义,若包含则为true,否则为false
对私有变量访问的成员函数:
const fileName& rootpath() const; //返回rootPath_
const fileName& caseName() const; //返回cae_
const word& system() const; //返回system_
const word& constant() const; //返回constant_
另外还提供三个路径获取函数:
DLListBase类解读(2008-08-12 16:53:00)
摘要:通过定义的内部结构link实现节点的双向链接,该类完成对双向链表的构造,控制对节点的操作,包括删除,替换,插入,追加,清除链表等,此外该类还提供了内部公有迭代类iterator和const_iterator;这两个类用于实现对链表对象DLListBase的遍历,前者能够实现对链表内元素的修改,后者不能对链表内元素修改。为了更好的实现遍历,DLListBase中还提供了first(),end()成员函数分别生成指向链表第一个元素和最后一个元素的迭代器iterator或const_iterator。
另外该类屏蔽了复制构造函数和赋值构造函数,因此不能通过以下方式进行DLListBase类对象的声明:
DLListBase llistA;
DLListBase llistB(llistA); //这是不允许的,因为复制构造函数被屏蔽
DLListBase llistC=llistA; //也是不行的,赋值构造被屏蔽
三个私有成员变量link* first_,link* last_及label nElmts_分别为指向第一个元素的指针,指向最后一个元素的指针和链表中元素的个数。
构造函数有两个一个为默认构造函数,其将三个私有成员变量均设为0,另外一个以link* a作为函数参数,将first_和last_都设为a,并且将a注册即a->prev_=a;a->next_=a; 私有成员变量nElmts_=1。
成员函数clear()将清除链表,其并不一一删除各元素,只是将自身三个私有变量的值重置为0,其他工作交由link的派生类或程序员来完成。......
DLListBase的内部公有结构link(2008-08-12 16:34:00)
摘要: link是在DLListBase类中定义的公有内部结构,用于实现双向链表节点的前后链接。其有两个成员变量都是link*指针类型,prev_和next_,分别指向该节点的前一个节点和后一个节点另外提供成员函数registered()来判断该link节点是否有前后节点,即是否被注册;及成员函数deregister()完成节点的注销(prev_=0;next_=0;)
该结构是entry类的基础,使得entry具有了双向链接的属性。......
HashTable类详解(2008-07-29 09:18:00)
摘要:OpenFOAM中哈希表的实现也采用了类模板技术,使得其可以实现多种不同类别哈希表的构造。
其类头声明如下:
template <class T, class Key, class Hash> class HashTable {};
其中三个模板参数T为实际存储对象的类型,Key为标示该对象的关键字,Hash类为表中采用的哈希函数对象类。
哈希表的实现采用的是多串链表的形式,在类内部定义了节点的结构:
struct hashedEntry {Key key_; hashedEntry* next_; T obj_;};
这里的三个成员变量key_, next_, obj_分别为节点标示关键字,next_为指向该串下一个节点的指针,obj_为实际保存的对象。
这里所谓的“多串链表”可以如下表示:
fst-->hashedEntry1--next_-->hashedEntry2--next_-->hashedEntry3--next_-->null;
snd-->hashedEntry1--next_-->hashedEntry2--next_-->hashedEntry3--next_-->null;
thrd-->hashedEntry1--next_-->null;
……
……
end-->hashedEntry1--next_-->hashedEntry2--……-->null;
每串链表的首地址之间在内存中是连续的,其相对位置通过模板参数Hash定义的哈希函数计算得到。
实现该多串链表,是通过定义hashedEntry** table_;得到的,各串首地址是通过构造函数里的语句......