TwoMeshRdmpTci.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <algorithm>
7 
9 #include "Evolution/DgSubcell/Tags/Inactive.hpp"
11 #include "Utilities/TMPL.hpp"
12 
13 namespace evolution::dg::subcell {
14 /*!
15  * \brief Troubled cell indicator using a relaxed discrete maximum principle,
16  * comparing the solution on two grids at the same point in time.
17  *
18  * Checks that the subcell solution \f$\underline{u}\f$ and the DG solution
19  * \f$u\f$ satisfy
20  *
21  * \f{align*}{
22  * \min(u)-\delta \le \underline{u} \le \max(u)+\delta
23  * \f}
24  *
25  * where
26  *
27  * \f{align*}{
28  * \delta = \max\left[\delta_0, \epsilon(\max(u) - \min(u))\right]
29  * \f}
30  *
31  * where \f$\delta_0\f$ and \f$\epsilon\f$ are constants controlling the maximum
32  * absolute and relative change allowed when projecting the DG solution to the
33  * subcell grid. We currently specify one value of \f$\delta_0\f$ and
34  * \f$\epsilon\f$ for all variables, but this could be generalized to choosing
35  * the allowed variation in a variable-specific manner.
36  */
37 template <typename... EvolvedVarsTags>
39  const Variables<tmpl::list<EvolvedVarsTags...>>& dg_evolved_vars,
40  const Variables<tmpl::list<Tags::Inactive<EvolvedVarsTags>...>>&
41  subcell_evolved_vars,
42  const double rdmp_delta0, const double rdmp_epsilon) noexcept {
43  ASSERT(rdmp_delta0 > 0.0, "The RDMP delta0 parameter must be positive.");
44  ASSERT(rdmp_epsilon > 0.0, "The RDMP epsilon parameter must be positive.");
45  bool cell_is_troubled = false;
46  tmpl::for_each<tmpl::list<EvolvedVarsTags...>>(
47  [&cell_is_troubled, &dg_evolved_vars, rdmp_delta0, rdmp_epsilon,
48  &subcell_evolved_vars](auto tag_v) noexcept {
49  if (cell_is_troubled) {
50  return;
51  }
52 
53  using tag = tmpl::type_from<decltype(tag_v)>;
54  using inactive_tag = Tags::Inactive<tag>;
55  const auto& dg_var = get<tag>(dg_evolved_vars);
56  const auto& subcell_var = get<inactive_tag>(subcell_evolved_vars);
57 
58  for (auto dg_it = dg_var.begin(), subcell_it = subcell_var.begin();
59  dg_it != dg_var.end() and subcell_it != subcell_var.end();
60  (void)++dg_it, (void)++subcell_it) {
61  ASSERT(not cell_is_troubled,
62  "If a cell has already been marked as troubled during the "
63  "two mesh RDMP TCI, we should not be continuing to check "
64  "other variables.");
65  using std::max;
66  using std::min;
67 
68  const double max_dg = max(*dg_it);
69  const double min_dg = min(*dg_it);
70  const double max_subcell = max(*subcell_it);
71  const double min_subcell = min(*subcell_it);
72  const double delta =
73  max(rdmp_delta0, rdmp_epsilon * (max_dg - min_dg));
74  cell_is_troubled =
75  max_subcell > max_dg + delta or min_subcell < min_dg - delta;
76  if (cell_is_troubled) {
77  return;
78  }
79  }
80  });
81  return cell_is_troubled;
82 }
83 } // namespace evolution::dg::subcell
algorithm
Assert.hpp
ASSERT
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
evolution::dg::subcell::two_mesh_rdmp_tci
bool two_mesh_rdmp_tci(const Variables< tmpl::list< EvolvedVarsTags... >> &dg_evolved_vars, const Variables< tmpl::list< Tags::Inactive< EvolvedVarsTags >... >> &subcell_evolved_vars, const double rdmp_delta0, const double rdmp_epsilon) noexcept
Troubled cell indicator using a relaxed discrete maximum principle, comparing the solution on two gri...
Definition: TwoMeshRdmpTci.hpp:38
Variables.hpp
evolution::dg::subcell
Implementation of a generic finite volume/conservative finite difference subcell limiter.
Definition: Actions.hpp:6
evolution::dg::subcell::Tags::Inactive
Mark a tag as holding data for the inactive grid.
Definition: Inactive.hpp:23
TMPL.hpp