5 #define GET_MASK_X 0x00f 6 #define GET_MASK_Y 0x0f0 7 #define GET_MASK_Z 0xf00 11 #define DOM_SET_POS(n,p,m) ( (n)|=((p)<<(m)) ) 12 #define DOM_GET_POS(n,m,g) ( ((n)&(g))>>(m) ) 14 #define DOM_IF_POS(n,m,d) ( ((n)>>(m))==(d) ) 21 fprintf(stderr,
"Error: ");
22 vfprintf(stderr, s, args);
23 fprintf(stderr,
"exiting the program\n");
34 double CellSize = IfBorder ? CutOffExt : 2.*CutOffExt;
38 NSect[d] = (int)(
Edge[d]/CellSize) + 2*IfMirror;
39 SigErr(CutOffExt > 2.*
Edge[d],
"Insufficient number of cells \n");
51 printf(
"CutOff larger than the cell size\n");
83 int risp = (c[0]+IfMirror)*
Mod10[0]+(c[1]+IfMirror)*
Mod10[1]+(c[2]+IfMirror)*
Mod10[2];
84 SigErr(risp >=
NCell,
"Probably the particle position is not a number or not in the box\n");
87 int DomDecBasics::GetCellChMirror(
int c[3],
int *NeiList){
91 for(
int cx=-1;cx<=1;cx++){
92 NeiCell[0] = NeiMod[0] + cx;
93 for(
int cy=-1;cy<=1;cy++){
94 NeiCell[1] = NeiMod[1] + cy;
95 for(
int cz=-1;cz<=1;cz++){
96 NeiList[NNei++] = NeiCell[0]*
Mod10[0] + NeiCell[1]*
Mod10[1] + NeiCell[2]*
Mod10[2];
104 cd[2] = (int)(c/(
double)
Mod10[2]);
105 cd[1] = (int)((c-cd[2]*
Mod10[2])/(double)Mod10[1]);
106 cd[0] = (int)(c-cd[1]*Mod10[1]-cd[2]*Mod10[2]);
110 int NeiMod[3] = {cd[0],cd[1],cd[2]};
113 for(
int cx=-1;cx<=1;cx++){
114 NeiCell[0] = NeiMod[0] + cx;
115 if(NeiCell[0] >=
NSect[0]) NeiCell[0] -=
NSect[0];
116 if(NeiCell[0] < 0) NeiCell[0] +=
NSect[0];
117 for(
int cy=-1;cy<=1;cy++){
118 NeiCell[1] = NeiMod[1] + cy;
119 if(NeiCell[1] >=
NSect[1]) NeiCell[1] -=
NSect[1];
120 if(NeiCell[1] < 0) NeiCell[1] +=
NSect[1];
121 for(
int cz=-1;cz<=1;cz++){
122 NeiCell[2] = NeiMod[2] + cz;
123 if(NeiCell[2] >=
NSect[2]) NeiCell[2] -=
NSect[2];
124 if(NeiCell[2] < 0) NeiCell[2] +=
NSect[2];
125 NeiList[NNei++] = NeiCell[0]*Mod10[0] + NeiCell[1]*Mod10[1] + NeiCell[2]*Mod10[2];
137 SigErr(c < 0,
"Probably the particle position is not a number\n");
141 int Mask[3] = {MASK_X,MASK_Y,MASK_Z};
142 int GetMask[3] = {GET_MASK_X,GET_MASK_Y,GET_MASK_Z};
143 int Move[3] = {0,0,0};
144 NeiCell[2] = (int)(c/(
double)Mod10[2]);
145 NeiCell[1] = (int)((c-NeiCell[2]*Mod10[2])/(double)Mod10[1]);
146 NeiCell[0] = (int)(c-NeiCell[1]*Mod10[1]-NeiCell[2]*Mod10[2]);
147 for(
int d=0;d<3;d++){
150 if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_LEFT ){
152 int nc = NeiCell[d] - 1;
153 if(nc < 0) nc =
NSect[d]-1;
154 NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
156 else if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_RIGHT ){
158 int nc = NeiCell[d] + 1;
159 if(nc >=
NSect[d]) nc = 0;
160 NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
164 for(
int d=0;d<3;d++){
165 nNei[d] = NeiCell[d];
166 if(Move[d] == DOM_LEFT){
167 nNei[d] = NeiCell[d] - 1;
168 if(nNei[d] < 0) nNei[d] =
NSect[d] - 1;
170 if(Move[d] == DOM_RIGHT){
171 nNei[d] = NeiCell[d] + 1;
172 if(nNei[d] >=
NSect[d]) nNei[d] = 0;
175 NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
178 for(
int dd=0;dd<3;dd++){
179 for(
int d=0;d<3;d++){
180 nNei[d] = NeiCell[d];
181 if(d == dd)
continue;
182 if(Move[d] == DOM_LEFT){
183 nNei[d] = NeiCell[d] - 1;
184 if(nNei[d] < 0) nNei[d] =
NSect[d] - 1;
186 if(Move[d] == DOM_RIGHT){
187 nNei[d] = NeiCell[d] + 1;
188 if(nNei[d] >=
NSect[d]) nNei[d] = 0;
191 NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
203 int Mask[3] = {MASK_X,MASK_Y,MASK_Z};
205 for(
int d=0;d<3;d++){
206 Border[d] = (int)(Pos[d]/
Edge[d]*
NSect[d]);
208 if(Pos[d] - Border[d]*CellLen[d] <
CutOff){
209 DOM_SET_POS(Coord,DOM_LEFT,Mask[d]);
211 if(-Pos[d] + (Border[d]+1)*CellLen[d] <
CutOff){
212 DOM_SET_POS(Coord,DOM_RIGHT,Mask[d]);
219 for(
int c=0;c<
NCell;c++){
235 for(
int c=0;c<
NCell;c++){
236 Cella[c].Curr1 = Cella[c].First;
237 Cella[c].Curr2 = Cella[c].First;
238 if(Cella[c].
NPart > 1)
239 Cella[c].Curr2 = Pc[Cella[c].Curr1].Next;
247 int pl = Cella[c].Last;
248 SigErr(pl == p,
"The particle %d is already the last in the cell %d\n",p,c);
255 for(
int d=0;d<3;d++){
256 Pc[p].Cell[d] = cd[d];
257 Pc[p].Pos[d] = Pos[d];
261 if(Cella[c].
NPart == 1){
266 if(pl >= 0) Pc[pl].Next = p;
270 void DdLinkedList::CheckMirror(
int p){
272 for(
int d=0;d<3;d++){
273 double Pos[3] = {Pc[p].Pos[0],Pc[p].Pos[1],Pc[p].Pos[2]};
274 int cd[3] = {Pc[p].Cell[0],Pc[p].Cell[1],Pc[p].Cell[2]};
275 if(Pc[p].Pos[d] -
CutOff < 0.){
276 Pos[d] = Pc[p].Pos[d] -
CutOff;
281 Pos[d] = Pc[p].Pos[d] +
CutOff;
287 void DdLinkedList::AddMirrorPart(
const int p,
int *cd,
double *Pos){
290 int pl = Cella[c].Last;
291 SigErr(pl == p,
"The particle %d is already the last in the cell %d\n",p,c);
298 for(
int d=0;d<3;d++){
299 Pc[p].Cell[d] = cd[d];
300 Pc[p].Pos[d] = Pos[d];
303 if(Cella[c].
NPart == 1){
308 if(pl >= 0) Pc[pl].Next = p;
314 SigErr(Cella[c].
NPart <= 0,
"Cannot remove, the cell is already empty\n");
315 SigErr(c < 0,
"The cell %d does not exist\n",c);
318 if(Cella[c].
NPart == 0){
325 if(pp == -2) Cella[c].First = pn;
326 else Pc[pp].Next = pn;
327 if(pn == -1) Cella[c].Last = pp;
328 else Pc[pn].Prev = pp;
337 int c1 =
pCella(Pc[p1].Cell);
338 int c2 =
pCella(Pc[p2].Cell);
340 if(Cella[c2].First == p2)
341 Cella[c2].First = p1;
342 if(Cella[c2].Last == p2)
344 if(Cella[c1].First == p1)
345 Cella[c1].First = p2;
346 if(Cella[c1].Last == p1)
350 if(Cella[c1].First == p2)
351 Cella[c1].First = p1;
352 else if(Cella[c1].First == p1)
353 Cella[c1].First = p2;
354 if(Cella[c1].Last == p2)
356 else if(Cella[c1].Last == p1)
359 int p1p = Pc[p1].Prev;
360 int p2p = Pc[p2].Prev;
361 int p1n = Pc[p1].Next;
362 int p2n = Pc[p2].Next;
363 if(p1p >= 0) Pc[p1p].Next = p2;
364 if(p1n >= 0) Pc[p1n].Prev = p2;
365 if(p2p >= 0) Pc[p2p].Next = p1;
366 if(p2n >= 0) Pc[p2n].Prev = p1;
367 Pn.
Prev = Pc[p1].Prev;
368 Pn.
Next = Pc[p1].Next;
369 Pn.
Coord = Pc[p1].Coord;
370 for(
int d=0;d<3;d++){
371 Pn.
Cell[d] = Pc[p1].Cell[d];
372 Pc[p1].Cell[d] = Pc[p2].Cell[d];
373 Pc[p2].Cell[d] = Pn.
Cell[d];
375 Pc[p1].Prev = Pc[p2].Prev;
376 Pc[p1].Next = Pc[p2].Next;
377 Pc[p1].Coord = Pc[p2].Coord;
378 Pc[p2].Prev = Pn.
Prev;
379 Pc[p2].Next = Pn.
Next;
380 Pc[p2].Coord = Pn.
Coord;
387 int c =
pCella(Pc[p].Cell);
388 SigErr(c < 0,
"The cell %d does not exist\n",c);
393 int cn =
pCella(NewPos,cd);
395 SetCoorNumb(NewPos,p);
402 int cn =
pCella(NewPos,cd);
404 SetCoorNumb(NewPos,p);
405 if(cn == co) return ;
410 SigErr(c >= NCell,
"The cell %d does not exist\n",c);
411 SigErr(Cella[c].Curr1 >=
NAllocP,
"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,
NAllocP);
412 return Cella[c].Curr1;
415 if(Cella[c].Curr1 < 0 || Cella[c].
NPart == 0){
416 Cella[c].Curr1 = Cella[c].First;
422 Cella[c].Curr1 = Pc[Cella[c].Curr1].Next;
425 for(SetCounters(c);IfItCell(c);IncrCurr(c)){
427 printf(
"%d) # %d %d_%d_%d %x\n",c,Cella[c].
NPart,Pc[p].Prev,ItCell(c),Pc[p].Next,Pc[p].Coord);
431 for(
int c=0;c<
NCell;c++)
443 SigErr(Cella[c].Curr1 >=
NAllocP,
"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,
NAllocP);
444 SigErr(Cella[c].Curr2 >=
NAllocP,
"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,
NAllocP);
445 *p1 = Cella[c].Curr1;
446 *p2 = Cella[c].Curr2;
449 if(Cella[c].
NPart < 2)
return 0;
450 if(Cella[c].Curr1 == -1){
451 Cella[c].Curr1 = Cella[c].First;
452 Cella[c].Curr2 = Pc[Cella[c].First].Next;
458 int p2 = Cella[c].Curr2;
459 Cella[c].Curr2 = Pc[p2].Next;
460 if(Pc[p2].Next == -1){
461 int p1 = Cella[c].Curr1;
462 Cella[c].Curr1 = Pc[p1].Next;
463 Cella[c].Curr2 = Pc[Pc[p1].Next].Next;
464 if(Cella[c].Curr2 == -1){
468 SigErr(Cella[c].Curr2 >=
NAllocP,
"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,
NAllocP);
475 DomPart::DomPart(
int ExtNPart){
477 Next =
new int[
NPart];
478 Prev =
new int[
NPart];
488 for(
int c=0;c<
NCell;c++){
489 Cella[c].Part.clear();
494 Cella[c].Part.push_back(p);
499 Cella[c].Part.remove(p);
506 Cella[c1].Part.remove(p);
507 Cella[c2].Part.push_back(p);
513 Cella[c1].Part.remove(p1);
514 Cella[c1].Part.push_back(p2);
515 Cella[c2].Part.remove(p2);
516 Cella[c2].Part.push_back(p2);
520 NCurr = Cella[c].Part.begin();
521 NCurr2 = Cella[c].Part.begin();
522 if(Cella[c].Part.size() > 1)
526 if(NCurr == Cella[c].Part.end())
return 0;
540 if(NCurr == Cella[c].Part.end())
546 if(NCurr2 == Cella[c].Part.end()){
553 for(SetCounters(c);IfItCell(c);IncrCurr(c)){
555 printf(
"%d) # %d %d\n",c,Cella[c].Part.size(),ItCell(c));
559 for(
int c=0;c<
NCell;c++)
569 for(
int c=0;c<
NCell;c++){
570 for(
int p=0;p<Cella[c].NPart;p++){
571 Cella[c].Part[p] = -1;
582 if(Cella[c].
NPart > NPCell){
583 printf(
"Maximum allocated size in the domain decomposition (%d) reached, terminating\n",NPCell);
584 assert(Cella[c].
NPart < NPCell);
586 Cella[c].Part[Cella[c].NPart++] = p;
596 int FoundPartInCell = 0;
598 for(
int p=0;p<Cella[c].NPart;p++){
599 if(p1==Cella[c].Part[p]){
600 for(
int pp=p;pp<Cella[c].NPart-1;pp++){
601 Temp = Cella[c].Part[pp];
602 Cella[c].Part[pp] = Cella[c].Part[pp+1];
603 Cella[c].Part[pp+1] = Temp;
612 assert(FoundPartInCell);
634 if(Cella[c].
NPart > 0) NCurr2++;
637 if(NCurr == Cella[c].
NPart)
return 0;
644 return Cella[c].Part[NCurr];
648 *p1 = Cella[c].Part[NCurr];
649 *p2 = Cella[c].Part[NCurr2];
652 if(NCurr >= Cella[c].
NPart)
658 if(NCurr2 >= Cella[c].
NPart){
665 for(SetCounters(c);IfItCell(c);IncrCurr(c)){
667 printf(
"%d) # %d %d\n",c,Cella[c].
NPart,ItCell(c));
671 for(
int c=0;c<
NCell;c++)
679 NGrid = 2*NGridExt-1;
680 int NVertex = NGrid*NGrid*NGrid;
681 Vertex =
new VERTEX[NVertex];
682 vPos =
new PPOS[NVertex];
690 for(
int d=0;d<3;d++){
691 s[d] = (int)(Pos[d]*NGrid);
693 return (s[0]*NGrid+s[1])*NGrid+s[2];
696 int v = GetVertex(Pos);
697 Vertex[v].v.push_back(t);
699 vPos[v].Pos[d] = Pos[d];
702 Vertex[v].v.push_back(t);
704 vPos[v].Pos[d] = Pos[d];
707 Vertex[v].v.remove(t);
710 tCurr = Vertex[v].v.begin();
713 if(tCurr == Vertex[v].v.end())
return 0;
724 Pos[d] = vPos[v].Pos[d];
int Coord
Coordination number.
void AddPart(const int p, double *Pos)
Add a particle to the cell c.
int IfItCouple(const int c)
Tell when the loop is over.
void SigErr(int Condition, const char *s,...)
Handle errors.
void PrintCells()
Print the the particles in the cells.
void MovePart(int p, double *OldPos, double *NewPos)
Move a part.
void Couple(const int c, int *p1, int *p2)
Returns the pointed couple of particle.
int NCell
Number of cells.
int VertCurr(int v)
Current vertex iterator for the vertex v.
void RemPart(int p, double *Pos)
Remove a part from the cell.
int GetCellCoord(int c, int Coord, int *NeiList)
Get the number of the neighbouring cells for the particles close to a wall.
int SetCutOff(double CutOffExt)
Set the CutOff.
void Erase()
Erase the content of the cells.
void SetCounters(int c)
Set the counters to the initial position.
int IfItCell(int c)
End the iteration in the cell.
void Erase()
Erase the pairlist.
void IncrCurrList(const int c)
Increment the pointers.
void PrintCell(const int c)
Print the content of one cell.
int NSect[3]
Number of cells per direction.
int IfItCouple(const int c)
Stop the loop and set the counter to zero.
DomPart & operator++()
Increase the iterator, deactivated.
int GetCellCh(int c, int *NeiList)
Get the number of the neighbouring cells.
void PrintCell(const int c)
Print the particles in a cell.
~NeiVertex()
Delete the class.
void AddPart(int p, double *Pos)
Add a part to the cell.
void SetCounters(int c)
Set the counters to the initial pointer.
NeiVertex(int NTriaExt, int NvPtExt, int NGridExt, double *EdgeExt)
Alloc NVertices.
int IfItCell(int v)
End of the counters.
void RemPart(const int p, double *Pos)
Remove a particle form the cell c.
int NPart
Total number of particle.
void SwapPart(int p1, double *Pos1, int p2, double *Pos2)
Swap two parts.
int ItCell(int c)
Value of the current particle in the cell c.
DomCell & operator=(const DomCell &Dc)
Return the cell class.
void PrintCells()
Print the content of every cell.
void SetCounters()
Set all the counters to zero.
int SetCoorNumb(double *Pos, int p)
Set the coordination umber to the part p.
void PrintCell(const int c)
Print the content of one cell.
void IncrCurr(int c)
Increase the counters.
void IncrCurrList(const int c)
Increment the pointers.
int IfItCell(int c)
End the iteration in the cell.
The previuos and consecutive particle in the cell linked list.
int IfItCell(const int c)
Stop the loop and set the counter to zero.
void AddPart(int p, double *Pos)
Add a part to the cell.
void PrintCell(const int c)
Print the content of a cell.
double CutOff
Cell CutOff.
void IncrCurr(int c)
Increase the counters.
void Add(int v, int t, double *Pos)
Add the triangle t at the vertex v.
void Couple(const int c, int *p1, int *p2)
Returns the pointed couple of particle.
DomCell & operator++()
Increase the iterator, deactivated.
int pNPart()
part in the class
void IncrCurrList(const int c)
Increment the current iterators in the cell.
void IncrCurr(int v)
Increment the counter.
void IncrCurr(const int c)
Increment the current part in the cell.
int pCella(const double Pos[3])
(x,y,z)->n
int Mod10[3]
Module 10 (nx,ny,nz) -> nc.
int Next
Next particle in the list.
void PosVertex(int v, double *Pos)
Position of the vertex v.
int Cell
Which cell it's belonging.
void RemPart(int p, double *Pos)
Remove a part from the cell.
int operator[](int col)
Returns a entry.
void Rem(int v, int t)
Remove the triangle t from the vertex v.
int ItCell(const int c)
Iterate in the cell.
int SwapPart(int p1, double *Pos1, int p2, double *Pos2)
Swap two particles.
void SetCounters(int c)
Set the counters to the initial pointer.
int GetCoorNumb(double *Pos)
Get the coordination number.
int NAllocP
Number of allocated part.
void SwapPart(int p1, double *Pos1, int p2, double *Pos2)
Swap two parts.
void MovePart(int p, double *OldPos, double *NewPos)
Move a part.
For every cube how many particles and which are the first and the last.
double InvEdge[3]
Inverse box size.
void Erase()
Erase the content of the cells.
int pNCell()
Print the number of cells.
void MovePart(const int p, double *OldPos, double *NewPos)
Move a particle form the cell c1 to the cell c2.
int IfItCouple(const int c)
Tell when the loop is over.
int Prev
Previous particle in the list.
The previuos and consecutive particle in the cell linked list.
int GetVertex(double *Pos)
Correspondent vertes for Pos.
int ItCell(int c)
Value of the current particle in the cell c.
void PrintCells()
Print the content of every cell.
void Couple(const int c, int *p1, int *p2)
Iterates along all couples.
int GetCell(double *Pos, int *NeiList)
Get the number of the neighbouring cells for a ghost particle.