Allink  v0.1
Cubo.mirror.cpp
00001 #include <Cubo.h>
00002 #define MASK_X 0
00003 #define MASK_Y 4
00004 #define MASK_Z 8
00005 #define GET_MASK_X 0x00f
00006 #define GET_MASK_Y 0x0f0
00007 #define GET_MASK_Z 0xf00
00008 #define DOM_CENTER 0
00009 #define DOM_LEFT   1
00010 #define DOM_RIGHT  2
00011 #define DOM_SET_POS(n,p,m)  ( (n)|=((p)<<(m)) )
00012 #define DOM_GET_POS(n,m,g)    ( ((n)&(g))>>(m) )
00013 //FIXME
00014 #define DOM_IF_POS(n,m,d)   ( ((n)>>(m))==(d) )
00015 //-----------------BASICS-----------------------------
00016 void DomDecBasics::SigErr(int IsWrong,const char * s, ...){
00017 #ifdef DEBUG
00018   if(IsWrong){
00019     va_list args;
00020     va_start(args, s);
00021     fprintf(stderr, "Error: ");
00022     vfprintf(stderr, s, args);
00023     fprintf(stderr, "exiting the program\n");
00024     va_end(args);
00025     abort();
00026   }
00027 #else  
00028   return;
00029 #endif
00030 }
00031 DomDecBasics::DomDecBasics(double EdgeExt[3],int NPartExt,double CutOffExt){
00032   IfMirror = 1;
00033   IfBorder = 0;
00034   double CellSize = IfBorder ? CutOffExt : 2.*CutOffExt;
00035   for(int d=0;d<3;d++){
00036     Edge[d] = EdgeExt[d];
00037     InvEdge[d] = 1./Edge[d];
00038     NSect[d] = (int)(Edge[d]/CellSize) + 2*IfMirror;
00039     SigErr(CutOffExt > 2.*Edge[d],"Insufficient number of cells \n");
00040   }
00041   NPart = 0;
00042   SetCutOff(CutOffExt);
00043   Mod10[0] = 1;
00044   Mod10[1] = NSect[0];
00045   Mod10[2] = NSect[1]*Mod10[1];
00046   NCell = NSect[0]*NSect[1]*NSect[2];
00047 }
00048 int DomDecBasics::SetCutOff(double CutOffExt){
00049   for(int d=0;d<3;d++){
00050     if(CutOffExt > Edge[d]/(double)NSect[d]){
00051       printf("CutOff larger than the cell size\n");
00052       return 1;
00053     }
00054   }
00055   CutOff = CutOffExt;
00056   return 0;
00057 }
00058 int DomDecBasics::pNPart(){
00059   return NPart;
00060 }
00061 int DomDecBasics::pNCell(){
00062   return NCell;
00063 }
00064 int DomDecBasics::GetCell(double *Pos,int *NeiList){
00065   int c = pCella(Pos);
00066   return GetCellCh(c,NeiList);
00067 }
00068 int DomDecBasics::pCella(const double Pos[3]){
00069   int ris[3];
00070   for(int d=0;d<3;d++){
00071     ris[d] = (int)(Pos[d]*InvEdge[d]*NSect[d]);
00072   }
00073   return pCella(ris);
00074 }
00075 int DomDecBasics::pCella(const double *Pos,int *cd){
00076   for(int d=0;d<3;d++){
00077     cd[d] = (int)(Pos[d]*InvEdge[d]*NSect[d]);
00078   }
00079   return pCella(cd);  
00080 }
00081 int DomDecBasics::pCella(const int c[3]){
00082   //+1 for the mirror notation
00083   int risp = (c[0]+IfMirror)*Mod10[0]+(c[1]+IfMirror)*Mod10[1]+(c[2]+IfMirror)*Mod10[2];
00084   SigErr(risp >= NCell,"Probably the particle position is not a number or not in the box\n");
00085   return risp;
00086 }
00087 int DomDecBasics::GetCellChMirror(int c[3],int *NeiList){
00088   int NeiMod[3];
00089   int NeiCell[3];
00090   int NNei = 0;
00091   for(int cx=-1;cx<=1;cx++){
00092     NeiCell[0] = NeiMod[0] + cx;
00093     for(int cy=-1;cy<=1;cy++){
00094       NeiCell[1] = NeiMod[1] + cy;
00095       for(int cz=-1;cz<=1;cz++){
00096    NeiList[NNei++] = NeiCell[0]*Mod10[0] + NeiCell[1]*Mod10[1] + NeiCell[2]*Mod10[2];
00097       }
00098     }
00099   }
00100   return NNei;
00101 }
00102 int DomDecBasics::GetCellCh(int c,int *NeiList){
00103   int cd[3];
00104   cd[2] = (int)(c/(double)Mod10[2]);
00105   cd[1] = (int)((c-cd[2]*Mod10[2])/(double)Mod10[1]);
00106   cd[0] = (int)(c-cd[1]*Mod10[1]-cd[2]*Mod10[2]);
00107   GetCellCh(cd,NeiList);
00108 }
00109 int DomDecBasics::GetCellCh(int *cd,int *NeiList){
00110   int NeiMod[3] = {cd[0],cd[1],cd[2]};
00111   int NeiCell[3];
00112   int NNei = 0;
00113   for(int cx=-1;cx<=1;cx++){
00114     NeiCell[0] = NeiMod[0] + cx;
00115     if(NeiCell[0] >= NSect[0]) NeiCell[0] -= NSect[0];
00116     if(NeiCell[0] < 0) NeiCell[0] += NSect[0];
00117     for(int cy=-1;cy<=1;cy++){
00118       NeiCell[1] = NeiMod[1] + cy;
00119       if(NeiCell[1] >= NSect[1]) NeiCell[1] -= NSect[1];
00120       if(NeiCell[1] < 0) NeiCell[1] += NSect[1];
00121      for(int cz=-1;cz<=1;cz++){
00122    NeiCell[2] = NeiMod[2] + cz;
00123    if(NeiCell[2] >= NSect[2]) NeiCell[2] -= NSect[2];
00124    if(NeiCell[2] < 0) NeiCell[2] += NSect[2];
00125    NeiList[NNei++] = NeiCell[0]*Mod10[0] + NeiCell[1]*Mod10[1] + NeiCell[2]*Mod10[2];
00126       }
00127     }
00128   }
00129   return NNei;
00130 }
00131 int DomDecBasics::GetCellCoord(double *Pos,int *NeiList){
00132   int c = pCella(Pos);
00133   int Coord = GetCoorNumb(Pos);
00134   return GetCellCoord(c,Coord,NeiList);
00135 }
00136 int DomDecBasics::GetCellCoord(int c,int Coord,int *NeiList){
00137   SigErr(c < 0,"Probably the particle position is not a number\n");
00138   int NNei = 0;
00139   int nNei[3];
00140   int NeiCell[3];
00141   int Mask[3]    = {MASK_X,MASK_Y,MASK_Z};
00142   int GetMask[3] = {GET_MASK_X,GET_MASK_Y,GET_MASK_Z};
00143   int Move[3] = {0,0,0};
00144   NeiCell[2] = (int)(c/(double)Mod10[2]);
00145   NeiCell[1] = (int)((c-NeiCell[2]*Mod10[2])/(double)Mod10[1]);
00146   NeiCell[0] = (int)(c-NeiCell[1]*Mod10[1]-NeiCell[2]*Mod10[2]);
00147   for(int d=0;d<3;d++){
00148     int d1 = (d+1)%3;
00149     int d2 = (d+2)%3;
00150     if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_LEFT ){
00151       Move[d] = DOM_LEFT;
00152       int nc = NeiCell[d] - 1;
00153       if(nc < 0) nc = NSect[d]-1;
00154       NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
00155     }
00156     else if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_RIGHT ){
00157       Move[d] = DOM_RIGHT;
00158       int nc = NeiCell[d] + 1;
00159       if(nc >= NSect[d]) nc = 0;
00160       NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
00161     }
00162   }
00163   if(NNei > 1){
00164     for(int d=0;d<3;d++){
00165       nNei[d] = NeiCell[d];
00166       if(Move[d] == DOM_LEFT){
00167    nNei[d] = NeiCell[d] - 1;
00168    if(nNei[d] < 0) nNei[d] = NSect[d] - 1;
00169       }
00170       if(Move[d] == DOM_RIGHT){
00171    nNei[d] = NeiCell[d] + 1;
00172    if(nNei[d] >= NSect[d]) nNei[d] = 0;
00173       }
00174     }
00175     NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
00176   }
00177   if(NNei == 4){
00178     for(int dd=0;dd<3;dd++){
00179       for(int d=0;d<3;d++){
00180    nNei[d] = NeiCell[d];
00181    if(d == dd) continue;
00182    if(Move[d] == DOM_LEFT){
00183      nNei[d] = NeiCell[d] - 1;
00184      if(nNei[d] < 0) nNei[d] = NSect[d] - 1;
00185    }
00186    if(Move[d] == DOM_RIGHT){
00187      nNei[d] = NeiCell[d] + 1;
00188      if(nNei[d] >= NSect[d]) nNei[d] = 0;
00189    }
00190       }
00191     NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
00192     }
00193   }
00194   NeiList[NNei++] = c;
00195   // for(int n=0;n<NNei;n++) assert(NeiList[n] < NCell);
00196   // for(int n=0;n<NNei;n++) assert(NeiList[n] >= 0);
00197   return NNei;
00198 }
00199 int DomDecBasics::GetCoorNumb(double *Pos){
00200   double CellLen[3];
00201   int Border[3];
00202   double BorderR[3];
00203   int Mask[3] = {MASK_X,MASK_Y,MASK_Z};
00204   int Coord = 0;
00205   for(int d=0;d<3;d++){
00206     Border[d]  = (int)(Pos[d]/Edge[d]*NSect[d]);
00207     CellLen[d] = (Edge[d]/(double)NSect[d]);
00208     if(Pos[d] - Border[d]*CellLen[d] < CutOff){
00209       DOM_SET_POS(Coord,DOM_LEFT,Mask[d]);
00210     }
00211     if(-Pos[d] + (Border[d]+1)*CellLen[d] < CutOff){
00212       DOM_SET_POS(Coord,DOM_RIGHT,Mask[d]);
00213     }
00214   }
00215   return Coord;
00216 }
00217 //-------------------LINKED-LIST-------------------------------
00218 void DdLinkedList::Erase(){
00219   for(int c=0;c<NCell;c++){
00220     Cella[c].NPart = 0;
00221     Cella[c].Last = -1;
00222   }
00223   // for(int p=0;p<NPart;p++){
00224   //   Pc[p].Cell = 0;
00225   //   Pc[p].Next = -1;
00226   //   Pc[p].Prev = -2;
00227   // }
00228   NPart = 0;
00229 }
00230 int DdLinkedList::SetCoorNumb(double *Pos,int p){
00231   Pc[p].Coord = GetCoorNumb(Pos);
00232   return Pc[p].Coord;
00233 }
00234 void DdLinkedList::SetCounters(int c1){
00235   for(int c=0;c<NCell;c++){
00236     Cella[c].Curr1 = Cella[c].First;
00237     Cella[c].Curr2 = Cella[c].First;
00238     if(Cella[c].NPart > 1)
00239       Cella[c].Curr2 = Pc[Cella[c].Curr1].Next;
00240   }
00241 }
00242 void DdLinkedList::AddPart(const int p,double *Pos){
00243   int cd[3];
00244   pCella(Pos,cd);
00245   SetCoorNumb(Pos,p);
00246   int c = pCella(cd);
00247   int pl = Cella[c].Last;
00248   SigErr(pl == p,"The particle %d is already the last in the cell %d\n",p,c);
00249   SigErr(p >= NAllocP,"More particle than allocated\n");
00250   SigErr(Cella[c].NPart >= NAllocP,"More particle than allocated\n");
00251   Cella[c].NPart++;
00252   NPart++;
00253   SigErr(pl >= NAllocP,"More particle than allocated\n");
00254   Cella[c].Last = p;
00255   for(int d=0;d<3;d++){
00256     Pc[p].Cell[d] = cd[d];
00257     Pc[p].Pos[d] = Pos[d];
00258   }
00259   AddPartMirror(p);
00260   Pc[p].Next = -1;
00261   if(Cella[c].NPart == 1){
00262     Cella[c].First = p;
00263     Pc[p].Prev = -2;
00264     return ;
00265   }
00266   if(pl >= 0) Pc[pl].Next = p;
00267   Pc[p].Prev = pl;
00268   //printf("%d - %d - %d c) %d last %d coord %x cell %d\n",pp,p,pn,c,Cella[c].Last,Pc[p].Coord,Pc[p].Cell);
00269 }
00270 void DdLinkedList::CheckMirror(int p){
00271   int NCellMirror = 0;
00272   for(int d=0;d<3;d++){
00273     double Pos[3] = {Pc[p].Pos[0],Pc[p].Pos[1],Pc[p].Pos[2]};
00274     int cd[3] = {Pc[p].Cell[0],Pc[p].Cell[1],Pc[p].Cell[2]};
00275     if(Pc[p].Pos[d] - CutOff < 0.){
00276       Pos[d] = Pc[p].Pos[d] - CutOff;
00277       cd[d] -= 1;
00278       AddPart(p,cd,Pos);
00279     }
00280     else if(Edge[d] - Pc[p].Pos[d] < CutOff){
00281       Pos[d] = Pc[p].Pos[d] + CutOff;
00282       cd[d] += 1;
00283       AddPart(p,cd,Pos);
00284     }
00285   }
00286 }
00287 void DdLinkedList::AddMirrorPart(const int p,int *cd,double *Pos){
00288   SetCoorNumb(Pos,p);
00289   int c = pCella(cd);
00290   int pl = Cella[c].Last;
00291   SigErr(pl == p,"The particle %d is already the last in the cell %d\n",p,c);
00292   SigErr(p >= NAllocP,"More particle than allocated\n");
00293   SigErr(Cella[c].NPart >= NAllocP,"More particle than allocated\n");
00294   Cella[c].NPart++;
00295   NPart++;
00296   SigErr(pl >= NAllocP,"More particle than allocated\n");
00297   Cella[c].Last = p;
00298   for(int d=0;d<3;d++){
00299     Pc[p].Cell[d] = cd[d];
00300     Pc[p].Pos[d] = Pos[d];
00301   }
00302   Pc[p].Next = -1;
00303   if(Cella[c].NPart == 1){
00304     Cella[c].First = p;
00305     Pc[p].Prev = -2;
00306     return ;
00307   }
00308   if(pl >= 0) Pc[pl].Next = p;
00309   Pc[p].Prev = pl;
00310 }
00311 void DdLinkedList::RemPart(const int p,const int c){
00312   SigErr(p >= NAllocP,"More particles than allocated\n");
00313   //assert(Cella[c].NPart > 0);
00314   SigErr(Cella[c].NPart <= 0,"Cannot remove, the cell is already empty\n");
00315   SigErr(c < 0,"The cell %d does not exist\n",c);
00316   Cella[c].NPart--;
00317   NPart--;
00318   if(Cella[c].NPart == 0){
00319     Cella[c].First = -2;
00320     Cella[c].Last  = -1;
00321     return ;
00322   }
00323   int pp = Pc[p].Prev;
00324   int pn = Pc[p].Next;
00325   if(pp == -2) Cella[c].First = pn;
00326   else Pc[pp].Next = pn;
00327   if(pn == -1) Cella[c].Last = pp;
00328   else Pc[pn].Prev = pp;
00329   for(int d=0;d<3;d++)
00330     Pc[p].Cell[d] = -1;
00331   //printf("%d - %d - %d c) %d last %d coord %x cell %d\n",pp,p,pn,c,Cella[c].Last,Pc[p].Coord,Pc[p].Cell);
00332   //  assert(pp != -2 && Pc[pp].Next != pp);
00333 }
00334 void DdLinkedList::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00335   if(p1==p2) return ;
00336   DOMAIN_PART Pn;
00337   int c1 = pCella(Pc[p1].Cell);
00338   int c2 = pCella(Pc[p2].Cell);
00339   if(c1!=c2){
00340     if(Cella[c2].First == p2)
00341       Cella[c2].First  = p1;
00342     if(Cella[c2].Last == p2)
00343       Cella[c2].Last  = p1;
00344     if(Cella[c1].First == p1)
00345       Cella[c1].First  = p2;
00346     if(Cella[c1].Last == p1)
00347       Cella[c1].Last  = p2;
00348   }
00349   if(c1==c2){
00350     if(Cella[c1].First == p2)
00351       Cella[c1].First = p1;
00352     else if(Cella[c1].First == p1)
00353       Cella[c1].First = p2;
00354     if(Cella[c1].Last == p2)
00355       Cella[c1].Last = p1;
00356     else if(Cella[c1].Last == p1)
00357       Cella[c1].Last = p2;
00358   }
00359   int p1p = Pc[p1].Prev;
00360   int p2p = Pc[p2].Prev;
00361   int p1n = Pc[p1].Next;
00362   int p2n = Pc[p2].Next;
00363   if(p1p >= 0) Pc[p1p].Next = p2;
00364   if(p1n >= 0) Pc[p1n].Prev = p2;
00365   if(p2p >= 0) Pc[p2p].Next = p1;
00366   if(p2n >= 0) Pc[p2n].Prev = p1;
00367   Pn.Prev  = Pc[p1].Prev;
00368   Pn.Next  = Pc[p1].Next;
00369   Pn.Coord = Pc[p1].Coord;
00370   for(int d=0;d<3;d++){
00371     Pn.Cell[d]  = Pc[p1].Cell[d];
00372     Pc[p1].Cell[d]  = Pc[p2].Cell[d];
00373     Pc[p2].Cell[d]  = Pn.Cell[d];
00374   }
00375   Pc[p1].Prev  = Pc[p2].Prev;
00376   Pc[p1].Next  = Pc[p2].Next;
00377   Pc[p1].Coord = Pc[p2].Coord;
00378   Pc[p2].Prev  = Pn.Prev;
00379   Pc[p2].Next  = Pn.Next;
00380   Pc[p2].Coord = Pn.Coord;
00381 }
00382 void DdLinkedList::RemPart(const int p,double *Pos){
00383   int c = pCella(Pos);
00384   RemPart(p,c);
00385 }
00386 void DdLinkedList::RemPart(const int p){
00387   int c = pCella(Pc[p].Cell);
00388   SigErr(c < 0,"The cell %d does not exist\n",c);
00389   return RemPart(p,c);
00390 }
00391 void DdLinkedList::MovePart(const int p,double *NewPos){
00392   int cd[3];
00393   int cn = pCella(NewPos,cd);
00394   int co = pCell(p);
00395   SetCoorNumb(NewPos,p);
00396   if(cn == co) return;
00397   RemPart(p,co);
00398   AddPart(p,cd);
00399 }
00400 void DdLinkedList::MovePart(const int p,double *OldPos,double *NewPos){
00401   int cd[3];
00402   int cn = pCella(NewPos,cd);
00403   int co = pCella(OldPos);
00404   SetCoorNumb(NewPos,p);
00405   if(cn == co) return ;
00406   RemPart(p,co);
00407   AddPart(p,cd);
00408 }
00409 int DdLinkedList::ItCell(const int c){
00410   SigErr(c >= NCell,"The cell %d does not exist\n",c);
00411   SigErr(Cella[c].Curr1 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,NAllocP);
00412   return Cella[c].Curr1;
00413 }
00414 int DdLinkedList::IfItCell(const int c){
00415   if(Cella[c].Curr1 < 0 || Cella[c].NPart == 0){
00416     Cella[c].Curr1 = Cella[c].First;
00417     return 0;
00418   }
00419   return 1;
00420 }
00421 void DdLinkedList::IncrCurr(const int c){
00422   Cella[c].Curr1 = Pc[Cella[c].Curr1].Next;
00423 }
00424 void DdLinkedList::PrintCell(const int c){
00425   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00426     int p = ItCell(c);
00427     printf("%d) # %d %d_%d_%d %x\n",c,Cella[c].NPart,Pc[p].Prev,ItCell(c),Pc[p].Next,Pc[p].Coord);
00428   }
00429 }
00430 void DdLinkedList::PrintCells(){
00431   for(int c=0;c<NCell;c++)
00432     PrintCell(c);
00433 }
00434 DomCell& DomCell::operator++(){
00435   //It++;
00436   return *this;
00437 }
00438 DomPart& DomPart::operator++(){
00439   
00440 
00441 }
00442 void DdLinkedList::Couple(const int c,int *p1,int *p2){
00443   SigErr(Cella[c].Curr1 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,NAllocP);
00444   SigErr(Cella[c].Curr2 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,NAllocP);
00445   *p1 = Cella[c].Curr1;
00446   *p2 = Cella[c].Curr2;
00447 }
00448 int DdLinkedList::IfItCouple(const int c){
00449   if(Cella[c].NPart < 2) return 0;
00450   if(Cella[c].Curr1 == -1){
00451     Cella[c].Curr1 = Cella[c].First;
00452     Cella[c].Curr2 = Pc[Cella[c].First].Next;
00453     return 0;
00454   }
00455   return 1;
00456 }
00457 void DdLinkedList::IncrCurrList(const int c){
00458   int p2 = Cella[c].Curr2;
00459   Cella[c].Curr2 = Pc[p2].Next;
00460   if(Pc[p2].Next == -1){
00461     int p1 = Cella[c].Curr1;
00462     Cella[c].Curr1 = Pc[p1].Next;
00463     Cella[c].Curr2 = Pc[Pc[p1].Next].Next;
00464     if(Cella[c].Curr2 == -1){
00465       Cella[c].Curr1 = -1;
00466     }
00467   }
00468   SigErr(Cella[c].Curr2 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,NAllocP);
00469 }
00470 DomCell& DomCell::operator=(const DomCell &Dc){
00471   return *this;
00472 }
00473 void operator+(DomCell &Dc){
00474 }
00475 DomPart::DomPart(int ExtNPart){
00476   NPart = ExtNPart;
00477   Next = new int[NPart];
00478   Prev = new int[NPart];
00479 }
00480 int DomPart::operator[](int col){
00481   return Next[col];
00482 } 
00483 //-------------------------------DdArray------------------------
00487 void DdArray::Erase(){
00488   for(int c=0;c<NCell;c++){
00489     Cella[c].Part.clear();
00490   }
00491 }
00492 void DdArray::AddPart(int p,double *Pos){
00493   int c = pCella(Pos);
00494   Cella[c].Part.push_back(p);
00495   NPart++;
00496 }
00497 void DdArray::RemPart(int p,double *Pos){
00498   int c = pCella(Pos);
00499   Cella[c].Part.remove(p);
00500   NPart--;
00501 }
00502 void DdArray::MovePart(int p,double *OldPos,double *NewPos){
00503   int c1 = pCella(OldPos);
00504   int c2 = pCella(NewPos);
00505   if(c1 == c2) return;
00506   Cella[c1].Part.remove(p);
00507   Cella[c2].Part.push_back(p);
00508 }
00509 void DdArray::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00510   int c1 = pCella(Pos1);
00511   int c2 = pCella(Pos2);
00512   if(c1 == c2) return;
00513   Cella[c1].Part.remove(p1);
00514   Cella[c1].Part.push_back(p2);
00515   Cella[c2].Part.remove(p2);
00516   Cella[c2].Part.push_back(p2);
00517 }
00518 void DdArray::SetCounters(int c){
00519   //if(Cella[c].Part.size() == 0) return;
00520   NCurr = Cella[c].Part.begin();
00521   NCurr2 = Cella[c].Part.begin();
00522   if(Cella[c].Part.size() > 1)
00523     ++NCurr2;
00524 };
00525 int DdArray::IfItCell(int c){
00526   if(NCurr == Cella[c].Part.end()) return 0;
00527   return 1;
00528 };
00529 void DdArray::IncrCurr(int c){
00530   ++NCurr;
00531 }
00532 int DdArray::ItCell(int c){
00533   return *NCurr;
00534 }
00535 void DdArray::Couple(const int c,int *p1,int *p2){
00536   *p1 = *NCurr;
00537   *p2 = *NCurr2;
00538 }
00539 int DdArray::IfItCouple(const int c){
00540   if(NCurr == Cella[c].Part.end())
00541     return 0;
00542   return 1;
00543 }
00544 void DdArray::IncrCurrList(const int c){
00545   ++NCurr2;
00546   if(NCurr2 == Cella[c].Part.end()){
00547     NCurr2 = NCurr;
00548     ++NCurr2;
00549     ++NCurr;
00550   }
00551 }
00552 void DdArray::PrintCell(const int c){
00553   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00554     int p = ItCell(c);
00555     printf("%d) # %d %d\n",c,Cella[c].Part.size(),ItCell(c));
00556   }
00557 }
00558 void DdArray::PrintCells(){
00559   for(int c=0;c<NCell;c++)
00560     PrintCell(c);
00561 }
00562 
00563 
00564 //--------------------------------DdFixedSize----------------------------
00568 void DdFixedSize::Erase(){
00569   for(int c=0;c<NCell;c++){
00570     for(int p=0;p<Cella[c].NPart;p++){
00571       Cella[c].Part[p] = -1;
00572     }
00573     Cella[c].NPart = 0;
00574   }
00575 }
00576 void DdFixedSize::AddPart(int p,double *Pos){
00577   int c = pCella(Pos);
00578   AddPart(p,c);
00579 }
00580 void DdFixedSize::AddPart(int p,int c){
00581   //printf("Adding %d in %d\n",p,c);
00582   if(Cella[c].NPart > NPCell){
00583     printf("Maximum allocated size in the domain decomposition (%d) reached, terminating\n",NPCell);
00584     assert(Cella[c].NPart < NPCell);
00585   }
00586   Cella[c].Part[Cella[c].NPart++] = p;
00587   NPart++;
00588 }
00589 void DdFixedSize::RemPart(int p1,double *Pos){
00590   int c = pCella(Pos);
00591   RemPart(p1,c);
00592 }
00593 void DdFixedSize::RemPart(int p1,int c){
00594   //PrintCell(c);
00595   //printf("removing %d from %d\n",p1,c);
00596   int FoundPartInCell = 0;
00597   int Temp = 0;
00598   for(int p=0;p<Cella[c].NPart;p++){
00599     if(p1==Cella[c].Part[p]){
00600       for(int pp=p;pp<Cella[c].NPart-1;pp++){
00601    Temp = Cella[c].Part[pp];
00602    Cella[c].Part[pp] = Cella[c].Part[pp+1];
00603    Cella[c].Part[pp+1] = Temp;
00604       }
00605       Cella[c].NPart--;
00606       NPart--;
00607       FoundPartInCell = 1;
00608       break;
00609     }
00610   }
00611   //PrintCell(c);
00612   assert(FoundPartInCell);
00613 }
00614 void DdFixedSize::MovePart(int p,double *OldPos,double *NewPos){
00615   int c1 = pCella(OldPos);
00616   int c2 = pCella(NewPos);
00617   if(c1 == c2) return;
00618   RemPart(p,c1);
00619   AddPart(p,c2);
00620 }
00621 void DdFixedSize::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00622   int c1 = pCella(Pos1);
00623   int c2 = pCella(Pos2);
00624   if(c1 == c2) return;
00625   RemPart(p1,c1);
00626   RemPart(p2,c2);
00627   AddPart(p1,c2);
00628   AddPart(p2,c1);
00629 }
00630 void DdFixedSize::SetCounters(int c){
00631   //if(Cella[c].Part.size() == 0) return;
00632   NCurr = 0;
00633   NCurr2 = 0;
00634   if(Cella[c].NPart > 0) NCurr2++;
00635 };
00636 int DdFixedSize::IfItCell(int c){
00637   if(NCurr == Cella[c].NPart) return 0;
00638   return 1;
00639 };
00640 void DdFixedSize::IncrCurr(int c){
00641   NCurr++;
00642 }
00643 int DdFixedSize::ItCell(int c){
00644   return Cella[c].Part[NCurr];
00645 }
00646 void DdFixedSize::Couple(const int c,int *p1,int *p2){
00647   //  printf("%d %d %d\n",NCurr,NCurr2,Cella[c].NPart);
00648   *p1 = Cella[c].Part[NCurr];
00649   *p2 = Cella[c].Part[NCurr2];
00650 }
00651 int DdFixedSize::IfItCouple(const int c){
00652   if(NCurr >= Cella[c].NPart)
00653     return 0;
00654   return 1;
00655 }
00656 void DdFixedSize::IncrCurrList(const int c){
00657   NCurr2++;
00658   if(NCurr2 >= Cella[c].NPart){
00659     NCurr2 = NCurr;
00660     NCurr2++;
00661     NCurr++;
00662   }
00663 }
00664 void DdFixedSize::PrintCell(const int c){
00665   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00666     int p = ItCell(c);
00667     printf("%d) # %d %d\n",c,Cella[c].NPart,ItCell(c));
00668   }
00669 }
00670 void DdFixedSize::PrintCells(){
00671   for(int c=0;c<NCell;c++)
00672     PrintCell(c);
00673 }
00674 //-----------------------------NeiVertex------------------------
00678 NeiVertex::NeiVertex(int NGridExt){
00679   NGrid = 2*NGridExt-1;
00680   int NVertex = NGrid*NGrid*NGrid;
00681   Vertex = new VERTEX[NVertex];
00682   vPos   = new PPOS[NVertex];
00683 }
00684 NeiVertex::~NeiVertex(){
00685   delete [] Vertex;
00686   delete [] vPos;
00687 }
00688 int NeiVertex::GetVertex(double *Pos){
00689   int s[3];
00690   for(int d=0;d<3;d++){
00691     s[d] = (int)(Pos[d]*NGrid);
00692   }
00693   return (s[0]*NGrid+s[1])*NGrid+s[2];
00694 }
00695 void NeiVertex::Add(double *Pos,int t){
00696   int v = GetVertex(Pos);
00697   Vertex[v].v.push_back(t);
00698   for(int d=0;d<3;d++)
00699     vPos[v].Pos[d] = Pos[d];  
00700 }
00701 void NeiVertex::Add(int v,int t,double *Pos){
00702   Vertex[v].v.push_back(t);
00703   for(int d=0;d<3;d++)
00704     vPos[v].Pos[d] = Pos[d];
00705 }
00706 void NeiVertex::Rem(int v,int t){
00707   Vertex[v].v.remove(t);
00708 }
00709 void NeiVertex::SetCounters(int v){
00710   tCurr = Vertex[v].v.begin();
00711 }
00712 int NeiVertex::IfItCell(int v){
00713   if(tCurr == Vertex[v].v.end()) return 0;
00714   return 1;
00715 };
00716 void NeiVertex::IncrCurr(int v){
00717   ++tCurr;
00718 }
00719 int NeiVertex::VertCurr(int v){
00720   return *tCurr;
00721 }
00722 void NeiVertex::PosVertex(int v,double *Pos){
00723   for(int d=0;d<3;d++)
00724     Pos[d] = vPos[v].Pos[d];
00725 }
00726 
00727 
00728 //-----------------------------