Exemple #1
0
  NEventData
  SysRescale::runEvent()
  {
    ++Sim->eventCount;
    const double currentkT(Sim->dynamics->getkT() / Sim->units.unitEnergy());

    dout << "Rescaling kT " << currentkT 
	 << " To " << _kT / Sim->units.unitEnergy() <<  std::endl;

    NEventData SDat;
    for (const shared_ptr<Species>& species : Sim->species)
      for (const unsigned long& partID : *species->getRange())
	SDat.L1partChanges.push_back(ParticleEventData(Sim->particles[partID], *species, RESCALE));
    
    Sim->dynamics->updateAllParticles();
    Sim->dynamics->rescaleSystemKineticEnergy(_kT / currentkT);
    
    //We must set the centre of mass velocity back to zero (assuming
    //this is the target velocity), otherwise it will drift with the
    //rescaling process
    Sim->setCOMVelocity();
    RealTime += (Sim->systemTime - LastTime) / std::exp(0.5 * scaleFactor);
    LastTime = Sim->systemTime;
    scaleFactor += std::log(currentkT);
    dt = _timestep;
    return SDat;
  }
Exemple #2
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;
  }
  void 
  GVolumetricPotential::runEvent(Particle& part, const double dt)  {
    //Despite the system not being streamed this must be done.  This is
    //because the scheduler and all interactions, locals and systems
    //expect the particle to be up to date.
    Sim->dynamics->updateParticle(part);

    const size_t oldCellIndex = _cellData.getCellID(part.getID());
    const int cellDirectionInt(Sim->dynamics->getSquareCellCollision3(part, calcPosition(oldCellIndex, part), _cellDimension));
    const 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 when recalculating this global"
		<< iEvent.stringData(Sim);
#endif

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

    //Calculate which cell the particle might end up in
    const auto oldCellCoord = _ordering.toCoord(oldCellIndex);
    auto newCellCoord = oldCellCoord;
    newCellCoord[cellDirection] += _ordering.getDimensions()[cellDirection] + ((cellDirectionInt > 0) ? 1 : -1);
    newCellCoord[cellDirection] %= _ordering.getDimensions()[cellDirection];
    const size_t newCellIndex = _ordering.toIndex(newCellCoord);


    Vector vNorm{0,0,0};
    vNorm[cellDirection] = (cellDirectionInt > 0) ? -1 : 1;

    NEventData EDat;

    //Run the collision and catch the data
    Sim->dynamics->updateParticle(part);    
    Vector pos(part.getPosition()), vel(part.getVelocity());
    Sim->BCs->applyBC(pos, vel);
    double potEnergyChange = 0.5 * (double(_volumeData[newCellIndex]) - double(_volumeData[oldCellIndex]));
    double arg =  vel[cellDirection] * vel[cellDirection] - 2 * potEnergyChange / Sim->species(part)->getMass(part);
    if (arg > 0)
      {
	EDat = ParticleEventData(part, *Sim->species(part), WALL);
	part.getVelocity()[cellDirection] *= std::sqrt(arg) / std::abs(part.getVelocity()[cellDirection]);
	_cellData.moveTo(oldCellIndex, newCellIndex, part.getID());
      }
    else
      EDat = Sim->dynamics->runPlaneEvent(part, vNorm, 1.0, 0.0);
    
    //Now we're past the event update the scheduler and plugins
    Sim->_sigParticleUpdate(EDat);
    Sim->ptrScheduler->fullUpdate(part);  
    for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
  }
