From 8bb6c0b313581aacf33c6879bd6395bfa4660695 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Sun, 29 Dec 2024 22:06:53 -0800 Subject: [PATCH 1/6] feat: add perturbation nb --- .../perturbation_graphene.ipynb | 321 ++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 other/materials_designer/specific_examples/perturbation_graphene.ipynb diff --git a/other/materials_designer/specific_examples/perturbation_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_graphene.ipynb new file mode 100644 index 00000000..213d3bdb --- /dev/null +++ b/other/materials_designer/specific_examples/perturbation_graphene.ipynb @@ -0,0 +1,321 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Create a Custom Perturbation in a Material\n", + "\n", + "Create a perturbation in a material with a custom function described with [SymPy](https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html) expressions. \n", + "\n", + "

Usage

\n", + "\n", + "1. Make sure to select Input Materials (in the outer runtime) before running the notebook.\n", + "1. Set perturbation parameters in cell 1.2. (or use default).\n", + "1. Set custom perturbation function with SymPy in cell 1.3.\n", + "1. Click “Run” > “Run All” to run all cells. \n", + "1. Wait for the run to complete (depending on the parameters can take a few min). \n", + "1. Scroll down to view results. \n", + "\n", + "## Notes\n", + "\n", + "1. For more information, see [Introduction](Introduction.ipynb)\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 Generic 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 = True\n", + "\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.05 # Ripple amplitude\n", + "WAVELENGTH_X = 1.0 # Wavelength along x\n", + "WAVELENGTH_Y = 1.0 # Wavelength along y\n", + "PHASE = 0.0 # Phase shift\n", + "\n", + "# Define the perturbation function\n", + "custom_sympy_function = AMPLITUDE * (\n", + " sp.sin(2 * sp.pi * x / WAVELENGTH_X + PHASE) +\n", + " sp.sin(2 * sp.pi * y / WAVELENGTH_Y + PHASE)\n", + ")" + ], + "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=30, length=30, vacuum_width=0, vacuum_length=0)\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_custom, 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 set_materials\n", + "\n", + "set_materials(material_with_custom_perturbation)" + ], + "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 +} From 05cfc0aaa394381494c778761be16b72b999984a Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Sun, 29 Dec 2024 22:20:31 -0800 Subject: [PATCH 2/6] wip: waves across x --- .../perturbation_graphene.ipynb | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/other/materials_designer/specific_examples/perturbation_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_graphene.ipynb index 213d3bdb..3981531e 100644 --- a/other/materials_designer/specific_examples/perturbation_graphene.ipynb +++ b/other/materials_designer/specific_examples/perturbation_graphene.ipynb @@ -115,16 +115,15 @@ "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.05 # Ripple amplitude\n", - "WAVELENGTH_X = 1.0 # Wavelength along x\n", - "WAVELENGTH_Y = 1.0 # Wavelength along y\n", - "PHASE = 0.0 # Phase shift\n", + "AMPLITUDE = 0.05 # Ripple amplitude in Angstroms\n", + "WAVELENGTH = 0.25 # Wavelength of ripples (approximately 100Å/4 to match image)\n", + "PHASE_X = 0.0 # Phase shift for x direction\n", + "PHASE_Y = sp.pi/2 # Phase shift for y direction to create cross-pattern\n", "\n", - "# Define the perturbation function\n", + "# Define the perturbation function - using both x and y components to create the ripple pattern\n", "custom_sympy_function = AMPLITUDE * (\n", - " sp.sin(2 * sp.pi * x / WAVELENGTH_X + PHASE) +\n", - " sp.sin(2 * sp.pi * y / WAVELENGTH_Y + PHASE)\n", + " sp.sin(2 * sp.pi * x / WAVELENGTH + PHASE_X) \n", + " # sp.sin(2 * sp.pi * y / WAVELENGTH + PHASE_Y)\n", ")" ], "metadata": { @@ -175,7 +174,7 @@ "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=30, length=30, vacuum_width=0, vacuum_length=0)\n", + "config = NanoribbonConfiguration(material=material, width=20, length=20, vacuum_width=0, vacuum_length=0)\n", "\n", "supercell = create_nanoribbon(config)\n", "visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")" From 32439924db1f6c40ec490c8ba34e1123bd5633c0 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:43:29 -0800 Subject: [PATCH 3/6] update: make work --- .../perturbation_graphene.ipynb | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/other/materials_designer/specific_examples/perturbation_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_graphene.ipynb index 3981531e..451788ab 100644 --- a/other/materials_designer/specific_examples/perturbation_graphene.ipynb +++ b/other/materials_designer/specific_examples/perturbation_graphene.ipynb @@ -3,22 +3,13 @@ { "cell_type": "markdown", "source": [ - "# Create a Custom Perturbation in a Material\n", + "# Perturbation of Graphene flake\n", "\n", - "Create a perturbation in a material with a custom function described with [SymPy](https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html) expressions. \n", + "## 0. Introduction\n", "\n", - "

Usage

