DOFIterator.h 8.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file DOFIterator.h */

#ifndef AMDIS_DOFITERATOR_H
#define AMDIS_DOFITERATOR_H

#include "DOFAdmin.h"
#include "FiniteElemSpace.h"
27
#include "AMDiS_fwd.h"
28
29
30

namespace AMDiS {

31
  /// Possible types of DOFIterator
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  typedef enum {
    USED_DOFS = 0, /**< iterate only used DOFs */
    FREE_DOFS = 1, /**< iterate only free DOFs */
    ALL_DOFS  = 2  /**< iterate all DOFs */
  } DOFIteratorType;


  /** \ingroup DOFAdministration
   * \brief
   * DOFIteratorBase can be the base class of Iterators for DOFIndexed objects
   * or it can be used stand alone. Than it iterates through DOFAdmin's dofFree
   * vector which stores whether a DOF is used or not. If it is used as base
   * class for another Iterator, it provides base functionality, to iterate
   * through the \ref iteratedObject of the sub class. All you have to do is to 
   * override the methods \ref goToBeginOfIteratedObject(), 
   * \ref goToEndOfIteratedObject() and \ref incObjectIterator(). 
   * Normally it is usefull to provide 
   * operator->() and operator*(), to dereference the iterator. But this is not 
   * possible in this base class, because it is template type independent.
   */
  class DOFIteratorBase
  {
  public:
    /** \brief
     * Constructs a DOFIteratorBase object of type t which can iterate through 
     * admin's dofFree vector
     */
    DOFIteratorBase(DOFAdmin* admin, DOFIteratorType t) 
      : dofAdmin(admin), 
	dofFree(&(dofAdmin->dofFree)),
	type(t)
63
    {}
64

65
    virtual ~DOFIteratorBase() {}
66
67
68
69
70
71
72
73
74

    /** \brief
     * Resets the iterator to the begin of the iterated object. 
     * Sub classes must
     * implement goToBeginOfIteratedObject() which resets the iterator.
     */
    virtual void reset() {
      position = 0;
      dofFreeIterator = dofFree->begin();
75
      if (dofFreeIterator == dofFree->end())
76
	return;
77

78
      goToBeginOfIteratedObject();
79
80
      if (type != ALL_DOFS)
	if (*dofFreeIterator == (type == USED_DOFS))
81
	  operator++();
82
    }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

    /** \brief
     * Resets the iterator to the begin of the iterated object. 
     * Sub classes must
     * implement goToBeginOfIteratedObject() which resets the iterator.
     */
    virtual void reset2() {
      position = 0;
      dofFreeIterator = dofFree->begin();
      if(dofFreeIterator == dofFree->end()) {
	return;
      }
      goToBeginOfIteratedObject();
      if(type != ALL_DOFS) { 
	if(*dofFreeIterator == (type == USED_DOFS))
	  operator++();
      }
100
    }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

    /** \brief
     * Prefix operator++.
     * Incrementation depends of the type of the iterator. If type is USED_DOFS,
     * the iterator points to the next used DOF after operator call. If type is
     * FREE_DOFS, it points to the next free DOF and if type is ALL_DOFS, it will
     * point to the next DOF regardless whether it is used or not. Sub classes
     * must implement incObjectIterator() which increments the object
     * iterator.
     */
    inline const DOFIteratorBase& operator++() {
      if (type == ALL_DOFS) {
	incObjectIterator();
	dofFreeIterator++;
	position++;
	return *this;
      }

      if (type == USED_DOFS) {
	if (position >= dofAdmin->getUsedSize()) {
	  position = dofAdmin->getSize();
	  goToEndOfIteratedObject();
	  dofFreeIterator = dofFree->end();
	  return *this;
	}
      }

      do {
	incObjectIterator();
	dofFreeIterator++;
	position++;
      } while ((dofFreeIterator != dofFree->end()) 
	       && (*dofFreeIterator == (type == USED_DOFS)));

      return *this;      
136
    }
137

138
    /// Postfix operator++.
139
140
141
142
    inline DOFIteratorBase operator++(int) { 
      DOFIteratorBase clone = *this;
      operator++();
      return clone;
143
    }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

