From 5547837680680fe684325c31062cf858aa1aafad Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 20 May 2024 14:16:28 -0600 Subject: [PATCH] Add assertions that we can only combine elements defined on the same reference cell. --- include/deal.II/fe/fe_system.h | 11 +++++ include/deal.II/fe/fe_tools.templates.h | 55 ++++++++++++++++------- source/fe/fe_system.cc | 59 +++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 15 deletions(-) diff --git a/include/deal.II/fe/fe_system.h b/include/deal.II/fe/fe_system.h index 68c1c724db..4e3ad8d6ba 100644 --- a/include/deal.II/fe/fe_system.h +++ b/include/deal.II/fe/fe_system.h @@ -1428,6 +1428,17 @@ FESystem::FESystem( for (const auto &p : fe_systems) extract(p); + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } # endif diff --git a/include/deal.II/fe/fe_tools.templates.h b/include/deal.II/fe/fe_tools.templates.h index 33d25c70ad..effb9c803b 100644 --- a/include/deal.II/fe/fe_tools.templates.h +++ b/include/deal.II/fe/fe_tools.templates.h @@ -198,8 +198,18 @@ namespace FETools for (unsigned int m = 0; m < multiplicities[base]; ++m) block_indices.push_back(fes[base]->n_dofs_per_cell()); + const ReferenceCell reference_cell = fes.front()->reference_cell(); + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell]( + const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); return FiniteElementData(dpo, - fes.front()->reference_cell(), + reference_cell, (do_tensor_product ? multiplied_n_components : n_components), @@ -249,6 +259,17 @@ namespace FETools { AssertDimension(fes.size(), multiplicities.size()); + const ReferenceCell reference_cell = fes.front()->reference_cell(); + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell]( + const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + // first count the number of dofs and components that will emerge from the // given FEs unsigned int n_shape_functions = 0; @@ -268,8 +289,7 @@ namespace FETools // for each shape function, copy the flags from the base element to this // one, taking into account multiplicities, and other complications unsigned int total_index = 0; - for (const unsigned int vertex_number : - fes.front()->reference_cell().vertex_indices()) + for (const unsigned int vertex_number : reference_cell.vertex_indices()) { for (unsigned int base = 0; base < fes.size(); ++base) for (unsigned int m = 0; m < multiplicities[base]; ++m) @@ -289,8 +309,7 @@ namespace FETools } // 2. Lines - for (const unsigned int line_number : - fes.front()->reference_cell().line_indices()) + for (const unsigned int line_number : reference_cell.line_indices()) { for (unsigned int base = 0; base < fes.size(); ++base) for (unsigned int m = 0; m < multiplicities[base]; ++m) @@ -312,9 +331,7 @@ namespace FETools // 3. Quads for (unsigned int quad_number = 0; quad_number < - (dim == 2 ? - 1 : - (dim == 3 ? fes.front()->reference_cell().n_faces() : 0)); + (dim == 2 ? 1 : (dim == 3 ? reference_cell.n_faces() : 0)); ++quad_number) { for (unsigned int base = 0; base < fes.size(); ++base) @@ -409,6 +426,18 @@ namespace FETools fes.size() > 0, ExcMessage( "This function only makes sense if at least one FiniteElement is provided.")); + + const ReferenceCell reference_cell = fes.front()->reference_cell(); + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell]( + const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + // first count the number of dofs and components that will emerge from the // given FEs unsigned int n_shape_functions = 0; @@ -454,8 +483,7 @@ namespace FETools // to this one, taking into account multiplicities, multiple components in // base elements, and other complications unsigned int total_index = 0; - for (const unsigned int vertex_number : - fes.front()->reference_cell().vertex_indices()) + for (const unsigned int vertex_number : reference_cell.vertex_indices()) { unsigned int comp_start = 0; for (unsigned int base = 0; base < fes.size(); ++base) @@ -487,8 +515,7 @@ namespace FETools } // 2. Lines - for (const unsigned int line_number : - fes.front()->reference_cell().line_indices()) + for (const unsigned int line_number : reference_cell.line_indices()) { unsigned int comp_start = 0; for (unsigned int base = 0; base < fes.size(); ++base) @@ -522,9 +549,7 @@ namespace FETools // 3. Quads for (unsigned int quad_number = 0; quad_number < - (dim == 2 ? - 1 : - (dim == 3 ? fes.front()->reference_cell().n_faces() : 0)); + (dim == 2 ? 1 : (dim == 3 ? reference_cell.n_faces() : 0)); ++quad_number) { unsigned int comp_start = 0; diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index 6825732313..2162db2865 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -333,6 +333,18 @@ FESystem::FESystem(const FiniteElement &fe1, { const std::vector *> fes = {&fe1, &fe2}; const std::vector multiplicities = {n1, n2}; + + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } @@ -363,6 +375,18 @@ FESystem::FESystem(const FiniteElement &fe1, &fe2, &fe3}; const std::vector multiplicities = {n1, n2, n3}; + + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } @@ -396,6 +420,18 @@ FESystem::FESystem(const FiniteElement &fe1, &fe3, &fe4}; const std::vector multiplicities = {n1, n2, n3, n4}; + + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } @@ -430,6 +466,18 @@ FESystem::FESystem(const FiniteElement &fe1, const std::vector *> fes = { &fe1, &fe2, &fe3, &fe4, &fe5}; const std::vector multiplicities = {n1, n2, n3, n4, n5}; + + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } @@ -447,6 +495,17 @@ FESystem::FESystem( FETools::Compositing::compute_nonzero_components(fes, multiplicities)) , base_elements(count_nonzeros(multiplicities)) { + const ReferenceCell reference_cell = fes.front()->reference_cell(); + (void)reference_cell; + Assert(std::all_of(fes.begin(), + fes.end(), + [reference_cell](const FiniteElement *fe) { + return fe->reference_cell() == reference_cell; + }), + ExcMessage("You cannot combine finite elements defined on " + "different reference cells into a combined element " + "such as an FESystem or FE_Enriched object.")); + initialize(fes, multiplicities); } -- 2.39.5