{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction\n", "\n", "This notebook demonstrates how to predict likely n- and p-type dopant atoms using pymatgen. This example uses the Materials API to download the structure of interest but any `Structure` object can be used. Two methods for choosing dopants are demonstrated. The first uses a simple Shannon radii comparison, whereas the second is based on the substitution probability of two atoms calculated using the `SubstitutionPredictor` utility in pymatgen. This code requires knowledge of the oxidation state of all elements in the structure. These can be guessed using pymatgen but should be checked to ensure the validity of the results.\n", "\n", "*Author: Alex Ganose (10/06/18)*" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Uncomment the subsequent lines in this cell to install dependencies for Google Colab.\n", "# !pip install pymatgen==2022.7.19" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Imports we need for generating dopant suggestions\n", "\n", "from pprint import pprint\n", "\n", "from pymatgen.analysis.local_env import CrystalNN\n", "from pymatgen.analysis.structure_prediction.dopant_predictor import (\n", " get_dopants_from_shannon_radii,\n", " get_dopants_from_substitution_probabilities,\n", ")\n", "from pymatgen.ext.matproj import MPRester" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Establish rester for accessing Materials API\n", "\n", "api_key = None # INSERT YOUR OWN API KEY\n", "\n", "mpr = MPRester(api_key=api_key)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we define a variable -- `num_dopants` for how many dopants you wish to explore." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "num_dopants = 5 # number of highest probability dopants you wish to see" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Download a structure and add oxidation states\n", "\n", "In this section, we use the Materials API to download a structure and add information on the oxidation states of the atoms." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mp_id = \"mp-856\" # Materials Project id for rutile SnO2\n", "\n", "structure = mpr.get_structure_by_material_id(mp_id)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The downloaded structure does not contain oxidation state information. There are two ways to add this information. The first is to specify the oxidation state of the elements manually." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "structure.add_oxidation_state_by_element({\"Sn\": 4, \"O\": -2})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, we can use pymatgen to guess the oxidation states. If using this method you should check that the oxidation states are what you expect." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "structure.add_oxidation_state_by_guess()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check what oxidation states pymatgen guessed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Specie O2-, Specie Sn4+]\n" ] } ], "source": [ "species = structure.composition.elements\n", "\n", "print(species)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Finding dopants by Shannon radii\n", "\n", "In this section, we use the known Shannon radii to predict likely dopants. We will prefer dopants which have the smallest difference in radius to the host atoms. As the Shannon radii depend on the coordination number of the site, we must first calculate the bonding in the structure. In this example, we do this using the `CrystalNN` class." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cnn = CrystalNN()\n", "bonded_structure = cnn.get_bonded_structure(structure)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pymatgen has a function to take a bonded structure with oxidation states and report the closest n- and p-type dopants, sorted by the difference in Shannon radii. Let's run this on our bonded structure:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'n_type': [{'dopant_species': Specie U6+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': 0.040000000000000036},\n", " {'dopant_species': Specie Nb5+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': -0.04999999999999993},\n", " {'dopant_species': Specie Ta5+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': -0.04999999999999993},\n", " {'dopant_species': Specie F-,\n", " 'original_species': Specie O2-,\n", " 'radii_diff': -0.06000000000000005},\n", " {'dopant_species': Specie Np5+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': 0.06000000000000005}],\n", " 'p_type': [{'dopant_species': Specie Ni2+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': 0.0},\n", " {'dopant_species': Specie Ru3+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': -0.009999999999999898},\n", " {'dopant_species': Specie Ir3+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': -0.009999999999999898},\n", " {'dopant_species': Specie Rh3+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': -0.02499999999999991},\n", " {'dopant_species': Specie Mg2+,\n", " 'original_species': Specie Sn4+,\n", " 'radii_diff': 0.030000000000000027}]}\n" ] } ], "source": [ "dopants = get_dopants_from_shannon_radii(bonded_structure, num_dopants=num_dopants)\n", "\n", "pprint(dopants)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most favoured n-type dopant is U on a Sn site. Unfortunately, this is not a sustainable or safe choice of dopant. The most common industrial n-type dopant for SnO2 is fluorine. While F is present in our list of suggested dopants, it found way down at suggestion number 4.\n", "\n", "Another limitation of the Shannon radii approach to choosing dopants is that the radii depend on both the coordination number and charge state. For many elements, the radii for many charge state/coordination number combinations have not been tabulated, meaning this approach is incomplete.\n", "\n", "Instead we should use a more robust approach to determine possible dopants. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Finding dopants by substitution probability\n", "\n", "In this section, we use the statistics provided by `SubstitutionPredictor` to predict likely dopants substitutions using a data-mined approach from ICSD data. Based on the species in the structure, we get a list of which species are likely to substitute in but have different charge states. The substitution prediction methodology is presented in: \n", "*Hautier, G., Fischer, C., Ehrlacher, V., Jain, A., and Ceder, G. (2011) Data Mined Ionic Substitutions for the Discovery of New Compounds. Inorganic Chemistry, 50(2), 656-663. doi:10.1021/ic102031h*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, we define a variable -- `threshold` for the threshold probability in making substitution/structure predictions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "threshold = 0.001 # probability threshold for substitution/structure predictions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pymatgen provides a function to filter the predicted substitutions by their charge states and return a list of n- and p-type dopants. Let's run the function on the structure we downloaded earlier:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:root:87 substitutions found\n", "INFO:root:11 substitutions found\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "{'n_type': [{'dopant_species': Specie F-,\n", " 'original_species': Specie O2-,\n", " 'probability': 0.06692682583342485},\n", " {'dopant_species': Specie Cl-,\n", " 'original_species': Specie O2-,\n", " 'probability': 0.021022638288432097},\n", " {'dopant_species': Specie Ta5+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.01948622124590853},\n", " {'dopant_species': Specie Sb5+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.010380692735493774},\n", " {'dopant_species': Specie Nb5+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.00998853178143717}],\n", " 'p_type': [{'dopant_species': Specie Co2+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.023398867249112974},\n", " {'dopant_species': Specie Cd2+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.022644061067779383},\n", " {'dopant_species': Specie Li+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.022394101830147096},\n", " {'dopant_species': Specie Fe2+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.020971777662831426},\n", " {'dopant_species': Specie Ca2+,\n", " 'original_species': Specie Sn4+,\n", " 'probability': 0.019487195581329015}]}\n" ] } ], "source": [ "dopants = get_dopants_from_substitution_probabilities(\n", " structure, num_dopants=num_dopants, threshold=threshold\n", ")\n", "\n", "pprint(dopants)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function returns a list of potential dopants sorted by their substitution probability. The most likely n-type dopant is F on a O site. Fluorine doped SnO2 (FTO) is one of the most widely used transparent conducting oxides, therefore validating this approach." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12" } }, "nbformat": 4, "nbformat_minor": 2 }