dune-grid  2.2.1
boundarydom.hh
Go to the documentation of this file.
1 #ifndef DUNE_DGF_BOUNDARYDOMBLOCK_HH
2 #define DUNE_DGF_BOUNDARYDOMBLOCK_HH
3 
4 #include <iostream>
5 #include <string>
6 #include <vector>
7 
10 
11 
12 namespace Dune
13 {
14 
15  namespace dgf
16  {
17 
18  struct DomainData
19  {
21 
23  : id_( 0 ),
24  parameter_( DGFBoundaryParameter::defaultValue() ),
25  defaultData_( false )
26  { }
27 
28  ~DomainData () { }
29 
30  // constructor
31  DomainData ( int id, BoundaryParameter parameter, bool defaultData = false )
32  : id_( id ),
33  parameter_( parameter ),
34  defaultData_( defaultData )
35  { }
36 
37  // return id
38  int id () const
39  {
40  return id_;
41  }
42 
43  // return true, if additional parameters given
44  bool hasParameter () const
45  {
46  return (!parameter_.empty());
47  }
48 
49  // return additional parameters
50  const BoundaryParameter & parameter () const
51  {
52  return parameter_;
53  }
54 
55  // reset data
56  void reset ( int id, BoundaryParameter parameter, bool defaultData = false )
57  {
58  id_ = id;
59  parameter_ = parameter;
60  defaultData_ = defaultData;
61  }
62 
63  // returns true if data origins from default boundary domain
64  bool isDefault () const
65  {
66  return defaultData_;
67  }
68 
69  friend std::ostream & operator<< ( std :: ostream & os, const DomainData & ddata )
70  {
71  os << "domain data: id = " << ddata.id();
72  if( ddata.hasParameter() )
73  os << ", parameter = " << ddata.parameter();
74  return os;
75  }
76 
77  private:
78  int id_;
79  BoundaryParameter parameter_;
80  bool defaultData_;
81 
82  }; // end struct DomainData
83 
84 
85  struct Domain
86  {
87  // dimension of world coordinates
88  const int dimensionworld;
89 
91 
92  // constructor
93  Domain( std::vector< double > p1, std::vector< double > p2, int id, BoundaryParameter & parameter )
94  : dimensionworld( p1.size() ),
95  left_( p1 ),
96  right_( p2 ),
97  data_( id, parameter )
98  {
99  if( int( p2.size() ) != dimensionworld )
100  {
101  DUNE_THROW(DGFException,
102  "ERROR in " << *this << "!");
103  }
104  }
105 
106  // constructor
107  Domain( std::vector< double > p1, std::vector< double > p2, DomainData & data )
108  : dimensionworld( p1.size() ),
109  left_( p1 ),
110  right_( p2 ),
111  data_( data )
112  {
113  if( int( p2.size() ) != dimensionworld )
114  {
115  DUNE_THROW(DGFException,
116  "ERROR in " << *this << "!");
117  }
118  }
119 
120  // copy constructor
121  Domain ( const Domain & other )
122  : dimensionworld( other.dimensionworld ),
123  left_( other.left_ ),
124  right_( other.right_ ),
125  data_( other.data_ )
126  {
127  if( dimensionworld != other.dimensionworld )
128  {
129  DUNE_THROW(DGFException,
130  "ERROR in " << *this << "!");
131  }
132  }
133 
134  // assignment
135  Domain & operator = ( const Domain & other )
136  {
137  if( dimensionworld != other.dimensionworld )
138  {
139  DUNE_THROW(DGFException,
140  "ERROR in " << *this << "!");
141  }
142 
143  left_ = other.left_;
144  right_= other.right_;
145  data_= other.data_;
146  return *this;
147  }
148 
149  // return true if point is contained in boundary domain
150  template< class Vector >
151  bool contains ( const Vector & x ) const
152  {
153  bool ret = true;
154  for( int i = 0; i < dimensionworld; ++i )
155  {
156  if( x[ i ] < left_[ i ] || x[ i ] > right_[ i ] )
157  ret = false;
158  }
159  return ret;
160  }
161 
162  const DomainData & data () const
163  {
164  return data_;
165  }
166 
167  // for error messages
168  friend std::ostream & operator<< ( std :: ostream &os, const Domain & domain )
169  {
170  const int dimensionworld = domain.dimensionworld;
171  os << "domain: " << std::endl;
172  os << "left = ";
173  for( int i = 0; i < dimensionworld; ++i )
174  os << domain.left_[ i ] << " ";
175  os << std::endl;
176  os << "right = ";
177  for( int i = 0; i < dimensionworld; ++i )
178  os << domain.right_[ i ] << " ";
179  os << std::endl;
180  os << domain.data();
181  return os;
182  }
183 
184  private:
185  std::vector< double > left_, right_;
186  DomainData data_;
187 
188  };
189 
191  : public BasicBlock
192  {
193  typedef DGFBoundaryParameter::type BoundaryParameter;
194 
195  // the dimension of the vertices (is given from user)
196  int dimworld_;
197 
198  // internal counter
199  int counter_;
200 
201  // default values if given
202  DomainData * default_;
203 
204  // storage for all domains;
205  int ndomains_;
206  std::vector< Domain > domains_;
207 
208  public:
209  // initialize vertex block and get first vertex
210  BoundaryDomBlock ( std::istream & in, int cdimworld );
211 
212  // destructor
214  {
215  if( default_ )
216  delete default_;
217  }
218 
219  // go to next domain in block
220  bool next ()
221  {
222  counter_++;
223  return ( counter_ < ndomains_ );
224  }
225 
226  // return domain
227  const Domain & domain () const
228  {
229  return domains_.at( counter_ );
230  }
231 
232  // return true if default is given
233  bool hasDefaultData () const
234  {
235  return bool( default_ );
236  }
237 
238  // return default data
239  const DomainData * defaultData () const
240  {
241  return default_;
242  }
243 
244  // return true if any boundary domain block has
245  // additional paramters
246  bool hasParameter () const;
247 
248  void reset ()
249  {
251  counter_ = -1;
252  }
253 
254  // return true while block is active
255  bool ok ()
256  {
257  return ( counter_ <= ndomains_ );
258  }
259 
260  // return data if all vectors in array are contained within
261  // a single domain
262  template< class Vector >
263  const DomainData * contains ( const std::vector< Vector > & v ) const
264  {
265  std::vector< int > index( ndomains_ );
266  for( int i = 0; i < ndomains_; ++i)
267  index[ i ] = i;
268 
269  size_t N = v.size();
270  for( size_t i = 0; i < N; ++i )
271  {
272  if( index.empty() )
273  break;
274 
275  const int n = index.size();
276  assert( n > 0 );
277  for( int j = n-1; j >= 0; --j )
278  {
279  bool inside = domains_[ index[ j ] ].contains( v[ i ] );
280  if( !inside )
281  index.erase( index.begin() + j );
282  }
283  }
284 
285  // check wheter no boundary domain found
286  if( index.empty() )
287  return default_;
288 
289  // check for ambiguity
290  if( index.size() > 1 )
291  dwarn << "WARNING: ambiguous boundary domain assignment, use first boundary domain in list" << std::endl;
292 
293  return &domains_[ index[ 0 ] ].data();
294  }
295 
296  private:
297  void readBlock ();
298  };
299 
300  } // end namespace dgf
301 
302 } // end namespace Dune
303 
304 #endif