void construct_galaxies(int halonr, int tree) { static int halosdone = 0; int prog, fofhalo, ngal; HaloAux[halonr].DoneFlag = 1; halosdone++; prog = Halo[halonr].FirstProgenitor; while(prog >= 0) { if(HaloAux[prog].DoneFlag == 0) construct_galaxies(prog, tree); prog = Halo[prog].NextProgenitor; } fofhalo = Halo[halonr].FirstHaloInFOFgroup; if(HaloAux[fofhalo].HaloFlag == 0) { HaloAux[fofhalo].HaloFlag = 1; while(fofhalo >= 0) { prog = Halo[fofhalo].FirstProgenitor; while(prog >= 0) { if(HaloAux[prog].DoneFlag == 0) construct_galaxies(prog, tree); prog = Halo[prog].NextProgenitor; } fofhalo = Halo[fofhalo].NextHaloInFOFgroup; } } // At this point, the galaxies for all progenitors of this halo have been // properly constructed. Also, the galaxies of the progenitors of all other // halos in the same FOF group have been constructed as well. We can hence go // ahead and construct all galaxies for the subhalos in this FOF halo, and // evolve them in time. fofhalo = Halo[halonr].FirstHaloInFOFgroup; if(HaloAux[fofhalo].HaloFlag == 1) { ngal = 0; HaloAux[fofhalo].HaloFlag = 2; while(fofhalo >= 0) { ngal = join_galaxies_of_progenitors(fofhalo, ngal); fofhalo = Halo[fofhalo].NextHaloInFOFgroup; } evolve_galaxies(Halo[halonr].FirstHaloInFOFgroup, ngal, tree); } }
/**@brief Main routine of L-Galaxies*/ int main(int argc, char **argv) { int filenr, *FileToProcess, *TaskToProcess, nfiles; char buf[1000]; time_t start, current; #ifdef PARALLEL MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask); MPI_Comm_size(MPI_COMM_WORLD, &NTask); #else NTask = 1; ThisTask = 0; #endif //PARALLEL #ifdef MCMC time(&global_starting_time); #endif if(ThisTask==0) { printf("\n\n\n"); printf("**************************************************************************\n"); printf("* *\n"); printf("* Copyright (C) <2016> <L-Galaxies> *\n"); printf("* *\n"); printf("* This program is free software: you can redistribute it and/or modify *\n"); printf("* it under the terms of the GNU General Public License as published by *\n"); printf("* the Free Software Foundation, either version 3 of the License, or *\n"); printf("* (at your option) any later version. *\n"); printf("* *\n"); printf("* This program is distributed in the hope that it will be useful, *\n"); printf("* but WITHOUT ANY WARRANTY; without even the implied warranty of *\n"); printf("* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\n"); printf("* GNU General Public License for more details. *\n"); printf("* *\n"); printf("* You should have received a copy of the GNU General Public License *\n"); printf("* along with this program. If not, see <http://www.gnu.org/licenses/> *\n"); printf("* *\n"); printf("**************************************************************************\n\n\n"); } if(argc > 3 || argc<2) { printf("\n Wrong number of runtime arguments\n\n"); printf("\n usage: ./L-Galaxies <parameterfile>\n\n"); endrun(0); } if (ThisTask == 0) printf("%s\n",COMPILETIMESETTINGS); /* check compatibility of some Makefile Options*/ check_options(); /*Reads the parameter file, given as an argument at run time. */ read_parameter_file(argv[1]); #ifdef MR_PLUS_MRII //Start with MR files and later change to MRII LastDarkMatterSnapShot=LastDarkMatterSnapShot_MR; sprintf(FileWithZList, "%s", FileWithZList_MR); sprintf(FileWithZList_OriginalCosm, "%s", FileWithZList_OriginalCosm_MR); #endif mymalloc_init(); sprintf(FinalOutputDir, "%s", OutputDir); #ifndef MCMC if(argc == 3) sprintf(OutputDir, "%s", argv[2]); #else FirstChainNumber=0; if(argc == 3) FirstChainNumber=atoi(argv[2]); #endif //time(&start); #ifdef COMPUTE_SPECPHOT_PROPERTIES //for dust_model mu_seed = -150; #endif init(); #ifdef STAR_FORMATION_HISTORY #ifdef PARALLEL if(ThisTask == 0) #endif write_sfh_bins(); #endif #ifndef MCMC nfiles=get_nr_files_to_process(ThisTask); FileToProcess=mymalloc("FileToProcess", sizeof(int) * nfiles); TaskToProcess=mymalloc("TaskToProcess", sizeof(int) * nfiles); assign_files_to_tasks(FileToProcess, TaskToProcess, ThisTask, NTask, nfiles); int file; for(file = 0; file < nfiles; file++) { if(ThisTask==TaskToProcess[file]) filenr=FileToProcess[file]; else continue; #else //MCMC /* In MCMC mode only one file is loaded into memory * and the sampling for all the steps is done on it */ sprintf(SimulationDir, "%s/", SimulationDir); for(filenr = MCMCTreeSampleFile; filenr <= MCMCTreeSampleFile; filenr++) { #endif //MCMC time(&start); #ifdef PARALLEL #ifndef MCMC time_t current; do time(¤t); //while(difftime(current, start) < 5.0 * ThisTask); while(difftime(current, start) < 1.0 * ThisTask); #endif #endif load_tree_table(filenr); #ifdef MCMC Senna(); // run the model in MCMC MODE #else SAM(filenr); // run the model in NORMAL MODE #endif #ifdef MCMC break; //break loop on files since the MCMC is done on a single file #else time(¤t); printf("\ndone tree file %d in %ldmin and %lds\n\n", filenr, (current - start)/60, (current - start)%60); #endif //MCMC free_tree_table(); //if temporary directory given as argument if(argc == 3) { #ifdef GALAXYTREE sprintf(buf, "mv %s/%s_galtree_%d %s", OutputDir,FileNameGalaxies, filenr, FinalOutputDir); #else sprintf(buf, "mv %s/%s_z*_%d %s", OutputDir,FileNameGalaxies, filenr, FinalOutputDir); #endif system(buf); } } #ifndef MCMC myfree(TaskToProcess); myfree(FileToProcess); #endif #ifdef PARALLEL MPI_Finalize(); #endif return 0; } /**@brief SAM() loops on trees and calls construct_galaxies.*/ #ifdef MCMC double SAM(int filenr) #else void SAM(int filenr) #endif { int treenr, halonr; #ifdef MCMC int ii; MCMC_GAL = mymalloc("MCMC_Gal", sizeof(struct MCMC_GALAXY) * MCMCAllocFactor); for(ii=0;ii<NOUT;ii++) TotMCMCGals[ii] = 0; #ifdef MR_PLUS_MRII change_dark_matter_sim("MR"); #else if(CurrentMCMCStep==1) read_sample_info(); #ifdef HALOMODEL else { int snap, ii; for(snap=0;snap<NOUT;snap++) for(ii=0;ii<NFofsInSample[snap];ii++) MCMC_FOF[ii].NGalsInFoF[snap]=0; } #endif //HALOMODEL #endif //MR_PLUS_MRII #endif //MCMC //to be used when we have tables for the scaling in any cosmology //read_scaling_parameters(); #ifndef MCMC #ifdef GALAXYTREE create_galaxy_tree_file(filenr); #else create_galaxy_files(filenr); #endif #endif #ifdef GALAXYTREE FILE *fdg = fopen("treengal.dat", "w"); #endif //*************************************************************************************** //*************************************************************************************** //for(treenr = 0; treenr < NTrees_Switch_MR_MRII; treenr++) for(treenr = 0; treenr < Ntrees; treenr++) { //printf("doing tree %d of %d\n", treenr, Ntrees); #ifdef MR_PLUS_MRII if(treenr == NTrees_Switch_MR_MRII) change_dark_matter_sim("MRII"); #endif load_tree(treenr); #ifdef MCMC #ifdef PRELOAD_TREES if(CurrentMCMCStep==1) #endif #endif scale_cosmology(TreeNHalos[treenr]); gsl_rng_set(random_generator, filenr * 100000 + treenr); NumMergers = 0; NHaloGal = 0; #ifdef GALAXYTREE NGalTree = 0; IndexStored = 0; #endif int snapnum; //LastSnapShotNr is the highest output snapshot /* we process the snapshots now in temporal order * (as a means to reduce peak memory usage) */ for(snapnum = 0; snapnum <= LastSnapShotNr; snapnum++) { #ifdef MCMC /* read the appropriate parameter list for current snapnum * into the parameter variables to be used in construct_galaxies */ read_mcmc_par(snapnum); #ifdef HALOMODEL //because we need halo masses even for FOFs //with no galaxies it needs to be done here assign_FOF_masses(snapnum, treenr); #endif #endif for(halonr = 0; halonr < TreeNHalos[treenr]; halonr++) if(HaloAux[halonr].DoneFlag == 0 && Halo[halonr].SnapNum == snapnum) construct_galaxies(filenr, treenr, halonr); } /* output remaining galaxies as needed */ while(NHaloGal) output_galaxy(treenr, 0); #ifndef MCMC #ifdef GALAXYTREE save_galaxy_tree_finalize(filenr, treenr); #ifndef PARALLEL if((treenr/100)*100==treenr) printf("treenr=%d TotGalCount=%d\n", treenr, TotGalCount); #endif fflush(stdout); fprintf(fdg, "%d\n", NGalTree); #endif #else//ifdef MCMC #endif free_galaxies_and_tree(); }//loop on trees #ifdef MCMC double lhood = get_likelihood(); #ifdef MR_PLUS_MRII free(MCMC_FOF); #else if(CurrentMCMCStep==ChainLength) free(MCMC_FOF); #endif myfree(MCMC_GAL); return lhood; #else //MCMC #ifdef GALAXYTREE close_galaxy_tree_file(); #else close_galaxy_files(); #endif return; #endif }
/**@brief construct_galaxies() recursively runs the semi-analytic model. * For each halo it checks if its main progenitor has been done, then * if all the halos in the FOF of its main progenitor have been * done and then runs the SAM in the current halo. This means that * for the first time its called it will walk up the tree into the * haloes in the earliest snapshot. * * When it finds a halo that needs to be done it calls * join_galaxies_of_progenitors and evolve_galaxies. */ void construct_galaxies(int filenr, int treenr, int halonr) { static int halosdone = 0; int prog, fofhalo, ngal, cenngal, p; HaloAux[halonr].DoneFlag = 1; halosdone++; prog = Halo[halonr].FirstProgenitor; while(prog >= 0) //If halo has a progenitor { if(HaloAux[prog].DoneFlag == 0) //If progenitor hasn't been done yet construct_galaxies(filenr, treenr, prog); prog = Halo[prog].NextProgenitor; //Jump to next halo in progenitors FOF } //Now check for the progenitors of all the halos in the current FOF group fofhalo = Halo[halonr].FirstHaloInFOFgroup; //Starting at the first halo in current FOF if(HaloAux[fofhalo].HaloFlag == 0) //If it hasn't been done { HaloAux[fofhalo].HaloFlag = 1; //mark as to do while(fofhalo >= 0) //go through all the halos in current FOF { prog = Halo[fofhalo].FirstProgenitor; while(prog >= 0) //build its progenitors { if(HaloAux[prog].DoneFlag == 0) construct_galaxies(filenr, treenr, prog); prog = Halo[prog].NextProgenitor; } fofhalo = Halo[fofhalo].NextHaloInFOFgroup; //Jump to next halo in FOF } } /* At this point, the galaxies for all progenitors of this halo have been * properly constructed. Also, the galaxies of the progenitors of all other * halos in the same FOF-group have been constructed as well. We can hence go * ahead and construct all galaxies for the subhalos in this FOF halo, and * evolve them in time. */ fofhalo = Halo[halonr].FirstHaloInFOFgroup; if(HaloAux[fofhalo].HaloFlag == 1) //If it is marked as an halo to do { ngal = 0; HaloAux[fofhalo].HaloFlag = 2; cenngal = set_merger_center(fofhalo); //Find type 0 for type 1 to merge into /*For all the halos in the current FOF join all the progenitor galaxies together * ngals will be the total number of galaxies in the current FOF*/ while(fofhalo >= 0) { ngal = join_galaxies_of_progenitors(fofhalo, ngal, &cenngal); fofhalo = Halo[fofhalo].NextHaloInFOFgroup; } /*Evolve the Galaxies -> SAM! */ evolve_galaxies(Halo[halonr].FirstHaloInFOFgroup, ngal, treenr, cenngal); for (p =0;p<ngal;p++) mass_checks("Construct_galaxies #1",p); } }
/**@brief Main routine of L-Galaxies*/ int main(int argc, char **argv) { int filenr, *FileToProcess, *TaskToProcess, nfiles; char buf[1000]; time_t start, current; //Catch floating point exceptions #ifdef DEBUG #endif #ifdef PARALLEL MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask); MPI_Comm_size(MPI_COMM_WORLD, &NTask); #else NTask = 1; ThisTask = 0; #endif //PARALLEL #ifdef MCMC time(&global_starting_time); #endif if(argc > 3) { printf("\n usage: L-Galaxies <parameterfile>\n\n"); endrun(0); } if (ThisTask == 0) printf("%s\n",COMPILETIMESETTINGS); /*Reads the parameter file, given as an argument at run time. */ read_parameter_file(argv[1]); #ifdef MR_PLUS_MRII //Start with MR files and later change to MRII LastDarkMatterSnapShot=LastDarkMatterSnapShot_MR; sprintf(FileWithZList, "%s", FileWithZList_MR); sprintf(FileWithZList_OriginalCosm, "%s", FileWithZList_OriginalCosm_MR); #endif mymalloc_init(); sprintf(FinalOutputDir, "%s", OutputDir); if(argc == 3) sprintf(OutputDir, "%s", argv[2]); //time(&start); /* check compatibility of some Makefile Options*/ check_options(); #ifdef COMPUTE_SPECPHOT_PROPERTIES //for dust_model mu_seed = -150; #endif init(); #ifdef STAR_FORMATION_HISTORY #ifdef PARALLEL if(ThisTask == 0) #endif write_sfh_bins(); #endif #ifdef MCMC #ifdef PARALLEL /* a small delay to avoid all processors reading trees at the same time*/ time(&start); do time(¤t); while(difftime(current, start) < 10.0 * ThisTask); #endif #endif #ifndef MCMC nfiles=get_nr_files_to_process(ThisTask); FileToProcess=mymalloc("FileToProcess", sizeof(int) * nfiles); TaskToProcess=mymalloc("TaskToProcess", sizeof(int) * nfiles); assign_files_to_tasks(FileToProcess, TaskToProcess, ThisTask, NTask, nfiles); int file; for(file = 0; file < nfiles; file++) { if(ThisTask==TaskToProcess[file]) filenr=FileToProcess[file]; else continue; #else //MCMC /* In MCMC mode only one file is loaded into memory * and the sampling for all the steps is done on it */ sprintf(SimulationDir, "%s/MergerTrees_%d/", SimulationDir, ThisTask); for(filenr = MCMCTreeSampleFile; filenr <= MCMCTreeSampleFile; filenr++) { #endif //MCMC time(&start); #ifdef READXFRAC get_xfrac_mesh(); #endif load_tree_table(filenr); /* Read in mesh dimensions */ #ifdef MCMC #ifdef PARALLEL time_t start, start2; /* a small delay to reset processors to the same time*/ time(&start2); do time(¤t); while(difftime(current, start2) < 10.0 * (NTask-ThisTask)); #endif Senna(); // run the model in MCMC MODE #else SAM(filenr); // run the model in NORMAL MODE #endif #ifdef MCMC break; //break loop on files since the MCMC is done on a single file #else time(¤t); printf("\ndone tree file %d in %ldmin and %lds\n\n", filenr, (current - start)/60, (current - start)%60); #endif //MCMC free_tree_table(); //if temporary directory given as argument if(argc == 3) { #ifdef GALAXYTREE sprintf(buf, "mv %s/%s_galtree_%d %s", OutputDir,FileNameGalaxies, filenr, FinalOutputDir); #else sprintf(buf, "mv %s/%s_z*_%d %s", OutputDir,FileNameGalaxies, filenr, FinalOutputDir); #endif system(buf); } } #ifndef MCMC myfree(TaskToProcess); myfree(FileToProcess); #endif #ifdef PARALLEL MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); #endif return 0; } /**@brief SAM() loops on trees and calls construct_galaxies.*/ #ifdef MCMC double SAM(int filenr) #else void SAM(int filenr) #endif { int treenr, halonr; time_t t_mark_a, t_mark_b; #ifdef MCMC int ii; MCMC_GAL = mymalloc("MCMC_Gal", sizeof(struct MCMC_GALAXY) * MCMCAllocFactor); for(ii=0;ii<NOUT;ii++) TotMCMCGals[ii] = 0; if(Sample_Cosmological_Parameters==1) { reset_cosmology (); #ifdef HALOMODEL initialize_halomodel(); #endif } #ifdef MR_PLUS_MRII change_dark_matter_sim("MR"); #else if(Sample_Cosmological_Parameters==1 || CurrentMCMCStep==1) read_sample_info(); else { int snap, ii; for(snap=0;snap<NOUT;snap++) for(ii=0;ii<NFofsInSample[snap];ii++) MCMC_FOF[ii].NGalsInFoF[snap]=0; } #endif #endif //to be used when we have tables for the scaling in any cosmology //read_scaling_parameters(); #ifndef MCMC #ifdef GALAXYTREE create_galaxy_tree_file(filenr); #else create_galaxy_files(filenr); #endif #ifdef ALL_SKY_LIGHTCONE int nr; for ( nr = 0; nr < NCONES; nr++) create_galaxy_lightcone_files(filenr, nr); #endif #endif #ifdef GALAXYTREE FILE *fdg = fopen("treengal.dat", "w"); #endif //*************************************************************************************** //*************************************************************************************** //for(treenr = 0; treenr < NTrees_Switch_MR_MRII; treenr++) //for(treenr = NTrees_Switch_MR_MRII; treenr < Ntrees; treenr++) /* Scan through all trees snapshot by snapshot */ int snapnum; //for(treenr = 0; treenr < NTrees_Switch_MR_MRII; treenr++) //for(treenr = NTrees_Switch_MR_MRII; treenr < Ntrees; treenr++) for(treenr = 0; treenr < Ntrees; treenr++) //for(treenr = 0; treenr < 1;treenr++) { //printf("doing tree %d of %d\n", treenr, Ntrees); #ifdef MR_PLUS_MRII if(treenr == NTrees_Switch_MR_MRII) change_dark_matter_sim("MRII"); #endif load_tree(treenr); #ifdef MCMC #ifdef PRELOAD_TREES if(Sample_Cosmological_Parameters==1 || CurrentMCMCStep==0) #endif #endif scale_cosmology(TreeNHalos[treenr]); gsl_rng_set(random_generator, filenr * 100000 + treenr); NumMergers = 0; NHaloGal = 0; #ifdef GALAXYTREE NGalTree = 0; IndexStored = 0; #endif //LastSnapShotNr is the highest output snapshot /* we process the snapshots now in temporal order * (as a means to reduce peak memory usage) */ for(snapnum = 0; snapnum <= LastSnapShotNr; snapnum++) //for(snapnum = 0; snapnum <= 30; snapnum++) { #ifdef MCMC /* read the appropriate parameter list for current snapnum * into the parameter variables to be used in construct_galaxies */ read_mcmc_par(snapnum); #else //used to allow parameter values to vary with redshift //re_set_parameters(snapnum); #endif //printf("doing snap=%d\n",snapnum); for(halonr = 0; halonr < TreeNHalos[treenr]; halonr++) if(HaloAux[halonr].DoneFlag == 0 && Halo[halonr].SnapNum == snapnum) construct_galaxies(filenr, treenr, halonr); } /* output remaining galaxies as needed */ while(NHaloGal) output_galaxy(treenr, 0); #ifndef MCMC #ifdef GALAXYTREE save_galaxy_tree_finalize(filenr, treenr); #ifndef PARALLEL if((treenr/100)*100==treenr) printf("treenr=%d TotGalCount=%d\n", treenr, TotGalCount); #endif fflush(stdout); fprintf(fdg, "%d\n", NGalTree); #endif #else//ifdef MCMC #ifdef PRELOAD_TREES if(Sample_Cosmological_Parameters==1) un_scale_cosmology(TreeNHalos[treenr]); #endif #endif free_galaxies_and_tree(); } #ifdef MCMC double lhood = get_likelihood(); #ifdef MR_PLUS_MRII free(MCMC_FOF); #else if(Sample_Cosmological_Parameters==1 || CurrentMCMCStep==ChainLength) free(MCMC_FOF); #endif #ifdef HALOMODEL if (Sample_Cosmological_Parameters==1) { gsl_spline_free(FofSpline); gsl_interp_accel_free(FofAcc); gsl_spline_free(SigmaSpline); gsl_interp_accel_free(SigmaAcc); gsl_spline_free(ellipSpline); gsl_interp_accel_free(ellipAcc); gsl_spline_free(PowSpline); } //if #endif myfree(MCMC_GAL); return lhood; #else //MCMC #ifdef GALAXYTREE close_galaxy_tree_file(); #else close_galaxy_files(); #endif #ifdef ALL_SKY_LIGHTCONE for (nr = 0; nr < NCONES; nr++) close_galaxy_lightcone_files(nr); #endif return; #endif }