SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Particles/MonteCarlo - TemplatedLocalFunctions.hpp Hit Total Coverage
Commit: 965048f86d23c819715b3af1ca3f880c8145d4bb Lines: 4 6 66.7 %
Date: 2024-05-16 17:00:40
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <vector>
       7             : 
       8             : #include "DataStructures/DataVector.hpp"
       9             : #include "DataStructures/Tensor/Tensor.hpp"
      10             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      11             : #include "Utilities/Gsl.hpp"
      12             : 
      13             : /// \cond
      14             : namespace Frame {
      15             : struct Fluid;
      16             : }  // namespace Frame
      17             : /// \endcond
      18             : 
      19             : /// Items related to the evolution of particles
      20             : /// Items related to Monte-Carlo radiation transport
      21             : namespace Particles::MonteCarlo {
      22             : 
      23             : struct Packet;
      24             : 
      25             : namespace detail {
      26             : 
      27             : void draw_single_packet(
      28             :     gsl::not_null<double*> time,
      29             :     gsl::not_null<std::array<double, 3>*> coord,
      30             :     gsl::not_null<std::array<double, 3>*> momentum,
      31             :     gsl::not_null<std::mt19937*> random_number_generator);
      32             : }  // namespace detail
      33             : 
      34             : 
      35             : /// Structure containing Monte-Carlo function templated on EnergyBins
      36             : /// and/or NeutrinoSpecies
      37             : template <size_t EnergyBins, size_t NeutrinoSpecies>
      38           1 : struct TemplatedLocalFunctions {
      39             :   /*!
      40             :    * \brief Function emitting Monte Carlo packets
      41             :    *
      42             :    * We emit a total energy emission_in_cell for each grid
      43             :    * cell, neutrino species, and neutrino energy bin. We aim for packets of
      44             :    * energy single_packet_energy in the fluid frame. The number of packets
      45             :    * is, in each bin b and for each species s,
      46             :    * `N = emission_in_cell[s][b] / single_packet_energy[s]`
      47             :    * and randomly rounded up or down to get integer number of packets (i.e.
      48             :    * if we want N=2.6 packets, there is a 60 percent chance of creating a 3rd
      49             :    * packet). The position of the packets is drawn from a homogeneous
      50             :    * distribution in the logical frame, and the direction of propagation of the
      51             :    * neutrinos is drawn from an isotropic distribution in the fluid frame.
      52             :    * Specifically, the 4-momentum of a packet of energy nu in the fluid frame
      53             :    * is
      54             :    * \f{align}
      55             :    * p^t &= \nu \\
      56             :    * p^x &= \nu * sin(\theta) * cos(\phi) \\
      57             :    * p^y &= \nu * sin(\theta) * sin(\phi) \\
      58             :    * p^z &= \nu * cos(theta)
      59             :    * \f}
      60             :    * with \f$cos(\theta)\f$ drawn from a uniform distribution in [-1,1] and
      61             :    * \f$\phi\f$ from a uniform distribution in \f$[0,2*\pi]\f$. We
      62             :    * transform to the inertial frame \f$p_t\f$ and \f$p^x,p^y,p^z\f$ using the
      63             :    * jacobian/inverse jacobian passed as option. The number of neutrinos in
      64             :    * each packet is defined as
      65             :    * `n = single_packet_energy[s] / energy_at_bin_center[b]`
      66             :    * Note that the packet energy is in code units and energy of a bin in MeV.
      67             :    */
      68           1 :   void emit_packets(
      69             :       gsl::not_null<std::vector<Packet>*> packets,
      70             :       gsl::not_null<std::mt19937*> random_number_generator,
      71             :       gsl::not_null<Scalar<DataVector>*> coupling_tilde_tau,
      72             :       gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> coupling_tilde_s,
      73             :       gsl::not_null<Scalar<DataVector>*> coupling_rho_ye,
      74             :       const double& time_start_step, const double& time_step,
      75             :       const Mesh<3>& mesh,
      76             :       const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>&
      77             :           emission_in_cell,
      78             :       const std::array<DataVector, NeutrinoSpecies>& single_packet_energy,
      79             :       const std::array<double, EnergyBins>& energy_at_bin_center,
      80             :       const Scalar<DataVector>& lorentz_factor,
      81             :       const tnsr::i<DataVector, 3, Frame::Inertial>&
      82             :           lower_spatial_four_velocity,
      83             :       const Jacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>&
      84             :           inertial_to_fluid_jacobian,
      85             :       const InverseJacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>&
      86             :           inertial_to_fluid_inverse_jacobian);
      87             : 
      88             :   /*!
      89             :    * \brief Evolve Monte-Carlo packets within an element.
      90             :    *
      91             :    * Evolve packets until (approximately) the provided final time
      92             :    * following the methods of \cite Foucart:2021mcb.
      93             :    * The vector of Packets should contain all MC packets that we wish
      94             :    * to advance in time. Note that this function only handles
      95             :    * propagation / absorption / scattering of packets, but not
      96             :    * emission. The final time of the packet may differ from the
      97             :    * desired final time by up to 5 percent, due to the fact that when
      98             :    * using the diffusion approximation (for large scattering
      99             :    * opacities) we take fixed time steps in the fluid frame,
     100             :    * leading to unpredictable time steps in the inertial frame.
     101             :    */
     102           1 :   void evolve_packets(
     103             :       gsl::not_null<std::vector<Packet>*> packets,
     104             :       gsl::not_null<std::mt19937*> random_number_generator,
     105             :       gsl::not_null<Scalar<DataVector>*> coupling_tilde_tau,
     106             :       gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*>
     107             :         coupling_tilde_s,
     108             :       gsl::not_null<Scalar<DataVector>*> coupling_rho_ye,
     109             :       double final_time, const Mesh<3>& mesh,
     110             :       const tnsr::I<DataVector, 3, Frame::ElementLogical>& mesh_coordinates,
     111             :       const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>&
     112             :           absorption_opacity_table,
     113             :       const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>&
     114             :           scattering_opacity_table,
     115             :       const std::array<double, EnergyBins>& energy_at_bin_center,
     116             :       const Scalar<DataVector>& lorentz_factor,
     117             :       const tnsr::i<DataVector, 3, Frame::Inertial>&
     118             :           lower_spatial_four_velocity,
     119             :       const Scalar<DataVector>& lapse,
     120             :       const tnsr::I<DataVector, 3, Frame::Inertial>& shift,
     121             :       const tnsr::i<DataVector, 3, Frame::Inertial>& d_lapse,
     122             :       const tnsr::iJ<DataVector, 3, Frame::Inertial>& d_shift,
     123             :       const tnsr::iJJ<DataVector, 3, Frame::Inertial>& d_inv_spatial_metric,
     124             :       const tnsr::ii<DataVector, 3, Frame::Inertial>& spatial_metric,
     125             :       const tnsr::II<DataVector, 3, Frame::Inertial>& inv_spatial_metric,
     126             :       const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
     127             :           mesh_velocity,
     128             :       const InverseJacobian<DataVector, 3, Frame::ElementLogical,
     129             :                             Frame::Inertial>&
     130             :           inverse_jacobian_logical_to_inertial,
     131             :       const Jacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>&
     132             :           inertial_to_fluid_jacobian,
     133             :       const InverseJacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>&
     134             :           inertial_to_fluid_inverse_jacobian);
     135             : 
     136             :   /// Interpolate the opacities from values tabulated as a function of
     137             :   /// neutrino energy in the fluid frame, to the value at the given
     138             :   /// fluid frame energy.
     139             :   /// We interpolate the logarithm of the opacity, linearly in fluid
     140             :   /// frame energy.
     141           1 :   void interpolate_opacities_at_fluid_energy(
     142             :       gsl::not_null<double*> absorption_opacity_packet,
     143             :       gsl::not_null<double*> scattering_opacity_packet,
     144             :       double fluid_frame_energy, size_t species, size_t index,
     145             :       const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>&
     146             :           absorption_opacity_table,
     147             :       const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>&
     148             :           scattering_opacity_table,
     149             :       const std::array<double, EnergyBins>& energy_at_bin_center);
     150             : 
     151             :   // Floor for opacity values (absorption or scattering).
     152             :   // This is used in two places. First, when interpolating opacities
     153             :   // in energy space, we interpolate log(max(kappa,opacity_floor)),
     154             :   // with kappa the tabulated value. Second, if kappa = opacity_floor
     155             :   // for some interaction, we assume that the interaction never happens.
     156           0 :   const double opacity_floor = 1.e-100;
     157             : };
     158             : 
     159             : }  // namespace Particles::MonteCarlo

Generated by: LCOV version 1.14