From 65d1eea4de800267c32b1dc3cb9962498058e19b Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 21 Jul 2014 18:16:23 -0500 Subject: [PATCH] Joint work with Arezou Ghesmati: Add GridTools::get_patch_around_cell(). --- doc/news/changes.h | 8 +- include/deal.II/grid/grid_tools.h | 39 ++++++ source/grid/grid_tools.cc | 39 ++++++ source/grid/grid_tools.inst.in | 12 +- tests/deal.II/get_patch_around_cell_01.cc | 114 +++++++++++++++ tests/deal.II/get_patch_around_cell_01.output | 131 ++++++++++++++++++ 6 files changed, 339 insertions(+), 4 deletions(-) create mode 100644 tests/deal.II/get_patch_around_cell_01.cc create mode 100644 tests/deal.II/get_patch_around_cell_01.output diff --git a/doc/news/changes.h b/doc/news/changes.h index 4d4eae2789..af56bf62b7 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -97,7 +97,7 @@ inconvenience this causes.
    -
  1. Ported: The build system now supports cmake-3.0.0 +
  2. Ported: The build system now supports CMake 3.0.
    (Matthias Maier, 2014/07/15)
  3. @@ -190,6 +190,12 @@ inconvenience this causes.

    Specific improvements

      +
    1. New: The function GridTools::get_patch_around_cell() extracts + the set of cells that surround a single cell. +
      + (Arezou Ghesmati, Wolfgang Bangerth, 2014/07/21) +
    2. +
    3. Fixed: Utilities::string_to_int() and Utilities::string_to_double() did not catch if the string given started with an integer or double but contained additional diff --git a/include/deal.II/grid/grid_tools.h b/include/deal.II/grid/grid_tools.h index 77d28dab3f..0b963dfc25 100644 --- a/include/deal.II/grid/grid_tools.h +++ b/include/deal.II/grid/grid_tools.h @@ -927,6 +927,45 @@ namespace GridTools fix_up_distorted_child_cells (const typename Triangulation::DistortedCellList &distorted_cells, Triangulation &triangulation); + /*@}*/ + /** + * @name Extracting and creating patches of cells surrounding a single cell + */ + /*@{*/ + + + /** + * This function returns a list of all the neighbor cells of the given cell. + * Here, a neighbor is defined as one having at least part of a face in common + * with the given cell, but not edge (in 3d) or vertex neighbors (in 2d and + * 3d). + * + * The first element of the returned list is the cell provided as + * argument. The remaining ones are neighbors: The function loops over all + * faces of that given cell and checks if that face is not on the boundary of + * the domain. Then, if the neighbor cell does not have any children (i.e., it + * is either at the same refinement level as the current cell, or coarser) + * then this neighbor cell is added to the list of cells. Otherwise, if the + * neighbor cell is refined and therefore has children, then this function + * loops over all subfaces of current face adds the neighbors behind these + * sub-faces to the list to be returned. + * + * The Container template argument can be either a triangulation + * or any of the DoF handler classes. Because the C++ language specifies that + * the container type can not be inferred from an iterator alone, you will + * need to explicitly specify the template argument when calling this + * function. + * + * @note Patches are often used in defining error estimators that require the + * solution of a local problem on the patch surrounding each of the cells of + * the mesh. This also requires manipulating the degrees of freedom associated + * with the cells of a patch. To this end, there are further functions working + * on patches in namespace DoFTools. + */ + template + std::vector + get_patch_around_cell(const typename Container::active_cell_iterator &cell); + /*@}*/ /** * @name Lower-dimensional meshes for parts of higher-dimensional meshes diff --git a/source/grid/grid_tools.cc b/source/grid/grid_tools.cc index 8a1e931f92..e6aca82084 100644 --- a/source/grid/grid_tools.cc +++ b/source/grid/grid_tools.cc @@ -2090,6 +2090,45 @@ next_cell: + template + std::vector + get_patch_around_cell(const typename Container::active_cell_iterator &cell) + { + std::vector patch; + patch.push_back (cell); + for (unsigned int face_number=0; face_number::faces_per_cell; ++face_number) + if (cell->face(face_number)->at_boundary()==false) + { + if (cell->neighbor(face_number)->has_children() == false) + patch.push_back (cell->neighbor(face_number)); + else + // the neighbor is refined. in 2d/3d, we can simply ask for the children + // of the neighbor because they can not be further refined and, + // consequently, the children is active + if (Container::dimension > 1) + { + for (unsigned int subface=0; subfaceface(face_number)->n_children(); ++subface) + patch.push_back (cell->neighbor_child_on_subface (face_number, subface)); + } + else + { + // in 1d, we need to work a bit harder: iterate until we find + // the child by going from cell to child to child etc + typename Container::cell_iterator neighbor + = cell->neighbor (face_number); + while (neighbor->has_children()) + neighbor = neighbor->child(1-face_number); + + Assert (neighbor->neighbor(1-face_number) == cell, ExcInternalError()); + patch.push_back (neighbor); + } + } + return patch; + } + + + + template