{ "cells": [ { "cell_type": "markdown", "id": "67195845-843f-4de5-b0ee-0addce775c64", "metadata": { "nbsphinx": "hidden", "tags": [] }, "source": [ "This notebook is part of the *orix* documentation https://orix.readthedocs.io. Links to the documentation won’t work from the notebook." ] }, { "cell_type": "markdown", "id": "f549c08a-bed7-4431-914c-b3edc609f476", "metadata": {}, "source": [ "# Crystal reference frame\n", "\n", "In this tutorial we will see how the crystal and sample reference frames are aligned in `orix`" ] }, { "cell_type": "code", "execution_count": null, "id": "d97dfe58-a726-4a19-b327-d5c3b6b15844", "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "from diffpy.structure import Atom, Lattice, Structure\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "from orix.crystal_map import Phase\n", "from orix.quaternion import Rotation\n", "from orix.vector import Miller\n", "\n", "\n", "plt.rcParams.update(\n", " {\n", " \"figure.figsize\": (10, 5),\n", " \"font.size\": 20,\n", " \"axes.grid\": True,\n", " \"lines.markersize\": 10,\n", " \"lines.linewidth\": 3,\n", " }\n", ")" ] }, { "cell_type": "markdown", "id": "a3e6c3aa-7cd7-4ed5-88cf-124b9b193532", "metadata": {}, "source": [ "## Alignment and the structure matrix\n", "\n", "The direct Bravais lattice is characterized by basis vectors ($\\mathbf{a}, \\mathbf{b}, \\mathbf{c}$) with unit cell edge lengths ($a$, $b$, $c$) and angles ($\\alpha$, $\\beta$, $\\gamma$).\n", "The reciprocal lattice has basis vectors given by\n", "\n", "$$\n", "\\mathbf{a^*} = \\frac{\\mathbf{b} \\times \\mathbf{c}}{\\mathbf{a} \\cdot (\\mathbf{b} \\times \\mathbf{c})},\\:\\:\n", "\\mathbf{b^*} = \\frac{\\mathbf{c} \\times \\mathbf{a}}{\\mathbf{a} \\cdot (\\mathbf{b} \\times \\mathbf{c})},\\:\\:\n", "\\mathbf{c^*} = \\frac{\\mathbf{a} \\times \\mathbf{b}}{\\mathbf{a} \\cdot (\\mathbf{b} \\times \\mathbf{c})},\n", "$$\n", "\n", "with reciprocal lattice parameters ($a^*$, $b^*$, $c^*$) and angles ($\\alpha^*$, $\\beta^*$, $\\gamma^*$).\n", "\n", "Using these two crystallographic lattices, we can define a standard Cartesian (orthonormal) reference frame by the unit vectors ($\\mathbf{e_1}, \\mathbf{e_2}, \\mathbf{e_3}$). In principle, the direct lattice reference frame can be oriented arbitrarily in the Cartesian reference frame. In `orix` we have chosen\n", "\n", "$$\n", "\\mathbf{e_1} ||\\: \\frac{\\mathbf{a}}{a},\\:\\:\n", "\\mathbf{e_2} ||\\: \\mathbf{e_3} \\times \\mathbf{e_1},\\:\\:\n", "\\mathbf{e_3} ||\\: \\frac{\\mathbf{c^*}}{c^*}.\n", "$$\n", "\n", "This alignment is used for example in Rowenhorst et al. (2015) and De Graef (2003), the latter which was the basis for the *EMsoft* Fortran suite of programs.\n", "Another common option is $\\mathbf{e_1} || \\mathbf{a^*}/a^*$, $\\mathbf{e_2} || \\mathbf{e_3} \\times \\mathbf{e_1}$, $\\mathbf{e_3} || \\mathbf{c}/c$, which is used for example in Britton et al. (2016) and the `diffpy.structure` Python package, which we'll come back to.\n", "\n", "In calculations, it is useful to describe the transformation of the Cartesian unit *row* vectors to the coordinates of the direct lattice vectors by the structure *row* matrix $\\mathbf{A}$ (also called the crystal *base*).\n", "Given the chosen alignment of basis vectors with the Cartesian reference frame, $\\mathbf{A}$ is defined as\n", "\n", "\\begin{equation}\n", "\\mathbf{A} = \n", "\\begin{pmatrix}\n", "a & 0 & 0\\\\\n", "b\\cos\\gamma & b\\sin\\gamma & 0\\\\\n", "c\\cos\\beta & -c\\frac{(\\cos\\beta\\cos\\gamma - \\cos\\alpha)}{\\sin\\gamma} & \\frac{\\mathrm{V}}{ab\\sin\\gamma}\n", "\\end{pmatrix},\n", "\\end{equation}\n", "\n", "where $V$ is the volume of the unit cell.\n", "\n", "In `orix`, we use the [Lattice](https://www.diffpy.org/diffpy.structure/mod_lattice.html#diffpy.structure.lattice.Lattice) class in `diffpy.structure` to keep track of these properties internally.\n", "Let's create a trigonal crystal with lattice parameters $(a, b, c)$ = (1.7, 1.7, 1.4) nm and ($\\alpha, \\beta, \\gamma$) = $(90^{\\circ}, 90^{\\circ}, 120^{\\circ})$" ] }, { "cell_type": "code", "execution_count": null, "id": "9f05c3e3-74fd-41ae-8660-ac997ac74d62", "metadata": {}, "outputs": [], "source": [ "lattice = Lattice(1.7, 1.7, 1.4, 90, 90, 120)\n", "lattice" ] }, { "cell_type": "markdown", "id": "932dcf90-8f5d-4e22-a121-d5676614b028", "metadata": {}, "source": [ "`diffpy.structure` stores the structure matrix in the `Lattice.base` property" ] }, { "cell_type": "code", "execution_count": null, "id": "20a8f43f-b2be-477c-900c-7771cf5c8a47", "metadata": {}, "outputs": [], "source": [ "lattice.base" ] }, { "cell_type": "markdown", "id": "bc67a5a6-3407-4bb6-b03a-58958eceb024", "metadata": {}, "source": [ "and we see that `diffpy.structure` does not use the `orix` alignment mentioned above, since $\\mathbf{e1} \\nparallel \\mathbf{a} / a$.\n", "Instead, we see that $\\mathbf{e3} \\parallel \\mathbf{c} / c$, which is in line with the alternative alignment mentioned above.\n", "\n", "Thus, the alignment is updated internally whenever a [Phase](../reference/generated/orix.crystal_map.Phase.rst) is created, a class which brings together this crystal lattice and a point group [Symmetry](../reference/generated/orix.quaternion.Symmetry.rst)" ] }, { "cell_type": "code", "execution_count": null, "id": "0c95a661-e26d-4b07-9ac6-d4908f37305f", "metadata": {}, "outputs": [], "source": [ "phase = Phase(point_group=\"321\", structure=Structure(lattice=lattice))\n", "phase.structure.lattice.base" ] }, { "cell_type": "markdown", "id": "e35f63a1-1008-41e0-a2e7-fcc54695de98", "metadata": {}, "source": [ "