openfoam学习心得——openfoam编程重新学

1、OpenFOAM编程入门:setRootCase都干了些啥?
setRootCase都干了些啥
2、blockMesh > log.blockMesh
运行blockMesh这个命令,并将其output写进log文件里面
可以看blockMesh源代码学习数据的写入
3、mesh.boundaryMesh() 返回polyBoundaryMesh类

polyBoundaryMesh类输出结果
(movingWall{type            wall;inGroups        List<word> 1(wall);nFaces          20;startFace       760;}fixedWalls{type            wall;inGroups        List<word> 1(wall);nFaces          60;startFace       780;}frontAndBack{type            patch;nFaces          800;startFace       840;}
)
**polyPatch类:**
type            wall;
inGroups        List<word> 1(wall);
nFaces          20;
startFace       760;**fvboundarymesh类****fvPatch类:**polyPatch可以理解为fvPatch的一个总和,fvpatch用来计算面中心等

4、openfoam Workshop
5、The openfoam technology primer–边界条件与几何场如何结合的
6、 TypeName (“base”)与defineTypeNameAndDebug(AlgorithmBase,0)-必须写类全名

展开为:
ClassName("base");
virtual const word& type() const {return typeName}
再展开:
ClassNameNoDebug("base");
static int debug
virtual const word& type() const {return typeName}
再展开:char*可以指向一个字符串TypeName ("base")最终展开
static const char* typeName_(){return "base"}  //返回classname
virtual const word& type() const {return typeName} //返回typename-虚函数,可被覆盖
static const ::Foam::word typeName
static int debug
这里初始化了两个变量但是没有赋值,下面来看赋值:
defineTypeNameAndDebug(AlgorithmBase,0)
展开为:
defineTypeName(AlgorithmBase)
defineDebugSwitch(AlgorithmBase,0)--debug有关,不深究
展开为:
defineTypeNameWithName(AlgorithmBase,AlgorithmBase::typeName_());
defineDebugSwitch(AlgorithmBase,0)
最后展开为:
const Foam::word AlgorithmBase::TypeName(AlgorithmBase::typeName_())
defineDebugSwitch(AlgorithmBase,0)

咋一看,对于此类类对象,其typeName_()与type()返回值是一样的,但是注意type() 方法是虚函数,固当用指针时,将产生奇效,如下:

autoPtr< incompressible::turbulenceModel > turbulence
turbulence->typeName_()  --返回turbulenceModel
turbulence->type()  --返回kOmega

7、 RTS机制相关宏函数展开
完整代码请移步:openfoam RTS机制分析

