Ejemplo n.º 1
0
bool 
dynamo::OverlapFunctions::CubePlane(const Vector& CubeOrigin, 
				    const Vector& CubeDimensions,
				    const Vector& PlaneOrigin, 
				    const Vector& PlaneNormal,
				    const double tol)
{
  Vector  relpos(CubeOrigin - PlaneOrigin);
  
  size_t counter[3] = {0, 0, 0};
  
  while (counter[NDIM-1] < 2)
    {
      Vector  pointpos(relpos);
      
      for (size_t iDim(0); iDim < NDIM; ++iDim)
	pointpos[iDim] += counter[iDim] * CubeDimensions[iDim];

      if ((pointpos | PlaneNormal) < tol) return true;
      
      ++counter[0];

      for (size_t iDim(0); iDim < NDIM-1; ++iDim)
	if (counter[iDim] > 1)
	  {
	    counter[iDim] = 0;
	    ++counter[iDim+1];
	  }
    }

  return false;
}
Ejemplo n.º 2
0
  void
  OPVTK::initialise()
  {
    size_t vecSize = 1;
  
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      {
	binWidth[iDim] *= Sim->dynamics.units().unitLength();
      
	if (binWidth[iDim] > 0.5 * Sim->primaryCellSize[iDim])
	  M_throw() << "Your bin width is too large for the " << iDim 
		    << " dimension";
      
	nBins[iDim] = static_cast<size_t>
	  (Sim->primaryCellSize[iDim] / binWidth[iDim]);
      
	//This is just to ensure the bin width fits an integer number of
	//times into the simulation
	binWidth[iDim] = Sim->primaryCellSize[iDim] / nBins[iDim];
      
	invBinWidth[iDim] = 1.0 / binWidth[iDim];
      
	vecSize *= nBins[iDim];
      }
  
    binVol = binWidth[0] * binWidth[1] * binWidth[2];
  
  
    if (CollisionStats)
      {
	collCounter.clear();
	collCounter.resize(vecSize, 0);
      }
  
    if (fields)
      {      
	mVsquared.resize(vecSize, 0.0);
	SampleCounter.resize(vecSize, 0);
	Momentum.resize(vecSize, Vector (0,0,0));
      
	std::string tmp("< ");
      
	for (size_t iDim(0); iDim < NDIM; ++iDim)
	  tmp += boost::lexical_cast<std::string>(nBins[iDim]) + " ";
      
	dout << "Number of bins " << tmp << ">" << std::endl;
      
	tmp = std::string("< ");
      
	for (size_t iDim(0); iDim < NDIM; ++iDim)
	  tmp +=boost::lexical_cast<std::string>
	    (binWidth[iDim]/Sim->dynamics.units().unitLength()) + " ";
      
	dout << "Bin width " << tmp << ">" << std::endl;  
      } 

    ticker();
  }
Ejemplo n.º 3
0
  GlobalEvent 
  GSOCells::getEvent(const Particle& part) const
  {
#ifdef ISSS_DEBUG
    if (!Sim->dynamics->isUpToDate(part))
      M_throw() << "Particle is not up to date";
#endif

    //This 
    //Sim->dynamics->updateParticle(part);
    //is not required as we compensate for the delay using 
    //Sim->dynamics->getParticleDelay(part)

    Vector CellOrigin;
    size_t ID(part.getID());

    for (size_t iDim(0); iDim < NDIM; ++iDim)
      {
	CellOrigin[iDim] = (ID % cuberootN) * cellDimension[iDim] - 0.5*Sim->primaryCellSize[iDim];
	ID /= cuberootN;
      }

    return GlobalEvent(part,
		       Sim->dynamics->
		       getSquareCellCollision2
		       (part, CellOrigin,
			cellDimension)
		       -Sim->dynamics->getParticleDelay(part),
		       CELL, *this);
  }
