SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DgSubcell - TwoMeshRdmpTci.hpp Hit Total Coverage
Commit: 37c384043430860f87787999aa7399d01bb3d213 Lines: 1 2 50.0 %
Date: 2024-04-20 02:24:02
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 <algorithm>
       7             : 
       8             : #include "DataStructures/Variables.hpp"
       9             : #include "Utilities/ErrorHandling/Assert.hpp"
      10             : #include "Utilities/TMPL.hpp"
      11             : 
      12             : namespace evolution::dg::subcell {
      13             : /*!
      14             :  * \brief Troubled cell indicator using a relaxed discrete maximum principle,
      15             :  * comparing the solution on two grids at the same point in time.
      16             :  *
      17             :  * Checks that the subcell solution \f$\underline{u}\f$ and the DG solution
      18             :  * \f$u\f$ satisfy
      19             :  *
      20             :  * \f{align*}{ \min(u)-\delta \le \underline{u} \le \max(u)+\delta \f}
      21             :  *
      22             :  * where
      23             :  *
      24             :  * \f{align*}{ \delta = \max\left[\delta_0, \epsilon(\max(u) - \min(u))\right]
      25             :  * \f}
      26             :  *
      27             :  * where \f$\delta_0\f$ and \f$\epsilon\f$ are constants controlling the maximum
      28             :  * absolute and relative change allowed when projecting the DG solution to the
      29             :  * subcell grid. We currently specify one value of \f$\delta_0\f$ and
      30             :  * \f$\epsilon\f$ for all variables, but this could be generalized to choosing
      31             :  * the allowed variation in a variable-specific manner.
      32             :  *
      33             :  * If all checks are passed and cell is not troubled, returns an integer `0`.
      34             :  * Otherwise returns 1-based index of the tag in the input Variables that fails
      35             :  * the check. For instance, if we have
      36             :  *
      37             :  *  - `Variables<tmpl::list<DgVar1, DgVar2, DgVar3>>` for `dg_evolved_vars`
      38             :  *  - `Variables<tmpl::list<SubVar1, SubVar2, SubVar3>>` for
      39             :  *    `subcell_evolved_vars`
      40             :  *
      41             :  * as inputs and TCI flags the second pair `DgVar2` and `SubVar2` not satisfying
      42             :  * two-mesh RDMP criteria, returned value is `2` since the second pair of tags
      43             :  * failed the check.
      44             :  *
      45             :  * \note Once a single pair of tags fails to satisfy the check, checks for the
      46             :  * remaining part of the input variables are skipped. In the example above, for
      47             :  * instance if the second pair (`DgVar2`,`SubVar2`) is flagged, the third pair
      48             :  * (`DgVar3`,`SubVar3`) is ignored and not checked.
      49             :  *
      50             :  */
      51             : template <typename... DgEvolvedVarsTags, typename... SubcellEvolvedVarsTags>
      52           1 : int two_mesh_rdmp_tci(
      53             :     const Variables<tmpl::list<DgEvolvedVarsTags...>>& dg_evolved_vars,
      54             :     const Variables<tmpl::list<SubcellEvolvedVarsTags...>>&
      55             :         subcell_evolved_vars,
      56             :     const double rdmp_delta0, const double rdmp_epsilon) {
      57             :   static_assert(sizeof...(DgEvolvedVarsTags) ==
      58             :                 sizeof...(SubcellEvolvedVarsTags));
      59             :   ASSERT(rdmp_delta0 > 0.0, "The RDMP delta0 parameter must be positive.");
      60             :   ASSERT(rdmp_epsilon > 0.0, "The RDMP epsilon parameter must be positive.");
      61             : 
      62             :   bool cell_is_troubled = false;
      63             :   int tci_status = 0;
      64             :   size_t tag_index = 0;
      65             : 
      66             :   tmpl::for_each<
      67             :       tmpl::list<tmpl::list<DgEvolvedVarsTags, SubcellEvolvedVarsTags>...>>(
      68             :       [&cell_is_troubled, &tag_index, &dg_evolved_vars, rdmp_delta0,
      69             :        rdmp_epsilon, &subcell_evolved_vars, &tci_status](auto tag_v) {
      70             :         if (cell_is_troubled) {
      71             :           return;
      72             :         }
      73             : 
      74             :         using tags_list = tmpl::type_from<decltype(tag_v)>;
      75             :         using tag = tmpl::front<tags_list>;
      76             :         using inactive_tag = tmpl::back<tags_list>;
      77             :         const auto& dg_var = get<tag>(dg_evolved_vars);
      78             :         const auto& subcell_var = get<inactive_tag>(subcell_evolved_vars);
      79             : 
      80             :         for (auto dg_it = dg_var.begin(), subcell_it = subcell_var.begin();
      81             :              dg_it != dg_var.end() and subcell_it != subcell_var.end();
      82             :              (void)++dg_it, (void)++subcell_it) {
      83             :           ASSERT(not cell_is_troubled,
      84             :                  "If a cell has already been marked as troubled during the "
      85             :                  "two mesh RDMP TCI, we should not be continuing to check "
      86             :                  "other variables.");
      87             :           using std::max;
      88             :           using std::min;
      89             : 
      90             :           const double max_dg = max(*dg_it);
      91             :           const double min_dg = min(*dg_it);
      92             :           const double max_subcell = max(*subcell_it);
      93             :           const double min_subcell = min(*subcell_it);
      94             :           const double delta =
      95             :               max(rdmp_delta0, rdmp_epsilon * (max_dg - min_dg));
      96             :           cell_is_troubled =
      97             :               max_subcell > max_dg + delta or min_subcell < min_dg - delta;
      98             :           if (cell_is_troubled) {
      99             :             tci_status = static_cast<int>(tag_index + 1);
     100             :             return;
     101             :           }
     102             :           ++tag_index;
     103             :         }
     104             :       });
     105             :   return tci_status;
     106             : }
     107             : }  // namespace evolution::dg::subcell

Generated by: LCOV version 1.14