55 template <
class T,
unsigned Dim,
class Mesh >
65 template <
class T,
unsigned Dim,
class Mesh >
75 template <
class T,
unsigned Dim,
class Mesh >
85 template <
class T,
unsigned Dim,
class Mesh >
94 template <
class T,
unsigned Dim,
class Mesh >
99 InterNodeList =
new bool[N];
100 SentToNodeList =
new bool[N];
101 InteractionNodes = 0;
105 MaxGlobalInterRadius = 0;
111 template <
class T,
unsigned Dim,
class Mesh >
114 delete [] InterNodeList;
115 delete [] SentToNodeList;
122 template <
class T,
unsigned Dim,
class Mesh >
134 template <
class T,
unsigned Dim,
class Mesh >
144 bool periodicBC[2*
Dim];
145 unsigned numPeriodicBC = 0;
147 for (
unsigned d=0; d<2*
Dim; ++d) {
148 periodicBC[d] = (pBConds[d] == periodicBCond);
149 if (periodicBC[d]) ++numPeriodicBC;
151 if (numPeriodicBC>0) {
154 swap_ghost_particles(PData.getLocalNum(), PData, periodicBC);
157 swap_ghost_particles(PData.getLocalNum(), PData);
162 swap_ghost_particles(PData.getLocalNum(), PData);
175 template <
class T,
unsigned Dim,
class Mesh >
180 DEBUGMSG(
"ParticleCashedLayout: rebuilding interaction node data."<<
endl);
183 InteractionNodes = 0;
185 T interRad = getMaxInteractionRadius();
189 for (j=0; j < N; ++j)
190 InterNodeList[j] =
false;
199 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
203 for (d=0; d <
Dim; ++d) {
204 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
205 chkDom[d].last() + interRad);
215 for ( ; tVN != touchingVN.second; ++tVN) {
218 DEBUGMSG(
" vnode: node = " << ((*tVN).second)->getNode());
219 DEBUGMSG(
", domain = " << ((*tVN).second)->getDomain() <<
endl);
220 unsigned vn = ((*tVN).second)->getNode();
221 if ( ! InterNodeList[vn] ) {
222 InterNodeList[vn] =
true;
228 DEBUGMSG(
" There are " << InteractionNodes <<
" inter. nodes." <<
endl);
233 NeedGhostSwap =
true;
243 template <
class T,
unsigned Dim,
class Mesh >
245 const bool periodicBC[2*
Dim])
250 DEBUGMSG(
"ParticleCashedLayout: rebuilding interaction node data."<<
endl);
253 InteractionNodes = 0;
255 T interRad = getMaxInteractionRadius();
259 for (j=0; j < N; ++j)
260 InterNodeList[j] =
false;
272 bool flipBit, activeBit[
Dim], refBit[
Dim];
282 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
285 chkDom = (*localVN).second->getDomain();
286 for (d=0; d<
Dim; ++d) {
287 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
288 chkDom[d].last() + interRad);
296 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
299 DEBUGMSG(
" vnode: node = " << ((*tVN).second)->getNode());
300 DEBUGMSG(
", domain = " << ((*tVN).second)->getDomain() <<
endl);
301 unsigned vn = ((*tVN).second)->getNode();
302 if ( ! InterNodeList[vn] ) {
303 InterNodeList[vn] =
true;
310 for (d=0; d<
Dim; ++d) {
311 if (periodicBC[2*d] && chkDom[d].first()<globalDom[d].first()) {
313 offset[d] = globalDom[d].length();
315 numRef = 2 * numRef + 1;
317 else if (periodicBC[2*d+1] && chkDom[d].last()>globalDom[d].last()) {
319 offset[d] = -globalDom[d].length();
321 numRef = 2 * numRef + 1;
325 activeBit[d] =
false;
331 for (j=0; j<numRef; ++j) {
337 while (d<Dim && !flipBit) {
356 for (d=0; d<
Dim; ++d) {
357 if (refBit[d]) refDom[d] = refDom[d] + offset[d];
365 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
368 DEBUGMSG(
" vnode: node = " << ((*tVN).second)->getNode());
369 DEBUGMSG(
", domain = " << ((*tVN).second)->getDomain() <<
endl);
370 unsigned vn = ((*tVN).second)->getNode();
371 if ( ! InterNodeList[vn] ) {
372 InterNodeList[vn] =
true;
377 if (!InterNodeList[pe]) {
379 bool interact =
false;
380 localVN2 = this->RLayout.
begin_iv();
381 while (localVN2 != endLocalVN && !interact) {
382 interact = refDom.
touches((*localVN2).second->getDomain());
386 InterNodeList[pe] =
true;
394 DEBUGMSG(
" There are " << InteractionNodes <<
" inter. nodes." <<
endl);
399 NeedGhostSwap =
true;
409 template <
class T,
unsigned Dim,
class Mesh >
416 unsigned LocalNum = PData.getLocalNum();
417 unsigned DestroyNum = PData.getDestroyNum();
425 PData.performDestroy();
426 LocalNum -= DestroyNum;
430 if ( ! this->RLayout.initialized())
431 this->rebuild_layout(LocalNum,PData);
435 this->apply_bconds(LocalNum, PData.R, this->getBConds(), this->RLayout.getDomain());
440 if (N > 1 && this->getUpdateFlag(this->
SWAP)) {
442 LocalNum = this->swap_particles(LocalNum, PData);
444 LocalNum = this->swap_particles(LocalNum, PData, *canSwap);
448 NeedGhostSwap =
true;
451 TotalNum = this->NodeCount[myN] = LocalNum;
476 msg->
get(this->NodeCount);
481 int notrecvd = N - 1;
483 while (notrecvd > 0) {
487 int remNodeCount = 0;
489 msg->
get(remNodeCount);
495 TotalNum += remNodeCount;
496 this->NodeCount[node] = remNodeCount;
497 if (remMaxRad > maxrad)
503 msg->
put(this->NodeCount, this->NodeCount + N);
511 PData.setTotalNum(TotalNum);
512 PData.setLocalNum(LocalNum);
515 if (maxrad != getMaxInteractionRadius()) {
516 setMaxInteractionRadius(maxrad);
521 bool periodicBC[2*
Dim];
522 unsigned numPeriodicBC = 0;
524 for (
unsigned d=0; d<2*
Dim; ++d) {
525 periodicBC[d] = (pBConds[d] == periodicBCond);
526 if (periodicBC[d]) ++numPeriodicBC;
528 if (numPeriodicBC>0) {
531 rebuild_interaction_data(periodicBC);
534 rebuild_interaction_data();
538 rebuild_interaction_data();
552 template <
class T,
unsigned Dim,
class Mesh >
560 if ( ! NeedGhostSwap )
return;
563 NeedGhostSwap =
false;
568 PData.ghostDestroy(PData.getGhostNum(), 0);
572 unsigned sendnum = 0;
573 for (i=0; i < N; i++)
574 if (InterNodeList[i] && this->NodeCount[i] > 0)
579 if (sendnum == 0 || LocalNum == 0) {
585 T interRad = 2.0 * getMaxInteractionRadius();
595 for (i=0; i < N; i++)
596 if (InterNodeList[i] && this->NodeCount[i] > 0)
597 this->SwapMsgList[i] =
new Message;
683 template <
class T,
unsigned Dim,
class Mesh >
687 const bool periodicBC[2*
Dim])
693 if ( ! NeedGhostSwap )
return;
696 NeedGhostSwap =
false;
702 PData.ghostDestroy(PData.getGhostNum(), 0);
707 unsigned sendnum = 0;
708 for (i=0; i < N; i++)
709 if (InterNodeList[i] && this->NodeCount[i] > 0)
713 if (sendnum == 0 || LocalNum == 0)
719 T interRad = getMaxInteractionRadius();
729 bool flipBit, activeBit[
Dim], refBit[
Dim];
743 for (i=0; i < N; i++)
744 if (InterNodeList[i] && this->NodeCount[i] > 0)
745 this->SwapMsgList[i] =
new Message;
751 for (i=0; i < LocalNum; ++i) {
754 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
758 for (j=0; j <
Dim; ++j)
759 pLoc[j] =
PRegion<T>(PData.R[i][j] - interRad,
760 PData.R[i][j] + interRad);
765 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
767 unsigned node = tVN->
getNode();
770 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
771 if (! InterNodeList[node]) {
772 ERRORMSG(
"ParticleCashedLayout: Cannot send ghost " << i);
773 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
776 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
777 SentToNodeList[node] =
true;
784 for (d=0; d<
Dim; ++d) {
785 if (periodicBC[2*d] && pLoc[d].first()<globalDom[d].first()) {
787 offset[d] = globalDom[d].length();
789 numRef = 2 * numRef + 1;
791 else if (periodicBC[2*d+1] && pLoc[d].last()>globalDom[d].last()) {
793 offset[d] = -globalDom[d].length();
795 numRef = 2 * numRef + 1;
799 activeBit[d] =
false;
804 if (numRef>0) savePos = PData.R[i];
807 for (j=0; j<numRef; ++j) {
810 PData.R[i] = savePos;
814 while (d<Dim && !flipBit) {
833 for (d=0; d<
Dim; ++d) {
835 refLoc[d] = refLoc[d] + offset[d];
836 PData.R[i][d] = PData.R[i][d] + offset[d];
841 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
845 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
847 unsigned node = tVN->
getNode();
850 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
851 if (! InterNodeList[node]) {
852 ERRORMSG(
"ParticleCashedLayout: Cannot send ghost " << i);
853 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
856 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
857 SentToNodeList[node] =
true;
863 if (InterNodeList[pe]) {
865 bool interact =
false;
867 while (localVN != endLocalVN && !interact) {
868 interact = refLoc.
touches((*localVN).second->getDomain());
872 PData.ghostPutMessage(*(this->SwapMsgList[pe]), 1, i);
876 if (numRef>0) PData.R[i] = savePos;
882 for (i=0; i < N; ++i) {
883 if (InterNodeList[i] && this->NodeCount[i] > 0) {
885 PData.ghostPutMessage(*(this->SwapMsgList[i]), (
unsigned)0, (
unsigned)0);
893 while (sendnum-- > 0) {
897 while (PData.ghostGetMessage(*recmsg, node) > 0);
907 template <
class T,
unsigned Dim,
class Mesh >
908 std::ostream& operator<<(std::ostream& out, const ParticleCashedLayout<T,Dim,Mesh>& L) {
910 out <<
"ParticleCashedLayout, with particle distribution:\n ";
912 out << L.getNodeCount(i) <<
" ";
913 out <<
"\nInteractLayout decomposition = " << L.getLayout();
922 template <
class T,
unsigned Dim,
class Mesh >
929 this->rebuild_neighbor_data();
934 InteractionNodes = 0;
935 setMaxInteractionRadius(0);
936 NeedGhostSwap =
true;
void update(IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &p, const ParticleAttrib< char > *canSwap=0)
T ParticlePeriodicBCond(const T t, const T minval, const T maxval)
ID_t getUserListID() const
#define P_SPATIAL_LAYOUT_TAG
int next_tag(int t, int s=1000)
#define P_SPATIAL_RETURN_TAG
void rebuild_interaction_data()
virtual void Repartition(UserList *)
T getMaxLocalInteractionRadius()
bool touches(const NDRegion< T, Dim > &nr) const
#define P_SPATIAL_GHOST_TAG
virtual int broadcast_others(Message *, int, bool delmsg=true)
Message & get(const T &cval)
Message & put(const T &val)
void swap_ghost_particles(unsigned, IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &)
touch_range_dv touch_range_rdv(const NDRegion< T, Dim > &domain)
void getCashedParticles(IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &)
Message * receive_block(int &node, int &tag)
static Communicate * Comm
bool send(Message *, int node, int tag, bool delmsg=true)
Inform & endl(Inform &inf)