diff --git a/src/scheme/PolynomialReconstruction.cpp b/src/scheme/PolynomialReconstruction.cpp index 941682b453c6cf13cd4774c4ce48968f142dda22..eea42b65b93e20d03a4db2857ba1f2e32447d43f 100644 --- a/src/scheme/PolynomialReconstruction.cpp +++ b/src/scheme/PolynomialReconstruction.cpp @@ -9,6 +9,7 @@ #include <analysis/QuadratureFormula.hpp> #include <analysis/QuadratureManager.hpp> #include <geometry/CubeTransformation.hpp> +#include <geometry/LineCubicTransformation.hpp> #include <geometry/LineParabolicTransformation.hpp> #include <geometry/LineTransformation.hpp> #include <geometry/PrismTransformation.hpp> @@ -443,10 +444,10 @@ _computeEjkBoundaryMean(const QuadratureFormula<1>& quadrature, } } -template <> +template <typename ConformTransformationT> void _computeEjkBoundaryMean(const QuadratureFormula<1>& quadrature, - const LineParabolicTransformation<2>& T, + const ConformTransformationT& T, const TinyVector<2>& Xj, const double Vi, const size_t degree, @@ -541,14 +542,39 @@ _computeEjkMeanByBoundary(const MeshType& mesh, const FaceId face_id = cell_face_list[i_face]; auto face_node_list = face_to_node_matrix[face_id]; - if (is_reversed) { - const LineParabolicTransformation<2> T{xr[face_node_list[1]], xl[face_id][0], xr[face_node_list[0]]}; - _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, - inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); - } else { - const LineParabolicTransformation<2> T{xr[face_node_list[0]], xl[face_id][0], xr[face_node_list[1]]}; - _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, - inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); +#warning rework + switch (mesh.degree()) { + case 2: { + if (is_reversed) { + const LineParabolicTransformation<2> T{xr[face_node_list[1]], xl[face_id][0], xr[face_node_list[0]]}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } else { + const LineParabolicTransformation<2> T{xr[face_node_list[0]], xl[face_id][0], xr[face_node_list[1]]}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } + break; + } + case 3: { + if (is_reversed) { + const LineCubicTransformation<2> T{xr[face_node_list[1]], xl[face_id][1], xl[face_id][0], + xr[face_node_list[0]]}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } else { + const LineCubicTransformation<2> T{xr[face_node_list[0]], xl[face_id][0], xl[face_id][1], + xr[face_node_list[1]]}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } + break; + } + default: { + std::ostringstream error_msg; + error_msg << "reconstruction on meshes of degree " << mesh.degree(); + throw NotImplementedError(error_msg.str()); + } } } } @@ -615,18 +641,45 @@ _computeEjkMeanByBoundaryInSymmetricCell(const MeshType& mesh, const FaceId face_id = cell_face_list[i_face]; auto face_node_list = face_to_node_matrix[face_id]; - const auto x0 = symmetrize_coordinates(origin, normal, xr[face_node_list[1]]); - const auto x1 = symmetrize_coordinates(origin, normal, xl[face_id][0]); - const auto x2 = symmetrize_coordinates(origin, normal, xr[face_node_list[0]]); + switch (mesh.degree()) { + case 2: { + const auto x0 = symmetrize_coordinates(origin, normal, xr[face_node_list[1]]); + const auto x1 = symmetrize_coordinates(origin, normal, xl[face_id][0]); + const auto x2 = symmetrize_coordinates(origin, normal, xr[face_node_list[0]]); - if (is_reversed) { - const LineParabolicTransformation<2> T{x2, x1, x0}; - _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, - inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); - } else { - const LineParabolicTransformation<2> T{x0, x1, x2}; - _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, - inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + if (is_reversed) { + const LineParabolicTransformation<2> T{x2, x1, x0}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } else { + const LineParabolicTransformation<2> T{x0, x1, x2}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } + break; + } + case 3: { + const auto x0 = symmetrize_coordinates(origin, normal, xr[face_node_list[1]]); + const auto x1 = symmetrize_coordinates(origin, normal, xl[face_id][1]); + const auto x2 = symmetrize_coordinates(origin, normal, xl[face_id][0]); + const auto x3 = symmetrize_coordinates(origin, normal, xr[face_node_list[0]]); + + if (is_reversed) { + const LineCubicTransformation<2> T{x3, x2, x1, x0}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } else { + const LineCubicTransformation<2> T{x0, x1, x2, x3}; + _computeEjkBoundaryMean(quadrature, T, Xj, Vi[cell_id], degree, basis_dimension, + inv_Vj_alpha_p_1_wq_X_prime_orth_ek, mean_of_ejk); + } + break; + } + default: { + std::ostringstream error_msg; + error_msg << "reconstruction on meshes of degree " << mesh.degree(); + throw NotImplementedError(error_msg.str()); + } } } } diff --git a/src/scheme/VariationalSolver.cpp b/src/scheme/VariationalSolver.cpp index 34f946900ae14ceafb9fdc4720cbd492c3157d98..d609cb5c2cc0e1b82e932e63b2e438897296e588 100644 --- a/src/scheme/VariationalSolver.cpp +++ b/src/scheme/VariationalSolver.cpp @@ -599,6 +599,10 @@ class VariationalSolverHandler::VariationalSolver final : public VariationalSolv LinearSolver solver; solver.solveLocalSystem(A, U, b); + + auto error = b - A * U; + std::cout << "CG REAL L2 ERROR: " << rang::fgB::yellow << std::sqrt(dot(error, error)) << rang::fg::reset << '\n'; + this->_forcebcBoundaryConditions(bc_list, U); const auto& cell_to_face_matrix = p_mesh->connectivity().cellToFaceMatrix();