33 template <
class T,
unsigned Dim,
class Mesh >
43 template <
class T,
unsigned Dim,
class Mesh >
53 template <
class T,
unsigned Dim,
class Mesh >
63 template <
class T,
unsigned Dim,
class Mesh >
72 template <
class T,
unsigned Dim,
class Mesh >
77 InterNodeList =
new bool[N];
78 SentToNodeList =
new bool[N];
84 MaxGlobalInterRadius = 0;
90 template <
class T,
unsigned Dim,
class Mesh >
93 delete [] InterNodeList;
94 delete [] SentToNodeList;
96 for (
int i=(PairList.size() - 1); i >= 0; --i)
103 template <
class T,
unsigned Dim,
class Mesh >
106 if (InterRadiusArray != 0) {
107 if (InterRadiusArray->size() > 0)
108 return *(max_element(InterRadiusArray->begin(),
109 InterRadiusArray->end()));
124 template <
class T,
unsigned Dim,
class Mesh >
133 bool periodicBC[2*
Dim];
134 unsigned numPeriodicBC = 0;
136 for (
unsigned d=0; d<2*
Dim; ++d) {
137 periodicBC[d] = (pBConds[d] == periodicBCond);
138 if (periodicBC[d]) ++numPeriodicBC;
140 if (numPeriodicBC>0) {
143 swap_ghost_particles(PData.getLocalNum(), PData, periodicBC);
146 swap_ghost_particles(PData.getLocalNum(), PData);
152 swap_ghost_particles(PData.getLocalNum(), PData);
156 bpi = PairList[
n]->begin();
157 epi = PairList[
n]->end();
167 template <
class T,
unsigned Dim,
class Mesh >
173 InteractionNodes = 0;
174 T interRad = 2.0 * getMaxInteractionRadius();
178 for (j=0; j < N; ++j)
179 InterNodeList[j] =
false;
188 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
192 for (d=0; d <
Dim; ++d) {
193 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
194 chkDom[d].last() + interRad);
200 this->RLayout.touch_range_rdv(chkDom);
202 for ( ; tVN != touchingVN.second; ++tVN) {
205 unsigned vn = ((*tVN).second)->getNode();
206 if ( ! InterNodeList[vn] ) {
207 InterNodeList[vn] =
true;
216 NeedGhostSwap =
true;
226 template <
class T,
unsigned Dim,
class Mesh >
228 const bool periodicBC[2*
Dim])
234 InteractionNodes = 0;
235 T interRad = 2.0 * getMaxInteractionRadius();
239 for (j=0; j < N; ++j)
240 InterNodeList[j] =
false;
252 bool flipBit, activeBit[
Dim], refBit[
Dim];
262 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
265 chkDom = (*localVN).second->getDomain();
266 for (d=0; d<
Dim; ++d) {
267 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
268 chkDom[d].last() + interRad);
274 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
277 unsigned vn = ((*tVN).second)->getNode();
278 if ( ! InterNodeList[vn] ) {
279 InterNodeList[vn] =
true;
286 for (d=0; d<
Dim; ++d) {
287 if (periodicBC[2*d] && chkDom[d].first()<globalDom[d].first()) {
289 offset[d] = globalDom[d].length();
291 numRef = 2 * numRef + 1;
293 else if (periodicBC[2*d+1] && chkDom[d].last()>globalDom[d].last()) {
295 offset[d] = -globalDom[d].length();
297 numRef = 2 * numRef + 1;
301 activeBit[d] =
false;
307 for (j=0; j<numRef; ++j) {
313 while (d<
Dim && !flipBit) {
332 for (d=0; d<
Dim; ++d) {
333 if (refBit[d]) refDom[d] = refDom[d] + offset[d];
339 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
342 unsigned vn = ((*tVN).second)->getNode();
343 if ( ! InterNodeList[vn] ) {
344 InterNodeList[vn] =
true;
349 if (!InterNodeList[pe]) {
351 bool interact =
false;
352 localVN2 = this->RLayout.
begin_iv();
353 while (localVN2 != endLocalVN && !interact) {
354 interact = refDom.
touches((*localVN2).second->getDomain());
358 InterNodeList[pe] =
true;
369 NeedGhostSwap =
true;
379 template <
class T,
unsigned Dim,
class Mesh >
386 unsigned LocalNum = PData.getLocalNum();
387 unsigned DestroyNum = PData.getDestroyNum();
389 T maxrad = getMaxLocalInteractionRadius();
393 PData.performDestroy();
394 LocalNum -= DestroyNum;
398 if ( ! this->RLayout.initialized())
399 rebuild_layout(LocalNum,PData);
403 apply_bconds(LocalNum, PData.R, this->getBConds(), this->RLayout.getDomain());
408 if (N > 1 && getUpdateFlag(this->
SWAP)) {
410 LocalNum = swap_particles(LocalNum, PData);
412 LocalNum = swap_particles(LocalNum, PData, *canSwap);
416 NeedGhostSwap =
true;
419 TotalNum = this->NodeCount[myN] = LocalNum;
444 msg->
get(this->NodeCount);
449 int notrecvd = N - 1;
451 while (notrecvd > 0) {
455 int remNodeCount = 0;
457 msg->
get(remNodeCount);
463 TotalNum += remNodeCount;
464 this->NodeCount[node] = remNodeCount;
465 if (remMaxRad > maxrad)
471 msg->
put(this->NodeCount, this->NodeCount + N);
479 PData.setTotalNum(TotalNum);
480 PData.setLocalNum(LocalNum);
483 if (maxrad != getMaxInteractionRadius()) {
484 setMaxInteractionRadius(maxrad);
489 bool periodicBC[2*
Dim];
490 unsigned numPeriodicBC = 0;
492 for (
unsigned d=0; d<2*
Dim; ++d) {
493 periodicBC[d] = (pBConds[d] == periodicBCond);
494 if (periodicBC[d]) ++numPeriodicBC;
496 if (numPeriodicBC>0) {
499 rebuild_interaction_data(periodicBC);
502 rebuild_interaction_data();
506 rebuild_interaction_data();
519 template <
class T,
unsigned Dim,
class Mesh >
527 if ( ! NeedGhostSwap )
return;
530 NeedGhostSwap =
false;
535 PData.ghostDestroy(PData.getGhostNum(), 0);
539 unsigned sendnum = 0;
540 for (i=0; i < N; i++)
541 if (InterNodeList[i] && this->NodeCount[i] > 0)
546 if (sendnum == 0 || LocalNum == 0) {
547 find_pairs(LocalNum, 0, LocalNum,
true, PData);
553 T interRad = 2.0 * getMaxInteractionRadius();
563 for (i=0; i < N; i++)
564 if (InterNodeList[i] && this->NodeCount[i] > 0)
565 this->SwapMsgList[i] =
new Message;
625 find_pairs(LocalNum, 0, LocalNum,
true, PData);
654 template <
class T,
unsigned Dim,
class Mesh >
658 const bool periodicBC[2*
Dim])
664 if ( ! NeedGhostSwap )
return;
667 NeedGhostSwap =
false;
672 PData.ghostDestroy(PData.getGhostNum(), 0);
677 unsigned sendnum = 0;
678 for (i=0; i < N; i++)
679 if (InterNodeList[i] && this->NodeCount[i] > 0)
684 if (sendnum == 0 || LocalNum == 0) {
685 find_pairs(LocalNum, 0, LocalNum,
true, PData);
691 T interRad = 2.0 * getMaxInteractionRadius();
699 bool flipBit, activeBit[
Dim], refBit[
Dim];
713 for (i=0; i < N; i++)
714 if (InterNodeList[i] && this->NodeCount[i] > 0)
715 this->SwapMsgList[i] =
new Message;
721 for (i=0; i < LocalNum; ++i) {
724 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
728 for (j=0; j < (
unsigned int)
Dim; ++j)
729 pLoc[j] =
PRegion<T>(PData.R[i][j] - interRad,
730 PData.R[i][j] + interRad);
734 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
736 unsigned node = tVN->
getNode();
739 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
740 if (! InterNodeList[node]) {
741 ERRORMSG(
"ParticleInteractLayout: Cannot send ghost " << i);
742 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
745 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
746 SentToNodeList[node] =
true;
753 for (d=0; d<
Dim; ++d) {
754 if (periodicBC[2*d] && pLoc[d].first()<globalDom[d].first()) {
756 offset[d] = globalDom[d].length();
758 numRef = 2 * numRef + 1;
760 else if (periodicBC[2*d+1] && pLoc[d].last()>globalDom[d].last()) {
762 offset[d] = -globalDom[d].length();
764 numRef = 2 * numRef + 1;
768 activeBit[d] =
false;
773 if (numRef>0) savePos = PData.R[i];
776 for (j=0; j<numRef; ++j) {
779 PData.R[i] = savePos;
783 while (d<
Dim && !flipBit) {
802 for (d=0; d<
Dim; ++d) {
804 refLoc[d] = refLoc[d] + offset[d];
805 PData.R[i][d] = PData.R[i][d] + offset[d];
810 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
814 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
816 unsigned node = tVN->
getNode();
819 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
820 if (! InterNodeList[node]) {
821 ERRORMSG(
"ParticleInteractLayout: Cannot send ghost " << i);
822 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
825 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
826 SentToNodeList[node] =
true;
831 if (InterNodeList[pe]) {
833 bool interact =
false;
835 while (localVN != endLocalVN && !interact) {
836 interact = refLoc.
touches((*localVN).second->getDomain());
840 PData.ghostPutMessage(*(this->SwapMsgList[pe]), 1, i);
844 if (numRef>0) PData.R[i] = savePos;
850 for (i=0; i < N; ++i) {
851 if (InterNodeList[i] && this->NodeCount[i] > 0) {
853 PData.ghostPutMessage(*(this->SwapMsgList[i]), (
unsigned)0, (
unsigned)0);
861 find_pairs(LocalNum, 0, LocalNum,
true, PData);
864 while (sendnum-- > 0) {
866 unsigned oldGN = PData.getGhostNum();
869 while (PData.ghostGetMessage(*recmsg, node) > 0);
873 find_pairs(LocalNum, LocalNum + oldGN, LocalNum + PData.getGhostNum(),
882 template <
class T,
unsigned Dim,
class Mesh >
884 const unsigned a1,
const unsigned a2,
const bool initLists,
891 unsigned vlen = PairList.size();
894 for (i=0; i < vlen; ++i)
895 PairList[i]->erase(PairList[i]->
begin(), PairList[i]->
end());
898 if (PairList.size() < LocalNum) {
899 int newamt = LocalNum - PairList.size();
900 PairList.reserve(newamt);
901 for (
int k=0; k < newamt; ++k)
902 PairList.push_back(
new std::vector<pair_t>);
907 if (a2 <= a1)
return;
910 for (i=0; i < LocalNum; ++i) {
912 T intrad1 = getInteractionRadius(i);
915 j = (a1 > i ? a1 : i + 1);
919 for (; j < LocalNum; ++j) {
921 T intrad2 = intrad1 + getInteractionRadius(j);
927 T sep2 =
dot(rsep, rsep);
931 if (sep2 < intrad2) {
932 PairList[i]->push_back(
pair_t(j, sep2));
933 PairList[j]->push_back(
pair_t(i, sep2));
939 for (; j < a2; ++j) {
941 T intrad2 = intrad1 + getInteractionRadius(j);
947 T sep2 =
dot(rsep, rsep);
952 if (sep2 < intrad2) {
953 PairList[i]->push_back(
pair_t(j, sep2));
962 template <
class T,
unsigned Dim,
class Mesh >
965 out <<
"ParticleInteractLayout, with particle distribution:\n ";
968 out <<
"\nInteractLayout decomposition = " << L.
getLayout();
977 template <
class T,
unsigned Dim,
class Mesh >
986 InteractionNodes = 0;
987 setMaxInteractionRadius(0);
988 NeedGhostSwap =
true;
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
#define P_SPATIAL_GHOST_TAG
#define P_SPATIAL_RETURN_TAG
#define P_SPATIAL_LAYOUT_TAG
T ParticlePeriodicBCond(const T t, const T minval, const T maxval)
std::ostream & operator<<(std::ostream &out, const ParticleInteractLayout< T, Dim, Mesh > &L)
Inform & endl(Inform &inf)
bool send(Message *, int node, int tag, bool delmsg=true)
virtual int broadcast_others(Message *, int, bool delmsg=true)
Message * receive_block(int &node, int &tag)
Message & put(const T &val)
Message & get(const T &cval)
int next_tag(int t, int s=1000)
int getNodeCount(unsigned i) const
RegionLayout< T, Dim, Mesh > & getLayout()
void find_pairs(const unsigned LocalNum, const unsigned a1, const unsigned a2, const bool initLists, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &PData)
~ParticleInteractLayout()
T getMaxLocalInteractionRadius()
void rebuild_interaction_data()
virtual void Repartition(UserList *)
void update(IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &p, const ParticleAttrib< char > *canSwap=0)
void swap_ghost_particles(unsigned, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &)
std::vector< pair_t >::iterator pair_iterator
void getPairlist(unsigned, pair_iterator &, pair_iterator &, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &)
bool touches(const NDRegion< T, Dim > &nr) const
touch_range_dv touch_range_rdv(const NDRegion< T, Dim > &domain)
ac_id_vnodes::iterator iterator_iv
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
static Communicate * Comm
ID_t getUserListID() const