]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Create new method dealii::Triangulation::create_triangulation(). 9195/head
authorPeter Munch <peterrmuench@gmail.com>
Wed, 25 Dec 2019 22:34:13 +0000 (23:34 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Sun, 19 Jan 2020 18:00:11 +0000 (19:00 +0100)
28 files changed:
include/deal.II/distributed/fully_distributed_tria.h
include/deal.II/distributed/fully_distributed_tria_util.h [deleted file]
include/deal.II/distributed/shared_tria.h
include/deal.II/distributed/tria.h
include/deal.II/grid/persistent_tria.h
include/deal.II/grid/tria.h
include/deal.II/grid/tria_description.h [new file with mode: 0644]
source/distributed/CMakeLists.txt
source/distributed/fully_distributed_tria.cc
source/distributed/shared_tria.cc
source/distributed/tria.cc
source/grid/CMakeLists.txt
source/grid/persistent_tria.cc
source/grid/tria.cc
source/grid/tria_description.cc [new file with mode: 0644]
source/grid/tria_description.inst.in [new file with mode: 0644]
tests/fullydistributed_grids/copy_distributed_tria_01.cc
tests/fullydistributed_grids/copy_distributed_tria_02.cc
tests/fullydistributed_grids/copy_serial_tria_01.cc
tests/fullydistributed_grids/copy_serial_tria_02.cc
tests/fullydistributed_grids/copy_serial_tria_03.cc
tests/fullydistributed_grids/copy_serial_tria_04.cc
tests/fullydistributed_grids/copy_serial_tria_05.cc
tests/fullydistributed_grids/copy_serial_tria_06.cc
tests/fullydistributed_grids/copy_serial_tria_07.cc
tests/fullydistributed_grids/copy_serial_tria_grouped_01.cc
tests/matrix_free/parallel_multigrid_fullydistributed.cc
tests/serialization/parallel_fullydistributed_construction_data_1.cc

index 7b6a44889238fc6ed09f5dd3cfd915b8d6e4178c..6e4b4c73a41ea4afe09eabec0e74dd643d43d772 100644 (file)
@@ -50,167 +50,6 @@ namespace parallel
    */
   namespace fullydistributed
   {
-    /**
-     * Configuration flags for fully distributed Triangulations.
-     * Settings can be combined using bitwise OR.
-     *
-     * @author Peter Munch, 2019
-     */
-    enum Settings
-    {
-      /**
-       * Default settings, other options are disabled.
-       */
-      default_setting = 0x0,
-      /**
-       * This flags needs to be set to use the geometric multigrid
-       * functionality. This option requires additional computation and
-       * communication.
-       */
-      construct_multigrid_hierarchy = 0x1
-    };
-
-    /**
-     * Information needed for each locally relevant cell, stored in
-     * ConstructionData and used during construction of a
-     * parallel::fullydistributed::Triangulation. This struct stores
-     * the cell id, the subdomain_id and the level_subdomain_id as well as
-     * information related to manifold_id and boundary_id.
-     *
-     * @author Peter Munch, 2019
-     */
-    template <int dim>
-    struct CellData
-    {
-      /**
-       * Constructor.
-       */
-      CellData() = default;
-
-      /**
-       * Boost serialization function
-       */
-      template <class Archive>
-      void
-      serialize(Archive &ar, const unsigned int /*version*/);
-
-      /**
-       * Comparison operator.
-       */
-      bool
-      operator==(const CellData<dim> &other) const;
-
-      /**
-       * Unique CellID of the cell.
-       */
-      CellId::binary_type id;
-
-      /**
-       * subdomain_id of the cell.
-       */
-      types::subdomain_id subdomain_id;
-
-      /**
-       * level_subdomain_id of the cell.
-       */
-      types::subdomain_id level_subdomain_id;
-
-      /**
-       * Manifold id of the cell.
-       */
-      types::material_id manifold_id;
-
-      /**
-       * Manifold id of all lines of the cell.
-       *
-       * @note Only used for 2D and 3D.
-       */
-      std::array<types::manifold_id, GeometryInfo<dim>::lines_per_cell>
-        manifold_line_ids;
-
-      /**
-       * Manifold id of all face quads of the cell.
-       *
-       * @note Only used for 3D.
-       */
-      std::array<types::manifold_id,
-                 dim == 1 ? 1 : GeometryInfo<3>::quads_per_cell>
-        manifold_quad_ids;
-
-      /**
-       * List of face number and boundary id of all non-internal faces of the
-       * cell.
-       */
-      std::vector<std::pair<unsigned int, types::boundary_id>> boundary_ids;
-    };
-
-
-
-    /**
-     * Data used to construct a fully distributed triangulation in
-     * parallel::fullydistributed::Triangulation::create_triangulation().
-     *
-     * @author Peter Munch, 2019
-     */
-    template <int dim, int spacedim>
-    struct ConstructionData
-    {
-      /**
-       * Boost serialization function
-       */
-      template <class Archive>
-      void
-      serialize(Archive &ar, const unsigned int /*version*/);
-
-      /**
-       * Comparison operator.
-       */
-      bool
-      operator==(const ConstructionData<dim, spacedim> &other) const;
-
-      /**
-       * Cells of the locally-relevant coarse-grid triangulation.
-       */
-      std::vector<dealii::CellData<dim>> coarse_cells;
-
-      /**
-       * Vertices of the locally-relevant coarse-grid triangulation.
-       */
-      std::vector<Point<spacedim>> coarse_cell_vertices;
-
-      /**
-       * List that for each locally-relevant coarse cell provides the
-       * corresponding global @ref GlossCoarseCellId.
-       */
-      std::vector<types::coarse_cell_id> coarse_cell_index_to_coarse_cell_id;
-
-      /**
-       * CellData for each locally relevant cell on each level. cell_infos[i]
-       * contains the CellData for each locally relevant cell on the ith
-       * level.
-       */
-      std::vector<std::vector<CellData<dim>>> cell_infos;
-
-      /**
-       * The MPI communicator used to create this struct. It will be compared
-       * to the communicator inside of parallel::fullydistributed::Triangulation
-       * and an assert is thrown if they do not match.
-       *
-       * @note This is necessary since the communicator inside of
-       * parallel::TriangulationBase is const and cannot be changed after the
-       * constructor has been called.
-       *
-       */
-      MPI_Comm comm;
-
-      /**
-       * @note settings See the description of the Settings enumerator.
-       */
-      Settings settings;
-    };
-
-
-
     /**
      * A distributed triangulation with a distributed coarse grid.
      *
@@ -299,26 +138,22 @@ namespace parallel
       virtual ~Triangulation() = default;
 
       /**
-       * Create a triangulation from the provided ConstructionData.
-       *
-       * @note The namespace dealii::fullydistributed::Util contains functions
-       *       to create ConstructionData.
+       * @copydoc Triangulation::create_triangulation()
        *
        * @note This is the function to be used instead of
        * Triangulation::create_triangulation() for some of the other
        * triangulations of deal.II.
-       *
-       * @param construction_data The data needed for this process.
        */
       void
       create_triangulation(
-        const ConstructionData<dim, spacedim> &construction_data);
+        const TriangulationDescription::Description<dim, spacedim>
+          &construction_data) override;
 
       /**
        * @note This function is not implemented for this class  and throws
        *       an assertion. Instead, use
        *       the other create_triangulation() function to create the
-       * triangulation.
+       *       triangulation.
        */
       virtual void
       create_triangulation(const std::vector<Point<spacedim>> &      vertices,
@@ -360,7 +195,7 @@ namespace parallel
       set_partitioner(
         const std::function<void(dealii::Triangulation<dim, spacedim> &,
                                  const unsigned int)> &partitioner,
-        const Settings &                               settings);
+        const TriangulationDescription::Settings &     settings);
 
       /**
        * Coarsen and refine the mesh according to refinement and coarsening
@@ -416,7 +251,7 @@ namespace parallel
       /**
        * store the Settings.
        */
-      Settings settings;
+      TriangulationDescription::Settings settings;
 
       /**
        * Partitioner used in copy_triangulation().
@@ -452,87 +287,6 @@ namespace parallel
         currently_processing_prepare_coarsening_and_refinement_for_internal_usage;
     };
 
-
-#ifndef DOXYGEN
-
-    template <int dim>
-    template <class Archive>
-    void
-    CellData<dim>::serialize(Archive &ar, const unsigned int /*version*/)
-    {
-      ar &id;
-      ar &subdomain_id;
-      ar &level_subdomain_id;
-      ar &manifold_id;
-      if (dim >= 2)
-        ar &manifold_line_ids;
-      if (dim >= 3)
-        ar &manifold_quad_ids;
-      ar &boundary_ids;
-    }
-
-
-    template <int dim, int spacedim>
-    template <class Archive>
-    void
-    ConstructionData<dim, spacedim>::serialize(Archive &ar,
-                                               const unsigned int /*version*/)
-    {
-      ar &coarse_cells;
-      ar &coarse_cell_vertices;
-      ar &coarse_cell_index_to_coarse_cell_id;
-      ar &cell_infos;
-      ar &settings;
-    }
-
-
-
-    template <int dim>
-    bool
-    CellData<dim>::operator==(const CellData<dim> &other) const
-    {
-      if (this->id != other.id)
-        return false;
-      if (this->subdomain_id != other.subdomain_id)
-        return false;
-      if (this->level_subdomain_id != other.level_subdomain_id)
-        return false;
-      if (this->manifold_id != other.manifold_id)
-        return false;
-      if (dim >= 2 && this->manifold_line_ids != other.manifold_line_ids)
-        return false;
-      if (dim >= 3 && this->manifold_quad_ids != other.manifold_quad_ids)
-        return false;
-      if (this->boundary_ids != other.boundary_ids)
-        return false;
-
-      return true;
-    }
-
-
-
-    template <int dim, int spacedim>
-    bool
-    ConstructionData<dim, spacedim>::
-    operator==(const ConstructionData<dim, spacedim> &other) const
-    {
-      if (this->coarse_cells != other.coarse_cells)
-        return false;
-      if (this->coarse_cell_vertices != other.coarse_cell_vertices)
-        return false;
-      if (this->coarse_cell_index_to_coarse_cell_id !=
-          other.coarse_cell_index_to_coarse_cell_id)
-        return false;
-      if (this->cell_infos != other.cell_infos)
-        return false;
-      if (this->settings != other.settings)
-        return false;
-
-      return true;
-    }
-
-#endif
-
   } // namespace fullydistributed
 } // namespace parallel
 
