dune-grid
2.2.0
|
00001 #ifndef DUNE_DGF_BOUNDARYDOMBLOCK_HH 00002 #define DUNE_DGF_BOUNDARYDOMBLOCK_HH 00003 00004 #include <iostream> 00005 #include <string> 00006 #include <vector> 00007 00008 #include <dune/grid/io/file/dgfparser/blocks/basic.hh> 00009 #include <dune/grid/io/file/dgfparser/parser.hh> 00010 00011 00012 namespace Dune 00013 { 00014 00015 namespace dgf 00016 { 00017 00018 struct DomainData 00019 { 00020 typedef DGFBoundaryParameter::type BoundaryParameter; 00021 00022 DomainData () 00023 : id_( 0 ), 00024 parameter_( DGFBoundaryParameter::defaultValue() ), 00025 defaultData_( false ) 00026 { } 00027 00028 ~DomainData () { } 00029 00030 // constructor 00031 DomainData ( int id, BoundaryParameter parameter, bool defaultData = false ) 00032 : id_( id ), 00033 parameter_( parameter ), 00034 defaultData_( defaultData ) 00035 { } 00036 00037 // return id 00038 int id () const 00039 { 00040 return id_; 00041 } 00042 00043 // return true, if additional parameters given 00044 bool hasParameter () const 00045 { 00046 return (!parameter_.empty()); 00047 } 00048 00049 // return additional parameters 00050 const BoundaryParameter & parameter () const 00051 { 00052 return parameter_; 00053 } 00054 00055 // reset data 00056 void reset ( int id, BoundaryParameter parameter, bool defaultData = false ) 00057 { 00058 id_ = id; 00059 parameter_ = parameter; 00060 defaultData_ = defaultData; 00061 } 00062 00063 // returns true if data origins from default boundary domain 00064 bool isDefault () const 00065 { 00066 return defaultData_; 00067 } 00068 00069 friend std::ostream & operator<< ( std :: ostream & os, const DomainData & ddata ) 00070 { 00071 os << "domain data: id = " << ddata.id(); 00072 if( ddata.hasParameter() ) 00073 os << ", parameter = " << ddata.parameter(); 00074 return os; 00075 } 00076 00077 private: 00078 int id_; 00079 BoundaryParameter parameter_; 00080 bool defaultData_; 00081 00082 }; // end struct DomainData 00083 00084 00085 struct Domain 00086 { 00087 // dimension of world coordinates 00088 const int dimensionworld; 00089 00090 typedef DGFBoundaryParameter::type BoundaryParameter; 00091 00092 // constructor 00093 Domain( std::vector< double > p1, std::vector< double > p2, int id, BoundaryParameter & parameter ) 00094 : dimensionworld( p1.size() ), 00095 left_( p1 ), 00096 right_( p2 ), 00097 data_( id, parameter ) 00098 { 00099 if( int( p2.size() ) != dimensionworld ) 00100 { 00101 DUNE_THROW(DGFException, 00102 "ERROR in " << *this << "!"); 00103 } 00104 } 00105 00106 // constructor 00107 Domain( std::vector< double > p1, std::vector< double > p2, DomainData & data ) 00108 : dimensionworld( p1.size() ), 00109 left_( p1 ), 00110 right_( p2 ), 00111 data_( data ) 00112 { 00113 if( int( p2.size() ) != dimensionworld ) 00114 { 00115 DUNE_THROW(DGFException, 00116 "ERROR in " << *this << "!"); 00117 } 00118 } 00119 00120 // copy constructor 00121 Domain ( const Domain & other ) 00122 : dimensionworld( other.dimensionworld ), 00123 left_( other.left_ ), 00124 right_( other.right_ ), 00125 data_( other.data_ ) 00126 { 00127 if( dimensionworld != other.dimensionworld ) 00128 { 00129 DUNE_THROW(DGFException, 00130 "ERROR in " << *this << "!"); 00131 } 00132 } 00133 00134 // assignment 00135 Domain & operator = ( const Domain & other ) 00136 { 00137 if( dimensionworld != other.dimensionworld ) 00138 { 00139 DUNE_THROW(DGFException, 00140 "ERROR in " << *this << "!"); 00141 } 00142 00143 left_ = other.left_; 00144 right_= other.right_; 00145 data_= other.data_; 00146 return *this; 00147 } 00148 00149 // return true if point is contained in boundary domain 00150 template< class Vector > 00151 bool contains ( const Vector & x ) const 00152 { 00153 bool ret = true; 00154 for( int i = 0; i < dimensionworld; ++i ) 00155 { 00156 if( x[ i ] < left_[ i ] || x[ i ] > right_[ i ] ) 00157 ret = false; 00158 } 00159 return ret; 00160 } 00161 00162 const DomainData & data () const 00163 { 00164 return data_; 00165 } 00166 00167 // for error messages 00168 friend std::ostream & operator<< ( std :: ostream &os, const Domain & domain ) 00169 { 00170 const int dimensionworld = domain.dimensionworld; 00171 os << "domain: " << std::endl; 00172 os << "left = "; 00173 for( int i = 0; i < dimensionworld; ++i ) 00174 os << domain.left_[ i ] << " "; 00175 os << std::endl; 00176 os << "right = "; 00177 for( int i = 0; i < dimensionworld; ++i ) 00178 os << domain.right_[ i ] << " "; 00179 os << std::endl; 00180 os << domain.data(); 00181 return os; 00182 } 00183 00184 private: 00185 std::vector< double > left_, right_; 00186 DomainData data_; 00187 00188 }; 00189 00190 class BoundaryDomBlock 00191 : public BasicBlock 00192 { 00193 typedef DGFBoundaryParameter::type BoundaryParameter; 00194 00195 // the dimension of the vertices (is given from user) 00196 int dimworld_; 00197 00198 // internal counter 00199 int counter_; 00200 00201 // default values if given 00202 DomainData * default_; 00203 00204 // storage for all domains; 00205 int ndomains_; 00206 std::vector< Domain > domains_; 00207 00208 public: 00209 // initialize vertex block and get first vertex 00210 BoundaryDomBlock ( std::istream & in, int cdimworld ); 00211 00212 // destructor 00213 ~BoundaryDomBlock () 00214 { 00215 if( default_ ) 00216 delete default_; 00217 } 00218 00219 // go to next domain in block 00220 bool next () 00221 { 00222 counter_++; 00223 return ( counter_ < ndomains_ ); 00224 } 00225 00226 // return domain 00227 const Domain & domain () const 00228 { 00229 return domains_.at( counter_ ); 00230 } 00231 00232 // return true if default is given 00233 bool hasDefaultData () const 00234 { 00235 return bool( default_ ); 00236 } 00237 00238 // return default data 00239 const DomainData * defaultData () const 00240 { 00241 return default_; 00242 } 00243 00244 // return true if any boundary domain block has 00245 // additional paramters 00246 bool hasParameter () const; 00247 00248 void reset () 00249 { 00250 BasicBlock::reset(); 00251 counter_ = -1; 00252 } 00253 00254 // return true while block is active 00255 bool ok () 00256 { 00257 return ( counter_ <= ndomains_ ); 00258 } 00259 00260 // return data if all vectors in array are contained within 00261 // a single domain 00262 template< class Vector > 00263 const DomainData * contains ( const std::vector< Vector > & v ) const 00264 { 00265 std::vector< int > index( ndomains_ ); 00266 for( int i = 0; i < ndomains_; ++i) 00267 index[ i ] = i; 00268 00269 size_t N = v.size(); 00270 for( size_t i = 0; i < N; ++i ) 00271 { 00272 if( index.empty() ) 00273 break; 00274 00275 const int n = index.size(); 00276 assert( n > 0 ); 00277 for( int j = n-1; j >= 0; --j ) 00278 { 00279 bool inside = domains_[ index[ j ] ].contains( v[ i ] ); 00280 if( !inside ) 00281 index.erase( index.begin() + j ); 00282 } 00283 } 00284 00285 // check wheter no boundary domain found 00286 if( index.empty() ) 00287 return default_; 00288 00289 // check for ambiguity 00290 if( index.size() > 1 ) 00291 dwarn << "WARNING: ambiguous boundary domain assignment, use first boundary domain in list" << std::endl; 00292 00293 return &domains_[ index[ 0 ] ].data(); 00294 } 00295 00296 private: 00297 void readBlock (); 00298 }; 00299 00300 } // end namespace dgf 00301 00302 } // end namespace Dune 00303 00304 #endif