<commit_before>package etomica.nbr;

import etomica.Atom;
import etomica.Debug;
import etomica.Phase;
import etomica.Space;
import etomica.nbr.cell.AtomsetIteratorCellular;

/**
 * Simple neighbor criterion based on distance moved by a leaf atom since
 * the last update.
 * @author andrew
 *
 */
public class NeighborCriterionSimple extends NeighborCriterion  {

	public NeighborCriterionSimple(Space space, double interactionRange, double neighborRadius) {
		super();
        this.space = space;
		this.interactionRange = interactionRange;
		double displacementLimit = (neighborRadius - interactionRange) * safetyFactor;
		displacementLimit2 = displacementLimit * displacementLimit;
		neighborRadius2 = neighborRadius * neighborRadius;
        cPair = space.makeCoordinatePair();
        dr = space.makeVector();
	}
	
	public void setSafetyFactor(double f) {
		if (safetyFactor < 0.0 || safetyFactor>0.5) throw new IllegalArgumentException("safety factor must be positive and less than 0.5");
		safetyFactor = f;
		double displacementLimit = (Math.sqrt(neighborRadius2) - interactionRange) * f;
		displacementLimit2 = displacementLimit * displacementLimit;
	}
	
	public double getSafetyFactor() {
		return safetyFactor;
	}
	
	public void setNeighborRadius(double r) {
		if (r < interactionRange) throw new IllegalArgumentException("Neighbor radius must be larger than interaction range");
		neighborRadius2 = r*r;
		double displacementLimit = (r - interactionRange) * safetyFactor;
		displacementLimit2 = displacementLimit * displacementLimit;
	}
	
	public double getNeighborRadius() {
		return Math.sqrt(neighborRadius2);
	}
	
	public boolean needUpdate(Atom atom) {
		r2 = atom.coord.position().Mv1Squared((Space.Vector)atom.allatomAgents[agentIndex]);
		if (Debug.DEBUG_NOW && r2 > displacementLimit2 / (4.0*safetyFactor*safetyFactor)) {
			System.out.println("atom "+atom+" exceeded safe limit ("+r2+" > "+displacementLimit2 / (4.0*safetyFactor*safetyFactor));
			System.out.println("old position "+(Space.Vector)atom.allatomAgents[agentIndex]);
			System.out.println("new position "+atom.coord.position());
		}
		return r2 > displacementLimit2;
	}

	public void setPhase(Phase phase) {
	    this.phase = phase;
	}
    
    public void setCellIterator(AtomsetIteratorCellular api) {
        cPair.setNearestImageTransformer(api);
        api.getNbrCellIterator().setPeriod(phase.boundary().dimensions());
    }

	public boolean unsafe() {
		if (Debug.DEBUG_NOW && r2 > displacementLimit2 / (4.0*safetyFactor*safetyFactor)) {
			System.out.println("some atom exceeded safe limit ("+r2+" > "+displacementLimit2 / (4.0*safetyFactor*safetyFactor));
		}
		return r2 > displacementLimit2 / (4.0*safetyFactor*safetyFactor);
	}

	public boolean accept(Atom[] a) {
		cPair.reset(a[0].coord,a[1].coord);
		if (Debug.DEBUG_NOW && ((Debug.LEVEL > 1 && Debug.anyAtom(a)) || (Debug.LEVEL == 1 && Debug.allAtoms(a)))) {
			if (cPair.r2() < neighborRadius2 || (Debug.LEVEL > 1 && Debug.allAtoms(a))) { 
				System.out.println("Atom "+a[0]+" and "+a[1]+" are "+(cPair.r2() < neighborRadius2 ? "" : "not ")+"neighbors, r2="+cPair.r2());
            }
		}
		return cPair.r2() < neighborRadius2;
	}
	
	public void reset(Atom atom) {
		((Space.Vector)atom.allatomAgents[agentIndex]).E(atom.coord.position());
	}

	private double interactionRange, displacementLimit2, neighborRadius2;
	Space.CoordinatePair cPair;
	protected static int agentIndex = Atom.requestAgentIndex(new Atom.AgentSource() {
		public Object makeAgent(Atom atom) {
			return atom.coord.position().clone();
		}
	});
	protected double safetyFactor = 0.4;
	protected double r2;
    private final Space space;
    private final Space.Vector dr;
    private Phase phase;<commit_msg>Pre-calculate and store value for maximum safe r2<commit_after>package etomica.nbr;

import etomica.Atom;
import etomica.Debug;
import etomica.Phase;
import etomica.Space;
import etomica.nbr.cell.AtomsetIteratorCellular;

/**
 * Simple neighbor criterion based on distance moved by a leaf atom since
 * the last update.
 * @author andrew
 *
 */
public class NeighborCriterionSimple extends NeighborCriterion  {

