SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/DiscontinuousGalerkin - InitializeMortars.hpp Hit Total Coverage
Commit: ebec864322c50bab8dca0a90baf8d01875114261 Lines: 1 12 8.3 %
Date: 2020-11-25 20:28:50
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <cstddef>
       8             : #include <tuple>
       9             : #include <utility>
      10             : #include <vector>
      11             : 
      12             : #include "DataStructures/DataBox/DataBox.hpp"
      13             : #include "DataStructures/DataBox/Prefixes.hpp"
      14             : #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
      15             : #include "Domain/Structure/CreateInitialMesh.hpp"
      16             : #include "Domain/Structure/Direction.hpp"
      17             : #include "Domain/Structure/Element.hpp"
      18             : #include "Domain/Structure/Neighbors.hpp"
      19             : #include "Domain/Structure/OrientationMap.hpp"
      20             : #include "Domain/Tags.hpp"
      21             : #include "NumericalAlgorithms/DiscontinuousGalerkin/MortarHelpers.hpp"
      22             : #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
      23             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      24             : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
      25             : #include "Utilities/Gsl.hpp"
      26             : #include "Utilities/TMPL.hpp"
      27             : 
      28             : /// \cond
      29             : namespace Frame {
      30             : struct Inertial;
      31             : }  // namespace Frame
      32             : namespace Parallel {
      33             : template <typename Metavariables>
      34             : class GlobalCache;
      35             : }  // namespace Parallel
      36             : /// \endcond
      37             : 
      38             : namespace dg {
      39             : namespace Actions {
      40             : /*!
      41             :  * \ingroup InitializationGroup
      42             :  * \brief Initialize mortars between elements for exchanging fluxes.
      43             :  *
      44             :  * If the template parameter `AddFluxBoundaryConditionMortars`
      45             :  * is set to `false` then the mortar data for flux boundary conditions are not
      46             :  * initialized and other boundary conditions can be applied. In this case, the
      47             :  * `Tags::Mortars` items have no entries for external boundary directions.
      48             :  *
      49             :  * For asynchronous boundary schemes, e.g. local time-stepping, this action also
      50             :  * initializes the `BoundaryScheme::receive_temporal_id` on mortars (see
      51             :  * `dg::Actions::ReceiveDataForFluxes`). It assumes that the current state is
      52             :  * _before_ any mortar communications take place and the first communication
      53             :  * will happen at what is currently the `receive_temporal_id`.
      54             :  *
      55             :  * Uses:
      56             :  * - DataBox:
      57             :  *   - `Tags::Element<Dim>`
      58             :  *   - `Tags::Mesh<Dim>`
      59             :  *   - `BoundaryScheme::receive_temporal_id`
      60             :  *   - `Tags::Interface<Tags::InternalDirections<Dim>, Tags::Mesh<Dim - 1>>`
      61             :  *   - `Tags::Interface<
      62             :  *   Tags::BoundaryDirectionsInterior<Dim>, Tags::Mesh<Dim - 1>>`
      63             :  *
      64             :  * DataBox changes:
      65             :  * - Adds:
      66             :  *   - `Tags::Mortars<BoundaryScheme::mortar_data_tag, dim>`
      67             :  *   - `Tags::Mortars<BoundaryScheme::receive_temporal_id, dim>`
      68             :  *   - `Tags::Mortars<Tags::Mesh<dim - 1>, dim>`
      69             :  *   - `Tags::Mortars<Tags::MortarSize<dim - 1>, dim>`
      70             :  * - Removes: nothing
      71             :  * - Modifies: nothing
      72             :  *
      73             :  * \note This action relies on the `SetupDataBox` aggregated initialization
      74             :  * mechanism, so `Actions::SetupDataBox` must be present in the `Initialization`
      75             :  * phase action list prior to this action.
      76             :  */
      77             : template <typename BoundaryScheme, bool AddFluxBoundaryConditionMortars = true>
      78           1 : struct InitializeMortars {
      79             :  private:
      80           0 :   static constexpr size_t dim = BoundaryScheme::volume_dim;
      81           0 :   using mortar_data_tag =
      82             :       ::Tags::Mortars<typename BoundaryScheme::mortar_data_tag, dim>;
      83             : 
      84             :  public:
      85           0 :   using initialization_tags = tmpl::list<domain::Tags::InitialExtents<dim>>;
      86             : 
      87           0 :   using next_temporal_id_tag = typename BoundaryScheme::receive_temporal_id_tag;
      88           0 :   using mortars_next_temporal_id_tag =
      89             :       ::Tags::Mortars<next_temporal_id_tag, dim>;
      90             : 
      91           0 :   using simple_tags =
      92             :       tmpl::list<mortar_data_tag,
      93             :                  ::Tags::Mortars<domain::Tags::Mesh<dim - 1>, dim>,
      94             :                  ::Tags::Mortars<::Tags::MortarSize<dim - 1>, dim>,
      95             :                  mortars_next_temporal_id_tag>;
      96             : 
      97           0 :   using compute_tags = tmpl::list<>;
      98             : 
      99             :   template <typename DataBox, typename... InboxTags, typename Metavariables,
     100             :             typename ArrayIndex, typename ActionList,
     101             :             typename ParallelComponent,
     102             :             Requires<db::tag_is_retrievable_v<domain::Tags::InitialExtents<dim>,
     103             :                                               DataBox>> = nullptr>
     104           0 :   static auto apply(DataBox& box,
     105             :                     const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     106             :                     const Parallel::GlobalCache<Metavariables>& /*cache*/,
     107             :                     const ArrayIndex& /*array_index*/, ActionList /*meta*/,
     108             :                     const ParallelComponent* const /*meta*/) noexcept {
     109             :     const auto& element = db::get<domain::Tags::Element<dim>>(box);
     110             :     const auto& initial_extents =
     111             :         db::get<domain::Tags::InitialExtents<dim>>(box);
     112             : 
     113             :     typename mortar_data_tag::type mortar_data{};
     114             :     typename ::Tags::Mortars<domain::Tags::Mesh<dim - 1>, dim>::type
     115             :         mortar_meshes{};
     116             :     typename ::Tags::Mortars<::Tags::MortarSize<dim - 1>, dim>::type
     117             :         mortar_sizes{};
     118             :     const auto& interface_meshes =
     119             :         db::get<domain::Tags::Interface<domain::Tags::InternalDirections<dim>,
     120             :                                         domain::Tags::Mesh<dim - 1>>>(box);
     121             :     for (const auto& direction_and_neighbors : element.neighbors()) {
     122             :       const auto& direction = direction_and_neighbors.first;
     123             :       const auto& neighbors = direction_and_neighbors.second;
     124             :       for (const auto& neighbor : neighbors) {
     125             :         const auto mortar_id = std::make_pair(direction, neighbor);
     126             :         mortar_data[mortar_id];  // Default initialize data
     127             :         mortar_meshes.emplace(
     128             :             mortar_id,
     129             :             dg::mortar_mesh(
     130             :                 interface_meshes.at(direction),
     131             :                 domain::Initialization::create_initial_mesh(
     132             :                     initial_extents, neighbor,
     133             :                     Spectral::Quadrature::GaussLobatto, neighbors.orientation())
     134             :                     .slice_away(direction.dimension())));
     135             :         mortar_sizes.emplace(
     136             :             mortar_id,
     137             :             dg::mortar_size(element.id(), neighbor, direction.dimension(),
     138             :                             neighbors.orientation()));
     139             :       }
     140             :     }
     141             : 
     142             :     if (AddFluxBoundaryConditionMortars) {
     143             :       const auto& boundary_meshes = db::get<
     144             :           domain::Tags::Interface<domain::Tags::BoundaryDirectionsInterior<dim>,
     145             :                                   domain::Tags::Mesh<dim - 1>>>(box);
     146             :       for (const auto& direction : element.external_boundaries()) {
     147             :         const auto mortar_id =
     148             :             std::make_pair(direction, ElementId<dim>::external_boundary_id());
     149             :         mortar_data[mortar_id];  // Default initialize data
     150             :         mortar_meshes.emplace(mortar_id, boundary_meshes.at(direction));
     151             :         mortar_sizes.emplace(mortar_id,
     152             :                              make_array<dim - 1>(Spectral::MortarSize::Full));
     153             :       }
     154             :     }
     155             : 
     156             :     // We don't need to initialize the "next" temporal id on mortars if data is
     157             :     // communicated synchronously
     158             :     using need_next_temporal_id_on_mortars = std::negation<
     159             :         std::is_same<typename BoundaryScheme::temporal_id_tag,
     160             :                      typename BoundaryScheme::receive_temporal_id_tag>>;
     161             :     if constexpr (need_next_temporal_id_on_mortars::value) {
     162             :       initialize_next_temporal_id_on_mortars(make_not_null(&box));
     163             :     }
     164             :     ::Initialization::mutate_assign<tmpl::list<
     165             :         mortar_data_tag, ::Tags::Mortars<domain::Tags::Mesh<dim - 1>, dim>,
     166             :         ::Tags::Mortars<::Tags::MortarSize<dim - 1>, dim>>>(
     167             :         make_not_null(&box), std::move(mortar_data), std::move(mortar_meshes),
     168             :         std::move(mortar_sizes));
     169             :     return std::make_tuple(std::move(box));
     170             :   }
     171             : 
     172             :   template <typename DataBox, typename... InboxTags, typename Metavariables,
     173             :             typename ArrayIndex, typename ActionList,
     174             :             typename ParallelComponent,
     175             :             Requires<not db::tag_is_retrievable_v<
     176             :                 domain::Tags::InitialExtents<dim>, DataBox>> = nullptr>
     177           0 :   static std::tuple<DataBox&&> apply(
     178             :       DataBox& /*box*/, const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     179             :       const Parallel::GlobalCache<Metavariables>& /*cache*/,
     180             :       const ArrayIndex& /*array_index*/, ActionList /*meta*/,
     181             :       const ParallelComponent* const /*meta*/) noexcept {
     182             :     ERROR(
     183             :         "Dependencies not fulfilled. Did you forget to terminate the phase "
     184             :         "after removing options?");
     185             :   }
     186             : 
     187             :  private:
     188             :   template <typename DbTagsList>
     189           0 :   static void initialize_next_temporal_id_on_mortars(
     190             :       const gsl::not_null<db::DataBox<DbTagsList>*> box) noexcept {
     191             :     const auto& next_temporal_id = get<next_temporal_id_tag>(*box);
     192             :     typename mortars_next_temporal_id_tag::type mortar_next_temporal_ids{};
     193             :     // Since no communication needs to happen for boundary conditions
     194             :     // the temporal id is not advanced on the boundary, so we only need to
     195             :     // initialize it on internal boundaries
     196             :     for (const auto& direction_and_neighbors :
     197             :          db::get<domain::Tags::Element<dim>>(*box).neighbors()) {
     198             :       const auto& direction = direction_and_neighbors.first;
     199             :       const auto& neighbors = direction_and_neighbors.second;
     200             :       for (const auto& neighbor : neighbors) {
     201             :         const auto mortar_id = std::make_pair(direction, neighbor);
     202             :         mortar_next_temporal_ids.insert({mortar_id, next_temporal_id});
     203             :       }
     204             :     }
     205             :     ::Initialization::mutate_assign<tmpl::list<mortars_next_temporal_id_tag>>(
     206             :         box, std::move(mortar_next_temporal_ids));
     207             :   }
     208             : };
     209             : }  // namespace Actions
     210             : }  // namespace dg

Generated by: LCOV version 1.14