diff --git a/other/materials_designer/specific_examples/grain_boundary_3d_fcc_metals_copper.ipynb b/other/materials_designer/specific_examples/grain_boundary_3d_fcc_metals_copper.ipynb new file mode 100644 index 00000000..5f2dd2d0 --- /dev/null +++ b/other/materials_designer/specific_examples/grain_boundary_3d_fcc_metals_copper.ipynb @@ -0,0 +1,468 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aa0a426af23f6def", + "metadata": { + "collapsed": false + }, + "source": [ + "# Grain Boundary 3D FCC Metals (Copper)\n", + "\n", + "## 0. Introduction\n", + "\n", + "This notebook demonstrates how to create a grain boundary structure for a 3D FCC metal, Cu in particular. The grain boundary is created by combining two slabs with different orientations. \n", + "\n", + "Aiming to reproduce the structure from the publication:\n", + "> **Timofey Frolov, David L. Olmsted, Mark Asta & Yuri Mishin**\n", + "> \"Structural phase transformations in metallic grain boundaries\"\n", + "> Nature Communications, volume 4, Article number: 1899 (2013)\n", + "> DOI: [10.1038/ncomms2919](https://www.nature.com/articles/ncomms2919) \n", + "\n", + "Focusing on reproducing the structures from Figure 1. b:\n", + "\n", + "\"Figure" + ] + }, + { + "cell_type": "markdown", + "id": "bff2f2c26b1fa6ba", + "metadata": { + "collapsed": false + }, + "source": [ + "## 1. Prepare the Environment\n", + "### 1.1. Set up the notebook \n", + "\n", + "Set the following flags to control the notebook behavior " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "45730b0f5384262b", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Enable interactive selection of terminations via UI prompt\n", + "IS_TERMINATIONS_SELECTION_INTERACTIVE = False\n", + "MATERIAL_NAME = \"Cu\"\n", + "\n", + "# Parameters for Phase 1\n", + "PHASE_1_MILLER_INDICES = (3,1,0)\n", + "PHASE_1_THICKNESS = 4 # in atomic layers\n", + "PHASE_1_USE_ORTHOGONAL_Z = True\n", + "\n", + "# Parameters for Phase 2\n", + "PHASE_2_MILLER_INDICES = (-3, -1, 0)\n", + "PHASE_2_THICKNESS = 4 # in atomic layers\n", + "PHASE_2_USE_ORTHOGONAL_Z = True\n", + "\n", + "INTERPHASE_GAP = 2.0 # in Angstrom\n", + "\n", + "# Maximum area for the superlattice search algorithm\n", + "MAX_AREA = 100 # in Angstrom^2\n", + "\n", + "# Parameters for the final material\n", + "SLAB_MILLER_INDICES = (0,0,1)\n", + "SLAB_THICKNESS = 4 # in atomic layers\n", + "SLAB_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n", + "SLAB_VACUUM = 20.0 # in Angstrom\n", + "\n", + "# Set the termination pair indices\n", + "TERMINATION_PAIR_INDEX = 0 # Will be overridden if interactive selection is used" + ] + }, + { + "cell_type": "markdown", + "id": "2460242f9e7d86f1", + "metadata": { + "collapsed": false + }, + "source": [ + "### 1.2. Install Packages\n", + "The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bae18ae87d3cc5ba", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install('mat3ra-api-examples', deps=False)\n", + " from utils.jupyterlite import install_packages\n", + " await install_packages(\"specific_examples|create_grain_boundary.ipynb\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "97eb71c0c9e31d2a", + "metadata": { + "collapsed": false + }, + "source": [ + "### 1.3. Get input material" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "950e5bef61bbd84a", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from mat3ra.standata.materials import Materials\n", + "from mat3ra.made.material import Material\n", + "\n", + "material = Material(Materials.get_by_name_first_match(MATERIAL_NAME))" + ] + }, + { + "cell_type": "markdown", + "id": "c4eb191c2e23b464", + "metadata": { + "collapsed": false + }, + "source": [ + "### 1.4. Preview Material" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4ebde830102b0b94", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from utils.visualize import visualize_materials as visualize\n", + "visualize([material], repetitions=[3, 3, 1], rotation=\"0x\")" + ] + }, + { + "cell_type": "markdown", + "id": "916ab91fcc23c7df", + "metadata": { + "collapsed": false + }, + "source": [ + "## 2. Create grain boundary\n", + "\n", + "### 2.1. Create Phase 1 and Phase 2 Slabs\n", + "Slab Configuration lets define the slab thickness, vacuum, and the Miller indices of the interfacial plane and get the slabs with possible terminations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7cc3daa852d868d", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n", + "\n", + "phase_1_configuration = SlabConfiguration(\n", + " bulk=material,\n", + " miller_indices=PHASE_1_MILLER_INDICES,\n", + " thickness=PHASE_1_THICKNESS,\n", + " use_orthogonal_z=PHASE_1_USE_ORTHOGONAL_Z\n", + ")\n", + "\n", + "phase_2_configuration = SlabConfiguration(\n", + " bulk=material,\n", + " miller_indices=PHASE_2_MILLER_INDICES,\n", + " thickness=PHASE_2_THICKNESS,\n", + " use_orthogonal_z=PHASE_2_USE_ORTHOGONAL_Z\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9e507e0b1534c0c5", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.2. Get possible terminations for the slabs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5bdc0e37e3ec9891", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "phase_1_terminations = get_terminations(phase_1_configuration)\n", + "phase_2_terminations = get_terminations(phase_2_configuration)" + ] + }, + { + "cell_type": "markdown", + "id": "aebec268223b617c", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.3. Visualize slabs for all possible terminations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f75092312b399f84", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "phase_1_slabs = [create_slab(phase_1_configuration, termination) for termination in phase_1_terminations]\n", + "phase_2_slabs = [create_slab(phase_2_configuration, termination) for termination in phase_2_terminations]\n", + "\n", + "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in phase_1_slabs], repetitions=[3, 3, 1], rotation=\"-90x\")\n", + "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in phase_2_slabs], repetitions=[3, 3, 1], rotation=\"-90x\")" + ] + }, + { + "cell_type": "markdown", + "id": "a766392c3f119616", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.4. Print terminations for the grain boundary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40b4ba55613d9658", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from itertools import product\n", + "\n", + "termination_pairs = list(product(phase_1_terminations, phase_2_terminations))\n", + "print(\"Termination Pairs (Phase 1, Phase 2)\")\n", + "for idx, termination_pair in enumerate(termination_pairs):\n", + " print(f\" {idx}: {termination_pair}\")" + ] + }, + { + "cell_type": "markdown", + "id": "11d4044d37604022", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.5. Select termination pair for the grain boundary" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8dfc5893f510bae4", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n", + "\n", + "termination_pair_index = TERMINATION_PAIR_INDEX\n", + "\n", + "termination_pair = termination_pairs[termination_pair_index]\n", + "if IS_TERMINATIONS_SELECTION_INTERACTIVE:\n", + " if sys.platform == \"emscripten\":\n", + " termination_pair = await ui_prompt_select_array_element_by_index_pyodide(termination_pairs, element_name=\"phase 1/phase 2 termination pair\")\n", + " else:\n", + " termination_pair = ui_prompt_select_array_element_by_index(termination_pairs, element_name=\"phase 1/phase 2 termination pair\")" + ] + }, + { + "cell_type": "markdown", + "id": "8d87cbbb0d1ac1ab", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.6. Initialize the Grain Boundary Configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "40b6c8662d071f18", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.grain_boundary import SlabGrainBoundaryConfiguration\n", + "\n", + "phase_1_termination, phase_2_termination = termination_pair\n", + "\n", + "# Create a slab configuration for the final grain boundary structure\n", + "slab_configuration = SlabConfiguration(\n", + " bulk=material,\n", + " miller_indices=SLAB_MILLER_INDICES,\n", + " thickness=SLAB_THICKNESS,\n", + " vacuum=SLAB_VACUUM,\n", + ")\n", + "\n", + "grain_boundary_configuration = SlabGrainBoundaryConfiguration(\n", + " phase_1_configuration=phase_1_configuration,\n", + " phase_2_configuration=phase_2_configuration,\n", + " phase_1_termination=phase_1_termination,\n", + " phase_2_termination=phase_2_termination,\n", + " gap=INTERPHASE_GAP,\n", + " slab_configuration=slab_configuration\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "7fed41afcde4cb67", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.7. Set Strain Matching Algorithm Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "44015c5407563d4e", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.interface import ZSLStrainMatchingParameters\n", + "from mat3ra.made.tools.build.grain_boundary.builders import SlabGrainBoundaryBuilderParameters\n", + "\n", + "zsl_strain_matching_parameters = ZSLStrainMatchingParameters(\n", + " max_area=MAX_AREA\n", + ")\n", + "\n", + "builder_parameters = SlabGrainBoundaryBuilderParameters(\n", + " strain_matching_parameters=zsl_strain_matching_parameters\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "id": "605ed08a67d51cc8", + "metadata": { + "collapsed": false + }, + "source": [ + "### 2.8. Generate grain boundary with strain matcher" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "884b458236270a29", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.grain_boundary import SlabGrainBoundaryBuilder\n", + "\n", + "grain_boundary_builder = SlabGrainBoundaryBuilder(build_parameters=builder_parameters)\n", + "grain_boundary = grain_boundary_builder.get_material(configuration=grain_boundary_configuration)" + ] + }, + { + "cell_type": "markdown", + "id": "3c6187f70eb5beac", + "metadata": { + "collapsed": false + }, + "source": [ + "## 2.9. Preview the grain boundary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "892c0e7c932cd725", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "visualize([grain_boundary], repetitions=[1, 1, 1])\n", + "visualize([grain_boundary], repetitions=[1, 1, 1], rotation=\"-90x\")" + ] + }, + { + "cell_type": "markdown", + "id": "479d26e4a9e77d44", + "metadata": { + "collapsed": false + }, + "source": [ + "## 3. Save the final material" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "503eff0dd5c1a160", + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from utils.jupyterlite import download_content_to_file\n", + "\n", + "download_content_to_file(grain_boundary, f\"{MATERIAL_NAME}-{PHASE_1_MILLER_INDICES}-{PHASE_2_MILLER_INDICES}_grain_boundary.json\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv-3.11", + "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.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}