Example #1
0
PairEventData
DynNewtonian::DSMCSpheresRun(Particle& p1, Particle& p2, const double& e, Vector rij) const
{
    updateParticlePair(Sim->particles[p1.getID()], Sim->particles[p2.getID()]);

    Vector vij = p1.getVelocity() - p2.getVelocity();
    Sim->BCs->applyBC(rij, vij);

    double rvdot = (rij | vij);

    PairEventData retVal(p1, p2,
                         *Sim->species[p1],
                         *Sim->species[p2],
                         CORE);

    retVal.rij = rij;
    retVal.rvdot = rvdot;

    double p1Mass = Sim->species[retVal.particle1_.getSpeciesID()]->getMass(p1.getID());
    double p2Mass = Sim->species[retVal.particle2_.getSpeciesID()]->getMass(p2.getID());
    double mu = p1Mass * p2Mass/(p1Mass+p2Mass);

    retVal.dP = rij * ((1.0 + e) * mu * rvdot / rij.nrm2());

    //This function must edit particles so it overrides the const!
    p1.getVelocity() -= retVal.dP / p1Mass;
    p2.getVelocity() += retVal.dP / p2Mass;

    retVal.particle1_.setDeltaKE(0.5 * p1Mass * (p1.getVelocity().nrm2()
                                 - retVal.particle1_.getOldVel().nrm2()));

    retVal.particle2_.setDeltaKE(0.5 * p2Mass * (p2.getVelocity().nrm2()
                                 - retVal.particle2_.getOldVel().nrm2()));
    return retVal;
}
Example #2
0
  PairEventData 
  DynCompression::SmoothSpheresColl(const IntEvent& event, const double& e, const double& d2, const EEventType& eType) 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], eType);
    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 r2 = retVal.rij.nrm2();
    retVal.rvdot = (retVal.rij | retVal.vijold);
    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;
      }

    retVal.impulse = retVal.rij * ((1.0 + e) * mu * (retVal.rvdot - growthRate * sqrt(d2 * r2)) / retVal.rij.nrm2());  
    particle1.getVelocity() -= retVal.impulse / p1Mass;
    particle2.getVelocity() += retVal.impulse / p2Mass;
    //If both particles have infinite mass we pretend no momentum was transferred
    retVal.impulse *= !infinite_masses;

    return retVal;
  }
Example #3
0
PairEventData
DynNewtonian::parallelCubeColl(const IntEvent& event, const double& e, const double&, const EEventType& eType) 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],
                         eType);

    Sim->BCs->applyBC(retVal.rij, retVal.vijold);

    size_t dim(0);

    for (size_t iDim(1); iDim < NDIM; ++iDim)
        if (fabs(retVal.rij[dim]) < fabs(retVal.rij[iDim])) dim = iDim;

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

    Vector collvec(0,0,0);

    if (retVal.rij[dim] < 0)
        collvec[dim] = -1;
    else
        collvec[dim] = 1;

    retVal.rvdot = (retVal.rij | retVal.vijold);

    retVal.dP = collvec * (1.0 + e) * mu * (collvec | retVal.vijold);

    //This function must edit particles so it overrides the const!
    particle1.getVelocity() -= retVal.dP / p1Mass;
    particle2.getVelocity() += retVal.dP / p2Mass;

    retVal.particle1_.setDeltaKE(0.5 * p1Mass * (particle1.getVelocity().nrm2()
                                 - retVal.particle1_.getOldVel().nrm2()));

    retVal.particle2_.setDeltaKE(0.5 * p2Mass * (particle2.getVelocity().nrm2()
                                 - retVal.particle2_.getOldVel().nrm2()));

    return retVal;
}
Example #4
0
  PairEventData 
  DynGravity::SmoothSpheresColl(Event& event, const double& ne,
				const double& d2, const EEventType& eType) const
  {
    Particle& particle1 = Sim->particles[event._particle1ID];
    Particle& particle2 = Sim->particles[event._particle2ID];

    updateParticlePair(particle1, particle2);  

    Vector rij = particle1.getPosition() - particle2.getPosition(),
      vij = particle1.getVelocity() - particle2.getVelocity();

    Sim->BCs->applyBC(rij, vij);


    //Check if two particles are collapsing
    //First, the elastic V calculation
    double vnrm = std::fabs((rij | vij) / rij.nrm());  
    double e = ne;
    if (vnrm < elasticV) e = 1.0;
  
    //Check if a particle is collapsing on a static particle
    if (!particle1.testState(Particle::DYNAMIC) 
	|| !particle2.testState(Particle::DYNAMIC))
      {
	double gnrm = g.nrm();
	if (gnrm > 0)
	  if (std::fabs((vij | g) / gnrm) < elasticV) e = 1.0;  
      }
  
    //Now the tc model;
    if (_tc > 0)
      {
	if ((Sim->systemTime - _tcList[particle1.getID()] < _tc)
	    || (Sim->systemTime - _tcList[particle2.getID()] < _tc))
	  e = 1.0;
      
	_tcList[particle1.getID()] = Sim->systemTime;
	_tcList[particle2.getID()] = Sim->systemTime;
      }

    return DynNewtonian::SmoothSpheresColl(event, e, d2, eType);
  }