Ejemplo n.º 4
0
void 
OPRijVij::process2PED(mapdata& ref, const PairEventData& PDat)
{
  Vector  rijnorm(PDat.rij / PDat.rij.nrm());
  Vector  vijnorm(PDat.vijold / PDat.vijold.nrm());

  double rvdot(rijnorm | vijnorm);

  for (size_t iDim(0); iDim < NDIM; ++iDim)
    {
      ref.rij[iDim].addVal(rijnorm[iDim]);
      ref.vij[iDim].addVal(vijnorm[iDim]);

      size_t id1(static_cast<size_t>((rijnorm[iDim] + 1.0) * 1000));
      size_t id2(static_cast<size_t>(-rvdot * 1000.0));

      ++ref.rijcostheta[iDim].at(id1).first;
      ref.rijcostheta[iDim].at(id1).second += rvdot;

      ++ref.costhetarij[iDim].at(id2).first;
      ref.costhetarij[iDim].at(id2).second += std::fabs(rijnorm[iDim]);


      id1 = static_cast<size_t>((rijnorm[iDim] + 1.0) * 100);
      id2 = static_cast<size_t>(-rvdot * 100.0);

      ++ref.anglemapcount;
      ++ref.anglemap[iDim][id1][id2];
    }
}
Ejemplo n.º 5
0
void
DynGravity::enforceParabola(Particle& part) const
{
    updateParticle(part);
    Vector pos(part.getPosition()), vel(part.getVelocity());
    Sim->BCs->applyBC(pos, vel);

    //Find the dimension that is closest to
    size_t dim = NDIM;
    double time = HUGE_VAL;
    for (size_t iDim(0); iDim < NDIM; ++iDim)
        if (g[iDim] != 0)
        {
            double tmpTime = std::abs(- vel[iDim] / g[iDim]);
            if ((std::abs(tmpTime) < time))
            {
                time = tmpTime;
                dim = iDim;
            }
        }

#ifdef DYNAMO_DEBUG
    if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!";
#endif

    part.getVelocity()[dim] = 0;
}
Ejemplo n.º 6
0
  NEventData 
  DynGravity::enforceParabola(Particle& part) const
  {
    updateParticle(part);

    const Species& species = *Sim->species(part);
    NEventData retval(ParticleEventData(part, species, VIRTUAL));

    Vector pos(part.getPosition()), vel(part.getVelocity());
    Sim->BCs->applyBC(pos, vel);

    //Find the dimension that is closest to 
    size_t dim = NDIM;
    double time = std::numeric_limits<float>::infinity();
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      if (g[iDim] != 0)
	{
	  double tmpTime = std::abs(- vel[iDim] / g[iDim]);
	  if ((std::abs(tmpTime) < time)) 
	    {
	      time = tmpTime;
	      dim = iDim;
	    }
	}

#ifdef DYNAMO_DEBUG
    if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!";
#endif

    part.getVelocity()[dim] = 0;
    return retval;
  }
Ejemplo n.º 7
0
  void
  GSOCells::runEvent(Particle& part, const double) const
  {
    Sim->dynamics->updateParticle(part);

    Vector CellOrigin;
    size_t ID(part.getID());

    for (size_t iDim(0); iDim < NDIM; ++iDim)
      {
	CellOrigin[iDim] = (ID % cuberootN) * cellDimension[iDim] - 0.5*Sim->primaryCellSize[iDim];
	ID /= cuberootN;
      }
  
    //Determine the cell transition direction, its saved
    int cellDirectionInt(Sim->dynamics->
			 getSquareCellCollision3
			 (part, CellOrigin, 
			  cellDimension));

    size_t cellDirection = abs(cellDirectionInt) - 1;

    GlobalEvent iEvent(getEvent(part));

#ifdef DYNAMO_DEBUG 
    if (std::isnan(iEvent.getdt()))
      M_throw() << "A NAN Interaction collision time has been found"
		<< iEvent.stringData(Sim);
  
    if (iEvent.getdt() == HUGE_VAL)
      M_throw() << "An infinite Interaction (not marked as NONE) collision time has been found\n"
		<< iEvent.stringData(Sim);
#endif

    Sim->systemTime += iEvent.getdt();
    
    Sim->ptrScheduler->stream(iEvent.getdt());
  
    Sim->stream(iEvent.getdt());

    Vector vNorm(0,0,0);

    Vector pos(part.getPosition()), vel(part.getVelocity());

    Sim->BCs->applyBC(pos, vel);

    vNorm[cellDirection] = (cellDirectionInt > 0) ? -1 : +1; 
    
    //Run the collision and catch the data
    NEventData EDat(Sim->dynamics->runPlaneEvent(part, vNorm, 1.0, 0.0));

    Sim->_sigParticleUpdate(EDat);

    //Now we're past the event update the scheduler and plugins
    Sim->ptrScheduler->fullUpdate(part);
  
    for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);

  }
