SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearOperators - ExponentialFilter.hpp Hit Total Coverage
Commit: a18e59fda1a195609825c55450f7d61ad20a91a4 Lines: 5 32 15.6 %
Date: 2026-06-11 22:10:41
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 <cstddef>
       7             : #include <optional>
       8             : #include <pup.h>
       9             : #include <string>
      10             : #include <unordered_set>
      11             : 
      12             : #include "NumericalAlgorithms/Spectral/Parity.hpp"
      13             : #include "Options/Auto.hpp"
      14             : #include "Options/String.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : 
      17             : /// \cond
      18             : class Matrix;
      19             : template <size_t Dim>
      20             : class Mesh;
      21             : 
      22             : /// \endcond
      23             : 
      24             : namespace Filters {
      25             : 
      26             : /*!
      27             :  * \ingroup DiscontinuousGalerkinGroup
      28             :  * \brief A cached exponential filter.
      29             :  *
      30             :  * Applies an exponential filter in each logical direction to each component of
      31             :  * the tensors `TagsToFilter`. The exponential filter rescales the 1d modal
      32             :  * coefficients \f$c_i\f$ as:
      33             :  *
      34             :  * \f{align*}{
      35             :  *  c_i\to c_i \exp\left[-\alpha_{\mathrm{ef}}
      36             :  *   \left(\frac{i}{N}\right)^{2\beta_{\mathrm{ef}}}\right]
      37             :  * \f}
      38             :  *
      39             :  * where \f$N\f$ is the basis degree (number of grid points per element per
      40             :  * dimension minus one), \f$\alpha_{\mathrm{ef}}\f$ determines how much the
      41             :  * coefficients are rescaled, and \f$\beta_{\mathrm{ef}}\f$ (given by the
      42             :  * `HalfPower` option) determines how aggressive/broad the filter is (lower
      43             :  * values means filtering more coefficients). Setting
      44             :  * \f$\alpha_{\mathrm{ef}}=36\f$ results in effectively zeroing the highest
      45             :  * coefficient (in practice it gets rescaled by machine epsilon). The same
      46             :  * \f$\alpha_{\mathrm{ef}}\f$ and \f$\beta_{\mathrm{ef}}\f$ are used in each
      47             :  * logical direction. For a discussion of filtering see section 5.3 of
      48             :  * \cite HesthavenWarburton.
      49             :  *
      50             :  * #### Design decision:
      51             :  *
      52             :  * - The reason for the `size_t` template parameter is to allow for different
      53             :  * `Alpha` and `HalfPower` parameters for different tensors while still being
      54             :  * able to cache the matrices.   If different `Alpha` or `HalfPower` parameters
      55             :  * are desired for filtering different tensors, then multiple filters must be
      56             :  * inserted into the GlobalCache with different `FilterIndex` values. In
      57             :  * the input file these will be specified as `ExpFilterFILTER_INDEX`, e.g.
      58             :  * \snippet LinearOperators/Test_Filtering.cpp multiple_exponential_filters
      59             :  */
      60             : template <size_t FilterIndex>
      61           1 : class Exponential {
      62             :  public:
      63             :   /// \brief The value of `exp(-alpha)` is what the highest modal coefficient is
      64             :   /// rescaled by.
      65           1 :   struct Alpha {
      66           0 :     using type = double;
      67           0 :     static constexpr Options::String help =
      68             :         "exp(-alpha) is rescaling of highest coefficient";
      69           0 :     static type lower_bound() { return 0.0; }
      70             :   };
      71             : 
      72             :   /*!
      73             :    * \brief Half of the exponent in the exponential.
      74             :    *
      75             :    * \f{align*}{
      76             :    *  c_i\to c_i \exp\left[-\alpha \left(\frac{i}{N}\right)^{2m}\right]
      77             :    * \f}
      78             :    */
      79           1 :   struct HalfPower {
      80           0 :     using type = unsigned;
      81           0 :     static constexpr Options::String help =
      82             :         "Half of the exponent in the generalized Gaussian";
      83           0 :     static type lower_bound() { return 1; }
      84             :   };
      85             : 
      86             :   /// \brief Turn the filter off
      87           1 :   struct Enable {
      88           0 :     using type = bool;
      89           0 :     static constexpr Options::String help = {"Enable the filter"};
      90             :   };
      91             : 
      92           0 :   struct BlocksToFilter {
      93           0 :     using type =
      94             :         Options::Auto<std::vector<std::string>, Options::AutoLabel::All>;
      95           0 :     static constexpr Options::String help = {
      96             :         "List of blocks or block groups to apply filtering to. All other "
      97             :         "blocks will have no filtering. You can also specify 'All' to do "
      98             :         "filtering in all blocks of the domain."};
      99             :   };
     100             : 
     101           0 :   using options = tmpl::list<Alpha, HalfPower, Enable, BlocksToFilter>;
     102           0 :   static constexpr Options::String help = {"An exponential filter."};
     103           0 :   static std::string name() {
     104             :     return "ExpFilter" + std::to_string(FilterIndex);
     105             :   }
     106             : 
     107           0 :   Exponential() = default;
     108             : 
     109           0 :   Exponential(double alpha, unsigned half_power, bool enable,
     110             :               const std::optional<std::vector<std::string>>& blocks_to_filter,
     111             :               const Options::Context& context = {});
     112             : 
     113             :   /// A cached matrix used to apply the filter to the given mesh
     114           1 :   const Matrix& filter_matrix(
     115             :       const Mesh<1>& mesh,
     116             :       Spectral::Parity parity = Spectral::Parity::Uninitialized) const;
     117             : 
     118           0 :   bool enable() const { return enable_; }
     119             : 
     120           0 :   const std::optional<std::unordered_set<std::string>>& blocks_to_filter()
     121             :       const {
     122             :     return blocks_to_filter_;
     123             :   }
     124             : 
     125             :   // NOLINTNEXTLINE(google-runtime-references)
     126           0 :   void pup(PUP::er& p);
     127             : 
     128             :  private:
     129             :   template <size_t LocalFilterIndex>
     130             :   // NOLINTNEXTLINE(readability-redundant-declaration)
     131           0 :   friend bool operator==(const Exponential<LocalFilterIndex>& lhs,
     132             :                          const Exponential<LocalFilterIndex>& rhs);
     133             : 
     134           0 :   double alpha_{36.0};
     135           0 :   unsigned half_power_{16};
     136           0 :   bool enable_{true};
     137           0 :   std::optional<std::unordered_set<std::string>> blocks_to_filter_{};
     138             : };
     139             : 
     140             : template <size_t LocalFilterIndex>
     141           0 : bool operator==(const Exponential<LocalFilterIndex>& lhs,
     142             :                 const Exponential<LocalFilterIndex>& rhs);
     143             : 
     144             : template <size_t FilterIndex>
     145           0 : bool operator!=(const Exponential<FilterIndex>& lhs,
     146             :                 const Exponential<FilterIndex>& rhs);
     147             : }  // namespace Filters

Generated by: LCOV version 1.14