diff --git a/dune/fufem/functiontools/basisidmapper.hh b/dune/fufem/functiontools/basisidmapper.hh index 6958939febc8e2bbb552f7a6b7cd31530fcaa6bc..590229b9d49cef007175fef7927cc3a6eb8b5fef 100644 --- a/dune/fufem/functiontools/basisidmapper.hh +++ b/dune/fufem/functiontools/basisidmapper.hh @@ -72,6 +72,7 @@ class BasisIdMapper typedef typename B::LocalFiniteElement LocalFiniteElement; const GridView& gridview = basis_.getGridView(); + const auto& idSet = gridview_.grid().globalIdSet(); storedFEs_.clear(); elementToFE_.clear(); @@ -79,18 +80,8 @@ class BasisIdMapper indices_[i].clear(); for (auto&& e : elements(gridview)) { - - const LocalFiniteElement& fe = basis_.getLocalFiniteElement(e); - - // store local finite element if not already done - // If we have a base class with virtual functions - // we must use the 'virtual copy constructor' hack - // using virtual clone() methods for ALL local FEs - typename StoredFEMap::const_iterator storedFEIt = storedFEs_.find(&fe); - if (storedFEIt == storedFEs_.end()) - storedFEs_[&fe] = SmartFEPointer(fe.clone()); - - elementToFE_[gridview_.grid().globalIdSet().id(e)] = &fe; + const IdType id = idSet.id(e); + const LocalFiniteElement& fe = storeElement(id, e); // if elements might vanish we need to store all elements up to level 0 if (allowVanishingElements_) @@ -138,27 +129,47 @@ class BasisIdMapper private: + void storeFiniteElement(const LocalFiniteElement& fe) + { + // store local finite element if not already done + // If we have a base class with virtual functions + // we must use the 'virtual copy constructor' hack + // using virtual clone() methods for ALL local FEs + if (storedFEs_.count(&fe) == 0) + storedFEs_.emplace(&fe, SmartFEPointer(fe.clone())); + } - void storeParents(Element e) + const LocalFiniteElement& storeElement(const IdType& elementId, const Element& element) { + const LocalFiniteElement& fe = basis_.getLocalFiniteElement(element); + storeFiniteElement(fe); + elementToFE_[elementId] = &fe; + return fe; + } - while(e.level() > 0) - { + void storeParents(const Element& element) + { + const auto& idSet = gridview_.grid().globalIdSet(); + + Element e = element; + IdType prevId = idSet.id(element); + while (e.level() > 0) { e = e.father(); - const IdType id = gridview_.grid().globalIdSet().id(e); + const IdType id = idSet.id(e); - // if father was already added we can stop - if (elementToFE_.find(id) != elementToFE_.end()) + // Element is its own father. This can happen when UGGrid is used + // with the setRefinementType(UGGrid::COPY) option. + // We can skip this element, but still might have to visit "real" + // father elements. + if (id == prevId) continue; - const LocalFiniteElement& fe = basis_.getLocalFiniteElement(e); - - // store local finite element if not already done - typename StoredFEMap::const_iterator storedFEIt = storedFEs_.find(&fe); - if (storedFEIt == storedFEs_.end()) - storedFEs_[&fe] = SmartFEPointer(fe.clone()); + // Father was already added. No need to visit rest of the hierarchy. + if (elementToFE_.count(id) != 0) + break; - elementToFE_[id] = &fe; + prevId = id; + storeElement(id, element); } }