/* Note: halonr is here the FOF-background subhalo (i.e. main halo) */
void evolve_galaxies(int halonr, int ngal, int treenr, int cenngal)
{
  int p, q, nstep, centralgal, merger_centralgal, currenthalo, prevgal, start, i;
  double infallingGas, deltaT, Zcurr;
  double time, previoustime, newtime;
  double AGNaccreted, t_Edd;
#ifdef STAR_FORMATION_HISTORY
  double age_in_years;
#endif

  // Eddington time in code units
  // code units are UnitTime_in_s/Hubble_h
  t_Edd=1.42e16*Hubble_h/UnitTime_in_s;

  //previoustime = NumToTime(Gal[0].SnapNum);
  previoustime = NumToTime(Halo[halonr].SnapNum-1);
  newtime = NumToTime(Halo[halonr].SnapNum);

  /* Time between snapshots */
  deltaT = previoustime - newtime;
  /* Redshift of current Snapnum */
  Zcurr = ZZ[Halo[halonr].SnapNum];

  centralgal = Gal[0].CentralGal;
	
  for (p =0;p<ngal;p++)
	  mass_checks("Evolve_galaxies #0",p);

  //print_galaxy("\n\ncheck1", centralgal, halonr);

 if(Gal[centralgal].Type != 0 || Gal[centralgal].HaloNr != halonr)
    terminate("Something wrong here ..... \n");

  /* Update all galaxies to same star-formation history time-bins.
   * Needed in case some galaxy has skipped a snapshot. */
#ifdef STAR_FORMATION_HISTORY
  age_in_years=(Age[0]-previoustime)*UnitTime_in_years/Hubble_h; //ROB: age_in_years is in units of "real years"!
  nstep=0;
  for (p=0; p<ngal; p++)
    sfh_update_bins(p,Halo[halonr].SnapNum-1,nstep,age_in_years);
#endif

  /* Handle the transfer of mass between satellites and central galaxies */
  deal_with_satellites(centralgal, ngal);

  /* Delete inconsequential galaxies */
  for (p =0;p<ngal;p++)
    if (Gal[p].Type ==2 && Gal[p].ColdGas+Gal[p].DiskMass+Gal[p].BulgeMass <1.e-8)
      Gal[p].Type = 3;
    else
      mass_checks("Evolve_galaxies #0.1",p);
   
  /* Calculate how much hot gas needs to be accreted to give the correct baryon fraction
   * in the main halo. This is the universal fraction, less any reduction due to reionization. */
  infallingGas = infall_recipe(centralgal, ngal, Zcurr);
  Gal[centralgal].PrimordialAccretionRate=infallingGas/deltaT;
  
  /* All the physics are computed in a number of intervals between snapshots
   * equal to STEPS */
  for (nstep = 0; nstep < STEPS; nstep++)
    {
      /* time to present of the current step */
      time = previoustime - (nstep + 0.5) * (deltaT / STEPS);

      /* Update all galaxies to the star-formation history time-bins of current step*/
#ifdef STAR_FORMATION_HISTORY
      age_in_years=(Age[0]-time)*UnitTime_in_years/Hubble_h;
      for (p=0; p<ngal; p++)
	sfh_update_bins(p,Halo[halonr].SnapNum-1,nstep,age_in_years);

#endif

      /* Infall onto central galaxy only, if required to make up a baryon deficit */
#ifndef GUO10
#ifndef GUO13
      if (infallingGas > 0.)
#endif
#endif
	add_infall_to_hot(centralgal, infallingGas / STEPS);

      mass_checks("Evolve_galaxies #0.5",centralgal);

      for (p = 0; p < ngal; p++)
	{
	  /* don't treat galaxies that have already merged */
	  if(Gal[p].Type == 3)
	    continue;
	  mass_checks("Evolve_galaxies #1",p);

	  if (Gal[p].Type == 0 || Gal[p].Type == 1)
	    {
	      reincorporate_gas(p, deltaT / STEPS);
	      /* determine cooling gas given halo properties and add it to the cold phase*/
	      mass_checks("Evolve_galaxies #1.5",p);
	      compute_cooling(p, deltaT / STEPS, ngal);
	    }
	}

      //this must be separated as now satellite AGN can heat central galaxies
      //therefore the AGN from all satellites must be computed, in a loop inside this function,
      //before gas is cooled into central galaxies (only suppress cooling, the gas is not actually heated)
      if(AGNRadioModeModel != 5)
	do_AGN_heating(deltaT / STEPS, ngal);

      for (p = 0; p < ngal; p++)
	{
	  cool_gas_onto_galaxy(p, deltaT / STEPS);
	  mass_checks("Evolve_galaxies #2",p);
	  starformation(p, centralgal, time, deltaT / STEPS, nstep);
	  mass_checks("Evolve_galaxies #3",p);
	  //print_galaxy("check3", centralgal, halonr);
	}

      /* Check for merger events */
      for(p = 0; p < ngal; p++)
	{
	  if(Gal[p].Type == 2 || (Gal[p].Type == 1 && Gal[p].MergeOn == 1))	/* satellite galaxy */
	    {
	      Gal[p].MergTime -= deltaT / STEPS;
	      if(Gal[p].MergTime < 0.0)
		{
		  NumMergers++;

		  if(Gal[p].Type == 1)
		    for(q = 0; q < ngal; q++)
		      if(Gal[q].Type == 2 && Gal[p].CentralGal == p)
			Gal[q].CentralGal = cenngal;

		  if(Gal[p].Type == 2)
		    merger_centralgal = Gal[p].CentralGal;
		  else
		    merger_centralgal = cenngal;

		  mass_checks("Evolve_galaxies #4",p);
		  mass_checks("Evolve_galaxies #4",merger_centralgal);
		  mass_checks("Evolve_galaxies #4",centralgal);

		  deal_with_galaxy_merger(p, merger_centralgal, centralgal, time, deltaT, nstep);

		  mass_checks("Evolve_galaxies #5",p);
		  mass_checks("Evolve_galaxies #5",merger_centralgal);
		  mass_checks("Evolve_galaxies #5",centralgal);

		}
	    }
	}//loop on all galaxies to detect mergers

#ifdef DETAILED_METALS_AND_MASS_RETURN
      //DELAYED ENRICHMENT AND MASS RETURN + FEEDBACK: No fixed yield or recycling fraction anymore. FB synced with enrichment
      for (p = 0; p < ngal; p++)
	update_yields_and_return_mass(p, centralgal, deltaT/STEPS, nstep);
#endif

    }/* end move forward in interval STEPS */

  for(p = 0; p < ngal; p++)
    {
      if(Gal[p].Type == 2)
	{
#ifndef UPDATETYPETWO
	  int jj;
	  float tmppos;
	  for(jj = 0; jj < 3; jj++)
	    {
	      tmppos = wrap(Gal[p].DistanceToCentralGal[jj],BoxSize);
	      tmppos *=  2.*sqrt(Gal[p].MergTime/Gal[p].OriMergTime);
	      Gal[p].Pos[jj] = Gal[p].MergCentralPos[jj] + tmppos;

	      if(Gal[p].Pos[jj] < 0)
		Gal[p].Pos[jj] = BoxSize + Gal[p].Pos[jj];
	      if(Gal[p].Pos[jj] > BoxSize)
		Gal[p].Pos[jj] = Gal[p].Pos[jj] - BoxSize;
	    }
#endif
	  /* Disruption of type 2 galaxies. Type 1 galaxies are not disrupted since usually
	   * bayonic component is more compact than dark matter.*/

	  if(DisruptionModel==0)
	    disrupt(p);
	}
    }

  for (p =0;p<ngal;p++)
    mass_checks("Evolve_galaxies #6",p);
  
#ifdef COMPUTE_SPECPHOT_PROPERTIES
#ifndef  POST_PROCESS_MAGS
  int n;
  /* If this is an output snapshot apply the dust model to each galaxy */
  for(n = 0; n < NOUT; n++)
    {
      if(Halo[halonr].SnapNum == ListOutputSnaps[n])
        {
    	  for(p = 0; p < ngal; p++)
    		  dust_model(p, n, halonr);
    	  break;
        }
    }
#endif  //POST_PROCESS_MAGS
#endif //COMPUTE_SPECPHOT_PROPERTIES

  /* now save the galaxies of all the progenitors (and free the associated storage) */
  int prog = Halo[halonr].FirstProgenitor;

  while(prog >= 0)
    {
      int currentgal;
      for(i = 0, currentgal = HaloAux[prog].FirstGalaxy; i < HaloAux[prog].NGalaxies; i++)
        {
    	  int nextgal = HaloGal[currentgal].NextGalaxy;
    	  /* this will write this galaxy to an output file and free the storage associate with it */
    	  output_galaxy(treenr, HaloGal[currentgal].HeapIndex);
    	  currentgal = nextgal;
        }
      prog = Halo[prog].NextProgenitor;
    }

  for(p = 0, prevgal = -1, currenthalo = -1, centralgal = -1, start = NGalTree; p < ngal; p++)
    {
      if(Gal[p].HaloNr != currenthalo)
	{
	  currenthalo = Gal[p].HaloNr;
	  HaloAux[currenthalo].FirstGalaxy = -1;
	  HaloAux[currenthalo].NGalaxies = 0;
	}

      mass_checks("Evolve_galaxies #7",p);

      if(Gal[p].Type != 3)
	{
	  if(NHaloGal >= MaxHaloGal)
	    {
	      int oldmax = MaxHaloGal;
	      AllocValue_MaxHaloGal *= ALLOC_INCREASE_FACTOR;
	      MaxHaloGal = AllocValue_MaxHaloGal;
	      if(MaxHaloGal<NHaloGal+1)
		MaxHaloGal=NHaloGal+1;
	      HaloGal = myrealloc_movable(HaloGal, sizeof(struct GALAXY) * MaxHaloGal);
	      HaloGalHeap = myrealloc_movable(HaloGalHeap, sizeof(int) * MaxHaloGal);
	      for(i = oldmax; i < MaxHaloGal; i++)
		HaloGalHeap[i] = i;
	    }

	  Gal[p].SnapNum = Halo[currenthalo].SnapNum;

#ifndef GUO10
#ifdef UPDATETYPETWO
	  update_type_two_coordinate_and_velocity(treenr, p, Gal[0].CentralGal);
#endif
#endif

	  /* when galaxies are outputed, the slot is filled with the
	   * last galaxy in the heap. New galaxies always take the last spot */
	  int nextgal = HaloGalHeap[NHaloGal];
	  HaloGal[nextgal] = Gal[p];
	  HaloGal[nextgal].HeapIndex = NHaloGal;

	  if(HaloAux[currenthalo].FirstGalaxy < 0)
	    HaloAux[currenthalo].FirstGalaxy = nextgal;

	  if(prevgal >= 0)
	    HaloGal[prevgal].NextGalaxy = nextgal;
	  prevgal = nextgal;

	  HaloAux[currenthalo].NGalaxies++;
	  NHaloGal++;


#ifdef GALAXYTREE
	  if(NGalTree >= MaxGalTree)
	    {
	      AllocValue_MaxGalTree *= ALLOC_INCREASE_FACTOR;
	      MaxGalTree = AllocValue_MaxGalTree;
	      if(MaxGalTree<NGalTree+1) MaxGalTree=NGalTree+1;
	      GalTree = myrealloc_movable(GalTree, sizeof(struct galaxy_tree_data) * MaxGalTree);
	    }
	  HaloGal[nextgal].GalTreeIndex = NGalTree;

	  memset(&GalTree[NGalTree], 0, sizeof(struct galaxy_tree_data));
	  GalTree[NGalTree].HaloGalIndex = nextgal;
	  GalTree[NGalTree].SnapNum = Halo[currenthalo].SnapNum;
	  GalTree[NGalTree].NextProgGal = -1;
	  GalTree[NGalTree].DescendantGal = -1;

	  GalTree[NGalTree].FirstProgGal = Gal[p].FirstProgGal;
	  if(Gal[p].Type == 0)
	    centralgal = NGalTree;
	  NGalTree++;
#endif
	}
    }

#ifdef GALAXYTREE
  for(p = start; p < NGalTree; p++)
    {
      if(centralgal < 0)
	terminate("centralgal < 0");
      GalTree[p].FOFCentralGal = centralgal;
    }
#endif

  report_memory_usage(&HighMark, "evolve_galaxies");
}
示例#2
0
/* Note: halonr is here the FOF-background subhalo (i.e. main halo) */
void evolve_galaxies(int halonr, int ngal, int treenr, int cenngal)
{
  int jj, p, q, nstep, centralgal, merger_centralgal, currenthalo, prevgal, start, i;
  double infallingGas, coolingGas, deltaT, Zcurr;  
  double time, previoustime, newtime;
  double AGNaccreted, t_Edd;
#ifdef STAR_FORMATION_HISTORY
  double age_in_years;
#endif
#ifdef HT09_DISRUPTION
  double CentralRadius, CentralMass, SatelliteRadius, SatelliteMass;
#endif

  // Eddington time in code units
  // Bizarrely, code units are UnitTime_in_s/Hubble_h
  t_Edd=1.42e16*Hubble_h/UnitTime_in_s;

  //previoustime = NumToTime(Gal[0].SnapNum);
  previoustime = NumToTime(Halo[halonr].SnapNum-1);
  newtime = NumToTime(Halo[halonr].SnapNum);

  /* Time between snapshots */
  deltaT = previoustime - newtime;
  /* Redshift of current Snapnum */
  Zcurr = ZZ[Halo[halonr].SnapNum];

  //if(halonr == 83)
  //	for(p=0;p<ngal;p++)
  //		printf("check halonr=%d id=%d type=%d\n", halonr, p,Gal[p].Type);


  centralgal = Gal[0].CentralGal;
	
  for (p =0;p<ngal;p++)
	  mass_checks("Evolve_galaxies #0",p);

 if(Gal[centralgal].Type != 0 || Gal[centralgal].HaloNr != halonr)
    terminate("Something wrong here ..... \n");


  /* Update all galaxies to same star-formation history time-bins.
   * Needed in case some galaxy has skipped a snapshot. */
#ifdef STAR_FORMATION_HISTORY
  age_in_years=(Age[0]-previoustime)*UnitTime_in_years/Hubble_h; //ROB: age_in_years is in units of "real years"!
  nstep=0;
  for (p=0; p<ngal; p++)
    sfh_update_bins(p,Halo[halonr].SnapNum-1,nstep,age_in_years);
#endif

  //if(halonr == 84)
   // 	print_galaxy("check00", centralgal, halonr);

    //for(p=0;p<ngal;p++)
    //	printf("prog=%d\n",Halo[halonr].FirstProgenitor);

  /* Handle the transfer of mass between satellites and central galaxies */
  deal_with_satellites(centralgal, ngal);


  /* Delete inconsequential galaxies */
  for (p =0;p<ngal;p++)
    if (Gal[p].Type ==2 && Gal[p].ColdGas+Gal[p].DiskMass+Gal[p].BulgeMass <1.e-8)
      Gal[p].Type = 3;
    else
      mass_checks("Evolve_galaxies #0.1",p);
   
  
  /* Calculate how much hot gas needs to be accreted to give the correct baryon fraction
   * in the main halo. This is the universal fraction, less any reduction due to reionization. */
  infallingGas = infall_recipe(centralgal, ngal, Zcurr);
  Gal[centralgal].PrimordialAccretionRate=infallingGas/deltaT;
  
  //if(halonr > 35 && halonr < 40)
  //	print_galaxy("check02", centralgal, halonr);


  /* All the physics are computed in a number of intervals between snapshots
   * equal to STEPS */
  for (nstep = 0; nstep < STEPS; nstep++)
    {
  	//printf("step=%d\n",nstep);
  	/* time to present of the current step */
	  time = previoustime - (nstep + 0.5) * (deltaT / STEPS);
     

	  /* Update all galaxies to the star-formation history time-bins of current step*/
#ifdef STAR_FORMATION_HISTORY
	  age_in_years=(Age[0]-time)*UnitTime_in_years/Hubble_h;
	  for (p=0; p<ngal; p++)
	  	sfh_update_bins(p,Halo[halonr].SnapNum-1,nstep,age_in_years);

#endif
	  //if(halonr > 35 && halonr < 40)
	 	// 		    	print_galaxy("check02.1", centralgal, halonr);

	  /* Infall onto central galaxy only, if required to make up a baryon deficit */
#ifndef GUO13
#ifndef GUO10
	  if (infallingGas > 0.)
#endif
#endif
	  	add_infall_to_hot(centralgal, infallingGas / STEPS);

	  //if(halonr == 84)
	 	//	    	print_galaxy("check02.5", centralgal, halonr);



	  mass_checks("Evolve_galaxies #0.5",centralgal);
      
	  for (p = 0; p < ngal; p++)
	    {
	  	//if((halonr > 28 && halonr < 32) || Gal[p].HaloNr==52)
	  		//if(Gal[p].SnapNum==31 || (halonr > 28 && halonr < 31))
	  		//	if(halonr ==140)
	  		// print_galaxy("check03", p, halonr);
	  	/* don't treat galaxies that have already merged */
		  if(Gal[p].Type == 3)
			  continue;

		  mass_checks("Evolve_galaxies #1",p);


		  if (Gal[p].Type == 0 || Gal[p].Type == 1)
		  {
		  	if((ReIncorporationRecipe == 0 && Gal[p].Type==0) || ReIncorporationRecipe > 0)
				  reincorporate_gas(p, deltaT / STEPS);
		  	 //if(halonr > 28 && halonr < 31)
		  	//			  print_galaxy("check04", p, halonr);
			  /* determine cooling gas given halo properties and add it to the cold phase*/
			  mass_checks("Evolve_galaxies #1.5",p);
			  coolingGas = cooling_recipe(p, deltaT / STEPS);
			  cool_gas_onto_galaxy(p, coolingGas);
			  //if(halonr > 28 && halonr < 31)
				//if(halonr ==140)
			  //print_galaxy("check05", p, halonr);

		  }


		  mass_checks("Evolve_galaxies #2",p);

#ifdef H2_AND_RINGS
      gas_inflow(p, deltaT / STEPS);
      //if(halonr > 38 && halonr < 40)
      //print_galaxy("check06", p, halonr);
#endif
		  /* stars form*/
		  starformation(p, centralgal, time, deltaT / STEPS, nstep);
		  //int ii;
		  //for (ii = 0; ii < ngal; ii++)
		  //	if(halonr > 28 && halonr < 31)
			//if(halonr ==140)
		  //	print_galaxy("check07", ii, halonr);
		  mass_checks("Evolve_galaxies #3",p);

	    } //for (p = 0; p < ngal; p++)
      
	  /* Check for merger events */
	  //if(Gal[p].Type == 1)
	  //for(p = 0; p < -1; p++)


	  for(p = 0; p < ngal; p++)
	    {
	    //if(halonr == 84)
	  	//	  print_galaxy("check07.01", p, halonr);
	  	#ifdef MERGE01
    	  if(Gal[p].Type == 2 || (Gal[p].Type == 1 && Gal[p].MergeOn == 1))	/* satellite galaxy */
#else
    	  if(Gal[p].Type == 2)
#endif
    	    {    		  
    		  Gal[p].MergTime -= deltaT / STEPS;

#ifdef HT09_DISRUPTION
    		  Gal[p].MergRadius -= get_deltar(p, deltaT/STEPS );
    		  if(Gal[p].MergRadius<0.)
    		  	Gal[p].MergRadius=0.;
    		  //printf("merge radius=%f detlar=%f\n",Gal[p].MergRadius, 100.*get_deltar(p, deltaT/STEPS ));
    		  disruption_code (p, time);

    		  /* a merger has occured! */
    		  //MergRadius is tracked for type 2's subject to disruption while MergTime is tracked for type 1's
    		 // if( ( Gal[p].Type == 2 && (Gal[p].MergRadius < Gal[centralgal].StellarDiskRadius+Gal[centralgal].BulgeSize || Gal[p].BulgeMass+Gal[p].DiskMass == 0) )
    			//	  || (Gal[p].Type == 1 && Gal[p].MergTime < 0.0))
    		 if( Gal[p].MergRadius < Gal[centralgal].StellarDiskRadius+Gal[centralgal].BulgeSize || Gal[p].BulgeMass+Gal[p].DiskMass == 0 )


    		  //if(Gal[p].MergTime < 0.0 || Gal[p].BulgeMass+Gal[p].DiskMass == 0)
#else
    		  if(Gal[p].MergTime < 0.0)
#endif
    		    {
    			  NumMergers++;

#ifdef MERGE01
    			  if(Gal[p].Type == 1)
    			  	for(q = 0; q < ngal; q++)
    			  		if(Gal[q].Type == 2 && Gal[p].CentralGal == p)
    			  			Gal[q].CentralGal = cenngal;

    			  if(Gal[p].Type == 2)
    				merger_centralgal = Gal[p].CentralGal;
    			  else
    				merger_centralgal = cenngal;
#else
    			  merger_centralgal = Gal[p].CentralGal;
#endif
    			 
    			  mass_checks("Evolve_galaxies #4",p);
    			  mass_checks("Evolve_galaxies #4",merger_centralgal);
    			  mass_checks("Evolve_galaxies #4",centralgal);
    			  //if(halonr == 140)
    			  //print_galaxy("check08", p, halonr);
    			  //if(halonr == 140)
    			  //print_galaxy("check09", merger_centralgal, halonr);
    			  deal_with_galaxy_merger(p, merger_centralgal, centralgal, time, deltaT, nstep);
    			  //if(halonr == 140)
    			  //print_galaxy("check10", p, halonr);
    			  //if(halonr == 140)
    			  //print_galaxy("check11", merger_centralgal, halonr);
    			  mass_checks("Evolve_galaxies #5",p);
    			  mass_checks("Evolve_galaxies #5",merger_centralgal);
    			  mass_checks("Evolve_galaxies #5",centralgal);

    		    }

    	    }// if(Gal[p].Type == 2)
	    }//loop on all galaxies to detect mergers

	  /* Cool gas onto AGN */
	  if (BlackHoleGrowth == 1)
	  {
		  for (p = 0; p < ngal; p++)
		  {
		  	AGNaccreted=min(Gal[p].BlackHoleGas, Gal[p].BlackHoleMass*BlackHoleAccretionRate*deltaT/(STEPS*t_Edd));
			  if (AGNaccreted > 0.)
			  {
				  Gal[p].BlackHoleMass += AGNaccreted;
				  Gal[p].BlackHoleGas -= AGNaccreted;
				  // Instantaneous accretion rate.  This will get overwritten on each mini-step but that's OK
				  Gal[p].QuasarAccretionRate = AGNaccreted*STEPS/deltaT;
			  }
		  }
	  }
	  
	  //DELAYED ENRICHMENT AND MASS RETURN + FEEDBACK: No fixed yield or recycling fraction anymore. FB synced with enrichment
	  for (p = 0; p < ngal; p++)
	  {
#ifdef DETAILED_METALS_AND_MASS_RETURN
	  update_yields_and_return_mass(p, centralgal, deltaT/STEPS, nstep);
#endif
	  }	  

#ifdef ALL_SKY_LIGHTCONE
	  int nr, istep, ix, iy, iz;
	  istep = Halo[halonr].SnapNum*STEPS + nstep;
	  Gal[p].SnapNum = Halo[halonr].SnapNum;
	  for (p = 0; p < ngal; p++)
	  	for (nr = 0; nr < NCONES; nr++)
	  		for (ix = 0; ix < NREPLICA; ix++)
	  			for (iy = 0; iy < NREPLICA; iy++)
	  				for (iz = 0; iz < NREPLICA; iz++)
	  					inside_lightcone(p, istep, nr, ix, iy, iz);
#endif


    }/* end move forward in interval STEPS */
  


  /* check the bulge size*/
  //checkbulgesize_main(ngal);
    

  for(p = 0; p < ngal; p++)
    {
	  if(Gal[p].Type == 2)
        {

	  	//if(halonr == 140)
	  	//print_galaxy("check12", p, halonr);
/*#ifdef UPDATETYPETWO
		  update_type_two_coordinate_and_velocity(treenr, p, centralgal);
#else*/
#ifndef UPDATETYPETWO
	  	int jj;
	  	float tmppos;
	  	for(jj = 0; jj < 3; jj++)
	  	{
	  		tmppos = wrap(Gal[p].DistanceToCentralGal[jj],BoxSize);
	  		tmppos *=  (Gal[p].MergTime/Gal[p].OriMergTime);
	  		Gal[p].Pos[jj] = Gal[p].MergCentralPos[jj] + tmppos;

	  		if(Gal[p].Pos[jj] < 0)
	  			Gal[p].Pos[jj] = BoxSize + Gal[p].Pos[jj];
	  		if(Gal[p].Pos[jj] > BoxSize)
	  			Gal[p].Pos[jj] = Gal[p].Pos[jj] - BoxSize;
	  	}
#endif
      /* Disruption of type 2 galaxies. Type 1 galaxies are not disrupted since usually
       * bayonic component is more compact than dark matter.*/

#ifdef DISRUPTION
	    //if(halonr == 84)
	  	//print_galaxy("check13", p, halonr);
		  disrupt(p, Gal[p].CentralGal);
		  //if(halonr == 84)
		  //print_galaxy("check014", p, halonr);


#endif
        }
	  //if(halonr > 20 && halonr < 31)
	  	//if(halonr ==140)
	 		 // print_galaxy("check015", p, halonr);
    }




  for (p =0;p<ngal;p++) mass_checks("Evolve_galaxies #6",p);
  
#ifdef COMPUTE_SPECPHOT_PROPERTIES
#ifndef  POST_PROCESS_MAGS
  int n;
  /* If this is an output snapshot apply the dust model to each galaxy */
  for(n = 0; n < NOUT; n++)
    {
      if(Halo[halonr].SnapNum == ListOutputSnaps[n])
        {
    	  for(p = 0; p < ngal; p++)
    		  dust_model(p, n, halonr);
    	  break;
        }
    }
#endif  //POST_PROCESS_MAGS
#endif //COMPUTE_SPECPHOT_PROPERTIES

  /* now save the galaxies of all the progenitors (and free the associated storage) */
  int prog = Halo[halonr].FirstProgenitor;

  while(prog >= 0)
  	{
      int currentgal;
      for(i = 0, currentgal = HaloAux[prog].FirstGalaxy; i < HaloAux[prog].NGalaxies; i++)
        {
    	  int nextgal = HaloGal[currentgal].NextGalaxy;
    	  /* this will write this galaxy to an output file and free the storage associate with it */
    	  output_galaxy(treenr, HaloGal[currentgal].HeapIndex);
    	  currentgal = nextgal;
        }
      prog = Halo[prog].NextProgenitor;
    }


  for(p = 0, prevgal = -1, currenthalo = -1, centralgal = -1, start = NGalTree; p < ngal; p++)
    {
	  if(Gal[p].HaloNr != currenthalo)
	    {
		  currenthalo = Gal[p].HaloNr;
		  HaloAux[currenthalo].FirstGalaxy = -1;
		  HaloAux[currenthalo].NGalaxies = 0;
	    }

	  mass_checks("Evolve_galaxies #7",p);

      /* may be wrong (what/why?) */
	  if(Gal[p].Type != 3)
	    {
		  if(NHaloGal >= MaxHaloGal)
		    {
			  int oldmax = MaxHaloGal;
			  AllocValue_MaxHaloGal *= ALLOC_INCREASE_FACTOR;
			  MaxHaloGal = AllocValue_MaxHaloGal;
              if(MaxHaloGal<NHaloGal+1) MaxHaloGal=NHaloGal+1;
			  HaloGal = myrealloc_movable(HaloGal, sizeof(struct GALAXY) * MaxHaloGal);
			  HaloGalHeap = myrealloc_movable(HaloGalHeap, sizeof(int) * MaxHaloGal);
			  for(i = oldmax; i < MaxHaloGal; i++)
				  HaloGalHeap[i] = i;
	  	    }

		  Gal[p].SnapNum = Halo[currenthalo].SnapNum;

#ifndef GUO10
#ifdef UPDATETYPETWO
		  update_type_two_coordinate_and_velocity(treenr, p, Gal[0].CentralGal);
#endif
#endif

		  /* when galaxies are outputed, the slot is filled with the
		   * last galaxy in the heap. New galaxies always take the last spot */
		  int nextgal = HaloGalHeap[NHaloGal];
		  HaloGal[nextgal] = Gal[p];
		  HaloGal[nextgal].HeapIndex = NHaloGal;

		  if(HaloAux[currenthalo].FirstGalaxy < 0)
			  HaloAux[currenthalo].FirstGalaxy = nextgal;

		  if(prevgal >= 0)
			  HaloGal[prevgal].NextGalaxy = nextgal;
		  prevgal = nextgal;

		  HaloAux[currenthalo].NGalaxies++;
		  NHaloGal++;


#ifdef GALAXYTREE
		  if(NGalTree >= MaxGalTree)
		    {
			  AllocValue_MaxGalTree *= ALLOC_INCREASE_FACTOR;
			  MaxGalTree = AllocValue_MaxGalTree;
			  if(MaxGalTree<NGalTree+1) MaxGalTree=NGalTree+1;
			  GalTree = myrealloc_movable(GalTree, sizeof(struct galaxy_tree_data) * MaxGalTree);
		    }
		  HaloGal[nextgal].GalTreeIndex = NGalTree;

		  memset(&GalTree[NGalTree], 0, sizeof(struct galaxy_tree_data));
		  GalTree[NGalTree].HaloGalIndex = nextgal;
		  GalTree[NGalTree].SnapNum = Halo[currenthalo].SnapNum;
		  GalTree[NGalTree].NextProgGal = -1;
		  GalTree[NGalTree].DescendantGal = -1;

		  GalTree[NGalTree].FirstProgGal = Gal[p].FirstProgGal;
		  if(Gal[p].Type == 0)
			  centralgal = NGalTree;
		  NGalTree++;
#endif
	    }
    }

#ifdef GALAXYTREE
  for(p = start; p < NGalTree; p++)
    {
      if(centralgal < 0)
    	  terminate("centralgal < 0");
      GalTree[p].FOFCentralGal = centralgal;
    }
#endif


  report_memory_usage(&HighMark, "evolve_galaxies");
}