Example #1
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 #2
0
  void
  OPMisc::eventUpdate(const IntEvent& eevent, const PairEventData& PDat)
  {
    stream(eevent.getdt());
    eventUpdate(PDat);

    newEvent(eevent.getParticle1ID(), eevent.getType(), getClassKey(eevent));
    newEvent(eevent.getParticle2ID(), eevent.getType(), getClassKey(eevent));
  }
Example #3
0
  void 
  OPCollMatrix::eventUpdate(const IntEvent& iEvent, const PairEventData&)
  {
    newEvent(iEvent.getParticle1ID(), iEvent.getType(), 
	     getClassKey(iEvent));

    newEvent(iEvent.getParticle2ID(), iEvent.getType(), 
	     getClassKey(iEvent));
  }
Example #4
0
  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);
  }
Example #5
0
  void 
  OPCollTicker::eventUpdate(const IntEvent &event, 
			    const PairEventData &) 
  {
    stream(event.getdt());
    ticker();
  }
Example #6
0
 void 
 OPViscosityE::eventUpdate(const IntEvent& iEvent, const PairEventData& PDat)
 {
   stream(iEvent.getdt());
   impulseDelG(PDat);
   updateConstDelG(PDat);
 }
Example #7
0
void 
OPRijVij::eventUpdate(const IntEvent& iEvent, const PairEventData& pDat)
{
  
  process2PED(rvdotacc[mapKey(iEvent.getType(), 
			      getClassKey(iEvent))], pDat);
}
Example #8
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 #9
0
  void
  ISWSequence::runEvent(Particle& p1, Particle& p2, const IntEvent& iEvent)
  {  
    ++Sim->eventCount;

    const double e = (_e->getProperty(p1.getID())
		+ _e->getProperty(p2.getID())) * 0.5;

    const double d = (_diameter->getProperty(p1.getID())
		+ _diameter->getProperty(p2.getID())) * 0.5;

    const double d2 = d * d;
    
    const double l = (_lambda->getProperty(p1.getID())
		      + _lambda->getProperty(p2.getID())) * 0.5;
  
    const double ld2 = d * l * d * l;

    const double pairenergy = alphabet[sequence[p1.getID() % sequence.size()]][sequence[p2.getID() % sequence.size()]] * _unitEnergy->getMaxValue();
    
    switch (iEvent.getType())
      {
      case CORE:
	{
	  PairEventData retVal(Sim->dynamics->SmoothSpheresColl(iEvent, e, d2, CORE));
	  Sim->_sigParticleUpdate(retVal);
	
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);

	  break;
	}
      case STEP_IN:
	{
	  PairEventData retVal(Sim->dynamics->SphereWellEvent(iEvent, pairenergy, ld2, 1));
	  if (retVal.getType() != BOUNCE) ICapture::add(p1, p2);      
	  Sim->_sigParticleUpdate(retVal);
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);

	  break;
	}
      case STEP_OUT:
	{
	  PairEventData retVal(Sim->dynamics->SphereWellEvent(iEvent, -pairenergy, ld2, 0));
	  if (retVal.getType() != BOUNCE) ICapture::remove(p1, p2);
	  Sim->_sigParticleUpdate(retVal);
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);
	  break;
	}
      default:
	M_throw() << "Unknown collision type";
      }
  }
Example #10
0
  void 
  OPThermalDiffusionE::eventUpdate(const IntEvent& iEvent, 
				   const PairEventData& PDat)
  {
    stream(iEvent.getdt());
    delG += impulseDelG(PDat);
    updateConstDelG(PDat);
  }
  void 
  OPThermalConductivitySpeciesSpeciesE::eventUpdate(const IntEvent& iEvent,
						    const PairEventData& PDat)
  {
    stream(iEvent.getdt());
    //impulseDelG(PDat);
    updateConstDelG(PDat);
  }
