Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
        }
    }
}
Exemplo n.º 3
0
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;
	    }
	}
    }
}
Exemplo n.º 4
0
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);
    }
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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);
        }
    }
}
Exemplo n.º 7
0
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);
	}
    }
}
Exemplo n.º 8
0
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);
    }  
}
Exemplo n.º 9
0
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);
    }
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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);
    }
}
Exemplo n.º 12
0
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");
}
Exemplo n.º 13
0
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);
    }
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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);
    }
}
Exemplo n.º 16
0
bool
test_rpacket_get_energy(double value) {
    rpacket_t rp;
    rpacket_set_energy(&rp, value);
    return value==rpacket_get_energy(&rp);
}