Allink
v0.1
|
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 }