ug4
Loading...
Searching...
No Matches
undirected.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022: G-CSC, Goethe University Frankfurt
3 * Author: Felix Salfelder, 2022
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 UG_GRAPH_INTERFACE_UNDIRECTED_H
34#define UG_GRAPH_INTERFACE_UNDIRECTED_H
35
36//#include "trace.h"
37#include "sparsematrix_boost.h"
38#include <boost/geometry/iterators/concatenate_iterator.hpp>
39#include <boost/graph/adjacency_list.hpp>
41
42#ifndef NDEBUG
43#include "common/stopwatch.h"
44#endif
45
46namespace ug{
47
48// Symmetrify matrix stencil
49template<class T>
51 typedef typename T::const_row_iterator const_row_iterator;
52public: // types
53 typedef typename T::value_type value_type;
54 typedef boost::adjacency_list<boost::vecS, boost::vecS> G;
55 typedef typename boost::graph_traits<T>::adjacency_iterator T_adj_it;
56 typedef typename boost::graph_traits<G>::adjacency_iterator G_adj_it;
57 class edge : public std::pair<int, int>{
58 public:
59 explicit edge() : std::pair<int, int>(){ untested();
60 }
61 edge(int a, int b) : std::pair<int, int>(a, b) {
62 }
66 edge(boost::graph_traits<G>::edge_descriptor){ untested();
67 incomplete();
68 }
69 };
70 typedef boost::geometry::concatenate_iterator<
74
75public:
76 explicit UndirectedMatrix(T const* m=nullptr)
77 : _matrix(m) {
78 if(m){
79 refresh();
80 }else{ untested();
81 }
82 }
88 _matrix = o._matrix;
90 return *this;
91 }
92
93public: // interface
94 void refresh();
95
96 int num_rows() const {
97 return std::max(_matrix->num_rows(), _matrix->num_cols());
98 }
99 int num_cols() const { untested();
100 return num_rows();
101 }
102 int out_degree(int v) const {
103 // could call in_degree?
104 return in_degree(v);
105 }
106 int in_degree(int v) const {
107 return boost::out_degree(v, *_matrix)
109 }
110 int degree(int v) const {
111 return out_degree(v);
112 }
113
114#if 0
115 edge_iterator begin_row(int row) const { untested();
116 auto r1 = boost::out_edges(row, *_matrix);
117 auto r2 = boost::out_edges(row, _extra_fill);
118
119 return edge_iterator(r1.first, r1.second, r2.first, r2.second);
120 }
121 edge_iterator end_row(int row) const { untested();
122 auto r1 = boost::out_edges(row, *_matrix);
123 auto r2 = boost::out_edges(row, _extra_fill);
124
125 return edge_iterator(r1.second, r1.second, r2.second, r2.second);
126 }
127#endif
129 auto r1 = boost::adjacent_vertices(row, *_matrix);
131
132 return adjacency_iterator(r1.first, r1.second, r2.first, r2.first);
133 }
135 auto r1 = boost::adjacent_vertices(row, *_matrix);
137
138 return adjacency_iterator(r1.second, r2.first, r2.second);
139 }
140
141private:
142 T const* _matrix;
144
145private:
146 class map_type{
147 public:
148 explicit map_type(T_adj_it const* i, T_adj_it const* e) : _it(i), _end(e){}
149
150 int operator[](int i) const{
151 assert(_it[i] != _end[i]);
152 return *_it[i];
153 }
154
155 private:
156 T_adj_it const* _it;
158 };
159}; // UndirectedMatrix
160
161// refresh missing fill. This is O(nonzeroes)
162template<class T>
164{
165#ifndef NDEBUG
166 double t = get_clock_s();
167#endif
168
169 assert(_matrix);
170 size_t N = _matrix->num_rows();
171 assert(N == _matrix->num_cols());
172 assert(!_matrix->iters()); // for now.
173
174 _extra_fill = G(N);
175
176 typedef boost::bucket_sorter<unsigned, unsigned,
177 map_type, boost::identity_property_map > container_type;
178
179 std::vector<T_adj_it> c(N);
180 std::vector<T_adj_it> e(N);
181 map_type M(&c[0], &e[0]);
182
183 container_type bs(N, N, M);
184
185 for(size_t k=0; k<N; ++k){
186 auto rr = boost::adjacent_vertices(k, *_matrix);
187 c[k] = rr.first;
188 e[k] = rr.second;
189
190 if(c[k] != e[k]){
191 bs.push(k);
192 }else{
193 }
194 }
195
196#if 0
197 for(size_t j=0; j<N; ++j){
198 std::cerr << "bs init " << j << "... ";
199 for(auto t : bs[j]){
200 std::cerr << " " << t;
201 }
202 std::cerr << "\n";
203 }
204#endif
205
206 for(size_t j=0; j<N; ++j){
207 // std::cerr << "====== " << j << " ====\n";
208 if(c[j] == e[j]){
209 }else if(*c[j]==j){
210 ++c[j];
211
212 if(c[j] == e[j]){ itested();
213 bs.remove(j);
214 }else{
215 bs.update(j);
216 }
217
218 }else{
219 assert(*c[j]>j);
220 }
221
222 // upper triangle, visit nonzeroes.
223 for(; c[j] != e[j];){
224 int k = *c[j];
225 if(c[k] == e[k]){
226 assert(size_t(k)<N);
227 assert(j<N);
228 // std::cerr << "lower fill0 " << k << " " << j << "\n";
229 boost::add_edge(k, j, _extra_fill);
230 }else if(*c[k] > j){
231 assert(size_t(k)<N);
232 assert(j<N);
233 // std::cerr << "lower fill1 " << k << " " << j << "\n";
234 boost::add_edge(k, j, _extra_fill);
235 }else if(*c[k] == j){
236 ++c[k];
237 if(c[k] == e[k]){
238 bs.remove(k);
239 }else{
240 bs.update(k);
241 }
242 }
243 ++c[j];
244
245 if(c[j] == e[j]){
246 bs.remove(j);
247 }else{
248 bs.update(j);
249 }
250 }
251
252 // lower triangle, visit subset of nonzeroes.
253 // std::cerr << "====== lower " << j << " ====\n";
254 assert(j<N);
255 auto bj = bs[j];
256
257 for(auto t=bj.begin(); t!=bj.end(); ){
258 int i = *t;
259 ++t;
260
261 // std::cerr << "upper fill " << j << " " << i << "\n";
262 boost::add_edge(j, i, _extra_fill);
263
264 assert(*c[i]==j);
265
266 ++c[i];
267 if(c[i] == e[i]){
268 bs.remove(i);
269 }else if(int(*c[i]) < i){ itested();
270 // std::cerr << "bs push " << i << " " << j << " " << *c[i] << "\n";
271 assert(*c[i] > j);
272 bs.update(i);
273 }else{ itested();
274 assert(*c[i] > j);
275 // bs.remove(i);
276 }
277
278 }
279 }
280
281 c.clear();
282 e.clear();
283 assert(!_matrix->iters());
284
285#ifndef NDEBUG
286 UG_LOG("Undirected refresh " << get_clock_s()-t << "\n");
287#endif
288}
289
290} // ug
291
292#endif // guard
Definition sparsematrix_boost.h:37
Definition sparsematrix_boost.h:152
Definition bucket_sorter.hpp:47
Definition undirected.h:57
edge(int a, int b)
Definition undirected.h:61
edge(boost::graph_traits< G >::edge_descriptor)
Definition undirected.h:66
edge()
Definition undirected.h:59
edge(boost::SM_edge< value_type >)
Definition undirected.h:63
Definition undirected.h:146
int operator[](int i) const
Definition undirected.h:150
T_adj_it const * _end
Definition undirected.h:157
map_type(T_adj_it const *i, T_adj_it const *e)
Definition undirected.h:148
T_adj_it const * _it
Definition undirected.h:156
Definition undirected.h:50
boost::graph_traits< T >::adjacency_iterator T_adj_it
Definition undirected.h:55
void refresh()
Definition undirected.h:163
boost::adjacency_list< boost::vecS, boost::vecS > G
Definition undirected.h:54
UndirectedMatrix(T const *m=nullptr)
Definition undirected.h:76
int num_rows() const
Definition undirected.h:96
UndirectedMatrix & operator=(UndirectedMatrix const &o)
Definition undirected.h:87
G _extra_fill
Definition undirected.h:143
UndirectedMatrix(UndirectedMatrix &&o)=delete
int degree(int v) const
Definition undirected.h:110
T::const_row_iterator const_row_iterator
Definition undirected.h:51
T::value_type value_type
Definition undirected.h:53
T const * _matrix
Definition undirected.h:142
int out_degree(int v) const
Definition undirected.h:102
UndirectedMatrix(UndirectedMatrix const &o)
Definition undirected.h:84
boost::graph_traits< G >::adjacency_iterator G_adj_it
Definition undirected.h:56
boost::geometry::concatenate_iterator< boost::SM_adjacency_iterator< value_type >, G_adj_it, int, int > adjacency_iterator
Definition undirected.h:73
int num_cols() const
Definition undirected.h:99
int in_degree(int v) const
Definition undirected.h:106
adjacency_iterator begin_row(int row) const
Definition undirected.h:128
adjacency_iterator end_row(int row) const
Definition undirected.h:134
#define UG_LOG(msg)
Definition log.h:367
#define untested()
Definition lua_table_handle.cpp:15
std::pair< typename graph_traits< T >::adjacency_iterator, typename graph_traits< T >::adjacency_iterator > adjacent_vertices(size_t v, ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:108
std::pair< SM_out_edge_iterator< typename T::value_type >, SM_out_edge_iterator< typename T::value_type > > out_edges(size_t v, ug::BidirectionalMatrix< T > const &g)
Definition bidirectional_boost.h:136
int out_degree(int v, ug::BidirectionalMatrix< T > const &M)
Definition bidirectional_boost.h:76
Definition smart_pointer.h:814
the ug namespace
double get_clock_s()
Definition stopwatch.h:103
stopwatch class for quickly taking times
#define incomplete()
Definition trace.h:10
#define itested()
Definition trace.h:9