From f2a38c62c5b90ad89c43716609674b9f288b1941 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 18:37:29 -0800
Subject: [PATCH 1/9] feat: add optimization tutorial nb
---
.../specific_examples/optimization_film.ipynb | 310 ++++++++++++++++++
1 file changed, 310 insertions(+)
create mode 100644 other/materials_designer/specific_examples/optimization_film.ipynb
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimization_film.ipynb
new file mode 100644
index 00000000..3e8920e9
--- /dev/null
+++ b/other/materials_designer/specific_examples/optimization_film.ipynb
@@ -0,0 +1,310 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "initial_id",
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Optimize Interface Film Position\n",
+ "\n",
+ "This notebook optimizes the position of a film in an interface structure by:\n",
+ "1. Evaluating energies across an x-y grid of positions\n",
+ "2. Finding the optimal position that minimizes interaction energy\n",
+ "3. Visualizing the energy landscape\n",
+ "\n",
+ "## 1. Set up the environment\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "b8a6ffb249ccdbdf"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "# Parameters for optimization\n",
+ "GRID_SIZE = (20, 20) # Resolution of the x-y grid\n",
+ "GRID_RANGE_X = (-0.5, 0.5) # Range to search in x direction (in crystal coordinates)\n",
+ "GRID_RANGE_Y = (-0.5, 0.5) # Range to search in y direction (in crystal coordinates)\n",
+ "USE_CARTESIAN = False # Whether to use Cartesian coordinates\n",
+ "SHADOWING_RADIUS = 2.5 # Radius for detecting surface atoms (in Angstroms)\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "98ad72572c74fc02",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 2. Import required packages\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "91163f0485653d87"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import plotly.graph_objects as go\n",
+ "from IPython.display import display\n",
+ "from mat3ra.made.material import Material\n",
+ "\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "d01a9276825e4d1a",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 3. Define visualization functions\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "c5d64955619553db"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "def plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=None):\n",
+ " \"\"\"\n",
+ " Create a 3D surface plot of the energy landscape.\n",
+ " \n",
+ " Args:\n",
+ " xy_matrix (List[np.ndarray]): X and Y coordinate matrices\n",
+ " energy_matrix (np.ndarray): Matrix of energy values\n",
+ " optimal_position (tuple, optional): The optimal (x,y) position to highlight\n",
+ " \"\"\"\n",
+ " x_vals, y_vals = xy_matrix\n",
+ " X, Y = np.meshgrid(x_vals, y_vals)\n",
+ " \n",
+ " # Create the 3D surface plot\n",
+ " fig = go.Figure(data=[\n",
+ " go.Surface(x=X, y=Y, z=energy_matrix, colorscale='Viridis')\n",
+ " ])\n",
+ " \n",
+ " # Add optimal position marker if provided\n",
+ " if optimal_position is not None:\n",
+ " x_opt, y_opt = optimal_position[0], optimal_position[1]\n",
+ " z_opt = np.min(energy_matrix)\n",
+ " fig.add_trace(go.Scatter3d(\n",
+ " x=[x_opt], y=[y_opt], z=[z_opt],\n",
+ " mode='markers',\n",
+ " marker=dict(size=8, color='red'),\n",
+ " name='Optimal Position'\n",
+ " ))\n",
+ " \n",
+ " fig.update_layout(\n",
+ " title='Interface Energy Landscape',\n",
+ " scene=dict(\n",
+ " xaxis_title='X Position',\n",
+ " yaxis_title='Y Position',\n",
+ " zaxis_title='Energy'\n",
+ " ),\n",
+ " width=800,\n",
+ " height=800\n",
+ " )\n",
+ " \n",
+ " fig.show()\n",
+ "\n",
+ "\n",
+ "def plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=None):\n",
+ " \"\"\"Create a 2D heatmap of the energy landscape.\"\"\"\n",
+ " x_vals, y_vals = xy_matrix\n",
+ "\n",
+ " fig = go.Figure(data=go.Heatmap(\n",
+ " x=x_vals,\n",
+ " y=y_vals,\n",
+ " z=energy_matrix,\n",
+ " colorscale='Viridis',\n",
+ " colorbar=dict(title='Energy')\n",
+ " ))\n",
+ "\n",
+ " if optimal_position is not None:\n",
+ " x_opt, y_opt = optimal_position[0], optimal_position[1]\n",
+ " fig.add_trace(go.Scatter(\n",
+ " x=[x_opt],\n",
+ " y=[y_opt],\n",
+ " mode='markers',\n",
+ " marker=dict(size=12, color='red', symbol='x'),\n",
+ " name='Optimal Position'\n",
+ " ))\n",
+ "\n",
+ " fig.update_layout(\n",
+ " title='Interface Energy Heatmap',\n",
+ " xaxis_title='X Position',\n",
+ " yaxis_title='Y Position',\n",
+ " width=800,\n",
+ " height=600\n",
+ " )\n",
+ "\n",
+ " fig.show()\n",
+ "\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "a168051e47adf306",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 6. Load and optimize material\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "77bd2763b4accaf6"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from mat3ra.made.tools.build.interface import get_optimal_film_displacement\n",
+ "# Import required packages \n",
+ "from utils.visualize import visualize_materials\n",
+ "from mat3ra.made.tools.build.interface import interface_displace_part\n",
+ "from mat3ra.made.tools.calculate.calculators import InterfaceMaterialCalculator\n",
+ "from mat3ra.made.tools.optimize import evaluate_calculator_on_xy_grid\n",
+ "from utils.jupyterlite import get_materials, set_materials\n",
+ "import numpy as np\n",
+ "import plotly.graph_objects as go\n",
+ "\n",
+ "# Parameters\n",
+ "GRID_SIZE = (20, 20)\n",
+ "GRID_RANGE_X = (-0.0, 1.0)\n",
+ "GRID_RANGE_Y = (-0.0, 1.0)\n",
+ "USE_CARTESIAN = False\n",
+ "\n",
+ "\n",
+ "\n",
+ "# Get the material\n",
+ "materials = get_materials(globals())\n",
+ "interface_material = materials[0]\n",
+ "interface_material = interface_displace_part(\n",
+ " interface_material,\n",
+ " displacement=[0.24, 1.1,0],\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "print(\"Material labels:\", interface_material.basis.labels)\n",
+ "\n",
+ "# Initialize calculator\n",
+ "calculator = InterfaceMaterialCalculator()\n",
+ "\n",
+ "# Calculate energy landscape\n",
+ "xy_matrix, energy_matrix = evaluate_calculator_on_xy_grid(\n",
+ " material=interface_material,\n",
+ " calculator_function=calculator.get_energy,\n",
+ " modifier=interface_displace_part,\n",
+ " grid_size_xy=GRID_SIZE,\n",
+ " grid_range_x=GRID_RANGE_X,\n",
+ " grid_range_y=GRID_RANGE_Y,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "\n",
+ "optimal_displacement = get_optimal_film_displacement(material=interface_material, calculator=calculator, \n",
+ " grid_size_xy=GRID_SIZE,\n",
+ " grid_range_x=GRID_RANGE_X,\n",
+ " grid_range_y=GRID_RANGE_Y,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN)\n",
+ " \n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "10ba8778c747f7ed",
+ "execution_count": null
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "\n",
+ "# Plot energy landscape\n",
+ "plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=optimal_displacement)\n",
+ "plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=optimal_displacement)\n",
+ "# Create optimized material\n",
+ "optimized_material = interface_displace_part(\n",
+ " interface_material,\n",
+ " displacement=optimal_displacement,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "\n",
+ "# Visualize materials\n",
+ "print(\"\\nVisualization of original and optimized materials:\")\n",
+ "visualize_materials([interface_material, optimized_material], repetitions=[3, 3,1])\n",
+ "visualize_materials([interface_material, optimized_material], repetitions=[3,3,1], rotation='-90x')\n",
+ "\n",
+ "print(f\"\\nOptimal displacement: {optimal_displacement}\")\n",
+ "\n",
+ "# Save optimized material (uncomment to use)\n",
+ "# set_materials(optimized_material)"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "1ea7e9ae1349ebab",
+ "execution_count": null
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "60b9d140c1196d72",
+ "execution_count": null
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "4d3331c6b4eb983c",
+ "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 d7b0c6f9712fd440bee89c92b3bdcb2f116279f8 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 18:55:37 -0800
Subject: [PATCH 2/9] update: add plots of energy xy
---
utils/plot.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/utils/plot.py b/utils/plot.py
index 331dcded..77d82005 100644
--- a/utils/plot.py
+++ b/utils/plot.py
@@ -1,6 +1,7 @@
from typing import Dict, List, Union
import matplotlib.pyplot as plt
+import numpy as np
import plotly.graph_objs as go
from ase.atoms import Atoms as ASEAtoms
from ase.optimize import BFGS, FIRE
@@ -151,3 +152,77 @@ def plot_rdf(material: Material, cutoff: float = 10.0, bin_size: float = 0.1):
plt.legend()
plt.grid()
plt.show()
+
+
+def plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=None):
+ """
+ Create a 3D surface plot of the energy landscape.
+
+ Args:
+ xy_matrix (List[np.ndarray]): X and Y coordinate matrices
+ energy_matrix (np.ndarray): Matrix of energy values
+ optimal_position (tuple, optional): The optimal (x,y) position to highlight
+ """
+ x_vals, y_vals = xy_matrix
+ X, Y = np.meshgrid(x_vals, y_vals)
+
+ # Create the 3D surface plot
+ fig = go.Figure(data=[go.Surface(x=X, y=Y, z=energy_matrix, colorscale="Viridis")])
+
+ # Add optimal position marker if provided
+ if optimal_position is not None:
+ x_opt, y_opt = optimal_position[0], optimal_position[1]
+ z_opt = np.min(energy_matrix)
+ fig.add_trace(
+ go.Scatter3d(
+ x=[x_opt],
+ y=[y_opt],
+ z=[z_opt],
+ mode="markers",
+ marker=dict(size=8, color="red"),
+ name="Optimal Position",
+ )
+ )
+
+ fig.update_layout(
+ title="Interface Energy Landscape",
+ scene=dict(xaxis_title="X Position", yaxis_title="Y Position", zaxis_title="Energy"),
+ width=800,
+ height=800,
+ )
+
+ fig.show()
+
+
+def plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=None):
+ """
+ Create a 2D heatmap of the energy landscape.
+
+ Args:
+ xy_matrix (List[np.ndarray]): X and Y coordinate matrices
+ energy_matrix (np.ndarray): Matrix of energy values
+ optimal_position (tuple, optional): The optimal (x,y) position to highlight
+ """
+ x_vals, y_vals = xy_matrix
+
+ fig = go.Figure(
+ data=go.Heatmap(x=x_vals, y=y_vals, z=energy_matrix, colorscale="Viridis", colorbar=dict(title="Energy"))
+ )
+
+ if optimal_position is not None:
+ x_opt, y_opt = optimal_position[0], optimal_position[1]
+ fig.add_trace(
+ go.Scatter(
+ x=[x_opt],
+ y=[y_opt],
+ mode="markers",
+ marker=dict(size=12, color="red", symbol="x"),
+ name="Optimal Position",
+ )
+ )
+
+ fig.update_layout(
+ title="Interface Energy Heatmap", xaxis_title="X Position", yaxis_title="Y Position", width=800, height=600
+ )
+
+ fig.show()
From d496ce98c44beb0c97ab310615c0961b8e5fc71c Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:08:16 -0800
Subject: [PATCH 3/9] feat: add optimization nb general
---
.../optimize_film_position.ipynb | 287 ++++++++++++++++++
1 file changed, 287 insertions(+)
create mode 100644 other/materials_designer/optimize_film_position.ipynb
diff --git a/other/materials_designer/optimize_film_position.ipynb b/other/materials_designer/optimize_film_position.ipynb
new file mode 100644
index 00000000..a61f4552
--- /dev/null
+++ b/other/materials_designer/optimize_film_position.ipynb
@@ -0,0 +1,287 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Optimize Interface Film Position\n",
+ "\n",
+ "Find most optimal position of the film on the substrate interface.\n",
+ "\n",
+ "
Usage
\n",
+ "\n",
+ "1. Make sure to select Input Material from the list of available materials. Must be an interface.\n",
+ "1. Set notebook parameters in cell 1.2. below (or use the default values).\n",
+ "1. Click \"Run\" > \"Run All\" to run all cells.\n",
+ "1. Wait for the run to complete.\n",
+ "1. Scroll down to view results.\n",
+ "\n",
+ "## Notes\n",
+ "\n",
+ "- The optimization is performed on a 2D grid of x,y translations.\n",
+ "- Interface material must have atoms labeled \"0\" for the substrate and \"1\" for the film.\n",
+ "\n",
+ "\n",
+ "## 1. Prepare the Environment\n",
+ "### 1.1. Install Packages\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "4dc7b2ed495d66e0"
+ },
+ {
+ "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(\"\")\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "dd86bee2985f1b50",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 1.2. Set optimization parameters\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "cca70ab27ef1d01d"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "MATERIAL_INDEX = 0 # Index of the material to optimize\n",
+ "# Grid parameters\n",
+ "GRID_SIZE = (20, 20) # Resolution of the x-y grid\n",
+ "GRID_RANGE_X = (-0.5, 0.5) # Range to search in x direction\n",
+ "GRID_RANGE_Y = (-0.5, 0.5) # Range to search in y direction\n",
+ "USE_CARTESIAN = False # Whether to use Cartesian coordinates\n",
+ "\n",
+ "# Visualization parameters\n",
+ "SHOW_3D_LANDSCAPE = False # Whether to show 3D energy landscape\n",
+ "STRUCTURE_REPETITIONS = [3, 3, 1] # Repetitions for structure visualization\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "12878fd61f5a6b13",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 3. Load Material\n",
+ "### 3.1. Make sure that loaded material is an interface material (atoms must have labels \"0\" for the substrate and \"1\" for the film)"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "463af646361cd982"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from utils.jupyterlite import get_materials\n",
+ "\n",
+ "materials = get_materials(globals())\n",
+ "interface_material = materials[MATERIAL_INDEX]\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "3d982a1ca641f0d8"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 3.2. Visualize the Material\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "e920a6dd4906d8e8"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from utils.visualize import visualize_materials\n",
+ "\n",
+ "visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS)\n",
+ "visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS, rotation='-90x')"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "5f4afdb7ac0c865b"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 3.3. Optimize Film Position"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "90255d774f62d1da"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from mat3ra.made.tools.build.interface import get_optimal_film_displacement\n",
+ "from mat3ra.made.tools.modify import interface_displace_part\n",
+ "from mat3ra.made.tools.calculate.calculators import InterfaceMaterialCalculator\n",
+ "from mat3ra.made.tools.optimize import evaluate_calculator_on_xy_grid\n",
+ "calculator = InterfaceMaterialCalculator()\n",
+ "\n",
+ "# Calculate energy landscape\n",
+ "xy_matrix, energy_matrix = evaluate_calculator_on_xy_grid(\n",
+ " material=interface_material,\n",
+ " calculator_function=calculator.get_energy,\n",
+ " modifier=interface_displace_part,\n",
+ " grid_size_xy=GRID_SIZE,\n",
+ " grid_range_x=GRID_RANGE_X,\n",
+ " grid_range_y=GRID_RANGE_Y,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "\n",
+ "# Find optimal position\n",
+ "optimal_displacement = get_optimal_film_displacement(\n",
+ " material=interface_material,\n",
+ " calculator=calculator,\n",
+ " grid_size_xy=GRID_SIZE,\n",
+ " grid_range_x=GRID_RANGE_X,\n",
+ " grid_range_y=GRID_RANGE_Y,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "\n",
+ "print(f\"\\nOptimal displacement vector: {optimal_displacement}\")\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "eb0b6e59c24dda4"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 4. Visualize Results\n",
+ "### 4.1. Plot Energy Landscape"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "2945179d3729935d"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from utils.plot import plot_energy_heatmap, plot_energy_landscape\n",
+ "# Plot energy landscape\n",
+ "plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=optimal_displacement[:2])\n",
+ "\n",
+ "if SHOW_3D_LANDSCAPE:\n",
+ " plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=optimal_displacement[:2])\n",
+ "\n",
+ "# Create optimized material\n",
+ "optimized_material = interface_displace_part(\n",
+ " interface_material,\n",
+ " displacement=optimal_displacement,\n",
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "41ac6b383001db6b",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 4.1. Visualize Original and Optimized Materials"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "82a1af573c6ca0e9"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "print(\"\\nVisualization of original and optimized materials:\")\n",
+ "visualize_materials([interface_material, optimized_material],\n",
+ " repetitions=STRUCTURE_REPETITIONS)\n",
+ "visualize_materials([interface_material, optimized_material],\n",
+ " repetitions=STRUCTURE_REPETITIONS,\n",
+ " rotation='-90x')\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "e7972543ae747b68",
+ "execution_count": null
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 5. Save Results\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "b4f6308e795e4f3c"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from utils.jupyterlite import download_content_to_file\n",
+ "download_content_to_file(optimized_material, f\"{interface_material.name}_optimized_xy.json\")"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "c81ec652fbb64316",
+ "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 1e8fa0cc38a55079390167ae7fb3b9e0f21e2292 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:10:28 -0800
Subject: [PATCH 4/9] update: adjust intro nb
---
other/materials_designer/Introduction.ipynb | 2 ++
other/materials_designer/optimize_film_position.ipynb | 5 +++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/other/materials_designer/Introduction.ipynb b/other/materials_designer/Introduction.ipynb
index dcd076a5..a2dd38f9 100644
--- a/other/materials_designer/Introduction.ipynb
+++ b/other/materials_designer/Introduction.ipynb
@@ -97,6 +97,8 @@
"\n",
"This notebook demonstrates a workflow for converting materials data from the [JARVIS](https://jarvis.nist.gov/) database into ESSE format for use with the Mat3ra.com platform.\n",
"\n",
+ "#### [6.1.4. Optimize film position on interface](optimize_film_position.ipynb).\n",
+ "\n",
"## 7. Read more\n",
"\n",
"### 7.1. Under the hood.\n",
diff --git a/other/materials_designer/optimize_film_position.ipynb b/other/materials_designer/optimize_film_position.ipynb
index a61f4552..0136b9f1 100644
--- a/other/materials_designer/optimize_film_position.ipynb
+++ b/other/materials_designer/optimize_film_position.ipynb
@@ -253,8 +253,9 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import download_content_to_file\n",
- "download_content_to_file(optimized_material, f\"{interface_material.name}_optimized_xy.json\")"
+ "from utils.jupyterlite import set_materials\n",
+ "\n",
+ "set_materials(optimized_material)"
],
"metadata": {
"collapsed": false
From 515576fdb57e6d9d3f6dd1cd5359669972be6467 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:25:35 -0800
Subject: [PATCH 5/9] update: restrucutre as other nbs
---
.../specific_examples/optimization_film.ipynb | 392 +++++++++++-------
1 file changed, 239 insertions(+), 153 deletions(-)
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimization_film.ipynb
index 3e8920e9..48d978a5 100644
--- a/other/materials_designer/specific_examples/optimization_film.ipynb
+++ b/other/materials_designer/specific_examples/optimization_film.ipynb
@@ -1,213 +1,261 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "initial_id",
+ "cell_type": "markdown",
+ "source": [
+ "# Optimize Interface Film Position\n",
+ "\n",
+ "## 0. Introduction\n",
+ "This notebook optimizes the position of a film in an interface structure by:\n",
+ "1. Creating an interface between two materials using Zero Strain Lattice (ZSL) matching\n",
+ "2. Evaluating energies across an x-y grid of positions\n",
+ "3. Finding the optimal position that minimizes interaction energy\n",
+ "4. Visualizing the energy landscape\n",
+ "\n",
+ "## 1. Prepare the Environment\n",
+ "### 1.1. Install Packages\n"
+ ],
"metadata": {
- "collapsed": true
+ "collapsed": false
},
+ "id": "567b1b812acb1718"
+ },
+ {
+ "cell_type": "code",
"outputs": [],
- "source": []
+ "source": [
+ "import sys\n",
+ "if sys.platform == \"emscripten\":\n",
+ " import micropip\n",
+ " await micropip.install('mat3ra-api-examples', deps=False)\n",
+ " from utils.jupyterlite import install_packages\n",
+ " await install_packages(\"specific_examples|create_interface_with_min_strain_zsl.ipynb\")\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "6cc535057854a4d1",
+ "execution_count": 0
},
{
"cell_type": "markdown",
"source": [
- "# Optimize Interface Film Position\n",
- "\n",
- "This notebook optimizes the position of a film in an interface structure by:\n",
- "1. Evaluating energies across an x-y grid of positions\n",
- "2. Finding the optimal position that minimizes interaction energy\n",
- "3. Visualizing the energy landscape\n",
- "\n",
- "## 1. Set up the environment\n"
+ "### 1.2. Set Parameters\n"
],
"metadata": {
"collapsed": false
},
- "id": "b8a6ffb249ccdbdf"
+ "id": "63d36e1a062ae33a"
},
{
"cell_type": "code",
"outputs": [],
"source": [
- "# Parameters for optimization\n",
+ "# Material selection\n",
+ "SUBSTRATE_NAME = \"Nickel\"\n",
+ "FILM_NAME = \"Graphene\"\n",
+ "\n",
+ "# Slab parameters\n",
+ "FILM_MILLER_INDICES = (0, 0, 1)\n",
+ "FILM_THICKNESS = 1 # in atomic layers\n",
+ "FILM_VACUUM = 0.0 # in angstroms\n",
+ "FILM_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "FILM_USE_ORTHOGONAL_Z = True\n",
+ "\n",
+ "SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n",
+ "SUBSTRATE_THICKNESS = 4 # in atomic layers\n",
+ "SUBSTRATE_VACUUM = 0.0 # in angstroms\n",
+ "SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
+ "\n",
+ "# Interface parameters\n",
+ "MAX_AREA = 50 # in Angstrom^2\n",
+ "INTERFACE_DISTANCE = 2.58 # in Angstrom\n",
+ "INTERFACE_VACUUM = 20.0 # in Angstrom\n",
+ "\n",
+ "# Optimization parameters\n",
"GRID_SIZE = (20, 20) # Resolution of the x-y grid\n",
- "GRID_RANGE_X = (-0.5, 0.5) # Range to search in x direction (in crystal coordinates)\n",
- "GRID_RANGE_Y = (-0.5, 0.5) # Range to search in y direction (in crystal coordinates)\n",
+ "GRID_RANGE_X = (-0.5, 0.5) # Range to search in x direction\n",
+ "GRID_RANGE_Y = (-0.5, 0.5) # Range to search in y direction\n",
"USE_CARTESIAN = False # Whether to use Cartesian coordinates\n",
- "SHADOWING_RADIUS = 2.5 # Radius for detecting surface atoms (in Angstroms)\n"
+ "\n",
+ "# Visualization parameters\n",
+ "SHOW_3D_LANDSCAPE = False # Whether to show 3D energy landscape\n",
+ "STRUCTURE_REPETITIONS = [3, 3, 1] # Repetitions for structure visualization\n"
],
"metadata": {
"collapsed": false
},
- "id": "98ad72572c74fc02",
- "execution_count": null
+ "id": "feed5532d2d5bf8",
+ "execution_count": 0
},
{
"cell_type": "markdown",
"source": [
- "## 2. Import required packages\n"
+ "## 2. Create Interface Material\n",
+ "### 2.1. Load Materials\n"
],
"metadata": {
"collapsed": false
},
- "id": "91163f0485653d87"
+ "id": "d4ee2a1c17a07fa7"
},
{
"cell_type": "code",
"outputs": [],
"source": [
- "import numpy as np\n",
- "import plotly.graph_objects as go\n",
- "from IPython.display import display\n",
+ "from utils.visualize import visualize_materials\n",
+ "from mat3ra.standata.materials import Materials\n",
"from mat3ra.made.material import Material\n",
- "\n"
+ "\n",
+ "substrate = Material(Materials.get_by_name_first_match(SUBSTRATE_NAME))\n",
+ "film = Material(Materials.get_by_name_first_match(FILM_NAME))\n",
+ "\n",
+ "# Preview materials\n",
+ "visualize_materials([substrate, film], repetitions=STRUCTURE_REPETITIONS, rotation=\"0x\")\n"
],
"metadata": {
"collapsed": false
},
- "id": "d01a9276825e4d1a",
- "execution_count": null
+ "id": "f1047ca2cc30b87a",
+ "execution_count": 0
},
{
"cell_type": "markdown",
"source": [
- "## 3. Define visualization functions\n"
+ "### 2.2. Create Slabs"
],
"metadata": {
"collapsed": false
},
- "id": "c5d64955619553db"
+ "id": "14c4e4f9aa6721a"
},
{
"cell_type": "code",
"outputs": [],
"source": [
- "def plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=None):\n",
- " \"\"\"\n",
- " Create a 3D surface plot of the energy landscape.\n",
- " \n",
- " Args:\n",
- " xy_matrix (List[np.ndarray]): X and Y coordinate matrices\n",
- " energy_matrix (np.ndarray): Matrix of energy values\n",
- " optimal_position (tuple, optional): The optimal (x,y) position to highlight\n",
- " \"\"\"\n",
- " x_vals, y_vals = xy_matrix\n",
- " X, Y = np.meshgrid(x_vals, y_vals)\n",
- " \n",
- " # Create the 3D surface plot\n",
- " fig = go.Figure(data=[\n",
- " go.Surface(x=X, y=Y, z=energy_matrix, colorscale='Viridis')\n",
- " ])\n",
- " \n",
- " # Add optimal position marker if provided\n",
- " if optimal_position is not None:\n",
- " x_opt, y_opt = optimal_position[0], optimal_position[1]\n",
- " z_opt = np.min(energy_matrix)\n",
- " fig.add_trace(go.Scatter3d(\n",
- " x=[x_opt], y=[y_opt], z=[z_opt],\n",
- " mode='markers',\n",
- " marker=dict(size=8, color='red'),\n",
- " name='Optimal Position'\n",
- " ))\n",
- " \n",
- " fig.update_layout(\n",
- " title='Interface Energy Landscape',\n",
- " scene=dict(\n",
- " xaxis_title='X Position',\n",
- " yaxis_title='Y Position',\n",
- " zaxis_title='Energy'\n",
- " ),\n",
- " width=800,\n",
- " height=800\n",
- " )\n",
- " \n",
- " fig.show()\n",
+ "from mat3ra.made.tools.build.slab import SlabConfiguration, PymatgenSlabGeneratorParameters, get_terminations, \\\n",
+ " create_slab\n",
"\n",
+ "# Configure slabs\n",
+ "film_slab_configuration = SlabConfiguration(\n",
+ " bulk=film,\n",
+ " miller_indices=FILM_MILLER_INDICES,\n",
+ " thickness=FILM_THICKNESS,\n",
+ " vacuum=FILM_VACUUM,\n",
+ " xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=FILM_USE_ORTHOGONAL_Z\n",
+ ")\n",
"\n",
- "def plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=None):\n",
- " \"\"\"Create a 2D heatmap of the energy landscape.\"\"\"\n",
- " x_vals, y_vals = xy_matrix\n",
+ "substrate_slab_configuration = SlabConfiguration(\n",
+ " bulk=substrate,\n",
+ " miller_indices=SUBSTRATE_MILLER_INDICES,\n",
+ " thickness=SUBSTRATE_THICKNESS,\n",
+ " vacuum=SUBSTRATE_VACUUM,\n",
+ " xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=SUBSTRATE_USE_ORTHOGONAL_Z,\n",
+ ")\n",
"\n",
- " fig = go.Figure(data=go.Heatmap(\n",
- " x=x_vals,\n",
- " y=y_vals,\n",
- " z=energy_matrix,\n",
- " colorscale='Viridis',\n",
- " colorbar=dict(title='Energy')\n",
- " ))\n",
+ "# Get terminations\n",
+ "params = PymatgenSlabGeneratorParameters(symmetrize=False)\n",
+ "film_slab_terminations = get_terminations(film_slab_configuration, params)\n",
+ "substrate_slab_terminations = get_terminations(substrate_slab_configuration, params)\n",
"\n",
- " if optimal_position is not None:\n",
- " x_opt, y_opt = optimal_position[0], optimal_position[1]\n",
- " fig.add_trace(go.Scatter(\n",
- " x=[x_opt],\n",
- " y=[y_opt],\n",
- " mode='markers',\n",
- " marker=dict(size=12, color='red', symbol='x'),\n",
- " name='Optimal Position'\n",
- " ))\n",
+ "# Create slabs\n",
+ "film_slabs = [create_slab(film_slab_configuration, termination) for termination in film_slab_terminations]\n",
+ "substrate_slabs = [create_slab(substrate_slab_configuration, termination, params) for termination in substrate_slab_terminations]\n",
"\n",
- " fig.update_layout(\n",
- " title='Interface Energy Heatmap',\n",
- " xaxis_title='X Position',\n",
- " yaxis_title='Y Position',\n",
- " width=800,\n",
- " height=600\n",
- " )\n",
- "\n",
- " fig.show()\n",
- "\n"
+ "# Visualize slabs\n",
+ "visualize_materials([{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in film_slabs],\n",
+ " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n",
+ "visualize_materials([{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in substrate_slabs],\n",
+ " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
],
"metadata": {
"collapsed": false
},
- "id": "a168051e47adf306",
- "execution_count": null
+ "id": "9ca8a2ad2b10c1f7",
+ "execution_count": 0
},
{
"cell_type": "markdown",
"source": [
- "## 6. Load and optimize material\n"
+ "### 3.3. Create Interface\n"
],
"metadata": {
"collapsed": false
},
- "id": "77bd2763b4accaf6"
+ "id": "61ba88b1f053c4fb"
},
{
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.tools.build.interface import get_optimal_film_displacement\n",
- "# Import required packages \n",
- "from utils.visualize import visualize_materials\n",
- "from mat3ra.made.tools.build.interface import interface_displace_part\n",
- "from mat3ra.made.tools.calculate.calculators import InterfaceMaterialCalculator\n",
- "from mat3ra.made.tools.optimize import evaluate_calculator_on_xy_grid\n",
- "from utils.jupyterlite import get_materials, set_materials\n",
- "import numpy as np\n",
- "import plotly.graph_objects as go\n",
+ "from mat3ra.made.tools.build.interface import InterfaceConfiguration, ZSLStrainMatchingParameters, \\\n",
+ " ZSLStrainMatchingInterfaceBuilderParameters, ZSLStrainMatchingInterfaceBuilder\n",
+ "from itertools import product\n",
"\n",
- "# Parameters\n",
- "GRID_SIZE = (20, 20)\n",
- "GRID_RANGE_X = (-0.0, 1.0)\n",
- "GRID_RANGE_Y = (-0.0, 1.0)\n",
- "USE_CARTESIAN = False\n",
+ "# Get termination pairs\n",
+ "termination_pairs = list(product(film_slab_terminations, substrate_slab_terminations))\n",
+ "print(\"Termination Pairs (Film, Substrate):\")\n",
+ "for idx, termination_pair in enumerate(termination_pairs):\n",
+ " print(f\" {idx}: {termination_pair}\")\n",
"\n",
+ "# Create interface with first termination pair\n",
+ "termination_pair = termination_pairs[0]\n",
+ "film_termination, substrate_termination = termination_pair\n",
"\n",
+ "interface_configuration = InterfaceConfiguration(\n",
+ " film_configuration=film_slab_configuration,\n",
+ " substrate_configuration=substrate_slab_configuration,\n",
+ " film_termination=film_termination,\n",
+ " substrate_termination=substrate_termination,\n",
+ " distance_z=INTERFACE_DISTANCE,\n",
+ " vacuum=INTERFACE_VACUUM\n",
+ ")\n",
"\n",
- "# Get the material\n",
- "materials = get_materials(globals())\n",
- "interface_material = materials[0]\n",
- "interface_material = interface_displace_part(\n",
- " interface_material,\n",
- " displacement=[0.24, 1.1,0],\n",
- " use_cartesian_coordinates=USE_CARTESIAN\n",
+ "# Build interface using ZSL matching\n",
+ "zsl_params = ZSLStrainMatchingParameters(max_area=MAX_AREA)\n",
+ "builder = ZSLStrainMatchingInterfaceBuilder(\n",
+ " build_parameters=ZSLStrainMatchingInterfaceBuilderParameters(\n",
+ " strain_matching_parameters=zsl_params\n",
+ " )\n",
")\n",
- "print(\"Material labels:\", interface_material.basis.labels)\n",
"\n",
- "# Initialize calculator\n",
+ "interfaces = builder.get_materials(configuration=interface_configuration)\n",
+ "interface_material = interfaces[0] # Select first interface\n",
+ "interface_material.name = f\"{FILM_NAME}_{SUBSTRATE_NAME}_interface\"\n",
+ "\n",
+ "# Visualize interface\n",
+ "visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS)\n",
+ "visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "1af1471d3c1ee856",
+ "execution_count": 0
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 3. Optimize Interface Position\n",
+ "### 3.1. Calculate Energy Landscape\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "8b20dc13f57cfce7"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [],
+ "source": [
+ "from mat3ra.made.tools.build.interface import get_optimal_film_displacement\n",
+ "from mat3ra.made.tools.modify import interface_displace_part\n",
+ "from mat3ra.made.tools.optimize import evaluate_calculator_on_xy_grid\n",
+ "from mat3ra.made.tools.calculate.calculators import InterfaceMaterialCalculator\n",
+ "\n",
"calculator = InterfaceMaterialCalculator()\n",
"\n",
"# Calculate energy landscape\n",
@@ -221,69 +269,107 @@
" use_cartesian_coordinates=USE_CARTESIAN\n",
")\n",
"\n",
- "optimal_displacement = get_optimal_film_displacement(material=interface_material, calculator=calculator, \n",
+ "# Find optimal position\n",
+ "optimal_displacement = get_optimal_film_displacement(\n",
+ " material=interface_material,\n",
+ " calculator=calculator,\n",
" grid_size_xy=GRID_SIZE,\n",
" grid_range_x=GRID_RANGE_X,\n",
" grid_range_y=GRID_RANGE_Y,\n",
- " use_cartesian_coordinates=USE_CARTESIAN)\n",
- " \n"
+ " use_cartesian_coordinates=USE_CARTESIAN\n",
+ ")\n",
+ "print(f\"\\nOptimal displacement vector: {optimal_displacement}\")\n"
],
"metadata": {
"collapsed": false
},
- "id": "10ba8778c747f7ed",
- "execution_count": null
+ "id": "3dd3a069a69b4be1",
+ "execution_count": 0
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 3.2. Visualize Results\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "4028cb9ac8d438f0"
},
{
"cell_type": "code",
"outputs": [],
"source": [
+ "from utils.plot import plot_energy_heatmap, plot_energy_landscape\n",
"\n",
"# Plot energy landscape\n",
- "plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=optimal_displacement)\n",
- "plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=optimal_displacement)\n",
- "# Create optimized material\n",
+ "plot_energy_heatmap(xy_matrix, energy_matrix, optimal_position=optimal_displacement[:2])\n",
+ "if SHOW_3D_LANDSCAPE:\n",
+ " plot_energy_landscape(xy_matrix, energy_matrix, optimal_position=optimal_displacement[:2])\n",
+ "\n",
+ "# Create and visualize optimized material\n",
"optimized_material = interface_displace_part(\n",
" interface_material,\n",
" displacement=optimal_displacement,\n",
" use_cartesian_coordinates=USE_CARTESIAN\n",
- ")\n",
- "\n",
- "# Visualize materials\n",
- "print(\"\\nVisualization of original and optimized materials:\")\n",
- "visualize_materials([interface_material, optimized_material], repetitions=[3, 3,1])\n",
- "visualize_materials([interface_material, optimized_material], repetitions=[3,3,1], rotation='-90x')\n",
- "\n",
- "print(f\"\\nOptimal displacement: {optimal_displacement}\")\n",
- "\n",
- "# Save optimized material (uncomment to use)\n",
- "# set_materials(optimized_material)"
+ ")"
],
"metadata": {
"collapsed": false
},
- "id": "1ea7e9ae1349ebab",
- "execution_count": null
+ "id": "27d655253dd79d2d",
+ "execution_count": 0
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 3.3. Visualize Material\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "262edee47baa8114"
},
{
"cell_type": "code",
"outputs": [],
- "source": [],
+ "source": [
+ "print(\"\\nVisualization of original and optimized materials:\")\n",
+ "visualize_materials([interface_material, optimized_material],\n",
+ " repetitions=STRUCTURE_REPETITIONS)\n",
+ "visualize_materials([interface_material, optimized_material],\n",
+ " repetitions=STRUCTURE_REPETITIONS,\n",
+ " rotation='-90x')"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "489288e70deb7d73"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# 4. Save optimized material"
+ ],
"metadata": {
"collapsed": false
},
- "id": "60b9d140c1196d72",
- "execution_count": null
+ "id": "78304054eca1564e"
},
{
"cell_type": "code",
"outputs": [],
- "source": [],
+ "source": [
+ "from utils.jupyterlite import download_content_to_file\n",
+ "\n",
+ "# Save optimized material\n",
+ "download_content_to_file(optimized_material, f\"{interface_material.name}_optimized_xy.json\")"
+ ],
"metadata": {
"collapsed": false
},
- "id": "4d3331c6b4eb983c",
- "execution_count": null
+ "id": "fb3a1781c32f144f",
+ "execution_count": 0
}
],
"metadata": {
From f3469760bb9a503eed9173177e657e814b297c8a Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:35:09 -0800
Subject: [PATCH 6/9] update: add description
---
.../specific_examples/optimization_film.ipynb | 37 ++++++++++++-------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimization_film.ipynb
index 48d978a5..e3788317 100644
--- a/other/materials_designer/specific_examples/optimization_film.ipynb
+++ b/other/materials_designer/specific_examples/optimization_film.ipynb
@@ -6,11 +6,19 @@
"# Optimize Interface Film Position\n",
"\n",
"## 0. Introduction\n",
- "This notebook optimizes the position of a film in an interface structure by:\n",
- "1. Creating an interface between two materials using Zero Strain Lattice (ZSL) matching\n",
- "2. Evaluating energies across an x-y grid of positions\n",
- "3. Finding the optimal position that minimizes interaction energy\n",
- "4. Visualizing the energy landscape\n",
+ "\n",
+ "This notebook demonstrates how to create Gr/Ni(111) interface and optimize film position.\n",
+ "\n",
+ "Following the manuscript:\n",
+ "\n",
+ "> **Arjun Dahal, Matthias Batzill**\n",
+ "> \"Graphene–nickel interfaces: a review\"\n",
+ "> Nanoscale, 6(5), 2548. (2014)\n",
+ "> [DOI: 10.1039/c3nr05279f](https://doi.org/10.1039/c3nr05279f)\n",
+ " \n",
+ "Recreating interface and shifting film to the most favorable energy position showed in the image below. Fig 1. b.\n",
+ "\n",
+ "
\n",
"\n",
"## 1. Prepare the Environment\n",
"### 1.1. Install Packages\n"
@@ -35,7 +43,7 @@
"collapsed": false
},
"id": "6cc535057854a4d1",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -87,7 +95,7 @@
"collapsed": false
},
"id": "feed5532d2d5bf8",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -118,7 +126,7 @@
"collapsed": false
},
"id": "f1047ca2cc30b87a",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -175,7 +183,7 @@
"collapsed": false
},
"id": "9ca8a2ad2b10c1f7",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -234,7 +242,7 @@
"collapsed": false
},
"id": "1af1471d3c1ee856",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -284,7 +292,7 @@
"collapsed": false
},
"id": "3dd3a069a69b4be1",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -318,7 +326,7 @@
"collapsed": false
},
"id": "27d655253dd79d2d",
- "execution_count": 0
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -344,7 +352,8 @@
"metadata": {
"collapsed": false
},
- "id": "489288e70deb7d73"
+ "id": "489288e70deb7d73",
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -369,7 +378,7 @@
"collapsed": false
},
"id": "fb3a1781c32f144f",
- "execution_count": 0
+ "execution_count": null
}
],
"metadata": {
From ce384024f56278d490b11f3ce2c7ca67b0f1fea6 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:37:17 -0800
Subject: [PATCH 7/9] chore: cleanup
---
.../specific_examples/optimization_film.ipynb | 25 ++++++++++++-------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimization_film.ipynb
index e3788317..368e0b79 100644
--- a/other/materials_designer/specific_examples/optimization_film.ipynb
+++ b/other/materials_designer/specific_examples/optimization_film.ipynb
@@ -33,10 +33,13 @@
"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|create_interface_with_min_strain_zsl.ipynb\")\n"
],
"metadata": {
@@ -171,13 +174,14 @@
"\n",
"# Create slabs\n",
"film_slabs = [create_slab(film_slab_configuration, termination) for termination in film_slab_terminations]\n",
- "substrate_slabs = [create_slab(substrate_slab_configuration, termination, params) for termination in substrate_slab_terminations]\n",
+ "substrate_slabs = [create_slab(substrate_slab_configuration, termination, params) for termination in\n",
+ " substrate_slab_terminations]\n",
"\n",
"# Visualize slabs\n",
"visualize_materials([{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in film_slabs],\n",
- " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n",
+ " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n",
"visualize_materials([{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in substrate_slabs],\n",
- " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
+ " repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
],
"metadata": {
"collapsed": false
@@ -188,7 +192,7 @@
{
"cell_type": "markdown",
"source": [
- "### 3.3. Create Interface\n"
+ "### 2.3. Create Interface\n"
],
"metadata": {
"collapsed": false
@@ -343,11 +347,14 @@
"outputs": [],
"source": [
"print(\"\\nVisualization of original and optimized materials:\")\n",
- "visualize_materials([interface_material, optimized_material],\n",
- " repetitions=STRUCTURE_REPETITIONS)\n",
- "visualize_materials([interface_material, optimized_material],\n",
- " repetitions=STRUCTURE_REPETITIONS,\n",
- " rotation='-90x')"
+ "visualize_materials([{\"material\": interface_material, \"title\": \"Original Interface\"},\n",
+ " {\"material\": optimized_material, \"title\": \"Optimized Interface\"}],\n",
+ " repetitions=STRUCTURE_REPETITIONS,\n",
+ " )\n",
+ "visualize_materials([{\"material\": interface_material, \"title\": \"Original Interface\"},\n",
+ " {\"material\": optimized_material, \"title\": \"Optimized Interface\"}],\n",
+ " repetitions=STRUCTURE_REPETITIONS,\n",
+ " rotation=\"-90x\")"
],
"metadata": {
"collapsed": false
From 8b1eb41d94f151fc36444047f50f2e49d6b63249 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:39:33 -0800
Subject: [PATCH 8/9] chore: cleanup
---
.../specific_examples/optimization_film.ipynb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimization_film.ipynb
index 368e0b79..6b6b5e61 100644
--- a/other/materials_designer/specific_examples/optimization_film.ipynb
+++ b/other/materials_designer/specific_examples/optimization_film.ipynb
@@ -301,7 +301,7 @@
{
"cell_type": "markdown",
"source": [
- "### 3.2. Visualize Results\n"
+ "### 3.2. Visualize Energy Landscape\n"
],
"metadata": {
"collapsed": false
@@ -335,7 +335,7 @@
{
"cell_type": "markdown",
"source": [
- "## 3.3. Visualize Material\n"
+ "### 3.3. Visualize Material\n"
],
"metadata": {
"collapsed": false
From 1dc037691e29dc01806803437661badcd7219cd4 Mon Sep 17 00:00:00 2001
From: VsevolodX
Date: Tue, 31 Dec 2024 00:45:47 -0800
Subject: [PATCH 9/9] chore: rename to have gr/ni
---
..._position_graphene_nickel_interface.ipynb} | 192 +++++++++---------
1 file changed, 96 insertions(+), 96 deletions(-)
rename other/materials_designer/specific_examples/{optimization_film.ipynb => optimize_film_position_graphene_nickel_interface.ipynb} (93%)
diff --git a/other/materials_designer/specific_examples/optimization_film.ipynb b/other/materials_designer/specific_examples/optimize_film_position_graphene_nickel_interface.ipynb
similarity index 93%
rename from other/materials_designer/specific_examples/optimization_film.ipynb
rename to other/materials_designer/specific_examples/optimize_film_position_graphene_nickel_interface.ipynb
index 6b6b5e61..75a5766a 100644
--- a/other/materials_designer/specific_examples/optimization_film.ipynb
+++ b/other/materials_designer/specific_examples/optimize_film_position_graphene_nickel_interface.ipynb
@@ -2,12 +2,16 @@
"cells": [
{
"cell_type": "markdown",
+ "id": "567b1b812acb1718",
+ "metadata": {
+ "collapsed": false
+ },
"source": [
- "# Optimize Interface Film Position\n",
+ "# Optimize Interface Film Position in Gr/Ni(111) Interface\n",
"\n",
"## 0. Introduction\n",
"\n",
- "This notebook demonstrates how to create Gr/Ni(111) interface and optimize film position.\n",
+ "This notebook demonstrates how to create Gr/Ni(111) interface and optimize the film position.\n",
"\n",
"Following the manuscript:\n",
"\n",
@@ -16,20 +20,21 @@
"> Nanoscale, 6(5), 2548. (2014)\n",
"> [DOI: 10.1039/c3nr05279f](https://doi.org/10.1039/c3nr05279f)\n",
" \n",
- "Recreating interface and shifting film to the most favorable energy position showed in the image below. Fig 1. b.\n",
+ "Recreating interface and shifting the film to the most favorable energy position showed in the image below. Fig 1. b.\n",
"\n",
"
\n",
"\n",
"## 1. Prepare the Environment\n",
"### 1.1. Install Packages\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "567b1b812acb1718"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "6cc535057854a4d1",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"import sys\n",
@@ -41,25 +46,25 @@
" from utils.jupyterlite import install_packages\n",
"\n",
" await install_packages(\"specific_examples|create_interface_with_min_strain_zsl.ipynb\")\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "6cc535057854a4d1",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "### 1.2. Set Parameters\n"
- ],
+ "id": "63d36e1a062ae33a",
"metadata": {
"collapsed": false
},
- "id": "63d36e1a062ae33a"
+ "source": [
+ "### 1.2. Set Parameters\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "feed5532d2d5bf8",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"# Material selection\n",
@@ -93,26 +98,26 @@
"# Visualization parameters\n",
"SHOW_3D_LANDSCAPE = False # Whether to show 3D energy landscape\n",
"STRUCTURE_REPETITIONS = [3, 3, 1] # Repetitions for structure visualization\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "feed5532d2d5bf8",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "## 2. Create Interface Material\n",
- "### 2.1. Load Materials\n"
- ],
+ "id": "d4ee2a1c17a07fa7",
"metadata": {
"collapsed": false
},
- "id": "d4ee2a1c17a07fa7"
+ "source": [
+ "## 2. Create Interface Material\n",
+ "### 2.1. Load Materials\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "f1047ca2cc30b87a",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from utils.visualize import visualize_materials\n",
@@ -124,25 +129,25 @@
"\n",
"# Preview materials\n",
"visualize_materials([substrate, film], repetitions=STRUCTURE_REPETITIONS, rotation=\"0x\")\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "f1047ca2cc30b87a",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "### 2.2. Create Slabs"
- ],
+ "id": "14c4e4f9aa6721a",
"metadata": {
"collapsed": false
},
- "id": "14c4e4f9aa6721a"
+ "source": [
+ "### 2.2. Create Slabs"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "9ca8a2ad2b10c1f7",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from mat3ra.made.tools.build.slab import SlabConfiguration, PymatgenSlabGeneratorParameters, get_terminations, \\\n",
@@ -182,25 +187,25 @@
" repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n",
"visualize_materials([{\"material\": slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in substrate_slabs],\n",
" repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "9ca8a2ad2b10c1f7",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "### 2.3. Create Interface\n"
- ],
+ "id": "61ba88b1f053c4fb",
"metadata": {
"collapsed": false
},
- "id": "61ba88b1f053c4fb"
+ "source": [
+ "### 2.3. Create Interface\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "1af1471d3c1ee856",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from mat3ra.made.tools.build.interface import InterfaceConfiguration, ZSLStrainMatchingParameters, \\\n",
@@ -241,26 +246,26 @@
"# Visualize interface\n",
"visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS)\n",
"visualize_materials([interface_material], repetitions=STRUCTURE_REPETITIONS, rotation=\"-90x\")\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "1af1471d3c1ee856",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "## 3. Optimize Interface Position\n",
- "### 3.1. Calculate Energy Landscape\n"
- ],
+ "id": "8b20dc13f57cfce7",
"metadata": {
"collapsed": false
},
- "id": "8b20dc13f57cfce7"
+ "source": [
+ "## 3. Optimize Interface Position\n",
+ "### 3.1. Calculate Energy Landscape\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "3dd3a069a69b4be1",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from mat3ra.made.tools.build.interface import get_optimal_film_displacement\n",
@@ -291,25 +296,25 @@
" use_cartesian_coordinates=USE_CARTESIAN\n",
")\n",
"print(f\"\\nOptimal displacement vector: {optimal_displacement}\")\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "3dd3a069a69b4be1",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "### 3.2. Visualize Energy Landscape\n"
- ],
+ "id": "4028cb9ac8d438f0",
"metadata": {
"collapsed": false
},
- "id": "4028cb9ac8d438f0"
+ "source": [
+ "### 3.2. Visualize Energy Landscape\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "27d655253dd79d2d",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from utils.plot import plot_energy_heatmap, plot_energy_landscape\n",
@@ -325,25 +330,25 @@
" displacement=optimal_displacement,\n",
" use_cartesian_coordinates=USE_CARTESIAN\n",
")"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "27d655253dd79d2d",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "### 3.3. Visualize Material\n"
- ],
+ "id": "262edee47baa8114",
"metadata": {
"collapsed": false
},
- "id": "262edee47baa8114"
+ "source": [
+ "### 3.3. Visualize Material\n"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "489288e70deb7d73",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"print(\"\\nVisualization of original and optimized materials:\")\n",
@@ -355,37 +360,32 @@
" {\"material\": optimized_material, \"title\": \"Optimized Interface\"}],\n",
" repetitions=STRUCTURE_REPETITIONS,\n",
" rotation=\"-90x\")"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "489288e70deb7d73",
- "execution_count": null
+ ]
},
{
"cell_type": "markdown",
- "source": [
- "# 4. Save optimized material"
- ],
+ "id": "78304054eca1564e",
"metadata": {
"collapsed": false
},
- "id": "78304054eca1564e"
+ "source": [
+ "# 4. Save optimized material"
+ ]
},
{
"cell_type": "code",
+ "execution_count": null,
+ "id": "fb3a1781c32f144f",
+ "metadata": {
+ "collapsed": false
+ },
"outputs": [],
"source": [
"from utils.jupyterlite import download_content_to_file\n",
"\n",
"# Save optimized material\n",
"download_content_to_file(optimized_material, f\"{interface_material.name}_optimized_xy.json\")"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "fb3a1781c32f144f",
- "execution_count": null
+ ]
}
],
"metadata": {