예제 #1
0
def thomson_scatter(r_packet, time_explosion):
    """
    Thomson scattering — no longer line scattering
    2) get the doppler factor at that position with the old angle
    3) convert the current energy and nu into the comoving
        frame with the old mu
    4) Scatter and draw new mu - update mu
    5) Transform the comoving energy and nu back using the new mu

    Parameters
    ----------
    r_packet : RPacket
    time_explosion: float
        time since explosion in seconds

    """
    old_doppler_factor = get_doppler_factor(r_packet.r, r_packet.mu,
                                            time_explosion)
    comov_nu = r_packet.nu * old_doppler_factor
    comov_energy = r_packet.energy * old_doppler_factor
    r_packet.mu = get_random_mu()
    inverse_new_doppler_factor = get_inverse_doppler_factor(
        r_packet.r, r_packet.mu, time_explosion)

    r_packet.nu = comov_nu * inverse_new_doppler_factor
    r_packet.energy = comov_energy * inverse_new_doppler_factor
    if montecarlo_configuration.full_relativity:
        r_packet.mu = angle_aberration_CMF_to_LF(r_packet, time_explosion,
                                                 r_packet.mu)
예제 #2
0
def line_scatter(r_packet, time_explosion, line_interaction_type,
                 numba_plasma):
    """
    Line scatter function that handles the scattering itself, including new angle drawn, and calculating nu out using macro atom
    r_packet: RPacket
    time_explosion: float
    line_interaction_type: enum
    numba_plasma: NumbaPlasma
    """

    old_doppler_factor = get_doppler_factor(r_packet.r, r_packet.mu,
                                            time_explosion)
    r_packet.mu = get_random_mu()

    inverse_new_doppler_factor = get_inverse_doppler_factor(
        r_packet.r, r_packet.mu, time_explosion)

    comov_energy = r_packet.energy * old_doppler_factor
    r_packet.energy = comov_energy * inverse_new_doppler_factor

    if line_interaction_type == LineInteractionType.SCATTER:
        line_emission(r_packet, r_packet.next_line_id, time_explosion,
                      numba_plasma)
    else:  # includes both macro atom and downbranch - encoded in the transition probabilities
        emission_line_id = macro_atom(r_packet, numba_plasma)
        line_emission(r_packet, emission_line_id, time_explosion, numba_plasma)
예제 #3
0
def test_unphysical_doppler_factor(mu, r, inv_t_exp, packet, model):
    # Set the params from test cases here
    # TODO: add relativity tests
    time_explosion = 1 / inv_t_exp

    # Perform any other setups just before this, they can be additional calls
    # to other methods or introduction of some temporary variables
    with pytest.raises(r_packet.SuperluminalError):
        obtained = r_packet.get_doppler_factor(r, mu, time_explosion)
예제 #4
0
def v_packet_initialize_line_id(v_packet, numba_plasma, numba_model):
    inverse_line_list_nu = numba_plasma.line_list_nu[::-1]
    doppler_factor = r_packet.get_doppler_factor(
        v_packet.r, v_packet.mu, numba_model.time_explosion
    )
    comov_nu = v_packet.nu * doppler_factor
    next_line_id = len(numba_plasma.line_list_nu) - np.searchsorted(
        inverse_line_list_nu, comov_nu
    )
    v_packet.next_line_id = next_line_id
예제 #5
0
def test_get_doppler_factor(mu, r, inv_t_exp, expected):
    # Set the params from test cases here
    # TODO: add relativity tests
    time_explosion = 1 / inv_t_exp

    # Perform any other setups just before this, they can be additional calls
    # to other methods or introduction of some temporary variables

    obtained = r_packet.get_doppler_factor(r, mu, time_explosion)

    # Perform required assertions
    assert_almost_equal(obtained, expected)