Ejemplo n.º 8
0
  void
  OPViscosityE::impulseDelG(const NEventData& ndat) 
  { 
    BOOST_FOREACH(const PairEventData& dat, ndat.L2partChanges)
      for (size_t iDim(0); iDim < NDIM; ++iDim)
	for (size_t jDim(0); jDim < NDIM; ++jDim)
	  delG[iDim][jDim] += dat.particle1_.getDeltaP()[iDim] 
	    * dat.rij[jDim];
  }
Ejemplo n.º 9
0
    /*! \brief Discovers if a cube and a point intersect.
      
      \param CubeOrigin The location of the cube relative to the point.
      \param CubeDimensions The size of the cube sides.
      \return If the point is inside/on the cube.
     */
    inline bool point_cube(const magnet::math::Vector& CubeOrigin, 
			   const magnet::math::Vector& CubeDimensions,
			   const double tol = 0)
    {
      for (size_t iDim(0); iDim < NDIM; ++iDim)
	if (fabs(CubeOrigin[iDim]) > (CubeDimensions[iDim] / 2))
	  return false;
      
      return true;
    }
Ejemplo n.º 10
0
  void 
  OPVACF::accPass()
  {
    ++count;
  
    BOOST_FOREACH(const std::tr1::shared_ptr<Species>& spec, Sim->dynamics.getSpecies())
      BOOST_FOREACH(const size_t& ID, *spec->getRange())
      for (size_t j = 0; j < CorrelatorLength; ++j)
	for (size_t iDim(0); iDim < NDIM; ++iDim)
	  accG2[spec->getID()][j][iDim] +=  G[ID].front()[iDim] * G[ID][j][iDim];
  }
Ejemplo n.º 11
0
PairEventData
DynNewtonian::parallelCubeColl(const IntEvent& event, const double& e, const double&, const EEventType& eType) const
{
    Particle& particle1 = Sim->particles[event.getParticle1ID()];
    Particle& particle2 = Sim->particles[event.getParticle2ID()];

    updateParticlePair(particle1, particle2);

    PairEventData retVal(particle1, particle2,
                         *Sim->species[particle1],
                         *Sim->species[particle2],
                         eType);

    Sim->BCs->applyBC(retVal.rij, retVal.vijold);

    size_t dim(0);

    for (size_t iDim(1); iDim < NDIM; ++iDim)
        if (fabs(retVal.rij[dim]) < fabs(retVal.rij[iDim])) dim = iDim;

    double p1Mass = Sim->species[retVal.particle1_.getSpeciesID()]->getMass(particle1.getID());
    double p2Mass = Sim->species[retVal.particle2_.getSpeciesID()]->getMass(particle2.getID());
    double mu = p1Mass * p2Mass/ (p1Mass + p2Mass);

    Vector collvec(0,0,0);

    if (retVal.rij[dim] < 0)
        collvec[dim] = -1;
    else
        collvec[dim] = 1;

    retVal.rvdot = (retVal.rij | retVal.vijold);

    retVal.dP = collvec * (1.0 + e) * mu * (collvec | retVal.vijold);

    //This function must edit particles so it overrides the const!
    particle1.getVelocity() -= retVal.dP / p1Mass;
    particle2.getVelocity() += retVal.dP / p2Mass;

    retVal.particle1_.setDeltaKE(0.5 * p1Mass * (particle1.getVelocity().nrm2()
                                 - retVal.particle1_.getOldVel().nrm2()));

    retVal.particle2_.setDeltaKE(0.5 * p2Mass * (particle2.getVelocity().nrm2()
                                 - retVal.particle2_.getOldVel().nrm2()));

    return retVal;
}
Ejemplo n.º 12
0
  size_t 
  OPVTK::getCellID(Vector  pos)
  {
    size_t retval(0);
    size_t factor(1);
  
    Sim->dynamics.BCs().applyBC(pos);

    for (size_t iDim(0); iDim < NDIM; ++iDim)
      {
	retval += factor 
	  * static_cast<size_t>((pos[iDim] + 0.5 * Sim->primaryCellSize[iDim]) 
				* invBinWidth[iDim]);
	factor *= nBins[iDim];
      }

    return retval;
  }
