Пример #1
0
def test_velocity_assignment(mpicomm=None, verbose=True):
    """
    Test Maxwell-Boltzmann velocity assignment subtroutine produces correct distribution, raising an exception if this test fails.

    """

    # Stop here if not root node.
    if mpicomm and (mpicomm.rank != 0): return

    if verbose: print "Testing Maxwell-Boltzmann velocity assignment: ",

    # Make a list of all test system constructors.
    import testsystems

    # Test parameters
    temperature = 298.0 * units.kelvin # test temperature
    kT = kB * temperature # thermal energy
    ntrials = 1000 # number of test trials
    systems_to_test = ['HarmonicOscillator', 'HarmonicOscillatorArray', 'AlanineDipeptideImplicit'] # systems to test
    
    for system_name in systems_to_test:
        #print '*' * 80
        #print system_name
   
        # Create system.
        constructor = getattr(testsystems, system_name)
        [system, coordinates] = constructor()

        # Create temporary filename.
        import tempfile # use a temporary file for testing
        file = tempfile.NamedTemporaryFile() 
        store_filename = file.name

        # Create repex instance.
        from repex import ReplicaExchange
        from thermodynamics import ThermodynamicState
        states = [ ThermodynamicState(system, temperature=temperature) ]
        simulation = ReplicaExchange(states=states, coordinates=coordinates, store_filename=store_filename)

        # Create integrator and context.
        natoms = system.getNumParticles()

        velocity_trials = numpy.zeros([ntrials, natoms, 3])
        kinetic_energy_trials = numpy.zeros([ntrials])

        for trial in range(ntrials):
            velocities = simulation._assign_Maxwell_Boltzmann_velocities(system, temperature)  
            kinetic_energy = 0.5 * units.sum(units.sum(system.masses * velocities**2)) 
            velocity_trials[trial,:,:] = velocities / (units.nanometers / units.picosecond)
            kinetic_energy_trials[trial] = kinetic_energy / units.kilocalories_per_mole
            
        velocity_mean = velocity_trials.mean(0)
        velocity_stderr = velocity_trials.std(0) / numpy.sqrt(ntrials)

        kinetic_analytical = (3.0/2.0) * natoms * kT / units.kilocalories_per_mole
        kinetic_mean = kinetic_energy_trials.mean()
        kinetic_error = kinetic_mean - kinetic_analytical
        kinetic_stderr = kinetic_energy_trials.std() / numpy.sqrt(ntrials)

        # Test if violations exceed tolerance.
        MAX_SIGMA = 6.0 # maximum number of standard errors allowed
        if numpy.any(numpy.abs(kinetic_error / kinetic_stderr) > MAX_SIGMA):
            print "analytical kinetic energy"
            print kinetic_analytical
            print "mean kinetic energy (kcal/mol)"
            print kinetic_mean
            print "difference (kcal/mol)"
            print kinetic_mean - kinetic_analytical
            print "stderr (kcal/mol)"
            print kinetic_stderr
            print "nsigma"
            print (kinetic_mean - kinetic_analytical) / kinetic_stderr
            raise Exception("Mean kinetic energy exceeds error tolerance of %.1f standard errors." % MAX_SIGMA)
        if numpy.any(numpy.abs(velocity_mean / velocity_stderr) > MAX_SIGMA):
            print "mean velocity (nm/ps)"
            print velocity_mean
            print "stderr (nm/ps)"
            print velocity_stderr
            print "nsigma"
            print velocity_mean / velocity_stderr
            raise Exception("Mean velocity exceeds error tolerance of %.1f standard errors." % MAX_SIGMA)
        
    if verbose: print "PASSED"
    return