def make_map(sph, L=200):
    '''Makes 2D-projected density map of the gas particles in the sph code'''

    N = L

    x, y = np.indices((N + 1, N + 1))

    x = L * (x.flatten() - N / 2.) / N
    y = L * (y.flatten() - N / 2.) / N
    z = x * 0.
    vx = 0. * x
    vy = 0. * x
    vz = 0. * x

    x = units.parsec(x)
    y = units.parsec(y)
    z = units.parsec(z)
    vx = units.kms(vx)
    vy = units.kms(vy)
    vz = units.kms(vz)

    rho, rhovx, rhovy, rhovz, rhoe = sph.get_hydro_state_at_point(
        x, y, z, vx, vy, vz)
    rho = rho.reshape((N + 1, N + 1))

    return rho
Exemplo n.º 2
0
def make_map(sph, L=200):

    N = L

    x, y = np.indices((N + 1, N + 1))

    x = L * (x.flatten() - N / 2.) / N
    y = L * (y.flatten() - N / 2.) / N
    z = x * 0.
    vx = 0. * x
    vy = 0. * x
    vz = 0. * x

    x = units.parsec(x)
    y = units.parsec(y)
    z = units.parsec(z)
    vx = units.kms(vx)
    vy = units.kms(vy)
    vz = units.kms(vz)

    rho, rhovx, rhovy, rhovz, rhoe = sph.get_hydro_state_at_point(
        x, y, z, vx, vy, vz)
    rho = rho.reshape((N + 1, N + 1))

    return rho
def make_map(sph, N=100, L=1, offset_x=None, offset_y=None):
    "Create a density map from an SPH code"
    x, y = numpy.indices((N + 1, N + 1))
    x = L * (x.flatten() - N / 2.) / N
    y = L * (y.flatten() - N / 2.) / N
    z = x * 0.
    vx = 0. * x
    vy = 0. * x
    vz = 0. * x

    x = units.parsec(x)
    if offset_x is not None:
        x += offset_x
    y = units.parsec(y)
    if offset_y is not None:
        y += offset_y
    z = units.parsec(z)
    vx = units.kms(vx)
    vy = units.kms(vy)
    vz = units.kms(vz)

    rho, rhovx, rhovy, rhovz, rhoe = sph.get_hydro_state_at_point(
        x, y, z, vx, vy, vz)
    rho = rho.reshape((N + 1, N + 1))
    return rho
Exemplo n.º 4
0
def new_cluster(number_of_stars=1000):
    masses = new_salpeter_mass_distribution(number_of_stars,
                                            mass_min=0.1 | units.MSun,
                                            mass_max=125.0 | units.MSun,
                                            alpha=-2.35)

    particles = Particles(number_of_stars)
    particles.mass = masses
    particles.x = units.parsec(random.gamma(2.0, 1.0, number_of_stars))
    particles.y = units.parsec(random.gamma(1.0, 1.0, number_of_stars))
    particles.z = units.parsec(random.random(number_of_stars))

    return particles
Exemplo n.º 5
0
def new_cluster(number_of_stars = 1000):
    masses = new_salpeter_mass_distribution(
        number_of_stars, 
        mass_min = 0.1 | units.MSun,
        mass_max = 125.0 | units.MSun, 
        alpha = -2.35
    )
    
    particles = Particles(number_of_stars)
    particles.mass = masses
    particles.x = units.parsec(random.gamma(2.0, 1.0, number_of_stars))
    particles.y = units.parsec(random.gamma(1.0, 1.0, number_of_stars))
    particles.z = units.parsec(random.random(number_of_stars))
    
    return particles
