/******************************************************************* * * DESCRIPTION: class CoupledCell * * AUTHOR: Amir Barylko & Jorge Beyoglonian * Version 2: Daniel Rodriguez. * * EMAIL: mailto://amir@dc.uba.ar * mailto://jbeyoglo@dc.uba.ar * mailto://drodrigu@dc.uba.ar * * DATE: 27/06/1998 * DATE: 06/03/1999 (v2) * *******************************************************************/ /** include files **/ #include #include "coupcell.h" // CoupledCell #include "cellstate.h" // class CellState #include "strutil.h" // class int2Str #include "atomcell.h" // class AtomicCell #include "procadm.h" // SingleProcessorAdmin #include "modeladm.h" // SingleModelAdm /** methods **/ CoupledCell::CoupledCell( const string &name ) : Coupled( name ) , state( NULL ) , localFn( LocalTransAdmin::InvalidFn ) { } /******************************************************************* * Function Name: ~CoupledCell ********************************************************************/ CoupledCell::~CoupledCell() { if( state ) delete state; } /******************************************************************* * Function Name: cellState ********************************************************************/ CoupledCell &CoupledCell::cellState( CellState *ptr ) { MASSERTMSG( ptr != NULL, "Attemp to set a CellState with a NULL value\n"); if( state ) delete state ; state = ptr ; return *this ; } /******************************************************************* * Function Name: createCells ********************************************************************/ CoupledCell &CoupledCell::createCells( const CellPositionList &neighbors, const CellPositionList &selectList, CellPartition *part) { partition = part; cellState( new CellState( *((nTupla *) &(dimension())), wrapped ) ); this->neighbors = neighbors; AtomicCell **matrix = new (AtomicCell *)[ dimension().totalElements() ] ; CellPositionList::const_iterator cursor; ///////////////////////////////////////////////////////////// // let's create first the cells sepecified in the select list ///////////////////////////////////////////////////////////// for (cursor = selectList.begin(); cursor != selectList.end(); cursor++) matrix[ cursor->calculateIndex( dimension() ) ] = &( SingleModelAdm::Instance().newAtomicCell( inertial, cellName(*cursor) ) ); ////////////////////// // cell creation ////////////////////// nTupla dim( dimension() ); AtomicCell *atomicCell; CellPositionList::const_iterator toFind; MASSERTMSG( !dim.contains(0), "Attemp to create a Coupled Cell Model with a dimension containing the value 0."); CellPosition counter( dim.dimension(), 0); register bool overflow = false; while ( !overflow ){ // Busco la posicion pos toFind = selectList.begin(); while (toFind != selectList.end() && !(*toFind == counter )) toFind++; if (toFind == selectList.end()) // no encontre matrix[ counter.calculateIndex( dim, false ) ] = &( SingleModelAdm::Instance().newAtomicCell( inertial , cellName(counter) ) ); atomicCell = matrix[ counter.calculateIndex( dim, false ) ]; // cout << "setting position for " << atomicCell->description() ; atomicCell->cellPosition(counter); // cout << atomicCell->cellPosition().print() << endl; atomicCell->neighborhood( new NeighborhoodValue( *cellState(), neighbors, counter)); // Neighborhoood must be set atomicCell->value( initialValue ); atomicCell->localFunction( localTransition() ); // inserts ordered by id addModel( *atomicCell ); overflow = counter.next( dim ); } ///////////////////// // links creation ///////////////////// CellPosition auxi; counter.fill( dim.dimension(), 0 ); overflow = false; while ( !overflow ) { MASSERTMSG( matrix[ counter.calculateIndex( dim, false ) ] != NULL, "Incorrect value for matrix in CoupledCell::CreateCells"); for (cursor = neighbors.begin(); cursor != neighbors.end(); cursor++) { // get the real position auxi = *cursor; auxi += counter; if (wrapped) { auxi.canonizar( dim ); // ADD FOR THE REVERSE NEIGHBOR LIST addInfluence( matrix[ auxi.calculateIndex( dim, false ) ]->description(), AtomicCell::outPort, matrix[ counter.calculateIndex( dim, false ) ]->description(), AtomicCell::neighborChangePort ); } else if (cellState()->includes( auxi )) // ADD FOR THE REVERSE NEIGHBOR LIST // make the link between neighbors addInfluence( matrix[ auxi.calculateIndex( dim, false ) ]->description(), AtomicCell::outPort, matrix[ counter.calculateIndex( dim, false ) ]->description(), AtomicCell::neighborChangePort ); } overflow = counter.next( dim ); } delete [] matrix; return *this; } /******************************************************************* * Method: localTransition ********************************************************************/ CoupledCell &CoupledCell::setLocalTransition( const CellPosition &pos, const LocalTransAdmin::Function &fName ) { AtomicCell &cell( static_cast< AtomicCell & >( SingleProcessorAdmin::Instance().processor( cellName( pos ) ).model() ) ); cell.localFunction( fName ); return *this ; } /******************************************************************* * Function Name: setCellValue ********************************************************************/ /* CoupledCell &CoupledCell::setCellValue( const ModelId &model, Value v ) { AtomicCell &cell( static_cast< AtomicCell & >( SingleProcessorAdmin::Instance().processor( model ).model() ) ); cell.value( Real(v) ); return *this ; } */ /******************************************************************* * Function Name: setCellValue ********************************************************************/ CoupledCell &CoupledCell::setCellValue( const CellPosition &pos, const Real &v ) { // AtomicCell &cell( static_cast< AtomicCell & >( SingleProcessorAdmin::Instance().processor( cellName( pos ) ).model() ) ); // cell.value( v ); // return *this ; // cout << "setting the initial value for " << pos.print() << endl; if ( cellPartition().localCellsInclude(pos) ) { setCellValue(pos.print(), v); (*cellState())[ *(CellPosition *) &pos ] = v; } return *this; } /******************************************************************* * Function Name: setCellValue ********************************************************************/ CoupledCell &CoupledCell::setCellValue( const string &sCellPos, const Real &v ) { // AtomicCell &cell( static_cast< AtomicCell & >( SingleProcessorAdmin::Instance().processor( cellName(sCellPos) ).model() ) ) ; AtomicCell &cell = static_cast ( SingleModelAdm::Instance().model( cellName(sCellPos) ) ); cell.value( v ); // cout << "value of " << cell.description() << " is " << cell.value() << endl; return *this ; } CellPosition CoupledCell::inverseNeighborhood(const CellPosition ¢er, const CellPosition &other) const { if ( !borderWrapped() ) { CellPosition nPos = other; nPos -= center; return nPos; } else { CellPositionList::const_iterator cursor = neighborsList().begin(); for (; cursor != neighborsList().end() ; cursor++) { CellPosition nPos = *cursor; nPos += center; nPos.canonizar( (CellPosition&) dimension() ); if (nPos == other ) return *cursor; } } // cout << "CoupledCell:inverseNeighborhood " << center.print() << " - " << other.print() // << endl; MException e; e.addText("inverseNeighborhood: no neighbor found"); MTHROW(e); } Processor &CoupledCell::createProcessor() { return SingleProcessorAdmin::Instance().generateProcessor(this, localProc() ) ; } CoupledCell &CoupledCell::setCellMachine(const CellPosition &cellPos, const MachineId &mid, const ProcId &pid) { AtomicCell &cell( static_cast (SingleModelAdm::Instance().model( cellName(cellPos) ) ) ); cell.setMachineProcId(mid, pid); if( cellPartition().localCellsInclude(cellPos) ) { cell.parentId( localProc() ); } else { cell.parentId( procInMachine( mid ) ); } return *this; }