\n", + "This notebook demonstrates how to recreate a material from the following manuscript:\n", "\n", - "1. Make sure to select Input Materials (in the outer runtime) before running the notebook.\n", - "1. Set perturbation parameters in cell 1.2. (or use default).\n", - "1. Set custom perturbation function with SymPy in cell 1.3.\n", - "1. Click “Run” > “Run All” to run all cells. \n", - "1. Wait for the run to complete (depending on the parameters can take a few min). \n", - "1. Scroll down to view results. \n", - "\n", - "## Notes\n", - "\n", - "1. For more information, see [Introduction](Introduction.ipynb)\n" + "> \n" ], "metadata": { "collapsed": false @@ -69,7 +60,7 @@ { "cell_type": "markdown", "source": [ - "### 1.2. Set Generic Perturbation Parameters" + "### 1.2. Set Nanoribbon and Perturbation Parameters" ], "metadata": { "collapsed": false @@ -81,8 +72,10 @@ "outputs": [], "source": [ "# Set whether to preserve geodesic distance and scale the cell accordingly to match PBC\n", - "PRESERVE_GEODESIC_DISTANCE = True\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", @@ -115,16 +108,32 @@ "variable_names = [\"x\", \"y\", \"z\"]\n", "x, y, z = sp.symbols(variable_names)\n", "\n", - "AMPLITUDE = 0.05 # Ripple amplitude in Angstroms\n", - "WAVELENGTH = 0.25 # Wavelength of ripples (approximately 100Å/4 to match image)\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.35 # 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 to create cross-pattern\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", - "# Define the perturbation function - using both x and y components to create the ripple pattern\n", - "custom_sympy_function = AMPLITUDE * (\n", - " sp.sin(2 * sp.pi * x / WAVELENGTH + PHASE_X) \n", - " # sp.sin(2 * sp.pi * y / WAVELENGTH + PHASE_Y)\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 @@ -174,7 +183,7 @@ "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=20, length=20, vacuum_width=0, vacuum_length=0)\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\")" @@ -238,7 +247,7 @@ "source": [ "from mat3ra.made.tools.build.perturbation import create_perturbation\n", "\n", - "material_with_custom_perturbation = create_perturbation(configuration_custom, builder)" + "material_with_custom_perturbation = create_perturbation(configuration=configuration_custom, builder=builder)" ], "metadata": { "collapsed": false @@ -294,6 +303,16 @@ }, "id": "29dfa0a329cca2fa", "execution_count": null + }, + { + "cell_type": "code", + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + }, + "id": "a8f75903965d493c", + "execution_count": null } ], "metadata": { From a31ebd0bb093e1b16030976f24c3238d2667aa35 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Mon, 30 Dec 2024 12:17:08 -0800 Subject: [PATCH 4/6] update: add description --- .../perturbation_graphene.ipynb | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/other/materials_designer/specific_examples/perturbation_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_graphene.ipynb index 451788ab..b72ab6d4 100644 --- a/other/materials_designer/specific_examples/perturbation_graphene.ipynb +++ b/other/materials_designer/specific_examples/perturbation_graphene.ipynb @@ -9,7 +9,15 @@ "\n", "This notebook demonstrates how to recreate a material from the following manuscript:\n", "\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 @@ -111,7 +119,7 @@ "# Set the parameters for the perturbation function\n", "AMPLITUDE = 0.09 # Ripple amplitude\n", "WAVELENGTH = 0.2 # Wavelength of ripples\n", - "EDGE_WIDTH = 0.35 # Width of edge effect\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", @@ -294,25 +302,15 @@ "cell_type": "code", "outputs": [], "source": [ - "from utils.jupyterlite import set_materials\n", + "from utils.jupyterlite import download_content_to_file\n", "\n", - "set_materials(material_with_custom_perturbation)" + "download_content_to_file(material_with_custom_perturbation, f\"{MATERIAL_NAME}_edge_perturbation.json\")" ], "metadata": { "collapsed": false }, "id": "29dfa0a329cca2fa", "execution_count": null - }, - { - "cell_type": "code", - "outputs": [], - "source": [], - "metadata": { - "collapsed": false - }, - "id": "a8f75903965d493c", - "execution_count": null } ], "metadata": { From fc73fefad3fad1fb6b1f4107f4e20aaa6474630d Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Mon, 30 Dec 2024 12:33:39 -0800 Subject: [PATCH 5/6] chore: rename to match docs --- ...urbation_graphene.ipynb => perturbation_ripple_graphene.ipynb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename other/materials_designer/specific_examples/{perturbation_graphene.ipynb => perturbation_ripple_graphene.ipynb} (100%) diff --git a/other/materials_designer/specific_examples/perturbation_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb similarity index 100% rename from other/materials_designer/specific_examples/perturbation_graphene.ipynb rename to other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb From 7533baa010c70a3aff0222f3f3f3082ad3e4d929 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:24:08 -0800 Subject: [PATCH 6/6] chore: rename title --- .../specific_examples/perturbation_ripple_graphene.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb b/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb index b72ab6d4..5bba83b5 100644 --- a/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb +++ b/other/materials_designer/specific_examples/perturbation_ripple_graphene.ipynb @@ -3,7 +3,7 @@ { "cell_type": "markdown", "source": [ - "# Perturbation of Graphene flake\n", + "# Ripple perturbation of a graphene sheet.\n", "\n", "## 0. Introduction\n", "\n",