renamed src to source

This commit is contained in:
Paul M. Sutter 2024-05-22 16:15:14 -04:00
parent 4dcaf3959b
commit 4d9c5ab2c1
71 changed files with 7 additions and 3 deletions

View file

@ -0,0 +1,16 @@
add_executable(voz1b1 voz1b1.c readfiles.c vozutil.c voz.h)
target_link_libraries(voz1b1 ${QHULL_LIBRARY} ${MATH_LIB})
#add_executable(jozov jozov.c findrtop.c)
#target_link_libraries(jozov ${MATH_LIB})
add_executable(vozinit vozinit.c readfiles.c)
target_link_libraries(vozinit ${MATH_LIB})
add_executable(voztie voztie.c readfiles.c)
target_link_libraries(voztie ${MATH_LIB})
install(TARGETS voz1b1 vozinit voztie DESTINATION ${VIDE_BIN})

81
c_source/zobov/findrtop.c Normal file
View file

@ -0,0 +1,81 @@
#include <math.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Find nb elements of Real array a having the largest value.
Returns index iord of these elements, ordered so iord[0] corresponds
to element a[iord[0]] having the largest value.
If nb > na, then the last nb-na elements of iord are undefined.
Elements of a that are equal are left in their original order.
Courtesy Andrew Hamilton.
*/
void findrtop(double *a, int na, int *iord, int nb)
{
#undef ORDER
#define ORDER(ia, ja) a[ia] > a[ja] || (a[ia] == a[ja] && ia < ja)
int i, ia, ib, it, n;
n = (na <= nb)? na : nb;
if (n <= 0) return;
/* heap first n elements, so smallest element is at top of heap */
for (ib = (n >> 1); ib < n; ib++) {
iord[ib] = ib;
}
for (ia = (n >> 1) - 1; ia >= 0; ia--) {
i = ia;
for (ib = (i << 1) + 1; ib < n; ib = (i << 1) + 1) {
if (ib+1 < n) {
if (ORDER(iord[ib], iord[ib+1])) ib++;
}
if (ORDER(ia, iord[ib])) {
iord[i] = iord[ib];
i = ib;
} else {
break;
}
}
iord[i] = ia;
}
/* now compare rest of elements of array to heap */
for (ia = n; ia < na; ia++) {
/* if new element is greater than smallest, sift it into heap */
i = 0;
if (ORDER(ia, iord[i])) {
for (ib = (i << 1) + 1; ib < n; ib = (i << 1) + 1) {
if (ib+1 < n) {
if (ORDER(iord[ib], iord[ib+1])) ib++;
}
if (ORDER(ia, iord[ib])) {
iord[i] = iord[ib];
i = ib;
} else {
break;
}
}
iord[i] = ia;
}
}
/* unheap iord so largest element is at top */
for (ia = n - 1; ia > 0; ia--) {
it = iord[ia];
i = 0;
iord[ia] = iord[i];
for (ib = (i << 1) + 1; ib < ia; ib = (i << 1) + 1) {
if (ib+1 < ia) {
if (ORDER(iord[ib], iord[ib+1])) ib++;
}
if (ORDER(it, iord[ib])) {
iord[i] = iord[ib];
i = ib;
} else {
break;
}
}
iord[i] = it;
}
}

580
c_source/zobov/jozov.c Normal file
View file