Exemplo n.º 6
0
def get_mass_via_number_density(cluster):
    # progressbar
    import sys
    pbwidth = 42

    # TODO: find different method to calculate M(<r)
    print "Counting particles for which radii < r to obtain M(<r)"
    radii = VectorQuantity.arange(units.kpc(1), units.kpc(10000),
                                  units.parsec(1000))
    M_gas_below_r = numpy.zeros(len(radii))
    M_dm_below_r = numpy.zeros(len(radii))
    N = len(radii)
    for i, r in enumerate(radii):
        M_gas_below_r[i] = ((numpy.where(cluster.gas.r < r)[0]).size)
        M_dm_below_r[i] = ((numpy.where(cluster.dm.r < r)[0]).size)
        if i % 1000 == 0:
            # update the bar
            progress = float(i + 1000) / N
            block = int(round(pbwidth * progress))
            text = "\rProgress: [{0}] {1:.1f}%".format(
                "#" * block + "-" * (pbwidth - block), progress * 100)
            sys.stdout.write(text)
            sys.stdout.flush()

    sys.stdout.write("\n")
    print "Done counting particles :-)... TODO: improve this method?!"

    M_gas_below_r *= cluster.M_gas / cluster.raw_data.Ngas
    M_dm_below_r *= cluster.M_dm / cluster.raw_data.Ndm

    amuse_plot.scatter(radii, M_gas_below_r, c="g", label="Gas")
    amuse_plot.scatter(radii, M_dm_below_r, c="b", label="DM")
Exemplo n.º 7
0
    def __init__(self,
                 parms,
                 dm_parms=None,
                 radius=None,
                 z=0,
                 free_beta=False):
        """ parms = ne0, rc, [rcut], [ne0_fac, rc_fac]
            dm_parms = M_DM, a  """

        # TODO: implement without need for dm_parms

        if radius is None:
            self.radius = VectorQuantity.arange(units.kpc(1), units.kpc(1e5),
                                                units.parsec(100))
        else:
            if type(radius) == numpy.ndarray:
                self.radius = radius | units.kpc
            else:
                self.radius = radius
        self.z = z
        self.ne0 = parms[0]
        self.rho0 = convert.ne_to_rho(self.ne0, self.z) | units.g / units.cm**3
        self.ne0 = self.ne0 | units.cm**-3
        self.rc = parms[1] | units.kpc
        self.model = 0
        self.rcut = None
        self.ne0_cc = None
        self.rho0_cc = None
        self.rc_cc = None
        self.free_beta = free_beta
        if len(parms) == 3 and not free_beta:
            self.model = 1
            self.rcut = parms[2] | units.kpc
        if len(parms) == 3 and free_beta:
            self.model = 3
            self.beta = parms[2]
        if len(parms) == 4 and free_beta:
            self.model = 4
            self.rcut = parms[2] | units.kpc
            self.beta = parms[3]
        if len(parms) == 5:
            self.model = 2
            ne0_fac = parms[3]
            rc_fac = parms[4]
            self.ne0_cc = ne0 * ne0_fac
            self.rho0_cc = self.ne0_cc * globals.mu * (globals.m_p | units.g)
            self.rc_cc = rc / rc_fac

        modelnames = {
            0: r"$\beta=2/3$",
            1: r"cut-off $\beta=2/3$",
            2: r"cut-off double $\beta (2/3)$",
            3: r"free $\beta$",
            4: r"cut-off free $\beta$"
        }
        self.modelname = modelnames[self.model]

        if dm_parms:
            self.M_dm = dm_parms[0]
            self.a = dm_parms[1]
def make_map(sph,N=100,L=1):

    x,y=numpy.indices( ( N+1,N+1 ))

    x=L*(x.flatten()-N/2.)/N
    y=L*(y.flatten()-N/2.)/N
    z=x*0.
    vx=0.*x
    vy=0.*x
    vz=0.*x

    x=units.parsec(x)
    y=units.parsec(y)
    z=units.parsec(z)
    vx=units.kms(vx)
    vy=units.kms(vy)
    vz=units.kms(vz)

    rho,rhovx,rhovy,rhovz,rhoe=sph.get_hydro_state_at_point(x,y,z,vx,vy,vz)
    rho=rho.reshape((N+1,N+1))

    return rho
