From 69b32c4b1cacfb7a791a2221826ed1620512a999 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Tue, 1 Oct 2024 20:06:36 -0700
Subject: [PATCH 01/23] upsdate: add get_materials wrapper
---
utils/jupyterlite.py | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 2f1ea7f6..73314b72 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -1,9 +1,10 @@
import json
import os
from enum import Enum
-from typing import Any, Dict, Optional
+from typing import Any, Dict, List, Optional
from IPython.display import Javascript, display
+from mat3ra.made.material import Material
UPLOADS_FOLDER = "uploads"
@@ -215,3 +216,25 @@ def get_data(key: str, globals_dict: Optional[Dict] = None):
get_data_pyodide(key, globals_dict)
elif ENVIRONMENT == EnvironmentEnum.PYTHON:
get_data_python(key, globals_dict)
+
+
+def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
+ """
+ Retrieve materials from the environment and assign them to globals_dict["materials_in"].
+
+ Args:
+ globals_dict (dict): The globals dictionary to populate.
+
+ Returns:
+ List[Material]: A list of Material objects.
+ """
+ get_data("materials_in", globals_dict)
+ if globals_dict is None:
+ globals_dict = globals()
+ if "materials_in" in globals_dict and globals_dict["materials_in"]:
+ materials = [Material(item) for item in globals_dict["materials_in"]]
+ print(f"Retrieved {len(materials)} materials.")
+ return materials
+ else:
+ print("No materials found.")
+ return []
From 76eb1267b1a2dc03883f3a1784db3553a0949b99 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Tue, 1 Oct 2024 20:06:54 -0700
Subject: [PATCH 02/23] update: add set_materials wrapper
---
utils/jupyterlite.py | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 73314b72..c41e5fde 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -238,3 +238,14 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
else:
print("No materials found.")
return []
+
+
+def set_materials(materials: List[Material]):
+ """
+ Serialize and send a list of Material objects to the environment.
+
+ Args:
+ materials (List[Material]): The list of Material objects to send.
+ """
+ materials_data = [material.to_json() for material in materials]
+ set_data("materials", materials_data)
From 4cb5be5eba7a823d7ebebf6e68838f9e89d4870b Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 17:46:30 -0700
Subject: [PATCH 03/23] update: get globals from current frame
---
utils/jupyterlite.py | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index c41e5fde..542dafb1 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -1,3 +1,4 @@
+import inspect
import json
import os
from enum import Enum
@@ -228,9 +229,17 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
Returns:
List[Material]: A list of Material objects.
"""
- get_data("materials_in", globals_dict)
+
if globals_dict is None:
- globals_dict = globals()
+ frame = inspect.currentframe()
+ try:
+ caller_frame = frame.f_back
+ caller_globals = caller_frame.f_globals
+ globals_dict = caller_globals
+ finally:
+ del frame # Avoid reference cycles
+ get_data("materials_in", globals_dict)
+
if "materials_in" in globals_dict and globals_dict["materials_in"]:
materials = [Material(item) for item in globals_dict["materials_in"]]
print(f"Retrieved {len(materials)} materials.")
From 156484f92a72c989a786af48cea5ed11f1726715 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 17:47:34 -0700
Subject: [PATCH 04/23] chore: ignore mypy in try
---
utils/jupyterlite.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 542dafb1..c70f5df9 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -233,8 +233,8 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
if globals_dict is None:
frame = inspect.currentframe()
try:
- caller_frame = frame.f_back
- caller_globals = caller_frame.f_globals
+ caller_frame = frame.f_back # type: ignore
+ caller_globals = caller_frame.f_globals # type: ignore
globals_dict = caller_globals
finally:
del frame # Avoid reference cycles
From 2f704bbd6a0d4ae775ba2ed2417ce84edd822327 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 18:15:38 -0700
Subject: [PATCH 05/23] feat: add logger function
---
utils/jupyterlite.py | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index c70f5df9..04df75af 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -258,3 +258,26 @@ def set_materials(materials: List[Material]):
"""
materials_data = [material.to_json() for material in materials]
set_data("materials", materials_data)
+
+
+def log(message: str, level: Optional[str] = None):
+ """
+ Log a message based on the VERBOSE flag in the caller's globals().
+
+ Args:
+ message (str): The message to log.
+ level (str): The severity level of the message (e.g., INFO, WARNING, ERROR).
+ """
+ frame = inspect.currentframe()
+ try:
+ caller_frame = frame.f_back # type: ignore
+ caller_globals = caller_frame.f_globals # type: ignore
+ verbose = caller_globals.get("VERBOSE", False)
+ finally:
+ del frame # Avoid reference cycles
+
+ if verbose:
+ if level is None:
+ print(message)
+ else:
+ print(f"{level}: {message}")
From fb09f3ed24330b70fe7151c2b3cff63815b34363 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 18:16:51 -0700
Subject: [PATCH 06/23] update: add severity enum
---
utils/jupyterlite.py | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 04df75af..986046af 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -15,6 +15,12 @@ class EnvironmentEnum(Enum):
PYTHON = "python"
+class SeverityLevelEnum(Enum):
+ INFO = "INFO"
+ WARNING = "WARNING"
+ ERROR = "ERROR"
+
+
# Environment detection
# default value for env.HOME from https://pyodide.org/en/stable/usage/api/js-api.html
ENVIRONMENT = EnvironmentEnum.PYODIDE if os.environ.get("HOME") == "/home/pyodide" else EnvironmentEnum.PYTHON
@@ -260,13 +266,13 @@ def set_materials(materials: List[Material]):
set_data("materials", materials_data)
-def log(message: str, level: Optional[str] = None):
+def log(message: str, level: Optional[SeverityLevelEnum] = None):
"""
Log a message based on the VERBOSE flag in the caller's globals().
Args:
message (str): The message to log.
- level (str): The severity level of the message (e.g., INFO, WARNING, ERROR).
+ level (SeverityLevelEnum): The severity level of the message (e.g., INFO, WARNING, ERROR).
"""
frame = inspect.currentframe()
try:
@@ -280,4 +286,4 @@ def log(message: str, level: Optional[str] = None):
if level is None:
print(message)
else:
- print(f"{level}: {message}")
+ print(f"{level.value}: {message}")
From 6574a9447fa7f5e50bf7d8f7dba5064bb7f71cc4 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 18:30:40 -0700
Subject: [PATCH 07/23] update: use log
---
utils/jupyterlite.py | 42 ++++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 986046af..ca73eb05 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -45,7 +45,7 @@ async def install_package_pyodide(pkg: str, verbose=True):
await micropip.install(pkg, deps=are_dependencies_installed)
pkg_name = pkg.split("/")[-1].split("-")[0] if is_url else pkg.split("==")[0]
if verbose:
- print(f"Installed {pkg_name}")
+ log(f"Installed {pkg_name}", force_verbose=verbose)
def install_package_python(pkg: str, verbose=True):
@@ -57,7 +57,7 @@ def install_package_python(pkg: str, verbose=True):
"""
subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])
if verbose:
- print(f"Installed {pkg}")
+ log(f"Installed {pkg}", force_verbose=verbose)
async def install_packages(notebook_name: str, requirements_path="config.yml", verbose=True):
@@ -118,7 +118,7 @@ async def install_packages(notebook_name: str, requirements_path="config.yml", v
install_package_python(pkg, verbose)
if verbose:
- print("Packages installed successfully.")
+ log("Packages installed successfully.", force_verbose=verbose)
os.environ["requirements_hash"] = requirements_hash
@@ -143,7 +143,7 @@ def set_data_pyodide(key: str, value: Any):
}})();
"""
display(Javascript(js_code))
- print(f"Status: {key} sent to host.")
+ log(f"Data for {key} sent to host.")
set_data_python(key, value)
@@ -161,7 +161,7 @@ def set_data_python(key: str, value: Any):
file_path = os.path.join(UPLOADS_FOLDER, f"{safe_name}.json")
with open(file_path, "w") as file:
json.dump(item, file)
- print(f"Data for {key} written to {file_path}")
+ log(f"Data for {key} written to {file_path}")
def set_data(key: str, value: Any):
@@ -203,7 +203,7 @@ def get_data_python(key: str, globals_dict: Optional[Dict] = None):
with open(os.path.join(UPLOADS_FOLDER, filename), "r") as file:
data = json.load(file)
name = os.path.splitext(filename)[0]
- print(f"{index}: Data from {name} has been read successfully.")
+ log(f"{index}: Data from {name} has been read successfully.")
index += 1
data_from_host.append(data)
if globals_dict is not None:
@@ -248,10 +248,10 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
if "materials_in" in globals_dict and globals_dict["materials_in"]:
materials = [Material(item) for item in globals_dict["materials_in"]]
- print(f"Retrieved {len(materials)} materials.")
+ log(f"Retrieved {len(materials)} materials.")
return materials
else:
- print("No materials found.")
+ log("No materials found.")
return []
@@ -266,23 +266,29 @@ def set_materials(materials: List[Material]):
set_data("materials", materials_data)
-def log(message: str, level: Optional[SeverityLevelEnum] = None):
+def log(message: str, level: Optional[SeverityLevelEnum] = None, force_verbose=None):
"""
Log a message based on the VERBOSE flag in the caller's globals().
Args:
message (str): The message to log.
level (SeverityLevelEnum): The severity level of the message (e.g., INFO, WARNING, ERROR).
+ force_verbose (bool): If True, log the message regardless of the VERBOSE flag in globals()
"""
- frame = inspect.currentframe()
- try:
- caller_frame = frame.f_back # type: ignore
- caller_globals = caller_frame.f_globals # type: ignore
- verbose = caller_globals.get("VERBOSE", False)
- finally:
- del frame # Avoid reference cycles
-
- if verbose:
+ if force_verbose is True:
+ should_log = True
+ elif force_verbose is False:
+ should_log = False
+ else:
+ # Inspect the caller's globals to get VERBOSE flag
+ frame = inspect.currentframe()
+ try:
+ caller_frame = frame.f_back # type: ignore
+ caller_globals = caller_frame.f_globals # type: ignore
+ should_log = caller_globals.get("VERBOSE", False)
+ finally:
+ del frame # Avoid reference cycles
+ if should_log:
if level is None:
print(message)
else:
From 5db5512b394c44366453a26b465b3bbec313b051 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:26:59 -0700
Subject: [PATCH 08/23] update: read verbose flag from envrion
---
utils/jupyterlite.py | 58 ++++++++++++++++++++++----------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index ca73eb05..061a4be3 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -33,6 +33,35 @@ class SeverityLevelEnum(Enum):
import sys
+def log(message: str, level: Optional[SeverityLevelEnum] = None, force_verbose=None):
+ """
+ Log a message based on the VERBOSE flag in the caller's globals().
+
+ Args:
+ message (str): The message to log.
+ level (SeverityLevelEnum): The severity level of the message (e.g., INFO, WARNING, ERROR).
+ force_verbose (bool): If True, log the message regardless of the VERBOSE flag in globals()
+ """
+ if force_verbose is True:
+ should_log = True
+ elif force_verbose is False:
+ should_log = False
+ else:
+ # Inspect the caller's globals to get VERBOSE flag
+ frame = inspect.currentframe()
+ try:
+ caller_frame = frame.f_back # type: ignore
+ caller_globals = caller_frame.f_globals # type: ignore
+ should_log = caller_globals.get("VERBOSE", os.environ.get("VERBOSE", True))
+ finally:
+ del frame # Avoid reference cycles
+ if should_log:
+ if level is None:
+ print(message)
+ else:
+ print(f"{level.value}: {message}")
+
+
async def install_package_pyodide(pkg: str, verbose=True):
"""
Install a package in a Pyodide environment.
@@ -264,32 +293,3 @@ def set_materials(materials: List[Material]):
"""
materials_data = [material.to_json() for material in materials]
set_data("materials", materials_data)
-
-
-def log(message: str, level: Optional[SeverityLevelEnum] = None, force_verbose=None):
- """
- Log a message based on the VERBOSE flag in the caller's globals().
-
- Args:
- message (str): The message to log.
- level (SeverityLevelEnum): The severity level of the message (e.g., INFO, WARNING, ERROR).
- force_verbose (bool): If True, log the message regardless of the VERBOSE flag in globals()
- """
- if force_verbose is True:
- should_log = True
- elif force_verbose is False:
- should_log = False
- else:
- # Inspect the caller's globals to get VERBOSE flag
- frame = inspect.currentframe()
- try:
- caller_frame = frame.f_back # type: ignore
- caller_globals = caller_frame.f_globals # type: ignore
- should_log = caller_globals.get("VERBOSE", False)
- finally:
- del frame # Avoid reference cycles
- if should_log:
- if level is None:
- print(message)
- else:
- print(f"{level.value}: {message}")
From 573e28aa2c4b1c69da39091f1d3cd1f4e207f72d Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:27:51 -0700
Subject: [PATCH 09/23] update: move notebook settings at the top for zsl
---
...create_interface_with_min_strain_zsl.ipynb | 67 +++++++++++--------
1 file changed, 40 insertions(+), 27 deletions(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index a4afb821..8b2ef068 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -50,8 +50,27 @@
"source": [
"# Enable interactive selection of terminations via UI prompt\n",
"IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n",
+ "\n",
+ "FILM_INDEX = 1\n",
+ "FILM_MILLER_INDICES = (0, 0, 1)\n",
+ "FILM_THICKNESS = 1 # in atomic layers\n",
+ "FILM_VACUUM = 0 # in atomic layers\n",
+ "FILM_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "FILM_USE_ORTHOGONAL_Z = True\n",
+ "\n",
+ "SUBSTRATE_INDEX = 0\n",
+ "SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n",
+ "SUBSTRATE_THICKNESS = 3 # in atomic layers\n",
+ "SUBSTRATE_VACUUM = 3 # in atomic layers\n",
+ "SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
+ "\n",
"# Maximum area for the superlattice search algorithm\n",
- "MAX_AREA = 50"
+ "MAX_AREA = 50\n",
+ "# Set the termination pair indices\n",
+ "TERMINATION_PAIR_INDEX = 0\n",
+ "INTERFACE_DISTANCE = 3.0 # in Angstrom\n",
+ "INTERFACE_VACUUM = 20.0 # in Angstrom"
],
"metadata": {
"collapsed": false
@@ -97,14 +116,11 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
+ "from utils.jupyterlite import get_materials\n",
"\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))\n",
- "substrate = materials[0]\n",
- "film = materials[1]"
+ "materials = get_materials()\n",
+ "substrate = materials[SUBSTRATE_INDEX]\n",
+ "film = materials[FILM_INDEX]"
],
"metadata": {
"collapsed": false
@@ -151,20 +167,20 @@
"\n",
"film_slab_configuration = SlabConfiguration(\n",
" bulk=film,\n",
- " miller_indices=(0, 0, 1),\n",
- " thickness=1, # in atomic layers\n",
- " vacuum=0, # in atomic layers\n",
- " xy_supercell_matrix=[[1, 0], [0, 1]],\n",
- " use_orthogonal_z=True\n",
+ " miller_indices=FILM_MILLER_INDICES,\n",
+ " thickness=FILM_THICKNESS, # in atomic layers\n",
+ " vacuum=FILM_VACUUM, # in atomic layers\n",
+ " xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=FILM_USE_ORTHOGONAL_Z\n",
")\n",
"\n",
"substrate_slab_configuration = SlabConfiguration(\n",
" bulk=substrate,\n",
- " miller_indices=(1,1,1),\n",
- " thickness=3, # in atomic layers\n",
- " vacuum=3, # in atomic layers\n",
- " xy_supercell_matrix=[[1, 0], [0, 1]],\n",
- " use_orthogonal_z=True\n",
+ " miller_indices=SUBSTRATE_MILLER_INDICES,\n",
+ " thickness=SUBSTRATE_THICKNESS, # in atomic layers\n",
+ " vacuum=SUBSTRATE_VACUUM, # in atomic layers\n",
+ " xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=SUBSTRATE_USE_ORTHOGONAL_Z\n",
")"
],
"metadata": {},
@@ -255,10 +271,9 @@
"source": [
"from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n",
"\n",
- "# Set the termination pair indices\n",
- "TERMINATION_PAIR_INDEX = 0\n",
+ "termination_pair_index = TERMINATION_PAIR_INDEX\n",
"\n",
- "termination_pair = termination_pairs[TERMINATION_PAIR_INDEX]\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=\"film/substrate termination pair\")\n",
@@ -293,8 +308,8 @@
" substrate_configuration=substrate_slab_configuration,\n",
" film_termination=film_termination,\n",
" substrate_termination=substrate_termination,\n",
- " distance=3.0, # in Angstrom\n",
- " vacuum=20.0 # in Angstrom\n",
+ " distance=INTERFACE_DISTANCE,\n",
+ " vacuum= INTERFACE_VACUUM\n",
")"
],
"metadata": {
@@ -437,10 +452,8 @@
"metadata": {},
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
- "\n",
- "materials_as_json = [selected_interface.to_json() for selected_interface in selected_interfaces]\n",
- "set_data(\"materials\", materials_as_json)"
+ "from utils.jupyterlite import set_materials\n",
+ "set_materials(selected_interfaces)"
]
}
],
From 33054f5501deb6b9b6b9a5697259f2a66ebd98e5 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:29:50 -0700
Subject: [PATCH 10/23] update: handle 1 material supplied
---
.../create_interface_with_min_strain_zsl.ipynb | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index 8b2ef068..2bec280f 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -120,7 +120,11 @@
"\n",
"materials = get_materials()\n",
"substrate = materials[SUBSTRATE_INDEX]\n",
- "film = materials[FILM_INDEX]"
+ "try: \n",
+ " film = materials[FILM_INDEX]\n",
+ "except IndexError:\n",
+ " print(\"Please select a film material. Film is set to substrate.\")\n",
+ " film = substrate"
],
"metadata": {
"collapsed": false
From bbfe34aa1c0a7bd1b3b196b7ccadd325d56f1c10 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:42:50 -0700
Subject: [PATCH 11/23] update: move notebook settings at the top for simple
interface
---
...te_interface_with_no_strain_matching.ipynb | 63 ++++++++++++-------
1 file changed, 42 insertions(+), 21 deletions(-)
diff --git a/other/materials_designer/create_interface_with_no_strain_matching.ipynb b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
index 10c81394..6c501fd0 100644
--- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb
+++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
@@ -43,7 +43,26 @@
"# Enable interactive selection of terminations via UI prompt\n",
"IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n",
"# Enable scaling of the film slab atomic coordinates to match the substrate lattice (preserve coordinates in crystal units).\n",
- "ENABLE_FILM_SCALING = True"
+ "ENABLE_FILM_SCALING = True\n",
+ "\n",
+ "FILM_INDEX = 1\n",
+ "FILM_MILLER_INDICES = (0, 0, 1)\n",
+ "FILM_THICKNESS = 1 # in atomic layers\n",
+ "FILM_VACUUM = 0 # in atomic layers\n",
+ "FILM_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "FILM_USE_ORTHOGONAL_Z = True\n",
+ "\n",
+ "SUBSTRATE_INDEX = 0\n",
+ "SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n",
+ "SUBSTRATE_THICKNESS = 3 # in atomic layers\n",
+ "SUBSTRATE_VACUUM = 3 # in atomic layers\n",
+ "SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
+ "SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
+ "\n",
+ "# Set the termination pair indices\n",
+ "TERMINATION_PAIR_INDEX = 0\n",
+ "INTERFACE_DISTANCE = 3.0 # in Angstrom\n",
+ "INTERFACE_VACUUM = 20.0 # in Angstrom"
],
"metadata": {
"collapsed": false
@@ -92,14 +111,15 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
+ "from utils.jupyterlite import get_materials\n",
"\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))\n",
- "substrate = materials[0]\n",
- "film = materials[1]"
+ "materials = get_materials()\n",
+ "substrate = materials[SUBSTRATE_INDEX]\n",
+ "try: \n",
+ " film = materials[FILM_INDEX]\n",
+ "except IndexError:\n",
+ " print(\"Please select a film material. Film is set to substrate.\")\n",
+ " film = substrate"
],
"metadata": {
"collapsed": false
@@ -148,20 +168,20 @@
"\n",
"film_slab_configuration = SlabConfiguration(\n",
" bulk=film,\n",
- " miller_indices=(0, 0, 1),\n",
- " thickness=1, # in atomic layers\n",
- " vacuum=0, # in atomic layers\n",
- " xy_supercell_matrix=[[1, 0], [0, 1]],\n",
- " use_orthogonal_z=True\n",
+ " miller_indices=FILM_MILLER_INDICES,\n",
+ " thickness=FILM_THICKNESS, # in atomic layers\n",
+ " vacuum=FILM_VACUUM, # in atomic layers\n",
+ " xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=FILM_USE_ORTHOGONAL_Z\n",
")\n",
"\n",
"substrate_slab_configuration = SlabConfiguration(\n",
" bulk=substrate,\n",
- " miller_indices=(1,1,1),\n",
- " thickness=3, # in atomic layers\n",
- " vacuum=3, # in atomic layers\n",
- " xy_supercell_matrix=[[1, 0], [0, 1]],\n",
- " use_orthogonal_z=True\n",
+ " miller_indices=SUBSTRATE_MILLER_INDICES,\n",
+ " thickness=SUBSTRATE_THICKNESS, # in atomic layers\n",
+ " vacuum=SUBSTRATE_VACUUM, # in atomic layers\n",
+ " xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n",
+ " use_orthogonal_z=SUBSTRATE_USE_ORTHOGONAL_Z\n",
")"
],
"metadata": {
@@ -255,10 +275,9 @@
"source": [
"from utils.io import ui_prompt_select_array_element_by_index, ui_prompt_select_array_element_by_index_pyodide\n",
"\n",
- "# Set the termination pair indices\n",
- "TERMINATION_PAIR_INDEX = 0\n",
+ "termination_pair_index = TERMINATION_PAIR_INDEX\n",
"\n",
- "termination_pair = termination_pairs[TERMINATION_PAIR_INDEX]\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=\"film/substrate termination pair\")\n",
@@ -293,6 +312,8 @@
" substrate_configuration=substrate_slab_configuration,\n",
" film_termination=film_termination,\n",
" substrate_termination=substrate_termination,\n",
+ " interface_distance=INTERFACE_DISTANCE, # in Angstrom\n",
+ " interface_vacuum=INTERFACE_VACUUM # in Angstrom\n",
")\n",
"\n",
"interface = create_interface(interface_configuration)"
From ab35b2c27e4d268c1e0c86e3f8c8d5090c57fb11 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:47:40 -0700
Subject: [PATCH 12/23] fis issues
---
.../create_interface_with_no_strain_matching.ipynb | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/other/materials_designer/create_interface_with_no_strain_matching.ipynb b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
index 6c501fd0..3313b4a1 100644
--- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb
+++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
@@ -226,8 +226,8 @@
"film_slabs = [create_slab(film_slab_configuration, termination) for termination in film_slab_terminations]\n",
"substrate_slabs = [create_slab(substrate_slab_configuration, termination) for termination in substrate_slab_terminations]\n",
"\n",
- "visualize([{\"material\":slab, \"title\": slab.metadata[\"termination\"]} for slab in film_slabs ], repetitions=[3, 3, 1], rotation=\"-90x\")\n",
- "visualize([{\"material\":slab, \"title\": slab.metadata[\"termination\"]} for slab in substrate_slabs ], repetitions=[3, 3, 1], rotation=\"-90x\") "
+ "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in film_slabs ], repetitions=[3, 3, 1], rotation=\"-90x\")\n",
+ "visualize([{\"material\":slab, \"title\": slab.metadata[\"build\"][\"termination\"]} for slab in substrate_slabs ], repetitions=[3, 3, 1], rotation=\"-90x\") "
],
"metadata": {
"collapsed": false
@@ -376,9 +376,8 @@
"metadata": {},
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
- "\n",
- "set_data(\"materials\", [interface.to_json()])"
+ "from utils.jupyterlite import set_materials\n",
+ "set_materials(interface)"
]
}
],
From 212013c5e1ee812eea761b49445771cf298c08f5 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:47:56 -0700
Subject: [PATCH 13/23] update: make array if not
---
utils/jupyterlite.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 061a4be3..195368a5 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -6,6 +6,7 @@
from IPython.display import Javascript, display
from mat3ra.made.material import Material
+from mat3ra.utils.array import convert_to_array_if_not
UPLOADS_FOLDER = "uploads"
@@ -291,5 +292,6 @@ def set_materials(materials: List[Material]):
Args:
materials (List[Material]): The list of Material objects to send.
"""
+ materials = convert_to_array_if_not(materials)
materials_data = [material.to_json() for material in materials]
set_data("materials", materials_data)
From eba39d612a50189d01b86d4523ab001d9802bfbe Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Wed, 2 Oct 2024 19:50:25 -0700
Subject: [PATCH 14/23] update: use set_materials++ in emt
---
.../create_interface_with_relaxation_ase_emt.ipynb | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb b/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
index b5a58f12..d435c62c 100644
--- a/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
+++ b/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
@@ -93,13 +93,10 @@
"metadata": {},
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
+ "from utils.jupyterlite import get_materials\n",
"\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))\n",
- "interface = materials[2]"
+ "materials = get_materials()\n",
+ "interface = materials[0]"
]
},
{
@@ -165,6 +162,7 @@
"source": [
"from utils.plot import create_realtime_plot, plot_update_callback\n",
"from mat3ra.made.tools.convert import from_ase\n",
+ "from mat3ra.made.material import Material\n",
"\n",
"# Add calculator to the interface for relaxation\n",
"ase_interface = to_ase(interface)\n",
@@ -243,9 +241,9 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
+ "from utils.jupyterlite import set_materials\n",
"final_interface.name = f\"{interface.name}, Relaxed with EMT\" if \"Relaxed\" not in interface.name else interface.name\n",
- "set_data(\"materials\", [final_interface.to_json()])"
+ "set_materials(final_interface)"
],
"metadata": {
"collapsed": false
From 00a41d697ee3c60395137e7a3961cce842c88f80 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Thu, 3 Oct 2024 12:50:46 -0700
Subject: [PATCH 15/23] update: use set_materials++ in other nbs
---
.../create_adatom_defect.ipynb | 16 +-
.../create_island_defect.ipynb | 1079 +++++++++++++++++
.../create_point_defect.ipynb | 14 +-
3 files changed, 1090 insertions(+), 19 deletions(-)
create mode 100644 other/materials_designer/create_island_defect.ipynb
diff --git a/other/materials_designer/create_adatom_defect.ipynb b/other/materials_designer/create_adatom_defect.ipynb
index 663cf617..98fbe122 100644
--- a/other/materials_designer/create_adatom_defect.ipynb
+++ b/other/materials_designer/create_adatom_defect.ipynb
@@ -95,8 +95,8 @@
{
"cell_type": "markdown",
"source": [
- "### 1.3. Get input material and \n",
- "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
+ "### 1.3. Get input material\n",
+ "Materials are loaded with `get_materials()`."
],
"metadata": {
"collapsed": false
@@ -107,12 +107,8 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
- "\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))"
+ "from utils.jupyterlite import get_materials\n",
+ "materials = get_materials(globals())"
],
"metadata": {
"collapsed": false
@@ -258,9 +254,9 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
+ "from utils.jupyterlite import set_materials\n",
"\n",
- "set_data(\"materials\", [slab_with_adatom_at_equidistant_position.to_json(), slab_with_adatom_at_crystal_site.to_json()])"
+ "set_materials([slab_with_adatom_at_equidistant_position, slab_with_adatom_at_crystal_site])"
],
"metadata": {
"collapsed": false
diff --git a/other/materials_designer/create_island_defect.ipynb b/other/materials_designer/create_island_defect.ipynb
new file mode 100644
index 00000000..27651b17
--- /dev/null
+++ b/other/materials_designer/create_island_defect.ipynb
@@ -0,0 +1,1079 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Create adatom defects in a slab material\n",
+ "\n",
+ "Create an adatom by specifying the chemical element, approximate position on surface and distance z, which will be resolved to:\n",
+ "- the equidistant position between the closes atoms on the surface according to Voronoi tesselation, \n",
+ "- or the crystal site of the next layer that is closest to specified position.\n",
+ "\n",
+ "
Usage
\n",
+ "\n",
+ "1. Make sure to select Input Materials (in the outer runtime) before running the notebook.\n",
+ "1. Set notebook parameters in cell 1.1. below (or use the default values).\n",
+ "1. Set defects parameters in cell 2.1. (or use default).\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",
+ "## Summary\n",
+ "1. Prepare the Environment: Set up the notebook and install packages, preview the input materials\n",
+ "1. Create the Defect: Add an adatom defect to the slab material\n",
+ "2. Visualize the Defect: Visualize the defect structure\n",
+ "\n",
+ "## Notes\n",
+ "\n",
+ "1. For more information, see [Introduction](Introduction.ipynb)\n",
+ "\n"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "f2e1e795020d7b3f"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 1. Prepare the Environment\n",
+ "### 1.1. Set up defect parameters "
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "5e43ff288847b784"
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from mat3ra.made.tools.analyze import get_atomic_coordinates_extremum\n",
+ "\n",
+ "DEFECT_TYPE = \"island\"\n",
+ "APPROXIMATE_POSITION_ON_SURFACE = [0.5, 0.5] # Position of the defect in crystal coordinates\n",
+ "DISTANCE_Z = 5.0 # Distance of the defect from the surface in Angstrom\n",
+ "CHEMICAL_ELEMENT = \"Ni\" # Element to be placed at the site \n",
+ "MILLER_INDICES = (1, 1, 1) # Miller indices of the surface\n",
+ "SLAB_THICKNESS = 5 # Thickness of the slab in unit cells\n",
+ "VACUUM = 6 # Vacuum thickness in Angstrom\n",
+ "SUPERCELL_MATRIX = [[5, 0, 0], [0, 5, 0], [0, 0, 1]]"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:34:47.390686Z",
+ "start_time": "2024-09-10T22:34:47.386116Z"
+ }
+ },
+ "id": "9d8b1890b34d850a",
+ "outputs": [],
+ "execution_count": 2
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 1.2. 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": "bb64de5ff32649f8"
+ },
+ {
+ "cell_type": "code",
+ "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(\"create_point_defect.ipynb\", \"../../config.yml\")"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:34:47.426652Z",
+ "start_time": "2024-09-10T22:34:47.422980Z"
+ }
+ },
+ "id": "ef664b14457530fd",
+ "outputs": [],
+ "execution_count": 3
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 1.3. Get input materials\n",
+ "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "919ad7af8dceeedd"
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from mat3ra.made.material import Material\n",
+ "from utils.jupyterlite import get_data\n",
+ "\n",
+ "# Get the list of input materials and load them into `materials_in` variable\n",
+ "get_data(\"materials_in\", globals())\n",
+ "materials = list(map(Material, globals()[\"materials_in\"]))"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:34:48.899678Z",
+ "start_time": "2024-09-10T22:34:47.443032Z"
+ }
+ },
+ "id": "be38fdda1984c654",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0: Data from 0-Ni has been read successfully.\n",
+ "1: Data from 1-Graphene has been read successfully.\n",
+ "2: Data from 10-Al2O3, Sapphire, RHL (R-3c) 3D (Bulk), mp-1143 (1) has been read successfully.\n",
+ "3: Data from 11-ZnO, Zinc Oxide, HEX (P6_3mc) 3D (Bulk), mp-2133 has been read successfully.\n",
+ "4: Data from 12-Cd4 Te4 has been read successfully.\n",
+ "5: Data from 13-Si4 C4 has been read successfully.\n",
+ "6: Data from 14-GaN, Gallium Nitride, HEX (P6_3mc) 3D (Bulk), mp-804 has been read successfully.\n",
+ "7: Data from 4-Te2Mo has been read successfully.\n",
+ "8: Data from 5-HfO2 has been read successfully.\n",
+ "9: Data from 6-Ni4(110), termination Ni_Pmmm_2, Slab, Terrace, 1 steps, [2 0 0] has been read successfully.\n",
+ "10: Data from 7-Ag4 has been read successfully.\n",
+ "11: Data from 8-Si, Silicene, HEX (P-3m1) 2D (Monolayer), 2dm-5934 has been read successfully.\n",
+ "12: Data from 9-GaAs, Gallium Arsenide, FCC (F-43m) 3D (Bulk), mp-2534 has been read successfully.\n",
+ "13: Data from C2(001)-C2(001), Interface, Strain 0.000pct has been read successfully.\n",
+ "14: Data from C2(001)-C2(001), Interface, Strain 0.397pct has been read successfully.\n",
+ "15: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced displaced has been read successfully.\n",
+ "16: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced optimal displaced has been read successfully.\n",
+ "17: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced has been read successfully.\n",
+ "18: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced optimal displaced has been read successfully.\n",
+ "19: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced has been read successfully.\n",
+ "20: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct optimal displaced has been read successfully.\n",
+ "21: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct optimized with ASE has been read successfully.\n",
+ "22: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct has been read successfully.\n",
+ "23: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct_displaced has been read successfully.\n",
+ "24: Data from Ga2N2(001)-C4Si4(111), Interface, Strain 0.082pct has been read successfully.\n",
+ "25: Data from Interface 45 degrees has been read successfully.\n",
+ "26: Data from Merged Material HEX final moire_5 deg has been read successfully.\n",
+ "27: Data from Merged Material59deg final moire_59deg has been read successfully.\n",
+ "28: Data from Ni12(001), termination Ni_Cmmm_6, Slab has been read successfully.\n",
+ "29: Data from Ni12(100), termination Ni_Pmma_6, Slab has been read successfully.\n",
+ "30: Data from Ni12(100), termination Ni_Pmmm_6, Slab has been read successfully.\n",
+ "31: Data from Ni144(100), termination Ni_Pm_9, Slab has been read successfully.\n",
+ "32: Data from Ni174(001), termination Ni_Pm_6, Slab has been read successfully.\n",
+ "33: Data from Ni270(111), termination Ni_P1_116, Slab has been read successfully.\n",
+ "34: Data from Ni4(001)-Ni4(110), Interface, Strain 0.222pct has been read successfully.\n",
+ "35: Data from Ni4(001)-Ni4(111), Interface, Strain 0.062pct has been read successfully.\n",
+ "36: Data from Ni4(001)-Ni4(111), Interface, Strain 0.227pct has been read successfully.\n",
+ "37: Data from Ni4(110)-Ni4(-1-10), Interface, Strain 0.000pct has been read successfully.\n",
+ "38: Data from Ni4(110)-Ni4(100), Interface, Strain 0.019pct has been read successfully.\n",
+ "39: Data from Ni4(110)-Ni4(110), Interface, Strain 0.000pct has been read successfully.\n",
+ "40: Data from Ni432(001), termination Ni_Pmmm_21, Slab has been read successfully.\n",
+ "41: Data from Ni90(001), termination Ni_P4:mmm_7, Slab has been read successfully.\n",
+ "42: Data from Ni90(111), termination Ni_P1_180, Slab has been read successfully.\n",
+ "43: Data from Si2(001)-Ag4(111), Interface, Strain 0.035pct has been read successfully.\n",
+ "44: Data from Si8(001), termination Si_P4:mmm_1, Slab has been read successfully.\n",
+ "45: Data from Si8(111), termination Si_P6:mmm_4, Slab has been read successfully.\n",
+ "46: Data from TEST 1.1 final moire_1.1deg has been read successfully.\n",
+ "47: Data from TEST 1.1 has been read successfully.\n",
+ "48: Data from TEST 5deg final moire_5deg has been read successfully.\n",
+ "49: Data from TEST 5deg has been read successfully.\n",
+ "50: Data from Twisted Interface 30.0 degrees - 24000 atoms has been read successfully.\n",
+ "51: Data from Twisted Interface 30.0 degrees has been read successfully.\n",
+ "52: Data from moire_1.1deg has been read successfully.\n",
+ "53: Data from moire_30deg has been read successfully.\n",
+ "54: Data from moire_5deg has been read successfully.\n",
+ "55: Data from rotated_basis -59 degrees has been read successfully.\n",
+ "56: Data from rotated_basis 1.1 degrees has been read successfully.\n",
+ "57: Data from rotated_basis 245 degrees has been read successfully.\n",
+ "58: Data from rotated_basis 5 degrees has been read successfully.\n"
+ ]
+ }
+ ],
+ "execution_count": 4
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 1.4. Create and preview Slab"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "a132fe0ef8bbf0d0"
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n",
+ "from utils.visualize import visualize_materials as visualize\n",
+ "from mat3ra.made.tools.build.defect.builders import CrystalSiteAdatomSlabDefectBuilder\n",
+ "\n",
+ "material = materials[8]\n",
+ "slab_config = SlabConfiguration(\n",
+ " bulk=material,\n",
+ " miller_indices=MILLER_INDICES,\n",
+ " thickness=SLAB_THICKNESS,\n",
+ " vacuum=VACUUM,\n",
+ " use_orthogonal_z=True,\n",
+ " xy_supercell_matrix=SUPERCELL_MATRIX\n",
+ ")\n",
+ "termination = get_terminations(slab_config)[1]\n",
+ "slab = create_slab(slab_config, termination)\n",
+ "print(slab.metadata.get(\"build\").get(\"configuration\").get(\"type\"))\n",
+ "new_slab = CrystalSiteAdatomSlabDefectBuilder().create_material_with_additional_layers(slab, 2)\n",
+ "visualize([{\"material\": slab, \"rotation\": \"0x\"}, {\"material\": slab, \"rotation\": \"-90x\"}], repetitions=[1, 1, 1])\n",
+ "visualize([{\"material\": new_slab, \"rotation\": \"0x\"}, {\"material\": new_slab, \"rotation\": \"-90x\"}], repetitions=[1, 1, 1])\n",
+ "print(slab.metadata.get(\"build\").get(\"configuration\").get(\"type\"))\n",
+ "\n"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:34:53.028769Z",
+ "start_time": "2024-09-10T22:34:48.914114Z"
+ }
+ },
+ "id": "e2d24109d3068c9e",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "SlabConfiguration\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Material - rotation: 0x', layout=Layout(align_self=…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "adf7327f1d2b421e95d606b0d654e630"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Hf700O1400 - Material - rotation: 0x', layout=Layout(align_self=…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "6895fadc9a094fe79cce34e442e8e551"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "SlabConfiguration\n"
+ ]
+ }
+ ],
+ "execution_count": 5
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 2. Create the Defect\n",
+ "### 2.1. Set adatom parameters"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "5da5b0380583c952"
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from mat3ra.made.tools.build.defect.builders import IslandSlabDefectBuilder\n",
+ "from mat3ra.made.tools.build.defect.configuration import IslandSlabDefectConfiguration\n",
+ "from mat3ra.made.tools.utils import coordinate as CoordinateCondition\n",
+ "from mat3ra.made.tools.modify import filter_by_box\n",
+ "condition = CoordinateCondition.CylinderCoordinateCondition(center_position=[0.25, 0.5], radius=0.25, min_z=0, max_z=1)\n",
+ "island_config = IslandSlabDefectConfiguration(\n",
+ " crystal=slab,\n",
+ " defect_type=\"island\",\n",
+ " condition=condition,\n",
+ " number_of_added_layers=3,\n",
+ ")\n",
+ "\n",
+ "slab_with_island = IslandSlabDefectBuilder().get_material(configuration=island_config)\n",
+ "visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
+ " {\"material\": slab_with_island, \"title\": \"Material with island defect\"}])\n",
+ "visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
+ " {\"material\": slab_with_island, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n",
+ "slab_with_island.metadata.get(\"build\").get(\"configuration\")\n",
+ "\n",
+ "\n",
+ "slab_with_island = filter_by_box(slab_with_island, [0.5, 0.5, 0.25], [0.75, 0.75, 1], invert_selection=True)\n",
+ "slab_with_island.name = slab_with_island.name + \" Island\"\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}], rotation=\"-40x\")"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:29.723604Z",
+ "start_time": "2024-09-10T22:35:18.526794Z"
+ }
+ },
+ "id": "a14402cb0adc7dd1",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Original material - rotation: 0x,0y,0z', layout=Lay…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "16c3f8c94c274253b6fb68d706e40759"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Original material - rotation: -90x', layout=Layout(…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "5a82b120520b452bb94e198f7fac7290"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Hf546O1090 - Material with island defect - rotation: -40x', layo…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "e66914e0c0064eb48dd7e03ffb80f95a"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "execution_count": 8
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "### 2.2. Create the adatom"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "489b51f0ee122c48"
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "\n",
+ "from mat3ra.made.tools.modify import filter_material_by_ids,filter_by_box\n",
+ "import numpy as np\n",
+ "from typing import Literal, List\n",
+ "\n",
+ "\n",
+ "def get_surface_atoms_indices(\n",
+ " material: Material,\n",
+ " surface: Literal[\"top\", \"bottom\", \"both\"] = \"top\",\n",
+ " n: int = 15,\n",
+ " m: int = 15\n",
+ ") -> List[int]:\n",
+ " \"\"\"\n",
+ " Get the indices of atoms on the surface of the material along the Z axis.\n",
+ "\n",
+ " Args:\n",
+ " material (Material): Material object.\n",
+ " surface (str): \"top\", \"bottom\", or \"both\".\n",
+ " n (int): Number of divisions along the X axis.\n",
+ " m (int): Number of divisions along the Y axis.\n",
+ "\n",
+ " Returns:\n",
+ " List[int]: List of indices of atoms on the surface.\n",
+ " \"\"\"\n",
+ " surface_atoms_indices = []\n",
+ "\n",
+ " # Get columns of atoms with grid n by m:\n",
+ " for i in range(n):\n",
+ " for j in range(m):\n",
+ " # Define the bounding box for the current grid cell\n",
+ " x_min, x_max = i / n, (i + 1) / n\n",
+ " y_min, y_max = j / m, (j + 1) / m\n",
+ "\n",
+ " # Filter atoms within this grid cell\n",
+ " atoms_column = filter_by_box(material, [x_min, y_min, 0], [x_max, y_max, 1])\n",
+ " \n",
+ "\n",
+ " if len(atoms_column.basis.coordinates.values) == 0:\n",
+ " continue # Skip empty columns\n",
+ "\n",
+ "\n",
+ " # Extract the z-coordinates\n",
+ " z_values = [coord[2] for coord in atoms_column.basis.coordinates.values]\n",
+ "\n",
+ " # Find the top and bottom atoms by Z-coordinate\n",
+ " top_atom_idx = np.argmax(z_values)\n",
+ " bottom_atom_idx = np.argmin(z_values)\n",
+ "\n",
+ " # Map these to the corresponding IDs\n",
+ " top_atom_id = atoms_column.basis.coordinates.ids[top_atom_idx]\n",
+ " bottom_atom_id = atoms_column.basis.coordinates.ids[bottom_atom_idx]\n",
+ "\n",
+ " # Add the appropriate IDs to the surface_atoms_indices list\n",
+ " if surface == \"top\" or surface == \"both\":\n",
+ " surface_atoms_indices.append(top_atom_id)\n",
+ " if surface == \"bottom\" or surface == \"both\":\n",
+ " surface_atoms_indices.append(bottom_atom_id)\n",
+ "\n",
+ " # Remove duplicates by converting the list to a set and back to a list\n",
+ " surface_atoms_indices = list(set(surface_atoms_indices))\n",
+ "\n",
+ " return surface_atoms_indices\n",
+ "\n",
+ "ids = get_surface_atoms_indices(slab_with_island, surface=\"top\")\n",
+ "top_atoms = filter_material_by_ids(slab_with_island, ids)\n",
+ "\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": top_atoms, \"title\": \"Surface Atoms only\"}], rotation=\"-90x\")\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": top_atoms, \"title\": \"Surface Atoms only\"}], rotation=\"0x\")"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "start_time": "2024-09-10T22:35:03.278751Z"
+ }
+ },
+ "id": "a990fa35742d7269",
+ "outputs": [
+ {
+ "ename": "KeyboardInterrupt",
+ "evalue": "",
+ "output_type": "error",
+ "traceback": [
+ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
+ "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)",
+ "Cell \u001B[0;32mIn[7], line 63\u001B[0m\n\u001B[1;32m 59\u001B[0m surface_atoms_indices \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mlist\u001B[39m(\u001B[38;5;28mset\u001B[39m(surface_atoms_indices))\n\u001B[1;32m 61\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m surface_atoms_indices\n\u001B[0;32m---> 63\u001B[0m ids \u001B[38;5;241m=\u001B[39m \u001B[43mget_surface_atoms_indices\u001B[49m\u001B[43m(\u001B[49m\u001B[43mslab_with_island\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43msurface\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mtop\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[1;32m 64\u001B[0m top_atoms \u001B[38;5;241m=\u001B[39m filter_material_by_ids(slab_with_island, ids)\n\u001B[1;32m 66\u001B[0m visualize([{\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mmaterial\u001B[39m\u001B[38;5;124m\"\u001B[39m: slab_with_island, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtitle\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mMaterial with island defect\u001B[39m\u001B[38;5;124m\"\u001B[39m}, {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mmaterial\u001B[39m\u001B[38;5;124m\"\u001B[39m: top_atoms, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtitle\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mSurface Atoms only\u001B[39m\u001B[38;5;124m\"\u001B[39m}], rotation\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m-90x\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
+ "Cell \u001B[0;32mIn[7], line 34\u001B[0m, in \u001B[0;36mget_surface_atoms_indices\u001B[0;34m(material, surface, n, m)\u001B[0m\n\u001B[1;32m 31\u001B[0m y_min, y_max \u001B[38;5;241m=\u001B[39m j \u001B[38;5;241m/\u001B[39m m, (j \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m) \u001B[38;5;241m/\u001B[39m m\n\u001B[1;32m 33\u001B[0m \u001B[38;5;66;03m# Filter atoms within this grid cell\u001B[39;00m\n\u001B[0;32m---> 34\u001B[0m atoms_column \u001B[38;5;241m=\u001B[39m \u001B[43mfilter_by_box\u001B[49m\u001B[43m(\u001B[49m\u001B[43mmaterial\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[43mx_min\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43my_min\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[43mx_max\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43my_max\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 37\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(atoms_column\u001B[38;5;241m.\u001B[39mbasis\u001B[38;5;241m.\u001B[39mcoordinates\u001B[38;5;241m.\u001B[39mvalues) \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m:\n\u001B[1;32m 38\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m \u001B[38;5;66;03m# Skip empty columns\u001B[39;00m\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:347\u001B[0m, in \u001B[0;36mfilter_by_box\u001B[0;34m(material, min_coordinate, max_coordinate, use_cartesian_coordinates, invert_selection)\u001B[0m\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mcondition\u001B[39m(coordinate):\n\u001B[1;32m 345\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m is_coordinate_in_box(coordinate, min_coordinate, max_coordinate)\n\u001B[0;32m--> 347\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfilter_by_condition_on_coordinates\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mmaterial\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcondition\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43muse_cartesian_coordinates\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43muse_cartesian_coordinates\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minvert_selection\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43minvert_selection\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:175\u001B[0m, in \u001B[0;36mfilter_by_condition_on_coordinates\u001B[0;34m(material, condition, use_cartesian_coordinates, invert_selection)\u001B[0m\n\u001B[1;32m 168\u001B[0m new_material \u001B[38;5;241m=\u001B[39m material\u001B[38;5;241m.\u001B[39mclone()\n\u001B[1;32m 169\u001B[0m ids \u001B[38;5;241m=\u001B[39m get_atom_indices_with_condition_on_coordinates(\n\u001B[1;32m 170\u001B[0m material,\n\u001B[1;32m 171\u001B[0m condition,\n\u001B[1;32m 172\u001B[0m use_cartesian_coordinates\u001B[38;5;241m=\u001B[39muse_cartesian_coordinates,\n\u001B[1;32m 173\u001B[0m )\n\u001B[0;32m--> 175\u001B[0m new_material \u001B[38;5;241m=\u001B[39m \u001B[43mfilter_material_by_ids\u001B[49m\u001B[43m(\u001B[49m\u001B[43mnew_material\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mids\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minvert\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43minvert_selection\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 176\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m new_material\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:141\u001B[0m, in \u001B[0;36mfilter_material_by_ids\u001B[0;34m(material, ids, invert)\u001B[0m\n\u001B[1;32m 129\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfilter_material_by_ids\u001B[39m(material: Material, ids: List[\u001B[38;5;28mint\u001B[39m], invert: \u001B[38;5;28mbool\u001B[39m \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Material:\n\u001B[1;32m 130\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 131\u001B[0m \u001B[38;5;124;03m Filter out only atoms corresponding to the ids.\u001B[39;00m\n\u001B[1;32m 132\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[38;5;124;03m Material: The filtered material object.\u001B[39;00m\n\u001B[1;32m 140\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m--> 141\u001B[0m new_material \u001B[38;5;241m=\u001B[39m \u001B[43mmaterial\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mclone\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 142\u001B[0m new_basis \u001B[38;5;241m=\u001B[39m new_material\u001B[38;5;241m.\u001B[39mbasis\n\u001B[1;32m 143\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m invert \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/code/entity.py:55\u001B[0m, in \u001B[0;36mInMemoryEntity.clone\u001B[0;34m(self, extra_context)\u001B[0m\n\u001B[1;32m 51\u001B[0m config\u001B[38;5;241m.\u001B[39mupdate(extra_context)\n\u001B[1;32m 52\u001B[0m \u001B[38;5;66;03m# To avoid:\u001B[39;00m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;66;03m# Argument 1 to \"__init__\" of \"BaseUnderscoreJsonPropsHandler\" has incompatible type \"Dict[str, Any]\";\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;66;03m# expected \"BaseUnderscoreJsonPropsHandler\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[38;5;18;43m__class__\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/material.py:58\u001B[0m, in \u001B[0;36mMaterial.__init__\u001B[0;34m(self, config)\u001B[0m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\u001B[38;5;28mself\u001B[39m, config: Any) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m---> 58\u001B[0m \u001B[38;5;28;43msuper\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[38;5;21;43m__init__\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 59\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname \u001B[38;5;241m=\u001B[39m \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39mname \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mformula\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/code/__init__.py:8\u001B[0m, in \u001B[0;36mBaseUnderscoreJsonPropsHandler.__init__\u001B[0;34m(self, config)\u001B[0m\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\u001B[38;5;28mself\u001B[39m, config: Dict[\u001B[38;5;28mstr\u001B[39m, Any] \u001B[38;5;241m=\u001B[39m {}) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m----> 8\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_json \u001B[38;5;241m=\u001B[39m \u001B[43mobject_utils\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mclone_deep\u001B[49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n",
+ "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/utils/object.py:22\u001B[0m, in \u001B[0;36mclone_deep\u001B[0;34m(obj)\u001B[0m\n\u001B[1;32m 21\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mclone_deep\u001B[39m(obj: Any) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Any:\n\u001B[0;32m---> 22\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mcopy\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
+ " \u001B[0;31m[... skipping similar frames: deepcopy at line 146 (4 times), _deepcopy_dict at line 231 (3 times)]\u001B[0m\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:206\u001B[0m, in \u001B[0;36m_deepcopy_list\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 204\u001B[0m append \u001B[38;5;241m=\u001B[39m y\u001B[38;5;241m.\u001B[39mappend\n\u001B[1;32m 205\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m a \u001B[38;5;129;01min\u001B[39;00m x:\n\u001B[0;32m--> 206\u001B[0m append(\u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43ma\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[1;32m 207\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
+ "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:128\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 124\u001B[0m d[PyStringMap] \u001B[38;5;241m=\u001B[39m PyStringMap\u001B[38;5;241m.\u001B[39mcopy\n\u001B[1;32m 126\u001B[0m \u001B[38;5;28;01mdel\u001B[39;00m d, t\n\u001B[0;32m--> 128\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mdeepcopy\u001B[39m(x, memo\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, _nil\u001B[38;5;241m=\u001B[39m[]):\n\u001B[1;32m 129\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"Deep copy operation on arbitrary Python objects.\u001B[39;00m\n\u001B[1;32m 130\u001B[0m \n\u001B[1;32m 131\u001B[0m \u001B[38;5;124;03m See the module's __doc__ string for more info.\u001B[39;00m\n\u001B[1;32m 132\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[1;32m 134\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m memo \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
+ "\u001B[0;31mKeyboardInterrupt\u001B[0m: "
+ ]
+ }
+ ],
+ "execution_count": 7
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 3. Visualize the Slabs with Adatom"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "462549d016073446"
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "## 4. Pass data to the outside runtime"
+ ],
+ "metadata": {
+ "collapsed": false
+ },
+ "id": "d381df29a6bbdd82"
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "e70a90e827bb4fae9dbecb8e206e218f"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: 0x', layout…",
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "4cef85ea912742e295e421260ea785af"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "\n",
+ "from mat3ra.made.tools.build.defect import create_slab_defect, TerraceSlabDefectBuilder\n",
+ "from mat3ra.made.tools.build.defect.configuration import TerraceSlabDefectConfiguration\n",
+ "from scipy.spatial import cKDTree\n",
+ "\n",
+ "def get_surface_atoms_indices(material: Material, distance_threshold: float = 2.5, depth: float = 5) -> List[int]:\n",
+ " \"\"\"\n",
+ " Identify exposed atoms on the top surface of the material.\n",
+ "\n",
+ " Args:\n",
+ " material (Material): Material object to get surface atoms from.\n",
+ " distance_threshold (float): Distance threshold to determine if an atom is considered \"covered\".\n",
+ " depth (float): Depth from the top surface to look for exposed atoms.\n",
+ "\n",
+ " Returns:\n",
+ " List[int]: List of indices of exposed top surface atoms.\n",
+ " \"\"\"\n",
+ " material.to_cartesian()\n",
+ " coordinates = np.array(material.basis.coordinates.values)\n",
+ " ids = material.basis.coordinates.ids\n",
+ " kd_tree = cKDTree(coordinates)\n",
+ " z_max = np.max(coordinates[:, 2])\n",
+ "\n",
+ " exposed_atoms_indices = []\n",
+ " for idx, (x, y, z) in enumerate(coordinates):\n",
+ " if z >= z_max - depth:\n",
+ " neighbors_above = kd_tree.query_ball_point([x, y, z + distance_threshold], r=distance_threshold)\n",
+ "\n",
+ " if not any(coordinates[n][2] > z for n in neighbors_above):\n",
+ " exposed_atoms_indices.append(ids[idx])\n",
+ " material.to_crystal()\n",
+ " return exposed_atoms_indices\n",
+ "\n",
+ "\n",
+ "configuration = TerraceSlabDefectConfiguration(\n",
+ " crystal=slab,\n",
+ ")\n",
+ "builder = TerraceSlabDefectBuilder()\n",
+ "terrace = create_slab_defect(configuration, builder)\n",
+ "\n",
+ "exposed_top_surface_atoms = get_surface_atoms_indices(slab_with_island, distance_threshold=2.5, depth=15)\n",
+ "exposed_atoms = filter_material_by_ids(slab_with_island, exposed_top_surface_atoms)\n",
+ "exposed_atoms.name = exposed_atoms.name + \" Surface Atoms\"\n",
+ "\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": exposed_atoms, \"title\": \"Exposed Atoms only\"}], rotation=\"-90x\")\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": exposed_atoms, \"title\": \"Exposed Atoms only\"}], rotation=\"0x\")"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.345111Z",
+ "start_time": "2024-08-24T01:06:40.137044Z"
+ }
+ },
+ "id": "61daa5afcbc078a9",
+ "execution_count": 7
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Island.json\n",
+ "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Surface Atoms Surface Atoms.json\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": "1565"
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from utils.jupyterlite import set_data\n",
+ "slab_with_island.name = slab_with_island.name + \" Island\"\n",
+ "exposed_atoms.name = exposed_atoms.name + \" Surface Atoms\"\n",
+ "set_data(\"materials_out\", [slab_with_island.to_json(), exposed_atoms.to_json()])\n",
+ "len(slab_with_island.basis.elements.ids)"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.345811Z",
+ "start_time": "2024-08-24T01:06:56.359197Z"
+ }
+ },
+ "id": "8f1f5b3ee69d0355",
+ "execution_count": 8
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "dbac8d90d33341668910696a72c31de8"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: 0x', layout…",
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "f8c99e61943541b993e1fdae2750ce32"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Island Passivated.json\n"
+ ]
+ }
+ ],
+ "source": [
+ "def passivate_top(material, element, bond_length, depth):\n",
+ " \"\"\"\n",
+ " Passivate the top surface of the material with the specified element.\n",
+ "\n",
+ " Args:\n",
+ " material (Material): Material object to passivate.\n",
+ " element (str): Element to use for passivation.\n",
+ " bond_length (float): Bond length to use for the passivation.\n",
+ " depth (float): Depth from the top surface to passivate.\n",
+ "\n",
+ " Returns:\n",
+ " Material: Material object with the top surface passivated.\n",
+ " \"\"\"\n",
+ " new_material = material.clone()\n",
+ " top_atom_indices = get_surface_atoms_indices(material, distance_threshold=2.2, depth=depth)\n",
+ " top_atoms = filter_material_by_ids(material, top_atom_indices)\n",
+ " new_material.to_cartesian()\n",
+ " top_atoms.to_cartesian()\n",
+ " top_atoms_coordinates = top_atoms.basis.coordinates.values\n",
+ " passivant_coordinates = np.array(top_atoms_coordinates) + [0, 0, bond_length]\n",
+ " \n",
+ " for coord in passivant_coordinates:\n",
+ " new_material.add_atom(element, coord)\n",
+ " new_material.to_crystal()\n",
+ " return new_material\n",
+ "\n",
+ "passivated_slab = passivate_top(slab_with_island, \"H\", 1.0, 15)\n",
+ "passivated_slab.name = passivated_slab.name + \" Passivated\"\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_slab, \"title\": \"Passivated Material\"}], rotation=\"-90x\")\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_slab, \"title\": \"Passivated Material\"}], rotation=\"0x\")\n",
+ "\n",
+ "set_data(\"materials_out\", [ passivated_slab.to_json()])"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.346107Z",
+ "start_time": "2024-08-24T01:52:08.525957Z"
+ }
+ },
+ "id": "b529792d4b077042",
+ "execution_count": 14
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "1708"
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(passivated_slab.basis.elements.values)"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.346715Z",
+ "start_time": "2024-08-24T01:07:06.686806Z"
+ }
+ },
+ "id": "4200a5b3ffb1a6ff",
+ "execution_count": 10
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "ca2650387e6b468ca2ca14d8505a6ba4"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from mat3ra.made.tools.modify import passivate_material, passivate_surface\n",
+ "\n",
+ "passivated_surface = passivate_surface(slab_with_island, passivant=\"H\", default_bond_length=1.0)\n",
+ "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_surface, \"title\": \"Passivated Material\"}], rotation=\"-90x\")"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.347606Z",
+ "start_time": "2024-08-24T01:07:06.695459Z"
+ }
+ },
+ "id": "e27584952f2dd760",
+ "execution_count": 11
+ },
+ {
+ "cell_type": "code",
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Commensurate lattice vectors: m1=0, m2=0, n1=0, n2=0\n"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "from scipy.optimize import minimize\n",
+ "\n",
+ "def find_commensurate_lattice(T, a1, a2, tol=1e-6):\n",
+ " \"\"\"\n",
+ " Finds commensurate lattice vectors for two 2D arbitrary bases.\n",
+ " \n",
+ " Parameters:\n",
+ " - T: 2x2 numpy array, the transformation matrix relating the two bases.\n",
+ " - a1, a2: numpy arrays, the vectors of the first basis.\n",
+ " - tol: float, tolerance for finding integer solutions.\n",
+ " \n",
+ " Returns:\n",
+ " - (m1, m2, n1, n2): tuple of integers that satisfy the commensurability condition.\n",
+ " \"\"\"\n",
+ " \n",
+ " def objective(vars):\n",
+ " m1, m2, n1, n2 = vars\n",
+ " return m1**2 + m2**2 + n1**2 + n2**2\n",
+ "\n",
+ " def constraint(vars):\n",
+ " m1, m2, n1, n2 = vars\n",
+ " lhs = m1 * a1 + m2 * a2\n",
+ " rhs = n1 * (T @ a1) + n2 * (T @ a2)\n",
+ " return np.linalg.norm(lhs - rhs)\n",
+ " \n",
+ " # Initial guess for m1, m2, n1, n2\n",
+ " initial_guess = [1, 0, 1, 0]\n",
+ " \n",
+ " # Constraints dictionary\n",
+ " constraints = {'type': 'eq', 'fun': constraint}\n",
+ " \n",
+ " # Solve the optimization problem\n",
+ " result = minimize(objective, initial_guess, constraints=constraints, method='SLSQP', options={'ftol': tol})\n",
+ " \n",
+ " if result.success:\n",
+ " m1, m2, n1, n2 = np.round(result.x).astype(int)\n",
+ " return m1, m2, n1, n2\n",
+ " else:\n",
+ " raise ValueError(\"No commensurate lattice found within the given tolerance.\")\n",
+ "\n",
+ "# Example usage:\n",
+ "a1 = np.array([1, 0])\n",
+ "a2 = np.array([-0.5, np.sqrt(3) / 2])\n",
+ "angle = np.pi / 3\n",
+ "T = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]])\n",
+ "m1, m2, n1, n2 = find_commensurate_lattice(T, a1, a2, tol=1e-1)\n",
+ "print(f\"Commensurate lattice vectors: m1={m1}, m2={m2}, n1={n1}, n2={n2}\")\n"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.347841Z",
+ "start_time": "2024-08-24T03:09:08.323562Z"
+ }
+ },
+ "id": "2aa667c6ee85aec9",
+ "execution_count": 21
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "from mat3ra.made.tools.build.defect import create_slab_defect, IslandSlabDefectBuilder\n",
+ "clean_material = Material.create(Material.default_config)\n",
+ "slab_111_config = SlabConfiguration(\n",
+ " bulk=clean_material,\n",
+ " miller_indices=(0,0, 1),\n",
+ " thickness=3,\n",
+ " vacuum=3,\n",
+ " xy_supercell_matrix=[[2, 0], [0, 2]],\n",
+ " use_orthogonal_z=True,\n",
+ " make_primitive=False\n",
+ ")\n",
+ "t_111 = get_terminations(slab_111_config)[0]\n",
+ "SLAB_111 = create_slab(slab_111_config, t_111)\n",
+ "\n",
+ "def test_create_island():\n",
+ " condition = CoordinateCondition.CylinderCoordinateCondition(\n",
+ " center_position=[0.5, 0.5], radius=0.15, min_z=0, max_z=1\n",
+ " )\n",
+ " island_config = IslandSlabDefectConfiguration(\n",
+ " crystal=SLAB_111,\n",
+ " defect_type=\"island\",\n",
+ " condition=condition,\n",
+ " number_of_added_layers=1,\n",
+ " )\n",
+ "\n",
+ " defect = create_slab_defect(configuration=island_config, builder=IslandSlabDefectBuilder())\n",
+ " visualize([{\"material\": SLAB_111, \"title\": \"Original material\"}, {\"material\": defect, \"title\": \"Material with island defect\"}])\n",
+ " visualize([{\"material\": SLAB_111, \"title\": \"Original material\"}, {\"material\": defect, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n",
+ "\n",
+ " # Only 2 atoms in the island were added for this configuration\n",
+ " NUMBER_OF_ATOMS_IN_ISLAND = 2\n",
+ " \n",
+ "\n",
+ " \n",
+ "test_create_island()\n"
+ ],
+ "metadata": {
+ "collapsed": false,
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:40:20.465560Z",
+ "start_time": "2024-09-10T22:40:19.735844Z"
+ }
+ },
+ "id": "5d1a7d4d0ba9c608",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si96 - Original material - rotation: 0x,0y,0z', layout=Layout(al…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "29a1f239671b498cb712bcfdb0d02a6c"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si96 - Original material - rotation: -90x', layout=Layout(align_…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "b96631b9fbea4c50a5e36204a6263899"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "execution_count": 14
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.348440Z",
+ "start_time": "2024-09-10T19:29:26.467504Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "gh_test_slab = {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.697840473, 0.0], [0.0, 0.0, 31.573922786]], 'constraints': [], 'labels': []}, 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [7.734, 0.0, 0.0], 'b': [3.867, 6.697840473, 0.0], 'c': [0.0, 0.0, 31.573922786], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'SlabConfiguration', 'bulk': {'name': 'Si8', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.5, 0.0, 0.0]}, {'id': 1, 'value': [0.25, 0.25, 0.75]}, {'id': 2, 'value': [0.5, 0.5, 0.5]}, {'id': 3, 'value': [0.25, 0.75, 0.25]}, {'id': 4, 'value': [0.0, 0.0, 0.5]}, {'id': 5, 'value': [0.75, 0.25, 0.25]}, {'id': 6, 'value': [0.0, 0.5, 0.0]}, {'id': 7, 'value': [0.75, 0.75, 0.75]}], 'units': 'crystal', 'cell': [[5.468763846, 0.0, 0.0], [0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]], 'constraints': [], 'labels': []}, 'lattice': {'a': 5.468763846, 'b': 5.468763846, 'c': 5.468763846, 'alpha': 90.0, 'beta': 90.0, 'gamma': 90.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [5.468763846, 0.0, 0.0], 'b': [0.0, 5.468763846, 0.0], 'c': [0.0, 0.0, 5.468763846], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}}, 'isUpdated': True}, 'miller_indices': (1, 1, 1), 'thickness': 4, 'vacuum': 6, 'xy_supercell_matrix': [[1, 0], [0, 1]], 'use_conventional_cell': True, 'use_orthogonal_z': True, 'make_primitive': False}}}, 'isUpdated': True}\n",
+ "\n",
+ "gh_test_material = {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': [[7.734, 0.0, 4.735709172302815e-16], [3.8670000000000018, 6.697840472868847, 4.735709172302815e-16], [0.0, 0.0, 31.573922786]]}, 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.69784, 0.0], [0.0, 0.0, 31.573923]], 'labels': []}, 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'IslandSlabDefectConfiguration', 'crystal': {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.697840473, 0.0], [0.0, 0.0, 31.573922786]], 'constraints': [], 'labels': []}, 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [7.734, 0.0, 0.0], 'b': [3.867, 6.697840473, 0.0], 'c': [0.0, 0.0, 31.573922786], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'SlabConfiguration', 'bulk': {'name': 'Si8', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.5, 0.0, 0.0]}, {'id': 1, 'value': [0.25, 0.25, 0.75]}, {'id': 2, 'value': [0.5, 0.5, 0.5]}, {'id': 3, 'value': [0.25, 0.75, 0.25]}, {'id': 4, 'value': [0.0, 0.0, 0.5]}, {'id': 5, 'value': [0.75, 0.25, 0.25]}, {'id': 6, 'value': [0.0, 0.5, 0.0]}, {'id': 7, 'value': [0.75, 0.75, 0.75]}], 'units': 'crystal', 'cell': [[5.468763846, 0.0, 0.0], [0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]], 'constraints': [], 'labels': []}, 'lattice': {'a': 5.468763846, 'b': 5.468763846, 'c': 5.468763846, 'alpha': 90.0, 'beta': 90.0, 'gamma': 90.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [5.468763846, 0.0, 0.0], 'b': [0.0, 5.468763846, 0.0], 'c': [0.0, 0.0, 5.468763846], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}}, 'isUpdated': True}, 'miller_indices': (1, 1, 1), 'thickness': 4, 'vacuum': 6, 'xy_supercell_matrix': [[1, 0], [0, 1]], 'use_conventional_cell': True, 'use_orthogonal_z': True, 'make_primitive': False}}}, 'isUpdated': True}, 'number_of_added_layers': 1, 'defect_type': 'ISLAND', 'condition': {'type': 'CylinderCoordinateCondition', 'center_position': [0.625, 0.5], 'radius': 0.25, 'min_z': 0.0, 'max_z': 1.0}}}}}\n",
+ "\n",
+ "gh_test_material = Material(gh_test_material)\n",
+ "gh_test_slab = Material(gh_test_slab)\n",
+ "visualize([{\"material\": gh_test_slab, \"title\": \"Original material\"}, {\"material\": gh_test_material, \"title\": \"Material with island defect\"}])\n",
+ "visualize([{\"material\": gh_test_slab, \"title\": \"Original material\"}, {\"material\": gh_test_material, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n"
+ ],
+ "id": "f88267e1da862e35",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si32 - Original material - rotation: 0x,0y,0z', layout=Layout(al…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "18d9d1eced5746fc864bacdc2918fb70"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si32 - Original material - rotation: -90x', layout=Layout(align_…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "72e621b113c54ac58201442909e2956c"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "execution_count": 12
+ },
+ {
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-10T22:35:17.348635Z",
+ "start_time": "2024-09-10T20:14:33.614506Z"
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "from pymatgen.core.surface import SlabGenerator as PymatgenSlabGenerator\n",
+ "from mat3ra.made.tools.convert import to_pymatgen, from_pymatgen\n",
+ "clean_material = Material.create(Material.default_config)\n",
+ "generator = PymatgenSlabGenerator(\n",
+ " initial_structure=to_pymatgen(clean_material),\n",
+ " miller_index=(0,0,1),\n",
+ " min_slab_size=3,\n",
+ " min_vacuum_size=1,\n",
+ " in_unit_planes=True,\n",
+ " reorient_lattice=True,\n",
+ " primitive=False\n",
+ " )\n",
+ "raw_slabs = generator.get_slabs()\n",
+ "material_slabs = [Material(from_pymatgen(slab)) for slab in raw_slabs]\n",
+ "# material_slabs = [Material(from_pymatgen(slab.get_orthogonal_c_slab())) for slab in raw_slabs]\n",
+ "visualize(material_slabs)\n",
+ "visualize(material_slabs, rotation=\"-90x\")"
+ ],
+ "id": "4681f90b3e4b25e9",
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si6 - Material - rotation: 0x,0y,0z', layout=Layout(align_self='…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "51b526bde1ac459b8712a867d5307898"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "GridBox(children=(VBox(children=(Label(value='Si6 - Material - rotation: -90x', layout=Layout(align_self='cent…"
+ ],
+ "application/vnd.jupyter.widget-view+json": {
+ "version_major": 2,
+ "version_minor": 0,
+ "model_id": "11fabcd68bdb4cabb9848d3ba8b7d0e0"
+ }
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "execution_count": 25
+ },
+ {
+ "metadata": {},
+ "cell_type": "code",
+ "outputs": [],
+ "execution_count": null,
+ "source": "",
+ "id": "51909da14eeaf743"
+ }
+ ],
+ "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
+}
diff --git a/other/materials_designer/create_point_defect.ipynb b/other/materials_designer/create_point_defect.ipynb
index db0fbed1..b6947837 100644
--- a/other/materials_designer/create_point_defect.ipynb
+++ b/other/materials_designer/create_point_defect.ipynb
@@ -91,7 +91,7 @@
"cell_type": "markdown",
"source": [
"### 1.3. Get input materials\n",
- "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
+ "Materials are loaded with `get_materials()`."
],
"metadata": {
"collapsed": false
@@ -102,12 +102,8 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
- "\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))"
+ "from utils.jupyterlite import get_materials\n",
+ "materials = get_materials(globals())"
],
"metadata": {
"collapsed": false
@@ -237,9 +233,9 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
+ "from utils.jupyterlite import set_materials\n",
"\n",
- "set_data(\"materials\", [material_with_defect_at_site_id.to_json(), material_with_defect_at_position.to_json()])"
+ "set_materials([material_with_defect_at_site_id, material_with_defect_at_position])"
],
"metadata": {
"collapsed": false
From 9ee963c5707f08cc6b64fcedea4572fa52b72d7a Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Thu, 3 Oct 2024 12:51:41 -0700
Subject: [PATCH 16/23] update: use set_materials++ in other nbs 2
---
.../materials_designer/create_nanoribbon.ipynb | 15 +++++----------
.../create_perturbation.ipynb | 18 +++++++-----------
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/other/materials_designer/create_nanoribbon.ipynb b/other/materials_designer/create_nanoribbon.ipynb
index 9c5bcebf..71cde2af 100644
--- a/other/materials_designer/create_nanoribbon.ipynb
+++ b/other/materials_designer/create_nanoribbon.ipynb
@@ -89,7 +89,7 @@
"cell_type": "markdown",
"source": [
"### 1.3. Get input materials\n",
- "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
+ "Materials are loaded with `get_materials()`."
],
"metadata": {
"collapsed": false
@@ -100,12 +100,8 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
- "\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))"
+ "from utils.jupyterlite import get_materials\n",
+ "materials = get_materials(globals())"
],
"metadata": {
"collapsed": false
@@ -232,9 +228,8 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
- "\n",
- "set_data(\"materials\", [nanoribbon.to_json()])"
+ "from utils.jupyterlite import set_materials\n",
+ "set_materials(nanoribbon)"
],
"metadata": {
"collapsed": false
diff --git a/other/materials_designer/create_perturbation.ipynb b/other/materials_designer/create_perturbation.ipynb
index d5045ed7..bd62db45 100644
--- a/other/materials_designer/create_perturbation.ipynb
+++ b/other/materials_designer/create_perturbation.ipynb
@@ -45,7 +45,7 @@
"cell_type": "code",
"outputs": [],
"source": [
- "SUPERCELL_MATRIX = [[5, 0, 0], [0, 5, 0], [0, 0, 1]] "
+ "SUPERCELL_MATRIX = [[30, 0, 0], [0, 30, 0], [0, 0, 1]] "
],
"metadata": {
"collapsed": false
@@ -86,7 +86,7 @@
"cell_type": "markdown",
"source": [
"### 1.3. Get input materials\n",
- "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
+ "Materials are loaded with `get_materials()`."
],
"metadata": {
"collapsed": false
@@ -97,12 +97,8 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
- "\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))"
+ "from utils.jupyterlite import get_materials\n",
+ "materials = get_materials(globals())"
],
"metadata": {
"collapsed": false
@@ -127,7 +123,7 @@
"from utils.visualize import visualize_materials as visualize\n",
"from mat3ra.made.tools.build.supercell import create_supercell\n",
"\n",
- "unit_cell = materials[0]\n",
+ "unit_cell = materials[7]\n",
"supercell = create_supercell(unit_cell, supercell_matrix=SUPERCELL_MATRIX)\n",
"visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")"
],
@@ -321,9 +317,9 @@
"cell_type": "code",
"outputs": [],
"source": [
- "from utils.jupyterlite import set_data\n",
+ "from utils.jupyterlite import set_materials\n",
"\n",
- "set_data(\"materials\", [material_with_perturbation.to_json(), material_with_custom_perturbation.to_json()])"
+ "set_materials([material_with_perturbation, material_with_custom_perturbation])"
],
"metadata": {
"collapsed": false
From 9696cc8f10d4de21b96e86780b52d0ab1244ddca Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Thu, 3 Oct 2024 13:33:33 -0700
Subject: [PATCH 17/23] update: small cleanups
---
other/materials_designer/create_nanoribbon.ipynb | 2 +-
other/materials_designer/create_perturbation.ipynb | 11 +++++++----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/other/materials_designer/create_nanoribbon.ipynb b/other/materials_designer/create_nanoribbon.ipynb
index 71cde2af..ed372b59 100644
--- a/other/materials_designer/create_nanoribbon.ipynb
+++ b/other/materials_designer/create_nanoribbon.ipynb
@@ -125,7 +125,7 @@
"source": [
"from utils.visualize import visualize_materials as visualize\n",
"\n",
- "material = materials[2]\n",
+ "material = materials[0]\n",
"visualize(material, repetitions=[3, 3, 1], rotation=\"0x\")"
],
"metadata": {
diff --git a/other/materials_designer/create_perturbation.ipynb b/other/materials_designer/create_perturbation.ipynb
index bd62db45..2bf77513 100644
--- a/other/materials_designer/create_perturbation.ipynb
+++ b/other/materials_designer/create_perturbation.ipynb
@@ -123,7 +123,7 @@
"from utils.visualize import visualize_materials as visualize\n",
"from mat3ra.made.tools.build.supercell import create_supercell\n",
"\n",
- "unit_cell = materials[7]\n",
+ "unit_cell = materials[0]\n",
"supercell = create_supercell(unit_cell, supercell_matrix=SUPERCELL_MATRIX)\n",
"visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")"
],
@@ -256,7 +256,8 @@
"metadata": {
"collapsed": false
},
- "id": "8d90932312c418ee"
+ "id": "8d90932312c418ee",
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -277,7 +278,8 @@
"metadata": {
"collapsed": false
},
- "id": "69ccc90b8c5c1191"
+ "id": "69ccc90b8c5c1191",
+ "execution_count": null
},
{
"cell_type": "markdown",
@@ -301,7 +303,8 @@
"metadata": {
"collapsed": false
},
- "id": "cbfe0878a16f6c83"
+ "id": "cbfe0878a16f6c83",
+ "execution_count": null
},
{
"cell_type": "markdown",
From eefdaa984e79b68d76091646dcd71f968351456d Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 12:01:19 -0700
Subject: [PATCH 18/23] chore: remove erroneous nb
---
.../create_island_defect.ipynb | 1079 -----------------
1 file changed, 1079 deletions(-)
delete mode 100644 other/materials_designer/create_island_defect.ipynb
diff --git a/other/materials_designer/create_island_defect.ipynb b/other/materials_designer/create_island_defect.ipynb
deleted file mode 100644
index 27651b17..00000000
--- a/other/materials_designer/create_island_defect.ipynb
+++ /dev/null
@@ -1,1079 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "source": [
- "# Create adatom defects in a slab material\n",
- "\n",
- "Create an adatom by specifying the chemical element, approximate position on surface and distance z, which will be resolved to:\n",
- "- the equidistant position between the closes atoms on the surface according to Voronoi tesselation, \n",
- "- or the crystal site of the next layer that is closest to specified position.\n",
- "\n",
- "Usage
\n",
- "\n",
- "1. Make sure to select Input Materials (in the outer runtime) before running the notebook.\n",
- "1. Set notebook parameters in cell 1.1. below (or use the default values).\n",
- "1. Set defects parameters in cell 2.1. (or use default).\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",
- "## Summary\n",
- "1. Prepare the Environment: Set up the notebook and install packages, preview the input materials\n",
- "1. Create the Defect: Add an adatom defect to the slab material\n",
- "2. Visualize the Defect: Visualize the defect structure\n",
- "\n",
- "## Notes\n",
- "\n",
- "1. For more information, see [Introduction](Introduction.ipynb)\n",
- "\n"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "f2e1e795020d7b3f"
- },
- {
- "cell_type": "markdown",
- "source": [
- "## 1. Prepare the Environment\n",
- "### 1.1. Set up defect parameters "
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "5e43ff288847b784"
- },
- {
- "cell_type": "code",
- "source": [
- "from mat3ra.made.tools.analyze import get_atomic_coordinates_extremum\n",
- "\n",
- "DEFECT_TYPE = \"island\"\n",
- "APPROXIMATE_POSITION_ON_SURFACE = [0.5, 0.5] # Position of the defect in crystal coordinates\n",
- "DISTANCE_Z = 5.0 # Distance of the defect from the surface in Angstrom\n",
- "CHEMICAL_ELEMENT = \"Ni\" # Element to be placed at the site \n",
- "MILLER_INDICES = (1, 1, 1) # Miller indices of the surface\n",
- "SLAB_THICKNESS = 5 # Thickness of the slab in unit cells\n",
- "VACUUM = 6 # Vacuum thickness in Angstrom\n",
- "SUPERCELL_MATRIX = [[5, 0, 0], [0, 5, 0], [0, 0, 1]]"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:34:47.390686Z",
- "start_time": "2024-09-10T22:34:47.386116Z"
- }
- },
- "id": "9d8b1890b34d850a",
- "outputs": [],
- "execution_count": 2
- },
- {
- "cell_type": "markdown",
- "source": [
- "### 1.2. 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": "bb64de5ff32649f8"
- },
- {
- "cell_type": "code",
- "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(\"create_point_defect.ipynb\", \"../../config.yml\")"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:34:47.426652Z",
- "start_time": "2024-09-10T22:34:47.422980Z"
- }
- },
- "id": "ef664b14457530fd",
- "outputs": [],
- "execution_count": 3
- },
- {
- "cell_type": "markdown",
- "source": [
- "### 1.3. Get input materials\n",
- "Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "919ad7af8dceeedd"
- },
- {
- "cell_type": "code",
- "source": [
- "from mat3ra.made.material import Material\n",
- "from utils.jupyterlite import get_data\n",
- "\n",
- "# Get the list of input materials and load them into `materials_in` variable\n",
- "get_data(\"materials_in\", globals())\n",
- "materials = list(map(Material, globals()[\"materials_in\"]))"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:34:48.899678Z",
- "start_time": "2024-09-10T22:34:47.443032Z"
- }
- },
- "id": "be38fdda1984c654",
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0: Data from 0-Ni has been read successfully.\n",
- "1: Data from 1-Graphene has been read successfully.\n",
- "2: Data from 10-Al2O3, Sapphire, RHL (R-3c) 3D (Bulk), mp-1143 (1) has been read successfully.\n",
- "3: Data from 11-ZnO, Zinc Oxide, HEX (P6_3mc) 3D (Bulk), mp-2133 has been read successfully.\n",
- "4: Data from 12-Cd4 Te4 has been read successfully.\n",
- "5: Data from 13-Si4 C4 has been read successfully.\n",
- "6: Data from 14-GaN, Gallium Nitride, HEX (P6_3mc) 3D (Bulk), mp-804 has been read successfully.\n",
- "7: Data from 4-Te2Mo has been read successfully.\n",
- "8: Data from 5-HfO2 has been read successfully.\n",
- "9: Data from 6-Ni4(110), termination Ni_Pmmm_2, Slab, Terrace, 1 steps, [2 0 0] has been read successfully.\n",
- "10: Data from 7-Ag4 has been read successfully.\n",
- "11: Data from 8-Si, Silicene, HEX (P-3m1) 2D (Monolayer), 2dm-5934 has been read successfully.\n",
- "12: Data from 9-GaAs, Gallium Arsenide, FCC (F-43m) 3D (Bulk), mp-2534 has been read successfully.\n",
- "13: Data from C2(001)-C2(001), Interface, Strain 0.000pct has been read successfully.\n",
- "14: Data from C2(001)-C2(001), Interface, Strain 0.397pct has been read successfully.\n",
- "15: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced displaced has been read successfully.\n",
- "16: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced optimal displaced has been read successfully.\n",
- "17: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced displaced has been read successfully.\n",
- "18: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced optimal displaced has been read successfully.\n",
- "19: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct displaced has been read successfully.\n",
- "20: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct optimal displaced has been read successfully.\n",
- "21: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct optimized with ASE has been read successfully.\n",
- "22: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct has been read successfully.\n",
- "23: Data from C2(001)-Ni4(111), Interface, Strain 0.105pct_displaced has been read successfully.\n",
- "24: Data from Ga2N2(001)-C4Si4(111), Interface, Strain 0.082pct has been read successfully.\n",
- "25: Data from Interface 45 degrees has been read successfully.\n",
- "26: Data from Merged Material HEX final moire_5 deg has been read successfully.\n",
- "27: Data from Merged Material59deg final moire_59deg has been read successfully.\n",
- "28: Data from Ni12(001), termination Ni_Cmmm_6, Slab has been read successfully.\n",
- "29: Data from Ni12(100), termination Ni_Pmma_6, Slab has been read successfully.\n",
- "30: Data from Ni12(100), termination Ni_Pmmm_6, Slab has been read successfully.\n",
- "31: Data from Ni144(100), termination Ni_Pm_9, Slab has been read successfully.\n",
- "32: Data from Ni174(001), termination Ni_Pm_6, Slab has been read successfully.\n",
- "33: Data from Ni270(111), termination Ni_P1_116, Slab has been read successfully.\n",
- "34: Data from Ni4(001)-Ni4(110), Interface, Strain 0.222pct has been read successfully.\n",
- "35: Data from Ni4(001)-Ni4(111), Interface, Strain 0.062pct has been read successfully.\n",
- "36: Data from Ni4(001)-Ni4(111), Interface, Strain 0.227pct has been read successfully.\n",
- "37: Data from Ni4(110)-Ni4(-1-10), Interface, Strain 0.000pct has been read successfully.\n",
- "38: Data from Ni4(110)-Ni4(100), Interface, Strain 0.019pct has been read successfully.\n",
- "39: Data from Ni4(110)-Ni4(110), Interface, Strain 0.000pct has been read successfully.\n",
- "40: Data from Ni432(001), termination Ni_Pmmm_21, Slab has been read successfully.\n",
- "41: Data from Ni90(001), termination Ni_P4:mmm_7, Slab has been read successfully.\n",
- "42: Data from Ni90(111), termination Ni_P1_180, Slab has been read successfully.\n",
- "43: Data from Si2(001)-Ag4(111), Interface, Strain 0.035pct has been read successfully.\n",
- "44: Data from Si8(001), termination Si_P4:mmm_1, Slab has been read successfully.\n",
- "45: Data from Si8(111), termination Si_P6:mmm_4, Slab has been read successfully.\n",
- "46: Data from TEST 1.1 final moire_1.1deg has been read successfully.\n",
- "47: Data from TEST 1.1 has been read successfully.\n",
- "48: Data from TEST 5deg final moire_5deg has been read successfully.\n",
- "49: Data from TEST 5deg has been read successfully.\n",
- "50: Data from Twisted Interface 30.0 degrees - 24000 atoms has been read successfully.\n",
- "51: Data from Twisted Interface 30.0 degrees has been read successfully.\n",
- "52: Data from moire_1.1deg has been read successfully.\n",
- "53: Data from moire_30deg has been read successfully.\n",
- "54: Data from moire_5deg has been read successfully.\n",
- "55: Data from rotated_basis -59 degrees has been read successfully.\n",
- "56: Data from rotated_basis 1.1 degrees has been read successfully.\n",
- "57: Data from rotated_basis 245 degrees has been read successfully.\n",
- "58: Data from rotated_basis 5 degrees has been read successfully.\n"
- ]
- }
- ],
- "execution_count": 4
- },
- {
- "cell_type": "markdown",
- "source": [
- "### 1.4. Create and preview Slab"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "a132fe0ef8bbf0d0"
- },
- {
- "cell_type": "code",
- "source": [
- "from mat3ra.made.tools.build.slab import SlabConfiguration, get_terminations, create_slab\n",
- "from utils.visualize import visualize_materials as visualize\n",
- "from mat3ra.made.tools.build.defect.builders import CrystalSiteAdatomSlabDefectBuilder\n",
- "\n",
- "material = materials[8]\n",
- "slab_config = SlabConfiguration(\n",
- " bulk=material,\n",
- " miller_indices=MILLER_INDICES,\n",
- " thickness=SLAB_THICKNESS,\n",
- " vacuum=VACUUM,\n",
- " use_orthogonal_z=True,\n",
- " xy_supercell_matrix=SUPERCELL_MATRIX\n",
- ")\n",
- "termination = get_terminations(slab_config)[1]\n",
- "slab = create_slab(slab_config, termination)\n",
- "print(slab.metadata.get(\"build\").get(\"configuration\").get(\"type\"))\n",
- "new_slab = CrystalSiteAdatomSlabDefectBuilder().create_material_with_additional_layers(slab, 2)\n",
- "visualize([{\"material\": slab, \"rotation\": \"0x\"}, {\"material\": slab, \"rotation\": \"-90x\"}], repetitions=[1, 1, 1])\n",
- "visualize([{\"material\": new_slab, \"rotation\": \"0x\"}, {\"material\": new_slab, \"rotation\": \"-90x\"}], repetitions=[1, 1, 1])\n",
- "print(slab.metadata.get(\"build\").get(\"configuration\").get(\"type\"))\n",
- "\n"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:34:53.028769Z",
- "start_time": "2024-09-10T22:34:48.914114Z"
- }
- },
- "id": "e2d24109d3068c9e",
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "SlabConfiguration\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Material - rotation: 0x', layout=Layout(align_self=…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "adf7327f1d2b421e95d606b0d654e630"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Hf700O1400 - Material - rotation: 0x', layout=Layout(align_self=…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "6895fadc9a094fe79cce34e442e8e551"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "SlabConfiguration\n"
- ]
- }
- ],
- "execution_count": 5
- },
- {
- "cell_type": "markdown",
- "source": [
- "## 2. Create the Defect\n",
- "### 2.1. Set adatom parameters"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "5da5b0380583c952"
- },
- {
- "cell_type": "code",
- "source": [
- "from mat3ra.made.tools.build.defect.builders import IslandSlabDefectBuilder\n",
- "from mat3ra.made.tools.build.defect.configuration import IslandSlabDefectConfiguration\n",
- "from mat3ra.made.tools.utils import coordinate as CoordinateCondition\n",
- "from mat3ra.made.tools.modify import filter_by_box\n",
- "condition = CoordinateCondition.CylinderCoordinateCondition(center_position=[0.25, 0.5], radius=0.25, min_z=0, max_z=1)\n",
- "island_config = IslandSlabDefectConfiguration(\n",
- " crystal=slab,\n",
- " defect_type=\"island\",\n",
- " condition=condition,\n",
- " number_of_added_layers=3,\n",
- ")\n",
- "\n",
- "slab_with_island = IslandSlabDefectBuilder().get_material(configuration=island_config)\n",
- "visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
- " {\"material\": slab_with_island, \"title\": \"Material with island defect\"}])\n",
- "visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
- " {\"material\": slab_with_island, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n",
- "slab_with_island.metadata.get(\"build\").get(\"configuration\")\n",
- "\n",
- "\n",
- "slab_with_island = filter_by_box(slab_with_island, [0.5, 0.5, 0.25], [0.75, 0.75, 1], invert_selection=True)\n",
- "slab_with_island.name = slab_with_island.name + \" Island\"\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}], rotation=\"-40x\")"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:29.723604Z",
- "start_time": "2024-09-10T22:35:18.526794Z"
- }
- },
- "id": "a14402cb0adc7dd1",
- "outputs": [
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Original material - rotation: 0x,0y,0z', layout=Lay…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "16c3f8c94c274253b6fb68d706e40759"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Hf500O1000 - Original material - rotation: -90x', layout=Layout(…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "5a82b120520b452bb94e198f7fac7290"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Hf546O1090 - Material with island defect - rotation: -40x', layo…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "e66914e0c0064eb48dd7e03ffb80f95a"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "execution_count": 8
- },
- {
- "cell_type": "markdown",
- "source": [
- "### 2.2. Create the adatom"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "489b51f0ee122c48"
- },
- {
- "cell_type": "code",
- "source": [
- "\n",
- "from mat3ra.made.tools.modify import filter_material_by_ids,filter_by_box\n",
- "import numpy as np\n",
- "from typing import Literal, List\n",
- "\n",
- "\n",
- "def get_surface_atoms_indices(\n",
- " material: Material,\n",
- " surface: Literal[\"top\", \"bottom\", \"both\"] = \"top\",\n",
- " n: int = 15,\n",
- " m: int = 15\n",
- ") -> List[int]:\n",
- " \"\"\"\n",
- " Get the indices of atoms on the surface of the material along the Z axis.\n",
- "\n",
- " Args:\n",
- " material (Material): Material object.\n",
- " surface (str): \"top\", \"bottom\", or \"both\".\n",
- " n (int): Number of divisions along the X axis.\n",
- " m (int): Number of divisions along the Y axis.\n",
- "\n",
- " Returns:\n",
- " List[int]: List of indices of atoms on the surface.\n",
- " \"\"\"\n",
- " surface_atoms_indices = []\n",
- "\n",
- " # Get columns of atoms with grid n by m:\n",
- " for i in range(n):\n",
- " for j in range(m):\n",
- " # Define the bounding box for the current grid cell\n",
- " x_min, x_max = i / n, (i + 1) / n\n",
- " y_min, y_max = j / m, (j + 1) / m\n",
- "\n",
- " # Filter atoms within this grid cell\n",
- " atoms_column = filter_by_box(material, [x_min, y_min, 0], [x_max, y_max, 1])\n",
- " \n",
- "\n",
- " if len(atoms_column.basis.coordinates.values) == 0:\n",
- " continue # Skip empty columns\n",
- "\n",
- "\n",
- " # Extract the z-coordinates\n",
- " z_values = [coord[2] for coord in atoms_column.basis.coordinates.values]\n",
- "\n",
- " # Find the top and bottom atoms by Z-coordinate\n",
- " top_atom_idx = np.argmax(z_values)\n",
- " bottom_atom_idx = np.argmin(z_values)\n",
- "\n",
- " # Map these to the corresponding IDs\n",
- " top_atom_id = atoms_column.basis.coordinates.ids[top_atom_idx]\n",
- " bottom_atom_id = atoms_column.basis.coordinates.ids[bottom_atom_idx]\n",
- "\n",
- " # Add the appropriate IDs to the surface_atoms_indices list\n",
- " if surface == \"top\" or surface == \"both\":\n",
- " surface_atoms_indices.append(top_atom_id)\n",
- " if surface == \"bottom\" or surface == \"both\":\n",
- " surface_atoms_indices.append(bottom_atom_id)\n",
- "\n",
- " # Remove duplicates by converting the list to a set and back to a list\n",
- " surface_atoms_indices = list(set(surface_atoms_indices))\n",
- "\n",
- " return surface_atoms_indices\n",
- "\n",
- "ids = get_surface_atoms_indices(slab_with_island, surface=\"top\")\n",
- "top_atoms = filter_material_by_ids(slab_with_island, ids)\n",
- "\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": top_atoms, \"title\": \"Surface Atoms only\"}], rotation=\"-90x\")\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": top_atoms, \"title\": \"Surface Atoms only\"}], rotation=\"0x\")"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "start_time": "2024-09-10T22:35:03.278751Z"
- }
- },
- "id": "a990fa35742d7269",
- "outputs": [
- {
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
- "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)",
- "Cell \u001B[0;32mIn[7], line 63\u001B[0m\n\u001B[1;32m 59\u001B[0m surface_atoms_indices \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mlist\u001B[39m(\u001B[38;5;28mset\u001B[39m(surface_atoms_indices))\n\u001B[1;32m 61\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m surface_atoms_indices\n\u001B[0;32m---> 63\u001B[0m ids \u001B[38;5;241m=\u001B[39m \u001B[43mget_surface_atoms_indices\u001B[49m\u001B[43m(\u001B[49m\u001B[43mslab_with_island\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43msurface\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mtop\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[1;32m 64\u001B[0m top_atoms \u001B[38;5;241m=\u001B[39m filter_material_by_ids(slab_with_island, ids)\n\u001B[1;32m 66\u001B[0m visualize([{\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mmaterial\u001B[39m\u001B[38;5;124m\"\u001B[39m: slab_with_island, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtitle\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mMaterial with island defect\u001B[39m\u001B[38;5;124m\"\u001B[39m}, {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mmaterial\u001B[39m\u001B[38;5;124m\"\u001B[39m: top_atoms, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtitle\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mSurface Atoms only\u001B[39m\u001B[38;5;124m\"\u001B[39m}], rotation\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m-90x\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
- "Cell \u001B[0;32mIn[7], line 34\u001B[0m, in \u001B[0;36mget_surface_atoms_indices\u001B[0;34m(material, surface, n, m)\u001B[0m\n\u001B[1;32m 31\u001B[0m y_min, y_max \u001B[38;5;241m=\u001B[39m j \u001B[38;5;241m/\u001B[39m m, (j \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m) \u001B[38;5;241m/\u001B[39m m\n\u001B[1;32m 33\u001B[0m \u001B[38;5;66;03m# Filter atoms within this grid cell\u001B[39;00m\n\u001B[0;32m---> 34\u001B[0m atoms_column \u001B[38;5;241m=\u001B[39m \u001B[43mfilter_by_box\u001B[49m\u001B[43m(\u001B[49m\u001B[43mmaterial\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[43mx_min\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43my_min\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[43mx_max\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43my_max\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 37\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(atoms_column\u001B[38;5;241m.\u001B[39mbasis\u001B[38;5;241m.\u001B[39mcoordinates\u001B[38;5;241m.\u001B[39mvalues) \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m:\n\u001B[1;32m 38\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m \u001B[38;5;66;03m# Skip empty columns\u001B[39;00m\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:347\u001B[0m, in \u001B[0;36mfilter_by_box\u001B[0;34m(material, min_coordinate, max_coordinate, use_cartesian_coordinates, invert_selection)\u001B[0m\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mcondition\u001B[39m(coordinate):\n\u001B[1;32m 345\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m is_coordinate_in_box(coordinate, min_coordinate, max_coordinate)\n\u001B[0;32m--> 347\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfilter_by_condition_on_coordinates\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mmaterial\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcondition\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43muse_cartesian_coordinates\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43muse_cartesian_coordinates\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minvert_selection\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43minvert_selection\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:175\u001B[0m, in \u001B[0;36mfilter_by_condition_on_coordinates\u001B[0;34m(material, condition, use_cartesian_coordinates, invert_selection)\u001B[0m\n\u001B[1;32m 168\u001B[0m new_material \u001B[38;5;241m=\u001B[39m material\u001B[38;5;241m.\u001B[39mclone()\n\u001B[1;32m 169\u001B[0m ids \u001B[38;5;241m=\u001B[39m get_atom_indices_with_condition_on_coordinates(\n\u001B[1;32m 170\u001B[0m material,\n\u001B[1;32m 171\u001B[0m condition,\n\u001B[1;32m 172\u001B[0m use_cartesian_coordinates\u001B[38;5;241m=\u001B[39muse_cartesian_coordinates,\n\u001B[1;32m 173\u001B[0m )\n\u001B[0;32m--> 175\u001B[0m new_material \u001B[38;5;241m=\u001B[39m \u001B[43mfilter_material_by_ids\u001B[49m\u001B[43m(\u001B[49m\u001B[43mnew_material\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mids\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43minvert\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43minvert_selection\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 176\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m new_material\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/tools/modify.py:141\u001B[0m, in \u001B[0;36mfilter_material_by_ids\u001B[0;34m(material, ids, invert)\u001B[0m\n\u001B[1;32m 129\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfilter_material_by_ids\u001B[39m(material: Material, ids: List[\u001B[38;5;28mint\u001B[39m], invert: \u001B[38;5;28mbool\u001B[39m \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Material:\n\u001B[1;32m 130\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 131\u001B[0m \u001B[38;5;124;03m Filter out only atoms corresponding to the ids.\u001B[39;00m\n\u001B[1;32m 132\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[38;5;124;03m Material: The filtered material object.\u001B[39;00m\n\u001B[1;32m 140\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m--> 141\u001B[0m new_material \u001B[38;5;241m=\u001B[39m \u001B[43mmaterial\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mclone\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 142\u001B[0m new_basis \u001B[38;5;241m=\u001B[39m new_material\u001B[38;5;241m.\u001B[39mbasis\n\u001B[1;32m 143\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m invert \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/code/entity.py:55\u001B[0m, in \u001B[0;36mInMemoryEntity.clone\u001B[0;34m(self, extra_context)\u001B[0m\n\u001B[1;32m 51\u001B[0m config\u001B[38;5;241m.\u001B[39mupdate(extra_context)\n\u001B[1;32m 52\u001B[0m \u001B[38;5;66;03m# To avoid:\u001B[39;00m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;66;03m# Argument 1 to \"__init__\" of \"BaseUnderscoreJsonPropsHandler\" has incompatible type \"Dict[str, Any]\";\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;66;03m# expected \"BaseUnderscoreJsonPropsHandler\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[38;5;18;43m__class__\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/made/material.py:58\u001B[0m, in \u001B[0;36mMaterial.__init__\u001B[0;34m(self, config)\u001B[0m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\u001B[38;5;28mself\u001B[39m, config: Any) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m---> 58\u001B[0m \u001B[38;5;28;43msuper\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[38;5;21;43m__init__\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 59\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname \u001B[38;5;241m=\u001B[39m \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39mname \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mformula\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/code/__init__.py:8\u001B[0m, in \u001B[0;36mBaseUnderscoreJsonPropsHandler.__init__\u001B[0;34m(self, config)\u001B[0m\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\u001B[38;5;28mself\u001B[39m, config: Dict[\u001B[38;5;28mstr\u001B[39m, Any] \u001B[38;5;241m=\u001B[39m {}) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m----> 8\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_json \u001B[38;5;241m=\u001B[39m \u001B[43mobject_utils\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mclone_deep\u001B[49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n",
- "File \u001B[0;32m~/code/GREEN/api-examples/.venv/lib/python3.11/site-packages/mat3ra/utils/object.py:22\u001B[0m, in \u001B[0;36mclone_deep\u001B[0;34m(obj)\u001B[0m\n\u001B[1;32m 21\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mclone_deep\u001B[39m(obj: Any) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Any:\n\u001B[0;32m---> 22\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mcopy\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
- " \u001B[0;31m[... skipping similar frames: deepcopy at line 146 (4 times), _deepcopy_dict at line 231 (3 times)]\u001B[0m\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:206\u001B[0m, in \u001B[0;36m_deepcopy_list\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 204\u001B[0m append \u001B[38;5;241m=\u001B[39m y\u001B[38;5;241m.\u001B[39mappend\n\u001B[1;32m 205\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m a \u001B[38;5;129;01min\u001B[39;00m x:\n\u001B[0;32m--> 206\u001B[0m append(\u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43ma\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[1;32m 207\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:146\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 144\u001B[0m copier \u001B[38;5;241m=\u001B[39m _deepcopy_dispatch\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;28mcls\u001B[39m)\n\u001B[1;32m 145\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m copier \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 146\u001B[0m y \u001B[38;5;241m=\u001B[39m \u001B[43mcopier\u001B[49m\u001B[43m(\u001B[49m\u001B[43mx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 147\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 148\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28missubclass\u001B[39m(\u001B[38;5;28mcls\u001B[39m, \u001B[38;5;28mtype\u001B[39m):\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:231\u001B[0m, in \u001B[0;36m_deepcopy_dict\u001B[0;34m(x, memo, deepcopy)\u001B[0m\n\u001B[1;32m 229\u001B[0m memo[\u001B[38;5;28mid\u001B[39m(x)] \u001B[38;5;241m=\u001B[39m y\n\u001B[1;32m 230\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m key, value \u001B[38;5;129;01min\u001B[39;00m x\u001B[38;5;241m.\u001B[39mitems():\n\u001B[0;32m--> 231\u001B[0m y[deepcopy(key, memo)] \u001B[38;5;241m=\u001B[39m \u001B[43mdeepcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mvalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmemo\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m y\n",
- "File \u001B[0;32m~/.pyenv/versions/3.11.2/lib/python3.11/copy.py:128\u001B[0m, in \u001B[0;36mdeepcopy\u001B[0;34m(x, memo, _nil)\u001B[0m\n\u001B[1;32m 124\u001B[0m d[PyStringMap] \u001B[38;5;241m=\u001B[39m PyStringMap\u001B[38;5;241m.\u001B[39mcopy\n\u001B[1;32m 126\u001B[0m \u001B[38;5;28;01mdel\u001B[39;00m d, t\n\u001B[0;32m--> 128\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mdeepcopy\u001B[39m(x, memo\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, _nil\u001B[38;5;241m=\u001B[39m[]):\n\u001B[1;32m 129\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"Deep copy operation on arbitrary Python objects.\u001B[39;00m\n\u001B[1;32m 130\u001B[0m \n\u001B[1;32m 131\u001B[0m \u001B[38;5;124;03m See the module's __doc__ string for more info.\u001B[39;00m\n\u001B[1;32m 132\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[1;32m 134\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m memo \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
- "\u001B[0;31mKeyboardInterrupt\u001B[0m: "
- ]
- }
- ],
- "execution_count": 7
- },
- {
- "cell_type": "markdown",
- "source": [
- "## 3. Visualize the Slabs with Adatom"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "462549d016073446"
- },
- {
- "cell_type": "markdown",
- "source": [
- "## 4. Pass data to the outside runtime"
- ],
- "metadata": {
- "collapsed": false
- },
- "id": "d381df29a6bbdd82"
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "data": {
- "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "e70a90e827bb4fae9dbecb8e206e218f"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: 0x', layout…",
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "4cef85ea912742e295e421260ea785af"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "\n",
- "from mat3ra.made.tools.build.defect import create_slab_defect, TerraceSlabDefectBuilder\n",
- "from mat3ra.made.tools.build.defect.configuration import TerraceSlabDefectConfiguration\n",
- "from scipy.spatial import cKDTree\n",
- "\n",
- "def get_surface_atoms_indices(material: Material, distance_threshold: float = 2.5, depth: float = 5) -> List[int]:\n",
- " \"\"\"\n",
- " Identify exposed atoms on the top surface of the material.\n",
- "\n",
- " Args:\n",
- " material (Material): Material object to get surface atoms from.\n",
- " distance_threshold (float): Distance threshold to determine if an atom is considered \"covered\".\n",
- " depth (float): Depth from the top surface to look for exposed atoms.\n",
- "\n",
- " Returns:\n",
- " List[int]: List of indices of exposed top surface atoms.\n",
- " \"\"\"\n",
- " material.to_cartesian()\n",
- " coordinates = np.array(material.basis.coordinates.values)\n",
- " ids = material.basis.coordinates.ids\n",
- " kd_tree = cKDTree(coordinates)\n",
- " z_max = np.max(coordinates[:, 2])\n",
- "\n",
- " exposed_atoms_indices = []\n",
- " for idx, (x, y, z) in enumerate(coordinates):\n",
- " if z >= z_max - depth:\n",
- " neighbors_above = kd_tree.query_ball_point([x, y, z + distance_threshold], r=distance_threshold)\n",
- "\n",
- " if not any(coordinates[n][2] > z for n in neighbors_above):\n",
- " exposed_atoms_indices.append(ids[idx])\n",
- " material.to_crystal()\n",
- " return exposed_atoms_indices\n",
- "\n",
- "\n",
- "configuration = TerraceSlabDefectConfiguration(\n",
- " crystal=slab,\n",
- ")\n",
- "builder = TerraceSlabDefectBuilder()\n",
- "terrace = create_slab_defect(configuration, builder)\n",
- "\n",
- "exposed_top_surface_atoms = get_surface_atoms_indices(slab_with_island, distance_threshold=2.5, depth=15)\n",
- "exposed_atoms = filter_material_by_ids(slab_with_island, exposed_top_surface_atoms)\n",
- "exposed_atoms.name = exposed_atoms.name + \" Surface Atoms\"\n",
- "\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": exposed_atoms, \"title\": \"Exposed Atoms only\"}], rotation=\"-90x\")\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": exposed_atoms, \"title\": \"Exposed Atoms only\"}], rotation=\"0x\")"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.345111Z",
- "start_time": "2024-08-24T01:06:40.137044Z"
- }
- },
- "id": "61daa5afcbc078a9",
- "execution_count": 7
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Island.json\n",
- "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Surface Atoms Surface Atoms.json\n"
- ]
- },
- {
- "data": {
- "text/plain": "1565"
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from utils.jupyterlite import set_data\n",
- "slab_with_island.name = slab_with_island.name + \" Island\"\n",
- "exposed_atoms.name = exposed_atoms.name + \" Surface Atoms\"\n",
- "set_data(\"materials_out\", [slab_with_island.to_json(), exposed_atoms.to_json()])\n",
- "len(slab_with_island.basis.elements.ids)"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.345811Z",
- "start_time": "2024-08-24T01:06:56.359197Z"
- }
- },
- "id": "8f1f5b3ee69d0355",
- "execution_count": 8
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "data": {
- "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "dbac8d90d33341668910696a72c31de8"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: 0x', layout…",
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "f8c99e61943541b993e1fdae2750ce32"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Data for materials_out written to uploads/Hf4O8(111), termination O2_P2:m_1, Slab Island Island Passivated.json\n"
- ]
- }
- ],
- "source": [
- "def passivate_top(material, element, bond_length, depth):\n",
- " \"\"\"\n",
- " Passivate the top surface of the material with the specified element.\n",
- "\n",
- " Args:\n",
- " material (Material): Material object to passivate.\n",
- " element (str): Element to use for passivation.\n",
- " bond_length (float): Bond length to use for the passivation.\n",
- " depth (float): Depth from the top surface to passivate.\n",
- "\n",
- " Returns:\n",
- " Material: Material object with the top surface passivated.\n",
- " \"\"\"\n",
- " new_material = material.clone()\n",
- " top_atom_indices = get_surface_atoms_indices(material, distance_threshold=2.2, depth=depth)\n",
- " top_atoms = filter_material_by_ids(material, top_atom_indices)\n",
- " new_material.to_cartesian()\n",
- " top_atoms.to_cartesian()\n",
- " top_atoms_coordinates = top_atoms.basis.coordinates.values\n",
- " passivant_coordinates = np.array(top_atoms_coordinates) + [0, 0, bond_length]\n",
- " \n",
- " for coord in passivant_coordinates:\n",
- " new_material.add_atom(element, coord)\n",
- " new_material.to_crystal()\n",
- " return new_material\n",
- "\n",
- "passivated_slab = passivate_top(slab_with_island, \"H\", 1.0, 15)\n",
- "passivated_slab.name = passivated_slab.name + \" Passivated\"\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_slab, \"title\": \"Passivated Material\"}], rotation=\"-90x\")\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_slab, \"title\": \"Passivated Material\"}], rotation=\"0x\")\n",
- "\n",
- "set_data(\"materials_out\", [ passivated_slab.to_json()])"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.346107Z",
- "start_time": "2024-08-24T01:52:08.525957Z"
- }
- },
- "id": "b529792d4b077042",
- "execution_count": 14
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "data": {
- "text/plain": "1708"
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(passivated_slab.basis.elements.values)"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.346715Z",
- "start_time": "2024-08-24T01:07:06.686806Z"
- }
- },
- "id": "4200a5b3ffb1a6ff",
- "execution_count": 10
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "data": {
- "text/plain": "GridBox(children=(VBox(children=(Label(value='Hf528O1037 - Material with island defect - rotation: -90x', layo…",
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "ca2650387e6b468ca2ca14d8505a6ba4"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from mat3ra.made.tools.modify import passivate_material, passivate_surface\n",
- "\n",
- "passivated_surface = passivate_surface(slab_with_island, passivant=\"H\", default_bond_length=1.0)\n",
- "visualize([{\"material\": slab_with_island, \"title\": \"Material with island defect\"}, {\"material\": passivated_surface, \"title\": \"Passivated Material\"}], rotation=\"-90x\")"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.347606Z",
- "start_time": "2024-08-24T01:07:06.695459Z"
- }
- },
- "id": "e27584952f2dd760",
- "execution_count": 11
- },
- {
- "cell_type": "code",
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Commensurate lattice vectors: m1=0, m2=0, n1=0, n2=0\n"
- ]
- }
- ],
- "source": [
- "import numpy as np\n",
- "from scipy.optimize import minimize\n",
- "\n",
- "def find_commensurate_lattice(T, a1, a2, tol=1e-6):\n",
- " \"\"\"\n",
- " Finds commensurate lattice vectors for two 2D arbitrary bases.\n",
- " \n",
- " Parameters:\n",
- " - T: 2x2 numpy array, the transformation matrix relating the two bases.\n",
- " - a1, a2: numpy arrays, the vectors of the first basis.\n",
- " - tol: float, tolerance for finding integer solutions.\n",
- " \n",
- " Returns:\n",
- " - (m1, m2, n1, n2): tuple of integers that satisfy the commensurability condition.\n",
- " \"\"\"\n",
- " \n",
- " def objective(vars):\n",
- " m1, m2, n1, n2 = vars\n",
- " return m1**2 + m2**2 + n1**2 + n2**2\n",
- "\n",
- " def constraint(vars):\n",
- " m1, m2, n1, n2 = vars\n",
- " lhs = m1 * a1 + m2 * a2\n",
- " rhs = n1 * (T @ a1) + n2 * (T @ a2)\n",
- " return np.linalg.norm(lhs - rhs)\n",
- " \n",
- " # Initial guess for m1, m2, n1, n2\n",
- " initial_guess = [1, 0, 1, 0]\n",
- " \n",
- " # Constraints dictionary\n",
- " constraints = {'type': 'eq', 'fun': constraint}\n",
- " \n",
- " # Solve the optimization problem\n",
- " result = minimize(objective, initial_guess, constraints=constraints, method='SLSQP', options={'ftol': tol})\n",
- " \n",
- " if result.success:\n",
- " m1, m2, n1, n2 = np.round(result.x).astype(int)\n",
- " return m1, m2, n1, n2\n",
- " else:\n",
- " raise ValueError(\"No commensurate lattice found within the given tolerance.\")\n",
- "\n",
- "# Example usage:\n",
- "a1 = np.array([1, 0])\n",
- "a2 = np.array([-0.5, np.sqrt(3) / 2])\n",
- "angle = np.pi / 3\n",
- "T = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]])\n",
- "m1, m2, n1, n2 = find_commensurate_lattice(T, a1, a2, tol=1e-1)\n",
- "print(f\"Commensurate lattice vectors: m1={m1}, m2={m2}, n1={n1}, n2={n2}\")\n"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.347841Z",
- "start_time": "2024-08-24T03:09:08.323562Z"
- }
- },
- "id": "2aa667c6ee85aec9",
- "execution_count": 21
- },
- {
- "cell_type": "code",
- "source": [
- "from mat3ra.made.tools.build.defect import create_slab_defect, IslandSlabDefectBuilder\n",
- "clean_material = Material.create(Material.default_config)\n",
- "slab_111_config = SlabConfiguration(\n",
- " bulk=clean_material,\n",
- " miller_indices=(0,0, 1),\n",
- " thickness=3,\n",
- " vacuum=3,\n",
- " xy_supercell_matrix=[[2, 0], [0, 2]],\n",
- " use_orthogonal_z=True,\n",
- " make_primitive=False\n",
- ")\n",
- "t_111 = get_terminations(slab_111_config)[0]\n",
- "SLAB_111 = create_slab(slab_111_config, t_111)\n",
- "\n",
- "def test_create_island():\n",
- " condition = CoordinateCondition.CylinderCoordinateCondition(\n",
- " center_position=[0.5, 0.5], radius=0.15, min_z=0, max_z=1\n",
- " )\n",
- " island_config = IslandSlabDefectConfiguration(\n",
- " crystal=SLAB_111,\n",
- " defect_type=\"island\",\n",
- " condition=condition,\n",
- " number_of_added_layers=1,\n",
- " )\n",
- "\n",
- " defect = create_slab_defect(configuration=island_config, builder=IslandSlabDefectBuilder())\n",
- " visualize([{\"material\": SLAB_111, \"title\": \"Original material\"}, {\"material\": defect, \"title\": \"Material with island defect\"}])\n",
- " visualize([{\"material\": SLAB_111, \"title\": \"Original material\"}, {\"material\": defect, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n",
- "\n",
- " # Only 2 atoms in the island were added for this configuration\n",
- " NUMBER_OF_ATOMS_IN_ISLAND = 2\n",
- " \n",
- "\n",
- " \n",
- "test_create_island()\n"
- ],
- "metadata": {
- "collapsed": false,
- "ExecuteTime": {
- "end_time": "2024-09-10T22:40:20.465560Z",
- "start_time": "2024-09-10T22:40:19.735844Z"
- }
- },
- "id": "5d1a7d4d0ba9c608",
- "outputs": [
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si96 - Original material - rotation: 0x,0y,0z', layout=Layout(al…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "29a1f239671b498cb712bcfdb0d02a6c"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si96 - Original material - rotation: -90x', layout=Layout(align_…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "b96631b9fbea4c50a5e36204a6263899"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "execution_count": 14
- },
- {
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.348440Z",
- "start_time": "2024-09-10T19:29:26.467504Z"
- }
- },
- "cell_type": "code",
- "source": [
- "gh_test_slab = {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.697840473, 0.0], [0.0, 0.0, 31.573922786]], 'constraints': [], 'labels': []}, 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [7.734, 0.0, 0.0], 'b': [3.867, 6.697840473, 0.0], 'c': [0.0, 0.0, 31.573922786], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'SlabConfiguration', 'bulk': {'name': 'Si8', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.5, 0.0, 0.0]}, {'id': 1, 'value': [0.25, 0.25, 0.75]}, {'id': 2, 'value': [0.5, 0.5, 0.5]}, {'id': 3, 'value': [0.25, 0.75, 0.25]}, {'id': 4, 'value': [0.0, 0.0, 0.5]}, {'id': 5, 'value': [0.75, 0.25, 0.25]}, {'id': 6, 'value': [0.0, 0.5, 0.0]}, {'id': 7, 'value': [0.75, 0.75, 0.75]}], 'units': 'crystal', 'cell': [[5.468763846, 0.0, 0.0], [0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]], 'constraints': [], 'labels': []}, 'lattice': {'a': 5.468763846, 'b': 5.468763846, 'c': 5.468763846, 'alpha': 90.0, 'beta': 90.0, 'gamma': 90.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [5.468763846, 0.0, 0.0], 'b': [0.0, 5.468763846, 0.0], 'c': [0.0, 0.0, 5.468763846], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}}, 'isUpdated': True}, 'miller_indices': (1, 1, 1), 'thickness': 4, 'vacuum': 6, 'xy_supercell_matrix': [[1, 0], [0, 1]], 'use_conventional_cell': True, 'use_orthogonal_z': True, 'make_primitive': False}}}, 'isUpdated': True}\n",
- "\n",
- "gh_test_material = {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': [[7.734, 0.0, 4.735709172302815e-16], [3.8670000000000018, 6.697840472868847, 4.735709172302815e-16], [0.0, 0.0, 31.573922786]]}, 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.69784, 0.0], [0.0, 0.0, 31.573923]], 'labels': []}, 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'IslandSlabDefectConfiguration', 'crystal': {'name': 'Si8(111), termination Si_P6/mmm_4, Slab', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}, {'id': 8, 'value': 'Si'}, {'id': 9, 'value': 'Si'}, {'id': 10, 'value': 'Si'}, {'id': 11, 'value': 'Si'}, {'id': 12, 'value': 'Si'}, {'id': 13, 'value': 'Si'}, {'id': 14, 'value': 'Si'}, {'id': 15, 'value': 'Si'}, {'id': 16, 'value': 'Si'}, {'id': 17, 'value': 'Si'}, {'id': 18, 'value': 'Si'}, {'id': 19, 'value': 'Si'}, {'id': 20, 'value': 'Si'}, {'id': 21, 'value': 'Si'}, {'id': 22, 'value': 'Si'}, {'id': 23, 'value': 'Si'}, {'id': 24, 'value': 'Si'}, {'id': 25, 'value': 'Si'}, {'id': 26, 'value': 'Si'}, {'id': 27, 'value': 'Si'}, {'id': 28, 'value': 'Si'}, {'id': 29, 'value': 'Si'}, {'id': 30, 'value': 'Si'}, {'id': 31, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.583333333, 0.958333333, 0.0125]}, {'id': 1, 'value': [0.583333333, 0.458333333, 0.0875]}, {'id': 2, 'value': [0.083333333, 0.458333333, 0.0125]}, {'id': 3, 'value': [0.083333333, 0.958333333, 0.0875]}, {'id': 4, 'value': [0.583333333, 0.458333333, 0.0125]}, {'id': 5, 'value': [0.583333333, 0.958333333, 0.0875]}, {'id': 6, 'value': [0.083333333, 0.958333333, 0.0125]}, {'id': 7, 'value': [0.083333333, 0.458333333, 0.0875]}, {'id': 8, 'value': [0.25, 0.625, 0.1125]}, {'id': 9, 'value': [0.25, 0.125, 0.1875]}, {'id': 10, 'value': [0.75, 0.125, 0.1125]}, {'id': 11, 'value': [0.75, 0.625, 0.1875]}, {'id': 12, 'value': [0.25, 0.125, 0.1125]}, {'id': 13, 'value': [0.25, 0.625, 0.1875]}, {'id': 14, 'value': [0.75, 0.625, 0.1125]}, {'id': 15, 'value': [0.75, 0.125, 0.1875]}, {'id': 16, 'value': [0.916666667, 0.291666667, 0.2125]}, {'id': 17, 'value': [0.916666667, 0.791666667, 0.2875]}, {'id': 18, 'value': [0.416666667, 0.791666667, 0.2125]}, {'id': 19, 'value': [0.416666667, 0.291666667, 0.2875]}, {'id': 20, 'value': [0.916666667, 0.791666667, 0.2125]}, {'id': 21, 'value': [0.916666667, 0.291666667, 0.2875]}, {'id': 22, 'value': [0.416666667, 0.291666667, 0.2125]}, {'id': 23, 'value': [0.416666667, 0.791666667, 0.2875]}, {'id': 24, 'value': [0.583333333, 0.958333333, 0.3125]}, {'id': 25, 'value': [0.583333333, 0.458333333, 0.3875]}, {'id': 26, 'value': [0.083333333, 0.458333333, 0.3125]}, {'id': 27, 'value': [0.083333333, 0.958333333, 0.3875]}, {'id': 28, 'value': [0.583333333, 0.458333333, 0.3125]}, {'id': 29, 'value': [0.583333333, 0.958333333, 0.3875]}, {'id': 30, 'value': [0.083333333, 0.958333333, 0.3125]}, {'id': 31, 'value': [0.083333333, 0.458333333, 0.3875]}], 'units': 'crystal', 'cell': [[7.734, 0.0, 0.0], [3.867, 6.697840473, 0.0], [0.0, 0.0, 31.573922786]], 'constraints': [], 'labels': []}, 'lattice': {'a': 7.734, 'b': 7.734, 'c': 31.573922786, 'alpha': 90.0, 'beta': 90.0, 'gamma': 60.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [7.734, 0.0, 0.0], 'b': [3.867, 6.697840473, 0.0], 'c': [0.0, 0.0, 31.573922786], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}, 'build': {'termination': 'Si_P6/mmm_4', 'configuration': {'type': 'SlabConfiguration', 'bulk': {'name': 'Si8', 'basis': {'elements': [{'id': 0, 'value': 'Si'}, {'id': 1, 'value': 'Si'}, {'id': 2, 'value': 'Si'}, {'id': 3, 'value': 'Si'}, {'id': 4, 'value': 'Si'}, {'id': 5, 'value': 'Si'}, {'id': 6, 'value': 'Si'}, {'id': 7, 'value': 'Si'}], 'coordinates': [{'id': 0, 'value': [0.5, 0.0, 0.0]}, {'id': 1, 'value': [0.25, 0.25, 0.75]}, {'id': 2, 'value': [0.5, 0.5, 0.5]}, {'id': 3, 'value': [0.25, 0.75, 0.25]}, {'id': 4, 'value': [0.0, 0.0, 0.5]}, {'id': 5, 'value': [0.75, 0.25, 0.25]}, {'id': 6, 'value': [0.0, 0.5, 0.0]}, {'id': 7, 'value': [0.75, 0.75, 0.75]}], 'units': 'crystal', 'cell': [[5.468763846, 0.0, 0.0], [0.0, 5.468763846, 0.0], [0.0, 0.0, 5.468763846]], 'constraints': [], 'labels': []}, 'lattice': {'a': 5.468763846, 'b': 5.468763846, 'c': 5.468763846, 'alpha': 90.0, 'beta': 90.0, 'gamma': 90.0, 'units': {'length': 'angstrom', 'angle': 'degree'}, 'type': 'TRI', 'vectors': {'a': [5.468763846, 0.0, 0.0], 'b': [0.0, 5.468763846, 0.0], 'c': [0.0, 0.0, 5.468763846], 'alat': 1, 'units': 'angstrom'}}, 'isNonPeriodic': False, '_id': '', 'metadata': {'boundaryConditions': {'type': 'pbc', 'offset': 0}}, 'isUpdated': True}, 'miller_indices': (1, 1, 1), 'thickness': 4, 'vacuum': 6, 'xy_supercell_matrix': [[1, 0], [0, 1]], 'use_conventional_cell': True, 'use_orthogonal_z': True, 'make_primitive': False}}}, 'isUpdated': True}, 'number_of_added_layers': 1, 'defect_type': 'ISLAND', 'condition': {'type': 'CylinderCoordinateCondition', 'center_position': [0.625, 0.5], 'radius': 0.25, 'min_z': 0.0, 'max_z': 1.0}}}}}\n",
- "\n",
- "gh_test_material = Material(gh_test_material)\n",
- "gh_test_slab = Material(gh_test_slab)\n",
- "visualize([{\"material\": gh_test_slab, \"title\": \"Original material\"}, {\"material\": gh_test_material, \"title\": \"Material with island defect\"}])\n",
- "visualize([{\"material\": gh_test_slab, \"title\": \"Original material\"}, {\"material\": gh_test_material, \"title\": \"Material with island defect\"}], rotation=\"-90x\")\n"
- ],
- "id": "f88267e1da862e35",
- "outputs": [
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si32 - Original material - rotation: 0x,0y,0z', layout=Layout(al…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "18d9d1eced5746fc864bacdc2918fb70"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si32 - Original material - rotation: -90x', layout=Layout(align_…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "72e621b113c54ac58201442909e2956c"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "execution_count": 12
- },
- {
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-09-10T22:35:17.348635Z",
- "start_time": "2024-09-10T20:14:33.614506Z"
- }
- },
- "cell_type": "code",
- "source": [
- "from pymatgen.core.surface import SlabGenerator as PymatgenSlabGenerator\n",
- "from mat3ra.made.tools.convert import to_pymatgen, from_pymatgen\n",
- "clean_material = Material.create(Material.default_config)\n",
- "generator = PymatgenSlabGenerator(\n",
- " initial_structure=to_pymatgen(clean_material),\n",
- " miller_index=(0,0,1),\n",
- " min_slab_size=3,\n",
- " min_vacuum_size=1,\n",
- " in_unit_planes=True,\n",
- " reorient_lattice=True,\n",
- " primitive=False\n",
- " )\n",
- "raw_slabs = generator.get_slabs()\n",
- "material_slabs = [Material(from_pymatgen(slab)) for slab in raw_slabs]\n",
- "# material_slabs = [Material(from_pymatgen(slab.get_orthogonal_c_slab())) for slab in raw_slabs]\n",
- "visualize(material_slabs)\n",
- "visualize(material_slabs, rotation=\"-90x\")"
- ],
- "id": "4681f90b3e4b25e9",
- "outputs": [
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si6 - Material - rotation: 0x,0y,0z', layout=Layout(align_self='…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "51b526bde1ac459b8712a867d5307898"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/plain": [
- "GridBox(children=(VBox(children=(Label(value='Si6 - Material - rotation: -90x', layout=Layout(align_self='cent…"
- ],
- "application/vnd.jupyter.widget-view+json": {
- "version_major": 2,
- "version_minor": 0,
- "model_id": "11fabcd68bdb4cabb9848d3ba8b7d0e0"
- }
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "execution_count": 25
- },
- {
- "metadata": {},
- "cell_type": "code",
- "outputs": [],
- "execution_count": null,
- "source": "",
- "id": "51909da14eeaf743"
- }
- ],
- "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 174690478072d92c2234e546c6f8ed567dc63cde Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 13:13:13 -0700
Subject: [PATCH 19/23] chore: small adjustments
---
.../create_interface_with_min_strain_zsl.ipynb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index 2bec280f..47921223 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -51,7 +51,7 @@
"# Enable interactive selection of terminations via UI prompt\n",
"IS_TERMINATIONS_SELECTION_INTERACTIVE = False \n",
"\n",
- "FILM_INDEX = 1\n",
+ "FILM_INDEX = 1 # Index in the list of materials, to access as materials[FILM_INDEX]\n",
"FILM_MILLER_INDICES = (0, 0, 1)\n",
"FILM_THICKNESS = 1 # in atomic layers\n",
"FILM_VACUUM = 0 # in atomic layers\n",
@@ -123,7 +123,7 @@
"try: \n",
" film = materials[FILM_INDEX]\n",
"except IndexError:\n",
- " print(\"Please select a film material. Film is set to substrate.\")\n",
+ " print(\"Film material not found. Re-using substrate material as film.\")\n",
" film = substrate"
],
"metadata": {
From da5a79601af0d6c071c371d2781d4df503e34191 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 13:18:37 -0700
Subject: [PATCH 20/23] chore: add a comment
---
.../create_interface_with_min_strain_zsl.ipynb | 2 +-
.../create_interface_with_no_strain_matching.ipynb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index 47921223..de89748c 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -68,7 +68,7 @@
"# Maximum area for the superlattice search algorithm\n",
"MAX_AREA = 50\n",
"# Set the termination pair indices\n",
- "TERMINATION_PAIR_INDEX = 0\n",
+ "TERMINATION_PAIR_INDEX = 0 # Will be overridden in interactive selection is used\n",
"INTERFACE_DISTANCE = 3.0 # in Angstrom\n",
"INTERFACE_VACUUM = 20.0 # in Angstrom"
],
diff --git a/other/materials_designer/create_interface_with_no_strain_matching.ipynb b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
index 3313b4a1..1257a6d0 100644
--- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb
+++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
@@ -60,7 +60,7 @@
"SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
"\n",
"# Set the termination pair indices\n",
- "TERMINATION_PAIR_INDEX = 0\n",
+ "TERMINATION_PAIR_INDEX = 0 # Will be overridden in interactive selection is used\n",
"INTERFACE_DISTANCE = 3.0 # in Angstrom\n",
"INTERFACE_VACUUM = 20.0 # in Angstrom"
],
From 5625fb8f6b042c04d7f34588b20344f15ce45025 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 15:47:04 -0700
Subject: [PATCH 21/23] chore: change layers -> angstroms
---
.../create_interface_with_min_strain_zsl.ipynb | 10 +++++-----
.../create_interface_with_no_strain_matching.ipynb | 8 ++++----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index de89748c..96e76f84 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -54,19 +54,19 @@
"FILM_INDEX = 1 # Index in the list of materials, to access as materials[FILM_INDEX]\n",
"FILM_MILLER_INDICES = (0, 0, 1)\n",
"FILM_THICKNESS = 1 # in atomic layers\n",
- "FILM_VACUUM = 0 # 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_INDEX = 0\n",
"SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n",
"SUBSTRATE_THICKNESS = 3 # in atomic layers\n",
- "SUBSTRATE_VACUUM = 3 # in atomic layers\n",
+ "SUBSTRATE_VACUUM = 3.0 # in angstroms\n",
"SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
"SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
"\n",
"# Maximum area for the superlattice search algorithm\n",
- "MAX_AREA = 50\n",
+ "MAX_AREA = 50 # in Angstrom^2\n",
"# Set the termination pair indices\n",
"TERMINATION_PAIR_INDEX = 0 # Will be overridden in interactive selection is used\n",
"INTERFACE_DISTANCE = 3.0 # in Angstrom\n",
@@ -173,7 +173,7 @@
" bulk=film,\n",
" miller_indices=FILM_MILLER_INDICES,\n",
" thickness=FILM_THICKNESS, # in atomic layers\n",
- " vacuum=FILM_VACUUM, # in atomic layers\n",
+ " vacuum=FILM_VACUUM, # in angstroms\n",
" xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n",
" use_orthogonal_z=FILM_USE_ORTHOGONAL_Z\n",
")\n",
@@ -182,7 +182,7 @@
" bulk=substrate,\n",
" miller_indices=SUBSTRATE_MILLER_INDICES,\n",
" thickness=SUBSTRATE_THICKNESS, # in atomic layers\n",
- " vacuum=SUBSTRATE_VACUUM, # in atomic layers\n",
+ " vacuum=SUBSTRATE_VACUUM, # in angstroms\n",
" xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n",
" use_orthogonal_z=SUBSTRATE_USE_ORTHOGONAL_Z\n",
")"
diff --git a/other/materials_designer/create_interface_with_no_strain_matching.ipynb b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
index 1257a6d0..fcb95efc 100644
--- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb
+++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
@@ -48,14 +48,14 @@
"FILM_INDEX = 1\n",
"FILM_MILLER_INDICES = (0, 0, 1)\n",
"FILM_THICKNESS = 1 # in atomic layers\n",
- "FILM_VACUUM = 0 # 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_INDEX = 0\n",
"SUBSTRATE_MILLER_INDICES = (1, 1, 1)\n",
"SUBSTRATE_THICKNESS = 3 # in atomic layers\n",
- "SUBSTRATE_VACUUM = 3 # in atomic layers\n",
+ "SUBSTRATE_VACUUM = 3.0 # in angstroms\n",
"SUBSTRATE_XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]]\n",
"SUBSTRATE_USE_ORTHOGONAL_Z = True\n",
"\n",
@@ -170,7 +170,7 @@
" bulk=film,\n",
" miller_indices=FILM_MILLER_INDICES,\n",
" thickness=FILM_THICKNESS, # in atomic layers\n",
- " vacuum=FILM_VACUUM, # in atomic layers\n",
+ " vacuum=FILM_VACUUM, # in angstroms\n",
" xy_supercell_matrix=FILM_XY_SUPERCELL_MATRIX,\n",
" use_orthogonal_z=FILM_USE_ORTHOGONAL_Z\n",
")\n",
@@ -179,7 +179,7 @@
" bulk=substrate,\n",
" miller_indices=SUBSTRATE_MILLER_INDICES,\n",
" thickness=SUBSTRATE_THICKNESS, # in atomic layers\n",
- " vacuum=SUBSTRATE_VACUUM, # in atomic layers\n",
+ " vacuum=SUBSTRATE_VACUUM, # in angstroms\n",
" xy_supercell_matrix=SUBSTRATE_XY_SUPERCELL_MATRIX,\n",
" use_orthogonal_z=SUBSTRATE_USE_ORTHOGONAL_Z\n",
")"
From affd48478d46fb7bcd85b10b63476e4aafc1deda Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 18:05:41 -0700
Subject: [PATCH 22/23] update: install mat3ra packages in utils in pyodide to
be able to load Material etc
---
utils/jupyterlite.py | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/utils/jupyterlite.py b/utils/jupyterlite.py
index 195368a5..25e548fe 100644
--- a/utils/jupyterlite.py
+++ b/utils/jupyterlite.py
@@ -1,12 +1,21 @@
import inspect
import json
import os
+import sys
from enum import Enum
from typing import Any, Dict, List, Optional
from IPython.display import Javascript, display
-from mat3ra.made.material import Material
-from mat3ra.utils.array import convert_to_array_if_not
+
+
+async def install_setup():
+ if sys.platform == "emscripten":
+ import micropip
+
+ await micropip.install("mat3ra-made")
+ await micropip.install("mat3ra-code")
+ await micropip.install("mat3ra-utils")
+
UPLOADS_FOLDER = "uploads"
@@ -31,7 +40,6 @@ class SeverityLevelEnum(Enum):
if ENVIRONMENT == EnvironmentEnum.PYTHON:
import subprocess
- import sys
def log(message: str, level: Optional[SeverityLevelEnum] = None, force_verbose=None):
@@ -99,6 +107,7 @@ async def install_packages(notebook_name: str, requirements_path="config.yml", v
verbose (bool): Whether to print the names of the installed packages and status of installation.
"""
if ENVIRONMENT == EnvironmentEnum.PYODIDE:
+ await install_setup()
await micropip.install("pyyaml")
# PyYAML has to be installed before being imported in Pyodide and can't appear at the top of the file
import yaml
@@ -255,7 +264,7 @@ def get_data(key: str, globals_dict: Optional[Dict] = None):
get_data_python(key, globals_dict)
-def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
+def get_materials(globals_dict: Optional[Dict] = None) -> List[Any]:
"""
Retrieve materials from the environment and assign them to globals_dict["materials_in"].
@@ -265,6 +274,7 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
Returns:
List[Material]: A list of Material objects.
"""
+ from mat3ra.made.material import Material
if globals_dict is None:
frame = inspect.currentframe()
@@ -285,13 +295,15 @@ def get_materials(globals_dict: Optional[Dict] = None) -> List[Material]:
return []
-def set_materials(materials: List[Material]):
+def set_materials(materials: List[Any]):
"""
Serialize and send a list of Material objects to the environment.
Args:
materials (List[Material]): The list of Material objects to send.
"""
+ from mat3ra.utils.array import convert_to_array_if_not
+
materials = convert_to_array_if_not(materials)
materials_data = [material.to_json() for material in materials]
set_data("materials", materials_data)
From 8fa789e979b2f5ee48849a174b849fe14b52c036 Mon Sep 17 00:00:00 2001
From: VsevolodX <79542055+VsevolodX@users.noreply.github.com>
Date: Fri, 4 Oct 2024 18:07:28 -0700
Subject: [PATCH 23/23] chore: add globals
---
.../create_interface_with_min_strain_zsl.ipynb | 3 ++-
.../create_interface_with_no_strain_matching.ipynb | 2 +-
.../create_interface_with_relaxation_ase_emt.ipynb | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
index 96e76f84..54d1f57d 100644
--- a/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
+++ b/other/materials_designer/create_interface_with_min_strain_zsl.ipynb
@@ -95,6 +95,7 @@
"\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(\"create_interface_with_min_strain_zsl.ipynb\", \"../../config.yml\")"
@@ -118,7 +119,7 @@
"source": [
"from utils.jupyterlite import get_materials\n",
"\n",
- "materials = get_materials()\n",
+ "materials = get_materials(globals())\n",
"substrate = materials[SUBSTRATE_INDEX]\n",
"try: \n",
" film = materials[FILM_INDEX]\n",
diff --git a/other/materials_designer/create_interface_with_no_strain_matching.ipynb b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
index fcb95efc..4a2940c4 100644
--- a/other/materials_designer/create_interface_with_no_strain_matching.ipynb
+++ b/other/materials_designer/create_interface_with_no_strain_matching.ipynb
@@ -113,7 +113,7 @@
"source": [
"from utils.jupyterlite import get_materials\n",
"\n",
- "materials = get_materials()\n",
+ "materials = get_materials(globals())\n",
"substrate = materials[SUBSTRATE_INDEX]\n",
"try: \n",
" film = materials[FILM_INDEX]\n",
diff --git a/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb b/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
index d435c62c..17a0a03e 100644
--- a/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
+++ b/other/materials_designer/create_interface_with_relaxation_ase_emt.ipynb
@@ -95,7 +95,7 @@
"source": [
"from utils.jupyterlite import get_materials\n",
"\n",
- "materials = get_materials()\n",
+ "materials = get_materials(globals())\n",
"interface = materials[0]"
]
},