48 template <
class T,
unsigned Dim,
class Mesh >
58 template <
class T,
unsigned Dim,
class Mesh >
68 template <
class T,
unsigned Dim,
class Mesh >
78 template <
class T,
unsigned Dim,
class Mesh >
87 template <
class T,
unsigned Dim,
class Mesh >
92 InterNodeList =
new bool[N];
93 SentToNodeList =
new bool[N];
98 MaxGlobalInterRadius = 0;
104 template <
class T,
unsigned Dim,
class Mesh >
107 delete [] InterNodeList;
108 delete [] SentToNodeList;
115 template <
class T,
unsigned Dim,
class Mesh >
127 template <
class T,
unsigned Dim,
class Mesh >
137 bool periodicBC[2*
Dim];
138 unsigned numPeriodicBC = 0;
140 for (
unsigned d=0; d<2*
Dim; ++d) {
141 periodicBC[d] = (pBConds[d] == periodicBCond);
142 if (periodicBC[d]) ++numPeriodicBC;
144 if (numPeriodicBC>0) {
147 swap_ghost_particles(PData.getLocalNum(), PData, periodicBC);
150 swap_ghost_particles(PData.getLocalNum(), PData);
155 swap_ghost_particles(PData.getLocalNum(), PData);
168 template <
class T,
unsigned Dim,
class Mesh >
174 InteractionNodes = 0;
176 T interRad = getMaxInteractionRadius();
180 for (j=0; j < N; ++j)
181 InterNodeList[j] =
false;
190 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
194 for (d=0; d <
Dim; ++d) {
195 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
196 chkDom[d].last() + interRad);
202 this->RLayout.touch_range_rdv(chkDom);
204 for ( ; tVN != touchingVN.second; ++tVN) {
207 unsigned vn = ((*tVN).second)->getNode();
208 if ( ! InterNodeList[vn] ) {
209 InterNodeList[vn] =
true;
218 NeedGhostSwap =
true;
228 template <
class T,
unsigned Dim,
class Mesh >
230 const bool periodicBC[2*
Dim])
236 InteractionNodes = 0;
238 T interRad = getMaxInteractionRadius();
242 for (j=0; j < N; ++j)
243 InterNodeList[j] =
false;
255 bool flipBit, activeBit[
Dim], refBit[
Dim];
265 for (localVN = this->RLayout.
begin_iv(); localVN != endLocalVN; ++localVN) {
268 chkDom = (*localVN).second->getDomain();
269 for (d=0; d<
Dim; ++d) {
270 chkDom[d] =
PRegion<T>(chkDom[d].first() - interRad,
271 chkDom[d].last() + interRad);
277 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
280 unsigned vn = ((*tVN).second)->getNode();
281 if ( ! InterNodeList[vn] ) {
282 InterNodeList[vn] =
true;
289 for (d=0; d<
Dim; ++d) {
290 if (periodicBC[2*d] && chkDom[d].first()<globalDom[d].first()) {
292 offset[d] = globalDom[d].length();
294 numRef = 2 * numRef + 1;
296 else if (periodicBC[2*d+1] && chkDom[d].last()>globalDom[d].last()) {
298 offset[d] = -globalDom[d].length();
300 numRef = 2 * numRef + 1;
304 activeBit[d] =
false;
310 for (j=0; j<numRef; ++j) {
316 while (d<
Dim && !flipBit) {
335 for (d=0; d<
Dim; ++d) {
336 if (refBit[d]) refDom[d] = refDom[d] + offset[d];
342 for (tVN = touchingVN.first; tVN != touchingVN.second; ++tVN) {
345 unsigned vn = ((*tVN).second)->getNode();
346 if ( ! InterNodeList[vn] ) {
347 InterNodeList[vn] =
true;
352 if (!InterNodeList[pe]) {
354 bool interact =
false;
355 localVN2 = this->RLayout.
begin_iv();
356 while (localVN2 != endLocalVN && !interact) {
357 interact = refDom.
touches((*localVN2).second->getDomain());
361 InterNodeList[pe] =
true;
372 NeedGhostSwap =
true;
382 template <
class T,
unsigned Dim,
class Mesh >
389 unsigned LocalNum = PData.getLocalNum();
390 unsigned DestroyNum = PData.getDestroyNum();
398 PData.performDestroy();
399 LocalNum -= DestroyNum;
403 if ( ! this->RLayout.initialized())
404 this->rebuild_layout(LocalNum,PData);
408 this->apply_bconds(LocalNum, PData.R, this->getBConds(), this->RLayout.getDomain());
413 if (N > 1 && this->getUpdateFlag(this->
SWAP)) {
415 LocalNum = this->swap_particles(LocalNum, PData);
417 LocalNum = this->swap_particles(LocalNum, PData, *canSwap);
421 NeedGhostSwap =
true;
424 TotalNum = this->NodeCount[myN] = LocalNum;
449 msg->
get(this->NodeCount);
454 int notrecvd = N - 1;
456 while (notrecvd > 0) {
460 int remNodeCount = 0;
462 msg->
get(remNodeCount);
468 TotalNum += remNodeCount;
469 this->NodeCount[node] = remNodeCount;
470 if (remMaxRad > maxrad)
476 msg->
put(this->NodeCount, this->NodeCount + N);
484 PData.setTotalNum(TotalNum);
485 PData.setLocalNum(LocalNum);
488 if (maxrad != getMaxInteractionRadius()) {
489 setMaxInteractionRadius(maxrad);
494 bool periodicBC[2*
Dim];
495 unsigned numPeriodicBC = 0;
497 for (
unsigned d=0; d<2*
Dim; ++d) {
498 periodicBC[d] = (pBConds[d] == periodicBCond);
499 if (periodicBC[d]) ++numPeriodicBC;
501 if (numPeriodicBC>0) {
504 rebuild_interaction_data(periodicBC);
507 rebuild_interaction_data();
511 rebuild_interaction_data();
525 template <
class T,
unsigned Dim,
class Mesh >
533 if ( ! NeedGhostSwap )
return;
536 NeedGhostSwap =
false;
541 PData.ghostDestroy(PData.getGhostNum(), 0);
545 unsigned sendnum = 0;
546 for (i=0; i < N; i++)
547 if (InterNodeList[i] && this->NodeCount[i] > 0)
552 if (sendnum == 0 || LocalNum == 0) {
558 T interRad = 2.0 * getMaxInteractionRadius();
568 for (i=0; i < N; i++)
569 if (InterNodeList[i] && this->NodeCount[i] > 0)
570 this->SwapMsgList[i] =
new Message;
656 template <
class T,
unsigned Dim,
class Mesh >
660 const bool periodicBC[2*
Dim])
666 if ( ! NeedGhostSwap )
return;
669 NeedGhostSwap =
false;
675 PData.ghostDestroy(PData.getGhostNum(), 0);
680 unsigned sendnum = 0;
681 for (i=0; i < N; i++)
682 if (InterNodeList[i] && this->NodeCount[i] > 0)
686 if (sendnum == 0 || LocalNum == 0)
692 T interRad = getMaxInteractionRadius();
702 bool flipBit, activeBit[
Dim], refBit[
Dim];
716 for (i=0; i < N; i++)
717 if (InterNodeList[i] && this->NodeCount[i] > 0)
718 this->SwapMsgList[i] =
new Message;
724 for (i=0; i < LocalNum; ++i) {
727 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
731 for (j=0; j <
Dim; ++j)
732 pLoc[j] =
PRegion<T>(PData.R[i][j] - interRad,
733 PData.R[i][j] + interRad);
738 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
740 unsigned node = tVN->
getNode();
743 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
744 if (! InterNodeList[node]) {
745 ERRORMSG(
"ParticleCashedLayout: Cannot send ghost " << i);
746 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
749 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
750 SentToNodeList[node] =
true;
757 for (d=0; d<
Dim; ++d) {
758 if (periodicBC[2*d] && pLoc[d].first()<globalDom[d].first()) {
760 offset[d] = globalDom[d].length();
762 numRef = 2 * numRef + 1;
764 else if (periodicBC[2*d+1] && pLoc[d].last()>globalDom[d].last()) {
766 offset[d] = -globalDom[d].length();
768 numRef = 2 * numRef + 1;
772 activeBit[d] =
false;
777 if (numRef>0) savePos = PData.R[i];
780 for (j=0; j<numRef; ++j) {
783 PData.R[i] = savePos;
787 while (d<
Dim && !flipBit) {
806 for (d=0; d<
Dim; ++d) {
808 refLoc[d] = refLoc[d] + offset[d];
809 PData.R[i][d] = PData.R[i][d] + offset[d];
814 memset((
void *)SentToNodeList, 0, N *
sizeof(
bool));
818 for (tVNit = touchingVN.first; tVNit != touchingVN.second; ++tVNit) {
820 unsigned node = tVN->
getNode();
823 if (this->NodeCount[node] > 0 && ! SentToNodeList[node]) {
824 if (! InterNodeList[node]) {
825 ERRORMSG(
"ParticleCashedLayout: Cannot send ghost " << i);
826 ERRORMSG(
" to node " << node <<
" ... skipping." <<
endl);
829 PData.ghostPutMessage(*(this->SwapMsgList[node]), 1, i);
830 SentToNodeList[node] =
true;
836 if (InterNodeList[pe]) {
838 bool interact =
false;
840 while (localVN != endLocalVN && !interact) {
841 interact = refLoc.
touches((*localVN).second->getDomain());
845 PData.ghostPutMessage(*(this->SwapMsgList[pe]), 1, i);
849 if (numRef>0) PData.R[i] = savePos;
855 for (i=0; i < N; ++i) {
856 if (InterNodeList[i] && this->NodeCount[i] > 0) {
858 PData.ghostPutMessage(*(this->SwapMsgList[i]), (
unsigned)0, (
unsigned)0);
866 while (sendnum-- > 0) {
870 while (PData.ghostGetMessage(*recmsg, node) > 0);
880 template <
class T,
unsigned Dim,
class Mesh >
883 out <<
"ParticleCashedLayout, with particle distribution:\n ";
886 out <<
"\nInteractLayout decomposition = " << L.
getLayout();
895 template <
class T,
unsigned Dim,
class Mesh >
904 InteractionNodes = 0;
905 setMaxInteractionRadius(0);
906 NeedGhostSwap =
true;
#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 ParticleCashedLayout< 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 getCashedParticles(IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &)
void swap_ghost_particles(unsigned, IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &)
void update(IpplParticleBase< ParticleCashedLayout< T, Dim, Mesh > > &p, const ParticleAttrib< char > *canSwap=0)
virtual void Repartition(UserList *)
T getMaxLocalInteractionRadius()
void rebuild_interaction_data()
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