Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include "DataStructures/DataBox/DataBox.hpp" 7 : #include "DataStructures/DataVector.hpp" 8 : #include "DataStructures/Index.hpp" 9 : #include "DataStructures/Tensor/Tensor.hpp" 10 : #include "Evolution/DgSubcell/ActiveGrid.hpp" 11 : #include "Evolution/DgSubcell/Tags/ActiveGrid.hpp" 12 : #include "Evolution/DgSubcell/Tags/Jacobians.hpp" 13 : #include "Evolution/DgSubcell/Tags/Mesh.hpp" 14 : #include "Evolution/Particles/MonteCarlo/CellVolume.hpp" 15 : #include "Evolution/Particles/MonteCarlo/Tags.hpp" 16 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/Tags.hpp" 17 : #include "Parallel/AlgorithmExecution.hpp" 18 : #include "Parallel/GlobalCache.hpp" 19 : 20 0 : namespace Particles::MonteCarlo { 21 : 22 : /// Mutator adding the Monte-Carlo contribution 23 : /// to the evolution of the fluid. 24 1 : struct FluidCouplingMutator { 25 0 : static const size_t Dim = 3; 26 : 27 : // We modify the fluid evolved variables, and reset the coupling 28 : // terms to zero. 29 0 : using return_tags = 30 : tmpl::list<grmhd::ValenciaDivClean::Tags::TildeTau, 31 : grmhd::ValenciaDivClean::Tags::TildeYe, 32 : grmhd::ValenciaDivClean::Tags::TildeS<Frame::Inertial>, 33 : Particles::MonteCarlo::Tags::CouplingTildeTau<DataVector>, 34 : Particles::MonteCarlo::Tags::CouplingTildeRhoYe<DataVector>, 35 : Particles::MonteCarlo::Tags::CouplingTildeS<DataVector, Dim>>; 36 0 : using argument_tags = tmpl::list< 37 : evolution::dg::subcell::Tags::Mesh<Dim>, 38 : evolution::dg::subcell::Tags::ActiveGrid, 39 : evolution::dg::subcell::fd::Tags::DetInverseJacobianLogicalToInertial>; 40 : 41 0 : static void apply( 42 : const gsl::not_null<Scalar<DataVector>*> tilde_tau, 43 : const gsl::not_null<Scalar<DataVector>*> tilde_ye, 44 : const gsl::not_null<tnsr::i<DataVector, Dim>*> tilde_s, 45 : const gsl::not_null<Scalar<DataVector>*> coupling_tilde_tau, 46 : const gsl::not_null<Scalar<DataVector>*> coupling_tilde_rho_ye, 47 : const gsl::not_null<tnsr::i<DataVector, Dim>*> coupling_tilde_s, 48 : const Mesh<Dim>& mesh, 49 : const evolution::dg::subcell::ActiveGrid& active_grid, 50 : const Scalar<DataVector>& det_inverse_jacobian_logical_to_inertial) { 51 : // Currently, MC skips all non-communication actions when not using 52 : // Subcell. 53 : if (active_grid != evolution::dg::subcell::ActiveGrid::Subcell) { 54 : return; 55 : } 56 : 57 : // Coupling terms are on the mesh with ghost zones, while the evolved 58 : // variables are not. We also need to normalize the coupling terms with the 59 : // cell volume to get the evolution of energy/momentum density 60 : const Index<3>& extents = mesh.extents(); 61 : const size_t num_ghost_zones = 1; 62 : const Index<3> extents_with_ghost{extents[0] + 2 * num_ghost_zones, 63 : extents[1] + 2 * num_ghost_zones, 64 : extents[2] + 2 * num_ghost_zones}; 65 : 66 : Scalar<DataVector> det_jacobian_logical_to_inertial(*tilde_tau); 67 : get(det_jacobian_logical_to_inertial) = 68 : 1.0 / get(det_inverse_jacobian_logical_to_inertial); 69 : Scalar<DataVector> cell_inertial_three_volume = 70 : make_with_value<Scalar<DataVector>>(*tilde_tau, 0.0); 71 : cell_inertial_coordinate_three_volume_finite_difference( 72 : &cell_inertial_three_volume, mesh, det_jacobian_logical_to_inertial); 73 : 74 : for (size_t i = 0; i < extents[0]; i++) { 75 : for (size_t j = 0; j < extents[1]; j++) { 76 : for (size_t k = 0; k < extents[2]; k++) { 77 : // The coupling terms are computed on a grid with ghost zone points, 78 : // the fluid variables are on the grid without GZ points 79 : // Index without GZ 80 : const size_t local_idx = collapsed_index(Index<3>{i, j, k}, extents); 81 : // Index with GZ 82 : const size_t extended_idx = 83 : collapsed_index(Index<3>{i + num_ghost_zones, j + num_ghost_zones, 84 : k + num_ghost_zones}, 85 : extents_with_ghost); 86 : // The MC coupling calculates the change in energy, momentum, and 87 : // lepton number. We need to divide by the cell 3-volume to get 88 : // the change in the evolved variables. 89 : const double& volume = get(cell_inertial_three_volume)[local_idx]; 90 : get(*tilde_tau)[local_idx] += 91 : get(*coupling_tilde_tau)[extended_idx] / volume; 92 : get(*tilde_ye)[local_idx] += 93 : get(*coupling_tilde_rho_ye)[extended_idx] / volume; 94 : for (size_t d = 0; d < 3; d++) { 95 : tilde_s->get(d)[local_idx] += 96 : coupling_tilde_s->get(d)[extended_idx] / volume; 97 : } 98 : } 99 : } 100 : } 101 : // Reset coupling terms to 0 after use 102 : get(*coupling_tilde_tau) = 0.0; 103 : get(*coupling_tilde_rho_ye) = 0.0; 104 : for (size_t d = 0; d < 3; d++) { 105 : coupling_tilde_s->get(d) = 0.0; 106 : } 107 : } 108 : }; 109 : 110 : } // namespace Particles::MonteCarlo