Skip to content

Commit

Permalink
Merge pull request #193 from thomas-rocke/DislocRefactor
Browse files Browse the repository at this point in the history
Dislocation simplification & generalisation
  • Loading branch information
jameskermode authored Nov 8, 2023
2 parents 37ba323 + 481bdf8 commit 04cab5a
Show file tree
Hide file tree
Showing 10 changed files with 821 additions and 386 deletions.
52 changes: 52 additions & 0 deletions docs/applications/cylinder_configurations.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,58 @@
"from visualisation import show_dislocation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Accessing Key Dislocation Properties\n",
"As defined in a dimensionless (alat=1) frame, each kind of dislocation has several key properties which describe the geometric layout of the atomic cell, and also the position and orientation of the dislocation. Such properties are stored in matscipy as attributes of each dislocation class, such that they can be accessed without actually needing to construct a dislocation.\n",
"\n",
"As an example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from matscipy.dislocation import BCCMixed111Dislocation\n",
"\n",
"print(\"For a BCC 1/2<111>{110} Mixed Dislocation\")\n",
"print()\n",
"\n",
"print(\"The dislocation is oriented in a cell described by the miller indices: \")\n",
"print(BCCMixed111Dislocation.axes)\n",
"\n",
"print(\"Dimensionless burgers vector is: \", BCCMixed111Dislocation.burgers_dimensionless)\n",
"\n",
"print(\"Dislocation core will be at fractional coords \", BCCMixed111Dislocation.unit_cell_core_position_dimensionless, \" within a unit cell\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Available Dislocation Systems\n",
"The available dislocation systems are:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matscipy.dislocation as disloc_mod\n",
"import inspect\n",
"# Find all classes in matscipy.dislocation which inherit from the Abstact Base Class CubicCrystalDislocation\n",
"for name, attr in disloc_mod.__dict__.items():\n",
" if inspect.isclass(attr):\n",
" if issubclass(attr, disloc_mod.CubicCrystalDislocation) and attr not in [disloc_mod.CubicCrystalDislocation, disloc_mod.CubicCrystalDissociatedDislocation]:\n",
" print(name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
251 changes: 251 additions & 0 deletions docs/applications/multispecies_dislocations.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Multi-species Dislocation Systems\n",
"The previous section discussed constructing cylindrical dislocation cells, using single-species systems as case studies. The dislocation classes in `matscipy.dislocation` can also be applied to systems which have much more chemical complexity. However, the following restrictions apply:\n",
"1. The desired system can be expressed in a cubic lattice\n",
"2. The desired system shares on-lattice geometry with an existing \"base\" crystal structure\n",
"\n",
"As an example, let's take Zincblende GaAs and compare with a diamond lattice:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ase.build import bulk\n",
"from ase.lattice.cubic import Diamond\n",
"import numpy as np\n",
"import nglview # this import is necessary for rendering of the 3D view\n",
"from visualisation import show_dislocation, interactive_view\n",
"from ase.visualize import view\n",
"\n",
"# Data from https://doi.org/10.1080/08927022.2011.602975\n",
"alat = 11.306/2\n",
"C11 = 98.47\n",
"C12 = 15.25\n",
"C44 = 57.89\n",
"\n",
"GaAs = bulk(\"GaAs\", crystalstructure=\"zincblende\", cubic=True, a=alat)\n",
"\n",
"diamond = Diamond(\"C\", latticeconstant=alat)\n",
"\n",
"gaas_pos = GaAs.get_scaled_positions()\n",
"dia_pos = diamond.get_scaled_positions()\n",
"\n",
"# Sort the coords, as bulk uses a different atom order\n",
"gaas_idxs = np.lexsort((gaas_pos[:, 0], gaas_pos[:, 1], gaas_pos[:, 2]))\n",
"dia_idxs = np.lexsort((dia_pos[:, 0], dia_pos[:, 1], dia_pos[:, 2]))\n",
"print(\"GaAs Fractional Coordinates\")\n",
"print(gaas_pos[gaas_idxs, :])\n",
"print()\n",
"print(\"Diamond Fractional Coordinates\")\n",
"print(dia_pos[dia_idxs, :])\n",
"\n",
"interactive_view(GaAs, name=\"GaAs Bulk\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that the fractional coordinates of the Zincblende GaAs are the same as the Diamond structure we generated. We can therefore say that Zincblende shares geometry with Diamond. The displacement field used to generate dislocation structures is agnostic to atomic chemistry, and so we can model Zincblende dislocations as if they were dislocations in a Diamond crystal with the lattice constant and elastic properties of the Zincblende crystal.\n",
"\n",
"To build a dislocation with this GaAs bulk, we can simply pass it as an argument in place of the lattice constant:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from matscipy.dislocation import DiamondGlide90degreePartial\n",
"\n",
"disloc = DiamondGlide90degreePartial(GaAs, C11, C12, C44)\n",
"\n",
"GaAs_bulk, GaAs_dislocation = disloc.build_cylinder(radius=3 * alat)\n",
"\n",
"show_dislocation(GaAs_dislocation, scale=0.35, d_name=\"GaAs 1/6<112> 90 degree partial\", \n",
" diamond_structure=True, CNA_color=False, add_bonds=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Additional Dislocations in Multispecies Systems\n",
"Dislocations in multispecies systems have additiional complexity over those in single-species crystals, due to the breaking of some symmetries caused by the added chemical complexity. For our Zincblende GaAs example, this means that we can have two different forms of some of our dislocations: $\\alpha$ (As-terminated), and $\\beta$ (Ga-terminated).\n",
"\n",
"$\\alpha$-$90^\\circ$ Partial Dislocation in GaAs:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# alpha-90 degree dislocation\n",
"GaAs = bulk(\"GaAs\", crystalstructure=\"zincblende\", cubic=True, a=alat)\n",
"symbols = np.array(GaAs.get_chemical_symbols())\n",
"# Swap Ga <-> As to get other alpha dislocation\n",
"new_symbols = symbols.copy()\n",
"new_symbols[symbols == \"Ga\"] = \"As\"\n",
"new_symbols[symbols == \"As\"] = \"Ga\"\n",
"GaAs.set_chemical_symbols(new_symbols)\n",
"disloc = DiamondGlide90degreePartial(GaAs, C11, C12, C44)\n",
"\n",
"GaAs_bulk, GaAs_dislocation = disloc.build_cylinder(radius=3 * alat)\n",
"view = show_dislocation(GaAs_dislocation, scale=0.35, d_name=\"GaAs 1/6<112> Alpha-90 degree partial\", \n",
" diamond_structure=True, CNA_color=False, add_bonds=True)\n",
"\n",
"view.control.zoom(0.8)\n",
"view"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\\beta$-$90^\\circ$ Partial Dislocation in GaAs:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"GaAs = bulk(\"GaAs\", crystalstructure=\"zincblende\", cubic=True, a=alat)\n",
"# beta dislocation is the one done by default, for the bulk built by ase.build.bulk\n",
"disloc = DiamondGlide90degreePartial(GaAs, C11, C12, C44)\n",
"\n",
"GaAs_bulk, GaAs_dislocation = disloc.build_cylinder(radius=3 * alat)\n",
"view = show_dislocation(GaAs_dislocation, scale=0.35, d_name=\"GaAs 1/6<112> Beta-90 degree partial\", \n",
" diamond_structure=True, CNA_color=False, add_bonds=True)\n",
"\n",
"view.control.zoom(0.8)\n",
"view"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dislocations in Disordered Systems\n",
"Generating dislocation structures for systems which have some chemical disorder is also possible, with some caveats:\n",
"1. The generation routines will only work reliably when given on-lattice bulk structures with cubic cells\n",
"2. The generated structure is based on a periodic replication of the base unit_cell, thus won't have true disorder\n",
"3. The displacement field applied to the bulk structure does not depend on atomic species - known lattice distortions caused by the disorder will not be captured\n",
"4. The current code only allows $C_{11}$, $C_{12}$, and $C_{44}$ to be specified, so more complex elastic effects (e.g. $C_{11} \\neq C_{22}$) cannot currently be captured\n",
"\n",
"With these in mind, a recommended workflow would be to start by generating the dislocation system for an ordered system, but using the elastic constants of the disordered system. From there, the disorder can be applied by simply changing the chemcical symbols of the atoms to match the target composition.\n",
"\n",
"To show a worked example of this, consider the alloy $\\text{In}_{0.5} \\text{Ga}_{0.5} \\text{As}$. This should form in a Zincblende structure, where the Ga sites from the previous GaAs bulk are now 50% occupied by In.\n",
"\n",
"In order to model this, we can generate a dislocation for GaAs, using the lattice constant and elastic properties of $\\text{In}_{0.5} \\text{Ga}_{0.5} \\text{As}$.\n",
"\n",
"NOTE: Whilst disordered systems like this $\\text{In}_{0.5} \\text{Ga}_{0.5} \\text{As}$ example should have off-lattice distortions in the bulk state, it is heavily recommended that the dislocation structures are generated using an on-lattice crystal. This is because the off-lattice structure will interact differently with the continuum displacement field, which could lead to overlapping/extremely close atoms, or generally incorrect core structures. The off-lattice distortions should ideally be found by relaxing the dislocation structure."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ase.build import bulk\n",
"from matscipy.dislocation import DiamondGlide90degreePartial\n",
"\n",
"# Data from https://doi.org/10.1080/08927022.2011.602975\n",
"alat = 11.2402/2\n",
"C11 = 120.31\n",
"C12 = 55.87\n",
"C44 = 58.26\n",
"\n",
"GaAs = bulk(\"GaAs\", crystalstructure=\"zincblende\", cubic=True, a=alat)\n",
"\n",
"\n",
"disloc = DiamondGlide90degreePartial(GaAs, C11, C12, C44)\n",
"\n",
"GaAs_bulk, GaAs_dislocation = disloc.build_cylinder(radius=3 * alat)\n",
"\n",
"show_dislocation(GaAs_dislocation, scale=0.35, d_name=\"GaAs 1/6<112> Beta-90 degree partial\", \n",
" diamond_structure=True, CNA_color=False, add_bonds=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From this GaAs structure, we then do Monte Carlo sampling to introduce 50% Indium to the structure:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"np.random.seed(1)\n",
"\n",
"species = np.array(GaAs_dislocation.get_chemical_symbols())\n",
"\n",
"Ga_idxs = np.argwhere(species == \"Ga\")[:, 0]\n",
"\n",
"# Choose random half of the idxs to be In\n",
"In_idxs = sorted(np.random.choice(Ga_idxs, size=int(Ga_idxs.shape[0]/2), replace=False))\n",
"\n",
"# Introduce the chemical disorder in In-Ga sites\n",
"species[In_idxs] = \"In\"\n",
"\n",
"InGaAs_bulk = GaAs_bulk.copy()\n",
"InGaAs_bulk.set_chemical_symbols(species)\n",
"\n",
"InGaAs_dislocation = GaAs_dislocation.copy()\n",
"InGaAs_dislocation.set_chemical_symbols(species)\n",
"\n",
"view = show_dislocation(InGaAs_dislocation, scale=0.35, d_name=\"InGaAs 1/6<112> Beta-90 degree partial\", \n",
" diamond_structure=True, CNA_color=False, add_bonds=True)\n",
"\n",
"# In and Ga have almost the same default colors in nglview\n",
"# so we add another component with the In atoms in red to\n",
"# see the chemical disorder better\n",
"In_ats = InGaAs_dislocation[In_idxs]\n",
"c = view.add_component(nglview.ASEStructure(In_ats),\n",
" default_representation=False)\n",
"c.add_spacefill(radius=1.0, color=\"red\")\n",
"view"
]
}
],
"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.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
3 changes: 2 additions & 1 deletion docs/applications/plasticity.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ Tutorials:

.. toctree::

cylinder_configurations.ipynb
cylinder_configurations.ipynb
multispecies_dislocations.ipynb
Loading

0 comments on commit 04cab5a

Please sign in to comment.