int64_t montecarlo_one_packet_loop(storage_model_t *storage, rpacket_t *packet, int64_t virtual_packet) { rpacket_set_tau_event(packet, 0.0); rpacket_set_nu_line(packet, 0.0); rpacket_set_virtual_packet(packet, virtual_packet); rpacket_set_status(packet, TARDIS_PACKET_STATUS_IN_PROCESS); // Initializing tau_event if it's a real packet. if (virtual_packet == 0) { rpacket_reset_tau_event(packet); } // For a virtual packet tau_event is the sum of all the tau's that the packet passes. while (rpacket_get_status(packet) == TARDIS_PACKET_STATUS_IN_PROCESS) { // Check if we are at the end of line list. if (!rpacket_get_last_line(packet)) { rpacket_set_nu_line(packet, storage->line_list_nu[rpacket_get_next_line_id(packet)]); } double distance; get_event_handler(packet, storage, &distance)(packet, storage, distance); if (virtual_packet > 0 && rpacket_get_tau_event(packet) > 10.0) { rpacket_set_tau_event(packet, 100.0); rpacket_set_status(packet, TARDIS_PACKET_STATUS_EMITTED); } } if (virtual_packet > 0) { rpacket_set_energy(packet, rpacket_get_energy(packet) * exp(-1.0 * rpacket_get_tau_event(packet))); } return rpacket_get_status(packet) == TARDIS_PACKET_STATUS_REABSORBED ? 1 : 0; }
void move_packet (rpacket_t * packet, storage_model_t * storage, double distance) { double doppler_factor = rpacket_doppler_factor (packet, storage); if (distance > 0.0) { double r = rpacket_get_r (packet); double new_r = sqrt (r * r + distance * distance + 2.0 * r * distance * rpacket_get_mu (packet)); rpacket_set_mu (packet, (rpacket_get_mu (packet) * r + distance) / new_r); rpacket_set_r (packet, new_r); if (rpacket_get_virtual_packet (packet) <= 0) { double comov_energy = rpacket_get_energy (packet) * doppler_factor; double comov_nu = rpacket_get_nu (packet) * doppler_factor; #ifdef WITHOPENMP #pragma omp atomic #endif storage->js[rpacket_get_current_shell_id (packet)] += comov_energy * distance; #ifdef WITHOPENMP #pragma omp atomic #endif storage->nubars[rpacket_get_current_shell_id (packet)] += comov_energy * distance * comov_nu; } } }
int64_t montecarlo_one_packet(storage_model_t *storage, rpacket_t *packet, int64_t virtual_mode) { int64_t i; rpacket_t virt_packet; double mu_bin; double mu_min; double doppler_factor_ratio; double weight; int64_t virt_id_nu; if (virtual_mode == 0) { montecarlo_one_packet_loop(storage, packet, 0); } else { for (i = 0; i < rpacket_get_virtual_packet_flag(packet); i++) { memcpy((void *)&virt_packet, (void *)packet, sizeof(rpacket_t)); if (virt_packet.r > storage->r_inner[0]) { mu_min = -1.0 * sqrt(1.0 - (storage->r_inner[0] / virt_packet.r) * (storage->r_inner[0] / virt_packet.r)); } else { mu_min = 0.0; } mu_bin = (1.0 - mu_min) / rpacket_get_virtual_packet_flag(packet); virt_packet.mu = mu_min + (i + rk_double(&mt_state)) * mu_bin; switch(virtual_mode) { case -2: weight = 1.0 / rpacket_get_virtual_packet_flag(packet); break; case -1: weight = 2.0 * virt_packet.mu / rpacket_get_virtual_packet_flag(packet); break; case 1: weight = (1.0 - mu_min) / 2.0 / rpacket_get_virtual_packet_flag(packet); break; default: fprintf(stderr, "Something has gone horribly wrong!\n"); } doppler_factor_ratio = rpacket_doppler_factor(packet, storage) / rpacket_doppler_factor(&virt_packet, storage); virt_packet.energy = rpacket_get_energy(packet) * doppler_factor_ratio; virt_packet.nu = rpacket_get_nu(packet) * doppler_factor_ratio; montecarlo_one_packet_loop(storage, &virt_packet, 1); if ((virt_packet.nu < storage->spectrum_end_nu) && (virt_packet.nu > storage->spectrum_start_nu)) { virt_id_nu = floor((virt_packet.nu - storage->spectrum_start_nu) / storage->spectrum_delta_nu); storage->spectrum_virt_nu[virt_id_nu] += virt_packet.energy * weight; } } } }
void increment_Edotlu_estimator (const rpacket_t * packet, storage_model_t * storage, int64_t line_idx) { if (storage->line_lists_Edotlu != NULL) { #ifdef WITHOPENMP #pragma omp atomic #endif storage->line_lists_Edotlu[line_idx] += rpacket_get_energy (packet); } }
inline void increment_j_blue_estimator(rpacket_t *packet, storage_model_t *storage, double d_line, int64_t j_blue_idx) { double comov_energy, r_interaction, mu_interaction, doppler_factor; double r = rpacket_get_r(packet); r_interaction = sqrt(r * r + d_line * d_line + 2.0 * r * d_line * rpacket_get_mu(packet)); mu_interaction = (rpacket_get_mu(packet) * r + d_line) / r_interaction; doppler_factor = 1.0 - mu_interaction * r_interaction * storage->inverse_time_explosion * INVERSE_C; comov_energy = rpacket_get_energy(packet) * doppler_factor; storage->line_lists_j_blues[j_blue_idx] += comov_energy / rpacket_get_nu(packet); }
void move_packet_across_shell_boundary (rpacket_t * packet, storage_model_t * storage, double distance, rk_state *mt_state) { move_packet (packet, storage, distance); if (rpacket_get_virtual_packet (packet) > 0) { double delta_tau_event = rpacket_get_chi_continuum(packet) * distance; rpacket_set_tau_event (packet, rpacket_get_tau_event (packet) + delta_tau_event); } else { rpacket_reset_tau_event (packet, mt_state); } if ((rpacket_get_current_shell_id (packet) < storage->no_of_shells - 1 && rpacket_get_next_shell_id (packet) == 1) || (rpacket_get_current_shell_id (packet) > 0 && rpacket_get_next_shell_id (packet) == -1)) { rpacket_set_current_shell_id (packet, rpacket_get_current_shell_id (packet) + rpacket_get_next_shell_id (packet)); } else if (rpacket_get_next_shell_id (packet) == 1) { rpacket_set_status (packet, TARDIS_PACKET_STATUS_EMITTED); } else if ((storage->reflective_inner_boundary == 0) || (rk_double (mt_state) > storage->inner_boundary_albedo)) { rpacket_set_status (packet, TARDIS_PACKET_STATUS_REABSORBED); } else { double doppler_factor = rpacket_doppler_factor (packet, storage); double comov_nu = rpacket_get_nu (packet) * doppler_factor; double comov_energy = rpacket_get_energy (packet) * doppler_factor; rpacket_set_mu (packet, rk_double (mt_state)); double inverse_doppler_factor = 1.0 / rpacket_doppler_factor (packet, storage); rpacket_set_nu (packet, comov_nu * inverse_doppler_factor); rpacket_set_energy (packet, comov_energy * inverse_doppler_factor); if (rpacket_get_virtual_packet_flag (packet) > 0) { montecarlo_one_packet (storage, packet, -2, mt_state); } } }
void move_packet_across_shell_boundary(rpacket_t *packet, storage_model_t *storage, double distance) { double comov_energy, doppler_factor, comov_nu, inverse_doppler_factor; move_packet(packet, storage, distance); if (rpacket_get_virtual_packet(packet) > 0) { double delta_tau_event = distance * storage->electron_densities[rpacket_get_current_shell_id(packet)] * storage->sigma_thomson; rpacket_set_tau_event(packet, rpacket_get_tau_event(packet) + delta_tau_event); } else { rpacket_reset_tau_event(packet); } if ((rpacket_get_current_shell_id(packet) < storage->no_of_shells - 1 && rpacket_get_next_shell_id(packet) == 1) || (rpacket_get_current_shell_id(packet) > 0 && rpacket_get_next_shell_id(packet) == -1)) { rpacket_set_current_shell_id(packet, rpacket_get_current_shell_id(packet) + rpacket_get_next_shell_id(packet)); rpacket_set_recently_crossed_boundary(packet, rpacket_get_next_shell_id(packet)); } else if (rpacket_get_next_shell_id(packet) == 1) { rpacket_set_status(packet, TARDIS_PACKET_STATUS_EMITTED); } else if ((storage->reflective_inner_boundary == 0) || (rk_double(&mt_state) > storage->inner_boundary_albedo)) { rpacket_set_status(packet, TARDIS_PACKET_STATUS_REABSORBED); } else { doppler_factor = rpacket_doppler_factor(packet, storage); comov_nu = rpacket_get_nu(packet) * doppler_factor; comov_energy = rpacket_get_energy(packet) * doppler_factor; rpacket_set_mu(packet, rk_double(&mt_state)); inverse_doppler_factor = 1.0 / rpacket_doppler_factor(packet, storage); rpacket_set_nu(packet, comov_nu * inverse_doppler_factor); rpacket_set_energy(packet, comov_energy * inverse_doppler_factor); rpacket_set_recently_crossed_boundary(packet, 1); if (rpacket_get_virtual_packet_flag(packet) > 0) { montecarlo_one_packet(storage, packet, -2); } } }
void montecarlo_thomson_scatter(rpacket_t *packet, storage_model_t *storage, double distance) { double comov_energy, doppler_factor, comov_nu, inverse_doppler_factor; doppler_factor = move_packet(packet, storage, distance); comov_nu = rpacket_get_nu(packet) * doppler_factor; comov_energy = rpacket_get_energy(packet) * doppler_factor; rpacket_set_mu(packet, 2.0 * rk_double(&mt_state) - 1.0); inverse_doppler_factor = 1.0 / rpacket_doppler_factor(packet, storage); rpacket_set_nu(packet, comov_nu * inverse_doppler_factor); rpacket_set_energy(packet, comov_energy * inverse_doppler_factor); rpacket_reset_tau_event(packet); rpacket_set_recently_crossed_boundary(packet, 0); storage->last_interaction_type[storage->current_packet_id] = 1; if (rpacket_get_virtual_packet_flag(packet) > 0) { montecarlo_one_packet(storage, packet, 1); } }
void montecarlo_thomson_scatter (rpacket_t * packet, storage_model_t * storage, double distance, rk_state *mt_state) { move_packet (packet, storage, distance); double doppler_factor = rpacket_doppler_factor (packet, storage); double comov_nu = rpacket_get_nu (packet) * doppler_factor; double comov_energy = rpacket_get_energy (packet) * doppler_factor; rpacket_set_mu (packet, 2.0 * rk_double (mt_state) - 1.0); double inverse_doppler_factor = 1.0 / rpacket_doppler_factor (packet, storage); rpacket_set_nu (packet, comov_nu * inverse_doppler_factor); rpacket_set_energy (packet, comov_energy * inverse_doppler_factor); rpacket_reset_tau_event (packet, mt_state); storage->last_interaction_type[rpacket_get_id (packet)] = 1; if (rpacket_get_virtual_packet_flag (packet) > 0) { montecarlo_one_packet (storage, packet, 1, mt_state); } }
inline double move_packet(rpacket_t *packet, storage_model_t *storage, double distance) { double new_r, doppler_factor, comov_energy, comov_nu; doppler_factor = rpacket_doppler_factor(packet, storage); if (distance > 0.0) { double r = rpacket_get_r(packet); new_r = sqrt(r * r + distance * distance + 2.0 * r * distance * rpacket_get_mu(packet)); rpacket_set_mu(packet, (rpacket_get_mu(packet) * r + distance) / new_r); rpacket_set_r(packet, new_r); if (rpacket_get_virtual_packet(packet) <= 0) { comov_energy = rpacket_get_energy(packet) * doppler_factor; comov_nu = rpacket_get_nu(packet) * doppler_factor; storage->js[rpacket_get_current_shell_id(packet)] += comov_energy * distance; storage->nubars[rpacket_get_current_shell_id(packet)] += comov_energy * distance * comov_nu; } } return doppler_factor; }
void increment_j_blue_estimator (const rpacket_t * packet, storage_model_t * storage, double d_line, int64_t j_blue_idx) { if (storage->line_lists_j_blues != NULL) { double r = rpacket_get_r (packet); double r_interaction = sqrt (r * r + d_line * d_line + 2.0 * r * d_line * rpacket_get_mu (packet)); double mu_interaction = (rpacket_get_mu (packet) * r + d_line) / r_interaction; double doppler_factor = 1.0 - mu_interaction * r_interaction * storage->inverse_time_explosion * INVERSE_C; double comov_energy = rpacket_get_energy (packet) * doppler_factor; #ifdef WITHOPENMP #pragma omp atomic #endif storage->line_lists_j_blues[j_blue_idx] += comov_energy / rpacket_get_nu (packet); } }
void montecarlo_main_loop(storage_model_t * storage, int64_t virtual_packet_flag, int nthreads, unsigned long seed) { int64_t finished_packets = 0; storage->virt_packet_count = 0; #ifdef WITH_VPACKET_LOGGING storage->virt_packet_nus = (double *)safe_malloc(sizeof(double) * storage->no_of_packets); storage->virt_packet_energies = (double *)safe_malloc(sizeof(double) * storage->no_of_packets); storage->virt_packet_last_interaction_in_nu = (double *)safe_malloc(sizeof(double) * storage->no_of_packets); storage->virt_packet_last_interaction_type = (int64_t *)safe_malloc(sizeof(int64_t) * storage->no_of_packets); storage->virt_packet_last_line_interaction_in_id = (int64_t *)safe_malloc(sizeof(int64_t) * storage->no_of_packets); storage->virt_packet_last_line_interaction_out_id = (int64_t *)safe_malloc(sizeof(int64_t) * storage->no_of_packets); storage->virt_array_size = storage->no_of_packets; #endif // WITH_VPACKET_LOGGING #ifdef WITHOPENMP omp_set_dynamic(0); if (nthreads > 0) { omp_set_num_threads(nthreads); } #pragma omp parallel firstprivate(finished_packets) { rk_state mt_state; rk_seed (seed + omp_get_thread_num(), &mt_state); #pragma omp master { fprintf(stderr, "Running with OpenMP - %d threads\n", omp_get_num_threads()); print_progress(0, storage->no_of_packets); } #pragma omp for #else rk_state mt_state; rk_seed (seed, &mt_state); fprintf(stderr, "Running without OpenMP\n"); #endif for (int64_t packet_index = 0; packet_index < storage->no_of_packets; ++packet_index) { int reabsorbed = 0; rpacket_t packet; rpacket_set_id(&packet, packet_index); rpacket_init(&packet, storage, packet_index, virtual_packet_flag); if (virtual_packet_flag > 0) { reabsorbed = montecarlo_one_packet(storage, &packet, -1, &mt_state); } reabsorbed = montecarlo_one_packet(storage, &packet, 0, &mt_state); storage->output_nus[packet_index] = rpacket_get_nu(&packet); if (reabsorbed == 1) { storage->output_energies[packet_index] = -rpacket_get_energy(&packet); } else { storage->output_energies[packet_index] = rpacket_get_energy(&packet); } if ( ++finished_packets%100 == 0 ) { #ifdef WITHOPENMP // WARNING: This only works with a static sheduler and gives an approximation of progress. // The alternative would be to have a shared variable but that could potentially decrease performance when using many threads. if (omp_get_thread_num() == 0 ) print_progress(finished_packets * omp_get_num_threads(), storage->no_of_packets); #else print_progress(finished_packets, storage->no_of_packets); #endif } } #ifdef WITHOPENMP } #endif print_progress(storage->no_of_packets, storage->no_of_packets); fprintf(stderr,"\n"); }
void montecarlo_line_scatter (rpacket_t * packet, storage_model_t * storage, double distance, rk_state *mt_state) { uint64_t next_line_id = rpacket_get_next_line_id (packet); uint64_t line2d_idx = next_line_id + storage->no_of_lines * rpacket_get_current_shell_id (packet); if (rpacket_get_virtual_packet (packet) == 0) { increment_j_blue_estimator (packet, storage, distance, line2d_idx); increment_Edotlu_estimator (packet, storage, line2d_idx); } double tau_line = storage->line_lists_tau_sobolevs[line2d_idx]; double tau_continuum = rpacket_get_chi_continuum(packet) * distance; double tau_combined = tau_line + tau_continuum; //rpacket_set_next_line_id (packet, rpacket_get_next_line_id (packet) + 1); if (next_line_id + 1 == storage->no_of_lines) { rpacket_set_last_line (packet, true); } if (rpacket_get_virtual_packet (packet) > 0) { rpacket_set_tau_event (packet, rpacket_get_tau_event (packet) + tau_line); rpacket_set_next_line_id (packet, next_line_id + 1); } else if (rpacket_get_tau_event (packet) < tau_combined) { move_packet (packet, storage, distance); double old_doppler_factor = rpacket_doppler_factor (packet, storage); rpacket_set_mu (packet, 2.0 * rk_double (mt_state) - 1.0); double inverse_doppler_factor = 1.0 / rpacket_doppler_factor (packet, storage); double comov_energy = rpacket_get_energy (packet) * old_doppler_factor; rpacket_set_energy (packet, comov_energy * inverse_doppler_factor); storage->last_interaction_in_nu[rpacket_get_id (packet)] = rpacket_get_nu (packet); storage->last_line_interaction_in_id[rpacket_get_id (packet)] = next_line_id; storage->last_line_interaction_shell_id[rpacket_get_id (packet)] = rpacket_get_current_shell_id (packet); storage->last_interaction_type[rpacket_get_id (packet)] = 2; int64_t emission_line_id = 0; if (storage->line_interaction_id == 0) { emission_line_id = next_line_id; } else if (storage->line_interaction_id >= 1) { emission_line_id = macro_atom (packet, storage, mt_state); } storage->last_line_interaction_out_id[rpacket_get_id (packet)] = emission_line_id; rpacket_set_nu (packet, storage->line_list_nu[emission_line_id] * inverse_doppler_factor); rpacket_set_nu_line (packet, storage->line_list_nu[emission_line_id]); rpacket_set_next_line_id (packet, emission_line_id + 1); rpacket_reset_tau_event (packet, mt_state); if (rpacket_get_virtual_packet_flag (packet) > 0) { bool virtual_close_line = false; if (!rpacket_get_last_line (packet) && fabs (storage->line_list_nu[rpacket_get_next_line_id (packet)] - rpacket_get_nu_line (packet)) < (rpacket_get_nu_line (packet)* 1e-7)) { virtual_close_line = true; } // QUESTIONABLE!!! bool old_close_line = rpacket_get_close_line (packet); rpacket_set_close_line (packet, virtual_close_line); montecarlo_one_packet (storage, packet, 1, mt_state); rpacket_set_close_line (packet, old_close_line); virtual_close_line = false; } } else { rpacket_set_tau_event (packet, rpacket_get_tau_event (packet) - tau_line); rpacket_set_next_line_id (packet, next_line_id + 1); } if (!rpacket_get_last_line (packet) && fabs (storage->line_list_nu[rpacket_get_next_line_id (packet)] - rpacket_get_nu_line (packet)) < (rpacket_get_nu_line (packet)* 1e-7)) { rpacket_set_close_line (packet, true); } }
int64_t montecarlo_one_packet (storage_model_t * storage, rpacket_t * packet, int64_t virtual_mode, rk_state *mt_state) { int64_t reabsorbed=-1; if (virtual_mode == 0) { reabsorbed = montecarlo_one_packet_loop (storage, packet, 0, mt_state); } else { if ((rpacket_get_nu (packet) > storage->spectrum_virt_start_nu) && (rpacket_get_nu(packet) < storage->spectrum_virt_end_nu)) { for (int64_t i = 0; i < rpacket_get_virtual_packet_flag (packet); i++) { double weight; rpacket_t virt_packet = *packet; double mu_min; if (rpacket_get_r(&virt_packet) > storage->r_inner[0]) { mu_min = -1.0 * sqrt (1.0 - (storage->r_inner[0] / rpacket_get_r(&virt_packet)) * (storage->r_inner[0] / rpacket_get_r(&virt_packet))); } else { mu_min = 0.0; } double mu_bin = (1.0 - mu_min) / rpacket_get_virtual_packet_flag (packet); rpacket_set_mu(&virt_packet,mu_min + (i + rk_double (mt_state)) * mu_bin); switch (virtual_mode) { case -2: weight = 1.0 / rpacket_get_virtual_packet_flag (packet); break; case -1: weight = 2.0 * rpacket_get_mu(&virt_packet) / rpacket_get_virtual_packet_flag (packet); break; case 1: weight = (1.0 - mu_min) / 2.0 / rpacket_get_virtual_packet_flag (packet); break; default: fprintf (stderr, "Something has gone horribly wrong!\n"); // FIXME MR: we need to somehow signal an error here // I'm adding an exit() here to inform the compiler about the impossible path exit(1); } double doppler_factor_ratio = rpacket_doppler_factor (packet, storage) / rpacket_doppler_factor (&virt_packet, storage); rpacket_set_energy(&virt_packet, rpacket_get_energy (packet) * doppler_factor_ratio); rpacket_set_nu(&virt_packet,rpacket_get_nu (packet) * doppler_factor_ratio); reabsorbed = montecarlo_one_packet_loop (storage, &virt_packet, 1, mt_state); #ifdef WITH_VPACKET_LOGGING #ifdef WITHOPENMP #pragma omp critical { #endif // WITHOPENMP if (storage->virt_packet_count >= storage->virt_array_size) { storage->virt_array_size *= 2; storage->virt_packet_nus = safe_realloc(storage->virt_packet_nus, sizeof(double) * storage->virt_array_size); storage->virt_packet_energies = safe_realloc(storage->virt_packet_energies, sizeof(double) * storage->virt_array_size); storage->virt_packet_last_interaction_in_nu = safe_realloc(storage->virt_packet_last_interaction_in_nu, sizeof(double) * storage->virt_array_size); storage->virt_packet_last_interaction_type = safe_realloc(storage->virt_packet_last_interaction_type, sizeof(int64_t) * storage->virt_array_size); storage->virt_packet_last_line_interaction_in_id = safe_realloc(storage->virt_packet_last_line_interaction_in_id, sizeof(int64_t) * storage->virt_array_size); storage->virt_packet_last_line_interaction_out_id = safe_realloc(storage->virt_packet_last_line_interaction_out_id, sizeof(int64_t) * storage->virt_array_size); } storage->virt_packet_nus[storage->virt_packet_count] = rpacket_get_nu(&virt_packet); storage->virt_packet_energies[storage->virt_packet_count] = rpacket_get_energy(&virt_packet) * weight; storage->virt_packet_last_interaction_in_nu[storage->virt_packet_count] = storage->last_interaction_in_nu[rpacket_get_id (packet)]; storage->virt_packet_last_interaction_type[storage->virt_packet_count] = storage->last_interaction_type[rpacket_get_id (packet)]; storage->virt_packet_last_line_interaction_in_id[storage->virt_packet_count] = storage->last_line_interaction_in_id[rpacket_get_id (packet)]; storage->virt_packet_last_line_interaction_out_id[storage->virt_packet_count] = storage->last_line_interaction_out_id[rpacket_get_id (packet)]; storage->virt_packet_count += 1; #ifdef WITHOPENMP } #endif // WITHOPENMP #endif // WITH_VPACKET_LOGGING if ((rpacket_get_nu(&virt_packet) < storage->spectrum_end_nu) && (rpacket_get_nu(&virt_packet) > storage->spectrum_start_nu)) { #ifdef WITHOPENMP #pragma omp critical { #endif // WITHOPENMP int64_t virt_id_nu = floor ((rpacket_get_nu(&virt_packet) - storage->spectrum_start_nu) / storage->spectrum_delta_nu); storage->spectrum_virt_nu[virt_id_nu] += rpacket_get_energy(&virt_packet) * weight; #ifdef WITHOPENMP } #endif // WITHOPENMP } } } else { return 1; } } return reabsorbed; }
void montecarlo_line_scatter(rpacket_t *packet, storage_model_t *storage, double distance) { double comov_energy = 0.0; int64_t emission_line_id = 0; double old_doppler_factor = 0.0; double inverse_doppler_factor = 0.0; double tau_line = 0.0; double tau_electron = 0.0; double tau_combined = 0.0; bool virtual_close_line = false; int64_t j_blue_idx = -1; if (rpacket_get_virtual_packet(packet) == 0) { j_blue_idx = rpacket_get_current_shell_id(packet) * storage->line_lists_j_blues_nd + rpacket_get_next_line_id(packet); increment_j_blue_estimator(packet, storage, distance, j_blue_idx); } tau_line = storage->line_lists_tau_sobolevs[rpacket_get_current_shell_id(packet) * storage->line_lists_tau_sobolevs_nd + rpacket_get_next_line_id(packet)]; tau_electron = storage->sigma_thomson * storage->electron_densities[rpacket_get_current_shell_id(packet)] * distance; tau_combined = tau_line + tau_electron; rpacket_set_next_line_id(packet, rpacket_get_next_line_id(packet) + 1); if (rpacket_get_next_line_id(packet) == storage->no_of_lines) { rpacket_set_last_line(packet, true); } if (rpacket_get_virtual_packet(packet) > 0) { rpacket_set_tau_event(packet, rpacket_get_tau_event(packet) + tau_line); } else if (rpacket_get_tau_event(packet) < tau_combined) { old_doppler_factor = move_packet(packet, storage, distance); rpacket_set_mu(packet, 2.0 * rk_double(&mt_state) - 1.0); inverse_doppler_factor = 1.0 / rpacket_doppler_factor(packet, storage); comov_energy = rpacket_get_energy(packet) * old_doppler_factor; rpacket_set_energy(packet, comov_energy * inverse_doppler_factor); storage->last_line_interaction_in_id[storage->current_packet_id] = rpacket_get_next_line_id(packet) - 1; storage->last_line_interaction_shell_id[storage->current_packet_id] = rpacket_get_current_shell_id(packet); storage->last_interaction_type[storage->current_packet_id] = 2; if (storage->line_interaction_id == 0) { emission_line_id = rpacket_get_next_line_id(packet) - 1; } else if (storage->line_interaction_id >= 1) { emission_line_id = macro_atom(packet, storage); } storage->last_line_interaction_out_id[storage->current_packet_id] = emission_line_id; rpacket_set_nu(packet, storage->line_list_nu[emission_line_id] * inverse_doppler_factor); rpacket_set_nu_line(packet, storage->line_list_nu[emission_line_id]); rpacket_set_next_line_id(packet, emission_line_id + 1); rpacket_reset_tau_event(packet); rpacket_set_recently_crossed_boundary(packet, 0); if (rpacket_get_virtual_packet_flag(packet) > 0) { virtual_close_line = false; if (!rpacket_get_last_line(packet) && fabs(storage->line_list_nu[rpacket_get_next_line_id(packet)] - rpacket_get_nu_line(packet)) / rpacket_get_nu_line(packet) < 1e-7) { virtual_close_line = true; } // QUESTIONABLE!!! bool old_close_line = rpacket_get_close_line(packet); rpacket_set_close_line(packet, virtual_close_line); montecarlo_one_packet(storage, packet, 1); rpacket_set_close_line(packet, old_close_line); virtual_close_line = false; } } else { rpacket_set_tau_event(packet, rpacket_get_tau_event(packet) - tau_line); } if (!rpacket_get_last_line(packet) && fabs(storage->line_list_nu[rpacket_get_next_line_id(packet)] - rpacket_get_nu_line(packet)) / rpacket_get_nu_line(packet) < 1e-7) { rpacket_set_close_line(packet, true); } }
bool test_rpacket_get_energy(double value) { rpacket_t rp; rpacket_set_energy(&rp, value); return value==rpacket_get_energy(&rp); }