ParticleEventData DynNewtonian::randomGaussianEvent(Particle& part, const double& sqrtT, const size_t dimensions) const { #ifdef DYNAMO_DEBUG if (dimensions > NDIM) M_throw() << "Number of dimensions passed larger than NDIM!"; #endif //See http://mathworld.wolfram.com/SpherePointPicking.html if (hasOrientationData()) M_throw() << "Need to implement thermostating of the rotational degrees" " of freedom"; //Ensure the particle is free streamed first updateParticle(part); //Collect the precoll data ParticleEventData tmpDat(part, *Sim->species[part], GAUSSIAN); double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID()); double factor = sqrtT / std::sqrt(mass); //Assign the new velocities for (size_t iDim = 0; iDim < dimensions; iDim++) part.getVelocity()[iDim] = Sim->normal_sampler() * factor; tmpDat.setDeltaKE(0.5 * mass * (part.getVelocity().nrm2() - tmpDat.getOldVel().nrm2())); return tmpDat; }
ParticleEventData DynNewtonian::runAndersenWallCollision(Particle& part, const Vector & vNorm, const double& sqrtT, const double) const { updateParticle(part); if (hasOrientationData()) M_throw() << "Need to implement thermostating of the rotational degrees" " of freedom"; //This gives a completely new random unit vector with a properly //distributed Normal component. See Granular Simulation Book ParticleEventData tmpDat(part, *Sim->species[part], WALL); double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID()); for (size_t iDim = 0; iDim < NDIM; iDim++) part.getVelocity()[iDim] = Sim->normal_sampler() * sqrtT / std::sqrt(mass); part.getVelocity() //This first line adds a component in the direction of the normal += vNorm * (sqrtT * sqrt(-2.0*log(1.0-Sim->uniform_sampler()) / mass) //This removes the original normal component -(part.getVelocity() | vNorm)); tmpDat.setDeltaKE(0.5 * mass * (part.getVelocity().nrm2() - tmpDat.getOldVel().nrm2())); return tmpDat; }
ParticleEventData DynCompression::runAndersenWallCollision(Particle& part, const Vector & vNorm, const double& sqrtT, const double d) const { updateParticle(part); if (hasOrientationData()) M_throw() << "Need to implement thermostating of the rotational degrees" " of freedom"; //This gives a completely new random unit vector with a properly //distributed Normal component. See Granular Simulation Book ParticleEventData tmpDat(part, *Sim->species[part], WALL); double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID()); std::normal_distribution<> normal_dist; std::uniform_real_distribution<> uniform_dist; for (size_t iDim = 0; iDim < NDIM; iDim++) part.getVelocity()[iDim] = normal_dist(Sim->ranGenerator) * sqrtT / std::sqrt(mass); part.getVelocity() //This first line adds a component in the direction of the normal += vNorm * (sqrtT * sqrt(-2.0*log(1.0 - uniform_dist(Sim->ranGenerator)) / mass) //This removes the original normal component -(part.getVelocity() | vNorm) //This adds on the velocity of the wall + d * growthRate) ; return tmpDat; }