func New(fTh RadialFuncType, ppt PressureProfileType, cType halo.ConcentrationType, m200c, z float64) *Halo { h := new(Halo) h.Z = z h.ppt = ppt cFunc := halo.ConcentrationFunc(cType, z) h.C200.R = haloRadius(m200c, 200*cosmo.RhoCritical(z)) h.C200.M = m200c h.C200.C = cFunc(m200c) h.Rs = h.C200.C * h.C200.R h.C500.R = h.OverdensityRadius(500 * cosmo.RhoCritical(z)) h.C500.M = haloMass(h.C500.R, 500*cosmo.RhoCritical(z)) h.C500.C = h.Rs * h.C500.R h.A200.R = h.OverdensityRadius(200 * cosmo.RhoAverage(z)) h.A200.M = haloMass(h.A200.R, 200*cosmo.RhoAverage(z)) h.A200.C = h.Rs * h.A200.R return h }
func (h *Halo) MinR() float64 { return haloRadius(MinHaloMass, cosmo.RhoCritical(h.Z)*500) / 100 }
func (h *Halo) ThermalPressure(ppt PressureProfileType, pt PressurePopulationType, r float64) float64 { // This is exceptionally wasteful: 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 h.ThermalPressure(ppt, ElectronPressure, r) * muFrac case ElectronPressure: switch ppt { case Planck2012: mFrac := h.C500.M / (planckPivotM500H / cosmo.H70) x := r / h.C500.R 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.C500.M / (arnaudPivotM500H / cosmo.H70) x := r / h.C500.R 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.") }