From: Peter Munch Date: Sun, 25 Oct 2020 19:09:11 +0000 (+0100) Subject: Introduce internal::TriangulationImplementation::Policy X-Git-Tag: v9.3.0-rc1~950^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F10439%2Fhead;p=dealii.git Introduce internal::TriangulationImplementation::Policy --- diff --git a/include/deal.II/grid/tria.h b/include/deal.II/grid/tria.h index 1f97433806..014d357e4b 100644 --- a/include/deal.II/grid/tria.h +++ b/include/deal.II/grid/tria.h @@ -90,6 +90,9 @@ namespace internal class TriaObjects; + template + class Policy; + /** * Forward declaration of a class into which we put much of the * implementation of the Triangulation class. See the .cc file for more @@ -3502,6 +3505,14 @@ protected: private: + /** + * Policy with the Triangulation-specific tasks related to creation, + * refinement, and coarsening. + */ + std::unique_ptr< + dealii::internal::TriangulationImplementation::Policy> + policy; + /** * If add_periodicity() is called, this variable stores the given periodic * face pairs on level 0 for later access during the identification of ghost diff --git a/source/grid/tria.cc b/source/grid/tria.cc index 4b61b9f4b9..445d6a8de9 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -1777,6 +1777,127 @@ namespace internal } } + + + /** + * An interface for algorithms that implement Triangulation-specific tasks + * related to creation, refinement, and coarsening. + */ + template + class Policy + { + public: + /** + * Destructor. + */ + virtual ~Policy() = default; + + /** + * Delete children of given cell. + */ + virtual void + delete_children( + Triangulation & triangulation, + typename Triangulation::cell_iterator &cell, + std::vector & line_cell_count, + std::vector &quad_cell_count) = 0; + + /** + * Execute refinement. + */ + virtual typename Triangulation::DistortedCellList + execute_refinement(Triangulation &triangulation, + const bool check_for_distorted_cells) = 0; + + /** + * Prevent distorted boundary cells. + */ + virtual void + prevent_distorted_boundary_cells( + Triangulation &triangulation) = 0; + + /** + * Prepare refinement. + */ + virtual void + prepare_refinement_dim_dependent( + Triangulation &triangulation) = 0; + + /** + * Check if coarsening is allowed for the given cell. + */ + virtual bool + coarsening_allowed( + const typename Triangulation::cell_iterator &cell) = 0; + + /** + * A sort of virtual copy constructor, this function returns a copy of + * the policy object. Derived classes need to override the function here + * in this base class and return an object of the same type as the derived + * class. + */ + virtual std::unique_ptr> + clone() = 0; + }; + + + + /** + * A simple implementation of the interface Policy. It simply delegates the + * task to the functions with the same name provided by class specified by + * the template argument T. + */ + template + class PolicyWrapper : public Policy + { + public: + void + delete_children( + Triangulation & tria, + typename Triangulation::cell_iterator &cell, + std::vector & line_cell_count, + std::vector &quad_cell_count) override + { + T::delete_children(tria, cell, line_cell_count, quad_cell_count); + } + + typename Triangulation::DistortedCellList + execute_refinement(Triangulation &triangulation, + const bool check_for_distorted_cells) override + { + return T::execute_refinement(triangulation, check_for_distorted_cells); + } + + void + prevent_distorted_boundary_cells( + Triangulation &triangulation) override + { + T::prevent_distorted_boundary_cells(triangulation); + } + + void + prepare_refinement_dim_dependent( + Triangulation &triangulation) override + { + T::prepare_refinement_dim_dependent(triangulation); + } + + bool + coarsening_allowed( + const typename Triangulation::cell_iterator &cell) + override + { + return T::template coarsening_allowed(cell); + } + + std::unique_ptr> + clone() override + { + return std::unique_ptr>( + new PolicyWrapper()); + } + }; + /** * A class into which we put many of the functions that implement * functionality of the Triangulation class. The main reason for this @@ -8860,8 +8981,9 @@ namespace internal * specialization). */ template - static void - prevent_distorted_boundary_cells(const Triangulation<1, spacedim> &); + static void prevent_distorted_boundary_cells(Triangulation<1, spacedim> &) + {} + template @@ -9604,6 +9726,9 @@ Triangulation::copy_triangulation( *other_tria.vertex_to_manifold_id_map_1d); } + if (other_tria.policy) + this->policy = other_tria.policy->clone(); + // inform those who are listening on other_tria of the copy operation other_tria.signals.copy(*this); // also inform all listeners of the current triangulation that the @@ -9649,6 +9774,12 @@ Triangulation::create_triangulation( // are used Assert(subcelldata.check_consistency(dim), ExcInternalError()); + this->policy = + std::make_unique>(); + // try to create a triangulation; if this fails, we still want to // throw an exception but if we just do so we'll get into trouble // because sometimes other objects are already attached to it: @@ -12621,8 +12752,7 @@ typename Triangulation::DistortedCellList Triangulation::execute_refinement() { const DistortedCellList cells_with_distorted_children = - internal::TriangulationImplementation::Implementation::execute_refinement( - *this, check_for_distorted_cells); + this->policy->execute_refinement(*this, check_for_distorted_cells); @@ -12705,8 +12835,10 @@ Triangulation::execute_coarsening() // inform all listeners that cell coarsening is going to happen signals.pre_coarsening_on_cell(cell); // use a separate function, since this is dimension specific - internal::TriangulationImplementation::Implementation:: - delete_children(*this, cell, line_cell_count, quad_cell_count); + this->policy->delete_children(*this, + cell, + line_cell_count, + quad_cell_count); } // re-compute number of lines and quads @@ -12903,8 +13035,7 @@ Triangulation::fix_coarsen_flags() if (cell->user_flag_set()) // if allowed: flag the // children for coarsening - if (internal::TriangulationImplementation::Implementation:: - template coarsening_allowed(cell)) + if (this->policy->coarsening_allowed(cell)) for (unsigned int c = 0; c < cell->n_children(); ++c) { Assert(cell->child(c)->refine_flag_set() == false, @@ -13688,8 +13819,7 @@ Triangulation::prepare_coarsening_and_refinement() // volume or at least with a part, that is negative, if the // cell is refined anisotropically. we have to check, whether // that can happen - internal::TriangulationImplementation::Implementation:: - prevent_distorted_boundary_cells(*this); + this->policy->prevent_distorted_boundary_cells(*this); ///////////////////////////////// // STEP 6: @@ -14151,8 +14281,7 @@ Triangulation::prepare_coarsening_and_refinement() // take care that no double refinement // is done at each line in 3d or higher // dimensions. - internal::TriangulationImplementation::Implementation:: - prepare_refinement_dim_dependent(*this); + this->policy->prepare_refinement_dim_dependent(*this); ////////////////////////////////////// // STEP 8: