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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Scherer
       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 "periodic_boundary_manager.h"
      34              : 
      35              : namespace ug {
      36              : 
      37            0 : PeriodicBoundaryManager::PeriodicBoundaryManager() :
      38            0 :                                 m_pGrid(NULL)/*, m_pSH(NULL)*/ {}
      39              : 
      40            0 : PeriodicBoundaryManager::~PeriodicBoundaryManager()
      41              : {
      42              :         // set grid to NULL to detach groups from grid
      43            0 :         set_grid(NULL);
      44            0 : }
      45              : 
      46            0 : void PeriodicBoundaryManager::set_grid(Grid* g)
      47              : {
      48              :         // group attachments
      49              :         Attachment<Group<Vertex>*> aGroupVRT;
      50              :         Attachment<Group<Edge>*> aGroupEDG;
      51              :         Attachment<Group<Face>*> aGroupFCE;
      52              : 
      53              :         // periodic info attachments
      54              :         Attachment<PeriodicStatus> aPeriodicStatus;
      55              : 
      56              :         // detach groups and unregister observer
      57            0 :         if(m_pGrid) {
      58              :                 m_pGrid->detach_from_vertices(aGroupVRT);
      59            0 :                 m_pGrid->detach_from_edges(aGroupEDG);
      60            0 :                 m_pGrid->detach_from_faces(aGroupFCE);
      61              : 
      62            0 :                 m_pGrid->detach_from_vertices(aPeriodicStatus);
      63            0 :                 m_pGrid->detach_from_edges(aPeriodicStatus);
      64            0 :                 m_pGrid->detach_from_faces(aPeriodicStatus);
      65              : 
      66            0 :                 m_pGrid->unregister_observer(this);
      67              :         }
      68              : 
      69            0 :         m_pGrid = dynamic_cast<MultiGrid*>(g);
      70              : 
      71              :         // attach groups and register observer
      72            0 :         if(m_pGrid != NULL) {
      73            0 :                 m_pGrid->attach_to_vertices_dv(aGroupVRT, NULL);
      74            0 :                 m_pGrid->attach_to_edges_dv(aGroupEDG, NULL);
      75            0 :                 m_pGrid->attach_to_faces_dv(aGroupFCE, NULL);
      76              : 
      77            0 :                 m_pGrid->attach_to_vertices_dv(aPeriodicStatus, P_NOT_PERIODIC);
      78            0 :                 m_pGrid->attach_to_edges_dv(aPeriodicStatus, P_NOT_PERIODIC);
      79            0 :                 m_pGrid->attach_to_faces_dv(aPeriodicStatus, P_NOT_PERIODIC);
      80              : 
      81              :                 // access grid with those attachments
      82            0 :                 m_aaGroupVRT.access(*m_pGrid, aGroupVRT);
      83              :                 m_aaGroupEDG.access(*m_pGrid, aGroupEDG);
      84              :                 m_aaGroupFCE.access(*m_pGrid, aGroupFCE);
      85              : 
      86              :                 m_aaPeriodicStatusVRT.access(*m_pGrid, aPeriodicStatus);
      87              :                 m_aaPeriodicStatusEDG.access(*m_pGrid, aPeriodicStatus);
      88              :                 m_aaPeriodicStatusFCE.access(*m_pGrid, aPeriodicStatus);
      89              : 
      90              :                 uint options = OT_GRID_OBSERVER | OT_VERTEX_OBSERVER | OT_EDGE_OBSERVER |
      91              :                                 OT_FACE_OBSERVER;
      92            0 :                 m_pGrid->register_observer(this, options);
      93              :         }
      94            0 : }
      95              : 
      96            0 : Grid* PeriodicBoundaryManager::get_grid() const {
      97            0 :         return m_pGrid;
      98              : }
      99              : 
     100              : //void PeriodicBoundaryManager::set_subset_handler(ISubsetHandler* sh) {
     101              : //      m_pSH = sh;
     102              : //      // very small memory overhead buys constant access time in match() methods
     103              : //      m_vIdentifier.resize(m_pSH->num_subsets());
     104              : //}
     105              : 
     106              : // group accessors
     107              : template <>
     108              : Grid::AttachmentAccessor<Vertex, Attachment<PeriodicBoundaryManager::Group<Vertex>* > >&
     109            0 : PeriodicBoundaryManager::get_group_accessor() {
     110            0 :         return m_aaGroupVRT;
     111              : }
     112              : 
     113              : template <>
     114              : Grid::AttachmentAccessor<Edge, Attachment<PeriodicBoundaryManager::Group<Edge>* > >&
     115            0 : PeriodicBoundaryManager::get_group_accessor() {
     116            0 :         return m_aaGroupEDG;
     117              : }
     118              : 
     119              : template <>
     120              : Grid::AttachmentAccessor<Face, Attachment<PeriodicBoundaryManager::Group<Face>* > >&
     121            0 : PeriodicBoundaryManager::get_group_accessor() {
     122            0 :         return m_aaGroupFCE;
     123              : }
     124              : 
     125              : template <>
     126              : const Grid::AttachmentAccessor<Vertex, Attachment<PeriodicBoundaryManager::Group<Vertex>* > >&
     127            0 : PeriodicBoundaryManager::get_group_accessor() const {
     128            0 :         return m_aaGroupVRT;
     129              : }
     130              : 
     131              : template <>
     132              : const Grid::AttachmentAccessor<Edge, Attachment<PeriodicBoundaryManager::Group<Edge>* > >&
     133            0 : PeriodicBoundaryManager::get_group_accessor() const {
     134            0 :         return m_aaGroupEDG;
     135              : }
     136              : 
     137              : template <>
     138              : const Grid::AttachmentAccessor<Face, Attachment<PeriodicBoundaryManager::Group<Face>* > >&
     139            0 : PeriodicBoundaryManager::get_group_accessor() const {
     140            0 :         return m_aaGroupFCE;
     141              : }
     142              : 
     143              : template <>
     144              : const Grid::AttachmentAccessor<Volume, Attachment<PeriodicBoundaryManager::Group<Volume>* > >&
     145            0 : PeriodicBoundaryManager::get_group_accessor() const {
     146            0 :         UG_THROW("not impled");
     147              : }
     148              : 
     149              : // periodic status accessors
     150              : template <>
     151              : const Grid::AttachmentAccessor<Vertex, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     152            0 : PeriodicBoundaryManager::get_periodic_status_accessor() const {
     153            0 :         return m_aaPeriodicStatusVRT;
     154              : }
     155              : 
     156              : template <>
     157              : Grid::AttachmentAccessor<Vertex, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     158            0 : PeriodicBoundaryManager::get_periodic_status_accessor() {
     159            0 :         return m_aaPeriodicStatusVRT;
     160              : }
     161              : 
     162              : template <>
     163              : const Grid::AttachmentAccessor<Edge, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     164            0 : PeriodicBoundaryManager::get_periodic_status_accessor() const {
     165            0 :         return m_aaPeriodicStatusEDG;
     166              : }
     167              : 
     168              : template <>
     169              : Grid::AttachmentAccessor<Edge, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     170            0 : PeriodicBoundaryManager::get_periodic_status_accessor() {
     171            0 :         return m_aaPeriodicStatusEDG;
     172              : }
     173              : 
     174              : template <>
     175              : Grid::AttachmentAccessor<Face, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     176            0 : PeriodicBoundaryManager::get_periodic_status_accessor() {
     177            0 :         return m_aaPeriodicStatusFCE;
     178              : }
     179              : 
     180              : template <>
     181              : const Grid::AttachmentAccessor<Face, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     182            0 : PeriodicBoundaryManager::get_periodic_status_accessor() const {
     183            0 :         return m_aaPeriodicStatusFCE;
     184              : }
     185              : 
     186              : template <>
     187              : Grid::AttachmentAccessor<Volume, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     188            0 : PeriodicBoundaryManager::get_periodic_status_accessor() {
     189            0 :         UG_THROW("not impled");
     190              : }
     191              : 
     192              : template <>
     193              : const Grid::AttachmentAccessor<Volume, Attachment<PeriodicBoundaryManager::PeriodicStatus> >&
     194            0 : PeriodicBoundaryManager::get_periodic_status_accessor() const {
     195            0 :         UG_THROW("not impled");
     196              : }
     197              : 
     198              : ///// grid observer methods
     199            0 : void PeriodicBoundaryManager::grid_to_be_destroyed(Grid* grid) {
     200              : 
     201              :         /// delete groups
     202            0 :         for (VertexIterator iter = m_pGrid->begin<Vertex>();
     203            0 :                         iter != m_pGrid->end<Vertex>(); ++iter) {
     204            0 :                 if(is_master(*iter)) delete m_aaGroupVRT[*iter];
     205              :         }
     206              : 
     207              :         for (EdgeIterator iter = m_pGrid->begin<Edge>();
     208            0 :                         iter != m_pGrid->end<Edge>(); ++iter) {
     209            0 :                 if(is_master(*iter)) delete m_aaGroupEDG[*iter];
     210              :         }
     211              : 
     212              :         for (FaceIterator iter = m_pGrid->begin<Face>();
     213            0 :                         iter != m_pGrid->end<Face>(); ++iter) {
     214            0 :                 if(is_master(*iter)) delete m_aaGroupFCE[*iter];
     215              :         }
     216              : 
     217            0 :         set_grid(NULL);
     218            0 : }
     219              : 
     220            0 : void PeriodicBoundaryManager::vertex_created(Grid* grid, Vertex* vrt,
     221              :                 GridObject* pParent, bool replacesParent) {
     222            0 :         handle_creation_cast_wrapper(vrt, pParent, replacesParent);
     223            0 : }
     224              : 
     225            0 : void PeriodicBoundaryManager::edge_created(Grid* grid, Edge* e, GridObject* pParent,
     226              :                 bool replacesParent) {
     227            0 :         handle_creation_cast_wrapper(e, pParent, replacesParent);
     228            0 : }
     229              : 
     230            0 : void PeriodicBoundaryManager::face_created(Grid* grid, Face* f, GridObject* pParent,
     231              :                 bool replacesParent) {
     232            0 :         handle_creation_cast_wrapper(f, pParent, replacesParent);
     233            0 : }
     234              : 
     235            0 : void PeriodicBoundaryManager::vertex_to_be_erased(Grid* grid, Vertex* vrt,
     236              :                 Vertex* replacedBy) {
     237            0 :         handle_deletion(vrt, replacedBy);
     238            0 : }
     239              : 
     240            0 : void PeriodicBoundaryManager::edge_to_be_erased(Grid* grid, Edge* e,
     241              :                 Edge* replacedBy) {
     242            0 :         handle_deletion(e, replacedBy);
     243            0 : }
     244              : 
     245            0 : void PeriodicBoundaryManager::face_to_be_erased(Grid* grid, Face* f,
     246              :                 Face* replacedBy) {
     247            0 :         handle_deletion(f, replacedBy);
     248            0 : }
     249              : 
     250              : /**
     251              :  * performs following checks on all elements in goc1 and goc2
     252              :  * 1. all elements given are periodic
     253              :  * 2. masters of groups are valid (master pointer of group valid + have at least one child)
     254              :  * 3. no duplicate master, slave pairs exists
     255              :  * 4.
     256              :  */
     257            0 : bool PeriodicBoundaryManager::check_periodicity(
     258              :                 const GridObjectCollection& goc1,
     259              :                 const GridObjectCollection& goc2, ISubsetHandler* sh) {
     260              : 
     261              :         Group<Vertex>::unique_pairs s_vert;
     262              :         Group<Edge>::unique_pairs s_edge;
     263              :         Group<Face>::unique_pairs s_face;
     264              : 
     265              :         UG_ASSERT(goc1.num_levels() == goc2.num_levels(),
     266              :                         "collections have different mg levels!")
     267              : 
     268            0 :         for (size_t lvl = 0; lvl < goc1.num_levels(); lvl++) {
     269              :                 // check faces
     270            0 :                 check_elements_periodicity<Face>(goc1.begin<Face>(lvl),
     271            0 :                                 goc1.end<Face>(lvl), s_face, sh);
     272            0 :                 check_elements_periodicity<Face>(goc2.begin<Face>(lvl),
     273            0 :                                 goc2.end<Face>(lvl), s_face, sh);
     274              : 
     275              :                 // check edges
     276            0 :                 check_elements_periodicity<Edge>(goc1.begin<Edge>(lvl),
     277            0 :                                 goc1.end<Edge>(lvl), s_edge, sh);
     278            0 :                 check_elements_periodicity<Edge>(goc2.begin<Edge>(lvl),
     279            0 :                                 goc2.end<Edge>(lvl), s_edge, sh);
     280              : 
     281              :                 // check vertices
     282            0 :                 check_elements_periodicity<Vertex>(goc1.begin<Vertex>(lvl),
     283            0 :                                 goc1.end<Vertex>(lvl), s_vert, sh);
     284            0 :                 check_elements_periodicity<Vertex>(goc2.begin<Vertex>(lvl),
     285            0 :                                 goc2.end<Vertex>(lvl), s_vert, sh);
     286              :         }
     287              : 
     288            0 :         return true;
     289              : }
     290              : 
     291              : 
     292              : template <class elem_t>
     293            0 : void PeriodicBoundaryManager::validity_check()
     294              : {
     295              :         typedef typename Grid::traits<elem_t>::iterator   iter_t;
     296              :         typedef typename Group<elem_t>::SlaveContainer    slave_container_t;
     297              :         typedef typename slave_container_t::iterator    slave_iter_t;
     298              : 
     299              :         Grid::AttachmentAccessor<elem_t, Attachment<PeriodicStatus> >
     300            0 :                 aaPS = get_periodic_status_accessor<elem_t>();
     301              : 
     302              :         Grid::AttachmentAccessor<elem_t, Attachment<Group<elem_t>* > >
     303            0 :                 aaGroup = get_group_accessor<elem_t>();
     304              : 
     305            0 :         Grid& g = *m_pGrid;
     306              : 
     307            0 :         for(iter_t i_elem = g.begin<elem_t>(); i_elem != g.end<elem_t>(); ++ i_elem)
     308              :         {
     309              :                 elem_t* e = *i_elem;
     310            0 :                 if(aaGroup[e]){
     311            0 :                         bool isMaster = (aaGroup[e]->m_master == e);
     312              :                         int elemSlaveCount = 0;
     313              :                         int totalSlaveCount = 0;
     314              :                         slave_container_t* slaveCon = &aaGroup[e]->get_slaves();
     315            0 :                         for(slave_iter_t i = slaveCon->begin(); i != slaveCon->end(); ++i)
     316              :                         {
     317            0 :                                 ++totalSlaveCount;
     318            0 :                                 if(*i == e)
     319            0 :                                         ++elemSlaveCount;
     320              :                         }
     321              : 
     322            0 :                         if(aaGroup[e]->m_master == NULL){
     323            0 :                                 UG_THROW("Group doesn't contain a master!\n"
     324              :                                                  << "  elem-info: " << ElementDebugInfo(g, e));
     325              :                         }
     326            0 :                         if(totalSlaveCount == 0){
     327            0 :                                 UG_THROW("Group doesn't contain slaves!\n"
     328              :                                                  << "  elem-info: " << ElementDebugInfo(g, e));
     329              :                         }
     330              : 
     331            0 :                         if(isMaster && (elemSlaveCount > 0)){
     332            0 :                                 UG_THROW("An element is contained both in the master list and in the"
     333              :                                                  " slave list of its group!\n"
     334              :                                                  << "  elem-info: " << ElementDebugInfo(g, e));
     335              :                         }
     336            0 :                         if(elemSlaveCount > 1){
     337            0 :                                 UG_THROW("Multi-occurance of an element in a groups slave list!\n"
     338              :                                                  << "  elem-info: " << ElementDebugInfo(g, e));
     339              :                         }
     340            0 :                         if((!isMaster) && (elemSlaveCount == 0)){
     341            0 :                                 UG_THROW("An element points to a group but is not contained in that group!\n"
     342              :                                                  << "  elem-info: " << ElementDebugInfo(g, e));
     343              :                         }
     344              :                         
     345              :                 //      the element is either master or slave. now check whether the states are correct
     346            0 :                         if(isMaster){
     347            0 :                                 if(aaPS[e] != P_MASTER){
     348            0 :                                         UG_THROW("An element is a groups master, but its state does not say so!\n"
     349              :                                                          << "  state: " << aaPS[e] << "\n"
     350              :                                                          << "  elem-info: " << ElementDebugInfo(g, e));
     351              :                                 }
     352              :                         //      make sure that all slaves have their group assigned
     353            0 :                                 for(slave_iter_t i = slaveCon->begin(); i != slaveCon->end(); ++i)
     354              :                                 {
     355            0 :                                         if(aaGroup[*i] != aaGroup[e]){
     356            0 :                                                 UG_THROW("A slave element was encountered, which does not"
     357              :                                                                  << " point to the same group as it's master!\n"
     358              :                                                                  << "  master: " << ElementDebugInfo(g, e) << "\n"
     359              :                                                                  << "  slave: " << ElementDebugInfo(g, *i) << "\n");
     360              :                                         }
     361              :                                 }
     362              :                         }
     363              :                         else{
     364            0 :                                 if(aaPS[e] == P_SLAVE_MASTER_UNKNOWN){
     365            0 :                                         UG_THROW("P_SLAVE_MASTER_UNKNOWN is not a valid state!\n"
     366              :                                                          << "  elem-info: " << ElementDebugInfo(g, e));
     367              :                                 }
     368            0 :                                 else if(aaPS[e] != P_SLAVE)
     369              :                                 {
     370            0 :                                         UG_THROW("An element is a slave, but its state does not say so!\n"
     371              :                                                          << "  state: " << aaPS[e] << "\n"
     372              :                                                          << "  elem-info: " << ElementDebugInfo(g, e));
     373              :                                 }
     374              : 
     375            0 :                                 if(aaGroup[e] != aaGroup[aaGroup[e]->m_master]){
     376            0 :                                         UG_THROW("A master element was encountered, which does not"
     377              :                                                          << " point to the same group as it's slave!\n"
     378              :                                                          << "  master: " << ElementDebugInfo(g, aaGroup[e]->m_master) << "\n"
     379              :                                                          << "  slave: " << ElementDebugInfo(g, e) << "\n");
     380              :                                 }
     381              :                         }
     382              :                 }
     383            0 :                 else if(aaPS[e] != P_NOT_PERIODIC){
     384            0 :                         UG_THROW("An element is marked as periodic but not contained in a group!\n"
     385              :                                          << "  state: " << aaPS[e] << "\n"
     386              :                                          << "  elem-info: " << ElementDebugInfo(g, e));
     387              :                 }
     388              :         }
     389            0 : }
     390              : 
     391            0 : void PeriodicBoundaryManager::validity_check()
     392              : {
     393            0 :         validity_check<Vertex>();
     394            0 :         validity_check<Edge>();
     395            0 :         validity_check<Face>();
     396            0 : }
     397              : 
     398              : //void PeriodicBoundaryManager::set_identifier(SmartPtr<IIdentifier> i, size_t si) {
     399              : //      UG_ASSERT(m_vIdentifier.capacity() >= si, "identifier vector not big enough")
     400              : //      m_vIdentifier[si] = i;
     401              : //}
     402              : 
     403              : } // end of namespace ug
        

Generated by: LCOV version 2.0-1