From 5e966a4a76304270fa44985061a15fe7164bb5ab Mon Sep 17 00:00:00 2001 From: Denis Davydov Date: Mon, 24 Aug 2015 17:31:57 +0200 Subject: [PATCH] introduce a parameter to allow FE_Nothing dominate other FEs made other FEs to comply with the new FE_Nothing; corrected documentation of FE_Nothing::compare_for_face_domination() --- doc/news/changes.h | 9 +++++++++ include/deal.II/fe/fe_nothing.h | 29 ++++++++++++++++++++++++----- source/fe/fe_bernstein.cc | 15 +++++++++++---- source/fe/fe_face.cc | 30 ++++++++++++++++++++++-------- source/fe/fe_nedelec.cc | 15 +++++++++++++-- source/fe/fe_nothing.cc | 31 +++++++++++++++++++++++++++---- source/fe/fe_q_base.cc | 15 +++++++++++---- source/fe/fe_q_hierarchical.cc | 19 +++++++++++-------- source/fe/fe_q_iso_q1.cc | 15 +++++++++++---- source/fe/fe_trace.cc | 15 +++++++++++---- 10 files changed, 150 insertions(+), 43 deletions(-) diff --git a/doc/news/changes.h b/doc/news/changes.h index f78659debb..1828acb7af 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -235,6 +235,15 @@ inconvenience this causes.
    +
  1. New: Introduce an option for FE_Nothing to dominate any other FE. + Therefore at interfaces where, for example, a Q1 meets an FE_Nothing, + we will force the traces of the two functions to be the same. Because the + FE_Nothing encodes a space that is zero everywhere, this means that the Q1 + field will be forced to become zero at this interface. +
    + (Denis Davydov, 2015/08/31) +
  2. +
  3. New: Jacobian second and third derivatives are now computed by the mapping classes and can be accessed through FEValues in much the same way as the Jacobian and Jacobian gradient.
    diff --git a/include/deal.II/fe/fe_nothing.h b/include/deal.II/fe/fe_nothing.h index 91b8212547..65bf2297aa 100644 --- a/include/deal.II/fe/fe_nothing.h +++ b/include/deal.II/fe/fe_nothing.h @@ -82,10 +82,18 @@ class FE_Nothing : public FiniteElement public: /** - * Constructor. Argument denotes the number of components to give this + * Constructor. First argument denotes the number of components to give this * finite element (default = 1). + * + * Second argument decides whether FE_Nothing + * will dominate any other FE in compare_for_face_domination() (default = false). + * Therefore at interfaces where, for example, a Q1 meets an FE_Nothing, + * we will force the traces of the two functions to be the same. Because the + * FE_Nothing encodes a space that is zero everywhere, this means that the Q1 + * field will be forced to become zero at this interface. */ - FE_Nothing (const unsigned int n_components = 1); + FE_Nothing (const unsigned int n_components = 1, + const bool dominate = false); /** * A sort of virtual copy constructor. Some places in the library, for @@ -205,9 +213,10 @@ public: * particular the * @ref hp_paper "hp paper". * - * In the current case, this element is always assumed to dominate, unless - * it is also of type FE_Nothing(). In that situation, either element can - * dominate. + * In the current case, this element is assumed to dominate if the second + * argument in the constructor @p dominate is true. When this argument is false + * and @p fe_other is also of type FE_Nothing(), either element can dominate. + * Otherwise there are no_requirements. */ virtual FiniteElementDomination::Domination @@ -261,6 +270,16 @@ public: const unsigned int index, FullMatrix &interpolation_matrix) const; + /** + * @return true if the FE dominates any other. + */ + bool is_dominating() const; + +private: + /** + * If true, this element will dominate any other apart from itself in compare_for_face_domination(); + */ + const bool dominate; }; diff --git a/source/fe/fe_bernstein.cc b/source/fe/fe_bernstein.cc index 72bb8a5918..fdba3c32af 100644 --- a/source/fe/fe_bernstein.cc +++ b/source/fe/fe_bernstein.cc @@ -236,11 +236,18 @@ FE_Bernstein::compare_for_face_domination (const FiniteElement*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_face.cc b/source/fe/fe_face.cc index b3d9e2db48..9732fab950 100644 --- a/source/fe/fe_face.cc +++ b/source/fe/fe_face.cc @@ -276,11 +276,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); @@ -608,11 +615,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_nedelec.cc b/source/fe/fe_nedelec.cc index ac21bd9e8f..8934aaad24 100644 --- a/source/fe/fe_nedelec.cc +++ b/source/fe/fe_nedelec.cc @@ -2296,8 +2296,9 @@ FE_Nedelec::compare_for_face_domination (const FiniteElement &fe_other else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { + // TODO: ??? // the FE_Nothing has no // degrees of // freedom. nevertheless, we @@ -2308,7 +2309,17 @@ FE_Nedelec::compare_for_face_domination (const FiniteElement &fe_other // and rather allow the // function to be discontinuous // along the interface - return FiniteElementDomination::other_element_dominates; +// return FiniteElementDomination::other_element_dominates; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_nothing.cc b/source/fe/fe_nothing.cc index fb3ea4497c..d122101c4d 100644 --- a/source/fe/fe_nothing.cc +++ b/source/fe/fe_nothing.cc @@ -28,14 +28,16 @@ namespace template -FE_Nothing::FE_Nothing (const unsigned int n_components) +FE_Nothing::FE_Nothing (const unsigned int n_components, + const bool dominate) : FiniteElement (FiniteElementData(std::vector(dim+1,0), n_components, 0, FiniteElementData::unknown), std::vector(), - std::vector() ) + std::vector() ), + dominate(dominate) { // in most other elements we have to set up all sorts of stuff // here. there isn't much that we have to do here; in particular, @@ -162,13 +164,34 @@ fill_fe_subface_values (const Mapping & /*mapping*/, // leave data fields empty } +template +bool +FE_Nothing::is_dominating() const +{ + return dominate; +} + template FiniteElementDomination::Domination FE_Nothing :: -compare_for_face_domination (const FiniteElement &) const +compare_for_face_domination (const FiniteElement &fe) const { - return FiniteElementDomination::no_requirements; + // if FE_Nothing does not dominate, there are no requirements + if (!dominate) + { + return FiniteElementDomination::no_requirements; + } + // if it does and the other is FE_Nothing, either can dominate + else if (dynamic_cast*>(&fe) != 0) + { + return FiniteElementDomination::either_element_can_dominate; + } + // otherwise we dominate whatever fe is provided + else + { + return FiniteElementDomination::this_element_dominates; + } } diff --git a/source/fe/fe_q_base.cc b/source/fe/fe_q_base.cc index f6eb9fdbdc..3c2b3d39e2 100644 --- a/source/fe/fe_q_base.cc +++ b/source/fe/fe_q_base.cc @@ -859,11 +859,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_q_hierarchical.cc b/source/fe/fe_q_hierarchical.cc index 98b151c4e4..a3a7641eaa 100644 --- a/source/fe/fe_q_hierarchical.cc +++ b/source/fe/fe_q_hierarchical.cc @@ -364,15 +364,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_q_iso_q1.cc b/source/fe/fe_q_iso_q1.cc index 5a154c4dde..35747b15e6 100644 --- a/source/fe/fe_q_iso_q1.cc +++ b/source/fe/fe_q_iso_q1.cc @@ -98,11 +98,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::neither_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); diff --git a/source/fe/fe_trace.cc b/source/fe/fe_trace.cc index 3d68c93ed0..87ed272a22 100644 --- a/source/fe/fe_trace.cc +++ b/source/fe/fe_trace.cc @@ -156,11 +156,18 @@ compare_for_face_domination (const FiniteElement &fe_other) const else return FiniteElementDomination::other_element_dominates; } - else if (dynamic_cast*>(&fe_other) != 0) + else if (const FE_Nothing *fe_nothing = dynamic_cast*>(&fe_other)) { - // 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; + 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; + } } Assert (false, ExcNotImplemented()); -- 2.39.5