Beispiel #1
0
def buildtree(input_atoms, u, v, j, e):
    if j == 0:
        atomsp = leapfrog(input_atoms, v * e)
        if u <= np.exp(-atomsp.get_total_energy()):
            # if u <= atomsp.get_total_energy():
            cp = [atomsp]
        else:
            # print 'Fail MH'
            cp = []
        sp = u < np.exp(delta_max - atomsp.get_total_energy())
        # sp = u < delta_max + atomsp.get_total_energy()
        if sp == 0:
            # print 'Fail slice test'
            pass
        return atomsp, atomsp, cp, sp
    else:
        neg_atoms, pos_atoms, cp, sp = buildtree(input_atoms, u, v, j - 1, e)
        if v == -1:
            neg_atoms, _, cpp, spp = buildtree(neg_atoms, u, v, j - 1, e)
        else:
            _, pos_atoms, cpp, spp = buildtree(pos_atoms, u, v, j - 1, e)
        datoms = pos_atoms.positions - neg_atoms.positions
        sp = sp * spp * (
            np.dot(datoms.flatten(), neg_atoms.get_momenta().flatten()) >= 0) \
             * (np.dot(datoms.flatten(),
                       pos_atoms.get_momenta().flatten()) >= 0)
        cp += cpp
        return neg_atoms, pos_atoms, cp, sp
Beispiel #2
0
def buildtree(input_atoms, u, v, j, e):
    if j == 0:
        atomsp = leapfrog(input_atoms, v * e)
        if u <= np.exp(-atomsp.get_total_energy()):
            # if u <= atomsp.get_total_energy():
            cp = [atomsp]
        else:
            # print 'Fail MH'
            cp = []
        sp = u < np.exp(delta_max - atomsp.get_total_energy())
        # sp = u < delta_max + atomsp.get_total_energy()
        if sp == 0:
            # print 'Fail slice test'
            pass
        return atomsp, atomsp, cp, sp
    else:
        neg_atoms, pos_atoms, cp, sp = buildtree(input_atoms, u, v, j - 1, e)
        if v == -1:
            neg_atoms, _, cpp, spp = buildtree(neg_atoms, u, v, j - 1, e)
        else:
            _, pos_atoms, cpp, spp = buildtree(pos_atoms, u, v, j - 1, e)
        datoms = pos_atoms.positions - neg_atoms.positions
        sp = sp * spp * (
            np.dot(datoms.flatten(), neg_atoms.get_momenta().flatten()) >= 0) \
             * (np.dot(datoms.flatten(),
                       pos_atoms.get_momenta().flatten()) >= 0)
        cp += cpp
        return neg_atoms, pos_atoms, cp, sp
Beispiel #3
0
def check_leapfrog_reversibility(value):
    """
    Test leapfrog with non-trivial momentum in reverse

    Parameters
    ----------
    value: list or tuple
        The values to use in the tests
    """
    atoms = value[0]
    calc = Spring(rt=1, k=100)
    atoms.set_momenta(np.ones((len(atoms), 3)))
    atoms.set_calculator(calc)
    atoms2 = leapfrog(atoms, 1, False)
    atoms3 = leapfrog(atoms2, -1, False)
    stats_check(atoms.positions, atoms3.positions)
Beispiel #4
0
    def _find_step_size(self, input_atoms, thermal_nrg=None, momentum=None):
        """
        Find a suitable starting step size for the simulation

        Parameters
        -----------
        input_atoms: ase.Atoms object
            The starting atoms for the simulation
        thermal_nrg:
            The thermal energy for the simulation

        Returns
        -------
        float:
            The step size
        """
        atoms = dc(input_atoms)
        step_size = .5
        if thermal_nrg:
            MaxwellBoltzmannDistribution(atoms,
                                         temp=thermal_nrg,
                                         force_temp=True)
        elif momentum:
            atoms.set_momenta(
                self.random_state.normal(0, 1,
                                         (len(atoms), 3)) * self.momentum)
        else:
            print('Some thermal energy needed')

        atoms_prime = leapfrog(atoms, step_size)

        a = 2 * (np.exp(-1 * atoms_prime.get_total_energy() +
                        atoms.get_total_energy()) > 0.5) - 1

        while (np.exp(-1 * atoms_prime.get_total_energy() +
                      atoms.get_total_energy()))**a > 2**-a:
            step_size *= 2**a
            print('trying step size', step_size)
            atoms_prime = leapfrog(atoms, step_size)
            if step_size < 1e-7 or step_size > 1e7:
                step_size = 1.
                break
        print('optimal step size', step_size)
        return step_size