Exemplo n.º 9
0
def plot_individual_cluster_mass(cluster):
    pyplot.figure(figsize=(24, 18))

    # TODO: use different method :-)...
    get_mass_via_number_density(cluster)
    # get_mass_via_number_density_parallel(cluster)
    # get_mass_via_density(cluster)

    pyplot.gca().set_xscale("log")
    pyplot.gca().set_yscale("log")

    # M_gas = (cluster.gas.mass.value_in(units.MSun))
    # M_dm = (cluster.dm.mass.value_in(units.MSun))
    # amuse_plot.scatter(cluster.gas.r, units.MSun(M_gas), c="g", label="Gas")
    # amuse_plot.scatter(cluster.dm.r, units.MSun(M_dm), c="b", label="DM")

    # Analytical solutions. Sample radii and plug into analytical expression.
    r = VectorQuantity.arange(units.kpc(1), units.kpc(10000),
                              units.parsec(100))

    # Plot analytical Hernquist model for the DM mass M(<r)
    amuse_plot.plot(r,
                    cluster.dm_cummulative_mass(r),
                    ls="solid",
                    c="k",
                    label="DM")
    # Plot analytical beta model (Donnert 2014) for the gas mass M(<r)
    amuse_plot.plot(r,
                    cluster.gas_cummulative_mass_beta(r),
                    ls="dotted",
                    c="k",
                    label=r"$\beta$-model")
    # Plot analytical double beta model (Donnert et al. 2016, in prep) gas M(<r)
    amuse_plot.plot(r,
                    cluster.gas_cummulative_mass_double_beta(r),
                    ls="dashed",
                    c="k",
                    label=r"double $\beta$-model")

    pyplot.xlabel(r"$r$ [kpc]")
    pyplot.ylabel(r"$M (<r)$ [MSun]")

    pyplot.gca().set_xscale("log")
    pyplot.gca().set_yscale("log")
    pyplot.legend(loc=4)
