def Findlt_King62(l, sp, potential, xv): """ Auxiliary function for 'ltidal', which returns the left-hand side - right-hand side of the King62 equation for tidal radius, as in eq.(12.21) of Mo, van den Bosch, White 10 Syntax: Findlt_King62(l,sp,potential,xv) where l: radius in the satellite [kpc] (float) sp: satellite potential (an object define in profiles.py) potential: host potential (a density profile object, or a list of such objects that constitute a composite potential) xv: phase-space coordinates [R,phi,z,VR,Vphi,Vz] in units of [kpc,radian,kpc,kpc/Gyr,kpc/Gyr,kpc/Gyr] (float array) """ r = np.sqrt(xv[0]**2. + xv[2]**2.) r1 = r * (1. - cfg.eps) r2 = r * (1. + cfg.eps) Om = Omega(xv) m = sp.M(l) M = pr.M(potential, r) M1 = pr.M(potential, r1) M2 = pr.M(potential, r2) dlnMdlnr = (np.log(M2) - np.log(M1)) / (np.log(r2) - np.log(r1)) return l - r * (m / M / (2. + Om**2. * r**3 / cfg.G / M - dlnMdlnr))**(1. / 3.)
def get_T(r, params, m=0., add_params=[], Ttype='jeans-alpha', do_smooth=False, polyorder=3, sigma=21, mode='interp', rlim=[-2, 0]): alpha, beta, gamma, p = params if Ttype[-5:] == 'Mreal': M = array(add_params) + array(m) else: M = prf.M(r, p, model='an') + m Rvir = p[-2] if Ttype == 'jeans-alpha' or Ttype == 'jeans' or Ttype == 'jeans-Mreal' or Ttype == 'alpha-p-Mreal': denominator = get_denominator(r, params, Ttype=Ttype) T = 0.5 * (3. - 2 * beta) / denominator * G * M / r elif Ttype == 'alpha' or Ttype == 'alpha-Mreal' or Ttype == 'betazero' or Ttype == 'gamma-Treal': denominator = get_denominator(r, params, Ttype=Ttype) T = 1.5 / denominator * G * M / r elif Ttype == 'zero': T = zeros_like(r) elif Ttype == 'virial' or Ttype == 'virial-Mreal': T = 0.5 * G * M / r elif Ttype == 'jeans-smooth': T = 0.5 * (3. - 2 * beta) / denominator * G * M / r do_smooth = True elif Ttype == 'Tdekel': # T from hydrostatic equilibrum (sigmar) (c, a, b, g, Rvir, Mvir) = p x = r / Rvir * c sigmar2 = prf.sigmar2_dekel_m(x, Mvir, Rvir, c, a, m=m, mtype='center') T = 1.5 * sigmar2 elif Ttype == 'Tmulti': (c, a, b, g, Rvir, Mvir) = p [Mratio, n] = add_params x = r / Rvir * c T = prf.K_Mratio(x, Mvir, Rvir, c, a, Mratio, n, m) if do_smooth: r_range = where((log10(r / Rvir) >= rlim[0]) & (log10(r / Rvir) < rlim[1])) T_smooth = nan * ones(size(T)) T_smooth[r_range] = savgol_filter(T[r_range], sigma, polyorder, deriv=0, mode=mode, delta=diff(log10(r))[0]) T = T_smooth return T
def fit_prof_constrained(r, data, params, constraint=(), w=1, model='an', y='brho', xi1=0.015, xi2=1.000): #least squares fitting result = minimize(min_res, params, args=(r, data, w, model, y), method='SLSQP', constraints=constraint) p = result2p(result, model) Rvir = p[-2] Mvir = p[-1] brho = prf.brho(r, p, model) rho = prf.rho(r, p, model) bs = prf.bs(r, p, model) s = prf.s(r, p, model) M = prf.M(r, p, model) V = prf.V(r, p, model) if y == 'brho': rms = rmslog(brho, data) if y == 'rho': rms = rmslog(rho, data) try: c2 = Rvir / r[bisect(bs, 2) - 1] except: c2 = 0 return { 'p': p, 'brho': brho, 'rho': rho, 'bs': bs, 's': s, 'M': M, 'V': V, 's1': prf.s(xi1 * Rvir, p, model), 's2': prf.s(xi2 * Rvir, p, model), 'bs1': prf.bs(xi1 * Rvir, p, model), 'bs2': prf.bs(xi2 * Rvir, p, model), 'c2': c2, 'rms': rms, 'Merr': (prf.calc_total_mass(r, rho, Rvir) - Mvir) / Mvir }
def E_diff(ri, pi, pf, m, alphai=0., alphaf=0., gammai=0., gammaf=0., betai=0., betaf=0., Ttype='jeans', model='an', method='halo', add_params=[], do_smooth=False): #returns the energy difference of the mass enclosing shell between the before and after states. the difference should be ideally zero according to the model if Ttype[-5:] == 'Mreal': Mi = array(add_params) else: Mi = prf.M(ri, pi, model) rf = prf.inv_M(Mi, pf, model) #the new radii that enclose the same masses Ui = prf.U(ri, pi, model) Uf = prf.U(rf, pf, model) if Ttype == 'gamma-Treal': Treal = add_params gammai = 1.5 * G * Mi / ri / Treal - prf.alpha_Dekel(ri, pi) gammaf = gammai Ti = get_T(ri, [alphai, betai, gammai, pi], m=0., add_params=add_params, Ttype=Ttype, do_smooth=do_smooth) Tf = get_T(rf, [alphaf, betaf, gammaf, pf], m=m, add_params=add_params, Ttype=Ttype, do_smooth=do_smooth) Ei = Ui - G * m / ri + Ti #0.5*G*Mi/ri Ef = Uf - G * m / rf + Tf #0.5*G*Mi/rf return array([Ef - Ei, (Ef - Ei) / abs(Ei)], dtype=float)
def evolve(r, ri, Mi, pi, m, alphai=0., alphaf=0., gammai=0., gammaf=0., betai=0., betaf=0., Ttype='jeans', Mcen=0, w=1, model='an', method='halo', add_params=[], Rvirf=0., Mvirf=0., component='d'): gamma = 0. if method == 'halo' or method == 'halo_noUex': if model == 'an': (ci, ai, bi, gi, Rviri, Mviri) = pi if Rvirf == 0.: Rvirf = Rviri if Mvirf == 0.: Mvirf = Mviri paramsf = Parameters() paramsf.add('c', value=ci, min=1e-16, vary=True) paramsf.add('a', value=ai, vary=True) paramsf.add('b', value=bi, vary=False) paramsf.add('g', value=gi, vary=False) paramsf.add('Rvir', value=float(Rvirf), vary=False) if component == 'd': paramsf.add('Mvir', value=float(Mvirf), vary=False) else: paramsf.add('Mvir', value=float(Mvirf), vary=True) if Ttype == 'jeans-gamma': paramsf.add('gamma', value=float(gamma), min=-1., max=1., vary=True) result = minimize(min_E_diff, paramsf, args=(r, pi, m, alphai, alphaf, gammai, gammaf, betai, betaf, Ttype, w, model, method, add_params)) if Ttype == 'jeans-gamma': gamma = result.values['gamma'] pf = fit.result2p(result, model) #energy error calc ere = E_diff(r, pi, pf, m, alphai, alphaf, gammai, gammaf, betai, betaf, Ttype, model, method, add_params)[1] errterms = [ log10(r / Rviri) < -1.33, #inner region (log10(r / Rviri) >= -1.33) & (log10(r / Rviri) <= -0.67), #middle region log10(r / Rviri) > -0.67, #outer region r == r ] #all ererms = [sqrt(mean(ere[errterm]**2)) for errterm in errterms] #cosider mass bath at center - important for a sequence Mcenf = Mcen + m rf = r rf0 = prf.inv_M(Mi, pf) Mf = prf.M(rf, pf, model) return { 'ri': ri, #initial radii 'rf0': rf0, #final radii 'rf': rf, #final radii, sorted 'Mf': Mf, #final mass profile 'Mcenf': Mcenf, #final mass at center 'pi': pi, #initial profile parameters 'pf': pf, #final profile parameters 'gammaf': gamma, # gamma 'm': m, #added mass 'model': model, #profile model used 'method': method, #evolution method used 'ere': ere, #energy relative error array 'ererms': ererms } #rms of energy relative error