SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DgSubcell - TwoMeshRdmpTci.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 50.0 % 2 1
Test Date: 2026-10-22 17:29:42
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 2.0-1