Ejemplo n.º 13
0
  void 
  GSOCells::initialise(size_t nID)
  {
    Global::initialise(nID);
  
    cuberootN = (unsigned long)(std::pow(Sim->N(), 1.0/3.0) + 0.5);
  
    if (boost::math::pow<3>(cuberootN) != Sim->N())
      M_throw() << "Cannot use single occupancy cells without a integer cube root of N"
		<< "\nN = " << Sim->N()
		<< "\nN^(1/3) = " << cuberootN;

    for (size_t iDim(0); iDim < NDIM; ++iDim)
      cellDimension[iDim] = Sim->primaryCellSize[iDim] / cuberootN;

    if (std::dynamic_pointer_cast<const DynGravity>(Sim->dynamics))
      dout << "Warning, in order for SingleOccupancyCells to work in gravity\n"
	   << "You must add the ParabolaSentinel Global event." << std::endl;

  }
Ejemplo n.º 14
0
  void 
  OPSCParameter::initialise() 
  {
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      if (Sim->primaryCellSize[iDim] != 1.0) 
	M_throw() << "Cannot use this parameter in a non-cubic box";
  
    maxWaveNumber = lrint(std::pow(Sim->N, 1.0/3.0));

    if (boost::math::pow<3>(maxWaveNumber) != Sim->N)
      M_throw() << "Failed, N does not have an integer cube root!";

    dout << "Max wavelength is "
	 << 1.0 / (maxWaveNumber * Sim->units.unitLength()) << std::endl;

    maxWaveNumber *= 2;

    runningsum.resize(maxWaveNumber + 1, 0);

    ticker();
  }
Ejemplo n.º 15
0
  IDRangeList
  GCells::getParticleNeighbours(const magnet::math::MortonNumber<3>& particle_cell_coords) const
  {
    if (verbose)
      {
	derr 
	  << "Getting neighbours of cell " << particle_cell_coords.toString()
	  << std::endl;
      }

    magnet::math::MortonNumber<3> zero_coords;
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      zero_coords[iDim] = (particle_cell_coords[iDim].getRealValue() + cellCount[iDim] - overlink)
	% cellCount[iDim];
    
    IDRangeList retval;
    //This initial reserve greatly speeds up the later inserts
    retval.getContainer().reserve(32);

    magnet::math::MortonNumber<3> coords(zero_coords);
    for (size_t x(0); x < 2 * overlink + 1; ++x)
      {
	coords[0] = (zero_coords[0].getRealValue() + x) % cellCount[0];
	for (size_t y(0); y < 2 * overlink + 1; ++y)
	  {
	    coords[1] = (zero_coords[1].getRealValue() + y) % cellCount[1];
	    for (size_t z(0); z < 2 * overlink + 1; ++z)
	      {
		coords[2] = (zero_coords[2].getRealValue() + z) % cellCount[2];

		const std::vector<size_t>&  nlist = list[coords.getMortonNum()];
		retval.getContainer().insert(retval.getContainer().end(), nlist.begin(), nlist.end());
	      }
	  }
      }

    return retval;
  }
Ejemplo n.º 16
0
  void 
  OPSCParameter::ticker()
  {
    ++count;

    for (size_t k(0); k <= maxWaveNumber; ++k)
      {
	std::complex<double> sum(0, 0);

	for (const Particle& part : Sim->particles)
	  {
	    double psum(0);
	  
	    for (size_t iDim(0); iDim < NDIM; ++iDim)
	      psum += part.getPosition()[iDim];
	  
	    psum *= 2.0 * M_PI * k;
	    sum += std::complex<double>(std::cos(psum), std::sin(psum));
	  }
      
	runningsum[k] += std::abs(sum);
      }
  }
Ejemplo n.º 17
0
  double 
  DynGravity::getParabolaSentinelTime(const Particle& part) const
  {
#ifdef DYNAMO_DEBUG
    if (!isUpToDate(part))
      M_throw() << "Particle is not up to date";
#endif
  
    if (!part.testState(Particle::DYNAMIC)) return std::numeric_limits<float>::infinity(); //Particle is not dynamic (does not feel gravity)

    Vector pos(part.getPosition()), vel(part.getVelocity());  
    Sim->BCs->applyBC(pos, vel);
  
    //We return the time of the next turning point, per dimension
    double time = std::numeric_limits<float>::infinity();
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      if (g[iDim] != 0)
	{
	  double tmpTime = - vel[iDim] / g[iDim];
	  if ((tmpTime > 0) && (tmpTime < time)) time = tmpTime;
	}
  
    return time;
  }
