#include /* jovoz.c by Mark Neyrinck */ #include #include #include #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 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 0) for (k=0;k 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 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 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 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