Exemplo n.º 10
0
def donnert_2014_figure1(analytical_P500=False):
    # Well, I will just eyeball the value of rho_0 in Figure 1 in Donnert (2014) and adopt this value, I suppose...
    # disturbed = InitialCluster(rho_0=(9e-27 | units.g/units.cm**3),
    #                            plot=False, do_print=False,
    #                            disturbed_cluster=True, cool_core_cluster=False)
    # coolcore = InitialCluster(rho_0=(3e-25 | units.g/units.cm**3),
    #                           plot=False, do_print=False,
    #                           disturbed_cluster=False, cool_core_cluster=True)
    # rickersarazin = InitialCluster(plot=False, do_print=False, disturbed_cluster=False, cool_core_cluster=False)

    r = VectorQuantity.arange(units.kpc(1), units.kpc(10000),
                              units.parsec(100))

    #fig, ((ax1, ax2), (ax3, ax4)) = pyplot.subplots(2, 2, figsize=(20, 20), dpi=500)
    fig, ((ax1, ax2), (ax3, ax4)) = pyplot.subplots(2, 2)

    # Plot the density situation
    pyplot.sca(ax1)
    amuse_plot.hist(r, bins=int(numpy.sqrt(len(r))), label="Hanky")
    # amuse_plot.loglog(coolcore.r, coolcore.rho_gas.as_quantity_in(units.g / units.cm**3),
    #                   c='k', ls='dotted', label="Gas, cool core")
    # amuse_plot.loglog(disturbed.r, disturbed.rho_gas.as_quantity_in(units.g / units.cm**3),
    #                   c='k', ls='dashed', label="Gas, disturbed")
    # amuse_plot.loglog(disturbed.r, disturbed.rho_dm.as_quantity_in(units.g / units.cm**3),
    #                   c='k', ls='solid', label="Dark Matter")
    amuse_plot.ylabel(r'$\rho$')
    amuse_plot.xlabel(r'$r$')
    pyplot.legend(loc=3, frameon=False, fontsize=12)

    ax1.set_ylim(ymin=1e-28, ymax=1e-23)

    # pyplot.axvline(x=disturbed.r_200.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_200.value_in(units.kpc), 7e-24, r'$r_{200}$', fontsize=12)
    # pyplot.axvline(x=disturbed.r_500.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_500.value_in(units.kpc), 7e-24, r'$r_{500}$', fontsize=12)

    # # a_hernq
    # intersect = disturbed.dm_density(disturbed.a)
    # ymin, ymax = ax1.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.g/units.cm**3)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=disturbed.a.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, c='k')
    # pyplot.text(disturbed.a.value_in(units.kpc), 5e-24, r'$a_{\rm Hernq}$', fontsize=12)

    # # r_core,dist
    # intersect = disturbed.gas_density(disturbed.r_c)
    # ymin, ymax = ax1.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.g/units.cm**3)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=disturbed.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls='--', c='k')
    # pyplot.text(disturbed.r_c.value_in(units.kpc), 5e-24, r'$r_{\rm core,dist}$', fontsize=12)

    # # r_core,cc
    # intersect = coolcore.gas_density(coolcore.r_c)
    # ymin, ymax = ax1.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.g/units.cm**3)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=coolcore.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls=':', c='k')
    # pyplot.text(coolcore.r_c.value_in(units.kpc), 5e-24, r'$r_{\rm core,cc}$', fontsize=12)

    # Plot the mass situation
    pyplot.sca(ax2)
    amuse_plot.hist(r, bins=int(numpy.sqrt(len(r))), label="Hanky")
    # amuse_plot.loglog(coolcore.r, coolcore.M_gas_below_r.as_quantity_in(units.MSun),
    #                   c='k', ls='dotted', label="Gas, cool core")
    # amuse_plot.loglog(disturbed.r, disturbed.M_gas_below_r.as_quantity_in(units.MSun),
    #                   c='k', ls='dashed', label="Gas, disturbed")
    # amuse_plot.loglog(disturbed.r, disturbed.M_dm_below_r.as_quantity_in(units.MSun),
    #                   c='k', ls='solid', label="Dark Matter")
    amuse_plot.ylabel(r'$M(<r)$')
    amuse_plot.xlabel(r'$r$')
    pyplot.legend(loc=8, frameon=False, fontsize=12)

    ax2.set_ylim(ymin=1e10, ymax=5e15)

    # pyplot.axvline(x=disturbed.r_200.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_200.value_in(units.kpc), 3e15, r'$r_{200}$', fontsize=12)
    # pyplot.axvline(x=disturbed.r_500.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_500.value_in(units.kpc), 3e15, r'$r_{500}$', fontsize=12)

    # # a_hernq
    # intersect = disturbed.dm_cummulative_mass(disturbed.a)
    # ymin, ymax = ax2.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.MSun)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=disturbed.a.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, c='k')
    # pyplot.text(disturbed.a.value_in(units.kpc), 2e15, r'$a_{\rm Hernq}$', fontsize=12)

    # # r_core,dist
    # intersect = disturbed.dm_cummulative_mass(disturbed.r_c)
    # ymin, ymax = ax2.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.MSun)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=disturbed.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls='--', c='k')
    # pyplot.text(disturbed.r_c.value_in(units.kpc), 2e15, r'$r_{\rm core,dist}$', fontsize=12)

    # # r_core,cc
    # intersect = coolcore.dm_cummulative_mass(coolcore.r_c)
    # ymin, ymax = ax2.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.MSun)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=coolcore.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls=':', c='k')
    # pyplot.text(coolcore.r_c.value_in(units.kpc), 2e15, r'$r_{\rm core,cc}$', fontsize=12)

    # Plot the temperature situation
    pyplot.sca(ax3)
    amuse_plot.hist(r, bins=int(numpy.sqrt(len(r))), label="Hanky")
    # amuse_plot.loglog(disturbed.r, disturbed.T_r.as_quantity_in(units.K),
    #                   c='k', ls='solid', label="disturbed")
    # amuse_plot.loglog(disturbed.r, disturbed.T_r_dm.as_quantity_in(units.K),
    #                   c='k', ls='dashdot', label="from DM, disturbed")
    # amuse_plot.loglog(disturbed.r, disturbed.T_r_gas.as_quantity_in(units.K),
    #                   c='k', ls='dashed', label="from Gas, disturbed")
    # amuse_plot.loglog(coolcore.r, coolcore.T_r.as_quantity_in(units.K),
    #                   c='k', ls='dotted', label="cool core")
    amuse_plot.ylabel(r'$T$')
    amuse_plot.xlabel(r'$r$')
    pyplot.legend(loc=10, frameon=False, fontsize=12)

    ax3.set_ylim(ymin=6e6, ymax=3e8)

    # pyplot.axvline(x=disturbed.r_200.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_200.value_in(units.kpc), 2.6e8, r'$r_{200}$', fontsize=12)
    # pyplot.axvline(x=disturbed.r_500.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.r_500.value_in(units.kpc), 2.6e8, r'$r_{500}$', fontsize=12)

    # pyplot.axvline(x=disturbed.a.value_in(units.kpc), lw=2, c='k')
    # pyplot.text(disturbed.a.value_in(units.kpc), 2.4e8, r'$a_{\rm Hernq}$', fontsize=12)

    # # r_core,dist
    # intersect = disturbed.temperature(disturbed.r_c)
    # ymin, ymax = ax3.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.K)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=disturbed.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls='--', c='k')
    # pyplot.text(disturbed.r_c.value_in(units.kpc), 2.4e8, r'$r_{\rm core,dist}$', fontsize=12)

    # # r_core,cc
    # intersect = coolcore.temperature(coolcore.r_c)
    # ymin, ymax = ax3.get_ylim()
    # ymin = (numpy.log(intersect.value_in(units.K)/ymin)) / (numpy.log(ymax/ymin))
    # pyplot.axvline(x=coolcore.r_c.value_in(units.kpc), ymin=ymin, ymax=1, lw=2, ls=':', c='k')
    # pyplot.text(coolcore.r_c.value_in(units.kpc), 2.4e8, r'$r_{\rm core,cc}$', fontsize=12)

    # TODO: pressure situation
    pyplot.sca(ax4)
    amuse_plot.hist(r, bins=int(numpy.sqrt(len(r))), label="Hanky")
    colours = [(255. / 255, 127. / 255, 0. / 255),
               (152. / 255, 78. / 255, 163. / 255),
               (77. / 255, 175. / 255, 74. / 255),
               (52. / 255, 126. / 255, 184. / 255),
               (228. / 255, 26. / 255, 28. / 255)]

    # print "Warning, the pressure plots make little sense because for each M_DM is the same but M_200 differs"
    # for i, M_200 in enumerate(VectorQuantity([3e15, 1.5e15, 1e15, 0.5e15, 0.1e15], units.MSun)):
    #     disturbed = InitialCluster(rho_0=(9e-27 | units.g/units.cm**3), M_200=M_200,
    #                                plot=False, do_print=False,
    #                                disturbed_cluster=True, cool_core_cluster=False)
    #     coolcore = InitialCluster(rho_0=(3e-25 | units.g/units.cm**3), M_200=M_200,
    #                               plot=False, do_print=False,
    #                               disturbed_cluster=False, cool_core_cluster=True)
    #     if analytical_P500:
    #         amuse_plot.loglog(disturbed.r/disturbed.r_500, (disturbed.P_gas/disturbed.find_p500_analytically()),
    #                           c=colours[i], ls='solid', label=r'{0} $M_\odot$'.format(disturbed.M_200.value_in(units.MSun)))
    #         amuse_plot.loglog(coolcore.r/coolcore.r_500, (coolcore.P_gas/coolcore.find_p500_analytically()),
    #                           c=colours[i], ls='dashed')
    #     else:
    #         amuse_plot.loglog(disturbed.r/disturbed.r_500, (disturbed.P_gas/disturbed.P_500),
    #                           c=colours[i], ls='solid', label=r'{0} $M_\odot$'.format(disturbed.M_200.value_in(units.MSun)))
    #         amuse_plot.loglog(coolcore.r/coolcore.r_500, (coolcore.P_gas/coolcore.P_500),
    #                           c=colours[i], ls='dashed')

    amuse_plot.ylabel(r'$P(r)/P_{500}$')
    amuse_plot.xlabel(r'$r/r_{500}$')
    legend = pyplot.legend(loc=3, frameon=False, fontsize=16)
    # Set the color situation
    # for colour, text in zip(colours, legend.get_texts()):
    #     text.set_color(colour)

    ax4.set_ylim(ymin=1e-2, ymax=1e3)
    ax4.set_xticks((0.01, 0.10, 1.00))
    ax4.set_xticklabels(("0.01", "0.10", "1.00"))
    ax4.set_xlim(xmin=0.01, xmax=2.0)
    ax4.minorticks_on()
    ax4.tick_params('both', length=10, width=2, which='major')
    ax4.tick_params('both', length=5, width=1, which='minor')
    ax4.text(0.015, 4, "disturbed", color="grey", fontsize=15)
    ax4.text(0.02, 110, "cool cores", color="grey", fontsize=15)
    ax4.text(0.2, 50, "Arnaud et al. 2010", color="black", fontsize=15)

    # Set the xticks situation
    for ax in [ax1, ax2, ax3]:
        ax.set_xscale("log")
        ax.set_yscale("log")
        ax.set_xticks((10, 100, 1000))
        ax.set_xticklabels(("10", "100", "1000"))
        ax.set_xlim(xmin=10, xmax=5000)
        ax.minorticks_on()
        ax.tick_params('both', length=10, width=2, which='major')
        ax.tick_params('both', length=5, width=1, which='minor')

    # pyplot.savefig("../img/Donnert2014_Figure1_by_TLRH.pdf", format="pdf", dpi=1000)
    pyplot.show()
