LCOV - code coverage report
Current view: top level - ugbase/lib_disc/ordering_strategies/algorithms - riverorder.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 66 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 108 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-2022:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Lukas Larisch
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__ORDERING_STRATEGIES_ALGORITHMS__RIVERORDER__
      34              : #define __H__UG__LIB_DISC__ORDERING_STRATEGIES_ALGORITHMS__RIVERORDER__
      35              : 
      36              : #include <boost/graph/adjacency_list.hpp>
      37              : #include <boost/graph/graph_traits.hpp>
      38              : #include <boost/graph/properties.hpp>
      39              : 
      40              : #include <vector>
      41              : #include <utility> //for pair
      42              : #include <climits> //INT_MAX
      43              : 
      44              : #include "lib_disc/domain.h"
      45              : #include "lib_disc/function_spaces/grid_function.h"
      46              : 
      47              : #include "lib_algebra/ordering_strategies/algorithms/IOrderingAlgorithm.h"
      48              : #include "lib_algebra/ordering_strategies/algorithms/util.h"
      49              : 
      50              : #include "common/error.h"
      51              : 
      52              : namespace ug{
      53              : 
      54              : 
      55              : 
      56              : template <typename TAlgebra, typename TDomain, typename O_t>
      57              : class RiverOrdering : public IOrderingAlgorithm<TAlgebra, O_t>
      58              : {
      59              : public:
      60              :         typedef typename TAlgebra::matrix_type M_t;
      61              :         typedef typename TAlgebra::vector_type V_t;
      62              :         typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> G_t;
      63              :         typedef IOrderingAlgorithm<TAlgebra, O_t> baseclass;
      64              : 
      65              :         /// Grid function type for the solution
      66              :         typedef GridFunction<TDomain, TAlgebra> GridFunc_t;
      67              : 
      68              :         typedef typename boost::graph_traits<G_t>::vertex_descriptor vd;
      69              :         typedef typename boost::graph_traits<G_t>::adjacency_iterator adj_iter;
      70              : 
      71            0 :         RiverOrdering() : m_ssIdx(-1){}
      72              : 
      73              :         /// clone constructor
      74              :         RiverOrdering( const LexOrdering<TAlgebra, TDomain, O_t> &parent )
      75              :                         : baseclass(), m_ssIdx(parent.m_ssIdx){}
      76              : 
      77            0 :         SmartPtr<IOrderingAlgorithm<TAlgebra, O_t> > clone()
      78              :         {
      79            0 :                 return make_sp(new RiverOrdering<TAlgebra, TDomain, O_t>(*this));
      80              :         }
      81              : 
      82              : 
      83            0 :         vd get_source_vertex(std::vector<BOOL>& visited, G_t& g){
      84            0 :                 for(unsigned i = 0; i < boost::num_vertices(g); ++i){
      85            0 :                         if(!visited[i] && m_sources[i]){
      86            0 :                                 if(boost::in_degree(i, g) == 1){
      87            0 :                                         visited[i] = true;
      88              :                                         adj_iter nIt, nEnd;
      89            0 :                                         boost::tie(nIt, nEnd) = boost::adjacent_vertices(i, g);
      90            0 :                                         m_sources[*nIt] = true;
      91            0 :                                         boost::clear_vertex(i, g);
      92              :                                         return i;
      93              :                                 }
      94            0 :                                 else if(boost::in_degree(i, g) == 0){
      95            0 :                                         visited[i] = true;
      96            0 :                                         return i;
      97              :                                 }
      98              :                                 else{}
      99              :                         }
     100              :                 }
     101              : 
     102              :                 return -1u;
     103              :         }
     104              : 
     105            0 :         void topological_ordering(O_t& o, G_t& g){
     106              :                 size_t n = boost::num_vertices(g);
     107            0 :                 std::vector<BOOL> visited(n, false);
     108            0 :                 for(unsigned i = 0; i < n; ++i){
     109            0 :                         auto v = get_source_vertex(visited, g);
     110            0 :                         o[v] = i;
     111              :                 }
     112            0 :         }
     113              : 
     114            0 :         void compute(){
     115            0 :                 topological_ordering(o, g);
     116              : 
     117            0 :                 g = G_t(0);
     118              : 
     119              :                 #ifdef UG_DEBUG
     120              :                 check();
     121              :                 #endif
     122            0 :         }
     123              : 
     124            0 :         void check(){
     125            0 :                 if(!is_permutation(o)){
     126            0 :                         UG_THROW(name() << "::check: Not a permutation!");
     127              :                 }
     128            0 :         }
     129              : 
     130            0 :         O_t& ordering(){
     131            0 :                 return o;
     132              :         }
     133              : 
     134            0 :         void init(M_t* A, const V_t& V){
     135              :                 const GridFunc_t* pGridF;
     136              :                 size_t numSources = 0;
     137              :                 std::string ssName;
     138              :                 size_t n = 0;
     139              : 
     140              :                 //graph construction
     141              :                 try{
     142            0 :                         if((pGridF = dynamic_cast<const GridFunc_t*>(&V)) == 0){
     143            0 :                                 UG_THROW(name() << "::init: No DoFDistribution specified.");
     144              :                         }
     145              : 
     146              :                         SmartPtr<DoFDistribution> dd = ((GridFunc_t*) pGridF)->dof_distribution();
     147              : 
     148              :                         n = dd->num_indices();
     149              : 
     150            0 :                         if(n != A->num_rows ()){
     151            0 :                                 UG_THROW(name() << "::init: #indices != #rows");
     152              :                         }
     153              : 
     154            0 :                         m_ssIdx = pGridF->domain()->subset_handler()->get_subset_index(m_ssName);
     155              : 
     156            0 :                         if(m_ssIdx < 0)
     157            0 :                                 UG_THROW(name() << "::init: Invalid subset for sources selected! Call 'select_sources(const char*)'.");
     158              : 
     159            0 :                         std::vector<std::vector<size_t> > vvConnection(n);
     160              :                         try{
     161            0 :                                 dd->get_connections<ug::Edge>(vvConnection);
     162              :                         }
     163            0 :                         UG_CATCH_THROW(name() << "::init: No adjacency graph available!");
     164              : 
     165            0 :                         g = G_t(n);
     166              : 
     167            0 :                         for(unsigned i = 0; i < n; ++i){
     168            0 :                                 for(unsigned j = 0; j < vvConnection[i].size(); ++j){
     169            0 :                                         if(i != vvConnection[i][j]){ //no self loops!
     170            0 :                                                 boost::add_edge(i, vvConnection[i][j], g);
     171              :                                         }
     172              :                                 }
     173              :                         }
     174            0 :                 }
     175            0 :                 catch(...){
     176            0 :                         throw;
     177              :                 }
     178              : 
     179            0 :                 o.resize(n);
     180            0 :                 m_sources = std::vector<BOOL>(n, false);
     181              : 
     182              :                 //select source vertices according to m_ssIdx
     183              :                 typedef typename GridFunc_t::template traits<ug::Vertex>::const_iterator ugVertIt_t;
     184              : 
     185              :                 ugVertIt_t ugVertIt = pGridF->template begin<ug::Vertex>();
     186              :                 ugVertIt_t ugVertEnd = pGridF->template end<ug::Vertex>();
     187              :                 size_t k = 0;
     188            0 :                 for(; ugVertIt != ugVertEnd; ++ugVertIt, ++k){
     189              :                         ug::Vertex* v = *ugVertIt;
     190              : 
     191            0 :                         int si = pGridF->domain()->subset_handler()->get_subset_index(v);
     192              : 
     193            0 :                         if(si == m_ssIdx){
     194            0 :                                 m_sources[k] = true;
     195              :                                 ++numSources;
     196              :                         }
     197              :                 }
     198              : 
     199              :                 #ifdef UG_ENABLE_DEBUG_LOGS
     200              :                 UG_LOG("Using " << name() << " (subset " << m_ssIdx << ", " << m_ssName
     201              :                                 << ", n=" << boost::num_vertices(g) << ", m=2*" << boost::num_edges(g)/2
     202              :                                 << ", s=" <<  numSources << ")\n");
     203              :                 #endif
     204            0 :         }
     205              : 
     206            0 :         void init(M_t*){
     207            0 :                 UG_THROW(name() << "::init: Cannot initialize smoother without a geometry. Specify the 2nd argument for init!");
     208              :         }
     209              : 
     210            0 :         void init(M_t*, const V_t&, const O_t&){
     211            0 :                 UG_THROW(name() << "::init: Algorithm does not support induced subgraph version!");
     212              :         }
     213              : 
     214            0 :         void init(M_t*, const O_t&){
     215            0 :                 UG_THROW(name() << "::init: Algorithm does not support induced subgraph version!");
     216              :         }
     217              : 
     218            0 :         virtual const char* name() const {return "RiverOrdering";}
     219              : 
     220            0 :         void select_sources(const char* ssName){
     221              :                 //m_ssIdx = ssIdx;
     222            0 :                 m_ssName = ssName;
     223            0 :         }
     224              : 
     225              : private:
     226              :         G_t g;
     227              :         O_t o;
     228              : 
     229              :         int m_ssIdx;
     230              :         const char* m_ssName;
     231              :         std::vector<BOOL> m_sources;
     232              : };
     233              : 
     234              : } // end namespace ug
     235              : 
     236              : #endif
        

Generated by: LCOV version 2.0-1