예제 #1
0
def test_proper_units():
    """
    Make sure two different proper units systems give the same answer.
    """

    grackle_dir = os.path.dirname(
        os.path.dirname(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
    data_file_path = bytearray(
        os.sep.join([grackle_dir, "input", "CloudyData_UVB=HM2012.h5"]),
        'utf-8')

    my_random_state = np.random.RandomState(20150725)
    for current_redshift in [0., 1., 3.]:

        # proper units
        chem_1 = chemistry_data()
        chem_1.use_grackle = 1
        chem_1.with_radiative_cooling = 0
        chem_1.primordial_chemistry = 1
        chem_1.metal_cooling = 1
        chem_1.UVbackground = 1
        chem_1.grackle_data_file = data_file_path
        chem_1.comoving_coordinates = 0
        chem_1.a_units = 1.0
        chem_1.a_value = 1.0 / (1.0 + current_redshift) / chem_1.a_units
        chem_1.density_units = random_logscale(-1,
                                               1,
                                               random_state=my_random_state)
        chem_1.length_units = random_logscale(0,
                                              2,
                                              random_state=my_random_state)
        chem_1.time_units = random_logscale(0, 2, random_state=my_random_state)
        chem_1.velocity_units = chem_1.length_units / chem_1.time_units
        fc_1 = setup_fluid_container(chem_1, converge=False)
        fc_1.calculate_temperature()
        fc_1.calculate_cooling_time()
        t_sort_1 = np.argsort(fc_1["temperature"])
        t_cool_1 = fc_1["cooling_time"][t_sort_1] * chem_1.time_units

        # proper units
        chem_2 = chemistry_data()
        chem_2.use_grackle = 1
        chem_2.with_radiative_cooling = 0
        chem_2.primordial_chemistry = 1
        chem_2.metal_cooling = 1
        chem_2.UVbackground = 1
        chem_2.grackle_data_file = data_file_path
        chem_2.comoving_coordinates = 0
        chem_2.a_units = 1.0
        chem_2.a_value = 1.0 / (1.0 + current_redshift) / chem_2.a_units
        chem_2.density_units = random_logscale(-28,
                                               -26,
                                               random_state=my_random_state)
        chem_2.length_units = random_logscale(0,
                                              2,
                                              random_state=my_random_state)
        chem_2.time_units = random_logscale(0, 2, random_state=my_random_state)
        chem_2.velocity_units = chem_2.length_units / chem_2.time_units
        fc_2 = setup_fluid_container(chem_2, converge=False)
        fc_2.calculate_temperature()
        fc_2.calculate_cooling_time()
        t_sort_2 = np.argsort(fc_2["temperature"])
        t_cool_2 = fc_2["cooling_time"][t_sort_2] * chem_2.time_units

        comp = "\nDU1: %e, LU1: %e, TU1: %e - DU2: %e, LU2: %e, TU2L %e." % \
            (chem_1.density_units, chem_1.length_units, chem_1.time_units,
             chem_2.density_units, chem_2.length_units, chem_2.time_units)

        assert_rel_equal(
            t_cool_1, t_cool_2, 4,
            (("Different proper unit system cooling times disagree for " +
              "z = %f with min/max = %f/%f.") %
             (current_redshift, (t_cool_1 / t_cool_2).min(),
              (t_cool_1 / t_cool_2).max()) + comp))
예제 #2
0
def test_proper_comoving_units_tabular():
    """
    Make sure proper and comoving units systems give the same
    answer with tabular cooling.
    """

    grackle_dir = os.path.dirname(
        os.path.dirname(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
    data_file_path = bytearray(
        os.sep.join([grackle_dir, "input", "CloudyData_UVB=HM2012.h5"]),
        'utf-8')

    my_random_state = np.random.RandomState(19650909)
    for current_redshift in [0., 1., 3., 6., 9.]:

        # comoving units
        chem_c = chemistry_data()
        chem_c.use_grackle = 1
        chem_c.with_radiative_cooling = 0
        chem_c.primordial_chemistry = 0
        chem_c.metal_cooling = 1
        chem_c.UVbackground = 1
        chem_c.grackle_data_file = data_file_path
        set_cosmology_units(chem_c,
                            current_redshift=current_redshift,
                            initial_redshift=99.)
        fc_c = setup_fluid_container(chem_c, converge=False)
        fc_c.calculate_temperature()
        fc_c.calculate_cooling_time()
        t_sort_c = np.argsort(fc_c["temperature"])
        t_cool_c = fc_c["cooling_time"][t_sort_c] * chem_c.time_units

        # proper units
        chem_p = chemistry_data()
        chem_p.use_grackle = 1
        chem_p.with_radiative_cooling = 0
        chem_p.primordial_chemistry = 0
        chem_p.metal_cooling = 1
        chem_p.UVbackground = 1
        chem_p.grackle_data_file = data_file_path
        chem_p.comoving_coordinates = 0
        chem_p.a_units = 1.0
        chem_p.a_value = 1.0 / (1.0 + current_redshift) / chem_p.a_units
        # Set the proper units to be of similar magnitude to the
        # comoving system to help the solver be more efficient.
        chem_p.density_units = random_logscale(-2, 2, random_state=my_random_state) * \
            chem_c.density_units / (1 + current_redshift)**3
        chem_p.length_units = random_logscale(-2, 2, random_state=my_random_state) * \
            chem_c.length_units * (1 + current_redshift)
        chem_p.time_units = random_logscale(-2, 2, random_state=my_random_state) * \
            chem_c.time_units
        chem_p.velocity_units = chem_p.length_units / chem_p.time_units
        fc_p = setup_fluid_container(chem_p, converge=False)
        fc_p.calculate_temperature()
        fc_p.calculate_cooling_time()
        t_sort_p = np.argsort(fc_p["temperature"])
        t_cool_p = fc_p["cooling_time"][t_sort_p] * chem_p.time_units

        comp = "\nDU1: %e, LU1: %e, TU1: %e - DU2: %e, LU2: %e, TU2L %e." % \
            (chem_p.density_units, chem_p.length_units, chem_p.time_units,
             chem_c.density_units, chem_c.length_units, chem_c.time_units)

        assert_rel_equal(
            t_cool_p, t_cool_c, 4,
            (("Proper and comoving tabular cooling times disagree for " +
              "z = %f with min/max = %f/%f.\n") %
             (current_redshift, (t_cool_p / t_cool_c).min(),
              (t_cool_p / t_cool_c).max()) + comp))
예제 #3
0
def test_equilibrium():
    """
    Test ionization equilibrium for a primordial gas against the analytical
    solution using the same rates.

    This test takes a long time because the iteration to convergence near
    T = 1e4 K is slow.
    """

    my_chem = chemistry_data()
    my_chem.use_grackle = 1
    my_chem.with_radiative_cooling = 0
    my_chem.primordial_chemistry = 1
    my_chem.metal_cooling = 0
    my_chem.UVbackground = 0
    my_chem.comoving_coordinates = 0
    my_chem.a_units = 1.0
    my_chem.a_value = 1.0
    my_chem.density_units = mass_hydrogen_cgs
    my_chem.length_units = 1.0
    my_chem.time_units = 1.0
    my_chem.velocity_units = my_chem.length_units / my_chem.time_units
    fc = setup_fluid_container(my_chem,
                               temperature=np.logspace(4.5, 9, 200),
                               converge=True,
                               tolerance=1e-6,
                               max_iterations=np.inf)

    fc.calculate_temperature()
    fc.calculate_cooling_time()
    t_sort = np.argsort(fc["temperature"])
    t_cool = fc["cooling_time"][t_sort] * my_chem.time_units
    my_T = fc["temperature"][t_sort]
    my_nH = fc.calculate_hydrogen_number_density().mean()

    cooling_rate_eq = -1 * total_cooling(my_T, my_nH) / my_nH**2
    cooling_rate_g = fc["energy"][t_sort] / t_cool * fc["density"] * \
        my_chem.density_units / my_nH**2

    # Make a cooling rate figure
    fontsize = 14
    axes = pyplot.axes()
    axes.loglog(my_T,
                -1 * cooling_rate_eq,
                color='black',
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                -1 * cooling_rate_g,
                color='black',
                alpha=0.7,
                linestyle="-",
                linewidth=1)
    axes.xaxis.set_label_text('T [K]', fontsize=fontsize)
    axes.yaxis.set_label_text(
        r'$-\Lambda$ / n${_{\rm H}}^{2}$ [erg s$^{-1}$ cm$^{3}$]',
        fontsize=fontsize)
    axes.set_xlim(1e4, 1e9)
    axes.set_ylim(1e-26, 2e-22)
    tick_labels = axes.xaxis.get_ticklabels() + \
        axes.yaxis.get_ticklabels()
    for tick_label in tick_labels:
        tick_label.set_size(fontsize)
    pyplot.savefig('cooling.png')
    pyplot.clf()

    # Make an ionization balance figure
    nH_eq = nHI(my_T, my_nH) + nHII(my_T, my_nH)
    nH_g = fc["HI"] + fc["HII"]
    fHI_eq = nHI(my_T, my_nH) / nH_eq
    fHI_g = fc["HI"] / nH_g
    fHII_eq = nHII(my_T, my_nH) / nH_eq
    fHII_g = fc["HII"] / nH_g

    nHe_eq = nHeI(my_T, my_nH) + nHeII(my_T, my_nH) + nHeIII(my_T, my_nH)
    nHe_g = fc["HeI"] + fc["HeII"] + fc["HeIII"]
    fHeI_eq = nHeI(my_T, my_nH) / nHe_eq
    fHeI_g = fc["HeI"] / nHe_g
    fHeII_eq = nHeII(my_T, my_nH) / nHe_eq
    fHeII_g = fc["HeII"] / nHe_g
    fHeIII_eq = nHeIII(my_T, my_nH) / nHe_eq
    fHeIII_g = fc["HeIII"] / nHe_g

    # Plot H ions
    axes = pyplot.axes()
    axes.loglog(my_T,
                fHI_eq,
                color="#B82E00",
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                fHII_eq,
                color="#B88A00",
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                fHI_g,
                label="HI",
                color="#B82E00",
                alpha=0.7,
                linestyle="-",
                linewidth=1.)
    axes.loglog(my_T,
                fHII_g,
                label="HII",
                color="#B88A00",
                alpha=0.7,
                linestyle="-",
                linewidth=1.)

    # Plot He ions
    axes.loglog(my_T,
                fHeI_eq,
                color="#002EB8",
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                fHeII_eq,
                color="#008AB8",
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                fHeIII_eq,
                color="#00B88A",
                alpha=0.7,
                linestyle="--",
                linewidth=1.5)
    axes.loglog(my_T,
                fHeI_g,
                label="HeI",
                color="#002EB8",
                alpha=0.7,
                linestyle="-",
                linewidth=1.)
    axes.loglog(my_T,
                fHeII_g,
                label="HeII",
                color="#008AB8",
                alpha=0.7,
                linestyle="-",
                linewidth=1.)
    axes.loglog(my_T,
                fHeIII_g,
                label="HeIII",
                color="#00B88A",
                alpha=0.7,
                linestyle="-",
                linewidth=1.)

    axes.xaxis.set_label_text('T [K]', fontsize=fontsize)
    axes.yaxis.set_label_text('fraction', fontsize=fontsize)
    axes.set_xlim(1e4, 1e9)
    axes.set_ylim(1e-10, 1)
    tick_labels = axes.xaxis.get_ticklabels() + \
        axes.yaxis.get_ticklabels()
    for tick_label in tick_labels:
        tick_label.set_size(fontsize)
    axes.legend(loc='best', prop=dict(size=fontsize))
    pyplot.savefig('fractions.png')

    test_precision = 1

    # test the cooling rates
    cool_ratio = cooling_rate_eq / cooling_rate_g
    assert_rel_equal(
        cooling_rate_eq, cooling_rate_g, test_precision,
        "Equilibrium cooling rates disagree with min/max = %f/%f." %
        (cool_ratio.min(), cool_ratio.max()))

    # test the ionization balance
    assert_rel_equal(
        fHI_eq, fHI_g, test_precision,
        "HI fractions disagree with min/max = %f/%f." %
        ((fHI_eq / fHI_g).min(), (fHI_eq / fHI_g).max()))

    assert_rel_equal(
        fHII_eq, fHII_g, test_precision,
        "HII fractions disagree with min/max = %f/%f." %
        ((fHII_eq / fHII_g).min(), (fHII_eq / fHII_g).max()))

    assert_rel_equal(
        fHeI_eq, fHeI_g, test_precision,
        "HeI fractions disagree with min/max = %f/%f." %
        ((fHeI_eq / fHeI_g).min(), (fHeI_eq / fHeI_g).max()))

    assert_rel_equal(
        fHeII_eq, fHeII_g, test_precision,
        "HeII fractions disagree with min/max = %f/%f." %
        ((fHeII_eq / fHeII_g).min(), (fHeII_eq / fHeII_g).max()))

    assert_rel_equal(
        fHeIII_eq, fHeIII_g, test_precision,
        "HeIII fractions disagree with min/max = %f/%f." %
        ((fHeIII_eq / fHeIII_g).min(), (fHeIII_eq / fHeIII_g).max()))