LCOV - code coverage report
Current view: top level - ugbase/lib_grid/refinement - refiner_interface.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 128 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 15 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 "refiner_interface.h"
      34              : #include "lib_grid/lib_grid_messages.h"
      35              : #include "common/catch_std.h"
      36              : 
      37              : //      FOR DEBUGGING ONLY:
      38              : #include "lib_grid/tools/periodic_boundary_manager.h"
      39              : 
      40              : #ifdef UG_PARALLEL
      41              :         #include "pcl/pcl_process_communicator.h"
      42              :         #include "pcl/pcl_util.h"
      43              : #endif
      44              : 
      45              : namespace ug{
      46              : 
      47            0 : bool IRefiner::mark(GridObject* o, RefinementMark refMark)
      48              : {
      49            0 :         switch(o->base_object_id()){
      50            0 :                 case VERTEX:    return mark(static_cast<Vertex*>(o), refMark);
      51            0 :                 case EDGE:              return mark(static_cast<Edge*>(o), refMark);
      52            0 :                 case FACE:              return mark(static_cast<Face*>(o), refMark);
      53            0 :                 case VOLUME:    return mark(static_cast<Volume*>(o), refMark);
      54              :         }
      55              :         return false;
      56              : }
      57              : 
      58            0 : RefinementMark IRefiner::get_mark(GridObject* o) const
      59              : {
      60            0 :         switch(o->base_object_id()){
      61            0 :                 case VERTEX:    return get_mark(static_cast<Vertex*>(o));
      62            0 :                 case EDGE:              return get_mark(static_cast<Edge*>(o));
      63            0 :                 case FACE:              return get_mark(static_cast<Face*>(o));
      64            0 :                 case VOLUME:    return get_mark(static_cast<Volume*>(o));
      65              :         }
      66              :         return RM_NONE;
      67              : }
      68              : 
      69            0 : void IRefiner::adaption_begins()
      70              : {
      71            0 :         if(!m_messageHub.valid()){
      72            0 :                 UG_THROW("A message-hub has to be assigned to IRefiner before adaption_begins may be called. "
      73              :                                 "Make sure that you assigned a grid to the refiner you're using.");
      74              :         }
      75              : 
      76              : //      we'll schedule an adaption-begins message
      77            0 :         if(adaptivity_supported())
      78            0 :                 m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_ADAPTION_BEGINS));
      79              :         else
      80            0 :                 m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_ADAPTION_BEGINS));
      81              : 
      82            0 :         m_adaptionIsActive = true;
      83            0 : }
      84              : 
      85            0 : void IRefiner::adaption_ends()
      86              : {
      87            0 :         if(!m_messageHub.valid()){
      88            0 :                 UG_THROW("A message-hub has to be assigned to IRefiner before adaption_ends may be called. "
      89              :                                 "Make sure that you assigned a grid to the refiner you're using.");
      90              :         }
      91              : 
      92            0 :         if(adaptivity_supported())
      93            0 :                 m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_ADAPTION_ENDS));
      94              :         else
      95            0 :                 m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_ADAPTION_ENDS));
      96              : 
      97            0 :         m_adaptionIsActive = false;
      98            0 : }
      99              : 
     100            0 : void IRefiner::refine()
     101              : {
     102              :         #ifdef UG_PARALLEL
     103              :                 PCL_DEBUG_BARRIER_ALL();
     104              :         #endif
     105              :         PROFILE_BEGIN_GROUP(IRefiner_refine, "grid");
     106              :         try
     107              :         {
     108            0 :                 if(m_projector.invalid() && grid()){
     109            0 :                         Grid& g = *grid();
     110            0 :                         if(g.has_vertex_attachment(aPosition)){
     111            0 :                                 m_projector = make_sp(new RefinementProjector(MakeGeometry3d(g, aPosition)));
     112              :                         }
     113            0 :                         else if(g.has_vertex_attachment(aPosition2)){
     114            0 :                                 m_projector = make_sp(new RefinementProjector(MakeGeometry3d(g, aPosition2)));
     115              :                         }
     116            0 :                         else if(g.has_vertex_attachment(aPosition1)){
     117            0 :                                 m_projector = make_sp(new RefinementProjector(MakeGeometry3d(g, aPosition1)));
     118              :                         }
     119              :                 }
     120              : 
     121            0 :                 if(!m_messageHub.valid()){
     122            0 :                         UG_THROW("A message-hub has to be assigned to IRefiner before refine may be called. "
     123              :                                         "Make sure that you assigned a grid to the refiner you're using.");
     124              :                 }
     125              : 
     126              :         //      we'll schedule an adaption-begins message, if adaption is not yet enabled.
     127              :                 bool locallyActivatedAdaption = false;
     128            0 :                 if(!m_adaptionIsActive){
     129              :                         locallyActivatedAdaption = true;
     130            0 :                         adaption_begins();
     131              :                 }
     132              : 
     133              :         //      now post a message, which informs that refinement begins
     134              : //              if(adaptivity_supported())
     135              : //                      m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_REFINEMENT_BEGINS));
     136              : //              else
     137              : //                      m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_REFINEMENT_BEGINS));
     138              : 
     139              :         //      now perform refinement
     140            0 :                 perform_refinement();
     141              : 
     142              :         //      post a message that refinement has been finished
     143              : //              if(adaptivity_supported())
     144              : //                      m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_REFINEMENT_ENDS));
     145              : //              else
     146              : //                      m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_REFINEMENT_ENDS));
     147              : 
     148              :         //      and finally - if we posted an adaption-begins message, then we'll post
     149              :         //      an adaption ends message, too.
     150            0 :                 if(locallyActivatedAdaption){
     151            0 :                         adaption_ends();
     152              :                 }
     153              :         }
     154            0 :         CATCH_STD_EXCEPTIONS();
     155              :         
     156              :         #ifdef UG_PARALLEL
     157              :                 PCL_DEBUG_BARRIER_ALL();
     158              :         #endif
     159            0 : }
     160              : 
     161              : 
     162            0 : bool IRefiner::coarsen()
     163              : {
     164              :         #ifdef UG_PARALLEL
     165              :                 PCL_DEBUG_BARRIER_ALL();
     166              :         #endif
     167              :         PROFILE_BEGIN_GROUP(IRefiner_coarsen, "grid");
     168              : //      if coarsen isn't supported, we'll leave right away
     169            0 :         if(!coarsening_supported())
     170              :                 return false;
     171              : 
     172            0 :         if(!m_messageHub.valid()){
     173            0 :                 UG_THROW("A message-hub has to be assigned to IRefiner before coarsen may be called. "
     174              :                                 "Make sure that you assigned a grid to the refiner you're using.");
     175              :         }
     176              : 
     177              : //      we'll schedule an adaption-begins message, if adaption is not yet enabled.
     178              :         bool locallyActivatedAdaption = false;
     179            0 :         if(!m_adaptionIsActive){
     180              :                 locallyActivatedAdaption = true;
     181            0 :                 adaption_begins();
     182              :         }
     183              : 
     184              : //      now post a message, which informs that coarsening begins
     185              : //      if(adaptivity_supported())
     186              : //              m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_COARSENING_BEGINS));
     187              : //      else
     188              : //              m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_COARSENING_BEGINS));
     189              : 
     190              : //      now perform coarsening
     191            0 :         bool retVal = perform_coarsening();
     192              : 
     193              : //      post a message that coarsening has been finished
     194              : //      if(adaptivity_supported())
     195              : //              m_messageHub->post_message(GridMessage_Adaption(GMAT_HNODE_COARSENING_ENDS));
     196              : //      else
     197              : //              m_messageHub->post_message(GridMessage_Adaption(GMAT_GLOBAL_COARSENING_ENDS));
     198              : 
     199              : //      and finally - if we posted an adaption-begins message, then we'll post
     200              : //      an adaption ends message, too.
     201            0 :         if(locallyActivatedAdaption)
     202            0 :                 adaption_ends();
     203              : 
     204              : //      done
     205              :         #ifdef UG_PARALLEL
     206              :                 PCL_DEBUG_BARRIER_ALL();
     207              :         #endif
     208              :         return retVal;
     209              : }
     210              : 
     211              : 
     212            0 : void IRefiner::set_message_hub(SPMessageHub msgHub)
     213              : {
     214            0 :         m_messageHub = msgHub;
     215            0 : }
     216              : 
     217            0 : void IRefiner::set_adjusted_marks_debug_filename(const char* filename)
     218              : {
     219            0 :         if(!filename)
     220            0 :                 m_adjustedMarksDebugFilename = "";
     221              :         else
     222            0 :                 m_adjustedMarksDebugFilename = filename;
     223            0 : }
     224              : 
     225              : 
     226            0 : int IRefiner::
     227              : get_local_edge_mark(Face* f, Edge* e) const
     228              : {
     229            0 :         const int edgeInd = GetEdgeIndex(f, e);
     230            0 :         UG_COND_THROW(edgeInd == -1, "Given edge is not an edge of the given face.");
     231              : 
     232            0 :         if(marked_local(f)){
     233            0 :                 const int faceLocalMark = get_local_mark(f);
     234            0 :                 return (faceLocalMark >> edgeInd) & 1;
     235              :         }
     236            0 :         else if(marked_full(f)){
     237              :                 return 1;
     238              :         }
     239            0 :         else if(marked_closure(f)){
     240              : 
     241            0 :                 return static_cast<int>(marked_full(e));
     242              :         }
     243              :         return 0;
     244              : }
     245              : 
     246            0 : int IRefiner::
     247              : get_local_edge_mark(Volume* vol, Edge* e) const
     248              : {
     249            0 :         const int edgeInd = GetEdgeIndex(vol, e);
     250            0 :         UG_COND_THROW(edgeInd == -1, "Given edge is not an edge of the given volume.");
     251              : 
     252            0 :         if(marked_local(vol)){
     253            0 :                 const int volLocalMark = get_local_mark(vol);
     254            0 :                 return (volLocalMark >> edgeInd) & 1;
     255              :         }
     256            0 :         else if(marked_full(vol)){
     257              :                 return 1;
     258              :         }
     259            0 :         else if(marked_closure(vol)){
     260            0 :                 return static_cast<int>(marked_full(e));
     261              :         }
     262              :         return 0;
     263              : }
     264              : 
     265            0 : int IRefiner::
     266              : get_local_face_mark(Volume* vol, Face* f) const
     267              : {
     268            0 :         int sideInd = GetFaceIndex(vol, f);
     269            0 :         UG_COND_THROW(sideInd == -1, "Given face is not a side of the given volume.");
     270              : 
     271            0 :         if(marked_local(vol)){
     272            0 :                 const int volLocalMark = get_local_mark(vol);
     273            0 :                 const size_t numFaceVrts = f->num_vertices();
     274            0 :                 Face::ConstVertexArray vrts = f->vertices();
     275              : 
     276              :                 int vinds[MAX_FACE_VERTICES];
     277            0 :                 for(size_t i = 0; i < numFaceVrts; ++i){
     278            0 :                         vinds[i] = GetVertexIndex(vol, vrts[i]);
     279              :                 }
     280              : 
     281              :                 int sideMark = 0;
     282              : 
     283            0 :                 for(size_t i = 0; i < numFaceVrts; ++i){
     284              :                         const int edgeInd =
     285            0 :                                         vol->get_edge_index_from_vertices(
     286            0 :                                                         vinds[i], vinds[(i+1)%numFaceVrts]);
     287              :                         
     288            0 :                         sideMark |= ((volLocalMark >> edgeInd) & 1) << i;
     289              :                 }
     290              : 
     291              :                 return sideMark;
     292              :         }
     293            0 :         else if(marked_full(vol)){
     294              :                 int sideMark = 0;
     295            0 :                 const size_t numFaceVrts = f->num_vertices();
     296            0 :                 for(size_t i = 0; i < numFaceVrts; ++i)
     297            0 :                         sideMark |= 1 << i;
     298            0 :                 return sideMark;
     299              :         }
     300            0 :         else if(marked_closure(vol)){
     301              :                 int sideMark = 0;
     302              :                 const size_t numFaceEdges = f->num_edges();
     303            0 :                 for(size_t iedge = 0; iedge < numFaceEdges; ++iedge){
     304            0 :                         if(marked_full(const_cast<IRefiner*>(this)->grid()->get_edge(f, iedge)))
     305            0 :                                 sideMark |= 1 << iedge;
     306              :                 }
     307              : 
     308            0 :                 return sideMark;
     309              :         }
     310              :         return 0;
     311              : }
     312              : 
     313              : 
     314            0 : size_t IRefiner::num_marked_edges(std::vector<int>& numMarkedEdgesOut)
     315              : {
     316              :         #ifdef UG_PARALLEL
     317              :                 std::vector<int> numLocal;
     318              :                 num_marked_edges_local(numLocal);
     319              :                 pcl::ProcessCommunicator com;
     320              :                 com.allreduce(numLocal, numMarkedEdgesOut, PCL_RO_SUM);
     321              :         #else
     322            0 :                 num_marked_edges_local(numMarkedEdgesOut);
     323              :         #endif
     324              : 
     325              :         size_t total = 0;
     326            0 :         for(size_t i = 0; i < numMarkedEdgesOut.size(); ++i){
     327            0 :                 total += numMarkedEdgesOut[i];
     328              :         }
     329            0 :         return total;
     330              : }
     331              : 
     332            0 : size_t IRefiner::num_marked_faces(std::vector<int>& numMarkedFacesOut)
     333              : {
     334              :         #ifdef UG_PARALLEL
     335              :                 std::vector<int> numLocal;
     336              :                 num_marked_faces_local(numLocal);
     337              :                 pcl::ProcessCommunicator com;
     338              :                 com.allreduce(numLocal, numMarkedFacesOut, PCL_RO_SUM);
     339              :         #else
     340            0 :                 num_marked_faces_local(numMarkedFacesOut);
     341              :         #endif
     342              : 
     343              :         size_t total = 0;
     344            0 :         for(size_t i = 0; i < numMarkedFacesOut.size(); ++i){
     345            0 :                 total += numMarkedFacesOut[i];
     346              :         }
     347            0 :         return total;
     348              : }
     349              : 
     350            0 : size_t IRefiner::num_marked_volumes(std::vector<int>& numMarkedVolsOut)
     351              : {
     352              :         #ifdef UG_PARALLEL
     353              :                 std::vector<int> numLocal;
     354              :                 num_marked_volumes_local(numLocal);
     355              :                 pcl::ProcessCommunicator com;
     356              :                 com.allreduce(numLocal, numMarkedVolsOut, PCL_RO_SUM);
     357              :         #else
     358            0 :                 num_marked_volumes_local(numMarkedVolsOut);
     359              :         #endif
     360              : 
     361              :         size_t total = 0;
     362            0 :         for(size_t i = 0; i < numMarkedVolsOut.size(); ++i){
     363            0 :                 total += numMarkedVolsOut[i];
     364              :         }
     365            0 :         return total;
     366              : }
     367              : 
     368            0 : size_t IRefiner::num_marked_elements(std::vector<int>& numMarkedElemsOut)
     369              : {
     370            0 :         if(grid()){
     371            0 :                 Grid& g = *grid();
     372              : 
     373              :                 size_t numVolumes = g.num<Volume>();
     374              :                 size_t numFaces = g.num<Face>();
     375              :                 size_t numEdges = g.num<Edge>();
     376              : 
     377              :                 #ifdef UG_PARALLEL
     378              :                         pcl::ProcessCommunicator com;
     379              :                         numVolumes = com.allreduce(numVolumes, PCL_RO_SUM);
     380              :                         numFaces = com.allreduce(numFaces, PCL_RO_SUM);
     381              :                         numEdges = com.allreduce(numEdges, PCL_RO_SUM);
     382              :                 #endif
     383              : 
     384            0 :                 if(numVolumes > 0)
     385            0 :                         return num_marked_volumes(numMarkedElemsOut);
     386            0 :                 else if(numFaces > 0)
     387            0 :                         return num_marked_faces(numMarkedElemsOut);
     388            0 :                 else if(numEdges > 0)
     389            0 :                         return num_marked_edges(numMarkedElemsOut);
     390              :                 else
     391              :                         return 0;
     392              :         }
     393              :         return 0;
     394              : }
     395              : 
     396              : }// end of namespace
        

Generated by: LCOV version 2.0-1