KMCLib中的Interactions
Interactions类用于描述KMC过程中所有能够发生的process并对其进行操作,
其中包括process的抽取,更新process的match list等。
这两天由于一直在学习CMake相关的东西,没有把看的代码及时总结。特地现在补上。
Interaction类可以看作是process相应的集合,他在全局角度操作process。
成员数据
std::vector<Process> processes_
通过构造函数的参数传入,是所有能在lattice上面发生的process对象的集合。std::vector<Process*> process_pointers_
存放指向processes_中process对象的指针,后面的函数都是在操作这个指针vector。std::vector<std::pair<double,int> > probability_table_
这里叫做概率列表,其实里面并没有放于概率的数据,其中的pair的第一个entry放的是incremental rate,第二个entry放的是对应这个process能在当前lattice上面发生的位点的总数(也就是他的nSite数)。bool implicit_wildcards_
是否使用通配符bool use_custom_rates_
是否使用自定义速率
其他的几个成员数据目前还没有看到具体怎么用,先挖个坑,后面填。
成员函数
这里也只是拎出来几个重要的。
int Interactions::totalAvailableSites() const
计算整个lattice中能够发生process(无论是哪个process)的位点的总数。void Interactions::updateProbabilityTable()
probability_table_这个变量在构造函数中初始化为与processes_长度相同全部为<0.0, 0>的vector。
这个函数就是使用两个迭代器遍历processes_和probability_table_,然后将总速率叠加,并将相应的nSite填充到probability_table_中,结构我用下面的列向量来进行表示:
$$
\left[\begin{matrix}
k_{0} & n_{0} \\
k_{0} + k_{1} & n_{1}\\
k_{0} + k_{1} + k_{2} & n_{2}\\
. & .\\
. & .\\
. & .\\
\end{matrix} \right]
$$int Interactions::pickProcessIndex() const
此函数的作用是在probability_table中随机抽取一种process,并返回此process在列表中的索引号。
这里算是kMC中比较重要的一个函数了,虽然代码不多,但是却可以在上面做文章。关键点就在于用什么算法进行查找并抽取事件。
这里KMCLib的作者直接使用了STL中的lower_bound函数,此函数内部是通过二分查找实现定位,也就是说此查找的复杂度为 $O(logN)$1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator it;
iterator_traits<ForwardIterator>::difference_type count, step;
count = distance(first,last);
while (count>0)
{
it = first; step=count/2; advance (it,step);
if (*it<val) { // or: if (comp(*it,val)), for version (2)
first=++it;
count-=step+1;
}
else count=step;
}
return first;
}void Interactions::updateProcessMatchLists()
该函数的原型:1
2void Interactions::updateProcessMatchLists(const Configuration & configuration,
const LatticeMap & lattice_map)此函数算是interaction类中最复杂的一个成员函数了。其作用是更新所有process的matchlist。通过将process的match list与configuration的minimal match list进行匹配,也就是使用两个迭代器分别遍历向量,判断entry是否相等,(根据MinimalMatchListEntry的运算符重载函数,相等也就意味着元素类型和相应的坐标都相等)。如果不相等就在process的matchlist中插入通配符
*
,若相等就要记录位置索引(因为插入通配符的原因,索引会发生偏移)。最后更新process中相关的信息即可。我结合着其中的unittest来把这个东东的图像总结出来:
首先建个3x3x3的lattice map,初始化一个configuration,其中每个各点有2个basis_points,分别初始化为:1
(V, B), (V, B), (V, B), (V, B), ...
其中的坐标分别为:
1
( (0.0, 0.0, 0.0), (0.3, 0.3, 0.3) ), (1.0, 1.0, 1.0), (1.3, 1.3, 1.3) ), ( (...), (...) ), ...
可能的所有元素类型映射:
1
"*": 0, "A": 1, "B":2, "C": 3
在创建一个process,其中包含三个元素,
元素类型为:1
A, B, V --> B, A, A
在执行此函数之后,程序会向process的match_list中插入相应的通配符,这样能够与configuration中minimal_match_list的顺序匹配上,当然直到process或者configuration的minimal_match_list的迭代器到达超尾位置,这种插入操作就终止了,然后更新process中的move_id相关信息.
操作之后按照下图的顺序:
则process的minimal_match_list元素顺序就更新为:1
2A, V, *, *, *, B
1, 3, 0, 0, 0, 2