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; } } }
double rpacket_doppler_factor (const rpacket_t *packet, const storage_model_t *storage) { return 1.0 - rpacket_get_mu (packet) * rpacket_get_r (packet) * storage->inverse_time_explosion * INVERSE_C; }
void compute_distance2boundary (rpacket_t * packet, const storage_model_t * storage) { double r = rpacket_get_r (packet); double mu = rpacket_get_mu (packet); double r_outer = storage->r_outer[rpacket_get_current_shell_id (packet)]; double r_inner = storage->r_inner[rpacket_get_current_shell_id (packet)]; double check, distance; if (mu > 0.0) { // direction outward rpacket_set_next_shell_id (packet, 1); distance = sqrt (r_outer * r_outer + ((mu * mu - 1.0) * r * r)) - (r * mu); } else { // going inward if ( (check = r_inner * r_inner + (r * r * (mu * mu - 1.0)) )>= 0.0) { // hit inner boundary rpacket_set_next_shell_id (packet, -1); distance = - r * mu - sqrt (check); } else { // miss inner boundary rpacket_set_next_shell_id (packet, 1); distance = sqrt (r_outer * r_outer + ((mu * mu - 1.0) * r * r)) - (r * mu); } } rpacket_set_d_boundary (packet, distance); }
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); }
extern inline tardis_error_t compute_distance2line(rpacket_t *packet, storage_model_t *storage, double *result) { tardis_error_t ret_val = TARDIS_ERROR_OK; if (rpacket_get_last_line(packet)) { *result = MISS_DISTANCE; } else { double r = rpacket_get_r(packet); double mu = rpacket_get_mu(packet); double nu = rpacket_get_nu(packet); double nu_line = rpacket_get_nu_line(packet); double t_exp = storage->time_explosion; double inverse_t_exp = storage->inverse_time_explosion; double last_line = storage->line_list_nu[rpacket_get_next_line_id(packet) - 1]; double next_line = storage->line_list_nu[rpacket_get_next_line_id(packet) + 1]; int64_t cur_zone_id = rpacket_get_current_shell_id(packet); double comov_nu, doppler_factor; doppler_factor = 1.0 - mu * r * inverse_t_exp * INVERSE_C; comov_nu = nu * doppler_factor; if (comov_nu < nu_line) { fprintf(stderr, "ERROR: Comoving nu less than nu_line!\n"); fprintf(stderr, "comov_nu = %f\n", comov_nu); fprintf(stderr, "nu_line = %f\n", nu_line); fprintf(stderr, "(comov_nu - nu_line) / nu_line = %f\n", (comov_nu - nu_line) / nu_line); fprintf(stderr, "last_line = %f\n", last_line); fprintf(stderr, "next_line = %f\n", next_line); fprintf(stderr, "r = %f\n", r); fprintf(stderr, "mu = %f\n", mu); fprintf(stderr, "nu = %f\n", nu); fprintf(stderr, "doppler_factor = %f\n", doppler_factor); fprintf(stderr, "cur_zone_id = %d\n", cur_zone_id); ret_val = TARDIS_ERROR_COMOV_NU_LESS_THAN_NU_LINE; } else { *result = ((comov_nu - nu_line) / nu) * C * t_exp; } } return ret_val; }
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); } }
inline double compute_distance2boundary(rpacket_t *packet, storage_model_t *storage) { double r = rpacket_get_r(packet); double mu = rpacket_get_mu(packet); double r_outer = storage->r_outer[rpacket_get_current_shell_id(packet)]; double r_inner = storage->r_inner[rpacket_get_current_shell_id(packet)]; double d_outer = sqrt(r_outer * r_outer + ((mu * mu - 1.0) * r * r)) - (r * mu); double d_inner; double result; if (rpacket_get_recently_crossed_boundary(packet) == 1) { rpacket_set_next_shell_id(packet, 1); return d_outer; } else { double check = r_inner * r_inner + (r * r * (mu * mu - 1.0)); if (check < 0.0) { rpacket_set_next_shell_id(packet, 1); return d_outer; } else { d_inner = mu < 0.0 ? -r * mu - sqrt(check) : MISS_DISTANCE; } } if (d_inner < d_outer) { rpacket_set_next_shell_id(packet, -1); return d_inner; } else { rpacket_set_next_shell_id(packet, 1); return d_outer; } }
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; }
tardis_error_t compute_distance2line (rpacket_t * packet, const storage_model_t * storage) { if (!rpacket_get_last_line (packet)) { double r = rpacket_get_r (packet); double mu = rpacket_get_mu (packet); double nu = rpacket_get_nu (packet); double nu_line = rpacket_get_nu_line (packet); double distance, nu_diff; double t_exp = storage->time_explosion; double inverse_t_exp = storage->inverse_time_explosion; int64_t cur_zone_id = rpacket_get_current_shell_id (packet); double doppler_factor = 1.0 - mu * r * inverse_t_exp * INVERSE_C; double comov_nu = nu * doppler_factor; if ( (nu_diff = comov_nu - nu_line) >= 0) { distance = (nu_diff / nu) * C * t_exp; rpacket_set_d_line (packet, distance); return TARDIS_ERROR_OK; } else { if (rpacket_get_next_line_id (packet) == storage->no_of_lines - 1) { fprintf (stderr, "last_line = %f\n", storage-> line_list_nu[rpacket_get_next_line_id (packet) - 1]); fprintf (stderr, "Last line in line list reached!"); } else if (rpacket_get_next_line_id (packet) == 0) { fprintf (stderr, "First line in line list!"); fprintf (stderr, "next_line = %f\n", storage-> line_list_nu[rpacket_get_next_line_id (packet) + 1]); } else { fprintf (stderr, "last_line = %f\n", storage-> line_list_nu[rpacket_get_next_line_id (packet) - 1]); fprintf (stderr, "next_line = %f\n", storage-> line_list_nu[rpacket_get_next_line_id (packet) + 1]); } fprintf (stderr, "ERROR: Comoving nu less than nu_line!\n"); fprintf (stderr, "comov_nu = %f\n", comov_nu); fprintf (stderr, "nu_line = %f\n", nu_line); fprintf (stderr, "(comov_nu - nu_line) / nu_line = %f\n", (comov_nu - nu_line) / nu_line); fprintf (stderr, "r = %f\n", r); fprintf (stderr, "mu = %f\n", mu); fprintf (stderr, "nu = %f\n", nu); fprintf (stderr, "doppler_factor = %f\n", doppler_factor); fprintf (stderr, "cur_zone_id = %" PRIi64 "\n", cur_zone_id); return TARDIS_ERROR_COMOV_NU_LESS_THAN_NU_LINE; } } else { rpacket_set_d_line (packet, MISS_DISTANCE); return TARDIS_ERROR_OK; } }
bool test_rpacket_get_r(double value) { rpacket_t rp; rpacket_set_r(&rp, value); return value==rpacket_get_r(&rp); }