SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DiscontinuousGalerkin/Limiters - SimpleWenoImpl.hpp Hit Total Coverage
Commit: 35a1e98cd3e4fdea528eb8100f99c2f707894fda Lines: 0 1 0.0 %
Date: 2024-04-19 00:10:48
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 <array>
       7             : #include <boost/functional/hash.hpp>  // IWYU pragma: keep
       8             : #include <cstddef>
       9             : #include <limits>
      10             : #include <string>
      11             : #include <type_traits>
      12             : #include <unordered_map>
      13             : #include <utility>
      14             : 
      15             : #include "DataStructures/Tensor/Tensor.hpp"
      16             : #include "DataStructures/Variables.hpp"
      17             : #include "Domain/Structure/Direction.hpp"
      18             : #include "Domain/Structure/Element.hpp"
      19             : #include "Domain/Structure/ElementId.hpp"
      20             : #include "Evolution/DiscontinuousGalerkin/Limiters/WenoGridHelpers.hpp"
      21             : #include "Evolution/DiscontinuousGalerkin/Limiters/WenoHelpers.hpp"
      22             : #include "Evolution/DiscontinuousGalerkin/Limiters/WenoOscillationIndicator.hpp"
      23             : #include "NumericalAlgorithms/Interpolation/RegularGridInterpolant.hpp"
      24             : #include "NumericalAlgorithms/LinearOperators/MeanValue.hpp"
      25             : #include "NumericalAlgorithms/Spectral/Basis.hpp"
      26             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      27             : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
      28             : #include "Utilities/Gsl.hpp"
      29             : 
      30             : namespace Limiters::Weno_detail {
      31             : 
      32             : // Compute the Simple WENO solution for one tensor component
      33             : //
      34             : // This interface is intended for use in limiters that check the troubled-cell
      35             : // indicator independently for each tensor component. These limiters generally
      36             : // need to limit only a subset of the tensor components.
      37             : //
      38             : // When calling `simple_weno_impl`,
      39             : // - `interpolator_buffer` may be empty
      40             : // - `modified_neighbor_solution_buffer` should contain one DataVector for each
      41             : //   neighboring element (i.e. for each entry in `neighbor_data`)
      42             : template <typename Tag, size_t VolumeDim, typename PackagedData>
      43             : void simple_weno_impl(
      44             :     const gsl::not_null<std::unordered_map<
      45             :         DirectionalId<VolumeDim>, intrp::RegularGrid<VolumeDim>,
      46             :         boost::hash<DirectionalId<VolumeDim>>>*>
      47             :         interpolator_buffer,
      48             :     const gsl::not_null<
      49             :         std::unordered_map<DirectionalId<VolumeDim>, DataVector,
      50             :                            boost::hash<DirectionalId<VolumeDim>>>*>
      51             :         modified_neighbor_solution_buffer,
      52             :     const gsl::not_null<typename Tag::type*> tensor,
      53             :     const double neighbor_linear_weight, const size_t tensor_storage_index,
      54             :     const Mesh<VolumeDim>& mesh, const Element<VolumeDim>& element,
      55             :     const std::unordered_map<DirectionalId<VolumeDim>, PackagedData,
      56             :                              boost::hash<DirectionalId<VolumeDim>>>&
      57             :         neighbor_data) {
      58             :   // Check that basis is LGL or LG
      59             :   // Note that the SimpleWeno implementation should generalize well to other
      60             :   // bases beyond LGL or LG, once the oscillation_indicator function has been
      61             :   // generalized.
      62             :   ASSERT(mesh.basis() == make_array<VolumeDim>(Spectral::Basis::Legendre),
      63             :          "Unsupported basis: " << mesh);
      64             :   ASSERT(mesh.quadrature() ==
      65             :                  make_array<VolumeDim>(Spectral::Quadrature::GaussLobatto) or
      66             :              mesh.quadrature() ==
      67             :                  make_array<VolumeDim>(Spectral::Quadrature::Gauss),
      68             :          "Unsupported quadrature: " << mesh);
      69             : 
      70             :   ASSERT(
      71             :       modified_neighbor_solution_buffer->size() == neighbor_data.size(),
      72             :       "modified_neighbor_solution_buffer->size() = "
      73             :           << modified_neighbor_solution_buffer->size()
      74             :           << "\nneighbor_data.size() = " << neighbor_data.size()
      75             :           << "\nmodified_neighbor_solution_buffer was incorrectly initialized "
      76             :              "before calling simple_weno_impl.");
      77             : 
      78             :   // Compute the modified neighbor solutions.
      79             :   // First extrapolate neighbor data onto local grid points, then shift the
      80             :   // extrapolated data so its mean matches the local mean.
      81             :   DataVector& component_to_limit = (*tensor)[tensor_storage_index];
      82             :   const double local_mean = mean_value(component_to_limit, mesh);
      83             :   for (const auto& neighbor_and_data : neighbor_data) {
      84             :     const auto& neighbor = neighbor_and_data.first;
      85             :     const auto& data = neighbor_and_data.second;
      86             : 
      87             :     if (interpolator_buffer->find(neighbor) == interpolator_buffer->end()) {
      88             :       // No interpolator found => create one
      89             :       const auto& direction = neighbor.direction;
      90             :       const auto& source_mesh = data.mesh;
      91             :       const auto target_1d_logical_coords =
      92             :           Weno_detail::local_grid_points_in_neighbor_logical_coords(
      93             :               mesh, source_mesh, element, direction);
      94             :       interpolator_buffer->insert(std::make_pair(
      95             :           neighbor, intrp::RegularGrid<VolumeDim>(source_mesh, mesh,
      96             :                                                   target_1d_logical_coords)));
      97             :     }
      98             : 
      99             :     // Avoid allocations by working directly in the preallocated buffer
     100             :     DataVector& buffer = modified_neighbor_solution_buffer->at(neighbor);
     101             : 
     102             :     interpolator_buffer->at(neighbor).interpolate(
     103             :         make_not_null(&buffer),
     104             :         get<Tag>(data.volume_data)[tensor_storage_index]);
     105             :     const double neighbor_mean = mean_value(buffer, mesh);
     106             :     buffer += (local_mean - neighbor_mean);
     107             :   }
     108             : 
     109             :   // Sum local and modified neighbor polynomials for the WENO reconstruction
     110             :   Weno_detail::reconstruct_from_weighted_sum(
     111             :       make_not_null(&component_to_limit), neighbor_linear_weight,
     112             :       Weno_detail::DerivativeWeight::PowTwoEll, mesh,
     113             :       *modified_neighbor_solution_buffer);
     114             : }
     115             : 
     116             : // Compute the Simple WENO solution for one tensor
     117             : //
     118             : // This interface is intended for use in limiters that check the troubled-cell
     119             : // indicator for the whole cell, and apply the limiter to all fields.
     120             : //
     121             : // When calling `simple_weno_impl`,
     122             : // - `interpolator_buffer` may be empty
     123             : // - `modified_neighbor_solution_buffer` should contain one DataVector for each
     124             : //   neighboring element (i.e. for each entry in `neighbor_data`)
     125             : template <typename Tag, size_t VolumeDim, typename PackagedData>
     126             : void simple_weno_impl(
     127             :     const gsl::not_null<std::unordered_map<
     128             :         DirectionalId<VolumeDim>, intrp::RegularGrid<VolumeDim>,
     129             :         boost::hash<DirectionalId<VolumeDim>>>*>
     130             :         interpolator_buffer,
     131             :     const gsl::not_null<
     132             :         std::unordered_map<DirectionalId<VolumeDim>, DataVector,
     133             :                            boost::hash<DirectionalId<VolumeDim>>>*>
     134             :         modified_neighbor_solution_buffer,
     135             :     const gsl::not_null<typename Tag::type*> tensor,
     136             :     const double neighbor_linear_weight, const Mesh<VolumeDim>& mesh,
     137             :     const Element<VolumeDim>& element,
     138             :     const std::unordered_map<DirectionalId<VolumeDim>, PackagedData,
     139             :                              boost::hash<DirectionalId<VolumeDim>>>&
     140             :         neighbor_data) {
     141             :   for (size_t tensor_storage_index = 0; tensor_storage_index < tensor->size();
     142             :        ++tensor_storage_index) {
     143             :     simple_weno_impl<Tag>(interpolator_buffer,
     144             :                           modified_neighbor_solution_buffer, tensor,
     145             :                           neighbor_linear_weight, tensor_storage_index, mesh,
     146             :                           element, neighbor_data);
     147             :   }
     148             : }
     149             : 
     150             : }  // namespace Limiters::Weno_detail

Generated by: LCOV version 1.14