Exemplo n.º 11
0
def plot_individual_cluster_density(cluster):
    """ Plot the particles' density radial profile and compare to model """
    pyplot.figure(figsize=(24, 18))

    # AMUSE datamodel particles. Gas has RHO and RHOm; dm rho from model.
    amuse_plot.scatter(cluster.gas.r,
                       cluster.gas.rho,
                       c="g",
                       edgecolor="face",
                       s=1,
                       label=r"Generated IC: gas $\rho$")
    # amuse_plot.scatter(cluster.gas.r,
    #    cluster.gas.rhom,
    #    c="r", edgecolor="face", s=1, label=r"Generated IC: gas $\rho_{\rm model}$")
    amuse_plot.scatter(cluster.dm.r,
                       cluster.dm.rho,
                       c="b",
                       edgecolor="none",
                       label=r"Generated IC: DM $\rho$")

    # Analytical solutions. Sample radii and plug into analytical expression.
    r = VectorQuantity.arange(units.kpc(1), units.kpc(10000),
                              units.parsec(100))

    # Plot analytical beta model (Donnert 2014) for the gas density
    amuse_plot.plot(r,
                    cluster.gas_density_double_beta(r),
                    c="k",
                    ls="dashed",
                    label=r"Analytical, $\beta$-model:"
                    "\n"
                    r"$\rho_0$ = {0} g/cm$^3$; $rc = ${1} kpc".format(
                        cluster.rho0gas.number, cluster.rc.number))
    # Plot analytical double beta model (Donnert et al. 2016, in prep) for gas
    amuse_plot.plot(
        r,
        cluster.gas_density_beta(r),
        c="k",
        ls="dotted",
        label=r"Analytical, double $\beta$-model:"
        "\n"
        r"$\rho_0$ = {0} g/cm$^3$; $rc =$ {1} kpc; $r_{{\rm cut}}$ = {2} kpc".
        format(cluster.rho0gas.number, cluster.rc.number, cluster.rcut.number))

    # Plot analytical Hernquist model for the DM density
    amuse_plot.plot(r,
                    cluster.dm_density(r),
                    c="k",
                    ls="solid",
                    label=r"Analytical, Hernquist-model"
                    "\n"
                    r"$M_{{\rm dm}}= ${0:.2e} MSun; $a = $ {1} kpc".format(
                        cluster.M_dm.number, cluster.a.number))

    pyplot.legend(loc=3)
    amuse_plot.xlabel(r"$r$")
    amuse_plot.ylabel(r"$\rho$")
    pyplot.gca().set_xlim(xmin=10, xmax=1e4)
    pyplot.gca().set_ylim(ymin=1e-30, ymax=9e-24)
    pyplot.gca().set_xscale("log")
    pyplot.gca().set_yscale("log")

    pyplot.axvline(x=cluster.R200.value_in(units.kpc), lw=1, c="grey")
    pyplot.text(cluster.R200.value_in(units.kpc), 5e-24,
                r"$r_{{cut}} =$ {0}".format(cluster.rcut))
    pyplot.axvline(x=cluster.rc.value_in(units.kpc), lw=1, c="grey")
    pyplot.text(cluster.rc.value_in(units.kpc), 5e-24,
                r"$rc =$ {0}".format(cluster.rc))
    pyplot.axvline(x=cluster.a.value_in(units.kpc), lw=1, c="grey")
    pyplot.text(cluster.a.value_in(units.kpc), 1e-24,
                r"$a =$ {0}".format(cluster.a))
