LCOV - code coverage report
Current view: top level - ugbase/lib_grid/refinement - hanging_node_refiner_multi_grid.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 24 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 18 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__HANGIN_NODE_REFINER_MULTI_GRID__
      34              : #define __H__UG__HANGIN_NODE_REFINER_MULTI_GRID__
      35              : 
      36              : #include "hanging_node_refiner_base.h"
      37              : #include "lib_grid/tools/selector_multi_grid.h"
      38              : 
      39              : namespace ug
      40              : {
      41              : 
      42              : ///     \addtogroup lib_grid_algorithms_refinement
      43              : ///     @{
      44              : 
      45              : ///     Specialization of ug::HangingNodeRefiner for ug::MultiGrid
      46              : /**     This class should be used, if hanging node refinement shall be
      47              :  * applied on a hierarchical grid (ug::MultiGrid).
      48              :  *
      49              :  * New elements will be constructed one level above their parent elements.
      50              :  *
      51              :  * HangingNodeRefiner_MultiGrid supports coarsening. Please note that coarsening
      52              :  * presumably has not yet reached its final implementation and behavior may
      53              :  * thus change in future revisions.
      54              :  * In the current implementation, refinement marks are removed during coarsening
      55              :  * and coarsening marks are removed during refinement. In order to use
      56              :  * coarsening and refinement on thus should first mark all elements which shall
      57              :  * be coarsened, perform coarsening, then mark all elements will shall be
      58              :  * refined and perform refinement (or vice versa).
      59              :  *
      60              :  * Take a look at ug::HangingNodeRefinerBase for a more in-depth documentation.
      61              :  *
      62              :  * \todo:       Avoid the removal of refinement marks during coarsening and of
      63              :  *                      coarsening marks during refinement.
      64              :  *
      65              :  * \sa ug::HangingNodeRefinerBase, ug::HangingNodeRefiner_Grid
      66              :  */
      67              : class HangingNodeRefiner_MultiGrid : public HangingNodeRefinerBase<MGSelector>
      68              : {
      69              :         public:
      70              :                 typedef HangingNodeRefinerBase<MGSelector>        BaseClass;
      71              :                 using BaseClass::mark;
      72              : 
      73              :                 enum HNodeCoarsenMarks{
      74              :                         HNCM_FIRST = HNRM_MAX + 1,
      75              :                         HNCM_NO_NBRS,
      76              :                         HNCM_NONE,
      77              :                         HNCM_PARTIAL,
      78              :                         HNCM_REPLACE,
      79              :                         HNCM_ALL,
      80              :                         HNCM_INVALID,
      81              :                         HNCM_UNKNOWN
      82              :                 };
      83              : 
      84              :         public:
      85              :                 HangingNodeRefiner_MultiGrid(SPRefinementProjector projector = SPNULL);
      86              :                 HangingNodeRefiner_MultiGrid(MultiGrid& mg,
      87              :                                                                         SPRefinementProjector projector = SPNULL);
      88              : 
      89              :                 virtual ~HangingNodeRefiner_MultiGrid();
      90              : 
      91              :                 virtual void grid_to_be_destroyed(Grid* grid);
      92              : 
      93              :                 virtual void assign_grid(MultiGrid& mg);
      94            0 :                 virtual Grid* get_associated_grid()             {return m_pMG;}//depreciated
      95            0 :                 virtual Grid* grid()                                    {return m_pMG;}
      96            0 :                 virtual MultiGrid* multi_grid()                 {return m_pMG;}
      97              : 
      98            0 :                 virtual bool adaptivity_supported() const       {return true;}
      99            0 :                 virtual bool coarsening_supported() const       {return true;}
     100              : 
     101              :         protected:
     102              :         ///     returns the number of (globally) marked edges on this level of the hierarchy
     103              :                 virtual void num_marked_edges_local(std::vector<int>& numMarkedEdgesOut);
     104              :         ///     returns the number of (globally) marked faces on this level of the hierarchy
     105              :                 virtual void num_marked_faces_local(std::vector<int>& numMarkedFacesOut);
     106              :         ///     returns the number of (globally) marked volumes on this level of the hierarchy
     107              :                 virtual void num_marked_volumes_local(std::vector<int>& numMarkedVolsOut);
     108              :                 
     109              :                 template <class TElem>
     110              :                 void num_marked_elems(std::vector<int>& numMarkedElemsOut);
     111              :                 
     112              :         ///     performs coarsening on the elements marked with RM_COARSEN.
     113              :         /**
     114              :          * The grid's message hub is informed using a "GridAdaption" message,
     115              :          * passing an instance of GridMessage_Adapation, with values
     116              :          * GMAT_HNODE_COARSENING_BEGINS and GMAT_HNODE_COARSENING_ENDS.
     117              :          * See lib_grid/lib_grid_messages.h for more details.
     118              :          *
     119              :          * automatically adjusts the selection so that only valid coarsening operations
     120              :          * are executed. Not that refinement marks are removed in this process.
     121              :          *
     122              :          * During a coarsening step only elements from the surface layer are removed.
     123              :          * If not all children of a sub-surface element are marked, then the marks are ignored.
     124              :          *
     125              :          * Note that coarsen in contrary to refine is conservative. While refine
     126              :          * extends the selection to construct a valid grid, coarsen shrinks the
     127              :          * selection. On could think of implementing an alternative non conservative
     128              :          * coarsen approach. However, the conservative one is the one mostly used
     129              :          * in adaptive multigrid methods and was thus chosen here.
     130              :          *
     131              :          * coarsen returns false, if no elements have been coarsened, true if at
     132              :          * least one has been coarsened.
     133              :          */
     134              :                 virtual bool perform_coarsening();
     135              : 
     136              :                 void save_coarsen_marks_to_file(ISelector& sel, const char* filename);
     137              :                 void debug_save(ISelector& sel, const char* filename);
     138              : 
     139              :         ///     a callback that allows to deny refinement of special vertices
     140              :                 virtual bool refinement_is_allowed(Vertex* elem);
     141              :         ///     a callback that allows to deny refinement of special edges
     142              :                 virtual bool refinement_is_allowed(Edge* elem);
     143              :         ///     a callback that allows to deny refinement of special faces
     144              :                 virtual bool refinement_is_allowed(Face* elem);
     145              :         ///     a callback that allows to deny refinement of special volumes
     146              :                 virtual bool refinement_is_allowed(Volume* elem);
     147              : 
     148              :         ///     performs registration and deregistration at a grid.
     149              :         /**     Initializes all grid related variables.
     150              :          *  call set_grid(NULL) to unregister the observer from a grid.
     151              :          *
     152              :          *      Please note that though the base grid features a set_grid method,
     153              :          *  it is not declared virtual. This is because we want to call it
     154              :          *  during construction and destruction.*/
     155              :                 void set_grid(MultiGrid* mg);
     156              : 
     157              :                 virtual void assign_hnode_marks();
     158              : 
     159              :         ///     creates required vertices in higher levels.
     160              :                 virtual void pre_refine();
     161              : 
     162              :         ///     called before elements are removed in coarsening
     163              :         /**     Default implementation is emtpy */
     164            0 :                 virtual void pre_coarsen()      {};
     165              : 
     166              :         ///     called after elements have been removed in coarsening
     167              :         /**     Default implementation is emtpy */
     168            0 :                 virtual void post_coarsen()     {};
     169              : 
     170              : 
     171              :         /**     Calls the base implementation and passes the mg-child vertices as
     172              :          *  newCornerVrts. If newCornerVrts were passed to this method, they
     173              :          *  are ignored.
     174              :          *  \{*/
     175              :         ///     calls base implementation and replaces cge with a normal edge.
     176              :                 virtual void process_constraining_edge(ConstrainingEdge* cge);
     177              : 
     178              :                 virtual void refine_edge_with_normal_vertex(Edge* e,
     179              :                                                                                         Vertex** newCornerVrts = NULL);
     180              :                 virtual void refine_edge_with_hanging_vertex(Edge* e,
     181              :                                                                                         Vertex** newCornerVrts = NULL);
     182              : 
     183              :                 virtual void refine_face_with_normal_vertex(Face* f,
     184              :                                                                                         Vertex** newCornerVrts = NULL);
     185              :                 virtual void refine_face_with_hanging_vertex(Face* f,
     186              :                                                                                         Vertex** newCornerVrts = NULL);
     187              : 
     188              :                 virtual void refine_volume_with_normal_vertex(Volume* v,
     189              :                                                                                         Vertex** newVolumeVrts = NULL);
     190              :         /*      \} */
     191              : 
     192              :         ///     Returns the vertex associated with the edge
     193              :                 virtual Vertex* get_center_vertex(Edge* e);
     194              : 
     195              :         ///     Associates a vertex with the edge.
     196              :                 virtual void set_center_vertex(Edge* e, Vertex* v);
     197              : 
     198              :         ///     Returns the vertex associated with the face
     199              :                 virtual Vertex* get_center_vertex(Face* f);
     200              : 
     201              :         ///     Associates a vertex with the face.
     202              :                 virtual void set_center_vertex(Face* f, Vertex* v);
     203              : 
     204              : 
     205              :         ///     collects corner vertices and fills them into the associated vector
     206              :         /**     The size of cornersOut is automatically adjusted.
     207              :          *  The i-th element of corners out will contain the child vertex of the
     208              :          *  i-th vertex of elem.*/
     209              :                 template <class TElem>
     210            0 :                 void collect_child_corners(std::vector<Vertex*>& cornersOut, TElem* elem)
     211              :                 {
     212            0 :                         cornersOut.resize(elem->num_vertices());
     213            0 :                         for(size_t i = 0; i < elem->num_vertices(); ++i){
     214              :                                 //UG_ASSERT(m_pMG->get_child_vertex(elem->vertex(i)), "A child vertex has to exists!");
     215            0 :                                 cornersOut[i] = m_pMG->get_child_vertex(elem->vertex(i));
     216              :                         }
     217            0 :                 }
     218              : 
     219              :         ///     Makes sure that only surface elements are marked and that only coarsen marks are used.
     220              :         /**     calls the overloaded template implementation for the four base element types.
     221              :          * this method is called prior to restrict_selection_to_coarsen_families.*/
     222              :                 virtual void restrict_selection_to_surface_coarsen_elements();
     223              : 
     224              :         ///     Deselects all elements which have an unselected sibling.
     225              :         /** Siblings are elements who share the same parent.
     226              :          * Calls the overloaded template implementation for the four base element types.
     227              :          * this method is called after to restrict_selection_to_surface_coarsen_elements.*/
     228              :                 virtual void restrict_selection_to_coarsen_families();
     229              : 
     230              :         ///     Deselects all non-surface elements and all elements not marked with RM_COARSEN
     231              :                 template <class TElem>
     232              :                 void restrict_selection_to_surface_coarsen_elements();
     233              : 
     234              :         ///     Only complete families (all siblings are selected) may be coarsened.
     235              :         /**     When calling this method, make sure that only surface elements are
     236              :          * marked/selected and that only the mark RM_COARSEN is used.*/
     237              :                 template <class TElem>
     238              :                 void restrict_selection_to_coarsen_families();
     239              : 
     240              :         ///     adjusts the selection marks to those specified in HNodeCoarsenMarks.
     241              :         /**     This method does not alter the selection itself, it only alters the
     242              :          * selection-mark, associated with each selected element. It neither
     243              :          * selects nor deselects any elements.
     244              :          * It iterates over all selected elements of the given type and assigns one
     245              :          * of the marks, depending on how many associated elements of the next higher
     246              :          * dimension are selected.
     247              :          * Note that this method should only be called for vertices, edges and faces.
     248              :          * It does not make sense to call it for volumes.*/
     249              : //              template <class TElem>
     250              : //              void classify_selection();
     251              : 
     252              :         ///     Applies marks like RM_COARSEN_CONSTRAINING or RM_COARSEN_UNCONSTRAIN
     253              :         /**     This method should first be called for Face, then for Edge, then for
     254              :          * Vertex.*/
     255              :                 //template <class TElem>
     256              :                 //void adjust_coarsen_marks_on_side_elements();
     257              : 
     258              :         ///deselect coarsen families, which are adjacent to unselected constraining elements
     259              :         /**     If at least one family was deselected, this method returns true.*/
     260              : //              template <class TElem>
     261              : //              bool deselect_invalid_coarsen_families();
     262              : //
     263              : //              template <class TElem>
     264              : //              void deselect_isolated_sides();
     265              : //
     266              : //              template <class TElem>
     267              : //              void deselect_uncoarsenable_parents();
     268              : 
     269              :         ///     called by the coarsen method in order to adjust the selection to valid elements.
     270              :         /**     This method is responsible to mark all elements that shall be coarsened.
     271              :          * Only sub-surface elements may be coarsened. If a sub-surface element has
     272              :          * a side, which is not a sub-surface element, then the element may not be
     273              :          * coarsened.
     274              :          * If scheduleCoarseningBeginsMessage is set to true, the method will schedule
     275              :          * a GridMessage_Adaption message which indicates that coarsening begins.*/
     276              :                 virtual void collect_objects_for_coarsen(bool scheduleCoarseningBeginsMessage = false);
     277              : 
     278              : 
     279              :         ////////////////////////////////////////
     280              :         //      Callbacks for PARALLELIZATION
     281              : 
     282              :         ///     called to check, whether another iteration of collect_objects_for_coarsen has to be performed.
     283              :         /**     This method is especially useful if coarsening shall be applied in a
     284              :          * parallel environment. Each process calls this method and basses a boolean,
     285              :          * which indicates if it requires the continuation of collect_objects_for_coarsen.
     286              :          * If one process does require continuation, then all processes have to continue.
     287              :          * The default implementation simply returns the local status.*/
     288              : //              virtual bool continue_collect_objects_for_coarsen(bool continueRequired)
     289              : //              {return continueRequired;}
     290              : 
     291              :         ///     called during collect_objects_for_coarsen when coarsen-marks shall be distributed
     292              :         /**     This method is especially useful if coarsening shall be applied in a
     293              :          * parallel environment. A derived class can implement this method to schedule
     294              :          * communication. The default implementation does nothing.
     295              :          * \{ */
     296              : //              virtual void broadcast_vertex_coarsen_marks()   {}
     297              : //              virtual void broadcast_edge_coarsen_marks()             {}
     298              : //              virtual void broadcast_face_coarsen_marks()             {}
     299              :         /** \} */
     300              : 
     301              :         ///     allows to check whether a distributed grid contains edges
     302              :         /**     The default implementation returns whether the local grid contains edges.*/
     303            0 :                 virtual bool contains_edges()                   {return m_pMG->num<Edge>() > 0;}
     304              : 
     305              :         ///     allows to check whether a distributed grid contains faces
     306              :         /**     The default implementation returns whether the local grid contains faces.*/
     307            0 :                 virtual bool contains_faces()                   {return m_pMG->num<Face>() > 0;}
     308              : 
     309              :         ///     allows to check whether a distributed grid contains volumes
     310              :         /**     The default implementation returns whether the local grid contains volumes.*/
     311            0 :                 virtual bool contains_volumes()                 {return m_pMG->num<Volume>() > 0;}
     312              : 
     313              :         /**     This callback is called during execution of the coarsen() method after
     314              :          * collect_objects_for_coarsen is done. It is responsible to mark
     315              :          * elements for hnode coarsening. That means all elements on which a hanging
     316              :          * node or constrained children shall be created have to be marked using
     317              :          * mark_for_hnode_refinement during this method. The default implementation
     318              :          * performs this marking for all local elements.*/
     319              :                 //virtual void assign_hnode_coarsen_marks();
     320              : 
     321            0 :                 virtual void broadcast_marks_horizontally(bool vertices, bool edges, bool faces,
     322            0 :                                                                                                   bool allowDeselection = false)        {}
     323            0 :                 virtual void broadcast_marks_vertically(bool vertices, bool edges,
     324              :                                                                                                 bool faces, bool volumes,
     325            0 :                                                                                                 bool allowDeselection = false)  {}
     326              : 
     327            0 :                 virtual void copy_marks_to_vmasters(bool vertices, bool edges,
     328            0 :                                                                                         bool faces, bool volumes)                       {}
     329              : 
     330            0 :                 virtual void copy_marks_to_vslaves(bool vertices, bool edges,
     331            0 :                                                                                         bool faces, bool volumes)                       {}
     332              : 
     333            0 :                 virtual bool one_proc_true(bool localProcTrue)          {return localProcTrue;}
     334              : 
     335              :         private:
     336              :                 MultiGrid*      m_pMG;
     337              : };
     338              : 
     339              : /// @}  // end of add_to_group command
     340              : 
     341              : }//     end of namespace
     342              : 
     343              : #endif
        

Generated by: LCOV version 2.0-1