diff --git a/include/deal.II/distributed/fully_distributed_tria_util.h b/include/deal.II/distributed/fully_distributed_tria_util.h
deleted file mode 100644 (file)
index ee026c9..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-// ---------------------------------------------------------------------
-//
-// Copyright (C) 2019 by the deal.II authors
-//
-// This file is part of the deal.II library.
-//
-// The deal.II library is free software; you can use it, redistribute
-// it, and/or modify it under the terms of the GNU Lesser General
-// Public License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// The full text of the license can be found in the file LICENSE.md at
-// the top level directory of deal.II.
-//
-// ---------------------------------------------------------------------
-
-#ifndef dealii_fully_distributed_tria_util_h
-#define dealii_fully_distributed_tria_util_h
-
-#include <deal.II/base/config.h>
-
-#include <deal.II/distributed/fully_distributed_tria.h>
-
-DEAL_II_NAMESPACE_OPEN
-
-namespace parallel
-{
-  namespace fullydistributed
-  {
-    /**
-     * A namespace for fully distributed triangulation utility functions.
-     *
-     * @ingroup fullydistributed
-     */
-    namespace Utilities
-    {
-      /**
-       * Construct parallel::fullydistributed::ConstructionData from a given
-       * partitioned triangulation `tria` and a specified process.
-       * The input triangulation can be either
-       * a serial triangulation of type dealii::Triangulation which has been
-       * colored (subdomain_id and/or level_subdomain_id has been set) or a
-       * distributed triangulation of type dealii::distributed::Triangulation,
-       * where the partitioning is adopted unaltered.
-       *
-       * @param tria Partitioned input triangulation.
-       * @param comm MPI_Communicator to be used. In the case
-       *             of dealii::distributed::Triangulation, the communicators
-       *             have to match.
-       * @param construct_multilevel_hierarchy Signal if the multigrid levels
-       *        should be constructed.
-       * @param my_rank_in Construct ConstructionData for this rank (only
-       *                   working for serial triangulations).
-       * @return ConstructionData to be used to setup
-       *         parallel::fullydistributed::Triangulation.
-       *
-       * @note Multilevel hierarchies are supported if it is enabled in
-       *       parallel::fullydistributed::Triangulation.
-       *
-       * @note Hanging nodes in the input triangulation are supported. However,
-       *       to be able to use this
-       *       feature, the user has to enable multilevel hierarchy support in
-       *       parallel::fullydistributed::Triangulation.
-       *
-       * @author Peter Munch, 2019
-       */
-      template <int dim, int spacedim = dim>
-      ConstructionData<dim, spacedim>
-      create_construction_data_from_triangulation(
-        const dealii::Triangulation<dim, spacedim> &tria,
-        const MPI_Comm                              comm,
-        const bool         construct_multilevel_hierarchy = false,
-        const unsigned int my_rank_in = numbers::invalid_unsigned_int);
-
-
-      /**
-       * Construct a parallel::fullydistributed::ConstructionData. In contrast
-       * to the function above, this function is also responsible for creating
-       * a serial triangulation and for its partitioning (by calling the
-       * provided std::functions). Internally only selected processes (every
-       * n-th/each root of a group of size group_size) create a serial
-       * triangulation and the ConstructionData for all processes in its group,
-       * which is communicated.
-       *
-       * @note A reasonable group size is the size of a NUMA domain or the
-       * size of a compute node.
-       *
-       * @param serial_grid_generator A function, which creates a serial triangulation.
-       * @param serial_grid_partitioner A function, which can partition a serial
-       *        triangulation, i.e., sets the sudomain_ids of the active cells.
-       *        The function takes as the first argument a serial triangulation,
-       *        as the second argument the MPI communicator, and as the third
-       *        argument the group size.
-       * @param comm MPI communicator
-       * @param group_size The size of each group.
-       * @param construct_multilevel_hierarchy Construct multigrid levels.
-       * @return ConstructionData to be used to setup
-       *         parallel::fullydistributed::Triangulation.
-       *
-       * @author Peter Munch, 2019
-       */
-      template <int dim, int spacedim = dim>
-      ConstructionData<dim, spacedim>
-      create_construction_data_from_triangulation_in_groups(
-        std::function<void(dealii::Triangulation<dim, spacedim> &)>
-                                                serial_grid_generator,
-        std::function<void(dealii::Triangulation<dim, spacedim> &,
-                           const MPI_Comm,
-                           const unsigned int)> serial_grid_partitioner,
-        const MPI_Comm                          comm,
-        const int                               group_size = 1,
-        const bool construct_multilevel_hierarchy          = false);
-
-    } // namespace Utilities
-  }   // namespace fullydistributed
-} // namespace parallel
-
-
-DEAL_II_NAMESPACE_CLOSE
-
-#endif
index b47dc03c83e3507ce3a9053997190b9ceeabacad..41295be797f73d46ebe4133d7eb04979f9a92fbd 100644 (file)
@@ -270,6 +270,16 @@ namespace parallel
                            const std::vector<CellData<dim>> &  cells,
                            const SubCellData &subcelldata) override;
 
+      /*
+       * @copydoc Triangulation::create_triangulation()
+       *
+       * @note Not inmplemented yet.
+       */
+      virtual void
+      create_triangulation(
+        const TriangulationDescription::Description<dim, spacedim>
+          &construction_data) override;
+
       /**
        * Copy @p other_tria to this triangulation.
        *
index 04fbe84ab9953c735a9d9bbe24007ac8d09604a0..35301b54de145d09cdb52d084b455290e3f62298 100644 (file)
@@ -406,6 +406,16 @@ namespace parallel
                            const std::vector<CellData<dim>> &  cells,
                            const SubCellData &subcelldata) override;
 
+      /*
+       * @copydoc Triangulation::create_triangulation()
+       *
+       * @note Not inmplemented yet.
+       */
+      virtual void
+      create_triangulation(
+        const TriangulationDescription::Description<dim, spacedim>
+          &construction_data) override;
+
       /**
        * Coarsen and refine the mesh according to refinement and coarsening
        * flags set.
index cf4a45ae21a0271127cdf39cdbf50200bd61b262..d7447a2cad447990984619cc728febf4b5b5cdce 100644 (file)
@@ -202,6 +202,16 @@ public:
                        const std::vector<CellData<dim>> &  cells,
                        const SubCellData &subcelldata) override;
 
+  /*
+   * @copydoc Triangulation::create_triangulation()
+   *
+   * @note Not inmplemented yet.
+   */
+  virtual void
+  create_triangulation(
+    const TriangulationDescription::Description<dim, spacedim>
+      &construction_data) override;
+
   /**
    * An overload of the respective function of the base class.
    *
index 428ec19a0524516277a4bff3524566aa3d8792d6..97b4572d525a8cd1c5768ee94f23131f3cb83e46 100644 (file)
@@ -25,6 +25,7 @@
 #include <deal.II/base/smartpointer.h>
 #include <deal.II/base/subscriptor.h>
 
+#include <deal.II/grid/tria_description.h>
 #include <deal.II/grid/tria_iterator_selector.h>
 
 #include <boost/serialization/map.hpp>
@@ -49,6 +50,17 @@ DEAL_II_NAMESPACE_OPEN
 template <int dim, int spacedim>
 class Manifold;
 
+template <int dim>
+struct CellData;
+
+struct SubCellData;
+
+namespace TriangulationDescription
+{
+  template <int, int>
+  struct Description;
+}
+
 namespace GridTools
 {
   template <typename CellIterator>
@@ -95,206 +107,6 @@ namespace hp
 }
 #endif
 
-/*------------------------------------------------------------------------*/
-
-/**
- * The CellData class (and the related SubCellData class) is used to
- * provide a comprehensive, but minimal, description of the cells when
- * creating a triangulation via Triangulation::create_triangulation().
- * Specifically, each CellData object -- describing one cell in a
- * triangulation -- has member variables for indices of the $2^d$ vertices
- * (the actual coordinates of the vertices are described in a separate
- * vector passed to Triangulation::create_triangulation(), so the CellData
- * object only needs to store indices into that vector), the material
- * id of the cell that can be used in applications to describe which
- * part of the domain a cell belongs to (see
- * @ref GlossMaterialId "the glossary entry on material ids"),
- * and a manifold id that is used to describe the geometry object
- * that is responsible for this cell (see
- * @ref GlossManifoldIndicator "the glossary entry on manifold ids")
- * to describe the manifold this object belongs to.
- *
- * This structure is also used to represent data for faces and edges when used
- * as a member of the SubCellData class. In this case, the template argument
- * @p structdim of an object will be less than the dimension @p dim of the
- * triangulation. If this is so, then #vertices array represents the indices of
- * the vertices of one face or edge of one of the cells passed to
- * Triangulation::create_triangulation(). Furthermore, for faces the
- * material id has no meaning, and the @p material_id field is reused
- * to store a @p boundary_id instead to designate which part of the boundary
- * the face or edge belongs to (see
- * @ref GlossBoundaryIndicator "the glossary entry on boundary ids").
- *
- * An example showing how this class can be used is in the
- * <code>create_coarse_grid()</code> function of step-14. There are also
- * many more use cases in the implementation of the functions of the
- * GridGenerator namespace.
- *
- * @ingroup grid
- */
-template <int structdim>
-struct CellData
-{
-  /**
-   * Indices of the vertices of this cell. These indices correspond
-   * to entries in the vector of vertex locations passed to
-   * Triangulation::create_triangulation().
-   */
-  unsigned int vertices[GeometryInfo<structdim>::vertices_per_cell];
-
-  /**
-   * Material or boundary indicator of this cell.
-   * This field is a union that stores <i>either</i> a boundary or
-   * a material id, depending on whether the current object is used
-   * to describe a cell (in a vector of CellData objects) or a
-   * face or edge (as part of a SubCellData object).
-   */
-  union
-  {
-    /**
-     * The material id of the cell being described. See the documentation
-     * of the CellData class for examples of how to use this field.
-     *
-     * This variable can only be used if the current object is used to
-     * describe a cell, i.e., if @p structdim equals the dimension
-     * @p dim of a triangulation.
-     */
-    types::material_id material_id;
-
-    /**
-     * The boundary id of a face or edge being described. See the documentation
-     * of the CellData class for examples of how to use this field.
-     *
-     * This variable can only be used if the current object is used to
-     * describe a face or edge, i.e., if @p structdim is less than the dimension
-     * @p dim of a triangulation. In this case, the CellData object this
-     * variable belongs to will be part of a SubCellData object.
-     */
-    types::boundary_id boundary_id;
-  };
-
-  /**
-   * Manifold identifier of this object. This identifier should be used to
-   * identify the manifold to which this object belongs, and from which this
-   * object will collect information on how to add points upon refinement.
-   *
-   * See the documentation of the CellData class for examples of how to use
-   * this field.
-   */
-  types::manifold_id manifold_id;
-
-  /**
-   * Default constructor. Sets the member variables to the following values:
-   *
-   * - vertex indices to invalid values
-   * - boundary or material id zero (the default for boundary or material ids)
-   * - manifold id to numbers::flat_manifold_id
-   */
-  CellData();
-
-  /**
-   * Comparison operator.
-   */
-  bool
-  operator==(const CellData<structdim> &other) const;
-
-  /**
-   * Boost serialization function
-   */
-  template <class Archive>
-  void
-  serialize(Archive &ar, const unsigned int version);
-
-  static_assert(structdim > 0,
-                "The class CellData can only be used for structdim>0.");
-};
-
-
-
-/**
- * The SubCellData class is used to describe information about faces and
- * edges at the boundary of a mesh when creating a triangulation via
- * Triangulation::create_triangulation(). It contains member variables
- * that describe boundary edges and boundary quads.
- *
- * The class has no template argument and is used both in the description
- * of boundary edges in 2d (in which case the contents of the
- * @p boundary_quads member variable are ignored), as well as in the
- * description of boundary edges and faces in 3d (in which case both the
- * @p boundary_lines and @p boundary_quads members may be used). It is also
- * used as the argument to Triangulation::create_triangulation() in 1d,
- * where the contents of objects of the current type are simply ignored.
- *
- * By default, Triangulation::create_triangulation() simply assigns
- * default boundary indicators and manifold indicators to edges and
- * quads at the boundary of the mesh. (See the glossary entries on
- * @ref GlossBoundaryIndicator "boundary ids"
- * and
- * @ref GlossManifoldIndicator "manifold ids"
- * for more information on what they represent.) As a consequence,
- * it is not <i>necessary</i> to explicitly describe the properties
- * of boundary objects. In all cases, these properties can also be
- * set at a later time, once the triangulation has already been
- * created. On the other hand, it is sometimes convenient to describe
- * boundary indicators or manifold ids at the time of creation. In
- * these cases, the current class can be used by filling the
- * @p boundary_lines and @p boundary_quads vectors with
- * CellData<1> and CellData<2> objects that correspond to boundary
- * edges and quads for which properties other than the default
- * values should be used.
- *
- * Each entry in the @p boundary_lines and @p boundary_quads vectors
- * then needs to correspond to an edge or quad of the cells that
- * are described by the vector of CellData objects passed to
- * Triangulation::create_triangulation(). I.e., the vertex indices
- * stored in each entry need to correspond to an edge or face
- * of the triangulation that has the same set of vertex indices,
- * and in the same order. For these boundary edges or quads, one can
- * then set either or both the CellData::boundary_id and
- * CellData::manifold_id.
- *
- * There are also use cases where one may want to set the manifold id
- * of an <i>interior</i> edge or face. Such faces, identified by
- * their vertex indices, may also appear in the
- * @p boundary_lines and @p boundary_quads vectors (despite the names of
- * these member variables). However, it is then obviously not allowed
- * to set a boundary id (because the object is not actually part of
- * the boundary). As a consequence, to be valid, the CellData::boundary_id
- * of interior edges or faces needs to equal
- * numbers::internal_face_boundary_id.
- *
- * @ingroup grid
- */
-struct SubCellData
-{
-  /**
-   * A vector of CellData<1> objects that describe boundary and manifold
-   * information for edges of 2d or 3d triangulations.
-   *
-   * This vector may not be used in the creation of 1d triangulations.
-   */
-  std::vector<CellData<1>> boundary_lines;
-
-  /**
-   * A vector of CellData<2> objects that describe boundary and manifold
-   * information for quads of 3d triangulations.
-   *
-   * This vector may not be used in the creation of 1d or 2d triangulations.
-   */
-  std::vector<CellData<2>> boundary_quads;
-
-  /**
-   * Determine whether the member variables above which may not be used in a
-   * given dimension are really empty. In other words, this function returns
-   * whether
-   * both @p boundary_lines and @p boundary_quads are empty vectors
-   * when @p dim equals one, and whether the @p boundary_quads
-   * vector is empty when @p dim equals two.
-   */
-  bool
-  check_consistency(const unsigned int dim) const;
-};
-
 
 /*------------------------------------------------------------------------*/
 
