Newer
Older
// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==

Thomas Witkowski
committed
// == http://www.amdis-fem.org ==
// == ==
// ============================================================================

Thomas Witkowski
committed
//
// 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"
/// 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();

Thomas Witkowski
committed
if (dofFreeIterator == dofFree->end())

Thomas Witkowski
committed
goToBeginOfIteratedObject();

Thomas Witkowski
committed
if (type != ALL_DOFS)
if (*dofFreeIterator == (type == USED_DOFS))
/** \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();
goToBeginOfIteratedObject();
if (*dofFreeIterator == (type == USED_DOFS))
/** \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()
/** \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;
}
/// 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() {}

Thomas Witkowski
committed
/// 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:

Thomas Witkowski
committed
/// Constructs a DOFIterator for cont of type t
DOFIterator(DOFIndexed<T> *obj, DOFIteratorType t)
: DOFIteratorBase(dynamic_cast<DOFAdmin*>(obj->getFeSpace()->getAdmin()), t),
/// 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;
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;
}
/// Object that is iterated
DOFIndexed<T> *iteratedObject;
/// Iterator for \ref iteratedObject
typename std::vector<T>::iterator it;
};
}
#endif // AMDIS_DOFITERATOR_H