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 <utility>
9 :
10 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
11 : #include "DataStructures/DataBox/Prefixes.hpp"
12 : #include "DataStructures/Variables.hpp"
13 : #include "Domain/TagsTimeDependent.hpp"
14 : #include "Evolution/DgSubcell/Projection.hpp"
15 : #include "Evolution/DgSubcell/SubcellOptions.hpp"
16 : #include "Evolution/DgSubcell/Tags/CellCenteredFlux.hpp"
17 : #include "Evolution/DgSubcell/Tags/DidRollback.hpp"
18 : #include "Evolution/DgSubcell/Tags/Mesh.hpp"
19 : #include "Evolution/DgSubcell/Tags/SubcellOptions.hpp"
20 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
21 : #include "NumericalAlgorithms/Spectral/Parity.hpp"
22 : #include "Utilities/Gsl.hpp"
23 : #include "Utilities/TMPL.hpp"
24 :
25 : namespace evolution::dg::subcell::fd {
26 : /*!
27 : * \brief Mutator that wraps the system's `FluxMutator` to correctly set the
28 : * cell-centered fluxes on the subcell grid.
29 : *
30 : * Currently we only use high-order FD if the FD order was specified in the
31 : * input file. We will need to extend this to support adaptive-order in the
32 : * future. In that case we need to check if the FD reconstruction reports back
33 : * the order to use.
34 : */
35 : template <typename System, typename FluxMutator, size_t Dim,
36 : bool ComputeOnlyOnRollback, typename Fr = Frame::Inertial>
37 1 : struct CellCenteredFlux {
38 0 : using flux_variables = typename System::flux_variables;
39 0 : using variables = typename System::variables_tag::tags_list;
40 :
41 0 : using return_tags =
42 : tmpl::list<subcell::Tags::CellCenteredFlux<flux_variables, Dim>>;
43 0 : using argument_tags = tmpl::push_front<
44 : typename FluxMutator::argument_tags, subcell::Tags::SubcellOptions<Dim>,
45 : subcell::Tags::Mesh<Dim>, domain::Tags::Mesh<Dim>,
46 : domain::Tags::MeshVelocity<Dim, Frame::Inertial>,
47 : ::Tags::Variables<variables>, subcell::Tags::DidRollback>;
48 :
49 : template <typename... FluxTags, typename... Args>
50 0 : static void apply(
51 : const gsl::not_null<std::optional<Variables<tmpl::list<FluxTags...>>>*>
52 : cell_centered_fluxes,
53 : const subcell::SubcellOptions& subcell_options,
54 : const Mesh<Dim>& subcell_mesh, const Mesh<Dim>& dg_mesh,
55 : const std::optional<tnsr::I<DataVector, Dim>>& dg_mesh_velocity,
56 : const ::Variables<variables>& cell_centered_flux_vars,
57 : const bool did_rollback, Args&&... args) {
58 : if (did_rollback or not ComputeOnlyOnRollback) {
59 : if (subcell_options.finite_difference_derivative_order() !=
60 : ::fd::DerivativeOrder::Two) {
61 : if (not cell_centered_fluxes->has_value()) {
62 : (*cell_centered_fluxes) =
63 : Variables<db::wrap_tags_in<::Tags::Flux, flux_variables,
64 : tmpl::size_t<Dim>, Fr>>{
65 : subcell_mesh.number_of_grid_points()};
66 : }
67 : FluxMutator::apply(
68 : make_not_null(&get<FluxTags>((*cell_centered_fluxes).value()))...,
69 : std::forward<Args>(args)...);
70 : if (dg_mesh_velocity.has_value()) {
71 : for (size_t i = 0; i < Dim; i++) {
72 : //
73 : // Project mesh velocity on face mesh. We only need the component
74 : // orthogonal to the face.
75 : const DataVector& cell_centered_mesh_velocity =
76 : evolution::dg::subcell::fd::project(
77 : dg_mesh_velocity.value().get(i), dg_mesh,
78 : subcell_mesh.extents(),
79 : i == 0 ? Spectral::Parity::Odd : Spectral::Parity::Even);
80 :
81 : tmpl::for_each<flux_variables>(
82 : [&cell_centered_flux_vars, &cell_centered_mesh_velocity,
83 : &cell_centered_fluxes, &i](auto tag_v) {
84 : using tag = tmpl::type_from<decltype(tag_v)>;
85 : using flux_tag =
86 : ::Tags::Flux<tag, tmpl::size_t<Dim>, Frame::Inertial>;
87 : using FluxTensor = typename flux_tag::type;
88 : const auto& var = get<tag>(cell_centered_flux_vars);
89 : auto& flux = get<flux_tag>(cell_centered_fluxes->value());
90 : for (size_t storage_index = 0; storage_index < var.size();
91 : ++storage_index) {
92 : const auto tensor_index =
93 : var.get_tensor_index(storage_index);
94 : const auto flux_storage_index =
95 : FluxTensor::get_storage_index(prepend(tensor_index, i));
96 : flux[flux_storage_index] -=
97 : cell_centered_mesh_velocity * var[storage_index];
98 : }
99 : });
100 : }
101 : }
102 : }
103 : }
104 : }
105 : };
106 : } // namespace evolution::dg::subcell::fd
|