决定用Palabos来做了。开始记录一些关于Palabos的笔记。一边学一边记笔记,算是来自于官网的搬运和翻译吧。
知识点: dynamics objects,block-lattice
5.9日更新,修正了一些错误。
1 离散化:构造格子网格
我们通常需要构造一个格子块。而这个格子块通常就是求解域,可以理解成一个这样的东西:
我们知道求解域分为好几种,最简单的就是矩形求解域,就像上图表示的这种。
上图是一个二维的例子。其实对应于具体的类就是BlockLattice2D。BlockLattice2D是一个类模板。Palabos和openfoam一样,大量采用了泛型编程。虽然目前还是刚刚看,不是很了解,但是这个东西应该非常重要。而且看官网的文档,这个类里面包括了非常多的虚函数,应该是不能直接用的东西。于是,要看看是在什么时候对这些类方法进行实现。
但是,如果边界比较复杂,或者局部需要加密的网格,就会用到多块的网格。这里就会用到MultiBlockLattice。
实际上,拿2D的举例,块(block)的继承关系如下图:
可以看到,块分为三种大的类型:
1.1 AtomicBlock2D
AtomicBlock2D应该是最为普通的一种,而前面提到的BlockLattice2D就是继承于它。构造的是一个矩形区域的格子块,其构造函数如下:
1 | AtomicBlock2D (plint nx_, plint ny_) |
可以看到,其参数主要就是nx和ny。后面那个构造函数是复制构造函数。
继承自AtomicBlock2D的,为构造格子块的类是BlockLattice2D。其构造函数是:
1 | template<typename T, template< typename U > class Descriptor> |
nx,ny表达了它继承自简单矩形块的构造方法,此外还多了一个参数,非常重要的参数,那就是Dynamics。Dynamics是动力学构造,在下一节介绍。
1.2 MultiBlock2D
看名字就可以看出来,MultiBlock2D体现在多块网格上。用在格子构造上的是其子类:MultiBlockLattice2D
官方声明:
1 | template<typename T, template< typename U > class Descriptor> |
其描述如下:
A complex LatticeBase, itself decomposed into smaller components.
This extensible class can be used for example for cache-optimized lattices, irregular domains (no memory allocation in areas exterior to the domain) and parallel lattices. The actual behavior of the lattice is parametrizable by a multiBlockHandler instance, which is given to the constructor.
The MultiBlockLattice does not itself possess LatticeProcessors. The Lattice- Processors are delegated to the respective LatticeBases.
翻译(凑合看看):
MultiBlockLattice2D是一种复杂的格子块,它可以分解成更小的组件。
这个可扩展类可用于缓存优化的格子、不规则域(在域外部没有内存分配)和并行网格。网格的实际行为可以通过一个multiBlockHandler实例参数化,该实例被提供给构造函数。
多块格子本身并不拥有格子处理器。这些格子处理器被委托给各自的基础格子。也就是多块格子它们格子有自己的格子处理器。
来看看其构造函数:
1 | template |
这里面包含的参数较多。但是可以看到MultiBlockManagement2D应该是管理多块网格的一个总的联系。BlockCommunicator2D 应该处理的是多块网格之间的数据传递,CombinedStatistics 是一个合并统计,需要进一步了解。MultiCellAccess2D 暂时未知,Dynamics就是指的格子的动态行为了。
MultiBlockLattice2D还有一个构造函数如下:
1 |
|
这个函数实际是为了指定一个背景网格的动态行为。
在官方文档中提到过:When constructing a new block-lattice, you must decide what type of collision is going to be executed on each of its cells, by assigning them a dynamics object. To avoid bugs related to cells without dynamics objects, the constructor of a block-lattice assigns a default-alue for the dynamics to all cells, the so-called background dynamics. After this, the dynamics of each cell can be redefined in order to adjust the behavior of the cells locally.
也就是说, 构造格子时,需要为每个格子分配动态行为:dynamics object。为了防止出现bug,在构造格子时,指定了一个背景动态行为:background dynamics。完成了背景动态行为的指定后,可以对需要单独处理的格子指定其的动态行为。通过两种方法:
- 指定某个格子的动态行为:
1
lattice.get(0,0,0).getDynamics().setOmega(newOmega);
调用get(0,0,0)获得坐标为(0,0,0)的这个cell然后调用getDynamcs()获得这个cell的动态再调用setOmega(newOmega)来设定这个单元的动态的松弛因子。恩,很好。很长。
- 指定某个格子块的动态行为:
1 | // Override background-dynamics to guarantee and independent per-cell |
同时,官方文档里也提到了,defineDynamics方法对不同的类有不同的实现。
1.3 MultiGrid2D
它和MultiBlock2D应该是有着本质的区别。MultiBlock2D体现的是“多块”网格,而MultiGrid2D体现的是“多重”网格。
同样的,创建网格用的应该还是其子类MultiGridLattice2D。
官方的描述:Main class when dealing with grid refinement.
可见,是处理细化网格的主要类。这种细化网格和前面的多块网格有什么区别?
看看它的构造函数:
1 | template<typename T , template< typename U > class Descriptor> |
和多块网格的构造函数有相似之处。MultiGrid2D的构造函数同样有一个管理器:MultiGridManagement2D,但是communicators_ 和combinedStatistics_ 都变成了向量。此外还多了一个 fineGridInstantiator_ 和coarseGridInstantiator_ 变量。从字面意思上看应该是精细网格界面实例化和粗糙网格界面实例化。其应用需要进一步看看实例。
但是可以肯定的是,对于精细网格,就是用的该类来处理。
2 动态行为(dynamics)
显然,动态行为是和物理行为相关最为紧密的。对于如何执行碰撞有和边界条件的实施有着重要的意义。
上图就是dynamic类的继承关系图,可见还是相当复杂的。带红色框的是文档化和结构化的类,也就是用的最多的类。下面列出来,可能会用到的动态:
- BGKdynamics:最基本的BGK动态
- ExternalForceDynamics:包含外力的BGK动态
- GuoExternalForceSmagorinskyBGKdynamics:这个应该是郭照立老师的包含外阿里的BGK动态
- MRTdynamics:多松弛动态,实际上这个多松弛用的并不多
- MomentumExchangeBounceBack:是处理无滑移边界条件的一个非常流行的实施手段。
来看看最基本的BGKdynamics,其构造函数如下:
1 | template<typename T , template< typename U > class Descriptor> |
可见,里面就只需要设置一个参数,那就是松弛因子。而这个类里面也就只包含一个成员变量,就是这个松弛因子omega_。
在BGKdynamics里面,包含了,包括碰撞的实施方法:collide;执行包含宏观量的碰撞方法:collideExternal;计算平衡态分布函数的方法:| computeEquilibrium |
暂时写到这里。主要看了两大类型的类。涉及到定义格子的blocklattice和定义格子动态行为的dynamic。
下一次写初始化和边界条件。