1 #ifndef PARALLEL_H_INCLUDED 2 #define PARALLEL_H_INCLUDED 3 4 #include <map> 5 #include <vector> 6 7 #include "myalloc.h" 8 #include "serialize.h" 9 #include "key.h" 10 11 namespace ALUGrid 12 { 13 14 struct GatherScatter; 15 typedef GatherScatter GatherScatterType; 16 17 // ParallelException 18 // ----------------- 19 20 struct ParallelException 21 { 22 class AccessPllException : public ALUGridException 23 { 24 public: whatParallelException25 virtual std::string what () const { return "AccessPllException"; } 26 }; 27 }; 28 29 30 ////////////////////////////////////////////////////////////////////////////// 31 // 32 // 33 // Interfaces for elements, faces, edges, and vertices for parallel computations 34 // 35 // 36 ////////////////////////////////////////////////////////////////////////////// 37 38 // Das 'MacroGridMoverIF' mu"s von den Parallelerweiterungen der 39 // Knoten, Kanten, Fl"achen und Elemente des Grobgitters implementiert 40 // werden, damit der Lastverteiler diese Objekte zuweisen, einpacken 41 // und rekonstruieren kann. 42 43 class MacroGridMoverIF 44 { 45 protected : MacroGridMoverIF()46 MacroGridMoverIF () {} ~MacroGridMoverIF()47 virtual ~MacroGridMoverIF () {} 48 49 private: 50 // type of move to map, derive from MyAlloc 51 class MoveTo 52 : public MyAlloc, 53 public std::map< int, int > 54 {}; 55 56 public : 57 typedef MoveTo moveto_t ; 58 59 enum { VERTEX = 1, EDGE1, FACE3, FACE4, 60 HEXA, TETRA, PERIODIC3, PERIODIC4=-65, 61 HBND3EXT, HBND4EXT, HBND3INT, HBND4INT = -22 , 62 ENDMARKER , ENDSTREAM } ; 63 64 static constexpr signed char NO_POINT=-111; 65 static constexpr signed char POINTTRANSMITTED=-112; 66 67 virtual void attach2 (int) = 0 ; 68 virtual void unattach2 (int) = 0 ; 69 70 virtual bool packAll ( std::vector< ObjectStream > & ) = 0; 71 virtual moveto_t* moveToMap () = 0 ; 72 virtual bool dunePackAll ( std::vector< ObjectStream > &, GatherScatterType & ) = 0; 73 virtual void unpackSelf ( ObjectStream &, bool ) = 0; 74 virtual void duneUnpackSelf ( ObjectStream &, bool, GatherScatterType * ) = 0; 75 virtual void computeBaryCenter( double (¢er)[3] ) const = 0; 76 }; 77 78 class MacroGridMoverDefault : public MacroGridMoverIF { 79 protected : MacroGridMoverDefault()80 MacroGridMoverDefault () {} ~MacroGridMoverDefault()81 virtual ~MacroGridMoverDefault () {} 82 public : 83 typedef MacroGridMoverIF :: moveto_t moveto_t ; 84 attach2(int)85 virtual void attach2 (int) { alugrid_assert (false);abort(); } unattach2(int)86 virtual void unattach2 (int) { alugrid_assert (false);abort(); } 87 packAll(std::vector<ObjectStream> &)88 virtual bool packAll ( std::vector< ObjectStream > &) { alugrid_assert (false); abort(); } moveToMap()89 virtual moveto_t* moveToMap () { alugrid_assert (false); abort(); return ((moveto_t *) 0); } dunePackAll(std::vector<ObjectStream> &,GatherScatterType &)90 virtual bool dunePackAll ( std::vector< ObjectStream > &, GatherScatterType & ) { alugrid_assert (false); return false; } unpackSelf(ObjectStream &,bool)91 virtual void unpackSelf ( ObjectStream &, bool ) { alugrid_assert (false); abort(); } duneUnpackSelf(ObjectStream &,const bool,GatherScatterType *)92 virtual void duneUnpackSelf (ObjectStream &, const bool, GatherScatterType *) {alugrid_assert (false);} computeBaryCenter(double (& center)[3])93 virtual void computeBaryCenter( double (¢er)[3] ) const { center[ 0 ] = center[ 1 ] = center[ 2 ] = 0; } 94 } ; 95 96 // LinkedObjekt ist die Schnittstelle, die im parallelen Gitter zur 97 // Identifikation ben"otigt wird. Das Identifikationsmodul wendet 98 // sich an diese Schnittstelle, um die Schl"ussel f"ur die Objekte 99 // des Gitters und eine obere Absch"atzung f"ur deren Verbindungsstern 100 // zu erhalten. Diese Abschh"atzung kann auch die globale Verbindung 101 // sein, d.h. der Vektor enth"alt alle Gebietsnummern, dann wird aber 102 // die Effizienz des Identifikationsmoduls schlecht. 103 104 // Note: The derivation from MacroGridMoverIF is artificial. Since all 105 // implementations of LinkedObject also derive from MacroGridMoverIf, 106 // this saves the additional pointer to the vtbl of MacroGridMoverIf. 107 108 class LinkedObject 109 : public MacroGridMoverDefault 110 { 111 public: 112 // Der Identifier wird f"ur alle Gitterobjekte einheitlich verwendet. 113 // Er ist der Schl"ussel f"ur die Identifikation der mehrdeutigen 114 // Gitterobjekte. Kanten benutzen eine Schl"ussell"ange von zwei, 115 // Fl"achen eine von drei und Elemente eine von vier. Wird nicht der 116 // gesamte Schl"ussel benutzt, werden die "ubrigen Eintr"age mit 117 // -1 gepaddet. 118 // Die Schnittstelle wird von den Parallelerweiterungen der Knoten 119 // Kanten, Fl"achen und (sp"ater auch) Elemente implementiert. 120 121 template <int size> 122 class IdentifierImpl 123 { 124 typedef IdentifierImpl< size > This; 125 template <int xsize> 126 void assign( const IdentifierImpl< xsize >& ); 127 128 template <int k, int s> 129 struct Spec 130 { lessSpec131 static bool less( const int (&a)[ size ], const int (&b)[ size ] ) 132 { 133 if( a[ k ] < b[ k ] ) return true; 134 else if( a[ k ] > b[ k ] ) return false ; 135 else return Spec<k+1,s>::less( a, b ); 136 } 137 }; 138 139 template <int k> 140 struct Spec< k, k > 141 { 142 static bool less( const int (&a)[ size ], const int (&b)[ size ] ) 143 { 144 return a[ k ] < b[ k ]; 145 } 146 }; 147 148 public: 149 int _i[ size ]; 150 static const int _endOfStream = -128 ; // must be a negative value 151 public : 152 inline IdentifierImpl (int = -1, int = -1, int = -1, int = -1) ; 153 template <int xsize> 154 inline IdentifierImpl (const IdentifierImpl< xsize > &) ; 155 template <int xsize> 156 inline const IdentifierImpl & operator = (const IdentifierImpl< xsize >&) ; 157 inline bool operator < (const This &) const ; 158 inline bool operator == (const This &) const ; 159 // read identifier from stream and return true if successful 160 bool read ( ObjectStream& ); 161 void write ( ObjectStream& ) const ; 162 inline bool isValid () const ; 163 // read stream termination marker 164 static void endOfStream( ObjectStream& os ) 165 { 166 os.writeObject( _endOfStream ); 167 } 168 169 } ; 170 171 // the identifier need at most 4 entries 172 typedef IdentifierImpl< 4 > Identifier ; 173 174 public : 175 virtual ~LinkedObject () {} 176 177 virtual Identifier getIdentifier () const = 0 ; 178 virtual std::vector< int > estimateLinkage () const = 0; 179 virtual void checkAndAddLinkage ( const int ) = 0; 180 }; 181 182 class LinkedObjectDefault 183 : public LinkedObject 184 { 185 public : 186 virtual ~LinkedObjectDefault () {} 187 virtual Identifier getIdentifier () const { alugrid_assert (false);abort(); return Identifier(); } 188 virtual std::vector< int > estimateLinkage () const { alugrid_assert (false); abort(); return std::vector< int >(); } 189 virtual void checkAndAddLinkage ( const int ) { alugrid_assert (false); abort(); } 190 } ; 191 192 // Die Schnittstelle 'RefineableObject' ist diejenige, an die sich 193 // der parallele Verfeinerer wendet, um z.B. die Requests heraus- 194 // zufinden und zu setzen. Die Requests werden einfach auf den Strom 195 // geschrieben, und sollten beim einlesen auf ihre G"ultigkeit 196 // getestet werden. Die Schnittstelle wird von den Parallelerweiterungen 197 // der Kanten und der Fl"achen implementiert. 198 199 // Note: The derivation from LinkedObject is artificial. Since all 200 // implementations of RefineableObject also derive from LinkedObject, 201 // this saves the additional pointer to the vtbl of LinkedObject. 202 203 class RefineableObject : public LinkedObjectDefault 204 { 205 protected : 206 RefineableObject () {} 207 virtual ~RefineableObject () {} 208 public : 209 virtual void getRefinementRequest (ObjectStream &) const = 0 ; 210 virtual bool setRefinementRequest (ObjectStream &) = 0 ; 211 } ; 212 213 214 class RefineableObjectDefault : public RefineableObject 215 { 216 protected : 217 RefineableObjectDefault () {} 218 virtual ~RefineableObjectDefault () {} 219 public : 220 virtual void getRefinementRequest (ObjectStream &) const { alugrid_assert (false);abort(); } 221 virtual bool setRefinementRequest (ObjectStream &) { alugrid_assert (false);abort(); return false ;} 222 } ; 223 224 // 225 // # # # # # # # ###### 226 // # ## # # # ## # # 227 // # # # # # # # # # ##### 228 // # # # # # # # # # # 229 // # # ## # # # ## # 230 // # # # ###### # # # ###### 231 // 232 /////////////////////////////////////////////////////////////////// 233 // 234 // --LinkedObject 235 // 236 /////////////////////////////////////////////////////////////////// 237 238 template <int size> 239 inline bool LinkedObject :: IdentifierImpl< size > :: isValid () const 240 { 241 return _i[ 0 ] == -1 ? false : true ; 242 } 243 244 template <int size> 245 inline LinkedObject :: IdentifierImpl< size > :: IdentifierImpl (int a, int b, int c, int d) 246 { 247 _i[ 0 ] = a; 248 if( size > 1 ) 249 _i[ 1 ] = b; 250 if( size > 2 ) 251 _i[ 2 ] = c; 252 if( size > 3 ) 253 _i[ 3 ] = d; 254 } 255 256 template <int size> 257 template <int xsize> 258 inline void LinkedObject :: IdentifierImpl< size > :: 259 assign (const IdentifierImpl< xsize >& x) 260 { 261 alugrid_assert( size <= xsize ); 262 alugrid_assert (x.isValid ()) ; 263 for( int i=0; i<size; ++i ) _i[ i ] = x._i[ i ]; 264 } 265 266 template <int size> 267 template <int xsize> 268 inline LinkedObject :: IdentifierImpl< size > :: 269 IdentifierImpl (const IdentifierImpl< xsize > & x) 270 { 271 assign( x ); 272 } 273 274 template <int size> 275 template <int xsize> 276 inline const LinkedObject :: IdentifierImpl< size > & 277 LinkedObject :: IdentifierImpl< size > :: operator = (const IdentifierImpl< xsize >& x) 278 { 279 assign( x ); 280 return * this ; 281 } 282 283 template <int size> 284 inline bool LinkedObject :: IdentifierImpl< size > :: operator < (const This & x) const 285 { 286 return Spec< 0, size-1 > :: less( _i, x._i ); 287 } 288 289 template <int size> 290 inline bool LinkedObject :: IdentifierImpl< size > :: operator == (const This & x) const 291 { 292 bool equal = _i[ 0 ] == x._i[ 0 ]; 293 for( int k=1; k<size; ++k ) 294 equal &= (_i[ k ] == x._i[ k ]); 295 return equal ; 296 } 297 298 // read identifier and return true if successful 299 template <int size> 300 inline bool LinkedObject::IdentifierImpl< size >::read ( ObjectStream& os ) 301 { 302 // if the next entry is end of stream do nothing more 303 os.readObject( _i[ 0 ] ); 304 if( _i[ 0 ] == _endOfStream ) 305 return false ; 306 307 for( int k=1; k<size; ++k ) 308 os.readObject( _i[ k ] ); 309 310 return true ; 311 } 312 313 template <int size> 314 inline void LinkedObject::IdentifierImpl< size >::write ( ObjectStream& os ) const 315 { 316 // write object to stream 317 for( int k=0; k<size; ++k ) 318 os.writeObject( _i[ k ] ); 319 } 320 321 } // namespace ALUGrid 322 323 #endif // #ifndef PARALLEL_H_INCLUDED 324