// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // == http://www.amdis-fem.org == // == == // ============================================================================ // // Software License for AMDiS // // Copyright (c) 2010 Dresden University of Technology // All rights reserved. // Authors: Simon Vey, Thomas Witkowski et al. // // This file is part of AMDiS // // See also license.opensource.txt in the distribution. /** \file DOFIterator.h */ #ifndef AMDIS_DOFITERATOR_H #define AMDIS_DOFITERATOR_H #include "DOFAdmin.h" #include "FiniteElemSpace.h" #include "AMDiS_fwd.h" namespace AMDiS { /// Possible types of DOFIterator 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) {} virtual ~DOFIteratorBase() {} /** \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(); if (dofFreeIterator == dofFree->end()) return; goToBeginOfIteratedObject(); if (type != ALL_DOFS) if (*dofFreeIterator == (type == USED_DOFS)) operator++(); } /** \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++(); } /** \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; } /// Postfix operator++. inline DOFIteratorBase operator++(int) { DOFIteratorBase clone = *this; operator++(); return clone; } 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; } inline DOFIteratorBase operator--(int) { DOFIteratorBase clone = *this; operator--(); return clone; } /// Dereferntiation of the \ref dofFreeIterator virtual bool isDofFree() { return *dofFreeIterator; } /** \brief * Returns whether \ref dofFreeIterator already has reached the end of * \ref dofFree */ inline bool end() { return (dofFreeIterator == dofFree->end()); } inline bool begin() { return (dofFreeIterator == dofFree->begin()); } /// Returns the current position index of this iterator inline int getDOFIndex() { return position; } protected: /// Override this to enable iteration through the object virtual void goToBeginOfIteratedObject() {} /// Override this to enable iteration through the object virtual void goToEndOfIteratedObject() {} /// Override this to enable iteration through the object virtual void incObjectIterator() {} virtual void decObjectIterator() {} protected: /// 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; }; /** \ingroup DOFAdministration * \brief * Implements a DOFIterator for a DOFIndexed<T> object */ template<typename T> class DOFIterator : public DOFIteratorBase { public: /// Constructs a DOFIterator for cont of type t DOFIterator(DOFIndexed<T> *obj, DOFIteratorType t) : DOFIteratorBase(dynamic_cast<DOFAdmin*>(obj->getFeSpace()->getAdmin()), t), iteratedObject(obj) {} /// Constructs a DOFIterator for cont of type t DOFIterator(DOFAdmin *admin, DOFIndexed<T> *obj, DOFIteratorType t) : DOFIteratorBase(admin, t), iteratedObject(obj) {} /// Dereference operator inline T& operator*() { return *it; } /// Dereference operator inline T* operator->() { return &(*it); } inline bool operator!=(const DOFIterator<T>& rhs) { if (this->iteratedObject != rhs.iteratedObject) return true; if (this->it != rhs.it) return true; return false; } inline bool operator==(const DOFIterator<T>& rhs) { return !(this->operator==(rhs)); } protected: /// Implementation of DOFIteratorBase::goToBeginOfIteratedObject() inline void goToBeginOfIteratedObject() { it = iteratedObject->begin(); } /// Implementation of DOFIteratorBase::goToEndOfIteratedObject() inline void goToEndOfIteratedObject() { it = iteratedObject->end(); } /// Implementation of DOFIteratorBase::incObjectIterator() inline void incObjectIterator() { ++it; } /// Implementation of DOFIteratorBase::incObjectIterator() inline void decObjectIterator() { --it; } protected: /// Object that is iterated DOFIndexed<T> *iteratedObject; /// Iterator for \ref iteratedObject typename std::vector<T>::iterator it; }; } #endif // AMDIS_DOFITERATOR_H