From 9282a1b949f66d9b34049198137cd84bd042285e Mon Sep 17 00:00:00 2001 From: Marc Fehling Date: Wed, 13 Jan 2021 20:02:19 -0700 Subject: [PATCH] simplex: compare_for_domination --- source/fe/fe_dgq.cc | 12 ++ source/fe/fe_q.cc | 33 ++++++ source/simplex/fe_lib.cc | 241 ++++++++++++++++++++++++++++++++++----- 3 files changed, 256 insertions(+), 30 deletions(-) diff --git a/source/fe/fe_dgq.cc b/source/fe/fe_dgq.cc index d5ff7a977a..f75719806e 100644 --- a/source/fe/fe_dgq.cc +++ b/source/fe/fe_dgq.cc @@ -30,6 +30,8 @@ #include +#include + #include #include #include @@ -694,6 +696,16 @@ FE_DGQ::compare_for_domination( else return FiniteElementDomination::other_element_dominates; } + else if (const Simplex::FE_DGP *fe_dgp_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_dgp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_dgp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } else if (const FE_Nothing *fe_nothing = dynamic_cast *>(&fe_other)) { diff --git a/source/fe/fe_q.cc b/source/fe/fe_q.cc index b851a3e5a7..607e267e3b 100644 --- a/source/fe/fe_q.cc +++ b/source/fe/fe_q.cc @@ -22,6 +22,8 @@ #include +#include + #include #include #include @@ -206,6 +208,37 @@ FE_Q::compare_for_domination( else return FiniteElementDomination::other_element_dominates; } + else if (const Simplex::FE_P *fe_p_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_p_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_p_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const Simplex::FE_WedgeP *fe_wp_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_wp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_wp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const Simplex::FE_PyramidP *fe_pp_other = + dynamic_cast *>( + &fe_other)) + { + if (this->degree < fe_pp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_pp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } else if (const FE_Nothing *fe_nothing = dynamic_cast *>(&fe_other)) { diff --git a/source/simplex/fe_lib.cc b/source/simplex/fe_lib.cc index 78bfcdd0f0..1327c9f977 100644 --- a/source/simplex/fe_lib.cc +++ b/source/simplex/fe_lib.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -434,15 +435,55 @@ namespace Simplex const FiniteElement &fe_other, const unsigned int codim) const { - (void)fe_other; - (void)codim; - - Assert((dynamic_cast *>(&fe_other)), - ExcNotImplemented()); - AssertDimension(dim, 2); - AssertDimension(this->degree, fe_other.tensor_degree()); + Assert(codim <= dim, ExcImpossibleInDim(dim)); + + // vertex/line/face domination + // (if fe_other is derived from FE_DGP) + // ------------------------------------ + if (codim > 0) + if (dynamic_cast *>(&fe_other) != nullptr) + // there are no requirements between continuous and discontinuous + // elements + return FiniteElementDomination::no_requirements; + + // vertex/line/face domination + // (if fe_other is not derived from FE_DGP) + // & cell domination + // ---------------------------------------- + if (const FE_P *fe_p_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_p_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_p_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Q *fe_q_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_q_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_q_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Nothing *fe_nothing = + dynamic_cast *>(&fe_other)) + { + if (fe_nothing->is_dominating()) + return FiniteElementDomination::other_element_dominates; + else + // the FE_Nothing has no degrees of freedom and it is typically used + // in a context where we don't require any continuity along the + // interface + return FiniteElementDomination::no_requirements; + } - return FiniteElementDomination::either_element_can_dominate; + Assert(false, ExcNotImplemented()); + return FiniteElementDomination::neither_element_dominates; } @@ -521,15 +562,52 @@ namespace Simplex const FiniteElement &fe_other, const unsigned int codim) const { - (void)fe_other; - (void)codim; - - Assert((dynamic_cast *>(&fe_other)), - ExcNotImplemented()); - AssertDimension(dim, 2); - AssertDimension(this->degree, fe_other.tensor_degree()); + Assert(codim <= dim, ExcImpossibleInDim(dim)); + + // vertex/line/face domination + // --------------------------- + if (codim > 0) + // this is a discontinuous element, so by definition there will + // be no constraints wherever this element comes together with + // any other kind of element + return FiniteElementDomination::no_requirements; + + // cell domination + // --------------- + if (const FE_DGP *fe_dgp_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_dgp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_dgp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_DGQ *fe_dgq_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_dgq_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_dgq_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Nothing *fe_nothing = + dynamic_cast *>(&fe_other)) + { + if (fe_nothing->is_dominating()) + return FiniteElementDomination::other_element_dominates; + else + // the FE_Nothing has no degrees of freedom and it is typically used + // in a context where we don't require any continuity along the + // interface + return FiniteElementDomination::no_requirements; + } - return FiniteElementDomination::either_element_can_dominate; + Assert(false, ExcNotImplemented()); + return FiniteElementDomination::neither_element_dominates; } @@ -630,14 +708,66 @@ namespace Simplex const FiniteElement &fe_other, const unsigned int codim) const { - (void)fe_other; - (void)codim; - - Assert((dynamic_cast *>(&fe_other)) || - (dynamic_cast *>(&fe_other)), - ExcNotImplemented()); + Assert(codim <= dim, ExcImpossibleInDim(dim)); + + // vertex/line/face domination + // (if fe_other is derived from FE_DGP) + // ------------------------------------ + if (codim > 0) + if (dynamic_cast *>(&fe_other) != nullptr) + // there are no requirements between continuous and discontinuous + // elements + return FiniteElementDomination::no_requirements; + + + // vertex/line/face domination + // (if fe_other is not derived from FE_DGP) + // & cell domination + // ---------------------------------------- + if (const FE_WedgeP *fe_wp_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_wp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_wp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_P *fe_p_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_p_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_p_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Q *fe_q_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_q_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_q_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Nothing *fe_nothing = + dynamic_cast *>(&fe_other)) + { + if (fe_nothing->is_dominating()) + return FiniteElementDomination::other_element_dominates; + else + // the FE_Nothing has no degrees of freedom and it is typically used + // in a context where we don't require any continuity along the + // interface + return FiniteElementDomination::no_requirements; + } - return FiniteElementDomination::this_element_dominates; + Assert(false, ExcNotImplemented()); + return FiniteElementDomination::neither_element_dominates; } @@ -812,14 +942,65 @@ namespace Simplex const FiniteElement &fe_other, const unsigned int codim) const { - (void)fe_other; - (void)codim; - - Assert((dynamic_cast *>(&fe_other)) || - (dynamic_cast *>(&fe_other)), - ExcNotImplemented()); + Assert(codim <= dim, ExcImpossibleInDim(dim)); + + // vertex/line/face domination + // (if fe_other is derived from FE_DGP) + // ------------------------------------ + if (codim > 0) + if (dynamic_cast *>(&fe_other) != nullptr) + // there are no requirements between continuous and discontinuous + // elements + return FiniteElementDomination::no_requirements; + + // vertex/line/face domination + // (if fe_other is not derived from FE_DGP) + // & cell domination + // ---------------------------------------- + if (const FE_PyramidP *fe_pp_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_pp_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_pp_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_P *fe_p_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_p_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_p_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Q *fe_q_other = + dynamic_cast *>(&fe_other)) + { + if (this->degree < fe_q_other->degree) + return FiniteElementDomination::this_element_dominates; + else if (this->degree == fe_q_other->degree) + return FiniteElementDomination::either_element_can_dominate; + else + return FiniteElementDomination::other_element_dominates; + } + else if (const FE_Nothing *fe_nothing = + dynamic_cast *>(&fe_other)) + { + if (fe_nothing->is_dominating()) + return FiniteElementDomination::other_element_dominates; + else + // the FE_Nothing has no degrees of freedom and it is typically used + // in a context where we don't require any continuity along the + // interface + return FiniteElementDomination::no_requirements; + } - return FiniteElementDomination::this_element_dominates; + Assert(false, ExcNotImplemented()); + return FiniteElementDomination::neither_element_dominates; } -- 2.39.5