Allink  v0.1
Cubo.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-----------------------------
00017 DomDecBasics::DomDecBasics(){
00018   //  signal(SIGSTOP,StopProg);
00019 }
00020 // void DomDecBasics::StopProg(int sig){
00021 //   printf("Program stopped\n");
00022 // }
00024 void DomDecBasics::SigErr(int IsWrong,const char * s, ...){
00025 #ifdef DEBUG
00026   if(IsWrong){
00027     va_list args;
00028     va_start(args, s);
00029     fprintf(stderr, "Dom Dec error: ");
00030     vfprintf(stderr, s, args);
00031     fprintf(stderr, "exiting the program\n");
00032     va_end(args);
00033     abort();
00034   }
00035 #else  
00036   return;
00037 #endif
00038 }
00040 int DomDecBasics::SetCutOff(double CutOffExt){
00041   for(int d=0;d<3;d++){
00042     if(CutOffExt > Edge[d]/(double)NSect[d]){
00043       printf("CutOff larger than the cell size\n");
00044       return 1;
00045     }
00046   }
00047   CutOff = CutOffExt;
00048   return 0;
00049 }
00051 int DomDecBasics::pNPart(){
00052   return NPart;
00053 }
00055 int DomDecBasics::pNCell(){
00056   return NCell;
00057 }
00059 int DomDecBasics::GetCell(double *Pos,int *NeiList){
00060   int c = pCella(Pos);
00061   return GetCellCh(c,NeiList);
00062 }
00064 int DomDecBasics::GetCellCh(int c,int *NeiList){
00065   SigErr(c < 0 || c > NCell,"cell value %d over the ranges\n",c);
00066   if(NCell == 1){
00067     return 1;
00068   }
00069   int NeiMod[3];
00070   int NeiCell[3];
00071   int NNei = 0;
00072   NeiMod[2] = (int)(c/(double)Mod10[2]);
00073   NeiMod[1] = (int)((c-NeiMod[2]*Mod10[2])/(double)Mod10[1]);
00074   NeiMod[0] = (int)(c-NeiMod[1]*Mod10[1]-NeiMod[2]*Mod10[2]);
00075   for(int n=0;n<27;n++) for(int d=0;d<3;d++) BoundCond[n][d] = 0.;
00076   for(int cx=-1;cx<=1;cx++){
00077     NeiCell[0] = NeiMod[0] + cx;
00078     if(NeiCell[0] >= NSect[0]){ 
00079       NeiCell[0] -= NSect[0];
00080       BoundCond[NNei][0] = -1.;
00081     }
00082     if(NeiCell[0] < 0){
00083       NeiCell[0] += NSect[0];
00084       BoundCond[NNei][0] = 1.;
00085     }
00086     for(int cy=-1;cy<=1;cy++){
00087       NeiCell[1] = NeiMod[1] + cy;
00088       if(NeiCell[1] >= NSect[1]){
00089    NeiCell[1] -= NSect[1];
00090    BoundCond[NNei][1] = -1.;
00091       }
00092       if(NeiCell[1] < 0){
00093    NeiCell[1] += NSect[1];
00094    BoundCond[NNei][1] = 1.;
00095       }
00096      for(int cz=-1;cz<=1;cz++){
00097    NeiCell[2] = NeiMod[2] + cz;
00098    if(NeiCell[2] >= NSect[2]){
00099      NeiCell[2] -= NSect[2];
00100      BoundCond[NNei][2] = -1.;
00101    }
00102    if(NeiCell[2] < 0){
00103      NeiCell[2] += NSect[2];
00104      BoundCond[NNei][2] = 1.;
00105    }
00106    NeiList[NNei] = NeiCell[0]*Mod10[0] + NeiCell[1]*Mod10[1] + NeiCell[2]*Mod10[2];
00107    NNei++;
00108       }
00109     }
00110   }
00111   //printf("\n %d) ",c);for(int i=0;i<NNei;i++) printf("%d ",NeiList[i]);
00112   return NNei;
00113 }
00115 int DomDecBasics::GetCellCoord(double *Pos,int *NeiList){
00116   int c = pCella(Pos);
00117   int Coord = GetCoorNumb(Pos);
00118   return GetCellCoord(c,Coord,NeiList);
00119 }
00121 int DomDecBasics::GetCellCoord(int c,int Coord,int *NeiList){
00122   SigErr(c < 0,"Probably the particle position is not a number cell %d\n",c);
00123   int NNei = 0;
00124   int nNei[3];
00125   int NeiCell[3];
00126   int Mask[3]    = {MASK_X,MASK_Y,MASK_Z};
00127   int GetMask[3] = {GET_MASK_X,GET_MASK_Y,GET_MASK_Z};
00128   int Move[3] = {0,0,0};
00129   NeiCell[2] = (int)(c/(double)Mod10[2]);
00130   NeiCell[1] = (int)((c-NeiCell[2]*Mod10[2])/(double)Mod10[1]);
00131   NeiCell[0] = (int)(c-NeiCell[1]*Mod10[1]-NeiCell[2]*Mod10[2]);
00132   for(int n=0;n<27;n++)for(int d=0;d<3;d++) BoundCond[n][d] = 0.;
00133   for(int d=0;d<3;d++){
00134     int d1 = (d+1)%3;
00135     int d2 = (d+2)%3;
00136     if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_RIGHT ){
00137       Move[d] = DOM_RIGHT;
00138       int nc = NeiCell[d] + 1.;
00139       if(nc >= NSect[d]){
00140    nc = 0;
00141    BoundCond[NNei][d] = -1.;
00142       }
00143       NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
00144     }
00145     else if( DOM_GET_POS(Coord,Mask[d],GetMask[d]) == DOM_LEFT ){
00146       Move[d] = DOM_LEFT;
00147       int nc = NeiCell[d] - 1.;
00148       if(nc < 0){
00149    nc = NSect[d]-1;
00150    BoundCond[NNei][d] = 1.;
00151       }
00152       NeiList[NNei++] = nc*Mod10[d] + NeiCell[d1]*Mod10[d1] + NeiCell[d2]*Mod10[d2];
00153     }
00154   }
00155   if(NNei > 1){
00156     for(int d=0;d<3;d++){
00157       nNei[d] = NeiCell[d];
00158       if(Move[d] == DOM_LEFT){
00159    nNei[d] = NeiCell[d] - 1;
00160    if(nNei[d] < 0) nNei[d] = NSect[d] - 1;
00161       }
00162       if(Move[d] == DOM_RIGHT){
00163    nNei[d] = NeiCell[d] + 1;
00164    if(nNei[d] >= NSect[d]) nNei[d] = 0;
00165       }
00166     }
00167     NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
00168   }
00169   if(NNei == 4){
00170     for(int dd=0;dd<3;dd++){
00171       for(int d=0;d<3;d++){
00172    nNei[d] = NeiCell[d];
00173    if(d == dd) continue;
00174    if(Move[d] == DOM_LEFT){
00175      nNei[d] = NeiCell[d] - 1;
00176      if(nNei[d] < 0) nNei[d] = NSect[d] - 1;
00177    }
00178    if(Move[d] == DOM_RIGHT){
00179      nNei[d] = NeiCell[d] + 1;
00180      if(nNei[d] >= NSect[d]) nNei[d] = 0;
00181    }
00182       }
00183       NeiList[NNei++] = nNei[0]*Mod10[0] + nNei[1]*Mod10[1] + nNei[2]*Mod10[2];
00184     }
00185   }
00186   NeiList[NNei++] = c;
00187   // for(int n=0;n<NNei;n++) assert(NeiList[n] < NCell);
00188   // for(int n=0;n<NNei;n++) assert(NeiList[n] >= 0);
00189   return NNei;
00190 }
00192 int DomDecBasics::pCella(const double Pos[3]){
00193   int ris[3];
00194   for(int d=0;d<3;d++){
00195     double PosBox = Pos[d] - floor(Pos[d]*InvEdge[d])*Edge[d];
00196     ris[d] = (int)(PosBox/Edge[d]*NSect[d]);
00197   }
00198   int risp = ris[0]*Mod10[0]+ris[1]*Mod10[1]+ris[2]*Mod10[2];
00199   SigErr(risp >= NCell,"Probably the particle position is not a number\n");
00200   return risp;
00201 }
00203 void DomDecBasics::pCella(const double Pos[3],int c[4]){
00204   for(int d=0;d<3;d++){
00205     double PosBox = Pos[d];// - floor(Pos[d]*InvEdge[d])*Edge[d];
00206     c[d] = (int)(PosBox/Edge[d]*NSect[d]);
00207   }
00208   c[4] = c[0]*Mod10[0]+c[1]*Mod10[1]+c[2]*Mod10[2];
00209   SigErr(c[4] >= NCell,"Probably the particle position is not a number\n");
00210 }
00212 int DomDecBasics::GetCoorNumb(double *Pos){
00213   double CellLen[3];
00214   int Border[3];
00215   double BorderR[3];
00216   int Mask[3] = {MASK_X,MASK_Y,MASK_Z};
00217   int Coord = 0;
00218   for(int d=0;d<3;d++){
00219     Border[d]  = (int)(Pos[d]/Edge[d]*NSect[d]);
00220     CellLen[d] = (Edge[d]/(double)NSect[d]);
00221     if(Pos[d] - Border[d]*CellLen[d] < CutOff){
00222       DOM_SET_POS(Coord,DOM_LEFT,Mask[d]);
00223     }
00224     if(-Pos[d] + (Border[d]+1)*CellLen[d] < CutOff){
00225       DOM_SET_POS(Coord,DOM_RIGHT,Mask[d]);
00226     }
00227   }
00228   return Coord;
00229 }
00230 //-------------------LINKED-LIST-------------------------------
00232 DdLinkedList::DdLinkedList(double EdgeExt[3],int NPartExt,double CutOffExt){
00233   for(int d=0;d<3;d++){
00234     Edge[d] = EdgeExt[d];
00235     InvEdge[d] = 1./Edge[d];
00236     //NSect[d] = (int)(Edge[d]/(2.*CutOffExt));
00237     NSect[d] = (int)(Edge[d]/CutOffExt);
00238     SigErr(CutOffExt > 2.*Edge[d],"Insufficient number of cells \n");
00239   }
00240   NPart = 0;
00241   SetCutOff(CutOffExt);
00242   Mod10[0] = 1;
00243   Mod10[1] = NSect[0];
00244   Mod10[2] = NSect[1]*Mod10[1];
00245   NCell = NSect[0]*NSect[1]*NSect[2];
00246   Cella = new DomCell[NCell];
00247   SigErr(Cella==NULL,"DomCell not allocated\n");
00248   for(int c=0;c<NCell;c++){
00249     Cella[c].NPart = 0;
00250     Cella[c].First = Cella[c].Last = -2;
00251   }
00252   NAllocP = NPartExt + 2000;
00253   Pc = new DOMAIN_PART[NAllocP];
00254   SigErr(Pc == NULL,"DOMAIN_PART not allocated\n");
00255   printf("%d\n",NCell);
00256 }
00258 void DdLinkedList::Erase(){
00259   for(int c=0;c<NCell;c++){
00260     Cella[c].NPart = 0;
00261     Cella[c].Last = -1;
00262   }
00263   for(int p=0;p<NPart;p++){
00264     Pc[p].Cell = -1;
00265     Pc[p].Next = -1;
00266     Pc[p].Prev = -2;
00267   }
00268   NPart = 0;
00269 }
00271 int DdLinkedList::SetCoorNumb(double *Pos,int p){
00272   Pc[p].Coord = GetCoorNumb(Pos);
00273   return Pc[p].Coord;
00274 }
00276 void DdLinkedList::AddPart(const int p,double *Pos){
00277   // for(int d=0;d<3;d++){
00278   //   SigErr(Pos[d] < 0. || Pos[d] > Edge[d],"particle %d over the boudaries 0< %lf < %lf\n",p,Pos[d],Edge[d]);}
00279   int c = pCella(Pos);
00280   SetCoorNumb(Pos,p);
00281   for(int d=0;d<3;d++) Pc[p].Pos[d] = Pos[d];
00282   AddPart(p,c);
00283 }
00285 void DdLinkedList::AddPart(const int p,const int c){
00286   //PrintCell(c);
00287   int pl = Cella[c].Last;
00288   SigErr(pl == p,"The particle %d is already the last in the cell %d\n",p,c);
00289   SigErr(p >= NAllocP,"More particle than allocated %d > %d\n",p,NAllocP);
00290   SigErr(Cella[c].NPart >= NAllocP,"More particle than allocated\n");
00291   Cella[c].NPart++;
00292   NPart++;
00293   Cella[c].Last = p;
00294   Pc[p].Cell = c;
00295   Pc[p].Next = -1;
00296   if(Cella[c].NPart == 1){
00297     Cella[c].First = p;
00298     Pc[p].Prev = -2;
00299   }
00300   else{
00301     if(pl >= 0) Pc[pl].Next = p;
00302     Pc[p].Prev = pl;
00303   }
00304   //printf("%d - %d - %d c) %d last %d coord %x cell %d (%lf %lf %lf)\n",Pc[p].Prev,p,Pc[p].Next,c,Cella[c].Last,Pc[p].Coord,Pc[p].Cell,Pc[p].Pos[0],Pc[p].Pos[1],Pc[p].Pos[2]);
00305 }
00307 void DdLinkedList::RemPart(const int p,double *Pos){
00308   int c = pCella(Pos);
00309   RemPart(p,c);
00310 }
00312 void DdLinkedList::RemPart(const int p,const int c){
00313   SigErr(p >= NAllocP,"More particles than allocated\n");
00314   //assert(Cella[c].NPart > 0);
00315   SigErr(Cella[c].NPart <= 0,"Cannot remove, the cell is already empty\n");
00316   SigErr(c < 0,"The cell %d does not exist\n",c);
00317   Cella[c].NPart--;
00318   NPart--;
00319   if(Cella[c].NPart == 0){
00320     Cella[c].First = -2;
00321     Cella[c].Last  = -1;
00322   }
00323   else{
00324     int pp = Pc[p].Prev;
00325     int pn = Pc[p].Next;
00326     if(pp == -2) Cella[c].First = pn;
00327     else Pc[pp].Next = pn;
00328     if(pn == -1) Cella[c].Last = pp;
00329     else Pc[pn].Prev = pp;
00330     Pc[p].Cell = -1;
00331   }
00332   //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);
00333   //  assert(pp != -2 && Pc[pp].Next != pp);
00334 }
00336 void DdLinkedList::RemPart(const int p){
00337   int c = Pc[p].Cell;
00338   SigErr(c < 0,"The cell %d or the particle %d does not exist\n",c,p);
00339   RemPart(p,c);
00340 }
00342 int DdLinkedList::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00343   if(p1==p2) return 0;
00344   DOMAIN_PART Pn;
00345   int c1 = Pc[p1].Cell;
00346   int c2 = Pc[p2].Cell;
00347   for(int d=0;d<3;d++){
00348     Pc[p1].Pos[d] = Pos2[d];
00349     Pc[p2].Pos[d] = Pos1[d];
00350   }
00351   if(c1!=c2){
00352     if(Cella[c2].First == p2)
00353       Cella[c2].First  = p1;
00354     if(Cella[c2].Last == p2)
00355       Cella[c2].Last  = p1;
00356     if(Cella[c1].First == p1)
00357       Cella[c1].First  = p2;
00358     if(Cella[c1].Last == p1)
00359       Cella[c1].Last  = p2;
00360   }
00361   if(c1==c2){
00362     if(Cella[c1].First == p2)
00363       Cella[c1].First = p1;
00364     else if(Cella[c1].First == p1)
00365       Cella[c1].First = p2;
00366     if(Cella[c1].Last == p2)
00367       Cella[c1].Last = p1;
00368     else if(Cella[c1].Last == p1)
00369       Cella[c1].Last = p2;
00370   }
00371   int p1p = Pc[p1].Prev;
00372   int p2p = Pc[p2].Prev;
00373   int p1n = Pc[p1].Next;
00374   int p2n = Pc[p2].Next;
00375   if(p1p >= 0) Pc[p1p].Next = p2;
00376   if(p1n >= 0) Pc[p1n].Prev = p2;
00377   if(p2p >= 0) Pc[p2p].Next = p1;
00378   if(p2n >= 0) Pc[p2n].Prev = p1;
00379   Pn.Prev  = Pc[p1].Prev;
00380   Pn.Next  = Pc[p1].Next;
00381   Pn.Coord = Pc[p1].Coord;
00382   Pn.Cell  = Pc[p1].Cell;
00383   Pc[p1].Prev  = Pc[p2].Prev;
00384   Pc[p1].Next  = Pc[p2].Next;
00385   Pc[p1].Coord = Pc[p2].Coord;
00386   Pc[p1].Cell  = Pc[p2].Cell;
00387   Pc[p2].Prev  = Pn.Prev;
00388   Pc[p2].Next  = Pn.Next;
00389   Pc[p2].Coord = Pn.Coord;
00390   Pc[p2].Cell  = Pn.Cell;
00391 }
00393 void DdLinkedList::MovePart(const int p,double *NewPos){
00394   int cn = pCella(NewPos);
00395   int co = pCell(p);
00396   SetCoorNumb(NewPos,p);
00397   for(int d=0;d<3;d++)Pc[p].Pos[d] = NewPos[d];
00398   if(cn == co) return;
00399   RemPart(p,co);
00400   AddPart(p,cn);
00401 }
00403 void DdLinkedList::MovePart(const int p,double *OldPos,double *NewPos){
00404   int cn = pCella(NewPos);
00405   int co = pCella(OldPos);
00406   SetCoorNumb(NewPos,p);
00407   for(int d=0;d<3;d++)Pc[p].Pos[d] = NewPos[d];
00408   if(cn == co) return ;
00409   RemPart(p,co);
00410   AddPart(p,cn);
00411 }
00413 void DdLinkedList::SetCounters(int c1){
00414   for(int c=0;c<NCell;c++){
00415     Cella[c].Curr1 = Cella[c].First;
00416     Cella[c].Curr2 = Cella[c].First;
00417     if(Cella[c].NPart > 1)
00418       Cella[c].Curr2 = Pc[Cella[c].Curr1].Next;
00419   }
00420 }
00421 int DdLinkedList::ItCell(const int c){
00422   SigErr(c >= NCell,"The cell %d does not exist\n",c);
00423   SigErr(Cella[c].Curr1 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,NAllocP);
00424   return Cella[c].Curr1;
00425 }
00427 int DdLinkedList::IfItCell(const int c){
00428   if(Cella[c].Curr1 < 0 || Cella[c].NPart == 0){
00429     Cella[c].Curr1 = Cella[c].First;
00430     return 0;
00431   }
00432   return 1;
00433 }
00435 void DdLinkedList::IncrCurr(const int c){
00436   Cella[c].Curr1 = Pc[Cella[c].Curr1].Next;
00437 }
00439 void DdLinkedList::PrintCell(const int c){
00440   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00441     int p = ItCell(c);
00442     printf("%d) # %d %d_%d_%d %x\n",c,Cella[c].NPart,Pc[p].Prev,ItCell(c),Pc[p].Next,Pc[p].Coord);
00443   }
00444 }
00446 void DdLinkedList::PrintCells(){
00447   for(int c=0;c<NCell;c++)
00448     PrintCell(c);
00449 }
00453 void DdLinkedList::SetCurr(int p){
00454   cCurr = Pc[p].Cell;
00455   SigErr(cCurr < 0,"The cell %d or the particle %d does not exists\n",cCurr,p);
00456   NNeiCurr = GetNei(Pc[p].Pos,NeiListCurr);
00457   nNeiCurr = 0;
00458   IfLoopCurr = 1;
00459   cCurr = NeiListCurr[nNeiCurr];
00460   p1Curr = p;
00461   p2Curr = Cella[cCurr].First;
00462   if(p2Curr == p1Curr) Pc[p2Curr].Next;
00463   while(p2Curr < 0){
00464     nNeiCurr++;
00465     //printf(" %d)  %d/%d %d %d\n",p,nNeiCurr,NNeiCurr,cCurr,p2Curr);
00466     if(nNeiCurr==NNeiCurr){
00467       IfLoopCurr = 0;
00468       break;
00469     }
00470     cCurr = NeiListCurr[nNeiCurr];
00471     p2Curr = Cella[cCurr].First;
00472   }
00473   //printf("%d) %d %d/%d %d\n",p,p2Curr,nNeiCurr,NNeiCurr,cCurr);
00474   //for(int n=0;n<27;n++)printf("  %d] %0.f %0.f %0.f\n",n,BoundCond[n][0],BoundCond[n][1],BoundCond[n][2]);
00475   //PrintCell(cCurr);
00476   Cella[cCurr].Curr1 = p1Curr;
00477   Cella[cCurr].Curr2 = p2Curr;
00478 }
00479 void DdLinkedList::NextCurr(){
00480   p2Curr = Pc[p2Curr].Next;
00481   if(p2Curr == p1Curr) Pc[p2Curr].Next;
00482   while(p2Curr < 0){
00483     nNeiCurr++;
00484     if(nNeiCurr==NNeiCurr){
00485       IfLoopCurr = 0;
00486       break;
00487     }
00488     cCurr = NeiListCurr[nNeiCurr];
00489     p2Curr = Cella[cCurr].First;
00490   }
00491   //printf("   %d) %d %d\n",p1Curr,p2Curr,nNeiCurr);
00492   Cella[cCurr].Curr1 = p1Curr;
00493   Cella[cCurr].Curr2 = p2Curr;
00494 }
00498 int DdLinkedList::IfCurr(){
00499   return IfLoopCurr;
00500 }
00502 void DdLinkedList::Dist2Curr(double *DistRel){
00503   for(int d=0;d<3;d++){
00504     DistRel[d] = Pc[p1Curr].Pos[d] - Pc[p2Curr].Pos[d];
00505     //TOFIX
00506     //printf("%d-%d) %.0f %.0f  %d %d-%d\n",p1Curr,p2Curr,BoundCond[nNeiCurr][d]*Edge[d],-floor(DistRel[d]*InvEdge[d] + .5)*Edge[d],nNeiCurr,Pc[p1Curr].Cell,Pc[p2Curr].Cell);
00507     //DistRel[d] += BoundCond[nNeiCurr][d]*Edge[d];
00508     DistRel[d] -= floor(DistRel[d]*InvEdge[d] + .5)*Edge[d];
00509   }
00510   DistRel[3] = SQR(DistRel[0]) + SQR(DistRel[1]) + SQR(DistRel[2]);
00511 }
00512 void DdLinkedList::SetCurrGhost(double *Pos){
00513   cCurr = pCella(Pos);
00514   SigErr(cCurr < 0,"The cell %d does not exists\n",cCurr);
00515   NNeiCurr = GetNei(Pos,NeiListCurr);
00516   nNeiCurr = 0;
00517   IfLoopCurr = 1;
00518   cCurr = NeiListCurr[nNeiCurr];
00519   for(int d=0;d<3;d++) PosCurr[d] = Pos[d];
00520   p2Curr = Cella[cCurr].First;
00521   while(p2Curr < 0){
00522     nNeiCurr++;
00523     //printf(" %d)  %d/%d %d %d\n",p,nNeiCurr,NNeiCurr,cCurr,p2Curr);
00524     if(nNeiCurr==NNeiCurr){
00525       IfLoopCurr = 0;
00526       break;
00527     }
00528     cCurr = NeiListCurr[nNeiCurr];
00529     p2Curr = Cella[cCurr].First;
00530   }
00531   //printf("%d) %d %d/%d %d\n",p,p2Curr,nNeiCurr,NNeiCurr,cCurr);
00532   //for(int n=0;n<27;n++)printf("  %d] %0.f %0.f %0.f\n",n,BoundCond[n][0],BoundCond[n][1],BoundCond[n][2]);
00533   //PrintCell(cCurr);
00534   Cella[cCurr].Curr2 = p2Curr;
00535 }
00536 void DdLinkedList::NextCurrGhost(){
00537   p2Curr = Pc[p2Curr].Next;
00538   while(p2Curr < 0){
00539     nNeiCurr++;
00540     if(nNeiCurr==NNeiCurr){
00541       IfLoopCurr = 0;
00542       break;
00543     }
00544     cCurr = NeiListCurr[nNeiCurr];
00545     p2Curr = Cella[cCurr].First;
00546   }
00547   //printf("   %d) %d %d\n",p1Curr,p2Curr,nNeiCurr);
00548   Cella[cCurr].Curr2 = p2Curr;
00549 }
00550 int DdLinkedList::IfCurrGhost(){
00551   return IfLoopCurr;
00552 }
00554 void DdLinkedList::Dist2CurrGhost(double *DistRel){
00555   for(int d=0;d<3;d++){
00556     DistRel[d] = PosCurr[d] - Pc[p2Curr].Pos[d];
00557     //TOFIX
00558     //printf("%d-%d) %.0f %.0f  %d %d-%d\n",p1Curr,p2Curr,BoundCond[nNeiCurr][d]*Edge[d],-floor(DistRel[d]*InvEdge[d] + .5)*Edge[d],nNeiCurr,Pc[p1Curr].Cell,Pc[p2Curr].Cell);
00559     //DistRel[d] += BoundCond[nNeiCurr][d]*Edge[d];
00560     DistRel[d] -= floor(DistRel[d]*InvEdge[d] + .5)*Edge[d];
00561   }
00562   DistRel[3] = SQR(DistRel[0]) + SQR(DistRel[1]) + SQR(DistRel[2]);
00563 }
00565 void DdLinkedList::Couple(const int c,int *p1,int *p2){
00566   SigErr(Cella[c].Curr1 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr1,NAllocP);
00567   SigErr(Cella[c].Curr2 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,NAllocP);
00568   *p1 = Cella[c].Curr1;
00569   *p2 = Cella[c].Curr2;
00570 }
00572 int DdLinkedList::IfItCouple(const int c){
00573   if(Cella[c].NPart < 2) return 0;
00574   if(Cella[c].Curr1 == -1){
00575     Cella[c].Curr1 = Cella[c].First;
00576     Cella[c].Curr2 = Pc[Cella[c].First].Next;
00577     return 0;
00578   }
00579   return 1;
00580 }
00582 void DdLinkedList::IncrCurrList(const int c){
00583   int p2 = Cella[c].Curr2;
00584   Cella[c].Curr2 = Pc[p2].Next;
00585   if(Pc[p2].Next == -1){
00586     int p1 = Cella[c].Curr1;
00587     Cella[c].Curr1 = Pc[p1].Next;
00588     Cella[c].Curr2 = Pc[Pc[p1].Next].Next;
00589     if(Cella[c].Curr2 == -1){
00590       Cella[c].Curr1 = -1;
00591     }
00592   }
00593   SigErr(Cella[c].Curr2 >= NAllocP,"Poiting to a particle %d over the number of allocated particles\n",Cella[c].Curr2,NAllocP);
00594 }
00595 int DdLinkedList::FindClosest(int p1){
00596   double DistRel[4];
00597   int pCloser = -1;
00598   double DistCurr = 1000000.;
00599   for(SetCurr(p1);IfCurr();NextCurr()){
00600     if(p2Curr <= p1Curr) continue;
00601     Dist2Curr(DistRel);
00602     if(DistRel[3] < DistCurr){
00603       DistCurr = DistRel[3];
00604       pCloser = p2Curr;
00605     }
00606   }
00607   return pCloser;
00608 }
00609 //--------------------DomPart-----DomCell---------------------
00611 DomCell& DomCell::operator++(){
00612   //It++;
00613   return *this;
00614 }
00616 DomPart& DomPart::operator++(){
00617 }
00619 DomCell& DomCell::operator=(const DomCell &Dc){
00620   return *this;
00621 }
00622 DomPart::DomPart(int ExtNPart){
00623   NPart = ExtNPart;
00624   Next = new int[NPart];
00625   Prev = new int[NPart];
00626 }
00627 int DomPart::operator[](int col){
00628   return Next[col];
00629 } 
00630 //-------------------------------DdArray------------------------
00634 DdArray::DdArray(double EdgeExt[3],int NPartExt,double CutOffExt){
00635   for(int d=0;d<3;d++){
00636     Edge[d] = EdgeExt[d];
00637     InvEdge[d] = 1./Edge[d];
00638     NSect[d] = (int)(Edge[d]/(double)(CutOffExt));
00639   }
00640   NPart = 0;
00641   CutOff = CutOffExt;
00642   Mod10[0] = 1;
00643   Mod10[1] = NSect[0];
00644   Mod10[2] = NSect[1]*Mod10[1];
00645   NCell = NSect[0]*NSect[1]*NSect[2];
00646   Cella = new DdCell[NCell];
00647   if(Cella == NULL) {printf("DomCell not allocated\n");}
00648 }
00649 void DdArray::Erase(){
00650   for(int c=0;c<NCell;c++){
00651     Cella[c].Part.clear();
00652   }
00653 }
00654 void DdArray::AddPart(int p,double *Pos){
00655   int c = pCella(Pos);
00656   Cella[c].Part.push_back(p);
00657   NPart++;
00658 }
00659 void DdArray::RemPart(int p,double *Pos){
00660   int c = pCella(Pos);
00661   Cella[c].Part.remove(p);
00662   NPart--;
00663 }
00664 void DdArray::MovePart(int p,double *OldPos,double *NewPos){
00665   int c1 = pCella(OldPos);
00666   int c2 = pCella(NewPos);
00667   if(c1 == c2) return;
00668   Cella[c1].Part.remove(p);
00669   Cella[c2].Part.push_back(p);
00670 }
00671 void DdArray::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00672   int c1 = pCella(Pos1);
00673   int c2 = pCella(Pos2);
00674   if(c1 == c2) return;
00675   Cella[c1].Part.remove(p1);
00676   Cella[c1].Part.push_back(p2);
00677   Cella[c2].Part.remove(p2);
00678   Cella[c2].Part.push_back(p2);
00679 }
00680 void DdArray::SetCounters(int c){
00681   //if(Cella[c].Part.size() == 0) return;
00682   NCurr = Cella[c].Part.begin();
00683   NCurr2 = Cella[c].Part.begin();
00684   if(Cella[c].Part.size() > 1)
00685     ++NCurr2;
00686 };
00687 int DdArray::IfItCell(int c){
00688   if(NCurr == Cella[c].Part.end()) return 0;
00689   return 1;
00690 };
00691 void DdArray::IncrCurr(int c){
00692   ++NCurr;
00693 }
00694 int DdArray::ItCell(int c){
00695   return *NCurr;
00696 }
00697 void DdArray::Couple(const int c,int *p1,int *p2){
00698   *p1 = *NCurr;
00699   *p2 = *NCurr2;
00700 }
00701 int DdArray::IfItCouple(const int c){
00702   if(NCurr == Cella[c].Part.end())
00703     return 0;
00704   return 1;
00705 }
00706 void DdArray::IncrCurrList(const int c){
00707   ++NCurr2;
00708   if(NCurr2 == Cella[c].Part.end()){
00709     NCurr2 = NCurr;
00710     ++NCurr2;
00711     ++NCurr;
00712   }
00713 }
00714 void DdArray::PrintCell(const int c){
00715   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00716     int p = ItCell(c);
00717     printf("%d) # %d %d\n",c,Cella[c].Part.size(),ItCell(c));
00718   }
00719 }
00720 void DdArray::PrintCells(){
00721   for(int c=0;c<NCell;c++)
00722     PrintCell(c);
00723 }
00724 //--------------------------------DdFixedSize----------------------------
00728 DdFixedSize::DdFixedSize(double EdgeExt[3],int NPartExt,double CutOffExt){
00729   for(int d=0;d<3;d++){
00730     Edge[d] = EdgeExt[d];
00731     InvEdge[d] = 1./Edge[d];
00732     NSect[d] = (int)(Edge[d]/(double)(CutOffExt));
00733   }
00734   NPart = 0;
00735   NPCell = 30;
00736   CutOff = CutOffExt;
00737   Mod10[0] = 1;
00738   Mod10[1] = NSect[0];
00739   Mod10[2] = NSect[1]*Mod10[1];
00740   NCell = NSect[0]*NSect[1]*NSect[2];
00741   Cella = new DdFixCell[NCell];
00742   for(int c=0;c<NCell;c++){
00743     Cella[c].Part = new int[NPCell];
00744   }
00745   if(Cella == NULL) {printf("DomCell not allocated\n");}
00746 }
00747 void DdFixedSize::Erase(){
00748   for(int c=0;c<NCell;c++){
00749     for(int p=0;p<Cella[c].NPart;p++){
00750       Cella[c].Part[p] = -1;
00751     }
00752     Cella[c].NPart = 0;
00753   }
00754 }
00755 void DdFixedSize::AddPart(int p,double *Pos){
00756   int c = pCella(Pos);
00757   AddPart(p,c);
00758 }
00759 void DdFixedSize::AddPart(int p,int c){
00760   //printf("Adding %d in %d\n",p,c);
00761   if(Cella[c].NPart > NPCell){
00762     printf("Maximum allocated size in the domain decomposition (%d) reached, terminating\n",NPCell);
00763     assert(Cella[c].NPart < NPCell);
00764   }
00765   Cella[c].Part[Cella[c].NPart++] = p;
00766   NPart++;
00767 }
00768 void DdFixedSize::RemPart(int p1,double *Pos){
00769   int c = pCella(Pos);
00770   RemPart(p1,c);
00771 }
00772 void DdFixedSize::RemPart(int p1,int c){
00773   //PrintCell(c);
00774   //printf("removing %d from %d\n",p1,c);
00775   int FoundPartInCell = 0;
00776   int Temp = 0;
00777   for(int p=0;p<Cella[c].NPart;p++){
00778     if(p1==Cella[c].Part[p]){
00779       for(int pp=p;pp<Cella[c].NPart-1;pp++){
00780    Temp = Cella[c].Part[pp];
00781    Cella[c].Part[pp] = Cella[c].Part[pp+1];
00782    Cella[c].Part[pp+1] = Temp;
00783       }
00784       Cella[c].NPart--;
00785       NPart--;
00786       FoundPartInCell = 1;
00787       break;
00788     }
00789   }
00790   //PrintCell(c);
00791   assert(FoundPartInCell);
00792 }
00793 void DdFixedSize::MovePart(int p,double *OldPos,double *NewPos){
00794   int c1 = pCella(OldPos);
00795   int c2 = pCella(NewPos);
00796   if(c1 == c2) return;
00797   RemPart(p,c1);
00798   AddPart(p,c2);
00799 }
00800 void DdFixedSize::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00801   int c1 = pCella(Pos1);
00802   int c2 = pCella(Pos2);
00803   if(c1 == c2) return;
00804   RemPart(p1,c1);
00805   RemPart(p2,c2);
00806   AddPart(p1,c2);
00807   AddPart(p2,c1);
00808 }
00809 void DdFixedSize::SetCounters(int c){
00810   //if(Cella[c].Part.size() == 0) return;
00811   NCurr = 0;
00812   NCurr2 = 0;
00813   if(Cella[c].NPart > 0) NCurr2++;
00814 };
00815 int DdFixedSize::IfItCell(int c){
00816   if(NCurr == Cella[c].NPart) return 0;
00817   return 1;
00818 };
00819 void DdFixedSize::IncrCurr(int c){
00820   NCurr++;
00821 }
00822 int DdFixedSize::ItCell(int c){
00823   return Cella[c].Part[NCurr];
00824 }
00825 void DdFixedSize::Couple(const int c,int *p1,int *p2){
00826   //  printf("%d %d %d\n",NCurr,NCurr2,Cella[c].NPart);
00827   *p1 = Cella[c].Part[NCurr];
00828   *p2 = Cella[c].Part[NCurr2];
00829 }
00830 int DdFixedSize::IfItCouple(const int c){
00831   if(NCurr >= Cella[c].NPart)
00832     return 0;
00833   return 1;
00834 }
00835 void DdFixedSize::IncrCurrList(const int c){
00836   NCurr2++;
00837   if(NCurr2 >= Cella[c].NPart){
00838     NCurr2 = NCurr;
00839     NCurr2++;
00840     NCurr++;
00841   }
00842 }
00843 void DdFixedSize::PrintCell(const int c){
00844   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00845     int p = ItCell(c);
00846     printf("%d) # %d %d\n",c,Cella[c].NPart,ItCell(c));
00847   }
00848 }
00849 void DdFixedSize::PrintCells(){
00850   for(int c=0;c<NCell;c++)
00851     PrintCell(c);
00852 }
00853 //-------------------DOUBLE-LOOP-------------------------------
00855 DdDoubleLoop::DdDoubleLoop(double EdgeExt[3],int NPartExt,double CutOffExt){
00856   for(int d=0;d<3;d++){
00857     Edge[d] = EdgeExt[d];
00858     InvEdge[d] = 1./Edge[d];
00859     NSect[d] = 1;
00860   }
00861   NPart = 0;
00862   SetCutOff(CutOffExt);
00863   Mod10[0] = 1;
00864   Mod10[1] = 1;
00865   Mod10[2] = 1;
00866   NCell = 0;
00867   Cella = new DomCell[NCell];
00868   SigErr(Cella==NULL,"DomCell not allocated\n");
00869   for(int c=0;c<NCell;c++){
00870     Cella[c].NPart = 0;
00871     Cella[c].First = Cella[c].Last = -2;
00872   }
00873   NAllocP = NPartExt + 2000;
00874   Pc = new DOMAIN_PART[NAllocP];
00875   SigErr(Pc == NULL,"DOMAIN_PART not allocated\n");
00876 }
00878 void DdDoubleLoop::Erase(){
00879   for(int c=0;c<NCell;c++){
00880     Cella[c].NPart = 0;
00881     Cella[c].Last = -1;
00882   }
00883   for(int p=0;p<NPart;p++){
00884     Pc[p].Cell = -1;
00885     Pc[p].Next = -1;
00886     Pc[p].Prev = -2;
00887   }
00888   NPart = 0;
00889 }
00891 int DdDoubleLoop::SetCoorNumb(double *Pos,int p){
00892   Pc[p].Coord = GetCoorNumb(Pos);
00893   return Pc[p].Coord;
00894 }
00896 void DdDoubleLoop::AddPart(const int p,double *Pos){
00897   for(int d=0;d<3;d++) Pc[p].Pos[d] = Pos[d];
00898   AddPart(p,0);
00899 }
00901 void DdDoubleLoop::AddPart(const int p,const int c){
00902   Cella[c].NPart++;
00903   NPart++;
00904   Cella[c].Last = p;
00905   Pc[p].Cell = c;
00906   Pc[p].Next = -1;
00907 }
00909 void DdDoubleLoop::RemPart(const int p,double *Pos){
00910   RemPart(p,0);
00911 }
00913 void DdDoubleLoop::RemPart(const int p,const int c){
00914   Cella[c].NPart--;
00915   NPart--;
00916   if(Cella[c].NPart == 0){
00917     Cella[c].First = -2;
00918     Cella[c].Last  = -1;
00919   }
00920   else{
00921     int pp = Pc[p].Prev;
00922     int pn = Pc[p].Next;
00923     if(pp == -2) Cella[c].First = pn;
00924     else Pc[pp].Next = pn;
00925     if(pn == -1) Cella[c].Last = pp;
00926     else Pc[pn].Prev = pp;
00927     Pc[p].Cell = -1;
00928   }
00929 }
00931 void DdDoubleLoop::RemPart(const int p){
00932   RemPart(p,0);
00933 }
00935 int DdDoubleLoop::SwapPart(int p1,double *Pos1,int p2,double *Pos2){
00936   printf("Swap part disabled\n");
00937 }
00939 void DdDoubleLoop::MovePart(const int p,double *NewPos){
00940   printf("Move part disabled\n");
00941 }
00943 void DdDoubleLoop::MovePart(const int p,double *OldPos,double *NewPos){
00944   printf("Move part disabled\n");
00945 }
00947 void DdDoubleLoop::SetCounters(int c){
00948   p1Curr = 0;
00949   p2Curr = 1;
00950   cCurr = 0;
00951 }
00952 int DdDoubleLoop::ItCell(const int c){
00953   return 0;
00954 }
00956 int DdDoubleLoop::IfItCell(const int c){
00957   if(p1Curr == NPart) return 0;
00958   return 1;
00959 }
00961 void DdDoubleLoop::IncrCurr(const int c){
00962   p2Curr++;
00963   if(p2Curr <= NPart){
00964       p1Curr++;
00965       p2Curr = p1Curr+1;
00966   }
00967 }
00969 void DdDoubleLoop::PrintCell(const int c){
00970   for(SetCounters(c);IfItCell(c);IncrCurr(c)){
00971     int p = ItCell(c);
00972     printf("%d) # %d %d_%d_%d %x\n",c,Cella[c].NPart,Pc[p].Prev,ItCell(c),Pc[p].Next,Pc[p].Coord);
00973   }
00974 }
00976 void DdDoubleLoop::PrintCells(){
00977   for(int c=0;c<NCell;c++)
00978     PrintCell(c);
00979 }
00981 void DdDoubleLoop::SetCurr(int p){
00982   cCurr = 0;
00983   p1Curr = p;
00984   p2Curr = p+1;
00985 }
00986 void DdDoubleLoop::NextCurr(){
00987   p2Curr++;
00988 }
00989 int DdDoubleLoop::IfCurr(){
00990   if(p2Curr == NPart) return 0;
00991   return 1;
00992 }
00994 void DdDoubleLoop::Dist2Curr(double *DistRel){
00995   for(int d=0;d<3;d++){
00996     DistRel[d] = Pc[p1Curr].Pos[d] - Pc[p2Curr].Pos[d];
00997     //TOFIX
00998     //DistRel[d] += BoundCond[nNeiCurr][d]*Edge[d];
00999     DistRel[d] -= floor(DistRel[d]*InvEdge[d] + .5)*Edge[d];
01000   }
01001   DistRel[3] = SQR(DistRel[0]) + SQR(DistRel[1]) + SQR(DistRel[2]);
01002 }
01003 //-----------------------------NeiVertex------------------------
01007 NeiVertex::NeiVertex(int NTriaExt,int NvPtExt,int NGridExt,double *EdgeExt){
01008   NTria = NTriaExt;
01009   NvPt = NvPtExt;
01010   NVert = NTria*NvPt;
01011   NGrid = 2*NGridExt-1;
01012   for(int d=0;d<3;d++){
01013     Edge[d] = EdgeExt[d];
01014   }
01015   Vertex = new VERTEX[NVert];
01016   vMemPos = new int[NVert];
01017   for(int v=0;v<NVert;v++){
01018     Vertex[v].NTria = 0;
01019   }
01020   NVert = 0;
01021 }
01022 NeiVertex::~NeiVertex(){
01023   delete [] Vertex;
01024 }
01025 int NeiVertex::GetVertex(double *Pos){
01026   int s[3] = {0,0,0};
01027   for(int d=0;d<3;d++){
01028     s[d] = (int)(Pos[d]/Edge[d]*NGrid);
01029   }
01030   return (s[0]*NGrid+s[1])*NGrid+s[2];
01031 }
01032 void NeiVertex::Add(double *Pos,int t){
01033   int v = GetVertex(Pos);
01034   Add(v,t,Pos);
01035 }
01036 void NeiVertex::Add(int v,int t,double *Pos){
01037   Vertex[NVert].v = v;
01038   for(int d=0;d<3;d++)
01039     Vertex[NVert].Pos[d] = Pos[d];
01040   Vertex[NVert].t[0] = t;
01041   //printf("Add %d %d %d\n",NVert,Vertex[NVert].v,Vertex[NVert].t[0]);
01042   NVert++;
01043 }
01044 void NeiVertex::CopyVert2To1(VERTEX Vert1,VERTEX Vert2){
01045   Vert1.v = Vert2.v;
01046   Vert1.NTria = Vert2.NTria;
01047   for(int d=0;d<3;d++) Vert1.Pos[d] = Vert2.Pos[d];
01048   for(int t=0;t<Vert1.NTria;t++) Vert1.t[t] = Vert2.t[t];
01049 }
01050 void NeiVertex::Swap(int v1,int v2){
01051   VERTEX Vert = Vertex[v1];
01052   Vertex[v1] = Vertex[v2];
01053   Vertex[v2] = Vert;
01054   CopyVert2To1(Vert,Vertex[v1]);
01055   CopyVert2To1(Vertex[v1],Vertex[v2]);
01056   CopyVert2To1(Vertex[v2],Vert);
01057 }
01058 void NeiVertex::Reorder(){
01059   //sorting
01060   for(int i=0;i<NVert;i++){
01061     for(int j=i;j>0;j--){
01062       if(Vertex[j].v < Vertex[j-1].v){
01063    Swap(j-1,j);
01064       }
01065       else
01066    break;
01067     }
01068   }
01069   for(int v=0;v<NVert;v++){
01070     int NDel = 0;
01071     Vertex[v].NTria = 1;
01072     for(int vv=v+1;Vertex[vv].v == Vertex[vv-1].v;vv++){
01073       if(vv > NVert) break;
01074       int t = vv-v;
01075       Vertex[v].t[t] = Vertex[vv].t[0];
01076       Vertex[v].NTria = t+1;
01077       NDel++;
01078       SigErr(NDel>MAX_JOINT_VERTEX,"Neighbour Vertices: the vertex has more conjunction points than expected\n");
01079     }
01080     for(int d=1;d<NDel+1;d++){
01081       for(int vv=v+1;vv<NVert-1;vv++){
01082         Swap(vv,vv+1);
01083       }
01084     }
01085     NVert -= NDel;
01086   }
01087 }
01088 void NeiVertex::SetCounters(){
01089   vCurr = 0;
01090   tCurr = 0;
01091 }
01093 void NeiVertex::SetCounters(int v){
01094   for(int vv=vCurr;vv<NVert;vv++){
01095     if(Vertex[vv].v == v){
01096       vCurr = vv;
01097       break;
01098     }
01099   }
01100   tCurr = 0;
01101 }
01102 int NeiVertex::IfItCell(int v){
01103   if(tCurr == Vertex[vCurr].NTria) return 0;
01104   return 1;
01105 }
01106 void NeiVertex::IncrCurr(int v){
01107   tCurr++;
01108 }
01109 int NeiVertex::VertCurr(int v){
01110   return vCurr;
01111 }
01112 int NeiVertex::TriaCurr(int v){
01113   return Vertex[vCurr].t[tCurr];
01114 }
01115 void NeiVertex::Print(){
01116   SetCounters();
01117   for(int v=0;v<NVert;v++){
01118     printf("---- (%d) ----\n",Vertex[v].v);
01119     for(SetCounters(v);IfItCell(v);IncrCurr(v)){
01120       printf("%d - ",VertCurr(v));
01121     }
01122     printf("\n");
01123   }
01124   SetCounters();
01125 }