Ejemplo n.º 18
0
void
OPRijVij::output(magnet::xml::XmlStream &XML)
{
  XML << magnet::xml::tag("RijVijComponents");
  
  typedef std::pair<const mapKey, mapdata> mappair;

  BOOST_FOREACH(const mappair& pair1, rvdotacc)
    {
      XML << magnet::xml::tag("Element")
	  << magnet::xml::attr("Type") 
	  << pair1.first.first
	  << magnet::xml::attr("EventName") 
	  << getName(pair1.first.second, Sim);

      
      for (size_t iDim(0); iDim < NDIM; ++iDim)
	{
	  XML << magnet::xml::tag("Rij")
	      << magnet::xml::attr("dimension")
	      << iDim
	      << magnet::xml::chardata();

	  pair1.second.rij[iDim].outputHistogram(XML, 1.0);

	  XML << magnet::xml::endtag("Rij");
	}

      for (size_t iDim(0); iDim < NDIM; ++iDim)
	{
	  XML << magnet::xml::tag("Vij")
	      << magnet::xml::attr("dimension")
	      << iDim
	      << magnet::xml::chardata();

	  pair1.second.vij[iDim].outputHistogram(XML, 1.0);

	  XML << magnet::xml::endtag("Vij");
	}

      for (size_t iDim(0); iDim < NDIM; ++iDim)
	{
	  XML << magnet::xml::tag("RijVijvsRij")
	      << magnet::xml::attr("dimension")
	      << iDim
	      << magnet::xml::chardata();

	  for (size_t i(0); i < 2000; ++i)
	    XML << ((i - 1000.0) / 1000.0) << " "
		<< pair1.second.rijcostheta[iDim][i].second 
	      / pair1.second.rijcostheta[iDim][i].first
		<< "\n";

	  XML << magnet::xml::endtag("RijVijvsRij");
	}

      for (size_t iDim(0); iDim < NDIM; ++iDim)
	{
	  XML << magnet::xml::tag("RijvsRijVij")
	      << magnet::xml::attr("dimension")
	      << iDim
	      << magnet::xml::chardata();

	  for (size_t i(0); i < 1000; ++i)
	    XML << ( static_cast<double>(i) / -1000.0) << " "
		<< pair1.second.costhetarij[iDim][i].second 
	      / pair1.second.costhetarij[iDim][i].first
		<< "\n";

	  XML << magnet::xml::endtag("RijvsRijVij");
	}

      for (size_t iDim(0); iDim < NDIM; ++iDim)
	{
	  XML << magnet::xml::tag("XijRvdot")
	      << magnet::xml::attr("dimension")
	      << iDim
	      << magnet::xml::chardata();

	  for (size_t i1(0); i1 < 200; ++i1)
	    {	      
	      for (size_t i2(0); i2 < 100; ++i2)
		XML << ( (static_cast<double>(i1) - 100.0) / 100.0) << " "
		    << ( static_cast<double>(i2) / -100.0) << " "
		    << static_cast<double>(pair1.second.anglemap[iDim][i1][i2])
		  / static_cast<double>(pair1.second.anglemapcount)
		    << "\n";

	      XML << "\n";
	    }
	  

	  XML << magnet::xml::endtag("XijRvdot");
	}
      
      XML << magnet::xml::endtag("Element");
    }
Ejemplo n.º 19
0
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");
	}
    }
Ejemplo n.º 20
0
  void 
  OPVTK::output(magnet::xml::XmlStream& XML)
  {
    XML << magnet::xml::tag("VTK")
	<< magnet::xml::attr("ImagesTaken") << imageCounter
	<< 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");


    ////////////SAMPLE COUNTS
    XML << magnet::xml::tag("DataArray")
	<< magnet::xml::attr("type") << "Int32"
	<< magnet::xml::attr("Name") << "Samples per cell"
	<< magnet::xml::attr("format") << "ascii"
	<< magnet::xml::chardata();

    for (size_t id(0); id < SampleCounter.size(); ++id)
      XML << SampleCounter[id];

    XML << "\n" << magnet::xml::endtag("DataArray");

    ////////////Momentum field
    XML << magnet::xml::tag("DataArray")
	<< magnet::xml::attr("type") << "Float32"
	<< magnet::xml::attr("Name") << "Avg Particle Momentum"
	<< magnet::xml::attr("NumberOfComponents") << NDIM   
	<< magnet::xml::attr("format") << "ascii"
	<< magnet::xml::chardata();

    for (size_t id(0); id < Momentum.size(); ++id)
      {
	for (size_t iDim(0); iDim < NDIM; ++iDim)
	  //Nans are not tolerated by paraview
	  if (SampleCounter[id])	  
	    XML << Momentum[id][iDim] 
	      / (SampleCounter[id] * Sim->dynamics.units().unitMomentum());
	  else
	    XML << 0.0;
      }

    XML << "\n" << magnet::xml::endtag("DataArray");
  

    ////////////Energy
    XML << magnet::xml::tag("DataArray")
	<< magnet::xml::attr("type") << "Float32"
	<< magnet::xml::attr("Name") << "Avg Particle Energy"
	<< magnet::xml::attr("format") << "ascii"
	<< magnet::xml::chardata();

    for (size_t id(0); id < SampleCounter.size(); ++id)
      //Nans are not tolerated by paraview
      if (SampleCounter[id])
	XML << mVsquared[id] * 0.5 
	  / (SampleCounter[id] * Sim->dynamics.units().unitEnergy());
      else
	XML << 0.0;

    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")
	<< magnet::xml::endtag("VTK");
  }
