예제 #1
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);

  }
예제 #2
0
  void
  GSOCells::runEvent(Particle& part, const double)
  {    
    Sim->dynamics->updateParticle(part);
    Sim->ptrScheduler->popNextEvent();
    Event iEvent = getEvent(part);

#ifdef DYNAMO_DEBUG 
    if (std::isnan(iEvent._dt))
      M_throw() << "A NAN Interaction collision time has been found";
  
    if (iEvent._dt == std::numeric_limits<float>::infinity())
      M_throw() << "An infinite Interaction (not marked as NONE) collision time has been found\n";
#endif
    
    //Move the system forward to the time of the event
    Sim->systemTime += iEvent._dt;
    Sim->ptrScheduler->stream(iEvent._dt);
    Sim->stream(iEvent._dt);
    ++Sim->eventCount;

    
    Sim->dynamics->updateParticle(part);
    Vector pos = part.getPosition() - cell_origins[part.getID()];
    Sim->BCs->applyBC(pos); //We don't apply the PBC, as 
    
    //dout << "!Particle " << part.getID() << " at " << part.getPosition() / Sim->units.unitLength() << std::endl;
    //dout << "!Cell origin " << cell_origins[part.getID()] / Sim->units.unitLength() << std::endl;
    //dout << "!Normal " << pos.normal() / Sim->units.unitLength() << std::endl;
    //dout << "!Distance " << pos.nrm() / Sim->units.unitLength() << std::endl;
    //dout << "!CellD " << _cellD / Sim->units.unitLength() << std::endl;
    //dout << "!Relative distance " << pos.nrm() / _cellD << std::endl;
    //dout << "!Perp velocity " << (pos.normal() | part.getVelocity()) << std::endl;

    //Now execute the event
    NEventData EDat(Sim->dynamics->runPlaneEvent(part, pos.normal(), 1.0, _cellD));
    //dout << "!Perp velocity post " << (pos.normal() | part.getVelocity()) << std::endl;
    //if (pos.nrm() > _cellD * 1.00000001)
    //  derr << "Particle " << part.getID() << " outside the cell by " << (pos.nrm() - _cellD) / _cellD  << std::endl;
    //if (pos.nrm() < _cellD * 0.99999999)
    //  derr << "Particle " << part.getID() << " inside the cell by " << (pos.nrm() - _cellD) / _cellD  << std::endl;
    
    //Now we're past the event update everything
    Sim->_sigParticleUpdate(EDat);
    Sim->ptrScheduler->fullUpdate(part);
    for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);

  }
예제 #3
0
  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);
  }
예제 #4
0
  void
  LRoughWall::runEvent(Particle& part, const LocalEvent& iEvent) const
  {
    ++Sim->eventCount;

    //Run the collision and catch the data
    NEventData EDat(Sim->dynamics->runRoughWallCollision
		    (part, vNorm, e, et, r));

    Sim->signalParticleUpdate(EDat);

    //Now we're past the event update the scheduler and plugins
    Sim->ptrScheduler->fullUpdate(part);
  
    BOOST_FOREACH(shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
  }
예제 #5
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);
  }
예제 #6
0
  void
  LOscillatingPlate::runEvent(const Particle& part, const LocalEvent& iEvent) const
  {
    ++Sim->eventCount;
  
    //Run the collision and catch the data
    NEventData EDat(Sim->dynamics.getLiouvillean().runOscilatingPlate
		    (part, rw0, nhat, delta, omega0, sigma, mass, 
		     e, timeshift, strongPlate));

    lastdSysTime = Sim->dSysTime;
    lastID = part.getID();

    Sim->signalParticleUpdate(EDat);

    //Now we're past the event update the scheduler and plugins
    //if (strongPlate) 
    //  Sim->ptrScheduler->fullUpdate(part);
    //else
    Sim->ptrScheduler->rebuildList();

    BOOST_FOREACH(shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
  }
예제 #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);
  }
