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]" ] },