LCOV - code coverage report
Current view: top level - ugbase/lib_grid/refinement - hanging_node_refiner_base.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 18 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 32 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__HANGING_NODE_REFINER_BASE__
      34              : #define __H__UG__HANGING_NODE_REFINER_BASE__
      35              : 
      36              : #include <queue>
      37              : #include <vector>
      38              : #include "lib_grid/lg_base.h"
      39              : #include "refiner_interface.h"
      40              : #include "ref_mark_adjuster_interface.h"
      41              : 
      42              : namespace ug
      43              : {
      44              : 
      45              : ///     \addtogroup lib_grid_algorithms_refinement
      46              : ///     @{
      47              : 
      48              : ///     Base class for a hanging-node refiner.
      49              : /**     A hanging node refiner allows to adaptively refine grid elements
      50              :  * by inserting hanging nodes at points where T-junctions would occur
      51              :  * (ug::HangingVertex).
      52              :  * If further refinement is performed, the refiner automatically
      53              :  * takes care to adjust the refined area, so that no more than
      54              :  * 1 hanging vertex resides on any edge.
      55              :  *
      56              :  * Each edge on which a hanging node lies is replaced by a
      57              :  * ug::ConstrainingEdge. Child-edges of a constraining edge have the
      58              :  * type ug::ConstrainedEdge.
      59              :  *
      60              :  * If volumes exist, the refiner may also create elements of type
      61              :  * ug::ConstrainingTriangle or ug::ConstrainingQuadrilateral, as well
      62              :  * as ug::ConstrainedTriangle and ug::ConstrainedQuadrilateral.
      63              :  *
      64              :  * Use the mark methods to mark elements which
      65              :  * shall be refined. A call to refine will then perform the refinement
      66              :  * and clear all marks.
      67              :  *
      68              :  * Please note: If you're using a hanging node refiner, you have to
      69              :  * be careful to not destroy the connections between hanging-vertices,
      70              :  * and constrained / constraining objects.
      71              :  *
      72              :  * Specializations of this class exist to support hanging node refinement
      73              :  * on flat and on hierarchical grids.
      74              :  *
      75              :  * Note that you may set a refinement callback, which will be
      76              :  * responsible to calculate new positions of newly created vertices.
      77              :  * By default a linear refinement callback is created for one of
      78              :  * the standard position attachments (ug::aPosition, ug::aPosition2,
      79              :  * ug::aPosition1 - whichever is present).
      80              :  *
      81              :  * This class can't be instantiated directly. Use one of its
      82              :  * specializations instead.
      83              :  *
      84              :  * For Developers: Note that HangingNodeRefinerBase stores flags together with
      85              :  * the refinement marks. Precisely the value 128 is used to flag whether an
      86              :  * element has to be refined using hanging-node-rules.
      87              :  *
      88              :  * \sa ug::HangingNodeRefiner_Grid, ug::HangingNodeRefiner_MultiGrid
      89              :  */
      90              : template <class TSelector>
      91              : class HangingNodeRefinerBase : public IRefiner, public GridObserver
      92              : {
      93              :         public:
      94              :                 using IRefiner::mark;
      95              : 
      96              :                 typedef TSelector       selector_t;
      97              : 
      98              :         /**     additional mark to RefinementMarks. Used to flag whether an element
      99              :          * will be refined with constraining.*/
     100              :                 enum HNodeRefMarks{
     101              :                         HNRM_TO_NORMAL =                1 << 5,
     102              :                         HNRM_TO_CONSTRAINED =   1 << 6,
     103              :                         HNRM_TO_CONSTRAINING =  1 << 7,
     104              :                         HNRM_MAX
     105              :                 };
     106              : 
     107              :         public:
     108              :                 HangingNodeRefinerBase(SPRefinementProjector projector = SPNULL);
     109              :                 virtual ~HangingNodeRefinerBase();
     110              : 
     111              :                 virtual void grid_to_be_destroyed(Grid* grid);
     112              : 
     113              :         ///     enables or disables node-dependency-order-1.
     114              :         /**     \{
     115              :          * If enabled, hanging nodes may only depend on non-hanging nodes.
     116              :          * An edge containing a hanging node thus will not have a hanging-node
     117              :          * as a corner vertex.
     118              :          *
     119              :          * Enabled by default.*/
     120              :                 void enable_node_dependency_order_1(bool bEnable);
     121            0 :                 bool node_dependency_order_1_enabled()                          {return m_nodeDependencyOrder1;}
     122              :         /**     \} */
     123              : 
     124              :         ///     Add a refmark adjuster, which will be called while marks are adjusted during refinement / coarsening
     125            0 :                 void add_ref_mark_adjuster(SPIRefMarkAdjuster adjuster)         {m_refMarkAdjusters.push_back(adjuster);}
     126              : 
     127              : 
     128              :                 virtual void clear_marks();
     129              : 
     130              :         ///     Marks a element for refinement.
     131              :         /**     \{ */
     132              :                 virtual bool mark(Vertex* v, RefinementMark refMark = RM_REFINE);
     133              :                 virtual bool mark(Edge* e, RefinementMark refMark = RM_REFINE);
     134              :                 virtual bool mark(Face* f, RefinementMark refMark = RM_REFINE);
     135              :                 virtual bool mark(Volume* v, RefinementMark refMark = RM_REFINE);
     136              :         /**     \} */
     137              : 
     138              :         ///     Marks the neighborhood of the current selection.
     139              :         /**     \sa ISelector::mark_neighborhood*/
     140              :                 virtual void mark_neighborhood(
     141              :                                                 size_t numIterations,
     142              :                                                 RefinementMark refMark,
     143              :                                                 bool sideNbrsOnly);
     144              : 
     145              :         ///     Returns the mark of a given element.
     146              :         /**     \{ */
     147              :                 virtual RefinementMark get_mark(Vertex* v) const;
     148              :                 virtual RefinementMark get_mark(Edge* e) const;
     149              :                 virtual RefinementMark get_mark(Face* f) const;
     150              :                 virtual RefinementMark get_mark(Volume* v) const;
     151              :         /**     \} */
     152              : 
     153              :                 
     154            0 :                 inline bool marked_refine(Edge* elem) const
     155              :                 {
     156              :                         return (m_selMarkedElements.get_selection_status(elem)
     157            0 :                                         & RM_REFINE) != 0;
     158              :                 }
     159              : 
     160              :                 template <class TElem>
     161              :                 inline bool marked_refine(TElem* elem) const
     162              :                 {
     163              :                         return (m_selMarkedElements.get_selection_status(elem)
     164              :                                         & (RM_CLOSURE | RM_LOCAL | RM_FULL)) != 0;
     165              :                 }
     166              : 
     167              :                 template <class TElem>
     168              :                 inline bool marked_adaptive(TElem* elem) const
     169              :                 {
     170              :                         return (m_selMarkedElements.get_selection_status(elem)
     171              :                                         & (RM_CLOSURE | RM_LOCAL));
     172              :                 }
     173              : 
     174              :                 template <class TElem>
     175              :                 inline bool marked_regular(TElem* elem) const
     176              :                 {
     177              :                         return marked_refine(elem) && (!(marked_adaptive(elem)));
     178              :                 }
     179              : 
     180              :                 template <class TElem>
     181              :                 inline bool marked_coarsen(TElem* elem) const
     182              :                 {
     183              :                         return (m_selMarkedElements.get_selection_status(elem)
     184              :                                         & RM_COARSEN) == RM_COARSEN;
     185              :                 }
     186              : 
     187              : 
     188              : 
     189              :                 virtual bool save_marks_to_file(const char* filename);
     190              : 
     191              :         protected:
     192              :                 typedef typename TSelector::template traits<Vertex>::iterator     sel_vrt_iter;
     193              :                 typedef typename TSelector::template traits<Edge>::iterator               sel_edge_iter;
     194              :                 typedef typename TSelector::template traits<Face>::iterator                       sel_face_iter;
     195              :                 typedef typename TSelector::template traits<Volume>::iterator             sel_vol_iter;
     196              : 
     197              :         ///     performs refinement on the marked elements.
     198              :         /**
     199              :          * The grid's message hub is informed using a "GridAdaption" message,
     200              :          * passing an instance of GridMessage_Adapation, with values
     201              :          * GMAT_HNODE_REFINEMENT_BEGINS and GMAT_HNODE_REFINEMENT_ENDS.
     202              :          * See lib_grid/lib_grid_messages.h for more details.
     203              :          *
     204              :          * as defined in lib_grid/
     205              :          *
     206              :          * automatically extends the refinement to avoid multiple hanging nodes
     207              :          * on a single edge or face.
     208              :          *
     209              :          * refine calls several virtual methods, which allow to influence the
     210              :          * refinement process. Most notably the methods
     211              :          *
     212              :          *              - collect_objects_for_refine
     213              :          *              - pre_refine
     214              :          *              - post_refine
     215              :          *
     216              :          * are called in the given order. During element refinement further
     217              :          * virtual methods are called, which perform the actual element refinement.
     218              :          */
     219              :                 void perform_refinement();
     220              : 
     221              : 
     222              :         ///     a callback that allows to deny refinement of special vertices
     223            0 :                 virtual bool refinement_is_allowed(Vertex* elem)        {return true;}
     224              :         ///     a callback that allows to deny refinement of special edges
     225            0 :                 virtual bool refinement_is_allowed(Edge* elem)          {return true;}
     226              :         ///     a callback that allows to deny refinement of special faces
     227            0 :                 virtual bool refinement_is_allowed(Face* elem)                  {return true;}
     228              :         ///     a callback that allows to deny refinement of special volumes
     229            0 :                 virtual bool refinement_is_allowed(Volume* elem)                {return true;}
     230              : 
     231              :         ///     performs registration and deregistration at a grid.
     232              :         /**     Sets a grid and performs registration at the given grid.
     233              :          *      The associated selector is also initialised with the given grid.
     234              :          *      It is cruical to call this method or everything will fail.
     235              :          *
     236              :          *  call set_grid(NULL) to unregister the observer from a grid.
     237              :          *
     238              :          *  Please note that this method is not declared virtual, since it
     239              :          *  is called during construction and destruction.*/
     240              :                 void set_grid(typename TSelector::grid_type* grid);
     241              : 
     242              :         ///     marks unmarked elements that have to be refined due to marked neighbors.
     243              :         /**
     244              :          * all elements that have to be refined will be written to the passed queues.
     245              :          * Note that this will most likely be more elements than just the marked ones.
     246              :          *
     247              :          * This method is virtual to allow derivates to mark additional elements as required.
     248              :          * Normally a a derived class will first call the method of its this class and
     249              :          * the perform its own operations.
     250              :          */
     251              :                 virtual void collect_objects_for_refine();
     252              : 
     253              :         /**     after each iteration in collet_objects_for_refine, this method determines
     254              :          * whether the iteration shall be continued. Important for parallel refiners.
     255              :          * The default implementation simply returns the specified value. This is fine
     256              :          * for serial environments.*/
     257            0 :                 virtual bool continue_collect_objects_for_refine(bool continueRequired)
     258            0 :                 {return continueRequired;}
     259              : 
     260              :         /**     This callback is called during execution of the refine() method after
     261              :          * collect_objects_for_refine has returned. It is responsible to mark
     262              :          * elements for hnode refinement. That means all elements on which a hanging
     263              :          * node or constrained children shall be created have to be marked using
     264              :          * mark_for_hnode_refinement during this method. The default implementation
     265              :          * performs this marking for all local elements.
     266              :          * Make sure to not mark any new elements for refinement during this method.*/
     267              :                 virtual void assign_hnode_marks();
     268              : 
     269              :         /**     called by refine after collect_objects_for_refine and before
     270              :          *      actual refinement begins.*/
     271            0 :                 virtual void pre_refine()       {}
     272              : 
     273              :         /**     called by refine after refinement is done.*/
     274            0 :                 virtual void post_refine()      {}
     275              : 
     276              :         ////////////////////////////////////////////////////////////////////////
     277              :         //      refine methods
     278              :         ///     called to refine the specified element.
     279              :         /**     Refines the element. Corner vertices of the newly created element
     280              :          *  can be specified through newCornerVrts. newCornerVrts = NULL (default)
     281              :          *  means, that the corner vertices of the original element shall be taken.
     282              :          *  \{ */
     283              :                 virtual void process_constrained_vertex(ConstrainedVertex* cdv);
     284              :                 virtual void process_constrained_edge(ConstrainedEdge* cde);
     285              :                 virtual void process_constraining_edge(ConstrainingEdge* cge);
     286              :                 virtual void refine_edge_with_normal_vertex(Edge* e,
     287              :                                                                                         Vertex** newCornerVrts = NULL);
     288              :                 virtual void refine_edge_with_hanging_vertex(Edge* e,
     289              :                                                                                         Vertex** newCornerVrts = NULL);
     290              : 
     291              :                 virtual void process_constrained_face(ConstrainedFace* cdf);
     292              :                 virtual void process_constraining_face(ConstrainingFace* cgf);
     293              :                 virtual void refine_face_with_normal_vertex(Face* f,
     294              :                                                                                         Vertex** newCornerVrts = NULL);
     295              :                 virtual void refine_face_with_hanging_vertex(Face* f,
     296              :                                                                                         Vertex** newCornerVrts = NULL);
     297              : 
     298              :                 virtual void refine_volume_with_normal_vertex(Volume* v,
     299              :                                                                                         Vertex** newVolumeVrts = NULL);
     300              :         /**     \} */
     301              : 
     302              :         ////////////////////////////////////////////////////////////////////////
     303              :         //      helpers. Make sure that everything is initialized properly
     304              :         //      before calling these methods.
     305              :         //      you should use this methods instead of directly marking elements.
     306            0 :                 inline bool is_marked(Vertex* v)                                {return m_selMarkedElements.is_selected(v);}
     307              :                 //inline void mark(Vertex* v)                                           {mark(v);}
     308              : 
     309            0 :                 inline bool is_marked(Edge* e)                                  {return m_selMarkedElements.is_selected(e);}
     310              :                 //inline void mark(Edge* e)                                             {mark(e);}
     311              : 
     312              :         ///     Returns the vertex associated with the edge
     313              :         /**     pure virtual method.
     314              :          *      Has to return the center vertex which was set to the edge via
     315              :          *      set_center_vertex. If no vertex was set, NULL has to be returned.*/
     316              :                 virtual Vertex* get_center_vertex(Edge* e) = 0;
     317              : 
     318              :         ///     Associates a vertex with the edge (pure virtual).
     319              :                 virtual void set_center_vertex(Edge* e, Vertex* v) = 0;
     320              : 
     321            0 :                 inline bool is_marked(Face* f)                                          {return m_selMarkedElements.is_selected(f);}
     322              :                 //inline void mark(Face* f)                                                     {mark(f);}
     323              : 
     324              :         ///     Returns the vertex associated with the face
     325              :         /**     pure virtual method.
     326              :          *      Has to return the center vertex which was set to the face via
     327              :          *      set_center_vertex. If no vertex was set, NULL has to be returned.*/
     328              :                 virtual Vertex* get_center_vertex(Face* f) = 0;
     329              : 
     330              :         ///     Associates a vertex with the face (pure virtual).
     331              :                 virtual void set_center_vertex(Face* f, Vertex* v) = 0;
     332              : 
     333            0 :                 inline bool is_marked(Volume* v)                                        {return m_selMarkedElements.is_selected(v);}
     334              :                 //inline void mark(Volume* v)                                           {mark(v);}
     335              : 
     336              : 
     337              :                 template <class TElem>
     338              :                 inline bool marked_to_normal(TElem* elem) const                 {return (m_selMarkedElements.get_selection_status(elem) & HNRM_TO_NORMAL) == HNRM_TO_NORMAL;}
     339              : 
     340              :                 template <class TElem>
     341              :                 inline bool marked_to_constrained(TElem* elem) const    {return (m_selMarkedElements.get_selection_status(elem) & HNRM_TO_CONSTRAINED) == HNRM_TO_CONSTRAINED;}
     342              : 
     343              :                 template <class TElem>
     344              :                 inline bool marked_to_constraining(TElem* elem) const   {return (m_selMarkedElements.get_selection_status(elem) & HNRM_TO_CONSTRAINING) == HNRM_TO_CONSTRAINING;}
     345              : 
     346              :                 template <class TElem>
     347              :                 void add_hmark(TElem* elem, HNodeRefMarks mark);
     348              : 
     349              :                 template <class TElem>
     350              :                 void remove_hmark(TElem* elem, uint mark);
     351              : 
     352              :         ///     removes coarsen marks from the selection
     353              :         /**     Note that derived classes are not informed about those deselections!*/
     354              :                 template <class TElem>
     355              :                 bool remove_coarsen_marks();
     356              : 
     357              :         ///     returns the selector which is internally used to mark elements.
     358              :         /**     Be sure to use it carefully!*/
     359            0 :                 TSelector& get_refmark_selector()   {return m_selMarkedElements;}
     360              : 
     361            0 :                 inline bool adjusting_ref_marks() const {return m_adjustingRefMarks;}
     362              : 
     363              :         private:
     364              :         ///     private copy constructor to avoid copy construction
     365              :                 HangingNodeRefinerBase(const HangingNodeRefinerBase&);
     366              : 
     367              :         protected:
     368              :                 TSelector                                                       m_selMarkedElements;
     369              :                 std::vector<SPIRefMarkAdjuster>           m_refMarkAdjusters;
     370              : 
     371              :         private:
     372              :                 Grid*           m_pGrid;
     373              :                 std::vector<Vertex*>      m_newlyMarkedRefVrts;
     374              :                 std::vector<Edge*>                m_newlyMarkedRefEdges;
     375              :                 std::vector<Face*>                        m_newlyMarkedRefFaces;
     376              :                 std::vector<Volume*>              m_newlyMarkedRefVols;
     377              :                 //todo: Use the following vectors during coarsening...
     378              :                 /*
     379              :                 std::vector<Vertex*>      m_newlyMarkedCoarseVrts;
     380              :                 std::vector<Edge*>                m_newlyMarkedCoarseEdges;
     381              :                 std::vector<Face*>                        m_newlyMarkedCoarseFaces;
     382              :                 std::vector<Volume*>              m_newlyMarkedCoarseVols;
     383              :                 */
     384              :                 bool            m_nodeDependencyOrder1;
     385              :                 //bool          m_automarkHigherDimensionalObjects; <-- unused
     386              :                 bool            m_adjustingRefMarks;///<     true during collect_objects_for_refine
     387              : };
     388              : 
     389              : /// @}  // end of add_to_group command
     390              : 
     391              : }//     end of namespace
     392              : 
     393              : #endif
        

Generated by: LCOV version 2.0-1