@ -0,0 +1,580 @@
#include <assert.h>
/* jovoz.c by Mark Neyrinck */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define BIGFLT 1e30 /* Biggest possible floating-point number */
#define NLINKS 1000 /* Number of possible links with the same rho_sl */
#define FF fflush(stdout)
typedef struct Particle {
float dens;
int nadj;
int ncnt;
int *adj;
} PARTICLE;
typedef struct Zone {
int core; /* Identity of peak particle */
int np; /* Number of particles in zone */
int npjoin; /* Number of particles in the joined void */
int nadj; /* Number of adjacent zones */
int nhl; /* Number of zones in final joined void */
float leak; /* Volume of last leak zone*/
int *adj; /* Each adjacent zone, with ... */
float *slv; /* Smallest Linking Volume */
float denscontrast; /* density contrast */
double vol; /* Total volume of all particles in the zone */
double voljoin; /* Total volume of all particles in the joined void */
} ZONE;
typedef struct ZoneT {
int nadj; /* Number of zones on border */
int *adj; /* Each adjacent zone, with ... */
float *slv; /* Smallest Linking Volume */
} ZONET;
void findrtop(double *a, int na, int *iord, int nb);
int main(int argc,char **argv) {
FILE *adj, *vol, *zon, *zon2, *txt;
PARTICLE *p;
ZONE *z;
ZONET *zt;
char *adjfile, *volfile, *zonfile, *zonfile2, *txtfile;
int i, j,k,l, h, h2,hl,n,np, np2, nzones, nhl, nhlcount, nhl2;
int *jumper, *jumped, *numinh;
int *zonenum, *zonelist, *zonelist2;
int link[NLINKS], link2, nl;
float lowvol, voltol, prob;
int q,q2;
int za, nin;
int testpart;
char already, interior, *inyet, *inyet2, added, beaten;
int *nm, **m;
float maxvol, minvol;
double *sorter, e1,maxdenscontrast;
int *iord;
int mockIndex;
e1 = exp(1.)-1.;
if (argc != 8) {
printf("Wrong number of arguments.\n");
printf("arg1: adjacency file\n");
printf("arg2: volume file\n");
printf("arg3: output file containing particles in each zone\n");
printf("arg4: output file containing zones in each void\n");
printf("arg5: output text file\n");
printf("arg6: Density threshold (0 for no threshold)\n");
printf("arg7: Beginning index of mock galaxies\n\n");
exit(0);
}
adjfile = argv[1];
volfile = argv[2];
zonfile = argv[3];
zonfile2 = argv[4];
txtfile = argv[5];
if (sscanf(argv[6],"%f",&voltol) == 0) {
printf("Bad density threshold.\n");
exit(0);
}
if (sscanf(argv[7],"%d",&mockIndex) == 0) {
printf("Bad mock galaxy index.\n");
exit(0);
}
printf("TOLERANCE: %f\n", voltol);
if (voltol <= 0.) {
printf("Proceeding without a density threshold.\n");
voltol = 1e30;
}
adj = fopen(adjfile, "r");
if (adj == NULL) {
printf("Unable to open %s\n",adjfile);
exit(0);
}
fread(&np,1, sizeof(int),adj);
if (mockIndex < 0)
mockIndex = np;
printf("adj: %d particles\n", np);
FF;
p = (PARTICLE *)malloc(np*sizeof(PARTICLE));
/* Adjacencies*/
for (i=0;i<np;i++) {
fread(&p[i].nadj,1,sizeof(pid_t),adj);
/* The number of adjacencies per particle */
if (p[i].nadj > 0)
p[i].adj = (pid_t *)malloc(p[i].nadj*sizeof(pid_t));
else p[i].adj = 0;
p[i].ncnt = 0; /* Temporarily, it's an adj counter */
}
for (i=0;i<np;i++) {
fread(&nin,1,sizeof(pid_t),adj);
if (nin > 0)
for (k=0;k<nin;k++) {
fread(&j,1,sizeof(pid_t),adj);
if (j < np) {
/* Set both halves of the pair */
assert(i < j);
if (p[i].ncnt == p[i].nadj)
{
int q;
printf("OVERFLOW for particle %d (pending %d). List of accepted:\n", i, j);
for (q=0;q<p[i].nadj;q++)
printf(" %d\n", p[i].adj[q]);
//abort();
}
if (p[j].ncnt == p[j].nadj)
{
int q;
printf("OVERFLOW for particle %d (pending %d). List of accepted:\n", j, i);
for (q=0;q<p[j].nadj;q++)
printf(" %d\n", p[j].adj[q]);
//abort();
}
p[i].adj[p[i].ncnt] = j;
p[j].adj[p[j].ncnt] = i;
p[i].ncnt++; p[j].ncnt++;
} else {
printf("%d: adj = %d\n",i,j);
}
}
}
fclose(adj);
/* Check that we got all the pairs */
/* adj = fopen(adjfile, "r");
fread(&np,1, sizeof(int),adj);*/
for (i=0;i<np;i++) {
/* fread(&nin,1,sizeof(int),adj); /* actually nadj */
// PMS
if (p[i].ncnt != p[i].nadj && i < mockIndex) {
/*if (p[i].ncnt != p[i].nadj) {*/
// END PMS
p[i].nadj = p[i].ncnt;
printf("We didn't get all of %d's adj's; %d != %d.\n",i,nin,p[i].nadj);
/*exit(0);*/
}
}
// fclose(adj);
/* Volumes */
vol = fopen(volfile, "r");
if (vol == NULL) {
printf("Unable to open volume file %s.\n\n",volfile);
exit(0);
}
fread(&np2,1, sizeof(int),adj);
if (np != np2) {
printf("Number of particles doesn't match! %d != %d\n",np,np2);
exit(0);
}
printf("%d particles\n", np);
FF;
for (i=0;i<np;i++) {
fread(&p[i].dens,1,sizeof(float),vol);
// PMS
if ((p[i].dens < 1e-30) || (p[i].dens > 1e30) && i < mockIndex) {
//if ((p[i].dens < 1e-30) || (p[i].dens > 1e30)) {
// END PMS
printf("Whacked-out volume found, of particle %d: %f\n",i,p[i].dens);
p[i].dens = 1.;
}
p[i].dens = 1./p[i].dens; /* Get density from volume */
}
fclose(vol);
jumped = (pid_t *)malloc(np*sizeof(pid_t));
jumper = (pid_t *)malloc(np*sizeof(pid_t));
numinh = (pid_t *)malloc(np*sizeof(pid_t));
/* find jumper */
for (i = 0; i < np; i++) {
minvol = p[i].dens; jumper[i] = -1;
for (j=0; j< p[i].nadj; j++) {
if (p[p[i].adj[j]].dens < minvol) {
jumper[i] = p[i].adj[j];
minvol = p[jumper[i]].dens;
}
}
numinh[i] = 0;
}
printf("About to jump ...\n"); FF;
/* Jump */
for (i = 0; i < np; i++) {
jumped[i] = i;
while (jumper[jumped[i]] > -1)
jumped[i] = jumper[jumped[i]];
numinh[jumped[i]]++;
}
printf("Post-jump ...\n"); FF;
nzones = 0;
for (i = 0; i < np; i++)
if (numinh[i] > 0) nzones++;
printf("%d initial zones found\n", nzones);
z = (ZONE *)malloc(nzones*sizeof(ZONE));
if (z == NULL) {
printf("Unable to allocate z\n");
exit(0);
}
zt = (ZONET *)malloc(nzones*sizeof(ZONET));
if (zt == NULL) {
printf("Unable to allocate zt\n");
exit(0);
}
zonenum = (int *)malloc(np*sizeof(int));
if (zonenum == NULL) {
printf("Unable to allocate zonenum\n");
exit(0);
}
h = 0;
for (i = 0; i < np; i++)
if (numinh[i] > 0) {
z[h].core = i;
zonenum[i] = h;
h++;
} else {
zonenum[i] = -1;
}
/* Count border particles */
for (i = 0; i < np; i++)
for (j = 0; j < p[i].nadj; j++) {
testpart = p[i].adj[j];
if (jumped[i] != jumped[testpart])
zt[zonenum[jumped[i]]].nadj++;
}
for (h=0;h<nzones;h++) {
zt[h].adj = (pid_t *)malloc(zt[h].nadj*sizeof(pid_t));
if (zt[h].adj == NULL) {
printf("Unable to allocate %d adj's of zone %d\n",zt[h].nadj,h);
exit(0);
}
zt[h].slv = (float *)malloc(zt[h].nadj*sizeof(float));
if (zt[h].slv == NULL) {
printf("Unable to allocate %d slv's of zone %d\n",zt[h].nadj,h);
exit(0);
}
zt[h].nadj = 0;
}
/* Find "weakest links" */
for (i = 0; i < np; i++) {
h = zonenum[jumped[i]];
for (j = 0; j < p[i].nadj; j++) {
testpart = p[i].adj[j];
if (h != zonenum[jumped[testpart]]) {
if (p[testpart].dens > p[i].dens) {
/* there could be a weakest link through testpart */
already = 0;
for (za = 0; za < zt[h].nadj; za++)
if (zt[h].adj[za] == zonenum[jumped[testpart]]) {
already = 1;
if (p[testpart].dens < zt[h].slv[za]) {
zt[h].slv[za] = p[testpart].dens;
}
}
if (already == 0) {
zt[h].adj[zt[h].nadj] = zonenum[jumped[testpart]];
zt[h].slv[zt[h].nadj] = p[testpart].dens;
zt[h].nadj++;
}
} else { /* There could be a weakest link through i */
already = 0;
for (za = 0; za < zt[h].nadj; za++)
if (zt[h].adj[za] == zonenum[jumped[testpart]]) {
already = 1;
if (p[i].dens < zt[h].slv[za]) {
zt[h].slv[za] = p[i].dens;
}
}
if (already == 0) {
zt[h].adj[zt[h].nadj] = zonenum[jumped[testpart]];
zt[h].slv[zt[h].nadj] = p[i].dens;
zt[h].nadj++;
}
}
}
}
}
printf("Found zone adjacencies\n"); FF;
/* Free particle adjacencies */
for (i=0;i<np; i++) if (p[i].adj != 0) free(p[i].adj);
/* Use z instead of zt */
for (h=0;h<nzones;h++) {
/*printf("%d ",zt[h].nadj);*/
z[h].nadj = zt[h].nadj;
z[h].adj = (pid_t *)malloc(zt[h].nadj*sizeof(pid_t));
z[h].slv = (float *)malloc(zt[h].nadj*sizeof(float));
for (za = 0; za<zt[h].nadj; za++) {
z[h].adj[za] = zt[h].adj[za];
z[h].slv[za] = zt[h].slv[za];
}
free(zt[h].adj);
free(zt[h].slv);
z[h].np = numinh[z[h].core];
}
free(zt);
free(numinh);
m = (pid_t **)malloc(nzones*sizeof(pid_t *));
/* Not in the zone struct since it'll be freed up (contiguously, we hope)
soon */
nm = (pid_t *)malloc(nzones*sizeof(pid_t));
for (h=0; h<nzones; h++) {
m[h] = (pid_t *)malloc(z[h].np*sizeof(pid_t));
nm[h] = 0;
z[h].vol = 0.;
}
for (i=0; i<np; i++) {
h = zonenum[jumped[i]];
if (i == z[h].core) {
m[h][nm[h]] = m[h][0];
m[h][0] = i; /* Put the core particle at the top of the list */
} else {
m[h][nm[h]] = i;
}
z[h].vol += 1.0/(double)p[i].dens;
nm[h] ++;
}
free(nm);
zon = fopen(zonfile,"w");
if (zon == NULL) {
printf("Problem opening zonefile %s.\n\n",zonfile);
exit(0);
}
fwrite(&np,1,sizeof(pid_t),zon);
fwrite(&nzones,1,sizeof(int),zon);
for (h=0; h<nzones; h++) {
// PMS
//printf("%d %d %d", &(z[h].np), m[h], z[h].np);
// END PMS
fwrite(&(z[h].np),1,sizeof(pid_t),zon);
fwrite(m[h],z[h].np,sizeof(pid_t),zon);
free(m[h]);
}
free(m);
close(zon);
inyet = (char *)malloc(nzones*sizeof(char));
inyet2 = (char *)malloc(nzones*sizeof(char));
zonelist = (int *)malloc(nzones*sizeof(int));
zonelist2 = (int *)malloc(nzones*sizeof(int));
sorter = (double *)malloc((nzones+1)*sizeof(double));
for (h = 0; h< nzones; h++) {
inyet[h] = 0;
inyet2[h] = 0;
}
nhl = 0;
maxvol = 0.;
minvol = BIGFLT;
maxdenscontrast = 0.;
for(i=0;i<np; i++){
if (p[i].dens > maxvol) maxvol = p[i].dens;
if (p[i].dens < minvol) minvol = p[i].dens;
}
printf("Densities range from %e to %e.\n",minvol,maxvol);FF;
zon2 = fopen(zonfile2,"w");
if (zon2 == NULL) {
printf("Problem opening zonefile %s.\n\n",zonfile2);
exit(0);
}
fwrite(&nzones,1,sizeof(int),zon2);
for (h = 0; h<nzones; h++) {
nhlcount = 0;
for (hl = 0; hl < nhl; hl++)
inyet[zonelist[hl]] = 0;
zonelist[0] = h;
inyet[h] = 1;
nhl = 1;
z[h].npjoin = z[h].np;
do {
/* Find the lowest-volume (highest-density) adjacency */
lowvol = BIGFLT; nl = 0; beaten = 0;
for (hl = 0; hl < nhl; hl++) {
h2 = zonelist[hl];
if (inyet[h2] == 1) { /* If it's not already identified as
an interior zone, with inyet=2 */
interior = 1;
for (za = 0; za < z[h2].nadj; za ++) {
if (inyet[z[h2].adj[za]] == 0) {
interior = 0;
if (z[h2].slv[za] == lowvol) {
link[nl] = z[h2].adj[za];
nl ++;
if (nl == NLINKS) {
printf("Too many links with the same rho_sl! Increase NLINKS from %d\n",nl);
exit(0);
}
}
if (z[h2].slv[za] < lowvol) {
lowvol = z[h2].slv[za];
link[0] = z[h2].adj[za];
nl = 1;
}
}
}
if (interior == 1) inyet[h2] = 2; /* No bordering exter. zones */
}
}
if (nl == 0) {
beaten = 1;
z[h].leak = maxvol;
continue;
}
if (lowvol > voltol) {
beaten = 1;
z[h].leak = lowvol;
continue;
}
for (l=0; l < nl; l++)
if (p[z[link[l]].core].dens < p[z[h].core].dens)
beaten = 1;
if (beaten == 1) {
z[h].leak = lowvol;
continue;
}
/* Add everything linked to the link(s) */
nhl2 = 0;
for (l=0; l < nl; l++) {
if (inyet2[link[l]] == 0) {
zonelist2[nhl2] = link[l];
inyet2[link[l]] = 1;
nhl2 ++;
added = 1;
while ((added == 1) && (beaten == 0)) {
added = 0;
for (hl = 0; (hl < nhl2) && (beaten == 0); hl++) {
h2 = zonelist2[hl];
if (inyet2[h2] == 1) {
interior = 1; /* Guilty until proven innocent */
for (za = 0; za < z[h2].nadj; za ++) {
link2 = z[h2].adj[za];
if ((inyet[link2]+inyet2[link2]) == 0) {
interior = 0;
if (z[h2].slv[za] <= lowvol) {
if (p[z[link2].core].dens < p[z[h].core].dens) {
beaten = 1;
break;
}
zonelist2[nhl2] = link2;
inyet2[link2] = 1;
nhl2++;
added = 1;
}
}
}
if (interior == 1) inyet2[h2] = 2;
}
}
}
}
}
for (hl = 0; hl < nhl2; hl++)
inyet2[zonelist2[hl]] = 0;
/* See if there's a beater */
if (beaten == 1) {
z[h].leak = lowvol;
} else {
for (h2 = 0; h2 < nhl2; h2++) {
zonelist[nhl] = zonelist2[h2];
inyet[zonelist2[h2]] = 1;
nhl++;
z[h].npjoin += z[zonelist2[h2]].np;
}
}
if (nhl/10000 > nhlcount) {
nhlcount = nhl/10000;
printf(" %d",nhl); FF;
}
} while((lowvol < BIGFLT) && (beaten == 0));
z[h].denscontrast = z[h].leak/p[z[h].core].dens;
if (z[h].denscontrast < 1.) z[h].denscontrast = 1.;
/* find biggest denscontrast */
if (z[h].denscontrast > maxdenscontrast) {
maxdenscontrast = (double)z[h].denscontrast;
}
/* Don't sort; want the core zone to be first */
if (nhlcount > 0) { /* Outputs the number of zones in large voids */
printf(" h%d:%d\n",h,nhl);
FF;
}
/* Calculate volume */
z[h].voljoin = 0.;
for (q = 0; q<nhl; q++) {
z[h].voljoin += z[zonelist[q]].vol;
}
z[h].nhl = nhl;
fwrite(&nhl,1,sizeof(int),zon2);
fwrite(zonelist,nhl,sizeof(int),zon2);
}
fclose(zon2);
printf("Maxdenscontrast = %f.\n",maxdenscontrast);
/* Assign sorter by probability (could use volume instead) */
for (h=0; h< nzones; h++)
sorter[h] = (double)z[h].denscontrast;
/* Text output file */
printf("about to sort ...\n");FF;
iord = (int *)malloc(nzones*sizeof(int));
findrtop(sorter, nzones, iord, nzones);
txt = fopen(txtfile,"w");
fprintf(txt,"%d particles, %d voids.\n", np, nzones);
fprintf(txt,"Void# FileVoid# CoreParticle CoreDens ZoneVol Zone#Part Void#Zones VoidVol Void#Part VoidDensContrast VoidProb\n");
for (h=0; h<nzones; h++) {
i = iord[h];
prob = exp(-5.12*(z[i].denscontrast-1.) - 0.8*pow(z[i].denscontrast-1.,2.8));
// PMS
if (z[i].np == 1) continue;
// END PMS
fprintf(txt,"%d %d %d %e %e %d %d %e %d %f %6.2e\n",
h+1, i, z[i].core, p[z[i].core].dens, z[i].vol, z[i].np, z[i].nhl, z[i].voljoin, z[i].npjoin, z[i].denscontrast, prob);
} /* h+1 to start from 1, not zero */
fclose(txt);
printf("Done!\n");FF;
return(0);
}

