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