/// Method for generating hit(s) using the information of G4Step object. template <> G4bool Geant4GenericSD<TrackerCombine>::ProcessHits(G4Step* step,G4TouchableHistory* ) { StepHandler h(step); bool return_code = false; if ( !userData.track || userData.current != h.track->GetTrackID() ) { return_code = userData.extractHit(collection(0)) != 0; userData.start(getCellID(step), step, h.pre); } // ....update ..... userData.update(step); void *prePV = h.volume(h.pre), *postPV = h.volume(h.post); if ( prePV != postPV ) { void* postSD = h.sd(h.post); return_code = userData.extractHit(collection(0)) != 0; if ( 0 != postSD ) { void* preSD = h.sd(h.pre); if ( preSD == postSD ) { userData.start(getCellID(step), step,h.post); } } } else if ( userData.track->GetTrackStatus() == fStopAndKill ) { return_code = userData.extractHit(collection(0)) != 0; } return return_code; }
LRESULT ListCtrl::onLButtonUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { if (!verify()) { return 0; } Point pt(lParam); std::pair<CellID, Rect> cellID; if (!getCellID(pt, cellID)) { return 0; } m_cellSelected = cellID.first; if (m_cellSelected.m_nCol == 0) { } //TRACE(L"m_cellSelected.m_nRow=%d, m_cellSelected.m_nCol=%d", m_cellSelected.m_nRow, m_cellSelected.m_nCol); Cell* pCell = getCell(cellID.first.m_nRow, cellID.first.m_nCol); if (pCell != NULL) { pCell->setRect(cellID.second); return pCell->sendMessage(WM_LBUTTONUP, wParam, lParam); } return 0; }
/// Method for generating hit(s) using the information of G4Step object. virtual G4bool ProcessHits(G4Step* step,G4TouchableHistory* history) { G4Track * track = step->GetTrack(); // check that particle is optical photon: if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) { return this->Geant4GenericSD<Calorimeter>::ProcessHits(step,history); } else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() != "Cerenkov") { track->SetTrackStatus(fStopAndKill); return false; } else { StepHandler h(step); HitContribution contrib = Geant4Hit::extractContribution(step); Position pos = h.prePos(); Geant4CalorimeterHit* hit=find(collection(Cerenkov_type),HitPositionCompare<Geant4CalorimeterHit>(pos)); if ( !hit ) { collection(Cerenkov_type)->insert(hit=new Geant4CalorimeterHit(pos)); hit->cellID = getCellID( step ) ; } hit->energyDeposit += contrib.deposit; hit->truth.push_back(contrib); track->SetTrackStatus(fStopAndKill); // don't step photon any further return true; } }
LRESULT ListCtrl::onTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { if (wParam == LIST_TIMER_MOUSEMOVE) { killTimer(LIST_TIMER_MOUSEMOVE); Point pt = m_ptMouseMove; std::pair<CellID, Rect> cellpt; std::pair<Cell*, Rect> cell; CellID cellMouseLeave; CellID cellMouseMove; Cell* pCell = NULL; if (getCellID(pt, cellpt)) { cellMouseMove = cellpt.first; if (cellMouseMove != m_cellMouseMove) { cellMouseLeave = m_cellMouseMove; m_cellMouseMove = cellMouseMove; //TRACE(L"cellMouseLeave.m_nRow = %d, cellMouseLeave.m_nCol = %d", cellMouseLeave.m_nRow, cellMouseLeave.m_nCol); //TRACE(L"m_cellMouseMove.m_nRow = %d, m_cellMouseMove.m_nCol = %d", m_cellMouseMove.m_nRow, m_cellMouseMove.m_nCol); } } if (getCellIndirect(cellMouseLeave, cell)) { cell.first->sendMessage(WM_MOUSELEAVE, (WPARAM)&cell.second); } if (getCellIndirect(m_cellMouseMove, cell)) { cell.first->sendMessage(WM_MOUSEMOVE, (WPARAM)&cell.second); } } return 1; }
void Grid::addArea(const Item::SharedArea &area) { if (area->size > cellDistance) { globalCell->areas.insert(std::make_pair(area->areaID, area)); area->cell.reset(); } else { Eigen::Vector2f position = Eigen::Vector2f::Zero(); switch (area->type) { case STREAMER_AREA_TYPE_CIRCLE: case STREAMER_AREA_TYPE_CYLINDER: { if (area->attach) { position = Eigen::Vector2f(area->attach->position[0], area->attach->position[1]); } else { position = boost::get<Eigen::Vector2f>(area->position); } break; } case STREAMER_AREA_TYPE_SPHERE: { if (area->attach) { position = Eigen::Vector2f(area->attach->position[0], area->attach->position[1]); } else { position = Eigen::Vector2f(boost::get<Eigen::Vector3f>(area->position)[0], boost::get<Eigen::Vector3f>(area->position)[1]); } break; } case STREAMER_AREA_TYPE_RECTANGLE: { boost::geometry::centroid(boost::get<Box2D>(area->position), position); break; } case STREAMER_AREA_TYPE_CUBOID: { Eigen::Vector3f centroid = boost::geometry::return_centroid<Eigen::Vector3f>(boost::get<Box3D>(area->position)); position = Eigen::Vector2f(centroid[0], centroid[1]); break; } case STREAMER_AREA_TYPE_POLYGON: { boost::geometry::centroid(boost::get<Polygon2D>(area->position), position); break; } } CellID cellID = getCellID(position); cells[cellID]->areas.insert(std::make_pair(area->areaID, area)); area->cell = cells[cellID]; } }
void ListCtrl::getToolTip(String& str) const { std::pair<CellID, Rect> cellpt; getCellID(m_ptMouseMove, cellpt); if (!isValidCellID(cellpt.first)) { str = L""; } str.format(L"ROW:%d COL:%d", cellpt.first.m_nRow, cellpt.first.m_nCol); }
void Grid::findMinimalCells(Player &player, std::vector<SharedCell> &playerCells) { for (int i = 0; i < translationMatrix.cols(); ++i) { Eigen::Vector2f position = Eigen::Vector2f(player.position[0], player.position[1]) + translationMatrix.col(i); boost::unordered_map<CellID, SharedCell>::iterator c = cells.find(getCellID(position, false)); if (c != cells.end()) { playerCells.push_back(c->second); } } playerCells.push_back(globalCell); }
void Grid::findMinimalCellsForPoint(const Eigen::Vector2f &point, std::vector<SharedCell> &pointCells) { for (int i = 0; i < translationMatrix.cols(); ++i) { Eigen::Vector2f position = point + translationMatrix.col(i); boost::unordered_map<CellID, SharedCell>::iterator c = cells.find(getCellID(position, false)); if (c != cells.end()) { pointCells.push_back(c->second); } } pointCells.push_back(globalCell); }
void Grid::addCheckpoint(const Item::SharedCheckpoint &checkpoint) { if (checkpoint->streamDistance > cellDistance || checkpoint->streamDistance < STREAMER_STATIC_DISTANCE_CUTOFF) { globalCell->checkpoints.insert(std::make_pair(checkpoint->checkpointID, checkpoint)); checkpoint->cell.reset(); } else { CellID cellID = getCellID(Eigen::Vector2f(checkpoint->position[0], checkpoint->position[1])); cells[cellID]->checkpoints.insert(std::make_pair(checkpoint->checkpointID, checkpoint)); checkpoint->cell = cells[cellID]; } }
void Grid::addRaceCheckpoint(const Item::SharedRaceCheckpoint &raceCheckpoint) { if (raceCheckpoint->streamDistance > cellDistance) { globalCell->raceCheckpoints.insert(std::make_pair(raceCheckpoint->raceCheckpointID, raceCheckpoint)); raceCheckpoint->cell.reset(); } else { CellID cellID = getCellID(Eigen::Vector2f(raceCheckpoint->position[0], raceCheckpoint->position[1])); cells[cellID]->raceCheckpoints.insert(std::make_pair(raceCheckpoint->raceCheckpointID, raceCheckpoint)); raceCheckpoint->cell = cells[cellID]; } }
void Grid::addPickup(const Item::SharedPickup &pickup) { if (pickup->streamDistance > cellDistance) { globalCell->pickups.insert(std::make_pair(pickup->pickupID, pickup)); pickup->cell.reset(); } else { CellID cellID = getCellID(Eigen::Vector2f(pickup->position[0], pickup->position[1])); cells[cellID]->pickups.insert(std::make_pair(pickup->pickupID, pickup)); pickup->cell = cells[cellID]; } }
void Grid::addMapIcon(const Item::SharedMapIcon &mapIcon) { if (mapIcon->streamDistance > cellDistance) { globalCell->mapIcons.insert(std::make_pair(mapIcon->mapIconID, mapIcon)); mapIcon->cell.reset(); } else { CellID cellID = getCellID(Eigen::Vector2f(mapIcon->position[0], mapIcon->position[1])); cells[cellID]->mapIcons.insert(std::make_pair(mapIcon->mapIconID, mapIcon)); mapIcon->cell = cells[cellID]; } }
void Grid::findAllCells(Player &player, std::vector<SharedCell> &playerCells) { boost::unordered_set<CellID> discoveredCells; for (int i = 0; i < translationMatrix.cols(); ++i) { Eigen::Vector2f position = Eigen::Vector2f(player.position[0], player.position[1]) + translationMatrix.col(i); boost::unordered_map<CellID, SharedCell>::iterator c = cells.find(getCellID(position, false)); if (c != cells.end()) { discoveredCells.insert(c->first); playerCells.push_back(c->second); } } processDiscoveredCells(player, playerCells, discoveredCells); playerCells.push_back(globalCell); }
/// Method for generating hit(s) using the information of G4Step object. template <> bool Geant4GenericSD<Calorimeter>::buildHits(G4Step* step,G4TouchableHistory*) { StepHandler h(step); Position pos = 0.5 * (h.prePos() + h.postPos()); HitContribution contrib = Geant4Hit::extractContribution(step); Geant4CalorimeterHit* hit=find(collection(0),HitPositionCompare<Geant4CalorimeterHit>(pos)); // G4cout << "----------- Geant4GenericSD<Calorimeter>::buildHits : position : " << pos << G4endl; if ( !hit ) { hit = new Geant4CalorimeterHit(pos); hit->cellID = getCellID( step ); collection(0)->insert(hit); } hit->truth.push_back(contrib); hit->energyDeposit += contrib.deposit; return true; }
void Grid::addTextLabel(const Item::SharedTextLabel &textLabel) { if (textLabel->streamDistance > cellDistance) { globalCell->textLabels.insert(std::make_pair(textLabel->textLabelID, textLabel)); textLabel->cell.reset(); } else { Eigen::Vector2f position = Eigen::Vector2f::Zero(); if (textLabel->attach) { position = Eigen::Vector2f(textLabel->attach->position[0], textLabel->attach->position[1]); } else { position = Eigen::Vector2f(textLabel->position[0], textLabel->position[1]);; } CellID cellID = getCellID(position); cells[cellID]->textLabels.insert(std::make_pair(textLabel->textLabelID, textLabel)); textLabel->cell = cells[cellID]; } }
void Grid::addObject(const Item::SharedObject &object) { if (object->streamDistance > cellDistance) { globalCell->objects.insert(std::make_pair(object->objectID, object)); object->cell.reset(); } else { Eigen::Vector2f position = Eigen::Vector2f::Zero(); if (object->attach) { position = Eigen::Vector2f(object->attach->position[0], object->attach->position[1]); } else { position = Eigen::Vector2f(object->position[0], object->position[1]); } CellID cellID = getCellID(Eigen::Vector2f(position[0], position[1])); cells[cellID]->objects.insert(std::make_pair(object->objectID, object)); object->cell = cells[cellID]; } }
void GCells::addCells(double maxdiam) { list.clear(); partCellData.clear(); NCells = 1; for (size_t iDim = 0; iDim < NDIM; iDim++) { cellCount[iDim] = int(Sim->primaryCellSize[iDim] / (maxdiam * (1.0 + 10 * std::numeric_limits<double>::epsilon()))); if (cellCount[iDim] < 2 * overlink + 1) cellCount[iDim] = 2 * overlink + 1; NCells *= cellCount[iDim]; dilatedCellMax[iDim] = cellCount[iDim] - 1; cellLatticeWidth[iDim] = Sim->primaryCellSize[iDim] / cellCount[iDim]; cellDimension[iDim] = cellLatticeWidth[iDim] + (cellLatticeWidth[iDim] - maxdiam) * lambda; cellOffset[iDim] = -(cellLatticeWidth[iDim] - maxdiam) * lambda * 0.5; } if (getMaxSupportedInteractionLength() < maxdiam) M_throw() << "The system size is too small to support the range of interactions specified (i.e. the system is smaller than the interaction diameter of one particle)."; //Find the required size of the morton array magnet::math::MortonNumber<3> coords(cellCount[0], cellCount[1], cellCount[2]); size_t sizeReq = coords.getMortonNum(); list.resize(sizeReq); //Empty Cells created! dout << "Cells <x,y,z> " << cellCount[0] << "," << cellCount[1] << "," << cellCount[2] << "\nCell Offset " << cellOffset[0] / Sim->units.unitLength() << "," << cellOffset[1] / Sim->units.unitLength() << "," << cellOffset[2] / Sim->units.unitLength() << "\nCells Dimension " << cellDimension[0] / Sim->units.unitLength() << "," << cellDimension[1] / Sim->units.unitLength() << "," << cellDimension[2] / Sim->units.unitLength() << "\nLattice spacing " << cellLatticeWidth[0] / Sim->units.unitLength() << "," << cellLatticeWidth[1] / Sim->units.unitLength() << "," << cellLatticeWidth[2] / Sim->units.unitLength() << "\nRequested supported length " << maxdiam / Sim->units.unitLength() << "\nSupported length " << getMaxSupportedInteractionLength() / Sim->units.unitLength() << "\nVector Size <N> " << sizeReq << std::endl; //Add the particles section //Required so particles find the right owning cell Sim->dynamics->updateAllParticles(); ////Add all the particles BOOST_FOREACH(const size_t& id, *range) { Particle& p = Sim->particles[id]; Sim->dynamics->updateParticle(p); addToCell(id); if (verbose) { boost::unordered_map<size_t, size_t>::iterator it = partCellData.find(id); magnet::math::MortonNumber<3> currentCell(it->second); magnet::math::MortonNumber<3> estCell(getCellID(Sim->particles[ID].getPosition())); Vector wrapped_pos = p.getPosition(); for (size_t n = 0; n < NDIM; ++n) { wrapped_pos[n] -= Sim->primaryCellSize[n] * lrint(wrapped_pos[n] / Sim->primaryCellSize[n]); } Vector origin_pos = wrapped_pos + 0.5 * Sim->primaryCellSize - cellOffset; derr << "Added particle ID=" << p.getID() << " to cell <" << currentCell[0].getRealValue() << "," << currentCell[1].getRealValue() << "," << currentCell[2].getRealValue() << ">" << "\nParticle is at this distance " << Vector(p.getPosition() - calcPosition(it->second, p)).toString() << " from the cell origin" << "\nParticle position " << p.getPosition().toString() << "\nParticle wrapped distance " << wrapped_pos.toString() << "\nParticle relative position " << origin_pos.toString() << "\nParticle cell number " << Vector(origin_pos[0] / cellLatticeWidth[0], origin_pos[1] / cellLatticeWidth[1], origin_pos[2] / cellLatticeWidth[2] ).toString() << std::endl; } } dout << "Cell loading " << float(partCellData.size()) / NCells << std::endl; }
IDRangeList GCells::getParticleNeighbours(const Vector& vec) const { return getParticleNeighbours(getCellID(vec)); }
void OPVTK::eventUpdate(const IntEvent& IEvent, const PairEventData& PDat) { if (CollisionStats) { ++collCounter[getCellID(PDat.particle1_.getParticle().getPosition())]; ++collCounter[getCellID(PDat.particle2_.getParticle().getPosition())]; if (!(++eventCounter % 50000)) { char *fileName; if ( asprintf(&fileName, "%05ld", ++collstatsfilecounter) < 0) M_throw() << "asprintf error in VTK"; std::ofstream of((std::string("CollStats") + fileName + std::string(".vtu")).c_str()); free(fileName); magnet::xml::XmlStream XML(of); XML << magnet::xml::tag("VTKFile") << magnet::xml::attr("type") << "ImageData" << magnet::xml::attr("version") << "0.1" << magnet::xml::attr("byte_order") << "LittleEndian" << magnet::xml::attr("compressor") << "vtkZLibDataCompressor" << magnet::xml::tag("ImageData") << magnet::xml::attr("WholeExtent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::attr("Origin"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << (Sim->primaryCellSize[iDim] * (-0.5)) / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::attr("Spacing"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << binWidth[iDim] / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::tag("Piece") << magnet::xml::attr("Extent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::tag("PointData"); //////////////////////////HERE BEGINS THE OUTPUT OF THE FIELDS ////////////SAMPLE COUNTS XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Int32" << magnet::xml::attr("Name") << "Collisions Per Snapshot" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); BOOST_FOREACH(const unsigned long& val, collCounter) XML << val; XML << "\n" << magnet::xml::endtag("DataArray"); BOOST_FOREACH(unsigned long& val, collCounter) val = 0; std::vector<size_t> density(nBins[0] * nBins[1] * nBins[2], 0); BOOST_FOREACH(const Particle& part, Sim->particleList) ++density[getCellID(part.getPosition())]; XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("Name") << "Density" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); BOOST_FOREACH(const size_t& val, density) XML << (val / binVol); XML << "\n" << magnet::xml::endtag("DataArray"); ////////////Postamble XML << magnet::xml::endtag("PointData") << magnet::xml::tag("CellData") << magnet::xml::endtag("CellData") << magnet::xml::endtag("Piece") << magnet::xml::endtag("ImageData") << magnet::xml::endtag("VTKFile"); } }
void OPVTK::ticker() { ++imageCounter; if (fields) { BOOST_FOREACH(const Particle & Part, Sim->particleList) { Vector position = Part.getPosition(), velocity = Part.getVelocity(); Sim->dynamics.BCs().applyBC(position, velocity); size_t id(getCellID(position)); //Samples ++SampleCounter[id]; double mass = Sim->dynamics.getSpecies(Part).getMass(Part.getID()); //Velocity Vectors Momentum[id] += velocity * mass; //Energy Field mVsquared[id] += velocity.nrm2() * mass; } } if (snapshots) { char *fileName; if ( asprintf(&fileName, "%05ld", imageCounter) < 0) M_throw() << "asprintf error in tinkerXYZ"; std::ofstream of((std::string("paraview") + fileName + std::string(".vtu")).c_str()); free(fileName); magnet::xml::XmlStream XML(of); XML //<< std::scientific //This has a minus one due to the digit in front of the decimal //An extra one is added if we're rounding << std::setprecision(std::numeric_limits<double>::digits10 - 1) << magnet::xml::prolog() << magnet::xml::tag("VTKFile") << magnet::xml::attr("type") << "UnstructuredGrid" << magnet::xml::attr("version") << "0.1" << magnet::xml::attr("byte_order") << "LittleEndian" << magnet::xml::tag("UnstructuredGrid") << magnet::xml::tag("Piece") << magnet::xml::attr("NumberOfPoints") << Sim->N << magnet::xml::attr("NumberOfCells") << 0 << magnet::xml::tag("Points") << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("format") << "ascii" << magnet::xml::attr("NumberOfComponents") << "3" << magnet::xml::chardata(); BOOST_FOREACH(const Particle& part, Sim->particleList) XML << part.getPosition()[0] / Sim->dynamics.units().unitLength() << " " << part.getPosition()[1] / Sim->dynamics.units().unitLength() << " " << part.getPosition()[2] / Sim->dynamics.units().unitLength() << "\n"; XML << magnet::xml::endtag("DataArray") << magnet::xml::endtag("Points") << magnet::xml::tag("Cells") << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Int32" << magnet::xml::attr("Name") << "connectivity" << magnet::xml::attr("format") << "ascii" << magnet::xml::endtag("DataArray") << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Int32" << magnet::xml::attr("Name") << "offsets" << magnet::xml::attr("format") << "ascii" << magnet::xml::endtag("DataArray") << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "UInt8" << magnet::xml::attr("Name") << "types" << magnet::xml::attr("format") << "ascii" << magnet::xml::endtag("DataArray") << magnet::xml::endtag("Cells") << magnet::xml::tag("CellData") << magnet::xml::endtag("CellData") << magnet::xml::tag("PointData"); //Velocity data XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("Name") << "Velocities" << magnet::xml::attr("NumberOfComponents") << "3" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); BOOST_FOREACH(const Particle& part, Sim->particleList) XML << part.getVelocity()[0] / Sim->dynamics.units().unitVelocity() << " " << part.getVelocity()[1] / Sim->dynamics.units().unitVelocity() << " " << part.getVelocity()[2] / Sim->dynamics.units().unitVelocity() << "\n"; XML << magnet::xml::endtag("DataArray"); XML << magnet::xml::endtag("PointData") << magnet::xml::endtag("Piece") << magnet::xml::endtag("UnstructuredGrid") << magnet::xml::endtag("VTKFile") ; } }
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); } }
inline bool SlicedCurvilinear<ScalarParam,dimensionParam,ValueScalarParam>::Locator::locatePoint( const typename SlicedCurvilinear<ScalarParam,dimensionParam,ValueScalarParam>::Point& position, bool traceHint) { /* If traceHint parameter is false or locator is invalid, start searching from scratch: */ if(!traceHint||cantTrace) { /* Start searching from cell whose cell center is closest to query position: */ FindClosestPointFunctor<CellCenter> f(position,ds->maxCellRadius2); ds->cellCenterTree.traverseTreeDirected(f); if(f.getClosestPoint()==0) // Bail out if no cell is close enough return false; /* Go to the found cell: */ Cell::operator=(ds->getCell(f.getClosestPoint()->value)); /* Initialize local cell position: */ for(int i=0;i<dimension;++i) cellPos[i]=Scalar(0.5); /* Now we can trace: */ cantTrace=false; } /* Perform Newton-Raphson iteration until it converges and the current cell contains the query point: */ Scalar maxOut; CellID previousCellID; // Cell ID to detect "thrashing" between cells CellID currentCellID=getCellID(); // Ditto Scalar previousMaxMove=Scalar(0); // Reason we went into the current cell int iteration=0; for(iteration=0;iteration<10;++iteration) { /* Perform Newton-Raphson iteration in the current cell until it converges, or goes really bad: */ while(true) { /* Do one step: */ bool converged=newtonRaphsonStep(position); /* Check for signs of convergence failure: */ maxOut=Scalar(0); for(int i=0;i<dimension;++i) { if(maxOut<-cellPos[i]) maxOut=-cellPos[i]; else if(maxOut<cellPos[i]-Scalar(1)) maxOut=cellPos[i]-Scalar(1); } if(converged||maxOut>Scalar(1)) // Tolerate at most one cell size out (this is somewhat ad-hoc) break; } /* Check if the current cell contains the query position: */ if(maxOut==Scalar(0)) return true; /* Check if this was the first step, and we're way off: */ if(iteration==0&&maxOut>Scalar(5)) { /* We had a tracing failure; just start searching from scratch: */ FindClosestPointFunctor<CellCenter> f(position,ds->maxCellRadius2); ds->cellCenterTree.traverseTreeDirected(f); if(f.getClosestPoint()==0) // Bail out if no cell is close enough { /* At this point, the locator is borked. Better not trace next time: */ cantTrace=true; /* And we're outside the grid, too: */ return false; } /* Go to the found cell: */ Cell::operator=(ds->getCell(f.getClosestPoint()->value)); previousCellID=currentCellID; currentCellID=f.getClosestPoint()->value; previousMaxMove=maxOut; /* Initialize the local cell position: */ for(int i=0;i<dimension;++i) cellPos[i]=Scalar(0.5); /* Start over: */ continue; } /* Otherwise, try moving to a different cell: */ Scalar maxMove=Scalar(0); int moveDim=0; int moveDir=0; for(int i=0;i<dimension;++i) { if(maxMove<-cellPos[i]) { /* Check if we can actually move in this direction: */ if(index[i]>0) { maxMove=-cellPos[i]; moveDim=i; moveDir=-1; } } else if(maxMove<cellPos[i]-Scalar(1)) { /* Check if we can actually move in this direction: */ if(index[i]<ds->numCells[moveDim]-1) { maxMove=cellPos[i]-Scalar(1); moveDim=i; moveDir=1; } } } /* If we can move somewhere, do it: */ if(moveDir==-1) { cellPos[moveDim]+=Scalar(1); --index[moveDim]; baseVertexIndex-=ds->vertexStrides[moveDim]; } else if(moveDir==1) { cellPos[moveDim]-=Scalar(1); ++index[moveDim]; baseVertexIndex+=ds->vertexStrides[moveDim]; } else { /* At this point, the locator is borked. Better not trace next time: */ cantTrace=true; /* We're not in the current cell, and can't move anywhere else -- we're outside the grid: */ return false; } /* Check if we've just moved back into the cell we just came from: */ CellID nextCellID=getCellID(); if(nextCellID==previousCellID&&maxMove<=previousMaxMove) return true; /* Check for thrashing on the next iteration step: */ previousCellID=currentCellID; currentCellID=nextCellID; previousMaxMove=maxMove; } /* Just to be safe, don't trace on the next step: */ cantTrace=true; /* Return true if the final cell contains the query position, with some fudge: */ return maxOut<Scalar(1.0e-4); }