粒子与网格归属问题
-
另外,假如你的问题只是邻域搜索的话,即
知道一个粒子编号,想求它所在的网格的其他粒子的编号,
那么还可以用最小堆实现。PS:最小堆是一个自动按照从小到大排列的数组。(可以在每个时间步开始的时候排序)
我们建立这样一个数组:
这个数组的下标为粒子编号,而存储的值是网格编号。这个数组总是按照网格编号进行排序。
(我们称之为数组a吧。网格编号记作CID,粒子编号记作PID)由于这个数组是从小到大排序好的,所以它应该大概是这样的
24 35 2 31 42 57
0 0 0 1 1 1
上面的代表粒子编号即下标,下面的是网格编号即值。
总之粒子编号是乱的但网格编号是排好的假如我知道某个粒子的编号是31,那么直接通过索引粒子编号就知道它在1号网格,即
a[31]=1
那么搜索所在网格的其他粒子的时候呢,只需要同时向前和向后搜索就行了。直到搜索得到的
网格编号和当前粒子的网格编号不等为止,即CID!=1即可。这就避免了搜索所有的粒子。
-
我现在用的最笨的方法弄得:
- 网格遍历
- 粒子遍历
- 如果粒子恰好在网格内,就把label存储在当前网格的DynamicList
forAll(U_, cell) { DynamicList<label> pL(0); scalar pN = 0; forAllConstIter(typename MomentumCloud<CloudType>, *this, iter) { const parcelType& p = iter(); if (p.cell() == cell) { pN += 1; pL.append(p.origId()); } } if (pN != 0) { Info<< "Cell[" << cell << "] has " << pN << " particles, " << "particle label is " << pL << nl; } }
输出结果还可以:
Cell[2295] has 2 particles, particle label is 2(20 21) Cell[2297] has 2 particles, particle label is 2(4 7) Cell[2298] has 1 particles, particle label is 1(3) Cell[2340] has 3 particles, particle label is 3(17 18 19) Cell[2341] has 5 particles, particle label is 5(11 13 14 15 16) Cell[2342] has 4 particles, particle label is 4(5 6 8 9) Cell[2343] has 1 particles, particle label is 1(1) Cell[2386] has 1 particles, particle label is 1(12) Cell[2387] has 1 particles, particle label is 1(10) Cell[2388] has 2 particles, particle label is 2(0 2)
但是这里面遍历网格+遍历粒子。肯定是要慢。
-
@李东岳 这么写呢?
List<DynamicList<label>> pL(U_.size()); forAllConstIter(typename MomentumCloud<CloudType>, *this, iter) { const parcelType& p = iter(); pL[p.cell()].append(p.origId()); }
或者
std::Multimap<label,label> Lp; forAllConstIter(typename MomentumCloud<CloudType>, *this, iter) { const parcelType& p = iter(); Lp.insert(std::pair<label,label>(p.cell(), p.origId())); }
都是我云的