Exemplo n.º 12
0
def merge_clusters_with_gas(sfeff=[0.3, 0.3],
                            Nstar=[1000, 1000],
                            totalNgas=40000,
                            t_end=30. | units.Myr,
                            dt_plot=0.05 | units.Myr,
                            Rscale=units.parsec([0.25, 0.25]),
                            tmerge=2.5 | units.Myr,
                            eps_star=0.001 | units.parsec,
                            runid="runtest",
                            feedback_efficiency=0.01,
                            subvirialfac=1.):

    try:
        os.mkdir(runid)
    except:
        pass
    print "Nstar, Ngas:", Nstar, totalNgas

    eps = 0.05 * Rscale.mean()

    IMF = SalpeterIMF(mass_max=100. | units.MSun)

    mean_star_mass = IMF.mass_mean()

    approx_gas_mass = 0. * mean_star_mass
    for e, N in zip(sfeff, Nstar):
        approx_gas_mass += (1 - e) * N * mean_star_mass / e
    mgas = approx_gas_mass / totalNgas

    print "gas particle mass:", mgas.in_(units.MSun)

    stars = []
    gas = []
    total_mass = 0. | units.MSun
    total_gas_mass = 0. | units.MSun
    total_star_mass = 0. | units.MSun
    for e, Ns, r in zip(sfeff, Nstar, Rscale):
        s, g = generate_cluster_with_gas(IMF,
                                         e,
                                         Ns,
                                         r,
                                         mgas,
                                         subvirialfac=subvirialfac,
                                         t_end=t_end)
        stars.append(s)
        gas.append(g)
        total_mass += s.mass.sum() + g.mass.sum()
        total_star_mass += s.mass.sum()
        total_gas_mass += g.mass.sum()

    print "total mass:", total_mass.in_(units.MSun)
    print "total star mass:", total_star_mass.in_(units.MSun)
    print "total gas mass:", total_gas_mass.in_(units.MSun)

    print "t_end:", t_end

    Rsep = (constants.G * total_mass * tmerge**2)**(1. / 3)

    stars[0].x = stars[0].x - Rsep / 2
    stars[1].x = stars[1].x + Rsep / 2
    gas[0].x = gas[0].x - Rsep / 2
    gas[1].x = gas[1].x + Rsep / 2

    conv = nbody_system.nbody_to_si(total_mass, Rsep)

    print "tmerge:", tmerge
    print "Rsep:", Rsep.in_(units.parsec)

    allgas = datamodel.Particles(0)
    allstars = datamodel.Particles(0)
    allgas.add_particles(gas[0])
    allgas.add_particles(gas[1])
    allstars.add_particles(stars[0])
    allstars.add_particles(stars[1])
    allgas.h_smooth = 0. | units.parsec
    allstars.radius = eps_star

    mu = 1.4 | units.amu
    gamma1 = 1.6667 - 1
    #  print 'min Temp:', (gamma1*min(allgas.u)*(1.4*units.amu)/constants.kB).in_(units.K)
    print 'min Temp:', (gamma1 * min(allgas.u) * mu / constants.kB).in_(
        units.K)

    print max(allgas.u)**0.5

    dt = smaller_nbody_power_of_two(dt_plot, conv)
    dt_star = smaller_nbody_power_of_two(0.001 | units.Myr, conv)  #0.001
    dt_sph = dt_star
    dt_fast = dt_star  # 8
    dt_feedback = dt_fast * 4  # 2

    if not dt_star <= dt_fast <= dt_feedback:
        raise Exception

    print 'dt_plot:', conv.to_nbody(dt_plot), dt_plot.in_(units.Myr)
    print 'dt:', conv.to_nbody(dt), dt.in_(units.Myr)
    print 'dt_feedback:', conv.to_nbody(dt_feedback), dt_feedback.in_(
        units.Myr)
    print 'dt_fast:', conv.to_nbody(dt_fast), dt_fast.in_(units.Myr)
    print 'dt_star:', conv.to_nbody(dt_star), dt_star.in_(units.Myr)
    print 'dt_sph:', conv.to_nbody(dt_sph), dt_sph.in_(units.Myr)

    sys = grav_gas_sse(
        PhiGRAPE,
        Gadget2,
        SSEplus,
        Octgrav,
        conv,
        mgas,
        allstars,
        allgas,
        dt_feedback,
        dt_fast,
        grav_parameters=(["epsilon_squared",
                          eps_star**2], ["timestep_parameter", 0.001]),
        #                                ["timestep", dt_star]),
        gas_parameters=(
            ["time_max", 32. | units.Myr],
            #                               ["courant", 0.15 | units.none],
            ["n_smooth", 64 | units.none],
            #                               ["artificial_viscosity_alpha",1.| units.none],
            ["n_smooth_tol", 0.005 | units.none],
            ## NB
            #                               ["max_size_timestep",7500. | units.yr],
            ## NB
            ["time_limit_cpu", 3600000 | units.s]),
        couple_parameters=(["epsilon_squared", eps**2], ["opening_angle",
                                                         0.5]),
        feedback_efficiency=feedback_efficiency,
        feedback_radius=0.025 * Rscale)

    nsnap = 0
    sys.synchronize_model()
    t = sys.model_time
    tout = t.value_in(units.Myr)
    ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
    ep = sys.potential_energy.value_in(1.e51 * units.erg)
    eth = sys.thermal_energy.value_in(1.e51 * units.erg)
    ef = sys.feedback_energy.value_in(1.e51 * units.erg)
    print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
    sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)

    print 'max smooth:', max(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'mean smooth:', sys.sph.gas_particles.radius.mean().in_(units.parsec)
    print 'min smooth:', min(sys.sph.gas_particles.radius).in_(units.parsec)
    print 'eps:', eps.in_(units.parsec)
    print 'feedback radius:', (0.01 * Rscale).in_(units.parsec)

    while (t < t_end - dt / 2):
        sys.evolve_model(t + dt)
        sys.synchronize_model()
        t = sys.model_time
        tout = t.value_in(units.Myr)
        ek = sys.kinetic_energy.value_in(1.e51 * units.erg)
        ep = sys.potential_energy.value_in(1.e51 * units.erg)
        eth = sys.thermal_energy.value_in(1.e51 * units.erg)
        ef = sys.feedback_energy.value_in(1.e51 * units.erg)
        print 't Ek Ep Eth Ef:', tout, ek, ep, eth, ef, ek + ep + eth - ef
        nsnap += 1
        sys.dump_system_state(runid + "/dump-%6.6i" % nsnap)