    inline const DOFIteratorBase& operator--() {
      if (type == ALL_DOFS) {
	decObjectIterator();
	dofFreeIterator--;
	position--;
	return *this;
      }

      do {
	decObjectIterator();
	dofFreeIterator--;
	position--;
      } while ((dofFreeIterator != dofFree->begin())
	       && (*dofFreeIterator == (type == USED_DOFS)));

      return *this;
161
    }
162
163
164
165
166
167
168

    inline DOFIteratorBase operator--(int) {
      DOFIteratorBase clone = *this;
      operator--();
      return clone;
    }
  
169
    /// Dereferntiation of the \ref dofFreeIterator
170
171
    virtual bool isDOFFree() {
      return *dofFreeIterator;
172
    }
173
174
175
176
177

    /** \brief
     * Returns whether \ref dofFreeIterator already has reached the end of 
     * \ref dofFree
     */
178
    inline bool end() { return (dofFreeIterator == dofFree->end()); }
179

180
    inline bool begin() { return (dofFreeIterator == dofFree->begin()); }
181

182
183
    /// Returns the current position index of this iterator
    inline int getDOFIndex() { return position; }
184
185

  protected:
186
187
    /// Override this to enable iteration through the object
    virtual void goToBeginOfIteratedObject() {}
188

189
190
    /// Override this to enable iteration through the object
    virtual void goToEndOfIteratedObject() {}
191

192
193
    /// Override this to enable iteration through the object
    virtual void incObjectIterator() {}
194
    
195
    virtual void decObjectIterator() {}
196
197

  protected:
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    /// DOFAdmin which contains the dofFree vector.
    DOFAdmin *dofAdmin;
    
    /// Current position index.
    int position;

    /// Stores which DOFs are used.
    std::vector<bool> *dofFree; 

    /// Iterator for dofFree.
    std::vector<bool>::iterator dofFreeIterator;

    /// Type of this iterator.
    const DOFIteratorType type;
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  };


  /** \ingroup DOFAdministration
   * \brief
   * Implements a DOFIterator for a DOFIndexed<T> object
   */
  template<typename T>
  class DOFIterator : public DOFIteratorBase
  {
  public:
    /** \brief
     * Constructs a DOFIterator for cont of type t
     */
    DOFIterator(DOFIndexed<T> *obj, DOFIteratorType t) 
      : DOFIteratorBase(dynamic_cast<DOFAdmin*>(obj->getFESpace()->getAdmin()), t),
	iteratedObject(obj)
229
    {}
230

231
    /// Constructs a DOFIterator for cont of type t
232
233
234
235
236
    DOFIterator(DOFAdmin *admin,
		DOFIndexed<T> *obj, 
		DOFIteratorType t) 
      : DOFIteratorBase(admin, t),
	iteratedObject(obj)
237
    {}
238

239
240
    /// Dereference operator
    inline T& operator*() { return *it; }
241

242
243
    /// Dereference operator
    inline T* operator->() { return &(*it); }
244
245
246
247
248

    inline bool operator!=(const DOFIterator<T>& rhs) {
      if(this->iteratedObject != rhs.iteratedObject) return true;
      if(this->it != rhs.it) return true;
      return false;
249
    }
250
251
252
253
254
255

    inline bool operator==(const DOFIterator<T>& rhs) {
      return !(this->operator==(rhs));
    }

  protected:
256
257
    /// Implementation of DOFIteratorBase::goToBeginOfIteratedObject()
    inline void goToBeginOfIteratedObject() { it = iteratedObject->begin(); }
258

259
260
    /// Implementation of DOFIteratorBase::goToEndOfIteratedObject()
    inline void goToEndOfIteratedObject() { it = iteratedObject->end(); }
261

262
263
    /// Implementation of DOFIteratorBase::incObjectIterator()
    inline void incObjectIterator() { ++it; }
264

265
266
    /// Implementation of DOFIteratorBase::incObjectIterator()
    inline void decObjectIterator() { --it; }
267
268

  protected:
269
    /// Object that is iterated
270
271
    DOFIndexed<T> *iteratedObject;

272
    /// Iterator for \ref iteratedObject
273
    typename std::vector<T>::iterator it;
274
275
276
277
278
  };

}

#endif // AMDIS_DOFITERATOR_H