Example #12
0
PairEventData
DynGravity::SmoothSpheresColl(const IntEvent& event, const double& ne,
                              const double& d2, const EEventType& eType) const
{
    Particle& particle1 = Sim->particles[event.getParticle1ID()];
    Particle& particle2 = Sim->particles[event.getParticle2ID()];

    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 #13
0
void
ISoftCore::runEvent(const Particle& p1, const Particle& p2, const IntEvent& iEvent) const
{
  ++Sim->eventCount;

  double d2 = (_diameter->getProperty(p1.getID())
	       + _diameter->getProperty(p2.getID())) * 0.5;
  d2 *= d2;
  
  double wd = (_wellDepth->getProperty(p1.getID())
	       + _wellDepth->getProperty(p2.getID())) * 0.5;

  switch (iEvent.getType())
    {
    case WELL_IN:
      {
	PairEventData retVal(Sim->dynamics.getLiouvillean()
			      .SphereWellEvent(iEvent, wd, d2));
	
	if (retVal.getType() != BOUNCE)
	  addToCaptureMap(p1, p2);      
	
	//Now we're past the event, update the scheduler and plugins
	Sim->signalParticleUpdate(retVal);
	Sim->ptrScheduler->fullUpdate(p1, p2);
	
	BOOST_FOREACH(magnet::ClonePtr<OutputPlugin> & Ptr, Sim->outputPlugins)
	  Ptr->eventUpdate(iEvent, retVal);


	break;
      }
    case WELL_OUT:
      {
	PairEventData retVal(Sim->dynamics.getLiouvillean()
			      .SphereWellEvent(iEvent, -wd, d2));
	
	if (retVal.getType() != BOUNCE)
	  removeFromCaptureMap(p1, p2);      
	
	Sim->signalParticleUpdate(retVal);

	//Now we're past the event, update the scheduler and plugins
	Sim->ptrScheduler->fullUpdate(p1, p2);
	
	BOOST_FOREACH(magnet::ClonePtr<OutputPlugin>& Ptr, 
		      Sim->outputPlugins)
	  Ptr->eventUpdate(iEvent, retVal);

	break;
      }
    default:
      M_throw() << "Unknown collision type";
    }
}
Example #14
0
  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;
  }
Example #15
0
  void
  ISquareWell::runEvent(Particle& p1, Particle& p2, const IntEvent& iEvent)
  {
    ++Sim->eventCount;

    double d = (_diameter->getProperty(p1.getID())
		+ _diameter->getProperty(p2.getID())) * 0.5;
    double d2 = d * d;

    double e = (_e->getProperty(p1.getID())
		+ _e->getProperty(p2.getID())) * 0.5;

    double l = (_lambda->getProperty(p1.getID())
		+ _lambda->getProperty(p2.getID())) * 0.5;
    double ld2 = d * l * d * l;

    double wd = (_wellDepth->getProperty(p1.getID())
		 + _wellDepth->getProperty(p2.getID())) * 0.5;
    switch (iEvent.getType())
      {
      case CORE:
	{
	  PairEventData retVal(Sim->dynamics->SmoothSpheresColl(iEvent, e, d2, CORE));
	  Sim->_sigParticleUpdate(retVal);
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);
	  break;
	}
      case STEP_IN:
	{
	  PairEventData retVal(Sim->dynamics->SphereWellEvent(iEvent, wd, ld2, 1));
	  if (retVal.getType() != BOUNCE) ICapture::add(p1, p2);
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	  Sim->_sigParticleUpdate(retVal);
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);
	  break;
	}
      case STEP_OUT:
	{
	  PairEventData retVal(Sim->dynamics->SphereWellEvent(iEvent, -wd, ld2, 0));
	  if (retVal.getType() != BOUNCE) ICapture::remove(p1, p2);
	  Sim->_sigParticleUpdate(retVal);
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	  for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);
	  break;
	}
      default:
	M_throw() << "Unknown collision type";
      } 
  }
Example #16
0
  void 
  OPVACF::eventUpdate(const IntEvent& iEvent, const PairEventData& PDat)
  {
    //Move the time forward
    currentdt += iEvent.getdt();
  
    //Now test if we've gone over the step time
    while (currentdt >= dt)
      {
	currentdt -= dt;
	newG(PDat);
      }
  }
