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 <type_traits> 9 : 10 : #include "DataStructures/DataBox/PrefixHelpers.hpp" 11 : #include "DataStructures/DataBox/Tag.hpp" 12 : #include "DataStructures/Tensor/Tensor.hpp" 13 : #include "DataStructures/Variables.hpp" 14 : #include "DataStructures/VariablesTag.hpp" 15 : #include "Domain/Tags.hpp" 16 : #include "ParallelAlgorithms/Events/Tags.hpp" 17 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp" 18 : #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp" 19 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp" 20 : #include "PointwiseFunctions/InitialDataUtilities/Tags/InitialData.hpp" 21 : #include "Utilities/CallWithDynamicType.hpp" 22 : #include "Utilities/Gsl.hpp" 23 : #include "Utilities/TMPL.hpp" 24 : 25 : /// \cond 26 : namespace Tags { 27 : struct Time; 28 : } // namespace Tags 29 : /// \endcond 30 : 31 : namespace evolution::Tags { 32 : /*! 33 : * \brief Computes the analytic solution and adds `::Tags::Analytic` of the 34 : * `std::optional<Tensor>`s to the DataBox. 35 : * 36 : * \note If `InitialDataList` is not an empty `tmpl::list`, then 37 : * `evolution::initial_data::Tags::InitialData` is retrieved and downcast to the 38 : * initial data for computing the errors. 39 : */ 40 : template <size_t Dim, typename AnalyticFieldsTagList, bool UsingDgSubcell, 41 : typename InitialDataList = tmpl::list<>> 42 1 : struct AnalyticSolutionsCompute 43 : : ::Tags::AnalyticSolutions<AnalyticFieldsTagList>, 44 : db::ComputeTag { 45 0 : using field_tags = AnalyticFieldsTagList; 46 0 : using base = ::Tags::AnalyticSolutions<AnalyticFieldsTagList>; 47 0 : using return_type = typename base::type; 48 0 : using argument_tags = tmpl::list< 49 : tmpl::conditional_t<std::is_same_v<InitialDataList, tmpl::list<>>, 50 : ::Tags::AnalyticSolutionOrData, 51 : evolution::initial_data::Tags::InitialData>, 52 : tmpl::conditional_t< 53 : UsingDgSubcell, 54 : Events::Tags::ObserverCoordinates<Dim, Frame::Inertial>, 55 : domain::Tags::Coordinates<Dim, Frame::Inertial>>, 56 : ::Tags::Time>; 57 : 58 : template <typename AnalyticSolution> 59 0 : static void function( 60 : const gsl::not_null<return_type*> analytic_solution, 61 : const AnalyticSolution& analytic_solution_computer, 62 : const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords, 63 : const double time) { 64 : if constexpr (::is_analytic_solution_v<AnalyticSolution>) { 65 : *analytic_solution = 66 : variables_from_tagged_tuple(analytic_solution_computer.variables( 67 : inertial_coords, time, AnalyticFieldsTagList{})); 68 : } else { 69 : (void)analytic_solution_computer; 70 : (void)inertial_coords; 71 : (void)time; 72 : *analytic_solution = std::nullopt; 73 : } 74 : } 75 : 76 0 : static void function( 77 : const gsl::not_null<return_type*> analytic_solution, 78 : const evolution::initial_data::InitialData& initial_data, 79 : const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords, 80 : const double time) { 81 : call_with_dynamic_type<void, InitialDataList>( 82 : &initial_data, [&analytic_solution, &inertial_coords, 83 : time](const auto* const data_or_solution) { 84 : function(analytic_solution, *data_or_solution, inertial_coords, time); 85 : }); 86 : } 87 : }; 88 : } // namespace evolution::Tags