Esempio n. 1
0
func initCorrectedHalo(h *Halo, cFunc num.Func1D, m500cCorrect float64) {
	rho500c := cosmo.RhoCritical(h.Z) * 500

	h.C500.M = m500cCorrect
	h.C500.R = haloRadius(h.C500.M, rho500c)
	initSearching(h, cFunc, h.C500.M, h.C500.R)

	// initDensityInfo may require that r500cBias and m500cBias be initialized.
	if h.ppt.RequiresBiasedMass() {
		// initial guess
		h.M500cBias = h.C500.M
		h.R500cBias = h.C500.R

		r500cBiasLhs := func(r500cBias float64) float64 { return r500cBias }
		r500cBiasRhs := func(r500cBias float64) float64 {
			h.R500cBias = r500cBias
			h.M500cBias = haloMass(r500cBias, rho500c)
			return h.OverdensityRadius(Biased, rho500c)
		}

		h.R500cBias = num.FindEqual(r500cBiasLhs, r500cBiasRhs,
			h.C500.R/2, h.C500.R)
		h.M500cBias = haloRadius(h.R500cBias, rho500c)
	}

	initDensityInfo(h, cFunc, h.C500.M, h.C500.R)

	h.R500cBias = h.OverdensityRadius(Biased, rho500c)
	h.M500cBias = haloMass(h.R500cBias, rho500c)
}
Esempio n. 2
0
// initDensityInfo modifies h so that its various DensityInfo fields
// correspond to a halo with the given m500c. Also updates h.Rs and h.rhoS
func initDensityInfo(h *Halo, cFunc num.Func1D, m, r float64) {
	rho500c := cosmo.RhoCritical(h.Z) * 500
	rho200a := cosmo.RhoAverage(h.Z) * 200

	// This sets c200 for us.
	initSearching(h, cFunc, m, r)

	h.A200.R = h.OverdensityRadius(Corrected, rho200a)
	h.A200.C = h.A200.R / h.Rs
	h.A200.M = haloMass(h.A200.R, rho200a)

	h.C500.R = h.OverdensityRadius(Corrected, rho500c)
	h.C500.C = h.C500.R / h.Rs
	h.C500.M = haloMass(h.C500.R, rho500c)

	// This will already be set if the biased mass is required.
	if !h.ppt.RequiresBiasedMass() {
		h.R500cBias = h.OverdensityRadius(Biased, rho500c)
		h.M500cBias = haloMass(h.R500cBias, rho500c)
	}
}
Esempio n. 3
0
func initBiasedHalo(h *Halo, cFunc num.Func1D, m500cBias float64) {
	rho500c := 500 * cosmo.RhoCritical(h.Z)

	h.R500cBias = haloRadius(m500cBias, rho500c)
	h.M500cBias = m500cBias

	bFracLhs := func(b float64) float64 { return b }
	bFracRhs := func(b float64) float64 {
		initSearching(h, cFunc, b*h.M500cBias, h.R500cBias)
		h.C500.R = h.OverdensityRadius(Corrected, rho500c)
		h.C500.M = haloMass(h.C500.R, rho500c)

		return h.BFrac(h.R500cBias)
	}

	// h.BFrac evaluated at r500cBias
	b := num.FindEqual(bFracLhs, bFracRhs, 1.0, 2.0)

	mR500cBias := m500cBias * b
	initDensityInfo(h, cFunc, mR500cBias, h.R500cBias)
}
Esempio n. 4
0
func initSearching(h *Halo, cFunc num.Func1D, m, r float64) {
	rho200c := cosmo.RhoCritical(h.Z) * 200

	m200cToR := func(m200c float64) float64 {
		h.C200.R = haloRadius(m200c, rho200c)
		h.C200.C = cFunc(m200c)
		h.C200.M = m200c

		h.Rs = h.C200.R / h.C200.C

		return h.MassEnclosed(Corrected, r)
	}

	m200c := num.FindEqualConst(m200cToR, m, m, m)

	h.C200.R = haloRadius(m200c, rho200c)
	h.C200.C = cFunc(m200c)
	h.C200.M = m200c

	h.Rs = h.C200.R / h.C200.C
}
Esempio n. 5
0
func pThermal(h *Halo, ppt PressureProfileType, pt PressurePopulationType, r float64) float64 {

	type battagliaParam func(m500c, z float64) float64
	makeBattagliaParam := func(a0, am, az float64) battagliaParam {
		return func(m500c, z float64) float64 {
			return a0 * math.Pow(1+z, az) *
				math.Pow(m500c/battagliaPMassPivot, am)
		}
	}

	pDeltaBattaglia := pDeltaBattagliaPre * cosmo.RhoCritical(h.Z) *
		h.C500.M / h.C500.R

	switch pt {
	case AllPressure:
		muFrac := cosmo.Mu / cosmo.ElectronMu
		return pThermal(h, ppt, ElectronPressure, r) * muFrac
	case ElectronPressure:
		switch ppt {
		case Planck2012:
			// This is a measured fit, so we need to use the biased mass.
			mFrac := h.M500cBias / (planckPivotM500H / cosmo.H70)
			x := r / h.R500cBias
			y := planckC500 * x

			scaledPressure := planckP0 / (math.Pow(y, planckGamma) *
				math.Pow(1.0+math.Pow(y, planckAlpha),
					(planckBeta-planckGamma)/planckAlpha))

			P500 := (planckA0kev * math.Pow(mFrac, 2.0/3.0+0.12) *
				math.Pow(cosmo.HubbleFrac(h.Z), 8.0/3.0) *
				(cosmo.H70 * cosmo.H70))

			PkeV := P500 * scaledPressure
			return PkeV * kevToPascal

		case Arnaud2009:

			mFrac := h.M500cBias / (arnaudPivotM500H / cosmo.H70)
			x := r / h.R500cBias
			y := arnaudC500 * x

			app := 0.1 - (arnaudAP+0.1)*math.Pow(x/2, 3.0)/
				(1+math.Pow(x/2, 3.0))

			scaledPressure := +math.Pow(mFrac, arnaudAP+app) *
				math.Pow(cosmo.H70, -1.5) *
				arnaudP0 / (math.Pow(y, arnaudGamma) *
				math.Pow(1+math.Pow(y, arnaudAlpha),
					(arnaudBeta-arnaudGamma)/arnaudAlpha))

			P500 := (arnaudA0kev * math.Pow(mFrac, 2.0/3.0) *
				math.Pow(cosmo.HubbleFrac(h.Z), 8.0/3.0) *
				(cosmo.H70 * cosmo.H70))

			PkeV := P500 * scaledPressure
			return PkeV * kevToPascal

		case BattagliaAGN2012:
			x := r / h.C500.R

			p0 := makeBattagliaParam(battagliaP0AGN,
				battagliaPmAGN,
				battagliaPzAGN)
			xc := makeBattagliaParam(battagliaX0AGN,
				battagliaXmAGN,
				battagliaXzAGN)
			beta := makeBattagliaParam(battagliaB0AGN,
				battagliaBmAGN,
				battagliaBzAGN)

			xFrac := x / xc(h.C500.M, h.Z)

			muFrac := cosmo.Mu / cosmo.ElectronMu

			return p0(h.C500.M, h.Z) * math.Pow(xFrac, battagliaPGamma) *
				math.Pow(1.0+math.Pow(xFrac, battagliaPAlpha),
					-beta(h.C500.M, h.Z)) * pDeltaBattaglia / muFrac

		case BattagliaShockHeating2012:
			x := r / h.C500.R

			p0 := makeBattagliaParam(battagliaP0ShockHeating,
				battagliaPmShockHeating,
				battagliaPzShockHeating)
			xc := makeBattagliaParam(battagliaX0ShockHeating,
				battagliaXmShockHeating,
				battagliaXzShockHeating)
			beta := makeBattagliaParam(battagliaB0ShockHeating,
				battagliaBmShockHeating,
				battagliaBzShockHeating)

			xFrac := x / xc(h.C500.M, h.Z)

			muFrac := cosmo.Mu / cosmo.ElectronMu

			return p0(h.C500.M, h.Z) * math.Pow(xFrac, battagliaPGamma) *
				math.Pow(1.0+math.Pow(xFrac, battagliaPAlpha),
					-beta(h.C500.M, h.Z)) * pDeltaBattaglia / muFrac
		}
		panic("Given unrecognized PressureProfileType.")
	}
	panic("Given unrecognized PressureType.")
}