示例#1
0
文件: lines.cpp 项目: pinggy/DynamO
  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);
  }
示例#2
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;
  }
  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;
  }
示例#4
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;
  }
示例#5
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;
  }