00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "cell.hh"
00012 #include "container.hh"
00013
00014
00015
00016
00017
00018
00019 template<class r_option>
00020 container_base<r_option>::container_base(fpoint xa,fpoint xb,fpoint ya,fpoint yb,fpoint za,fpoint zb,
00021 int xn,int yn,int zn,bool xper,bool yper,bool zper,int memi)
00022 : ax(xa),bx(xb),ay(ya),by(yb),az(za),bz(zb),
00023 xsp(xn/(xb-xa)),ysp(yn/(yb-ya)),zsp(zn/(zb-za)),
00024 nx(xn),ny(yn),nz(zn),nxy(xn*yn),nxyz(xn*yn*zn),
00025 hx(xper?2*xn+1:xn),hy(yper?2*yn+1:yn),hz(zper?2*zn+1:zn),hxy(hx*hy),hxyz(hx*hy*hz),
00026 xperiodic(xper),yperiodic(yper),zperiodic(zper),
00027 mv(0),wall_number(0),current_wall_size(init_wall_size),
00028 radius(this),sz(radius.mem_size) {
00029 int l;
00030 co=new int[nxyz];
00031 for(l=0;l<nxyz;l++) co[l]=0;
00032 mem=new int[nxyz];
00033 for(l=0;l<nxyz;l++) mem[l]=memi;
00034 id=new int*[nxyz];
00035 for(l=0;l<nxyz;l++) id[l]=new int[memi];
00036 p=new fpoint*[nxyz];
00037 for(l=0;l<nxyz;l++) p[l]=new fpoint[sz*memi];
00038 mask=new unsigned int[hxyz];
00039 for(l=0;l<hxyz;l++) mask[l]=0;
00040 s_size=3*(hxy+hz*(hx+hy));if(s_size<18) s_size=18;
00041 sl=new int[s_size];
00042 walls=new wall*[current_wall_size];
00043 mrad=new fpoint[hgridsq*seq_length];
00044 initialize_radii();
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 template<class r_option>
00057 void container_base<r_option>::initialize_radii() {
00058 const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28;
00059 const fpoint xstep=(bx-ax)/nx/fgrid;
00060 const fpoint ystep=(by-ay)/ny/fgrid;
00061 const fpoint zstep=(bz-az)/nz/fgrid;
00062 int i,j,k,lx,ly,lz,l=0,q;
00063 unsigned int *e=const_cast<unsigned int*> (wl);
00064 fpoint xlo,ylo,zlo,xhi,yhi,zhi,minr;fpoint *radp=mrad;
00065 unsigned int f;
00066 for(zlo=0,zhi=zstep,lz=0;lz<hgrid;zlo=zhi,zhi+=zstep,lz++) {
00067 for(ylo=0,yhi=ystep,ly=0;ly<hgrid;ylo=yhi,yhi+=ystep,ly++) {
00068 for(xlo=0,xhi=xstep,lx=0;lx<hgrid;xlo=xhi,xhi+=xstep,l++,lx++) {
00069 minr=large_number;
00070 for(q=e[0]+1;q<seq_length;q++) {
00071 f=e[q];
00072 i=(f&127)-64;
00073 j=(f>>7&127)-64;
00074 k=(f>>14&127)-64;
00075 if((f&b2)==b2) {
00076 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i-1,j,k);
00077 if((f&b1)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
00078 } else if((f&b1)==b1) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
00079 if((f&b4)==b4) {
00080 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j-1,k);
00081 if((f&b3)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
00082 } else if((f&b3)==b3) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
00083 if((f&b6)==b6) {
00084 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k-1);
00085 if((f&b5)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
00086 } else if((f&b5)==b5) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
00087 }
00088 q--;
00089 while(q>0) {
00090 radp[q]=minr;
00091 f=e[q];
00092 i=(f&127)-64;
00093 j=(f>>7&127)-64;
00094 k=(f>>14&127)-64;
00095 compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k);
00096 q--;
00097 }
00098 radp[0]=minr;
00099 e+=seq_length;
00100 radp+=seq_length;
00101 }
00102 }
00103 }
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 template<class r_option>
00117 inline void container_base<r_option>::compute_minimum(fpoint &minr,fpoint &xlo,fpoint &xhi,fpoint &ylo,fpoint &yhi,fpoint &zlo,fpoint &zhi,int ti,int tj,int tk) {
00118 const fpoint boxx=(bx-ax)/nx,boxy=(by-ay)/ny,boxz=(bz-az)/nz;
00119 fpoint radsq,temp;
00120 if(ti>0) {temp=boxx*ti-xhi;radsq=temp*temp;}
00121 else if(ti<0) {temp=xlo-boxx*(1+ti);radsq=temp*temp;}
00122 else radsq=0;
00123
00124 if(tj>0) {temp=boxy*tj-yhi;radsq+=temp*temp;}
00125 else if(tj<0) {temp=ylo-boxy*(1+tj);radsq+=temp*temp;}
00126
00127 if(tk>0) {temp=boxz*tk-zhi;radsq+=temp*temp;}
00128 else if(tk<0) {temp=zlo-boxz*(1+tk);radsq+=temp*temp;}
00129
00130 if(radsq<minr) minr=radsq;
00131 }
00132
00133
00134 template<class r_option>
00135 container_base<r_option>::~container_base() {
00136 int l;
00137 for(l=0;l<nxyz;l++) delete [] p[l];
00138 for(l=0;l<nxyz;l++) delete [] id[l];
00139 delete [] p;
00140 delete [] id;
00141 delete [] mem;
00142 delete [] co;
00143 delete [] mask;
00144 delete [] sl;
00145 delete [] walls;
00146 delete [] mrad;
00147 }
00148
00149
00150 template<class r_option>
00151 void container_base<r_option>::draw_particles(ostream &os) {
00152 int c,l,i;
00153 for(l=0;l<nxyz;l++) {
00154 for(c=0;c<co[l];c++) {
00155 os << id[l][c];
00156 for(i=sz*c;i<sz*(c+1);i++) os << " " << p[l][i];
00157 os << "\n";
00158 }
00159 }
00160 }
00161
00162
00163
00164 template<class r_option>
00165 void container_base<r_option>::draw_particles() {
00166 draw_particles(cout);
00167 }
00168
00169
00170
00171
00172 template<class r_option>
00173 void container_base<r_option>::draw_particles(const char *filename) {
00174 ofstream os;
00175 os.open(filename,ofstream::out|ofstream::trunc);
00176 draw_particles(os);
00177 os.close();
00178 }
00179
00180
00181 template<class r_option>
00182 void container_base<r_option>::draw_particles_pov(ostream &os) {
00183 int l,c;
00184 for(l=0;l<nxyz;l++) {
00185 for(c=0;c<co[l];c++) {
00186 os << "// id " << id[l][c] << "\n";
00187 os << "sphere{<" << p[l][sz*c] << "," << p[l][sz*c+1] << ","
00188 << p[l][sz*c+2] << ">,";
00189 radius.rad(os,l,c);
00190 os << "}\n";
00191 }
00192 }
00193 }
00194
00195
00196
00197 template<class r_option>
00198 void container_base<r_option>::draw_particles_pov() {
00199 draw_particles_pov(cout);
00200 }
00201
00202
00203
00204
00205 template<class r_option>
00206 void container_base<r_option>::draw_particles_pov(const char *filename) {
00207 ofstream os;
00208 os.open(filename,ofstream::out|ofstream::trunc);
00209 draw_particles_pov(os);
00210 os.close();
00211 }
00212
00213
00214 template<class r_option>
00215 void container_base<r_option>::put(int n,fpoint x,fpoint y,fpoint z) {
00216 if(x>ax&&y>ay&&z>az) {
00217 int i,j,k;
00218 i=int((x-ax)*xsp);j=int((y-ay)*ysp);k=int((z-az)*zsp);
00219 if(i<nx&&j<ny&&k<nz) {
00220 i+=nx*j+nxy*k;
00221 if(co[i]==mem[i]) add_particle_memory(i);
00222 p[i][sz*co[i]]=x;p[i][sz*co[i]+1]=y;p[i][sz*co[i]+2]=z;
00223 radius.store_radius(i,co[i],0.5);
00224 id[i][co[i]++]=n;
00225 }
00226 }
00227 }
00228
00229
00230
00231
00232
00233 template<class r_option>
00234 void container_base<r_option>::put(int n,fpoint x,fpoint y,fpoint z,fpoint r) {
00235 if(x>ax&&y>ay&&z>az) {
00236 int i,j,k;
00237 i=int((x-ax)*xsp);j=int((y-ay)*ysp);k=int((z-az)*zsp);
00238 if(i<nx&&j<ny&&k<nz) {
00239 i+=nx*j+nxy*k;
00240 if(co[i]==mem[i]) add_particle_memory(i);
00241 p[i][sz*co[i]]=x;p[i][sz*co[i]+1]=y;p[i][sz*co[i]+2]=z;
00242 radius.store_radius(i,co[i],r);
00243 id[i][co[i]++]=n;
00244 }
00245 }
00246 }
00247
00248
00249 template<class r_option>
00250 void container_base<r_option>::add_particle_memory(int i) {
00251 int *idp;fpoint *pp;
00252 int l,nmem=2*mem[i];
00253 #if VOROPP_VERBOSE >=3
00254 cerr << "Particle memory in region " << i << " scaled up to " << nmem << endl;
00255 #endif
00256 if(nmem>max_particle_memory)
00257 voropp_fatal_error("Absolute maximum memory allocation exceeded",VOROPP_MEMORY_ERROR);
00258 idp=new int[nmem];
00259 for(l=0;l<co[i];l++) idp[l]=id[i][l];
00260 pp=new fpoint[sz*nmem];
00261 for(l=0;l<sz*co[i];l++) pp[l]=p[i][l];
00262 mem[i]=nmem;
00263 delete [] id[i];id[i]=idp;
00264 delete [] p[i];p[i]=pp;
00265 }
00266
00267
00268 template<class r_option>
00269 inline void container_base<r_option>::add_list_memory() {
00270 int i,j=0,*ps;
00271 ps=new int[s_size*2];
00272 #if VOROPP_VERBOSE >=2
00273 cerr << "List memory scaled up to " << s_size*2 << endl;
00274 #endif
00275 if(s_start<=s_end) {
00276 for(i=s_start;i<s_end;i++) ps[j++]=sl[i];
00277 } else {
00278 for(i=s_start;i<s_size;i++) ps[j++]=sl[i];
00279 for(i=0;i<s_end;i++) ps[j++]=sl[i];
00280 }
00281 s_size*=2;
00282 s_start=0;s_end=j;
00283 delete [] sl;sl=ps;
00284 }
00285
00286
00287 template<class r_option>
00288 void container_base<r_option>::import(istream &is) {
00289 radius.import(is);
00290 }
00291
00292
00293
00294 template<class r_option>
00295 inline void container_base<r_option>::import() {
00296 import(cin);
00297 }
00298
00299
00300
00301
00302 template<class r_option>
00303 inline void container_base<r_option>::import(const char *filename) {
00304 ifstream is;
00305 is.open(filename,ifstream::in);
00306 if(is.fail()) voropp_fatal_error("Unable to open file for import",VOROPP_FILE_ERROR);
00307 import(is);
00308 is.close();
00309 }
00310
00311
00312 template<class r_option>
00313 void container_base<r_option>::region_count() {
00314 int i,j,k,ijk=0;
00315 for(k=0;k<nz;k++) {
00316 for(j=0;j<ny;j++) {
00317 for(i=0;i<nx;i++) cout << "Region (" << i << "," << j << "," << k << "): " << co[ijk++] << " particles" << endl;
00318 }
00319 }
00320 }
00321
00322
00323 template<class r_option>
00324 void container_base<r_option>::clear() {
00325 for(int ijk=0;ijk<nxyz;ijk++) co[ijk]=0;
00326 radius.clear_max();
00327 }
00328
00329
00330
00331
00332 template<class r_option>
00333 void container_base<r_option>::draw_cells_gnuplot(const char *filename,fpoint xmin,fpoint xmax,fpoint ymin,fpoint ymax,fpoint zmin,fpoint zmax) {
00334 fpoint x,y,z,px,py,pz;
00335 voropp_loop l1(this);
00336 int q,s;
00337 voronoicell c;
00338 ofstream os;
00339 os.open(filename,ofstream::out|ofstream::trunc);
00340 s=l1.init(xmin,xmax,ymin,ymax,zmin,zmax,px,py,pz);
00341 do {
00342 for(q=0;q<co[s];q++) {
00343 x=p[s][sz*q]+px;y=p[s][sz*q+1]+py;z=p[s][sz*q+2]+pz;
00344 if(x>xmin&&x<xmax&&y>ymin&&y<ymax&&z>zmin&&z<zmax) {
00345 if(compute_cell(c,l1.ip,l1.jp,l1.kp,s,q,x,y,z)) c.draw_gnuplot(os,x,y,z);
00346 }
00347 }
00348 } while((s=l1.inc(px,py,pz))!=-1);
00349 os.close();
00350 }
00351
00352
00353
00354 template<class r_option>
00355 void container_base<r_option>::draw_cells_gnuplot(const char *filename) {
00356 draw_cells_gnuplot(filename,ax,bx,ay,by,az,bz);
00357 }
00358
00359
00360
00361
00362 template<class r_option>
00363 void container_base<r_option>::draw_cells_pov(const char *filename,fpoint xmin,fpoint xmax,fpoint ymin,fpoint ymax,fpoint zmin,fpoint zmax) {
00364 fpoint x,y,z,px,py,pz;
00365 voropp_loop l1(this);
00366 int q,s;
00367 voronoicell c;
00368 ofstream os;
00369 os.open(filename,ofstream::out|ofstream::trunc);
00370 s=l1.init(xmin,xmax,ymin,ymax,zmin,zmax,px,py,pz);
00371 do {
00372 for(q=0;q<co[s];q++) {
00373 os << "// cell " << id[s][q] << "\n";
00374 x=p[s][sz*q]+px;y=p[s][sz*q+1]+py;z=p[s][sz*q+2]+pz;
00375 if(x>xmin&&x<xmax&&y>ymin&&y<ymax&&z>zmin&&z<zmax) {
00376 if (compute_cell(c,l1.ip,l1.jp,l1.kp,s,q,x,y,z)) c.draw_pov(os,x,y,z);
00377 }
00378 }
00379 } while((s=l1.inc(px,py,pz))!=-1);
00380 os.close();
00381 }
00382
00383
00384
00385 template<class r_option>
00386 void container_base<r_option>::draw_cells_pov(const char *filename) {
00387 draw_cells_pov(filename,ax,bx,ay,by,az,bz);
00388 }
00389
00390
00391
00392
00393
00394 template<class r_option>
00395 void container_base<r_option>::compute_all_cells() {
00396 voronoicell c;
00397 int i,j,k,ijk=0,q;
00398 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00399 for(q=0;q<co[ijk];q++) compute_cell(c,i,j,k,ijk,q);
00400 }
00401 }
00402
00403
00404
00405
00406 template<class r_option>
00407 void container_base<r_option>::store_cell_volumes(fpoint *bb) {
00408 voronoicell c;
00409 int i,j,k,ijk=0,q;
00410 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00411 for(q=0;q<co[ijk];q++) {
00412 if (compute_cell(c,i,j,k,ijk,q)) {
00413 bb[id[ijk][q]]=c.volume();
00414 } else {
00415 bb[id[ijk][q]]=0;
00416 }
00417 }
00418 }
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428 template<class r_option>
00429 fpoint container_base<r_option>::packing_fraction(fpoint *bb,fpoint cx,fpoint cy,fpoint cz,fpoint r) {
00430 voropp_loop l1(this);
00431 fpoint px,py,pz,x,y,z,rsq=r*r,pvol=0,vvol=0;
00432 int q,s;
00433 s=l1.init(cx,cy,cz,r,px,py,pz);
00434 do {
00435 for(q=0;q<co[s];q++) {
00436 x=p[s][sz*q]+px-cx;
00437 y=p[s][sz*q+1]+py-cy;
00438 z=p[s][sz*q+2]+pz-cz;
00439 if (x*x+y*y+z*z<rsq) {
00440 pvol+=radius.volume(s,q);
00441 vvol+=bb[id[s][q]];
00442 }
00443 }
00444 } while((s=l1.inc(px,py,pz))!=-1);
00445 return vvol>tolerance?pvol/vvol*4.1887902047863909846168578443726:0;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 template<class r_option>
00456 fpoint container_base<r_option>::packing_fraction(fpoint *bb,fpoint xmin,fpoint xmax,fpoint ymin,fpoint ymax,fpoint zmin,fpoint zmax) {
00457 voropp_loop l1(this);
00458 fpoint x,y,z,px,py,pz,pvol=0,vvol=0;
00459 int q,s;
00460 s=l1.init(xmin,xmax,ymin,ymax,zmin,zmax,px,py,pz);
00461 do {
00462 for(q=0;q<co[s];q++) {
00463 x=p[s][sz*q]+px;
00464 y=p[s][sz*q+1]+py;
00465 z=p[s][sz*q+2]+pz;
00466 if(x>xmin&&x<xmax&&y>ymin&&y<ymax&&z>zmin&&z<zmax) {
00467 pvol+=radius.volume(s,q);
00468 vvol+=bb[id[s][q]];
00469 }
00470 }
00471 } while((s=l1.inc(px,py,pz))!=-1);
00472 return vvol>tolerance?pvol/vvol*4.1887902047863909846168578443726:0;
00473 }
00474
00475
00476
00477 template<class r_option>
00478 fpoint container_base<r_option>::sum_cell_volumes() {
00479 voronoicell c;
00480 int i,j,k,ijk=0,q;fpoint vol=0;
00481 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00482 for(q=0;q<co[ijk];q++) if (compute_cell(c,i,j,k,ijk,q)) vol+=c.volume();
00483 }
00484 return vol;
00485 }
00486
00487
00488
00489 template<class r_option>
00490 void container_base<r_option>::print_facet_information() {
00491 voronoicell c;
00492 int i,j,k,ijk=0,q;
00493 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00494 for(q=0;q<co[ijk];q++) if (compute_cell(c,i,j,k,ijk,q)) {
00495 cout << "Particle " << id[ijk][q] << ":\n";
00496 c.facets(cout);
00497 }
00498 }
00499 }
00500
00501
00502
00503 template<class r_option>
00504 inline void container_base<r_option>::count_all_faces(ostream &os) {
00505 voronoicell c;
00506 fpoint x,y,z;
00507 int i,j,k,ijk=0,q;
00508 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00509 for(q=0;q<co[ijk];q++) {
00510 x=p[ijk][sz*q];y=p[ijk][sz*q+1];z=p[ijk][sz*q+2];
00511 os << id[ijk][q] << " " << x << " " << y << " " << z;
00512 radius.print(os,ijk,q);
00513 if (compute_cell(c,i,j,k,ijk,q,x,y,z)) {
00514 os << " " << c.number_of_faces() << "\n";
00515 } else os << " 0\n";
00516 }
00517 }
00518 }
00519
00520
00521
00522 template<class r_option>
00523 void container_base<r_option>::count_all_faces() {
00524 count_all_faces(cout);
00525 }
00526
00527
00528
00529
00530 template<class r_option>
00531 void container_base<r_option>::count_all_faces(const char* filename) {
00532 ofstream os;
00533 os.open(filename,ofstream::out|ofstream::trunc);
00534 count_all_faces(os);
00535 os.close();
00536 }
00537
00538
00539
00540 template<class r_option>
00541 template<class n_option>
00542 inline void container_base<r_option>::print_all(ostream &os,voronoicell_base<n_option> &c) {
00543 fpoint x,y,z;
00544 int i,j,k,ijk=0,q;
00545 for(k=0;k<nz;k++) for(j=0;j<ny;j++) for(i=0;i<nx;i++,ijk++) {
00546 for(q=0;q<co[ijk];q++) {
00547 x=p[ijk][sz*q];y=p[ijk][sz*q+1];z=p[ijk][sz*q+2];
00548 os << id[ijk][q] << " " << x << " " << y << " " << z;
00549 radius.print(os,ijk,q);
00550 if (compute_cell(c,i,j,k,ijk,q,x,y,z)) {
00551 os << " " << c.volume();
00552 c.neighbors(os);
00553 os << "\n";
00554 } else os << " 0\n";
00555 }
00556 }
00557 }
00558
00559
00560
00561 template<class r_option>
00562 void container_base<r_option>::print_all(ostream &os) {
00563 voronoicell c;
00564 print_all(os,c);
00565 }
00566
00567
00568 template<class r_option>
00569 void container_base<r_option>::print_all() {
00570 voronoicell c;
00571 print_all(cout,c);
00572 }
00573
00574
00575
00576
00577 template<class r_option>
00578 inline void container_base<r_option>::print_all(const char* filename) {
00579 voronoicell c;
00580 ofstream os;
00581 os.open(filename,ofstream::out|ofstream::trunc);
00582 print_all(os,c);
00583 os.close();
00584 }
00585
00586
00587
00588
00589 template<class r_option>
00590 void container_base<r_option>::print_all_neighbor(ostream &os) {
00591 voronoicell_neighbor c;
00592 print_all(os,c);
00593 }
00594
00595
00596
00597 template<class r_option>
00598 void container_base<r_option>::print_all_neighbor() {
00599 voronoicell_neighbor c;
00600 print_all(cout,c);
00601 }
00602
00603
00604
00605
00606 template<class r_option>
00607 inline void container_base<r_option>::print_all_neighbor(const char* filename) {
00608 voronoicell_neighbor c;
00609 ofstream os;
00610 os.open(filename,ofstream::out|ofstream::trunc);
00611 print_all(os,c);
00612 os.close();
00613 }
00614
00615
00616
00617
00618
00619
00620 template<class r_option>
00621 template<class n_option>
00622 inline bool container_base<r_option>::initialize_voronoicell(voronoicell_base<n_option> &c,fpoint x,fpoint y,fpoint z) {
00623 fpoint x1,x2,y1,y2,z1,z2;
00624 if(xperiodic) x1=-(x2=0.5*(bx-ax));else {x1=ax-x;x2=bx-x;}
00625 if(yperiodic) y1=-(y2=0.5*(by-ay));else {y1=ay-y;y2=by-y;}
00626 if(zperiodic) z1=-(z2=0.5*(bz-az));else {z1=az-z;z2=bz-z;}
00627 c.init(x1,x2,y1,y2,z1,z2);
00628 for(int j=0;j<wall_number;j++) {
00629 if (!(walls[j]->cut_cell(c,x,y,z))) return false;
00630 }
00631 return true;
00632 }
00633
00634
00635
00636
00637
00638
00639 template<class r_option>
00640 bool container_base<r_option>::point_inside(fpoint x,fpoint y,fpoint z) {
00641 if(x<ax||x>bx||y<ay||y>by||z<az||z>bz) return false;
00642 return point_inside_walls(x,y,z);
00643 }
00644
00645
00646
00647
00648
00649
00650
00651 template<class r_option>
00652 bool container_base<r_option>::point_inside_walls(fpoint x,fpoint y,fpoint z) {
00653 for(int j=0;j<wall_number;j++) if(!walls[j]->point_inside(x,y,z)) return false;
00654 return true;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 template<class r_option>
00672 template<class n_option>
00673 bool container_base<r_option>::compute_cell_sphere(voronoicell_base<n_option> &c,int i,int j,int k,int ijk,int s,fpoint x,fpoint y,fpoint z) {
00674
00675
00676
00677 const fpoint length_scale=1;
00678 fpoint x1,y1,z1,qx,qy,qz,lr=0,lrs=0,ur,urs,rs;
00679 int q,t;
00680 voropp_loop l(this);
00681 if (!initialize_voronoicell(c,x,y,z)) return false;
00682
00683
00684
00685
00686 radius.init(ijk,s);
00687 while(radius.cutoff(lrs)<c.maxradsq()) {
00688 ur=lr+0.5*length_scale;urs=ur*ur;
00689 t=l.init(x,y,z,ur,qx,qy,qz);
00690 do {
00691 for(q=0;q<co[t];q++) {
00692 x1=p[t][sz*q]+qx-x;y1=p[t][sz*q+1]+qy-y;z1=p[t][sz*q+2]+qz-z;
00693 rs=x1*x1+y1*y1+z1*z1;
00694 if(lrs-tolerance<rs&&rs<urs&&(q!=s||ijk!=t)) {
00695 if (!c.nplane(x1,y1,z1,radius.scale(rs,t,q),id[t][q])) return false;
00696 }
00697 }
00698 } while((t=l.inc(qx,qy,qz))!=-1);
00699 lr=ur;lrs=urs;
00700 }
00701 return true;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 template<class r_option>
00713 template<class n_option>
00714 inline bool container_base<r_option>::compute_cell_sphere(voronoicell_base<n_option> &c,int i,int j,int k,int ijk,int s) {
00715 fpoint x=p[ijk][sz*s],y=p[ijk][sz*s+1],z=p[ijk][sz*s+2];
00716 return compute_cell_sphere(c,i,j,k,ijk,s,x,y,z);
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 template<class r_option>
00729 template<class n_option>
00730 inline bool container_base<r_option>::compute_cell(voronoicell_base<n_option> &c,int i,int j,int k,int ijk,int s) {
00731 fpoint x=p[ijk][sz*s],y=p[ijk][sz*s+1],z=p[ijk][sz*s+2];
00732 return compute_cell(c,i,j,k,ijk,s,x,y,z);
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 template<class r_option>
00760 template<class n_option>
00761 bool container_base<r_option>::compute_cell(voronoicell_base<n_option> &c,int i,int j,int k,int ijk,int s,fpoint x,fpoint y,fpoint z) {
00762 const fpoint boxx=(bx-ax)/nx,boxy=(by-ay)/ny,boxz=(bz-az)/nz;
00763 fpoint x1,y1,z1,qx=0,qy=0,qz=0;
00764 fpoint xlo,ylo,zlo,xhi,yhi,zhi,rs;
00765 int ci,cj,ck,di,dj,dk,dijk,ei,ej,ek,eijk,si,sj,sk,sijk;
00766 fpoint gxs,gys,gzs,*radp;
00767 int f,g,l;unsigned int q,*e;
00768 const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28;
00769
00770 radius.init(ijk,s);
00771
00772
00773 if (!initialize_voronoicell(c,x,y,z)) return false;
00774 fpoint crs,mrs;
00775
00776 int next_count=3,list_index=0,list_size=8;
00777 int count_list[]={7,11,15,19,26,35,45,59};
00778
00779
00780 for(l=0;l<s;l++) {
00781 x1=p[ijk][sz*l]-x;
00782 y1=p[ijk][sz*l+1]-y;
00783 z1=p[ijk][sz*l+2]-z;
00784 rs=radius.scale(x1*x1+y1*y1+z1*z1,ijk,l);
00785 if (!c.nplane(x1,y1,z1,rs,id[ijk][l])) return false;
00786 }
00787 l++;
00788 while(l<co[ijk]) {
00789 x1=p[ijk][sz*l]-x;
00790 y1=p[ijk][sz*l+1]-y;
00791 z1=p[ijk][sz*l+2]-z;
00792 rs=radius.scale(x1*x1+y1*y1+z1*z1,ijk,l);
00793 if (!c.nplane(x1,y1,z1,rs,id[ijk][l])) return false;
00794 l++;
00795 }
00796
00797
00798
00799
00800 mrs=c.maxradsq();
00801
00802
00803
00804
00805
00806 unsigned int m1,m2;
00807 fpoint fx=x-ax-boxx*i,fy=y-ay-boxy*j,fz=z-az-boxz*k;
00808 si=int(fx*xsp*fgrid);sj=int(fy*ysp*fgrid);sk=int(fz*zsp*fgrid);
00809
00810
00811
00812
00813
00814
00815
00816
00817 if(si>=hgrid) {
00818 gxs=fx;
00819 m1=127+(3<<21);si=fgrid-1-si;m2=1+(1<<21);
00820 } else {m1=m2=0;gxs=boxx-fx;}
00821 if(sj>=hgrid) {
00822 gys=fy;
00823 m1|=(127<<7)+(3<<24);sj=fgrid-1-sj;m2|=(1<<7)+(1<<24);
00824 } else gys=boxy-fy;
00825 if(sk>=hgrid) {
00826 gzs=fz;
00827 m1|=(127<<14)+(3<<27);sk=fgrid-1-sk;m2|=(1<<14)+(1<<27);
00828 } else gzs=boxz-fz;
00829 gxs*=gxs;gys*=gys;gzs*=gzs;
00830
00831
00832
00833
00834 if(si<0) si=0;if(sj<0) sj=0;if(sk<0) sk=0;
00835
00836
00837
00838 sijk=si+hgrid*(sj+hgrid*sk);
00839 radp=mrad+sijk*seq_length;
00840 e=(const_cast<unsigned int*> (wl))+sijk*seq_length;
00841
00842
00843
00844 f=e[0];g=0;
00845 do {
00846
00847
00848
00849 if(g==next_count) {
00850 mrs=c.maxradsq();
00851 if(list_index!=list_size) next_count=count_list[list_index++];
00852 }
00853
00854
00855
00856 if(mrs<radius.cutoff(radp[g])) return true;
00857 g++;
00858
00859
00860
00861
00862 q=e[g];q^=m1;q+=m2;
00863 di=q&127;di-=64;
00864 dj=(q>>7)&127;dj-=64;
00865 dk=(q>>14)&127;dk-=64;
00866
00867
00868 if(xperiodic) {if(di<-nx) continue;else if(di>nx) continue;}
00869 else {if(di<-i) continue;else if(di>=nx-i) continue;}
00870 if(yperiodic) {if(dj<-ny) continue;else if(dj>ny) continue;}
00871 else {if(dj<-j) continue;else if(dj>=ny-j) continue;}
00872 if(zperiodic) {if(dk<-nz) continue;else if(dk>nz) continue;}
00873 else {if(dk<-k) continue;else if(dk>=nz-k) continue;}
00874
00875
00876
00877
00878
00879
00880 if(compute_min_max_radius(di,dj,dk,fx,fy,fz,gxs,gys,gzs,crs,mrs)) continue;
00881
00882
00883
00884 di+=i;dj+=j;dk+=k;
00885 if(xperiodic) {if(di<0) {qx=ax-bx;di+=nx;} else if(di>=nx) {qx=bx-ax;di-=nx;} else qx=0;}
00886 if(yperiodic) {if(dj<0) {qy=ay-by;dj+=ny;} else if(dj>=ny) {qy=by-ay;dj-=ny;} else qy=0;}
00887 if(zperiodic) {if(dk<0) {qz=az-bz;dk+=nz;} else if(dk>=nz) {qz=bz-az;dk-=nz;} else qz=0;}
00888 dijk=di+nx*(dj+ny*dk);
00889
00890
00891
00892
00893
00894 if(mrs>radius.cutoff(crs)) {
00895 for(l=0;l<co[dijk];l++) {
00896 x1=p[dijk][sz*l]+qx-x;
00897 y1=p[dijk][sz*l+1]+qy-y;
00898 z1=p[dijk][sz*l+2]+qz-z;
00899 rs=radius.scale(x1*x1+y1*y1+z1*z1,dijk,l);
00900 if (!c.nplane(x1,y1,z1,rs,id[dijk][l])) return false;
00901 }
00902 } else {
00903 for(l=0;l<co[dijk];l++) {
00904 x1=p[dijk][sz*l]+qx-x;
00905 y1=p[dijk][sz*l+1]+qy-y;
00906 z1=p[dijk][sz*l+2]+qz-z;
00907 rs=radius.scale(x1*x1+y1*y1+z1*z1,dijk,l);
00908 if(rs<mrs) {
00909 if (!c.nplane(x1,y1,z1,rs,id[dijk][l])) return false;
00910 }
00911 }
00912 }
00913 } while(g<f);
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923 ci=xperiodic?nx:i;
00924 cj=yperiodic?ny:j;
00925 ck=zperiodic?nz:k;
00926
00927
00928
00929 mv++;
00930 if(mv==0) {
00931 for(l=0;l<hxyz;l++) mask[l]=0;
00932 mv=1;
00933 }
00934
00935
00936 s_start=s_end=0;
00937
00938 while(g<seq_length-1) {
00939
00940
00941
00942 if(g==next_count) {
00943 mrs=c.maxradsq();
00944 if(list_index!=list_size) next_count=count_list[list_index++];
00945 }
00946
00947
00948
00949 if(mrs<radius.cutoff(radp[g])) return true;
00950 g++;
00951
00952
00953
00954
00955 q=e[g];q^=m1;q+=m2;
00956 di=q&127;di-=64;
00957 dj=(q>>7)&127;dj-=64;
00958 dk=(q>>14)&127;dk-=64;
00959
00960
00961
00962
00963 ei=ci+di;
00964 ej=cj+dj;
00965 ek=ck+dk;
00966 if(ei<0) continue;else if(ei>=hx) continue;
00967 if(ej<0) continue;else if(ej>=hy) continue;
00968 if(ek<0) continue;else if(ek>=hz) continue;
00969 eijk=ei+hx*(ej+hy*ek);
00970 mask[eijk]=mv;
00971
00972
00973
00974
00975
00976
00977 if(compute_min_max_radius(di,dj,dk,fx,fy,fz,gxs,gys,gzs,crs,mrs)) continue;
00978
00979
00980
00981 di+=i;dj+=j;dk+=k;
00982 if(xperiodic) {if(di<0) {qx=ax-bx;di+=nx;} else if(di>=nx) {qx=bx-ax;di-=nx;} else qx=0;}
00983 if(yperiodic) {if(dj<0) {qy=ay-by;dj+=ny;} else if(dj>=ny) {qy=by-ay;dj-=ny;} else qy=0;}
00984 if(zperiodic) {if(dk<0) {qz=az-bz;dk+=nz;} else if(dk>=nz) {qz=bz-az;dk-=nz;} else qz=0;}
00985 dijk=di+nx*(dj+ny*dk);
00986
00987
00988
00989
00990
00991 if(mrs>radius.cutoff(crs)) {
00992 for(l=0;l<co[dijk];l++) {
00993 x1=p[dijk][sz*l]+qx-x;
00994 y1=p[dijk][sz*l+1]+qy-y;
00995 z1=p[dijk][sz*l+2]+qz-z;
00996 rs=radius.scale(x1*x1+y1*y1+z1*z1,dijk,l);
00997 if (!c.nplane(x1,y1,z1,rs,id[dijk][l])) return false;
00998 }
00999 } else {
01000 for(l=0;l<co[dijk];l++) {
01001 x1=p[dijk][sz*l]+qx-x;
01002 y1=p[dijk][sz*l+1]+qy-y;
01003 z1=p[dijk][sz*l+2]+qz-z;
01004 rs=radius.scale(x1*x1+y1*y1+z1*z1,dijk,l);
01005 if(rs<mrs) {
01006 if(!c.nplane(x1,y1,z1,rs,id[dijk][l])) return false;
01007 }
01008 }
01009 }
01010
01011
01012
01013 if(s_end+18>s_size) add_list_memory();
01014
01015
01016
01017
01018 if((q&b2)==b2) {
01019 if(ei>0) if(mask[eijk-1]!=mv) {mask[eijk-1]=mv;sl[s_end++]=ei-1;sl[s_end++]=ej;sl[s_end++]=ek;}
01020 if((q&b1)==0) if(ei<hx-1) if(mask[eijk+1]!=mv) {mask[eijk+1]=mv;sl[s_end++]=ei+1;sl[s_end++]=ej;sl[s_end++]=ek;}
01021 } else if((q&b1)==b1) {if(ei<hx-1) if(mask[eijk+1]!=mv) {mask[eijk+1]=mv;sl[s_end++]=ei+1;sl[s_end++]=ej;sl[s_end++]=ek;}}
01022 if((q&b4)==b4) {if(ej>0) if(mask[eijk-hx]!=mv) {mask[eijk-hx]=mv;sl[s_end++]=ei;sl[s_end++]=ej-1;sl[s_end++]=ek;}
01023 if((q&b3)==0) if(ej<hy-1) if(mask[eijk+hx]!=mv) {mask[eijk+hx]=mv;sl[s_end++]=ei;sl[s_end++]=ej+1;sl[s_end++]=ek;}
01024 } else if((q&b3)==b3) {if(ej<hy-1) if(mask[eijk+hx]!=mv) {mask[eijk+hx]=mv;sl[s_end++]=ei;sl[s_end++]=ej+1;sl[s_end++]=ek;}}
01025 if((q&b6)==b6) {if(ek>0) if(mask[eijk-hxy]!=mv) {mask[eijk-hxy]=mv;sl[s_end++]=ei;sl[s_end++]=ej;sl[s_end++]=ek-1;}
01026 if((q&b5)==0) if(ek<hz-1) if(mask[eijk+hxy]!=mv) {mask[eijk+hxy]=mv;sl[s_end++]=ei;sl[s_end++]=ej;sl[s_end++]=ek+1;}
01027 } else if((q&b5)==b5) if(ek<hz-1) if(mask[eijk+hxy]!=mv) {mask[eijk+hxy]=mv;sl[s_end++]=ei;sl[s_end++]=ej;sl[s_end++]=ek+1;}
01028 }
01029
01030
01031 if(mrs<radius.cutoff(radp[g])) return true;
01032
01033
01034
01035 fx+=boxx*ci;fy+=boxy*cj;fz+=boxz*ck;
01036
01037
01038
01039
01040 while(s_start!=s_end) {
01041
01042
01043 if(s_start==s_size) s_start=0;
01044
01045
01046
01047 di=sl[s_start++];dj=sl[s_start++];dk=sl[s_start++];
01048 xlo=di*boxx-fx;xhi=xlo+boxx;
01049 ylo=dj*boxy-fy;yhi=ylo+boxy;
01050 zlo=dk*boxz-fz;zhi=zlo+boxz;
01051
01052
01053
01054 if(di>ci) {
01055 if(dj>cj) {
01056 if(dk>ck) {
01057 if(corner_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;
01058 } else if(dk<ck) {
01059 if(corner_test(c,xlo,ylo,zhi,xhi,yhi,zlo)) continue;
01060 } else {
01061 if(edge_z_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;
01062 }
01063 } else if(dj<cj) {
01064 if(dk>ck) {
01065 if(corner_test(c,xlo,yhi,zlo,xhi,ylo,zhi)) continue;
01066 } else if(dk<ck) {
01067 if(corner_test(c,xlo,yhi,zhi,xhi,ylo,zlo)) continue;
01068 } else {
01069 if(edge_z_test(c,xlo,yhi,zlo,xhi,ylo,zhi)) continue;
01070 }
01071 } else {
01072 if(dk>ck) {
01073 if(edge_y_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;
01074 } else if(dk<ck) {
01075 if(edge_y_test(c,xlo,ylo,zhi,xhi,yhi,zlo)) continue;
01076 } else {
01077 if(face_x_test(c,xlo,ylo,zlo,yhi,zhi)) continue;
01078 }
01079 }
01080 } else if(di<ci) {
01081 if(dj>cj) {
01082 if(dk>ck) {
01083 if(corner_test(c,xhi,ylo,zlo,xlo,yhi,zhi)) continue;
01084 } else if(dk<ck) {
01085 if(corner_test(c,xhi,ylo,zhi,xlo,yhi,zlo)) continue;
01086 } else {
01087 if(edge_z_test(c,xhi,ylo,zlo,xlo,yhi,zhi)) continue;
01088 }
01089 } else if(dj<cj) {
01090 if(dk>ck) {
01091 if(corner_test(c,xhi,yhi,zlo,xlo,ylo,zhi)) continue;
01092 } else if(dk<ck) {
01093 if(corner_test(c,xhi,yhi,zhi,xlo,ylo,zlo)) continue;
01094 } else {
01095 if(edge_z_test(c,xhi,yhi,zlo,xlo,ylo,zhi)) continue;
01096 }
01097 } else {
01098 if(dk>ck) {
01099 if(edge_y_test(c,xhi,ylo,zlo,xlo,yhi,zhi)) continue;
01100 } else if(dk<ck) {
01101 if(edge_y_test(c,xhi,ylo,zhi,xlo,yhi,zlo)) continue;
01102 } else {
01103 if(face_x_test(c,xhi,ylo,zlo,yhi,zhi)) continue;
01104 }
01105 }
01106 } else {
01107 if(dj>cj) {
01108 if(dk>ck) {
01109 if(edge_x_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;
01110 } else if(dk<ck) {
01111 if(edge_x_test(c,xlo,ylo,zhi,xhi,yhi,zlo)) continue;
01112 } else {
01113 if(face_y_test(c,xlo,ylo,zlo,xhi,zhi)) continue;
01114 }
01115 } else if(dj<cj) {
01116 if(dk>ck) {
01117 if(edge_x_test(c,xlo,yhi,zlo,xhi,ylo,zhi)) continue;
01118 } else if(dk<ck) {
01119 if(edge_x_test(c,xlo,yhi,zhi,xhi,ylo,zlo)) continue;
01120 } else {
01121 if(face_y_test(c,xlo,yhi,zlo,xhi,zhi)) continue;
01122 }
01123 } else {
01124 if(dk>ck) {
01125 if(face_z_test(c,xlo,ylo,zlo,xhi,yhi)) continue;
01126 } else if(dk<ck) {
01127 if(face_z_test(c,xlo,ylo,zhi,xhi,yhi)) continue;
01128 } else {
01129 cout << "Can't happen ... happened\n";
01130 }
01131 }
01132 }
01133
01134
01135
01136 if(xperiodic) {ei=i+di-nx;if(ei<0) {qx=ax-bx;ei+=nx;} else if(ei>=nx) {qx=bx-ax;ei-=nx;} else qx=0;} else ei=di;
01137 if(yperiodic) {ej=j+dj-ny;if(ej<0) {qy=ay-by;ej+=ny;} else if(ej>=ny) {qy=by-ay;ej-=ny;} else qy=0;} else ej=dj;
01138 if(zperiodic) {ek=k+dk-nz;if(ek<0) {qz=az-bz;ek+=nz;} else if(ek>=nz) {qz=bz-az;ek-=nz;} else qz=0;} else ek=dk;
01139 eijk=ei+nx*(ej+ny*ek);
01140
01141
01142
01143
01144 for(l=0;l<co[eijk];l++) {
01145 x1=p[eijk][sz*l]+qx-x;
01146 y1=p[eijk][sz*l+1]+qy-y;
01147 z1=p[eijk][sz*l+2]+qz-z;
01148 rs=radius.scale(x1*x1+y1*y1+z1*z1,eijk,l);
01149 if (!c.nplane(x1,y1,z1,rs,id[eijk][l])) return false;
01150 }
01151
01152
01153 if((s_start<=s_end?s_size-s_end+s_start:s_end-s_start)<18) add_list_memory();
01154
01155
01156
01157 dijk=di+hx*(dj+hy*dk);
01158 if(di>0) if(mask[dijk-1]!=mv) {if(s_end==s_size) s_end=0;mask[dijk-1]=mv;sl[s_end++]=di-1;sl[s_end++]=dj;sl[s_end++]=dk;}
01159 if(dj>0) if(mask[dijk-hx]!=mv) {if(s_end==s_size) s_end=0;mask[dijk-hx]=mv;sl[s_end++]=di;sl[s_end++]=dj-1;sl[s_end++]=dk;}
01160 if(dk>0) if(mask[dijk-hxy]!=mv) {if(s_end==s_size) s_end=0;mask[dijk-hxy]=mv;sl[s_end++]=di;sl[s_end++]=dj;sl[s_end++]=dk-1;}
01161 if(di<hx-1) if(mask[dijk+1]!=mv) {if(s_end==s_size) s_end=0;mask[dijk+1]=mv;sl[s_end++]=di+1;sl[s_end++]=dj;sl[s_end++]=dk;}
01162 if(dj<hy-1) if(mask[dijk+hx]!=mv) {if(s_end==s_size) s_end=0;mask[dijk+hx]=mv;sl[s_end++]=di;sl[s_end++]=dj+1;sl[s_end++]=dk;}
01163 if(dk<hz-1) if(mask[dijk+hxy]!=mv) {if(s_end==s_size) s_end=0;mask[dijk+hxy]=mv;sl[s_end++]=di;sl[s_end++]=dj;sl[s_end++]=dk+1;}
01164 }
01165
01166 return true;
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 template<class r_option>
01179 template<class n_option>
01180 inline bool container_base<r_option>::corner_test(voronoicell_base<n_option> &c,fpoint xl,fpoint yl,fpoint zl,fpoint xh,fpoint yh,fpoint zh) {
01181 if(c.plane_intersects_guess(xh,yl,zl,radius.cutoff(xl*xh+yl*yl+zl*zl))) return false;
01182 if(c.plane_intersects(xh,yh,zl,radius.cutoff(xl*xh+yl*yh+zl*zl))) return false;
01183 if(c.plane_intersects(xl,yh,zl,radius.cutoff(xl*xl+yl*yh+zl*zl))) return false;
01184 if(c.plane_intersects(xl,yh,zh,radius.cutoff(xl*xl+yl*yh+zl*zh))) return false;
01185 if(c.plane_intersects(xl,yl,zh,radius.cutoff(xl*xl+yl*yl+zl*zh))) return false;
01186 if(c.plane_intersects(xh,yl,zh,radius.cutoff(xl*xh+yl*yl+zl*zh))) return false;
01187 return true;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 template<class r_option>
01202 template<class n_option>
01203 inline bool container_base<r_option>::edge_x_test(voronoicell_base<n_option> &c,fpoint x0,fpoint yl,fpoint zl,fpoint x1,fpoint yh,fpoint zh) {
01204 if(c.plane_intersects_guess(x0,yl,zh,radius.cutoff(yl*yl+zl*zh))) return false;
01205 if(c.plane_intersects(x1,yl,zh,radius.cutoff(yl*yl+zl*zh))) return false;
01206 if(c.plane_intersects(x1,yl,zl,radius.cutoff(yl*yl+zl*zl))) return false;
01207 if(c.plane_intersects(x0,yl,zl,radius.cutoff(yl*yl+zl*zl))) return false;
01208 if(c.plane_intersects(x0,yh,zl,radius.cutoff(yl*yh+zl*zl))) return false;
01209 if(c.plane_intersects(x1,yh,zl,radius.cutoff(yl*yh+zl*zl))) return false;
01210 return true;
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 template<class r_option>
01225 template<class n_option>
01226 inline bool container_base<r_option>::edge_y_test(voronoicell_base<n_option> &c,fpoint xl,fpoint y0,fpoint zl,fpoint xh,fpoint y1,fpoint zh) {
01227 if(c.plane_intersects_guess(xl,y0,zh,radius.cutoff(xl*xl+zl*zh))) return false;
01228 if(c.plane_intersects(xl,y1,zh,radius.cutoff(xl*xl+zl*zh))) return false;
01229 if(c.plane_intersects(xl,y1,zl,radius.cutoff(xl*xl+zl*zl))) return false;
01230 if(c.plane_intersects(xl,y0,zl,radius.cutoff(xl*xl+zl*zl))) return false;
01231 if(c.plane_intersects(xh,y0,zl,radius.cutoff(xl*xh+zl*zl))) return false;
01232 if(c.plane_intersects(xh,y1,zl,radius.cutoff(xl*xh+zl*zl))) return false;
01233 return true;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 template<class r_option>
01248 template<class n_option>
01249 inline bool container_base<r_option>::edge_z_test(voronoicell_base<n_option> &c,fpoint xl,fpoint yl,fpoint z0,fpoint xh,fpoint yh,fpoint z1) {
01250 if(c.plane_intersects_guess(xl,yh,z0,radius.cutoff(xl*xl+yl*yh))) return false;
01251 if(c.plane_intersects(xl,yh,z1,radius.cutoff(xl*xl+yl*yh))) return false;
01252 if(c.plane_intersects(xl,yl,z1,radius.cutoff(xl*xl+yl*yl))) return false;
01253 if(c.plane_intersects(xl,yl,z0,radius.cutoff(xl*xl+yl*yl))) return false;
01254 if(c.plane_intersects(xh,yl,z0,radius.cutoff(xl*xh+yl*yl))) return false;
01255 if(c.plane_intersects(xh,yl,z1,radius.cutoff(xl*xh+yl*yl))) return false;
01256 return true;
01257 }
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 template<class r_option>
01268 template<class n_option>
01269 inline bool container_base<r_option>::face_x_test(voronoicell_base<n_option> &c,fpoint xl,fpoint y0,fpoint z0,fpoint y1,fpoint z1) {
01270 if(c.plane_intersects_guess(xl,y0,z0,radius.cutoff(xl*xl))) return false;
01271 if(c.plane_intersects(xl,y0,z1,radius.cutoff(xl*xl))) return false;
01272 if(c.plane_intersects(xl,y1,z1,radius.cutoff(xl*xl))) return false;
01273 if(c.plane_intersects(xl,y1,z0,radius.cutoff(xl*xl))) return false;
01274 return true;
01275 }
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 template<class r_option>
01286 template<class n_option>
01287 inline bool container_base<r_option>::face_y_test(voronoicell_base<n_option> &c,fpoint x0,fpoint yl,fpoint z0,fpoint x1,fpoint z1) {
01288 if(c.plane_intersects_guess(x0,yl,z0,radius.cutoff(yl*yl))) return false;
01289 if(c.plane_intersects(x0,yl,z1,radius.cutoff(yl*yl))) return false;
01290 if(c.plane_intersects(x1,yl,z1,radius.cutoff(yl*yl))) return false;
01291 if(c.plane_intersects(x1,yl,z0,radius.cutoff(yl*yl))) return false;
01292 return true;
01293 }
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 template<class r_option>
01304 template<class n_option>
01305 inline bool container_base<r_option>::face_z_test(voronoicell_base<n_option> &c,fpoint x0,fpoint y0,fpoint zl,fpoint x1,fpoint y1) {
01306 if(c.plane_intersects_guess(x0,y0,zl,radius.cutoff(zl*zl))) return false;
01307 if(c.plane_intersects(x0,y1,zl,radius.cutoff(zl*zl))) return false;
01308 if(c.plane_intersects(x1,y1,zl,radius.cutoff(zl*zl))) return false;
01309 if(c.plane_intersects(x1,y0,zl,radius.cutoff(zl*zl))) return false;
01310 return true;
01311 }
01312
01313
01314
01315 template<class r_option>
01316 voropp_loop::voropp_loop(container_base<r_option> *q) : sx(q->bx-q->ax), sy(q->by-q->ay), sz(q->bz-q->az),
01317 xsp(q->xsp),ysp(q->ysp),zsp(q->zsp),
01318 ax(q->ax),ay(q->ay),az(q->az),
01319 nx(q->nx),ny(q->ny),nz(q->nz),nxy(q->nxy),nxyz(q->nxyz),
01320 xperiodic(q->xperiodic),yperiodic(q->yperiodic),zperiodic(q->zperiodic) {}
01321
01322
01323
01324
01325 inline int voropp_loop::init(fpoint vx,fpoint vy,fpoint vz,fpoint r,fpoint &px,fpoint &py,fpoint &pz) {
01326 ai=step_int((vx-ax-r)*xsp);
01327 bi=step_int((vx-ax+r)*xsp);
01328 if(!xperiodic) {
01329 if(ai<0) {ai=0;if(bi<0) bi=0;}
01330 if(bi>=nx) {bi=nx-1;if(ai>=nx) ai=nx-1;}
01331 }
01332 aj=step_int((vy-ay-r)*ysp);
01333 bj=step_int((vy-ay+r)*ysp);
01334 if(!yperiodic) {
01335 if(aj<0) {aj=0;if(bj<0) bj=0;}
01336 if(bj>=ny) {bj=ny-1;if(aj>=ny) aj=ny-1;}
01337 }
01338 ak=step_int((vz-az-r)*zsp);
01339 bk=step_int((vz-az+r)*zsp);
01340 if(!zperiodic) {
01341 if(ak<0) {ak=0;if(bk<0) bk=0;}
01342 if(bk>=nz) {bk=nz-1;if(ak>=nz) ak=nz-1;}
01343 }
01344 i=ai;j=aj;k=ak;
01345 aip=ip=step_mod(i,nx);apx=px=step_div(i,nx)*sx;
01346 ajp=jp=step_mod(j,ny);apy=py=step_div(j,ny)*sy;
01347 akp=kp=step_mod(k,nz);apz=pz=step_div(k,nz)*sz;
01348 inc1=aip-step_mod(bi,nx);
01349 inc2=nx*(ny+ajp-step_mod(bj,ny))+inc1;
01350 inc1+=nx;
01351 s=aip+nx*(ajp+ny*akp);
01352 return s;
01353 }
01354
01355
01356
01357
01358
01359 inline int voropp_loop::init(fpoint xmin,fpoint xmax,fpoint ymin,fpoint ymax,fpoint zmin,fpoint zmax,fpoint &px,fpoint &py,fpoint &pz) {
01360 ai=step_int((xmin-ax)*xsp);
01361 bi=step_int((xmax-ax)*xsp);
01362 if(!xperiodic) {
01363 if(ai<0) {ai=0;if(bi<0) bi=0;}
01364 if(bi>=nx) {bi=nx-1;if(ai>=nx) ai=nx-1;}
01365 }
01366 aj=step_int((ymin-ay)*ysp);
01367 bj=step_int((ymax-ay)*ysp);
01368 if(!yperiodic) {
01369 if(aj<0) {aj=0;if(bj<0) bj=0;}
01370 if(bj>=ny) {bj=ny-1;if(aj>=ny) aj=ny-1;}
01371 }
01372 ak=step_int((zmin-az)*zsp);
01373 bk=step_int((zmax-az)*zsp);
01374 if(!zperiodic) {
01375 if(ak<0) {ak=0;if(bk<0) bk=0;}
01376 if(bk>=nz) {bk=nz-1;if(ak>=nz) ak=nz-1;}
01377 }
01378 i=ai;j=aj;k=ak;
01379 aip=ip=step_mod(i,nx);apx=px=step_div(i,nx)*sx;
01380 ajp=jp=step_mod(j,ny);apy=py=step_div(j,ny)*sy;
01381 akp=kp=step_mod(k,nz);apz=pz=step_div(k,nz)*sz;
01382 inc1=aip-step_mod(bi,nx);
01383 inc2=nx*(ny+ajp-step_mod(bj,ny))+inc1;
01384 inc1+=nx;
01385 s=aip+nx*(ajp+ny*akp);
01386 return s;
01387 }
01388
01389
01390
01391 inline int voropp_loop::inc(fpoint &px,fpoint &py,fpoint &pz) {
01392 if(i<bi) {
01393 i++;
01394 if(ip<nx-1) {ip++;s++;} else {ip=0;s+=1-nx;px+=sx;}
01395 return s;
01396 } else if(j<bj) {
01397 i=ai;ip=aip;px=apx;j++;
01398 if(jp<ny-1) {jp++;s+=inc1;} else {jp=0;s+=inc1-nxy;py+=sy;}
01399 return s;
01400 } else if(k<bk) {
01401 i=ai;ip=aip;j=aj;jp=ajp;px=apx;py=apy;k++;
01402 if(kp<nz-1) {kp++;s+=inc2;} else {kp=0;s+=inc2-nxyz;pz+=sz;}
01403 return s;
01404 } else return -1;
01405 }
01406
01407
01408
01409
01410 inline int voropp_loop::step_int(fpoint a) {
01411 return a<0?int(a)-1:int(a);
01412 }
01413
01414
01415 inline int voropp_loop::step_mod(int a,int b) {
01416 return a>=0?a%b:b-1-(b-1-a)%b;
01417 }
01418
01419
01420 inline int voropp_loop::step_div(int a,int b) {
01421 return a>=0?a/b:-1+(a+1)/b;
01422 }
01423
01424
01425
01426 template<class r_option>
01427 void container_base<r_option>::add_wall(wall& w) {
01428 if(wall_number==current_wall_size) {
01429 current_wall_size*=2;
01430 if(current_wall_size>max_wall_size)
01431 voropp_fatal_error("Wall memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
01432 wall **pwall;
01433 pwall=new wall*[current_wall_size];
01434 for(int i=0;i<wall_number;i++) pwall[i]=walls[i];
01435 delete [] walls;walls=pwall;
01436 }
01437 walls[wall_number++]=&w;
01438 }
01439
01440
01441
01442
01443
01444 inline void radius_poly::store_radius(int i,int j,fpoint r) {
01445 cc->p[i][4*j+3]=r;
01446 if(r>max_radius) max_radius=r;
01447 }
01448
01449
01450 inline void radius_poly::clear_max() {
01451 max_radius=0;
01452 }
01453
01454
01455
01456
01457 inline void radius_mono::import(istream &is) {
01458 int n;fpoint x,y,z;
01459 is >> n >> x >> y >> z;
01460 while(!is.eof()) {
01461 cc->put(n,x,y,z);
01462 is >> n >> x >> y >> z;
01463 }
01464 }
01465
01466
01467
01468
01469 inline void radius_poly::import(istream &is) {
01470 int n;fpoint x,y,z,r;
01471 is >> n >> x >> y >> z >> r;
01472 while(!is.eof()) {
01473 cc->put(n,x,y,z,r);
01474 is >> n >> x >> y >> z >> r;
01475 }
01476 }
01477
01478
01479
01480
01481
01482
01483 inline void radius_poly::init(int ijk,int s) {
01484 crad=cc->p[ijk][4*s+3];
01485 mul=1+(crad*crad-max_radius*max_radius)/((max_radius+crad)*(max_radius+crad));
01486 crad*=crad;
01487 }
01488
01489
01490
01491
01492
01493
01494
01495 inline fpoint radius_poly::cutoff(fpoint lrs) {
01496 return mul*lrs;
01497 }
01498
01499
01500
01501
01502
01503
01504 inline fpoint radius_mono::cutoff(fpoint lrs) {
01505 return lrs;
01506 }
01507
01508
01509
01510
01511
01512 inline void radius_mono::rad(ostream &os,int l,int c) {
01513 os << "s";
01514 }
01515
01516
01517
01518
01519
01520 inline void radius_poly::rad(ostream &os,int l,int c) {
01521 os << cc->p[l][4*c+3];
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531 inline fpoint radius_mono::volume(int ijk,int s) {
01532 return 0.125;
01533 }
01534
01535
01536
01537
01538
01539 inline fpoint radius_poly::volume(int ijk,int s) {
01540 fpoint a=cc->p[ijk][4*s+3];
01541 return a*a*a;
01542 }
01543
01544
01545
01546
01547
01548
01549
01550 inline fpoint radius_poly::scale(fpoint rs,int t,int q) {
01551 return rs+crad-cc->p[t][4*q+3]*cc->p[t][4*q+3];
01552 }
01553
01554
01555
01556
01557
01558
01559 inline fpoint radius_mono::scale(fpoint rs,int t,int q) {
01560 return rs;
01561 }
01562
01563
01564
01565
01566
01567 inline void radius_poly::print(ostream &os,int ijk,int q) {
01568 os << " " << cc->p[ijk][4*q+3];
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584 template<class r_option>
01585 inline bool container_base<r_option>::compute_min_max_radius(int di,int dj,int dk,fpoint fx,fpoint fy,fpoint fz,fpoint gxs,fpoint gys,fpoint gzs,fpoint &crs,fpoint mrs) {
01586 fpoint xlo,ylo,zlo;
01587 const fpoint boxx=(bx-ax)/nx,boxy=(by-ay)/ny,boxz=(bz-az)/nz;
01588 const fpoint bxsq=boxx*boxx+boxy*boxy+boxz*boxz;
01589 if(di>0) {
01590 xlo=di*boxx-fx;
01591 crs=xlo*xlo;
01592 if(dj>0) {
01593 ylo=dj*boxy-fy;
01594 crs+=ylo*ylo;
01595 if(dk>0) {
01596 zlo=dk*boxz-fz;
01597 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01598 crs+=bxsq+2*(boxx*xlo+boxy*ylo+boxz*zlo);
01599 } else if(dk<0) {
01600 zlo=(dk+1)*boxz-fz;
01601 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01602 crs+=bxsq+2*(boxx*xlo+boxy*ylo-boxz*zlo);
01603 } else {
01604 if(radius.cutoff(crs)>mrs) return true;
01605 crs+=boxx*(2*xlo+boxx)+boxy*(2*ylo+boxy)+gzs;
01606 }
01607 } else if(dj<0) {
01608 ylo=(dj+1)*boxy-fy;
01609 crs+=ylo*ylo;
01610 if(dk>0) {
01611 zlo=dk*boxz-fz;
01612 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01613 crs+=bxsq+2*(boxx*xlo-boxy*ylo+boxz*zlo);
01614 } else if(dk<0) {
01615 zlo=(dk+1)*boxz-fz;
01616 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01617 crs+=bxsq+2*(boxx*xlo-boxy*ylo-boxz*zlo);
01618 } else {
01619 if(radius.cutoff(crs)>mrs) return true;
01620 crs+=boxx*(2*xlo+boxx)+boxy*(-2*ylo+boxy)+gzs;
01621 }
01622 } else {
01623 if(dk>0) {
01624 zlo=dk*boxz-fz;
01625 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01626 crs+=boxz*(2*zlo+boxz);
01627 } else if(dk<0) {
01628 zlo=(dk+1)*boxz-fz;
01629 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01630 crs+=boxz*(-2*zlo+boxz);
01631 } else {
01632 if(radius.cutoff(crs)>mrs) return true;
01633 crs+=gzs;
01634 }
01635 crs+=gys+boxx*(2*xlo+boxx);
01636 }
01637 } else if(di<0) {
01638 xlo=(di+1)*boxx-fx;
01639 crs=xlo*xlo;
01640 if(dj>0) {
01641 ylo=dj*boxy-fy;
01642 crs+=ylo*ylo;
01643 if(dk>0) {
01644 zlo=dk*boxz-fz;
01645 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01646 crs+=bxsq+2*(-boxx*xlo+boxy*ylo+boxz*zlo);
01647 } else if(dk<0) {
01648 zlo=(dk+1)*boxz-fz;
01649 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01650 crs+=bxsq+2*(-boxx*xlo+boxy*ylo-boxz*zlo);
01651 } else {
01652 if(radius.cutoff(crs)>mrs) return true;
01653 crs+=boxx*(-2*xlo+boxx)+boxy*(2*ylo+boxy)+gzs;
01654 }
01655 } else if(dj<0) {
01656 ylo=(dj+1)*boxy-fy;
01657 crs+=ylo*ylo;
01658 if(dk>0) {
01659 zlo=dk*boxz-fz;
01660 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01661 crs+=bxsq+2*(-boxx*xlo-boxy*ylo+boxz*zlo);
01662 } else if(dk<0) {
01663 zlo=(dk+1)*boxz-fz;
01664 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01665 crs+=bxsq+2*(-boxx*xlo-boxy*ylo-boxz*zlo);
01666 } else {
01667 if(radius.cutoff(crs)>mrs) return true;
01668 crs+=boxx*(-2*xlo+boxx)+boxy*(-2*ylo+boxy)+gzs;
01669 }
01670 } else {
01671 if(dk>0) {
01672 zlo=dk*boxz-fz;
01673 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01674 crs+=boxz*(2*zlo+boxz);
01675 } else if(dk<0) {
01676 zlo=(dk+1)*boxz-fz;
01677 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01678 crs+=boxz*(-2*zlo+boxz);
01679 } else {
01680 if(radius.cutoff(crs)>mrs) return true;
01681 crs+=gzs;
01682 }
01683 crs+=gys+boxx*(-2*xlo+boxx);
01684 }
01685 } else {
01686 if(dj>0) {
01687 ylo=dj*boxy-fy;
01688 crs=ylo*ylo;
01689 if(dk>0) {
01690 zlo=dk*boxz-fz;
01691 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01692 crs+=boxz*(2*zlo+boxz);
01693 } else if(dk<0) {
01694 zlo=(dk+1)*boxz-fz;
01695 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01696 crs+=boxz*(-2*zlo+boxz);
01697 } else {
01698 if(radius.cutoff(crs)>mrs) return true;
01699 crs+=gzs;
01700 }
01701 crs+=boxy*(2*ylo+boxy);
01702 } else if(dj<0) {
01703 ylo=(dj+1)*boxy-fy;
01704 crs=ylo*ylo;
01705 if(dk>0) {
01706 zlo=dk*boxz-fz;
01707 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01708 crs+=boxz*(2*zlo+boxz);
01709 } else if(dk<0) {
01710 zlo=(dk+1)*boxz-fz;
01711 crs+=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01712 crs+=boxz*(-2*zlo+boxz);
01713 } else {
01714 if(radius.cutoff(crs)>mrs) return true;
01715 crs+=gzs;
01716 }
01717 crs+=boxy*(-2*ylo+boxy);
01718 } else {
01719 if(dk>0) {
01720 zlo=dk*boxz-fz;crs=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01721 crs+=boxz*(2*zlo+boxz);
01722 } else if(dk<0) {
01723 zlo=(dk+1)*boxz-fz;crs=zlo*zlo;if(radius.cutoff(crs)>mrs) return true;
01724 crs+=boxz*(-2*zlo+boxz);
01725 } else {
01726 crs=0;
01727 cout << "Can't happen ... happened\n";
01728 }
01729 crs+=gys;
01730 }
01731 crs+=gxs;
01732 }
01733 return false;
01734 }
01735
01736 #include "worklist.cc"