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 <unordered_map> 8 : #include <utility> 9 : 10 : #include "DataStructures/ApplyMatrices.hpp" 11 : #include "DataStructures/Variables.hpp" 12 : #include "Domain/Structure/Element.hpp" 13 : #include "Domain/Structure/ElementId.hpp" 14 : #include "Domain/Tags.hpp" 15 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 16 : #include "NumericalAlgorithms/Spectral/Projection.hpp" 17 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 18 : #include "Utilities/Gsl.hpp" 19 : #include "Utilities/TMPL.hpp" 20 : #include "Utilities/TaggedTuple.hpp" 21 : 22 : namespace amr::projectors { 23 : 24 : /// \brief Update the Tensors corresponding to TensorTags after an AMR 25 : /// change 26 : /// 27 : /// There is a specialization for 28 : /// `ProjectTensors<tmpl::list<TensorTags...>>` that can be used if a 29 : /// `tmpl::list` is available. 30 : /// 31 : /// \details For each item corresponding to each tag in TensorTags, project 32 : /// the data for each tensor from the old mesh to the new mesh 33 : /// 34 : /// \see ProjectVariables 35 : template <size_t Dim, typename... TensorTags> 36 1 : struct ProjectTensors : tt::ConformsTo<amr::protocols::Projector> { 37 0 : using return_tags = tmpl::list<TensorTags...>; 38 0 : using argument_tags = tmpl::list<domain::Tags::Mesh<Dim>>; 39 : 40 0 : static void apply( 41 : const gsl::not_null<typename TensorTags::type*>... tensors, 42 : const Mesh<Dim>& new_mesh, 43 : const std::pair<Mesh<Dim>, Element<Dim>>& old_mesh_and_element) { 44 : const auto& old_mesh = old_mesh_and_element.first; 45 : if (old_mesh == new_mesh) { 46 : return; // mesh was not refined, so no projection needed 47 : } 48 : const auto projection_matrices = 49 : Spectral::p_projection_matrices(old_mesh, new_mesh); 50 : const auto& old_extents = old_mesh.extents(); 51 : const auto project_tensor = [&projection_matrices, 52 : old_extents](auto& tensor) { 53 : for (size_t i = 0; i < tensor.size(); ++i) { 54 : tensor[i] = apply_matrices(projection_matrices, tensor[i], old_extents); 55 : } 56 : }; 57 : EXPAND_PACK_LEFT_TO_RIGHT(project_tensor(*tensors)); 58 : } 59 : 60 : template <typename... Tags> 61 0 : static void apply( 62 : const gsl::not_null<typename TensorTags::type*>... /*tensors*/, 63 : const Mesh<Dim>& /*new_mesh*/, 64 : const tuples::TaggedTuple<Tags...>& /*parent_items*/) { 65 : ERROR("h-refinement not implemented yet"); 66 : } 67 : 68 : template <typename... Tags> 69 0 : static void apply( 70 : const gsl::not_null<typename TensorTags::type*>... /*tensors*/, 71 : const Mesh<Dim>& /*new_mesh*/, 72 : const std::unordered_map<ElementId<Dim>, tuples::TaggedTuple<Tags...>>& 73 : /*children_items*/) { 74 : ERROR("h-refinement not implemented yet"); 75 : } 76 : }; 77 : 78 : /// \cond 79 : template <size_t Dim, typename... TensorTags> 80 : struct ProjectTensors<Dim, tmpl::list<TensorTags...>> 81 : : public ProjectTensors<Dim, TensorTags...> {}; 82 : /// \endcond 83 : } // namespace amr::projectors