第一个要学习的宏函数如下,顺带学习下如何展开宏函数:
#define declareRunTimeSelectionTable(autoPtr,baseType,argNames,argList,parList)\\/* Construct from argList function pointer type */                         \typedef autoPtr<baseType> (*argNames##ConstructorPtr)argList;              \\/* Construct from argList function table type */                           \typedef HashTable<argNames##ConstructorPtr, word, string::hash>            \argNames##ConstructorTable;                                            \\/* Construct from argList function pointer table pointer */                \static argNames##ConstructorTable* argNames##ConstructorTablePtr_;         \\/* Table constructor called from the table add function */                 \static void construct##argNames##ConstructorTables();                      \\/* Table destructor called from the table add function destructor */       \static void destroy##argNames##ConstructorTables();                        \\/* Class to add constructor from argList to table */                       \template<class baseType##Type>                                             \class add##argNames##ConstructorToTable                                    \{                                                                          \public:                                                                    \\static autoPtr<baseType> New argList                                   \{                                                                      \return autoPtr<baseType>(new baseType##Type parList);              \}                                                                      \\add##argNames##ConstructorToTable                                      \(                                                                      \const word& lookup = baseType##Type::typeName                      \)                                                                      \{                                                                      \construct##argNames##ConstructorTables();                          \if (!argNames##ConstructorTablePtr_->insert(lookup, New))          \{                                                                  \std::cerr<< "Duplicate entry " << lookup                       \<< " in runtime selection table " << #baseType             \<< std::endl;                                              \error::safePrintStack(std::cerr);                              \}                                                                  \}                                                                      \\~add##argNames##ConstructorToTable()                                   \{                                                                      \destroy##argNames##ConstructorTables();                            \}                                                                      \};                                                                         \\/* Class to add constructor from argList to table */                       \/* Remove only the entry (not the table) upon destruction */               \template<class baseType##Type>                                             \class addRemovable##argNames##ConstructorToTable                           \{                                                                          \/* retain lookup name for later removal */                             \const word& lookup_;                                                   \\public:                                                                    \\static autoPtr<baseType> New argList                                   \{                                                                      \return autoPtr<baseType>(new baseType##Type parList);              \}                                                                      \\addRemovable##argNames##ConstructorToTable                             \(                                                                      \const word& lookup = baseType##Type::typeName                      \)                                                                      \:                                                                      \lookup_(lookup)                                                    \{                                                                      \construct##argNames##ConstructorTables();                          \argNames##ConstructorTablePtr_->set(lookup, New);                  \}                                                                      \\~addRemovable##argNames##ConstructorToTable()                          \{                                                                      \if (argNames##ConstructorTablePtr_)                                \{                                                                  \argNames##ConstructorTablePtr_->erase(lookup_);                \}                                                                  \}                                                                      \};
 declareRunTimeSelectionTable--一次声明对应一个构造函数(autoPtr, AlgorithmBase, Word,   argNames--word构造、copy构造等(const word& algorithmName    argList-此构造函数形参数),(algorithmName))
展开后如下:
上面宏中###是为了区分开参数与非参数
typedef autoPtr< AlgorithmBase > (*WordConstructorPtr)( const word& algorithmName );
函数指针--WordConstructorPtr理解成一个类,其对象就是函数指针
string::hash默认参数,word是key,value是WordConstructorPtr类(或叫函数指针)
typedef HashTable< WordConstructorPtr, word, string::hash > WordConstructorTable;
初始化哈希表指针-静态的,父类、子类对象均可访问此表-所有对象访问的都是同一张表
static WordConstructorTable* WordConstructorTablePtr_;
函数声明
static void constructWordConstructorTables();
static void destroyWordConstructorTables();
template< class AlgorithmBaseType >--类中类
class addWordConstructorToTable --将构造函数添加到Hash表中
{public:static autoPtr< AlgorithmBase > New ( const word& algorithmName ){给指向基类的指针动态分配内存-指向由word构造生成的基类对象return autoPtr< AlgorithmBase >(new AlgorithmBaseType (algorithmName));}找类中的typename静态名称addWordConstructorToTable ( const word& lookup = AlgorithmBaseType::typeName ){调用前面声明的函数constructWordConstructorTables();New函数是一个前面指定好的函数指针类型if (!WordConstructorTablePtr_->insert(lookup, New)){std::cerr<< "Duplicate entry "<< lookup << " in runtime selection table "<< "AlgorithmBase" << std::endl;error::safePrintStack(std::cerr);}}析构函数,因为前面的函数中一旦调用将产生有动态分配的内存~addWordConstructorToTable(){destroyWordConstructorTables();}
};
类中类
template< class AlgorithmBaseType >
class addRemovableWordConstructorToTable
{const word& lookup_;  私有成员public:静态函数:返回一个基类指针,其指向的可能是别的对象======植入进哈希表的是一个函数static autoPtr< AlgorithmBase > New ( const word& algorithmName ){return autoPtr< AlgorithmBase >(new AlgorithmBaseType (algorithmName));}======植入进哈希表的是一个函数addRemovableWordConstructorToTable ( const word& lookup = AlgorithmBaseType::typeName ): lookup_(lookup){constructWordConstructorTables();WordConstructorTablePtr_->set(lookup, New);}=======删除某个哈希表元素~addRemovableWordConstructorToTable(){if (WordConstructorTablePtr_){WordConstructorTablePtr_->erase(lookup_);}}
};