121
c_source/zobov/readfiles.c Normal file
View file

@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#define DL for (d=0;d<3;d++) /* Dimension loop */
#define BF 1e30
/* Positions */
/* Returns number of particles read */
int posread(char *posfile, float ***p, float fact) {
FILE *pos;
int np,dum,d,i;
float xmin,xmax,ymin,ymax,zmin,zmax;
float *ptemp;
pos = fopen(posfile, "r");
if (pos == NULL) {
printf("Unable to open position file %s\n\n",posfile);
exit(0);
}
/* Fortran77 4-byte headers and footers */
/* Delete "dum" statements if you don't need them */
/* Read number of particles */
fread(&dum,1,4,pos); fread(&np,1, sizeof(int),pos); fread(&dum,1,4,pos);
/* Allocate the arrays */
(*p) = (float **)malloc(np*sizeof(float *));
ptemp = (float *)malloc(np*sizeof(float));
printf("np = %d\n",np);
/* Fill the arrays */
fread(&dum,1,4,pos);
fread(ptemp,np,4,pos);
for (i=0; i<np; i++) {
(*p)[i] = (float *)malloc(3*sizeof(float));
if ((*p)[i] == NULL) {
printf("Unable to allocate particle array in readfiles!\n");
fflush(stdout);
exit(0);
}
(*p)[i][0] = ptemp[i];
}
fread(&dum,1,4,pos);
fread(&dum,1,4,pos);
fread(ptemp,np,4,pos);
for (i=0; i<np; i++) (*p)[i][1] = ptemp[i];
fread(&dum,1,4,pos);
fread(&dum,1,4,pos);
fread(ptemp,np,4,pos);
for (i=0; i<np; i++) (*p)[i][2] = ptemp[i];
fread(&dum,1,4,pos);
fclose(pos);
free(ptemp);
/* Get into physical units (Mpc/h) */
printf("%f\n",fact);fflush(stdout);
for (i=0; i<np; i++) DL (*p)[i][d] *= fact;
/* Test range -- can comment out */
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=0; i<np;i++) {
if ((*p)[i][0]<xmin) xmin = (*p)[i][0]; if ((*p)[i][0]>xmax) xmax = (*p)[i][0];
if ((*p)[i][1]<ymin) ymin = (*p)[i][1]; if ((*p)[i][1]>ymax) ymax = (*p)[i][1];
if ((*p)[i][2]<zmin) zmin = (*p)[i][2]; if ((*p)[i][2]>zmax) zmax = (*p)[i][2];
}
printf("np: %d, x: %f,%f; y: %f,%f; z: %f,%f\n",np,xmin,xmax, ymin,ymax, zmin,zmax); fflush(stdout);
return(np);
}
/* Velocities */
/* Returns number of particles read */
/* Used in voboz, but not zobov, which doesn't use velocities */
int velread(char *velfile, float ***v, float fact) {
FILE *vel;
int np,dum,d,i;
float xmin,xmax,ymin,ymax,zmin,zmax;
vel = fopen(velfile, "r");
if (vel == NULL) {
printf("Unable to open velocity file %s\n\n",velfile);
exit(0);
}
/* Fortran77 4-byte headers and footers */
/* Delete "dum" statements if you don't need them */
/* Read number of particles */
fread(&dum,1,4,vel); fread(&np,1, sizeof(int),vel); fread(&dum,1,4,vel);
/* Allocate the arrays */
(*v) = (float **)malloc(3*sizeof(float*));
for (i=0;i<3;i++) (*v)[i] = (float *)malloc(np*sizeof(float));
/* Fill the arrays */
fread(&dum,1,4,vel); fread((*v)[0],np,4,vel); fread(&dum,1,4,vel);
fread(&dum,1,4,vel); fread((*v)[1],np,4,vel); fread(&dum,1,4,vel);
fread(&dum,1,4,vel); fread((*v)[2],np,4,vel); fread(&dum,1,4,vel);
fclose(vel);
/* Convert from code units into physical units (km/sec) */
for (i=0; i<np; i++) DL (*v)[d][i] *= fact;
/* Test range -- can comment out */
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=0; i<np;i++) {
if ((*v)[0][i] < xmin) xmin = (*v)[0][i]; if ((*v)[0][i] > xmax) xmax = (*v)[0][i];
if ((*v)[1][i] < ymin) ymin = (*v)[1][i]; if ((*v)[1][i] > ymax) ymax = (*v)[1][i];
if ((*v)[2][i] < zmin) zmin = (*v)[2][i]; if ((*v)[2][i] > zmax) zmax = (*v)[2][i];
}
printf("vx: %f,%f; vy: %f,%f; vz: %f,%f\n",xmin,xmax, ymin,ymax, zmin,zmax);
return(np);
}

