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 <optional> 8 : #include <tuple> 9 : #include <utility> 10 : 11 : #include "DataStructures/DataBox/DataBox.hpp" 12 : #include "DataStructures/Variables.hpp" 13 : #include "Domain/CoordinateMaps/Tags.hpp" 14 : #include "Domain/Tags.hpp" 15 : #include "Domain/TagsTimeDependent.hpp" 16 : #include "Evolution/Initialization/InitialData.hpp" 17 : #include "Evolution/Initialization/Tags.hpp" 18 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 19 : #include "Parallel/AlgorithmExecution.hpp" 20 : #include "Parallel/GlobalCache.hpp" 21 : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp" 22 : #include "PointwiseFunctions/AnalyticData/Tags.hpp" 23 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp" 24 : #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp" 25 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp" 26 : #include "PointwiseFunctions/InitialDataUtilities/Tags/InitialData.hpp" 27 : #include "Time/Tags/Time.hpp" 28 : #include "Utilities/CallWithDynamicType.hpp" 29 : #include "Utilities/ErrorHandling/Error.hpp" 30 : #include "Utilities/Gsl.hpp" 31 : #include "Utilities/Requires.hpp" 32 : #include "Utilities/TMPL.hpp" 33 : #include "Utilities/TaggedTuple.hpp" 34 : 35 : /// \cond 36 : namespace Parallel { 37 : template <typename Metavariables> 38 : class GlobalCache; 39 : } // namespace Parallel 40 : /// \endcond 41 : 42 : namespace evolution { 43 : namespace Initialization { 44 0 : namespace Actions { 45 : /// \ingroup InitializationGroup 46 : /// \brief Sets variables needed for evolution of hyperbolic systems 47 : /// 48 : /// Uses: 49 : /// - DataBox: 50 : /// * `CoordinatesTag` 51 : /// - GlobalCache: 52 : /// * `OptionTags::AnalyticSolutionBase` or `OptionTags::AnalyticDataBase` 53 : /// 54 : /// DataBox changes: 55 : /// - Adds: nothing 56 : /// - Removes: nothing 57 : /// - Modifies: 58 : /// * System::variables_tag (if system has no primitive variables) 59 : /// * System::primitive_variables_tag (if system has primitive variables) 60 : template <typename LogicalCoordinatesTag> 61 1 : struct SetVariables { 62 0 : using simple_tags_from_options = tmpl::list<::Tags::Time>; 63 : 64 : template <typename DbTagsList, typename... InboxTags, typename Metavariables, 65 : typename ArrayIndex, typename ActionList, 66 : typename ParallelComponent> 67 0 : static Parallel::iterable_action_return_t apply( 68 : db::DataBox<DbTagsList>& box, 69 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 70 : const Parallel::GlobalCache<Metavariables>& /*cache*/, 71 : const ArrayIndex& /*array_index*/, ActionList /*meta*/, 72 : const ParallelComponent* const /*meta*/) { 73 : if constexpr (db::tag_is_retrievable_v< 74 : evolution::initial_data::Tags::InitialData, 75 : db::DataBox<DbTagsList>>) { 76 : using derived_classes = 77 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 78 : evolution::initial_data::InitialData>; 79 : call_with_dynamic_type<void, derived_classes>( 80 : &db::get<evolution::initial_data::Tags::InitialData>(box), 81 : [&box](const auto* const data_or_solution) { 82 : using initial_data_subclass = 83 : std::decay_t<decltype(*data_or_solution)>; 84 : if constexpr (is_analytic_data_v<initial_data_subclass> or 85 : is_analytic_solution_v<initial_data_subclass>) { 86 : impl<Metavariables>(make_not_null(&box), *data_or_solution); 87 : } else { 88 : ERROR( 89 : "Trying to use " 90 : "'evolution::Initialization::Actions::SetVariables' with a " 91 : "class that's not marked as analytic solution or analytic " 92 : "data. To support numeric initial data, add a " 93 : "system-specific initialization routine to your executable."); 94 : } 95 : }); 96 : } else if constexpr (db::tag_is_retrievable_v< 97 : ::Tags::AnalyticSolutionOrData, 98 : db::DataBox<DbTagsList>>) { 99 : impl<Metavariables>(make_not_null(&box), 100 : db::get<::Tags::AnalyticSolutionOrData>(box)); 101 : } else { 102 : ERROR( 103 : "Either ::Tags::AnalyticSolutionOrData or " 104 : "evolution::initial_data::Tags::InitialData must be in the " 105 : "DataBox."); 106 : } 107 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 108 : } 109 : 110 : private: 111 : template <typename Metavariables, typename DbTagsList, typename T> 112 0 : static void impl(const gsl::not_null<db::DataBox<DbTagsList>*> box, 113 : const T& solution_or_data) { 114 : const double initial_time = db::get<::Tags::Time>(*box); 115 : const auto inertial_coords = 116 : db::get<::domain::CoordinateMaps::Tags::CoordinateMap< 117 : Metavariables::volume_dim, Frame::Grid, Frame::Inertial>>(*box)( 118 : db::get<::domain::Tags::ElementMap<Metavariables::volume_dim, 119 : Frame::Grid>>(*box)( 120 : db::get<LogicalCoordinatesTag>(*box)), 121 : initial_time, db::get<::domain::Tags::FunctionsOfTime>(*box)); 122 : 123 : using system = typename Metavariables::system; 124 : 125 : if constexpr (Metavariables::system::has_primitive_and_conservative_vars) { 126 : using primitives_tag = typename system::primitive_variables_tag; 127 : // Set initial data from analytic solution 128 : db::mutate<primitives_tag>( 129 : [&initial_time, &inertial_coords, &solution_or_data]( 130 : const gsl::not_null<typename primitives_tag::type*> 131 : primitive_vars) { 132 : primitive_vars->assign_subset( 133 : evolution::Initialization::initial_data( 134 : solution_or_data, inertial_coords, initial_time, 135 : typename Metavariables::analytic_variables_tags{})); 136 : }, 137 : box); 138 : using non_conservative_variables = 139 : typename system::non_conservative_variables; 140 : using variables_tag = typename system::variables_tag; 141 : if constexpr (not std::is_same_v<non_conservative_variables, 142 : tmpl::list<>>) { 143 : db::mutate<variables_tag>( 144 : [&initial_time, &inertial_coords, &solution_or_data]( 145 : const gsl::not_null<typename variables_tag::type*> 146 : evolved_vars) { 147 : evolved_vars->assign_subset( 148 : evolution::Initialization::initial_data( 149 : solution_or_data, inertial_coords, initial_time, 150 : non_conservative_variables{})); 151 : }, 152 : box); 153 : } 154 : } else { 155 : using variables_tag = typename system::variables_tag; 156 : 157 : // Set initial data from analytic solution 158 : using Vars = typename variables_tag::type; 159 : db::mutate<variables_tag>( 160 : [&initial_time, &inertial_coords, 161 : &solution_or_data](const gsl::not_null<Vars*> vars) { 162 : vars->assign_subset(evolution::Initialization::initial_data( 163 : solution_or_data, inertial_coords, initial_time, 164 : typename Vars::tags_list{})); 165 : }, 166 : box); 167 : } 168 : } 169 : }; 170 : } // namespace Actions 171 : } // namespace Initialization 172 : } // namespace evolution