Ejemplo n.º 21
0
  void
  CSRingDSMC::initialise(size_t nID)
  {
    ID = nID;
    dt = tstep;

    n12 = 0;
    n13 = 0;

    factor12 = range1->size()
      * diameter * M_PI * chi12 * tstep 
      / Sim->dynamics.getSimVolume();
  
    factor13 = range1->size()
      * diameter * M_PI * chi13 * tstep 
      / Sim->dynamics.getSimVolume();
  
    if (maxprob12 == 0.0)
      { 
	boost::variate_generator
	  <dynamo::baseRNG&, boost::uniform_int<size_t> >
	  id1sampler(Sim->ranGenerator, 
		     boost::uniform_int<size_t>(0, (range1->size()/2) - 1));
      
	//Just do some quick testing to get an estimate
	for (size_t n = 0; n < 1000; ++n)
	  {
	    size_t pairID(id1sampler());
	    const Particle& p1(Sim->particleList[*(range1->begin() + 2 * pairID)]);
	    const Particle& p2(Sim->particleList[*(range1->begin() + 2 * pairID + 1)]);
	  
	    Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2);
	  
	    CPDData PDat;
	  
	    for (size_t iDim(0); iDim < NDIM; ++iDim)
	      PDat.rij[iDim] = Sim->normal_sampler();
	  
	    PDat.rij *= diameter / PDat.rij.nrm();
	  
	    Sim->dynamics.getLiouvillean().DSMCSpheresTest(p1, p2, maxprob12, 
							   factor12, PDat);
	  }
      }

    if (maxprob13 == 0.0)
      { 
	boost::variate_generator
	  <dynamo::baseRNG&, boost::uniform_int<size_t> >
	  id1sampler(Sim->ranGenerator, 
		     boost::uniform_int<size_t>(0, range1->size() - 1));
      
	//Just do some quick testing to get an estimate
	for (size_t n = 0; n < 1000; ++n)
	  {
	    const Particle& p1(Sim->particleList[*(range1->begin() + id1sampler())]);

	    size_t secondID(id1sampler());

	    while ((secondID == p1.getID())
		   || ((secondID % 2) 
		       ? ((secondID-1) == p1.getID())
		       : ((secondID+1) == p1.getID())))
	      secondID = id1sampler();

	    const Particle& p2(Sim->particleList[*(range1->begin() + secondID)]);
	  
	    Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2);
	  
	    CPDData PDat;
	  
	    for (size_t iDim(0); iDim < NDIM; ++iDim)
	      PDat.rij[iDim] = Sim->normal_sampler();
	  
	    PDat.rij *= diameter / PDat.rij.nrm();
	  
	    Sim->dynamics.getLiouvillean().DSMCSpheresTest(p1, p2, maxprob13, 
							   factor13, PDat);
	  }
      }

    if (maxprob12 > 0.5)
      derr << "MaxProbability12 is " << maxprob12
	   << "\nNpairs12 per step is " << range1->size() * maxprob12 << std::endl;
    else
      dout << "MaxProbability12 is " << maxprob12
	   << "\nNpairs12 per step is " << range1->size() * maxprob12 << std::endl;

    if (maxprob13 > 0.5)
      derr << "MaxProbability13 is " << maxprob13
	   << "\nNpairs13 per step is " << range1->size() * maxprob13 << std::endl;
    else
      dout << "MaxProbability13 is " << maxprob13
	   << "\nNpairs13 per step is " << range1->size() * maxprob13 << std::endl;
  
    if (range1->size() * maxprob12 < 2.0)
      derr << "The 12 probability is low" << std::endl;

    if (range1->size() * maxprob13 < 2.0)
      derr << "The 13 probability is low" << std::endl;
  }