Beispiel #5
0
    def _find_step_size(self, input_atoms, thermal_nrg=None, momentum=None):
        """
        Find a suitable starting step size for the simulation

        Parameters
        -----------
        input_atoms: ase.Atoms object
            The starting atoms for the simulation
        thermal_nrg:
            The thermal energy for the simulation

        Returns
        -------
        float:
            The step size
        """
        atoms = dc(input_atoms)
        step_size = .5
        if thermal_nrg:
            MaxwellBoltzmannDistribution(atoms, temp=thermal_nrg,
                                         force_temp=True)
        elif momentum:
            atoms.set_momenta(self.random_state.normal(0, 1, (
                len(atoms), 3)))
        else:
            print('Some thermal energy needed')

        atoms_prime = leapfrog(atoms, step_size)

        a = 2 * (np.exp(
            -1 * atoms_prime.get_total_energy() + atoms.get_total_energy()
        ) > 0.5) - 1

        while (np.exp(-1 * atoms_prime.get_total_energy() +
                          atoms.get_total_energy())) ** a > 2 ** -a:
            step_size *= 2 ** a
            print('trying step size', step_size)
            atoms_prime = leapfrog(atoms, step_size)
            if step_size < 1e-7 or step_size > 1e7:
                step_size = 1.
                break
        print('optimal step size', step_size)
        return step_size
Beispiel #6
0
def check_leapfrog_no_momentum(value):
    """
    Test leapfrog with null forces

    Parameters
    ----------
    value: list or tuple
        The values to use in the tests
    """
    atoms = value[0]
    calc = Spring(rt=1, k=100)
    atoms.set_calculator(calc)
    atoms2 = leapfrog(atoms, 1, False)
    stats_check(atoms.positions, atoms2.positions)
Beispiel #7
0
def check_leapfrog_momentum(value):
    """
    Test leapfrog with non-trivial momentum

    Parameters
    ----------
    value: list or tuple
        The values to use in the tests
    """
    atoms = value[0]
    calc = Spring(rt=1, k=100)
    atoms.set_momenta(np.ones((len(atoms), 3)))
    atoms.set_calculator(calc)
    atoms2 = leapfrog(atoms, 1, False)
    stats_check(atoms.positions, atoms2.positions - atoms.get_velocities())
Beispiel #8
0
def classical_dynamics(atoms, stepsize, n_steps):
    """
    Create a new atomic configuration by simulating the hamiltonian dynamics
    of the system

    Parameters
    ----------
    atoms: ase.Atoms ase.Atoms
        The atomic configuration
    stepsize: float
        The step size for the simulation
    n_steps: int
        The number of steps

    Returns
    -------
         list of ase.Atoms
        This list contains all the moves made during the simulation
    """
    atoms.get_forces()
    traj = [atoms]
    for n in range(n_steps):
        traj.append(leapfrog(traj[-1], stepsize))
    return traj
Beispiel #9
0
def classical_dynamics(atoms, stepsize, n_steps):
    """
    Create a new atomic configuration by simulating the hamiltonian dynamics
    of the system

    Parameters
    ----------
    atoms: ase.Atoms ase.Atoms
        The atomic configuration
    stepsize: float
        The step size for the simulation
    n_steps: int
        The number of steps

    Returns
    -------
         list of ase.Atoms
        This list contains all the moves made during the simulation
    """
    atoms.get_forces()
    traj = [atoms]
    for n in range(n_steps):
        traj.append(leapfrog(traj[-1], stepsize))
    return traj