@@ -2020,6 +1832,20 @@ public:
                        const std::vector<CellData<dim>> &  cells,
                        const SubCellData &                 subcelldata);
 
+  /**
+   * Create a triangulation from the provided
+   * TriangulationDescription::Description.
+   *
+   * @note The namespace construction::Utilities contains functions
+   *       to create TriangulationDescription::Description.
+   *
+   * @param construction_data The data needed for this process.
+   */
+  virtual void
+  create_triangulation(
+    const TriangulationDescription::Description<dim, spacedim>
+      &construction_data);
+
   /**
    * For backward compatibility, only. This function takes the cell data in
    * the ordering as requested by deal.II versions up to 5.2, converts it to
@@ -4129,18 +3955,6 @@ private:
 #ifndef DOXYGEN
 
 
-template <int structdim>
-template <class Archive>
-void
-CellData<structdim>::serialize(Archive &ar, const unsigned int /*version*/)
-{
-  ar &vertices;
-  ar &material_id;
-  ar &boundary_id;
-  ar &manifold_id;
-}
-
-
 
 namespace internal
 {
diff --git a/include/deal.II/grid/tria_description.h b/include/deal.II/grid/tria_description.h
new file mode 100644 (file)
index 0000000..d927f68
--- /dev/null
@@ -0,0 +1,571 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+#ifndef dealii_grid_construction_utilities_h
+#define dealii_grid_construction_utilities_h
+
+#include <deal.II/base/config.h>
+
+#include <deal.II/base/mpi.h>
+
+#include <deal.II/grid/cell_id.h>
+#include <deal.II/grid/tria.h>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+/*------------------------------------------------------------------------*/
+
+/**
+ * The CellData class (and the related SubCellData class) is used to
+ * provide a comprehensive, but minimal, description of the cells when
+ * creating a triangulation via Triangulation::create_triangulation().
+ * Specifically, each CellData object -- describing one cell in a
+ * triangulation -- has member variables for indices of the $2^d$ vertices
+ * (the actual coordinates of the vertices are described in a separate
+ * vector passed to Triangulation::create_triangulation(), so the CellData
+ * object only needs to store indices into that vector), the material
+ * id of the cell that can be used in applications to describe which
+ * part of the domain a cell belongs to (see
+ * @ref GlossMaterialId "the glossary entry on material ids"),
+ * and a manifold id that is used to describe the geometry object
+ * that is responsible for this cell (see
+ * @ref GlossManifoldIndicator "the glossary entry on manifold ids")
+ * to describe the manifold this object belongs to.
+ *
+ * This structure is also used to represent data for faces and edges when used
+ * as a member of the SubCellData class. In this case, the template argument
+ * @p structdim of an object will be less than the dimension @p dim of the
+ * triangulation. If this is so, then #vertices array represents the indices of
+ * the vertices of one face or edge of one of the cells passed to
+ * Triangulation::create_triangulation(). Furthermore, for faces the
+ * material id has no meaning, and the @p material_id field is reused
+ * to store a @p boundary_id instead to designate which part of the boundary
+ * the face or edge belongs to (see
+ * @ref GlossBoundaryIndicator "the glossary entry on boundary ids").
+ *
+ * An example showing how this class can be used is in the
+ * <code>create_coarse_grid()</code> function of step-14. There are also
+ * many more use cases in the implementation of the functions of the
+ * GridGenerator namespace.
+ *
+ * @ingroup grid
+ */
+template <int structdim>
+struct CellData
+{
+  /**
+   * Indices of the vertices of this cell. These indices correspond
+   * to entries in the vector of vertex locations passed to
+   * Triangulation::create_triangulation().
+   */
+  unsigned int vertices[GeometryInfo<structdim>::vertices_per_cell];
+
+  /**
+   * Material or boundary indicator of this cell.
+   * This field is a union that stores <i>either</i> a boundary or
+   * a material id, depending on whether the current object is used
+   * to describe a cell (in a vector of CellData objects) or a
+   * face or edge (as part of a SubCellData object).
+   */
+  union
+  {
+    /**
+     * The material id of the cell being described. See the documentation
+     * of the CellData class for examples of how to use this field.
+     *
+     * This variable can only be used if the current object is used to
+     * describe a cell, i.e., if @p structdim equals the dimension
+     * @p dim of a triangulation.
+     */
+    types::material_id material_id;
+
+    /**
+     * The boundary id of a face or edge being described. See the documentation
+     * of the CellData class for examples of how to use this field.
+     *
+     * This variable can only be used if the current object is used to
+     * describe a face or edge, i.e., if @p structdim is less than the dimension
+     * @p dim of a triangulation. In this case, the CellData object this
+     * variable belongs to will be part of a SubCellData object.
+     */
+    types::boundary_id boundary_id;
+  };
+
+  /**
+   * Manifold identifier of this object. This identifier should be used to
+   * identify the manifold to which this object belongs, and from which this
+   * object will collect information on how to add points upon refinement.
+   *
+   * See the documentation of the CellData class for examples of how to use
+   * this field.
+   */
+  types::manifold_id manifold_id;
+
+  /**
+   * Default constructor. Sets the member variables to the following values:
+   *
+   * - vertex indices to invalid values
+   * - boundary or material id zero (the default for boundary or material ids)
+   * - manifold id to numbers::flat_manifold_id
+   */
+  CellData();
+
+  /**
+   * Comparison operator.
+   */
+  bool
+  operator==(const CellData<structdim> &other) const;
+
+  /**
+   * Boost serialization function
+   */
+  template <class Archive>
+  void
+  serialize(Archive &ar, const unsigned int version);
+
+  static_assert(structdim > 0,
+                "The class CellData can only be used for structdim>0.");
+};
+
+
+
+/**
+ * The SubCellData class is used to describe information about faces and
+ * edges at the boundary of a mesh when creating a triangulation via
+ * Triangulation::create_triangulation(). It contains member variables
+ * that describe boundary edges and boundary quads.
+ *
+ * The class has no template argument and is used both in the description
+ * of boundary edges in 2d (in which case the contents of the
+ * @p boundary_quads member variable are ignored), as well as in the
+ * description of boundary edges and faces in 3d (in which case both the
+ * @p boundary_lines and @p boundary_quads members may be used). It is also
+ * used as the argument to Triangulation::create_triangulation() in 1d,
+ * where the contents of objects of the current type are simply ignored.
+ *
+ * By default, Triangulation::create_triangulation() simply assigns
+ * default boundary indicators and manifold indicators to edges and
+ * quads at the boundary of the mesh. (See the glossary entries on
+ * @ref GlossBoundaryIndicator "boundary ids"
+ * and
+ * @ref GlossManifoldIndicator "manifold ids"
+ * for more information on what they represent.) As a consequence,
+ * it is not <i>necessary</i> to explicitly describe the properties
+ * of boundary objects. In all cases, these properties can also be
+ * set at a later time, once the triangulation has already been
+ * created. On the other hand, it is sometimes convenient to describe
+ * boundary indicators or manifold ids at the time of creation. In
+ * these cases, the current class can be used by filling the
+ * @p boundary_lines and @p boundary_quads vectors with
+ * CellData<1> and CellData<2> objects that correspond to boundary
+ * edges and quads for which properties other than the default
+ * values should be used.
+ *
+ * Each entry in the @p boundary_lines and @p boundary_quads vectors
+ * then needs to correspond to an edge or quad of the cells that
+ * are described by the vector of CellData objects passed to
+ * Triangulation::create_triangulation(). I.e., the vertex indices
+ * stored in each entry need to correspond to an edge or face
+ * of the triangulation that has the same set of vertex indices,
+ * and in the same order. For these boundary edges or quads, one can
+ * then set either or both the CellData::boundary_id and
+ * CellData::manifold_id.
+ *
+ * There are also use cases where one may want to set the manifold id
+ * of an <i>interior</i> edge or face. Such faces, identified by
+ * their vertex indices, may also appear in the
+ * @p boundary_lines and @p boundary_quads vectors (despite the names of
+ * these member variables). However, it is then obviously not allowed
+ * to set a boundary id (because the object is not actually part of
+ * the boundary). As a consequence, to be valid, the CellData::boundary_id
+ * of interior edges or faces needs to equal
+ * numbers::internal_face_boundary_id.
+ *
+ * @ingroup grid
+ */
+struct SubCellData
+{
+  /**
+   * A vector of CellData<1> objects that describe boundary and manifold
+   * information for edges of 2d or 3d triangulations.
+   *
+   * This vector may not be used in the creation of 1d triangulations.
+   */
+  std::vector<CellData<1>> boundary_lines;
+
+  /**
+   * A vector of CellData<2> objects that describe boundary and manifold
+   * information for quads of 3d triangulations.
+   *
+   * This vector may not be used in the creation of 1d or 2d triangulations.
+   */
+  std::vector<CellData<2>> boundary_quads;
+
+  /**
+   * Determine whether the member variables above which may not be used in a
+   * given dimension are really empty. In other words, this function returns
+   * whether
+   * both @p boundary_lines and @p boundary_quads are empty vectors
+   * when @p dim equals one, and whether the @p boundary_quads
+   * vector is empty when @p dim equals two.
+   */
+  bool
+  check_consistency(const unsigned int dim) const;
+};
+
+
+template <int structdim>
+template <class Archive>
+void
+CellData<structdim>::serialize(Archive &ar, const unsigned int /*version*/)
+{
+  ar &vertices;
+  ar &material_id;
+  ar &boundary_id;
+  ar &manifold_id;
+}
+
+/**
+ * A namespace dedicated to the struct Description, which can be used in
+ * Triangulation::create_triangulation().
+ */
+namespace TriangulationDescription
+{
+  /**
+   * Configuration flags for Triangulations.
+   * Settings can be combined using bitwise OR.
+   *
+   * @author Peter Munch, 2019
+   */
+  enum Settings
+  {
+    /**
+     * Default settings, other options are disabled.
+     */
+    default_setting = 0x0,
+    /**
+     * This flag needs to be set to use the geometric multigrid
+     * functionality. This option requires additional computation and
+     * communication.
+     */
+    construct_multigrid_hierarchy = 0x1
+  };
+
+  /**
+   * Information needed for each locally relevant cell, stored in
+   * Description and used during construction of a
+   * Triangulation. This struct stores
+   * the cell id, the subdomain_id and the level_subdomain_id as well as
+   * information related to manifold_id and boundary_id.
+   *
+   * @author Peter Munch, 2019
+   */
+  template <int dim>
+  struct CellData
+  {
+    /**
+     * Constructor.
+     */
+    CellData() = default;
+
+    /**
+     * Boost serialization function
+     */
+    template <class Archive>
+    void
+    serialize(Archive &ar, const unsigned int /*version*/);
+
+    /**
+     * Comparison operator.
+     */
+    bool
+    operator==(const CellData<dim> &other) const;
+
+    /**
+     * Unique CellID of the cell.
+     */
+    CellId::binary_type id;
+
+    /**
+     * subdomain_id of the cell.
+     */
+    types::subdomain_id subdomain_id;
+
+    /**
+     * level_subdomain_id of the cell.
+     */
+    types::subdomain_id level_subdomain_id;
+
+    /**
+     * Manifold id of the cell.
+     */
+    types::material_id manifold_id;
+
+    /**
+     * Manifold id of all lines of the cell.
+     *
+     * @note Only used for 2D and 3D.
+     */
+    std::array<types::manifold_id, GeometryInfo<dim>::lines_per_cell>
+      manifold_line_ids;
+
+    /**
+     * Manifold id of all face quads of the cell.
+     *
+     * @note Only used for 3D.
+     */
+    std::array<types::manifold_id,
+               dim == 1 ? 1 : GeometryInfo<3>::quads_per_cell>
+      manifold_quad_ids;
+
+    /**
+     * List of face number and boundary id of all non-internal faces of the
+     * cell.
+     */
+    std::vector<std::pair<unsigned int, types::boundary_id>> boundary_ids;
+  };
+
+  /**
+   * Data used in Triangulation::create_triangulation().
+   *
+   * @author Peter Munch, 2019
+   */
+  template <int dim, int spacedim>
+  struct Description
+  {
+    /**
+     * Boost serialization function
+     */
+    template <class Archive>
+    void
+    serialize(Archive &ar, const unsigned int /*version*/);
+
+    /**
+     * Comparison operator.
+     */
+    bool
+    operator==(const Description<dim, spacedim> &other) const;
+
+    /**
+     * Cells of the locally-relevant coarse-grid triangulation.
+     */
+    std::vector<dealii::CellData<dim>> coarse_cells;
+
+    /**
+     * Vertices of the locally-relevant coarse-grid triangulation.
+     */
+    std::vector<Point<spacedim>> coarse_cell_vertices;
+
+    /**
+     * List that for each locally-relevant coarse cell provides the
+     * corresponding global @ref GlossCoarseCellId.
+     */
+    std::vector<types::coarse_cell_id> coarse_cell_index_to_coarse_cell_id;
+
+    /**
+     * CellData for each locally relevant cell on each level. cell_infos[i]
+     * contains the CellData for each locally relevant cell on the ith
+     * level.
+     */
+    std::vector<std::vector<CellData<dim>>> cell_infos;
+
+    /**
+     * The MPI communicator used to create this struct. It will be compared
+     * to the communicator inside of the Triangulation
+     * and an assert is thrown if they do not match.
+     *
+     * @note Please note this is necessary since the communicator inside of
+     * parallel::TriangulationBase is const and cannot be changed after the
+     * constructor has been called.
+     *
+     */
+    MPI_Comm comm;
+
+    /**
+     * Properties to be use in the construction of the triangulation.
+     */
+    Settings settings;
+  };
+
+
+  /**
+   * A namespace for TriangulationDescription::Description utility functions.
+   *
+   * @ingroup TriangulationDescription
+   */
+  namespace Utilities
+  {
+    /**
+     * Construct TriangulationDescription::Description from a given
+     * partitioned triangulation `tria` and a specified process.
+     * The input triangulation can be either
+     * a serial triangulation of type dealii::Triangulation which has been
+     * colored (subdomain_id and/or level_subdomain_id has been set) or a
+     * distributed triangulation of type dealii::distributed::Triangulation,
+     * where the partitioning is adopted unaltered.
+     *
+     * @param tria Partitioned input triangulation.
+     * @param comm MPI_Communicator to be used. In the case
+     *             of dealii::distributed::Triangulation, the communicators
+     *             have to match.
+     * @param construct_multilevel_hierarchy Signal if the multigrid levels
+     *        should be constructed.
+     * @param my_rank_in Construct Description for this rank (only
+     *                   working for serial triangulations).
+     * @return Description to be used to setup a Triangulation.
+     *
+     * @note Multilevel hierarchies are supported if it is enabled in
+     *       parallel::fullydistributed::Triangulation.
+     *
+     * @note Hanging nodes in the input triangulation are supported. However,
+     *       to be able to use this
+     *       feature in the case of parallel::fullydistributed::Triangulation,
+     *       the user has to enable multilevel hierarchy support in
+     *       parallel::fullydistributed::Triangulation.
+     *
+     * @author Peter Munch, 2019
+     */
+    template <int dim, int spacedim = dim>
+    Description<dim, spacedim>
+    create_description_from_triangulation(
+      const dealii::Triangulation<dim, spacedim> &tria,
+      const MPI_Comm                              comm,
+      const bool         construct_multilevel_hierarchy = false,
+      const unsigned int my_rank_in = numbers::invalid_unsigned_int);
+
+
+    /**
+     * Construct a construction::Description. In contrast
+     * to the function above, this function is also responsible for creating
+     * a serial triangulation and for its partitioning (by calling the
+     * provided std::functions). Internally only selected processes (every
+     * n-th/each root of a group of size group_size) create a serial
+     * triangulation and the ConstructionData for all processes in its group,
+     * which is communicated.
+     *
+     * @note A reasonable group size is the size of a NUMA domain or the
+     * size of a compute node.
+     *
+     * @param serial_grid_generator A function, which creates a serial triangulation.
+     * @param serial_grid_partitioner A function, which can partition a serial
+     *        triangulation, i.e., sets the sudomain_ids of the active cells.
+     *        The function takes as the first argument a serial triangulation,
+     *        as the second argument the MPI communicator, and as the third
+     *        argument the group size.
+     * @param comm MPI communicator
+     * @param group_size The size of each group.
+     * @param construct_multilevel_hierarchy Construct multigrid levels.
+     * @return Description to be used to setup a Triangulation.
+     *
+     * @author Peter Munch, 2019
+     */
+    template <int dim, int spacedim = dim>
+    Description<dim, spacedim>
+    create_description_from_triangulation_in_groups(
+      const std::function<void(dealii::Triangulation<dim, spacedim> &)>
+        &                                            serial_grid_generator,
+      const std::function<void(dealii::Triangulation<dim, spacedim> &,
+                               const MPI_Comm,
+                               const unsigned int)> &serial_grid_partitioner,
+      const MPI_Comm                                 comm,
+      const int                                      group_size = 1,
+      const bool construct_multilevel_hierarchy                 = false);
+
+  } // namespace Utilities
+
+
+
+  template <int dim>
+  template <class Archive>
+  void
+  CellData<dim>::serialize(Archive &ar, const unsigned int /*version*/)
+  {
+    ar &id;
+    ar &subdomain_id;
+    ar &level_subdomain_id;
+    ar &manifold_id;
+    if (dim >= 2)
+      ar &manifold_line_ids;
+    if (dim >= 3)
+      ar &manifold_quad_ids;
+    ar &boundary_ids;
+  }
+
+
+  template <int dim, int spacedim>
+  template <class Archive>
+  void
+  Description<dim, spacedim>::serialize(Archive &ar,
+                                        const unsigned int /*version*/)
+  {
+    ar &coarse_cells;
+    ar &coarse_cell_vertices;
+    ar &coarse_cell_index_to_coarse_cell_id;
+    ar &cell_infos;
+    ar &settings;
+  }
+
+
+
+  template <int dim>
+  bool
+  CellData<dim>::operator==(const CellData<dim> &other) const
+  {
+    if (this->id != other.id)
+      return false;
+    if (this->subdomain_id != other.subdomain_id)
+      return false;
+    if (this->level_subdomain_id != other.level_subdomain_id)
+      return false;
+    if (this->manifold_id != other.manifold_id)
+      return false;
+    if (dim >= 2 && this->manifold_line_ids != other.manifold_line_ids)
+      return false;
+    if (dim >= 3 && this->manifold_quad_ids != other.manifold_quad_ids)
+      return false;
+    if (this->boundary_ids != other.boundary_ids)
+      return false;
+
+    return true;
+  }
+
+
+
+  template <int dim, int spacedim>
+  bool
+  Description<dim, spacedim>::
+  operator==(const Description<dim, spacedim> &other) const
+  {
+    if (this->coarse_cells != other.coarse_cells)
+      return false;
+    if (this->coarse_cell_vertices != other.coarse_cell_vertices)
+      return false;
+    if (this->coarse_cell_index_to_coarse_cell_id !=
+        other.coarse_cell_index_to_coarse_cell_id)
+      return false;
+    if (this->cell_infos != other.cell_infos)
+      return false;
+    if (this->settings != other.settings)
+      return false;
+
+    return true;
+  }
+} // namespace TriangulationDescription
+
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
index 358bbe16f17036ccaea1c313bafc9e529c2810cc..06ff3ee3af8e1b03a74cceed21a6cffc5f15930c 100644 (file)
@@ -20,7 +20,6 @@ SET(_unity_include_src
   cell_weights.cc
   cell_data_transfer.cc
   fully_distributed_tria.cc
-  fully_distributed_tria_util.cc
   solution_transfer.cc
   tria.cc
   tria_base.cc
@@ -45,7 +44,6 @@ SET(_inst
   cell_weights.inst.in
   cell_data_transfer.inst.in
   fully_distributed_tria.inst.in
-  fully_distributed_tria_util.inst.in
   solution_transfer.inst.in
   tria.inst.in
   shared_tria.inst.in
index 080c0fd2fc734fb31e5828f0d9721e18e6d13d69..247363b0307c8c61ba38aed50c7f1b23e0ea8965 100644 (file)
@@ -18,7 +18,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 
 #include <deal.II/grid/grid_tools.h>
 
@@ -42,7 +41,7 @@ namespace parallel
     template <int dim, int spacedim>
     Triangulation<dim, spacedim>::Triangulation(MPI_Comm mpi_communicator)
       : parallel::DistributedTriangulationBase<dim, spacedim>(mpi_communicator)
-      , settings(Settings::default_setting)
+      , settings(TriangulationDescription::Settings::default_setting)
       , partitioner([](dealii::Triangulation<dim, spacedim> &tria,
                        const unsigned int                    n_partitions) {
         GridTools::partition_triangulation_zorder(n_partitions, tria);
@@ -57,7 +56,8 @@ namespace parallel
     template <int dim, int spacedim>
     void
     Triangulation<dim, spacedim>::create_triangulation(
-      const ConstructionData<dim, spacedim> &construction_data)
+      const TriangulationDescription::Description<dim, spacedim>
+        &construction_data)
     {
       // check if the communicator of this parallel triangulation has been used
       // to construct the ConstructionData
@@ -68,7 +68,8 @@ namespace parallel
       settings = construction_data.settings;
 
       // set the smoothing properties
-      if (settings & construct_multigrid_hierarchy)
+      if (settings &
+          TriangulationDescription::Settings::construct_multigrid_hierarchy)
         this->set_mesh_smoothing(
           static_cast<
             typename dealii::Triangulation<dim, spacedim>::MeshSmoothing>(
@@ -123,110 +124,19 @@ namespace parallel
           for (auto i : coarse_cell_id_to_coarse_cell_index_vector)
             this->coarse_cell_id_to_coarse_cell_index_vector.emplace_back(i);
 
-          // 3) create coarse grid
-          dealii::parallel::Triangulation<dim, spacedim>::create_triangulation(
-            construction_data.coarse_cell_vertices,
-            construction_data.coarse_cells,
-            SubCellData());
-
-          Assert(this->n_cells() ==
-                   this->coarse_cell_id_to_coarse_cell_index_vector.size(),
-                 ExcInternalError());
-          Assert(this->n_cells() ==
-                   this->coarse_cell_index_to_coarse_cell_id_vector.size(),
-                 ExcInternalError());
+          // create locally-relevant
+          currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
+            true;
+          currently_processing_create_triangulation_for_internal_usage = true;
+          dealii::Triangulation<dim, spacedim>::create_triangulation(
+            construction_data);
+          currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
+            false;
+          currently_processing_create_triangulation_for_internal_usage = false;
 
           // create a copy of cell_infos such that we can sort them
           auto cell_infos = construction_data.cell_infos;
 
-          // sort cell_infos on each level separately
-          for (auto &cell_info : cell_infos)
-            std::sort(cell_info.begin(),
-                      cell_info.end(),
-                      [&](CellData<dim> a, CellData<dim> b) {
-                        const CellId a_id(a.id);
-                        const CellId b_id(b.id);
-
-                        const auto a_coarse_cell_index =
-                          this->coarse_cell_id_to_coarse_cell_index(
-                            a_id.get_coarse_cell_id());
-                        const auto b_coarse_cell_index =
-                          this->coarse_cell_id_to_coarse_cell_index(
-                            b_id.get_coarse_cell_id());
-
-                        // according to their coarse-cell index and if that is
-                        // same according to their cell id (the result is that
-                        // cells on each level are sorted according to their
-                        // index on that level - what we need in the following
-                        // operations)
-                        if (a_coarse_cell_index != b_coarse_cell_index)
-                          return a_coarse_cell_index < b_coarse_cell_index;
-                        else
-                          return a_id < b_id;
-                      });
-
-          // 4) create all levels via a sequence of refinements
-          for (unsigned int level = 0; level < cell_infos.size(); ++level)
-            {
-              // a) set manifold ids here (because new vertices have to be
-              //    positioned correctly during each refinement step)
-              {
-                auto cell      = this->begin(level);
-                auto cell_info = cell_infos[level].begin();
-                for (; cell_info != cell_infos[level].end(); ++cell_info)
-                  {
-                    while (cell_info->id !=
-                           cell->id().template to_binary<dim>())
-                      ++cell;
-                    if (spacedim == 3)
-                      for (unsigned int quad = 0;
-                           quad < GeometryInfo<spacedim>::quads_per_cell;
-                           ++quad)
-                        cell->quad(quad)->set_manifold_id(
-                          cell_info->manifold_quad_ids[quad]);
-
-                    if (spacedim >= 2)
-                      for (unsigned int line = 0;
-                           line < GeometryInfo<spacedim>::lines_per_cell;
-                           ++line)
-                        cell->line(line)->set_manifold_id(
-                          cell_info->manifold_line_ids[line]);
-
-                    cell->set_manifold_id(cell_info->manifold_id);
-                  }
-              }
-
-              // b) perform refinement on all levels but on the finest
-              if (level + 1 != cell_infos.size())
-                {
-                  // find cells that should have children and mark them for
-                  // refinement
-                  auto coarse_cell    = this->begin(level);
-                  auto fine_cell_info = cell_infos[level + 1].begin();
-
-                  // loop over all cells on the next level
-                  for (; fine_cell_info != cell_infos[level + 1].end();
-                       ++fine_cell_info)
-                    {
-                      // find the parent of that cell
-                      while (!coarse_cell->id().is_parent_of(
-                        CellId(fine_cell_info->id)))
-                        ++coarse_cell;
-
-                      // set parent for refinement
-                      coarse_cell->set_refine_flag();
-                    }
-
-                  // execute refinement
-                  currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
-                    true;
-                  dealii::Triangulation<dim, spacedim>::
-                    execute_coarsening_and_refinement();
-                  currently_processing_prepare_coarsening_and_refinement_for_internal_usage =
-                    false;
-                }
-            }
-
           // 4a) set all cells artificial (and set the actual
           //     (level_)subdomain_ids in the next step)
           for (auto cell = this->begin(); cell != this->end(); ++cell)
@@ -239,7 +149,7 @@ namespace parallel
                 dealii::numbers::artificial_subdomain_id);
             }
 
-          // 4b) set actual (level_)subdomain_ids as well as boundary ids
+          // 4b) set actual (level_)subdomain_ids
           for (unsigned int level = 0; level < cell_infos.size(); ++level)
             {
               auto cell      = this->begin(level);
@@ -255,16 +165,9 @@ namespace parallel
                     cell->set_subdomain_id(cell_info->subdomain_id);
 
                   // level subdomain id
-                  if (settings & construct_multigrid_hierarchy)
+                  if (settings & TriangulationDescription::Settings::
+                                   construct_multigrid_hierarchy)
                     cell->set_level_subdomain_id(cell_info->level_subdomain_id);
-
-                  // boundary ids
-                  for (auto pair : cell_info->boundary_ids)
-                    {
-                      Assert(cell->at_boundary(pair.first),
-                             ExcMessage("Cell face is not on the boundary!"));
-                      cell->face(pair.first)->set_boundary_id(pair.second);
-                    }
                 }
             }
         }
@@ -336,8 +239,8 @@ namespace parallel
         }
 
       // create construction data
-      const auto construction_data =
-        Utilities::create_construction_data_from_triangulation(
+      const auto construction_data = TriangulationDescription::Utilities::
+        create_description_from_triangulation(
           *other_tria_ptr,
           this->mpi_communicator,
           this->is_multilevel_hierarchy_constructed());
@@ -353,7 +256,7 @@ namespace parallel
     Triangulation<dim, spacedim>::set_partitioner(
       const std::function<void(dealii::Triangulation<dim, spacedim> &,
                                const unsigned int)> &partitioner,
-      const Settings &                               settings)
+      const TriangulationDescription::Settings &     settings)
     {
       this->partitioner = partitioner;
       this->settings    = settings;
@@ -367,7 +270,8 @@ namespace parallel
     {
       parallel::Triangulation<dim, spacedim>::update_number_cache();
 
-      if (settings & construct_multigrid_hierarchy)
+      if (settings &
+          TriangulationDescription::Settings::construct_multigrid_hierarchy)
         parallel::Triangulation<dim, spacedim>::fill_level_ghost_owners();
     }
 
@@ -426,7 +330,9 @@ namespace parallel
     bool
     Triangulation<dim, spacedim>::is_multilevel_hierarchy_constructed() const
     {
-      return (settings & construct_multigrid_hierarchy);
+      return (
+        settings &
+        TriangulationDescription::Settings::construct_multigrid_hierarchy);
     }
 
 
index c12179d6a1dd13b9aa97a052280d8b16f4a7ca1d..31cdf26447b8c9ced9d744d028e26f51e46f9e62 100644 (file)
@@ -380,6 +380,19 @@ namespace parallel
 
 
 
+    template <int dim, int spacedim>
+    void
+    Triangulation<dim, spacedim>::create_triangulation(
+      const TriangulationDescription::Description<dim, spacedim>
+        &construction_data)
+    {
+      (void)construction_data;
+
+      Assert(false, ExcInternalError());
+    }
+
+
+
     template <int dim, int spacedim>
     void
     Triangulation<dim, spacedim>::copy_triangulation(
index d0b98421c369e6f360876fbf7b2df054eedf2520..02d22bc7db9f62acd67a0ed87e7a1b67b8a8763d 100644 (file)
@@ -2215,6 +2215,20 @@ namespace parallel
     }
 
 
+
+    template <int dim, int spacedim>
+    void
+    Triangulation<dim, spacedim>::create_triangulation(
+      const TriangulationDescription::Description<dim, spacedim>
+        &construction_data)
+    {
+      (void)construction_data;
+
+      Assert(false, ExcInternalError());
+    }
+
+
+
     // This anonymous namespace contains utility for
     // the function Triangulation::communicate_locally_moved_vertices
     namespace CommunicateLocallyMovedVertices
index d23cd2d9fcae49d2a37bb6fac293098c9f1f4a77..5fe419f85633ff5a5bfec7e57c368215d6fc6423 100644 (file)
@@ -28,6 +28,7 @@ SET(_unity_include_src
   manifold_lib.cc
   persistent_tria.cc
   tria_accessor.cc
+  tria_description.cc
   tria_faces.cc
   tria_levels.cc
   tria_objects.cc
@@ -63,6 +64,7 @@ SET(_inst
   manifold.inst.in
   manifold_lib.inst.in
   tria_accessor.inst.in
+  tria_description.inst.in
   tria.inst.in
   tria_objects.inst.in
   )
index 6a8e49366c2032b4d16e7dd163ec6e1be60f3915..a0515b9fbd70548ef59dba45959bd8372da0f277 100644 (file)
@@ -145,6 +145,18 @@ PersistentTriangulation<dim, spacedim>::create_triangulation(
 
 
 
+template <int dim, int spacedim>
+void
+PersistentTriangulation<dim, spacedim>::create_triangulation(
+  const TriangulationDescription::Description<dim, spacedim> &construction_data)
+{
+  (void)construction_data;
+
+  Assert(false, ExcInternalError());
+}
+
+
+
 template <int dim, int spacedim>
 void
 PersistentTriangulation<dim, spacedim>::create_triangulation_compatibility(
index e3fe1d7f6e5adf212d63ef375fa52d0f18e12b14..94beff75822c5a331cadf7d42751a8d118f41c9a 100644 (file)
@@ -10744,6 +10744,125 @@ Triangulation<dim, spacedim>::create_triangulation(
 
 
 
+template <int dim, int spacedim>
+void
+Triangulation<dim, spacedim>::create_triangulation(
+  const TriangulationDescription::Description<dim, spacedim> &construction_data)
+{
+  // 1) create coarse grid
+  create_triangulation(construction_data.coarse_cell_vertices,
+                       construction_data.coarse_cells,
+                       SubCellData());
+
+  // create a copy of cell_infos such that we can sort them
+  auto cell_infos = construction_data.cell_infos;
+
+  // sort cell_infos on each level separately
+  for (auto &cell_info : cell_infos)
+    std::sort(
+      cell_info.begin(),
+      cell_info.end(),
+      [&](TriangulationDescription::CellData<dim> a,
+          TriangulationDescription::CellData<dim> b) {
+        const CellId a_id(a.id);
+        const CellId b_id(b.id);
+
+        const auto a_coarse_cell_index =
+          this->coarse_cell_id_to_coarse_cell_index(a_id.get_coarse_cell_id());
+        const auto b_coarse_cell_index =
+          this->coarse_cell_id_to_coarse_cell_index(b_id.get_coarse_cell_id());
+
+        // according to their coarse-cell index and if that is
+        // same according to their cell id (the result is that
+        // cells on each level are sorted according to their
+        // index on that level - what we need in the following
+        // operations)
+        if (a_coarse_cell_index != b_coarse_cell_index)
+          return a_coarse_cell_index < b_coarse_cell_index;
+        else
+          return a_id < b_id;
+      });
+
+  // 2) create all levels via a sequence of refinements
+  for (unsigned int level = 0; level < cell_infos.size(); ++level)
+    {
+      // a) set manifold ids here (because new vertices have to be
+      //    positioned correctly during each refinement step)
+      {
+        auto cell      = this->begin(level);
+        auto cell_info = cell_infos[level].begin();
+        for (; cell_info != cell_infos[level].end(); ++cell_info)
+          {
+            while (cell_info->id != cell->id().template to_binary<dim>())
+              ++cell;
+            if (spacedim == 3)
+              for (unsigned int quad = 0;
+                   quad < GeometryInfo<spacedim>::quads_per_cell;
+                   ++quad)
+                cell->quad(quad)->set_manifold_id(
+                  cell_info->manifold_quad_ids[quad]);
+
+            if (spacedim >= 2)
+              for (unsigned int line = 0;
+                   line < GeometryInfo<spacedim>::lines_per_cell;
+                   ++line)
+                cell->line(line)->set_manifold_id(
+                  cell_info->manifold_line_ids[line]);
+
+            cell->set_manifold_id(cell_info->manifold_id);
+          }
+      }
+
+      // b) perform refinement on all levels but on the finest
+      if (level + 1 != cell_infos.size())
+        {
+          // find cells that should have children and mark them for
+          // refinement
+          auto coarse_cell    = this->begin(level);
+          auto fine_cell_info = cell_infos[level + 1].begin();
+
+          // loop over all cells on the next level
+          for (; fine_cell_info != cell_infos[level + 1].end();
+               ++fine_cell_info)
+            {
+              // find the parent of that cell
+              while (
+                !coarse_cell->id().is_parent_of(CellId(fine_cell_info->id)))
+                ++coarse_cell;
+
+              // set parent for refinement
+              coarse_cell->set_refine_flag();
+            }
+
+          // execute refinement
+          dealii::Triangulation<dim,
+                                spacedim>::execute_coarsening_and_refinement();
+        }
+    }
+
+  // 3) set boundary ids
+  for (unsigned int level = 0; level < cell_infos.size(); ++level)
+    {
+      auto cell      = this->begin(level);
+      auto cell_info = cell_infos[level].begin();
+      for (; cell_info != cell_infos[level].end(); ++cell_info)
+        {
+          // find cell that has the correct cell
+          while (cell_info->id != cell->id().template to_binary<dim>())
+            ++cell;
+
+          // boundary ids
+          for (auto pair : cell_info->boundary_ids)
+            {
+              Assert(cell->at_boundary(pair.first),
+                     ExcMessage("Cell face is not on the boundary!"));
+              cell->face(pair.first)->set_boundary_id(pair.second);
+            }
+        }
+    }
+}
+
+
 template <int dim, int spacedim>
 void
 Triangulation<dim, spacedim>::flip_all_direction_flags()
diff --git a/source/grid/tria_description.cc b/source/grid/tria_description.cc
new file mode 100644 (file)
index 0000000..da532e6
--- /dev/null
@@ -0,0 +1,662 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/base/geometry_info.h>
+#include <deal.II/base/mpi.h>
+
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_handler.h>
+
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace TriangulationDescription
+{
+  namespace Utilities
+  {
+    namespace
+    {
+      /**
+       * Set the user_flag of a cell and of all its parent cells.
+       */
+      template <int dim, int spacedim>
+      void
+      set_user_flag_reverse(TriaIterator<CellAccessor<dim, spacedim>> cell)
+      {
+        cell->set_user_flag();
+        if (cell->level() != 0)
+          set_user_flag_reverse(cell->parent());
+      }
+
+
+      /**
+       * Convert the binary representation of a CellId to coarse-cell id as
+       * if the finest level were the coarsest level ("level coarse-grid id").
+       */
+      template <int dim>
+      types::coarse_cell_id
+      convert_cell_id_binary_type_to_level_coarse_cell_id(
+        const typename CellId::binary_type &binary_representation)
+      {
+        // exploiting the structure of CellId::binary_type
+        // see also the documentation of CellId
+
+        // actual coarse-grid id
+        const unsigned int coarse_cell_id  = binary_representation[0];
+        const unsigned int n_child_indices = binary_representation[1] >> 2;
+
+        const unsigned int children_per_value =
+          sizeof(CellId::binary_type::value_type) * 8 / dim;
+        unsigned int child_level  = 0;
+        unsigned int binary_entry = 2;
+
+        // path to the get to the cell
+        std::vector<unsigned int> cell_indices;
+        while (child_level < n_child_indices)
+          {
+            Assert(binary_entry < binary_representation.size(),
+                   ExcInternalError());
+
+            for (unsigned int j = 0; j < children_per_value; ++j)
+              {
+                unsigned int cell_index =
+                  (((binary_representation[binary_entry] >> (j * dim))) &
+                   (GeometryInfo<dim>::max_children_per_cell - 1));
+                cell_indices.push_back(cell_index);
+                ++child_level;
+                if (child_level == n_child_indices)
+                  break;
+              }
+            ++binary_entry;
+          }
+
+        // compute new coarse-grid id: c_{i+1} = c_{i}*2^dim + q;
+        types::coarse_cell_id level_coarse_cell_id = coarse_cell_id;
+        for (auto i : cell_indices)
+          level_coarse_cell_id =
+            level_coarse_cell_id * GeometryInfo<dim>::max_children_per_cell + i;
+
+        return level_coarse_cell_id;
+      }
+    } // namespace
+
+
+    template <int dim, int spacedim>
+    Description<dim, spacedim>
+    create_description_from_triangulation(
+      const dealii::Triangulation<dim, spacedim> &tria,
+      const MPI_Comm                              comm,
+      const bool         construct_multilevel_hierarchy,
+      const unsigned int my_rank_in)
+    {
+      if (auto tria_pdt = dynamic_cast<
+            const parallel::distributed::Triangulation<dim, spacedim> *>(&tria))
+        AssertThrow(comm == tria_pdt->get_communicator(),
+                    ExcMessage("MPI communicators do not match."));
+
+      // First, figure out for what rank we are supposed to build the
+      // ConstructionData object
+      unsigned int my_rank = my_rank_in;
+      AssertThrow(my_rank == numbers::invalid_unsigned_int ||
+                    my_rank < dealii::Utilities::MPI::n_mpi_processes(comm),
+                  ExcMessage(
+                    "Rank has to be smaller than available processes."));
+
+      if (auto tria_pdt = dynamic_cast<
+            const parallel::distributed::Triangulation<dim, spacedim> *>(&tria))
+        {
+          AssertThrow(
+            my_rank == numbers::invalid_unsigned_int ||
+              my_rank == dealii::Utilities::MPI::this_mpi_process(comm),
+            ExcMessage(
+              "If parallel::distributed::Triangulation as source triangulation, my_rank has to equal global rank."));
+
+          my_rank = dealii::Utilities::MPI::this_mpi_process(comm);
+        }
+      else if (auto tria_serial =
+                 dynamic_cast<const dealii::Triangulation<dim, spacedim> *>(
+                   &tria))
+        {
+          if (my_rank == numbers::invalid_unsigned_int)
+            my_rank = dealii::Utilities::MPI::this_mpi_process(comm);
+        }
+      else
+        {
+          AssertThrow(
+            false, ExcMessage("This type of triangulation is not supported!"));
+        }
+
+      Description<dim, spacedim> construction_data;
+
+      // store the communicator
+      construction_data.comm = comm;
+
+
+      std::map<unsigned int, std::vector<unsigned int>>
+                                           coinciding_vertex_groups;
+      std::map<unsigned int, unsigned int> vertex_to_coinciding_vertex_group;
+
+      GridTools::collect_coinciding_vertices(tria,
+                                             coinciding_vertex_groups,
+                                             vertex_to_coinciding_vertex_group);
+
+      // helper function, which collects all vertices belonging to a cell
+      // (also taking into account periodicity)
+      auto add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells =
+        [coinciding_vertex_groups, vertex_to_coinciding_vertex_group](
+          TriaIterator<CellAccessor<dim, spacedim>> &cell,
+          std::vector<bool> &vertices_owned_by_locally_owned_cells) {
+          // add local vertices
+          for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
+               ++v)
+            {
+              vertices_owned_by_locally_owned_cells[cell->vertex_index(v)] =
+                true;
+              const auto coinciding_vertex_group =
+                vertex_to_coinciding_vertex_group.find(cell->vertex_index(v));
+              if (coinciding_vertex_group !=
+                  vertex_to_coinciding_vertex_group.end())
+                for (const auto &co_vertex : coinciding_vertex_groups.at(
+                       coinciding_vertex_group->second))
+                  vertices_owned_by_locally_owned_cells[co_vertex] = true;
+            }
+        };
+
+      // check if multilevel hierarchy should be constructed
+      if (construct_multilevel_hierarchy == false)
+        {
+          AssertThrow(
+            tria.has_hanging_nodes() == false,
+            ExcMessage(
+              "Hanging nodes are only supported if multilevel hierarchy is constructed!"));
+
+          construction_data.settings =
+            TriangulationDescription::Settings::default_setting;
+
+          // 1) collect vertices of active locally owned cells
+          std::vector<bool> vertices_owned_by_locally_owned_cells(
+            tria.n_vertices());
+          for (auto cell : tria.cell_iterators())
+            if (cell->is_active() && cell->subdomain_id() == my_rank)
+              add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
+                cell, vertices_owned_by_locally_owned_cells);
+
+          // helper function to determine if cell is locally relevant
+          // (i.e. a cell which is connected to a vertex via a locally owned
+          // active cell)
+          auto is_locally_relevant = [&](
+                                       TriaIterator<CellAccessor<dim, spacedim>>
+                                         &cell) {
+            for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
+                 ++v)
+              if (vertices_owned_by_locally_owned_cells[cell->vertex_index(v)])
+                return true;
+            return false;
+          };
+
+          // 2) process all local and ghost cells: set up needed data
+          // structures and collect all locally relevant vertices
+          // for second sweep
+          std::map<unsigned int, unsigned int> vertices_locally_relevant;
+          construction_data.cell_infos.resize(1);
+
+          for (auto cell : tria.cell_iterators())
+            if (cell->is_active() && is_locally_relevant(cell))
+              {
+                // to be filled
+                CellData<dim> cell_info;
+
+                // a) extract cell definition (with old numbering of
+                // vertices)
+                dealii::CellData<dim> cell_data;
+                cell_data.material_id = cell->material_id();
+                cell_data.manifold_id = cell->manifold_id();
+                for (unsigned int v = 0;
+                     v < GeometryInfo<dim>::vertices_per_cell;
+                     ++v)
+                  cell_data.vertices[v] = cell->vertex_index(v);
+                construction_data.coarse_cells.push_back(cell_data);
+
+                // b) save indices of each vertex of this cell
+                for (unsigned int v = 0;
+                     v < GeometryInfo<dim>::vertices_per_cell;
+                     ++v)
+                  vertices_locally_relevant[cell->vertex_index(v)] =
+                    numbers::invalid_unsigned_int;
+
+                // c) save boundary_ids of each face of this cell
+                for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell;
+                     ++f)
+                  {
+                    types::boundary_id boundary_ind =
+                      cell->face(f)->boundary_id();
+                    if (boundary_ind != numbers::internal_face_boundary_id)
+                      cell_info.boundary_ids.emplace_back(f, boundary_ind);
+                  }
+
+                // d) compute a new coarse-cell id (by ignoring all parent
+                // level)
+                types::coarse_cell_id new_coarse_cell_id =
+                  convert_cell_id_binary_type_to_level_coarse_cell_id<dim>(
+                    cell->id().template to_binary<dim>());
+
+                //    store the coarse cell id
+                cell_info.id = CellId(new_coarse_cell_id, 0, nullptr)
+                                 .template to_binary<dim>();
+
+                //    save coarse_cell_index -> coarse_cell_id mapping
+                construction_data.coarse_cell_index_to_coarse_cell_id.push_back(
+                  new_coarse_cell_id);
+
+                // e) store manifold id of cell
+                cell_info.manifold_id = cell->manifold_id();
+
+                // ... of lines
+                if (dim >= 2)
+                  for (unsigned int line = 0;
+                       line < GeometryInfo<dim>::lines_per_cell;
+                       ++line)
+                    cell_info.manifold_line_ids[line] =
+                      cell->line(line)->manifold_id();
+
+                // ... of quads
+                if (dim == 3)
+                  for (unsigned int quad = 0;
+                       quad < GeometryInfo<dim>::quads_per_cell;
+                       ++quad)
+                    cell_info.manifold_quad_ids[quad] =
+                      cell->quad(quad)->manifold_id();
+
+                // f) store subdomain_id
+                cell_info.subdomain_id = cell->subdomain_id();
+
+                // g) store invalid level_subdomain_id (since multilevel
+                //    hierarchy is not constructed)
+                cell_info.level_subdomain_id = numbers::invalid_subdomain_id;
+
+                construction_data.cell_infos[0].emplace_back(cell_info);
+              }
+
+          // 3) enumerate locally relevant vertices
+          unsigned int vertex_counter = 0;
+          for (auto &vertex : vertices_locally_relevant)
+            {
+              construction_data.coarse_cell_vertices.push_back(
+                tria.get_vertices()[vertex.first]);
+              vertex.second = vertex_counter++;
+            }
+
+          // 4) correct vertices of cells (make them local)
+          for (auto &cell : construction_data.coarse_cells)
+            for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
+                 ++v)
+              cell.vertices[v] = vertices_locally_relevant[cell.vertices[v]];
+        }
+      else
+        {
+          construction_data.settings =
+            TriangulationDescription::Settings::construct_multigrid_hierarchy;
+
+          // 1) collect locally relevant cells (set user_flag)
+          std::vector<bool> old_user_flags;
+          tria.save_user_flags(old_user_flags);
+
+          // 1a) clear user_flags
+          const_cast<dealii::Triangulation<dim, spacedim> &>(tria)
+            .clear_user_flags();
+
+          // 1b) loop over levels (from fine to coarse) and mark on each level
+          //     the locally relevant cells
+          for (unsigned int level =
+                 tria.get_triangulation().n_global_levels() - 1;
+               level != numbers::invalid_unsigned_int;
+               level--)
+            {
+              // collect vertices connected to a (on any level) locally owned
+              // cell
+              std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
+                tria.n_vertices());
+              for (auto cell : tria.cell_iterators_on_level(level))
+                if (cell->level_subdomain_id() == my_rank ||
+                    (cell->active() && cell->subdomain_id() == my_rank))
+                  add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
+                    cell, vertices_owned_by_locally_owned_cells_on_level);
+
+              for (auto cell : tria.active_cell_iterators())
+                if (cell->subdomain_id() == my_rank)
+                  add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
+                    cell, vertices_owned_by_locally_owned_cells_on_level);
+
+              // helper function to determine if cell is locally relevant
+              // (i.e. a cell which is connected to a vertex via a locally
+              // owned cell)
+              auto is_locally_relevant_on_level =
+                [&](TriaIterator<CellAccessor<dim, spacedim>> &cell) {
+                  for (unsigned int v = 0;
+                       v < GeometryInfo<dim>::vertices_per_cell;
+                       ++v)
+                    if (vertices_owned_by_locally_owned_cells_on_level
+                          [cell->vertex_index(v)])
+                      return true;
+                  return false;
+                };
+
+              // mark all locally relevant cells
+              for (auto cell : tria.cell_iterators_on_level(level))
+                if (is_locally_relevant_on_level(cell))
+                  set_user_flag_reverse(cell);
+            }
+
+          // 2) set_up coarse-grid triangulation
+          {
+            std::map<unsigned int, unsigned int> vertices_locally_relevant;
+
+            // a) loop over all cells
+            for (auto cell : tria.cell_iterators_on_level(0))
+              {
+                if (!cell->user_flag_set())
+                  continue;
+
+                // extract cell definition (with old numbering of vertices)
+                dealii::CellData<dim> cell_data;
+                cell_data.material_id = cell->material_id();
+                cell_data.manifold_id = cell->manifold_id();
+                for (unsigned int v = 0;
+                     v < GeometryInfo<dim>::vertices_per_cell;
+                     ++v)
+                  cell_data.vertices[v] = cell->vertex_index(v);
+                construction_data.coarse_cells.push_back(cell_data);
+
+                // save indices of each vertex of this cell
+                for (unsigned int v = 0;
+                     v < GeometryInfo<dim>::vertices_per_cell;
+                     ++v)
+                  vertices_locally_relevant[cell->vertex_index(v)] =
+                    numbers::invalid_unsigned_int;
+
+                // save translation for corase grid: lid -> gid
+                construction_data.coarse_cell_index_to_coarse_cell_id.push_back(
+                  cell->id().get_coarse_cell_id());
+              }
+
+            // b) enumerate locally relevant vertices
+            unsigned int vertex_counter = 0;
+            for (auto &vertex : vertices_locally_relevant)
+              {
+                construction_data.coarse_cell_vertices.push_back(
+                  tria.get_vertices()[vertex.first]);
+                vertex.second = vertex_counter++;
+              }
+
+            // c) correct vertices of cells (make them local)
+            for (auto &cell : construction_data.coarse_cells)
+              for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
+                   ++v)
+                cell.vertices[v] = vertices_locally_relevant[cell.vertices[v]];
+          }
+
+
+          // 3) collect info of each cell
+          construction_data.cell_infos.resize(
+            tria.get_triangulation().n_global_levels());
+
+          // collect local vertices on active level
+          std::vector<bool> vertices_owned_by_locally_owned_active_cells(
+            tria.n_vertices());
+          for (auto cell : tria.active_cell_iterators())
+            if (cell->subdomain_id() == my_rank)
+              add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
+                cell, vertices_owned_by_locally_owned_active_cells);
+
+          // helper function to determine if cell is locally relevant
+          // on active level
+          auto is_locally_relevant_on_active_level =
+            [&](TriaIterator<CellAccessor<dim, spacedim>> &cell) {
+              if (cell->active())
+                for (unsigned int v = 0;
+                     v < GeometryInfo<dim>::vertices_per_cell;
+                     ++v)
+                  if (vertices_owned_by_locally_owned_active_cells
+                        [cell->vertex_index(v)])
+                    return true;
+              return false;
+            };
+
+          for (unsigned int level = 0;
+               level < tria.get_triangulation().n_global_levels();
+               ++level)
+            {
+              // collect local vertices on level
+              std::vector<bool> vertices_owned_by_locally_owned_cells_on_level(
+                tria.n_vertices());
+              for (auto cell : tria.cell_iterators_on_level(level))
+                if (cell->level_subdomain_id() == my_rank ||
+                    (cell->active() && cell->subdomain_id() == my_rank))
+                  add_vertices_of_cell_to_vertices_owned_by_locally_owned_cells(
+                    cell, vertices_owned_by_locally_owned_cells_on_level);
+
+              // helper function to determine if cell is locally relevant
+              // on level
+              auto is_locally_relevant_on_level =
+                [&](TriaIterator<CellAccessor<dim, spacedim>> &cell) {
+                  for (unsigned int v = 0;
+                       v < GeometryInfo<dim>::vertices_per_cell;
+                       ++v)
+                    if (vertices_owned_by_locally_owned_cells_on_level
+                          [cell->vertex_index(v)])
+                      return true;
+                  return false;
+                };
+
+              auto &level_cell_infos = construction_data.cell_infos[level];
+              for (auto cell : tria.cell_iterators_on_level(level))
+                {
+                  // check if cell is locally relevant
+                  if (!(cell->user_flag_set()))
+                    continue;
+
+                  CellData<dim> cell_info;
+
+                  // save coarse-cell id
+                  cell_info.id = cell->id().template to_binary<dim>();
+
+                  // save boundary_ids of each face of this cell
+                  for (unsigned int f = 0;
+                       f < GeometryInfo<dim>::faces_per_cell;
+                       ++f)
+                    {
+                      types::boundary_id boundary_ind =
+                        cell->face(f)->boundary_id();
+                      if (boundary_ind != numbers::internal_face_boundary_id)
+                        cell_info.boundary_ids.emplace_back(f, boundary_ind);
+                    }
+
+                  // save manifold id
+                  {
+                    // ... of cell
+                    cell_info.manifold_id = cell->manifold_id();
+
+                    // ... of lines
+                    if (dim >= 2)
+                      for (unsigned int line = 0;
+                           line < GeometryInfo<dim>::lines_per_cell;
+                           ++line)
+                        cell_info.manifold_line_ids[line] =
+                          cell->line(line)->manifold_id();
+
+                    // ... of quads
+                    if (dim == 3)
+                      for (unsigned int quad = 0;
+                           quad < GeometryInfo<dim>::quads_per_cell;
+                           ++quad)
+                        cell_info.manifold_quad_ids[quad] =
+                          cell->quad(quad)->manifold_id();
+                  }
+
+                  // subdomain and level subdomain id
+                  cell_info.subdomain_id = numbers::artificial_subdomain_id;
+                  cell_info.level_subdomain_id =
+                    numbers::artificial_subdomain_id;
+
+                  if (is_locally_relevant_on_active_level(cell))
+                    {
+                      cell_info.level_subdomain_id = cell->level_subdomain_id();
+                      cell_info.subdomain_id       = cell->subdomain_id();
+                    }
+                  else if (is_locally_relevant_on_level(cell))
+                    {
+                      cell_info.level_subdomain_id = cell->level_subdomain_id();
+                    }
+                  // else: cell is locally relevant but an artificial cell
+
+                  level_cell_infos.emplace_back(cell_info);
+                }
+            }
+
+          const_cast<dealii::Triangulation<dim, spacedim> &>(tria)
+            .load_user_flags(old_user_flags);
+        }
+
+      return construction_data;
+    }
+
+
+
+    template <int dim, int spacedim>
+    Description<dim, spacedim>
+    create_description_from_triangulation_in_groups(
+      const std::function<void(dealii::Triangulation<dim, spacedim> &)>
+        &                                            serial_grid_generator,
+      const std::function<void(dealii::Triangulation<dim, spacedim> &,
+                               const MPI_Comm,
+                               const unsigned int)> &serial_grid_partitioner,
+      const MPI_Comm                                 comm,
+      const int                                      group_size,
+      const bool construct_multilevel_hierarchy)
+    {
+#ifndef DEAL_II_WITH_MPI
+      (void)serial_grid_generator;
+      (void)serial_grid_partitioner;
+      (void)comm;
+      (void)group_size;
+      (void)construct_multilevel_hierarchy;
+
+      return Description<dim, spacedim>();
+#else
+      const unsigned int my_rank =
+        dealii::Utilities::MPI::this_mpi_process(comm);
+      const unsigned int group_root = (my_rank / group_size) * group_size;
+
+      const int mpi_tag =
+        dealii::Utilities::MPI::internal::Tags::fully_distributed_create;
+
+      // check if process is root of the group
+      if (my_rank == group_root)
+        {
+          // Step 1: create serial triangulation
+          dealii::Triangulation<dim, spacedim> tria(
+            construct_multilevel_hierarchy ?
+              dealii::Triangulation<dim, spacedim>::none :
+              dealii::Triangulation<dim, spacedim>::
+                limit_level_difference_at_vertices);
+          serial_grid_generator(tria);
+
+          // Step 2: partition active cells and ...
+          serial_grid_partitioner(tria, comm, group_size);
+
+          // ... cells on the levels if multigrid is required
+          if (construct_multilevel_hierarchy)
+            GridTools::partition_multigrid_levels(tria);
+
+          const unsigned int end_group =
+            std::min(group_root + group_size,
+                     dealii::Utilities::MPI::n_mpi_processes(comm));
+
+          // 3) create ConstructionData for the other processes in group
+          for (unsigned int other_rank = group_root + 1; other_rank < end_group;
+               other_rank++)
+            {
+              // 3a) create construction data for other ranks
+              const auto construction_data =
+                create_description_from_triangulation(
+                  tria, comm, construct_multilevel_hierarchy, other_rank);
+              // 3b) pack
+              std::vector<char> buffer;
+              dealii::Utilities::pack(construction_data, buffer, false);
+
+              // 3c) send ConstructionData
+              const auto ierr = MPI_Send(buffer.data(),
+                                         buffer.size(),
+                                         MPI_CHAR,
+                                         other_rank,
+                                         mpi_tag,
+                                         comm);
+              AssertThrowMPI(ierr);
+            }
+
+          // 4) create ConstructionData for this process (root of group)
+          return create_description_from_triangulation(
+            tria, comm, construct_multilevel_hierarchy, my_rank);
+        }
+      else
+        {
+          // 3a) recv packed ConstructionData from group-root process
+          //     (counter-part of 3c of root process)
+          MPI_Status status;
+          auto       ierr = MPI_Probe(group_root, mpi_tag, comm, &status);
+          AssertThrowMPI(ierr);
+
+          int len;
+          MPI_Get_count(&status, MPI_CHAR, &len);
+
+          std::vector<char> buf(len);
+          ierr = MPI_Recv(buf.data(),
+                          len,
+                          MPI_CHAR,
+                          status.MPI_SOURCE,
+                          status.MPI_TAG,
+                          comm,
+                          &status);
+          AssertThrowMPI(ierr);
+
+          // 3b) unpack ConstructionData (counter-part of 3b of root process)
+          auto construction_data =
+            dealii::Utilities::template unpack<Description<dim, spacedim>>(
+              buf, false);
+
+          // WARNING: serialization cannot handle the MPI communicator
+          // which is the reason why we have to set it here explicitly
+          construction_data.comm = comm;
+
+          return construction_data;
+        }
+#endif
+    }
+
+  } // namespace Utilities
+} // namespace TriangulationDescription
+
+
+
+/*-------------- Explicit Instantiations -------------------------------*/
+#include "tria_description.inst"
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/source/grid/tria_description.inst.in b/source/grid/tria_description.inst.in
new file mode 100644 (file)
index 0000000..3c3049a
--- /dev/null
@@ -0,0 +1,48 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2010 - 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+  {
+    namespace TriangulationDescription
+    \{
+      namespace Utilities
+      \{
+#if deal_II_dimension <= deal_II_space_dimension
+        template Description<deal_II_dimension, deal_II_space_dimension>
+        create_description_from_triangulation(
+          const dealii::Triangulation<deal_II_dimension,
+                                      deal_II_space_dimension> &tria,
+          const MPI_Comm                                        comm,
+          const bool         construct_multilevel_hierarchy,
+          const unsigned int my_rank_in);
+
+        template Description<deal_II_dimension, deal_II_space_dimension>
+        create_description_from_triangulation_in_groups(
+          const std::function<void(
+            dealii::Triangulation<deal_II_dimension, deal_II_space_dimension>
+              &)> &               serial_grid_generator,
+          const std::function<void(
+            dealii::Triangulation<deal_II_dimension, deal_II_space_dimension> &,
+            const MPI_Comm,
+            const unsigned int)> &serial_grid_partitioner,
+          const MPI_Comm          comm,
+          const int               group_size,
+          const bool              construct_multilevel_hierarchy);
+#endif
+      \}
+    \}
+  }
index 41e90e8663a38bab97236035538c75d31cae3ed8..40937b7b6ce29b14f2b11570034ee53f80fc6976 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -29,6 +28,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -50,8 +50,9 @@ test(int n_refinements, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(tria_pdt, comm);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      tria_pdt, comm);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 0cc9c3e05f600eb2ab890a5a0c46bde689e59153..26e81d361a6c06745d848d3a5b413931abff3525 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -29,6 +28,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -50,8 +50,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form pdt
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(tria_pdt, comm, true);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      tria_pdt, comm, true);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 67024e98638e779126907af4b2112a7d846e1919..b73dee3bff03200cdef731d422f25ca187920dd1 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -29,6 +28,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -50,8 +50,9 @@ test(int n_refinements, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 93429f131e7f6831920ad3757f134454f4e9fc40..05113f4baecdd8af69209d1a155aad2623439e5c 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -29,6 +28,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -52,8 +52,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm, true);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm, true);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 9d60c7b541bea5205bbf53ad351ea57807c5dc6c..012c5a14a71ef469d9efdb1e7e7777967842a216 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -30,6 +29,7 @@
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/manifold_lib.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -79,8 +79,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm)
   tria_pft.set_manifold(0, SphericalManifold<dim>(center));
 
   // extract relevant information form pdt
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm, true);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm, true);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 673bfcde7a2b3dd0ac8df8114c93a38f6c5f4b00..d5893996b99296b5adc2dcaf41d168691a9cd222 100644 (file)
@@ -19,7 +19,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -29,6 +28,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -93,8 +93,9 @@ test(const int n_refinements, const int n_subdivisions, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 67521b23d010341f5a889a83f3612125712bae21..f4b81116d6d81642b1d0562c84da7fb766c95839 100644 (file)
@@ -20,7 +20,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -30,6 +29,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include "./tests.h"
 
@@ -53,8 +53,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm, true);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm, true);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 2a3367e0eb51ac5f6ba8d8709bc388408f2d13f9..851807ada15dc2aa5eca226618edccc94f802ad5 100644 (file)
@@ -20,7 +20,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -30,6 +29,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include <deal.II/matrix_free/matrix_free.h>
 