11
c_source/zobov/voz.h Normal file
View file

@ -0,0 +1,11 @@
#define MAXVERVER 100000
#define NGUARD 84 /*Actually, the number of SPACES between guard points
##define NGUARD 42 /*Actually, the number of SPACES between guard points
in each dim */
typedef int pid_t;
typedef struct Partadj {
pid_t nadj;
pid_t *adj;
} PARTADJ;

352
c_source/zobov/voz1b1.c Normal file
View file

@ -0,0 +1,352 @@
#include "libqhull/qhull_a.h"
#include "voz.h"
#define DL for (d=0;d<3;d++)
#define BF 1e30
#define MAX(a,b) ( ((a) < (b)) ? (a) : (b) )
int delaunadj (coordT *points, int nvp, int nvpbuf, int nvpall, PARTADJ **adjs);
int vorvol (coordT *deladjs, coordT *points, pointT *intpoints, int numpoints, float *vol);
int posread(char *posfile, float ***p, float fact);
int main(int argc, char *argv[]) {
int exitcode;
pid_t i, j, np;
float **r;
coordT rtemp[3], *parts;
coordT deladjs[3*MAXVERVER], points[3*MAXVERVER];
pointT intpoints[3*MAXVERVER];
FILE *pos, *out;
char *posfile, outfile[200], *suffix, *outDir;
PARTADJ *adjs;
float *vols;
realT predict, xmin,xmax,ymin,ymax,zmin,zmax;
pid_t *orig;
int isitinbuf;
char isitinmain, d;
int numdiv;
pid_t nvp, nvpall, nvpbuf;
realT width, width2, totwidth, totwidth2, bf, s, g;
float border, boxsize;
realT c[3];
int b[3];
double totalvol;
if (argc != 10) {
printf("Wrong number of arguments.\n");
printf("arg1: position file\n");
printf("arg2: border size\n");
printf("arg3: boxsize\n");
printf("arg4: suffix\n");
printf("arg5: number of divisions\n");
printf("arg6-8: b[0-2]\n\n");
printf("arg9: output directory\n");
exit(0);
}
posfile = argv[1];
if (sscanf(argv[2],"%f",&border) != 1) {
printf("That's no border size; try again.\n");
exit(0);
}
if (sscanf(argv[3],"%f",&boxsize) != 1) {
printf("That's no boxsize; try again.\n");
exit(0);
}
suffix = argv[4];
if (sscanf(argv[5],"%d",&numdiv) != 1) {
printf("%s is no number of divisions; try again.\n",argv[5]);
exit(0);
}
if (numdiv == 1) {
printf("Only using one division; should only use for an isolated segment.\n");
}
if (numdiv < 1) {
printf("Cannot have a number of divisions less than 1. Resetting to 1.\n");
numdiv = 1;
}
if (sscanf(argv[6],"%d",&b[0]) != 1) {
printf("That's no b index; try again.\n");
exit(0);
}
if (sscanf(argv[7],"%d",&b[1]) != 1) {
printf("That's no b index; try again.\n");
exit(0);
}
if (sscanf(argv[8],"%d",&b[2]) != 1) {
printf("That's no b index; try again.\n");
exit(0);
}
outDir = argv[9];
/* Boxsize should be the range in r, yielding a range 0-1 */
np = posread(posfile,&r,1./boxsize);
printf("%d particles\n",np);fflush(stdout);
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=0; i<np;i++) {
if (r[i][0]<xmin) xmin = r[i][0]; if (r[i][0]>xmax) xmax = r[i][0];
if (r[i][1]<ymin) ymin = r[i][1]; if (r[i][1]>ymax) ymax = r[i][1];
if (r[i][2]<zmin) zmin = r[i][2]; if (r[i][2]>zmax) zmax = r[i][2];
}
printf("np: %d, x: %f,%f; y: %f,%f; z: %f,%f\n",np,xmin,xmax, ymin,ymax, zmin,zmax); fflush(stdout);
width = 1./(float)numdiv;
width2 = 0.5*width;
if (border > 0.) bf = border;
else bf = 0.1;
/* In units of 0-1, the thickness of each subregion's buffer*/
totwidth = width+2.*bf;
totwidth2 = width2 + bf;
s = width/(float)NGUARD;
if ((bf*bf - 2.*s*s) < 0.) {
printf("bf = %f, s = %f.\n",bf,s);
printf("Not enough guard points for given border.\nIncrease guards to >= %f\n.",
sqrt(2.)*width/bf);
exit(0);
}
g = (bf / 2.)*(1. + sqrt(1 - 2.*s*s/(bf*bf)));
printf("s = %f, bf = %f, g = %f.\n",s,bf,g);
fflush(stdout);
adjs = (PARTADJ *)malloc(np*sizeof(PARTADJ));
if (adjs == NULL) {
printf("Unable to allocate adjs\n");
exit(1);
}
DL c[d] = ((float)b[d])*width;
printf("c: %f,%f,%f\n",c[0],c[1],c[2]);
/* Assign temporary array*/
nvpbuf = 0; /* Number of particles to tesselate, including
buffer */
nvp = 0; /* Without the buffer */
for (i=0; i<np; i++) {
isitinbuf = 1;
isitinmain = 1;
DL {
rtemp[d] = (double)r[i][d] - (double)c[d];
if (rtemp[d] > 0.5) rtemp[d] --;
if (rtemp[d] < -0.5) rtemp[d] ++;
isitinbuf = isitinbuf && (fabs(rtemp[d]) < totwidth2);
isitinmain = isitinmain && (fabs(rtemp[d]) <= width2);
}
if (isitinbuf) nvpbuf++;
if (isitinmain) nvp++;
}
nvpbuf += 6*(NGUARD+1)*(NGUARD+1); /* number of guard
points */
parts = (coordT *)malloc(3*nvpbuf*sizeof(coordT));
orig = (pid_t *)malloc(nvpbuf*sizeof(pid_t));
if (parts == NULL) {
printf("Unable to allocate parts\n");
fflush(stdout);
exit(1);
}
if (orig == NULL) {
printf("Unable to allocate orig\n");
fflush(stdout);
exit(1);
}
nvp = 0; nvpall = 0; /* nvp = number of particles without buffer */
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=0; i<np; i++) {
isitinmain = 1;
DL {
rtemp[d] = (realT)r[i][d] - (realT)c[d];
if (rtemp[d] > 0.5) rtemp[d] --;
if (rtemp[d] < -0.5) rtemp[d] ++;
isitinmain = isitinmain && (fabs(rtemp[d]) <= width2);
}
if (isitinmain) {
parts[3*nvp] = rtemp[0];
parts[3*nvp+1] = rtemp[1];
parts[3*nvp+2] = rtemp[2];
orig[nvp] = i;
nvp++;
if (rtemp[0] < xmin) xmin = rtemp[0];
if (rtemp[0] > xmax) xmax = rtemp[0];
if (rtemp[1] < ymin) ymin = rtemp[1];
if (rtemp[1] > ymax) ymax = rtemp[1];
if (rtemp[2] < zmin) zmin = rtemp[2];
if (rtemp[2] > zmax) zmax = rtemp[2];
}
}
printf("nvp = %d\n",nvp);
printf("x: %f,%f; y: %f,%f; z:%f,%f\n",xmin,xmax,ymin,ymax,zmin,zmax);
nvpbuf = nvp;
for (i=0; i<np; i++) {
isitinbuf = 1;
isitinmain = 1;
DL {
rtemp[d] = (realT)r[i][d] - (realT)c[d];
if (rtemp[d] > 0.5) rtemp[d] --;
if (rtemp[d] < -0.5) rtemp[d] ++;
isitinbuf = isitinbuf && (fabs(rtemp[d])<totwidth2);
isitinmain = isitinmain && (fabs(rtemp[d]) <= width2);
}
if (isitinbuf && !isitinmain) {
/*printf("%3.3f ",sqrt(rtemp[0]*rtemp[0] + rtemp[1]*rtemp[1] +
rtemp[2]*rtemp[2]));
printf("|%2.2f,%2.2f,%2.2f,%f,%f",r[i][0],r[i][1],r[i][2],width2,totwidth2);*/
parts[3*nvpbuf] = rtemp[0];
parts[3*nvpbuf+1] = rtemp[1];
parts[3*nvpbuf+2] = rtemp[2];
orig[nvpbuf] = i;
nvpbuf++;
if (rtemp[0] < xmin) xmin = rtemp[0];
if (rtemp[0] > xmax) xmax = rtemp[0];
if (rtemp[1] < ymin) ymin = rtemp[1];
if (rtemp[1] > ymax) ymax = rtemp[1];
if (rtemp[2] < zmin) zmin = rtemp[2];
if (rtemp[2] > zmax) zmax = rtemp[2];
}
}
printf("nvpbuf = %d\n",nvpbuf);
printf("x: %f,%f; y: %f,%f; z:%f,%f\n",xmin,xmax,ymin,ymax,zmin,zmax);
nvpall = nvpbuf;
predict = pow(width+2.*bf,3)*(float)np;
printf("There should be ~ %f points; there are %d\n",predict,nvpbuf);
for (i=0;i<np;i++) free(r[i]);
free(r);
/* Add guard points */
for (i=0; i<NGUARD+1; i++) {
for (j=0; j<NGUARD+1; j++) {
/* Bottom */
parts[3*nvpall] = -width2 + (realT)i * s;
parts[3*nvpall+1] = -width2 + (realT)j * s;
parts[3*nvpall+2] = -width2 - g;
nvpall++;
/* Top */
parts[3*nvpall] = -width2 + (realT)i * s;
parts[3*nvpall+1] = -width2 + (realT)j * s;
parts[3*nvpall+2] = width2 + g;
nvpall++;
}
}
for (i=0; i<NGUARD+1; i++) { /* Don't want to overdo the corners*/
for (j=0; j<NGUARD+1; j++) {
parts[3*nvpall] = -width2 + (realT)i * s;
parts[3*nvpall+1] = -width2 - g;
parts[3*nvpall+2] = -width2 + (realT)j * s;
nvpall++;
parts[3*nvpall] = -width2 + (realT)i * s;
parts[3*nvpall+1] = width2 + g;
parts[3*nvpall+2] = -width2 + (realT)j * s;
nvpall++;
}
}
for (i=0; i<NGUARD+1; i++) {
for (j=0; j<NGUARD+1; j++) {
parts[3*nvpall] = -width2 - g;
parts[3*nvpall+1] = -width2 + (realT)i * s;
parts[3*nvpall+2] = -width2 + (realT)j * s;
nvpall++;
parts[3*nvpall] = width2 + g;
parts[3*nvpall+1] = -width2 + (realT)i * s;
parts[3*nvpall+2] = -width2 + (realT)j * s;
nvpall++;
}
}
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=nvpbuf;i<nvpall;i++) {
if (parts[3*i] < xmin) xmin = parts[3*i];
if (parts[3*i] > xmax) xmax = parts[3*i];
if (parts[3*i+1] < ymin) ymin = parts[3*i+1];
if (parts[3*i+1] > ymax) ymax = parts[3*i+1];
if (parts[3*i+2] < zmin) zmin = parts[3*i+2];
if (parts[3*i+2] > zmax) zmax = parts[3*i+2];
}
printf("Added guard points to total %d points (should be %d)\n",nvpall,
nvpbuf + 6*(NGUARD+1)*(NGUARD+1));
printf("x: %f,%f; y: %f,%f; z:%f,%f\n",xmin,xmax,ymin,ymax,zmin,zmax);
/* Do tesselation*/
printf("File read. Tessellating ...\n"); fflush(stdout);
exitcode = delaunadj(parts, nvp, nvpbuf, nvpall, &adjs);
if (exitcode != 0)
{
printf("Error while tesselating. Stopping here."); fflush(stdout);
exit(1);
}
/* Now calculate volumes*/
printf("Now finding volumes ...\n"); fflush(stdout);
vols = (float *)malloc(nvp*sizeof(float));
if (vols == NULL) {
printf("Unable to allocate vols\n");
exit(1);
}
for (i=0; i<nvp; i++) { /* Just the original particles
Assign adjacency coordinate array*/
/* Volumes */
for (j = 0; j < adjs[i].nadj; j++)
DL {
deladjs[3*j + d] = parts[3*adjs[i].adj[j]+d] - parts[3*i+d];
if (deladjs[3*j+d] < -0.5) deladjs[3*j+d]++;
if (deladjs[3*j+d] > 0.5) deladjs[3*j+d]--;
}
exitcode = vorvol(deladjs, points, intpoints, adjs[i].nadj, &(vols[i]));
vols[i] *= (float)np;
if (i % 1000 == 0)
printf("%d: %d, %f\n",i,adjs[i].nadj,vols[i]);
}
/* Get the adjacencies back to their original values */
for (i=0; i<nvp; i++)
for (j = 0; j < adjs[i].nadj; j++)
adjs[i].adj[j] = orig[adjs[i].adj[j]];
totalvol = 0.;
for (i=0;i<nvp; i++) {
totalvol += (double)vols[i];
}
printf("Average volume = %g\n",totalvol/(float)nvp);
/* Now the output!
First number of particles */
sprintf(outfile,"%s/part.%s.%02d.%02d.%02d",outDir,suffix,b[0],b[1],b[2]);
printf("Output to %s\n\n",outfile);
out = fopen(outfile,"w");
if (out == NULL) {
printf("Unable to open %s\n",outfile);
exit(1);
}
fwrite(&np,1, sizeof(int),out);
fwrite(&nvp,1, sizeof(int),out);
printf("nvp = %d\n",nvp);
/* Tell us where the original particles were */
fwrite(orig,sizeof(pid_t),nvp,out);
/* Volumes*/
fwrite(vols,sizeof(float),nvp,out);
/* Adjacencies */
for (i=0;i<nvp;i++) {
fwrite(&(adjs[i].nadj),1,sizeof(pid_t),out);
if (adjs[i].nadj > 0)
fwrite(adjs[i].adj,adjs[i].nadj,sizeof(pid_t),out);
else printf("0");
}
fclose(out);
return(0);
}

