SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/GrMhd/ValenciaDivClean/Actions - NumericInitialData.hpp Hit Total Coverage
Commit: eb45036e71ee786d31156fb02c6e736b9a032426 Lines: 5 52 9.6 %
Date: 2024-04-18 22:31:00
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 <cstddef>
       7             : #include <string>
       8             : #include <variant>
       9             : 
      10             : #include "DataStructures/DataBox/DataBox.hpp"
      11             : #include "DataStructures/Tensor/EagerMath/DotProduct.hpp"
      12             : #include "DataStructures/Tensor/EagerMath/RaiseOrLowerIndex.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "Domain/Structure/ElementId.hpp"
      15             : #include "Domain/Tags.hpp"
      16             : #include "IO/Importers/Actions/ReadVolumeData.hpp"
      17             : #include "IO/Importers/ElementDataReader.hpp"
      18             : #include "IO/Importers/Tags.hpp"
      19             : #include "Options/String.hpp"
      20             : #include "Parallel/AlgorithmExecution.hpp"
      21             : #include "Parallel/GlobalCache.hpp"
      22             : #include "Parallel/Invoke.hpp"
      23             : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
      24             : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
      25             : #include "PointwiseFunctions/Hydro/Tags.hpp"
      26             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      27             : #include "PointwiseFunctions/InitialDataUtilities/Tags/InitialData.hpp"
      28             : #include "Utilities/ErrorHandling/Error.hpp"
      29             : #include "Utilities/Gsl.hpp"
      30             : #include "Utilities/SetNumberOfGridPoints.hpp"
      31             : #include "Utilities/TMPL.hpp"
      32             : #include "Utilities/TaggedTuple.hpp"
      33             : 
      34           1 : namespace grmhd::ValenciaDivClean {
      35             : 
      36             : /*!
      37             :  * \brief Numeric initial data loaded from volume data files
      38             :  *
      39             :  * This class can be factory-created in the input file to start an evolution
      40             :  * from numeric initial data. It selects the hydro variables to load from the
      41             :  * volume data files and allows to choose constant values for some of them.
      42             :  *
      43             :  * Where the density is below the `DensityCutoff` the fluid variables are set to
      44             :  * vacuum (zero density, pressure, energy and velocity, and unit Lorentz
      45             :  * factor). To evolve the initial data, an atmosphere treatment is likely
      46             :  * required to fix the value of the fluid variables in these regions.
      47             :  */
      48           1 : class NumericInitialData : public evolution::initial_data::InitialData {
      49             :  public:
      50             :   /// Name of a variable in the volume data file. Can be optional, in which case
      51             :   /// a constant value can be supplied instead of a dataset name.
      52             :   template <typename Tag, typename IsRequired>
      53           1 :   struct VarName {
      54           0 :     using tag = Tag;
      55           0 :     static constexpr bool is_required = IsRequired::value;
      56           0 :     static std::string name() { return db::tag_name<Tag>(); }
      57           0 :     using type = std::conditional_t<is_required, std::string,
      58             :                                     std::variant<double, std::string>>;
      59           0 :     static constexpr Options::String help =
      60             :         "Name of the variable in the volume data file. For optional variables "
      61             :         "you may instead specify a double that is used as a constant value "
      62             :         "on the entire grid.";
      63             :   };
      64             : 
      65             :   // These are the hydro variables that we support loading from volume
      66             :   // data files
      67           0 :   using required_primitive_vars =
      68             :       tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
      69             :                  hydro::Tags::LowerSpatialFourVelocity<DataVector, 3>>;
      70           0 :   using optional_primitive_vars =
      71             :       tmpl::list<hydro::Tags::ElectronFraction<DataVector>,
      72             :                  hydro::Tags::MagneticField<DataVector, 3>>;
      73           0 :   using primitive_vars_option_tags =
      74             :       tmpl::append<db::wrap_tags_in<VarName, required_primitive_vars,
      75             :                                     std::bool_constant<true>>,
      76             :                    db::wrap_tags_in<VarName, optional_primitive_vars,
      77             :                                     std::bool_constant<false>>>;
      78           0 :   struct PrimitiveVars
      79             :       : tuples::tagged_tuple_from_typelist<primitive_vars_option_tags> {
      80           0 :     static constexpr Options::String help =
      81             :         "Primitive hydro variables: 'RestMassDensity' and "
      82             :         "'LowerSpatialFourVelocity' (which is u_i = W * gamma_ij v^j). ";
      83           0 :     using options = tags_list;
      84             :     using TaggedTuple::TaggedTuple;
      85             :   };
      86             : 
      87           0 :   using all_vars =
      88             :       tmpl::append<required_primitive_vars, optional_primitive_vars>;
      89             : 
      90             :   // Input-file options
      91           0 :   struct Variables {
      92           0 :     using type = PrimitiveVars;
      93           0 :     static constexpr Options::String help =
      94             :         "Set of initial data variables from which the Valencia evolution "
      95             :         "variables are computed.";
      96             :   };
      97             : 
      98           0 :   struct DensityCutoff {
      99           0 :     using type = double;
     100           0 :     static constexpr Options::String help =
     101             :         "Where the density is below this cutoff the fluid variables are set to "
     102             :         "vacuum (zero density, pressure, energy and velocity, and unit Lorentz "
     103             :         "factor). "
     104             :         "During the evolution, atmosphere treatment will typically kick in and "
     105             :         "fix the value of the fluid variables in these regions. Therefore, "
     106             :         "it makes sense to set this density cutoff to the same value as the "
     107             :         "atmosphere density cutoff.";
     108           0 :     static constexpr double lower_bound() { return 0.; }
     109             :   };
     110             : 
     111           0 :   using options = tmpl::list<
     112             :       importers::OptionTags::FileGlob, importers::OptionTags::Subgroup,
     113             :       importers::OptionTags::ObservationValue,
     114             :       importers::OptionTags::EnableInterpolation, Variables, DensityCutoff>;
     115             : 
     116           0 :   static constexpr Options::String help =
     117             :       "Numeric initial data loaded from volume data files";
     118             : 
     119           0 :   NumericInitialData() = default;
     120           0 :   NumericInitialData(const NumericInitialData& rhs) = default;
     121           0 :   NumericInitialData& operator=(const NumericInitialData& rhs) = default;
     122           0 :   NumericInitialData(NumericInitialData&& /*rhs*/) = default;
     123           0 :   NumericInitialData& operator=(NumericInitialData&& /*rhs*/) = default;
     124           0 :   ~NumericInitialData() = default;
     125             : 
     126             :   /// \cond
     127             :   explicit NumericInitialData(CkMigrateMessage* msg);
     128             :   using PUP::able::register_constructor;
     129             :   WRAPPED_PUPable_decl_template(NumericInitialData);
     130             :   /// \endcond
     131             : 
     132           0 :   std::unique_ptr<evolution::initial_data::InitialData> get_clone()
     133             :       const override {
     134             :     return std::make_unique<NumericInitialData>(*this);
     135             :   }
     136             : 
     137           0 :   NumericInitialData(
     138             :       std::string file_glob, std::string subfile_name,
     139             :       std::variant<double, importers::ObservationSelector> observation_value,
     140             :       bool enable_interpolation, PrimitiveVars selected_variables,
     141             :       double density_cutoff);
     142             : 
     143           0 :   const importers::ImporterOptions& importer_options() const {
     144             :     return importer_options_;
     145             :   }
     146             : 
     147           0 :   const PrimitiveVars& selected_variables() const {
     148             :     return selected_variables_;
     149             :   }
     150             : 
     151           0 :   double density_cutoff() const { return density_cutoff_; }
     152             : 
     153           0 :   size_t volume_data_id() const;
     154             : 
     155             :   template <typename... AllTags>
     156           0 :   void select_for_import(
     157             :       const gsl::not_null<tuples::TaggedTuple<AllTags...>*> all_fields) const {
     158             :     // Select the subset of the available variables that we want to read from
     159             :     // the volume data file
     160             :     tmpl::for_each<primitive_vars_option_tags>([&all_fields,
     161             :                                                 this](const auto option_tag_v) {
     162             :       using option_tag = tmpl::type_from<std::decay_t<decltype(option_tag_v)>>;
     163             :       using tag = typename option_tag::tag;
     164             :       static constexpr bool is_required = option_tag::is_required;
     165             :       const auto& selected_dataset_name = get<option_tag>(selected_variables_);
     166             :       if constexpr (is_required) {
     167             :         // Always select required tags for import
     168             :         get<importers::Tags::Selected<tag>>(*all_fields) =
     169             :             selected_dataset_name;
     170             :       } else {
     171             :         // Only select optional tags for import if a dataset name was
     172             :         // specified
     173             :         if (std::holds_alternative<std::string>(selected_dataset_name)) {
     174             :           get<importers::Tags::Selected<tag>>(*all_fields) =
     175             :               std::get<std::string>(selected_dataset_name);
     176             :         }
     177             :       }
     178             :     });
     179             :   }
     180             : 
     181             :   template <typename... AllTags, size_t ThermodynamicDim>
     182           0 :   void set_initial_data(
     183             :       const gsl::not_null<Scalar<DataVector>*> rest_mass_density,
     184             :       const gsl::not_null<Scalar<DataVector>*> electron_fraction,
     185             :       const gsl::not_null<Scalar<DataVector>*> specific_internal_energy,
     186             :       const gsl::not_null<tnsr::I<DataVector, 3>*> spatial_velocity,
     187             :       const gsl::not_null<tnsr::I<DataVector, 3>*> magnetic_field,
     188             :       const gsl::not_null<Scalar<DataVector>*> div_cleaning_field,
     189             :       const gsl::not_null<Scalar<DataVector>*> lorentz_factor,
     190             :       const gsl::not_null<Scalar<DataVector>*> pressure,
     191             :       const gsl::not_null<Scalar<DataVector>*> temperature,
     192             :       const gsl::not_null<tuples::TaggedTuple<AllTags...>*> numeric_data,
     193             :       const tnsr::II<DataVector, 3>& inv_spatial_metric,
     194             :       const EquationsOfState::EquationOfState<true, ThermodynamicDim>&
     195             :           equation_of_state) const {
     196             :     // Rest mass density from dataset
     197             :     *rest_mass_density =
     198             :         std::move(get<hydro::Tags::RestMassDensity<DataVector>>(*numeric_data));
     199             :     const size_t num_points = get(*rest_mass_density).size();
     200             :     // Electron fraction from dataset or constant value
     201             :     const std::variant<double, std::string>& electron_fraction_selection =
     202             :         get<VarName<hydro::Tags::ElectronFraction<DataVector>,
     203             :                     std::bool_constant<false>>>(selected_variables_);
     204             :     if (std::holds_alternative<std::string>(electron_fraction_selection)) {
     205             :       *electron_fraction = std::move(
     206             :           get<hydro::Tags::ElectronFraction<DataVector>>(*numeric_data));
     207             :     } else {
     208             :       const double constant_electron_fraction =
     209             :           std::get<double>(electron_fraction_selection);
     210             :       set_number_of_grid_points(electron_fraction, num_points);
     211             :       get(*electron_fraction) = constant_electron_fraction;
     212             :     }
     213             :     // Velocity and Lorentz factor from u_i dataset
     214             :     // W = 1 + W^2 v_i v^i
     215             :     // where W v_i = u_i, so we first raise the index on W v_i with the
     216             :     // spatial metric and then compute its magnitude. We use
     217             :     // `spatial_velocity` as intermediate memory buffer for W v^i.
     218             :     const auto& u_i = get<hydro::Tags::LowerSpatialFourVelocity<DataVector, 3>>(
     219             :         *numeric_data);
     220             :     raise_or_lower_index(spatial_velocity, u_i, inv_spatial_metric);
     221             :     dot_product(lorentz_factor, u_i, *spatial_velocity);
     222             :     get(*lorentz_factor) += 1.;
     223             :     for (size_t d = 0; d < 3; ++d) {
     224             :       spatial_velocity->get(d) /= get(*lorentz_factor);
     225             :     }
     226             :     // Specific internal energy, and pressure from EOS
     227             :     set_number_of_grid_points(specific_internal_energy, num_points);
     228             :     set_number_of_grid_points(pressure, num_points);
     229             :     for (size_t i = 0; i < num_points; ++i) {
     230             :       double& local_rest_mass_density = get(*rest_mass_density)[i];
     231             :       // Apply the EOS only where the density is above the cutoff, because the
     232             :       // fluid model breaks down in the zero-density limit
     233             :       if (local_rest_mass_density <= density_cutoff_) {
     234             :         local_rest_mass_density = 0.;
     235             :         get(*specific_internal_energy)[i] = 0.;
     236             :         get(*pressure)[i] = 0.;
     237             :         get(*temperature)[i] = 0.;
     238             :         // Also reset velocity and Lorentz factor below cutoff to be safe
     239             :         for (size_t d = 0; d < 3; ++d) {
     240             :           spatial_velocity->get(d)[i] = 0.;
     241             :         }
     242             :         get(*lorentz_factor)[i] = 1.;
     243             :       } else {
     244             :         if constexpr (ThermodynamicDim == 1) {
     245             :           get(*specific_internal_energy)[i] =
     246             :               get(equation_of_state.specific_internal_energy_from_density(
     247             :                   Scalar<double>(local_rest_mass_density)));
     248             :           get(*pressure)[i] = get(equation_of_state.pressure_from_density(
     249             :               Scalar<double>(local_rest_mass_density)));
     250             :           get(*temperature)[i] = get(equation_of_state.temperature_from_density(
     251             :               Scalar<double>(local_rest_mass_density)));
     252             :         } else if constexpr (ThermodynamicDim == 2) {
     253             :           get(*specific_internal_energy)[i] =
     254             :               get(equation_of_state
     255             :                       .specific_internal_energy_from_density_and_temperature(
     256             :                           Scalar<double>(local_rest_mass_density),
     257             :                           Scalar<double>(0.)));
     258             :           get(*pressure)[i] =
     259             :               get(equation_of_state.pressure_from_density_and_energy(
     260             :                   Scalar<double>(local_rest_mass_density),
     261             :                   Scalar<double>(get(*specific_internal_energy)[i])));
     262             :           get(*temperature)[i] =
     263             :               get(equation_of_state.temperature_from_density_and_energy(
     264             :                   Scalar<double>(local_rest_mass_density),
     265             :                   Scalar<double>(get(*specific_internal_energy)[i])));
     266             :         } else {
     267             :           // Loaded the electron fraction previously.
     268             :           get(*specific_internal_energy)[i] =
     269             :               get(equation_of_state
     270             :                       .specific_internal_energy_from_density_and_temperature(
     271             :                           Scalar<double>(local_rest_mass_density),
     272             :                           Scalar<double>(0.),
     273             :                           Scalar<double>(get(*electron_fraction)[i])));
     274             :           get(*pressure)[i] =
     275             :               get(equation_of_state.pressure_from_density_and_energy(
     276             :                   Scalar<double>(local_rest_mass_density),
     277             :                   Scalar<double>(get(*specific_internal_energy)[i]),
     278             :                   Scalar<double>(get(*electron_fraction)[i])));
     279             :           get(*temperature)[i] =
     280             :               get(equation_of_state.temperature_from_density_and_energy(
     281             :                   Scalar<double>(local_rest_mass_density),
     282             :                   Scalar<double>(get(*specific_internal_energy)[i]),
     283             :                   Scalar<double>(get(*electron_fraction)[i])));
     284             :         }
     285             :       }
     286             :     }
     287             :     // Magnetic field from dataset or constant value
     288             :     const std::variant<double, std::string>& magnetic_field_selection =
     289             :         get<VarName<hydro::Tags::MagneticField<DataVector, 3>,
     290             :                     std::bool_constant<false>>>(selected_variables_);
     291             :     if (std::holds_alternative<std::string>(magnetic_field_selection)) {
     292             :       *magnetic_field = std::move(
     293             :           get<hydro::Tags::MagneticField<DataVector, 3>>(*numeric_data));
     294             :     } else {
     295             :       const double constant_magnetic_field =
     296             :           std::get<double>(magnetic_field_selection);
     297             :       if (constant_magnetic_field != 0.) {
     298             :         ERROR(
     299             :             "Choose a magnetic field dataset or set it to zero. "
     300             :             "Nonzero uniform magnetic fields cannot currently be chosen "
     301             :             "in the input file. Generate a dataset for the nonzero "
     302             :             "uniform magnetic field if you need to.");
     303             :       }
     304             :       set_number_of_grid_points(magnetic_field, num_points);
     305             :       std::fill(magnetic_field->begin(), magnetic_field->end(),
     306             :                 constant_magnetic_field);
     307             :     }
     308             :     // Divergence cleaning field
     309             :     set_number_of_grid_points(div_cleaning_field, num_points);
     310             :     get(*div_cleaning_field) = 0.;
     311             :   }
     312             : 
     313           0 :   void pup(PUP::er& p) override;
     314             : 
     315           0 :   friend bool operator==(const NumericInitialData& lhs,
     316             :                          const NumericInitialData& rhs);
     317             : 
     318             :  private:
     319           0 :   importers::ImporterOptions importer_options_{};
     320           0 :   PrimitiveVars selected_variables_{};
     321           0 :   double density_cutoff_{};
     322             : };
     323             : 
     324           0 : namespace Actions {
     325             : 
     326             : /*!
     327             :  * \brief Dispatch loading numeric initial data from files.
     328             :  *
     329             :  * Place this action before
     330             :  * grmhd::ValenciaDivClean::Actions::SetNumericInitialData in the action list.
     331             :  * See importers::Actions::ReadAllVolumeDataAndDistribute for details, which is
     332             :  * invoked by this action.
     333             :  */
     334           1 : struct ReadNumericInitialData {
     335           0 :   using const_global_cache_tags =
     336             :       tmpl::list<evolution::initial_data::Tags::InitialData>;
     337             : 
     338             :   template <typename DbTagsList, typename... InboxTags, typename Metavariables,
     339             :             typename ArrayIndex, typename ActionList,
     340             :             typename ParallelComponent>
     341           0 :   static Parallel::iterable_action_return_t apply(
     342             :       db::DataBox<DbTagsList>& box,
     343             :       const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     344             :       Parallel::GlobalCache<Metavariables>& cache,
     345             :       const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
     346             :       const ParallelComponent* const /*meta*/) {
     347             :     // Select the subset of the available variables that we want to read from
     348             :     // the volume data file
     349             :     const auto& initial_data = dynamic_cast<const NumericInitialData&>(
     350             :         db::get<evolution::initial_data::Tags::InitialData>(box));
     351             :     tuples::tagged_tuple_from_typelist<db::wrap_tags_in<
     352             :         importers::Tags::Selected, NumericInitialData::all_vars>>
     353             :         selected_fields{};
     354             :     initial_data.select_for_import(make_not_null(&selected_fields));
     355             :     // Dispatch loading the variables from the volume data file
     356             :     // - Not using `ckLocalBranch` here to make sure the simple action
     357             :     //   invocation is asynchronous.
     358             :     auto& reader_component = Parallel::get_parallel_component<
     359             :         importers::ElementDataReader<Metavariables>>(cache);
     360             :     Parallel::simple_action<importers::Actions::ReadAllVolumeDataAndDistribute<
     361             :         3, NumericInitialData::all_vars, ParallelComponent>>(
     362             :         reader_component, initial_data.importer_options(),
     363             :         initial_data.volume_data_id(), std::move(selected_fields));
     364             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     365             :   }
     366             : };
     367             : 
     368             : /*!
     369             :  * \brief Receive numeric initial data loaded by
     370             :  * grmhd::ValenciaDivClean::Actions::ReadNumericInitialData.
     371             :  *
     372             :  * Place this action in the action list after
     373             :  * grmhd::ValenciaDivClean::Actions::ReadNumericInitialData to wait until the
     374             :  * data for this element has arrived, and then compute the remaining primitive
     375             :  * variables and store them in the DataBox to be used as initial data.
     376             :  *
     377             :  * This action modifies the tags listed in `hydro::grmhd_tags` in the DataBox
     378             :  * (i.e., the hydro primitives). It does not modify conservative variables, so
     379             :  * it relies on a primitive-to-conservative update in the action list before
     380             :  * the evolution can start.
     381             :  *
     382             :  * \requires This action requires that the (inverse) spatial metric is available
     383             :  * through the DataBox, so it should run after GR initial data has been loaded.
     384             :  *
     385             :  * \requires This action also requires an equation of state, which is retrieved
     386             :  * from the DataBox as `hydro::Tags::GrmhdEquationOfState`.
     387             :  */
     388           1 : struct SetNumericInitialData {
     389           0 :   static constexpr size_t Dim = 3;
     390           0 :   using inbox_tags =
     391             :       tmpl::list<importers::Tags::VolumeData<NumericInitialData::all_vars>>;
     392             : 
     393             :   template <typename DbTagsList, typename... InboxTags, typename Metavariables,
     394             :             typename ActionList, typename ParallelComponent>
     395           0 :   static Parallel::iterable_action_return_t apply(
     396             :       db::DataBox<DbTagsList>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
     397             :       const Parallel::GlobalCache<Metavariables>& /*cache*/,
     398             :       const ElementId<Dim>& /*element_id*/, const ActionList /*meta*/,
     399             :       const ParallelComponent* const /*meta*/) {
     400             :     auto& inbox =
     401             :         tuples::get<importers::Tags::VolumeData<NumericInitialData::all_vars>>(
     402             :             inboxes);
     403             :     const auto& initial_data = dynamic_cast<const NumericInitialData&>(
     404             :         db::get<evolution::initial_data::Tags::InitialData>(box));
     405             :     const size_t volume_data_id = initial_data.volume_data_id();
     406             :     if (inbox.find(volume_data_id) == inbox.end()) {
     407             :       return {Parallel::AlgorithmExecution::Retry, std::nullopt};
     408             :     }
     409             :     auto numeric_data = std::move(inbox.extract(volume_data_id).mapped());
     410             : 
     411             :     const auto& inv_spatial_metric =
     412             :         db::get<gr::Tags::InverseSpatialMetric<DataVector, Dim>>(box);
     413             :     const auto& equation_of_state =
     414             :         db::get<hydro::Tags::GrmhdEquationOfState>(box);
     415             : 
     416             :     db::mutate<hydro::Tags::RestMassDensity<DataVector>,
     417             :                hydro::Tags::ElectronFraction<DataVector>,
     418             :                hydro::Tags::SpecificInternalEnergy<DataVector>,
     419             :                hydro::Tags::SpatialVelocity<DataVector, 3>,
     420             :                hydro::Tags::MagneticField<DataVector, 3>,
     421             :                hydro::Tags::DivergenceCleaningField<DataVector>,
     422             :                hydro::Tags::LorentzFactor<DataVector>,
     423             :                hydro::Tags::Pressure<DataVector>,
     424             :                hydro::Tags::Temperature<DataVector>>(
     425             :         [&initial_data, &numeric_data, &inv_spatial_metric, &equation_of_state](
     426             :             const gsl::not_null<Scalar<DataVector>*> rest_mass_density,
     427             :             const gsl::not_null<Scalar<DataVector>*> electron_fraction,
     428             :             const gsl::not_null<Scalar<DataVector>*> specific_internal_energy,
     429             :             const gsl::not_null<tnsr::I<DataVector, 3>*> spatial_velocity,
     430             :             const gsl::not_null<tnsr::I<DataVector, 3>*> magnetic_field,
     431             :             const gsl::not_null<Scalar<DataVector>*> div_cleaning_field,
     432             :             const gsl::not_null<Scalar<DataVector>*> lorentz_factor,
     433             :             const gsl::not_null<Scalar<DataVector>*> pressure,
     434             :             const gsl::not_null<Scalar<DataVector>*> temperature) {
     435             :           initial_data.set_initial_data(
     436             :               rest_mass_density, electron_fraction, specific_internal_energy,
     437             :               spatial_velocity, magnetic_field, div_cleaning_field,
     438             :               lorentz_factor, pressure, temperature,
     439             :               make_not_null(&numeric_data), inv_spatial_metric,
     440             :               equation_of_state);
     441             :         },
     442             :         make_not_null(&box));
     443             : 
     444             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     445             :   }
     446             : };
     447             : 
     448             : }  // namespace Actions
     449             : 
     450             : }  // namespace grmhd::ValenciaDivClean

Generated by: LCOV version 1.14