@@ -53,8 +53,9 @@ test(int n_refinements, MPI_Comm comm)
   parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
 
   // extract relevant information form serial triangulation
-  auto construction_data = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm);
+  auto construction_data =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm);
 
   // actually create triangulation
   tria_pft.create_triangulation(construction_data);
index 00c4ae4a2355a9346d1fda680ef8105c61d30c30..802f916e5929eb7bd13da3d216c7d4b1792d32c1 100644 (file)
@@ -20,7 +20,6 @@
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -53,7 +52,7 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm)
     [](dealii::Triangulation<dim> &tria, const unsigned int n_partitions) {
       GridTools::partition_triangulation_zorder(n_partitions, tria);
     },
-    parallel::fullydistributed::Settings::construct_multigrid_hierarchy);
+    TriangulationDescription::Settings::construct_multigrid_hierarchy);
 
   // actually create triangulation
   tria_pft.copy_triangulation(basetria);
index f5769e97f6683b0400bbbd84664f5c10e2e17f3e..ecc8d57a2ccdbbf6ffa784f2a7ba8cb8ec94a2fe 100644 (file)
 
 
 // Create the ConstructionData with
-// create_construction_data_from_triangulation_in_groups, i.e. by a set of
+// create_description_from_triangulation_in_groups, i.e. by a set of
 // master processes.
 
 #include <deal.II/base/mpi.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/shared_tria.h>
 #include <deal.II/distributed/tria.h>
 
