From 9f96210d032b26aa003375716f2b9bf22b199990 Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Wed, 25 Dec 2019 23:34:13 +0100 Subject: [PATCH] Create new method dealii::Triangulation::create_triangulation(). --- .../distributed/fully_distributed_tria.h | 258 +------ .../distributed/fully_distributed_tria_util.h | 120 ---- include/deal.II/distributed/shared_tria.h | 10 + include/deal.II/distributed/tria.h | 10 + include/deal.II/grid/persistent_tria.h | 10 + include/deal.II/grid/tria.h | 238 +------ include/deal.II/grid/tria_description.h | 571 +++++++++++++++ source/distributed/CMakeLists.txt | 2 - source/distributed/fully_distributed_tria.cc | 144 +--- source/distributed/shared_tria.cc | 13 + source/distributed/tria.cc | 14 + source/grid/CMakeLists.txt | 2 + source/grid/persistent_tria.cc | 12 + source/grid/tria.cc | 119 ++++ source/grid/tria_description.cc | 662 ++++++++++++++++++ source/grid/tria_description.inst.in | 48 ++ .../copy_distributed_tria_01.cc | 7 +- .../copy_distributed_tria_02.cc | 7 +- .../copy_serial_tria_01.cc | 7 +- .../copy_serial_tria_02.cc | 7 +- .../copy_serial_tria_03.cc | 7 +- .../copy_serial_tria_04.cc | 7 +- .../copy_serial_tria_05.cc | 7 +- .../copy_serial_tria_06.cc | 7 +- .../copy_serial_tria_07.cc | 3 +- .../copy_serial_tria_grouped_01.cc | 17 +- .../parallel_multigrid_fullydistributed.cc | 12 +- ...el_fullydistributed_construction_data_1.cc | 12 +- 28 files changed, 1582 insertions(+), 751 deletions(-) delete mode 100644 include/deal.II/distributed/fully_distributed_tria_util.h create mode 100644 include/deal.II/grid/tria_description.h create mode 100644 source/grid/tria_description.cc create mode 100644 source/grid/tria_description.inst.in diff --git a/include/deal.II/distributed/fully_distributed_tria.h b/include/deal.II/distributed/fully_distributed_tria.h index 7b6a448892..6e4b4c73a4 100644 --- a/include/deal.II/distributed/fully_distributed_tria.h +++ b/include/deal.II/distributed/fully_distributed_tria.h @@ -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 - struct CellData - { - /** - * Constructor. - */ - CellData() = default; - - /** - * Boost serialization function - */ - template - void - serialize(Archive &ar, const unsigned int /*version*/); - - /** - * Comparison operator. - */ - bool - operator==(const CellData &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::lines_per_cell> - manifold_line_ids; - - /** - * Manifold id of all face quads of the cell. - * - * @note Only used for 3D. - */ - std::array::quads_per_cell> - manifold_quad_ids; - - /** - * List of face number and boundary id of all non-internal faces of the - * cell. - */ - std::vector> boundary_ids; - }; - - - - /** - * Data used to construct a fully distributed triangulation in - * parallel::fullydistributed::Triangulation::create_triangulation(). - * - * @author Peter Munch, 2019 - */ - template - struct ConstructionData - { - /** - * Boost serialization function - */ - template - void - serialize(Archive &ar, const unsigned int /*version*/); - - /** - * Comparison operator. - */ - bool - operator==(const ConstructionData &other) const; - - /** - * Cells of the locally-relevant coarse-grid triangulation. - */ - std::vector> coarse_cells; - - /** - * Vertices of the locally-relevant coarse-grid triangulation. - */ - std::vector> coarse_cell_vertices; - - /** - * List that for each locally-relevant coarse cell provides the - * corresponding global @ref GlossCoarseCellId. - */ - std::vector 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>> 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 &construction_data); + const TriangulationDescription::Description + &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> & vertices, @@ -360,7 +195,7 @@ namespace parallel set_partitioner( const std::function &, 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 - template - void - CellData::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 - template - void - ConstructionData::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 - bool - CellData::operator==(const CellData &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 - bool - ConstructionData:: - operator==(const ConstructionData &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 index ee026c9a89..0000000000 --- a/include/deal.II/distributed/fully_distributed_tria_util.h +++ /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 - -#include - -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 - ConstructionData - create_construction_data_from_triangulation( - const dealii::Triangulation &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 - ConstructionData - create_construction_data_from_triangulation_in_groups( - std::function &)> - serial_grid_generator, - std::function &, - 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 diff --git a/include/deal.II/distributed/shared_tria.h b/include/deal.II/distributed/shared_tria.h index b47dc03c83..41295be797 100644 --- a/include/deal.II/distributed/shared_tria.h +++ b/include/deal.II/distributed/shared_tria.h @@ -270,6 +270,16 @@ namespace parallel const std::vector> & cells, const SubCellData &subcelldata) override; + /* + * @copydoc Triangulation::create_triangulation() + * + * @note Not inmplemented yet. + */ + virtual void + create_triangulation( + const TriangulationDescription::Description + &construction_data) override; + /** * Copy @p other_tria to this triangulation. * diff --git a/include/deal.II/distributed/tria.h b/include/deal.II/distributed/tria.h index 04fbe84ab9..35301b54de 100644 --- a/include/deal.II/distributed/tria.h +++ b/include/deal.II/distributed/tria.h @@ -406,6 +406,16 @@ namespace parallel const std::vector> & cells, const SubCellData &subcelldata) override; + /* + * @copydoc Triangulation::create_triangulation() + * + * @note Not inmplemented yet. + */ + virtual void + create_triangulation( + const TriangulationDescription::Description + &construction_data) override; + /** * Coarsen and refine the mesh according to refinement and coarsening * flags set. diff --git a/include/deal.II/grid/persistent_tria.h b/include/deal.II/grid/persistent_tria.h index cf4a45ae21..d7447a2cad 100644 --- a/include/deal.II/grid/persistent_tria.h +++ b/include/deal.II/grid/persistent_tria.h @@ -202,6 +202,16 @@ public: const std::vector> & cells, const SubCellData &subcelldata) override; + /* + * @copydoc Triangulation::create_triangulation() + * + * @note Not inmplemented yet. + */ + virtual void + create_triangulation( + const TriangulationDescription::Description + &construction_data) override; + /** * An overload of the respective function of the base class. * diff --git a/include/deal.II/grid/tria.h b/include/deal.II/grid/tria.h index 428ec19a05..97b4572d52 100644 --- a/include/deal.II/grid/tria.h +++ b/include/deal.II/grid/tria.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -49,6 +50,17 @@ DEAL_II_NAMESPACE_OPEN template class Manifold; +template +struct CellData; + +struct SubCellData; + +namespace TriangulationDescription +{ + template + struct Description; +} + namespace GridTools { template @@ -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 - * create_coarse_grid() function of step-14. There are also - * many more use cases in the implementation of the functions of the - * GridGenerator namespace. - * - * @ingroup grid - */ -template -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::vertices_per_cell]; - - /** - * Material or boundary indicator of this cell. - * This field is a union that stores either 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 &other) const; - - /** - * Boost serialization function - */ - template - 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 necessary 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 interior 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> 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> 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> & 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 + &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 -template -void -CellData::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 index 0000000000..d927f680b5 --- /dev/null +++ b/include/deal.II/grid/tria_description.h @@ -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 + +#include + +#include +#include + + +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 + * create_coarse_grid() function of step-14. There are also + * many more use cases in the implementation of the functions of the + * GridGenerator namespace. + * + * @ingroup grid + */ +template +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::vertices_per_cell]; + + /** + * Material or boundary indicator of this cell. + * This field is a union that stores either 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 &other) const; + + /** + * Boost serialization function + */ + template + 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 necessary 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 interior 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> 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> 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 +template +void +CellData::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 + struct CellData + { + /** + * Constructor. + */ + CellData() = default; + + /** + * Boost serialization function + */ + template + void + serialize(Archive &ar, const unsigned int /*version*/); + + /** + * Comparison operator. + */ + bool + operator==(const CellData &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::lines_per_cell> + manifold_line_ids; + + /** + * Manifold id of all face quads of the cell. + * + * @note Only used for 3D. + */ + std::array::quads_per_cell> + manifold_quad_ids; + + /** + * List of face number and boundary id of all non-internal faces of the + * cell. + */ + std::vector> boundary_ids; + }; + + /** + * Data used in Triangulation::create_triangulation(). + * + * @author Peter Munch, 2019 + */ + template + struct Description + { + /** + * Boost serialization function + */ + template + void + serialize(Archive &ar, const unsigned int /*version*/); + + /** + * Comparison operator. + */ + bool + operator==(const Description &other) const; + + /** + * Cells of the locally-relevant coarse-grid triangulation. + */ + std::vector> coarse_cells; + + /** + * Vertices of the locally-relevant coarse-grid triangulation. + */ + std::vector> coarse_cell_vertices; + + /** + * List that for each locally-relevant coarse cell provides the + * corresponding global @ref GlossCoarseCellId. + */ + std::vector 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>> 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 + Description + create_description_from_triangulation( + const dealii::Triangulation &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 + Description + create_description_from_triangulation_in_groups( + const std::function &)> + & serial_grid_generator, + const std::function &, + 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 + template + void + CellData::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 + template + void + Description::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 + bool + CellData::operator==(const CellData &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 + bool + Description:: + operator==(const Description &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 diff --git a/source/distributed/CMakeLists.txt b/source/distributed/CMakeLists.txt index 358bbe16f1..06ff3ee3af 100644 --- a/source/distributed/CMakeLists.txt +++ b/source/distributed/CMakeLists.txt @@ -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 diff --git a/source/distributed/fully_distributed_tria.cc b/source/distributed/fully_distributed_tria.cc index 080c0fd2fc..247363b030 100644 --- a/source/distributed/fully_distributed_tria.cc +++ b/source/distributed/fully_distributed_tria.cc @@ -18,7 +18,6 @@ #include #include -#include #include @@ -42,7 +41,7 @@ namespace parallel template Triangulation::Triangulation(MPI_Comm mpi_communicator) : parallel::DistributedTriangulationBase(mpi_communicator) - , settings(Settings::default_setting) + , settings(TriangulationDescription::Settings::default_setting) , partitioner([](dealii::Triangulation &tria, const unsigned int n_partitions) { GridTools::partition_triangulation_zorder(n_partitions, tria); @@ -57,7 +56,8 @@ namespace parallel template void Triangulation::create_triangulation( - const ConstructionData &construction_data) + const TriangulationDescription::Description + &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::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::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::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 a, CellData 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()) - ++cell; - if (spacedim == 3) - for (unsigned int quad = 0; - quad < GeometryInfo::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::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:: - 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::set_partitioner( const std::function &, 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::update_number_cache(); - if (settings & construct_multigrid_hierarchy) + if (settings & + TriangulationDescription::Settings::construct_multigrid_hierarchy) parallel::Triangulation::fill_level_ghost_owners(); } @@ -426,7 +330,9 @@ namespace parallel bool Triangulation::is_multilevel_hierarchy_constructed() const { - return (settings & construct_multigrid_hierarchy); + return ( + settings & + TriangulationDescription::Settings::construct_multigrid_hierarchy); } diff --git a/source/distributed/shared_tria.cc b/source/distributed/shared_tria.cc index c12179d6a1..31cdf26447 100644 --- a/source/distributed/shared_tria.cc +++ b/source/distributed/shared_tria.cc @@ -380,6 +380,19 @@ namespace parallel + template + void + Triangulation::create_triangulation( + const TriangulationDescription::Description + &construction_data) + { + (void)construction_data; + + Assert(false, ExcInternalError()); + } + + + template void Triangulation::copy_triangulation( diff --git a/source/distributed/tria.cc b/source/distributed/tria.cc index d0b98421c3..02d22bc7db 100644 --- a/source/distributed/tria.cc +++ b/source/distributed/tria.cc @@ -2215,6 +2215,20 @@ namespace parallel } + + template + void + Triangulation::create_triangulation( + const TriangulationDescription::Description + &construction_data) + { + (void)construction_data; + + Assert(false, ExcInternalError()); + } + + + // This anonymous namespace contains utility for // the function Triangulation::communicate_locally_moved_vertices namespace CommunicateLocallyMovedVertices diff --git a/source/grid/CMakeLists.txt b/source/grid/CMakeLists.txt index d23cd2d9fc..5fe419f856 100644 --- a/source/grid/CMakeLists.txt +++ b/source/grid/CMakeLists.txt @@ -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 ) diff --git a/source/grid/persistent_tria.cc b/source/grid/persistent_tria.cc index 6a8e49366c..a0515b9fbd 100644 --- a/source/grid/persistent_tria.cc +++ b/source/grid/persistent_tria.cc @@ -145,6 +145,18 @@ PersistentTriangulation::create_triangulation( +template +void +PersistentTriangulation::create_triangulation( + const TriangulationDescription::Description &construction_data) +{ + (void)construction_data; + + Assert(false, ExcInternalError()); +} + + + template void PersistentTriangulation::create_triangulation_compatibility( diff --git a/source/grid/tria.cc b/source/grid/tria.cc index e3fe1d7f6e..94beff7582 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -10744,6 +10744,125 @@ Triangulation::create_triangulation( +template +void +Triangulation::create_triangulation( + const TriangulationDescription::Description &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 a, + TriangulationDescription::CellData 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()) + ++cell; + if (spacedim == 3) + for (unsigned int quad = 0; + quad < GeometryInfo::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::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::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()) + ++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 void Triangulation::flip_all_direction_flags() diff --git a/source/grid/tria_description.cc b/source/grid/tria_description.cc new file mode 100644 index 0000000000..da532e6ae4 --- /dev/null +++ b/source/grid/tria_description.cc @@ -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 +#include + +#include + +#include +#include + +#include +#include +#include + +DEAL_II_NAMESPACE_OPEN + +namespace TriangulationDescription +{ + namespace Utilities + { + namespace + { + /** + * Set the user_flag of a cell and of all its parent cells. + */ + template + void + set_user_flag_reverse(TriaIterator> 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 + 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 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::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::max_children_per_cell + i; + + return level_coarse_cell_id; + } + } // namespace + + + template + Description + create_description_from_triangulation( + const dealii::Triangulation &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 *>(&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 *>(&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 *>( + &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 construction_data; + + // store the communicator + construction_data.comm = comm; + + + std::map> + coinciding_vertex_groups; + std::map 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> &cell, + std::vector &vertices_owned_by_locally_owned_cells) { + // add local vertices + for (unsigned int v = 0; v < GeometryInfo::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 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> + &cell) { + for (unsigned int v = 0; v < GeometryInfo::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 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 cell_info; + + // a) extract cell definition (with old numbering of + // vertices) + dealii::CellData cell_data; + cell_data.material_id = cell->material_id(); + cell_data.manifold_id = cell->manifold_id(); + for (unsigned int v = 0; + v < GeometryInfo::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::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::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( + cell->id().template to_binary()); + + // store the coarse cell id + cell_info.id = CellId(new_coarse_cell_id, 0, nullptr) + .template to_binary(); + + // 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::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::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::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 old_user_flags; + tria.save_user_flags(old_user_flags); + + // 1a) clear user_flags + const_cast &>(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 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> &cell) { + for (unsigned int v = 0; + v < GeometryInfo::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 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 cell_data; + cell_data.material_id = cell->material_id(); + cell_data.manifold_id = cell->manifold_id(); + for (unsigned int v = 0; + v < GeometryInfo::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::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::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 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> &cell) { + if (cell->active()) + for (unsigned int v = 0; + v < GeometryInfo::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 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> &cell) { + for (unsigned int v = 0; + v < GeometryInfo::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 cell_info; + + // save coarse-cell id + cell_info.id = cell->id().template to_binary(); + + // save boundary_ids of each face of this cell + for (unsigned int f = 0; + f < GeometryInfo::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::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::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 &>(tria) + .load_user_flags(old_user_flags); + } + + return construction_data; + } + + + + template + Description + create_description_from_triangulation_in_groups( + const std::function &)> + & serial_grid_generator, + const std::function &, + 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(); +#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 tria( + construct_multilevel_hierarchy ? + dealii::Triangulation::none : + dealii::Triangulation:: + 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 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 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>( + 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 index 0000000000..3c3049a5cd --- /dev/null +++ b/source/grid/tria_description.inst.in @@ -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 + create_description_from_triangulation( + const dealii::Triangulation &tria, + const MPI_Comm comm, + const bool construct_multilevel_hierarchy, + const unsigned int my_rank_in); + + template Description + create_description_from_triangulation_in_groups( + const std::function + &)> & serial_grid_generator, + const std::function &, + const MPI_Comm, + const unsigned int)> &serial_grid_partitioner, + const MPI_Comm comm, + const int group_size, + const bool construct_multilevel_hierarchy); +#endif + \} + \} + } diff --git a/tests/fullydistributed_grids/copy_distributed_tria_01.cc b/tests/fullydistributed_grids/copy_distributed_tria_01.cc index 41e90e8663..40937b7b6c 100644 --- a/tests/fullydistributed_grids/copy_distributed_tria_01.cc +++ b/tests/fullydistributed_grids/copy_distributed_tria_01.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include "./tests.h" @@ -50,8 +50,9 @@ test(int n_refinements, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_distributed_tria_02.cc b/tests/fullydistributed_grids/copy_distributed_tria_02.cc index 0cc9c3e05f..26e81d361a 100644 --- a/tests/fullydistributed_grids/copy_distributed_tria_02.cc +++ b/tests/fullydistributed_grids/copy_distributed_tria_02.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include "./tests.h" @@ -50,8 +50,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_01.cc b/tests/fullydistributed_grids/copy_serial_tria_01.cc index 67024e9863..b73dee3bff 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_01.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_01.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include "./tests.h" @@ -50,8 +50,9 @@ test(int n_refinements, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_02.cc b/tests/fullydistributed_grids/copy_serial_tria_02.cc index 93429f131e..05113f4bae 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_02.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_02.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include "./tests.h" @@ -52,8 +52,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_03.cc b/tests/fullydistributed_grids/copy_serial_tria_03.cc index 9d60c7b541..012c5a14a7 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_03.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_03.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include #include "./tests.h" @@ -79,8 +79,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm) tria_pft.set_manifold(0, SphericalManifold(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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_04.cc b/tests/fullydistributed_grids/copy_serial_tria_04.cc index 673bfcde7a..d5893996b9 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_04.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_04.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include "./tests.h" @@ -93,8 +93,9 @@ test(const int n_refinements, const int n_subdivisions, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_05.cc b/tests/fullydistributed_grids/copy_serial_tria_05.cc index 67521b23d0..f4b81116d6 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_05.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_05.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include #include "./tests.h" @@ -53,8 +53,9 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_06.cc b/tests/fullydistributed_grids/copy_serial_tria_06.cc index 2a3367e0eb..851807ada1 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_06.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_06.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include #include @@ -53,8 +53,9 @@ test(int n_refinements, MPI_Comm comm) parallel::fullydistributed::Triangulation 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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_07.cc b/tests/fullydistributed_grids/copy_serial_tria_07.cc index 00c4ae4a23..802f916e59 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_07.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_07.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -53,7 +52,7 @@ test(int n_refinements, const int n_subdivisions, MPI_Comm comm) [](dealii::Triangulation &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); diff --git a/tests/fullydistributed_grids/copy_serial_tria_grouped_01.cc b/tests/fullydistributed_grids/copy_serial_tria_grouped_01.cc index f5769e97f6..ecc8d57a2c 100644 --- a/tests/fullydistributed_grids/copy_serial_tria_grouped_01.cc +++ b/tests/fullydistributed_grids/copy_serial_tria_grouped_01.cc @@ -15,13 +15,12 @@ // 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 #include -#include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include @@ -42,7 +42,7 @@ template 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 basetria( Triangulation::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( + // create_description_from_triangulation_in_groups + auto construction_data_2 = TriangulationDescription::Utilities:: + create_description_from_triangulation_in_groups( [n_refinements](dealii::Triangulation &tria) { GridGenerator::hyper_L(tria); tria.refine_global(n_refinements); diff --git a/tests/matrix_free/parallel_multigrid_fullydistributed.cc b/tests/matrix_free/parallel_multigrid_fullydistributed.cc index 77c57bcdd9..9dcf07c6a7 100644 --- a/tests/matrix_free/parallel_multigrid_fullydistributed.cc +++ b/tests/matrix_free/parallel_multigrid_fullydistributed.cc @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -32,6 +31,7 @@ #include #include +#include #include #include @@ -458,8 +458,8 @@ test() parallel::fullydistributed::Triangulation 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 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); diff --git a/tests/serialization/parallel_fullydistributed_construction_data_1.cc b/tests/serialization/parallel_fullydistributed_construction_data_1.cc index 67d52e1463..aa6a030dc4 100644 --- a/tests/serialization/parallel_fullydistributed_construction_data_1.cc +++ b/tests/serialization/parallel_fullydistributed_construction_data_1.cc @@ -17,12 +17,12 @@ // check serialization for ConstructionData #include -#include #include #include #include #include +#include #include @@ -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); -- 2.39.5