std::pair<int,int> SudokuGenerator::randomCell (char** sudoku, std::vector<std::pair<int,int>>& cells) const { while (!cells.empty ()) { int pos = rand () % (int) cells.size(); if (isEmpty (cells[pos].first, cells[pos].second, sudoku)) { std::pair<int,int> cell = cells[pos]; removeFromCell (cells, pos); return cell; } else { removeFromCell (cells, pos); } } return std::make_pair (-1,-1); }
void GCellsShearing::runEvent(Particle& part, const double) const { Sim->dynamics->updateParticle(part); size_t oldCell(partCellData[part.getID()]); magnet::math::MortonNumber<3> oldCellCoords(oldCell); Vector oldCellPosition(calcPosition(oldCellCoords)); //Determine the cell transition direction, its saved int cellDirectionInt(Sim->dynamics-> getSquareCellCollision3(part, oldCellPosition, cellDimension)); size_t cellDirection = abs(cellDirectionInt) - 1; magnet::math::MortonNumber<3> endCell = oldCellCoords; //The ID of the cell the particle enters if ((cellDirection == 1) && (oldCellCoords[1] == ((cellDirectionInt < 0) ? 0 : (cellCount[1] - 1)))) { //We're wrapping in the y direction, we have to compute //which cell its entering endCell[1] = (endCell[1].getRealValue() + cellCount[1] + ((cellDirectionInt < 0) ? -1 : 1)) % cellCount[1]; //Remove the old x contribution //Calculate the final x value //Time till transition, assumes the particle is up to date double dt = Sim->dynamics->getSquareCellCollision2(part, oldCellPosition, cellDimension); //Predict the position of the particle in the x dimension Sim->dynamics->advanceUpdateParticle(part, dt); Vector tmpPos = part.getPosition(); //This rewinds the particle again Sim->dynamics->updateParticle(part); //Adding this extra half cell ensures we get into the next //simulation image, to calculate the position of the new cell tmpPos[1] += ((cellDirectionInt < 0) ? -0.5 : 0.5) * cellDimension[1]; //Determine the x position (in cell coords) of the particle and //add it to the endCellID Sim->BCs->applyBC(tmpPos, dt); endCell[0] = getCellID(tmpPos)[0]; removeFromCell(part.getID()); addToCell(part.getID(), endCell.getMortonNum()); //Get rid of the virtual event that is next, update is delayed till //after all events are added Sim->ptrScheduler->popNextEvent(); //Check the entire neighbourhood, could check just the new //neighbours and the extra LE neighbourhood strip but its a lot //of code if (isUsedInScheduler) { BOOST_FOREACH(const size_t& id2, getParticleNeighbours(part)) { Sim->ptrScheduler->addInteractionEvent(part, id2); BOOST_FOREACH(const nbHoodSlot& nbs, sigNewNeighbourNotify) nbs.second(part, id2); } }