예제 #8
0
  void 
  GWaker::runEvent(const Particle& part, const double dt) const
  {
    GlobalEvent iEvent(getEvent(part));
    iEvent.setdt(dt); //We only trust the schedulers time, as we don't
    //track the motion of the system in Globals
  
#ifdef DYNAMO_DEBUG 
    if (boost::math::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->dSysTime += iEvent.getdt();
    
    Sim->ptrScheduler->stream(iEvent.getdt());
  
    Sim->dynamics.stream(iEvent.getdt());

    Sim->dynamics.getLiouvillean().updateParticle(part);

    //Here is where the particle goes to sleep or wakes
    ++Sim->eventCount;
  
    _neighbors = 0;

    //Add the interaction events
    Sim->ptrScheduler->getParticleNeighbourhood(part, magnet::function::MakeDelegate(this, &GWaker::nblistCallback));
  
    //  if (_neighbors < 10)
    //    {
    iEvent.addTime(Sim->freestreamAcc);      
    Sim->freestreamAcc = 0;

    ParticleEventData EDat(part, Sim->dynamics.getSpecies(part), iEvent.getType());
      
    Vector newVel(Sim->normal_sampler(),Sim->normal_sampler(),Sim->normal_sampler());
    newVel *= _wakeVelocity / newVel.nrm();
      
    const_cast<Particle&>(part).getVelocity() = newVel;
    const_cast<Particle&>(part).setState(Particle::DYNAMIC);
      
    EDat.setDeltaKE(0.5 * EDat.getSpecies().getMass(part.getID())
		    * (part.getVelocity().nrm2() 
		       - EDat.getOldVel().nrm2()));
      
    Sim->signalParticleUpdate(EDat);
      
    BOOST_FOREACH(shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, EDat);
    //    }
    //  else
    //    Sim->freestreamAcc += iEvent.getdt();

    //Now we're past the event, update the scheduler and plugins
    Sim->ptrScheduler->fullUpdate(part);
  }
예제 #9
0
  void 
  SSleep::runEvent() const
  {
    double locdt = 0;

    dt = HUGE_VAL;
    
#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);

    //++Sim->eventCount;

    NEventData SDat;

    typedef std::map<size_t, Vector>::value_type locPair;
    BOOST_FOREACH(const locPair& p, stateChange)
      {
	const Particle& part = Sim->particleList[p.first];
	Sim->dynamics.getLiouvillean().updateParticle(part);
      
#ifdef DYNAMO_DEBUG 
	if (stateChange.find(part.getID()) == stateChange.end())
	  M_throw() << "Running an event for a particle with no state change!";
#endif

	EEventType type = WAKEUP;
	if ((stateChange[part.getID()][0] == 0) 
	    && (stateChange[part.getID()][1] == 0) 
	    && (stateChange[part.getID()][2] == 0))
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = SLEEP;
	    else
	      type = RESLEEP;
	  }
	else
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = CORRECT;
	    else
	      type = WAKEUP;
	  }

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

	switch (type)
	  {
	  case SLEEP:
	    const_cast<Particle&>(part).clearState(Particle::DYNAMIC);
	  case RESLEEP:
	    const_cast<Particle&>(part).getVelocity() = Vector(0,0,0);
	    break;
	  case CORRECT:
	    const_cast<Particle&>(part).getVelocity() += stateChange[part.getID()];
	  case WAKEUP:
	    const_cast<Particle&>(part).setState(Particle::DYNAMIC);
	    break;
	  default:
	    M_throw() << "Bad event type!";
	  }
	  
	EDat.setDeltaKE(0.5 * EDat.getSpecies().getMass(part.getID())
			* (part.getVelocity().nrm2() 
			   - EDat.getOldVel().nrm2()));

	SDat.L1partChanges.push_back(EDat);
      }

    //Must clear the state before calling the signal, otherwise this
    //will erroneously schedule itself again
    stateChange.clear(); 
    Sim->signalParticleUpdate(SDat);

    BOOST_FOREACH(const ParticleEventData& PDat, SDat.L1partChanges)
      Sim->ptrScheduler->fullUpdate(PDat.getParticle());
  
    locdt += Sim->freestreamAcc;

    Sim->freestreamAcc = 0;
  
    BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins)
      Ptr->eventUpdate(*this, SDat, locdt); 
  }