Ejemplo n.º 22
0
  void 
  CSRingDSMC::runEvent() const
  {
    double locdt = dt;
  
#ifdef DYNAMO_DEBUG 
    if (boost::math::isnan(locdt))
      M_throw() << "A NAN system event time has been found";
#endif
    
    Sim->dSysTime += locdt;
    
    Sim->ptrScheduler->stream(locdt);
  
    //dynamics must be updated first
    Sim->dynamics.stream(locdt);

    dt = tstep;

    locdt += Sim->freestreamAcc;
    Sim->freestreamAcc = 0;

    BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(*this, NEventData(), locdt);

    //////////////////// T(1,2) operator
    double intPart;
    double fracpart = std::modf(maxprob12 * range1->size(), &intPart);
 
    size_t nmax = static_cast<size_t>(intPart) + (Sim->uniform_sampler() < fracpart);
  
    {
      boost::variate_generator
	<dynamo::baseRNG&, boost::uniform_int<size_t> >
	id1sampler(Sim->ranGenerator, 
		   boost::uniform_int<size_t>(0, (range1->size()/2) - 1));
    
      for (size_t n = 0; n < nmax; ++n)
	{
	  size_t pairID(id1sampler());
	  const Particle& p1(Sim->particleList[*(range1->begin() + 2 * pairID)]);
	  const Particle& p2(Sim->particleList[*(range1->begin() + 2 * pairID + 1)]);
	
	  Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2);
	
	  CPDData PDat;
	
	  for (size_t iDim(0); iDim < NDIM; ++iDim)
	    PDat.rij[iDim] = Sim->normal_sampler();
	
	  PDat.rij *= diameter / PDat.rij.nrm();
	
	  if (Sim->dynamics.getLiouvillean().DSMCSpheresTest
	      (p1, p2, maxprob12, factor12, PDat))
	    {
	      ++Sim->eventCount;
	      ++n12;

	      const PairEventData
		SDat(Sim->dynamics.getLiouvillean().DSMCSpheresRun(p1, p2, e, PDat));
	    
	      Sim->signalParticleUpdate(SDat);
	    
	      Sim->ptrScheduler->fullUpdate(p1, p2);
	    
	      BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins)
		Ptr->eventUpdate(*this, SDat, 0.0);
	    }
	}
    }

    //////////////////// T(1,3) operator
    {
      fracpart = std::modf(maxprob13 * range1->size(), &intPart);
    
      nmax = static_cast<size_t>(intPart) + (Sim->uniform_sampler() < fracpart);
    
      boost::variate_generator
	<dynamo::baseRNG&, boost::uniform_int<size_t> >
	id1sampler(Sim->ranGenerator, 
		   boost::uniform_int<size_t>(0, range1->size() - 1));
    
      for (size_t n = 0; n < nmax; ++n)
	{
	  const Particle& p1(Sim->particleList[*(range1->begin() + id1sampler())]);
	
	  size_t secondID(id1sampler());
	
	  while ((secondID == p1.getID())
		 || ((secondID % 2) 
		     ? ((secondID-1) == p1.getID())
		     : ((secondID+1) == p1.getID())))
	    secondID = id1sampler();
	
	  const Particle& p2(Sim->particleList[*(range1->begin() + secondID)]);
	
	  Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2);
	
	  CPDData PDat;
	
	  for (size_t iDim(0); iDim < NDIM; ++iDim)
	    PDat.rij[iDim] = Sim->normal_sampler();
	
	  PDat.rij *= diameter / PDat.rij.nrm();
	
	  if (Sim->dynamics.getLiouvillean().DSMCSpheresTest
	      (p1, p2, maxprob13, factor13, PDat))
	    {
	      ++Sim->eventCount;
	      ++n13;

	      const PairEventData
		SDat(Sim->dynamics.getLiouvillean().DSMCSpheresRun(p1, p2, e, PDat));

	      Sim->signalParticleUpdate(SDat);
	    
	      Sim->ptrScheduler->fullUpdate(p1, p2);
	    
	      BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins)
		Ptr->eventUpdate(*this, SDat, 0.0);
	    }
	}
    }
  }