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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }