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 <pup.h> 8 : 9 : #include "DataStructures/CachedTempBuffer.hpp" 10 : #include "DataStructures/DataBox/Prefixes.hpp" 11 : #include "DataStructures/DataVector.hpp" 12 : #include "DataStructures/TaggedTuple.hpp" 13 : #include "DataStructures/Tensor/Tensor.hpp" 14 : #include "Elliptic/Systems/Poisson/Tags.hpp" 15 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp" 16 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 17 : #include "Options/String.hpp" 18 : #include "PointwiseFunctions/InitialDataUtilities/AnalyticSolution.hpp" 19 : #include "PointwiseFunctions/MathFunctions/MathFunction.hpp" 20 : #include "Utilities/ContainerHelpers.hpp" 21 : #include "Utilities/Gsl.hpp" 22 : #include "Utilities/TMPL.hpp" 23 : 24 : namespace Poisson::Solutions { 25 : 26 : namespace detail { 27 : template <typename DataType, size_t Dim> 28 : struct MathFunctionVariables { 29 : using Cache = CachedTempBuffer< 30 : Tags::Field<DataType>, 31 : ::Tags::deriv<Tags::Field<DataType>, tmpl::size_t<Dim>, Frame::Inertial>, 32 : ::Tags::Flux<Tags::Field<DataType>, tmpl::size_t<Dim>, Frame::Inertial>, 33 : ::Tags::FixedSource<Tags::Field<DataType>>>; 34 : 35 : const tnsr::I<DataType, Dim>& x; 36 : const ::MathFunction<Dim, Frame::Inertial>& math_function; 37 : 38 : void operator()(gsl::not_null<Scalar<DataType>*> field, 39 : gsl::not_null<Cache*> cache, 40 : Tags::Field<DataType> /*meta*/) const; 41 : void operator()(gsl::not_null<tnsr::i<DataType, Dim>*> field_gradient, 42 : gsl::not_null<Cache*> cache, 43 : ::Tags::deriv<Tags::Field<DataType>, tmpl::size_t<Dim>, 44 : Frame::Inertial> /*meta*/) const; 45 : void operator()(gsl::not_null<tnsr::I<DataType, Dim>*> flux_for_field, 46 : gsl::not_null<Cache*> cache, 47 : ::Tags::Flux<Tags::Field<DataType>, tmpl::size_t<Dim>, 48 : Frame::Inertial> /*meta*/) const; 49 : void operator()(gsl::not_null<Scalar<DataType>*> fixed_source_for_field, 50 : gsl::not_null<Cache*> cache, 51 : ::Tags::FixedSource<Tags::Field<DataType>> /*meta*/) const; 52 : }; 53 : } // namespace detail 54 : 55 : template <size_t Dim> 56 0 : class MathFunction : public elliptic::analytic_data::AnalyticSolution { 57 : public: 58 0 : struct Function { 59 0 : using type = std::unique_ptr<::MathFunction<Dim, Frame::Inertial>>; 60 0 : static constexpr Options::String help = "The solution function"; 61 : }; 62 : 63 0 : using options = tmpl::list<Function>; 64 0 : static constexpr Options::String help{ 65 : "Any solution to the Poisson equation given by a MathFunction " 66 : "implementation, such as a Gaussian."}; 67 : 68 0 : MathFunction() = default; 69 0 : MathFunction(const MathFunction&) = delete; 70 0 : MathFunction& operator=(const MathFunction&) = delete; 71 0 : MathFunction(MathFunction&&) = default; 72 0 : MathFunction& operator=(MathFunction&&) = default; 73 0 : ~MathFunction() override = default; 74 0 : std::unique_ptr<elliptic::analytic_data::AnalyticSolution> get_clone() 75 : const override; 76 : 77 0 : MathFunction( 78 : std::unique_ptr<::MathFunction<Dim, Frame::Inertial>> math_function); 79 : 80 0 : const ::MathFunction<Dim, Frame::Inertial>& math_function() const { 81 : return *math_function_; 82 : } 83 : 84 : /// \cond 85 : explicit MathFunction(CkMigrateMessage* m); 86 : using PUP::able::register_constructor; 87 : WRAPPED_PUPable_decl_template(MathFunction); // NOLINT 88 : /// \endcond 89 : 90 : template <typename DataType, typename... RequestedTags> 91 0 : tuples::TaggedTuple<RequestedTags...> variables( 92 : const tnsr::I<DataType, Dim>& x, 93 : tmpl::list<RequestedTags...> /*meta*/) const { 94 : using VarsComputer = detail::MathFunctionVariables<DataType, Dim>; 95 : typename VarsComputer::Cache cache{get_size(*x.begin())}; 96 : const VarsComputer computer{x, *math_function_}; 97 : return {cache.get_var(computer, RequestedTags{})...}; 98 : } 99 : 100 : template <typename... RequestedTags> 101 0 : tuples::TaggedTuple<RequestedTags...> variables( 102 : const tnsr::I<DataVector, Dim>& x, const Mesh<Dim>& /*mesh*/, 103 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical, 104 : Frame::Inertial>& /*inv_jacobian*/, 105 : tmpl::list<RequestedTags...> meta) const { 106 : return variables(x, meta); 107 : } 108 : 109 : // NOLINTNEXTLINE(google-runtime-references) 110 0 : void pup(PUP::er& p) override; 111 : 112 : private: 113 0 : std::unique_ptr<::MathFunction<Dim, Frame::Inertial>> math_function_; 114 : }; 115 : 116 : template <size_t Dim> 117 0 : bool operator==(const MathFunction<Dim>& lhs, const MathFunction<Dim>& rhs); 118 : 119 : template <size_t Dim> 120 0 : bool operator!=(const MathFunction<Dim>& lhs, const MathFunction<Dim>& rhs); 121 : 122 : } // namespace Poisson::Solutions