예제 #6
0
def test_frame_transformations(packet, mu, r, inv_t_exp, full_relativity):
    packet = r_packet.RPacket(r=r, mu=mu, energy=packet.energy, nu=packet.nu)
    mc.full_relativity = bool(full_relativity)
    mc.full_relativity = full_relativity

    inverse_doppler_factor = r_packet.get_inverse_doppler_factor(
        r, mu, 1 / inv_t_exp)
    r_packet.angle_aberration_CMF_to_LF(packet, 1 / inv_t_exp, packet.mu)

    doppler_factor = r_packet.get_doppler_factor(r, mu, 1 / inv_t_exp)
    mc.full_relativity = False

    assert_almost_equal(doppler_factor * inverse_doppler_factor, 1.0)
예제 #7
0
def test_compute_distance2line_relativistic(mu, r, t_exp, nu, nu_line,
                                            full_relativity, packet, runner):
    packet = r_packet.RPacket(r=r, nu=nu, mu=mu, energy=packet.energy)
    # packet.nu_line = nu_line
    numba_estimator = Estimators(
        runner.j_estimator,
        runner.nu_bar_estimator,
        runner.j_blue_estimator,
        runner.Edotlu_estimator,
    )
    mc.full_relativity = bool(full_relativity)

    doppler_factor = r_packet.get_doppler_factor(r, mu, t_exp)
    comov_nu = packet.nu * doppler_factor
    distance = r_packet.calculate_distance_line(packet, comov_nu, nu_line,
                                                t_exp)
    r_packet.move_r_packet(packet, distance, t_exp, numba_estimator)

    doppler_factor = r_packet.get_doppler_factor(r, mu, t_exp)
    comov_nu = packet.nu * doppler_factor
    mc.full_relativity = False

    assert_allclose(comov_nu, nu_line, rtol=1e-14)
예제 #8
0
def test_move_r_packet(
    packet_params,
    expected_params,
    packet,
    model,
    estimators,
    ENABLE_FULL_RELATIVITY,
):
    distance = 1.0e13
    packet.nu = packet_params["nu"]
    packet.mu = packet_params["mu"]
    packet.energy = packet_params["energy"]
    packet.r = packet_params["r"]

    numba_config.ENABLE_FULL_RELATIVITY = ENABLE_FULL_RELATIVITY
    r_packet.move_r_packet.recompile(
    )  # This must be done as move_r_packet was jitted with ENABLE_FULL_RELATIVITY
    doppler_factor = r_packet.get_doppler_factor(packet.r, packet.mu,
                                                 model.time_explosion)

    r_packet.move_r_packet(packet, distance, model.time_explosion, estimators)

    assert_almost_equal(packet.mu, expected_params["mu"])
    assert_almost_equal(packet.r, expected_params["r"])

    expected_j = expected_params["j"]
    expected_nubar = expected_params["nubar"]

    if ENABLE_FULL_RELATIVITY:
        expected_j *= doppler_factor
        expected_nubar *= doppler_factor

    numba_config.ENABLE_FULL_RELATIVITY = False
    assert_allclose(estimators.j_estimator[packet.current_shell_id],
                    expected_j,
                    rtol=5e-7)
    assert_allclose(
        estimators.nu_bar_estimator[packet.current_shell_id],
        expected_nubar,
        rtol=5e-7,
    )
예제 #9
0
def test_compute_distance2line(packet_params, expected_params, packet, model):
    packet = r_packet.RPacket(packet.r, packet.mu, packet.nu, packet.energy)
    nu_line = packet_params["nu_line"]
    # packet.next_line_id = packet_params['next_line_id']
    # packet.last_line = packet_params['last_line']

    time_explosion = model.time_explosion

    doppler_factor = r_packet.get_doppler_factor(packet.r, packet.mu,
                                                 time_explosion)
    comov_nu = packet.nu * doppler_factor

    d_line = 0
    obtained_tardis_error = None
    try:
        d_line = r_packet.calculate_distance_line(packet, comov_nu, nu_line,
                                                  time_explosion)
    except r_packet.MonteCarloException:
        obtained_tardis_error = r_packet.MonteCarloException

    assert_almost_equal(d_line, expected_params["d_line"])
    assert obtained_tardis_error == expected_params["tardis_error"]
