int main (int argc, string argv[]) #endif { #ifndef SIM_SOCLIB long c; while ((c = getopt(argc, argv, "h")) != -1) { switch(c) { case 'h': Help(); exit(-1); break; default: fprintf(stderr, "Only valid option is \"-h\".\n"); exit(-1); break; } } #endif Global = NULL; initparam(defv); startrun(); initoutput(); tab_init(); Global->tracktime = 0; Global->partitiontime = 0; Global->treebuildtime = 0; Global->forcecalctime = 0; Global->current_id = 0; CLOCK(Global->computestart); printf("COMPUTESTART = %12lu\n",Global->computestart); CREATE(SlaveStart, NPROC); WAIT_FOR_END(NPROC); CLOCK(Global->computeend); printf("COMPUTEEND = %12lu\n",Global->computeend); printf("COMPUTETIME = %12lu\n",Global->computeend - Global->computestart); printf("TRACKTIME = %12lu\n",Global->tracktime); printf("PARTITIONTIME = %12lu\t%5.2f\n",Global->partitiontime, ((float)Global->partitiontime)/Global->tracktime); printf("TREEBUILDTIME = %12lu\t%5.2f\n",Global->treebuildtime, ((float)Global->treebuildtime)/Global->tracktime); printf("FORCECALCTIME = %12lu\t%5.2f\n",Global->forcecalctime, ((float)Global->forcecalctime)/Global->tracktime); printf("RESTTIME = %12lu\t%5.2f\n", Global->tracktime - Global->partitiontime - Global->treebuildtime - Global->forcecalctime, ((float)(Global->tracktime-Global->partitiontime- Global->treebuildtime-Global->forcecalctime))/ Global->tracktime); MAIN_END; }
void nemo_main(void) { startrun(); /* set params, input data */ initoutput(); /* begin system output */ while (tnow < tstop + 0.1/freq) /* while not past tstop */ stepsystem(); /* advance N-body system */ stopoutput(); /* finish up output */ }
int main(int argc, string argv[]) { initparam(argv, defv); // initialize param access headline = defv[0] + 1; // use default headline startrun(); // get params & input data startoutput(); // activate output code if (nstep == 0) { // if data just initialized treeforce(); // calculate initial forces output(); // generate initial output } if (dtime != 0.0) // if time steps requested while (tstop - tnow > 0.01 * dtime) { // while not past tstop stepsystem(); // advance step by step output(); // output results each time } return (0); // end with proper status }
int main(int argc, string argv[]) { initparam(argv, defv); // initialize param access headline = defv[0] + 1; // use default headline startrun(); // get params & input data startoutput(); // activate output code if (nstep == 0) { // if data just initialized treeforce_initial_0 = wtime(); treeforce(); // calculate initial forces treeforce_initial_1 = wtime(); output(); // generate initial output } if (dtime != 0.0) // if time steps requested // TODO: make this work in timesteps? treeforce_0 = wtime(); while (nstep <= timesteps) { // while not past tstop stepsystem(); // advance step by step output(); // output results each time } // while (tstop - tnow > 0.01 * dtime) { // while not past tstop // stepsystem(); // advance step by step // output(); // output results each time // } treeforce_1 = wtime(); finaloutput(); bodyptr p; bodyptr q; float phi = 0.0f; for (p = bodytab; p < bodytab+nbody; p++) {// loop over all bodies for (q = bodytab; q < bodytab+nbody; q++) {// loop over all bodies // printf("Pos(p) = (%.8f,%.8f,%.8f)\n", Pos(p)[0], Pos(p)[1], Pos(p)[2]); // printf("Pos(q) = (%.8f,%.8f,%.8f)\n", Pos(q)[0], Pos(q)[1], Pos(q)[2]); float rx = Pos(q)[0] - Pos(p)[0]; float ry = Pos(q)[1] - Pos(p)[1]; float rz = Pos(q)[2] - Pos(p)[2]; float r2 = rx*rx + ry*ry + rz*rz + eps; float r2inv = 1.0 / sqrt(r2); float r6inv = r2inv * r2inv * r2inv; float mass = Mass(q); phi += mass * r6inv; } } printf(" Answer = %f\n", phi); return (0); // end with proper status }
/*============================================================================== * MAIN: where everything starts .... *==============================================================================*/ int main(int argc, char **argv) { gridls *grid_list; /* pointer to list of grids */ int no_grids; /* total number of grids */ int no_timestep; /* number of coarse grid timesteps */ int no_first_timestep; /* number of initial timestep */ double timecounter; /* time variable */ double timestep; /* timestep size */ double timecounter_final; /* for all sorts of tests... */ char AMIGA_input[MAXSTRING]; #ifdef WITH_MPI uint64_t newparts; #endif /*============================================================ * we always read the relevant parameters from an input file! *===========================================================*/ if(argc<2) { fprintf(stderr,"usage: %s AMIGA.input\n", argv[0]); fprintf(stderr," or %s --parameterfile\n", argv[0]); exit(1); } /*============================================================ * maybe the user only wants the parameterfile? *===========================================================*/ if(strcmp(argv[1],"--parameterfile") == 0) { global_io.params = (io_parameter_t) calloc(1,sizeof(io_parameter_struct_t)); global_io.params->outfile_prefix = (char *) calloc(MAXSTRING,sizeof(char)); global.a = 1; strcpy(global_io.params->outfile_prefix,"AHF"); write_parameterfile(); exit(0); } else { strcpy(AMIGA_input, argv[1]); } /* check for some DEFINEFLAGS mistakes */ #if (defined NCPUREADING_EQ_NFILES && defined BCASTHEADER) fprintf(stderr,"you cannot define NCPUREADING_EQ_NFILES and BCASTHEADER at the same time\nABORTING\n"); exit(1); #endif #if (!defined WITH_MPI) WRITEAHFLOGO(stderr); #endif /* how much memory per node and particle for this particular run */ global.bytes_node = sizeof(struct node); global.bytes_part = sizeof(struct particle); # ifdef WITH_MPI /* Initialize the MPI environment */ common_initmpi(&argc, &argv); # ifdef MPI_TIMING global_mpi.start = MPI_Wtime(); # endif # endif /*======================================================== * startrun: input the initial data from infile *========================================================*/ timing.io -= time(NULL); timing.startrun -= time(NULL); startrun((argc > 1) ? argv[1] : NULL, &timecounter, ×tep, &no_first_timestep); timing.startrun += time(NULL); #ifdef DEBUG_STARTRUN /*=========================================================== * DEBUG_STARTRUN: * we simply check if the particles have been read correctly *===========================================================*/ { FILE *fpout; char outname[MAXSTRING]; partptr cur_part; #ifdef WITH_MPI sprintf(outname,"test-%d.ascii",global_mpi.rank); #else sprintf(outname,"test.ascii"); #endif fpout = fopen(outname,"w"); for(cur_part=global_info.fst_part; cur_part<(global_info.fst_part+global_info.no_part); cur_part++) fprintf(fpout,"%e %e %e\n",cur_part->pos[X]*simu.boxsize,cur_part->pos[Y]*simu.boxsize,cur_part->pos[Z]*simu.boxsize); fclose(fpout); #ifdef WITH_MPI MPI_Barrier(MPI_COMM_WORLD); #endif //exit(0); } #endif /* DEBUG_STARTRUN */ /*========================================================================================== * AHFptfocus: * * only use a certain type of particles ("pt") and focus ("focus") the AHF analysis on them * *==========================================================================================*/ #if (defined AHFptfocus && defined MULTIMASS && defined GAS_PARTICLES) /* global_info.no_part * global_info.fst_part * => the no. of particles and relevant pointer for this CPU */ timing.ptfocus -= time(NULL); { long unsigned no_part; partptr fst_part, cur_part, new_part; int ikeep; fprintf(stderr,"\n==================================================================\n"); fprintf(stderr," AHFptfocus\n"); fprintf(stderr," ? ARE YOU SURE ABOUT THIS FLAG ?\n"); fprintf(stderr,"==================================================================\n"); fprintf(stderr,"AHF will now remove all particles whose type is not %d\n",AHFptfocus); fprintf(stderr,"starting with %ld particles -> ",global_info.no_part); /* 1. count number of particles to keep */ no_part = 0; for(cur_part=global_info.fst_part; cur_part<(global_info.fst_part+global_info.no_part); cur_part++) { /* we only want ot keep those particles with type AHFptfocus */ if(AHFptfocus == 0) { if(cur_part->u >= AHFptfocus) no_part++; } else { if(fabs(cur_part->u+AHFptfocus) < ZERO) no_part++; } /* only keep the high-resolution particles */ // if(cur_part->u >= 0 || cur_part->u == PDM || cur_part->u == PSTAR) // no_part++; } /* allocate memory for new particles */ fst_part = c_part(no_part); /* 2. remove all other particles */ new_part = fst_part; for(cur_part=global_info.fst_part; cur_part<(global_info.fst_part+global_info.no_part); cur_part++) { ikeep = 0; /* we only want ot keep those particles with type AHFptfocus */ if(AHFptfocus == 0) { if(cur_part->u >= AHFptfocus) ikeep = 1; } else { if(fabs(cur_part->u+AHFptfocus) < ZERO) ikeep = 1; } /* only keep the high-resolution particles */ // if(cur_part->u >= 0 || cur_part->u == PDM || cur_part->u == PSTAR) // ikeep = 1; if(ikeep) { new_part->pos[X] = cur_part->pos[X]; new_part->pos[Y] = cur_part->pos[Y]; new_part->pos[Z] = cur_part->pos[Z]; new_part->mom[X] = cur_part->mom[X]; new_part->mom[Y] = cur_part->mom[Y]; new_part->mom[Z] = cur_part->mom[Z]; new_part->weight = cur_part->weight; new_part->u = cur_part->u; #if (!(defined AHF_NO_PARTICLES && defined AHFlean)) new_part->id = cur_part->id; #endif new_part++; } } /* erase old particle list and store new one */ free(global_info.fst_part); global_info.fst_part = fst_part; /* update global.no_part parameter */ global_info.no_part = no_part; fprintf(stderr,"ended with %ld particles\n\n",global_info.no_part); } timing.ptfocus += time(NULL); #endif /* AHFptfocus */ #ifdef AHFrfocus /*==================================================================== * This is for focussing on a Sphere defined in param.h * This assumes that periodicity can be neglected for deciding * whether a particle is inside the selected sphere or not. *====================================================================*/ timing.rfocus -= time(NULL); local_focusSphere(); timing.rfocus += time(NULL); #endif # if (defined WITH_MPI && defined MPI_TIMING) global_mpi.stop = MPI_Wtime(); io_logging_msg(global_io.log, INT32_C(1), "Startrun done in %fs", global_mpi.stop-global_mpi.start); global_mpi.start = global_mpi.stop; # endif # ifdef WITH_MPI timing.loadbalance -= time(NULL); /* Sort the particles in a particle block structure */ io_logging_section(global_io.log, "Initial Load-Balancing and Particle Distribution"); io_logging_subsection(global_io.log, "Loadbalancing"); loadbalance_update(global_io.log, global_info.loadbal, global_info.fst_part, global_info.no_part); # ifdef MPI_TIMING global_mpi.stop = MPI_Wtime(); io_logging_msg(global_io.log, INT32_C(1), "Loadbalance done in %fs", global_mpi.stop-global_mpi.start); global_mpi.start = global_mpi.stop; # else io_logging_msg(global_io.log, INT32_C(1), "Loadbalance done."); # endif loadbalance_log(global_io.log, global_info.loadbal); timing.loadbalance += time(NULL); # else /* Generate the SFC keys for all particles */ timing.sfckey -= time(NULL); for (uint64_t i=0; i<global_info.no_part; i++) { partptr part=global_info.fst_part+i; part->sfckey = sfc_curve_calcKey(global_info.ctype, (double)(part->pos[0]), (double)(part->pos[1]), (double)(part->pos[2]), BITS_PER_DIMENSION); } /* Sorting all particles to have fast access later on */ qsort(global_info.fst_part, global_info.no_part, sizeof(part), &cmp_sfckey_part); timing.sfckey += time(NULL); # endif /* WITH_MPI*/ # ifdef WITH_MPI timing.distribution -= time(NULL); /* Do a first sort of the particles, required for distributing */ io_logging_subsection(global_io.log, "Sorting particles"); qsort(global_info.fst_part, global_info.no_part, sizeof(part), &cmp_sfckey_part); # ifdef MPI_TIMING global_mpi.stop = MPI_Wtime(); io_logging_msg(global_io.log, INT32_C(1), "Sorting done in %fs", global_mpi.stop-global_mpi.start); global_mpi.start = global_mpi.stop; # else io_logging_msg(global_io.log, INT32_C(1), "Sorting done."); # endif /* Distribute the particles */ io_logging_subsection(global_io.log, "Distributing particles"); io_logging_msg(global_io.log, INT32_C(0), "Currently having %"PRIu64" particles.", global_info.no_part); comm_dist_part(global_io.log, &(global_info.fst_part), &(global_info.no_part), global_info.loadbal); # ifdef MPI_TIMING global_mpi.stop = MPI_Wtime(); io_logging_msg(global_io.log, INT32_C(1), "Distributing done in %fs", global_mpi.stop-global_mpi.start); global_mpi.start = global_mpi.stop; # else io_logging_msg(global_io.log, INT32_C(1), "Distributing done."); # endif io_logging_msg(global_io.log, INT32_C(0), "Having %"PRIu64" particles!", global_info.no_part); /* Do the AHF distribution*/ io_logging_subsection(global_io.log, "AHF distribution (duplicating)"); newparts = comm_dist_part_ahf(global_io.log, &(global_info.fst_part), &(global_info.no_part), global_info.loadbal); io_logging_msg(global_io.log, INT32_C(0), "Received %"PRIu64" new particles.", newparts); /* We need to sort the particles again */ qsort(global_info.fst_part, global_info.no_part, sizeof(part), &cmp_sfckey_part); # ifdef MPI_TIMING global_mpi.stop = MPI_Wtime(); io_logging_msg(global_io.log, INT32_C(1), "AHF distribution done in %fs", global_mpi.stop-global_mpi.start); global_mpi.start = global_mpi.stop; # else io_logging_msg(global_io.log, INT32_C(1), "AHF distribution done."); # endif timing.distribution += time(NULL); # endif /* WITH_MPI */ #ifdef AHFsplit_only /*==================================================================== * we only split the data using the SFC and * dump the data into multilpe files *====================================================================*/ { io_file_t dumpf; io_file_strg_struct_t strg; char *fname; /* Start tge section */ io_logging_section(global_io.log, "Dumping AHF chunk to file"); /* First generate the filename */ fname = (char *)malloc( sizeof(char) *( strlen(global_io.params->outfile_prefix)+30)); if (fname == NULL) { io_logging_memfatal(global_io.log, "filename string"); common_terminate(EXIT_FAILURE); } sprintf(fname, "%s.chunk.%04i.dump", global_io.params->outfile_prefix, global_mpi.rank); io_logging_msg(global_io.log, UINT32_C(0), "Used filename: %s", fname); fflush(NULL); MPI_Barrier(MPI_COMM_WORLD); /* Assign particles to structure */ strg.posx.val = (void *)(global_info.fst_part->pos); strg.posx.stride = (char *)((global_info.fst_part+1)->pos ) - (char *)(global_info.fst_part->pos); strg.posy.val = (void *)(global_info.fst_part->pos+1); strg.posy.stride = (char *)((global_info.fst_part+1)->pos+1) - (char *)(global_info.fst_part->pos+1); strg.posz.val = (void *)(global_info.fst_part->pos+2); strg.posz.stride = (char *)((global_info.fst_part+1)->pos+2) - (char *)(global_info.fst_part->pos+2); strg.momx.val = (void *)(global_info.fst_part->mom); strg.momx.stride = (char *)((global_info.fst_part+1)->mom ) - (char *)(global_info.fst_part->mom); strg.momy.val = (void *)(global_info.fst_part->mom+1); strg.momy.stride = (char *)((global_info.fst_part+1)->mom+1) - (char *)(global_info.fst_part->mom+1); strg.momz.val = (void *)(global_info.fst_part->mom+2); strg.momz.stride = (char *)((global_info.fst_part+1)->mom+2) - (char *)(global_info.fst_part->mom+2); # ifdef MULTIMASS strg.weight.val = (void *)&(global_info.fst_part->weight); strg.weight.stride = (char *)&((global_info.fst_part+1)->weight) - (char *)&(global_info.fst_part->weight); # else strg.weight.val = NULL; strg.weight.stride = (ptrdiff_t)0; # endif /* MULTIMASS */ # ifdef GAS_PARTICLES strg.u.val = (void *)&(global_info.fst_part->u); strg.u.stride = (char *)&((global_info.fst_part+1)->u) - (char *)&(global_info.fst_part->u); # else strg.u.val = NULL; strg.u.stride = (ptrdiff_t)0; # endif /* GAS_PARTICLE */ # if (defined AHFlean && defined AHF_NO_PARTICLES) strg.id.val = NULL; strg.id.stride = (ptrdiff_t)0; # else strg.id.val = &(global_info.fst_part->id); strg.id.stride = (char *)&((global_info.fst_part+1)->id) - (char *)&(global_info.fst_part->id); # endif strg.bytes_float = sizeof(global_info.fst_part->pos[0]); # if (defined AHFlean && defined AHF_NO_PARTICLES) strg.bytes_int = 0; # else strg.bytes_int = sizeof(global_info.fst_part->id); # endif /* Open the dump file now */ dumpf = io_file_open(global_io.log, fname, IO_FILE_ARES, IO_FILE_UNKOWN_SWAPPING, IO_FILE_WRITE, 0); /* Write the particles */ io_file_writepart(global_io.log, dumpf, 0, global_info.no_part, strg); /* Set the header values */ ((io_ares_t)dumpf)->header->no_part = (uint64_t)simu.no_part; ((io_ares_t)dumpf)->header->no_species = UINT64_C(0); ((io_ares_t)dumpf)->header->no_vpart = simu.no_vpart; ((io_ares_t)dumpf)->header->boxsize = simu.boxsize; ((io_ares_t)dumpf)->header->omega0 = simu.omega0; ((io_ares_t)dumpf)->header->lambda0 = simu.lambda0; ((io_ares_t)dumpf)->header->pmass = simu.pmass; ((io_ares_t)dumpf)->header->minweight = simu.min_weight; ((io_ares_t)dumpf)->header->maxweight = simu.max_weight; ((io_ares_t)dumpf)->header->a_initial = simu.a_initial; ((io_ares_t)dumpf)->header->a_current = global.a; ((io_ares_t)dumpf)->header->timestep = timestep; ((io_ares_t)dumpf)->header->minkey = global_info.loadbal->fstkey[global_mpi.rank]; ((io_ares_t)dumpf)->header->maxkey = global_info.loadbal->lstkey[global_mpi.rank]; ((io_ares_t)dumpf)->header->lb_level = global_info.loadbal->level; ((io_ares_t)dumpf)->header->rank = global_mpi.rank; ((io_ares_t)dumpf)->header->size = global_mpi.size; /* Log the file */ io_file_log(global_io.log, dumpf); /* Close the file and clean up*/ io_file_close(global_io.log, &dumpf); free(fname); } common_terminate(EXIT_SUCCESS); #endif /* AHFsplit_only */ #ifdef AHF_DUMP_AFTER_READ_TO_ASCII /*==================================================================== * write an ASCII file of the data just read *====================================================================*/ { FILE *dumpf; char *fname; /* First generate the filename */ fname = (char *)malloc( sizeof(char) *( strlen(global_io.params->outfile_prefix)+35)); if (fname == NULL) { io_logging_memfatal(global_io.log, "filename string"); common_terminate(EXIT_FAILURE); } #ifdef WITH_MPI sprintf(fname, "%s.chunk.%04i.ascii", global_io.params->outfile_prefix, global_mpi.rank); #else sprintf(fname, "%s.DUMP.ascii", global_io.params->outfile_prefix); #endif io_logging_msg(global_io.log, UINT32_C(0), "Used filename: %s", fname); fflush(NULL); #ifdef WITH_MPI MPI_Barrier(MPI_COMM_WORLD); #endif dumpf = fopen(fname, "w"); fprintf(dumpf, "# x y z vx vy vz ID\n"); for (uint64_t i=0L; i<global_info.no_part; i++) { fprintf(dumpf, "%15e %15e %15e %15e %15e %15e %lu\n", global_info.fst_part[i].pos[0], global_info.fst_part[i].pos[1], global_info.fst_part[i].pos[2], global_info.fst_part[i].mom[0], global_info.fst_part[i].mom[1], global_info.fst_part[i].mom[2], (unsigned long)global_info.fst_part[i].id); } fclose(dumpf); common_terminate(EXIT_SUCCESS); } #endif #ifdef WITH_MPI loadbalance_minimalMemory(global_io.log, global_info.loadbal); #endif io_logging_msg(global_io.log, INT32_C(5), "amiga_main: running with %" PRIu64 " particles", global_info.no_part); io_logging_part(global_io.log, "Handing over logging to AMIGA"); timing.io += time(NULL); /*===================================================================== * at this point we completely read in the data file * and are ready to proceed with generating the * grid hierarchy or what else we plan to do... *=====================================================================*/ /*==================================================================== * GENERATE THE FULL BLOWN AMR HIERARCHY AND ORGANIZE IT INTO A TREE *====================================================================*/ #ifdef NEWAMR /* 1. organize the particles into a tree */ generate_tree(global_info.no_part, global_info.fst_part, simu.Nth_dom); /* 2. percolate the tree to find isolated patches on each level */ /* 3. transfer isolated patches to halo structures */ #else /* NEWAMR */ /*===================================================================== * generate the domain grids: simu.NGRID_MIN^3, ...., simu.NGRID_DOM^3 *=====================================================================*/ timing.gendomgrids -= time(NULL); grid_list = gen_domgrids(&no_grids); timing.gendomgrids += time(NULL); /*===================================================================== * build initial linked list *=====================================================================*/ timing.ll -= time(NULL); ll(global_info.no_part, global_info.fst_part, global.dom_grid); global.fst_part = global_info.fst_part; global.no_part = global_info.no_part; timing.ll += time(NULL); /*================================================================ * assign particles to the domain grid with simu.NGRID_DOM^3 nodes *================================================================*/ zero_dens(global.dom_grid); assign_npart(global.dom_grid); /*================================================================ * initialize some counters *================================================================*/ no_timestep = no_first_timestep+1; /* count total number of integration steps */ global.total_time = 0.; /* cumulative total time for simulation */ global.output_count = 0; /* count the number of outputs */ /* make *current* time step available to AHF/etc. routines */ global.no_timestep = no_first_timestep; /*========================================================================================= * recursively call gen_AMRhierarchy() to generate the AMR hierarchy... *=========================================================================================*/ global.fst_cycle = TRUE; gen_AMRhierarchy(&grid_list, &no_grids); /*========================================================================================= * eventually perform AHF analysis of AMR hierarchy *=========================================================================================*/ ahf.time -= time(NULL); /* get spatially connected refinement patches */ timing.ahf_gridinfo -= time(NULL); ahf_gridinfo(grid_list, no_grids-1); timing.ahf_gridinfo += time(NULL); /* get AHF halos */ timing.ahf_halos -= time(NULL); ahf_halos(grid_list); timing.ahf_halos += time(NULL); ahf.time += time(NULL); /*========================================================================================= * update logfile and say bye-bye *=========================================================================================*/ write_logfile(timecounter, timestep, no_timestep); /* free all allocated memory... */ free(grid_list); #endif /* NEWAMR */ /*============================================================================ * BYE BYE! *============================================================================*/ free(io.icfile_name); free(io.dumpfile_name); free(io.logfile_name); free(io.outfile_prefix); free(global.termfile_name); free(global.fst_part); if(global.fst_gas) free(global.fst_gas); if(global.fst_star) free(global.fst_star); fprintf(io.logfile, "==========================================================\n"); fprintf(io.logfile, " FINISHED (v%3.1f/%03d)\n",VERSION,BUILD); fprintf(io.logfile, "==========================================================\n"); fclose(io.logfile); # ifdef WITH_MPI /* Gracefully terminate MPI */ MPI_Finalize(); # endif return EXIT_SUCCESS; }
/*============================================================================== * MAIN: where everything starts .... *==============================================================================*/ int main(int argc, char **argv) { FILE *fpout; char AMIGA_input[MAXSTRING], outfile[MAXSTRING]; int no_timestep; double timecounter; double timestep; uint64_t Nobserver; uint64_t iobserver, jobserver; partptr cur_part; double Rsphere,Rsphere_min,Rsphere_max,Rfrac; int Nspheres; uint64_t isphere; int iseed=ISEED; HALO halo; double x_fac, r_fac, v_fac; uint64_t ineighbour; double dx,dy,dz,d; double vx,vy,vz,vlos; double Hubble; double *Hlos, *Hsphere, *sigmaHsphere; uint64_t norm; int omp_id; time_t elapsed = (time_t)0; #ifdef OBSERVER_FROM_FILE FILE *fpin; char observer_file[MAXSTRING], line[MAXSTRING]; double *xobs, *yobs, *zobs, *vxobs, *vyobs, *vzobs; int idummy; #endif //======================================================== // deal with command line //======================================================== #ifdef OBSERVER_FROM_FILE if(argc<6) { fprintf(stderr,"usage: %s sigmaH.input observer_file Nspheres Rsphere_min Rsphere_max\n", argv[0]); fprintf(stderr," or %s --parameterfile\n", argv[0]); exit(1); } #else if(argc<6) { fprintf(stderr,"usage: %s sigmaH.input Nobserver Nspheres Rsphere_min Rsphere_max\n", argv[0]); fprintf(stderr," or %s --parameterfile\n", argv[0]); exit(1); } #endif // maybe the user only wants the parameterfile? if(strcmp(argv[1],"--parameterfile") == 0) { global_io.params = (io_parameter_t) calloc(1,sizeof(io_parameter_struct_t)); global_io.params->outfile_prefix = (char *) calloc(MAXSTRING,sizeof(char)); global.a = 1; strcpy(global_io.params->outfile_prefix,"AHF"); write_parameterfile(); exit(0); } else { strcpy(AMIGA_input, argv[1]); Nspheres = (uint64_t) atoi(argv[3]); Rsphere_min = (double) atof(argv[4]); Rsphere_max = (double) atof(argv[5]); #ifdef OBSERVER_FROM_FILE strcpy(observer_file, argv[2]); #else Nobserver = (uint64_t) atoi(argv[2]); #endif } #ifdef OBSERVER_FROM_FILE //======================================================== // get observers from file //======================================================== fpin = fopen(observer_file,"r"); if(fpin == NULL) { fprintf(stderr,"FATAL: cannot open %s for reading\n",observer_file); exit(0); } Nobserver = 0; xobs = NULL; yobs = NULL; zobs = NULL; vxobs = NULL; vyobs = NULL; vzobs = NULL; // read first line fgets(line,MAXSTRING,fpin); while(!feof(fpin)) { if(strncmp(line,"#",1) != 0) { Nobserver++; xobs = (double *) realloc(xobs, Nobserver*sizeof(double)); yobs = (double *) realloc(yobs, Nobserver*sizeof(double)); zobs = (double *) realloc(zobs, Nobserver*sizeof(double)); vxobs = (double *) realloc(vxobs,Nobserver*sizeof(double)); vyobs = (double *) realloc(vyobs,Nobserver*sizeof(double)); vzobs = (double *) realloc(vzobs,Nobserver*sizeof(double)); // scan line for positions and velocities (if there are no velocities, do not try to use them!) // generic input format // sscanf(line,"%lf %lf %lf %lf %lf %lf", // (xobs+(Nobserver-1)), // (yobs+(Nobserver-1)), // (zobs+(Nobserver-1)), // (vxobs+(Nobserver-1)), // (vyobs+(Nobserver-1)), // (vzobs+(Nobserver-1)) ); // void files from Stefan sscanf(line,"%d %lf %lf %lf", &idummy, (xobs+(Nobserver-1)), (yobs+(Nobserver-1)), (zobs+(Nobserver-1))); vxobs[Nobserver-1] = 0.0; vyobs[Nobserver-1] = 0.0; vzobs[Nobserver-1] = 0.0; } // read next line fgets(line,MAXSTRING,fpin); } fclose(fpin); #endif //======================================================== // startrun //======================================================== elapsed = (time_t)0; elapsed -= time(NULL); timing.io -= time(NULL); timing.startrun -= time(NULL); startrun((argc > 1) ? argv[1] : NULL, &timecounter, ×tep, &no_timestep); timing.startrun += time(NULL); timing.io += time(NULL); fprintf(stderr,"\nsigmaH parameters:\n"); fprintf(stderr,"------------------\n"); fprintf(stderr,"Nobserver = %"PRIu64"\n",Nobserver); fprintf(stderr,"Nspheres = %d\n",Nspheres); fprintf(stderr,"Rsphere_min = %lf\n",Rsphere_min); fprintf(stderr,"Rsphere_max = %lf\n\n",Rsphere_max); elapsed += time(NULL); fprintf(stderr,"o startrun done in %ld sec.\n",elapsed); // some relevant stuff global.fst_part = global_info.fst_part; //======================================================== // generate SFC keys //======================================================== elapsed = (time_t)0; elapsed -= time(NULL); fprintf(stderr,"o generating sfc keys ... "); timing.sfckey -= time(NULL); for (uint64_t i=0; i<global_info.no_part; i++) { partptr part=global_info.fst_part+i; part->sfckey = sfc_curve_calcKey(global_info.ctype, (double)(part->pos[0]), (double)(part->pos[1]), (double)(part->pos[2]), BITS_PER_DIMENSION); } // sorting all particles to have fast access later on qsort(global_info.fst_part, global_info.no_part, sizeof(part), &cmp_sfckey_part); timing.sfckey += time(NULL); elapsed += time(NULL); fprintf(stderr," done in %ld sec.\n",elapsed); //======================================================== // analysis //======================================================== elapsed = (time_t)0; elapsed -= time(NULL); fprintf(stderr,"o placing observers:\n"); ahf.time -= time(NULL); // derive mean Hlos for every observer and every sphere radius //============================================================= // dump observer positions to file sprintf(outfile,"%s-Nobserver%07"PRIu64,global_io.params->outfile_prefix,Nobserver); fpout = fopen(outfile,"w"); if(fpout == NULL) { fprintf(stderr,"FATAL: cannot open %s for writing\n",outfile); exit(0); } // prepare some conversion factors x_fac = simu.boxsize; r_fac = simu.boxsize * global.a; v_fac = simu.boxsize / simu.t_unit / global.a; //NOTE: AHF stores a^2 \dot{x} as velocity!!!! Hubble = calc_Hubble(global.a); // [km/sec/Mpc] fprintf(stderr," Hubble = %lf\n",Hubble); fprintf(stderr," boxsize = %lf\n",simu.boxsize); fprintf(stderr," a = %lf\n",global.a); fprintf(stderr," r_fac = %lf\n",r_fac); fprintf(stderr," v_fac = %lf\n",v_fac); // array to hold all Hlos values Hlos = (double *) calloc(Nobserver*Nspheres, sizeof(double)); #ifdef WITH_OPENMP // obtain thread number to serve as seed omp_id = omp_get_thread_num(); iseed *= omp_id; #endif // loop over all observers #ifdef WITH_OPENMP #pragma omp parallel for schedule(dynamic) private(jobserver,iobserver,cur_part,halo,isphere,Rsphere,ineighbour,dx,dy,dz,d,vx,vy,vz,vlos,iseed,norm) shared(Hlos,Nobserver,global_info,v_fac,r_fac) #endif for(iobserver=0; iobserver<Nobserver; iobserver++) { /*=========================================================== * OBSERVER_FROM_FILE *===========================================================*/ #ifdef OBSERVER_FROM_FILE halo.pos.x = xobs[iobserver] /x_fac; halo.pos.y = yobs[iobserver] /x_fac; halo.pos.z = zobs[iobserver] /x_fac; halo.vel.x = vxobs[iobserver] /v_fac; halo.vel.y = vyobs[iobserver] /v_fac; halo.vel.z = vzobs[iobserver] /v_fac; #endif // OBSERVER_FROM_FILE /*=========================================================== * OBSERVER_CLOSEST_RANDOM_HALO *===========================================================*/ #ifdef OBSERVER_CLOSEST_RANDOM_HALO // pick random position throughout box halo.pos.x = (float)(ran3(&iseed)); halo.pos.y = (float)(ran3(&iseed)); halo.pos.z = (float)(ran3(&iseed)); halo.npart = 0; Rfrac = 0.25; while(halo.npart == 0) { #ifdef DEBUG fprintf(stderr," observer at %f %f %f\n",halo.pos.x*simu.boxsize,halo.pos.y*simu.boxsize,halo.pos.z*simu.boxsize); #endif // search for neighbours about that position halo.gatherRad = Rfrac*Rsphere_min/simu.boxsize; halo.npart = 0; halo.ipart = NULL; ahf_halos_sfc_gatherParts(&halo); #ifdef DEBUG fprintf(stderr," -> found %ld nearest neighbours to observer\n",halo.npart); #endif // pick closest particle if(halo.npart > 0) { sort_halo_particles(&halo); cur_part = global_info.fst_part + halo.ipart[0]; #ifdef DEBUG fprintf(stderr," -> using ipart=%ld\n",halo.ipart[0]); #endif } else { Rfrac *= 2.; #ifdef DEBUG fprintf(stderr," -> increasing neighbour search radius to %lf\n",Rfrac*Rsphere_min); #endif } } // remove from halo structure again if(halo.npart > 0) free(halo.ipart); halo.ipart = NULL; halo.npart = 0; // prepare halo structure as we are re-using ahf_halos_sfc_gatherParts() halo.pos.x = cur_part->pos[X]; halo.pos.y = cur_part->pos[Y]; halo.pos.z = cur_part->pos[Z]; halo.vel.x = cur_part->mom[X]; halo.vel.y = cur_part->mom[Y]; halo.vel.z = cur_part->mom[Z]; #endif // OBSERVER_CLOSEST_RANDOM_HALO /*=========================================================== * OBSERVER_RANDOM_HALO *===========================================================*/ #ifdef OBSERVER_RANDOM_HALO // pick a random particle as the observer jobserver = (uint64_t) (ran3(&iseed) * global_info.no_part); while(jobserver >= global_info.no_part) jobserver = (uint64_t) (ran3(&iseed) * global_info.no_part); cur_part = global_info.fst_part + jobserver; // prepare halo structure as we are re-using ahf_halos_sfc_gatherParts() halo.pos.x = cur_part->pos[X]; halo.pos.y = cur_part->pos[Y]; halo.pos.z = cur_part->pos[Z]; //fprintf(stderr,"cur_part=%ld jobserver=%ld global_info.no_part=%ld global_info.fst_part=%ld...",cur_part,jobserver,global_info.no_part,global_info.fst_part); halo.vel.x = cur_part->mom[X]; halo.vel.y = cur_part->mom[Y]; halo.vel.z = cur_part->mom[Z]; //fprintf(stderr,"set\n"); #endif /*=========================================================== * OBSERVER_RANDOM_POINT *===========================================================*/ #ifdef OBSERVER_RANDOM_POINT halo.pos.x = (float)(ran3(&iseed)); halo.pos.y = (float)(ran3(&iseed)); halo.pos.z = (float)(ran3(&iseed)); halo.vel.x = 0.0; halo.vel.y = 0.0; halo.vel.z = 0.0; #endif /*=========================================================== * OBSERVER_AT_REST *===========================================================*/ #ifdef OBSERVER_AT_REST halo.vel.x = 0.0; halo.vel.y = 0.0; halo.vel.z = 0.0; #endif fprintf(fpout,"%f %f %f %f %f %f\n", halo.pos.x*simu.boxsize, halo.pos.y*simu.boxsize, halo.pos.z*simu.boxsize, halo.vel.x*v_fac, halo.vel.y*v_fac, halo.vel.z*v_fac); fflush(fpout); /*=========================================================== * SPHERE LOOP *===========================================================*/ // loop over all spheres for this observer for(isphere=0; isphere<Nspheres; isphere++) { // sphere radius in internal units Rsphere = (Rsphere_min + (double)isphere*(Rsphere_max-Rsphere_min)/((double)(Nspheres-1)))/simu.boxsize; // add gathering radius and prepare array to hold neighbours halo.gatherRad = Rsphere; halo.npart = 0; halo.ipart = NULL; // collect all particles inside the gathering radius ahf_halos_sfc_gatherParts(&halo); #ifdef DEBUG fprintf(stderr," (sfc gathered %ld neighbours)",halo.npart); #endif // perform statistic for all neighbours Hlos[Hidx(isphere,iobserver,Nspheres)] = 0.0; norm = 0; for(ineighbour=0; ineighbour<halo.npart; ineighbour++) { cur_part = global_info.fst_part+halo.ipart[ineighbour]; // 3D distance dx = (cur_part->pos[X] - halo.pos.x); dy = (cur_part->pos[Y] - halo.pos.y); // distance in internal units dz = (cur_part->pos[Z] - halo.pos.z); if (dx > 0.5) dx -= 1.0; if (dy > 0.5) dy -= 1.0; if (dz > 0.5) dz -= 1.0; if (dx < -0.5) dx += 1.0; // take care of periodic boundary conditions if (dy < -0.5) dy += 1.0; if (dz < -0.5) dz += 1.0; dx *= r_fac; dy *= r_fac; // distance (eventually) in physical units dz *= r_fac; d = sqrt(pow2(dx)+pow2(dy)+pow2(dz)); // 3D velocity vx = (cur_part->mom[X] - halo.vel.x) * v_fac; vy = (cur_part->mom[Y] - halo.vel.y) * v_fac; // peculiar velocity in physical units vz = (cur_part->mom[Z] - halo.vel.z) * v_fac; vx += Hubble * (dx); vy += Hubble * (dy); // add correct Hubble flow vz += Hubble * (dz); // line-of-sight velocity as measured by present observer vlos = (vx*dx + vy*dy + vz*dz)/d; // accumulate Hlos if(d > MACHINE_ZERO) { // Hubble parameter as measured by present observer Hlos[Hidx(isphere,iobserver,Nspheres)] += vlos/d; norm++; } } // ineighbour // mean Hlos for this sphere if(norm > 0) Hlos[Hidx(isphere,iobserver,Nspheres)] /= (double)norm; else Hlos[Hidx(isphere,iobserver,Nspheres)] = -1.; // physically remove particles from memory if(halo.ipart) { free(halo.ipart); halo.npart = 0; halo.ipart = NULL; } } // isphere } // iobserver fclose(fpout); elapsed += time(NULL); fprintf(stderr," done in %ld sec.\n",elapsed); // collapse Hlos values obtaining mean and stddev for every sphere //================================================================= elapsed = (time_t)0; elapsed -= time(NULL); fprintf(stderr,"o calculating means and stddevs ... "); Hsphere = (double *) calloc(Nspheres, sizeof(double)); sigmaHsphere = (double *) calloc(Nspheres, sizeof(double)); #ifdef WITH_OPENMP #pragma omp parallel for schedule(static) private(isphere,iobserver) shared(Nobserver,Hlos,Hsphere) #endif for(isphere=0; isphere<Nspheres; isphere++) { norm = 0; for(iobserver=0; iobserver<Nobserver; iobserver++) { if(Hlos[Hidx(isphere,iobserver,Nspheres)] > 0.) { Hsphere[isphere] += Hlos[Hidx(isphere,iobserver,Nspheres)]; norm++; } } if(norm > 0) Hsphere[isphere] /= (double)norm; else Hsphere[isphere] = -1.; } #ifdef WITH_OPENMP #pragma omp parallel for schedule(static) private(isphere,iobserver) shared(Nobserver,Hlos,Hsphere,Hubble) #endif for(isphere=0; isphere<Nspheres; isphere++) { norm = 0; for(iobserver=0; iobserver<Nobserver; iobserver++) { if(Hsphere[isphere] > 0.) { sigmaHsphere[isphere] += pow2((Hsphere[isphere]-Hubble)/Hubble); norm++; } } if(norm > 0) sigmaHsphere[isphere] /= (double)norm; else sigmaHsphere[isphere] -1.; } elapsed += time(NULL); fprintf(stderr," done in %ld sec.\n",elapsed); ahf.time += time(NULL); //======================================================== // output //======================================================== elapsed = (time_t)0; elapsed -= time(NULL); // full information for each sphere //================================== for(isphere=0; isphere<Nspheres; isphere++) { // sphere radius Rsphere = (Rsphere_min + (double)isphere*(Rsphere_max-Rsphere_min)/((double)(Nspheres-1))); // construct outfile name sprintf(outfile,"%s-Nobserver%07"PRIu64"-Nspheres%03d-Rpshere%lf",global_io.params->outfile_prefix,Nobserver,Nspheres,Rsphere); fprintf(stderr,"o writing Rsphere=%lf information to: %s ... ",Rsphere,outfile); // open output file fpout = fopen(outfile,"w"); if(fpout == NULL) { fprintf(stderr,"FATAL: cannot open %s for writing\n",outfile); exit(0); } fprintf(fpout,"# Hlos(1)\n"); for(iobserver=0; iobserver<Nobserver; iobserver++) { fprintf(fpout,"%lf\n",Hlos[Hidx(isphere,iobserver,Nspheres)]); } } fclose(fpout); // reduced information //===================== sprintf(outfile,"%s-Nobserver%07"PRIu64"-Nspheres%03d-Rsphere_min%lf-Rpshere_max%lf",global_io.params->outfile_prefix,Nobserver,Nspheres,Rsphere_min,Rsphere_max); fprintf(stderr,"o writing sphere information to: %s ... ",outfile); // open output file fpout = fopen(outfile,"w"); if(fpout == NULL) { fprintf(stderr,"FATAL: cannot open %s for writing\n",outfile); exit(0); } fprintf(fpout,"# Rsphere(1) Hsphere(2) sigmaH(3)\n"); for(isphere=0; isphere<Nspheres; isphere++) { Rsphere = (Rsphere_min + (double)isphere*(Rsphere_max-Rsphere_min)/((double)(Nspheres-1))); fprintf(fpout,"%lf %lf %lf\n",Rsphere,Hsphere[isphere],sigmaHsphere[isphere]); } fclose(fpout); elapsed += time(NULL); fprintf(stderr," done in %ld sec.\n",elapsed); //======================================================== // update logfile //======================================================== //write_logfile(timecounter, timestep, no_timestep); //======================================================== // BYE BYE //======================================================== free(Hlos); free(Hsphere); free(sigmaHsphere); #ifdef OBSERVER_FROM_FILE free(xobs); free(yobs); free(zobs); free(vxobs); free(vyobs); free(vzobs); #endif if(io.icfile_name) free(io.icfile_name); if(io.dumpfile_name) free(io.dumpfile_name); if(io.logfile_name) free(io.logfile_name); if(io.outfile_prefix) free(io.outfile_prefix); if(global.termfile_name) free(global.termfile_name); if(global.fst_part) free(global.fst_part); if(global.fst_gas) free(global.fst_gas); if(global.fst_star) free(global.fst_star); fprintf(io.logfile, "==========================================================\n"); fprintf(io.logfile, " FINISHED (v%3.1f/%03d)\n",VERSION,BUILD); fprintf(io.logfile, "==========================================================\n"); fclose(io.logfile); return EXIT_SUCCESS; }