IntEvent IHardSphere::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics->isUpToDate(p1)) M_throw() << "Particle 1 is not up to date: ID1=" << p1.getID() << ", ID2=" << p2.getID() << ", delay1=" << Sim->dynamics->getParticleDelay(p1); if (!Sim->dynamics->isUpToDate(p2)) M_throw() << "Particle 2 is not up to date: ID1=" << p1.getID() << ", ID2=" << p2.getID() << ", delay2=" << Sim->dynamics->getParticleDelay(p2); if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, d); if (Sim->dynamics->sphereOverlap(p1, p2, d)) ++_overlapped_tests; if (dt != HUGE_VAL) return IntEvent(p1, p2, dt, CORE, *this); return IntEvent(p1,p2,HUGE_VAL, NONE, *this); }
IntEvent IDumbbells::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif CPDData colldat(*Sim, p1, p2); double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; double l = (_length->getProperty(p1.getID()) + _length->getProperty(p2.getID())) * 0.5; if (isCaptured(p1, p2)) { //Run this to determine when the spheres no longer intersect Sim->dynamics.getLiouvillean() .SphereSphereOutRoot(colldat, (l + d) * (l + d), p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC)); //colldat.dt has the upper limit of the line collision time //Lower limit is right now //Test for a line collision //Upper limit can be HUGE_VAL! if (Sim->dynamics.getLiouvillean().getOffCenterSphereOffCenterSphereCollision (colldat, l, d, p1, p2)) return IntEvent(p1, p2, colldat.dt, CORE, *this); return IntEvent(p1, p2, colldat.dt, WELL_OUT, *this); } if (Sim->dynamics.getLiouvillean() .SphereSphereInRoot(colldat, (l + d) * (l + d), p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) return IntEvent(p1, p2, colldat.dt, WELL_IN, *this); return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent ISoftCore::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; if (isCaptured(p1, p2)) { double dt = Sim->dynamics.getLiouvillean().SphereSphereOutRoot(p1, p2, d); if (dt != HUGE_VAL) return IntEvent(p1, p2, dt, WELL_OUT, *this); } else { double dt = Sim->dynamics.getLiouvillean() .SphereSphereInRoot(p1, p2, d); if (dt != HUGE_VAL) { #ifdef DYNAMO_OverlapTesting if (Sim->dynamics.getLiouvillean().sphereOverlap(p1, p2, d)) M_throw() << "Overlapping particles found" << ", particle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << Sim->dynamics.getLiouvillean() .sphereOverlap(p1, p2, d) / Sim->dynamics.units().unitLength(); #endif return IntEvent(p1, p2, dt, WELL_IN, *this); } } return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent ILines::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics->isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics->isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif double l = (_length->getProperty(p1.getID()) + _length->getProperty(p2.getID())) * 0.5; if (isCaptured(p1, p2)) { //Run this to determine when the spheres no longer intersect double dt = Sim->dynamics->SphereSphereOutRoot(p1, p2, l); std::pair<bool, double> colltime = Sim->dynamics->getLineLineCollision(l, p1, p2, dt); if (colltime.second == HUGE_VAL) return IntEvent(p1, p2, dt, NBHOOD_OUT, *this); //Something happens in the time interval if (colltime.first) //Its a collision! return IntEvent(p1, p2, colltime.second, CORE, *this); else //Its a virtual event, we need to recalculate in a bit return IntEvent(p1, p2, colltime.second, VIRTUAL, *this); } else { double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, l); if (dt != HUGE_VAL) return IntEvent(p1, p2, dt, NBHOOD_IN, *this); } return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent ISoftCore::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif CPDData colldat(*Sim, p1, p2); double d2 = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; d2 *= d2; if (isCaptured(p1, p2)) { if (Sim->dynamics.getLiouvillean() .SphereSphereOutRoot(colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) return IntEvent(p1, p2, colldat.dt, WELL_OUT, *this); } else if (Sim->dynamics.getLiouvillean() .SphereSphereInRoot(colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) { #ifdef DYNAMO_OverlapTesting if (Sim->dynamics.getLiouvillean().sphereOverlap(colldat,d2)) M_throw() << "Overlapping cores (but not registered as captured) particles found in soft core" << "\nparticle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - sqrt(d2)) / Sim->dynamics.units().unitLength(); #endif return IntEvent(p1, p2, colldat.dt, WELL_IN, *this); } return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent ISquareWell::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics->isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics->isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; double l = (_lambda->getProperty(p1.getID()) + _lambda->getProperty(p2.getID())) * 0.5; IntEvent retval(p1, p2, HUGE_VAL, NONE, *this); if (isCaptured(p1, p2)) { double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, d); if (dt != HUGE_VAL) retval = IntEvent(p1, p2, dt, CORE, *this); dt = Sim->dynamics->SphereSphereOutRoot(p1, p2, l * d); if (retval.getdt() > dt) retval = IntEvent(p1, p2, dt, STEP_OUT, *this); } else { double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, l * d); if (dt != HUGE_VAL) retval = IntEvent(p1, p2, dt, STEP_IN, *this); } return retval; }
IntEvent IRotatedParallelCubes::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; #endif #ifdef DYNAMO_DEBUG if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif CPDData colldat(*Sim, p1, p2); colldat.rij = Rotation * Vector(colldat.rij); colldat.vij = Rotation * Vector(colldat.vij); double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; if (Sim->dynamics.getLiouvillean().CubeCubeInRoot(colldat, d)) { #ifdef DYNAMO_OverlapTesting if (Sim->dynamics.getLiouvillean().cubeOverlap(colldat, d)) M_throw() << "Overlapping particles found" << ", particle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - d) / Sim->dynamics.units().unitLength(); #endif return IntEvent(p1, p2, colldat.dt, CORE, *this); } return IntEvent(p1,p2,HUGE_VAL, NONE, *this); }
IntEvent ISWSequence::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics->isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics->isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; double l = (_lambda->getProperty(p1.getID()) + _lambda->getProperty(p2.getID())) * 0.5; const double pairenergy = alphabet[sequence[p1.getID() % sequence.size()]][sequence[p2.getID() % sequence.size()]] * _unitEnergy->getMaxValue(); /* Check if there is no well here at all, and just use a hard core interaction */ if (pairenergy == 0) { double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, d); if (dt != HUGE_VAL) return IntEvent(p1, p2, dt, CORE, *this); else return IntEvent(p1, p2, HUGE_VAL, NONE, *this); } if (isCaptured(p1, p2)) { IntEvent retval(p1, p2, HUGE_VAL, NONE, *this); double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, d); if (dt != HUGE_VAL) retval = IntEvent(p1, p2, dt, CORE, *this); dt = Sim->dynamics->SphereSphereOutRoot(p1, p2, l * d); if (retval.getdt() > dt) retval = IntEvent(p1, p2, dt, STEP_OUT, *this); return retval; } else { double dt = Sim->dynamics->SphereSphereInRoot(p1, p2, l * d); if (dt != HUGE_VAL) return IntEvent(p1, p2, dt, STEP_IN, *this); } return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent ISWSequence::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif #ifdef DYNAMO_CollDebug std::cerr << "\n Testing p1 = " << p1.getID() << " p2 = " << p2.getID(); #endif CPDData colldat(*Sim, p1, p2); double d = (_diameter->getProperty(p1.getID()) + _diameter->getProperty(p2.getID())) * 0.5; double d2 = d * d; double l = (_lambda->getProperty(p1.getID()) + _lambda->getProperty(p2.getID())) * 0.5; double ld2 = d * l * d * l; IntEvent retval(p1, p2, HUGE_VAL, NONE, *this); if (isCaptured(p1, p2)) { if (Sim->dynamics.getLiouvillean() .SphereSphereInRoot(colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) { #ifdef DYNAMO_OverlapTesting //Check that there is no overlap if (Sim->dynamics.getLiouvillean().sphereOverlap(colldat, d2)) M_throw() << "Overlapping particles found" << ", particle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - sqrt(d2))/Sim->dynamics.units().unitLength(); #endif retval = IntEvent(p1, p2, colldat.dt, CORE, *this); } if (Sim->dynamics.getLiouvillean() .SphereSphereOutRoot(colldat, ld2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) if (retval.getdt() > colldat.dt) retval = IntEvent(p1, p2, colldat.dt, WELL_OUT, *this); } else if (Sim->dynamics.getLiouvillean() .SphereSphereInRoot(colldat, ld2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) { #ifdef DYNAMO_OverlapTesting if (Sim->dynamics.getLiouvillean().sphereOverlap(colldat,ld2)) { if (Sim->dynamics.getLiouvillean().sphereOverlap(colldat,d2)) M_throw() << "Overlapping cores (but not registerd as captured) particles found in square well" << "\nparticle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - sqrt(d2))/Sim->dynamics.units().unitLength(); else M_throw() << "Overlapping wells (but not registerd as captured) particles found" << "\nparticle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - sqrt(ld2))/Sim->dynamics.units().unitLength(); } #endif retval = IntEvent(p1, p2, colldat.dt, WELL_IN, *this); } return retval; }
IntEvent INull::getEvent(const Particle &p1, const Particle &p2) const { return IntEvent(p1, p2, HUGE_VAL, NONE, *this); }
IntEvent IStepped::getEvent(const Particle &p1, const Particle &p2) const { #ifdef DYNAMO_DEBUG if (!Sim->dynamics.getLiouvillean().isUpToDate(p1)) M_throw() << "Particle 1 is not up to date"; if (!Sim->dynamics.getLiouvillean().isUpToDate(p2)) M_throw() << "Particle 2 is not up to date"; if (p1 == p2) M_throw() << "You shouldn't pass p1==p2 events to the interactions!"; #endif CPDData colldat(*Sim, p1, p2); const_cmap_it capstat = getCMap_it(p1,p2); IntEvent retval(p1, p2, HUGE_VAL, NONE, *this); if (capstat == captureMap.end()) { double d = steps.front().first * _unitLength->getMaxValue(); double d2 = d * d; //Not captured, test for capture if (Sim->dynamics.getLiouvillean().SphereSphereInRoot (colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) { #ifdef DYNAMO_OverlapTesting //Check that there is no overlap if (Sim->dynamics.getLiouvillean().sphereOverlap(colldat, d2)) M_throw() << "Overlapping particles found" << ", particle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - steps.front().first) / Sim->dynamics.units().unitLength(); #endif retval = IntEvent(p1, p2, colldat.dt, WELL_IN, *this); } } else { //Within the potential, look for further capture or release //First check if there is an inner step to interact with if (capstat->second < static_cast<int>(steps.size())) { double d = steps[capstat->second].first * _unitLength->getMaxValue(); double d2 = d * d; if (Sim->dynamics.getLiouvillean().SphereSphereInRoot (colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) { #ifdef DYNAMO_OverlapTesting //Check that there is no overlap if (Sim->dynamics.getLiouvillean().sphereOverlap (colldat, d2)) M_throw() << "Overlapping particles found" << ", particle1 " << p1.getID() << ", particle2 " << p2.getID() << "\nOverlap = " << (sqrt(colldat.r2) - d) /Sim->dynamics.units().unitLength(); #endif retval = IntEvent(p1, p2, colldat.dt, WELL_IN , *this); } } {//Now test for the outward step double d = steps[capstat->second-1].first * _unitLength->getMaxValue(); double d2 = d * d; if (Sim->dynamics.getLiouvillean().SphereSphereOutRoot (colldat, d2, p1.testState(Particle::DYNAMIC), p2.testState(Particle::DYNAMIC))) if (retval.getdt() > colldat.dt) retval = IntEvent(p1, p2, colldat.dt, WELL_OUT, *this); } } return retval; }