#include "v_base.hh"
#include "config.hh"
namespace voro {
voro_base::voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_) :
nx(nx_), ny(ny_), nz(nz_), nxy(nx_*ny_), nxyz(nxy*nz_), boxx(boxx_), boxy(boxy_), boxz(boxz_),
xsp(1/boxx_), ysp(1/boxy_), zsp(1/boxz_), mrad(new double[wl_hgridcu*wl_seq_length]) {
const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28;
const double xstep=boxx/wl_fgrid,ystep=boxy/wl_fgrid,zstep=boxz/wl_fgrid;
int i,j,k,lx,ly,lz,q;
unsigned int f,*e=const_cast<unsigned int*> (wl);
double xlo,ylo,zlo,xhi,yhi,zhi,minr,*radp=mrad;
for(zlo=0,zhi=zstep,lz=0;lz<wl_hgrid;zlo=zhi,zhi+=zstep,lz++) {
for(ylo=0,yhi=ystep,ly=0;ly<wl_hgrid;ylo=yhi,yhi+=ystep,ly++) {
for(xlo=0,xhi=xstep,lx=0;lx<wl_hgrid;xlo=xhi,xhi+=xstep,lx++) {
minr=large_number;
for(q=e[0]+1;q<wl_seq_length;q++) {
f=e[q];
i=(f&127)-64;
j=(f>>7&127)-64;
k=(f>>14&127)-64;
if((f&b2)==b2) {
compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i-1,j,k);
if((f&b1)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
} else if((f&b1)==b1) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k);
if((f&b4)==b4) {
compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j-1,k);
if((f&b3)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
} else if((f&b3)==b3) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k);
if((f&b6)==b6) {
compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k-1);
if((f&b5)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
} else if((f&b5)==b5) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1);
}
q--;
while(q>0) {
radp[q]=minr;
f=e[q];
i=(f&127)-64;
j=(f>>7&127)-64;
k=(f>>14&127)-64;
compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k);
q--;
}
*radp=minr;
e+=wl_seq_length;
radp+=wl_seq_length;
}
}
}
}
void voro_base::compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk) {
double radsq,temp;
if(ti>0) {temp=boxx*ti-xhi;radsq=temp*temp;}
else if(ti<0) {temp=xlo-boxx*(1+ti);radsq=temp*temp;}
else radsq=0;
if(tj>0) {temp=boxy*tj-yhi;radsq+=temp*temp;}
else if(tj<0) {temp=ylo-boxy*(1+tj);radsq+=temp*temp;}
if(tk>0) {temp=boxz*tk-zhi;radsq+=temp*temp;}
else if(tk<0) {temp=zlo-boxz*(1+tk);radsq+=temp*temp;}
if(radsq<minr) minr=radsq;
}
bool voro_base::contains_neighbor(const char *format) {
char *fmp=(const_cast<char*>(format));
while(*fmp!=0) {
if(*fmp=='%') {
fmp++;
if(*fmp=='n') return true;
else if(*fmp==0) return false;
}
fmp++;
}
return false;
}
#include "v_base_wl.cc"
}