예제 #10
0
def test_move_packet(packet_params, expected_params, packet, model,
                     full_relativity):
    distance = 1e13
    packet.nu = packet_params["nu"]
    packet.mu = packet_params["mu"]
    packet.energy = packet_params["energy"]
    packet.r = packet_params["r"]
    # model.full_relativity = full_relativity
    mc.full_relativity = full_relativity

    doppler_factor = r_packet.get_doppler_factor(packet.r, packet.mu,
                                                 model.time_explosion)
    numba_estimator = Estimators(packet_params["j"], packet_params["nu_bar"],
                                 0, 0)
    r_packet.move_r_packet(packet, distance, model.time_explosion,
                           numba_estimator)

    assert_almost_equal(packet.mu, expected_params["mu"])
    assert_almost_equal(packet.r, expected_params["r"])

    expected_j = expected_params["j"]
    expected_nubar = expected_params["nubar"]
    if full_relativity:
        expected_j *= doppler_factor
        expected_nubar *= doppler_factor

    mc.full_relativity = False

    assert_allclose(
        numba_estimator.j_estimator[packet.current_shell_id],
        expected_j,
        rtol=5e-7,
    )
    assert_allclose(
        numba_estimator.nu_bar_estimator[packet.current_shell_id],
        expected_nubar,
        rtol=5e-7,
    )
예제 #11
0
def test_calculate_distance_line(packet_params, expected_params, static_packet,
                                 model):
    nu_line = packet_params["nu_line"]
    is_last_line = packet_params["is_last_line"]

    time_explosion = model.time_explosion

    doppler_factor = r_packet.get_doppler_factor(static_packet.r,
                                                 static_packet.mu,
                                                 time_explosion)
    comov_nu = static_packet.nu * doppler_factor

    d_line = 0
    obtained_tardis_error = None
    try:
        d_line = r_packet.calculate_distance_line(static_packet, comov_nu,
                                                  is_last_line, nu_line,
                                                  time_explosion)
    except r_packet.MonteCarloException:
        obtained_tardis_error = r_packet.MonteCarloException

    assert_almost_equal(d_line, expected_params["d_line"])
    assert obtained_tardis_error == expected_params["tardis_error"]
예제 #12
0
def trace_vpacket_within_shell(v_packet, numba_model, numba_plasma):
    """
    Trace VPacket within one shell (relatively simple operation)
    """
    r_inner = numba_model.r_inner[v_packet.current_shell_id]
    r_outer = numba_model.r_outer[v_packet.current_shell_id]

    distance_boundary, delta_shell = calculate_distance_boundary(
        v_packet.r, v_packet.mu, r_inner, r_outer
    )
    # defining start for line interaction
    start_line_id = v_packet.next_line_id

    # e scattering initialization

    cur_electron_density = numba_plasma.electron_density[
        v_packet.current_shell_id
    ]
    tau_electron = calculate_tau_electron(
        cur_electron_density, distance_boundary
    )
    tau_trace_combined = tau_electron

    # Calculating doppler factor
    doppler_factor = get_doppler_factor(
        v_packet.r, v_packet.mu, numba_model.time_explosion
    )
    comov_nu = v_packet.nu * doppler_factor
    cur_line_id = start_line_id

    for cur_line_id in range(start_line_id, len(numba_plasma.line_list_nu)):
        # if tau_trace_combined > 10: ### FIXME ?????
        #    break

        nu_line = numba_plasma.line_list_nu[cur_line_id]
        # TODO: Check if this is what the C code does

        tau_trace_line = numba_plasma.tau_sobolev[
            cur_line_id, v_packet.current_shell_id
        ]

        if cur_line_id == len(numba_plasma.line_list_nu) - 1:
            is_last_line = True
        else:
            is_last_line = False

        distance_trace_line = calculate_distance_line(
            v_packet,
            comov_nu,
            is_last_line,
            nu_line,
            numba_model.time_explosion,
        )

        if cur_line_id != (len(numba_plasma.line_list_nu) - 1):
            test_for_close_line(
                v_packet,
                cur_line_id,
                numba_plasma.line_list_nu[cur_line_id - 1],
                numba_plasma,
            )

        if distance_boundary <= distance_trace_line:
            break

        tau_trace_combined += tau_trace_line

    else:
        if cur_line_id == (len(numba_plasma.line_list_nu) - 1):
            cur_line_id += 1
    v_packet.next_line_id = cur_line_id

    return tau_trace_combined, distance_boundary, delta_shell
