决定用Palabos来做了。开始记录一些关于Palabos的笔记。一边学一边记笔记,算是来自于官网的搬运和翻译吧。

知识点: dynamics objects,block-lattice

5.9日更新,修正了一些错误。

1 离散化:构造格子网格

我们通常需要构造一个格子块。而这个格子块通常就是求解域,可以理解成一个这样的东西:

blocklattice.png
blocklattice.png

我们知道求解域分为好几种,最简单的就是矩形求解域,就像上图表示的这种。

上图是一个二维的例子。其实对应于具体的类就是BlockLattice2D。BlockLattice2D是一个类模板。Palabos和openfoam一样,大量采用了泛型编程。虽然目前还是刚刚看,不是很了解,但是这个东西应该非常重要。而且看官网的文档,这个类里面包括了非常多的虚函数,应该是不能直接用的东西。于是,要看看是在什么时候对这些类方法进行实现

但是,如果边界比较复杂,或者局部需要加密的网格,就会用到多块的网格。这里就会用到MultiBlockLattice

实际上,拿2D的举例,块(block)的继承关系如下图:

block2D的继承图
block2D的继承图

可以看到,块分为三种大的类型:

1.1 AtomicBlock2D

AtomicBlock2D应该是最为普通的一种,而前面提到的BlockLattice2D就是继承于它。构造的是一个矩形区域的格子块,其构造函数如下:

1
2
AtomicBlock2D (plint nx_, plint ny_)
AtomicBlock2D (AtomicBlock2D const &rhs)

可以看到,其参数主要就是nx和ny。后面那个构造函数是复制构造函数。
继承自AtomicBlock2D的,为构造格子块的类是BlockLattice2D。其构造函数是:

1
2
3
4
5
template<typename T, template< typename U > class Descriptor>
plb::BlockLattice2D< T, Descriptor >::BlockLattice2D ( plint nx_,
plint ny_,
Dynamics< T, Descriptor > * backgroundDynamics_
)

nx,ny表达了它继承自简单矩形块的构造方法,此外还多了一个参数,非常重要的参数,那就是Dynamics。Dynamics是动力学构造,在下一节介绍。

1.2 MultiBlock2D

看名字就可以看出来,MultiBlock2D体现在多块网格上。用在格子构造上的是其子类:MultiBlockLattice2D

官方声明:

1
2
3
template<typename T, template< typename U > class Descriptor>
class plb::MultiBlockLattice2D< T, Descriptor >
A complex LatticeBase, itself decomposed into smaller components.

其描述如下:

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
2
3
4
5
6
7
template class Descriptor>
plb::MultiBlockLattice2D< T, Descriptor >::MultiBlockLattice2D ( MultiBlockManagement2D const & multiBlockManagement_,
BlockCommunicator2D * blockCommunicator_,
CombinedStatistics * combinedStatistics_,
MultiCellAccess2D< T, Descriptor > * multiCellAccess_,
Dynamics< T, Descriptor > * backgroundDynamics_
)

这里面包含的参数较多。但是可以看到MultiBlockManagement2D应该是管理多块网格的一个总的联系。BlockCommunicator2D 应该处理的是多块网格之间的数据传递,CombinedStatistics 是一个合并统计,需要进一步了解。MultiCellAccess2D 暂时未知,Dynamics就是指的格子的动态行为了。

MultiBlockLattice2D还有一个构造函数如下:

1
2
3
4
5

plb::MultiBlockLattice2D< T, Descriptor >::MultiBlockLattice2D ( plint nx,
plint ny,
Dynamics< T, Descriptor > * backgroundDynamics_
)

这个函数实际是为了指定一个背景网格的动态行为

官方文档中提到过: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
2
3
4
// Override background-dynamics to guarantee and independent per-cell
// copy of the dynamics object.
defineDynamics( lattice, lattice.getBoundingBox(),
new BGKdynamics );

同时,官方文档里也提到了,defineDynamics方法对不同的类有不同的实现。

1.3 MultiGrid2D

它和MultiBlock2D应该是有着本质的区别。MultiBlock2D体现的是“多块”网格,而MultiGrid2D体现的是“多重”网格。

同样的,创建网格用的应该还是其子类MultiGridLattice2D

官方的描述:Main class when dealing with grid refinement.

可见,是处理细化网格的主要类。这种细化网格和前面的多块网格有什么区别?

看看它的构造函数:

1
2
3
4
5
6
7
8
9
template<typename T , template< typename U > class Descriptor>
plb::MultiGridLattice2D< T, Descriptor >::MultiGridLattice2D ( MultiGridManagement2D management,
std::vector< BlockCommunicator2D * > communicators_,
std::vector< CombinedStatistics * > combinedStatistics_,
Dynamics< T, Descriptor > * backgroundDynamics,
plint behaviorLevel,
FineGridInterfaceInstantiator< T, Descriptor > * fineGridInstantiator_,
CoarseGridInterfaceInstantiator< T, Descriptor > * coarseGridInstantiator_
)

和多块网格的构造函数有相似之处。MultiGrid2D的构造函数同样有一个管理器:MultiGridManagement2D,但是communicators_ 和combinedStatistics_ 都变成了向量。此外还多了一个 fineGridInstantiator_ 和coarseGridInstantiator_ 变量。从字面意思上看应该是精细网格界面实例化和粗糙网格界面实例化。其应用需要进一步看看实例。

但是可以肯定的是,对于精细网格,就是用的该类来处理

2 动态行为(dynamics)

显然,动态行为是和物理行为相关最为紧密的。对于如何执行碰撞有和边界条件的实施有着重要的意义。

Dynamics的继承关系图
Dynamics的继承关系图

上图就是dynamic类的继承关系图,可见还是相当复杂的。带红色框的是文档化和结构化的类,也就是用的最多的类。下面列出来,可能会用到的动态:

来看看最基本的BGKdynamics,其构造函数如下:

1
2
template<typename T , template< typename U > class Descriptor>
plb::BGKdynamics< T, Descriptor >::BGKdynamics ( T omega_ )

可见,里面就只需要设置一个参数,那就是松弛因子。而这个类里面也就只包含一个成员变量,就是这个松弛因子omega_。

在BGKdynamics里面,包含了,包括碰撞的实施方法:collide;执行包含宏观量的碰撞方法:collideExternal;计算平衡态分布函数的方法:| computeEquilibrium |

暂时写到这里。主要看了两大类型的类。涉及到定义格子的blocklattice和定义格子动态行为的dynamic。

下一次写初始化和边界条件。