1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi: set et ts=4 sw=2 sts=2: 3 #ifndef DUNE_AMG_DEPENDENCY_HH 4 #define DUNE_AMG_DEPENDENCY_HH 5 6 7 #include <bitset> 8 #include <ostream> 9 10 #include "graph.hh" 11 #include "properties.hh" 12 #include <dune/common/propertymap.hh> 13 14 15 namespace Dune 16 { 17 namespace Amg 18 { 19 /** 20 * @addtogroup ISTL_PAAMG 21 * 22 * @{ 23 */ 24 /** @file 25 * @author Markus Blatt 26 * @brief Provides classes for initializing the link attributes of a matrix graph. 27 */ 28 29 /** 30 * @brief Class representing the properties of an ede in the matrix graph. 31 * 32 * During the coarsening process the matrix graph needs to hold different 33 * properties of its edges. 34 * This class ontains methods for getting and setting these edge attributes. 35 */ 36 class EdgeProperties 37 { 38 friend std::ostream& operator<<(std::ostream& os, const EdgeProperties& props); 39 public: 40 /** @brief Flags of the link.*/ 41 enum {INFLUENCE, DEPEND, SIZE}; 42 43 private: 44 45 std::bitset<SIZE> flags_; 46 public: 47 /** @brief Constructor. */ 48 EdgeProperties(); 49 50 /** @brief Access the bits directly */ 51 std::bitset<SIZE>::reference operator[](std::size_t v); 52 53 /** @brief Access the bits directly */ 54 bool operator[](std::size_t v) const; 55 56 /** 57 * @brief Checks wether the vertex the edge points to depends on 58 * the vertex the edge starts. 59 * @return True if it depends on the starting point. 60 */ 61 bool depends() const; 62 63 /** 64 * @brief Marks the edge as one of which the end point depends on 65 * the starting point. 66 */ 67 void setDepends(); 68 69 /** 70 * @brief Resets the depends flag. 71 */ 72 void resetDepends(); 73 74 /** 75 * @brief Checks wether the start vertex is influenced by the end vertex. 76 * @return True if it is influenced. 77 */ 78 bool influences() const; 79 80 /** 81 * @brief Marks the edge as one of which the start vertex by the end vertex. 82 */ 83 void setInfluences(); 84 85 /** 86 * @brief Resets the influence flag. 87 */ 88 void resetInfluences(); 89 90 /** 91 * @brief Checks wether the edge is one way. 92 * I.e. either the influence or the depends flag but is set. 93 */ 94 bool isOneWay() const; 95 96 /** 97 * @brief Checks wether the edge is two way. 98 * I.e. both the influence flag and the depends flag are that. 99 */ 100 bool isTwoWay() const; 101 102 /** 103 * @brief Checks wether the edge is strong. 104 * I.e. the influence or depends flag is set. 105 */ 106 bool isStrong() const; 107 108 /** 109 * @brief Reset all flags. 110 */ 111 void reset(); 112 113 /** 114 * @brief Prints the attributes of the edge for debugging. 115 */ 116 void printFlags() const; 117 }; 118 119 /** 120 * @brief Class representing a node in the matrix graph. 121 * 122 * Contains methods for getting and setting node attributes. 123 */ 124 class VertexProperties { 125 friend std::ostream& operator<<(std::ostream& os, const VertexProperties& props); 126 public: 127 enum { ISOLATED, VISITED, FRONT, BORDER, SIZE }; 128 private: 129 130 /** @brief The attribute flags. */ 131 std::bitset<SIZE> flags_; 132 133 public: 134 /** @brief Constructor. */ 135 VertexProperties(); 136 137 /** @brief Access the bits directly */ 138 std::bitset<SIZE>::reference operator[](std::size_t v); 139 140 /** @brief Access the bits directly */ 141 bool operator[](std::size_t v) const; 142 143 /** 144 * @brief Marks that node as being isolated. 145 * 146 * A node is isolated if it ha not got any strong connections to other nodes 147 * in the matrix graph. 148 */ 149 void setIsolated(); 150 151 /** 152 * @brief Checks wether the node is isolated. 153 */ 154 bool isolated() const; 155 156 /** 157 * @brief Resets the isolated flag. 158 */ 159 void resetIsolated(); 160 161 /** 162 * @brief Mark the node as already visited. 163 */ 164 void setVisited(); 165 166 /** 167 * @brief Checks wether the node is marked as visited. 168 */ 169 bool visited() const; 170 171 /** 172 * @brief Resets the visited flag. 173 */ 174 void resetVisited(); 175 176 /** 177 * @brief Marks the node as belonging to the current clusters front. 178 */ 179 void setFront(); 180 181 /** 182 * @brief Checks wether the node is marked as a front node. 183 */ 184 bool front() const; 185 186 /** 187 * @brief Resets the front node flag. 188 */ 189 void resetFront(); 190 191 /** 192 * @brief Marks the vertex as excluded from the aggregation. 193 */ 194 void setExcludedBorder(); 195 196 /** 197 * @brief Tests whether the vertex is excluded from the aggregation. 198 * @return True if the vertex is excluded from the aggregation process. 199 */ 200 bool excludedBorder() const; 201 202 /** 203 * @brief Marks the vertex as included in the aggregation. 204 */ 205 void resetExcludedBorder(); 206 207 /** 208 * @brief Reset all flags. 209 */ 210 void reset(); 211 212 }; 213 214 template<typename G, std::size_t i> 215 class PropertyGraphVertexPropertyMap 216 : public RAPropertyMapHelper<typename std::bitset<VertexProperties::SIZE>::reference, 217 PropertyGraphVertexPropertyMap<G,i> > 218 { 219 public: 220 221 typedef ReadWritePropertyMapTag Category; 222 223 enum { 224 /** @brief the index to access in the bitset. */ 225 index = i 226 }; 227 228 /** 229 * @brief The type of the graph with internal properties. 230 */ 231 typedef G Graph; 232 233 /** 234 * @brief The type of the bitset. 235 */ 236 typedef std::bitset<VertexProperties::SIZE> BitSet; 237 238 /** 239 * @brief The reference type. 240 */ 241 typedef typename BitSet::reference Reference; 242 243 /** 244 * @brief The value type. 245 */ 246 typedef bool ValueType; 247 248 /** 249 * @brief The vertex descriptor. 250 */ 251 typedef typename G::VertexDescriptor Vertex; 252 253 /** 254 * @brief Constructor. 255 * @param g The graph whose properties we access. 256 */ PropertyGraphVertexPropertyMap(G & g)257 PropertyGraphVertexPropertyMap(G& g) 258 : graph_(&g) 259 {} 260 261 /** 262 * @brief Default constructor. 263 */ PropertyGraphVertexPropertyMap()264 PropertyGraphVertexPropertyMap() 265 : graph_(0) 266 {} 267 268 269 /** 270 * @brief Get the properties associated to a vertex. 271 * @param vertex The vertex whose Properties we want. 272 */ operator [](const Vertex & vertex) const273 Reference operator[](const Vertex& vertex) const 274 { 275 return graph_->getVertexProperties(vertex)[index]; 276 } 277 private: 278 Graph* graph_; 279 }; 280 281 } // end namespace Amg 282 283 template<typename G, typename EP, typename VM, typename EM> 284 struct PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> > 285 { 286 typedef Amg::PropertyGraphVertexPropertyMap<Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM>, Amg::VertexProperties::VISITED> Type; 287 }; 288 289 template<typename G, typename EP, typename VM, typename EM> 290 typename PropertyMapTypeSelector<Amg::VertexVisitedTag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> >::Type get(const Amg::VertexVisitedTag & tag,Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM> & graph)291 get([[maybe_unused]] const Amg::VertexVisitedTag& tag, Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM>& graph) 292 { 293 return Amg::PropertyGraphVertexPropertyMap<Amg::PropertiesGraph<G,Amg::VertexProperties,EP,VM,EM>, Amg::VertexProperties::VISITED>(graph); 294 } 295 296 namespace Amg 297 { operator <<(std::ostream & os,const EdgeProperties & props)298 inline std::ostream& operator<<(std::ostream& os, const EdgeProperties& props) 299 { 300 return os << props.flags_; 301 } 302 EdgeProperties()303 inline EdgeProperties::EdgeProperties() 304 : flags_() 305 {} 306 307 inline std::bitset<EdgeProperties::SIZE>::reference operator [](std::size_t v)308 EdgeProperties::operator[](std::size_t v) 309 { 310 return flags_[v]; 311 } 312 operator [](std::size_t i) const313 inline bool EdgeProperties::operator[](std::size_t i) const 314 { 315 return flags_[i]; 316 } 317 reset()318 inline void EdgeProperties::reset() 319 { 320 flags_.reset(); 321 } 322 setInfluences()323 inline void EdgeProperties::setInfluences() 324 { 325 // Set the INFLUENCE bit 326 //flags_ |= (1<<INFLUENCE); 327 flags_.set(INFLUENCE); 328 } 329 influences() const330 inline bool EdgeProperties::influences() const 331 { 332 // Test the INFLUENCE bit 333 return flags_.test(INFLUENCE); 334 } 335 setDepends()336 inline void EdgeProperties::setDepends() 337 { 338 // Set the first bit. 339 //flags_ |= (1<<DEPEND); 340 flags_.set(DEPEND); 341 } 342 resetDepends()343 inline void EdgeProperties::resetDepends() 344 { 345 // reset the first bit. 346 //flags_ &= ~(1<<DEPEND); 347 flags_.reset(DEPEND); 348 } 349 depends() const350 inline bool EdgeProperties::depends() const 351 { 352 // Return the first bit. 353 return flags_.test(DEPEND); 354 } 355 resetInfluences()356 inline void EdgeProperties::resetInfluences() 357 { 358 // reset the second bit. 359 flags_ &= ~(1<<INFLUENCE); 360 } 361 isOneWay() const362 inline bool EdgeProperties::isOneWay() const 363 { 364 // Test whether only the first bit is set 365 //return isStrong() && !isTwoWay(); 366 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==(1<<DEPEND); 367 } 368 isTwoWay() const369 inline bool EdgeProperties::isTwoWay() const 370 { 371 // Test whether the first and second bit is set 372 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND)))==((1<<INFLUENCE)|(1<<DEPEND)); 373 } 374 isStrong() const375 inline bool EdgeProperties::isStrong() const 376 { 377 // Test whether the first or second bit is set 378 return ((flags_) & std::bitset<SIZE>((1<<INFLUENCE)|(1<<DEPEND))).to_ulong(); 379 } 380 381 operator <<(std::ostream & os,const VertexProperties & props)382 inline std::ostream& operator<<(std::ostream& os, const VertexProperties& props) 383 { 384 return os << props.flags_; 385 } 386 VertexProperties()387 inline VertexProperties::VertexProperties() 388 : flags_() 389 {} 390 391 392 inline std::bitset<VertexProperties::SIZE>::reference operator [](std::size_t v)393 VertexProperties::operator[](std::size_t v) 394 { 395 return flags_[v]; 396 } 397 operator [](std::size_t v) const398 inline bool VertexProperties::operator[](std::size_t v) const 399 { 400 return flags_[v]; 401 } 402 setIsolated()403 inline void VertexProperties::setIsolated() 404 { 405 flags_.set(ISOLATED); 406 } 407 isolated() const408 inline bool VertexProperties::isolated() const 409 { 410 return flags_.test(ISOLATED); 411 } 412 resetIsolated()413 inline void VertexProperties::resetIsolated() 414 { 415 flags_.reset(ISOLATED); 416 } 417 setVisited()418 inline void VertexProperties::setVisited() 419 { 420 flags_.set(VISITED); 421 } 422 visited() const423 inline bool VertexProperties::visited() const 424 { 425 return flags_.test(VISITED); 426 } 427 resetVisited()428 inline void VertexProperties::resetVisited() 429 { 430 flags_.reset(VISITED); 431 } 432 setFront()433 inline void VertexProperties::setFront() 434 { 435 flags_.set(FRONT); 436 } 437 front() const438 inline bool VertexProperties::front() const 439 { 440 return flags_.test(FRONT); 441 } 442 resetFront()443 inline void VertexProperties::resetFront() 444 { 445 flags_.reset(FRONT); 446 } 447 setExcludedBorder()448 inline void VertexProperties::setExcludedBorder() 449 { 450 flags_.set(BORDER); 451 } 452 excludedBorder() const453 inline bool VertexProperties::excludedBorder() const 454 { 455 return flags_.test(BORDER); 456 } 457 resetExcludedBorder()458 inline void VertexProperties::resetExcludedBorder() 459 { 460 flags_.reset(BORDER); 461 } 462 reset()463 inline void VertexProperties::reset() 464 { 465 flags_.reset(); 466 } 467 468 /** @} */ 469 } 470 } 471 #endif 472