예제 #1
0
    def create_q_matrices(self):
        q_sn_ia = matrix.q_sn(constants.CHANDRASEKHAR_LIMIT,
                              feh=self.context["abundances"].feh(),
                              sn_yields=self.context["sn_yields"])
        imf_sn_file = open(f"{self.context['output_dir']}/imf_supernova_rates",
                           "w+")
        matrices_file = open(f"{self.context['output_dir']}/qm-matrices", "w+")
        if self.context["return_fractions"] is True:
            return_fraction_file = open(
                f"{self.context['output_dir']}/return_fractions", "w+")

        for i in range(0, self.total_time_steps):
            m_inf, m_sup = self.mass_intervals[i]
            q = np.zeros((constants.Q_MATRIX_ROWS, constants.Q_MATRIX_COLUMNS))
            phi, supernova_Ia_rates, supernova_II_rates, r = 0.0, 0.0, 0.0, 0.0

            if m_sup > constants.M_MIN and m_sup > m_inf:
                q += newton_cotes(
                    m_inf, m_sup, lambda m: global_imf(
                        m, self.initial_mass_function, self.context[
                            "binary_fraction"]) * matrix.q(m, self.context))

                supernova_Ia_rates = self.sn_Ia_rates[
                    i] * self.initial_mass_function.stars_per_mass_unit * dtd_correction(
                        self.context)
                q += q_sn_ia * supernova_Ia_rates

                phi = newton_cotes(
                    m_inf, m_sup,
                    lambda m: global_imf(m, self.initial_mass_function, self.
                                         context["binary_fraction"]))

                supernova_II_rates = newton_cotes(
                    m_inf, m_sup, lambda m: imf_supernovae_II(
                        m, self.initial_mass_function, self.context[
                            "binary_fraction"]))

                if self.context["return_fractions"] is True:
                    r = return_fraction(m_inf, m_sup, self.context["expelled"],
                                        self.initial_mass_function,
                                        self.context["binary_fraction"])

            np.savetxt(matrices_file,
                       q,
                       fmt="%15.10f",
                       header=self._matrix_header(m_sup, m_inf))
            imf_sn_file.write(
                f"  {phi:.10f}  {supernova_Ia_rates:.10f}  {supernova_II_rates:.10f}  {self.energies[i]:.10f}\n"
            )
            if self.context["return_fractions"] is True:
                return_fraction_file.write(f"{r:.10f}\n")

        matrices_file.close()
        imf_sn_file.close()
        if self.context["return_fractions"] is True:
            return_fraction_file.close()
