.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples_generated/01-gettingstarted/03-manipulating-atoms.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_generated_01-gettingstarted_03-manipulating-atoms.py: .. _manipulatingatoms: Manipulating Atoms ================== This tutorial shows how to build and manipulate structures with ASE. .. GENERATED FROM PYTHON SOURCE LINES 11-16 Ag adatom on Ni slab -------------------- We will set up a one layer slab of four Ni atoms with one Ag adatom. Define the slab atoms: .. GENERATED FROM PYTHON SOURCE LINES 16-30 .. code-block:: Python from math import sqrt from ase import Atoms a = 3.55 atoms = Atoms( 'Ni4', cell=[sqrt(2) * a, sqrt(2) * a, 1.0, 90, 90, 120], pbc=(1, 1, 0), scaled_positions=[(0, 0, 0), (0.5, 0, 0), (0, 0.5, 0), (0.5, 0.5, 0)], ) atoms.center(vacuum=5.0, axis=2) .. GENERATED FROM PYTHON SOURCE LINES 31-32 Have a look at the cell and positions of the atoms: .. GENERATED FROM PYTHON SOURCE LINES 32-34 .. code-block:: Python print(atoms.cell) .. rst-class:: sphx-glr-script-out .. code-block:: none Cell([[5.020458146424487, 0.0, 0.0], [-2.5102290732122423, 4.347844293440141, 0.0], [0.0, 0.0, 10.0]]) .. GENERATED FROM PYTHON SOURCE LINES 36-37 .. code-block:: Python print(atoms.positions) .. rst-class:: sphx-glr-script-out .. code-block:: none [[ 0. 0. 5. ] [ 2.51022907 0. 5. ] [-1.25511454 2.17392215 5. ] [ 1.25511454 2.17392215 5. ]] .. GENERATED FROM PYTHON SOURCE LINES 39-41 .. code-block:: Python print(atoms[0]) .. rst-class:: sphx-glr-script-out .. code-block:: none Atom('Ni', [np.float64(0.0), np.float64(0.0), np.float64(5.0)], index=0) .. GENERATED FROM PYTHON SOURCE LINES 42-53 Visualizing a structure ^^^^^^^^^^^^^^^^^^^^^^^ Write the structure to a file and plot the whole system by bringing up the :mod:`ase.gui`: .. code-block:: python from ase.visualize import view atoms.write('slab.xyz') view(atoms) .. GENERATED FROM PYTHON SOURCE LINES 55-61 Alternatively, we can plot structures with Matplotlib. Throughout this tutorial, we will be using matplotlib to visualize the structures. Note, however, that in practice using the view function or opening structures in the :mod:`ase gui ` directly from the terminal with ``ase gui structure.xyz`` gives an interactive view, which might be preferred. .. GENERATED FROM PYTHON SOURCE LINES 61-69 .. code-block:: Python import matplotlib.pyplot as plt from ase.visualize.plot import plot_atoms fig, ax = plt.subplots() plot_atoms(atoms, ax, rotation=('-80x,0y,0z')) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_001.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 70-72 Note that we added the ``rotation`` argument, so that we can get a side view of the cell. .. GENERATED FROM PYTHON SOURCE LINES 74-84 Repeating a structure ^^^^^^^^^^^^^^^^^^^^^ Within the viewer (called :mod:`ase gui `) it is possible to repeat the unit cell in all three directions (using the :menuselection:`Repeat --> View` window). From the command line, use ``ase gui -r 3,3,2 slab.xyz``. Alternatively, you can also do this directly in ase with the repeat function of the Atoms object. .. GENERATED FROM PYTHON SOURCE LINES 84-87 .. code-block:: Python atoms_repeated = atoms.repeat((3, 3, 2)) .. GENERATED FROM PYTHON SOURCE LINES 88-90 This gives a repeated atoms object. We visualize it here again in matplotlib. .. GENERATED FROM PYTHON SOURCE LINES 90-94 .. code-block:: Python fig, ax = plt.subplots() plot_atoms(atoms_repeated, ax, rotation=('-80x,0y,0z')) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_002.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 95-100 Adding atoms ^^^^^^^^^^^^ We now add an adatom in a three-fold site at a height of ``h=1.9`` Å: To generate the new positions of the adatom, we are using numpy. .. GENERATED FROM PYTHON SOURCE LINES 100-109 .. code-block:: Python import numpy as np h = 1.9 relative = (1 / 6, 1 / 6, 0.5) absolute = np.dot(relative, atoms.cell) + (0, 0, h) atoms.append('Ag') atoms.positions[-1] = absolute .. GENERATED FROM PYTHON SOURCE LINES 110-111 The structure now looks like this: .. GENERATED FROM PYTHON SOURCE LINES 111-115 .. code-block:: Python fig, ax = plt.subplots() plot_atoms(atoms, ax, rotation=('-80x,0y,0z')) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_003.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 116-123 Interface building ================== Now, we will make an interface with Ni(111) and water. First we need a layer of water. One layer of water is constructed in the following script and saved in the file ``water.traj``. .. GENERATED FROM PYTHON SOURCE LINES 123-148 .. code-block:: Python import numpy as np from ase import Atoms p = np.array( [ [0.27802511, -0.07732213, 13.46649107], [0.91833251, -1.02565868, 13.41456626], [0.91865997, 0.87076761, 13.41228287], [1.85572027, 2.37336781, 13.56440907], [3.13987926, 2.3633134, 13.4327577], [1.77566079, 2.37150862, 14.66528237], [4.52240322, 2.35264513, 13.37435864], [5.16892729, 1.40357034, 13.42661052], [5.15567324, 3.30068395, 13.4305779], [6.10183518, -0.0738656, 13.27945071], [7.3856151, -0.07438536, 13.40814585], [6.01881192, -0.08627583, 12.1789428], ] ) c = np.array([[8.490373, 0.0, 0.0], [0.0, 4.901919, 0.0], [0.0, 0.0, 26.93236]]) water = Atoms('4(OH2)', positions=p, cell=c, pbc=[1, 1, 0]) water.write('water.traj') .. GENERATED FROM PYTHON SOURCE LINES 149-151 With the atoms object saved as trajectory file, we can also read the atoms from this file. .. GENERATED FROM PYTHON SOURCE LINES 151-156 .. code-block:: Python from ase.io import read water = read('water.traj') .. GENERATED FROM PYTHON SOURCE LINES 157-161 Visualization ------------- Lets take a look at the structure. For this, you can use view to open the ASE gui as show above. Here, we are using matplotlib again. .. GENERATED FROM PYTHON SOURCE LINES 161-165 .. code-block:: Python fig, ax = plt.subplots() plot_atoms(water, ax) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_004.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_004.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 166-167 and let's look at the unit cell. .. GENERATED FROM PYTHON SOURCE LINES 167-170 .. code-block:: Python print(water.cell) .. rst-class:: sphx-glr-script-out .. code-block:: none Cell([8.490373, 4.901919, 26.93236]) .. GENERATED FROM PYTHON SOURCE LINES 171-175 Creating a Ni slab ------------------ We will need a Ni(111) slab which matches the water as closely as possible. A 2x4 orthogonal fcc111 supercell should be good enough. .. GENERATED FROM PYTHON SOURCE LINES 175-185 .. code-block:: Python from ase.build import fcc111 slab = fcc111('Ni', size=[2, 4, 3], a=3.55, orthogonal=True) fig, ax = plt.subplots() plot_atoms(slab, ax) print(slab.cell) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_005.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_005.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Cell([5.020458146424487, 8.695688586880282, 0.0]) .. GENERATED FROM PYTHON SOURCE LINES 186-191 Manipulating a Structure ------------------------ Looking at the two unit cells, we can see that they match with around 2 percent difference, if we rotate one of the cells 90 degrees in the plane. Let's rotate the cell: .. GENERATED FROM PYTHON SOURCE LINES 191-197 .. code-block:: Python water.cell = [water.cell[1, 1], water.cell[0, 0], 0.0] fig, ax = plt.subplots() plot_atoms(water, ax) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_006.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_006.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 198-199 Let's also :meth:`~ase.Atoms.rotate` the molecules: .. GENERATED FROM PYTHON SOURCE LINES 199-205 .. code-block:: Python water.rotate(90, 'z', center=(0, 0, 0)) fig, ax = plt.subplots() plot_atoms(water, ax) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_007.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_007.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 206-207 Now we can wrap the atoms into the cell .. GENERATED FROM PYTHON SOURCE LINES 207-212 .. code-block:: Python water.wrap() fig, ax = plt.subplots() plot_atoms(water, ax) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_008.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_008.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 213-220 The :meth:`~ase.Atoms.wrap` method only works if periodic boundary conditions are enabled. We have a 2 percent lattice mismatch between Ni(111) and the water, so we scale the water in the plane to match the cell of the slab. The argument *scale_atoms=True* indicates that the atomic positions should be scaled with the unit cell. The default is *scale_atoms=False* indicating that the cartesian coordinates remain the same when the cell is changed. .. GENERATED FROM PYTHON SOURCE LINES 220-226 .. code-block:: Python water.set_cell(slab.cell, scale_atoms=True) zmin = water.positions[:, 2].min() zmax = slab.positions[:, 2].max() water.positions += (0, 0, zmax - zmin + 1.5) .. GENERATED FROM PYTHON SOURCE LINES 227-230 Adding one Structure to the Other --------------------------------- Finally we add the water onto the slab: .. GENERATED FROM PYTHON SOURCE LINES 230-238 .. code-block:: Python interface = slab + water interface.center(vacuum=6, axis=2) interface.write('NiH2O.traj') fig, ax = plt.subplots() plot_atoms(interface, ax) .. image-sg:: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_009.png :alt: 03 manipulating atoms :srcset: /examples_generated/01-gettingstarted/images/sphx_glr_03-manipulating-atoms_009.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 239-241 Adding two atoms objects will take the positions from both and the cell and boundary conditions from the first. .. _sphx_glr_download_examples_generated_01-gettingstarted_03-manipulating-atoms.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 03-manipulating-atoms.ipynb <03-manipulating-atoms.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 03-manipulating-atoms.py <03-manipulating-atoms.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 03-manipulating-atoms.zip <03-manipulating-atoms.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_