	public NeighborCriterionSimple(Space space, double interactionRange, double neighborRadius) {
		super();
        this.space = space;
		this.interactionRange = interactionRange;
        neighborRadius2 = neighborRadius * neighborRadius;
        setSafetyFactor(0.4);
        cPair = space.makeCoordinatePair();
        dr = space.makeVector();
	}
	
	public void setSafetyFactor(double f) {
		if (safetyFactor < 0.0 || safetyFactor > 0.5) throw new IllegalArgumentException("safety factor must be positive and less than 0.5");
		safetyFactor = f;
		double displacementLimit = (Math.sqrt(neighborRadius2) - interactionRange) * f;
		displacementLimit2 = displacementLimit * displacementLimit;
        r2MaxSafe = displacementLimit2 / (4.0*safetyFactor*safetyFactor);
	}
	
	public double getSafetyFactor() {
		return safetyFactor;
	}
	
	public void setNeighborRadius(double r) {
		if (r < interactionRange) throw new IllegalArgumentException("Neighbor radius must be larger than interaction range");
		neighborRadius2 = r*r;
		double displacementLimit = (r - interactionRange) * safetyFactor;
		displacementLimit2 = displacementLimit * displacementLimit;
        r2MaxSafe = displacementLimit2 / (4.0*safetyFactor*safetyFactor);
	}
	
	public double getNeighborRadius() {
		return Math.sqrt(neighborRadius2);
	}
	
	public boolean needUpdate(Atom atom) {
		r2 = atom.coord.position().Mv1Squared((Space.Vector)atom.allatomAgents[agentIndex]);
		if (Debug.DEBUG_NOW && r2 > displacementLimit2 / (4.0*safetyFactor*safetyFactor)) {
			System.out.println("atom "+atom+" exceeded safe limit ("+r2+" > "+displacementLimit2 / (4.0*safetyFactor*safetyFactor));
			System.out.println("old position "+(Space.Vector)atom.allatomAgents[agentIndex]);
			System.out.println("new position "+atom.coord.position());
		}
		return r2 > displacementLimit2;
	}

	public void setPhase(Phase phase) {
	    this.phase = phase;
	}
    
    public void setCellIterator(AtomsetIteratorCellular api) {
        cPair.setNearestImageTransformer(api);
        api.getNbrCellIterator().setPeriod(phase.boundary().dimensions());
    }

	public boolean unsafe() {
		if (Debug.DEBUG_NOW && r2 > displacementLimit2 / (4.0*safetyFactor*safetyFactor)) {
			System.out.println("some atom exceeded safe limit ("+r2+" > "+displacementLimit2 / (4.0*safetyFactor*safetyFactor));
		}
		return r2 > r2MaxSafe;
	}

	public boolean accept(Atom[] a) {
		cPair.reset(a[0].coord,a[1].coord);
		if (Debug.DEBUG_NOW && ((Debug.LEVEL > 1 && Debug.anyAtom(a)) || (Debug.LEVEL == 1 && Debug.allAtoms(a)))) {
			if (cPair.r2() < neighborRadius2 || (Debug.LEVEL > 1 && Debug.allAtoms(a))) { 
				System.out.println("Atom "+a[0]+" and "+a[1]+" are "+(cPair.r2() < neighborRadius2 ? "" : "not ")+"neighbors, r2="+cPair.r2());
            }
		}
		return cPair.r2() < neighborRadius2;
	}
	
	public void reset(Atom atom) {
		((Space.Vector)atom.allatomAgents[agentIndex]).E(atom.coord.position());
	}

	private double interactionRange, displacementLimit2, neighborRadius2;
	Space.CoordinatePair cPair;
	protected static int agentIndex = Atom.requestAgentIndex(new Atom.AgentSource() {
		public Object makeAgent(Atom atom) {
			return atom.coord.position().clone();
		}
	});
	protected double safetyFactor;
    protected double safetyFactor2;
	protected double r2, r2MaxSafe;
    private final Space space;
    private final Space.Vector dr;
    private Phase phase;
{'fraction_non_alphanumeric': 0.12306060204216947, 'fraction_numerical': 0.016178225699509347, 'mean_word_length': 4.545588235294118, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3211600', 'n_tokens_mistral': 2534, 'n_tokens_neox': 2329, 'n_words': 530}