上面声明了一个静态数据成员-一张哈希表,key-typename;value是一个函数:此函数的功能是为基类指针复制基类或子类对象。下面的宏将上述静态变量与函数展开。

defineRunTimeSelectionTable(AlgorithmBase, Word)展开后如下:
初始化
AlgorithmBase::WordConstructorTable* AlgorithmBase::WordConstructorTablePtr_ = __null;不至于变成野指针void AlgorithmBase::constructWordConstructorTables() {static bool constructed = false;if (!constructed) {constructed = true;初始化哈希表指针-分配了内存AlgorithmBase::WordConstructorTablePtr_ = new AlgorithmBase::WordConstructorTable; }};如果这个指针不为空指针,就删除堆内存的对象,并设置为空指针void AlgorithmBase::destroyWordConstructorTables() {if (AlgorithmBase::WordConstructorTablePtr_) {delete AlgorithmBase::WordConstructorTablePtr_;AlgorithmBase::WordConstructorTablePtr_ = __null;}};

至此,上述的类变定义完成了,我们也搞清楚了类中每个函数的意思,下面还有一个宏来使用上面定义好的类。

addToRunTimeSelectionTable(AlgorithmBase, AlgorithmBase, Word)展开为:
这里告诉我们如何调用类中类
AlgorithmBase::addWordConstructorToTable< AlgorithmBase > addAlgorithmBaseWordConstructorToAlgorithmBaseTable_;

上面初始化一个类中类对象,在初始化过程中,为基类的哈希表中插入了key-value对,这说明这个表会一直存在。即时再用别的基类对象访问这个表,此表仍然存在相同的数据。第一个AlgorithmBase表示addWordConstructorToTable方法位于基类中,第二个参数AlgorithmBase,代表了插入的key-value的typename函数以及New函数的功能,其返回的是一个基类还是子类对象有此参数指定。可能有点难理解,我们来看其子类。

class AlgorithmNew
:public AlgorithmBase
{public: // Declare the static variable typeName of the class AlgorithmNew.TypeName ("new");// Empty constructor. AlgorithmNew () {};// Word constructor.AlgorithmNew (const word& algorithmName) {};// Make the class callable (function object) virtual void operator()(){Info << "AlgorithmNew::operator()()" << endl;}
};
defineTypeNameAndDebug(AlgorithmNew, 0);
addToRunTimeSelectionTable(AlgorithmBase, AlgorithmNew , Word);

此时基类的static成员,哈希表中应该是这样的:
AlgorithmBase – New函数–返回基类指针,指针指向的是以word构造生成的AlgorithmBase类对象
AlgorithmNew – New函数–返回基类指针,指针指向的是以word构造生成的AlgorithmNew类对象

再来一个继承:

class AlgorithmAdditional
:public AlgorithmNew
{public: // Declare the static variable typeName of the class AlgorithmAdditional.TypeName ("additional");// Empty constructor. AlgorithmAdditional () {};// Word constructor.AlgorithmAdditional (const word& algorithmName) {};// Make the class callable (function object) virtual void operator()(){// Call base operator explicitly.AlgorithmNew::operator()();// Perform additional operations.Info << "AlgorithmAdditional::operator()()" << endl;}
};defineTypeNameAndDebug(AlgorithmAdditional, 0);
addToRunTimeSelectionTable(AlgorithmBase, AlgorithmAdditional , Word)

此时基类的static成员,哈希表中应该是这样的:
AlgorithmBase – New函数–返回基类指针,指针指向的是以word构造生成的AlgorithmBase类对象
AlgorithmNew – New函数–返回基类指针,指针指向的是以word构造生成的AlgorithmNew类对象
AlgorithmAdditional – New函数–返回基类指针,指针指向的是以word构造生成的AlgorithmAdditional 类对象