Example #17
0
void 
OPCubeComp::eventUpdate(const IntEvent& iEvent, const PairEventData& pDat)
{
  mapdata& ref = angles[mapKey(iEvent.getType(), getClassKey(iEvent))];

  std::vector<double> vals(NDIM, 0);

  for (size_t i(0); i < NDIM; ++i)
    vals[i] = pDat.rij[i] * pDat.rij[i] / Sim->dynamics.units().unitArea();

  std::sort(vals.begin(), vals.end());
  
  for (size_t i(0); i < NDIM; ++i)
    ref.angles[i].addVal(vals[i]);
}
Example #18
0
  void
  IStepped::runEvent(Particle& p1, Particle& p2, const IntEvent& iEvent)
  {
    ++Sim->eventCount;

    const double length_scale = 0.5 * (_lengthScale->getProperty(p1.getID()) + _lengthScale->getProperty(p2.getID()));
    const double energy_scale = 0.5 * (_energyScale->getProperty(p1.getID()) + _energyScale->getProperty(p2.getID()));

    ICapture::const_iterator capstat = ICapture::find(ICapture::key_type(p1, p2));
    const size_t old_step_ID = (capstat == ICapture::end()) ? 0 : capstat->second;
    const std::pair<double, double> step_bounds = _potential->getStepBounds(old_step_ID);

    size_t new_step_ID;
    size_t edge_ID;
    double diameter;
    switch (iEvent.getType())
      {
      case STEP_OUT:
	{
	  new_step_ID = _potential->outer_step_ID(old_step_ID);
	  edge_ID = _potential->outer_edge_ID(old_step_ID);
	  diameter = step_bounds.second * length_scale;
	  break;
	}
      case STEP_IN:
	{
	  new_step_ID = _potential->inner_step_ID(old_step_ID);
	  edge_ID = _potential->inner_edge_ID(old_step_ID);
	  diameter = step_bounds.first * length_scale;
	  break;
	}
      default:
	M_throw() << "Unknown event type";
      } 

    PairEventData retVal = Sim->dynamics->SphereWellEvent(iEvent, _potential->getEnergyChange(new_step_ID, old_step_ID) * energy_scale, diameter * diameter, new_step_ID);
    EdgeData& data = _edgedata[std::pair<size_t, EEventType>(edge_ID, retVal.getType())];
    ++data.counter;
    data.rdotv_sum += retVal.rvdot;
    //Check if the particles changed their step ID
    if (retVal.getType() != BOUNCE) ICapture::operator[](ICapture::key_type(p1, p2)) = new_step_ID;
    Sim->_sigParticleUpdate(retVal);
    Sim->ptrScheduler->fullUpdate(p1, p2);
    for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins)
      Ptr->eventUpdate(iEvent, retVal);
  }
Example #19
0
  void
  ISWSequence::runEvent(const Particle& p1,
			const Particle& p2,
			const IntEvent& iEvent) const
  {  
    ++Sim->eventCount;

    double e = (_e->getProperty(p1.getID())
		+ _e->getProperty(p2.getID())) * 0.5;

    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;

    switch (iEvent.getType())
      {
      case CORE:
	{
	  PairEventData retVal(Sim->dynamics.getLiouvillean().SmoothSpheresColl(iEvent, e, d2, CORE));
	  Sim->signalParticleUpdate(retVal);
	
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	
	  BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);

	  break;
	}
      case WELL_IN:
	{
	  PairEventData retVal(Sim->dynamics.getLiouvillean()
			       .SphereWellEvent
			       (iEvent, alphabet
				[sequence[p1.getID() % sequence.size()]]
				[sequence[p2.getID() % sequence.size()]] 
				* _unitEnergy->getMaxValue(), 
				ld2));
	
	  if (retVal.getType() != BOUNCE)
	    addToCaptureMap(p1, p2);      

	  Sim->signalParticleUpdate(retVal);

	  Sim->ptrScheduler->fullUpdate(p1, p2);
	
	  BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);

	  break;
	}
      case WELL_OUT:
	{
	  PairEventData retVal(Sim->dynamics.getLiouvillean()
			       .SphereWellEvent
			       (iEvent, -alphabet
				[sequence[p1.getID() % sequence.size()]]
				[sequence[p2.getID() % sequence.size()]]
				* _unitEnergy->getMaxValue(), 
				ld2));
	
	  if (retVal.getType() != BOUNCE)
	    removeFromCaptureMap(p1, p2);
	
	  Sim->signalParticleUpdate(retVal);

	  Sim->ptrScheduler->fullUpdate(p1, p2);
	
	  BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin> & Ptr, Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retVal);

	  break;
	}
      default:
	M_throw() << "Unknown collision type";
      }
  }
  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;
  }
Example #21
0
  void 
  OPIntEnergyHist::eventUpdate(const IntEvent &event, 
			    const PairEventData &) 
  {
    intEnergyHist.addVal(_ptrOPMisc->getConfigurationalU(), event.getdt());
  }
Example #22
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;
  }
Example #23
0
  bool 
  Interaction::isInteraction(const IntEvent &coll) const
  { 
    return isInteraction(Sim->particles[coll.getParticle1ID()],
			 Sim->particles[coll.getParticle2ID()]); 
  }
Example #24
0
 classKey getClassKey(const IntEvent& i)
 {
   return classKey(i.getInteractionID(), INTERACTION);
 }