Beispiel #10
0
def buildtree(input_atoms, u, v, j, e, e0, rs, beta=1):
    """
    Build the tree of samples for NUTS, recursively

    Parameters
    -----------
    input_atoms: ase.Atoms object
        The atoms for the tree
    u: float
        slice parameter, the baseline energy to compare against
    v: -1 or 1
        The direction of the tree leaves, negative means that we simulate
        backwards in time
    j: int
        The tree depth
    e: float
        The stepsize
    e0: float
        Current energy
    rs: numpy.random.RandomState object
        The random state object used to generate the random numbers.  Use of a
        unified random number generator with a known seed should help us to
        generate reproducible simulations
    beta: float
        Thermodynamic beta, a proxy for thermal energy
    Returns
    -------
    Many things
    """
    if j == 0:
        atoms_prime = leapfrog(input_atoms, v * e)
        neg_delta_energy = e0 - atoms_prime.get_total_energy()
        try:
            exp1 = np.exp(neg_delta_energy)
            exp2 = np.exp(Emax + neg_delta_energy)
        except:
            exp1 = 0
            exp2 = 0
        # print exp1, exp2
        # n_prime = int(u <= np.exp(-atoms_prime.get_total_energy()))
        # s_prime = int(u <= np.exp(Emax-atoms_prime.get_total_energy()))
        n_prime = int(u <= exp1)
        s_prime = int(u < exp2)
        return (atoms_prime, atoms_prime, atoms_prime, n_prime, s_prime,
                min(1, np.exp(-atoms_prime.get_total_energy() +
                              input_atoms.get_total_energy())), 1)
    else:
        (neg_atoms, pos_atoms, atoms_prime, n_prime, s_prime, a_prime,
         na_prime) = buildtree(input_atoms, u, v, j - 1, e, e0, rs, beta)
        if s_prime == 1:
            if v == -1:
                (neg_atoms, _, atoms_prime_prime, n_prime_prime, s_prime_prime,
                 app, napp) = buildtree(neg_atoms, u, v, j - 1, e, e0, rs,
                                        beta)
            else:
                (_, pos_atoms, atoms_prime_prime, n_prime_prime, s_prime_prime,
                 app, napp) = buildtree(pos_atoms, u, v, j - 1, e, e0, rs,
                                        beta)

            if rs.uniform() < float(n_prime_prime / (
                    max(n_prime + n_prime_prime, 1))):
                atoms_prime = atoms_prime_prime

            a_prime = a_prime + app
            na_prime = na_prime + napp

            datoms = pos_atoms.positions - neg_atoms.positions
            span = datoms.flatten()
            s_prime = s_prime_prime * (
                span.dot(neg_atoms.get_velocities().flatten()) >= 0) * (
                          span.dot(pos_atoms.get_velocities().flatten()) >= 0)
            n_prime = n_prime + n_prime_prime
        return (neg_atoms, pos_atoms, atoms_prime, n_prime, s_prime, a_prime,
                na_prime)
Beispiel #11
0
def buildtree(input_atoms, u, v, j, e, e0, rs, beta=1):
    """
    Build the tree of samples for NUTS, recursively

    Parameters
    -----------
    input_atoms: ase.Atoms object
        The atoms for the tree
    u: float
        slice parameter, the baseline energy to compare against
    v: -1 or 1
        The direction of the tree leaves, negative means that we simulate
        backwards in time
    j: int
        The tree depth
    e: float
        The stepsize
    e0: float
        Current energy
    rs: numpy.random.RandomState object
        The random state object used to generate the random numbers.  Use of a
        unified random number generator with a known seed should help us to
        generate reproducible simulations
    beta: float
        Thermodynamic beta, a proxy for thermal energy
    Returns
    -------
    Many things
    """
    if j == 0:
        atoms_prime = leapfrog(input_atoms, v * e)
        neg_delta_energy = e0 - atoms_prime.get_total_energy()
        try:
            exp1 = np.exp(neg_delta_energy)
            exp2 = np.exp(Emax + neg_delta_energy)
        except:
            exp1 = 0
            exp2 = 0
        # print exp1, exp2
        # n_prime = int(u <= np.exp(-atoms_prime.get_total_energy()))
        # s_prime = int(u <= np.exp(Emax-atoms_prime.get_total_energy()))
        n_prime = int(u <= exp1)
        s_prime = int(u < exp2)
        return (atoms_prime, atoms_prime, atoms_prime, n_prime, s_prime,
                min(
                    1,
                    np.exp(-atoms_prime.get_total_energy() +
                           input_atoms.get_total_energy())), 1)
    else:
        (neg_atoms, pos_atoms, atoms_prime, n_prime, s_prime, a_prime,
         na_prime) = buildtree(input_atoms, u, v, j - 1, e, e0, rs, beta)
        if s_prime == 1:
            if v == -1:
                (neg_atoms, _, atoms_prime_prime, n_prime_prime, s_prime_prime,
                 app, napp) = buildtree(neg_atoms, u, v, j - 1, e, e0, rs,
                                        beta)
            else:
                (_, pos_atoms, atoms_prime_prime, n_prime_prime, s_prime_prime,
                 app, napp) = buildtree(pos_atoms, u, v, j - 1, e, e0, rs,
                                        beta)

            if rs.uniform() < float(n_prime_prime /
                                    (max(n_prime + n_prime_prime, 1))):
                atoms_prime = atoms_prime_prime

            a_prime = a_prime + app
            na_prime = na_prime + napp

            datoms = pos_atoms.positions - neg_atoms.positions
            span = datoms.flatten()
            s_prime = s_prime_prime * (span.dot(
                neg_atoms.get_velocities().flatten()) >= 0) * (span.dot(
                    pos_atoms.get_velocities().flatten()) >= 0)
            n_prime = n_prime + n_prime_prime
        return (neg_atoms, pos_atoms, atoms_prime, n_prime, s_prime, a_prime,
                na_prime)