这个表在编译的时候就已经永恒存在了,可以发现都是以word构造生成的对象,要是我有别的构造呢?如copy构造,原理相同。
注意,表中的New函数是定义在addWordConstructorToTable类中-此类为基类中的类的,在基类中同样有一个New函数,充当selector

 static autoPtr< AlgorithmBase > New (const word& algorithmName){输入一个typename--也就是keyWordConstructorTable::iterator cstrIter =WordConstructorTablePtr_->find(algorithmName);找不到就报错// If the Factory Method was not found. if (cstrIter == WordConstructorTablePtr_->end()){FatalErrorIn("AlgorithmBase::New(const word&)")   << "Unknown AlgorithmBase type "<< algorithmName << nl << nl<< "Valid AlgorithmBase types are :" << endl<< WordConstructorTablePtr_->sortedToc()<< exit(FatalError);}cstrIter()--返回key对应的value,也就是new函数,并传参定义基类指针。return cstrIter()(algorithmName);}

从上面代码我们可以学习到,哈希表类中有个迭代器的类中类,()运算符被重载,用来返回key对应的value。
综上学习完毕,RTS机制说直接点就是在基类中生成一个静态的哈希表,基类和子类每编译一次,就往哈希表中加入一个值,其加入值的方法也很精妙,竟然是初始化类中类对象,这个值是永恒的,与求解器运行与否无关,同时基类中还会有一个静态的New函数,用来做选择,看看到底调用哈希表中的哪个函数指针,生成什么类型的对象赋予基类指针。可以猜想定义湍流模型肯定是需要往哈希表中加值的。

8、湍流模型中的RTS分析
1. turbulenceModel 类中
declareRunTimeNewSelectionTable宏-–生成一个哈希表,同时生成往哈希表中插值的类,此时的类中类New函数–也就是此类中哈希表的value返回的是key值所对应类的New函数–选择器:
defineRunTimeSelectionTable宏–这个宏是定义declareRunTimeNewSelectionTable宏中所声明的函数用的

2.RASModel类中
declareRunTimeSelectionTable宏–生成一个哈希表,同时生成往哈希表中插值的类,这个返回的是基类或子类对象。
defineRunTimeSelectionTable(RASModel, dictionary)宏–说明是哈希表中New函数返回的对象是由字典构造生成的。
addToRunTimeSelectionTable(turbulenceModel, RASModel, turbulenceModel)宏–说明将RASModel类添加到turbulenceModel类的哈希表中:
也就是RASModel(类的typename) New—这个函数返回RASModel::New

3、kEpsilon类中
addToRunTimeSelectionTable(RASModel, kEpsilon, dictionary)宏–说明将kEpsilon类添加到RASModel的哈希表中,采用字典构造生成kEpsilon类对象,返回给基类指针。

把类添加到哈希表等同于key=类的typename,value=New函数(属于类中类的New函数),其返回此类对象。某一个类中存在哈希表,则存在select(属于基类的New函数),可以在哈希表中用迭代器来选择函数执行。

故而我们在文件中指定的都是typename–可能与类名相同,也可能不同,一般是一样的。

综上,autoPtr< incompressible::turbulenceModel > turbulence
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);运行过程为,turbulenceModel::New根据字典选择RASModel,则调用RASModel中的RASModel::New函数,然后根据字典选择kEpsilon,则在生成kEpsilon对象。

