def test_diffusion_coefficient():
    from ase.md.analysis import DiffusionCoefficient
    from ase.atoms import Atoms
    from ase.units import fs as fs_conversion

    eps = 1e-10
    # Creating simple trajectories
    # Textbook case. The displacement coefficient should be 0.5 A^2 / fs except for the final molecule

    ###### He atom

    he = Atoms('He', positions=[(0, 0, 0)])
    traj_he = [he.copy() for i in range(2)]
    traj_he[1].set_positions([(1, 1, 1)])

    timestep = 1 * fs_conversion #fs

    dc_he = DiffusionCoefficient(traj_he, timestep)
    dc_he.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_he.get_diffusion_coefficients()[0][0]
    # Answer in \AA^2/<ASE time unit>
    ans_orig = 5.0e-01 / fs_conversion
    #dc_he.print_data()

    assert(abs(ans - ans_orig) < eps)

    ###### CO molecule

    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, 1)])
    traj_co = [co.copy() for i in range(2)]
    traj_co[1].set_positions([(-1, -1, -1), (-1, -1, 0)])

    dc_co = DiffusionCoefficient(traj_co, timestep, molecule=False)
    dc_co.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_co.get_diffusion_coefficients()[0][0]
    #dc_co.print_data()

    assert(abs(ans - ans_orig) < eps)

    for index in range(2):
        dc_co = DiffusionCoefficient(traj_co, timestep, atom_indices=[index], molecule=False)
        dc_co.calculate() 
        ans = dc_co.get_diffusion_coefficients()[0][0]
        assert(abs(ans - ans_orig) < eps)

    dc_co = DiffusionCoefficient(traj_co, timestep, molecule=True)
    dc_co.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_co.get_diffusion_coefficients()[0][0]
    #dc_co.print_data()

    assert(abs(ans - ans_orig) < eps)
Beispiel #2
0
def test_co_molecule():
    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, 1)])
    traj_co = [co.copy() for i in range(2)]
    traj_co[1].set_positions([(-1, -1, -1), (-1, -1, 0)])

    dc_co = DiffusionCoefficient(traj_co, timestep, molecule=False)
    dc_co.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_co.get_diffusion_coefficients()[0][0]

    assert (abs(ans - ans_orig) < eps)

    for index in range(2):
        dc_co = DiffusionCoefficient(traj_co,
                                     timestep,
                                     atom_indices=[index],
                                     molecule=False)
        dc_co.calculate()
        ans = dc_co.get_diffusion_coefficients()[0][0]
        assert (abs(ans - ans_orig) < eps)

    dc_co = DiffusionCoefficient(traj_co, timestep, molecule=True)
    dc_co.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_co.get_diffusion_coefficients()[0][0]

    assert (abs(ans - ans_orig) < eps)
Beispiel #3
0
    def _get_jmol_images(
        atoms: Atoms,
        energies: np.ndarray,
        modes: np.ndarray,
        ir_intensities: Union[Sequence[float], np.ndarray] = None
    ) -> Iterator[Atoms]:
        """Get vibrational modes as a series of Atoms with attached data

        For each image (Atoms object):

            - eigenvalues are attached to image.arrays['mode']
            - "mode#" and "frequency_cm-1" are set in image.info
            - "IR_intensity" is set if provided in ir_intensities
            - "masses" is removed

        This is intended to set up the object for JMOL-compatible export using
        ase.io.extxyz.


        Args:
            atoms: The base atoms object; all images have the same positions
            energies: Complex vibrational energies in eV
            modes: Eigenvectors array corresponding to atoms and energies. This
                should cover the full set of atoms (i.e. modes =
                vib.get_modes(all_atoms=True)).
            ir_intensities: If available, IR intensities can be included in the
                header lines. This does not affect the visualisation, but may
                be convenient when comparing to experimental data.
        Returns:
            Iterator of Atoms objects

        """
        for i, (energy, mode) in enumerate(zip(energies, modes)):
            # write imaginary frequencies as negative numbers
            if energy.imag > energy.real:
                energy = float(-energy.imag)
            else:
                energy = energy.real

            image = atoms.copy()
            image.info.update({
                'mode#': str(i),
                'frequency_cm-1': energy / units.invcm,
            })
            image.arrays['mode'] = mode

            # Custom masses are quite useful in vibration analysis, but will
            # show up in the xyz file unless we remove them
            if image.has('masses'):
                del image.arrays['masses']

            if ir_intensities is not None:
                image.info['IR_intensity'] = float(ir_intensities[i])

            yield image
Beispiel #4
0
    def update(self, atoms: Atoms):
        if atoms is None and self.atoms is None:
            raise RuntimeError("Need an Atoms object to do anything!")

        changes = compare_atoms(self.atoms, atoms)

        if changes:
            self.results = {}
            self.atoms = atoms.copy()

            if self.need_setup(changes):
                self.setup()
