예제 #1
0
    /// 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;
    }
예제 #2
0
파일: wfxListCtrl.cpp 프로젝트: wxtnote/wfc
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;
}
예제 #3
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;
        }
      }
예제 #4
0
파일: wfxListCtrl.cpp 프로젝트: wxtnote/wfc
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;
}
예제 #5
0
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];
	}
}
예제 #6
0
파일: wfxListCtrl.cpp 프로젝트: wxtnote/wfc
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);
}
예제 #7
0
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);
}
예제 #8
0
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);
}
예제 #9
0
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];
	}
}
예제 #10
0
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];
    }
}
예제 #11
0
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];
    }
}
예제 #12
0
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];
    }
}
예제 #13
0
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);
}
예제 #14
0
    /// 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;
    }
예제 #15
0
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];
    }
}
예제 #16
0
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];
    }
}
예제 #17
0
파일: cells.cpp 프로젝트: subratv/DynamO
  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;
  }
예제 #18
0
파일: cells.cpp 프로젝트: subratv/DynamO
 IDRangeList
 GCells::getParticleNeighbours(const Vector& vec) const
 {
   return getParticleNeighbours(getCellID(vec));
 }
예제 #19
0
파일: vtk.cpp 프로젝트: herbsolo/DynamO
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");
	}
    }
예제 #20
0
파일: vtk.cpp 프로젝트: armando-2011/DynamO
  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")
	  ;
      }
  }
예제 #21
0
  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);
	}