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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-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              : #include "./std_hnode_adjuster.h"
      34              : #include "lib_grid/tools/periodic_boundary_manager.h"
      35              : #include "lib_grid/algorithms/debug_util.h"
      36              : 
      37              : namespace ug{
      38              : 
      39              : // marks geometric object e for refinement if it is periodic
      40              : template <class TElem>
      41            0 : static void mark_if_periodic(IRefiner& ref, TElem* e) {
      42            0 :         if(!ref.grid())
      43              :                 return;
      44            0 :         if(!ref.grid()->has_periodic_boundaries())
      45              :                 return;
      46              : 
      47            0 :         PeriodicBoundaryManager& pbm = *ref.grid()->periodic_boundary_manager();
      48              : 
      49              :         // ensure element is periodic
      50            0 :         if(!pbm.is_periodic(e))
      51              :                 return;
      52              : 
      53            0 :         RefinementMark refMark = ref.get_mark(e);
      54            0 :         if(pbm.is_master(e))
      55              :         {
      56              :                 typedef typename PeriodicBoundaryManager::Group<TElem>::SlaveContainer SlaveContainer;
      57              :                 typedef typename PeriodicBoundaryManager::Group<TElem>::SlaveIterator SlaveIterator;
      58            0 :                 SlaveContainer& slaves = *pbm.slaves(e);
      59            0 :                 for (SlaveIterator iter = slaves.begin(); iter != slaves.end(); ++iter)
      60            0 :                         ref.mark(*iter, refMark);
      61              :         }
      62              :         else { // is slave
      63            0 :                 ref.mark(pbm.master(e), refMark);
      64              :         }
      65              : }
      66              : 
      67            0 : void StdHNodeAdjuster::
      68              : ref_marks_changed(IRefiner& ref,
      69              :                                   const std::vector<Vertex*>& vrts,
      70              :                                   const std::vector<Edge*>& edges,
      71              :                                   const std::vector<Face*>& faces,
      72              :                                   const std::vector<Volume*>& vols)
      73              : {
      74            0 :         if(!ref.grid())
      75            0 :                 return;
      76            0 :         Grid& grid = *ref.grid();
      77              : 
      78              :         Grid::edge_traits::secure_container             assEdges;
      79              :         Grid::face_traits::secure_container             assFaces;
      80              :         Grid::volume_traits::secure_container   assVols;
      81              : 
      82              : ////////////////////////////////
      83              : //      VERTICES
      84            0 :         if(node_dependency_order_1_enabled()){
      85              :         //      make sure that a hanging node is never constrained by an element which
      86              :         //      is has constrained vertices as corners
      87            0 :                 for(size_t i_vrt = 0; i_vrt < vrts.size(); ++i_vrt){
      88            0 :                         Vertex* vrt = vrts[i_vrt];
      89            0 :                         if(!vrt->is_constrained())
      90            0 :                                 continue;
      91            0 :                         ConstrainedVertex* hv = dynamic_cast<ConstrainedVertex*>(vrt);
      92            0 :                         if(!hv)
      93            0 :                                 continue;
      94              : 
      95              :                 //      make sure that all parents are marked
      96              :                         GridObject* co = hv->get_constraining_object();
      97            0 :                         if(co){
      98            0 :                                 if(Edge* e = dynamic_cast<Edge*>(co)){
      99            0 :                                         ref.mark(e);
     100              :                                 }
     101            0 :                                 else if(Face* f = dynamic_cast<Face*>(co)){
     102            0 :                                         ref.mark(f);
     103              :                                 }
     104              :                         }
     105              :                 }
     106              :         }
     107              : 
     108              : ////////////////////////////////
     109              : //      EDGES
     110            0 :         for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge){
     111            0 :                 Edge* e = edges[i_edge];
     112              : 
     113            0 :                 if(ref.get_mark(e) != RM_REFINE)
     114            0 :                         continue;
     115              : 
     116              :         //      check whether hangingNodeOrder1 is enabled. If so, we have to check
     117              :         //      for associated hanging vertices and push them to qHVrts.
     118            0 :                 if(node_dependency_order_1_enabled()){
     119            0 :                         for(size_t i = 0; i < 2; ++i){
     120            0 :                                 if(e->vertex(i)->is_constrained()){
     121            0 :                                         Vertex* v = e->vertex(i);
     122            0 :                                         ref.mark(v);
     123              :                                 }
     124              :                         }
     125              :                 }
     126              : 
     127              :         //      depending on the type of the edge, we have to perform different operations
     128            0 :                 if(ConstrainedEdge* cde = dynamic_cast<ConstrainedEdge*>(e))
     129              :                 {
     130              :                 //      the edge is a constrained edge. Make sure that its constraining edge
     131              :                 //      or face will be refined.
     132            0 :                         if(ConstrainingEdge* cge = dynamic_cast<ConstrainingEdge*>(
     133              :                                                                                 cde->get_constraining_object()))
     134              :                         {
     135            0 :                                 ref.mark(cge);
     136              :                         }
     137            0 :                         else if(ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(
     138              :                                                                                 cde->get_constraining_object()))
     139              :                         {
     140            0 :                                 ref.mark(cgf);
     141              :                         }
     142              :                         else{
     143              :                                 UG_ASSERT(grid.is_parallel(),
     144              :                                                   "Constrained edge doesn't have a constraining edge. In "
     145              :                                                   "a serial environment this should always be the case!"
     146              :                                                   << " At: " << GetGridObjectCenter(grid, e));
     147              :                         }
     148              :                 }
     149            0 :                 else if(ConstrainingEdge* cge = dynamic_cast<ConstrainingEdge*>(e))
     150              :                 {
     151              :                 //      associated faces and volumes have to be marked
     152            0 :                         if(grid.num_faces() > 0){
     153              :                                 grid.associated_elements(assFaces, cge);
     154            0 :                                 for(size_t i = 0; i < assFaces.size(); ++i){
     155            0 :                                         if (!(ref.get_mark(assFaces[i]) & RM_ANISOTROPIC)) // do not mark RM_REFINE if already marked anisotropic
     156            0 :                                                 ref.mark(assFaces[i]);
     157              :                                 }
     158              :                         }
     159              : 
     160            0 :                         if(grid.num_volumes() > 0){
     161              :                                 grid.associated_elements(assVols, cge);
     162            0 :                                 for(size_t i = 0; i < assVols.size(); ++i){
     163            0 :                                         if (!(ref.get_mark(assVols[i]) & RM_ANISOTROPIC)) // do not mark RM_REFINE if already marked anisotropic
     164            0 :                                                 ref.mark(assVols[i]);
     165              :                                 }
     166              :                         }
     167              :                 }
     168              : //NOTE: The check below was intended to replace the one above to reduce element refinement.
     169              : //              However, since constrained edges may be marked after this check has
     170              : //              been performed for a constraining edge, at least in parallel environments,
     171              : //              this implementation leads to problems (segfaults!)
     172              :                 // else if(ConstrainingEdge* cge = dynamic_cast<ConstrainingEdge*>(e))
     173              :                 // {
     174              :                 // //   if one of the constrained objects is marked, then all associated faces
     175              :                 // //   and volumes have to be marked, too
     176              :                 //      const size_t nce = cge->num_constrained_edges();
     177              :                 //      bool oneIsMarked = false;
     178              :                 //      for(size_t i = 0; i < nce; ++i){
     179              :                 //              const RefinementMark rm = ref.get_mark(cge->constrained_edge(i));
     180              :                 //              if(rm & RM_REFINE){
     181              :                 //                      oneIsMarked = true;
     182              :                 //                      break;
     183              :                 //              }
     184              :                 //      }
     185              : 
     186              :                 //      if(oneIsMarked){
     187              :                 //              if(grid.num_faces() > 0){
     188              :                 //                      grid.associated_elements(assFaces, cge);
     189              :                 //                      for(size_t i = 0; i < assFaces.size(); ++i){
     190              :                 //                              if (!(ref.get_mark(assFaces[i]) & RM_ANISOTROPIC)) // do not mark RM_REFINE if already marked anisotropic
     191              :                 //                                      ref.mark(assFaces[i]);
     192              :                 //                      }
     193              :                 //              }
     194              : 
     195              :                 //              if(grid.num_volumes() > 0){
     196              :                 //                      grid.associated_elements(assVols, cge);
     197              :                 //                      for(size_t i = 0; i < assVols.size(); ++i){
     198              :                 //                              if (!(ref.get_mark(assVols[i]) & RM_ANISOTROPIC)) // do not mark RM_REFINE if already marked anisotropic
     199              :                 //                                      ref.mark(assVols[i]);
     200              :                 //                      }
     201              :                 //              }
     202              :                 //      }
     203              :                 // }
     204              :         }
     205              : 
     206              : ////////////////////////////////
     207              : //      FACES
     208            0 :         for(size_t i_face = 0; i_face < faces.size(); ++i_face){
     209            0 :                 Face* f = faces[i_face];
     210            0 :                 RefinementMark refMark = ref.get_mark(f);
     211              :         //      check whether hangingNodeOrder1 is enabled. If so, we have to check
     212              :         //      for associated hanging vertices and push them to qHVrts.
     213            0 :                 if(node_dependency_order_1_enabled()){
     214            0 :                         for(size_t i = 0; i < f->num_vertices(); ++i){
     215            0 :                                 if(f->vertex(i)->is_constrained())
     216            0 :                                         ref.mark(f->vertex(i));
     217              :                         }
     218              :                 }
     219              : 
     220              :         //      we have to make sure that associated edges are marked.
     221            0 :                 if(refMark != RM_LOCAL){
     222              :                         grid.associated_elements(assEdges, f);
     223            0 :                         for(size_t i = 0; i < assEdges.size(); ++i){
     224            0 :                                 if(refMark > ref.get_mark(assEdges[i]))
     225            0 :                                         ref.mark(assEdges[i], refMark);
     226              :                         }
     227              :                 }
     228              : 
     229              :         //      constrained and constraining faces require special treatment
     230            0 :                 if(ConstrainedFace* cdf = dynamic_cast<ConstrainedFace*>(f)){
     231              :                 //      make sure that its constraining face will be refined
     232            0 :                         if(ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(
     233              :                                                                                 cdf->get_constraining_object()))
     234              :                         {
     235            0 :                                 ref.mark(cgf);
     236              :                         }
     237              :                         else{
     238              :                                 UG_ASSERT(grid.is_parallel(),
     239              :                                                   "Constrained face doesn't have a constraining face. In "
     240              :                                                   "a serial environment this should always be the case!"
     241              :                                                   << " At: " << GetGridObjectCenter(grid, f));
     242              :                         }
     243              :                 }
     244            0 :                 else if(ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(f)){
     245              :                 //      associated volumes have to be marked
     246            0 :                         if(grid.num_volumes() > 0){
     247              :                                 grid.associated_elements(assVols, cgf);
     248            0 :                                 for(size_t i = 0; i < assVols.size(); ++i){
     249              :                                 //todo: also check whether the local mark matches
     250            0 :                                         if (!(ref.get_mark(assVols[i]) & RM_ANISOTROPIC)) // do not mark RM_REFINE if already marked anisotropic
     251            0 :                                                 ref.mark(assVols[i]);
     252              :                                 }
     253              :                         }
     254              :                 }
     255              :         }
     256              : 
     257              : ////////////////////////////////
     258              : //      VOLUMES
     259            0 :         for(size_t i_vol = 0; i_vol < vols.size(); ++i_vol){
     260            0 :                 Volume* v = vols[i_vol];
     261            0 :                 RefinementMark refMark = ref.get_mark(v);
     262              :         //      we have to make sure that all associated edges and faces are marked.
     263            0 :                 if(refMark != RM_LOCAL){
     264              :                         grid.associated_elements(assEdges, v);
     265            0 :                         for(size_t i = 0; i < assEdges.size(); ++i){
     266            0 :                                 if(refMark > ref.get_mark(assEdges[i]))
     267            0 :                                         ref.mark(assEdges[i], refMark);
     268              :                         }
     269              : 
     270              :                         grid.associated_elements(assFaces, v);
     271            0 :                         for(size_t i = 0; i < assFaces.size(); ++i){
     272            0 :                                 if(refMark > ref.get_mark(assFaces[i]))
     273            0 :                                         ref.mark(assFaces[i], refMark);
     274              :                         }
     275              :                 }
     276              :         }
     277              : 
     278              : ////////////////////////////////
     279              : // Periodic boundaries
     280            0 :         if(grid.has_periodic_boundaries()){
     281            0 :                 for(size_t i_vrt = 0; i_vrt < vrts.size(); ++i_vrt)
     282            0 :                         mark_if_periodic(ref, vrts[i_vrt]);
     283              : 
     284            0 :                 for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge)
     285            0 :                         mark_if_periodic(ref, edges[i_edge]);
     286              : 
     287            0 :                 for(size_t i_face = 0; i_face < faces.size(); ++i_face)
     288            0 :                         mark_if_periodic(ref, faces[i_face]);
     289              : 
     290              :                 // omit volumes, as these are not meant to be periodic
     291              :         }
     292              : }
     293              : }// end of namespace
        

Generated by: LCOV version 2.0-1