diff --git a/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb new file mode 100644 index 00000000..5bba83b5 --- /dev/null +++ b/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb @@ -0,0 +1,337 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Ripple perturbation of a graphene sheet.\n", + "\n", + "## 0. Introduction\n", + "\n", + "This notebook demonstrates how to recreate a material from the following manuscript:\n", + "\n", + "> Thompson-Flagg, R. C., Moura, M. J. B., & Marder, M.\n", + "> Rippling of graphene. \n", + "> EPL (Europhysics Letters), 85(4), 46002. 2009\n", + "> [DOI: 10.1209/0295-5075/85/46002](https://doi.org/10.1209/0295-5075/85/46002)\n", + "\n", + "\n", + "Recreating material from Fig. 1:\n", + "\n", + "\"Rippling\n" + ], + "metadata": { + "collapsed": false + }, + "id": "367a698b29e22bd7" + }, + { + "cell_type": "markdown", + "source": [ + "## 1. Prepare the Environment" + ], + "metadata": { + "collapsed": false + }, + "id": "193a4e6a78fd5bd7" + }, + { + "cell_type": "markdown", + "source": [ + "### 1.1. Install Packages\n", + "The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))." + ], + "metadata": { + "collapsed": false + }, + "id": "f38b2711726e5859" + }, + { + "cell_type": "code", + "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", + "\n", + " await install_packages(\"specific-examples\")" + ], + "metadata": { + "collapsed": false + }, + "id": "7a6e28cfae1a7b46", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.2. Set Nanoribbon and Perturbation Parameters" + ], + "metadata": { + "collapsed": false + }, + "id": "11db992e02891067" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Set whether to preserve geodesic distance and scale the cell accordingly to match PBC\n", + "PRESERVE_GEODESIC_DISTANCE = False\n", + "\n", + "NANORIBBON_SIZE = 40 # in unit cells, lateral width and length of the nanoribbon\n", + "VACUUM_SIZE = 10 # in unit cells, lateral width and length of the vacuum region\n", + "\n", + "# Set whether to use Cartesian coordinates for the perturbation function\n", + "USE_CARTESIAN_COORDINATES = False\n", + "MATERIAL_NAME = \"Graphene\"" + ], + "metadata": { + "collapsed": false + }, + "id": "a40d7b697c413113", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.3. Define Custom Perturbation Function\n", + "Provide a [SymPy](https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html) expression for the perturbation function. The expression should be a function of `x`, `y` and `z` variables." + ], + "metadata": { + "collapsed": false + }, + "id": "e6a19c741406eafe" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "import sympy as sp\n", + "\n", + "# Variables for the perturbation function (for SymPy)\n", + "variable_names = [\"x\", \"y\", \"z\"]\n", + "x, y, z = sp.symbols(variable_names)\n", + "\n", + "# Set the parameters for the perturbation function\n", + "AMPLITUDE = 0.09 # Ripple amplitude\n", + "WAVELENGTH = 0.2 # Wavelength of ripples\n", + "EDGE_WIDTH = 0.25 # Width of edge effect\n", + "PHASE_X = 0.0 # Phase shift for x direction\n", + "PHASE_Y = sp.pi/2 # Phase shift for y direction\n", + "\n", + "# Create edge masks for both x and y using polynomial functions\n", + "left_edge_x = sp.Max(0, (EDGE_WIDTH - x) / EDGE_WIDTH)\n", + "right_edge_x = sp.Max(0, (x - (1 - EDGE_WIDTH)) / EDGE_WIDTH)\n", + "left_edge_y = sp.Max(0, (EDGE_WIDTH - y) / EDGE_WIDTH)\n", + "right_edge_y = sp.Max(0, (y - (1 - EDGE_WIDTH)) / EDGE_WIDTH)\n", + "\n", + "# Combine edge masks\n", + "edge_mask_x = left_edge_x + right_edge_x\n", + "edge_mask_y = left_edge_y + right_edge_y\n", + "edge_mask = edge_mask_x + edge_mask_y\n", + "\n", + "# Wave pattern\n", + "wave_pattern = (\n", + " sp.sin(2 * sp.pi * x / WAVELENGTH + PHASE_X) * \n", + " sp.sin(2 * sp.pi * y / WAVELENGTH + PHASE_Y)\n", + ")\n", + "\n", + "# Combine waves with edge mask\n", + "custom_sympy_function = AMPLITUDE * wave_pattern * edge_mask" + ], + "metadata": { + "collapsed": false + }, + "id": "203911c2413c7447", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.4. Get input materials" + ], + "metadata": { + "collapsed": false + }, + "id": "edf02101e27a2742" + }, + { + "cell_type": "code", + "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))" + ], + "metadata": { + "collapsed": false + }, + "id": "e0c53233ce728cc1", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.5. Create and preview Nanoribbon" + ], + "metadata": { + "collapsed": false + }, + "id": "cf29b7f6fe114d8f" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.nanoribbon import create_nanoribbon, NanoribbonConfiguration\n", + "from utils.visualize import visualize_materials as visualize\n", + "\n", + "config = NanoribbonConfiguration(material=material, width=NANORIBBON_SIZE, length=NANORIBBON_SIZE, vacuum_width=VACUUM_SIZE, vacuum_length=VACUUM_SIZE)\n", + "\n", + "supercell = create_nanoribbon(config)\n", + "visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")" + ], + "metadata": { + "collapsed": false + }, + "id": "897ba7aa4e402d24", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## 2. Create a target material\n", + "### 2.1. Set custom perturbation parameters\n" + ], + "metadata": { + "collapsed": false + }, + "id": "6d4adf0d580e0340" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.perturbation import CellMatchingDistancePreservingSlabPerturbationBuilder, \\\n", + " PerturbationConfiguration, SlabPerturbationBuilder\n", + "from mat3ra.made.tools.utils.perturbation import PerturbationFunctionHolder\n", + "\n", + "custom_perturbation_function = PerturbationFunctionHolder(function=custom_sympy_function,\n", + " variables=variable_names)\n", + "configuration_custom = PerturbationConfiguration(\n", + " material=supercell,\n", + " perturbation_function_holder=custom_perturbation_function,\n", + " use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)\n", + "\n", + "if PRESERVE_GEODESIC_DISTANCE:\n", + " builder = CellMatchingDistancePreservingSlabPerturbationBuilder()\n", + "else:\n", + " builder = SlabPerturbationBuilder()" + ], + "metadata": { + "collapsed": false + }, + "id": "8d90932312c418ee", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 2.2. Apply perturbation to the material" + ], + "metadata": { + "collapsed": false + }, + "id": "7695d5d1df6be2e3" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.perturbation import create_perturbation\n", + "\n", + "material_with_custom_perturbation = create_perturbation(configuration=configuration_custom, builder=builder)" + ], + "metadata": { + "collapsed": false + }, + "id": "69ccc90b8c5c1191", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 3. Visualize the Material" + ], + "metadata": { + "collapsed": false + }, + "id": "10e7ca8950839991" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "visualize([\n", + " {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\"},\n", + " {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\", \"rotation\": \"-90x\"}\n", + "])" + ], + "metadata": { + "collapsed": false + }, + "id": "cbfe0878a16f6c83", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## 4. Pass data to the outside runtime" + ], + "metadata": { + "collapsed": false + }, + "id": "9e0b241366592109" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from utils.jupyterlite import download_content_to_file\n", + "\n", + "download_content_to_file(material_with_custom_perturbation, f\"{MATERIAL_NAME}_edge_perturbation.json\")" + ], + "metadata": { + "collapsed": false + }, + "id": "29dfa0a329cca2fa", + "execution_count": null + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}