Example #25
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 #26
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 #27
0
  void
  IDumbbells::runEvent(const Particle& p1, 
		       const Particle& p2,
		       const IntEvent& iEvent) const
  {
    double d = (_diameter->getProperty(p1.getID())
		+ _diameter->getProperty(p2.getID())) * 0.5;

    double l = (_length->getProperty(p1.getID())
		+ _length->getProperty(p2.getID())) * 0.5;

    double e = (_e->getProperty(p1.getID())
		+ _e->getProperty(p2.getID())) * 0.5;

    switch (iEvent.getType())
      {
      case CORE:
	{
	  ++Sim->eventCount;
	  //We have a line interaction! Run it
	  PairEventData retval(Sim->dynamics.getLiouvillean()
			       .runOffCenterSphereOffCenterSphereCollision
			       (iEvent, e, l, d));

	  Sim->signalParticleUpdate(retval);
	
	  Sim->ptrScheduler->fullUpdate(p1, p2);
	
	  BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin> & Ptr, 
			Sim->outputPlugins)
	    Ptr->eventUpdate(iEvent, retval);

	  break;
	}
      case WELL_IN:
	{
	  addToCaptureMap(p1, p2);

	  //Unfortunately we cannot be smart as this well event may have
	  //been pushed into both particles update lists, therefore we
	  //must do a full update
	  Sim->ptrScheduler->fullUpdate(p1, p2);

	  Sim->freestreamAcc += iEvent.getdt();
	  break;
	}
      case WELL_OUT:
	{
	  removeFromCaptureMap(p1, p2);

	  //Unfortunately we cannot be smart as this well event may have
	  //been pushed into both particles update lists, therefore we
	  //must do a full update
	  Sim->ptrScheduler->fullUpdate(p1, p2);

	  Sim->freestreamAcc += iEvent.getdt();
	  break;
	}
      default:
	M_throw() << "Unknown collision type";
      }
  }
Example #28
0
void
IStepped::runEvent(const Particle& p1, 
		    const Particle& p2,
		    const IntEvent& iEvent) const
{
  ++Sim->eventCount;

  switch (iEvent.getType())
    {
    case WELL_OUT:
      {
	cmap_it capstat = getCMap_it(p1,p2);
	
	double d = steps[capstat->second-1].first * _unitLength->getMaxValue();
	double d2 = d * d;
	double dE = steps[capstat->second-1].second;
	if (capstat->second > 1)
	  dE -= steps[capstat->second - 2].second;
	dE *= _unitEnergy->getMaxValue();

	PairEventData retVal(Sim->dynamics.getLiouvillean().SphereWellEvent
			      (iEvent, dE, d2));
	
	if (retVal.getType() != BOUNCE)
	  if (!(--capstat->second))
	    //capstat is zero so delete
	    captureMap.erase(capstat);

	Sim->signalParticleUpdate(retVal);

	Sim->ptrScheduler->fullUpdate(p1, p2);
	
	BOOST_FOREACH(magnet::ClonePtr<OutputPlugin> & Ptr, Sim->outputPlugins)
	  Ptr->eventUpdate(iEvent, retVal);
	break;
      }
    case WELL_IN:
      {
	cmap_it capstat = getCMap_it(p1, p2);
	
	if (capstat == captureMap.end())
	  capstat = captureMap.insert
	    (captureMapType::value_type
	     ((p1.getID() < p2.getID())
	      ? cMapKey(p1.getID(), p2.getID())
	      : cMapKey(p2.getID(), p1.getID()),
	      0)).first;
	
	double d = steps[capstat->second].first * _unitLength->getMaxValue();
	double d2 = d * d;
	double dE = steps[capstat->second].second;
	if (capstat->second > 0)
	  dE -= steps[capstat->second - 1].second;
	dE *= _unitEnergy->getMaxValue();


	PairEventData retVal = Sim->dynamics.getLiouvillean().SphereWellEvent(iEvent, -dE, d2);
	
	if (retVal.getType() != BOUNCE)
	  ++(capstat->second);
	else if (!capstat->second)
	  captureMap.erase(capstat);
	
	Sim->signalParticleUpdate(retVal);
	
	Sim->ptrScheduler->fullUpdate(p1, p2);
	
	BOOST_FOREACH(magnet::ClonePtr<OutputPlugin> & Ptr, Sim->outputPlugins)
	  Ptr->eventUpdate(iEvent, retVal);
	    
	break;
      }
    default:
      M_throw() << "Unknown collision type";
    } 
}
Example #29
0
bool
System::operator<(const IntEvent& iEvent) const
{
    return dt < iEvent.getdt();
}