@@ -31,6 +30,7 @@
 #include <deal.II/grid/grid_out.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include <boost/archive/text_oarchive.hpp>
 
@@ -42,7 +42,7 @@ template <int dim, int spacedim = dim>
 void
 test(int n_refinements, MPI_Comm comm)
 {
-  // 1) create ConstructionData with create_construction_data_from_triangulation
+  // 1) create ConstructionData with create_description_from_triangulation
   Triangulation<dim> basetria(
     Triangulation<dim>::limit_level_difference_at_vertices);
   GridGenerator::hyper_L(basetria);
@@ -52,13 +52,14 @@ test(int n_refinements, MPI_Comm comm)
     Utilities::MPI::n_mpi_processes(comm), basetria);
   GridTools::partition_multigrid_levels(basetria);
 
-  auto construction_data_1 = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm, true);
+  auto construction_data_1 =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm, true);
 
   // 2) create ConstructionData with
-  // create_construction_data_from_triangulation_in_groups
-  auto construction_data_2 = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation_in_groups<dim, spacedim>(
+  // create_description_from_triangulation_in_groups
+  auto construction_data_2 = TriangulationDescription::Utilities::
+    create_description_from_triangulation_in_groups<dim, spacedim>(
       [n_refinements](dealii::Triangulation<dim, spacedim> &tria) {
         GridGenerator::hyper_L(tria);
         tria.refine_global(n_refinements);
index 77c57bcdd9888764445d0e717b2ae1fffd512b3f..9dcf07c6a7bbee28baec8bc8b5450d05b802b36e 100644 (file)
@@ -22,7 +22,6 @@
 #include <deal.II/base/utilities.h>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
@@ -32,6 +31,7 @@
 
 #include <deal.II/grid/grid_generator.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include <deal.II/lac/affine_constraints.h>
 #include <deal.II/lac/la_parallel_vector.h>
@@ -458,8 +458,8 @@ test()
       parallel::fullydistributed::Triangulation<dim> tria_pft(MPI_COMM_WORLD);
 
       // extract relevant information form pdt
-      auto construction_data = parallel::fullydistributed::Utilities::
-        create_construction_data_from_triangulation(tria, MPI_COMM_WORLD, true);
+      auto construction_data = TriangulationDescription::Utilities::
+        create_description_from_triangulation(tria, MPI_COMM_WORLD, true);
 
       // actually create triangulation
       tria_pft.create_triangulation(construction_data);
@@ -486,10 +486,8 @@ test()
         parallel::fullydistributed::Triangulation<dim> tria_pft(MPI_COMM_WORLD);
 
         // extract relevant information form pdt
-        auto construction_data = parallel::fullydistributed::Utilities::
-          create_construction_data_from_triangulation(tria,
-                                                      MPI_COMM_WORLD,
-                                                      true);
+        auto construction_data = TriangulationDescription::Utilities::
+          create_description_from_triangulation(tria, MPI_COMM_WORLD, true);
 
         // actually create triangulation
         tria_pft.create_triangulation(construction_data);
index 67d52e146367caf9ab5cb8d7fed7f7359fb4a394..aa6a030dc453beb28727d65c29d231fd88690cef 100644 (file)
 // check serialization for ConstructionData<dim, spacedim>
 
 #include <deal.II/distributed/fully_distributed_tria.h>
-#include <deal.II/distributed/fully_distributed_tria_util.h>
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/grid/grid_generator.h>
 #include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_description.h>
 
 #include <boost/serialization/vector.hpp>
 
@@ -43,8 +43,9 @@ test(MPI_Comm comm)
   GridTools::partition_triangulation_zorder(
     Utilities::MPI::n_mpi_processes(comm), basetria);
 
-  auto t1 = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm);
+  auto t1 =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm);
 
   // compare equal ConstructionDatas
   auto t2 = t1;
@@ -55,8 +56,9 @@ test(MPI_Comm comm)
   GridTools::partition_triangulation_zorder(
     Utilities::MPI::n_mpi_processes(comm), basetria);
 
-  auto t3 = parallel::fullydistributed::Utilities::
-    create_construction_data_from_triangulation(basetria, comm);
+  auto t3 =
+    TriangulationDescription::Utilities::create_description_from_triangulation(
+      basetria, comm);
 
   // compare different ConstructionDatas
   verify(t1, t3);

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.