197
c_source/zobov/vozinit.c Normal file
View file

@ -0,0 +1,197 @@
#include "libqhull/qhull_a.h"
#include "voz.h"
#define NUMCPU 2
#define DL for (d=0;d<3;d++)
#define BF 1e30
#define QHULL_MAX_PARTICLES ((1L<<24)-1)
int posread(char *posfile, float ***p, float fact);
int main(int argc, char *argv[]) {
int i, np;
float **rfloat, rtemp[3];
FILE *pos, *scr;
char *posfile, scrfile[200], systemstr[90], *suffix, *outDir, *vobozPath;
float xmin,xmax,ymin,ymax,zmin,zmax;
int isitinbuf;
char isitinmain, d;
int numdiv;
int p;
int nvp, nvpall, nvpbuf, nvpmin, nvpmax, nvpbufmin, nvpbufmax; /* yes, the insurance */
float width, width2, totwidth, totwidth2, bf, s, g;
float widthX, widthY, widthZ;
float border, boxsize, boxsizeX, boxsizeY, boxsizeZ;
float c[3];
int numGuards;
int b[3];
int numThreads;
int mockIndex;
if (argc != 10) {
printf("Wrong number of arguments.\n");
printf("arg1: position file\n");
printf("arg2: buffer size (default 0.1)\n");
printf("arg3: box size\n");
printf("arg6: number of divisions (default 2)\n");
printf("arg7: suffix describing this run\n");
printf("arg8: number of parallel threads\n");
printf("arg9: location of voboz executables\n");
printf("arg10: output directory\n");
printf("arg11: index of mock galaxies\n\n");
exit(0);
}
posfile = argv[1];
suffix = argv[2];
if (sscanf(suffix,"%f",&border) != 1) {
printf("That's no border size; try again.\n");
exit(0);
}
suffix = argv[3];
if (sscanf(suffix,"%f",&boxsize) != 1) {
printf("That's no boxsize; try again.\n");
exit(0);
}
suffix = argv[4];
if (sscanf(suffix,"%d",&numdiv) != 1) {
printf("That's no number of divisions; try again.\n");
exit(0);
}
if (numdiv < 1) {
printf("Cannot have a number of divisions less than 1. Resetting to 1:\n");
numdiv = 1;
}
suffix = argv[5];
vobozPath = argv[6];
if (sscanf(vobozPath,"%d",&numThreads) != 1) {
printf("That's no number of threads; try again.\n");
exit(0);
}
vobozPath = argv[7];
outDir = argv[8];
if (sscanf(argv[9],"%d",&mockIndex) != 1) {
printf("That's no mock galaxy index; try again.\n");
exit(0);
}
/* Read the position file */
np = posread(posfile,&rfloat,1./boxsize);
/* Boxsize should be the range in r, yielding a range 0-1 */
width = boxsize/(float)numdiv;
//width = 1./(float)numdiv;
width2 = 0.5*width;
if (border > 0.) bf = border;
else bf = 0.1;
/* In units of 0-1, the thickness of each subregion's buffer*/
totwidth = width+2.*bf;
totwidth2 = width2 + bf;
s = width/(float)NGUARD;
if ((bf*bf - 2.*s*s) < 0.) {
printf("Not enough guard points for given border.\nIncrease guards to >= %f\n.",
totwidth/sqrt(0.5*bf*bf));
printf("bf = %f\n",bf);
exit(0);
}
g = (bf / 2.)*(1. + sqrt(1 - 2.*s*s/(bf*bf)));
printf("s = %f, bf = %f, g = %f.\n",s,bf,g);
nvpmax = 0; nvpbufmax = 0; nvpmin = np; nvpbufmin = np;
for (b[0] = 0; b[0] < numdiv; b[0]++) {
c[0] = ((float)b[0]+0.5)*width;
for (b[1] = 0; b[1] < numdiv; b[1]++) {
c[1] = ((float)b[1]+0.5)*width;
for (b[2] = 0; b[2] < numdiv; b[2]++) {
c[2] = ((float)b[2]+0.5)*width;
nvp = 0; /* Number of particles excluding buffer */
nvpbuf = 0; /* Number of particles to tesselate, including
buffer */
xmin = BF; xmax = -BF; ymin = BF; ymax = -BF; zmin = BF; zmax = -BF;
for (i=0; i<np; i++) {
isitinbuf = 1; isitinmain = 1;
for (d=0; d<3; d++) {
rtemp[d] = rfloat[i][d] - c[d];
if (rtemp[d] > 0.5) rtemp[d] --;
if (rtemp[d] < -0.5) rtemp[d] ++;
isitinbuf = isitinbuf && (fabs(rtemp[d]) < totwidth2);
isitinmain = isitinmain && (fabs(rtemp[d]) <= width2);
}
if (isitinbuf) {
nvpbuf++;
}
if (isitinmain) {
nvp++;
if (rtemp[0] < xmin) xmin = rtemp[0];
if (rtemp[0] > xmax) xmax = rtemp[0];
if (rtemp[1] < ymin) ymin = rtemp[1];
if (rtemp[1] > ymax) ymax = rtemp[1];
if (rtemp[2] < zmin) zmin = rtemp[2];
if (rtemp[2] > zmax) zmax = rtemp[2];
}
}
if (nvp > nvpmax) nvpmax = nvp;
if (nvpbuf > nvpbufmax) nvpbufmax = nvpbuf;
if (nvp < nvpmin) nvpmin = nvp;
if (nvpbuf < nvpbufmin) nvpbufmin = nvpbuf;
printf("b=(%d,%d,%d), c=(%f,%f,%f), nvp=%d, nvpbuf=%d\n",
b[0],b[1],b[2],c[0],c[1],c[2],nvp,nvpbuf);
}
}
}
printf("Nvp range: %d,%d\n",nvpmin,nvpmax);
printf("Nvpbuf range: %d,%d\n",nvpbufmin,nvpbufmax);
numGuards = 6*(NGUARD+1)*(NGUARD+1);
printf("Total max particles: %d\n" , nvpbufmax+numGuards);
if (nvpbufmax+numGuards >= QHULL_MAX_PARTICLES)
{
printf("Too many particles to tesselate per division (Qhull will overflow). Increase divisions or reduce buffer size.\n");
fflush(stdout);
exit(1);
}
/* Output script file */
sprintf(scrfile,"scr%s",suffix);
printf("Writing script file to %s.\n",scrfile);fflush(stdout);
scr = fopen(scrfile,"w");
if (scr == NULL) {
printf("Problem opening script file.\n");
fflush(stdout);
exit(1);
}
fprintf(scr,"#!/bin/bash -f\n");
p = 0;
for (b[0]=0;b[0]<numdiv; b[0]++) {
for (b[1] = 0; b[1] < numdiv; b[1]++) {
for (b[2] = 0; b[2] < numdiv; b[2]++) {
//fprintf(scr,"%s/../c_tools/zobov2/voz1b1/voz1b1_2 %s %f %f %f %f %s %d %d %d %d %d %d %s&\n",
// vobozPath,
// posfile,border,boxsize,boxsize,boxsize,suffix,numdiv,numdiv, numdiv,b[0],b[1],b[2],
// outDir);
fprintf(scr,"%s/voz1b1 %s %f %f %s %d %d %d %d %s&\n",
vobozPath,
posfile,border,boxsize,suffix,numdiv,b[0],b[1],b[2],
outDir);
p++;
if ((p == numThreads)) { fprintf(scr, "wait\n"); p = 0; }
}
}
}
fprintf(scr,"wait\n");
fprintf(scr,"%s/voztie %d %s %s %d\n", vobozPath, numdiv,suffix, outDir, mockIndex);
fclose(scr);
sprintf(systemstr,"chmod u+x %s",scrfile);
system(systemstr);
return(0);
}

