package simulate;

/**
 * Basic hard-(rod/disk/sphere) potential.
 * Energy is infinite if disks overlap, and is zero otherwise.  Collision diameter describes
 * size of disks.
 * Suitable for use in space of any dimension.
 */
public class PotentialHardDisk implements PotentialHard
{
   /**
    * Separation at which disks first overlap
    */
   protected double collisionDiameter;
   /**
    * Square of collisionDiameter
    */
   protected double sig2;
   private double lastCollisionVirial = 0.0;
    

    public PotentialHardDisk(double d) {
        setCollisionDiameter(d);
    }

    /**
     * Time to collision of pair, assuming free-flight kinematics
     */
    public double collisionTime(AtomPair pair) {
        double r2 = pair.r2();
        double bij = pair.vDotr();
        if(r2 < sig2) {return (bij > 0) ? Double.MAX_VALUE : 0.0;}  //inside wall; no collision
        double time = Double.MAX_VALUE;

        if(bij < 0.0) {
          double velocitySquared = pair.v2();
          double discriminant = bij*bij - velocitySquared * ( r2 - sig2 );
          if(discriminant > 0) {
            time = (-bij - Math.sqrt(discriminant))/velocitySquared;
          }
        }
        return time;
    }
    
    /**
     * Implements collision dynamics and updates lastCollisionVirial
     */
    public void bump(AtomPair pair) {
        double r2 = pair.r2();
        lastCollisionVirial = 2.0/(pair.atom1().rm() + pair.atom2().rm())*pair.vDotr();
        double factor = lastCollisionVirial/r2;
        pair.cPair.push(factor);
    }
    
    public final double lastCollisionVirial() {
        return lastCollisionVirial;
    }
    
    /**
     * Accessor method for collision diameter
     */
    public double getCollisionDiameter() {return collisionDiameter;}
    /**
     * Accessor method for collision diameter
     */
    public void setCollisionDiameter(double c) {
        collisionDiameter = c;
        sig2 = c*c;
    }
    
    /**
     * Interaction energy of the pair.
     * Zero if separation is greater than collision diameter, infinity otherwise
     */
    public double energy(AtomPair pair) {
        return (pair.r2() < sig2) ? Double.MAX_VALUE : 0.0;
    }
    
    /**
     * Correction for trucation of the potential
     * Identically zero for this model
     */
    public double energyLRC(int n1, int n2, double V) {return 0.0;}
    
    /**
     * Returns true if separation of pair is less than collision diameter, false otherwise
     */
    public boolean overlap(AtomPair pair) {return pair.r2() < sig2;}
    
}