Beispiel #5
0
def test_atom():
    # Creating simple trajectories
    # Textbook case. The displacement coefficient should
    # be 0.5 A^2 / fs except for the final molecule

    # He atom

    he = Atoms('He', positions=[(0, 0, 0)])
    traj_he = [he.copy() for i in range(2)]
    traj_he[1].set_positions([(1, 1, 1)])

    dc_he = DiffusionCoefficient(traj_he, timestep)
    dc_he.calculate(ignore_n_images=0, number_of_segments=1)
    ans = dc_he.get_diffusion_coefficients()[0][0]

    assert (abs(ans - ans_orig) < eps)
Beispiel #6
0
    def __init__(
        self,
        atoms: Atoms,
        hessian: Union[RealSequence4D, np.ndarray],
        indices: Union[Sequence[int], np.ndarray] = None,
    ) -> None:

        if indices is None:
            self._indices = np.arange(len(atoms), dtype=int)
        else:
            self._indices = np.array(indices, dtype=int)

        n_atoms = self._check_dimensions(atoms,
                                         np.asarray(hessian),
                                         indices=self._indices)
        self._atoms = atoms.copy()

        self._hessian2d = (np.asarray(hessian).reshape(3 * n_atoms,
                                                       3 * n_atoms).copy())
Beispiel #7
0
def center_at_origin(atoms: Atoms) -> Atoms:
    """
    Returns a copy of the atoms object centered at the lowest atoms in the z axis
    :param atoms: Atoms object
    :return: Copy of the translated Atoms object
    """
    ads = atoms.copy()
    if len(ads) == 1:
        ads[0].position = (0, 0, 0)
    else:
        tags, layer_pos = get_layers(ads, (0, 0, 1), 0.3)

        if sum(tags == 0) == 1:
            center = atoms[0].position
        else:
            lowest_atoms = ads[tags == 0]
            center = np.mean([a.position for a in lowest_atoms], axis=0)

        ads.translate(-center)
    return ads
Beispiel #8
0
positions = np.array(
    [
        [4.0725, -4.0725, -1.3575],
        [1.3575, -1.3575, -1.3575],
        [2.715, -2.715, 0.0],
        [4.0725, 1.3575, -1.3575],
        [0.0, 0.0, 0.0],
        [2.715, 2.715, 0.0],
        [6.7875, -1.3575, -1.3575],
        [5.43, 0.0, 0.0],
    ]
)
cell = np.array([[5.43, 5.43, 0.0], [5.43, -5.43, 0.0], [0.00, 0.00, 40.0]])
atoms = Atoms(positions=positions, symbols=["Si"] * 8, cell=cell, pbc=[True, True, False])
atoms.translate(np.array([6.1, -0.1, 10.1]))
result_atoms = atoms.copy()
result_atoms.wrap()
correct_pos = np.array(
    [
        [4.7425, 1.2575, 8.7425],
        [7.4575, -1.4575, 8.7425],
        [3.385, 2.615, 10.1],
        [4.7425, -4.1725, 8.7425],
        [6.1, -0.1, 10.1],
        [3.385, -2.815, 10.1],
        [2.0275, -1.4575, 8.7425],
        [0.67, -0.1, 10.1],
    ]
)
assert np.allclose(correct_pos, result_atoms.get_positions())
from ase.md.analysis import DiffusionCoefficient
from ase.atoms import Atoms
from ase.units import fs as fs_conversion

eps = 1e-10
# Creating simple trajectories
# Textbook case. The displacement coefficient should be 0.5 A^2 / fs except for the final molecule

###### He atom

he = Atoms('He', positions=[(0, 0, 0)])
traj_he = [he.copy() for i in range(2)]
traj_he[1].set_positions([(1, 1, 1)])

timestep = 1 * fs_conversion  #fs

dc_he = DiffusionCoefficient(traj_he, timestep)
dc_he.calculate(ignore_n_images=0, number_of_segments=1)
ans = dc_he.get_diffusion_coefficients()[0][0]
# Answer in \AA^2/<ASE time unit>
ans_orig = 5.0e-01 / fs_conversion
#dc_he.print_data()

assert (abs(ans - ans_orig) < eps)

###### CO molecule

co = Atoms('CO', positions=[(0, 0, 0), (0, 0, 1)])
traj_co = [co.copy() for i in range(2)]
traj_co[1].set_positions([(-1, -1, -1), (-1, -1, 0)])
Beispiel #10
0
    def copy(self):
        atoms = AseAtoms.copy(self)
        atoms.transfer(self)
        atoms.set_celldisp(self.get_celldisp())

        return atoms