dune-grid  2.2.0
boundarydom.hh
Go to the documentation of this file.
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