void sfh_initialise(int p) { /* Initialises the sfh-variables for a galaxy */ int i; for (i=0;i<SFH_NBIN;i++){ Gal[p].sfh_dt[i]=0.; Gal[p].sfh_t[i]=0.; Gal[p].sfh_flag[i]=0; Gal[p].sfh_Nbins[i]=0; Gal[p].sfh_DiskMass[i]=0.; Gal[p].sfh_BulgeMass[i]=0.; Gal[p].sfh_ICM[i]=0.; Gal[p].sfh_MetalsDiskMass[i]=metals_init(); Gal[p].sfh_MetalsBulgeMass[i]=metals_init(); Gal[p].sfh_MetalsICM[i]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[i]=elements_init(); Gal[p].sfh_ElementsBulgeMass[i]=elements_init(); Gal[p].sfh_ElementsICM[i]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[i]=0.; #endif } /* Create first bin */ Gal[p].sfh_ibin=0; /* Age is used for comparing galaxies during mergers, * so needs to have a value set in case a merger happens before stars * form (which can happen). */ Gal[p].sfh_age=0.; }
void sfh_merge(int p, int p1) { /* Merge galaxy p1 into galaxy p */ int i; /* Perform minimal test that the two galaxies have the same time structure */ if (Gal[p1].sfh_ibin != Gal[p].sfh_ibin) { printf("sfh_merge: trying to merge galaxies with different sfh bins\n"); sfh_print(p); sfh_print(p1); exit(1); } /* The zero-ing of galaxy p1 here is not strictly necessary as galaxy p1 should * cease to exist after merging, but helps to make mass conservation explicit. */ for(i=0;i<=Gal[p].sfh_ibin;i++) { Gal[p].sfh_DiskMass[i]+=Gal[p1].sfh_DiskMass[i]; Gal[p].sfh_BulgeMass[i]+=Gal[p1].sfh_BulgeMass[i]; Gal[p].sfh_ICM[i]+=Gal[p1].sfh_ICM[i]; Gal[p1].sfh_DiskMass[i]=0.; Gal[p1].sfh_BulgeMass[i]=0.; Gal[p1].sfh_ICM[i]=0.; Gal[p].sfh_MetalsDiskMass[i]= metals_add(Gal[p].sfh_MetalsDiskMass[i],Gal[p1].sfh_MetalsDiskMass[i],1.); Gal[p].sfh_MetalsBulgeMass[i]= metals_add(Gal[p].sfh_MetalsBulgeMass[i],Gal[p1].sfh_MetalsBulgeMass[i],1.); Gal[p].sfh_MetalsICM[i]= metals_add(Gal[p].sfh_MetalsICM[i],Gal[p1].sfh_MetalsICM[i],1.); Gal[p1].sfh_MetalsDiskMass[i]=metals_init(); Gal[p1].sfh_MetalsBulgeMass[i]=metals_init(); Gal[p1].sfh_MetalsICM[i]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[i] = elements_add(Gal[p].sfh_ElementsDiskMass[i],Gal[p1].sfh_ElementsDiskMass[i],1.); Gal[p].sfh_ElementsBulgeMass[i] = elements_add(Gal[p].sfh_ElementsBulgeMass[i],Gal[p1].sfh_ElementsBulgeMass[i],1.); Gal[p].sfh_ElementsICM[i] = elements_add(Gal[p].sfh_ElementsICM[i],Gal[p1].sfh_ElementsICM[i],1.); Gal[p1].sfh_ElementsDiskMass[i]=elements_init(); Gal[p1].sfh_ElementsBulgeMass[i]=elements_init(); Gal[p1].sfh_ElementsICM[i]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[i]+=Gal[p1].sfh_BurstMass[i]; Gal[p1].sfh_BurstMass[i]=0.; #endif } /* Again, not strictly necessary, but safe. */ Gal[p1].sfh_ibin=0; Gal[p1].sfh_age=0.; }
/**@brief Removes h from units of galaxy properties. If desired (makefile option * FIX_OUTPUT_UNITS is set), the output properties of the galaxies can be scaled * to physical units excluding any factors of h == Hubble/100 km/s/Mpc. */ void fix_units_for_ouput(struct GALAXY_OUTPUT *o) { int j; o->Pos[0] /= Hubble_h; o->Pos[1] /= Hubble_h; o->Pos[2] /= Hubble_h; o->CentralMvir /= Hubble_h; o->Mvir /= Hubble_h; o->Rvir /= Hubble_h; #ifdef HALOPROPERTIES o->HaloM_Mean200 /= Hubble_h; o->HaloM_Crit200 /= Hubble_h; o->HaloM_TopHat /= Hubble_h; o->HaloPos[0] /= Hubble_h; o->HaloPos[1] /= Hubble_h; o->HaloPos[2] /= Hubble_h; o->HaloSpin[0] /= Hubble_h; o->HaloSpin[1] /= Hubble_h; o->HaloSpin[2] /= Hubble_h; #endif o->GasSpin[0] /= Hubble_h; o->GasSpin[1] /= Hubble_h; o->GasSpin[2] /= Hubble_h; o->StellarSpin[0] /= Hubble_h; o->StellarSpin[1] /= Hubble_h; o->StellarSpin[2] /= Hubble_h; o->HotRadius /= Hubble_h; o->ColdGas /= Hubble_h; o->DiskMass /= Hubble_h; o->BulgeMass /= Hubble_h; o->HotGas /= Hubble_h; o->EjectedMass /= Hubble_h; o->BlackHoleMass /= Hubble_h; o->ICM /= Hubble_h; o->BulgeSize /= Hubble_h; o->StellarDiskRadius /= Hubble_h; o->GasDiskRadius /= Hubble_h; o->CoolingRadius /= sqrt(Hubble_h); #ifdef TRACK_BURST o->BurstMass /= Hubble_h; #endif o->MetalsColdGas=metals_add(metals_init(),o->MetalsColdGas,1./Hubble_h); o->MetalsDiskMass=metals_add(metals_init(),o->MetalsDiskMass,1./Hubble_h); o->MetalsBulgeMass=metals_add(metals_init(),o->MetalsBulgeMass,1./Hubble_h); o->MetalsHotGas=metals_add(metals_init(),o->MetalsHotGas,1./Hubble_h); o->MetalsEjectedMass=metals_add(metals_init(),o->MetalsEjectedMass,1./Hubble_h); o->MetalsICM=metals_add(metals_init(),o->MetalsICM,1./Hubble_h); #ifdef STAR_FORMATION_HISTORY for(j=0;j<=o->sfh_ibin;j++) { o->sfh_DiskMass[j] /= Hubble_h; o->sfh_BulgeMass[j] /= Hubble_h; o->sfh_ICM[j] /= Hubble_h; #ifdef TRACK_BURST o->sfh_BurstMass[j] /= Hubble_h; #endif o->sfh_MetalsDiskMass[j]=metals_add(metals_init(), o->sfh_MetalsDiskMass[j],1./Hubble_h); o->sfh_MetalsBulgeMass[j]=metals_add(metals_init(), o->sfh_MetalsBulgeMass[j],1./Hubble_h); o->sfh_MetalsICM[j]=metals_add(metals_init(), o->sfh_MetalsICM[j],1./Hubble_h); } #endif }
void prepare_galaxy_for_output(int n, struct GALAXY *g, struct GALAXY_OUTPUT *o) #endif { int j,ibin; #ifndef NO_PROPS_OUTPUTS o->Type = g->Type; o->SnapNum = g->SnapNum; o->CentralMvir = get_virial_mass(Halo[g->HaloNr].FirstHaloInFOFgroup); o->CentralRvir = get_virial_radius(Halo[g->HaloNr].FirstHaloInFOFgroup); o->Mvir = g->Mvir; o->Rvir = g->Rvir; o->Vvir = g->Vvir; for(j = 0; j < 3; j++) { o->Pos[j] = g->Pos[j]; o->DistanceToCentralGal[j] = wrap(Halo[Halo[g->HaloNr].FirstHaloInFOFgroup].Pos[j] - g->Pos[j],BoxSize);; } o->ColdGas = g->ColdGas; o->DiskMass = g->DiskMass; o->BulgeMass = g->BulgeMass; o->HotGas = g->HotGas; o->BlackHoleMass = g->BlackHoleMass; #endif #ifdef COMPUTE_SPECPHOT_PROPERTIES #ifndef POST_PROCESS_MAGS #ifdef OUTPUT_REST_MAGS /* Luminosities are converted into Mags in various bands */ for(j = 0; j < NMAG; j++) o->Mag[j] = lum_to_mag(g->Lum[j][n]); #endif #endif //ndef POST_PROCESS_MAGS #endif //COMPUTE_SPECPHOT_PROPERTIES #ifndef LIGHT_OUTPUT #ifndef NO_PROPS_OUTPUTS #ifdef GALAXYTREE o->HaloID = HaloIDs[g->HaloNr].HaloID; o->Redshift = ZZ[g->SnapNum]; int ii = (int) floor(o->Pos[0] * ScaleFactor); int jj = (int) floor(o->Pos[1] * ScaleFactor); int kk = (int) floor(o->Pos[2] * ScaleFactor); o->PeanoKey = peano_hilbert_key(ii, jj, kk, Hashbits); o->SubID = calc_big_db_subid_index(g->SnapNum, Halo[g->HaloNr].FileNr, Halo[g->HaloNr].SubhaloIndex); int tmpfirst = Halo[g->HaloNr].FirstHaloInFOFgroup; int lenmax = 0; int next = tmpfirst; while(next != -1) { if(Halo[next].Len > lenmax) { lenmax = Halo[next].Len; tmpfirst = next; } next = Halo[next].NextHaloInFOFgroup; } o->MMSubID = calc_big_db_subid_index(g->SnapNum, Halo[tmpfirst].FileNr, Halo[tmpfirst].SubhaloIndex); #endif o->LookBackTimeToSnap = NumToTime(g->SnapNum)*UnitTime_in_years/Hubble_h; o->InfallVmax = g->InfallVmax; o->InfallSnap = g->InfallSnap; o-> InfallHotGas = g-> InfallHotGas; o->HotRadius = g->HotRadius; #ifdef HALOPROPERTIES o->HaloM_Mean200 = g->HaloM_Mean200; o->HaloM_Crit200 = g->HaloM_Crit200; o->HaloM_TopHat = g->HaloM_TopHat; o->HaloVelDisp = g->HaloVelDisp; o->HaloVmax = g->HaloVmax; #endif o->Len = g->Len; o->Vmax = g->Vmax; o->BulgeSize = g->BulgeSize; o->EjectedMass = g->EjectedMass; o->BlackHoleGas = g->BlackHoleGas; for(j = 0; j < 3; j++) { o->Vel[j] = g->Vel[j]; #ifdef HALOSPIN o->HaloSpin[j] = g->HaloSpin[j]; #endif #ifndef H2_AND_RINGS o->GasSpin[j] = g->GasSpin[j]; o->StellarSpin[j] = g->StellarSpin[j]; #else o->DiskSpin[j] = g->DiskSpin[j]; #endif #ifdef HALOPROPERTIES o->HaloPos[j] = g->HaloPos[j]; o->HaloVel[j] = g->HaloVel[j]; o->HaloSpin[j] = g->HaloSpin[j]; #endif } o->XrayLum = g->XrayLum; o->GasDiskRadius = g->GasDiskRadius; o->StellarDiskRadius = g->StellarDiskRadius; o->CoolingRadius = g->CoolingRadius; o->ICM = g->ICM; //o->MetalsICM = CORRECTDBFLOAT(g->MetalsICM); o->MetalsICM = g->MetalsICM; o->QuasarAccretionRate = g->QuasarAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS; o->RadioAccretionRate = g->RadioAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS; o->CosInclination = g->CosInclination; if(g->Type == 2 || (g->Type == 1 && g->MergeOn == 1)) { o->OriMergTime=g->OriMergTime; o->MergTime = g->MergTime; } else { o->OriMergTime=0.0; o->MergTime = 0.0; } #ifndef GALAXYTREE o->HaloIndex = g->HaloNr; #endif #ifdef MBPID o->MostBoundID = g->MostBoundID; #endif #ifdef GALAXYTREE o->DisruptOn = g->DisruptOn; #endif #ifdef MERGE01 o->MergeOn = g->MergeOn; #endif //METALS /*o->MetalsColdGas = CORRECTDBFLOAT(g->MetalsColdGas); o->MetalsDiskMass = CORRECTDBFLOAT(g->MetalsDiskMass); o->MetalsBulgeMass = CORRECTDBFLOAT(g->MetalsBulgeMass); o->MetalsHotGas = CORRECTDBFLOAT(g->MetalsHotGas); o->MetalsEjectedMass = CORRECTDBFLOAT(g->MetalsEjectedMass); #ifdef METALS_SELF o->MetalsHotGasSelf = CORRECTDBFLOAT(g->MetalsHotGasSelf); #endif*/ o->MetalsColdGas = g->MetalsColdGas; o->MetalsDiskMass = g->MetalsDiskMass; o->MetalsBulgeMass = g->MetalsBulgeMass; o->MetalsHotGas = g->MetalsHotGas; o->MetalsEjectedMass = g->MetalsEjectedMass; #ifdef METALS_SELF o->MetalsHotGasSelf = g->MetalsHotGasSelf; #endif #ifdef TRACK_BURST o->BurstMass=g->BurstMass; #endif #ifdef H2_AND_RINGS for(j=0; j<RNUM; j++) { o->H2fractionr[j] = g -> H2fractionr[j]; o->ColdGasr[j] = g->ColdGasr[j]; o->DiskMassr[j] = g->DiskMassr[j]; o->MetalsColdGasr[j] = g->MetalsColdGasr[j]; o->MetalsDiskMassr[j] = g->MetalsDiskMassr[j]; } #endif //STAR FORMATION HISTORIES / RATES #ifdef STAR_FORMATION_HISTORY o->sfh_ibin=g->sfh_ibin; ibin=0; for (j=0;j<=o->sfh_ibin;j++) { #ifndef NORMALIZEDDB // o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.-NumToTime(g->SnapNum))*UnitTime_in_years/Hubble_h; //Time from middle of this sfh bin to snapshot - converted from code units to years //o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.)*UnitTime_in_years/Hubble_h; //ROB: Lookback time to middle of SFH bin, in years //ROB: Now use LookBackTimeToSnap + sfh_time instead. // o->sfh_dt[j]=g->sfh_dt[j]*UnitTime_in_years/Hubble_h; o->sfh_DiskMass[j]=g->sfh_DiskMass[j]; o->sfh_BulgeMass[j]=g->sfh_BulgeMass[j]; o->sfh_ICM[j]=g->sfh_ICM[j]; o->sfh_MetalsDiskMass[j]=g->sfh_MetalsDiskMass[j]; o->sfh_MetalsBulgeMass[j]=g->sfh_MetalsBulgeMass[j]; o->sfh_MetalsICM[j]=g->sfh_MetalsICM[j]; //#ifdef DETAILED_METALS_AND_MASS_RETURN #ifdef INDIVIDUAL_ELEMENTS o->sfh_ElementsDiskMass[j]=g->sfh_ElementsDiskMass[j]; o->sfh_ElementsBulgeMass[j]=g->sfh_ElementsBulgeMass[j]; o->sfh_ElementsICM[j]=g->sfh_ElementsICM[j]; #endif //#endif #ifdef TRACK_BURST o->sfh_BurstMass[j]=g->sfh_BurstMass[j]; #endif #else // NORMALIZEDDB sfh_bin[j].sfh_DiskMass = g->sfh_DiskMass[j]; sfh_bin[j].sfh_BulgeMass = g->sfh_BulgeMass[j]; sfh_bin[j].sfh_ICM = g->sfh_ICM[j]; sfh_bin[j].sfh_MetalsDiskMass = g->sfh_MetalsDiskMass[j]; sfh_bin[j].sfh_MetalsBulgeMass = g->sfh_MetalsBulgeMass[j]; sfh_bin[j].sfh_MetalsICM = g->sfh_MetalsICM[j]; sfh_bin[j].sfh_ibin = j; sfh_bin[j].snapnum = g->SnapNum; sfh_bin[j].GalID = -1; // TODO must be reset #endif // NORMALIZEDDB } //Set all non-used array elements to zero: // important if we want to read files in database that all values are valid SQLServer floats for (j=o->sfh_ibin+1;j<SFH_NBIN;j++) { #ifndef NORMALIZEDDB // o->sfh_time[j]=0.; // o->sfh_dt[j]=0.; o->sfh_DiskMass[j]=0.; o->sfh_BulgeMass[j]=0.; o->sfh_ICM[j]=0.; o->sfh_MetalsDiskMass[j]=metals_init(); o->sfh_MetalsBulgeMass[j]=metals_init(); o->sfh_MetalsICM[j]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS o->sfh_ElementsDiskMass[j]=elements_init(); o->sfh_ElementsBulgeMass[j]=elements_init(); o->sfh_ElementsICM[j]=elements_init(); #endif #ifdef TRACK_BURST o->sfh_BurstMass[j]=0.; #endif #else sfh_bin[j].sfh_DiskMass=0; sfh_bin[j].sfh_BulgeMass=0; sfh_bin[j].sfh_ICM=0; sfh_bin[j].sfh_ibin = 0; sfh_bin[j].snapnum = g->SnapNum; // TODO other elements not important, are not being written anyway. Or are they used elsewhere? #endif } #endif //STAR_FORMATION_HISTORY #ifdef INDIVIDUAL_ELEMENTS /*for (j=0;j<ELEMENT_NUM;j++) { o->DiskMass_elements[j]=g->DiskMass_elements[j]; o->BulgeMass_elements[j]=g->BulgeMass_elements[j]; o->ColdGas_elements[j]=g->ColdGas_elements[j]; o->HotGas_elements[j]=g->HotGas_elements[j]; o->EjectedMass_elements[j]=g->EjectedMass_elements[j]; o->ICM_elements[j]=g->ICM_elements[j]; }*/ /*o->DiskMass_elements = CORRECTDBFLOAT(g->DiskMass_elements); o->BulgeMass_elements = CORRECTDBFLOAT(g->BulgeMass_elements); o->ColdGas_elements = CORRECTDBFLOAT(g->ColdGas_elements); o->HotGas_elements = CORRECTDBFLOAT(g->HotGas_elements); o->ICM_elements = CORRECTDBFLOAT(g->ICM_elements);*/ o->DiskMass_elements = g->DiskMass_elements; o->BulgeMass_elements = g->BulgeMass_elements; o->ColdGas_elements = g->ColdGas_elements; o->HotGas_elements = g->HotGas_elements; o->EjectedMass_elements = g->EjectedMass_elements; o->ICM_elements = g->ICM_elements; #endif o->PrimordialAccretionRate = CORRECTDBFLOAT(g->PrimordialAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->CoolingRate = CORRECTDBFLOAT(g->CoolingRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->CoolingRate_beforeAGN = CORRECTDBFLOAT(g->CoolingRate_beforeAGN * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); //NOTE: in Msun/yr #ifdef SAVE_MEMORY o->Sfr = CORRECTDBFLOAT(g->Sfr * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); #ifdef H2_AND_RINGS for(j=0; j<RNUM; j++) o->Sfrr[j] = g->Sfrr[j] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS; #endif #else o->Sfr = CORRECTDBFLOAT(g->Sfr[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); #endif #endif //NO_PROPS_OUTPUTS //MAGNITUDES #ifdef COMPUTE_SPECPHOT_PROPERTIES #ifdef POST_PROCESS_MAGS /* int N_vespa_files=29, N_vespa_AgeBins=16; double vespa_age[17]={0.000125893, 0.02000, 0.03000, 0.04800, 0.07400, 0.11500, 0.17700, 0.27500, 0.42500, 0.65800, 1.02000, 1.57000, 2.44000, 3.78000, 5.84000, 9.04000, 14.0000}; int vespa_sfh_IDs[29]={0, 1, 12, 16, 2, 22, 23, 27, 29, 36, 42, 44, 50, 53, 54, 55, 56, 57, 61, 62, 63, 64, 65, 71, 81, 82, 90, 94, 99}; double vespa_sfh[N_vespa_AgeBins], vespa_metal[N_vespa_AgeBins], dumb[6]; int ii, jj, kk; char buf[1000], sbuf[1000]; FILE *fa; for (ii=1;ii<N_vespa_files;ii++) { sprintf(buf, "./devel/vespa_sfh/disc_good_%d.txt", vespa_sfh_IDs[ii]); if(!(fa = fopen(buf, "r"))) { char sbuf[1000]; sprintf(sbuf, "can't open file `%s'\n", buf); terminate(sbuf); } for(jj=0;jj<6;jj++) fgets(buf, 300, fa); //read vespa SFH and metallicities for (jj=0;jj<N_vespa_AgeBins;jj++) { vespa_sfh[jj]=0.; vespa_metal[jj]=0.; fscanf(fa,"%lg %lg %lg %lg %lg %lg %lg %lg\n", &dumb[0], &dumb[1], &vespa_sfh[jj], &dumb[2], &vespa_metal[jj], &dumb[3], &dumb[4], &dumb[5]); } fclose(fa); for (jj=0;jj<SFH_NBIN;jj++) { if(jj<N_vespa_AgeBins) { o->sfh_time[jj]=(vespa_age[jj]+vespa_age[jj+1])/2.*1.e9; o->sfh_dt[jj]=(vespa_age[jj+1]-vespa_age[jj])/2.*1.e9; o->sfh_DiskMass[jj]=vespa_sfh[jj]; o->sfh_BulgeMass[jj]=0.; o->sfh_MetalsDiskMass[jj]=vespa_metal[jj]*o->sfh_DiskMass[jj]; o->sfh_MetalsBulgeMass[jj]=metals_init(); } else { o->sfh_time[jj]=0.; o->sfh_dt[jj]=0.; o->sfh_DiskMass[jj]=0.; o->sfh_BulgeMass[jj]=0.; o->sfh_MetalsDiskMass[jj]=metals_init(); o->sfh_MetalsBulgeMass[jj]=metals_init(); } } post_process_spec_mags(o); sprintf(buf, "./devel/vespa_sfh/output_spectradisc_good_%d.txt", vespa_sfh_IDs[ii]); if(!(fa = fopen(buf, "w"))) { char sbuf[1000]; sprintf(sbuf, "can't open file `%s'\n", buf); terminate(sbuf); } for(jj=0;jj<NMAG;jj++) fprintf(fa,"%e\n",o->Mag[jj]); fclose(fa); exit(0); } */ //Convert recorded star formation histories into mags #ifdef NORMALIZEDDB post_process_spec_mags(o, &(sfh_bin[0])); #else post_process_spec_mags(o); #endif #else //ndef POST_PROCESS_MAGS #ifdef OUTPUT_REST_MAGS // Luminosities are converted into Mags in various bands for(j = 0; j < NMAG; j++) { //o->Mag[j] = lum_to_mag(g->Lum[j][n]); -> DONE ON TOP FOR LIGHT_OUTPUT AS WELL o->MagBulge[j] = lum_to_mag(g->LumBulge[j][n]); o->MagDust[j] = lum_to_mag(g->LumDust[j][n]); #ifdef ICL o->MagICL[j] = lum_to_mag(g->ICLLum[j][n]); #endif } #if defined(READXFRAC) || defined(WITHRADIATIVETRANSFER) o->Xfrac3d = g->Xfrac3d; #endif #endif //OUTPUT_REST_MAGS #ifdef OUTPUT_OBS_MAGS #ifdef COMPUTE_OBS_MAGS // Luminosities in various bands for(j = 0; j < NMAG; j++) { o->ObsMag[j] = lum_to_mag(g->ObsLum[j][n]); o->ObsMagBulge[j] = lum_to_mag(g->ObsLumBulge[j][n]); o->ObsMagDust[j] = lum_to_mag(g->ObsLumDust[j][n]); #ifdef ICL o->ObsMagICL[j] = lum_to_mag(g->ObsICL[j][n]); #endif #ifdef OUTPUT_MOMAF_INPUTS o->dObsMag[j] = lum_to_mag(g->dObsLum[j][n]); o->dObsMagBulge[j] = lum_to_mag(g->dObsLumBulge[j][n]); o->dObsMagDust[j] = lum_to_mag(g->dObsLumDust[j][n]); #ifdef ICL o->dObsMagICL[j] = lum_to_mag(g->dObsICL[j][n]); #endif #endif } #endif //COMPUTE_OBS_MAGS #endif //OUTPUT_OBS_MAGS #endif //ndef POST_PROCESS_MAGS #endif //COMPUTE_SPECPHOT_PROPERTIES #ifndef NO_PROPS_OUTPUTS if((g->DiskMass+g->BulgeMass)> 0.0) { o->MassWeightAge = g->MassWeightAge[n] / (g->DiskMass+g->BulgeMass); o->MassWeightAge = o->MassWeightAge / 1000. * UnitTime_in_Megayears / Hubble_h; //Age in Gyr } else o->MassWeightAge = 0.; #endif #ifdef FIX_OUTPUT_UNITS fix_units_for_ouput(o); #endif #endif //ndef LIGHT_OUTPUT // DEBUG // printf(" EXIT sfh_bin %d %f\n",sfh_bin,sfh_bin[0].sfh_DiskMass); }
void sfh_update_bins(int p, int snap, int step, double time) { /* Adds new bins as required. * Then merges bins whenever you have three or more of the same size. * Assumes that time counts from zero at the big bang. */ int i, j; // loop index int SFH_ibin; //desired ibin (i.e. bin in question in for loop below) SFH_ibin=0; Gal[p].sfh_age=time; //t=time/SFH_TIME_INTERVAL; //ibin=Gal[p].sfh_ibin; for(i=0;i<SFH_NBIN;i++) if(SFH_Nbins[snap][step][i]>0) //i.e. If bin is active... SFH_ibin=i; //Assign with 'bin in question' if (Gal[p].sfh_ibin == 0) //i.e. If highest active bin is bin 0... { for(i=0;i<=SFH_ibin;i++) { Gal[p].sfh_t[i]=SFH_t[snap][step][i]; Gal[p].sfh_Nbins[i]=SFH_Nbins[snap][step][i]; } Gal[p].sfh_ibin=SFH_ibin; } else //i.e. If highest active bin is > bin 0... { i=0; while(i<=SFH_ibin) //Up to 'bin in question'... { if(i<=Gal[p].sfh_ibin) //...until highest active bin is reached... { if(Gal[p].sfh_Nbins[i]!= SFH_Nbins[snap][step][i]) //...and until bin has grown to required size. { // Merge bins i and i+1 Gal[p].sfh_Nbins[i]+=Gal[p].sfh_Nbins[i+1]; Gal[p].sfh_t[i]=Gal[p].sfh_t[i+1]; Gal[p].sfh_DiskMass[i]+=Gal[p].sfh_DiskMass[i+1]; Gal[p].sfh_BulgeMass[i]+=Gal[p].sfh_BulgeMass[i+1]; Gal[p].sfh_ICM[i]+=Gal[p].sfh_ICM[i+1]; Gal[p].sfh_MetalsDiskMass[i]=metals_add(Gal[p].sfh_MetalsDiskMass[i],Gal[p].sfh_MetalsDiskMass[i+1],1.); Gal[p].sfh_MetalsBulgeMass[i]=metals_add(Gal[p].sfh_MetalsBulgeMass[i],Gal[p].sfh_MetalsBulgeMass[i+1],1.); Gal[p].sfh_MetalsICM[i]= metals_add(Gal[p].sfh_MetalsICM[i],Gal[p].sfh_MetalsICM[i+1],1.); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[i] = elements_add(Gal[p].sfh_ElementsDiskMass[i],Gal[p].sfh_ElementsDiskMass[i+1],1.); Gal[p].sfh_ElementsBulgeMass[i] = elements_add(Gal[p].sfh_ElementsBulgeMass[i],Gal[p].sfh_ElementsBulgeMass[i+1],1.); Gal[p].sfh_ElementsICM[i] = elements_add(Gal[p].sfh_ElementsICM[i],Gal[p].sfh_ElementsICM[i+1],1.); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[i]+=Gal[p].sfh_BurstMass[i+1]; #endif // Relabel all the other bins for(j=i+1;j<Gal[p].sfh_ibin;j++) { Gal[p].sfh_Nbins[j]=Gal[p].sfh_Nbins[j+1]; Gal[p].sfh_t[j]=Gal[p].sfh_t[j+1]; Gal[p].sfh_DiskMass[j]=Gal[p].sfh_DiskMass[j+1]; Gal[p].sfh_BulgeMass[j]=Gal[p].sfh_BulgeMass[j+1]; Gal[p].sfh_ICM[j]=Gal[p].sfh_ICM[j+1]; Gal[p].sfh_MetalsDiskMass[j]=Gal[p].sfh_MetalsDiskMass[j+1]; Gal[p].sfh_MetalsBulgeMass[j]=Gal[p].sfh_MetalsBulgeMass[j+1]; Gal[p].sfh_MetalsICM[j]=Gal[p].sfh_MetalsICM[j+1]; #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=Gal[p].sfh_ElementsDiskMass[j+1]; Gal[p].sfh_ElementsBulgeMass[j]=Gal[p].sfh_ElementsBulgeMass[j+1]; Gal[p].sfh_ElementsICM[j]=Gal[p].sfh_ElementsICM[j+1]; #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=Gal[p].sfh_BurstMass[j+1]; #endif } //set last bin to zero Gal[p].sfh_flag[j]=0; Gal[p].sfh_Nbins[j]=0; Gal[p].sfh_t[j]=0.; Gal[p].sfh_DiskMass[j]=0.; Gal[p].sfh_BulgeMass[j]=0.; Gal[p].sfh_ICM[j]=0.; Gal[p].sfh_MetalsDiskMass[j]=metals_init(); Gal[p].sfh_MetalsBulgeMass[j]=metals_init(); Gal[p].sfh_MetalsICM[j]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=elements_init(); Gal[p].sfh_ElementsBulgeMass[j]=elements_init(); Gal[p].sfh_ElementsICM[j]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=0.; #endif Gal[p].sfh_ibin=j-1; /* If there are no more time bins in the galaxy to merge and * the last bin still doesn't have the required size * re-size it according to the reference structure SFH */ if(Gal[p].sfh_Nbins[i+1]==0) { Gal[p].sfh_Nbins[i]=SFH_Nbins[snap][step][i]; Gal[p].sfh_t[i]=SFH_t[snap][step][i]; i+=1; } } else i+=1; } else { //no more bins available in the galaxy, fill the rest times from SFH array for(j=i;j<=SFH_ibin;j++) { Gal[p].sfh_Nbins[j]=SFH_Nbins[snap][step][j]; Gal[p].sfh_t[j]=SFH_t[snap][step][j]; Gal[p].sfh_DiskMass[j]=0.; Gal[p].sfh_BulgeMass[j]=0.; Gal[p].sfh_ICM[j]=0.; Gal[p].sfh_MetalsDiskMass[j]=metals_init(); Gal[p].sfh_MetalsBulgeMass[j]=metals_init(); Gal[p].sfh_MetalsICM[j]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=elements_init(); Gal[p].sfh_ElementsBulgeMass[j]=elements_init(); Gal[p].sfh_ElementsICM[j]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=0.; #endif Gal[p].sfh_ibin=j; } i=j; } }//end while }//end else for(i=0;i<SFH_NBIN;i++) { if(i==0) Gal[p].sfh_dt[i]=NumToTime(0)-Gal[p].sfh_t[i]; else Gal[p].sfh_dt[i]=Gal[p].sfh_t[i-1]-Gal[p].sfh_t[i]; } }
/*@brief Copies all the relevant properties from the Galaxy structure into the Galaxy output structure, some units are corrected.*/ void prepare_galaxy_for_output(int n, struct GALAXY *g, struct GALAXY_OUTPUT *o) { int j; o->Type = g->Type; o->SnapNum = g->SnapNum; o->CentralMvir = get_virial_mass(Halo[g->HaloNr].FirstHaloInFOFgroup); o->Mvir = g->Mvir; o->Rvir = g->Rvir; o->Vvir = g->Vvir; for(j = 0; j < 3; j++) { o->Pos[j] = g->Pos[j]; o->DistanceToCentralGal[j] = wrap(Halo[Halo[g->HaloNr].FirstHaloInFOFgroup].Pos[j] - g->Pos[j],BoxSize);; } o->ColdGas = g->ColdGas; o->DiskMass = g->DiskMass; o->BulgeMass = g->BulgeMass; o->HotGas = g->HotGas; o->BlackHoleMass = g->BlackHoleMass; #ifndef POST_PROCESS_MAGS #ifdef OUTPUT_REST_MAGS /* Luminosities are converted into Mags in various bands */ for(j = 0; j < NMAG; j++) o->Mag[j] = lum_to_mag(g->Lum[j][n]); #endif #endif #ifndef LIGHT_OUTPUT #ifdef GALAXYTREE o->HaloID = HaloIDs[g->HaloNr].HaloID; o->Redshift = ZZ[g->SnapNum]; int ii = (int) floor(o->Pos[0] * ScaleFactor); int jj = (int) floor(o->Pos[1] * ScaleFactor); int kk = (int) floor(o->Pos[2] * ScaleFactor); o->PeanoKey = peano_hilbert_key(ii, jj, kk, Hashbits); o->SubID = calc_big_db_subid_index(g->SnapNum, Halo[g->HaloNr].FileNr, Halo[g->HaloNr].SubhaloIndex); int tmpfirst = Halo[g->HaloNr].FirstHaloInFOFgroup; int lenmax = 0; int next = tmpfirst; while(next != -1) { if(Halo[next].Len > lenmax) { lenmax = Halo[next].Len; tmpfirst = next; } next = Halo[next].NextHaloInFOFgroup; } o->MMSubID = calc_big_db_subid_index(g->SnapNum, Halo[tmpfirst].FileNr, Halo[tmpfirst].SubhaloIndex); #endif o->LookBackTimeToSnap = NumToTime(g->SnapNum)*UnitTime_in_years/Hubble_h; o->InfallVmax = g->InfallVmax; o->InfallSnap = g->InfallSnap; o->HotRadius = g->HotRadius; #ifdef HALOPROPERTIES o->HaloM_Mean200 = g->HaloM_Mean200; o->HaloM_Crit200 = g->HaloM_Crit200; o->HaloM_TopHat = g->HaloM_TopHat; o->HaloVelDisp = g->HaloVelDisp; o->HaloVmax = g->HaloVmax; #endif o->Len = g->Len; o->Vmax = g->Vmax; o->BulgeSize = g->BulgeSize; o->EjectedMass = g->EjectedMass; o->BlackHoleGas = g->BlackHoleGas; for(j = 0; j < 3; j++) { o->Vel[j] = g->Vel[j]; #ifdef HALOSPIN o->HaloSpin[j] = g->HaloSpin[j]; #endif o->GasSpin[j] = g->GasSpin[j]; o->StellarSpin[j] = g->StellarSpin[j]; #ifdef HALOPROPERTIES o->HaloPos[j] = g->HaloPos[j]; o->HaloVel[j] = g->HaloVel[j]; o->HaloSpin[j] = g->HaloSpin[j]; #endif } o->XrayLum = g->XrayLum; o->GasDiskRadius = g->GasDiskRadius; o->StellarDiskRadius = g->StellarDiskRadius; o->CoolingRadius = g->CoolingRadius; o->ICM = g->ICM; //o->MetalsICM = CORRECTDBFLOAT(g->MetalsICM); o->MetalsICM = g->MetalsICM; o->QuasarAccretionRate = g->QuasarAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS; o->RadioAccretionRate = g->RadioAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS; o->CosInclination = g->CosInclination; if(g->Type == 2 || (g->Type == 1 && g->MergeOn == 1)) { o->OriMergTime=g->OriMergTime; o->MergTime = g->MergTime; } else { o->OriMergTime=0.0; o->MergTime = 0.0; } #ifndef GALAXYTREE o->HaloIndex = g->HaloNr; #endif #ifdef MBPID o->MostBoundID = g->MostBoundID; #endif #ifdef GALAXYTREE o->DisruptOn = g->DisruptOn; #endif #ifdef MERGE01 o->MergeOn = g->MergeOn; #endif //METALS /*o->MetalsColdGas = CORRECTDBFLOAT(g->MetalsColdGas); o->MetalsDiskMass = CORRECTDBFLOAT(g->MetalsDiskMass); o->MetalsBulgeMass = CORRECTDBFLOAT(g->MetalsBulgeMass); o->MetalsHotGas = CORRECTDBFLOAT(g->MetalsHotGas); o->MetalsEjectedMass = CORRECTDBFLOAT(g->MetalsEjectedMass); #ifdef METALS_SELF o->MetalsHotGasSelf = CORRECTDBFLOAT(g->MetalsHotGasSelf); #endif*/ o->MetalsColdGas = g->MetalsColdGas; o->MetalsDiskMass = g->MetalsDiskMass; o->MetalsBulgeMass = g->MetalsBulgeMass; o->MetalsHotGas = g->MetalsHotGas; o->MetalsEjectedMass = g->MetalsEjectedMass; #ifdef METALS_SELF o->MetalsHotGasSelf = g->MetalsHotGasSelf; #endif //STAR FORMATION HISTORIES / RATES #ifdef STAR_FORMATION_HISTORY o->sfh_ibin=g->sfh_ibin; for (j=0;j<=o->sfh_ibin;j++) { // Lookback time from output snap to middle of SFh bin, in years o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.-NumToTime(g->SnapNum))*UnitTime_in_years/Hubble_h; //o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.)*UnitTime_in_years/Hubble_h; //ROB: Lookback time to middle of SFH bin, in years o->sfh_dt[j]=g->sfh_dt[j]*UnitTime_in_years/Hubble_h; o->sfh_DiskMass[j]=g->sfh_DiskMass[j]; o->sfh_BulgeMass[j]=g->sfh_BulgeMass[j]; o->sfh_ICM[j]=g->sfh_ICM[j]; o->sfh_MetalsDiskMass[j]=g->sfh_MetalsDiskMass[j]; o->sfh_MetalsBulgeMass[j]=g->sfh_MetalsBulgeMass[j]; o->sfh_MetalsICM[j]=g->sfh_MetalsICM[j]; #ifdef YIELDS o->sfh_ElementsDiskMass[j]=g->sfh_ElementsDiskMass[j]; o->sfh_ElementsBulgeMass[j]=g->sfh_ElementsBulgeMass[j]; o->sfh_ElementsICM[j]=g->sfh_ElementsICM[j]; #endif } for (j=o->sfh_ibin+1;j<SFH_NBIN;j++) { o->sfh_time[j]=0.; o->sfh_DiskMass[j]=0.; o->sfh_BulgeMass[j]=0.; o->sfh_ICM[j]=0.; o->sfh_MetalsDiskMass[j]=metals_init(); o->sfh_MetalsBulgeMass[j]=metals_init(); o->sfh_MetalsICM[j]=metals_init(); #ifdef YIELDS o->sfh_ElementsDiskMass[j]=elements_init(); o->sfh_ElementsBulgeMass[j]=elements_init(); o->sfh_ElementsICM[j]=elements_init(); #endif } #endif #ifdef YIELDS /*for (j=0;j<ELEMENT_NUM;j++) { o->DiskMass_elements[j]=g->DiskMass_elements[j]; o->BulgeMass_elements[j]=g->BulgeMass_elements[j]; o->ColdGas_elements[j]=g->ColdGas_elements[j]; o->HotGas_elements[j]=g->HotGas_elements[j]; o->EjectedMass_elements[j]=g->EjectedMass_elements[j]; o->ICM_elements[j]=g->ICM_elements[j]; }*/ /*o->DiskMass_elements = CORRECTDBFLOAT(g->DiskMass_elements); o->BulgeMass_elements = CORRECTDBFLOAT(g->BulgeMass_elements); o->ColdGas_elements = CORRECTDBFLOAT(g->ColdGas_elements); o->HotGas_elements = CORRECTDBFLOAT(g->HotGas_elements); o->ICM_elements = CORRECTDBFLOAT(g->ICM_elements);*/ o->DiskMass_elements = g->DiskMass_elements; o->BulgeMass_elements = g->BulgeMass_elements; o->ColdGas_elements = g->ColdGas_elements; o->HotGas_elements = g->HotGas_elements; o->EjectedMass_elements = g->EjectedMass_elements; o->ICM_elements = g->ICM_elements; #endif //NOTE: in Msun/yr #ifdef SAVE_MEMORY o->Sfr = CORRECTDBFLOAT(g->Sfr * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); #else o->Sfr = CORRECTDBFLOAT(g->Sfr[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS); #endif //MAGNITUDES #ifdef POST_PROCESS_MAGS //Convert recorded star formation histories into mags post_process_mags(o); #else //POST_PROCESS_MAGS #ifdef OUTPUT_REST_MAGS // Luminosities are converted into Mags in various bands for(j = 0; j < NMAG; j++) { //o->Mag[j] = lum_to_mag(g->Lum[j][n]); -> DONE ON TOP FOR LIGHT_OUTPUT AS WELL o->MagBulge[j] = lum_to_mag(g->LumBulge[j][n]); o->MagDust[j] = lum_to_mag(g->LumDust[j][n]); #ifdef ICL o->MagICL[j] = lum_to_mag(g->ICLLum[j][n]); #endif } if((g->DiskMass+g->BulgeMass)> 0.0) { o->MassWeightAge = g->MassWeightAge[n] / (g->DiskMass+g->BulgeMass); o->MassWeightAge = o->MassWeightAge / 1000. * UnitTime_in_Megayears / Hubble_h; //Age in Gyr } else o->MassWeightAge = 0.; #endif //OUTPUT_REST_MAGS #ifdef OUTPUT_OBS_MAGS #ifdef COMPUTE_OBS_MAGS // Luminosities in various bands for(j = 0; j < NMAG; j++) { o->ObsMag[j] = lum_to_mag(g->ObsLum[j][n]); o->ObsMagBulge[j] = lum_to_mag(g->ObsLumBulge[j][n]); o->ObsMagDust[j] = lum_to_mag(g->ObsLumDust[j][n]); #ifdef ICL o->ObsMagICL[j] = lum_to_mag(g->ObsICL[j][n]); #endif #ifdef OUTPUT_MOMAF_INPUTS o->dObsMag[j] = lum_to_mag(g->dObsLum[j][n]); o->dObsMagBulge[j] = lum_to_mag(g->dObsLumBulge[j][n]); o->dObsMagDust[j] = lum_to_mag(g->dObsLumDust[j][n]); #endif } #endif //COMPUTE_OBS_MAGS #endif //OUTPUT_OBS_MAGS #endif //POST_PROCESS_MAGS #ifdef FIX_OUTPUT_UNITS fix_units_for_ouput(o); #endif #endif //ndef LIGHT_OUTPUT }