SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Particles/MonteCarlo/Actions - TimeStepActions.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 25.0 % 8 2
Test Date: 2026-10-22 17:29:42
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 <array>
       7              : #include <cstddef>
       8              : #include <optional>
       9              : #include <random>
      10              : #include <vector>
      11              : 
      12              : #include "DataStructures/DataBox/DataBox.hpp"
      13              : #include "DataStructures/Tensor/EagerMath/RaiseOrLowerIndex.hpp"
      14              : #include "DataStructures/Variables.hpp"
      15              : #include "Domain/Tags.hpp"
      16              : #include "Domain/TagsTimeDependent.hpp"
      17              : #include "Evolution/DgSubcell/ActiveGrid.hpp"
      18              : #include "Evolution/DgSubcell/Tags/ActiveGrid.hpp"
      19              : #include "Evolution/DgSubcell/Tags/Coordinates.hpp"
      20              : #include "Evolution/DgSubcell/Tags/Jacobians.hpp"
      21              : #include "Evolution/DgSubcell/Tags/Mesh.hpp"
      22              : #include "Evolution/Particles/MonteCarlo/InverseJacobianInertialToFluidCompute.hpp"
      23              : #include "Evolution/Particles/MonteCarlo/MortarData.hpp"
      24              : #include "Evolution/Particles/MonteCarlo/NeutrinoInteractionTable.hpp"
      25              : #include "Evolution/Particles/MonteCarlo/Tags.hpp"
      26              : #include "Evolution/Particles/MonteCarlo/TemplatedLocalFunctions.hpp"
      27              : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
      28              : #include "Parallel/AlgorithmExecution.hpp"
      29              : #include "Parallel/GlobalCache.hpp"
      30              : #include "PointwiseFunctions/GeneralRelativity/DerivativeSpatialMetric.hpp"
      31              : #include "PointwiseFunctions/GeneralRelativity/InverseSpacetimeMetric.hpp"
      32              : #include "PointwiseFunctions/GeneralRelativity/SpacetimeNormalVector.hpp"
      33              : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
      34              : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
      35              : #include "PointwiseFunctions/Hydro/Tags.hpp"
      36              : #include "Time/Tags/TimeStepId.hpp"
      37              : #include "Time/Time.hpp"
      38              : #include "Time/TimeStepId.hpp"
      39              : 
      40              : namespace Particles::MonteCarlo {
      41              : 
      42              : /// Mutator advancing neutrinos by a single step
      43              : template <size_t EnergyBins, size_t NeutrinoSpecies>
      44            1 : struct TimeStepMutator {
      45            0 :   static const size_t Dim = 3;
      46              : 
      47            0 :   using return_tags =
      48              :       tmpl::list<Particles::MonteCarlo::Tags::PacketsOnElement,
      49              :                  Particles::MonteCarlo::Tags::CouplingTildeTau<DataVector>,
      50              :                  Particles::MonteCarlo::Tags::CouplingTildeRhoYe<DataVector>,
      51              :                  Particles::MonteCarlo::Tags::CouplingTildeS<DataVector, Dim>,
      52              :                  Particles::MonteCarlo::Tags::RandomNumberGenerator,
      53              :                  Particles::MonteCarlo::Tags::DesiredPacketEnergyAtEmission<
      54              :                      NeutrinoSpecies>>;
      55              :   // To do : check carefully DG vs Subcell quantities... everything should
      56              :   // be on the Subcell grid!
      57            0 :   using argument_tags = tmpl::list<
      58              :       ::Tags::TimeStepId, ::Tags::Next<::Tags::TimeStepId>,
      59              :       hydro::Tags::GrmhdEquationOfState,
      60              :       Particles::MonteCarlo::Tags::InteractionRatesTable<EnergyBins,
      61              :                                                          NeutrinoSpecies>,
      62              :       hydro::Tags::ElectronFraction<DataVector>,
      63              :       hydro::Tags::RestMassDensity<DataVector>,
      64              :       hydro::Tags::Temperature<DataVector>,
      65              :       hydro::Tags::LorentzFactor<DataVector>,
      66              :       hydro::Tags::SpatialVelocity<DataVector, 3, Frame::Inertial>,
      67              :       gr::Tags::Lapse<DataVector>,
      68              :       gr::Tags::Shift<DataVector, Dim, Frame::Inertial>,
      69              :       gh::Tags::Phi<DataVector, 3, Frame::Inertial>,
      70              :       gr::Tags::SpatialMetric<DataVector, Dim, Frame::Inertial>,
      71              :       gr::Tags::InverseSpatialMetric<DataVector, Dim, Frame::Inertial>,
      72              :       gr::Tags::SqrtDetSpatialMetric<DataVector>,
      73              :       Particles::MonteCarlo::Tags::CellLightCrossingTime<DataVector>,
      74              :       evolution::dg::subcell::Tags::Mesh<Dim>,
      75              :       evolution::dg::subcell::Tags::Coordinates<Dim, Frame::ElementLogical>,
      76              :       domain::Tags::MeshVelocity<Dim>,
      77              :       evolution::dg::subcell::fd::Tags::InverseJacobianLogicalToInertial<Dim>,
      78              :       evolution::dg::subcell::fd::Tags::DetInverseJacobianLogicalToInertial,
      79              :       domain::Tags::InverseJacobian<Dim + 1, Frame::Inertial, Frame::Fluid>,
      80              :       domain::Tags::Jacobian<Dim + 1, Frame::Inertial, Frame::Fluid>,
      81              :       Particles::MonteCarlo::Tags::MortarDataTag<Dim>>;
      82              : 
      83            0 :   static void apply(
      84              :       const gsl::not_null<std::vector<Packet>*> packets,
      85              :       const gsl::not_null<Scalar<DataVector>*> coupling_tilde_tau,
      86              :       const gsl::not_null<Scalar<DataVector>*> coupling_tilde_rho_ye,
      87              :       const gsl::not_null<tnsr::i<DataVector, Dim>*> coupling_tilde_s,
      88              :       const gsl::not_null<std::mt19937*> random_number_generator,
      89              :       const gsl::not_null<std::array<DataVector, NeutrinoSpecies>*>
      90              :           single_packet_energy,
      91              :       const TimeStepId& current_step_id, const TimeStepId& next_step_id,
      92              : 
      93              :       const EquationsOfState::EquationOfState<true, 3>& equation_of_state,
      94              :       const NeutrinoInteractionTable<EnergyBins, NeutrinoSpecies>&
      95              :           interaction_table,
      96              :       const Scalar<DataVector>& electron_fraction,
      97              :       const Scalar<DataVector>& rest_mass_density,
      98              :       const Scalar<DataVector>& temperature,
      99              :       const Scalar<DataVector>& lorentz_factor,
     100              :       const tnsr::I<DataVector, Dim, Frame::Inertial>& spatial_velocity,
     101              :       const Scalar<DataVector>& lapse,
     102              :       const tnsr::I<DataVector, Dim, Frame::Inertial>& shift,
     103              :       const tnsr::iaa<DataVector, Dim, Frame::Inertial>& phi,
     104              : 
     105              :       const tnsr::ii<DataVector, Dim, Frame::Inertial>& spatial_metric,
     106              :       const tnsr::II<DataVector, Dim, Frame::Inertial>& inv_spatial_metric,
     107              :       const Scalar<DataVector>& sqrt_determinant_spatial_metric,
     108              :       const Scalar<DataVector>& cell_light_crossing_time, const Mesh<Dim>& mesh,
     109              :       const tnsr::I<DataVector, Dim, Frame::ElementLogical>& mesh_coordinates,
     110              :       const std::optional<tnsr::I<DataVector, Dim, Frame::Inertial>>&
     111              :           mesh_velocity,
     112              :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     113              :                             Frame::Inertial>&
     114              :           inverse_jacobian_logical_to_inertial,
     115              :       const Scalar<DataVector>& det_inverse_jacobian_logical_to_inertial,
     116              :       const InverseJacobian<DataVector, Dim + 1, Frame::Inertial, Frame::Fluid>&
     117              :           inertial_to_fluid_inverse_jacobian,
     118              :       const Jacobian<DataVector, Dim + 1, Frame::Inertial, Frame::Fluid>&
     119              :           inertial_to_fluid_jacobian,
     120              :       const MortarData<Dim>& mortar_data) {
     121              :     // Number of ghost zones for MC is assumed to be 1 for now.
     122              :     const size_t num_ghost_zones = 1;
     123              :     // Get information stored in various databox containers in
     124              :     // the format expected by take_time_step_on_element
     125              :     const double start_time = current_step_id.step_time().value();
     126              :     const double end_time = next_step_id.step_time().value();
     127              :     Scalar<DataVector> det_jacobian_logical_to_inertial(lapse);
     128              :     get(det_jacobian_logical_to_inertial) =
     129              :         1.0 / get(det_inverse_jacobian_logical_to_inertial);
     130              :     const DirectionalIdMap<Dim, std::optional<DataVector>>&
     131              :         electron_fraction_ghost = mortar_data.electron_fraction;
     132              :     const DirectionalIdMap<Dim, std::optional<DataVector>>&
     133              :         baryon_density_ghost = mortar_data.rest_mass_density;
     134              :     const DirectionalIdMap<Dim, std::optional<DataVector>>& temperature_ghost =
     135              :         mortar_data.temperature;
     136              :     const DirectionalIdMap<Dim, std::optional<DataVector>>&
     137              :         cell_light_crossing_time_ghost = mortar_data.cell_light_crossing_time;
     138              : 
     139              :     // Calculate temporary tensors needed for MC evolution
     140              :     using deriv_lapse = ::Tags::deriv<gr::Tags::Lapse<DataVector>,
     141              :                                       tmpl::size_t<3>, Frame::Inertial>;
     142              :     using deriv_shift = ::Tags::deriv<gr::Tags::Shift<DataVector, 3>,
     143              :                                       tmpl::size_t<3>, Frame::Inertial>;
     144              :     using deriv_spatial_metric =
     145              :         ::Tags::deriv<gr::Tags::SpatialMetric<DataVector, 3>, tmpl::size_t<3>,
     146              :                       Frame::Inertial>;
     147              :     using deriv_inverse_spatial_metric =
     148              :         ::Tags::deriv<gr::Tags::InverseSpatialMetric<DataVector, 3>,
     149              :                       tmpl::size_t<3>, Frame::Inertial>;
     150              :     using temporary_tags = tmpl::list<
     151              :         hydro::Tags::LowerSpatialFourVelocity<DataVector, Dim, Frame::Inertial>,
     152              :         gr::Tags::SpacetimeNormalVector<DataVector, 3>,
     153              :         gr::Tags::InverseSpacetimeMetric<DataVector, 3>, deriv_lapse,
     154              :         deriv_shift, deriv_spatial_metric, deriv_inverse_spatial_metric>;
     155              :     Variables<temporary_tags> temp_tags{mesh.number_of_grid_points(), 0.0};
     156              : 
     157              :     // u_i = \gamma_{ij} v^j W
     158              :     auto& lower_spatial_four_velocity =
     159              :         get<hydro::Tags::LowerSpatialFourVelocity<DataVector, Dim,
     160              :                                                   Frame::Inertial>>(temp_tags);
     161              :     raise_or_lower_index(make_not_null(&lower_spatial_four_velocity),
     162              :                          spatial_velocity, spatial_metric);
     163              :     for (size_t i = 0; i < Dim; i++) {
     164              :       lower_spatial_four_velocity.get(i) *= get(lorentz_factor);
     165              :     }
     166              :     // For the metric, we adapt the calculations performed for the time
     167              :     // derivative of in GhGrMhd. First get n^a and g^ab
     168              :     auto& spacetime_normal_vector =
     169              :         get<gr::Tags::SpacetimeNormalVector<DataVector, 3>>(temp_tags);
     170              :     auto& inv_spacetime_metric =
     171              :         get<gr::Tags::InverseSpacetimeMetric<DataVector, 3>>(temp_tags);
     172              :     gr::spacetime_normal_vector(make_not_null(&spacetime_normal_vector), lapse,
     173              :                                 shift);
     174              :     gr::inverse_spacetime_metric(make_not_null(&inv_spacetime_metric), lapse,
     175              :                                  shift, inv_spatial_metric);
     176              : 
     177              :     auto& d_lapse = get<deriv_lapse>(temp_tags);
     178              :     auto& d_shift = get<deriv_shift>(temp_tags);
     179              :     // Temporary store phi_iab n^a n^b in d_lapse. This is phi_two_normals in GH
     180              :     for (size_t i = 0; i < Dim; i++) {
     181              :       for (size_t a = 0; a < Dim + 1; a++) {
     182              :         for (size_t b = 0; b < Dim + 1; b++) {
     183              :           d_lapse.get(i) += phi.get(i, a, b) * spacetime_normal_vector.get(a) *
     184              :                             spacetime_normal_vector.get(b);
     185              :         }
     186              :       }
     187              :     }
     188              :     // Shift derivative using stored quantity in d_lapse
     189              :     // We use d_i shift^j =
     190              :     // (g^{j+1 b} phi_{iba} n^a + n^{j+1} phi_{iab} n^a n_b) * lapse
     191              :     // as in TimeDerivative.hpp in GhGrMhd
     192              :     for (size_t i = 0; i < Dim; i++) {
     193              :       for (size_t j = 0; j < Dim; j++) {
     194              :         d_shift.get(i, j) +=
     195              :             d_lapse.get(i) * spacetime_normal_vector.get(j + 1);
     196              :         for (size_t a = 0; a < Dim + 1; a++) {
     197              :           for (size_t b = 0; b < Dim + 1; b++) {
     198              :             d_shift.get(i, j) += inv_spacetime_metric.get(j + 1, b) *
     199              :                                  phi.get(i, b, a) *
     200              :                                  spacetime_normal_vector.get(a);
     201              :           }
     202              :         }
     203              :         d_shift.get(i, j) *= get(lapse);
     204              :       }
     205              :     }
     206              :     // Now use d_i lapse = - lapse * 0.5 * phi_{iab} n^a n^b
     207              :     // As we already stored phi_{iab} n^a n^b in d_i lapse,
     208              :     // we just multiply by (-0.5 * lapse)
     209              :     for (size_t i = 0; i < Dim; i++) {
     210              :       d_lapse.get(i) *= (-0.5) * get(lapse);
     211              :     }
     212              : 
     213              :     // Extract d_i \gamma_{jk} from phi_{i,j+1,k+1}
     214              :     auto& d_spatial_metric = get<deriv_spatial_metric>(temp_tags);
     215              :     for (size_t i = 0; i < Dim; i++) {
     216              :       for (size_t j = 0; j < Dim; j++) {
     217              :         for (size_t k = j; k < Dim; k++) {
     218              :           d_spatial_metric.get(i, j, k) = phi.get(i, j + 1, k + 1);
     219              :         }
     220              :       }
     221              :     }
     222              : 
     223              :     auto& d_inv_spatial_metric = get<deriv_inverse_spatial_metric>(temp_tags);
     224              :     gr::deriv_inverse_spatial_metric(make_not_null(&d_inv_spatial_metric),
     225              :                                      inv_spatial_metric, d_spatial_metric);
     226              : 
     227              :     TemplatedLocalFunctions<EnergyBins, NeutrinoSpecies> templated_functions;
     228              :     templated_functions.take_time_step_on_element(
     229              :         packets, coupling_tilde_tau, coupling_tilde_rho_ye, coupling_tilde_s,
     230              :         random_number_generator, single_packet_energy, start_time, end_time,
     231              :         equation_of_state, interaction_table, electron_fraction,
     232              :         rest_mass_density, temperature, lorentz_factor,
     233              :         lower_spatial_four_velocity, lapse, shift, d_lapse, d_shift,
     234              :         d_inv_spatial_metric, spatial_metric, inv_spatial_metric,
     235              :         sqrt_determinant_spatial_metric, cell_light_crossing_time, mesh,
     236              :         mesh_coordinates, num_ghost_zones, mesh_velocity,
     237              :         inverse_jacobian_logical_to_inertial, det_jacobian_logical_to_inertial,
     238              :         inertial_to_fluid_jacobian, inertial_to_fluid_inverse_jacobian,
     239              :         electron_fraction_ghost, baryon_density_ghost, temperature_ghost,
     240              :         cell_light_crossing_time_ghost);
     241              :   }
     242              : };
     243              : 
     244              : namespace Actions {
     245              : 
     246              : /// Action taking a single time step of the Monte-Carlo evolution
     247              : /// algorithm, assuming that the fluid and metric data in the ghost
     248              : /// zones have been communicated and that packets are on the elements
     249              : /// that owns them.
     250              : template <size_t EnergyBins, size_t NeutrinoSpecies>
     251            1 : struct TakeTimeStep {
     252              :   template <typename DbTags, typename... InboxTags, typename ArrayIndex,
     253              :             typename ActionList, typename ParallelComponent,
     254              :             typename Metavariables>
     255            0 :   static Parallel::iterable_action_return_t apply(
     256              :       db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     257              :       const Parallel::GlobalCache<Metavariables>& /*cache*/,
     258              :       const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
     259              :       const ParallelComponent* const /*meta*/) {
     260              :     ASSERT(db::get<evolution::dg::subcell::Tags::ActiveGrid>(box) ==
     261              :                evolution::dg::subcell::ActiveGrid::Subcell,
     262              :            "MC assumes that we are using the Subcell grid!");
     263              : 
     264              :     db::mutate_apply(TimeStepMutator<EnergyBins, NeutrinoSpecies>{},
     265              :                      make_not_null(&box));
     266              :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     267              :   }
     268              : };
     269              : 
     270              : }  // namespace Actions
     271              : }  // namespace Particles::MonteCarlo
        

Generated by: LCOV version 2.0-1