{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Finding defects in a POSCAR file\n\nIn this example, we'll demonstrate how to automatically find defects in a POSCAR file\n\nLet's get started!\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import os\nfrom itertools import product\n\nimport numpy as np\nimport pyvista as pv\n\nimport pyprocar.pyposcar as p\nfrom pyprocar.utils import DATA_DIR\n\ndata_dir = os.path.join(DATA_DIR, \"examples\", \"PyPoscar\", \"03-defects\")\n# You do not need this. This is to ensure an image is rendered off screen when generating exmaple gallery.\npv.OFF_SCREEN = True"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Utility function for creating GIF visualizations\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def create_gif(atoms, labels, unit_cell, save_file):\n    plotter = pv.Plotter()\n    title = save_file.split(os.sep)[-1].split(\".\")[0]\n    plotter.add_title(title)\n    plotter.add_mesh(\n        unit_cell.delaunay_3d().extract_feature_edges(),\n        color=\"black\",\n        line_width=5,\n        render_lines_as_tubes=True,\n    )\n    plotter.add_point_labels(\n        points=atoms.points, labels=labels, show_points=False, always_visible=True\n    )\n    plotter.add_mesh(\n        atoms,\n        scalars=\"atoms\",\n        point_size=30,\n        render_points_as_spheres=True,\n        show_scalar_bar=False,\n    )\n    path = plotter.generate_orbital_path(n_points=36)\n    plotter.open_gif(os.path.join(data_dir, save_file))\n    plotter.orbit_on_path(path, write_frames=True, viewup=[0, 0, 1], step=0.05)\n    plotter.close()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Finding defects\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(\"Loading an AGNR with a defect in it\")\na = p.poscar.Poscar(os.path.join(data_dir, \"POSCAR-AGNR-defect.vasp\"), verbose=False)\na.parse()\n\ndefects = p.defects.FindDefect(a)\nprint(\"The defects are:\")\nprint(defects.all_defects)\n\nprint(\"\\n\\nThe warning above indicates that there are two different types of defects\")\n\nprint(\"saving a file with the defects, defects.vasp\")\ndefects.write_defects(filename=os.path.join(data_dir, \"defects.vasp\"))\nprint(\n    \"Inspection of the file defects.vasp shows that the first type of defects are subtitutionals (0D), and the second are the AGRN edges (1D)\"\n)\n\n\ntmp_a = p.Poscar(os.path.join(data_dir, \"POSCAR-AGNR-defect.vasp\"))\ntmp_a.parse()\n\n# Convert positions to Cartesian coordinates for visualization\natoms_before = pv.PolyData(np.dot(tmp_a.dpos, tmp_a.lat))\natoms_before[\"atoms\"] = tmp_a.elm\nlabels_before = [elm for elm, point in zip(tmp_a.elm, tmp_a.dpos)]\n# Define the unit cell using lattice vectors\nunit_cell_comb = list(product([0, 1], repeat=3))\nunit_cell = np.array(\n    [\n        comb[0] * tmp_a.lat[0] + comb[1] * tmp_a.lat[1] + comb[2] * tmp_a.lat[2]\n        for comb in unit_cell_comb\n    ]\n)\nunit_cell_before = pv.PolyData(unit_cell)\n\ntmp_a = p.Poscar(os.path.join(data_dir, \"defects.vasp\"))\ntmp_a.parse()\n\n# Convert positions to Cartesian coordinates for visualization\natoms_after = pv.PolyData(np.dot(tmp_a.dpos, tmp_a.lat))\natoms_after[\"atoms\"] = tmp_a.elm\nlabels_after = [elm for elm, point in zip(tmp_a.elm, tmp_a.dpos)]\n# Define the unit cell using lattice vectors\nunit_cell_comb = list(product([0, 1], repeat=3))\nunit_cell = np.array(\n    [\n        comb[0] * tmp_a.lat[0] + comb[1] * tmp_a.lat[1] + comb[2] * tmp_a.lat[2]\n        for comb in unit_cell_comb\n    ]\n)\nunit_cell_after = pv.PolyData(unit_cell)\n\ncreate_gif(\n    atoms=atoms_before,\n    labels=labels_before,\n    unit_cell=unit_cell_before,\n    save_file=\"atoms_before_defect_finding.gif\",\n)\ncreate_gif(\n    atoms=atoms_after,\n    labels=labels_after,\n    unit_cell=unit_cell_after,\n    save_file=\"atoms_after_defect_finding.gif\",\n)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.20"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}