openfoam学习心得——openfoam编程进阶相关推荐

  1. openfoam学习心得—壁面函数在CFD中如何实施

    openfoam学习心得-壁面函数在CFD中如何实施 最近研究壁面函数,发现邱教授博客,讲的很是不错!记录一下 http://xiaopingqiu.github.io/2016/04/25/wall ...

  2. openfoam学习心得--N-S方程无数种写法汇总与转换

    openfoam学习心得–N-S方程无数种写法汇总与转换以及守恒与非守恒型 在学习openfoam的途中,楼主被流体中存在的无数个方程.同一个方程无数种写法弄的晕头转向,决定对此做一些总结,方便以后查 ...

  3. C++学习心得和进阶路线总结

    C++学习心得和进阶路线总结 借用王国维老先生的话,C++学习也可以分为四个阶段 C++缺点之一,是相对许多语言复杂,而且难学难精.许多人说学习C语言只需一本K&R<C程序设计语言> ...

  4. OpenFOAM学习网站汇总(更新中)

    推荐几个好用的OpenFOAM学习网站: 官网,里面包含了相应的安装包及配套安装教程以及CFD的一些基本知识: 苏军伟的博客,里面讲述了苏教授对于OpenFOAM求解器的一些理解,对于初学者有很大帮助 ...

  5. 【一起学OpenFOAM】04 OpenFOAM的学习资源

    OpenFOAM的学习资料并不多,个人猜测也许是与软件的类型有关系. 对于商用软件来讲,由于要占领市场,软件开发商自然是巴不得会用软件的人越多越好,因为他们卖的是软件,会用的人越多,软件卖得越好.他们 ...

  6. 计算机编程老鸟的心得,java入门123——一个老鸟java学习心得.docx

    java入门123--一个老鸟的java学习心得 学习Java心得体会 学习了一学期的Java课程,觉得是该总结自己的心得体会了.开始学习任何一门课(包括java),兴趣最重要.一直觉得自己在学计算机 ...

  7. c语言编程基础心得,C语言编程学习心得体会

    C语言是在国内外广泛使用的一种计算机语言.其语言功能丰富.表达能力强.使用灵活方便.既具有高级语言的优点,又具有低级语言的许多特点,适合编写系统软件.本文是C语言编程学习心得,希望对大家有帮助. C语 ...

  8. c语言程序培训,C语言编程培训学习心得

    说到C语言学习真的是千言万语,可以说C语言在世界语言排行榜中位居前列,像一些操作系统.驱动软件.多媒体软件.大型游戏. 杀毒软件等等软件操作系统,都是C\C++的特区,对于其他语言来讲真的是望尘莫及. ...

  9. c语言编程培训心得体会,编程培训个人心得体会 编程学习心得

    <编程培训个人心得体会 编程学习心得>由会员分享,可在线阅读,更多相关<编程培训个人心得体会 编程学习心得(4页珍藏版)>请在人人文库网上搜索. 1.编程培训个人心得体会 编程 ...

最新文章

  1. mqttnet 详解_MQTTnet 3.0.5学习笔记
  2. 利用windows的rar工具创建自解压安装文件的方法
  3. linux 系统迁移到固态硬盘,windows 和 Linux 系统 从硬盘迁移到SSD
  4. 云服务器可以安装操作系统么,云服务器安装操作系统吗
  5. ant的下载与安装——mybatis学习笔记之预备篇(一)
  6. WindowsAPI中PostMessage与SendMessage的区别
  7. python大于小于_在Python中大于/小于Pandas DataFrames / Series之间的比较
  8. mui 时间样式错乱_微信公众号素材样式中心在哪?公众号动态分割线怎么添加?...
  9. 【转载】向量空间模型VSM及余弦计算
  10. ECCV 2020 论文大盘点-实例分割篇
  11. LaTeX TikZ绘图——组合数学中棋盘多项式的画法
  12. php jquery mysql,使用PHP / MySQL搜索并使用jQuery动态更新
  13. django1.11 mysql配置_Mysql没有使用python3.6与Django 1.11.7连接
  14. Kubernetes master无法加入etcd 集群解决方法
  15. Python【每日一问】27
  16. Python-查看python版本-常用代码-VS编译器版本号
  17. android 汉字笔顺,汉字笔画顺序之启动界面一
  18. SI4463实验笔记
  19. 深度篇——目标检测史(五) 细说 SSD 目标检测
  20. 数据脱敏:k-anonymity,l-diversity,t-closeness

热门文章

  1. 数据结构作业(校园导航系统)
  2. 靖哥哥教你一步一步安装redis监控redis-stat-超详细
  3. DHTMLX Gantt 甘特图 使用
  4. 富士服务器A系列说明书,富士伺服驱动器FALDIC-用户手册.pdf
  5. Place Holder 方法
  6. 邓俊辉《数据结构》-向量学习笔记
  7. SQL SERVER数据库置疑后恢复步骤
  8. 数码管段码代码查询工具
  9. clientX,clientY,screenX,screenY,offsetX,offsetY 区别测试
  10. 实习工作日志-2019.02.25