void ILines::runEvent(Particle& p1, Particle& p2, const IntEvent& iEvent) { PairEventData retval; switch (iEvent.getType()) { case CORE: { ++Sim->eventCount; //We have a line interaction! Run it double e = (_e->getProperty(p1.getID()) + _e->getProperty(p2.getID())) * 0.5; double l = (_length->getProperty(p1.getID()) + _length->getProperty(p2.getID())) * 0.5; retval = Sim->dynamics->runLineLineCollision(iEvent, e, l); break; } case NBHOOD_IN: { ICapture::add(p1, p2); retval = PairEventData(p1, p2, *Sim->species[p1], *Sim->species[p2], VIRTUAL); iEvent.setType(VIRTUAL); break; } case NBHOOD_OUT: { ICapture::remove(p1, p2); retval = PairEventData(p1, p2, *Sim->species[p1], *Sim->species[p2], VIRTUAL); iEvent.setType(VIRTUAL); break; } case VIRTUAL: { retval = PairEventData(p1, p2, *Sim->species[p1], *Sim->species[p2], VIRTUAL); iEvent.setType(VIRTUAL); break; } default: M_throw() << "Unknown collision type"; } Sim->_sigParticleUpdate(retval); Sim->ptrScheduler->fullUpdate(p1, p2); for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins) Ptr->eventUpdate(iEvent, retval); }
PairEventData ILines::runEvent(Particle& p1, Particle& p2, const IntEvent& iEvent) { PairEventData retval; switch (iEvent.getType()) { case CORE: { ++Sim->eventCount; //We have a line interaction! Run it const double e = _e->getProperty(p1, p2); const double l = _length->getProperty(p1, p2); retval = Sim->dynamics->runLineLineCollision(iEvent, e, l); break; } case NBHOOD_IN: { ICapture::add(p1, p2); retval = PairEventData(p1, p2, *Sim->species(p1), *Sim->species(p2), VIRTUAL); iEvent.setType(VIRTUAL); break; } case NBHOOD_OUT: { ICapture::remove(p1, p2); retval = PairEventData(p1, p2, *Sim->species(p1), *Sim->species(p2), VIRTUAL); iEvent.setType(VIRTUAL); break; } case VIRTUAL: { retval = PairEventData(p1, p2, *Sim->species(p1), *Sim->species(p2), VIRTUAL); iEvent.setType(VIRTUAL); break; } default: M_throw() << "Unknown collision type"; } return retval; }
PairEventData DynNewtonianMCCMap::SphereWellEvent(const IntEvent& event, const double& deltaKE, const double &, size_t newstate) 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), event.getType()); Sim->BCs->applyBC(retVal.rij,retVal.vijold); retVal.rvdot = (retVal.rij | retVal.vijold); double p1Mass = Sim->species[retVal.particle1_.getSpeciesID()]->getMass(particle1); double p2Mass = Sim->species[retVal.particle2_.getSpeciesID()]->getMass(particle2); double mu = p1Mass * p2Mass / (p1Mass + p2Mass); double R2 = retVal.rij.nrm2(); //Calculate the deformed energy change of the system (the one used in the dynamics) double MCDeltaKE = deltaKE; //If there are entries for the current and possible future energy, then take them into account detail::CaptureMap contact_map = *_interaction; //Add the current bias potential MCDeltaKE += W(contact_map) * Sim->ensemble->getEnsembleVals()[2]; //subtract the possible bias potential in the new state contact_map[detail::CaptureMap::key_type(particle1, particle2)] = newstate; MCDeltaKE -= W(contact_map) * Sim->ensemble->getEnsembleVals()[2]; //Test if the deformed energy change allows a capture event to occur double sqrtArg = retVal.rvdot * retVal.rvdot + 2.0 * R2 * MCDeltaKE / mu; if ((MCDeltaKE < 0) && (sqrtArg < 0)) { event.setType(BOUNCE); retVal.setType(BOUNCE); retVal.impulse = retVal.rij * 2.0 * mu * retVal.rvdot / R2; } else { retVal.particle1_.setDeltaU(-0.5 * deltaKE); retVal.particle2_.setDeltaU(-0.5 * deltaKE); if (retVal.rvdot < 0) retVal.impulse = retVal.rij * (2.0 * MCDeltaKE / (std::sqrt(sqrtArg) - retVal.rvdot)); else retVal.impulse = retVal.rij * (-2.0 * MCDeltaKE / (retVal.rvdot + std::sqrt(sqrtArg))); } #ifdef DYNAMO_DEBUG if (std::isnan(retVal.impulse[0])) M_throw() << "A nan dp has ocurred"; #endif //This function must edit particles so it overrides the const! particle1.getVelocity() -= retVal.impulse / p1Mass; particle2.getVelocity() += retVal.impulse / p2Mass; return retVal; }
PairEventData DynNewtonianMC::SphereWellEvent(const IntEvent& event, const double& deltaKE, const double &, size_t) 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], event.getType()); Sim->BCs->applyBC(retVal.rij,retVal.vijold); retVal.rvdot = (retVal.rij | retVal.vijold); 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); double R2 = retVal.rij.nrm2(); double CurrentE = Sim->getOutputPlugin<OPMisc>()->getConfigurationalU(); //Calculate the deformed energy change of the system (the one used in the dynamics) double MCDeltaKE = deltaKE; //If there are entries for the current and possible future energy, then take them into account MCDeltaKE += W(CurrentE) * Sim->ensemble->getEnsembleVals()[2]; MCDeltaKE -= W(CurrentE - deltaKE) * Sim->ensemble->getEnsembleVals()[2]; //Test if the deformed energy change allows a capture event to occur double sqrtArg = retVal.rvdot * retVal.rvdot + 2.0 * R2 * MCDeltaKE / mu; if ((MCDeltaKE < 0) && (sqrtArg < 0)) { event.setType(BOUNCE); retVal.setType(BOUNCE); retVal.impulse = retVal.rij * 2.0 * mu * retVal.rvdot / R2; } else { retVal.particle1_.setDeltaU(-0.5 * deltaKE); retVal.particle2_.setDeltaU(-0.5 * deltaKE); if (retVal.rvdot < 0) retVal.impulse = retVal.rij * (2.0 * MCDeltaKE / (std::sqrt(sqrtArg) - retVal.rvdot)); else retVal.impulse = retVal.rij * (-2.0 * MCDeltaKE / (retVal.rvdot + std::sqrt(sqrtArg))); } #ifdef DYNAMO_DEBUG if (boost::math::isnan(retVal.impulse[0])) M_throw() << "A nan dp has ocurred"; #endif //This function must edit particles so it overrides the const! particle1.getVelocity() -= retVal.impulse / p1Mass; particle2.getVelocity() += retVal.impulse / p2Mass; return retVal; }
PairEventData DynCompression::SphereWellEvent(const IntEvent& event, const double& deltaKE, const double& d2, size_t) 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], event.getType()); Sim->BCs->applyBC(retVal.rij, retVal.vijold); double p1Mass = Sim->species[retVal.particle1_.getSpeciesID()]->getMass(particle1.getID()); double p2Mass = Sim->species[retVal.particle2_.getSpeciesID()]->getMass(particle2.getID()); double mu = 1.0 / ((1.0 / p1Mass) + (1.0 / p2Mass)); bool infinite_masses = (p1Mass == HUGE_VAL) && (p2Mass == HUGE_VAL); if (infinite_masses) { p1Mass = p2Mass = 1; mu = 0.5; } Vector urij = retVal.rij / retVal.rij.nrm(); retVal.rvdot = (urij | retVal.vijold); double sqrtArg = std::pow(retVal.rvdot - growthRate * sqrt(d2), 2) + (2.0 * deltaKE / mu); if ((deltaKE < 0) && (sqrtArg < 0)) { event.setType(BOUNCE); retVal.setType(BOUNCE); retVal.impulse = urij * (2.0 * mu * (retVal.rvdot - growthRate * sqrt(d2))); } else if (deltaKE==0) retVal.impulse = Vector(0,0,0); else { retVal.particle1_.setDeltaU(-0.5 * deltaKE); retVal.particle2_.setDeltaU(-0.5 * deltaKE); if (retVal.rvdot < 0) retVal.impulse = urij * (2.0 * deltaKE / (growthRate * sqrt(d2) + std::sqrt(sqrtArg) - retVal.rvdot )); else retVal.impulse = urij * (2.0 * deltaKE / (growthRate * sqrt(d2) - std::sqrt(sqrtArg) - retVal.rvdot )); ; } retVal.rvdot *= retVal.rij.nrm(); #ifdef DYNAMO_DEBUG if (std::isnan(retVal.impulse[0])) M_throw() << "A nan dp has ocurred" << "\ndeltaKE = " << deltaKE << "\ngrowthRate = " << growthRate << "\nd2 = " << d2 << "\nsqrtArg = " << sqrtArg << "\nrvdot = " << retVal.rvdot << "\nArg " << (growthRate * sqrt(d2) - std::sqrt(sqrtArg) - retVal.rvdot) ; #endif particle1.getVelocity() -= retVal.impulse / p1Mass; particle2.getVelocity() += retVal.impulse / p2Mass; retVal.impulse *= !infinite_masses; return retVal; }