
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\06-PyPoscar\plot_subsitution_pyposcar.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_06-PyPoscar_plot_subsitution_pyposcar.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_06-PyPoscar_plot_subsitution_pyposcar.py:


.. _ref_subsitution_poscar:

Substituting Atoms in a POSCAR File
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In this example, we'll demonstrate how to substitute atoms in a POSCAR file using the `pyprocar` package. 
Specifically, we will:

1. Read a POSCAR file containing atomic positions and lattice vectors.
2. Visualize the initial atomic positions.
3. Substitute a boron (B) atom with a nitrogen (N) atom.
4. Visualize the atomic positions after the substitution.
5. Create GIFs to visualize the atomic structures from different angles.

Before diving in, make sure to have `pyvista`, `numpy`, and `pyprocar` installed.

.. GENERATED FROM PYTHON SOURCE LINES 18-33

.. code-block:: Python


    import os
    from itertools import product

    import numpy as np
    import pyvista as pv

    import pyprocar.pyposcar as p
    from pyprocar.utils import DATA_DIR

    # Define the data directory
    data_dir = os.path.join(DATA_DIR, "examples", "PyPoscar", "00-Poscar")
    # You do not need this. This is to ensure an image is rendered off screen when generating exmaple gallery.
    pv.OFF_SCREEN = True








.. GENERATED FROM PYTHON SOURCE LINES 34-36

Reading and Parsing the POSCAR File
++++++++++++++++++++++++++++++++++++

.. GENERATED FROM PYTHON SOURCE LINES 36-55

.. code-block:: Python


    # Read the POSCAR file
    a = p.Poscar(os.path.join(data_dir, "POSCAR-YB6.vasp"))
    a.parse()

    # Display lattice, elements, and positions
    print("Lattice:")
    print(a.lat)
    print("\nElements:")
    print(a.elm)
    print("\nPositions in Direct coordinates")
    print(a.dpos)


    # Convert positions to Cartesian coordinates for visualization
    atoms_before = pv.PolyData(np.dot(a.dpos, a.lat))
    atoms_before["atoms"] = a.elm
    labels_before = [elm + f":{point}" for elm, point in zip(a.elm, a.dpos)]





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Lattice:
    [[4.098 0.    0.   ]
     [0.    4.098 0.   ]
     [0.    0.    4.098]]

    Elements:
    ['B', 'B', 'B', 'B', 'B', 'B', 'Y']

    Positions in Direct coordinates
    [[ 0.1989  0.5     0.5   ]
     [ 0.8011  0.5     0.5   ]
     [ 0.5     0.1989  0.5   ]
     [ 0.5     0.8011  0.5   ]
     [ 0.5     0.5     0.1989]
     [ 0.5     0.5     0.8011]
     [-0.     -0.      0.    ]]




.. GENERATED FROM PYTHON SOURCE LINES 56-58

Atom Substitution
+++++++++++++++++

.. GENERATED FROM PYTHON SOURCE LINES 58-84

.. code-block:: Python


    # Substitute the second B atom with an N atom
    print("\n\nChanging the the second atom from B to N\n" + "-" * 40)
    new_pos = a.dpos[1]
    a.remove(atoms=1)
    a.add(position=new_pos, element="N", direct=True)
    print("\nElements after substitution:")
    print(a.elm)
    print("\nPositions in Direct coordinates after substitution:")
    print(a.dpos)

    # Define the unit cell using lattice vectors
    unit_cell_comb = list(product([0, 1], repeat=3))
    unit_cell = np.array(
        [
            comb[0] * a.lat[0] + comb[1] * a.lat[1] + comb[2] * a.lat[2]
            for comb in unit_cell_comb
        ]
    )
    unit_cell = pv.PolyData(unit_cell)

    # Convert positions to Cartesian coordinates for visualization
    atoms_after = pv.PolyData(np.dot(a.dpos, a.lat))
    atoms_after["atoms"] = a.elm
    labels_after = [elm + f":{point}" for elm, point in zip(a.elm, a.dpos)]





