{ "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 an hexagonal crystal with lattice parameters $(a, b, c)$ = (1.4, 1.4, 1.7) 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.4, 1.4, 1.7, 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) $S$" ] }, { "cell_type": "code", "execution_count": null, "id": "0c95a661-e26d-4b07-9ac6-d4908f37305f", "metadata": {}, "outputs": [], "source": [ "phase = Phase(point_group=\"6/mmm\", structure=Structure(lattice=lattice))\n", "phase.structure.lattice.base" ] }, { "cell_type": "markdown", "id": "e35f63a1-1008-41e0-a2e7-fcc54695de98", "metadata": {}, "source": [ "