Example #5
0
bool
DynNewtonian::DSMCSpheresTest(Particle& p1, Particle& p2, double& maxprob, const double& factor, Vector rij) const
{
    updateParticlePair(Sim->particles[p1.getID()], Sim->particles[p2.getID()]);

    Vector vij = p1.getVelocity() - p2.getVelocity();
    Sim->BCs->applyBC(rij, vij);

    //Sim->BCs->applyBC(pdat.rij, pdat.vij);
    double rvdot = (rij | vij);

    if (rvdot > 0)
        return false; //Positive rvdot

    double prob = factor * (-rvdot);

    if (prob > maxprob)
        maxprob = prob;

    return prob > Sim->uniform_sampler() * maxprob;
}
Example #6
0
  PairEventData
  LSLLOD::DSMCSpheresRun(const Particle& p1, 
			 const Particle& p2, 
			 const double& e,
			 CPDData& pdat) const
  {
    updateParticlePair(p1, p2);  

    PairEventData retVal(p1, p2,
			 Sim->dynamics.getSpecies(p1),
			 Sim->dynamics.getSpecies(p2),
			 CORE);
 
    retVal.vijold = pdat.vij;

    retVal.rij = pdat.rij;
    retVal.rvdot = pdat.rvdot;

    double p1Mass = retVal.particle1_.getSpecies().getMass(p1.getID()); 
    double p2Mass = retVal.particle2_.getSpecies().getMass(p2.getID());
    double mu = p1Mass * p2Mass/(p1Mass+p2Mass);

    retVal.dP = retVal.rij * ((1.0 + e) * mu * retVal.rvdot 
			      / retVal.rij.nrm2());  

    //This function must edit particles so it overrides the const!
    const_cast<Particle&>(p1).getVelocity() -= retVal.dP / p1Mass;
    const_cast<Particle&>(p2).getVelocity() += retVal.dP / p2Mass;

    retVal.particle1_.setDeltaKE(0.5 * p1Mass
				 * (p1.getVelocity().nrm2() 
				    - retVal.particle1_.getOldVel().nrm2()));
  
    retVal.particle2_.setDeltaKE(0.5 * p2Mass
				 * (p2.getVelocity().nrm2() 
				    - retVal.particle2_.getOldVel().nrm2()));

    return retVal;
  }
PairEventData
DynNewtonianMCCMap::SphereWellEvent(Event& event, const double& deltaKE, const double &, size_t newstate) const
{
    Particle& particle1 = Sim->particles[event._particle1ID];
    Particle& particle2 = Sim->particles[event._particle2ID];

    updateParticlePair(particle1, particle2);

    PairEventData retVal(particle1, particle2, *Sim->species(particle1), *Sim->species(particle2), event._type);

    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._type = 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;
}
Example #8
0
PairEventData
DynNewtonian::SmoothSpheresColl(const IntEvent& event, const double& e, const double&, const EEventType& eType) 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],
                         eType);

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

    retVal.rvdot = (retVal.rij | retVal.vijold);

    //Treat special cases if one particle has infinite mass
    if ((p1Mass == 0) && (p2Mass != 0))
        //if (!particle1.testState(Particle::DYNAMIC) && particle2.testState(Particle::DYNAMIC))
    {
        retVal.dP = p2Mass * retVal.rij * ((1.0 + e) * retVal.rvdot / retVal.rij.nrm2());
        //This function must edit particles so it overrides the const!
        particle2.getVelocity() += retVal.dP / p2Mass;
    }
    else if ((p1Mass != 0) && (p2Mass == 0))
        //if (particle1.testState(Particle::DYNAMIC) && !particle2.testState(Particle::DYNAMIC))
    {
        retVal.dP = p1Mass * retVal.rij * ((1.0 + e) * retVal.rvdot / retVal.rij.nrm2());
        //This function must edit particles so it overrides the const!
        particle1.getVelocity() -= retVal.dP / p1Mass;
    }
    else
    {
        bool isInfInf = (p1Mass == 0) && (p2Mass == 0);

        //If both particles have infinite mass we just collide them as identical masses
        if (isInfInf) p1Mass = p2Mass = 1;

        double mu = p1Mass * p2Mass / (p1Mass + p2Mass);

        retVal.dP = retVal.rij * ((1.0 + e) * mu * retVal.rvdot / retVal.rij.nrm2());

        //This function must edit particles so it overrides the const!
        particle1.getVelocity() -= retVal.dP / p1Mass;
        particle2.getVelocity() += retVal.dP / p2Mass;

        //If both particles have infinite mass we pretend no momentum was transferred
        retVal.dP *= !isInfInf;
    }

    retVal.particle1_.setDeltaKE(0.5 * p1Mass * (particle1.getVelocity().nrm2()
                                 - retVal.particle1_.getOldVel().nrm2()));

    retVal.particle2_.setDeltaKE(0.5 * p2Mass * (particle2.getVelocity().nrm2()
                                 - retVal.particle2_.getOldVel().nrm2()));

    lastCollParticle1 = particle1.getID();
    lastCollParticle2 = particle2.getID();
    lastAbsoluteClock = Sim->systemTime;

    return retVal;
}
Example #9
0
  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;
  }
Example #10
0
  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;
  }