Exemple #4
0
  void 
  SysRescale::runEvent() const
  {
    double locdt = dt;

    Sim->systemTime += locdt;
  
    Sim->ptrScheduler->stream(locdt);
  
    //dynamics must be updated first
    Sim->stream(locdt);
  
    ++Sim->eventCount;
    
    double currentkT(Sim->dynamics->getkT()
		     / Sim->units.unitEnergy());

    dout << "Rescaling kT " << currentkT 
	 << " To " << _kT / Sim->units.unitEnergy() <<  std::endl;

    NEventData SDat;

    for (const shared_ptr<Species>& species : Sim->species)
      for (const unsigned long& partID : *species->getRange())
      SDat.L1partChanges.push_back(ParticleEventData(Sim->particles[partID], *species, RESCALE));

    Sim->dynamics->updateAllParticles();
    Sim->dynamics->rescaleSystemKineticEnergy(_kT / currentkT);

    RealTime += (Sim->systemTime - LastTime) / std::exp(0.5 * scaleFactor);
    
    LastTime = Sim->systemTime;

    scaleFactor += std::log(currentkT);

    (*Sim->_sigParticleUpdate)(SDat);
  
    //Only 1ParticleEvents occur
    for (const ParticleEventData& PDat : SDat.L1partChanges)
      Sim->ptrScheduler->fullUpdate(Sim->particles[PDat.getParticleID()]);
  
    for (shared_ptr<OutputPlugin>& Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(*this, SDat, locdt); 

    for (shared_ptr<OutputPlugin>& Ptr : Sim->outputPlugins)
      Ptr->temperatureRescale(1.0/currentkT);

    dt = _timestep;
  
    Sim->ptrScheduler->rebuildList();
  }
  void 
  GParabolaSentinel::runEvent(const Particle& part, const double) const
  {
    Sim->dynamics.getLiouvillean().updateParticle(part);

    GlobalEvent iEvent(getEvent(part));

    if (iEvent.getdt() == HUGE_VAL)
      {
	//We've numerically drifted slightly passed the parabola, so
	//just reschedule the particles events, no need to enforce anything
	Sim->ptrScheduler->fullUpdate(part);
	return;
      }

#ifdef DYNAMO_DEBUG 
    if (boost::math::isnan(iEvent.getdt()))
      M_throw() << "A NAN Interaction collision time has been found when recalculating this global"
		<< iEvent.stringData(Sim);
#endif

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

    Sim->dynamics.getLiouvillean().enforceParabola(part);
  
#ifdef DYNAMO_DEBUG
    iEvent.addTime(Sim->freestreamAcc);
  
    Sim->freestreamAcc = 0;

    NEventData EDat(ParticleEventData(part, Sim->dynamics.getSpecies(part), VIRTUAL));

    Sim->signalParticleUpdate(EDat);

    BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
#else
    Sim->freestreamAcc += iEvent.getdt();
#endif

    Sim->ptrScheduler->fullUpdate(part);
  }
Exemple #6
0
  void 
  GPBCSentinel::runEvent(Particle& part, const double dt) const
  {
    GlobalEvent iEvent(part, dt, VIRTUAL, *this);

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

    NEventData EDat(ParticleEventData(part, *Sim->species[part], VIRTUAL));

    Sim->signalParticleUpdate(EDat);

    BOOST_FOREACH(shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);

    Sim->ptrScheduler->fullUpdate(part);
  }
Exemple #7
0
  void 
  GFrancesco::runEvent(Particle& part, const double)
  {
    const double dt = _eventTimes[part] - Sim->systemTime;
    _eventTimes[part] = HUGE_VAL;
    Event iEvent(part, dt, GLOBAL, GAUSSIAN, ID);
    
    Sim->systemTime += dt;
    Sim->ptrScheduler->stream(dt);
    Sim->stream(dt);

    Sim->dynamics->updateParticle(part);
    NEventData EDat(ParticleEventData(part, *Sim->species(part), GAUSSIAN));
    
    //Kill the rotational motion
    Sim->dynamics->getRotData(part).angularVelocity = Vector{0,0,0};
    //Reassign the linear motion
    part.getVelocity() = _vel * (Sim->dynamics->getRotData(part).orientation * magnet::math::Quaternion::initialDirector());

    Sim->_sigParticleUpdate(EDat);
    for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
    Sim->ptrScheduler->fullUpdate(part);
  }