From: kanschat Date: Mon, 24 Jun 2013 09:45:06 +0000 (+0000) Subject: total ordering across processors X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da3975bce9ba1bae8339c5b739ad0e95dbb26385;p=dealii-svn.git total ordering across processors git-svn-id: https://svn.dealii.org/trunk@29864 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index efcb9bcf2a..fb6ef1dbb1 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -147,6 +147,13 @@ this function.
    +
  1. New: TriaRawIterator::operator < (TriaRawIterator&) now implements a total ordering +relation for cells even on distributed::parallel::Triangulation across processors. +Additionally, TriaRawAccessor and CellAccessor now have an ordering relation. +
    +(Guido Kanschat, 2013/06/24) +
  2. +
  3. New: CellAccessor::id() that returns a unique CellId that also works in parallel computations (where level and index is not useful). diff --git a/deal.II/include/deal.II/grid/tria_accessor.h b/deal.II/include/deal.II/grid/tria_accessor.h index 6bb84f8646..750e4738ff 100644 --- a/deal.II/include/deal.II/grid/tria_accessor.h +++ b/deal.II/include/deal.II/grid/tria_accessor.h @@ -345,6 +345,14 @@ protected: * object with exactly the same data. */ TriaAccessorBase &operator = (const TriaAccessorBase &); + + /** + * Ordering of accessors. If #structure_dimension is less than + * #dimension, we simply compare the index of such an object. If + * #structure_dimension equals #dimension, we compare the level() + * first, and the index() only if levels are equal. + */ + bool operator < (const TriaAccessorBase& other) const; protected: /** @@ -2848,6 +2856,16 @@ public: * for more information. */ bool active () const; + + /** + * Ordering of accessors. This function implements a total ordering + * of cells even on a parallel::distributed::Triangulation. This + * function first compares level_subdomain_id(). If these are equal, + * and both cells are active, it compares subdomain_id(). If this is + * inconclusive, TriaAccessorBase::operator < () is called. + */ + bool operator < (const CellAccessor& other) const; + /** * Return whether this cell is owned by the current processor diff --git a/deal.II/include/deal.II/grid/tria_accessor.templates.h b/deal.II/include/deal.II/grid/tria_accessor.templates.h index 2e4d9462ea..b712d5f072 100644 --- a/deal.II/include/deal.II/grid/tria_accessor.templates.h +++ b/deal.II/include/deal.II/grid/tria_accessor.templates.h @@ -136,6 +136,22 @@ TriaAccessorBase::operator != (const TriaAccessorBase +inline +bool +TriaAccessorBase::operator < (const TriaAccessorBase &other) const +{ + Assert (tria == other.tria, TriaAccessorExceptions::ExcCantCompareIterators()); + + if (present_level != other.present_level) + return (present_level < other.present_level); + + return (present_index < other.present_index); + +} + + + template inline int @@ -2963,6 +2979,26 @@ CellAccessor::neighbor_face_no (const unsigned int neighbor) const return neighbor_of_coarser_neighbor(neighbor).first; } + +template +inline +bool +CellAccessor::operator < (const CellAccessor &other) const +{ + Assert (this->tria == other.tria, TriaAccessorExceptions::ExcCantCompareIterators()); + + if (level_subdomain_id() != other.level_subdomain_id()) + return (level_subdomain_id() < other.level_subdomain_id()); + + if (active() && other.active() && + (subdomain_id() != other.subdomain_id())) + return (subdomain_id() < other.subdomain_id()); + + return TriaAccessorBase::operator < (other); +} + + + DEAL_II_NAMESPACE_CLOSE #endif diff --git a/deal.II/include/deal.II/grid/tria_iterator.h b/deal.II/include/deal.II/grid/tria_iterator.h index dc75dd1242..eb97f7f5ee 100644 --- a/deal.II/include/deal.II/grid/tria_iterator.h +++ b/deal.II/include/deal.II/grid/tria_iterator.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // $Id$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012, 2013 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -436,21 +436,36 @@ public: bool operator != (const TriaRawIterator &) const; /** - * Offer a weak ordering of iterators, - * which is needed to make @p maps with - * iterators being keys. An iterator - * pointing to an element @p a is - * less than another iterator pointing - * to an element @p b if - * level(a)Accessor::structure_dimension < + * Accessor::dimension, we simply compare the index of such an + * object. This consitutes an ordering of the elements of same + * dimension on a mesh on a single process. For a distributed mesh, + * the result of the ordering relation between faces across + * processes is not defined, but most likely irrelevant. + * + * For cells, there is a total ordering even in a + * distributed::parallel::Triangulation. The ordering is lexicographic + * according to the following hierarchy (in the sense, that the next + * test is only applied if the previous was inconclusive): + * + *
      + *
    1. The past-the-end iterator is always ordered last. Two + * past-the-end iterators rank the same, thus false is returned in + * that case.
    2. + * + *
    3. The level subdomain id
    4. + *
    5. If both cells are active, the subdomain id.
    6. + *
    7. The level of the cell.
    8. + *
    9. The index of a cell inside the level.
    10. + *
    */ bool operator < (const TriaRawIterator &) const; @@ -1155,39 +1170,21 @@ TriaRawIterator::state () const template inline bool -TriaRawIterator::operator < (const TriaRawIterator &i) const +TriaRawIterator::operator < (const TriaRawIterator &other) const { - Assert (Accessor::structure_dimension!=Accessor::dimension || - state() != IteratorState::invalid, - ExcDereferenceInvalidCell(accessor)); - Assert (Accessor::structure_dimension==Accessor::dimension || - state() != IteratorState::invalid, - ExcDereferenceInvalidObject(accessor)); - - Assert (Accessor::structure_dimension!=Accessor::dimension || - i.state() != IteratorState::invalid, - ExcDereferenceInvalidCell(i.accessor)); - Assert (Accessor::structure_dimension==Accessor::dimension || - i.state() != IteratorState::invalid, - ExcDereferenceInvalidObject(i.accessor)); + Assert (state() != IteratorState::invalid, ExcDereferenceInvalidObject(accessor)); + Assert (other.state() != IteratorState::invalid, ExcDereferenceInvalidObject(other.accessor)); - Assert (&accessor.get_triangulation() == &i.accessor.get_triangulation(), + Assert (&accessor.get_triangulation() == &other.accessor.get_triangulation(), ExcInvalidComparison()); - - if (Accessor::structure_dimension==Accessor::dimension) - return ((((accessor.level() < i.accessor.level()) || - ((accessor.level() == i.accessor.level()) && - (accessor.index() < i.accessor.index())) ) && - (state()==IteratorState::valid) && - (i.state()==IteratorState::valid) ) || - ((state()==IteratorState::valid) && - (i.state()==IteratorState::past_the_end))); - else - return ((((accessor.index() < i.accessor.index()) ) && - (state()==IteratorState::valid) && - (i.state()==IteratorState::valid) ) || - ((state()==IteratorState::valid) && - (i.state()==IteratorState::past_the_end))); + + // Deal with iterators past end + if (state()==IteratorState::past_the_end) + return false; + if (other.state()==IteratorState::past_the_end) + return true; + + return ((**this) < (*other)); }