예제 #13
0
def trace_vpacket_volley(
    r_packet, vpacket_collection, numba_model, numba_plasma
):
    """
    Shoot a volley of vpackets (the vpacket collection specifies how many)
    from the current position of the rpacket.

    Parameters
    ----------
    r_packet : [type]
        [description]
    vpacket_collection : [type]
        [description]
    numba_model : [type]
        [description]
    numba_plasma : [type]
        [description]
    """

    if (r_packet.nu < vpacket_collection.v_packet_spawn_start_frequency) or (
        r_packet.nu > vpacket_collection.v_packet_spawn_end_frequency
    ):

        return

    no_of_vpackets = vpacket_collection.number_of_vpackets
    if no_of_vpackets == 0:
        return

    ### TODO theoretical check for r_packet nu within vpackets bins - is done somewhere else I think
    if r_packet.r > numba_model.r_inner[0]:  # not on inner_boundary
        r_inner_over_r = numba_model.r_inner[0] / r_packet.r
        mu_min = -math.sqrt(1 - r_inner_over_r * r_inner_over_r)
        v_packet_on_inner_boundary = False
        if montecarlo_configuration.full_relativity:
            mu_min = angle_aberration_LF_to_CMF(
                r_packet, numba_model.time_explosion, mu_min
            )
    else:
        v_packet_on_inner_boundary = True
        mu_min = 0.0

    mu_bin = (1.0 - mu_min) / no_of_vpackets
    r_packet_doppler_factor = get_doppler_factor(
        r_packet.r, r_packet.mu, numba_model.time_explosion
    )
    for i in range(no_of_vpackets):
        v_packet_mu = mu_min + i * mu_bin + np.random.random() * mu_bin

        if v_packet_on_inner_boundary:  # The weights are described in K&S 2014
            weight = 2 * v_packet_mu / no_of_vpackets
        else:
            weight = (1 - mu_min) / (2 * no_of_vpackets)

        # C code: next line, angle_aberration_CMF_to_LF( & virt_packet, storage);
        if montecarlo_configuration.full_relativity:
            v_packet_mu = angle_aberration_CMF_to_LF(
                r_packet, numba_model.time_explosion, v_packet_mu
            )
        v_packet_doppler_factor = get_doppler_factor(
            r_packet.r, v_packet_mu, numba_model.time_explosion
        )

        # transform between r_packet mu and v_packet_mu

        doppler_factor_ratio = r_packet_doppler_factor / v_packet_doppler_factor

        v_packet_nu = r_packet.nu * doppler_factor_ratio
        v_packet_energy = r_packet.energy * weight * doppler_factor_ratio

        v_packet = VPacket(
            r_packet.r,
            v_packet_mu,
            v_packet_nu,
            v_packet_energy,
            r_packet.current_shell_id,
            r_packet.next_line_id,
            i,
            r_packet.is_close_line,
        )

        if r_packet.next_line_id <= (len(numba_plasma.line_list_nu) - 1):
            test_for_close_line(
                v_packet,
                r_packet.next_line_id,
                numba_plasma.line_list_nu[r_packet.next_line_id - 1],
                numba_plasma,
            )

        tau_vpacket = trace_vpacket(v_packet, numba_model, numba_plasma)

        v_packet.energy *= math.exp(-tau_vpacket)

        vpacket_collection.set_properties(
            v_packet.nu,
            v_packet.energy,
            r_packet.last_interaction_in_nu,
            r_packet.last_interaction_type,
            r_packet.last_line_interaction_in_id,
            r_packet.last_line_interaction_out_id,
        )