SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Particles/MonteCarlo/Actions - TimeStepActions.hpp Hit Total Coverage
Commit: de0084593a37be7727c6c4da0be2184b0f8d9ed4 Lines: 2 8 25.0 %
Date: 2025-11-04 23:26:01
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 1.14