303
c_source/zobov/voztie.c Normal file
View file

@ -0,0 +1,303 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "voz.h"
int compare_int(const void *a, const void *b)
{
const int *ia = (const int *)a;
const int *ib = (const int *)b;
if ((*ia) < (*ib))
return -1;
else if ((*ia) > (*ib))
return 1;
else
return 0;
}
int main(int argc, char *argv[]) {
FILE *part, *adj, *vol;
char partfile[200], *suffix, adjfile[200], volfile[200], *outDir;
float *vols, volstemp;
int *cnt_adj;
PARTADJ *adjs;
int numdiv,np,np2,na;
pid_t i,j,k,p,nout;
pid_t nvp,npnotdone,nvpmax, nvpsum, *orig;
double avgnadj, avgvol;
int numRemoved = 0;
// PMS
int mockIndex;
// END PMS
if (argc != 5) {
printf("Wrong number of arguments.\n");
printf("arg1: number of divisions (default 2)\n");
printf("arg2: suffix describing this run\n");
printf("arg3: file directory\n");
printf("arg4: Beginning index of mock particles\n\n");
exit(0);
}
if (sscanf(argv[1],"%d",&numdiv) != 1) {
printf("That's no number of divisions; try again.\n");
exit(0);
}
if (numdiv < 1) {
printf("Cannot have a number of divisions less than 1. Resetting to 1:\n");
numdiv = 1;
}
suffix = argv[2];
outDir = argv[3];
if (sscanf(argv[4],"%d",&mockIndex) != 1) {
printf("That's no mock galaxy index; try again.\n");
exit(0);
}
np = -1; nvpmax = -1; nvpsum = 0;
for (i = 0; i < numdiv; i++) {
for (j = 0; j < numdiv; j++) {
for (k = 0; k < numdiv; k++) {
sprintf(partfile,"%s/part.%s.%02d.%02d.%02d",outDir,suffix,i,j,k);
part = fopen(partfile,"r");
if (part == NULL) {
printf("Unable to open file %s.\n\n",partfile);
exit(0);
}
fread(&np2,1,sizeof(int),part);
fread(&nvp,1,sizeof(int),part);
nvpsum += nvp;
if (np == -1)
np = np2;
else
if (np2 != np) {
printf("Incompatible total particle numbers: %d,%d\n\n",np,np2);
exit(0);
}
if (nvp > nvpmax) nvpmax = nvp;
fclose(part);
}
}
}
printf("We have %d particles to tie together.\n",np); fflush(stdout);
printf("The maximum number of particles in a file is %d.\n",nvpmax);
// PMS
if (mockIndex == -1) mockIndex = np;
// END PMS
cnt_adj = (int *)malloc(np*sizeof(int));
if (cnt_adj == NULL)
printf("Could not allocate cnt_adj.\n");
adjs = (PARTADJ *)malloc(np*sizeof(PARTADJ));
if (adjs == NULL) printf("Couldn't allocate adjs.\n");
vols = (float *)malloc(np*sizeof(float));
if (vols == NULL) printf("Couldn't allocate vols.\n");
orig = (pid_t *)malloc(nvpmax*sizeof(pid_t));
if (orig == NULL) printf("Couldn't allocate orig.\n");
if ((cnt_adj==NULL) || (vols == NULL) || (orig == NULL) || (adjs == NULL)) {
printf("Not enough memory to allocate. Exiting.\n");
exit(0);
}
for (p=0;p<np;p++)
{
vols[p] = -1.;
adjs[p].nadj = 0;
adjs[p].adj = 0;
}
nvpsum = 0;
for (i = 0; i < numdiv; i++) {
for (j = 0; j < numdiv; j++) {
for (k = 0; k < numdiv; k++) {
sprintf(partfile,"%s/part.%s.%02d.%02d.%02d",outDir,suffix,i,j,k);
part = fopen(partfile,"r");
if (part == NULL) {
printf("Unable to open file %s.\n\n",partfile);
exit(0);
}
fread(&np2,1,sizeof(pid_t),part);
fread(&nvp,1,sizeof(pid_t),part);
/*printf("nvp = %d\n",nvp);fflush(stdout);*/
nvpsum += nvp;
fread(orig,nvp,sizeof(pid_t),part);
for (p=0;p<nvp;p++) {
fread(&volstemp,1,sizeof(float),part);
if (vols[orig[p]] > -1.)
if (fabs(vols[orig[p]]-volstemp)/volstemp > 1.5e-3 && orig[p] < mockIndex) {
printf("Inconsistent volumes for p. %d: (%10g,%10g)!\n",
orig[p],vols[orig[p]],volstemp);
//exit(0);
}
vols[orig[p]] = volstemp;
}
for (p=0;p<nvp;p++) {
fread(&na,1,sizeof(int),part);
pid_t pid = orig[p];
if (na > 0) {
pid_t *previous_adj = adjs[pid].adj;
assert(adjs[pid].nadj == 0 || adjs[pid].nadj == na);
adjs[pid].nadj = na;
adjs[pid].adj = (pid_t *)malloc(na*sizeof(pid_t));
if (adjs[pid].adj == 0) {
printf("Couldn't allocate adjs[orig[%d]].adj.\n",p);
exit(0);
}
fread(adjs[pid].adj,na,sizeof(pid_t),part);
if (previous_adj != 0)
{
qsort(previous_adj, na, sizeof(pid_t), compare_int);
qsort(adjs[pid].adj, na, sizeof(pid_t), compare_int);
if (memcmp(previous_adj, adjs[pid].adj, sizeof(pid_t)*na) != 0)
{
printf("Inconsistent adjacencies between two divisions.\n");
abort();
}
}
} else {
printf("0"); fflush(stdout);
}
}
fclose(part);
printf("%d ",k);
}
}
}
printf("\n");
// PMS : remove mock galaxies and anything adjacent to a mock galaxy
printf("\nRemoving mock galaxies...\n");
// completely unlink mock particles
for (i = mockIndex; i < np; i++) {
vols[i] = 1.e-29;
adjs[i].nadj = 0;
}
// unlink particles adjacent to mock galaxies
for (i = 0; i < mockIndex; i++) {
for (j = 0; j < adjs[i].nadj; j++) {
if (adjs[i].adj[j] > mockIndex) {
//printf("KILLING %d\n", i);
vols[i] = 1.e-29;
adjs[i].nadj = 0;
numRemoved++;
break;
}
}
}
// update all other adjacencies
for (i = 0; i < mockIndex; i++) {
int numAdjSaved = 0;
for (j = 0; j < adjs[i].nadj; j++) {
if ( adjs[adjs[i].adj[j]].nadj != 0) {
adjs[i].adj[numAdjSaved] = adjs[i].adj[j];
numAdjSaved++;
}
}
adjs[i].nadj = numAdjSaved;
}
printf("Removed %d mock galaxies and %d adjacent galaxies.\n", np-mockIndex,
numRemoved);
printf("There are %d galaxies remaining.\n", mockIndex-numRemoved);
// END PMS
npnotdone = 0; avgnadj = 0.; avgvol = 0.;
for (p=0;p<np;p++) {
// PMS
if (vols[p] == 1.e-29) continue;
// END PMS
if (vols[p] == -1.) npnotdone++;
avgnadj += (double)(adjs[p].nadj);
avgvol += (double)(vols[p]);
}
if (npnotdone > 0)
printf("%d particles not done!\n", npnotdone);
printf("%d particles done more than once.\n",nvpsum-np);
avgnadj /= (double)np;
avgvol /= (double)np;
printf("Average # adjacencies = %lf (%f for Poisson)\n",avgnadj,
48.*3.141593*3.141593/35.+2.);
printf("Average volume = %lf\n",avgvol);
/* Now the output! */
sprintf(adjfile,"%s/adj%s.dat",outDir,suffix);
sprintf(volfile,"%s/vol%s.dat",outDir,suffix);
printf("Outputting to%s, %s\n\n", adjfile, volfile);
adj = fopen(adjfile,"w");
if (adj == NULL) {
printf("Unable to open %s\n",adjfile);
exit(0);
}
fwrite(&mockIndex,1, sizeof(int),adj);
/* Adjacencies: first the numbers of adjacencies,
and the number we're actually going to write per particle */
// Recount the number of adjacencies after merge
for(i=0;i<mockIndex;i++)
cnt_adj[i] = adjs[i].nadj;
for (i=0;i<mockIndex;i++)
fwrite(&cnt_adj[i],1,sizeof(int),adj);
/* Now the lists of adjacencies (without double counting) */
for (i=0;i<mockIndex;i++) {
nout = 0;
for (j=0;j<adjs[i].nadj; j++)
if (adjs[i].adj[j] > i)
nout++;
fwrite(&nout,1,sizeof(int),adj);
for (j=0;j<adjs[i].nadj; j++) {
pid_t id = adjs[i].adj[j];
if (id > i)
fwrite(&id,1,sizeof(pid_t),adj);
}
}
fclose(adj);
/* Volumes */
vol = fopen(volfile,"w");
if (vol == NULL) {
printf("Unable to open %s\n",volfile);
exit(0);
}
// PMS
fwrite(&mockIndex,1, sizeof(int),vol);
fwrite(vols,sizeof(float),mockIndex,vol);
//fwrite(&np,1, sizeof(int),vol);
//fwrite(vols,sizeof(float),np,vol);
// END PMS
fclose(vol);
free(vols);
free(cnt_adj);
free(adjs);
free(orig);
return(0);
}

