]> https://gitweb.dealii.org/ - dealii.git/commitdiff
add CellId CellAccessor::id()
authorTimo Heister <timo.heister@gmail.com>
Mon, 24 Jun 2013 08:25:48 +0000 (08:25 +0000)
committerTimo Heister <timo.heister@gmail.com>
Mon, 24 Jun 2013 08:25:48 +0000 (08:25 +0000)
git-svn-id: https://svn.dealii.org/trunk@29859 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/changes.h
deal.II/include/deal.II/grid/cell_id.h [new file with mode: 0644]
deal.II/include/deal.II/grid/tria_accessor.h

index 621adb69620ba1ab2caa2a020fe8f986aaa59aa9..efcb9bcf2a0adaf968d28e5ac60a91feb2b7ca7b 100644 (file)
@@ -147,6 +147,13 @@ this function.
 
 <ol>
 
+<li> New: CellAccessor::id() that returns a unique CellId that
+also works in parallel computations (where level and index is not
+useful).
+<br>
+(Timo Heister, 2013/06/24)
+</li>
+
 <li> New: added ConstantTensorFunction<rank, dim> and ZeroTensorFunction<rank, dim> to provide
 a tensor valued analogue to ConstantFunction and ZeroFunction.
 <br>
diff --git a/deal.II/include/deal.II/grid/cell_id.h b/deal.II/include/deal.II/grid/cell_id.h
new file mode 100644 (file)
index 0000000..5dee607
--- /dev/null
@@ -0,0 +1,118 @@
+//---------------------------------------------------------------------------
+//    $Id: tria_accessor.h 29697 2013-05-31 21:53:39Z bangerth $
+//
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//---------------------------------------------------------------------------
+#ifndef __deal2__cell_id_h
+#define __deal2__cell_id_h
+
+DEAL_II_NAMESPACE_OPEN
+
+
+/**
+ * A class to represent a unique ID for a cell in a Triangulation.
+ * This class stores the index of the coarse cell together with the
+ * information on how to reach the cell from that coarse cell (which
+ * child index to take on each level). The internal representation
+ * is not exposed on purpose.
+ *
+ * TODO: does it make sense to implement a more efficient representation
+ * (internally and/or as a string)? If yes, something like a 64bit int
+ * as in p4est would be a good option.
+ */
+class CellId
+{
+public:
+  /**
+   * construct CellId with a given coarse_cell_index and list of child indices
+   */
+  explicit CellId(unsigned int coarse_cell_id_, std::vector<unsigned char> id_)
+  : coarse_cell_id(coarse_cell_id_), id(id_)
+  {}
+
+  /**
+   * construct an empty CellId.
+   */
+  CellId()
+  : coarse_cell_id(-1)
+  {}
+
+  /**
+   * compare two CellIds
+   */
+  bool operator== (const CellId & other) const;
+
+  /**
+   * compare two CellIds
+   */
+  bool operator!= (const CellId & other) const;
+
+
+  friend std::istream& operator>> (std::istream& is, CellId& cid);
+  friend std::ostream& operator<< (std::ostream& os, const CellId& cid);
+private:
+  unsigned int coarse_cell_id;
+  std::vector<unsigned char> id;
+};
+
+/**
+ * output CellId into a stream
+ */
+inline std::ostream& operator<< (std::ostream& os, const CellId& cid)
+{
+  os << cid.coarse_cell_id << '_' << cid.id.size() << ':';
+  for (unsigned int i=0;i<cid.id.size();++i)
+    os << static_cast<int>(cid.id[i]);
+  return os;
+}
+
+/**
+ * read CellId from a stream
+ */
+inline std::istream& operator>> (std::istream& is, CellId& cid)
+{
+  is >> cid.coarse_cell_id;
+  char dummy;
+  is >> dummy;
+  Assert(dummy=='_', ExcMessage("invalid CellId"));
+  unsigned int idsize;
+  is >> idsize;
+  is >> dummy;
+  Assert(dummy==':', ExcMessage("invalid CellId"));
+
+  char value;
+  cid.id.clear();
+  for (unsigned int i=0;i<idsize;++i)
+    {
+      is >> value;
+      cid.id.push_back(value-'0');
+    }
+  return is;
+}
+
+inline bool
+CellId::operator== (const CellId & other) const
+{
+  if (this->coarse_cell_id != other.coarse_cell_id)
+    return false;
+  return id == other.id;
+}
+
+/**
+ *
+ */
+inline bool
+CellId::operator!= (const CellId & other) const
+{
+  return !(*this == other);
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
index 349756f6122d979751bdc34f252a39df3f3cd864..6bb84f86460a263d80f6c3a94b0a669bd218f30e 100644 (file)
@@ -19,6 +19,7 @@
 #include <deal.II/base/point.h>
 #include <deal.II/grid/tria_iterator_base.h>
 #include <deal.II/grid/tria_iterator_selector.h>
+#include <deal.II/grid/cell_id.h>
 
 
 namespace std
@@ -2821,7 +2822,8 @@ public:
 
   /**
    *  Return an iterator to the
-   *  parent.
+   *  parent. Throws an exception if this cell has no parent, i.e. has
+   *  level 0.
    */
   TriaIterator<CellAccessor<dim,spacedim> >
   parent () const;
@@ -2990,6 +2992,15 @@ public:
   void set_neighbor (const unsigned int i,
                      const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const;
 
+  /**
+   * Return a unique ID for the current cell. This ID is constructed from the
+   * path in the hierarchy from the coarse father cell and works correctly
+   * in parallel computations.
+   *
+   * Note: This operation takes O(log(level)) time.
+   */
+  CellId id() const;
+
   /**
    * @}
    */
@@ -3170,6 +3181,39 @@ CellAccessor (const TriaAccessor<structdim2,dim2,spacedim2> &)
                       "the conversion is not valid in the current context."));
 }
 
+template <int dim, int spacedim>
+CellId
+CellAccessor<dim,spacedim>::id() const
+{
+  std::vector<unsigned char> id(this->level(), -1);
+  unsigned int coarse_index;
+
+  CellAccessor<dim,spacedim> ptr = *this;
+  while (ptr.level()>0)
+    {
+      // find the 'v'st child of our parent we are
+      unsigned char v=-1;
+      for (unsigned int c=0;c<ptr.parent()->n_children();++c)
+        {
+          if (ptr.parent()->child_index(c)==ptr.index())
+            {
+              v = c;
+              break;
+            }
+        }
+
+      Assert(v!=-1, ExcInternalError());
+      id[ptr.level()-1] = v;
+
+      ptr.copy_from( *(ptr.parent()));
+    }
+
+  Assert(ptr.level()==0, ExcInternalError());
+  coarse_index = ptr.index();
+
+  return CellId(coarse_index, id);
+}
+
 
 #ifndef DOXYGEN
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.