Skip to content
Snippets Groups Projects
DOFIterator.h 7.96 KiB
Newer Older
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ==                                                                        ==
// ============================================================================
//
// 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"
  /// 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.
     */
      position = 0;
      dofFreeIterator = dofFree->begin();
      goToBeginOfIteratedObject();
      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.
     */
      position = 0;
      dofFreeIterator = dofFree->begin();
Thomas Witkowski's avatar
Thomas Witkowski committed
      if (dofFreeIterator == dofFree->end()) 
Thomas Witkowski's avatar
Thomas Witkowski committed
      
      goToBeginOfIteratedObject();
Thomas Witkowski's avatar
Thomas Witkowski committed
      if (type != ALL_DOFS)
	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
      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; 
    }
    /// 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() {}
    /// 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;
    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