{ "cells": [ { "cell_type": "markdown", "id": "animal-applicant", "metadata": {}, "source": [ "## Defining the primitive crystal structure and degrees of freedom \n", "\n", "This tutorial demonstrates:\n", "- Defining the primitive crystal structure and degrees of freedom (DoF) (the \"prim\")\n", "- `casm init`: Initializing a CASM project\n", "- `casm sym`: Getting symmetry information\n", "- `casm info -m PrimInfo`: Querying information about a prim without initializing a project\n", "\n", "It includes three examples:\n", "\n", "1. [HCP Zr with O octahedral interstitial -- Occupation cluster expansion project](#occupation_clex)\n", "2. [ZrH2 -- Strain polynomial effective Hamiltonian prim](#strain_polynomial)\n", "3. [ZrH2 -- Coupled strain-displacement cluster expansion effective Hamiltonian prim](#coupled)\n" ] }, { "cell_type": "markdown", "id": "forced-venture", "metadata": {}, "source": [ "\n", "\n", "## 1) HCP Zr with O octahedral interstitial -- Occupation cluster expansion project\n", "\n", "### HCP Zr with octahedral interstitial O / vacancy disorder\n", "\n", "Compared to most metals, HCP Zr has a unusually high solubility of O, up to around 35 at%, which fills octahedral interstitial positions in the HCP structure. \n", "\n", "This CASM project was used to:\n", "- study the thermodynamic properties of Zr and its oxides\n", "- fit a configurational cluster expansion effective Hamiltonian\n", "- construct a first-principles based phase diagram \n", "\n", "Based on empirical knowledge of the system, this model makes the approximations:\n", "- that the HCP Zr crystal is perfect\n", "- octahedral interstitial positions may be either vacant or filled with oxygen atoms.\n", "\n", "To begin, CASM requires a \"prim\", a primitive description of the crystal structure and allowed degrees of freedom (DoF). It is provided as a JSON formatted file.\n", "\n", "
\n", "Note: The Prim JSON format reference is located here.\n", "
\n", "\n", "### Components of the \"prim\"\n", "\n", "The \"prim\" defines the primitive crystal structure and degrees of freedom. \n", "\n", "In general the \"prim\" includes:\n", "- lattice vectors\n", "- crystal basis sites\n", "- global degrees of freedom\n", "- site degrees of freedom, including allowed occupant species on each basis site. \n", "\n", "\n", "For this particular project, it contains:\n", "\n", "- **lattice_vectors**: Row-vector matrix of crystal lattice vectors. Units are typically Angstrom, but are ultimately determined by the method used to perform calculations. \n", "\n", "- **basis**: An array of crystal basis sites, including coordinate and allowed degrees of freedom. For this ZrO project, the basis sites contain:\n", "\n", " - **coordinate**: The location of the basis site, according to the \"coordinate_mode\".\n", " \n", " - **occupants**: A list of the possible occupant species that may reside at each site. The names are case sensitive, and “Va” is reserved for vacancies.\n", "\n", "- **coordinate_mode**: Defines the units of basis site coordinates. May be one of:\n", "\n", " - \"Cartesian\": To specify basis coordinates using Cartesian coordinates:\n", " $$ r_{cart} = (x, y, z) $$\n", "\n", " - \"Fractional\" or \"Direct\": To specify basis coordinates defined in terms of the lattice vectors:\n", " $$ r_{cart} = L r_{frac}, $$\n", " where:\n", " - $r_{frac}$ are the coordinates in the fractional representation\n", " - $r_{cart}$ are the coordinates in the Cartesian representation\n", " - $L$ is the lattice as a column-vector matrix. \n", " \n", "
\n", "For \"lattice_vectors\", it is common, but not required, to use the results of a fully relaxed calculation of the structure with the default occupation values. The default occupation on each site is the species listed first in \"occupants\". For occupation cluster expansions, ideal supercells of the prim lattice are used for the initial state of DFT calculations and it is the default reference for strain.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "id": "sophisticated-boost", "metadata": {}, "outputs": [], "source": [ "prim_str='\n", "{\n", " \"basis\" : [\n", " {\n", " \"coordinate\" : [ 0.0000000, 0.0000000, 0.0000000 ],\n", " \"occupants\" : [ \"Zr\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.6666666666, 0.3333333333, 0.5000000 ],\n", " \"occupants\" : [ \"Zr\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.3333333333, 0.6666666666, 0.2500000 ],\n", " \"occupants\" : [ \"Va\", \"O\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.3333333333, 0.6666666666, 0.7500000 ],\n", " \"occupant_dof\" : [ \"Va\", \"O\" ]\n", " }\n", " ],\n", " \"coordinate_mode\" : \"Fractional\",\n", " \"description\" : \"hcp Zr with octahedral interstitial O \",\n", " \"lattice_vectors\" : [\n", " [ 3.23398686, 0.00000000, 0.00000000 ],\n", " [ -1.61699343, 2.80071477, 0.00000000 ],\n", " [ -0.00000000, 0.00000000, 5.16867834 ]\n", " ],\n", " \"title\" : \"ZrO\"\n", "}'" ] }, { "cell_type": "markdown", "id": "6da78b05", "metadata": {}, "source": [ "### Initializing a CASM Project\n", "\n", "Running `casm init` will:\n", "1. Read a [Prim](https://prisms-center.github.io/CASMcode_docs/formats/casm/crystallography/BasicStructure/) file and perform some checks\n", "2. Perform a symmetry analysis\n", "3. Generate default directories\n", "\n", "When the prim file is read, CASM will check for a standardized representation:\n", "- **primitive form:** \n", " - CASM checks if there is an equivalent, smaller unit cell\n", " - If there is, CASM will print the recommended prim and prompt the user to consider using it\n", "- **standard orientation:**\n", " - CASM uses a standardized comparison to identify unique lattices\n", " - Upon initialization:\n", " - CASM checks if the lattice is the Niggli reduced cell\n", " - CASM checks if the lattice is oriented in a standard way\n", " - If the input lattice is not in the standard form, CASM will print a recommended prim and prompt the user to consider using it\n", "\n", "#### The `.casm` directory\n", "\n", "Project files that the user should not typically modify directly, including a copy of the prim, are stored in a hidden `.casm` sub-directory of the CASM project directory. The presense or absence of the `.casm` directory is used by CASM to detect a CASM project." ] }, { "cell_type": "markdown", "id": "measured-graphics", "metadata": {}, "source": [ "### Getting started\n", "\n", "The following code creates an `init/ZrO` subdirectory of the current working directory for purposes of this example. For a real project, modify the paths to the location where you want to create a CASM project." ] }, { "cell_type": "code", "execution_count": null, "id": "41cccf6e", "metadata": {}, "outputs": [], "source": [ "# remember the directory where we start\n", "start=$(pwd)\n", "\n", "# make a subdirectory for our ZrO CASM project\n", "mkdir -p $start/init/ZrO && cd $start/init/ZrO" ] }, { "cell_type": "code", "execution_count": null, "id": "52839f8c", "metadata": {}, "outputs": [], "source": [ "# create the prim.json file\n", "echo \"$prim_str\" > prim.json\n", "\n", "# print the prim.json file contents\n", "cat prim.json" ] }, { "cell_type": "code", "execution_count": null, "id": "industrial-squad", "metadata": {}, "outputs": [], "source": [ "# initialize the new CASM project\n", "ccasm init\n", "\n", "# view the project directory\n", "ls ." ] }, { "cell_type": "markdown", "id": "8635eeae", "metadata": {}, "source": [ "### Checking the initialized project\n", "\n", "After initializing the project:\n", "- Check that CASM has identified all the expected symmetries.\n", " - Add signicificant digits if necessary.\n", " - Default tolerance is 1e-5 for crysllographic comparisons.\n", " \n", "
\n", "If the prim symmetry is incorrect, the effective Hamiltonians that CASM generates will also have the wrong symmetry!\n", "
\n" ] }, { "cell_type": "markdown", "id": "consolidated-lease", "metadata": {}, "source": [ "### The `casm sym` command\n", "\n", "After the project is initialized, the symmetry CASM has found can be printed using the `sym` command. `sym` will print information about three important symmetry groups. Each group is a vector of representative symmetry operations. \n", "\n", "The symmetery operations transform a spatial coordinate $ x \\rightarrow x'$ according to:\n", "\n", "$$ x' = A*x+b, $$\n", "\n", "where:\n", "- $A$ is the 3x3 \"operation matrix\"\n", "- $b$ is the \"shift\" translation vector. \n", "\n", "Operations may be printed either in fractional coordinates (FRAC) or Cartesian coordinates (CART).\n", "\n", "### Important symmetry groups\n", "\n", "The `casm sym` command provides information on three symmetry groups:\n", "\n", "- **lattice point group**: Maps lattice points, keeps origin fixed\n", " - This is the point group of the Bravais lattice: the list of operations that map the lattice (i.e. all points that are integer multiples of the lattice vectors) onto itself and keep the origin fixed.\n", " - The \"shift\" vectors will always be zero. \n", "\n", "- **factor group**: Maps lattice points and equivalent basis sites\n", " - The crystal space group is the set of all symmetry operations that map the lattice onto itself and map basis sites onto equivalent basis sites (i.e. all degrees of freedom are equivalent).\n", " - The crystal space group is not limited to operations that keep the origin fixed, so due to the perdiodicity of the crystal the crystal space group is infinite.\n", " - The factor group is a finite description of the crystal space group, in which all operations that differ only by a \"shift\" are represented by a single operation whose \"shift\" lies within the primitive cell.\n", " - Formally, this is a group formed by the cosets of $T$ in $S$, where $T$ is the translation group of the Bravais lattice and $S$ is the crystal space group.\n", "\n", "- **crystal point group**: Factor group, with \"shift\"$=\\vec{0}$\n", " - This is the group of point operations formed by taking the factor group operations and setting their \"shift\" to zero.\n", " - Macroscopic properties of the crystal must exhibit the symmetries of the crystal point group. \n", " - It is by definition a subgroup of the lattice point group.\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "polar-virginia", "metadata": {}, "outputs": [], "source": [ "# print the factor group using the Cartesian representation\n", "ccasm sym --coord CART --factor-group" ] }, { "cell_type": "markdown", "id": "dried-liabilities", "metadata": {}, "source": [ "### Brief symmetry representation\n", "\n", "- Use `ccasm sym --brief` to print a brief description of:\n", " - The lattice point group\n", " - The factor group\n", " - The crystal point group\n", "- The brief description follows the conventions of the International Tables for Crystallography. \n", "- The option `--coord CART` can be used to print the Cartesian representation." ] }, { "cell_type": "code", "execution_count": null, "id": "bb7fc0dc", "metadata": {}, "outputs": [], "source": [ "# view the lattice point group (brief form)\n", "ccasm sym --brief --lattice-point-group" ] }, { "cell_type": "code", "execution_count": null, "id": "62ab3daa", "metadata": {}, "outputs": [], "source": [ "# view the factor group (brief form)\n", "ccasm sym --brief --factor-group" ] }, { "cell_type": "code", "execution_count": null, "id": "christian-departure", "metadata": {}, "outputs": [], "source": [ "# view the crystal point group (brief form)\n", "ccasm sym --brief --crystal-point-group" ] }, { "cell_type": "markdown", "id": "empirical-bikini", "metadata": {}, "source": [ "### The `info` method\n", "\n", "The `info` method gives more direct and flexible access to CASM data and methods via JSON input and output. \n", "\n", "It currently allows for getting detailed information about a prim, supercells, and the neighbor lists used in effective Hamiltonian evalautions, with additional options planned for the future. \n", "\n", "For any data that does not require a CASM project it will work whether or not a CASM project exists, but if called from within a CASM project, then that project will be used for default input values such as the prim. " ] }, { "cell_type": "code", "execution_count": null, "id": "5c31a839", "metadata": {}, "outputs": [], "source": [ "# list available \"info\" methods\n", "ccasm info -h" ] }, { "cell_type": "code", "execution_count": null, "id": "listed-sullivan", "metadata": {}, "outputs": [], "source": [ "# list input and output options for a particular method\n", "ccasm info --desc PrimInfo" ] }, { "cell_type": "markdown", "id": "formal-appliance", "metadata": {}, "source": [ "### Using `info` \n", "\n", "As an example, we can get information about the ZrO prim without initializing a CASM project.\n", "\n", "In this case, we request the indices of the sites in each orbit of the asymmetric unit.\n", "\n", "The asymmetric unit is the minimum set of sites necessary to generate all the other sites upon application of the factor group.\n", "\n", "In other words, the asymmetric unit is the set of symmetrically distinct sites." ] }, { "cell_type": "code", "execution_count": null, "id": "cc46a6ad", "metadata": {}, "outputs": [], "source": [ "# create and check the input file\n", "info_input_str='{\n", " \"prim\": '${prim_str}',\n", " \"properties\": [\n", " \"asymmetric_unit\"\n", " ]\n", "}'\n", "echo $info_input_str" ] }, { "cell_type": "code", "execution_count": null, "id": "f51e6201", "metadata": {}, "outputs": [], "source": [ "# run the `info` command and store output to a file `ZrO_info.json`\n", "ccasm info -m PrimInfo -i \"$info_input_str\" > ZrO_info.json" ] }, { "cell_type": "markdown", "id": "bf55a6ab", "metadata": {}, "source": [ "### Example using `jq`\n", "\n", "For those comfortable with the command line, the [`jq` program](https://stedolan.github.io/jq/) is a very useful tool for parsing JSON data.\n", "\n", "The shows just two examples using `jq`:\n", "- Printing the keys from the top level of the document\n", "- Printing the value of one of the attributes" ] }, { "cell_type": "code", "execution_count": null, "id": "nasty-techno", "metadata": {}, "outputs": [], "source": [ "# list names of output properties in ZrO_info.json\n", "jq 'keys' ZrO_info.json\n", "\n", "echo \"asymmetric_unit:\"\n", "jq '.asymmetric_unit' ZrO_info.json" ] }, { "cell_type": "markdown", "id": "commercial-encounter", "metadata": {}, "source": [ "\n", "\n", "## 2) ZrH2 -- Strain polynomial effective Hamiltonian prim\n", "\n", "
\n", "Note: The Prim JSON format reference is located here.\n", "
\n", "\n", "All continuous DoF are represented as vectors having a standard basis that is related to the fixed reference frame of the crystal. The DoF object may optionally encode a user-specified basis in terms of the standard basis. The user-specified basis may fully span the standard basis or only a subspace. Within a `\"dofs\"` object, each DoF is given by the key/object pair `\"\" : {...}` where `` is the name specifier of a particular DoF type and the associated object specifies non-default options.\n", "\n", "The options include:\n", "\n", "- `axis_names`: array of string\n", "\n", " Names given to the user-specified basis vectors when writing basis function formulas. The length of `axis_names` must match the number of rows in `basis`. \n", " \n", "- `basis`: row-vector matrix\n", "\n", " The basis provides the user-specified basis vectors in terms of the standard basis. The number of rows is the dimension of user-specified basis. The number of columns must equal the number of dimensions in the standard basis (i.e. 3 for displacement, 6 for strain).\n", " \n", "\n", "#### Example: Strain DoF, using the Green-Lagrange strain metric with custom user basis excluding shear strain:\n", "\n", " \"dofs\" : {\n", " \"GLstrain\" : {\n", " \"axis_names\" : [\"E_{xx}\", \"E_{yy}\", \"E_{zz}\"], \n", " \"basis\" : [\n", " [1.0, 0.0, 0.0, 0.0, 0.0, 0.0], \n", " [0.0, 1.0, 0.0, 0.0, 0.0, 0.0],\n", " [0.0, 0.0, 1.0, 0.0, 0.0, 0.0]\n", " ]\n", " }\n", " }\n", "\n", "\n", "Allowed global DoF include:\n", "\n", "- \"GLstrain\": Green-Lagrange strain metric, $\\frac{1}{2}(C-I)$\n", "- \"Hstrain\": Hencky strain metric, $\\frac{1}{2}ln(C)$\n", "- \"Bstrain\": Biot strain metric, $(U-I)$ \n", "- \"Ustrain\": Stretch tensor, $U$\n", "- \"EAstrain\": Euler-Almansi strain metric, $\\frac{1}{2}(I-(F F^{T})^{-1})$\n", "\n", "The strain metrics are defined in terms of the deformation gradient tensor, $F$, and Green's deformation tensor, $C$. The deformation gradient tensor relates the strained and unstrained lattices through $L^{strained} = F * L^{ideal}$, and can be decomposed, via $F = R * U$, into a rotation tensor, $R$, and stretch tensor, $U$. Green's deformation tensor, $C = F^{T}*F$, excludes rigid rotations.\n", "\n", "For all strain metrics, the standard basis is:\n", "\n", "$$ [E_{xx}, E_{yy}, E_{zz}, \\sqrt(2)E_{yz}, \\sqrt(2)E_{xz}, \\sqrt(2)E_{xy}],$$\n", "\n", "and the default axis names are:\n", "\n", "$$[e_1, e_2, e_3, e_4, e_5, e_6].$$\n" ] }, { "cell_type": "code", "execution_count": null, "id": "gentle-recording", "metadata": {}, "outputs": [], "source": [ "ZrH2_GLstrain_prim_str='{\n", " \"basis\" : [\n", " {\n", " \"coordinate\" : [ 0.000000000000, 0.000000000000, 0.000000000000 ],\n", " \"occupants\" : [ \"Zr\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.250000000000, 0.250000000000, 0.250000000000 ],\n", " \"occupants\" : [ \"H\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.750000000000, 0.750000000000, 0.750000000000 ],\n", " \"occupants\" : [ \"H\" ]\n", " }\n", " ],\n", " \"dofs\": {\n", " \"GLstrain\": {}\n", " },\n", " \"coordinate_mode\" : \"Fractional\",\n", " \"lattice_vectors\" : [\n", " [ 0.000000000000, 2.410696500000, 2.410696500000 ],\n", " [ 2.410696500000, 0.000000000000, 2.410696500000 ],\n", " [ 2.410696500000, 2.410696500000, 0.000000000000 ]\n", " ],\n", " \"title\" : \"ZrH2\"\n", "}'\n", "\n", "ZrH2_GLstrain_info_input_str='{ \n", " \"prim\": '${ZrH2_GLstrain_prim_str}',\n", " \"properties\": [\n", " \"factor_group\"\n", " ]\n", "}'\n", "echo $ZrH2_GLstrain_info_input_str > info_input.json\n", "cat info_input.json" ] }, { "cell_type": "code", "execution_count": null, "id": "109c96fa", "metadata": {}, "outputs": [], "source": [ "pwd" ] }, { "cell_type": "code", "execution_count": null, "id": "587f0bf8", "metadata": {}, "outputs": [], "source": [ "# write the factor group information to the `ZrH2_GLstrain_info.json`\n", "ccasm info -m PrimInfo -i \"$ZrH2_GLstrain_info_input_str\" > ZrH2_GLstrain_info.json\n", "\n", "# list names of output properties in ZrH2_GLstrain_info.json\n", "cat ZrH2_GLstrain_info.json | jq 'keys'" ] }, { "cell_type": "code", "execution_count": null, "id": "1d855c27", "metadata": {}, "outputs": [], "source": [ "# get factor group size\n", "cat ZrH2_GLstrain_info.json | jq '.factor_group.group_operations | length'" ] }, { "cell_type": "markdown", "id": "signal-laser", "metadata": {}, "source": [ "\n", "\n", "## 3) ZrH2 -- Coupled strain-displacement cluster expansion effective Hamiltonian prim\n", "\n", "
\n", "Note: The Prim JSON format reference is located here.\n", "
\n", "\n", "Continuous site DoF are specified with a \"dofs\" parameter that is equivalent to the global \"dofs\" paremeter, but specified for each basis site.\n", "\n", "#### Example: Displacement DoF, in the xy plane only\n", "\n", " \"dofs\" : {\n", " \"disp\" : {\n", " \"axis_names\" : [\"dx\", \"dy\"], \n", " \"basis\" : [\n", " [1.0, 0.0, 0.0],\n", " [0.0, 1.0, 0.0]\n", " ]\n", " }\n", " }\n", "\n", "\n", "Allowed site DoF include:\n", "\n", "- \"disp\": Displacement, with standard basis $[dx, dy, dz]$\n", "\n", "Additionally, for this prim we will use the \"selectivedynamics\" species property to indicate that DFT calculations should fix Zr atoms at the position defined by the strain and displacement DoF, but allow H atoms to relax. Molecular occupants, and atomic occupants with user-specified properties are specified using the `\"species\"` parameter. The JSON format for Molecule specifications is given [here](https://prisms-center.github.io/CASMcode_docs/formats/casm/crystallography/BasicStructure/#molecule-json-object).\n" ] }, { "cell_type": "code", "execution_count": null, "id": "7860b999", "metadata": {}, "outputs": [], "source": [ "ZrH2_GLstrain_disp_prim_str='{\n", " \"basis\" : [\n", " {\n", " \"coordinate\" : [ 0.0000000, 0.0000000, 0.0000000 ],\n", " \"occupant_dof\" : [ \"Zr\" ],\n", " \"dofs\": {\n", " \"disp\": {}\n", " }\n", " },\n", " {\n", " \"coordinate\" : [ 0.2500000, 0.2500000, 0.2500000 ],\n", " \"occupant_dof\" : [ \"H\" ]\n", " },\n", " {\n", " \"coordinate\" : [ 0.7500000, 0.7500000, 0.7500000 ],\n", " \"occupant_dof\" : [ \"H\" ]\n", " }\n", " ],\n", " \"species\" : {\n", " \"H\": {\n", " \"properties\": {\n", " \"selectivedynamics\": {\n", " \"value\": [1, 1, 1]\n", " }\n", " }\n", " },\n", " \"Zr\": {\n", " \"properties\": {\n", " \"selectivedynamics\": {\n", " \"value\": [0, 0, 0]\n", " }\n", " }\n", " }\n", " },\n", " \"dofs\" : {\n", " \"GLstrain\" : {}\n", " },\n", " \"coordinate_mode\" : \"Fractional\",\n", " \"description\" : \"Cubic ZrH_{2}\",\n", " \"lattice_vectors\" : [\n", " [0.0 , 2.4106965, 2.4106965],\n", " [2.4106965, 0.0 , 2.4106965],\n", " [2.4106965, 2.4106965, 0.0 ]\n", " ],\n", " \"title\" : \"ZrH2\"\n", "}'\n", "\n", "ZrH2_GLstrain_disp_info_input_str='{\n", " \"prim\": '${ZrH2_GLstrain_disp_prim_str}',\n", " \"properties\": [\n", " \"factor_group\"\n", " ]\n", "}'" ] }, { "cell_type": "code", "execution_count": null, "id": "speaking-solomon", "metadata": {}, "outputs": [], "source": [ "ccasm info -m PrimInfo -i \"$ZrH2_GLstrain_disp_info_input_str\" > ZrH2_GLstrain_disp_info.json\n", "\n", "# list names of output properties in ZrH2_GLstrain_disp_info.json\n", "jq 'keys' ZrH2_GLstrain_disp_info.json" ] }, { "cell_type": "code", "execution_count": null, "id": "a7e14457", "metadata": {}, "outputs": [], "source": [ "# get factor group size\n", "cat ZrH2_GLstrain_info.json | jq '.factor_group.group_operations | length'" ] }, { "cell_type": "markdown", "id": "9040c535", "metadata": {}, "source": [ "### The following cleans up the data that was created" ] }, { "cell_type": "code", "execution_count": null, "id": "specialized-flexibility", "metadata": {}, "outputs": [], "source": [ "cd $start && rm -r $start/init" ] } ], "metadata": { "kernelspec": { "display_name": "Bash", "language": "bash", "name": "bash" }, "language_info": { "codemirror_mode": "shell", "file_extension": ".sh", "mimetype": "text/x-sh", "name": "bash" } }, "nbformat": 4, "nbformat_minor": 5 }