245
c_source/zobov/vozutil.c Normal file
View file

@ -0,0 +1,245 @@
#include "libqhull/qhull_a.h"
#include "voz.h"
#define FOREACHvertex2_(vertices) FOREACHsetelement_(vertexT, vertices2,vertex2)
/*char qh_version[] = "user_eg 3.1 2001/10/04"; */
int compar(const void * n1, const void * n2) {
int i1,i2;
i1 = *(int *)n1;
i2 = *(int *)n2;
return 2*(i1 > i2) - 1 + (i1 == i2);
}
/* Finds Delaunay adjacencies of a set of points */
int delaunadj (coordT *points, int nvp, int nvpbuf, int nvpall, PARTADJ **adjs) {
int dim= 3; /* dimension of points */
boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[250]; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= stdout; /* output from qh_produce_output()
use NULL to skip qh_produce_output() */
FILE *errfile= stderr; /* error messages from qhull code */
int exitcode; /* 0 if no error from qhull */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
int i, ver, count;
int numfacets, numsimplicial, numridges, totneighbors, numneighbors,
numcoplanars, numtricoplanars;
setT *vertices, *vertices2, *vertex_points, *coplanar_points;
vertexT *vertex, **vertexp;
vertexT *vertex2, **vertex2p;
int vertex_i, vertex_n;
facetT *facet, **facetp, *neighbor, **neighborp;
pointT *point, **pointp;
int numdiv;
PARTADJ adjst;
int errorReported = 0;
adjst.adj = (int *)malloc(MAXVERVER*sizeof(int));
if (adjst.adj == NULL) {
printf("Unable to allocate adjst.adj\n");
exit(0);
}
/* Delaunay triangulation*/
sprintf (flags, "qhull s d Qt");
exitcode= qh_new_qhull (dim, nvpall, points, ismalloc,
flags, outfile, errfile);
if (!exitcode) { /* if no error */
/* 'qh facet_list' contains the convex hull */
/* From qh_printvneighbors */
qh_countfacets(qh facet_list, NULL, 0, &numfacets, &numsimplicial,
&totneighbors, &numridges, &numcoplanars, &numtricoplanars);
qh_vertexneighbors();
vertices= qh_facetvertices (qh facet_list, NULL, 0);
vertex_points= qh_settemp (nvpall);
coplanar_points= qh_settemp (nvpall);
qh_setzero (vertex_points, 0, nvpall);
qh_setzero (coplanar_points, 0, nvpall);
FOREACHvertex_(vertices)
qh_point_add (vertex_points, vertex->point, vertex);
FORALLfacet_(qh facet_list) {
FOREACHpoint_(facet->coplanarset)
qh_point_add (coplanar_points, point, facet);
}
ver = 0;
FOREACHvertex_i_(vertex_points) {
(*adjs)[ver].nadj = 0;
if (vertex) {
/* Count the neighboring vertices, check that all are real
neighbors */
adjst.nadj = 0;
FOREACHneighbor_(vertex) {
if ((*adjs)[ver].nadj > -1) {
if (neighbor->visitid) {
vertices2 = neighbor->vertices;
FOREACHvertex2_(vertices2) {
if (ver != qh_pointid(vertex2->point)) {
adjst.adj[adjst.nadj] = (int)qh_pointid(vertex2->point);
adjst.nadj ++;
if (adjst.nadj > MAXVERVER) {
printf("Increase MAXVERVER to at least %d!\n",adjst.nadj);
exit(0);
}
}
}
} else {
printf(" %d",ver);
(*adjs)[ver].nadj = -1; /* There are unreal vertices here */
}
}
}
} else (*adjs)[ver].nadj = -2;
/* Enumerate the unique adjacencies*/
if (adjst.nadj >= 4) {
qsort((void *)adjst.adj, adjst.nadj, sizeof(int), &compar);
count = 1;
for (i=1; i<adjst.nadj; i++)
if (adjst.adj[i] != adjst.adj[i-1]) {
if (adjst.adj[i] >= nvpbuf && !errorReported) {
errorReported = 1;
printf("Guard point encountered. Increase border and/or nguard.\n");
printf("P:(%f,%f,%f), G: (%f,%f,%f)\n",points[3*ver],points[3*ver+1],points[3*ver+2],
points[3*adjst.adj[i]],points[3*adjst.adj[i]+1],points[3*adjst.adj[i]+2]);
}
count++;
}
(*adjs)[ver].adj = (int *)malloc(count*sizeof(int));
if ((*adjs)[ver].adj == NULL) {
printf("Unable to allocate (*adjs)[ver].adj\n");
exit(0);
}
(*adjs)[ver].adj[0] = adjst.adj[0];
count = 1;
for (i=1; i<adjst.nadj; i++)
if (adjst.adj[i] != adjst.adj[i-1]) {
(*adjs)[ver].adj[count] = adjst.adj[i];
count++;
}
(*adjs)[ver].nadj = count;
} else {
printf("Number of adjacencies %d < 4, particle %d -> %d\n",adjst.nadj,ver,ver);
exit(0);
}
ver++;
if (ver == nvp) break;
}
qh_settempfree (&coplanar_points);
qh_settempfree (&vertex_points);
qh_settempfree (&vertices);
}
qh_freeqhull(!qh_ALL); /* free long memory */
qh_memfreeshort (&curlong, &totlong); /* free short memory and memory allocator */
if (curlong || totlong)
fprintf (errfile, "qhull internal warning (delaunadj): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
free(adjst.adj);
return exitcode;
}
/* Calculates the Voronoi volume from a set of Delaunay adjacencies */
int vorvol (coordT *deladjs, coordT *points, pointT *intpoints, int numpoints, float *vol) {
int dim= 3; /* dimension of points */
boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[250]; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= NULL; /* output from qh_produce_output()
use NULL to skip qh_produce_output() */
FILE *errfile= stderr; /* error messages from qhull code */
int exitcode; /* 0 if no error from qhull */
facetT *facet; /* set by FORALLfacets */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
coordT *point, *normp, *coordp, *feasiblep, *deladj;
int i, j, k;
boolT zerodiv;
float runsum;
char region;
/*coordT *points;
pointT *intpoints;*/
/* make point array from adjacency coordinates (add offset)*/
/*points = (coordT *)malloc(4*numpoints*sizeof(coordT));
if (points == NULL) {
printf("Unable to allocate points\n");
exit(0);
}*/
for (i=0; i<numpoints; i++) {
runsum = 0.;
deladj = deladjs + 3*i;
point = points + 4*i;
for (j=0;j<3;j++) {
runsum += deladj[j]*deladj[j];
point[j] = deladj[j];
}
point[3] = -0.5*runsum;
}
sprintf (flags, "qhull H0");
exitcode= qh_new_qhull (4, numpoints, points, ismalloc,
flags, outfile, errfile);
numpoints = 0;
if (!exitcode) { /* if no error */
FORALLfacets {
numpoints++;
}
/* Now we know how many points */
/*intpoints = (pointT *)malloc(dim*numpoints*sizeof(pointT));
if (intpoints == NULL) {
printf("Unable to allocate intpoints\n");
exit(0);
}*/
j = 0;
FORALLfacets {
if (!qh feasible_point) {
fprintf (stdout, "qhull input error (qh_printafacet): option 'Fp' needs qh feasible_point\n");
qh_errexit( qh_ERRinput, NULL, NULL);
}
point= coordp= intpoints + j*3;
j++;
normp= facet->normal;
feasiblep= qh feasible_point;
if (facet->offset < -qh MINdenom) {
for (k= qh hull_dim; k--; )
*(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
}else {
for (k= qh hull_dim; k--; ) {
*(coordp++)= qh_divzero (*(normp++), facet->offset, qh MINdenom_1,
&zerodiv) + *(feasiblep++);
if (zerodiv) {
qh_memfree (point, qh normal_size);
printf("LABELprintinfinite\n");
exit(0);
}
}
}
}
}
qh_freeqhull (!qh_ALL);
qh_memfreeshort (&curlong, &totlong);
/* Now we calculate the volume */
sprintf (flags, "qhull FA");
exitcode= qh_new_qhull (dim, numpoints, intpoints, ismalloc,
flags, outfile, errfile);
qh_getarea(qh facet_list);
*vol = qh totvol;
qh_freeqhull (!qh_ALL);
qh_memfreeshort (&curlong, &totlong);
if (curlong || totlong)
fprintf (errfile, "qhull internal warning (vorvol): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
/*free(points); free(intpoints);*/
return exitcode;
}

View file

@ -0,0 +1,25 @@
This is the readme file for ZOBOV (ZOnes Bordering On Voidness),
version 1.0 (Jan 5, 2008) a void-finding algorithm for sets of
particles (e.g. a cosmological N-body simulation) by Mark Neyrinck.
It is an inversion of the halo-finding algorithm VOBOZ (VOronoi BOund
Zones), which was also written by Mark Neyrinck, with the guidance of
Nick Gnedin and Andrew Hamilton.
The gz file which once contained this file should include the
following files:
Makefile jozov.c readme.txt voz1b1.c voztie.c
findrtop.c readfiles.c voz.h vozinit.c vozutil.c
For instructions on installing and running ZOBOV, please see
http://www.ifa.hawaii.edu/~neyrinck/zobov/. To use ZOBOV, you will
need to download the Qhull package, at http://www.qhull.org. For help
in understanding ZOBOV, please see the paper describing it
(arXiv:0712.3049), If these resources are insufficient, feel free to
email Mark.Neyrinck@colorado.edu with questions.
This is free software. It may be freely copied, modified, and
redistributed, as long as ZOBOV and its author are acknowledged.
There is no warranty or other guarantee of fitness for ZOBOV; it is
provided "as is." I welcome bug reports (but do not guarantee their
fixing), which should be sent to Mark.Neyrinck@colorado.edu.