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);
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 >
963 std::ostream& operator<<(std::ostream& out, const ParticleInteractLayout<T,Dim,Mesh>&
L) {
965 out <<
"ParticleInteractLayout, with particle distribution:\n ";
967 out <<
L.getNodeCount(i) <<
" ";
968 out <<
"\nInteractLayout decomposition = " <<
L.getLayout();
977 template <
class T,
unsigned Dim,
class Mesh >
986 InteractionNodes = 0;
987 setMaxInteractionRadius(0);
988 NeedGhostSwap =
true;
ID_t getUserListID() const
Message & put(const T &val)
void rebuild_interaction_data()
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent this
Message * receive_block(int &node, int &tag)
std::vector< pair_t >::iterator pair_iterator
int next_tag(int t, int s=1000)
#define P_SPATIAL_GHOST_TAG
Message & get(const T &cval)
clearpage the user may choose between constant or variable radius This model includes fringe fields begin
virtual int broadcast_others(Message *, int, bool delmsg=true)
Inform & endl(Inform &inf)
#define P_SPATIAL_RETURN_TAG
clearpage the user may choose between constant or variable radius This model includes fringe fields L
touch_range_dv touch_range_rdv(const NDRegion< T, Dim > &domain)
T getMaxLocalInteractionRadius()
static Communicate * Comm
void update(IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &p, const ParticleAttrib< char > *canSwap=0)
virtual void Repartition(UserList *)
void getPairlist(unsigned, pair_iterator &, pair_iterator &, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &)
#define P_SPATIAL_LAYOUT_TAG
bool send(Message *, int node, int tag, bool delmsg=true)
~ParticleInteractLayout()
void find_pairs(const unsigned LocalNum, const unsigned a1, const unsigned a2, const bool initLists, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &PData)
T ParticlePeriodicBCond(const T t, const T minval, const T maxval)
bool touches(const NDRegion< T, Dim > &nr) const
void swap_ghost_particles(unsigned, IpplParticleBase< ParticleInteractLayout< T, Dim, Mesh > > &)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.