SpECTRE Documentation Coverage Report
Current view: top level - Domain/Amr - UpdateAmrDecision.cpp Hit Total Coverage
Commit: ebec864322c50bab8dca0a90baf8d01875114261 Lines: 1 3 33.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             : #include "Domain/Amr/UpdateAmrDecision.hpp"
       5             : 
       6             : #include "Domain/Amr/Helpers.hpp"
       7             : #include "Domain/Structure/Direction.hpp"
       8             : #include "Domain/Structure/Element.hpp"    // IWYU pragma: keep
       9             : #include "Domain/Structure/ElementId.hpp"  // IWYU pragma: keep
      10             : #include "Domain/Structure/Neighbors.hpp"  // IWYU pragma: keep
      11             : #include "ErrorHandling/Assert.hpp"
      12             : #include "Utilities/GenerateInstantiations.hpp"
      13             : #include "Utilities/Gsl.hpp"
      14             : 
      15             : template <size_t VolumeDim>
      16           1 : class OrientationMap;
      17             : 
      18             : namespace amr {
      19             : 
      20             : template <size_t VolumeDim>
      21           0 : bool update_amr_decision(
      22             :     const gsl::not_null<std::array<amr::Flag, VolumeDim>*> my_current_amr_flags,
      23             :     const Element<VolumeDim>& element, const ElementId<VolumeDim>& neighbor_id,
      24             :     const std::array<amr::Flag, VolumeDim>& neighbor_amr_flags) noexcept {
      25             :   const auto& element_id = element.id();
      26             :   bool my_amr_decision_changed = false;
      27             :   bool neighbor_found = false;
      28             :   std::array<size_t, VolumeDim> my_desired_levels =
      29             :       amr::desired_refinement_levels(element_id, *my_current_amr_flags);
      30             : 
      31             :   for (const auto& direction_neighbors : element.neighbors()) {
      32             :     const Neighbors<VolumeDim>& neighbors_in_dir = direction_neighbors.second;
      33             : 
      34             :     if (1 == neighbors_in_dir.ids().count(neighbor_id)) {
      35             :       // finding the same neighbor twice (which can happen with periodic
      36             :       // domains) is okay, and may be needed when examining a Join
      37             :       neighbor_found = true;
      38             :       const Direction<VolumeDim> direction_to_neighbor =
      39             :           direction_neighbors.first;
      40             :       const OrientationMap<VolumeDim>& orientation_of_neighbor =
      41             :           neighbors_in_dir.orientation();
      42             :       const std::array<size_t, VolumeDim> neighbor_desired_levels =
      43             :           amr::desired_refinement_levels_of_neighbor(
      44             :               neighbor_id, neighbor_amr_flags, orientation_of_neighbor);
      45             : 
      46             :       // update flags if my element wants to be two or more levels
      47             :       // coarser than the neighbor in any dimension
      48             :       for (size_t d = 0; d < VolumeDim; ++d) {
      49             :         if (amr::Flag::Split == gsl::at(*my_current_amr_flags, d) or
      50             :             gsl::at(my_desired_levels, d) >=
      51             :                 gsl::at(neighbor_desired_levels, d)) {
      52             :           continue;
      53             :         }
      54             :         const size_t difference =
      55             :             gsl::at(neighbor_desired_levels, d) - gsl::at(my_desired_levels, d);
      56             :         ASSERT(difference < 4 and difference > 0,
      57             :                "neighbor level = " << gsl::at(neighbor_desired_levels, d)
      58             :                                    << ", my level = "
      59             :                                    << gsl::at(my_desired_levels, d));
      60             :         if (amr::Flag::Join == gsl::at(*my_current_amr_flags, d)) {
      61             :           if (3 == difference) {
      62             :             // My split neighbor wants to split, so I need to split to keep
      63             :             // refinement levels within one.
      64             :             gsl::at(*my_current_amr_flags, d) = amr::Flag::Split;
      65             :             gsl::at(my_desired_levels, d) += 2;
      66             :             my_amr_decision_changed = true;
      67             :           } else if (2 == difference) {
      68             :             // My split neighbor wants to stay the same, or my neighbor
      69             :             // split, so I need to stay the same to keep refinement levels
      70             :             // within one.
      71             :             gsl::at(*my_current_amr_flags, d) = amr::Flag::DoNothing;
      72             :             ++gsl::at(my_desired_levels, d);
      73             :             my_amr_decision_changed = true;
      74             :           }
      75             :         } else {
      76             :           if (2 == difference) {
      77             :             // my split neighbor wants to split, so I need to split to
      78             :             // keep refinement levels within one
      79             :             gsl::at(*my_current_amr_flags, d) = amr::Flag::Split;
      80             :             ++gsl::at(my_desired_levels, d);
      81             :             my_amr_decision_changed = true;
      82             :           }
      83             :         }
      84             :       }
      85             : 
      86             :       // update flags if the neighbor is a potential sibling that my element
      87             :       // cannot join
      88             :       const size_t dimension_of_direction_to_neighbor =
      89             :           direction_to_neighbor.dimension();
      90             :       if (amr::has_potential_sibling(element_id, direction_to_neighbor) and
      91             :           amr::Flag::Join == gsl::at(*my_current_amr_flags,
      92             :                                      dimension_of_direction_to_neighbor) and
      93             :           (my_desired_levels != neighbor_desired_levels)) {
      94             :         gsl::at(*my_current_amr_flags, dimension_of_direction_to_neighbor) =
      95             :             amr::Flag::DoNothing;
      96             :         ++gsl::at(my_desired_levels, dimension_of_direction_to_neighbor);
      97             :         my_amr_decision_changed = true;
      98             :       }
      99             :     }
     100             :   }
     101             :   ASSERT(neighbor_found, "Could not find neighbor " << neighbor_id);
     102             :   return my_amr_decision_changed;
     103             : }
     104             : 
     105             : /// \cond
     106             : #define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
     107             : 
     108             : #define INSTANTIATE(_, data)                                 \
     109             :   template bool update_amr_decision(                         \
     110             :       const gsl::not_null<std::array<amr::Flag, DIM(data)>*> \
     111             :           my_current_amr_flags,                              \
     112             :       const Element<DIM(data)>& element,                     \
     113             :       const ElementId<DIM(data)>& neighbor_id,               \
     114             :       const std::array<amr::Flag, DIM(data)>& neighbor_amr_flags) noexcept;
     115             : 
     116             : GENERATE_INSTANTIATIONS(INSTANTIATE, (1, 2, 3))
     117             : 
     118             : #undef DIM
     119             : #undef INSTANTIATE
     120             : /// \endcond
     121             : }  // namespace amr

Generated by: LCOV version 1.14