LCOV - code coverage report
Current view: top level - ugbase/lib_grid/tools - periodic_boundary_manager.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 10 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 16 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              : #ifndef PERIODIC_IDENTIFIER_H_
      34              : #define PERIODIC_IDENTIFIER_H_
      35              : 
      36              : #include "lib_grid/grid/grid.h"
      37              : #include "lib_grid/multi_grid.h"
      38              : #include "lib_grid/grid/grid_base_objects.h"
      39              : 
      40              : #include <set>
      41              : 
      42              : namespace ug {
      43              : 
      44              : /// Interface to match periodic geometric elements
      45              : /**
      46              :  *
      47              :  */
      48              : class IIdentifier {
      49              : public:
      50              :         virtual ~IIdentifier() {}
      51              :         virtual bool match(Vertex*, Vertex*) = 0;
      52              :         virtual bool match(Edge*, Edge*) = 0;
      53              :         virtual bool match(Face*, Face*) = 0;
      54            0 :         virtual bool match(Volume*, Volume*) {UG_THROW("not impled, because volume identification is not supported.")}
      55              : };
      56              : 
      57              : /// This class matches geometric elements which are parallel translated.
      58              : /**
      59              :  * Usage: class needs to be instantiated with the position attachment used on the Domain.
      60              :  * Before using any match methods, the translation vector needs to be set with set_shift()
      61              :  * \tparam <TPosAA>{class needs to be instantiated with the
      62              :  * position attachment used on the Domain.}
      63              :  */
      64              : template<class TPosAA> class ParallelShiftIdentifier: public IIdentifier {
      65              : public:
      66            0 :         virtual bool match(Vertex* v1, Vertex* v2) {return match_impl(v1, v2);}
      67            0 :         virtual bool match(Edge* e1, Edge* e2) {return match_impl(e1, e2);}
      68            0 :         virtual bool match(Face* f1, Face* f2) {return match_impl(f1, f2);}
      69              : 
      70            0 :         virtual ~ParallelShiftIdentifier() {}
      71              :         typedef typename TPosAA::ValueType AttachmentType;
      72            0 :         ParallelShiftIdentifier(TPosAA& aa) : m_aaPos(aa) {}
      73              :         void set_shift(AttachmentType& shift) {m_shift = shift; VecScale(m_shift_opposite, m_shift, -1);}
      74              : protected:
      75              :         AttachmentType m_shift;
      76              :         AttachmentType m_shift_opposite;
      77              :         TPosAA& m_aaPos;
      78              :         template<class TElem> bool match_impl(TElem*, TElem*) const;
      79              : };
      80              : 
      81              : 
      82              : //template<class TPosAA, int dim> class TransformationBasedIdentifier : public IIdentifier {
      83              : //public:
      84              : //      TransformationBasedIdentifier(TPosAA& aa) : m_aaPos(aa) {}
      85              : //      void setTransformation(MathMatrix<dim,dim>& T) {this->T = T;}
      86              : //
      87              : //      virtual bool match(Vertex*, Vertex*);
      88              : //      virtual bool match(Edge*, Edge*);
      89              : //      virtual bool match(Face*, Face*);
      90              : //protected:
      91              : //      MathMatrix<dim,dim> T;
      92              : //      TPosAA& m_aaPos;
      93              : //};
      94              : 
      95              : ///
      96              : /**
      97              :  *
      98              :  */
      99              : class PeriodicBoundaryManager : public GridObserver {
     100              : public:
     101              : 
     102              :         /**
     103              :          * A Group instance holds a master of type TElem and several children.
     104              :          */
     105              :         template <class TElem, class Container = std::vector<TElem*> >
     106            0 :         class Group
     107              :         {
     108              :                 public:
     109              :                         typedef Container SlaveContainer;
     110              :                         typedef typename Container::iterator SlaveIterator;
     111              :                         // the set typedefs are used to check for periodicity after identification
     112              :                         typedef typename std::pair<TElem*, TElem*> master_slave_pair;
     113              :                         typedef typename std::set<master_slave_pair> unique_pairs;
     114              : 
     115            0 :                         Group(TElem* m = NULL) : m_master(m) {}
     116              : 
     117              :                         void add_slave(TElem* e) {
     118              :                                 UG_ASSERT(e, "add_slave: slave not valid");
     119              :                                 UG_ASSERT(e != m_master, "element already master!");
     120            0 :                                 m_slaves.push_back(e); }
     121              : 
     122            0 :                         Container& get_slaves() { return m_slaves; }
     123              :                         TElem* m_master;
     124              : 
     125              :                 protected:
     126              :                         Container m_slaves;
     127              :         };
     128              : 
     129              :         enum PeriodicStatus {
     130              :                 P_SLAVE, P_SLAVE_MASTER_UNKNOWN, P_MASTER, P_NOT_PERIODIC
     131              :         };
     132              : 
     133              :         PeriodicBoundaryManager();
     134              :         ~PeriodicBoundaryManager();
     135              : 
     136              :         // sets grid and inits group info attachment accessors
     137              :         void set_grid(Grid* g);
     138              :         Grid* get_grid() const;
     139              : 
     140              :         // sets the subset handler to use for element lookup
     141              : //      void set_subset_handler(ISubsetHandler* sh);
     142              : 
     143              :         ///
     144              :         /**
     145              :          * ATTENTION: method assumes, that e1 and e2 are matching!
     146              :          * identifies element e1 with e2. If element type has sides, it will recursively
     147              :          * ascend to the lowest dimension type (vertex) and identifies them.
     148              :          * @param e1
     149              :          * @param e2
     150              :          * @param i identifier to use to perform geometrical matching of elements
     151              :          */
     152              :         template <class TElem> void identify(TElem* e1, TElem* e2, IIdentifier& i);
     153              : 
     154              :         template <class TElem> bool is_periodic(TElem* e) const;
     155              :         template <class TElem> bool is_slave(TElem*) const;
     156              :         template <class TElem> bool is_master(TElem*) const;
     157              :         template <class TElem> TElem* master(TElem* e) const;
     158              :         template <class TElem> typename Group<TElem>::SlaveContainer* slaves(
     159              :                         TElem* e) const;
     160              :         template <class TElem> void print_identification() const;
     161              : 
     162              : 
     163              :         /// grid observation methods
     164              :         virtual void grid_to_be_destroyed(Grid* grid);
     165              :         virtual void vertex_created(Grid* grid, Vertex* vrt,
     166              :                                                                                 GridObject* pParent = NULL,
     167              :                                                                                 bool replacesParent = false);
     168              : 
     169              :         virtual void edge_created(Grid* grid, Edge* e,
     170              :                                                                 GridObject* pParent = NULL,
     171              :                                                                 bool replacesParent = false);
     172              : 
     173              :         virtual void face_created(Grid* grid, Face* f,
     174              :                                                                 GridObject* pParent = NULL,
     175              :                                                                 bool replacesParent = false);
     176              : 
     177              :         virtual void vertex_to_be_erased(Grid* grid, Vertex* vrt,
     178              :                                                                          Vertex* replacedBy = NULL);
     179              : 
     180              :         virtual void edge_to_be_erased(Grid* grid, Edge* e,
     181              :                                                                          Edge* replacedBy = NULL);
     182              : 
     183              :         virtual void face_to_be_erased(Grid* grid, Face* f,
     184              :                                                                          Face* replacedBy = NULL);
     185              : 
     186              :         /// checks that all elements of given gocs are periodic (called after identification)
     187              :         bool check_periodicity(const GridObjectCollection& goc1,
     188              :                                                           const GridObjectCollection& goc2,
     189              :                                                           ISubsetHandler* sh = NULL);
     190              : 
     191              :         /**     makes sure that all master/slave identifications are correct and that
     192              :          * no unconnected masters or slaves exist.
     193              :          * This method iterates over all elements of the grid and is thus rather expensive.*/
     194              :         void validity_check();
     195              : 
     196              :         /**
     197              :          * sets the identifier instance to use for subset index si
     198              :          * @param i identifier pointer
     199              :          * @param si
     200              :          */
     201              : //      void set_identifier(SmartPtr<IIdentifier> i, size_t si);
     202              : 
     203              : protected:
     204              :         // no copy construction allowed
     205              :         PeriodicBoundaryManager(const PeriodicBoundaryManager&)     {}
     206              : 
     207              :         /// grid instance we operate on
     208              :         MultiGrid* m_pGrid;
     209              : 
     210              :         /// store subset handler of domain to lookup element subset ids
     211              : //      ISubsetHandler* m_pSH;
     212              : 
     213              :         /// identifier mapping to subset indices
     214              :         /**
     215              :          * stores IIdentifier pointers to subset index position to look them up
     216              :          * in constant time.
     217              :          */
     218              : //      std::vector<SmartPtr<IIdentifier> > m_vIdentifier;
     219              : 
     220              :         /// attachment accessors for Groups
     221              :         Grid::AttachmentAccessor<Vertex, Attachment<Group<Vertex>* > > m_aaGroupVRT;
     222              :         Grid::AttachmentAccessor<Edge, Attachment<Group<Edge>* > > m_aaGroupEDG;
     223              :         Grid::AttachmentAccessor<Face, Attachment<Group<Face>* > > m_aaGroupFCE;
     224              : 
     225              :         /// attachment accessors for PeriodicStatus
     226              :         Grid::AttachmentAccessor<Vertex, Attachment<PeriodicStatus> > m_aaPeriodicStatusVRT;
     227              :         Grid::AttachmentAccessor<Edge, Attachment<PeriodicStatus> > m_aaPeriodicStatusEDG;
     228              :         Grid::AttachmentAccessor<Face, Attachment<PeriodicStatus> > m_aaPeriodicStatusFCE;
     229              : 
     230              :         /// make element e slave of group g
     231              :         template <class TElem> void make_slave(Group<TElem>* g, TElem* e);
     232              :         template <class TElem> bool remove_slave(TElem* slave);
     233              : 
     234              :         // make e a master of g
     235              :         template <class TElem> void make_master(Group<TElem>* g, TElem* e);
     236              : 
     237              :         template <class TElem> void merge_groups(Group<TElem>* g0, Group<TElem>* g1);
     238              : 
     239              :         // get typed attachment accessor for group attachment
     240              :         template <class TElem>
     241              :         const Grid::AttachmentAccessor<TElem, Attachment<Group<TElem>* > >&
     242              :         get_group_accessor() const;
     243              : 
     244              :         template <class TElem>
     245              :         Grid::AttachmentAccessor<TElem, Attachment<Group<TElem>* > >&
     246              :         get_group_accessor();
     247              : 
     248              :         // get typed attachment accessor for periodic status attachment
     249              :         template <class TElem>
     250              :         const Grid::AttachmentAccessor<TElem, Attachment<PeriodicStatus> >&
     251              :         get_periodic_status_accessor() const;
     252              : 
     253              :         template <class TElem>
     254              :         Grid::AttachmentAccessor<TElem, Attachment<PeriodicStatus> >&
     255              :         get_periodic_status_accessor();
     256              : 
     257              :         // gets group of given element e
     258              :         template <class TElem> Group<TElem>* group(TElem* e) const;
     259              :         // set group attachment to element e
     260              :         template <class TElem> void set_group(Group<TElem>* g, TElem* e);
     261              :         template <class TElem> void remove_group(Group<TElem>* g);
     262              : 
     263              :         ///     replaces all group occurrances of pParent by the specified elem
     264              :         template <class TElem>
     265              :         void replace_parent(TElem* e, TElem* pParent);
     266              : 
     267              :         /// handles creation of element type
     268              :         template <class TElem, class TParent>
     269              :         void handle_creation(TElem* e, TParent* pParent);
     270              : 
     271              :         /// handles deletion of element type
     272              :         template <class TElem>
     273              :         void handle_deletion(TElem* e, TElem* replacedBy);
     274              : 
     275              :         /// casts parent pointer to exact type before calling handle_creation
     276              :         template <class TElem>
     277              :         void handle_creation_cast_wrapper(TElem* e, GridObject* parent, bool replacesParent);
     278              : 
     279              :         template <class TElem, class TIterator>
     280              :         void check_elements_periodicity(
     281              :                         TIterator begin,
     282              :                         TIterator end,
     283              :                         typename Group<TElem>::unique_pairs& s,
     284              :                         ISubsetHandler* sh);
     285              : 
     286              :         template <class TElem>
     287              :         void validity_check();
     288              : 
     289              : };
     290              : 
     291              : ///     Accesses attachements with consideration to periodic boundaries
     292              : /**     Slave element redirects to related master element
     293              :  *  also works in case of no periodic boundary conditions
     294              :  *  (but is then probably slower than standard attachment accessor)
     295              :  */
     296              : template <class TElem,class TAttachment>
     297              : class PeriodicAttachmentAccessor
     298              : {
     299              :         public:
     300              :                 typedef typename TAttachment::ValueType ValueType;
     301              :                 typedef typename attachment_value_traits<ValueType>::reference RefType;
     302              :                 typedef typename attachment_value_traits<ValueType>::const_reference ConstRefType;
     303              : 
     304              :                 PeriodicAttachmentAccessor() : m_pbm(NULL)      {}
     305              : 
     306              :                 PeriodicAttachmentAccessor(Grid& g, TAttachment& a) : m_pbm(NULL)
     307              :                 {
     308              :                         access(g, a);
     309              :                 }
     310              : 
     311              :                 PeriodicAttachmentAccessor(PeriodicBoundaryManager& pbm) : m_pbm(&pbm) {}
     312              : 
     313              :                 bool access(Grid& g, TAttachment& a)
     314              :                 {
     315              :                         if (!(m_pbm)) m_pbm = g.periodic_boundary_manager();
     316              :                         return m_aa.access(g, a);
     317              :                 }
     318              : 
     319              :                 RefType operator[](TElem* e)    {
     320              :                         if(m_pbm && m_pbm->is_slave(e))
     321              :                                 return m_aa[m_pbm->master(e)];
     322              :                         return m_aa[e];
     323              :                 }
     324              : 
     325              :                 ConstRefType operator[](TElem* e) const {
     326              :                         if(m_pbm && m_pbm->is_slave(e))
     327              :                                 return m_aa[m_pbm->master(e)];
     328              :                         return m_aa[e];
     329              :                 }
     330              : 
     331              :         private:
     332              :                 Grid::AttachmentAccessor<TElem, TAttachment>      m_aa;
     333              :                 PeriodicBoundaryManager* m_pbm;
     334              : };
     335              : 
     336              : 
     337              : /**
     338              :  * \brief identifies subset 1 with subset 2. If the grid of given domain has no
     339              :  * periodic boundary manager attached, one will be created.
     340              :  *
     341              :  * \param dom Domain the periodic boundary should be defined on
     342              :  * \param sInd1 subset index which elements should be identified with elements from
     343              :  * those of sInd2
     344              :  * \param sInd2 \see{sInd1}
     345              :  */
     346              : template <class TDomain>
     347              : void IdentifySubsets(TDomain& dom, int sInd1, int sInd2);
     348              : 
     349              : /**
     350              :  * \brief identifies subset 1 with subset 2. If the grid of given domain has no
     351              :  * periodic boundary manager attached, one will be created.
     352              :  *
     353              :  * \param dom Domain the periodic boundary should be defined on
     354              :  * \param sName1 subset name which elements should be identified with elements from
     355              :  * those of sName2
     356              :  * \param sName2 \see {sName1}
     357              :  */
     358              : template <class TDomain>
     359              : void IdentifySubsets(TDomain& dom, const char* sName1, const char* sName2);
     360              : 
     361              : } // end of namespace ug
     362              : 
     363              : // include implementation
     364              : #include "./periodic_boundary_manager_impl.hpp"
     365              : 
     366              : #endif /* PERIODIC_IDENTIFIER_H_ */
        

Generated by: LCOV version 2.0-1