1919#include " NumericalAlgorithms/Spectral/MaximumNumberOfPoints.hpp"
2020#include " NumericalAlgorithms/Spectral/Mesh.hpp"
2121#include " NumericalAlgorithms/Spectral/MinimumNumberOfPoints.hpp"
22+ #include " NumericalAlgorithms/Spectral/Parity.hpp"
2223#include " NumericalAlgorithms/Spectral/Quadrature.hpp"
2324#include " NumericalAlgorithms/Spectral/QuadratureWeights.hpp"
2425#include " Utilities/Algorithm.hpp"
3132#include " Utilities/StaticCache.hpp"
3233
3334namespace evolution ::dg::subcell::fd {
34- const Matrix& projection_matrix (
35- const Mesh<1 >& dg_mesh, const size_t subcell_extents,
36- const Spectral::Quadrature& subcell_quadrature) {
35+ const Matrix& projection_matrix (const Mesh<1 >& dg_mesh,
36+ const size_t subcell_extents,
37+ const Spectral::Quadrature& subcell_quadrature,
38+ const Spectral::Parity parity) {
3739 ASSERT (dg_mesh.basis (0 ) == Spectral::Basis::Legendre or
38- dg_mesh.basis (0 ) == Spectral::Basis::Cartoon,
39- " FD Subcell projection only supports Legendre or Cartoon bases right "
40+ dg_mesh.basis (0 ) == Spectral::Basis::Cartoon or
41+ dg_mesh.basis (0 ) == Spectral::Basis::ZernikeB1,
42+ " FD Subcell projection only supports Legendre, Cartoon, or ZernikeB1 "
43+ " bases right "
4044 " now but got basis "
4145 << dg_mesh.basis (0 ));
4246 ASSERT (subcell_quadrature == Spectral::Quadrature::FaceCentered or
@@ -46,7 +50,39 @@ const Matrix& projection_matrix(
4650 " subcell_quadrature option in projection_matrix should be "
4751 " FaceCentered, CellCentered, or a Cartoon quadrature, but got "
4852 << subcell_quadrature);
49- static const auto cache = make_static_cache<
53+ ASSERT (dg_mesh.basis (0 ) != Spectral::Basis::ZernikeB1 or
54+ parity != Spectral::Parity::Uninitialized,
55+ " Parity must be set when using ZernikeB1" );
56+
57+ const static auto zernike_b1_cache = make_static_cache<
58+ CacheRange<
59+ Spectral::minimum_number_of_points<
60+ Spectral::Basis::ZernikeB1,
61+ Spectral::Quadrature::GaussRadauUpper>,
62+ Spectral::maximum_number_of_points<Spectral::Basis::ZernikeB1> + 1 >,
63+ CacheRange<Spectral::minimum_number_of_points<
64+ Spectral::Basis::FiniteDifference,
65+ Spectral::Quadrature::CellCentered>,
66+ Spectral::maximum_number_of_points<
67+ Spectral::Basis::FiniteDifference> +
68+ 1 >,
69+ CacheEnumeration<Spectral::Quadrature, Spectral::Quadrature::CellCentered,
70+ Spectral::Quadrature::FaceCentered>,
71+ CacheEnumeration<Spectral::Parity, Spectral::Parity::Even,
72+ Spectral::Parity::Odd>>(
73+ [](const size_t local_num_dg_points, const size_t local_num_fd_points,
74+ const Spectral::Quadrature local_subcell_quadrature,
75+ const Spectral::Parity local_parity) {
76+ return Spectral::interpolation_matrix<
77+ Spectral::Basis::ZernikeB1, Spectral::Quadrature::GaussRadauUpper>(
78+ local_num_dg_points,
79+ Spectral::collocation_points (
80+ Mesh<1 >{local_num_fd_points, Spectral::Basis::FiniteDifference,
81+ local_subcell_quadrature}),
82+ local_parity);
83+ });
84+
85+ const static auto legendre_cache = make_static_cache<
5086 CacheRange<
5187 Spectral::minimum_number_of_points<
5288 Spectral::Basis::Legendre, Spectral::Quadrature::GaussLobatto>,
@@ -74,9 +110,13 @@ const Matrix& projection_matrix(
74110 if (dg_mesh.basis (0 ) == Spectral::Basis::Cartoon) {
75111 static const Matrix cartoon_matrix{1 , 1 , 1.0 };
76112 return cartoon_matrix;
113+ } else if (dg_mesh.basis (0 ) == Spectral::Basis::ZernikeB1) {
114+ return zernike_b1_cache (dg_mesh.extents (0 ), subcell_extents,
115+ subcell_quadrature, parity);
116+ } else {
117+ return legendre_cache (dg_mesh.extents (0 ), subcell_extents,
118+ dg_mesh.quadrature (0 ), subcell_quadrature);
77119 }
78- return cache (dg_mesh.extents (0 ), subcell_extents, dg_mesh.quadrature (0 ),
79- subcell_quadrature);
80120}
81121
82122namespace {
0 commit comments