예제 #2
0
    def explosive_nucleosynthesis_two_steps_t(self):
        t_ini = stellar_lifetime(self.m_max, self.z)
        t_limit_massive = stellar_lifetime(4.0, self.z)
        t_end = min(stellar_lifetime(self.m_min, self.z), constants.TOTAL_TIME)

        delta_t_1 = stellar_lifetime(100.0, self.z) / 2
        delta_t_2 = 50 * delta_t_1

        steps_with_delta_t_1 = math.ceil((t_limit_massive - t_ini) / delta_t_1)
        t_ini_for_delta_2 = t_ini + (delta_t_1 * steps_with_delta_t_1)
        steps_with_delta_t_2 = math.ceil(
            (t_end - t_ini_for_delta_2) / delta_t_2)
        delta_t_2 = (t_end - t_ini_for_delta_2) / steps_with_delta_t_2
        self.total_time_steps = steps_with_delta_t_1 + steps_with_delta_t_2

        mass_intervals_file = open(
            f"{self.context['output_dir']}/mass_intervals", "w+")
        mass_intervals_file.write(" ".join([
            str(i) for i in [
                t_ini, t_end, steps_with_delta_t_1, steps_with_delta_t_2,
                delta_t_1, delta_t_2
            ]
        ]))

        for step in range(0, steps_with_delta_t_1):
            t_inf = t_ini + (delta_t_1 * step)
            t_sup = t_ini + (delta_t_1 * (step + 1))

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        for step in range(0, steps_with_delta_t_2):
            t_inf = t_ini_for_delta_2 + (delta_t_2 * step)
            t_sup = t_ini_for_delta_2 + (delta_t_2 * (step + 1))

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        mass_intervals_file.close()
예제 #3
0
    def explosive_nucleosynthesis_fixed_n_steps(self, n_massive, n_small):
        t_ini = stellar_lifetime(self.m_max, self.z)
        t_limit_massive = stellar_lifetime(4.0, self.z)
        t_end = min(stellar_lifetime(self.m_min, self.z), constants.TOTAL_TIME)

        delta_t_1 = (t_limit_massive - t_ini) / n_massive
        delta_t_2 = (t_end - t_limit_massive) / n_small

        self.total_time_steps = n_massive + n_small

        mass_intervals_file = open(
            f"{self.context['output_dir']}/mass_intervals", "w+")
        mass_intervals_file.write(" ".join([
            str(i)
            for i in [t_ini, t_end, n_massive, n_small, delta_t_1, delta_t_2]
        ]))

        for step in range(0, n_massive):
            t_inf = t_ini + (delta_t_1 * step)
            t_sup = t_ini + (delta_t_1 * (step + 1))

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        for step in range(0, n_small):
            t_inf = t_limit_massive + (delta_t_2 * step)
            t_sup = t_limit_massive + (delta_t_2 * (step + 1))

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        mass_intervals_file.close()
예제 #4
0
    def explosive_nucleosynthesis_step_t(self):
        t_ini = stellar_lifetime(self.m_max, self.z)
        t_end = min(stellar_lifetime(self.m_min, self.z), constants.TOTAL_TIME)

        delta_t = (t_end - t_ini) / self.total_time_steps

        mass_intervals_file = open(
            f"{self.context['output_dir']}/mass_intervals", "w+")
        mass_intervals_file.write(" ".join(
            [str(i) for i in [t_ini, t_end, self.total_time_steps, delta_t]]))

        for step in range(0, self.total_time_steps):
            t_inf = t_ini + (delta_t * step)
            t_sup = t_ini + (delta_t * (step + 1))

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        mass_intervals_file.close()
예제 #5
0
    def explosive_nucleosynthesis_step_logt(self):
        t_ini = stellar_lifetime(min(self.m_max, max_mass_allowed(self.z)),
                                 self.z)
        t_end = min(stellar_lifetime(self.m_min, self.z), constants.TOTAL_TIME)
        t_ini_log = math.log10(t_ini * 1e9)
        t_end_log = math.log10(t_end * 1e9)

        delta_t_log = (t_end_log - t_ini_log) / self.total_time_steps

        mass_intervals_file = open(
            f"{self.context['output_dir']}/mass_intervals", "w+")
        mass_intervals_file.write(" ".join([
            str(i) for i in [t_ini, t_end, self.total_time_steps, delta_t_log]
        ]))

        for step in range(0, self.total_time_steps):
            t_inf_log = t_ini_log + (delta_t_log * step)
            t_sup_log = t_ini_log + (delta_t_log * (step + 1))

            t_inf = math.pow(10, t_inf_log - 9)
            t_sup = math.pow(10, t_sup_log - 9)

            m_inf = stellar_mass(t_sup, self.z)
            m_sup = stellar_mass(t_inf, self.z)

            mass_intervals_file.write('\n' + f'{m_sup:14.10f}  ' +
                                      f'{m_inf:14.10f}  ' + str(step + 1))

            self.mass_intervals.append([m_inf, m_sup])
            self.energies.append(
                total_energy_ejected(t_sup) - total_energy_ejected(t_inf))
            self.sn_Ia_rates.append(newton_cotes(t_inf, t_sup, self.dtd))

        mass_intervals_file.close()
예제 #6
0
def test_imf_binary_secondary_integrates_phi_secondary():
    m_in_binaries_range = 5.0
    m_inf = 2 * m_in_binaries_range
    imf = select_imf(np.random.choice(settings.valid_values["imf"]),
                     settings.default)

    expected = settings.default['binary_fraction'] * \
        functions.newton_cotes(m_inf, constants.B_MAX, functions.phi_secondary(m_in_binaries_range, imf))
    assert functions.imf_binary_secondary(m_in_binaries_range, imf) == expected
예제 #7
0
def test_return_fractions():
    imf = select_imf(np.random.choice(settings.valid_values["imf"]),
                     settings.default)
    default_yields_file = settings.default['expelled_elements_filename']
    stellar_yields = elements.Expelled(default_yields_file)

    expected = functions.newton_cotes(
        1, 100, lambda m: (functions.global_imf(m, imf) / m) *
        (m - stellar_yields.for_mass(m)['remnants']))

    assert functions.return_fraction(1, 100, stellar_yields, imf) == expected