#include "cellpartition.h" const unsigned long CellPartition::InvalidCellIndex(-1); CellPartition::CellPartition(const nTupla& dimension, bool border) : currentIndex(0), localElements(0), dim(dimension), wrapped(border) { } CellPartition::~CellPartition() { PartitionZoneList::iterator cursor1; PartitionCellList::iterator cursor2; for( cursor1 = localCells.begin(); cursor1 != localCells.end(); cursor1++) delete *cursor1 ; for( cursor2 = remoteNeighbors.begin() ; cursor2 != remoteNeighbors.end(); cursor2++) delete *cursor2 ; } CellPartition &CellPartition::addLocalZone(const string &zoneStr) { PartitionZoneDetails *pzone = new PartitionZoneDetails( zoneStr ); MASSERTMSG( !localCellsInclude(pzone->zone.firstCell()) ," Cannot add zone: " + zoneStr + " because it will overlapto existing zones.") pzone->firstIndex = currentIndex; currentIndex += pzone->zone.dimension().totalElements(); localElements += pzone->zone.dimension().totalElements(); pzone->lastIndex = currentIndex - 1; localCells.push_back( pzone ); return *this; } CellPartition &CellPartition::addNeighborCell(const CellPosition &cell) { if( !localCellsInclude(cell) && !neighborCellsInclude(cell) ) { PartitionCellDetails *cellDetail = new PartitionCellDetails; cellDetail->cell = cell; cellDetail->cellIndex = currentIndex; remoteNeighbors.push_back( cellDetail ); currentIndex++; } return *this; } CellPartition &CellPartition::addNeighborCells(const CellPositionList &neighborList) { CellPartition::LocalCellsIterator cells; CellPositionList::const_iterator neighbors; nTupla pos; for (cells = begin(); cells != end() ; cells++) { for(neighbors = neighborList.begin(); neighbors != neighborList.end(); neighbors++ ) { pos = *cells; pos += *neighbors; if( borderWrapped() ) { pos.canonizar( dimension() ); addNeighborCell(pos); } else { if(dimension().includes( pos ) ) { addNeighborCell( pos ); } } } } return *this; } bool CellPartition::localCellsInclude( CellPosition cell) const { PartitionZoneList::const_iterator cursor; if( borderWrapped() ) cell.canonizar( dimension() ); cursor = localCells.begin() ; while( cursor != localCells.end() ) { if( cell.isInRegion( (*cursor)->zone.firstCell() , (*cursor)->zone.lastCell() ) ) return true; cursor++; } return false; } bool CellPartition::neighborCellsInclude( CellPosition cell) const { PartitionCellList::const_iterator cursor; if ( borderWrapped() ) cell.canonizar( dimension() ); cursor = remoteNeighbors.begin(); while( cursor != remoteNeighbors.end() ) { if( (*cursor)->cell == cell ) return true; cursor++; } return false; } unsigned long CellPartition::cellIndex( CellPosition cell ) const { PartitionZoneList::const_iterator cursor; if( borderWrapped() ) cell.canonizar( dimension() ); cursor = localCells.begin(); while( cursor != localCells.end() ) { if( cell.isInRegion( (*cursor)->zone.firstCell() , (*cursor)->zone.lastCell() ) ) { nTupla pos = cell; pos -= (*cursor)->zone.firstCell(); return (*cursor)->firstIndex + pos.totalElements() - 1; } cursor++; } PartitionCellList::const_iterator cursor2; cursor2 = remoteNeighbors.begin(); while( cursor2 != remoteNeighbors.end() ) { if( (*cursor2)->cell == cell) { return (*cursor2)->cellIndex; } cursor2++; } return InvalidCellIndex; } CellPartition::LocalCellsIterator CellPartition::begin() const { LocalCellsIterator it( localCells.begin() , localCells.end() ); return it; } CellPartition::LocalCellsIterator CellPartition::end() const { LocalCellsIterator it; return it; } CellPartition::LocalCellsIterator &CellPartition::LocalCellsIterator::operator++( int ) { cursor++; if( cursor == currentZone->zone.end() ) { zones++; if( zones == zoneListEnd ) currentZone = NULL; else cursor = (*zones)->zone.begin() ; } return *this; } CellPartition::LocalCellsIterator &CellPartition::LocalCellsIterator::operator=(const LocalCellsIterator &it) { cursor = it.cursor; zones = it.zones; currentZone = it.currentZone; zoneListEnd = it.zoneListEnd; return *this; } CellPartition::LocalCellsIterator::LocalCellsIterator( const CellPartition::PartitionZoneList::const_iterator &begin, const CellPartition::PartitionZoneList::const_iterator &end) { zones = begin; zoneListEnd = end; if ( begin != end ) { currentZone = *begin; cursor = currentZone->zone.begin(); } else { currentZone = NULL; } } CellPartition::LocalCellsIterator::LocalCellsIterator(const CellPartition::PartitionZoneList::const_iterator &begin, const CellPartition::PartitionZoneList::const_iterator &end , PartitionZoneDetails *current) { zones = begin; zoneListEnd = end; currentZone = current; cursor = currentZone->zone.begin(); } bool CellPartition::LocalCellsIterator::operator ==(const LocalCellsIterator &it ) const { if( currentZone == NULL) return it.currentZone == NULL; else return *cursor == *it; }