.. rst-class:: sphx-glr-script-out

 .. code-block:: none



    Changing the the second atom from B to N
    ----------------------------------------

    Elements after substitution:
    ['B', 'B', 'B', 'B', 'B', 'Y', 'N']

    Positions in Direct coordinates after substitution:
    [[ 0.1989  0.5     0.5   ]
     [ 0.5     0.1989  0.5   ]
     [ 0.5     0.8011  0.5   ]
     [ 0.5     0.5     0.1989]
     [ 0.5     0.5     0.8011]
     [-0.     -0.      0.    ]
     [ 0.8011  0.5     0.5   ]]




.. GENERATED FROM PYTHON SOURCE LINES 85-87

Visualization of Atomic Structures
++++++++++++++++++++++++++++++++++

.. GENERATED FROM PYTHON SOURCE LINES 87-136

.. code-block:: Python


    # Visualize the atomic structures side by side
    plotter = pv.Plotter(shape=(1, 2), border=False)
    # Before substitution
    plotter.subplot(0, 0)
    plotter.add_mesh(
        unit_cell.delaunay_3d().extract_feature_edges(),
        color="black",
        line_width=5,
        render_lines_as_tubes=True,
    )
    plotter.add_point_labels(
        points=atoms_before.points,
        labels=labels_before,
        show_points=False,
        always_visible=True,
    )
    plotter.add_mesh(
        atoms_before,
        scalars="atoms",
        point_size=30,
        render_points_as_spheres=True,
        show_scalar_bar=False,
    )
    plotter.add_title("Before substitution")
    # After substitution
    plotter.subplot(0, 1)
    plotter.add_mesh(
        unit_cell.delaunay_3d().extract_feature_edges(),
        color="black",
        line_width=5,
        render_lines_as_tubes=True,
    )
    plotter.add_point_labels(
        points=atoms_after.points,
        labels=labels_after,
        show_points=False,
        always_visible=True,
    )
    plotter.add_mesh(
        atoms_after,
        scalars="atoms",
        point_size=30,
        render_points_as_spheres=True,
        show_scalar_bar=False,
    )
    plotter.add_title("After substitution")
    plotter.show()




.. image-sg:: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_001.png
   :alt: plot subsitution pyposcar
   :srcset: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 137-139

Creating GIFs for Visualization
+++++++++++++++++++++++++++++++

.. GENERATED FROM PYTHON SOURCE LINES 139-181

.. code-block:: Python



    # Define a function to create a GIF visualization of the atomic structure
    def create_gif(atoms, labels, unit_cell, save_file):
        plotter = pv.Plotter()
        title = save_file.split(os.sep)[-1].split(".")[0]
        plotter.add_title(title)
        plotter.add_mesh(
            unit_cell.delaunay_3d().extract_feature_edges(),
            color="black",
            line_width=5,
            render_lines_as_tubes=True,
        )
        plotter.add_point_labels(
            points=atoms.points, labels=labels, show_points=False, always_visible=True
        )
        plotter.add_mesh(
            atoms,
            scalars="atoms",
            point_size=30,
            render_points_as_spheres=True,
            show_scalar_bar=False,
        )
        path = plotter.generate_orbital_path(n_points=36)
        plotter.open_gif(os.path.join(data_dir, save_file))
        plotter.orbit_on_path(path, write_frames=True, viewup=[0, 0, 1], step=0.05)
        plotter.close()


    # Create GIFs for atomic structures before and after substitution
    create_gif(
        atoms=atoms_before,
        labels=labels_before,
        unit_cell=unit_cell,
        save_file="atoms_before.gif",
    )
    create_gif(
        atoms=atoms_after,
        labels=labels_after,
        unit_cell=unit_cell,
        save_file="atoms_after.gif",
    )



.. rst-class:: sphx-glr-horizontal


    *

      .. image-sg:: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_002.gif
          :alt: plot subsitution pyposcar
          :srcset: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_002.gif
          :class: sphx-glr-multi-img

    *

      .. image-sg:: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_003.gif
          :alt: plot subsitution pyposcar
          :srcset: /examples/06-PyPoscar/images/sphx_glr_plot_subsitution_pyposcar_003.gif
          :class: sphx-glr-multi-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 8.542 seconds)


.. _sphx_glr_download_examples_06-PyPoscar_plot_subsitution_pyposcar.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_subsitution_pyposcar.ipynb <plot_subsitution_pyposcar.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_subsitution_pyposcar.py <plot_subsitution_pyposcar.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_subsitution_pyposcar.zip <plot_subsitution_pyposcar.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
