From: Wolfgang Bangerth Date: Tue, 20 Aug 2024 23:41:45 +0000 (-0600) Subject: Reintroduce a fast path for FESystem::compare_for_domination(). X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1de632b6e139911cb6d8b796fcd04ead32a3cee2;p=dealii.git Reintroduce a fast path for FESystem::compare_for_domination(). --- diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index c711de1344..13d6869bba 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -2432,29 +2432,63 @@ FESystem::compare_for_domination( FiniteElementDomination::Domination domination = FiniteElementDomination::no_requirements; - for (unsigned int c = 0; c < this->n_components(); ++c) + // If the two elements have the same number of base elements, + // and the base elements have the same multiplicities, we can + // get away with only comparing each of the bases: + if ((this->n_base_elements() == fe_sys_other->n_base_elements()) && + // Use a lambda function to test whether all base elements have + // the same multiplicity: + [&]() { + for (unsigned int b = 0; b < this->n_base_elements(); ++b) + if (this->element_multiplicity(b) != + fe_sys_other->element_multiplicity(b)) + return false; + return true; + }()) { - const unsigned int base_element_index_in_fe_sys_this = - this->component_to_base_index(c).first; - const unsigned int base_element_index_in_fe_sys_other = - fe_sys_other->component_to_base_index(c).first; - - Assert(this->base_element(base_element_index_in_fe_sys_this) - .n_components() == - fe_sys_other - ->base_element(base_element_index_in_fe_sys_other) - .n_components(), - ExcNotImplemented()); - - // for this pair of base elements, check who dominates and combine - // with previous result - const FiniteElementDomination::Domination base_domination = - (this->base_element(base_element_index_in_fe_sys_this) - .compare_for_domination(fe_sys_other->base_element( - base_element_index_in_fe_sys_other), - codim)); - - domination = domination & base_domination; + for (unsigned int b = 0; b < this->n_base_elements(); ++b) + { + Assert(this->base_element(b).n_components() == + fe_sys_other->base_element(b).n_components(), + ExcNotImplemented()); + // for this pair of base elements, check who dominates and combine + // with previous result + const FiniteElementDomination::Domination base_domination = + (this->base_element(b).compare_for_domination( + fe_sys_other->base_element(b), codim)); + + domination = domination & base_domination; + } + } + else + // The two elements do not line up either with their numbers of + // base elements, or with the multiplicities of the base elements + { + for (unsigned int c = 0; c < this->n_components(); ++c) + { + const unsigned int base_element_index_in_fe_sys_this = + this->component_to_base_index(c).first; + const unsigned int base_element_index_in_fe_sys_other = + fe_sys_other->component_to_base_index(c).first; + + Assert(this->base_element(base_element_index_in_fe_sys_this) + .n_components() == + fe_sys_other + ->base_element(base_element_index_in_fe_sys_other) + .n_components(), + ExcNotImplemented()); + + // for this pair of base elements, check who dominates and combine + // with previous result + const FiniteElementDomination::Domination base_domination = + (this->base_element(base_element_index_in_fe_sys_this) + .compare_for_domination( + fe_sys_other->base_element( + base_element_index_in_fe_sys_other), + codim)); + + domination = domination & base_domination; + } } return domination;