예제 #10
0
파일: sleep.cpp 프로젝트: Bradleydi/DynamO
  void 
  SSleep::runEvent()
  {
    double locdt = 0;

    dt = HUGE_VAL;
    
#ifdef DYNAMO_DEBUG 
    if (std::isnan(locdt))
      M_throw() << "A NAN system event time has been found";
#endif
  
    Sim->systemTime += locdt;
    Sim->ptrScheduler->stream(locdt);
  
    //dynamics must be updated first
    Sim->stream(locdt);

    //++Sim->eventCount;

    NEventData SDat;

    typedef std::map<size_t, Vector>::value_type locPair;
    for (const locPair& p : stateChange)
      {
	Particle& part = Sim->particles[p.first];
	Sim->dynamics->updateParticle(part);
      
#ifdef DYNAMO_DEBUG 
	if (stateChange.find(part.getID()) == stateChange.end())
	  M_throw() << "Running an event for a particle with no state change!";
#endif

	EEventType type = WAKEUP;
	if ((stateChange[part.getID()][0] == 0) 
	    && (stateChange[part.getID()][1] == 0) 
	    && (stateChange[part.getID()][2] == 0))
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = SLEEP;
	    else
	      type = RESLEEP;
	  }
	else
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = CORRECT;
	    else
	      type = WAKEUP;
	  }

	ParticleEventData EDat(part, *Sim->species(part), type);

	switch (type)
	  {
	  case SLEEP:
	    part.clearState(Particle::DYNAMIC);
	  case RESLEEP:
	    part.getVelocity() = Vector{0,0,0};
	    break;
	  case CORRECT:
	    part.getVelocity() += stateChange[part.getID()];
	  case WAKEUP:
	    part.setState(Particle::DYNAMIC);
	    break;
	  default:
	    M_throw() << "Bad event type!";
	  }
	  
	SDat.L1partChanges.push_back(EDat);
      }

    //Must clear the state before calling the signal, otherwise this
    //will erroneously schedule itself again
    stateChange.clear(); 
    Sim->_sigParticleUpdate(SDat);

    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); 
  }
예제 #11
0
파일: sleep.cpp 프로젝트: MarkRunWu/DynamO
  void 
  SSleep::runEvent() const
  {
    double locdt = 0;

    dt = HUGE_VAL;
    
#ifdef DYNAMO_DEBUG 
    if (boost::math::isnan(locdt))
      M_throw() << "A NAN system event time has been found";
#endif
  
    Sim->systemTime += locdt;
    Sim->ptrScheduler->stream(locdt);
  
    //dynamics must be updated first
    Sim->stream(locdt);

    //++Sim->eventCount;

    NEventData SDat;

    typedef std::map<size_t, Vector>::value_type locPair;
    BOOST_FOREACH(const locPair& p, stateChange)
      {
	Particle& part = Sim->particles[p.first];
	Sim->dynamics->updateParticle(part);
      
#ifdef DYNAMO_DEBUG 
	if (stateChange.find(part.getID()) == stateChange.end())
	  M_throw() << "Running an event for a particle with no state change!";
#endif

	EEventType type = WAKEUP;
	if ((stateChange[part.getID()][0] == 0) 
	    && (stateChange[part.getID()][1] == 0) 
	    && (stateChange[part.getID()][2] == 0))
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = SLEEP;
	    else
	      type = RESLEEP;
	  }
	else
	  {
	    if (part.testState(Particle::DYNAMIC)) 
	      type = CORRECT;
	    else
	      type = WAKEUP;
	  }

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

	switch (type)
	  {
	  case SLEEP:
	    part.clearState(Particle::DYNAMIC);
	  case RESLEEP:
	    part.getVelocity() = Vector(0,0,0);
	    break;
	  case CORRECT:
	    part.getVelocity() += stateChange[part.getID()];
	  case WAKEUP:
	    part.setState(Particle::DYNAMIC);
	    break;
	  default:
	    M_throw() << "Bad event type!";
	  }
	  
	EDat.setDeltaKE(0.5 * Sim->species[EDat.getSpeciesID()]->getMass(part.getID())
			* (part.getVelocity().nrm2() 
			   - EDat.getOldVel().nrm2()));

	SDat.L1partChanges.push_back(EDat);
      }